Endless Tower w/ difficulty

Louis T Steinhil

New member
Messages
172
Points
0
Age
35
Discord
Louis T Steinhil#8600
Emulator
Hercules
Hello guys anyone can help me with this script? I'm converting my endless tower from rAthena to Hercules. Since we don't have this what should I use instead?

*instance_live_info(<info type>{,<instance id>});

Returns the specified <info type> of instance attached to the npc or, if
an instance ID is specified, of that instance.

Valid <info type>:
ILI_NAME - Instance Name
Return the name of the instance or "" if that fails.
ILI_MODE - Instance Mode
Return IM_NONE, IM_CHAR, IM_PARTY, IM_GUILD, IM_CLAN or -1 if that fails.
ILI_OWNER - Owner ID
Return an ID according to the instance mode of the instance attached/specified or -1 if that fails.
When the instance mode is IM_NONE, ILI_OWNER will return the npc ID that created the instance,
IM_CHAR - the owner char ID
IM_PARTY - the party ID
IM_GUILD - the guild ID
IM_CLAN - the clan ID

Examples:
// Return the instance name of the instance attached to the npc.
.@instance_name$ = instance_live_info(ILI_NAME);

// Return the guild owner ID of the given instance ID.
.@owner = instance_live_info(ILI_OWNER, instance_id(IM_GUILD));


This part links the value of what the player chose so it would supply the data if it's easy / hard etc.

1@tower,29,365,1 script #1F Controller 844,{
end;

OnInstanceInit:
'level_mode = $ENDLESSMODE[instance_live_info(ILI_OWNER)]; <----

callfunc "F_Tower_Monster",1,instance_mapname("1@tower"),instance_npcname("#1F Controller")+"::OnMyMobDead";


https://rathena.org/board/topic/133368-quests-games-endless-tower-instance-with-difficulty/

 
Think the closest to have for now is saving the relevant information you want in instance creation.

*instance_create("<instance_name>", <owner_id>{, <owner_type>})

Creates an instance using the name "<instance_name>" for the <owner_id> of
<owner_type> (when not provided, defaults to IOT_PARTY). Most instance_*
commands are used in conjunction with this command and depend on the
ID this command returns.

Valid <owner_type> values:
- IOT_NONE (0) - <owner_id> can be any arbitrary number.
- IOT_CHAR (1) - <owner_id> is account ID.
- IOT_PARTY (2) - <owner_id> is party ID.
- IOT_GUILD (3) - <owner_id> is guild ID.

Example:
// Store the Party ID of the invoking character.
.@party_id = getcharid(CHAR_ID_PARTY);

// Attempt to create an instance using that party ID.
.@id = instance_create("Endless Tower", .@party_id);
if (.@id == -1) { // Invalid type - not used anymore
// ...
} else if (.@id == -2) { // Invalid Party ID
// ...
} else if (.@id == -4) { // Already exists
// ...
} else if (.@id < 0) { // Unspecified error while queuing instance.
// ...
}




The alternative would be to change the way instance is handled in source code, or implement a plugin to fetch instance info similar on how rAthena does and uses on that script. From what I understood, you want to retrieve the instance level mode by supplying the instance owner id?

 
Last edited by a moderator:
I think your options are:

1. Recreate the script command in herc, shouldn't be that hard, I believe this info is available, just need to make a script command to get it

2. Save a dynamic global variable using the instance ID as suffix using setd between instance_create and instance_init. Once the instance starts, you can copy the value from the global variable into an instance variable. Something like that:

// create instance
.@instanceId = instance_create(...)

// Make global var
setd(sprintf("$@instance_type_%d", .@instanceId), 1 /* whatever you need to store */);

// Init it
instance_init(...)

// ------

// This is called on instance_init
OnInstanceInit:
.@varName$ = sprintf("$@instance_type_%d", instance_id());
'instanceType = getd(.@varName$);
setd(.@varName$, 0); // Clean up so you don't mess up future id reuses
end;




References:

- OnInstanceInit: https://github.com/HerculesWS/Hercules/blob/stable/doc/script_commands.txt#L1151

