Skip to content

Commit

Permalink
Merge pull request #1264 from rathena/feature/instance_expansion
Browse files Browse the repository at this point in the history
Expanded the instance system to support new modes
* New modes include: No player attached, single player, and guild.
* Modified the instance_db to allow instance idle time to be adjustable.
* Removed Map1 from the instance_db as the EnterMap is always the same value.
* Adjusted the stored maps of instances to dynamic arrays to conserve memory.
- Max amount of possible maps increased to 255.
* Instances will now be destroyed even if the owner cannot be found.
* Corrected the return value when entering an instance when a character, party, or guild does not have an instance.
* Expanded script command instance_create to take in an owner ID and an optional mode.
* Added a new script command instance_check_guild (works the same as instance_check_party).
* Corrected a few script commands to properly stop the script engine on failures for instance script commands.
* Removed the instance name lookup for when entering an instance as instance_id is now passed.
- Adjusted script command instance_enter to no longer require the instance name.
* Cleaned up script command instance_warpall.
* Adjusted script command instance_announce to check when instance ID is 0 rather than -1 since instance IDs are stored as unsigned now.
* Refactored all instance_id to unsigned short.
* Updated documentation to reflect changes.
  • Loading branch information
aleos89 committed May 25, 2016
2 parents 6f0ed15 + 28ad9ac commit 32c829d
Show file tree
Hide file tree
Showing 32 changed files with 819 additions and 381 deletions.
5 changes: 3 additions & 2 deletions db/import-tmpl/instance_db.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Instance Database
//
// Structure of Database:
// ID,Name,LimitTime,EnterMap,EnterX,EnterY,Map1,Map2,Map3,Map4,Map5,Map6,Map7,Map8

// ID,Name,LimitTime,IdleTimeOut,EnterMap,EnterX,EnterY,Map2,Map3,...,Map255
//
// EnterMap is considered as Map1
12 changes: 7 additions & 5 deletions db/pre-re/instance_db.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Instance Database
//
// Structure of Database:
// ID,Name,LimitTime,EnterMap,EnterX,EnterY,Map1,Map2,Map3,Map4,Map5,Map6,Map7,Map8
// ID,Name,LimitTime,IdleTimeOut,EnterMap,EnterX,EnterY,Map2,Map3,...,Map255
//
// EnterMap is considered as Map1

1,Endless Tower,14400,1@tower,50,355,1@tower,2@tower,3@tower,4@tower,5@tower,6@tower
2,Sealed Catacomb,7200,1@cata,100,224,1@cata,2@cata
3,Orc's Memory,3600,1@orcs,179,15,1@orcs,2@orcs
4,Nidhoggur's Nest,14400,1@nyd,32,36,1@nyd,2@nyd
1,Endless Tower,14400,300,1@tower,50,355,2@tower,3@tower,4@tower,5@tower,6@tower
2,Sealed Catacomb,7200,300,1@cata,100,224,2@cata
3,Orc's Memory,3600,300,1@orcs,179,15,2@orcs
4,Nidhoggur's Nest,14400,300,1@nyd,32,36,2@nyd
30 changes: 16 additions & 14 deletions db/re/instance_db.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
// Instance Database
//
// Structure of Database:
// ID,Name,LimitTime,EnterMap,EnterX,EnterY,Map1,Map2,Map3,Map4,Map5,Map6,Map7,Map8
// ID,Name,LimitTime,IdleTimeOut,EnterMap,EnterX,EnterY,Map2,...,Map255
//
// EnterMap is considered as Map1