- instance_create: https://github.com/HerculesWS/Hercules/blob/stable/doc/script_commands.txt#L9730

- instance_init: https://github.com/HerculesWS/Hercules/blob/stable/doc/script_commands.txt#L9793

 
I think your options are:

1. Recreate the script command in herc, shouldn't be that hard, I believe this info is available, just need to make a script command to get it

2. Save a dynamic global variable using the instance ID as suffix using setd between instance_create and instance_init. Once the instance starts, you can copy the value from the global variable into an instance variable. Something like that:

// create instance .@instanceId = instance_create(...) // Make global var setd(sprintf("$@instance_type_%d", .@instanceId), 1 /* whatever you need to store */); // Init it instance_init(...) // ------ // This is called on instance_init OnInstanceInit: .@varName$ = sprintf("$@instance_type_%d", instance_id()); 'instanceType = getd(.@varName$); setd(.@varName$, 0); // Clean up so you don't mess up future id reuses end;

// create instance
.@instanceId = instance_create(...)

// Make global var
setd(sprintf("$@instance_type_%d", .@instanceId), 1 /* whatever you need to store */);

// Init it
instance_init(...)

// ------

// This is called on instance_init
OnInstanceInit:
.@varName$ = sprintf("$@instance_type_%d", instance_id());
'instanceType = getd(.@varName$);
setd(.@varName$, 0); // Clean up so you don't mess up future id reuses
end;




References:

- OnInstanceInit: https://github.com/HerculesWS/Hercules/blob/stable/doc/script_commands.txt#L1151

- instance_create: https://github.com/HerculesWS/Hercules/blob/stable/doc/script_commands.txt#L9730

- instance_init: https://github.com/HerculesWS/Hercules/blob/stable/doc/script_commands.txt#L9793
This seems to be okay but i got an error on getunitdata.
 

 setd("$ENDLESSMODE[" + .@instance + "]", .@level_mode);                
dispbottom "Choice: " + getd("$ENDLESSMODE[" + .@instance + "]");

OnInstanceInit:
    .@level_mode = getd("$ENDLESSMODE[" + instance_id() + "]");
    'level_mode = .@level_mode; 

 

function script F_Tower_Monster_Summon {
.@map$ = getarg(0, "");
.@x1 = getarg(1, 0);
.@y1 = getarg(2, 0);
.@x2 = getarg(3, 0);
.@y2 = getarg(4, 0);
.@mob_name$ = getarg(5, "");
.@mob_id = getarg(6, 0);
.@amount = getarg(7, 0);
.@label$ = getarg(8, "");

switch('level_mode){
case 1://Normal
.@bonus_hp_rate += 0;
.@bonus_dmg_rate += 0;
.@bonus_damagetaken += 0;
.@bonus_def += 0;
.@bonus_mdef += 0;
.@bonus_hit += 0;
.@bonus_flee += 0;
break;
case 2://Veteran
.@bonus_hp_rate += 40;
.@bonus_dmg_rate += 40;
.@bonus_damagetaken += -10;
.@bonus_def += 40;
.@bonus_mdef += 40;
.@bonus_hit += 40;
.@bonus_flee += 40;
break;
case 3://Nightmare
.@bonus_hp_rate += 80;
.@bonus_dmg_rate += 80;
.@bonus_damagetaken += -20;
.@bonus_def += 80;
.@bonus_mdef += 80;
.@bonus_hit += 80;
.@bonus_flee += 80;
break;
case 4://Hell
.@bonus_hp_rate += 100;
.@bonus_dmg_rate += 100;
.@bonus_damagetaken += -30;
.@bonus_def += 100;
.@bonus_mdef += 100;
.@bonus_hit += 100;
.@bonus_flee += 100;
break;
case 5://Torment
.@bonus_hp_rate += 200;
.@bonus_dmg_rate += 200;
.@bonus_damagetaken += -40;
.@bonus_def += 200;
.@bonus_mdef += 200;
.@bonus_hit += 200;
.@bonus_flee += 200;
break;
}
deletearray $@mobid,getarraysize($@mobid);
areamonster .@map$, .@x1, .@y1, .@x2, .@y2, .@mob_name$, .@mob_id, .@amount, .@label$;
copyarray .@GID, $@mobid, getarraysize($@mobid);
if(!.@bonus_hp_rate&& !.@bonus_dmg_rate&& !.@bonus_damagetaken&& !.@bonus_def&& !.@bonus_mdef&& !.@bonus_hit&& !.@bonus_flee)
return;
getunitdata .@GID, .@ST;

if(.@bonus_hp_rate){
.@HP = .@ST[UDT_MAXHP] + ((.@ST[UDT_MAXHP] * .@bonus_hp_rate ) /100);
for(.@i=0;.@i<getarraysize(.@GID);.@i++){
setunitdata(.@GID[.@i], UDT_MAXHP, .@HP);
setunitdata(.@GID[.@i], UDT_HP, .@HP);
}
}
if(.@bonus_dmg_rate){
.@ATKMIN = .@ST[UDT_ATKMIN] + ((.@ST[UDT_ATKMIN] * .@bonus_dmg_rate) /100);
.@ATKMAX = .@ST[UDT_ATKMAX] + ((.@ST[UDT_ATKMAX] * .@bonus_dmg_rate) /100);
.@MATKMIN = .@ST[UDT_MATKMIN] + ((.@ST[UDT_MATKMIN] * .@bonus_dmg_rate) /100);
.@MATKMAX = .@ST[UDT_MATKMAX] + ((.@ST[UDT_MATKMAX] * .@bonus_dmg_rate) /100);
for(.@i=0;.@i<getarraysize(.@GID);.@i++){
setunitdata(.@GID[.@i], UDT_ATKMIN, .@ATKMIN);
setunitdata(.@GID[.@i], UDT_ATKMAX, .@ATKMAX);
setunitdata(.@GID[.@i], UDT_MATKMIN, .@MATKMIN);
setunitdata(.@GID[.@i], UDT_MATKMAX, .@MATKMAX);
}
}
if(.@bonus_damagetaken){
.@DAMAGETAKEN = .@ST[UDT_DAMAGE_TAKEN_RATE] + ((.@ST[UDT_DAMAGE_TAKEN_RATE] * .@bonus_damagetaken) /100);
for(.@i=0;.@i<getarraysize(.@GID);.@i++){
setunitdata(.@GID[.@i], UDT_DAMAGE_TAKEN_RATE, .@DAMAGETAKEN);
}
}
if(.@bonus_def){
.@DEF = .@ST[UDT_DEF] + ((.@ST[UDT_DEF] * .@bonus_def) /100);
for(.@i=0;.@i<getarraysize(.@GID);.@i++){
setunitdata(.@GID[.@i], UDT_DEF, .@DEF);
}
}
if(.@bonus_mdef){
.@MDEF = .@ST[UDT_MDEF] + ((.@ST[UDT_MDEF] * .@bonus_mdef) /100);
for(.@i=0;.@i<getarraysize(.@GID);.@i++){
setunitdata(.@GID[.@i], UDT_MDEF, .@MDEF);
}
}
if(.@bonus_hit){
.@HIT = .@ST[UDT_HIT] + ((.@ST[UDT_HIT] * .@bonus_hit) /100);
for(.@i=0;.@i<getarraysize(.@GID);.@i++){
setunitdata(.@GID[.@i], UDT_HIT, .@HIT);
}
}
if(.@bonus_flee){
.@FLEE = .@ST[UDT_FLEE] + ((.@ST[UDT_FLEE] * .@bonus_flee) /100);
for(.@i=0;.@i<getarraysize(.@GID);.@i++){
setunitdata(.@GID[.@i], UDT_FLEE, .@FLEE);
}
}
return;
}


Error:
 