1,Endless Tower,14400,1@tower,50,355,1@tower,2@tower,3@tower,4@tower,5@tower,6@tower
2,Sealed Catacomb,7200,1@cata,100,224,1@cata,2@cata
3,Orc's Memory,3600,1@orcs,179,15,1@orcs,2@orcs
4,Nidhoggur's Nest,14400,1@nyd,32,36,1@nyd,2@nyd
5,Mistwood Maze,7200,1@mist,89,29,1@mist
6,Culvert,3600,1@pump,63,98,1@pump,2@pump
7,Octopus Cave,3600,1@cash,199,99,1@cash
8,Bangungot Hospital 2F,3600,1@ma_h,40,157,1@ma_h
9,Buwaya Cave,3600,1@ma_c,35,57,1@ma_c
10,Bakonawa Lake,7200,1@ma_b,64,51,1@ma_b
11,Wolfchev's Laboratory,14400,1@lhz,45,148,1@lhz
12,Old Glast Heim,3600,1@gl_k,150,20,1@gl_k,2@gl_k
13,Eclage Interior,1200,1@ecl,60,50,1@ecl
1,Endless Tower,14400,300,1@tower,50,355,2@tower,3@tower,4@tower,5@tower,6@tower
2,Sealed Catacomb,7200,300,1@cata,100,224,2@cata
3,Orc's Memory,3600,300,1@orcs,179,15,2@orcs
4,Nidhoggur's Nest,14400,300,1@nyd,32,36,2@nyd
5,Mistwood Maze,7200,300,1@mist,89,29
6,Culvert,3600,300,1@pump,63,98,2@pump
7,Octopus Cave,3600,300,1@cash,199,99
8,Bangungot Hospital 2F,3600,300,1@ma_h,40,157
9,Buwaya Cave,3600,300,1@ma_c,35,57
10,Bakonawa Lake,7200,300,1@ma_b,64,51
11,Wolfchev's Laboratory,14400,300,1@lhz,45,148
12,Old Glast Heim,3600,300,1@gl_k,150,20,2@gl_k
13,Eclage Interior,1200,300,1@ecl,60,50
87 changes: 61 additions & 26 deletions doc/script_commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//===== By: ==================================================
//= rAthena Dev Team
//===== Last Updated: ========================================
//= 20150610
//= 20160523
//===== Description: =========================================
//= A reference manual for the rAthena scripting language.
//= Commands are sorted depending on their functionality.
Expand Down Expand Up @@ -472,8 +472,8 @@ nothing - A permanent variable attached to the character, the default variable
ends it. When a scope ends, its variables are converted to values
('return .@var;' returns a value, not a reference).
"'" - An instance variable.
These are used with the instancing system, and are unique to each
party's instance.
These are used with the instancing system and are unique to each
instance type.
"#" - A permanent local account variable.
They are stored by char-server in the `acc_reg_num` table and
`acc_reg_str`.
Expand Down Expand Up @@ -503,6 +503,8 @@ $@name$ - temporary global string variable
.name$ - NPC string variable
.@name - scope integer variable
.@name$ - scope string variable
'name - instance integer variable
'name$ - instance string variable
#name - permanent local account integer variable
#name$ - permanent local account string variable
##name - permanent global account integer variable
Expand Down Expand Up @@ -8117,17 +8119,23 @@ This command will open a book item at the specified page.
========================
---------------------------------------

*instance_create("<instance name>");
*instance_create("<instance name>"{,<instance mode>{,<owner id>}});

Creates an instance for the party of the attached player. The instance name,
along with all other instance data, is read from 'db/(pre-)re/instance_db.txt'.
Upon success, the command generates a unique instance ID, duplicates all listed
maps and NPCs, sets the alive time, and triggers the "OnInstanceInit" label in
all NPCs inside the instance.
Creates an instance for the <owner id> of <mode>. The instance name, along with
all other instance data, is read from 'db/(pre-)re/instance_db.txt'. Upon success,
the command generates a unique instance ID, duplicates all listed maps and NPCs,
sets the alive time, and triggers the "OnInstanceInit" label in all NPCs inside
the instance.

Instance Mode options:
IM_NONE: Attached to no one.
IM_CHAR: Attached to a single character.
IM_PARTY: Attached to a party (default instance mode).
IM_GUILD: Attached to a guild.

The command returns the instance ID upon success, and these values upon failure:
-1: Invalid type.
-2: Party not found.
-2: Character/Party/Guild not found.
-3: Instance already exists.
-4: No free instances (MAX_INSTANCE exceeded).

Expand All @@ -8137,20 +8145,21 @@ The command returns the instance ID upon success, and these values upon failure:

Destroys instance with the ID <instance id>. If no ID is specified, the instance
the script is attached to is used. If the script is not attached to an instance,
the instance of the currently attached player's party is used. If that fails,
the script will come to a halt.
the instance of the currently attached player is used (if it is a character, party,
or guild mode). If it is not owned by anyone, no player needs to be attached. If
that fails, the script will come to a halt.

---------------------------------------

*instance_enter("<instance name>"{,<x>,<y>,<char_id>});
*instance_enter({<x>,<y>,<char_id>});

Warps player to the specified instance after the script terminates. The map and
coordinates are located in 'db/(pre-)re/instance_db.txt'.