Code:
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): #1F Controller at 0001@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): #1F Controller at 0001@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): #1F Controller at 0001@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): #1F Controller at 0001@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): #1F Controller at 0001@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): #1F Controller at 0001@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): Immortal Furnace#1 at 0002@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): Immortal Furnace#1 at 0002@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): Immortal Furnace#1 at 0002@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): Immortal Furnace#1 at 0002@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): Immortal Furnace#1 at 0002@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): Immortal Furnace#2 at 0003@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): Immortal Furnace#2 at 0003@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): Immortal Furnace#2 at 0003@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): Immortal Furnace#3 at 0004@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): Immortal Furnace#3 at 0004@tower (29,365)
[Warning]: buildin_getunitdata: Error in finding object with given GID 0!
[Debug]: Source (NPC): Immortal Furnace#3 at 0004@tower (29,365)
 
Last edited by a moderator:
I am not sure what exactly is wrong, but as far as I can tell, this code doesn't make much sense... I have only skimmed through the initial part, but:

$@mobid is an empty array, and is being copied into .@GID (Thus, .@GID would be an array too?), but then .@GID is passed to getunitdata, which doesn't expect an array... and getunitdata result is not used at all..

So I am really not sure what it is trying to do

 
I am not sure what exactly is wrong, but as far as I can tell, this code doesn't make much sense... I have only skimmed through the initial part, but:

$@mobid is an empty array, and is being copied into .@GID (Thus, .@GID would be an array too?), but then .@GID is passed to getunitdata, which doesn't expect an array... and getunitdata result is not used at all..

So I am really not sure what it is trying to do
Sorry wasn't aware that $@mobid[] was not available in herc. 
 

Code:
Returned value is an array with the game ID of the spawned monster(s) depending
on the amount spawned. Array is stored in $@mobid[].
 
I think I got it now. Thanks!

screenHercules002.jpg

Code:
freeloop(true);	
	// Summon mobs and store their IDs
	for (.@i = 0; .@i < .@amount; .@i++) {
		.@mobGID = areamonster(.@map$, .@x1, .@y1, .@x2, .@y2, .@mob_name$, .@mob_id, 1, .@label$);

			.@MAXHP = getunitdata(.@mobGID, UDT_MAXHP);
			.@HP = getunitdata(.@mobGID, UDT_HP);
			setunitdata(.@mobGID, UDT_MAXHP, .@MAXHP + ((.@MAXHP * .@bonus_hp_rate) / 100));
			setunitdata(.@mobGID, UDT_HP, .@HP + ((.@HP * .@bonus_hp_rate) / 100));
			
			.@ATKMIN = getunitdata(.@mobGID, UDT_ATKMIN);
			.@ATKMAX = getunitdata(.@mobGID, UDT_ATKMAX);
			setunitdata(.@mobGID, UDT_ATKMIN, .@ATKMIN + ((.@ATKMIN * .@bonus_dmg_rate) / 100));
			setunitdata(.@mobGID, UDT_ATKMAX, .@ATKMAX + ((.@ATKMAX * .@bonus_dmg_rate) / 100));

			.@DAMAGETAKEN = getunitdata(.@mobGID, UDT_DAMAGE_TAKEN_RATE);
			setunitdata(.@mobGID, UDT_DAMAGE_TAKEN_RATE, .@DAMAGETAKEN + ((.@DAMAGETAKEN * .@bonus_damagetaken) / 100));

			.@DEF = getunitdata(.@mobGID, UDT_DEF);
			setunitdata(.@mobGID, UDT_DEF, .@DEF + ((.@DEF * .@bonus_def) / 100));

			.@MDEF = getunitdata(.@mobGID, UDT_MDEF);
			setunitdata(.@mobGID, UDT_MDEF, .@MDEF + ((.@MDEF * .@bonus_mdef) / 100));

			.@HIT = getunitdata(.@mobGID, UDT_HIT);
			setunitdata(.@mobGID, UDT_HIT, .@HIT + ((.@HIT * .@bonus_hit) / 100));

			.@FLEE = getunitdata(.@mobGID, UDT_FLEE);
			setunitdata(.@mobGID, UDT_FLEE, .@FLEE + ((.@FLEE * .@bonus_flee) / 100));	

	}
freeloop(false);
 
Last edited by a moderator:
Back
Top