The command returns 0 upon success, and these values upon failure:
1: Party not found.
2: Party does not have an instance.
3: Other errors (invalid instance name, instance doesn't match with party).
1: Party/Guild not found (for party/guild modes).
2: Character/Party/Guild does not have an instance.
3: Other errors (invalid instance name, instance doesn't match with character/party/guild).

Put -1 for x and y if want to warp player with default entrance coordinates.

Expand All @@ -8160,25 +8169,27 @@ Put -1 for x and y if want to warp player with default entrance coordinates.

Returns the unique name of the instanced script. If no ID is specified,
the instance the script is attached to is used. If the script is not attached to
an instance, the instance of the currently attached player's party is used. If
that fails, the script will come to a halt.
an instance, the instance of the currently attached NPC, player, party, or guild
is used. If that fails, the script will come to a halt.

---------------------------------------

*instance_mapname("<map name>"{,<instance id>})

Returns the unique name of the instanced map. If no instance ID is specified,
the instance the script is attached to is used. If the script is not attached to
an instance, the instance of the currently attached player's party is used. If
that fails, the command returns an empty string instead.
an instance, the instance of the currently attached player is used (if it is a
character, party, or guild mode). If it is not owned by anyone, no player needs
to be attached. If that fails, the command returns an empty string instead.

---------------------------------------

*instance_id()

Returns the unique instance id of the attached script. If the script is not
attached to an instance, the instance of the currently attached player's party is
used. If that fails, the function will return 0.
attached to an instance, the instance of the currently attached player is
used (if it is a character, party, or guild mode). If it is not owned by anyone, no
player needs to be attached. If that fails, the function will return 0.

---------------------------------------

Expand All @@ -8187,17 +8198,19 @@ used. If that fails, the function will return 0.
Warps all players in the instance <instance id> to <map name> at given
coordinates. If no ID is specified, the instance the script is attached to
is used. If the script is not attached to an instance, the instance of the
currently attached player's party is used. If that fails, the script will
come to a halt.
currently attached player is used (if it is a character, party, or guild
mode). If it is not owned by anyone, no player needs to be attached. If that
fails, the script will come to a halt.

---------------------------------------

*instance_announce <instance id>,"<text>",<flag>{,<fontColor>{,<fontType>{,<fontSize>{,<fontAlign>{,<fontY>}}}}};

Broadcasts a message to all players in the instance <instance id> currently
residing on an instance map. If -1 is specified for <instance id>, the instance
residing on an instance map. If 0 is specified for <instance id>, the instance
the script is attached to is used. If the script is not attached to an instance,
the instance of the currently attached player's party is used.
the instance of the currently attached player is used (if it is a character,
party, or guild mode). If it is not owned by anyone, no player needs to be attached.

For details on the other parameters, see 'announce'.

Expand Down Expand Up @@ -8225,6 +8238,28 @@ if (instance_check_party(getcharid(1),2,2,149)) {

---------------------------------------

*instance_check_guild(<guild id>{,<amount>{,<min>{,<max>}}})

This function checks if a guild meets certain requirements, returning 1 if all
conditions are met and 0 otherwise. It will only check online characters.

amount - number of online guild members (default is 1).
min - minimum level of all characters in the guild (default is 1).
max - maximum level of all characters in the guild (default is max level in conf).

Example:

if (instance_check_guild(getcharid(2),2,2,149)) {
mes "Your guild meets the Memorial Dungeon requirements.",
mes "All online members are between levels 1-150 and at least two are online.";
close;
} else {
mes "Sorry, your guild does not meet requirements.";
close;
}

---------------------------------------

=========================
|8.- Quest Log commands.|
=========================
Expand Down
2 changes: 1 addition & 1 deletion npc/instances/EndlessTower.txt
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ e_tower,81,105,0 script Tower Protection Stone 406,{
}

L_Enter:
switch(instance_enter("Endless Tower")) {
switch(instance_enter()) {
case 3:
mes "An unknown error has occurred.";
close;
Expand Down
2 changes: 1 addition & 1 deletion npc/instances/NydhoggsNest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ nyd_dun02,100,201,3 script Yggdrasil Gatekeeper 111,8,8,{
close;

L_Enter:
switch(instance_enter("Nidhoggur's Nest")) {
switch(instance_enter()) {
case 3:
mes "[Yggdrasil Gatekeeper]";
mes "An unknown error has occurred.";
Expand Down
2 changes: 1 addition & 1 deletion npc/instances/OrcsMemory.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ gef_fild10,242,202,0 script Dimensional Gorge Piece 406,{
mes "In order to generate a dungeon you must be the Party Leader and have at least 2 members in the party.";
close;
L_Enter:
switch(instance_enter("Orc's Memory")) {
switch(instance_enter()) {
case 3:
mes "An unknown error has occurred.";
close;
Expand Down
2 changes: 1 addition & 1 deletion npc/instances/SealedShrine.txt
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ monk_test,306,151,3 script Grave of Baphomet#edq 111,{
//set .@ins_bapho_check2,checkquest(3045,PLAYTIME);

if (.@ins_bapho_check == -1) {
switch(instance_enter("Sealed Catacomb")) {
switch(instance_enter()) {
case 3:
case 2:
mes "It's cold to the touch. It doesn't respond.";
Expand Down
2 changes: 1 addition & 1 deletion npc/re/instances/BakonawaLake.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ ma_scene01,174,179,4 script Taho 541,{
mes "Now I'm weaving, so you can go down when I'm done.";
close;
case 2:
switch(instance_enter(.@md_name$)) {
switch(instance_enter()) {
case 3:
mes "[Taho]";
mes "An unknown error occurred.";
Expand Down
2 changes: 1 addition & 1 deletion npc/re/instances/BangungotHospital.txt
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ L_Enter:
cutin "",255;
end;
case 2:
switch(instance_enter(.@md_name$)) {
switch(instance_enter()) {
case 3:
mes "[Nurse Maenne]";
mes "A critical situation has happened.";
Expand Down
2 changes: 1 addition & 1 deletion npc/re/instances/BuwayaCave.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ OnTouch:
}
switch(select("Enter.:Turn back.")) {
case 1:
switch(instance_enter("Buwaya Cave")) {
switch(instance_enter()) {
case 3:
mes "[Guard]";
mes "Oh, now is not a good time.";
Expand Down
2 changes: 1 addition & 1 deletion npc/re/instances/EclageInterior.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ ecl_hub01,130,15,0 script It is closed shut. 844,{
mes "It is pretty difficult to guide an outsider like you.";
close;
}
switch (instance_enter(.@md_name$)) {
switch (instance_enter()) {
case 3:
mes "An unknown error has occurred.";
close;
Expand Down
2 changes: 1 addition & 1 deletion npc/re/instances/HazyForest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ bif_fild01,161,355,0 script Log Tunnel 844,{
next;
if(select("Enter the tunnel.:Give up.") == 2)
close;
switch(instance_enter("Mistwood Maze")) {
switch(instance_enter()) {
case 3:
mes "[Laphine Soldier]";
mes "Something doesn't feel right. Looks like something dangerous is going on, so you'd better turn back today.";
Expand Down
2 changes: 1 addition & 1 deletion npc/re/instances/MalangdoCulvert.txt
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ mal_in01,160,34,4 script Missing, the Cleaner 545,{
}
end;
L_Enter:
switch(instance_enter("Culvert")) {
switch(instance_enter()) {
case 3:
mes "An unknown error has occurred.";
close;
Expand Down
2 changes: 1 addition & 1 deletion npc/re/instances/OctopusCave.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ mal_dun01,153,237,5 script Weird Entrance 844,{
switch(select("Go in.:Stop.")) {
case 1:
if (countitem(6442)) {
switch(instance_enter("Octopus Cave")) {
switch(instance_enter()) {
case 3:
mes "[Starfish]";
mes "Ah, now is not the time...";
Expand Down
2 changes: 1 addition & 1 deletion npc/re/instances/OldGlastHeim.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ glast_01,204,273,6 script Hugin#ghinstance 755,{
mes "The time gap was created. When you're ready, talk to me again.";
close;
case 2:
switch(instance_enter(.@md_name$)) {
switch(instance_enter()) {
case 3:
mes "An unknown error has occurred.";
close;
Expand Down
2 changes: 1 addition & 1 deletion npc/re/instances/WolfchevLaboratory.txt
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ lhz_dun04,147,279,0 script Laboratory Entrance#memo CLEAR_NPC,{
mes "You have stopped entering to Wolfchev's laboratory.";
close;
}
if (instance_enter("Wolfchev's Laboratory") != 0) { // probably missing failure cases
if (instance_enter() != 0) { // probably missing failure cases
mes "^FF0000Warning^000000";
mes ""+ strcharinfo(0) +". . .";
mes "^FF0000Unregistered personnel^000000";
Expand Down
1 change: 1 addition & 0 deletions src/common/mmo.h
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,7 @@ struct guild {
struct guild_expulsion expulsion[MAX_GUILDEXPULSION];
struct guild_skill skill[MAX_GUILDSKILL];
struct Channel *channel;
unsigned short instance_id;

/* Used by char-server to save events for guilds */
unsigned short save_flag;
Expand Down
Loading

5 comments on commit 32c829d

@Keysito
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aleos89 this is the instance don't attach any charid right?

@Atemo
Copy link
Contributor

@Atemo Atemo commented on 32c829d May 25, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please read the header :
* New modes include: No player attached, single player, and guild.
:D

@cydh
Copy link
Contributor

@cydh cydh commented on 32c829d May 26, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, now....
entering instance must be in same NPC where the instance created. /hmm
how if the NPC is reloaded?

and then next, we need adjust party to make it not broken if the leader is leaving (official behavior), so even party member are scammed by party leader, they still can continue the instance. xD

@secretdataz
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cydh that only applies to IM_NONE mode tho. please correct me if i'm wrong.

@M4karov
Copy link

@M4karov M4karov commented on 32c829d Jun 2, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//English
Hello guys! Testing instantiates Old Glast Heim , I realized that to undo the group the map-server closes alone, someone is going through it ?
Img: http://prntscr.com/bbb3lr

//Português
Olá pessoal! Testando a instancia Old Glast Heim, percebi que ao desfazer o grupo o map-server fecha sozinho, alguém está passando por isso?
Img: http://prntscr.com/bbb3lr

Please sign in to comment.