Explorar el Código

Instance System Rewrite!
- Removed a bunch of script commands and replaced others
- Rewrote the way instances are created
- Added Instance Database files
- Fixed and rewrote instances scripts (Euphy)
- Added reloading to instancedb
- Instances are now persistent through @reloadscript
- Special thanks to Auriga (emulator) for the base of their system
- Special thanks to Euphy for doing major testing and script rewrites for this
- Special thanks to Lemongrass and Lighta for some help along the way

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17386 54d463be-8e91-2dee-dedb-b68131a5f0ec

akinari1087 hace 12 años
padre
commit
cd95d1cada

+ 4 - 1
conf/msg_conf/map_msg.conf

@@ -501,6 +501,10 @@
 //----------------------
 510: You have %d new emails (%d unread)
 
+// Instancing
+515: Your instance has been reloaded.
+516: Instance database has been reloaded.
+
 // Bot detect messages (currently unused)
 535: Possible use of BOT (99%% of chance) or modified client by '%s' (account: %d, char_id: %d). This player ask your name when you are hidden.
 536: Character '%s' (account: %d) is trying to use a bot (it tries to detect a fake player).
@@ -928,7 +932,6 @@
 1096: PartyLock |
 1097: GuildLock |
 1098: Loadevent |
-1099: Src4instance |
 1100: Chmautojoin |
 1101: nousecart |
 1102: noitemconsumption |

+ 9 - 0
db/pre-re/instance_db.txt

@@ -0,0 +1,9 @@
+// Instance Database
+//
+// Structure of Database:
+// ID,Name,LimitTime,EnterMap,EnterX,EnterY,Map1,Map2,Map3,Map4,Map5,Map6,Map7,Map8
+//
+0,Endless Tower,14400,1@tower,50,355,1@tower,2@tower,3@tower,4@tower,5@tower,6@tower
+1,Sealed Catacomb,7200,1@cata,100,224,1@cata,2@cata
+2,Orc's Memory,3600,1@orcs,179,15,1@orcs,2@orcs
+3,Nidhoggur's Nest,14400,1@nyd,32,36,1@nyd,2@nyd

+ 17 - 0
db/re/instance_db.txt

@@ -0,0 +1,17 @@
+// Instance Database
+//
+// Structure of Database:
+// ID,Name,LimitTime,EnterMap,EnterX,EnterY,Map1,Map2,Map3,Map4,Map5,Map6,Map7,Map8
+//
+0,Endless Tower,14400,1@tower,50,355,1@tower,2@tower,3@tower,4@tower,5@tower,6@tower
+1,Sealed Catacomb,7200,1@cata,100,224,1@cata,2@cata
+2,Orc's Memory,3600,1@orcs,179,15,1@orcs,2@orcs
+3,Nidhoggur's Nest,14400,1@nyd,32,36,1@nyd,2@nyd
+4,Mistwood Maze,7200,1@mist,89,29,1@mist
+5,Culvert,3600,1@pump,63,98,1@pump,2@pump
+6,Octopus Cave,3600,1@cash,199,99,1@cash
+7,Bangungot Hospital 2F,3600,1@ma_h,40,157,1@ma_h
+8,Buwaya Cave,3600,1@ma_c,31,56,1@ma_c
+9,Bakonawa Lake,7200,1@ma_b,77,52,1@ma_b
+//10,Wolfchev's Laboratory,14400,1@lhz,45,148,1@lhz
+//11,Old Glast Heim,3600,1@gl_k,150,20,1@gl_k,2@gl_k

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1145 - 3808
npc/instances/EndlessTower.txt


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 224 - 329
npc/instances/NydhoggsNest.txt


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 215 - 489
npc/instances/OrcsMemory.txt


+ 365 - 578
npc/instances/SealedShrine.txt

@@ -3,7 +3,7 @@
 //===== By: ================================================== 
 //= L0ne_W0lf
 //===== Current Version: ===================================== 
-//= 2.2
+//= 2.3
 //===== Compatible With: ===================================== 
 //= rAthena SVN
 //===== Description: ========================================= 
@@ -21,11 +21,12 @@
 //=     Removed checking quest 3045, unofficial check.
 //= 1.7 Fixed a checkquest condition never setting quest. [L0ne_W0lf]
 //= 1.8 Added 'instance_check_party' command to the script for proper checking if
-//=		the invoking party meets the requirements to join the Memorial Dungeon.
+//=     the invoking party meets the requirements to join the Memorial Dungeon.
 //= 1.9 Fixed broken else/if chaining. [Joseph]
 //= 2.0 Some optimization. [Euphy]
 //= 2.1 Fixed quest being removed before the 12 hours cool down. [Joseph]
 //= 2.2 Removed extra setquest (quest id:3040).	[Joseph]
+//= 2.3 Instance system rewrite. [Euphy]
 //============================================================ 
 
 // Sealed Catacomb Entrance
@@ -94,7 +95,7 @@ monk_test,309,146,3	script	Friar Patrick#edq	412,{
 		}
 		break;
 	case 2:
-		if (BaseLevel > 74) {
+		if (BaseLevel >= 75) {
 
 			set .@party_id,getcharid(1);
 
@@ -107,72 +108,15 @@ monk_test,309,146,3	script	Friar Patrick#edq	412,{
 			// Two hour play limit
 			//set .@ins_bapho_check2,checkquest(3045,PLAYTIME);
 
-			if(!instance_check_party(.@party_id,2,75)){
-				mes "I'm sorry but your Party does not meet the requirements to join the Memorial Dungeon.";
-				close;
-			}
-
 			if (.@ins_bapho_check == -1) {
-				if (getpartyleader(.@party_id,2) == getcharid(0)) {
-					set .@instance, instance_create("Sealed Catacombs", .@party_id);
-					if (.@instance < 0) {
-						mes "[Friar Patrick]";
-						mes "Party name is "+getpartyname(.@party_id)+"...";
-						mes "Name of the leader is "+.@partymembername$[0]+"...";
+				if (getpartyleader(.@party_id,2) == getcharid(0) && instance_check_party(.@party_id,2,75)) {
+					mes "[Friar Patrick]";
+					mes "Party name is "+getpartyname(.@party_id)+"...";
+					mes "Name of the leader is "+strcharinfo(0)+"...";
+					if (instance_create("Sealed Catacomb") < 0) {
 						mes "Umm... But it seems that there is a problem here... I'll check quickly. Please wait.";
 					}
 					else {
-
-						for( set .@i, 1; .@i <= 2; set .@i, .@i + 1 ) {
-							if( instance_attachmap("" + .@i + "@cata", .@instance) == "" )
-								break;
-						}
-						if( .@i < 2 ) {
-							instance_destroy(.@instance);
-							close;
-						}
-
-						instance_attach(.@instance);
-						instance_set_timeout 7200,300,.@instance;
-						instance_init(.@instance);
-
-						// First Floor
-						disablenpc instance_npcname("Ancient Hero's Soul#1F", instance_id());
-						disablenpc instance_npcname("ins_bapho_to_2f", instance_id());
-
-						for( set .@i, 1; .@i < 13; set .@i, .@i + 1 ) {
-							disablenpc instance_npcname("Gravestone#1F_"+.@i+"T", instance_id());
-							disablenpc instance_npcname("Gravestone#1F_"+.@i+"F", instance_id());
-						}
-						for( set .@i, 1; .@i <= 12; set .@i, .@i + 1 ) {
-							disablenpc instance_npcname("Bobbing Torch#"+.@i, instance_id());
-						}
-
-						// Second Floor
-						disablenpc instance_npcname("ins_baphomet_1f_timer", instance_id());
-						disablenpc instance_npcname("ins_2f_enter_broad", instance_id());
-						disablenpc instance_npcname("Magical Seal#0", instance_id());
-						disablenpc instance_npcname("Magical Seal#2", instance_id());
-						disablenpc instance_npcname("Magical Seal#4", instance_id());
-						disablenpc instance_npcname("Magical Seal#8", instance_id());
-						disablenpc instance_npcname("Magical Seal#10", instance_id());
-						disablenpc instance_npcname("Ancient Hero's Soul#2F", instance_id());
-						disablenpc instance_npcname("control_baphomet", instance_id());
-						disablenpc instance_npcname("ins_2f_hero_broad2", instance_id());
-						disablenpc instance_npcname("2f_callmon_pattern_c", instance_id());
-						disablenpc instance_npcname("2f_callmon_pattern", instance_id());
-						disablenpc instance_npcname("ins_2f_hero_pattern_c", instance_id());
-						disablenpc instance_npcname("ins_2f_hero_pattern", instance_id());
-
-						// Pick proper grave
-						donpcevent instance_npcname("ins_baphomet_lotto", instance_id())+"::OnEnable";
-
-						// Spawn monsters.
-						donpcevent instance_npcname("ins_1f_spawn_mobs", instance_id())+"::OnEnable";
-
-						mes "[Friar Patrick]";
-						mes "Party name is "+getpartyname(.@party_id)+"...";
-						mes "Name of the leader is "+.@partymembername$[0]+"...";
 						mes "Okay... I'll adjust the shrine's seal so that you and your group can enter.";
 						next;
 						mes "[Friar Patrick]";
@@ -210,10 +154,9 @@ monk_test,309,146,3	script	Friar Patrick#edq	412,{
 				mes "[Friar Patrick]";
 				mes "Haaaaaaap... Hocus Pocus Wingardium Abracadabra!!!!!";
 				next;
-				if (checkquest(3040)>=0) erasequest 3040;
+				erasequest 3040;
 				if (checkquest(3041)>=0) erasequest 3041;
 				if (checkquest(3045)>=0) erasequest 3045;
-				set party_instance_id4,0;
 				mes "[Friar Patrick]";
 				mes "Huu... It's over. Now that I've released Baphomet's Curse, you can enter again.";
 			}
@@ -262,57 +205,50 @@ monk_test,306,151,3	script	Grave of Baphomet#edq	111,{
 	if (countitem(6002)) delitem 6002,countitem(6002); //Token_Of_Apostle
 	mes "This gravestone has a carving of a wicked devil with large horns. It arouses an ominous feeling.";
 	next;
-	switch(select("Touch the stone.:Step back.")) {
-	case 1:
-		set .@party_id,getcharid(1);
-		set .@instance, instance_id(1);
-		instance_attach(.@instance);
-		
-		// 12 hour cooldown
-		set .@ins_bapho_check,checkquest(3040,PLAYTIME);
-		// Two hour play limit
-		//set .@ins_bapho_check2,checkquest(3045,PLAYTIME);
-		
-		if(!instance_check_party(.@party_id,2,75)){
-			mes "I'm sorry but your Party does not meet the requirements to join the Memorial Dungeon.";
+	if(select("Touch the stone.:Step back.") == 2)
+		close;
+
+	// 12 hour cooldown
+	set .@ins_bapho_check,checkquest(3040,PLAYTIME);
+	// Two hour play limit
+	//set .@ins_bapho_check2,checkquest(3045,PLAYTIME);
+
+	if (.@ins_bapho_check == -1) {
+		switch(instance_enter("Sealed Catacomb")) {
+		case 3:
+		case 2:
+			mes "It's cold to the touch. It doesn't respond.";
 			close;
-		}
-		if (.@ins_bapho_check == -1) {
-			if (has_instance("1@cata") == "") {
-				mes "It's cold to the touch. It doesn't respond.";
-			} else if((party_instance_id4 != 0) && (party_instance_id4 != getcharid(1))) {
-				mes "It seems you have entered this shrine recently... You cannot reenter because Baphomet's Curse still remains. Baphomet's Curse disappears only after a certain amount of time has passed.";
-			} else {
-				mapannounce "monk_test","[" + strcharinfo(0) + "] member of the [" + getpartyname(.@party_id) + "] party has entered the Sealed Shrine.",bc_map,"0x00ff99";
-				if (checkquest(3040) == -1) setquest 3040;
-				set party_instance_id4,getcharid(1);
-				warp "1@cata",100,224;
-				end;
-			}
-		} else if (.@ins_bapho_check == 0 || .@ins_bapho_check == 1) {
-			mes "[Friar Patrick]";
-			mes "It seems you have entered this shrine recently... You cannot reenter because the curse of Baphomet still remains.";
-			mes "The curse of Baphomet disappears after a certain amount of time after you entered.";
-		} else if (.@ins_bapho_check == 2) {
-			mes "[Friar Patrick]";
-			mes "Umm... It seems the curse of Baphomet weakened. I'll clear the bad curse.";
-			next;
-			mes "[Friar Patrick]";
-			mes "Haaaaaaap... Wingardium Leviosa Expecto Patronum !!!!!";
-			specialeffect2 EF_HOLYHIT;
-			if (checkquest(3040)>=0) erasequest 3040;
-			if (checkquest(3041)>=0) erasequest 3041;
-			if (checkquest(3045)>=0) erasequest 3045;
-			set party_instance_id4,0;
-			next;
+		case 1:
 			mes "[Friar Patrick]";
-			mes "Huu... It's over. Now I released all of the curses on you. You can enter again.";
+			mes "To enter this dangerous place, you can't go alone. Come again after you join a party.";
+			close;
+		case 0:
+			mapannounce "monk_test","[" + strcharinfo(0) + "] member of the [" + getpartyname(.@party_id) + "] party has entered the Sealed Shrine.",bc_map,"0x00ff99";
+			setquest 3040;
+			//warp "1@cata",100,224;
+			close;
 		}
-		break;
-	case 2:
-		break;
+	} else if (.@ins_bapho_check == 0 || .@ins_bapho_check == 1) {
+		mes "[Friar Patrick]";
+		mes "It seems you have entered this shrine recently... You cannot reenter because the curse of Baphomet still remains.";
+		mes "The curse of Baphomet disappears after a certain amount of time after you entered.";
+		close;
+	} else if (.@ins_bapho_check == 2) {
+		mes "[Friar Patrick]";
+		mes "Umm... It seems the curse of Baphomet weakened. I'll clear the bad curse.";
+		next;
+		mes "[Friar Patrick]";
+		mes "Haaaaaaap... Wingardium Leviosa Expecto Patronum !!!!!";
+		specialeffect2 EF_HOLYHIT;
+		erasequest 3040;
+		if (checkquest(3041)>=0) erasequest 3041;
+		if (checkquest(3045)>=0) erasequest 3045;
+		next;
+		mes "[Friar Patrick]";
+		mes "Huu... It's over. Now I released all of the curses on you. You can enter again.";
+		close;
 	}
-	close;
 }
 
 prt_monk,261,91,3	script	Rust Blackhand#edq	826,{
@@ -485,250 +421,52 @@ prt_monk,261,91,3	script	Rust Blackhand#edq	826,{
 // Sealed Shrine Interior
 //============================================================
 1@cata,1,2,0	script	ins_baphomet_lotto	-1,{
-OnEnable:
-	switch(rand(1,13)) {
-	case 1:
-		enablenpc instance_npcname("Gravestone#1F_1T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 2:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 3:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 4:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 5:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 6:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 7:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 8:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 9:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 10:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 11:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 12:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12T", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13F", instance_id());
-		end;
-	case 13:
-		enablenpc instance_npcname("Gravestone#1F_1F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_2F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_3F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_4F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_5F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_6F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_7F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_8F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_9F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_10F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_11F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_12F", instance_id());
-		enablenpc instance_npcname("Gravestone#1F_13T", instance_id());
-		end;
+OnInstanceInit:
+	// Pick one "true" Gravestone and 12 "false" Gravestones.
+	set .@true, rand(1,13);
+	for(set .@i,1; .@i<13; set .@i,.@i+1) {
+		disablenpc instance_npcname("Gravestone#1F_1"+((.@i == .@true)?"F":"T"));
 	}
+	disablenpc instance_npcname("ins_baphomet_lotto");
 	end;
 }
 
 1@cata,3,2,0	script	ins_baphomet_lotto2	-1,{
 OnEnable:
-	enablenpc instance_npcname("Bobbing Torch#1", instance_id());
-	enablenpc instance_npcname("Bobbing Torch#2", instance_id());
-	enablenpc instance_npcname("Bobbing Torch#3", instance_id());
-	enablenpc instance_npcname("Bobbing Torch#4", instance_id());
-	enablenpc instance_npcname("Bobbing Torch#5", instance_id());
-	enablenpc instance_npcname("Bobbing Torch#6", instance_id());
-	enablenpc instance_npcname("Bobbing Torch#7", instance_id());
-	enablenpc instance_npcname("Bobbing Torch#8", instance_id());
-	enablenpc instance_npcname("Bobbing Torch#9", instance_id());
-	enablenpc instance_npcname("Bobbing Torch#10", instance_id());
-	enablenpc instance_npcname("Bobbing Torch#11", instance_id());
-	enablenpc instance_npcname("Bobbing Torch#12", instance_id());
+	for(set .@i,1; .@i<12; set .@i,.@i+1)
+		enablenpc instance_npcname("Bobbing Torch#"+.@i);
 	end;
 }
 
 1@cata,4,2,0	script	ins_baphomet_lotto3	-1,{
 OnEnable:
-	monster "1@cata",0,0,"Apostle of Baphomet",1869,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1291,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1869,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1291,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1869,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1291,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1869,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1132,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1117,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1132,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1117,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1132,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1291,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1117,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
-	monster "1@cata",0,0,"Apostle of Baphomet",1869,1,instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
+	set .@label$, instance_npcname("ins_baphomet_lotto3")+"::OnMyMobDead";
+	set .@map$, instance_mapname("1@cata");
+	monster .@map$,0,0,"Apostle of Baphomet",1869,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1291,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1869,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1291,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1869,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1291,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1869,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1132,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1117,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1132,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1117,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1132,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1291,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1117,1,.@label$;
+	monster .@map$,0,0,"Apostle of Baphomet",1869,1,.@label$;
 	end;
 
 OnDisable:
-	killmonster "1@cata",instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead";
+	killmonster instance_mapname("1@cata"),instance_npcname("ins_baphomet_lotto3")+"::OnMyMobDead";
 	end;
 
 OnMyMobDead:
-	if (mobcount("1@cata",instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnMyMobDead") < 1) {
-		instance_announce 0, "All apostles of Baphomet are dead!",bc_map,"0x00ff99";
+	set .@map$, instance_mapname("1@cata");
+	if (mobcount(.@map$,instance_npcname("ins_baphomet_lotto3")+"::OnMyMobDead") < 1) {
+		mapannounce .@map$, "All apostles of Baphomet are dead!",bc_map,"0x00ff99";
 	}
 	getitem 6002,1; //Token_Of_Apostle
 	end;
@@ -804,12 +542,12 @@ OnMyMobDead:
 			mes "Yes... This is... My pendant...";
 			next;
 			delitem 6003,1; //Soul_Pendant
-			enablenpc instance_npcname("Ancient Hero's Soul#1F", instance_id());
-			disablenpc instance_npcname("Gravestone#", instance_id());
+			enablenpc instance_npcname("Ancient Hero's Soul#1F");
+			disablenpc instance_npcname("Gravestone#");
 			mes "[Voice of the Gravestone]";
 			mes "Now I can substantialize my soul. I'll wait for you in front of the altar of fire located at the center of this grave. Let's meet there.";
 			next;
-			instance_announce 0, "Ancient Hero's Soul : I'll wait for you in front of the altar of fire located at the center",bc_map,"0xFFFF00";
+			mapannounce instance_mapname("1@cata"), "Ancient Hero's Soul : I'll wait for you in front of the altar of fire located at the center",bc_map,"0xFFFF00";
 			mes "I can feel the voice becoming faint.";
 			close;
 		}
@@ -958,9 +696,9 @@ OnTouch:
 			mes "[Ancient Hero's Soul]";
 			mes "To remind you again, I must be substantialized within the next hour. So everyone, finish your work within that time!";
 			set 'ins_baphomet,3;
-			donpcevent instance_npcname("ins_baphomet_1f_timer", instance_id())+"::OnEnable";
-			donpcevent instance_npcname("ins_baphomet_lotto2", instance_id())+"::OnEnable";
-			donpcevent instance_npcname("ins_baphomet_lotto3", instance_id())+"::OnEnable";
+			donpcevent instance_npcname("ins_baphomet_1f_timer")+"::OnEnable";
+			donpcevent instance_npcname("ins_baphomet_lotto2")+"::OnEnable";
+			donpcevent instance_npcname("ins_baphomet_lotto3")+"::OnEnable";
 		}
 		else {
 			mes "[Ancient Hero's Soul]";
@@ -1015,7 +753,7 @@ OnTouch:
 		next;
 		set 'ins_baphomet,5;
 		specialeffect EF_TELEPORTATION;
-		enablenpc instance_npcname("ins_bapho_to_2f", instance_id());
+		enablenpc instance_npcname("ins_bapho_to_2f");
 		mes "[Ancient Hero's Soul]";
 		mes "Now you can go to the main altar. It is located in the bottom right corner of this floor.";
 		next;
@@ -1025,7 +763,7 @@ OnTouch:
 		mes "[Ancient Hero's Soul]";
 		mes "Go ahead, warriors.";
 		cutin "",255;
-		instance_announce 0, "Ancient Hero's Soul : Now you can go to the Main Altar's gate. It is located in the Southeast",bc_map,"0xFFFF00";
+		mapannounce instance_mapname("1@cata"), "Ancient Hero's Soul : Now you can go to the Main Altar's gate. It is located in the Southeast",bc_map,"0xFFFF00";
 		close;
 	}
 	else if ('ins_baphomet == 4) {
@@ -1052,6 +790,10 @@ OnTouch:
 		cutin "",255;
 		close;
 	}
+
+OnInstanceInit:
+	disablenpc instance_npcname("Ancient Hero's Soul#1F");
+	end;
 }
 
 // To 2F Warp
@@ -1061,7 +803,7 @@ OnTouch:
 	if (countitem(6002) > 0) {
 		delitem 6002,countitem(6002); //Token_Of_Apostle
 		set 'ins_baphomet,5;
-		warp "2@cata",80,144;
+		warp instance_mapname("2@cata"),80,144;
 		end;
 	}
 	else {
@@ -1069,6 +811,10 @@ OnTouch:
 		mes "Where is your Token of Apostle? I said you should carry the Token of Apostle to pass this gate.";
 		close;
 	}
+
+OnInstanceInit:
+	disablenpc instance_npcname("ins_bapho_to_2f");
+	end;
 }
 
 // Gravestones
@@ -1133,7 +879,7 @@ OnTouch:
 			specialeffect2 EF_HOLYHIT;
 			getitem 6001,1; //Essence_Of_Fire
 			mes "The symbol of inheritor shines. Then a small crystal falls into my hand from the torch.";
-			disablenpc instance_npcname(strnpcinfo(0), instance_id());
+			disablenpc instance_npcname(strnpcinfo(0));
 			close;
 		}
 		else if (('ins_baphomet == 3) && (countitem(6001) > 10)) {
@@ -1154,6 +900,10 @@ OnTouch:
 		percentheal -50,0;
 		close;
 	}
+
+OnInstanceInit:
+	disablenpc instance_npcname(strnpcinfo(0));
+	end;
 }
 1@cata,267,210,0	duplicate(Bobbing Torch#SS)	Bobbing Torch#1	844
 1@cata,85,182,0	duplicate(Bobbing Torch#SS)	Bobbing Torch#2	844
@@ -1169,34 +919,38 @@ OnTouch:
 1@cata,155,14,0	duplicate(Bobbing Torch#SS)	Bobbing Torch#12	844
 
 1@cata,1,1,0	script	ins_baphomet_1f_timer	-1,{
+OnInstanceInit:
+	disablenpc instance_npcname("ins_baphomet_1f_timer");
+	end;
+
 OnEnable:
-	enablenpc instance_npcname("ins_baphomet_1f_timer", instance_id());
+	enablenpc instance_npcname("ins_baphomet_1f_timer");
 	initnpctimer;
 	end;
 
-OnDisable:;
-	disablenpc instance_npcname("ins_baphomet_1f_timer", instance_id());
+OnDisable:
+	disablenpc instance_npcname("ins_baphomet_1f_timer");
 	stopnpctimer;
 	end;
 
 OnTimer1800000:
-	instance_announce 0, "Ancient Hero's Soul : We don't have enough time! Hurry up!",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("1@cata"), "Ancient Hero's Soul : We don't have enough time! Hurry up!",bc_map,"0xFFFF00";
 	end;
 
 OnTimer2400000:
-	instance_announce 0, "Ancient Hero's Soul : My body is disappearing... Hurry up!",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("1@cata"), "Ancient Hero's Soul : My body is disappearing... Hurry up!",bc_map,"0xFFFF00";
 	end;
 
 OnTimer3000000:
-	instance_announce 0, "Ancient Hero's Soul : Everything is over... There is no other way but to wait for the next chance...",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("1@cata"), "Ancient Hero's Soul : Everything is over... There is no other way but to wait for the next chance...",bc_map,"0xFFFF00";
 	end;
 
 OnTimer3050000:
-	instance_announce 0, "Ancient Hero's Soul : We failed... However... We still have a chance. I hope you will train yourselves until the time comes.",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("1@cata"), "Ancient Hero's Soul : We failed... However... We still have a chance. I hope you will train yourselves until the time comes.",bc_map,"0xFFFF00";
 	end;
 
 OnTimer3100000:
-	instance_announce 0, "You've failed to open the seal of main altar.",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("1@cata"), "You've failed to open the seal of main altar.",bc_map,"0xFFFF00";
 	end;
 
 OnTimer3500000:
@@ -1207,106 +961,110 @@ OnTimer3500000:
 
 2@cata,80,144,0	script	ins_2f_enter	-1,3,3,{
 OnTouch:
-	donpcevent instance_npcname("ins_2f_enter_broad", instance_id())+"::OnEnable";
-	disablenpc instance_npcname("ins_2f_enter", instance_id());
+	donpcevent instance_npcname("ins_2f_enter_broad")+"::OnEnable";
+	disablenpc instance_npcname("ins_2f_enter");
 	end;
 }
 
 2@cata,1,1,0	script	ins_2f_enter_broad	-1,{
-OnEnable:
-	enablenpc instance_npcname("ins_2f_enter_broad", instance_id());
-	initnpctimer;
+OnInstanceInit:
+OnDisable:
+	disablenpc instance_npcname("ins_2f_enter_broad");
 	end;
 
-OnDisable:
-	disablenpc instance_npcname("ins_2f_enter_broad", instance_id());
+OnEnable:
+	enablenpc instance_npcname("ins_2f_enter_broad");
+	initnpctimer;
 	end;
 
 OnTimer10000:
-	instance_announce 0, "Baphomet : Humans... interfering again...",bc_map,"0xdb7093";
+	mapannounce instance_mapname("2@cata"), "Baphomet : Humans... interfering again...",bc_map,"0xdb7093";
 	end;
 
 OnTimer13000:
-	instance_announce 0, "Apostle of Baphomet : Humans! Humans have invaded our sanctum!",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Apostle of Baphomet : Humans! Humans have invaded our sanctum!",bc_map,"0xFFFF00";
 	end;
 
 OnTimer16000:
-	instance_announce 0, "Apostle of Baphomet : Kill the humans! Do not stop the revival of our Master!",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Apostle of Baphomet : Kill the humans! Do not stop the revival of our Master!",bc_map,"0xFFFF00";
 	end;
 
 OnTimer18000:
-	instance_announce 0, "Apostle of Baphomet : Hurry up and release the seals of the altars! Our Master's return is upon us!",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Apostle of Baphomet : Hurry up and release the seals of the altars! Our Master's return is upon us!",bc_map,"0xFFFF00";
 	stopnpctimer;
-	disablenpc instance_npcname("ins_2f_enter_broad", instance_id());
+	disablenpc instance_npcname("ins_2f_enter_broad");
 	end;
 }
 
 2@cata,50,67,0	script	slave_left	-1,5,5,{
 OnTouch:
-	disablenpc instance_npcname("slave_left", instance_id());
-	instance_announce 0, "Apostle of Baphomet : Kill the humans! Don't let them interrupt the revival of our Master!",bc_map,"0xFFFF00";
-	monster "2@cata",55,67,"Apostle of Baphomet",1869,1;
-	monster "2@cata",51,67,"Apostle of Baphomet",1291,1;
-	monster "2@cata",58,67,"Apostle of Baphomet",1292,1;
-	monster "2@cata",53,67,"Apostle of Baphomet",1291,1;
-	monster "2@cata",54,67,"Apostle of Baphomet",1869,1;
-	monster "2@cata",55,67,"Apostle of Baphomet",1291,1;
-	monster "2@cata",56,67,"Apostle of Baphomet",1117,1;
-	monster "2@cata",58,66,"Apostle of Baphomet",1869,1;
-	monster "2@cata",56,66,"Apostle of Baphomet",1117,1;
-	monster "2@cata",60,66,"Apostle of Baphomet",1132,1;
-	monster "2@cata",59,66,"Apostle of Baphomet",1117,1;
-	monster "2@cata",54,66,"Apostle of Baphomet",1132,1;
-	monster "2@cata",55,66,"Apostle of Baphomet",1292,1;
-	monster "2@cata",56,66,"Apostle of Baphomet",1132,1;
-	monster "2@cata",50,65,"Apostle of Baphomet",1867,1;
-	monster "2@cata",61,65,"Apostle of Baphomet",1292,1;
+	set .@map$, instance_mapname("2@cata");
+	mapannounce .@map$, "Apostle of Baphomet : Kill the humans! Don't let them interrupt the revival of our Master!",bc_map,"0xFFFF00";
+	monster .@map$,55,67,"Apostle of Baphomet",1869,1;
+	monster .@map$,51,67,"Apostle of Baphomet",1291,1;
+	monster .@map$,58,67,"Apostle of Baphomet",1292,1;
+	monster .@map$,53,67,"Apostle of Baphomet",1291,1;
+	monster .@map$,54,67,"Apostle of Baphomet",1869,1;
+	monster .@map$,55,67,"Apostle of Baphomet",1291,1;
+	monster .@map$,56,67,"Apostle of Baphomet",1117,1;
+	monster .@map$,58,66,"Apostle of Baphomet",1869,1;
+	monster .@map$,56,66,"Apostle of Baphomet",1117,1;
+	monster .@map$,60,66,"Apostle of Baphomet",1132,1;
+	monster .@map$,59,66,"Apostle of Baphomet",1117,1;
+	monster .@map$,54,66,"Apostle of Baphomet",1132,1;
+	monster .@map$,55,66,"Apostle of Baphomet",1292,1;
+	monster .@map$,56,66,"Apostle of Baphomet",1132,1;
+	monster .@map$,50,65,"Apostle of Baphomet",1867,1;
+	monster .@map$,61,65,"Apostle of Baphomet",1292,1;
+	disablenpc instance_npcname("slave_left");
 	end;
 }
 
 2@cata,109,67,0	script	slave_right	-1,5,5,{
 OnTouch:
-	disablenpc instance_npcname("slave_right", instance_id());
-	instance_announce 0, "Apostle of Baphomet : Kill the humans! Don't let them interrupt the revival of our Master!",bc_map,"0xFFFF00";
-	monster "2@cata",105,67,"Apostle of Baphomet",1869,1;
-	monster "2@cata",104,67,"Apostle of Baphomet",1291,1;
-	monster "2@cata",107,67,"Apostle of Baphomet",1869,1;
-	monster "2@cata",106,67,"Apostle of Baphomet",1291,1;
-	monster "2@cata",102,67,"Apostle of Baphomet",1869,1;
-	monster "2@cata",103,67,"Apostle of Baphomet",1291,1;
-	monster "2@cata",103,67,"Apostle of Baphomet",1117,1;
-	monster "2@cata",109,66,"Apostle of Baphomet",1117,1;
-	monster "2@cata",108,66,"Apostle of Baphomet",1132,1;
-	monster "2@cata",101,66,"Apostle of Baphomet",1117,1;
-	monster "2@cata",106,66,"Apostle of Baphomet",1292,1;
-	monster "2@cata",102,66,"Apostle of Baphomet",1132,1;
-	monster "2@cata",104,66,"Apostle of Baphomet",1292,1;
-	monster "2@cata",103,66,"Apostle of Baphomet",1132,1;
-	monster "2@cata",109,65,"Apostle of Baphomet",1867,1;
-	monster "2@cata",108,65,"Apostle of Baphomet",1292,1;
+	set .@map$, instance_mapname("2@cata");
+	mapannounce .@map$, "Apostle of Baphomet : Kill the humans! Don't let them interrupt the revival of our Master!",bc_map,"0xFFFF00";
+	monster .@map$,105,67,"Apostle of Baphomet",1869,1;
+	monster .@map$,104,67,"Apostle of Baphomet",1291,1;
+	monster .@map$,107,67,"Apostle of Baphomet",1869,1;
+	monster .@map$,106,67,"Apostle of Baphomet",1291,1;
+	monster .@map$,102,67,"Apostle of Baphomet",1869,1;
+	monster .@map$,103,67,"Apostle of Baphomet",1291,1;
+	monster .@map$,103,67,"Apostle of Baphomet",1117,1;
+	monster .@map$,109,66,"Apostle of Baphomet",1117,1;
+	monster .@map$,108,66,"Apostle of Baphomet",1132,1;
+	monster .@map$,101,66,"Apostle of Baphomet",1117,1;
+	monster .@map$,106,66,"Apostle of Baphomet",1292,1;
+	monster .@map$,102,66,"Apostle of Baphomet",1132,1;
+	monster .@map$,104,66,"Apostle of Baphomet",1292,1;
+	monster .@map$,103,66,"Apostle of Baphomet",1132,1;
+	monster .@map$,109,65,"Apostle of Baphomet",1867,1;
+	monster .@map$,108,65,"Apostle of Baphomet",1292,1;
+	disablenpc instance_npcname("slave_right");
 	end;
 }
 
 2@cata,79,39,0	script	slave_down	-1,5,5,{
 OnTouch:
-	disablenpc instance_npcname("slave_down", instance_id());
-	instance_announce 0, "Apostle of Baphomet : Kill the humans! Don't let them interrupt the revival of our Master!",bc_map,"0xFFFF00";
-	monster "2@cata",78,41,"Apostle of Baphomet",1869,1;
-	monster "2@cata",79,42,"Apostle of Baphomet",1291,1;
-	monster "2@cata",78,46,"Apostle of Baphomet",1869,1;
-	monster "2@cata",81,41,"Apostle of Baphomet",1291,1;
-	monster "2@cata",81,42,"Apostle of Baphomet",1869,1;
-	monster "2@cata",79,43,"Apostle of Baphomet",1291,1;
-	monster "2@cata",77,40,"Apostle of Baphomet",1117,1;
-	monster "2@cata",79,41,"Apostle of Baphomet",1132,1;
-	monster "2@cata",79,42,"Apostle of Baphomet",1117,1;
-	monster "2@cata",79,43,"Apostle of Baphomet",1132,1;
-	monster "2@cata",79,48,"Apostle of Baphomet",1117,1;
-	monster "2@cata",78,49,"Apostle of Baphomet",1132,1;
-	monster "2@cata",78,41,"Apostle of Baphomet",1292,1;
-	monster "2@cata",74,42,"Apostle of Baphomet",1292,1;
-	monster "2@cata",72,48,"Apostle of Baphomet",1867,1;
-	monster "2@cata",72,38,"Apostle of Baphomet",1292,1;
+	set .@map$, instance_mapname("2@cata");
+	mapannounce .@map$, "Apostle of Baphomet : Kill the humans! Don't let them interrupt the revival of our Master!",bc_map,"0xFFFF00";
+	monster .@map$,78,41,"Apostle of Baphomet",1869,1;
+	monster .@map$,79,42,"Apostle of Baphomet",1291,1;
+	monster .@map$,78,46,"Apostle of Baphomet",1869,1;
+	monster .@map$,81,41,"Apostle of Baphomet",1291,1;
+	monster .@map$,81,42,"Apostle of Baphomet",1869,1;
+	monster .@map$,79,43,"Apostle of Baphomet",1291,1;
+	monster .@map$,77,40,"Apostle of Baphomet",1117,1;
+	monster .@map$,79,41,"Apostle of Baphomet",1132,1;
+	monster .@map$,79,42,"Apostle of Baphomet",1117,1;
+	monster .@map$,79,43,"Apostle of Baphomet",1132,1;
+	monster .@map$,79,48,"Apostle of Baphomet",1117,1;
+	monster .@map$,78,49,"Apostle of Baphomet",1132,1;
+	monster .@map$,78,41,"Apostle of Baphomet",1292,1;
+	monster .@map$,74,42,"Apostle of Baphomet",1292,1;
+	monster .@map$,72,48,"Apostle of Baphomet",1867,1;
+	monster .@map$,72,38,"Apostle of Baphomet",1292,1;
+	disablenpc instance_npcname("slave_down");
 	end;
 }
 
@@ -1323,20 +1081,25 @@ OnTouch:
 	}
 	if (.@seal_check == 2) erasequest 3041;
 	specialeffect EF_LEXDIVINA;
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
-	if (strnpcinfo(2) == "0") areamobuseskill "2@cata",79,81,10,1929,686,1,0,0,26,0;
-	else if (strnpcinfo(2) == "2") areamobuseskill "2@cata",123,109,10,1929,686,1,0,0,26,0;
-	else if (strnpcinfo(2) == "4") areamobuseskill "2@cata",123,22,10,1929,686,1,0,0,26,0;
-	else if (strnpcinfo(2) == "8") areamobuseskill "2@cata",35,21,10,1929,686,1,0,0,26,0;
-	else if (strnpcinfo(2) == "10") areamobuseskill "2@cata",35,109,10,1929,686,1,0,0,26,0;
+	disablenpc instance_npcname(strnpcinfo(0));
+	set .@map$, instance_mapname("2@cata");
+	if (strnpcinfo(2) == "0") areamobuseskill .@map$,79,81,10,1929,"NPC_INVINCIBLEOFF",1,0,0,e_hlp,0;
+	else if (strnpcinfo(2) == "2") areamobuseskill .@map$,123,109,10,1929,"NPC_INVINCIBLEOFF",1,0,0,e_hlp,0;
+	else if (strnpcinfo(2) == "4") areamobuseskill .@map$,123,22,10,1929,"NPC_INVINCIBLEOFF",1,0,0,e_hlp,0;
+	else if (strnpcinfo(2) == "8") areamobuseskill .@map$,35,21,10,1929,"NPC_INVINCIBLEOFF",1,0,0,e_hlp,0;
+	else if (strnpcinfo(2) == "10") areamobuseskill .@map$,35,109,10,1929,"NPC_INVINCIBLEOFF",1,0,0,e_hlp,0;
 	percentheal -50,0;
 	sc_start Eff_Stone,20000,0;
 	setquest 3041;
-	instance_announce 0, "The seal activated by putting magical power into the altar.",bc_map,"0x87ceeb";
+	mapannounce .@map$, "The seal activated by putting magical power into the altar.",bc_map,"0x87ceeb";
 	mes "I can feel the power of the altar came back by adding magical power.";
 	next;
 	mes "But you can't use your magic for 3 minutes because you used your SP on the altar.";
 	close;
+
+OnInstanceInit:
+	disablenpc instance_npcname(strnpcinfo(0));
+	end;
 }
 2@cata,79,81,0	duplicate(Magical Seal#SS)	Magical Seal#0	844
 2@cata,123,109,0	duplicate(Magical Seal#SS)	Magical Seal#2	844
@@ -1356,10 +1119,10 @@ OnTouch:
 		specialeffect EF_METEORSTORM;
 		specialeffect EF_METEORSTORM;
 		mes "[" + strcharinfo(0) + "]";
-		mes "Watch out! Something... Something is comming.";
+		mes "Watch out! Something... Something is coming.";
 		set 'ins_baphomet,6;
-		donpcevent instance_npcname("ins_2f_hero_broad", instance_id())+"::OnEnable";
-		disablenpc instance_npcname("The Main Altar#ss", instance_id());
+		donpcevent instance_npcname("ins_2f_hero_broad")+"::OnEnable";
+		disablenpc instance_npcname("The Main Altar#ss");
 		close;
 	}
 	else {
@@ -1378,8 +1141,6 @@ OnTouch:
 	mes "Good job, my descendants... You've finished the long-cherished task that me and my bretheren could not complete.";
 	next;
 	mes "[Ancient Hero's Soul]";
-	next;
-	mes "[Ancient Hero's Soul]";
 	mes "I really appreciate your help.";
 	mes "Our souls can finally rest in peace...";
 	next;
@@ -1403,291 +1164,317 @@ OnTouch:
 		cutin "",255;
 		close;
 	}
+
+OnInstanceInit:
+	disablenpc instance_npcname("Ancient Hero's Soul#2F");
+	end;
 }
 
 2@cata,1,2,0	script	ins_2f_hero_broad	-1,{
 OnEnable:
-	enablenpc instance_npcname("ins_2f_hero_broad", instance_id());
+	enablenpc instance_npcname("ins_2f_hero_broad");
 	initnpctimer;
 	end;
 
 OnDisable:
-	disablenpc instance_npcname("ins_2f_hero_broad", instance_id());
+	disablenpc instance_npcname("ins_2f_hero_broad");
 	end;
 
 OnTimer3000:
-	instance_announce 0, "Ancient Hero's Soul : My God! The seal of the Main Altar is weakening!",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : My God! The seal of the Main Altar is weakening!",bc_map,"0xFFFF00";
 	end;
 
 OnTimer6000:
-	instance_announce 0, "Ancient Hero's Soul : My descendants... Listen carefully to what I'm going to say.",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : My descendants... Listen carefully to what I'm going to say.",bc_map,"0xFFFF00";
 	end;
 
 OnTimer9000:
-	instance_announce 0, "Ancient Hero's Soul : The altars that control the Main Altar's power are located in the Northeast, Southeast, Southwest and Northwest corners of this room.",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : The altars that control the Main Altar's power are located in the Northeast, Southeast, Southwest and Northwest corners of this room.",bc_map,"0xFFFF00";
 	end;
 
 OnTimer12000:
-	instance_announce 0, "Ancient Hero's Soul : Find these altars and activate their seals before Baphomet revives.",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : Find these altars and activate their seals before Baphomet revives.",bc_map,"0xFFFF00";
 	end;
 
 OnTimer15000:
-	instance_announce 0, "Baphomet : It's too late, weaklings... Now, you'll feel the despair of death!",bc_map,"0xdb7093";
+	mapannounce instance_mapname("2@cata"), "Baphomet : It's too late, weaklings... Now, you'll feel the despair of death!",bc_map,"0xdb7093";
 	end;
 
 OnTimer17000:
-	instance_announce 0, "Baphomet : No one can harm me here. You will be my first sacrifice.",bc_map,"0xdb7093";
-	donpcevent instance_npcname("control_baphomet", instance_id())+"::OnEnable";
-	donpcevent instance_npcname("ins_2f_hero_broad2", instance_id())+"::OnEnable";
+	mapannounce instance_mapname("2@cata"), "Baphomet : No one can harm me here. You will be my first sacrifice.",bc_map,"0xdb7093";
+	donpcevent instance_npcname("control_baphomet")+"::OnEnable";
+	donpcevent instance_npcname("ins_2f_hero_broad2")+"::OnEnable";
 	stopnpctimer;
-	disablenpc instance_npcname("ins_2f_hero_broad", instance_id());
+	disablenpc instance_npcname("ins_2f_hero_broad");
 	end;
 }
 
 2@cata,3,3,0	script	control_baphomet	-1,{
-OnEnable:
-	enablenpc instance_npcname("control_baphomet", instance_id());
-	donpcevent instance_npcname("2f_callmon_pattern_c", instance_id())+"::OnEnable";
-	monster "2@cata",79,64,"Baphomet#",1929,1,instance_npcname("control_baphomet", instance_id())+"::OnMyMobDead";
+OnInstanceInit:
+OnDisable:
+	disablenpc instance_npcname("control_baphomet");
 	end;
 
-OnDisable:
-	disablenpc "control_baphomet";
+OnEnable:
+	enablenpc instance_npcname("control_baphomet");
+	donpcevent instance_npcname("2f_callmon_pattern_c")+"::OnEnable";
+	monster instance_mapname("2@cata"),79,64,"Baphomet#",1929,1,instance_npcname("control_baphomet")+"::OnMyMobDead";
 	end;
 
 OnMyMobDead:
-	if (mobcount("2@cata",instance_npcname("control_baphomet", instance_id())+"::OnMyMobDead") < 1) {
+	set .@map$, instance_mapname("2@cata");
+	if (mobcount(.@map$,instance_npcname("control_baphomet")+"::OnMyMobDead") < 1) {
 		set 'ins_baphomet,7;
 		erasequest 3041;
-		instance_announce 0, "Baphomet : No! Nonono! How dare these weaklings defeat me!... No!!...",bc_map,"0xdb7093";
-		enablenpc instance_npcname("Ancient Hero's Soul#2F", instance_id());
-		disablenpc instance_npcname("slave_down", instance_id());
-		disablenpc instance_npcname("slave_left", instance_id());
-		disablenpc instance_npcname("slave_right", instance_id());
-		donpcevent instance_npcname("ins_2f_hero_broad", instance_id())+"::OnDisable";
-		donpcevent instance_npcname("ins_2f_hero_broad2", instance_id())+"::OnDisable";
-		donpcevent instance_npcname("ins_2f_hero_pattern_c", instance_id())+"::OnDisable";
-		donpcevent instance_npcname("2f_callmon_pattern_c", instance_id())+"::OnDisable";
-		donpcevent instance_npcname("2f_callmon_pattern", instance_id())+"::OnDisable";
-		donpcevent instance_npcname("ins_2f_hero_pattern", instance_id())+"::OnDisable";
-		donpcevent instance_npcname("ins_2f_enter_broad", instance_id())+"::OnDisable";
-		donpcevent instance_npcname("control_baphomet", instance_id())+"::OnDisable";
-		disablenpc instance_npcname("control_baphomet", instance_id());
+		mapannounce .@map$, "Baphomet : No! Nonono! How dare these weaklings defeat me!... No!!...",bc_map,"0xdb7093";
+		enablenpc instance_npcname("Ancient Hero's Soul#2F");
+		disablenpc instance_npcname("slave_down");
+		disablenpc instance_npcname("slave_left");
+		disablenpc instance_npcname("slave_right");
+		donpcevent instance_npcname("ins_2f_hero_broad")+"::OnDisable";
+		donpcevent instance_npcname("ins_2f_hero_broad2")+"::OnDisable";
+		donpcevent instance_npcname("ins_2f_hero_pattern_c")+"::OnDisable";
+		donpcevent instance_npcname("2f_callmon_pattern_c")+"::OnDisable";
+		donpcevent instance_npcname("2f_callmon_pattern")+"::OnDisable";
+		donpcevent instance_npcname("ins_2f_hero_pattern")+"::OnDisable";
+		donpcevent instance_npcname("ins_2f_enter_broad")+"::OnDisable";
+		donpcevent instance_npcname("control_baphomet")+"::OnDisable";
+		disablenpc instance_npcname("control_baphomet");
 	}
 	end;
 }
 
 2@cata,2,2,0	script	ins_2f_hero_broad2	-1,{
-OnEnable:
-	enablenpc instance_npcname("ins_2f_hero_broad2", instance_id());
-	initnpctimer;
+OnInstanceInit:
+OnDisable:
+	disablenpc instance_npcname("ins_2f_hero_broad2");
 	end;
 
-OnDisable:
-	disablenpc instance_npcname("ins_2f_hero_broad2", instance_id());
+OnEnable:
+	enablenpc instance_npcname("ins_2f_hero_broad2");
+	initnpctimer;
 	end;
 
 OnTimer8000:
-	instance_announce 0, "Ancient Hero's Soul : Don't be discouraged, Baphomet can still be defeated!",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : Don't be discouraged, Baphomet can still be defeated!",bc_map,"0xFFFF00";
 	end;
 
 OnTimer11000:
-	instance_announce 0, "Ancient Hero's Soul : Go to the altars and activate their seals.",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : Go to the altars and activate their seals.",bc_map,"0xFFFF00";
 	end;
 
 OnTimer13000:
-	instance_announce 0, "Ancient Hero's Soul : Once the seals recover their power, Baphomet will be vulnerable.",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : Once the seals recover their power, Baphomet will be vulnerable.",bc_map,"0xFFFF00";
 	end;
 
 OnTimer16000:
-	instance_announce 0, "Ancient Hero's Soul : You should lure Baphomet to the unsealed Altars. Otherwise, your efforts will be futile.",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : You should lure Baphomet to the unsealed Altars. Otherwise, your efforts will be futile.",bc_map,"0xFFFF00";
 	end;
 
 OnTimer19000:
-	instance_announce 0, "Ancient Hero's Soul : We have only 1 hour to stop Baphomet. If time runs out, the power of the seals will be useless.",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : We have only 1 hour to stop Baphomet. If time runs out, the power of the seals will be useless.",bc_map,"0xFFFF00";
 	end;
 
 OnTimer22000:
-	instance_announce 0, "Baphomet : It's useless. Make more seals. I'll crush them all. None of you will survive!",bc_map,"0xdb7093";
+	mapannounce instance_mapname("2@cata"), "Baphomet : It's useless. Make more seals. I'll crush them all. None of you will survive!",bc_map,"0xdb7093";
 	end;
 
 OnTimer26000:
-	instance_announce 0, "Ancient Hero's Soul : The magical power of the central seal is running out. Go to the central seal and put the magical power.",bc_map,"0xFFFF00";
-	enablenpc instance_npcname("Magical Seal#0", instance_id());
-	disablenpc instance_npcname("Magical Seal#2", instance_id());
-	disablenpc instance_npcname("Magical Seal#4", instance_id());
-	disablenpc instance_npcname("Magical Seal#8", instance_id());
-	disablenpc instance_npcname("Magical Seal#10", instance_id());
-	donpcevent instance_npcname("ins_2f_hero_pattern_c", instance_id())+"::OnEnable";
+	mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : The magical power of the central seal is running out. Go to the central seal and put the magical power.",bc_map,"0xFFFF00";
+	enablenpc instance_npcname("Magical Seal#0");
+	disablenpc instance_npcname("Magical Seal#2");
+	disablenpc instance_npcname("Magical Seal#4");
+	disablenpc instance_npcname("Magical Seal#8");
+	disablenpc instance_npcname("Magical Seal#10");
+	donpcevent instance_npcname("ins_2f_hero_pattern_c")+"::OnEnable";
 	stopnpctimer;
-	disablenpc instance_npcname("ins_2f_hero_broad2", instance_id());
+	disablenpc instance_npcname("ins_2f_hero_broad2");
 	end;
 }
 
 2@cata,4,1,0	script	2f_callmon_pattern_c	-1,{
+OnInstanceInit:
+	disablenpc instance_npcname("2f_callmon_pattern_c");
+	end;
+
 OnEnable:
-	enablenpc instance_npcname("2f_callmon_pattern_c", instance_id());
+	enablenpc instance_npcname("2f_callmon_pattern_c");
 	initnpctimer;
-	donpcevent instance_npcname("2f_callmon_pattern_c", instance_id())+"::Ongo";
+	donpcevent instance_npcname("2f_callmon_pattern_c")+"::Ongo";
 	end;
 
 OnDisable:
 	stopnpctimer;
-	disablenpc instance_npcname("2f_callmon_pattern_c", instance_id());
+	disablenpc instance_npcname("2f_callmon_pattern_c");
 	end;
 
 Ongo:
-	donpcevent instance_npcname("2f_callmon_pattern", instance_id())+"::OnEnable";
+	donpcevent instance_npcname("2f_callmon_pattern")+"::OnEnable";
 	end;
 
 OnTimer3600000:
-	donpcevent instance_npcname("2f_callmon_pattern_c", instance_id())+"::OnDisable";
+	donpcevent instance_npcname("2f_callmon_pattern_c")+"::OnDisable";
 	end;
 }
 
 2@cata,4,2,0	script	2f_callmon_pattern	-1,{
+OnInstanceInit:
+	disablenpc instance_npcname("2f_callmon_pattern");
+	end;
+
 OnEnable:
-	enablenpc instance_npcname("2f_callmon_pattern", instance_id());
+	enablenpc instance_npcname("2f_callmon_pattern");
 	stopnpctimer;
 	initnpctimer;
 	end;
 
 OnDisable:
-	disablenpc instance_npcname("2f_callmon_pattern", instance_id());
+	disablenpc instance_npcname("2f_callmon_pattern");
 	stopnpctimer;
 	end;
 
 OnTimer300000:
-	enablenpc instance_npcname("slave_down", instance_id());
-	enablenpc instance_npcname("slave_left", instance_id());
-	enablenpc instance_npcname("slave_right", instance_id());
-	donpcevent instance_npcname("2f_callmon_pattern_c", instance_id())+"::Ongo";
+	enablenpc instance_npcname("slave_down");
+	enablenpc instance_npcname("slave_left");
+	enablenpc instance_npcname("slave_right");
+	donpcevent instance_npcname("2f_callmon_pattern_c")+"::Ongo";
 	end;
 }
 
 2@cata,3,1,0	script	ins_2f_hero_pattern_c	-1,{
+OnInstanceInit:
+	disablenpc instance_npcname("ins_2f_hero_pattern_c");
+	end;
+
 OnEnable:
-	enablenpc instance_npcname("ins_2f_hero_pattern_c", instance_id());
+	enablenpc instance_npcname("ins_2f_hero_pattern_c");
 	initnpctimer;
-	donpcevent instance_npcname("ins_2f_hero_pattern_c", instance_id())+"::Ongo";
+	donpcevent instance_npcname("ins_2f_hero_pattern_c")+"::Ongo";
 	end;
 
 Ongo:
-	donpcevent instance_npcname("ins_2f_hero_pattern", instance_id())+"::OnEnable";
+	donpcevent instance_npcname("ins_2f_hero_pattern")+"::OnEnable";
 	end;
 
 OnDisable:
 	stopnpctimer;
-	disablenpc instance_npcname("Magical Seal#0", instance_id());
-	disablenpc instance_npcname("Magical Seal#2", instance_id());
-	disablenpc instance_npcname("Magical Seal#4", instance_id());
-	disablenpc instance_npcname("Magical Seal#8", instance_id());
-	disablenpc instance_npcname("Magical Seal#10", instance_id());
-	donpcevent instance_npcname("ins_2f_hero_pattern", instance_id())+"::OnDisable";
-	disablenpc instance_npcname("ins_2f_hero_pattern_c", instance_id());
+	disablenpc instance_npcname("Magical Seal#0");
+	disablenpc instance_npcname("Magical Seal#2");
+	disablenpc instance_npcname("Magical Seal#4");
+	disablenpc instance_npcname("Magical Seal#8");
+	disablenpc instance_npcname("Magical Seal#10");
+	donpcevent instance_npcname("ins_2f_hero_pattern")+"::OnDisable";
+	disablenpc instance_npcname("ins_2f_hero_pattern_c");
 	end;
 
 OnTimer3600000:
-	instance_announce 0, "Baphomet : krrrr... Now you can't stop me with the seals. All you can do is wait for death!",bc_map,"0xdb7093";
+	mapannounce instance_mapname("2@cata"), "Baphomet : krrrr... Now you can't stop me with the seals. All you can do is wait for death!",bc_map,"0xdb7093";
 	end;
 
 OnTimer3605000:
-	instance_announce 0, "Ancient Hero's Soul : We can't stop Baphomet with the magical power of the seals anymore. Now everything depends on God...",bc_map,"0xFFFF00";
-	donpcevent instance_npcname("ins_2f_hero_pattern_c", instance_id())+"::OnDisable";
+	mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : We can't stop Baphomet with the magical power of the seals anymore. Now everything depends on God...",bc_map,"0xFFFF00";
+	donpcevent instance_npcname("ins_2f_hero_pattern_c")+"::OnDisable";
 	end;
 }
 
 2@cata,3,2,0	script	ins_2f_hero_pattern	-1,{
+OnInstanceInit:
+	disablenpc instance_npcname("ins_2f_hero_pattern");
+	end;
+
 OnEnable:
-	enablenpc instance_npcname("ins_2f_hero_pattern", instance_id());
+	enablenpc instance_npcname("ins_2f_hero_pattern");
 	initnpctimer;
 	end;
 
 OnDisable:
-	disablenpc instance_npcname("ins_2f_hero_pattern", instance_id());
+	disablenpc instance_npcname("ins_2f_hero_pattern");
 	stopnpctimer;
 	end;
 
 OnTimer70000:
 	switch(rand(1,5)) {
 	case 1:
-		instance_announce 0, "Ancient Hero's Soul : The seal of the Main Altar is running out. Strengthen the Main Altar's seal!",bc_map,"0xFFFF00";
-		enablenpc instance_npcname("Magical Seal#0", instance_id());
-		disablenpc instance_npcname("Magical Seal#2", instance_id());
-		disablenpc instance_npcname("Magical Seal#4", instance_id());
-		disablenpc instance_npcname("Magical Seal#8", instance_id());
-		disablenpc instance_npcname("Magical Seal#10", instance_id());
+		mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : The seal of the Main Altar is running out. Strengthen the Main Altar's seal!",bc_map,"0xFFFF00";
+		enablenpc instance_npcname("Magical Seal#0");
+		disablenpc instance_npcname("Magical Seal#2");
+		disablenpc instance_npcname("Magical Seal#4");
+		disablenpc instance_npcname("Magical Seal#8");
+		disablenpc instance_npcname("Magical Seal#10");
 		break;
 	case 2:
-		instance_announce 0, "Ancient Hero's Soul : The magical power of the seal at 2 o'clock is running out. Go to 2 o'clock and put the magical power in the seal.",bc_map,"0xFFFF00";
-		disablenpc instance_npcname("Magical Seal#0", instance_id());
-		enablenpc instance_npcname("Magical Seal#2", instance_id());
-		disablenpc instance_npcname("Magical Seal#4", instance_id());
-		disablenpc instance_npcname("Magical Seal#8", instance_id());
-		disablenpc instance_npcname("Magical Seal#10", instance_id());
+		mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : The magical power of the seal at 2 o'clock is running out. Go to 2 o'clock and put the magical power in the seal.",bc_map,"0xFFFF00";
+		disablenpc instance_npcname("Magical Seal#0");
+		enablenpc instance_npcname("Magical Seal#2");
+		disablenpc instance_npcname("Magical Seal#4");
+		disablenpc instance_npcname("Magical Seal#8");
+		disablenpc instance_npcname("Magical Seal#10");
 		break;
 	case 3:
-		instance_announce 0, "Ancient Hero's Soul : The magical power of the seal at 4 o'clock is running out. Go to 4 o'clock and put the magical power in the seal.",bc_map,"0xFFFF00";
-		disablenpc instance_npcname("Magical Seal#0", instance_id());
-		disablenpc instance_npcname("Magical Seal#2", instance_id());
-		enablenpc instance_npcname("Magical Seal#4", instance_id());
-		disablenpc instance_npcname("Magical Seal#8", instance_id());
-		disablenpc instance_npcname("Magical Seal#10", instance_id());
+		mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : The magical power of the seal at 4 o'clock is running out. Go to 4 o'clock and put the magical power in the seal.",bc_map,"0xFFFF00";
+		disablenpc instance_npcname("Magical Seal#0");
+		disablenpc instance_npcname("Magical Seal#2");
+		enablenpc instance_npcname("Magical Seal#4");
+		disablenpc instance_npcname("Magical Seal#8");
+		disablenpc instance_npcname("Magical Seal#10");
 		break;
 	case 4:
-		instance_announce 0, "Ancient Hero's Soul : The magical power of the seal at 8 o'clock is running out. Go to 8 o'clock and put the magical power in the seal.",bc_map,"0xFFFF00";
-		disablenpc instance_npcname("Magical Seal#0", instance_id());
-		disablenpc instance_npcname("Magical Seal#2", instance_id());
-		disablenpc instance_npcname("Magical Seal#4", instance_id());
-		enablenpc instance_npcname("Magical Seal#8", instance_id());
-		disablenpc instance_npcname("Magical Seal#10", instance_id());
+		mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : The magical power of the seal at 8 o'clock is running out. Go to 8 o'clock and put the magical power in the seal.",bc_map,"0xFFFF00";
+		disablenpc instance_npcname("Magical Seal#0");
+		disablenpc instance_npcname("Magical Seal#2");
+		disablenpc instance_npcname("Magical Seal#4");
+		enablenpc instance_npcname("Magical Seal#8");
+		disablenpc instance_npcname("Magical Seal#10");
 		break;
 	case 5:
-		instance_announce 0, "Ancient Hero's Soul : The magical power of the seal at 10 o'clock is running out. Go to 10 o'clock and put the magical power in the seal.",bc_map,"0xFFFF00";
-		disablenpc instance_npcname("Magical Seal#0", instance_id());
-		disablenpc instance_npcname("Magical Seal#2", instance_id());
-		disablenpc instance_npcname("Magical Seal#4", instance_id());
-		disablenpc instance_npcname("Magical Seal#8", instance_id());
-		enablenpc instance_npcname("Magical Seal#10", instance_id());
+		mapannounce instance_mapname("2@cata"), "Ancient Hero's Soul : The magical power of the seal at 10 o'clock is running out. Go to 10 o'clock and put the magical power in the seal.",bc_map,"0xFFFF00";
+		disablenpc instance_npcname("Magical Seal#0");
+		disablenpc instance_npcname("Magical Seal#2");
+		disablenpc instance_npcname("Magical Seal#4");
+		disablenpc instance_npcname("Magical Seal#8");
+		enablenpc instance_npcname("Magical Seal#10");
 	}
 	stopnpctimer;
-	donpcevent instance_npcname("ins_2f_hero_pattern_c", instance_id())+"::Ongo";
+	donpcevent instance_npcname("ins_2f_hero_pattern_c")+"::Ongo";
 	end;
 }
 
 
 1@cata,1,1,0	script	ins_1f_spawn_mobs	-1,{
-OnEnable:
-	monster "1@cata",0,0,"Zombie Master",1298,10;
-	monster "1@cata",0,0,"Wraith Dead",1291,10;
-	//monster "1@cata",0,0,"Ancient Mimic",1699,10;
-	monster "1@cata",0,0,"Flame Skull",1869,10;
-	monster "1@cata",0,0,"Skeleton General",1290,10;
-	monster "1@cata",0,0,"Zombie Master",1298,10;
-	monster "1@cata",0,0,"Skeleton General",1290,10;
-	monster "1@cata",0,0,"Flame Skull",1869,10;
-	monster "1@cata",0,0,"Wraith Dead",1291,10;
-	monster "1@cata",0,0,"Wraith Dead",1291,10;
-	monster "1@cata",0,0,"Khalitzburg",1132,10;
-	monster "1@cata",0,0,"Khalitzburg",1132,10;
-	monster "1@cata",0,0,"Flame Skull",1869,10;
-	monster "1@cata",0,0,"Flame Skull",1869,10;
-	monster "1@cata",0,0,"Ancient Mimic",1699,10;
-	monster "1@cata",0,0,"Zombie Master",1298,10;
-	monster "1@cata",0,0,"Ancient Mimic",1699,10;
-	monster "1@cata",0,0,"Zombie Master",1298,10;
-	monster "1@cata",0,0,"Wraith Dead",1291,10;
-	monster "1@cata",0,0,"Skeleton General",1290,10;
-	monster "1@cata",0,0,"Skeleton General",1290,10;
-	monster "1@cata",0,0,"Wind Ghost",1263,10;
-	monster "1@cata",0,0,"Wind Ghost",1263,10;
-	monster "1@cata",0,0,"Wind Ghost",1263,10;
-	monster "1@cata",0,0,"Lude",1509,10;
-	monster "1@cata",0,0,"Lude",1509,10;
-	monster "1@cata",0,0,"Evil Druid",1117,10;
-	monster "1@cata",0,0,"Evil Druid",1117,10;
-	monster "1@cata",0,0,"Evil Druid",1117,10;
-	monster "1@cata",0,0,"Banshee",1867,10;
-	monster "1@cata",0,0,"Dark Illusion",1302,1;
+OnInstanceInit:
+	set 'ins_baphomet, 0;
+	set .@map$, instance_mapname("1@cata");
+	monster .@map$,0,0,"Zombie Master",1298,10;
+	monster .@map$,0,0,"Wraith Dead",1291,10;
+	//monster .@map$,0,0,"Ancient Mimic",1699,10;
+	monster .@map$,0,0,"Flame Skull",1869,10;
+	monster .@map$,0,0,"Skeleton General",1290,10;
+	monster .@map$,0,0,"Zombie Master",1298,10;
+	monster .@map$,0,0,"Skeleton General",1290,10;
+	monster .@map$,0,0,"Flame Skull",1869,10;
+	monster .@map$,0,0,"Wraith Dead",1291,10;
+	monster .@map$,0,0,"Wraith Dead",1291,10;
+	monster .@map$,0,0,"Khalitzburg",1132,10;
+	monster .@map$,0,0,"Khalitzburg",1132,10;
+	monster .@map$,0,0,"Flame Skull",1869,10;
+	monster .@map$,0,0,"Flame Skull",1869,10;
+	monster .@map$,0,0,"Ancient Mimic",1699,10;
+	monster .@map$,0,0,"Zombie Master",1298,10;
+	monster .@map$,0,0,"Ancient Mimic",1699,10;
+	monster .@map$,0,0,"Zombie Master",1298,10;
+	monster .@map$,0,0,"Wraith Dead",1291,10;
+	monster .@map$,0,0,"Skeleton General",1290,10;
+	monster .@map$,0,0,"Skeleton General",1290,10;
+	monster .@map$,0,0,"Wind Ghost",1263,10;
+	monster .@map$,0,0,"Wind Ghost",1263,10;
+	monster .@map$,0,0,"Wind Ghost",1263,10;
+	monster .@map$,0,0,"Lude",1509,10;
+	monster .@map$,0,0,"Lude",1509,10;
+	monster .@map$,0,0,"Evil Druid",1117,10;
+	monster .@map$,0,0,"Evil Druid",1117,10;
+	monster .@map$,0,0,"Evil Druid",1117,10;
+	monster .@map$,0,0,"Banshee",1867,10;
+	monster .@map$,0,0,"Dark Illusion",1302,1;
+	disablenpc instance_npcname("ins_1f_spawn_mobs");
 	end;
-}
+}

+ 141 - 170
npc/re/instances/HazyForest.txt

@@ -3,7 +3,7 @@
 //===== By: ================================================== 
 //= Euphy
 //===== Current Version: ===================================== 
-//= 1.0
+//= 1.1
 //===== Compatible With: ===================================== 
 //= rAthena SVN
 //===== Description: ========================================= 
@@ -12,6 +12,7 @@
 //= Contains the Wandering Guardian quest.
 //===== Additional Comments: ================================= 
 //= 1.0 First version. [Euphy]
+//= 1.1 Instance system rewrite. [Euphy]
 //============================================================ 
 
 // Instance Creation
@@ -79,70 +80,31 @@ bif_fild01,158,340,5	script	Laphine Soldier#mist	447,{
 		next;
 		switch(select("Venture into the Hazy Forest.:Give up.")) {
 		case 1:
-			set .@instance, instance_create(.@md_name$,.@party_id);
-			if (.@instance >= 0) {
-				if (instance_attachmap("1@mist",.@instance) != "") {
-
-					instance_attach(.@instance);
-					instance_set_timeout 7200,300,.@instance;
-					instance_init(.@instance);
-
-					donpcevent instance_npcname("#Whisper_mist", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Tom's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Tomba's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Remi's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Tired Rem's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Ron's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Rover's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Mona's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Namon's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Sad Neoron's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Spyder's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Tito's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Pumba's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Tete's Garden Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("The Gardeners' Tree", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("#Dragon Herder", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Mysterious Young Man#mis", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Loki#mist", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("Collapsed Girl#mist", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("#Mist Mobs Respawn1", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("#Mist Mobs Respawn2", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("#Mist Mobs Respawn3", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("#Mist Mobs Respawn4", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("#Mist Mobs Respawn5", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("#Fragments of Memory", instance_id())+"::OnInstanceInit";
-					donpcevent instance_npcname("#mist_warp_init", instance_id())+"::OnInstanceInit";
-
-					mes "[Laphine Soldier]";
-					mes "Party Name "+getpartyname(.@party_id)+"...";
-					mes "Party Leader "+strcharinfo(0)+"...";
-					mes "I've got it. I've written them down on the report here.";
-					next;
-					mes "[Laphine Soldier]";
-					mes "You'll get permission soon.";
-					mes "Now go to the log tunnel, the only way to get into the Hazy Forest.";
-					mes "You understand?";
-					next;
-					mes "[Laphine Soldier]";
-					mes "We can't go against the forest,";
-					mes "but maybe you humans can.";
-					mes "Good luck!";
-					close;
-				} else
-					instance_destroy(.@instance);
-			}
 			mes "[Laphine Soldier]";
 			mes "Party Name "+getpartyname(.@party_id)+"...";
 			mes "Party Leader "+strcharinfo(0)+"...";
-			mes "Hmm...";
+			if (instance_create(.@md_name$) < 0) {
+				mes "Hmm...";
+				next;
+				mes "[Laphine Soldier]";
+				if (.@playtime == -1)
+					mes "It's dangerous in the forest.";
+				else
+					mes "The atmosphere is somewhat tense in the forest.";
+				mes "...Why don't you just go back today?";
+				close;
+			}
+			mes "I've got it. I've written them down on the report here.";
 			next;
 			mes "[Laphine Soldier]";
-			if (.@playtime == -1)
-				mes "It's dangerous in the forest.";
-			else
-				mes "The atmosphere is somewhat tense in the forest.";
-			mes "...Why don't you just go back today?";
+			mes "You'll get permission soon.";
+			mes "Now go to the log tunnel, the only way to get into the Hazy Forest.";
+			mes "You understand?";
+			next;
+			mes "[Laphine Soldier]";
+			mes "We can't go against the forest,";
+			mes "but maybe you humans can.";
+			mes "Good luck!";
 			close;
 		case 2:
 			mes "[Laphine Soldier]";
@@ -177,31 +139,33 @@ bif_fild01,161,355,0	script	Log Tunnel	844,{
 	next;
 	if(select("Enter the tunnel.:Give up.") == 2)
 		close;
-	// TODO: Add official MD_Enter cases.
-	if (!getcharid(1)) {
+	switch(instance_enter("Mistwood Maze")) {
+	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.";
+		close;
+	case 2:
+		mes "You try to crawl into the log, but some mysterious power pushes you back with a gush of wind.";
+		mes "It seems like you can't force your way into the forest.";
+		close;
+	case 1:
 		mes "[Laphine Soldier]";
 		mes "Hey, look!";
 		mes "Are you going alone?";
 		mes "That's impossible. Too rash.";
 		mes "Team up with some friends and go together!";
 		close;
-	}
-	set .@playtime, checkquest(7211,PLAYTIME);
-	if (has_instance("1@mist") == "") {
-		if (.@playtime == 0 || .@playtime == 1) {
-			mes "You try to crawl into the log, but some mysterious power pushes you back with a gush of wind.";
-			mes "It seems like you can't force your way into the forest.";
-			close;
-		}
+	case 0:
+		if (checkquest(7211,PLAYTIME) == 2) erasequest 7211;
+		if (checkquest(7211,PLAYTIME) == -1) setquest 7211;
+		mapannounce "bif_fild01",getpartyname(getcharid(1))+" party's "+strcharinfo(0)+" member is entering the Mistwood Maze.",bc_map,"0x00ff99"; //FW_NORMAL 12 0 0
+		//warp "1@mist",89,29;
+		close;
+	default:
 		mes "The world beyond the log tunnel looks dark and suffocating.";
 		mes "Your instinct is screaming that this forest is dangerous.";
 		close;
 	}
-	if (.@playtime == 2) erasequest 7211;
-	if (checkquest(7211,PLAYTIME) == -1) setquest 7211;
-	mapannounce "bif_fild01",getpartyname(getcharid(1))+" party's "+strcharinfo(0)+" member is entering the Mistwood Maze.",bc_map,"0x00ff99"; //FW_NORMAL 12 0 0
-	warp "1@mist",89,29;
-	close;
 }
 
 // Instance Scripts
@@ -209,43 +173,44 @@ bif_fild01,161,355,0	script	Log Tunnel	844,{
 1@mist,89,29,0	script	#Whisper_mist	844,1,1,{
 	end;
 OnInstanceInit:
-	enablenpc instance_npcname("#Whisper_mist", instance_id());
+	enablenpc instance_npcname("#Whisper_mist");
 	end;
 OnTouch:
-	disablenpc instance_npcname("#Whisper_mist", instance_id());
+	disablenpc instance_npcname("#Whisper_mist");
 	initnpctimer;
 	end;
 OnTimer10000:
 OnTimer20000:
-	instance_announce 0,"Whisper: Who's this? Who's this!? The forest is open! Tom, Tomba, Tired Rem, Remi! Wake up!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Whisper: Who's this? Who's this!? The forest is open! Tom, Tomba, Tired Rem, Remi! Wake up!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	end;
 OnTimer60000:
-	instance_announce 0,"Loud Whisper: What are the forest keepers doing? What are the gardeners doing??",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Loud Whisper: What are the forest keepers doing? What are the gardeners doing??",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	end;
 OnTimer120000:
-	instance_announce 0,"Loud Whisper: Don't go out, wander around forever, and play with us!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Loud Whisper: Don't go out, wander around forever, and play with us!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	end;
 OnTimer180000:
-	instance_announce 0,"Loud Whisper: Useless, useless. Wandering around and around, you'll meet your end!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Loud Whisper: Useless, useless. Wandering around and around, you'll meet your end!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	stopnpctimer;
 	end;
 }
 
 // callfunc "F_Mora_Mist",<warp to enable>,<success message>,<fail message>{,<end flag>}
 function	script	F_Mora_Mist	{
-	if (mobcount("1@mist",instance_npcname(strnpcinfo(0), instance_id())+"::OnMyMobDead") == 0) {
+	set .@map$, instance_mapname("1@mist");
+	if (mobcount(.@map$,instance_npcname(strnpcinfo(0))+"::OnMyMobDead") == 0) {
 		mes "Obviously no one is taking care of it.";
 		mes "It seems like you can chop down the garden tree.";
 		next;
 		if(select("Chop down the garden tree.:Give up.") == 2)
 			close;
 		mes "You chop down the tree, which was blocking the path of the maze, "+((getarg(3,0))?"clearing the way out of the forest.":"so now you can continue.");
-		instance_announce 0,getarg(1),bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
-		enablenpc instance_npcname(getarg(0), instance_id());
-		disablenpc instance_npcname(strnpcinfo(0), instance_id());
+		mapannounce .@map$,getarg(1),bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+		enablenpc instance_npcname(getarg(0));
+		disablenpc instance_npcname(strnpcinfo(0));
 		close;
 	} else
-		instance_announce 0,((getarg(3,0))?getarg(2):getarg(2)+"'s Cry: Huh? Who's doing bad things to my tree?!"),bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+		mapannounce .@map$,((getarg(3,0))?getarg(2):getarg(2)+"'s Cry: Huh? Who's doing bad things to my tree?!"),bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	end;
 }
 
@@ -257,7 +222,7 @@ function	script	F_Mora_Mist	{
 		"Tom";
 	end;
 OnInstanceInit:
-	monster "1@mist",249,120,"Tom",2136,1,instance_npcname("Tom's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),249,120,"Tom",2136,1,instance_npcname("Tom's Garden Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -271,7 +236,7 @@ OnMyMobDead:
 		"Tomba";
 	end;
 OnInstanceInit:
-	monster "1@mist",200,64,"Tomba",2136,1,instance_npcname("Tomba's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),200,64,"Tomba",2136,1,instance_npcname("Tomba's Garden Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -285,7 +250,7 @@ OnMyMobDead:
 		"Remi";
 	end;
 OnInstanceInit:
-	monster "1@mist",154,184,"Remi the Tired",2137,1,instance_npcname("Remi's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),154,184,"Remi the Tired",2137,1,instance_npcname("Remi's Garden Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -299,16 +264,16 @@ OnMyMobDead:
 		"Rem";
 	end;
 OnInstanceInit:
-	monster "1@mist",101,107,"Rem the Gardener",2136,1,instance_npcname("Tired Rem's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),101,107,"Rem the Gardener",2136,1,instance_npcname("Tired Rem's Garden Tree")+"::OnMyMobDead";
 	end;
 OnTimer10000:
-	instance_announce 0,"Whisper of the Forest: So Tom's, Tomba's, Remi's, and Rem's garden trees were all chopped down?",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Whisper of the Forest: So Tom's, Tomba's, Remi's, and Rem's garden trees were all chopped down?",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	end;
 OnTimer15000:
-	instance_announce 0,"Whisper of the Forest: Trouble, trouble, we're in big trouble.",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Whisper of the Forest: Trouble, trouble, we're in big trouble.",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	end;
 OnTimer20000:
-	instance_announce 0,"Loud Whisper: They've come to the second deepest forest. Gardeners of the deep forest, watch out!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Loud Whisper: They've come to the second deepest forest. Gardeners of the deep forest, watch out!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	stopnpctimer;
 	end;
 OnMyMobDead:
@@ -323,7 +288,7 @@ OnMyMobDead:
 		"Ron";
 	end;
 OnInstanceInit:
-	monster "1@mist",227,178,"Ron the Gardener",2134,1,instance_npcname("Ron's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),227,178,"Ron the Gardener",2134,1,instance_npcname("Ron's Garden Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -337,7 +302,7 @@ OnMyMobDead:
 		"Rover";
 	end;
 OnInstanceInit:
-	monster "1@mist",304,237,"Rover the Strutter",2134,1,instance_npcname("Rover's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),304,237,"Rover the Strutter",2134,1,instance_npcname("Rover's Garden Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -351,7 +316,7 @@ OnMyMobDead:
 		"Mona";
 	end;
 OnInstanceInit:
-	monster "1@mist",239,253,"Mona the Seedseeker",2133,1,instance_npcname("Mona's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),239,253,"Mona the Seedseeker",2133,1,instance_npcname("Mona's Garden Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -365,7 +330,7 @@ OnMyMobDead:
 		"Namon";
 	end;
 OnInstanceInit:
-	monster "1@mist",89,173,"Brave Namon",2134,1,instance_npcname("Namon's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),89,173,"Brave Namon",2134,1,instance_npcname("Namon's Garden Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -379,7 +344,7 @@ OnMyMobDead:
 		"Neoron";
 	end;
 OnInstanceInit:
-	monster "1@mist",143,265,"Sad Neoron",2137,1,instance_npcname("Sad Neoron's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),143,265,"Sad Neoron",2137,1,instance_npcname("Sad Neoron's Garden Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -393,19 +358,19 @@ OnMyMobDead:
 		"Spyder";
 	end;
 OnInstanceInit:
-	monster "1@mist",209,200,"Spyder the Eight-Legged",2132,1,instance_npcname("Spyder's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),209,200,"Spyder the Eight-Legged",2132,1,instance_npcname("Spyder's Garden Tree")+"::OnMyMobDead";
 	end;
 OnTimer5000:
-	instance_announce 0,"Roaring Whisper: The path is about to open. The tight bolts have been removed!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Roaring Whisper: The path is about to open. The tight bolts have been removed!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	end;
 OnTimer9000:
-	instance_announce 0,"Roaring Whisper: A forest opened, another opened, and the other is going to open as well. Tito and Pumba, they are heading your way!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Roaring Whisper: A forest opened, another opened, and the other is going to open as well. Tito and Pumba, they are heading your way!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	end;
 OnTimer13000:
-	instance_announce 0,"Roaring Whisper: Where you get after wandering around, around and around, everybody you've met while wandering around, around and around,",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Roaring Whisper: Where you get after wandering around, around and around, everybody you've met while wandering around, around and around,",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	end;
 OnTimer17000:
-	instance_announce 0,"Roaring Whisper: all the gardeners will be waiting for you, with their clippers in their hands-!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Roaring Whisper: all the gardeners will be waiting for you, with their clippers in their hands-!",bc_map,"0xccffcc"; //FW_NORMAL 12 0 0
 	stopnpctimer;
 	end;
 OnMyMobDead:
@@ -420,7 +385,7 @@ OnMyMobDead:
 		"Tito";
 	end;
 OnInstanceInit:
-	monster "1@mist",264,291,"Tito the Flipper",2133,1,instance_npcname("Tito's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),264,291,"Tito the Flipper",2133,1,instance_npcname("Tito's Garden Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -434,7 +399,7 @@ OnMyMobDead:
 		"Pumba";
 	end;
 OnInstanceInit:
-	monster "1@mist",309,165,"Diligent Pumba",2134,1,instance_npcname("Pumba's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),309,165,"Diligent Pumba",2134,1,instance_npcname("Pumba's Garden Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -448,7 +413,7 @@ OnMyMobDead:
 		"Tete";
 	end;
 OnInstanceInit:
-	monster "1@mist",277,343,"Carefree Tete",2136,1,instance_npcname("Tete's Garden Tree", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),277,343,"Carefree Tete",2136,1,instance_npcname("Tete's Garden Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -461,19 +426,20 @@ OnMyMobDead:
 		"Gardeners: We're not dead, yet!!!!",1;
 	end;
 OnInstanceInit:
-	monster "1@mist",318,137,"Baby Tom",2136,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",321,137,"Tomba the Baby",2136,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",324,137,"Exhausted Remi",2137,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",319,135,"Rem the Exhausted",2136,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",323,135,"Ron the Ex-Gardener",2134,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",320,133,"Rover the Strutter",2134,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",323,133,"Mona the Seedpicker",2133,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",317,132,"Timid Namon",2134,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",326,132,"Indifferent Neoron",2137,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",317,129,"Spyder the Seven-Legged",2132,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",320,129,"Tito the Flapper",2133,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",324,129,"Lazy Pumba",2134,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
-	monster "1@mist",327,129,"Careless Tete",2136,1,instance_npcname("The Gardeners' Tree", instance_id())+"::OnMyMobDead";
+	set .@map$, instance_mapname("1@mist");
+	monster .@map$,318,137,"Baby Tom",2136,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,321,137,"Tomba the Baby",2136,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,324,137,"Exhausted Remi",2137,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,319,135,"Rem the Exhausted",2136,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,323,135,"Ron the Ex-Gardener",2134,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,320,133,"Rover the Strutter",2134,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,323,133,"Mona the Seedpicker",2133,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,317,132,"Timid Namon",2134,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,326,132,"Indifferent Neoron",2137,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,317,129,"Spyder the Seven-Legged",2132,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,320,129,"Tito the Flapper",2133,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,324,129,"Lazy Pumba",2134,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
+	monster .@map$,327,129,"Careless Tete",2136,1,instance_npcname("The Gardeners' Tree")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
 	end;
@@ -481,7 +447,7 @@ OnMyMobDead:
 
 1@mist,73,290,0	script	Mysterious Flower#1	844,{
 	specialeffect EF_LEVEL99_4;
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	disablenpc instance_npcname(strnpcinfo(0));
 	getitem 12561,1; //Mysterious_Seed
 	end;
 }
@@ -547,21 +513,22 @@ OnInstanceInit:
 		case 5: setarray .@c[0],268,183; break;
 		case 6: setarray .@c[0],65,278; break;
 	}
-	monster "1@mist",.@c[0],.@c[1],"Wandering Purple Dragon",2131,1,instance_npcname("#Dragon Herder", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),.@c[0],.@c[1],"Wandering Purple Dragon",2131,1,instance_npcname("#Dragon Herder")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
-	if (mobcount("1@mist",instance_npcname("#Dragon Herder", instance_id())+"::OnMyMobDead") == 0) {
-		donpcevent instance_npcname("Collapsed Girl#mist", instance_id())+"::OnEnable";
-		donpcevent instance_npcname("Mysterious Young Man#mis", instance_id())+"::OnEnable";
-		donpcevent instance_npcname("Loki#mist", instance_id())+"::OnEnable";
-		instance_announce 0,"The Dragon's Cry: Am I being punished... for abandoning the way... of the guardian...?",bc_map,"0xffff00"; //FW_NORMAL 12 0 0
-		disablenpc instance_npcname("#Dragon Herder", instance_id());
+	set .@map$, instance_mapname("1@mist");
+	if (mobcount(.@map$,instance_npcname("#Dragon Herder")+"::OnMyMobDead") == 0) {
+		donpcevent instance_npcname("Collapsed Girl#mist")+"::OnEnable";
+		donpcevent instance_npcname("Mysterious Young Man#mis")+"::OnEnable";
+		donpcevent instance_npcname("Loki#mist")+"::OnEnable";
+		mapannounce .@map$,"The Dragon's Cry: Am I being punished... for abandoning the way... of the guardian...?",bc_map,"0xffff00"; //FW_NORMAL 12 0 0
+		disablenpc instance_npcname("#Dragon Herder");
 		initnpctimer;
 	}
 	end;
 OnTimer3000:
 	stopnpctimer;
-	instance_announce 0,"Voice in your head: ...Will you... save... me... please......?",bc_map,"0xffff00"; //FW_NORMAL 12 0 0
+	mapannounce instance_mapname("1@mist"),"Voice in your head: ...Will you... save... me... please......?",bc_map,"0xffff00"; //FW_NORMAL 12 0 0
 	end;
 }
 
@@ -705,12 +672,11 @@ OnTimer3000:
 		close;
 	}
 	end;
-OnInstanceInit:
 OnEnable:
-	enablenpc instance_npcname("Mysterious Young Man#mis", instance_id());
+	enablenpc instance_npcname("Mysterious Young Man#mis");
 	end;
 OnDisable:
-	disablenpc instance_npcname("Mysterious Young Man#mis", instance_id());
+	disablenpc instance_npcname("Mysterious Young Man#mis");
 	end;
 }
 
@@ -761,10 +727,10 @@ OnDisable:
 	end;
 OnInstanceInit:
 OnDisable:
-	disablenpc instance_npcname("Loki#mist", instance_id());
+	disablenpc instance_npcname("Loki#mist");
 	end;
 OnEnable:
-	enablenpc instance_npcname("Loki#mist", instance_id());
+	enablenpc instance_npcname("Loki#mist");
 	end;
 }
 
@@ -774,10 +740,10 @@ OnEnable:
 	close;
 OnInstanceInit:
 OnDisable:
-	disablenpc instance_npcname("Collapsed Girl#mist", instance_id());
+	disablenpc instance_npcname("Collapsed Girl#mist");
 	end;
 OnEnable:
-	enablenpc instance_npcname("Collapsed Girl#mist", instance_id());
+	enablenpc instance_npcname("Collapsed Girl#mist");
 	end;
 }
 
@@ -905,7 +871,7 @@ mora,48,152,3	script	Sharp Eyed Man	512,{
 		mes "You still have things to do.";
 		next;
 		mes "[Nydhogg the Guardian]";
-		mes "... Oh, yes. It's late, but I have to fulfill my duties as a guardian.";
+		mes "...Oh, yes. It's late, but I have to fulfill my duties as a guardian.";
 		mes "Now I know. I'll destroy Morroc with my own hands.";
 		mes "I will fulfill my duties as a guardian.";
 		next;
@@ -961,68 +927,73 @@ mora,48,152,3	script	Sharp Eyed Man	512,{
 1@mist,1,1,0	script	#Mist Mobs Respawn1	844,{
 	end;
 OnInstanceInit:
-	monster "1@mist",0,0,"Miming",2137,15,instance_npcname("#Mist Mobs Respawn1", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),0,0,"Miming",2137,15,instance_npcname("#Mist Mobs Respawn1")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
-	set .@num_mobs, 15 - mobcount("1@mist",instance_npcname("#Mist Mobs Respawn1", instance_id())+"::OnMyMobDead");
+	set .@map$, instance_mapname("1@mist");
+	set .@num_mobs, 15 - mobcount(.@map$,instance_npcname("#Mist Mobs Respawn1")+"::OnMyMobDead");
 	if (.@num_mobs > 0)
-		monster "1@mist",0,0,"Miming",2137,.@num_mobs,instance_npcname("#Mist Mobs Respawn1", instance_id())+"::OnMyMobDead";
+		monster .@map$,0,0,"Miming",2137,.@num_mobs,instance_npcname("#Mist Mobs Respawn1")+"::OnMyMobDead";
 	end;
 }
 
 1@mist,1,2,0	script	#Mist Mobs Respawn2	844,{
 	end;
 OnInstanceInit:
-	monster "1@mist",0,0,"Pom Spider",2132,35,instance_npcname("#Mist Mobs Respawn2", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),0,0,"Pom Spider",2132,35,instance_npcname("#Mist Mobs Respawn2")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
-	set .@num_mobs, 35 - mobcount("1@mist",instance_npcname("#Mist Mobs Respawn2", instance_id())+"::OnMyMobDead");
+	set .@map$, instance_mapname("1@mist");
+	set .@num_mobs, 35 - mobcount(.@map$,instance_npcname("#Mist Mobs Respawn2")+"::OnMyMobDead");
 	if (.@num_mobs > 0)
-		monster "1@mist",0,0,"Pom Spider",2132,.@num_mobs,instance_npcname("#Mist Mobs Respawn2", instance_id())+"::OnMyMobDead";
+		monster .@map$,0,0,"Pom Spider",2132,.@num_mobs,instance_npcname("#Mist Mobs Respawn2")+"::OnMyMobDead";
 	end;
 }
 
 1@mist,1,3,0	script	#Mist Mobs Respawn3	844,{
 	end;
 OnInstanceInit:
-	monster "1@mist",0,0,"Angra Mantis",2133,35,instance_npcname("#Mist Mobs Respawn3", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),0,0,"Angra Mantis",2133,35,instance_npcname("#Mist Mobs Respawn3")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
-	set .@num_mobs, 35 - mobcount("1@mist",instance_npcname("#Mist Mobs Respawn3", instance_id())+"::OnMyMobDead");
+	set .@map$, instance_mapname("1@mist");
+	set .@num_mobs, 35 - mobcount(.@map$,instance_npcname("#Mist Mobs Respawn3")+"::OnMyMobDead");
 	if (.@num_mobs > 0)
-		monster "1@mist",0,0,"Angra Mantis",2133,.@num_mobs,instance_npcname("#Mist Mobs Respawn3", instance_id())+"::OnMyMobDead";
+		monster .@map$,0,0,"Angra Mantis",2133,.@num_mobs,instance_npcname("#Mist Mobs Respawn3")+"::OnMyMobDead";
 	end;
 }
 
 1@mist,1,4,0	script	#Mist Mobs Respawn4	844,{
 	end;
 OnInstanceInit:
-	monster "1@mist",0,0,"Parus",2134,35,instance_npcname("#Mist Mobs Respawn4", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),0,0,"Parus",2134,35,instance_npcname("#Mist Mobs Respawn4")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
-	set .@num_mobs, 35 - mobcount("1@mist",instance_npcname("#Mist Mobs Respawn4", instance_id())+"::OnMyMobDead");
+	set .@map$, instance_mapname("1@mist");
+	set .@num_mobs, 35 - mobcount(.@map$,instance_npcname("#Mist Mobs Respawn4")+"::OnMyMobDead");
 	if (.@num_mobs > 0)
-		monster "1@mist",0,0,"Parus",2134,.@num_mobs,instance_npcname("#Mist Mobs Respawn4", instance_id())+"::OnMyMobDead";
+		monster .@map$,0,0,"Parus",2134,.@num_mobs,instance_npcname("#Mist Mobs Respawn4")+"::OnMyMobDead";
 	end;
 }
 
 1@mist,1,5,0	script	#Mist Mobs Respawn5	844,{
 	end;
 OnInstanceInit:
-	monster "1@mist",0,0,"Little Fatum",2136,15,instance_npcname("#Mist Mobs Respawn5", instance_id())+"::OnMyMobDead";
+	monster instance_mapname("1@mist"),0,0,"Little Fatum",2136,15,instance_npcname("#Mist Mobs Respawn5")+"::OnMyMobDead";
 	end;
 OnMyMobDead:
-	set .@num_mobs, 15 - mobcount("1@mist",instance_npcname("#Mist Mobs Respawn5", instance_id())+"::OnMyMobDead");
+	set .@map$, instance_mapname("1@mist");
+	set .@num_mobs, 15 - mobcount(.@map$,instance_npcname("#Mist Mobs Respawn5")+"::OnMyMobDead");
 	if (.@num_mobs > 0)
-		monster "1@mist",0,0,"Little Fatum",2136,.@num_mobs,instance_npcname("#Mist Mobs Respawn5", instance_id())+"::OnMyMobDead";
+		monster .@map$,0,0,"Little Fatum",2136,.@num_mobs,instance_npcname("#Mist Mobs Respawn5")+"::OnMyMobDead";
 	end;
 }
 
 1@mist,1,6,0	script	#Fragments of Memory	844,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname("#Fragments of Memory", instance_id());
-	monster "1@mist",0,0,"Guardian's Fragments of Memory",2138,15;
+	disablenpc instance_npcname("#Fragments of Memory");
+	monster instance_mapname("1@mist"),0,0,"Guardian's Fragments of Memory",2138,15;
 	end;
 }
 
@@ -1058,7 +1029,7 @@ bif_fild01,38,374,0	script	Mysterious Flower#ep14_1	844,{
 OnTouch:
 	if (checkquest(7211,PLAYTIME) == -1)
 		setquest 7211;
-	warp "1@mist",116,40;
+	warp instance_mapname("1@mist"),116,40;
 	end;
 }
 
@@ -1160,21 +1131,21 @@ OnTouch:
 1@mist,1,1,0	script	#mist_warp_init	844,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname("a25_a18-1", instance_id());
-	disablenpc instance_npcname("a27-2_af1-2", instance_id());
-	disablenpc instance_npcname("a15-2_a4-1", instance_id());
-	disablenpc instance_npcname("a4-2_a11", instance_id());
-	disablenpc instance_npcname("b4-2_b2", instance_id());
-	disablenpc instance_npcname("b7_bf1-2", instance_id());
-	disablenpc instance_npcname("b31_b16", instance_id());
-	disablenpc instance_npcname("b27-3_bN-1", instance_id());
-	disablenpc instance_npcname("b6-1_b33", instance_id());
-	disablenpc instance_npcname("b5_b14", instance_id());
-	disablenpc instance_npcname("c1_c13-1", instance_id());
-	disablenpc instance_npcname("c13-3_c4", instance_id());
-	disablenpc instance_npcname("c19_c4", instance_id());
-	disablenpc instance_npcname("#to_bif02", instance_id());
-	disablenpc instance_npcname("#mist_warp_init", instance_id());
+	disablenpc instance_npcname("a25_a18-1");
+	disablenpc instance_npcname("a27-2_af1-2");
+	disablenpc instance_npcname("a15-2_a4-1");
+	disablenpc instance_npcname("a4-2_a11");
+	disablenpc instance_npcname("b4-2_b2");
+	disablenpc instance_npcname("b7_bf1-2");
+	disablenpc instance_npcname("b31_b16");
+	disablenpc instance_npcname("b27-3_bN-1");
+	disablenpc instance_npcname("b6-1_b33");
+	disablenpc instance_npcname("b5_b14");
+	disablenpc instance_npcname("c1_c13-1");
+	disablenpc instance_npcname("c13-3_c4");
+	disablenpc instance_npcname("c19_c4");
+	disablenpc instance_npcname("#to_bif02");
+	disablenpc instance_npcname("#mist_warp_init");
 	end;
 }
 1@mist,247,123,0	warp	a25_a18-1	1,1,1@mist,164,66	//Tom
@@ -1190,4 +1161,4 @@ OnInstanceInit:
 1@mist,95,287,0	warp	c1_c13-1	1,1,1@mist,323,276	//Tito
 1@mist,324,325,0	warp	c13-3_c4	1,1,1@mist,49,316	//Pumba
 1@mist,280,344,0	warp	c19_c4	1,1,1@mist,49,316	//Tete
-1@mist,345,186,0	warp	#to_bif02	1,1,bif_fild02,151,121	//The Gardeners' Tree
+1@mist,345,186,0	warp	#to_bif02	1,1,bif_fild02,151,121	//The Gardeners' Tree

+ 168 - 208
npc/re/instances/MalangdoCulvert.txt

@@ -3,7 +3,7 @@
 //===== By: ================================================== 
 //= Euphy
 //===== Current Version: ===================================== 
-//= 1.0b
+//= 1.1
 //===== Compatible With: ===================================== 
 //= rAthena SVN
 //===== Description: ========================================= 
@@ -16,6 +16,7 @@
 //=     Letters "n" and "h" in NPC names indicate difficulty.
 //= 1.0a There is no minimum party size on official servers.
 //= 1.0b Fixed incorrect use of 'close'. [Joseph]
+//= 1.1 Instance system rewrite. [Euphy]
 //============================================================ 
 
 // Quest NPCs
@@ -401,77 +402,29 @@ mal_in01,160,34,4	script	Missing, the Cleaner	545,{
 				mes "What a rookie.";
 				close;
 			case 2:
-				set .@instance, instance_create(.@md_name$,.@party_id);
-				if (.@instance < 0) {
+				if (instance_create(.@md_name$) < 0) {
 					mes "Party name: "+getpartyname(.@party_id);
 					mes "Party leader: "+strcharinfo(0);
 					mes "^0000ff"+.@md_name$+"^000000 - Reservation Failed!";
 					close;
 				}
-				if (instance_attachmap("1@pump",.@instance) == "" || instance_attachmap("2@pump",.@instance) == "") {
-					mes "^0000ff"+.@md_name$+"^000000 - Reservation Failed!";
-					instance_destroy(.@instance);
-					close;
-				}
-				instance_attach(.@instance);
-				instance_set_timeout 3600,300,.@instance;
-				instance_init(.@instance);
-
-				// Common Scripts
-				donpcevent instance_npcname("Missing, the Cleaner#0", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Culvert Entrance#i", instance_id())+"::OnInstanceInit";
-
-				// Normal Mode
-				donpcevent instance_npcname("Missing, the Cleaner#nf", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Monster Hole#n", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_n1", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_n2", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_n3", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_n4", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_n5", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_n6", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Boss Creation#n", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Missing, the Cleaner#no", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Culvert Entrance#n", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Hydra#n", instance_id())+"::OnInstanceInit";
-
-				// Hard Mode
-				donpcevent instance_npcname("Missing, the Cleaner#hf", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Monster Hole#h", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_h1", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_h2", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_h3", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_h4", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_h5", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_h6", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_h7", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_h8", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_h9", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("#Culvert_h10", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Boss Creation#h", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Missing, the Cleaner#ho", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Culvert Entrance#h", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("Hydra#h", instance_id())+"::OnInstanceInit";
-
 				mes "^3333FF"+.@md_name$+"^000000 - Reserving";
 				mes "After making the reservation, you";
 				mes "have to select Enter the Culvert.";
 				close;
 			case 3:
-				goto L_Enter;
+				callsub L_Enter,0;
 			}
 		}
 		if(select("Enter Culvert:Cancel") == 2)
 			end;
-		goto L_Enter;
+		callsub L_Enter,1;
 	} else if (.@playtime == 0 || .@playtime == 1) {
 		mes "You can enter the Culvert if the gate is open.";
 		next;
 		if(select("Enter Culvert:Cancel") == 2)
 			close;
-		goto L_Enter;
+		callsub L_Enter,0;
 	} else if (.@playtime == 2) {
 		mes "^0000ffThe gate to the Culvert is open again.^000000";
 		erasequest 12254;
@@ -479,21 +432,24 @@ mal_in01,160,34,4	script	Missing, the Cleaner	545,{
 	}
 	end;
 L_Enter:
-	// TODO: Add official MD_Enter cases.
-	if (has_instance("1@pump") == "") {
-		if (checkquest(12254,PLAYTIME) == 0 || checkquest(12254,PLAYTIME) == 1) {
-			mes "The gate to the Culvert is still closed.";
-			mes "You must wait until you are able to enter or find a party leader who can create the instance.";
-			close;
-		}
-		mes "The memorial dungeon Culvert does not exist.";
-		mes "The party leader has not reserved entrance to the dungeon yet.";
+	switch(instance_enter("Culvert")) {
+	case 3:
+		mes "An unknown error has occurred.";
+		close;
+	case 2:
+		mes "The gate to the Culvert is still closed.";
+		mes "You must wait until you are able to enter or find a party leader who can create the instance.";
+		close;
+	case 1:
+		mes "Only party members can participate.";
 		close;
+	case 0:
+		mapannounce "mal_in01", strcharinfo(0)+" of the party "+getpartyname(.@party_id)+" is entering the Culvert.",bc_map,"0x00ff99";
+		if (checkquest(12254) == -1) setquest 12254;
+		//warp "1@pump",63,98;
+		if (getarg(0) == 0) close;
+		else end;
 	}
-	mapannounce "mal_in01", strcharinfo(0)+" of the party "+getpartyname(.@party_id)+" is entering the Culvert.",bc_map,"0x00ff99";
-	if (checkquest(12254) == -1) setquest 12254;
-	warp "1@pump",63,98;
-	close;
 }
 
 // Instance: Common Scripts
@@ -521,9 +477,9 @@ L_Enter:
 			close;
 		}
 		set 'party_id,getcharid(1);
-		instance_announce 0,"Missing: Move toward the 3 o'clock direction and wait for my next order!",bc_map,"0xff88ff",FW_NORMAL,15;
-		disablenpc instance_npcname("Missing, the Cleaner#0", instance_id());
-		enablenpc instance_npcname("Missing, the Cleaner#n", instance_id());
+		mapannounce instance_mapname("1@pump"),"Missing: Move toward the 3 o'clock direction and wait for my next order!",bc_map,"0xff88ff",FW_NORMAL,15;
+		disablenpc instance_npcname("Missing, the Cleaner#0");
+		enablenpc instance_npcname("Missing, the Cleaner#n");
 		close;
 	case 2:
 		if (BaseLevel < 140) {
@@ -543,9 +499,9 @@ L_Enter:
 			close;
 		}
 		set 'party_id,getcharid(1);
-		instance_announce 0,"Missing: I'll go in first, so follow me! I'll open up a gate at the 3 o'clock direction!",bc_map,"0xff88ff",FW_NORMAL,15;
-		disablenpc instance_npcname("Missing, the Cleaner#0", instance_id());
-		enablenpc instance_npcname("Culvert Entrance#i", instance_id());
+		mapannounce instance_mapname("1@pump"),"Missing: I'll go in first, so follow me! I'll open up a gate at the 3 o'clock direction!",bc_map,"0xff88ff",FW_NORMAL,15;
+		disablenpc instance_npcname("Missing, the Cleaner#0");
+		enablenpc instance_npcname("Culvert Entrance#i");
 		close;
 	case 3:
 		mes "[Missing, the Cleaner]";
@@ -553,21 +509,18 @@ L_Enter:
 		close;
 	}
 	end;
-OnInstanceInit:
-	enablenpc instance_npcname("Missing, the Cleaner#0", instance_id());
-	end;
 }
 
 1@pump,84,105,0	script	Culvert Entrance#i	45,3,3,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname("Culvert Entrance#i", instance_id());
+	disablenpc instance_npcname("Culvert Entrance#i");
 	end;
 OnTouch:
 	if (BaseLevel >= 140)
-		warp "2@pump",38,88;
+		warp instance_mapname("2@pump"),38,88;
 	else
-		warp "1@pump",74,105;
+		warp instance_mapname("1@pump"),74,105;
 	end;
 }
 
@@ -638,56 +591,58 @@ function	script	F_mal_missing	{
 		mes "[Missing, the Cleaner]";
 		mes "Ok! Let's start now!";
 		set .@i$, charat(strnpcinfo(2),0);
-		enablenpc instance_npcname("Missing, the Cleaner#"+.@i$, instance_id());
-		donpcevent instance_npcname("Missing, the Cleaner#"+.@i$, instance_id())+"::OnStart";
-		disablenpc instance_npcname("Culvert Entrance#"+.@i$, instance_id());
-		disablenpc instance_npcname("Missing, the Cleaner#"+.@i$+"o", instance_id());
-		donpcevent instance_npcname("Monster Hole#"+.@i$, instance_id())+"::OnClear";
-		disablenpc instance_npcname(strnpcinfo(0), instance_id());
+		enablenpc instance_npcname("Missing, the Cleaner#"+.@i$);
+		donpcevent instance_npcname("Missing, the Cleaner#"+.@i$)+"::OnStart";
+		disablenpc instance_npcname("Culvert Entrance#"+.@i$);
+		disablenpc instance_npcname("Missing, the Cleaner#"+.@i$+"o");
+		donpcevent instance_npcname("Monster Hole#"+.@i$)+"::OnClear";
+		disablenpc instance_npcname(strnpcinfo(0));
 		close;
 	}
 	close;
 OnInstanceInit:
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	disablenpc instance_npcname(strnpcinfo(0));
 	end;
 }
 
 1@pump,84,105,4	script	Missing, the Cleaner#n	545,{
 	callfunc "F_mal_missing";
-	donpcevent instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnStart";
+	donpcevent instance_npcname("Missing, the Cleaner#n")+"::OnStart";
 	close;
 OnInstanceInit:
-	disablenpc instance_npcname("Missing, the Cleaner#n", instance_id());
+	disablenpc instance_npcname("Missing, the Cleaner#n");
 	end;
 OnStart:
-	killmonster "1@pump",instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnMyMobDead";
-	disablenpc instance_npcname("Missing, the Cleaner#n", instance_id());
+	killmonster instance_mapname("1@pump"),instance_npcname("Missing, the Cleaner#n")+"::OnMyMobDead";
+	disablenpc instance_npcname("Missing, the Cleaner#n");
 	initnpctimer;
 	end;
 OnAddSeaweed:
-	areamonster "1@pump",55,99,61,105,"Contaminated Seaweed",2191,1,instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnMyMobDead";
-	set .@mob_dead_num, mobcount("1@pump",instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnMyMobDead");
+	set .@map$, instance_mapname("1@pump");
+	areamonster .@map$,55,99,61,105,"Contaminated Seaweed",2191,1,instance_npcname("Missing, the Cleaner#n")+"::OnMyMobDead";
+	set .@mob_dead_num, mobcount(.@map$,instance_npcname("Missing, the Cleaner#n")+"::OnMyMobDead");
 	if (.@mob_dead_num >= 6)
-		donpcevent instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnFail";
+		donpcevent instance_npcname("Missing, the Cleaner#n")+"::OnFail";
 	else
-		instance_announce 0,"Contaminated Seaweed: "+.@mob_dead_num+" stem",bc_map,"0xff3333",FW_NORMAL,20;
+		mapannounce .@map$,"Contaminated Seaweed: "+.@mob_dead_num+" stem",bc_map,"0xff3333",FW_NORMAL,20;
 	end;
 OnMyMobDead:
 	end;
 OnFail:
 	stopnpctimer;
-	donpcevent instance_npcname("Monster Hole#n", instance_id())+"::OnClear";
-	killmonster "1@pump",instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnMyMobDead";
-	enablenpc instance_npcname("Missing, the Cleaner#nf", instance_id());
-	instance_announce 0,"What is this!! Seaweed is all over the culverts! You're done with cleaning! Get out!!",bc_map,"0xff88ff",FW_NORMAL,15;
-	disablenpc instance_npcname("Missing, the Cleaner#n", instance_id());
+	donpcevent instance_npcname("Monster Hole#n")+"::OnClear";
+	set .@map$, instance_mapname("1@pump");
+	killmonster .@map$,instance_npcname("Missing, the Cleaner#n")+"::OnMyMobDead";
+	enablenpc instance_npcname("Missing, the Cleaner#nf");
+	mapannounce .@map$,"What is this!! Seaweed is all over the culverts! You're done with cleaning! Get out!!",bc_map,"0xff88ff",FW_NORMAL,15;
+	disablenpc instance_npcname("Missing, the Cleaner#n");
 	end;
 OnTimer100:
-	instance_announce 0,"First culvert will be opened in 5 sec. Cleaner can find the opened drain and click to start cleaning.",bc_map,"0x00ffcc",FW_NORMAL,15;
+	mapannounce instance_mapname("1@pump"),"First culvert will be opened in 5 sec. Cleaner can find the opened drain and click to start cleaning.",bc_map,"0x00ffcc",FW_NORMAL,15;
 	end;
 OnTimer5500:
-	instance_announce 0,"The one who's in charge of cleaning the culvert cannot move or be attacked until the casting is over.",bc_map,"0x00ffcc",FW_NORMAL,15;
-	donpcevent instance_npcname("Monster Hole#n", instance_id())+"::OnSpawn";
+	mapannounce instance_mapname("1@pump"),"The one who's in charge of cleaning the culvert cannot move or be attacked until the casting is over.",bc_map,"0x00ffcc",FW_NORMAL,15;
+	donpcevent instance_npcname("Monster Hole#n")+"::OnSpawn";
 	end;
 OnTimer45000:
 OnTimer95000:
@@ -698,12 +653,12 @@ OnTimer295000:
 OnTimer345000:
 OnTimer395000:
 OnTimer445000:
-	instance_announce 0,"Next culvert will be opened in 5 sec. Please hurry up and find the position of the next culvert.",bc_map,"0x00ffcc",FW_NORMAL,15;
+	mapannounce instance_mapname("1@pump"),"Next culvert will be opened in 5 sec. Please hurry up and find the position of the next culvert.",bc_map,"0x00ffcc",FW_NORMAL,15;
 	end;
 OnTimer50000:
 OnTimer100000:
 OnTimer150000:
-	donpcevent instance_npcname("Monster Hole#n", instance_id())+"::OnSpawn";
+	donpcevent instance_npcname("Monster Hole#n")+"::OnSpawn";
 	end;
 OnTimer200000:
 OnTimer250000:
@@ -711,38 +666,36 @@ OnTimer300000:
 OnTimer350000:
 OnTimer400000:
 OnTimer450000:
-	set .@mob_dead_num, mobcount("1@pump",instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnMyMobDead");
+	set .@mob_dead_num, mobcount(instance_mapname("1@pump"),instance_npcname("Missing, the Cleaner#n")+"::OnMyMobDead");
 	if (.@mob_dead_num >= 6)
-		donpcevent instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnFail";
+		donpcevent instance_npcname("Missing, the Cleaner#n")+"::OnFail";
 	else
-		donpcevent instance_npcname("Monster Hole#n", instance_id())+"::OnSpawn";
+		donpcevent instance_npcname("Monster Hole#n")+"::OnSpawn";
 	end;
 OnTimer515000:
-	set .@mob_dead_num, mobcount("1@pump",instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnMyMobDead");
-	instance_announce 0,"Contaminated Seaweed: "+.@mob_dead_num+" stem. Missing will come and inspect the results of the cleaning soon.",bc_map,"0xff3333",FW_NORMAL,20;
+	set .@map$, instance_mapname("1@pump");
+	set .@mob_dead_num, mobcount(.@map$,instance_npcname("Missing, the Cleaner#n")+"::OnMyMobDead");
+	mapannounce .@map$,"Contaminated Seaweed: "+.@mob_dead_num+" stem. Missing will come and inspect the results of the cleaning soon.",bc_map,"0xff3333",FW_NORMAL,20;
 	end;
 OnTimer520000:
 	stopnpctimer;
-	set .@mob_dead_num, mobcount("1@pump",instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnMyMobDead");
+	set .@mob_dead_num, mobcount(instance_mapname("1@pump"),instance_npcname("Missing, the Cleaner#n")+"::OnMyMobDead");
 	if (.@mob_dead_num >= 6)
-		donpcevent instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnFail";
+		donpcevent instance_npcname("Missing, the Cleaner#n")+"::OnFail";
 	else
-		donpcevent instance_npcname("Boss Creation#n", instance_id())+"::OnEnable";
+		donpcevent instance_npcname("Boss Creation#n")+"::OnEnable";
 	end;
 }
 
 1@pump,1,1,4	script	Monster Hole#n	-1,{
 	end;
-OnInstanceInit:
-	enablenpc instance_npcname(strnpcinfo(0), instance_id());
-	end;
 OnSpawn:
 	set .@i$, charat(strnpcinfo(2),0);
 	if (.@i$ == "n")
 		set .@n,6;
 	else if (.@i$ == "h")
 		set .@n,10;
-	donpcevent instance_npcname("#Culvert_"+.@i$+rand(1,.@n), instance_id())+"::OnEnable";
+	donpcevent instance_npcname("#Culvert_"+.@i$+rand(1,.@n))+"::OnEnable";
 	end;
 OnClear:
 	set .@i$, charat(strnpcinfo(2),0);
@@ -751,21 +704,22 @@ OnClear:
 	else if (.@i$ == "h")
 		set .@n,10;
 	for(set .@i,1; .@i<=.@n; set .@i,.@i+1)
-		donpcevent instance_npcname("#Culvert_"+.@i$+.@n, instance_id())+"::OnClear";
+		donpcevent instance_npcname("#Culvert_"+.@i$+.@n)+"::OnClear";
 	end;
 }
 
-1@pump,36,111,4	script	#Culvert_n1	844,{
+1@pump,36,111,4	script	#Culvert_n1	844,14,14,{ //temporary workaround for ALL_SAMEMAP
 	progressbar "0xFFFF00",10;
 	stopnpctimer;
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	disablenpc instance_npcname(strnpcinfo(0));
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	disablenpc instance_npcname(strnpcinfo(0));
 	end;
 OnEnable:
-	enablenpc instance_npcname(strnpcinfo(0), instance_id());
-	set .@label$, instance_npcname(strnpcinfo(0), instance_id())+"::OnMyMobDead";
+	enablenpc instance_npcname(strnpcinfo(0));
+	set .@label$, instance_npcname(strnpcinfo(0))+"::OnMyMobDead";
+	set .@map$, instance_mapname("1@pump");
 	set .@index, atoi(charat(strnpcinfo(2),9));
 	switch(.@index) {
 		case 1: setarray .@c[0],32,107,40,115; break;
@@ -775,12 +729,12 @@ OnEnable:
 		case 5: setarray .@c[0],71,76,79,84; break;
 		case 6: setarray .@c[0],54,97,62,105; break;
 	}
-	areamonster "1@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Abysmal Crab",2176,rand(1,3),.@label$;
-	areamonster "1@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Abysmal Marse",2175,rand(1,3),.@label$;
-	areamonster "1@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Ancient Vadon",2174,rand(1,3),.@label$;
-	areamonster "1@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Abysmal Shellfish",2178,rand(1,3),.@label$;
-	areamonster "1@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Ancient Kukre",2179,rand(1,3),.@label$;
-	areamonster "1@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Abysmal Cornutus",2177,rand(1,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Abysmal Crab",2176,rand(1,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Abysmal Marse",2175,rand(1,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Ancient Vadon",2174,rand(1,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Abysmal Shellfish",2178,rand(1,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Ancient Kukre",2179,rand(1,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Abysmal Cornutus",2177,rand(1,3),.@label$;
 	specialeffect EF_MAPPILLAR2,ALL_SAMEMAP; //currently broken
 	getmapxy(.@map$,.@x,.@y,1);
 	getpartymember 'party_id,2;
@@ -798,67 +752,70 @@ OnMyMobDead:
 	end;
 OnClear:
 	stopnpctimer;
-	killmonster "1@pump",instance_npcname(strnpcinfo(0), instance_id())+"::OnMyMobDead";
+	killmonster instance_mapname("1@pump"),instance_npcname(strnpcinfo(0))+"::OnMyMobDead";
 	end;
 OnTimer49500:	//OnTimer50000 clashes with the timer in "Missing, the Cleaner#h".
-	donpcevent instance_npcname("Missing, the Cleaner#n", instance_id())+"::OnAddSeaweed";
-	donpcevent instance_npcname(strnpcinfo(0), instance_id())+"::OnClear";
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	donpcevent instance_npcname("Missing, the Cleaner#n")+"::OnAddSeaweed";
+	donpcevent instance_npcname(strnpcinfo(0))+"::OnClear";
+	disablenpc instance_npcname(strnpcinfo(0));
+	end;
+OnTouch:
+	specialeffect EF_MAPPILLAR2;
 	end;
 }
-1@pump,68,124,4	duplicate(#Culvert_n1)	#Culvert_n2	844
-1@pump,80,114,4	duplicate(#Culvert_n1)	#Culvert_n3	844
-1@pump,40,80,4	duplicate(#Culvert_n1)	#Culvert_n4	844
-1@pump,75,80,4	duplicate(#Culvert_n1)	#Culvert_n5	844
-1@pump,58,101,4	duplicate(#Culvert_n1)	#Culvert_n6	844
+1@pump,68,124,4	duplicate(#Culvert_n1)	#Culvert_n2	844,14,14
+1@pump,80,114,4	duplicate(#Culvert_n1)	#Culvert_n3	844,14,14
+1@pump,40,80,4	duplicate(#Culvert_n1)	#Culvert_n4	844,14,14
+1@pump,75,80,4	duplicate(#Culvert_n1)	#Culvert_n5	844,14,14
+1@pump,58,101,4	duplicate(#Culvert_n1)	#Culvert_n6	844,14,14
 
 1@pump,1,1,4	script	Boss Creation#n	-1,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	disablenpc instance_npcname(strnpcinfo(0));
 	end;
 OnEnable:
-	enablenpc instance_npcname(strnpcinfo(0), instance_id());
+	enablenpc instance_npcname(strnpcinfo(0));
 	initnpctimer;
 	end;
 OnTimer100:
 	set .@i$, charat(strnpcinfo(2),0);
 	if (.@i$ == "n")
-		instance_announce 0,"Hmm! That wasn't so bad!",bc_map,"0xff88ff",FW_NORMAL,15;
+		mapannounce instance_mapname("1@pump"),"Hmm! That wasn't so bad!",bc_map,"0xff88ff",FW_NORMAL,15;
 	else if (.@i$ == "h")
-		instance_announce 0,"Hmm! You guys are pretty good!!",bc_map,"0xff88ff",FW_NORMAL,15;
+		mapannounce instance_mapname("2@pump"),"Hmm! You guys are pretty good!!",bc_map,"0xff88ff",FW_NORMAL,15;
 	end;
 OnTimer5000:
-	instance_announce 0,"Let's pack up and go... WHAT!!?",bc_map,"0xff88ff",FW_NORMAL,15;
+	mapannounce strnpcinfo(4),"Let's pack up and go... WHAT!!?",bc_map,"0xff88ff",FW_NORMAL,15;
 	end;
 OnTimer10000:
-	instance_announce 0,"I sense something strange!! Don't loosen up-- prepare for a fight!!",bc_map,"0xff88ff",FW_NORMAL,15;
+	mapannounce strnpcinfo(4),"I sense something strange!! Don't loosen up-- prepare for a fight!!",bc_map,"0xff88ff",FW_NORMAL,15;
 	end;
 OnTimer20000:
 	stopnpctimer;
 	set .@i$, charat(strnpcinfo(2),0);
-	set .@label$, instance_npcname(strnpcinfo(0), instance_id())+"::OnMyMobDead";
+	set .@label$, instance_npcname(strnpcinfo(0))+"::OnMyMobDead";
 	if (rand(1,100) > 50) {
 		if (.@i$ == "n")
-			monster "1@pump",0,0,"Weird Coelacanth",2188,1,.@label$;
+			monster instance_mapname("1@pump"),0,0,"Weird Coelacanth",2188,1,.@label$;
 		else if (.@i$ == "h")
-			monster "2@pump",0,0,"Mutant Coelacanth",2189,1,.@label$;
-		instance_announce 0,"Something big inside the abyss appears with a huge noise.",bc_map,"0x00ffcc",FW_NORMAL,15;
+			monster instance_mapname("2@pump"),0,0,"Mutant Coelacanth",2189,1,.@label$;
+		mapannounce strnpcinfo(4),"Something big inside the abyss appears with a huge noise.",bc_map,"0x00ffcc",FW_NORMAL,15;
 	} else {
 		if (.@i$ == "n")
-			monster "1@pump",0,0,"Gloomy Coelacanth",2187,1,.@label$;
+			monster instance_mapname("1@pump"),0,0,"Gloomy Coelacanth",2187,1,.@label$;
 		else if (.@i$ == "h")
-			monster "2@pump",0,0,"Violent Coelacanth",2190,1,.@label$;
-		instance_announce 0,"Something savage inside the abyss appears with a huge noise.",bc_map,"0x00ffcc",FW_NORMAL,15;
+			monster instance_mapname("2@pump"),0,0,"Violent Coelacanth",2190,1,.@label$;
+		mapannounce strnpcinfo(4),"Something savage inside the abyss appears with a huge noise.",bc_map,"0x00ffcc",FW_NORMAL,15;
 	}
 	end;
 OnMyMobDead:
-	if (mobcount(strnpcinfo(4),instance_npcname(strnpcinfo(0), instance_id())+"::OnMyMobDead") < 1) {
-		instance_announce 0,"You've destroyed all monsters in the culverts. There are trophies lying on the ground, please look for them.",bc_map,"0xffff00",FW_NORMAL,15;
+	if (mobcount(strnpcinfo(4),instance_npcname(strnpcinfo(0))+"::OnMyMobDead") < 1) {
+		mapannounce strnpcinfo(4),"You've destroyed all monsters in the culverts. There are trophies lying on the ground, please look for them.",bc_map,"0xffff00",FW_NORMAL,15;
 		set .@i$, charat(strnpcinfo(2),0);
 		set .@map$, strnpcinfo(4);
-		enablenpc instance_npcname("Culvert Entrance#"+.@i$, instance_id());
-		enablenpc instance_npcname("Missing, the Cleaner#"+.@i$+"o", instance_id());
+		enablenpc instance_npcname("Culvert Entrance#"+.@i$);
+		enablenpc instance_npcname("Missing, the Cleaner#"+.@i$+"o");
 		if (.@i$ == "n") {
 			for(set .@i,0; .@i<10; set .@i,.@i+1) {
 				set .@j, rand(1,6401);
@@ -883,7 +840,7 @@ OnMyMobDead:
 			}
 		}
 	} else
-		instance_announce 0,"There are still monsters alive.",bc_map,"0x00ff99",FW_NORMAL,20;
+		mapannounce strnpcinfo(4),"There are still monsters alive.",bc_map,"0x00ff99",FW_NORMAL,20;
 	end;
 }
 
@@ -917,14 +874,14 @@ OnMyMobDead:
 	mes "If Tomas closes this down, we will lose our jobs!";
 	close;
 OnInstanceInit:
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	disablenpc instance_npcname(strnpcinfo(0));
 	end;
 }
 
 1@pump,32,100,0	script	Culvert Entrance#n	45,3,3,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	disablenpc instance_npcname(strnpcinfo(0));
 	end;
 OnTouch:
 	warp "mal_in01",161,32;
@@ -944,40 +901,39 @@ OnInstanceInit:
 
 2@pump,39,88,4	script	Missing, the Cleaner#h	545,{
 	callfunc "F_mal_missing";
-	donpcevent instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnStart";
+	donpcevent instance_npcname("Missing, the Cleaner#h")+"::OnStart";
 	close;
-OnInstanceInit:
-	enablenpc instance_npcname("Missing, the Cleaner#h", instance_id());
-	end;
 OnStart:
-	killmonster "2@pump",instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnMyMobDead";
-	disablenpc instance_npcname("Missing, the Cleaner#h", instance_id());
+	killmonster instance_mapname("2@pump"),instance_npcname("Missing, the Cleaner#h")+"::OnMyMobDead";
+	disablenpc instance_npcname("Missing, the Cleaner#h");
 	initnpctimer;
 	end;
 OnAddSeaweed:
-	areamonster "2@pump",75,78,85,88,"Contaminated Seaweed",2191,1,instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnMyMobDead";
-	set .@mob_dead_num, mobcount("2@pump",instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnMyMobDead");
+	set .@map$, instance_mapname("2@pump");
+	areamonster .@map$,75,78,85,88,"Contaminated Seaweed",2191,1,instance_npcname("Missing, the Cleaner#h")+"::OnMyMobDead";
+	set .@mob_dead_num, mobcount(.@map$,instance_npcname("Missing, the Cleaner#h")+"::OnMyMobDead");
 	if (.@mob_dead_num >= 6)
-		donpcevent instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnFail";
+		donpcevent instance_npcname("Missing, the Cleaner#h")+"::OnFail";
 	else
-		instance_announce 0,"Proliferous Contaminated Seaweed: "+.@mob_dead_num+" stem",bc_map,"0xff3333",FW_NORMAL,20;
+		mapannounce .@map$,"Proliferous Contaminated Seaweed: "+.@mob_dead_num+" stem",bc_map,"0xff3333",FW_NORMAL,20;
 	end;
 OnMyMobDead:
 	end;
 OnFail:
 	stopnpctimer;
-	donpcevent instance_npcname("Monster Hole#h", instance_id())+"::OnClear";
-	killmonster "2@pump",instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnMyMobDead";
-	enablenpc instance_npcname("Missing, the Cleaner#hf", instance_id());
-	instance_announce 0,"What is this!! Seaweed is all over the culverts! You're done with cleaning! Get out!!",bc_map,"0xff88ff",FW_NORMAL,15;
-	disablenpc instance_npcname("Missing, the Cleaner#h", instance_id());
+	donpcevent instance_npcname("Monster Hole#h")+"::OnClear";
+	set .@map$, instance_mapname("2@pump");
+	killmonster .@map$, instance_npcname("Missing, the Cleaner#h")+"::OnMyMobDead";
+	enablenpc instance_npcname("Missing, the Cleaner#hf");
+	mapannounce .@map$,"What is this!! Seaweed is all over the culverts! You're done with cleaning! Get out!!",bc_map,"0xff88ff",FW_NORMAL,15;
+	disablenpc instance_npcname("Missing, the Cleaner#h");
 	end;
 OnTimer100:
-	instance_announce 0,"First culvert will be opened in 5 sec. Cleaner can find the opened drain and click to start cleaning.",bc_map,"0x00ffcc",FW_NORMAL,15;
+	mapannounce instance_mapname("2@pump"),"First culvert will be opened in 5 sec. Cleaner can find the opened drain and click to start cleaning.",bc_map,"0x00ffcc",FW_NORMAL,15;
 	end;
 OnTimer5500:
-	instance_announce 0,"The one who's in charge of cleaning the culvert cannot move or be attacked until the casting is over.",bc_map,"0x00ffcc",FW_NORMAL,15;
-	donpcevent instance_npcname("Monster Hole#h", instance_id())+"::OnSpawn";
+	mapannounce instance_mapname("2@pump"),"The one who's in charge of cleaning the culvert cannot move or be attacked until the casting is over.",bc_map,"0x00ffcc",FW_NORMAL,15;
+	donpcevent instance_npcname("Monster Hole#h")+"::OnSpawn";
 	end;
 OnTimer35000:
 OnTimer75000:
@@ -988,12 +944,12 @@ OnTimer235000:
 OnTimer275000:
 OnTimer315000:
 OnTimer355000:
-	instance_announce 0,"Next culvert will be opened in 5 sec. Please hurry up and find the position of the next culvert.",bc_map,"0x00ffcc",FW_NORMAL,15;
+	mapannounce instance_mapname("2@pump"),"Next culvert will be opened in 5 sec. Please hurry up and find the position of the next culvert.",bc_map,"0x00ffcc",FW_NORMAL,15;
 	end;
 OnTimer40000:
 OnTimer80000:
 OnTimer120000:
-	donpcevent instance_npcname("Monster Hole#h", instance_id())+"::OnSpawn";
+	donpcevent instance_npcname("Monster Hole#h")+"::OnSpawn";
 	end;
 OnTimer160000:
 OnTimer200000:
@@ -1001,36 +957,37 @@ OnTimer240000:
 OnTimer280000:
 OnTimer320000:
 OnTimer360000:
-	set .@mob_dead_num, mobcount("2@pump",instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnMyMobDead");
+	set .@mob_dead_num, mobcount(instance_mapname("2@pump"),instance_npcname("Missing, the Cleaner#h")+"::OnMyMobDead");
 	if (.@mob_dead_num >= 6)
-		donpcevent instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnFail";
+		donpcevent instance_npcname("Missing, the Cleaner#h")+"::OnFail";
 	else
-		donpcevent instance_npcname("Monster Hole#h", instance_id())+"::OnSpawn";
+		donpcevent instance_npcname("Monster Hole#h")+"::OnSpawn";
 	end;
 OnTimer420000:
-	instance_announce 0,"It seems Missing will come and inspect the results of the cleaning soon. Shall we clean up the mess around here?",bc_map,"0xff3333",FW_NORMAL,20;
+	mapannounce instance_mapname("2@pump"),"It seems Missing will come and inspect the results of the cleaning soon. Shall we clean up the mess around here?",bc_map,"0xff3333",FW_NORMAL,20;
 	end;
 OnTimer425000:
 	stopnpctimer;
-	set .@mob_dead_num, mobcount("2@pump",instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnMyMobDead");
+	set .@mob_dead_num, mobcount(instance_mapname("2@pump"),instance_npcname("Missing, the Cleaner#h")+"::OnMyMobDead");
 	if (.@mob_dead_num >= 6)
-		donpcevent instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnFail";
+		donpcevent instance_npcname("Missing, the Cleaner#h")+"::OnFail";
 	else
-		donpcevent instance_npcname("Boss Creation#h", instance_id())+"::OnEnable";
+		donpcevent instance_npcname("Boss Creation#h")+"::OnEnable";
 	end;
 }
 
-2@pump,53,114,4	script	#Culvert_h1	844,{
+2@pump,53,114,4	script	#Culvert_h1	844,14,14,{ //temporary workaround for ALL_SAMEMAP
 	progressbar "0xFFFF00",15;
 	stopnpctimer;
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	disablenpc instance_npcname(strnpcinfo(0));
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	disablenpc instance_npcname(strnpcinfo(0));
 	end;
 OnEnable:
-	enablenpc instance_npcname(strnpcinfo(0), instance_id());
-	set .@label$, instance_npcname(strnpcinfo(0), instance_id())+"::OnMyMobDead";
+	enablenpc instance_npcname(strnpcinfo(0));
+	set .@label$, instance_npcname(strnpcinfo(0))+"::OnMyMobDead";
+	set .@map$, instance_mapname("2@pump");
 	set .@index, atoi(substr(strnpcinfo(2),9,getstrlen(strnpcinfo(2))-1));
 	switch(.@index) {
 		case 1: setarray .@c[0],49,110,57,118; break;
@@ -1044,12 +1001,12 @@ OnEnable:
 		case 9: setarray .@c[0],96,70,104,78; break;
 		case 10: setarray .@c[0],111,46,119,54; break;
 	}
-	areamonster "2@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Ancient Marc",2182,rand(2,3),.@label$;
-	areamonster "2@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Ancient Sword Fish",2181,rand(2,3),.@label$;
-	areamonster "2@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Ancient Strouf",2180,rand(2,3),.@label$;
-	areamonster "2@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Mutant Anolian",2183,rand(2,3),.@label$;
-	areamonster "2@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Abysmal Obeaune",2184,rand(2,3),.@label$;
-	areamonster "2@pump",.@c[0],.@c[1],.@c[2],.@c[3],"Metamorphous Kapha",2185,rand(2,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Ancient Marc",2182,rand(2,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Ancient Sword Fish",2181,rand(2,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Ancient Strouf",2180,rand(2,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Mutant Anolian",2183,rand(2,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Abysmal Obeaune",2184,rand(2,3),.@label$;
+	areamonster .@map$,.@c[0],.@c[1],.@c[2],.@c[3],"Metamorphous Kapha",2185,rand(2,3),.@label$;
 	specialeffect EF_MAPPILLAR2,ALL_SAMEMAP; //currently broken
 	initnpctimer;
 	end;
@@ -1057,23 +1014,26 @@ OnMyMobDead:
 	end;
 OnClear:
 	stopnpctimer;
-	killmonster "2@pump",instance_npcname(strnpcinfo(0), instance_id())+"::OnMyMobDead";
+	killmonster instance_mapname("2@pump"),instance_npcname(strnpcinfo(0))+"::OnMyMobDead";
 	end;
 OnTimer39500:	//OnTimer40000 clashes with the timer in "Missing, the Cleaner#h".
-	donpcevent instance_npcname("Missing, the Cleaner#h", instance_id())+"::OnAddSeaweed";
-	donpcevent instance_npcname(strnpcinfo(0), instance_id())+"::OnClear";
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	donpcevent instance_npcname("Missing, the Cleaner#h")+"::OnAddSeaweed";
+	donpcevent instance_npcname(strnpcinfo(0))+"::OnClear";
+	disablenpc instance_npcname(strnpcinfo(0));
+	end;
+OnTouch:
+	specialeffect EF_MAPPILLAR2;
 	end;
 }
-2@pump,79,109,4	duplicate(#Culvert_h1)	#Culvert_h2	844
-2@pump,114,114,4	duplicate(#Culvert_h1)	#Culvert_h3	844
-2@pump,98,98,4	duplicate(#Culvert_h1)	#Culvert_h4	844
-2@pump,62,96,4	duplicate(#Culvert_h1)	#Culvert_h5	844
-2@pump,57,70,4	duplicate(#Culvert_h1)	#Culvert_h6	844
-2@pump,47,49,4	duplicate(#Culvert_h1)	#Culvert_h7	844
-2@pump,81,63,4	duplicate(#Culvert_h1)	#Culvert_h8	844
-2@pump,100,74,4	duplicate(#Culvert_h1)	#Culvert_h9	844
-2@pump,115,50,4	duplicate(#Culvert_h1)	#Culvert_h10	844
+2@pump,79,109,4	duplicate(#Culvert_h1)	#Culvert_h2	844,14,14
+2@pump,114,114,4	duplicate(#Culvert_h1)	#Culvert_h3	844,14,14
+2@pump,98,98,4	duplicate(#Culvert_h1)	#Culvert_h4	844,14,14
+2@pump,62,96,4	duplicate(#Culvert_h1)	#Culvert_h5	844,14,14
+2@pump,57,70,4	duplicate(#Culvert_h1)	#Culvert_h6	844,14,14
+2@pump,47,49,4	duplicate(#Culvert_h1)	#Culvert_h7	844,14,14
+2@pump,81,63,4	duplicate(#Culvert_h1)	#Culvert_h8	844,14,14
+2@pump,100,74,4	duplicate(#Culvert_h1)	#Culvert_h9	844,14,14
+2@pump,115,50,4	duplicate(#Culvert_h1)	#Culvert_h10	844,14,14
 
 2@pump,1,1,4	duplicate(Monster Hole#n)	Monster Hole#h	-1
 2@pump,1,1,4	duplicate(Boss Creation#n)	Boss Creation#h	-1
@@ -1081,4 +1041,4 @@ OnTimer39500:	//OnTimer40000 clashes with the timer in "Missing, the Cleaner#h".
 2@pump,38,100,0	duplicate(Culvert Entrance#n)	Culvert Entrance#h	45,3,3
 
 //MD_Putmob "2@pump" 0 0 0 0 20 HYDRA 0 0 2
-2@pump,1,1,4	duplicate(Hydra#n)	Hydra#h	-1
+2@pump,1,1,4	duplicate(Hydra#n)	Hydra#h	-1

+ 266 - 278
npc/re/instances/OctopusCave.txt

@@ -3,7 +3,7 @@
 //===== By: ================================================== 
 //= Muad_Dib
 //===== Current Version: ===================================== 
-//= 1.0
+//= 1.1
 //===== Compatible With: ===================================== 
 //= rAthena SVN
 //===== Description: ========================================= 
@@ -11,6 +11,7 @@
 //= Defeat the Disgusting Octopus.
 //===== Additional Comments: ================================= 
 //= 1.0 First version. [Euphy]
+//= 1.1 Instance system rewrite. [Euphy]
 //============================================================ 
 
 // Instance Creation
@@ -39,7 +40,7 @@ mal_dun01,151,235,5	script	Starfish	551,{
 	mes "It is just roughly blocked for now.";
 	mes "But someday this cave must be sealed forever, hehe!";
 	next;
-	while (1) {
+	while(1) {
 		switch(select("Ask what's going on.:Ask to open the gate.:Go to other location.")) {
 		case 1:
 			mes "[Starfish]";
@@ -83,8 +84,7 @@ mal_dun01,151,235,5	script	Starfish	551,{
 			}
 			if (.@playtime == 2) erasequest 4197;
 			if (countitem(6442)) {
-				set .@instance, instance_create(.@md_name$,.@party_id);
-				if (.@instance < 0) {
+				if (instance_create(.@md_name$) < 0) {
 					mes "[Starfish]";
 					mes "Party name is... "+getpartyname(.@party_id)+".";
 					mes "Party leader is... "+strcharinfo(0)+".";
@@ -92,37 +92,6 @@ mal_dun01,151,235,5	script	Starfish	551,{
 					mes "Now is not the time, please wait.";
 					close;
 				}
-				if (instance_attachmap("1@cash",.@instance) == "") {
-					mes "^0000ff"+.@md_name$+"^000000 - Reservation Failed!";
-					instance_destroy(.@instance);
-					close;
-				}
-				instance_attach(.@instance);
-				instance_set_timeout 3600,300,.@instance;
-				instance_init(.@instance);
-
-				donpcevent instance_npcname("oct_enter", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_enter_broad", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_foot_4", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_foot1", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_foot_exit1", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_foot2", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_foot_exit2", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_foot3", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_foot_exit3", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_foot4", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_foot_exit4", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_mob_con", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_backattack1", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_backattack2", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_backattack3", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_backattack4", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_boss_con", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_boss_foot", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_boss_warp", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_exit_1", instance_id())+"::OnInstanceInit";
-				donpcevent instance_npcname("oct_exit_2", instance_id())+"::OnInstanceInit";
-
 				mes "[Starfish]";
 				mes "I will open the gate for a while to ^0000ff"+.@md_name$+"^000000.";
 				mes "Please catch that pervert octopus,";
@@ -150,24 +119,30 @@ mal_dun01,153,237,5	script	Weird Entrance	844,{
 	switch(select("Go in.:Stop.")) {
 	case 1:
 		if (countitem(6442)) {
-			// TODO: Add official MD_Enter cases.
-			if (has_instance("1@cash") == "") {
-				if (checkquest(4197,PLAYTIME) == 0 || checkquest(4197,PLAYTIME) == 1) {
-					mes "[Starfish]";
-					mes "Ah, now is not the time...";
-					mes "Would you come back later? Hehe.";
-					close;
-				}
+			switch(instance_enter("Octopus Cave")) {
+			case 3:
+				mes "[Starfish]";
+				mes "Ah, now is not the time...";
+				mes "Would you come back later? Hehe.";
+				close;
+			case 2:
+			case 1:
+				mes "[Starfish]";
+				mes "There is a secret with that entrance.";
+				mes "So, please be careful with it, will ya? Hehe.";
+				close;
+			case 0:
+				mapannounce "mal_dun01", getpartyname(getcharid(1))+" party's "+strcharinfo(0)+" member started to hunt the Octopus!",bc_map,"0x00ff99";
+				if (checkquest(4197) == -1) setquest 4197;
+				//warp "1@cash",199,99;
+				close;
+			default:
 				mes "[Starfish]";
 				mes "Shhh... Weird aura is";
 				mes "coming from that entrance.";
 				mes "Big trouble is waiting, if you go in now.";
 				close;
 			}
-			mapannounce "mal_dun01", getpartyname(getcharid(1))+" party's "+strcharinfo(0)+" member started to hunt the Octopus!",bc_map,"0x00ff99";
-			if (checkquest(4197) == -1) setquest 4197;
-			warp "1@cash",199,99;
-			close;
 		}
 		mes "[Starfish]";
 		mes "You should definitely prepare";
@@ -186,169 +161,170 @@ mal_dun01,153,237,5	script	Weird Entrance	844,{
 //============================================================
 1@cash,199,99,0	script	oct_enter	139,4,4,{
 	end;
-OnInstanceInit:
-	enablenpc instance_npcname("oct_enter", instance_id());
-	end;
 OnTouch:
-	donpcevent instance_npcname("oct_enter_broad", instance_id())+"::OnEnable";
+	donpcevent instance_npcname("oct_enter_broad")+"::OnEnable";
 	specialeffect EF_BASH;
-	disablenpc instance_npcname("oct_enter", instance_id());
+	disablenpc instance_npcname("oct_enter");
 	end;
 }
 
 1@cash,1,1,0	script	oct_enter_broad	-1,{
 	end;
 OnInstanceInit:
-	donpcevent instance_npcname("oct_enter_broad", instance_id())+"::OnDisable";
+	donpcevent instance_npcname("oct_enter_broad")+"::OnDisable";
 	end;
 OnEnable:
-	enablenpc instance_npcname("oct_enter_broad", instance_id());
-	donpcevent instance_npcname("oct_foot_4", instance_id())+"::OnEnable";
-	donpcevent instance_npcname("oct_mob_con", instance_id())+"::OnEnable";
+	enablenpc instance_npcname("oct_enter_broad");
+	donpcevent instance_npcname("oct_foot_4")+"::OnEnable";
+	donpcevent instance_npcname("oct_mob_con")+"::OnEnable";
 	initnpctimer;
 	end;
 OnDisable:
-	disablenpc instance_npcname("oct_enter_broad", instance_id());
+	disablenpc instance_npcname("oct_enter_broad");
 	end;
 OnTimer1000:
-	instance_announce 0,"Pervert Octopus : How dare you to come inside of my place!",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("1@cash"),"Pervert Octopus : How dare you to come inside of my place!",bc_map,"0xFFFF00";
 	end;
 OnTimer4000:
-	instance_announce 0,"Pervert Octopus : But I blocked all the cave gates!! There is nothing you can do!",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("1@cash"),"Pervert Octopus : But I blocked all the cave gates!! There is nothing you can do!",bc_map,"0xFFFF00";
 	end;
 OnTimer7000:
-	instance_announce 0,"Pervert Octopus : My juniors~ There is your toy! Play with it~ kakaka",bc_map,"0xFFFF00";
+	mapannounce instance_mapname("1@cash"),"Pervert Octopus : My juniors~ There is your toy! Play with it~ kakaka",bc_map,"0xFFFF00";
 	stopnpctimer;
-	donpcevent instance_npcname("oct_enter_broad", instance_id())+"::OnDisable";
+	donpcevent instance_npcname("oct_enter_broad")+"::OnDisable";
 	end;
 }
 
 1@cash,3,3,0	script	oct_foot_4	-1,{
 	end;
 OnInstanceInit:
-	donpcevent instance_npcname("oct_foot_4", instance_id())+"::OnDisable";
+	donpcevent instance_npcname("oct_foot_4")+"::OnDisable";
 	end;
 OnEnable:
-	enablenpc instance_npcname("oct_foot_4", instance_id());
-	donpcevent instance_npcname("oct_foot1", instance_id())+"::OnEnable";
-	donpcevent instance_npcname("oct_foot2", instance_id())+"::OnEnable";
-	donpcevent instance_npcname("oct_foot3", instance_id())+"::OnEnable";
-	donpcevent instance_npcname("oct_foot4", instance_id())+"::OnEnable";
-	monster "1@cash",20,114,"Octopus Leg#1",2193,1,instance_npcname("oct_foot_4", instance_id())+"::OnMyMobDead";
-	monster "1@cash",88,190,"Octopus Leg#2",2193,1,instance_npcname("oct_foot_4", instance_id())+"::OnMyMobDead";
-	monster "1@cash",307,215,"Octopus Leg#3",2193,1,instance_npcname("oct_foot_4", instance_id())+"::OnMyMobDead";
-	monster "1@cash",372,131,"Octopus Leg#4",2193,1,instance_npcname("oct_foot_4", instance_id())+"::OnMyMobDead";
+	enablenpc instance_npcname("oct_foot_4");
+	donpcevent instance_npcname("oct_foot1")+"::OnEnable";
+	donpcevent instance_npcname("oct_foot2")+"::OnEnable";
+	donpcevent instance_npcname("oct_foot3")+"::OnEnable";
+	donpcevent instance_npcname("oct_foot4")+"::OnEnable";
+	set .@map$, instance_mapname("1@cash");
+	monster .@map$,20,114,"Octopus Leg#1",2193,1,instance_npcname("oct_foot_4")+"::OnMyMobDead";
+	monster .@map$,88,190,"Octopus Leg#2",2193,1,instance_npcname("oct_foot_4")+"::OnMyMobDead";
+	monster .@map$,307,215,"Octopus Leg#3",2193,1,instance_npcname("oct_foot_4")+"::OnMyMobDead";
+	monster .@map$,372,131,"Octopus Leg#4",2193,1,instance_npcname("oct_foot_4")+"::OnMyMobDead";
 	end;
 OnDisable:
-	disablenpc instance_npcname("oct_foot_4", instance_id());
+	disablenpc instance_npcname("oct_foot_4");
 	end;
 OnMyMobDead:
-	if (mobcount("1@cash",instance_npcname("oct_foot_4", instance_id())+"::OnMyMobDead") < 1) {
-		donpcevent instance_npcname("oct_boss_con", instance_id())+"::OnEnable";
-		instance_announce 0,"Hey you!! I'll personally take care of you all! Let's bring it on!",bc_map,"0x00ff99";
-		enablenpc instance_npcname("oct_boss_warp", instance_id());
-		instance_warpall "1@cash",199,99;
+	set .@map$, instance_mapname("1@cash");
+	if (mobcount(.@map$,instance_npcname("oct_foot_4")+"::OnMyMobDead") < 1) {
+		donpcevent instance_npcname("oct_boss_con")+"::OnEnable";
+		mapannounce .@map$,"Hey you!! I'll personally take care of you all! Let's bring it on!",bc_map,"0x00ff99";
+		enablenpc instance_npcname("oct_boss_warp");
+		instance_warpall .@map$,199,99;
 		end;
 	}
-	instance_announce 0,"Arrgg!! That hurts!!! I need another strategy...",bc_map,"0x00ff99";
+	mapannounce .@map$,"Arrgg!! That hurts!!! I need another strategy...",bc_map,"0x00ff99";
 	end;
 }
 
 1@cash,20,114,0	script	oct_foot1	139,6,6,{
 	end;
 OnInstanceInit:
-	donpcevent instance_npcname(strnpcinfo(0), instance_id())+"::OnDisable";
+	donpcevent instance_npcname(strnpcinfo(0))+"::OnDisable";
 	end;
 OnEnable:
-	enablenpc instance_npcname(strnpcinfo(0), instance_id());
-	set .@label$, instance_npcname(strnpcinfo(0), instance_id())+"::OnMyMobDead";
+	enablenpc instance_npcname(strnpcinfo(0));
+	set .@label$, instance_npcname(strnpcinfo(0))+"::OnMyMobDead";
 	set .@i, atoi(charat(strnpcinfo(0),8));
+	set .@map$, instance_mapname("1@cash");
 	switch(.@i) {
 	case 1:
-		areamonster "1@cash",34,96,38,100,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",39,90,41,92,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",38,76,40,78,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",39,58,41,60,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",50,38,56,44,"Octopus's Henchman",2192,5,.@label$;
-		areamonster "1@cash",68,32,72,36,"Octopus's Henchman",2192,5,.@label$;
-		areamonster "1@cash",83,26,85,28,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",107,28,109,30,"Octopus's Henchman",2192,1,.@label$;
-		areamonster "1@cash",123,28,125,30,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",134,31,138,35,"Octopus's Henchman",2192,5,.@label$;
-		areamonster "1@cash",142,39,146,43,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,34,96,38,100,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,39,90,41,92,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,38,76,40,78,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,39,58,41,60,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,50,38,56,44,"Octopus's Henchman",2192,5,.@label$;
+		areamonster .@map$,68,32,72,36,"Octopus's Henchman",2192,5,.@label$;
+		areamonster .@map$,83,26,85,28,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,107,28,109,30,"Octopus's Henchman",2192,1,.@label$;
+		areamonster .@map$,123,28,125,30,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,134,31,138,35,"Octopus's Henchman",2192,5,.@label$;
+		areamonster .@map$,142,39,146,43,"Octopus's Henchman",2192,2,.@label$;
 		break;
 	case 2:
-		areamonster "1@cash",139,113,143,117,"Octopus's Henchman",2192,5,.@label$;
-		areamonster "1@cash",135,104,137,106,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",123,93,127,97,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",113,90,115,92,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",103,89,105,91,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",89,90,91,92,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",74,104,76,106,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",74,120,76,122,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",83,131,87,135,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",92,142,94,144,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",98,159,100,161,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",94,180,98,184,"Octopus's Henchman",2192,5,.@label$;
+		areamonster .@map$,139,113,143,117,"Octopus's Henchman",2192,5,.@label$;
+		areamonster .@map$,135,104,137,106,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,123,93,127,97,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,113,90,115,92,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,103,89,105,91,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,89,90,91,92,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,74,104,76,106,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,74,120,76,122,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,83,131,87,135,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,92,142,94,144,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,98,159,100,161,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,94,180,98,184,"Octopus's Henchman",2192,5,.@label$;
 		break;
 	case 3:
-		areamonster "1@cash",299,209,303,213,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",292,203,296,207,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",291,186,293,188,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",292,166,294,168,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",293,151,295,153,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",299,137,303,141,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",300,123,304,127,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",300,104,304,108,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",279,101,281,103,"Octopus's Henchman",2192,2,.@label$;
-		monster "1@cash",260,103,"Octopus's Henchman",2192,1,.@label$;
+		areamonster .@map$,299,209,303,213,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,292,203,296,207,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,291,186,293,188,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,292,166,294,168,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,293,151,295,153,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,299,137,303,141,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,300,123,304,127,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,300,104,304,108,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,279,101,281,103,"Octopus's Henchman",2192,2,.@label$;
+		monster .@map$,260,103,"Octopus's Henchman",2192,1,.@label$;
 		break;
 	case 4:
-		areamonster "1@cash",363,123,367,127,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",364,108,368,112,"Octopus's Henchman",2192,5,.@label$;
-		areamonster "1@cash",363,93,367,97,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",364,72,366,74,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",364,58,366,60,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",355,44,359,48,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",346,36,350,40,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",319,28,325,34,"Octopus's Henchman",2192,5,.@label$;
-		areamonster "1@cash",305,27,307,29,"Octopus's Henchman",2192,2,.@label$;
-		areamonster "1@cash",276,29,280,33,"Octopus's Henchman",2192,5,.@label$;
-		areamonster "1@cash",258,37,262,41,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,363,123,367,127,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,364,108,368,112,"Octopus's Henchman",2192,5,.@label$;
+		areamonster .@map$,363,93,367,97,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,364,72,366,74,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,364,58,366,60,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,355,44,359,48,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,346,36,350,40,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,319,28,325,34,"Octopus's Henchman",2192,5,.@label$;
+		areamonster .@map$,305,27,307,29,"Octopus's Henchman",2192,2,.@label$;
+		areamonster .@map$,276,29,280,33,"Octopus's Henchman",2192,5,.@label$;
+		areamonster .@map$,258,37,262,41,"Octopus's Henchman",2192,2,.@label$;
 		break;
 	}
 	end;
 OnDisable:
-	killmonster "1@cash",instance_npcname(strnpcinfo(0), instance_id())+"::OnMyMobDead"; // Not in official script.
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	killmonster instance_mapname("1@cash"),instance_npcname(strnpcinfo(0))+"::OnMyMobDead"; // Not in official script.
+	disablenpc instance_npcname(strnpcinfo(0));
 	end;
 OnTouch:
 	if (getd("."+strnpcinfo(0)+instance_id())) end;
 	setd "."+strnpcinfo(0)+instance_id(),1;
-	hideonnpc instance_npcname(strnpcinfo(0), instance_id());
-	instance_announce 0,"Come out all my babies and help me out!",bc_map,"0xFFFF00";
+	hideonnpc instance_npcname(strnpcinfo(0));
+	mapannounce instance_mapname("1@cash"),"Come out all my babies and help me out!",bc_map,"0xFFFF00";
 	initnpctimer;
 	end;
 OnTimer5000:
-	instance_announce 0,"Let's give them a lesson!",bc_map,"0xFFFF00";
-	set .@label$, instance_npcname(strnpcinfo(0), instance_id())+"::OnMyMobDead";
+	set .@map$, instance_mapname("1@cash");
+	mapannounce .@map$,"Let's give them a lesson!",bc_map,"0xFFFF00";
+	set .@label$, instance_npcname(strnpcinfo(0))+"::OnMyMobDead";
 	set .@i, atoi(charat(strnpcinfo(0),8));
 	switch(.@i) {
 	case 1:
-		areamonster "1@cash",18,112,22,116,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",18,112,22,116,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,18,112,22,116,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,18,112,22,116,"Octopus's Henchman",2192,3,.@label$;
 		break;
 	case 2:
-		areamonster "1@cash",86,188,90,192,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",96,98,100,102,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,86,188,90,192,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,96,98,100,102,"Octopus's Henchman",2192,3,.@label$;
 		break;
 	case 3:
-		areamonster "1@cash",305,213,309,217,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",305,213,309,217,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,305,213,309,217,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,305,213,309,217,"Octopus's Henchman",2192,3,.@label$;
 		break;
 	case 4:
-		areamonster "1@cash",370,129,374,133,"Octopus's Henchman",2192,3,.@label$;
-		areamonster "1@cash",370,129,374,133,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,370,129,374,133,"Octopus's Henchman",2192,3,.@label$;
+		areamonster .@map$,370,129,374,133,"Octopus's Henchman",2192,3,.@label$;
 		break;
 	}
 	end;
@@ -356,17 +332,18 @@ OnTimer30000:
 	setd "."+strnpcinfo(0)+instance_id(),0;
 	stopnpctimer;
 	set .@i, atoi(charat(strnpcinfo(0),8));
-	donpcevent instance_npcname("oct_foot_exit"+.@i, instance_id())+"::OnEnable";
-	donpcevent instance_npcname(strnpcinfo(0), instance_id())+"::OnDisable";
+	donpcevent instance_npcname("oct_foot_exit"+.@i)+"::OnEnable";
+	donpcevent instance_npcname(strnpcinfo(0))+"::OnDisable";
 	end;
 OnMyMobDead:
-	if (mobcount("1@cash",instance_npcname(strnpcinfo(0), instance_id())+"::OnMyMobDead") < 1) {
-		instance_announce 0,"You hurt my babies!!? You'll have to pay for this!!!",bc_map,"0x00ff99";
+	set .@map$, instance_mapname("1@cash");
+	if (mobcount(.@map$,instance_npcname(strnpcinfo(0))+"::OnMyMobDead") < 1) {
+		mapannounce .@map$,"You hurt my babies!!? You'll have to pay for this!!!",bc_map,"0x00ff99";
 		setd "."+strnpcinfo(0)+instance_id(),0;
 		stopnpctimer;
 		set .@i, atoi(charat(strnpcinfo(0),8));
-		donpcevent instance_npcname("oct_foot_exit"+.@i, instance_id())+"::OnEnable";
-		donpcevent instance_npcname(strnpcinfo(0), instance_id())+"::OnDisable";
+		donpcevent instance_npcname("oct_foot_exit"+.@i)+"::OnEnable";
+		donpcevent instance_npcname(strnpcinfo(0))+"::OnDisable";
 		end;
 	}
 	end;
@@ -378,13 +355,13 @@ OnMyMobDead:
 1@cash,16,117,0	script	oct_foot_exit1	45,2,2,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	disablenpc instance_npcname(strnpcinfo(0));
 	end;
 OnEnable:
-	enablenpc instance_npcname(strnpcinfo(0), instance_id());
+	enablenpc instance_npcname(strnpcinfo(0));
 	end;
 OnTouch:
-	warp "1@cash",198,99;
+	warp instance_mapname("1@cash"),198,99;
 	end;
 }
 1@cash,77,193,0	duplicate(oct_foot_exit1)	oct_foot_exit2	45,2,2
@@ -394,196 +371,205 @@ OnTouch:
 1@cash,15,15,0	script	oct_mob_con	-1,{
 	end;
 OnInstanceInit:
-	donpcevent instance_npcname("oct_mob_con", instance_id())+"::OnDisable";
+	donpcevent instance_npcname("oct_mob_con")+"::OnDisable";
 	end;
 OnEnable:
-	enablenpc instance_npcname("oct_mob_con", instance_id());
-	monster "1@cash",32,94,"Hydra",1068,1;
-	monster "1@cash",41,101,"Hydra",1068,1;
-	monster "1@cash",35,78,"Hydra",1068,1;
-	monster "1@cash",35,62,"Hydra",1068,1;
-	monster "1@cash",49,54,"Hydra",1068,1;
-	monster "1@cash",70,28,"Hydra",1068,1;
-	monster "1@cash",83,22,"Hydra",1068,1;
-	monster "1@cash",99,23,"Hydra",1068,1;
-	monster "1@cash",115,23,"Hydra",1068,1;
-	monster "1@cash",132,25,"Hydra",1068,1;
-	monster "1@cash",100,185,"Hydra",1068,1;
-	monster "1@cash",92,178,"Hydra",1068,1;
-	monster "1@cash",92,162,"Hydra",1068,1;
-	monster "1@cash",70,121,"Hydra",1068,1;
-	monster "1@cash",70,105,"Hydra",1068,1;
-	monster "1@cash",105,85,"Hydra",1068,1;
-	monster "1@cash",121,84,"Hydra",1068,1;
-	monster "1@cash",292,209,"Hydra",1068,1;
-	monster "1@cash",303,206,"Hydra",1068,1;
-	monster "1@cash",290,163,"Hydra",1068,1;
-	monster "1@cash",299,150,"Hydra",1068,1;
-	monster "1@cash",308,141,"Hydra",1068,1;
-	monster "1@cash",308,125,"Hydra",1068,1;
-	monster "1@cash",295,97,"Hydra",1068,1;
-	monster "1@cash",279,97,"Hydra",1068,1;
-	monster "1@cash",370,111,"Hydra",1068,1;
-	monster "1@cash",370,110,"Hydra",1068,1;
-	monster "1@cash",371,96,"Hydra",1068,1;
-	monster "1@cash",371,80,"Hydra",1068,1;
-	monster "1@cash",367,55,"Hydra",1068,1;
-	monster "1@cash",343,29,"Hydra",1068,1;
-	monster "1@cash",327,24,"Hydra",1068,1;
-	monster "1@cash",311,22,"Hydra",1068,1;
-	monster "1@cash",295,22,"Hydra",1068,1;
-	monster "1@cash",279,22,"Hydra",1068,1;
-	areamonster "1@cash",30,67,50,87,"Stapo",1784,1;
-	areamonster "1@cash",102,19,122,39,"Stapo",1784,1;
-	areamonster "1@cash",89,138,109,158,"Stapo",1784,1;
-	areamonster "1@cash",112,83,132,103,"Stapo",1784,1;
-	areamonster "1@cash",283,168,303,188,"Stapo",1784,1;
-	areamonster "1@cash",292,97,312,117,"Stapo",1784,1;
-	areamonster "1@cash",355,64,375,84,"Stapo",1784,1;
-	areamonster "1@cash",317,17,337,37,"Stapo",1784,1;
-	donpcevent instance_npcname("oct_backattack1", instance_id())+"::OnEnable";
-	donpcevent instance_npcname("oct_backattack2", instance_id())+"::OnEnable";
-	donpcevent instance_npcname("oct_backattack3", instance_id())+"::OnEnable";
-	donpcevent instance_npcname("oct_backattack4", instance_id())+"::OnEnable";
-	donpcevent instance_npcname("oct_mob_con", instance_id())+"::OnDisable";
+	set .@map$, instance_mapname("1@cash");
+	enablenpc instance_npcname("oct_mob_con");
+	monster .@map$,32,94,"Hydra",1068,1;
+	monster .@map$,41,101,"Hydra",1068,1;
+	monster .@map$,35,78,"Hydra",1068,1;
+	monster .@map$,35,62,"Hydra",1068,1;
+	monster .@map$,49,54,"Hydra",1068,1;
+	monster .@map$,70,28,"Hydra",1068,1;
+	monster .@map$,83,22,"Hydra",1068,1;
+	monster .@map$,99,23,"Hydra",1068,1;
+	monster .@map$,115,23,"Hydra",1068,1;
+	monster .@map$,132,25,"Hydra",1068,1;
+	monster .@map$,100,185,"Hydra",1068,1;
+	monster .@map$,92,178,"Hydra",1068,1;
+	monster .@map$,92,162,"Hydra",1068,1;
+	monster .@map$,70,121,"Hydra",1068,1;
+	monster .@map$,70,105,"Hydra",1068,1;
+	monster .@map$,105,85,"Hydra",1068,1;
+	monster .@map$,121,84,"Hydra",1068,1;
+	monster .@map$,292,209,"Hydra",1068,1;
+	monster .@map$,303,206,"Hydra",1068,1;
+	monster .@map$,290,163,"Hydra",1068,1;
+	monster .@map$,299,150,"Hydra",1068,1;
+	monster .@map$,308,141,"Hydra",1068,1;
+	monster .@map$,308,125,"Hydra",1068,1;
+	monster .@map$,295,97,"Hydra",1068,1;
+	monster .@map$,279,97,"Hydra",1068,1;
+	monster .@map$,370,111,"Hydra",1068,1;
+	monster .@map$,370,110,"Hydra",1068,1;
+	monster .@map$,371,96,"Hydra",1068,1;
+	monster .@map$,371,80,"Hydra",1068,1;
+	monster .@map$,367,55,"Hydra",1068,1;
+	monster .@map$,343,29,"Hydra",1068,1;
+	monster .@map$,327,24,"Hydra",1068,1;
+	monster .@map$,311,22,"Hydra",1068,1;
+	monster .@map$,295,22,"Hydra",1068,1;
+	monster .@map$,279,22,"Hydra",1068,1;
+	areamonster .@map$,30,67,50,87,"Stapo",1784,1;
+	areamonster .@map$,102,19,122,39,"Stapo",1784,1;
+	areamonster .@map$,89,138,109,158,"Stapo",1784,1;
+	areamonster .@map$,112,83,132,103,"Stapo",1784,1;
+	areamonster .@map$,283,168,303,188,"Stapo",1784,1;
+	areamonster .@map$,292,97,312,117,"Stapo",1784,1;
+	areamonster .@map$,355,64,375,84,"Stapo",1784,1;
+	areamonster .@map$,317,17,337,37,"Stapo",1784,1;
+	donpcevent instance_npcname("oct_backattack1")+"::OnEnable";
+	donpcevent instance_npcname("oct_backattack2")+"::OnEnable";
+	donpcevent instance_npcname("oct_backattack3")+"::OnEnable";
+	donpcevent instance_npcname("oct_backattack4")+"::OnEnable";
+	donpcevent instance_npcname("oct_mob_con")+"::OnDisable";
 	end;
 OnDisable:
-	disablenpc instance_npcname("oct_mob_con", instance_id());
+	disablenpc instance_npcname("oct_mob_con");
 	end;
 }
 
 1@cash,45,53,0	script	oct_backattack1	139,3,3,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname("oct_backattack1", instance_id());
+	disablenpc instance_npcname("oct_backattack1");
 	end;
 OnTouch:
-	monster "1@cash",39,59,"Hydra",1068,1;
-	monster "1@cash",40,59,"Hydra",1068,1;
-	monster "1@cash",41,59,"Hydra",1068,1;
-	monster "1@cash",47,50,"Hydra",1068,1;
-	monster "1@cash",48,50,"Hydra",1068,1;
-	monster "1@cash",49,50,"Hydra",1068,1;
-	monster "1@cash",41,53,"Octopus's Henchman",2192,1;
-	instance_announce 0,"Don't let them break through, stop them!!!",bc_map,"0x00ff99";
+	set .@map$, instance_mapname("1@cash");
+	monster .@map$,39,59,"Hydra",1068,1;
+	monster .@map$,40,59,"Hydra",1068,1;
+	monster .@map$,41,59,"Hydra",1068,1;
+	monster .@map$,47,50,"Hydra",1068,1;
+	monster .@map$,48,50,"Hydra",1068,1;
+	monster .@map$,49,50,"Hydra",1068,1;
+	monster .@map$,41,53,"Octopus's Henchman",2192,1;
+	mapannounce .@map$,"Don't let them break through, stop them!!!",bc_map,"0x00ff99";
 	specialeffect EF_BASH;
-	disablenpc instance_npcname("oct_backattack1", instance_id());
+	disablenpc instance_npcname("oct_backattack1");
 	end;
 OnEnable:
-	enablenpc instance_npcname("oct_backattack1", instance_id());
+	enablenpc instance_npcname("oct_backattack1");
 	end;
 }
 
 1@cash,78,99,0	script	oct_backattack2	139,3,3,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname("oct_backattack2", instance_id());
+	disablenpc instance_npcname("oct_backattack2");
 	end;
 OnTouch:
 	if (getd("."+instance_id())) end;
 	setd "."+instance_id(),1;
 	initnpctimer;
-	monster "1@cash",71,105,"Octopus's Henchman ",2192,1;
-	instance_announce 0,"Headquarters are empty, GO!!!",bc_map,"0x00ff99";
-	hideonnpc instance_npcname("oct_backattack2", instance_id());
+	set .@map$, instance_mapname("1@cash");
+	monster .@map$,71,105,"Octopus's Henchman ",2192,1;
+	mapannounce .@map$,"Headquarters are empty, GO!!!",bc_map,"0x00ff99";
+	hideonnpc instance_npcname("oct_backattack2");
 	end;
 OnTimer2000:
-	monster "1@cash",71,105,"Octopus's Henchman ",2192,1;
-	instance_announce 0,"Run, RUN! Go, GO!!!",bc_map,"0x00ff99";
+	set .@map$, instance_mapname("1@cash");
+	monster .@map$,71,105,"Octopus's Henchman ",2192,1;
+	mapannounce .@map$,"Run, RUN! Go, GO!!!",bc_map,"0x00ff99";
 	end;
 OnTimer4000:
-	monster "1@cash",71,105,"Octopus's Henchman ",2192,1;
-	instance_announce 0,"No time, come out fast!",bc_map,"0x00ff99";
+	set .@map$, instance_mapname("1@cash");
+	monster .@map$,71,105,"Octopus's Henchman ",2192,1;
+	mapannounce .@map$,"No time, come out fast!",bc_map,"0x00ff99";
 	end;
 OnTimer6000:
-	monster "1@cash",71,105,"Octopus's Henchman ",2192,3;
-	instance_announce 0,"Let's take over the headquarters!!!",bc_map,"0x00ff99";
+	set .@map$, instance_mapname("1@cash");
+	monster .@map$,71,105,"Octopus's Henchman ",2192,3;
+	mapannounce .@map$,"Let's take over the headquarters!!!",bc_map,"0x00ff99";
 	end;
 OnTimer8000:
-	monster "1@cash",71,105,"Octopus's Henchman ",2192,1;
-	instance_announce 0,"There is no time to lose, hurry up!!!",bc_map,"0x00ff99";
+	set .@map$, instance_mapname("1@cash");
+	monster .@map$,71,105,"Octopus's Henchman ",2192,1;
+	mapannounce .@map$,"There is no time to lose, hurry up!!!",bc_map,"0x00ff99";
 	stopnpctimer;
 	end;
 OnEnable:
-	enablenpc instance_npcname("oct_backattack2", instance_id());
+	enablenpc instance_npcname("oct_backattack2");
 	end;
 }
 
 1@cash,299,144,0	script	oct_backattack3	139,3,3,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname("oct_backattack2", instance_id());
+	disablenpc instance_npcname("oct_backattack3");
 	end;
 OnTouch:
 	if (getd("."+instance_id())) end;
 	setd "."+instance_id(),1;
-	monster "1@cash",293,153,"Octopus's Henchman ",2192,1;
-	monster "1@cash",294,152,"Octopus's Henchman ",2192,1;
-	monster "1@cash",292,153,"Octopus's Henchman ",2192,1;
-	monster "1@cash",293,151,"Octopus's Henchman ",2192,1;
-	monster "1@cash",293,152,"Octopus's Henchman ?",2175,1;
-	instance_announce 0,"Kakaka! Suprised??!!",bc_map,"0x00ff99";
+	set .@map$, instance_mapname("1@cash");
+	monster .@map$,293,153,"Octopus's Henchman ",2192,1;
+	monster .@map$,294,152,"Octopus's Henchman ",2192,1;
+	monster .@map$,292,153,"Octopus's Henchman ",2192,1;
+	monster .@map$,293,151,"Octopus's Henchman ",2192,1;
+	monster .@map$,293,152,"Octopus's Henchman ?",2175,1;
+	mapannounce .@map$,"Kakaka! Suprised??!!",bc_map,"0x00ff99";
 	initnpctimer;
-	hideonnpc instance_npcname("oct_backattack3", instance_id());
+	hideonnpc instance_npcname("oct_backattack3");
 	end;
 OnTimer5000:
-	instance_announce 0,"... Looks like we have a spy among us.",bc_map,"0x00ff99";
+	mapannounce instance_mapname("1@cash"),"... Looks like we have a spy among us.",bc_map,"0x00ff99";
 	stopnpctimer;
 	end;
 OnEnable:
-	enablenpc instance_npcname("oct_backattack3", instance_id());
+	enablenpc instance_npcname("oct_backattack3");
 	end;
 }
 
 1@cash,336,36,0	script	oct_backattack4	139,3,3,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname("oct_backattack2", instance_id());
+	disablenpc instance_npcname("oct_backattack4");
 	end;
 OnTouch:
 	if (getd("."+instance_id())) end;
 	setd "."+instance_id(),1;
-	monster "1@cash",332,37,"Octopus's Henchman ",2192,1;
-	monster "1@cash",332,36,"Octopus's Henchman ",2192,1;
-	monster "1@cash",332,35,"Octopus's Henchman ",2192,1;
-	monster "1@cash",332,34,"Octopus's Henchman ",2192,1;
-	monster "1@cash",341,37,"Octopus's Henchman ",2192,1;
-	monster "1@cash",341,36,"Octopus's Henchman ",2192,1;
-	monster "1@cash",341,35,"Octopus's Henchman ",2192,1;
-	monster "1@cash",341,34,"Octopus's Henchman ",2192,1;
-	monster "1@cash",260,40,"Mercenary Squid",2175,1;
-	monster "1@cash",260,41,"Mercenary Squid",2175,1;
-	monster "1@cash",260,39,"Mercenary Squid",2175,1;
-	monster "1@cash",259,40,"Mercenary Squid",2175,1;
-	monster "1@cash",261,40,"Mercenary Squid",2175,1;
-	instance_announce 0,"What a successful pincer tactic! The enemy is strong! Let's not lose yourselves! Anyway, where are all the mercenaries??",bc_map,"0x00ff99";
+	set .@map$, instance_mapname("1@cash");
+	monster .@map$,332,37,"Octopus's Henchman ",2192,1;
+	monster .@map$,332,36,"Octopus's Henchman ",2192,1;
+	monster .@map$,332,35,"Octopus's Henchman ",2192,1;
+	monster .@map$,332,34,"Octopus's Henchman ",2192,1;
+	monster .@map$,341,37,"Octopus's Henchman ",2192,1;
+	monster .@map$,341,36,"Octopus's Henchman ",2192,1;
+	monster .@map$,341,35,"Octopus's Henchman ",2192,1;
+	monster .@map$,341,34,"Octopus's Henchman ",2192,1;
+	monster .@map$,260,40,"Mercenary Squid",2175,1;
+	monster .@map$,260,41,"Mercenary Squid",2175,1;
+	monster .@map$,260,39,"Mercenary Squid",2175,1;
+	monster .@map$,259,40,"Mercenary Squid",2175,1;
+	monster .@map$,261,40,"Mercenary Squid",2175,1;
+	mapannounce .@map$,"What a successful pincer tactic! The enemy is strong! Let's not lose yourselves! Anyway, where are all the mercenaries??",bc_map,"0x00ff99";
 	initnpctimer;
-	hideonnpc instance_npcname("oct_backattack4", instance_id());
+	hideonnpc instance_npcname("oct_backattack4");
 	end;
 OnTimer5000:
-	instance_announce 0,"Mercenary Squid : eh...eh... wrong direction. No enemies are shown in this direction.",bc_map,"0x00ff99";
+	mapannounce instance_mapname("1@cash"),"Mercenary Squid : eh...eh... wrong direction. No enemies are shown in this direction.",bc_map,"0x00ff99";
 	end;
 OnTimer7000:
-	instance_announce 0,"Pervert Octopus : Fools! Can't you read the map??!! Useless!!",bc_map,"0x00ff99";
+	mapannounce instance_mapname("1@cash"),"Pervert Octopus : Fools! Can't you read the map??!! Useless!!",bc_map,"0x00ff99";
 	stopnpctimer;
 	end;
 OnEnable:
-	enablenpc instance_npcname("oct_backattack4", instance_id());
+	enablenpc instance_npcname("oct_backattack4");
 	end;
 }
 
 1@cash,2,2,0	script	oct_boss_con	-1,{
 	end;
 OnInstanceInit:
-	donpcevent instance_npcname("oct_boss_con", instance_id())+"::OnDisable";
+	donpcevent instance_npcname("oct_boss_con")+"::OnDisable";
 	end;
 OnDisable:
-	disablenpc instance_npcname("oct_boss_con", instance_id());
+	disablenpc instance_npcname("oct_boss_con");
 	end;
 OnEnable:
-	enablenpc instance_npcname("oct_boss_con", instance_id());
-	donpcevent instance_npcname("oct_boss_foot", instance_id())+"::OnEnable";
-	monster "1@cash",199,188,"Disgusting Octopus",2194,1,instance_npcname("oct_boss_con", instance_id())+"::OnMyMobDead";
+	enablenpc instance_npcname("oct_boss_con");
+	donpcevent instance_npcname("oct_boss_foot")+"::OnEnable";
+	monster instance_mapname("1@cash"),199,188,"Disgusting Octopus",2194,1,instance_npcname("oct_boss_con")+"::OnMyMobDead";
 	initnpctimer;
 	end;
 OnTimer7000:
@@ -631,16 +617,17 @@ OnTimer49000:
 	initnpctimer;
 	end;
 OnAnnounce:
-	instance_announce 0,"Disgusting Octopus : "+getarg(rand(3)),bc_map,"0xFFFF00";
+	mapannounce instance_mapname("1@cash"),"Disgusting Octopus : "+getarg(rand(3)),bc_map,"0xFFFF00";
 	return;
 OnMyMobDead:
-	if (mobcount("1@cash",instance_npcname("oct_boss_con", instance_id())+"::OnMyMobDead") < 1) {
-		instance_announce 0,"Disgusting Octopus : That's it for the today! Next time, I will play with you badly!",bc_map,"0xFFFF00";
-		enablenpc instance_npcname("oct_exit_1", instance_id());
-		enablenpc instance_npcname("oct_exit_2", instance_id());
-		donpcevent instance_npcname("oct_boss_foot", instance_id())+"::OnDisable";
+	set .@map$, instance_mapname("1@cash");
+	if (mobcount(.@map$,instance_npcname("oct_boss_con")+"::OnMyMobDead") < 1) {
+		mapannounce .@map$,"Disgusting Octopus : That's it for the today! Next time, I will play with you badly!",bc_map,"0xFFFF00";
+		enablenpc instance_npcname("oct_exit_1");
+		enablenpc instance_npcname("oct_exit_2");
+		donpcevent instance_npcname("oct_boss_foot")+"::OnDisable";
 		stopnpctimer;
-		donpcevent instance_npcname("oct_boss_con", instance_id())+"::OnDisable";
+		donpcevent instance_npcname("oct_boss_con")+"::OnDisable";
 		end;
 	}
 	end;
@@ -649,22 +636,23 @@ OnMyMobDead:
 1@cash,4,4,0	script	oct_boss_foot	-1,{
 	end;
 OnInstanceInit:
-	donpcevent instance_npcname("oct_boss_foot", instance_id())+"::OnDisable";
+	donpcevent instance_npcname("oct_boss_foot")+"::OnDisable";
 	end;
 OnEnable:
-	enablenpc instance_npcname("oct_boss_foot", instance_id());
+	enablenpc instance_npcname("oct_boss_foot");
 	initnpctimer;
 	end;
 OnCall:
-	if (mobcount("1@cash",instance_npcname("oct_boss_foot", instance_id())+"::OnMyMobDead") < 100) {
+	set .@map$, instance_mapname("1@cash");
+	if (mobcount(.@map$,instance_npcname("oct_boss_foot")+"::OnMyMobDead") < 100) {
 		switch(rand(2)) {
 		case 0:
-			instance_announce 0,"Disgusting Octopus : Do you know how many legs octopus have? It doesn't matter, I have unlimited legs!!",bc_map,"0xFFFF00";
-			areamonster "1@cash",192,181,206,195,"Octopus Leg",2193,1,instance_npcname("oct_boss_foot", instance_id())+"::OnMyMobDead";
+			mapannounce .@map$,"Disgusting Octopus : Do you know how many legs octopus have? It doesn't matter, I have unlimited legs!!",bc_map,"0xFFFF00";
+			areamonster .@map$,192,181,206,195,"Octopus Leg",2193,1,instance_npcname("oct_boss_foot")+"::OnMyMobDead";
 			break;
 		case 1:
-			instance_announce 0,"Disgusting Octopus : I...cannot..hold anymore, my babies~ please come out and fight!",bc_map,"0xFFFF00";
-			areamonster "1@cash",192,181,206,195,"Octopus's Henchman ",2192,5,instance_npcname("oct_boss_foot", instance_id())+"::OnMyMobDead";
+			mapannounce .@map$,"Disgusting Octopus : I...cannot..hold anymore, my babies~ please come out and fight!",bc_map,"0xFFFF00";
+			areamonster .@map$,192,181,206,195,"Octopus's Henchman ",2192,5,instance_npcname("oct_boss_foot")+"::OnMyMobDead";
 			break;
 		}
 	}
@@ -672,12 +660,12 @@ OnCall:
 	end;
 OnTimer10000:
 	stopnpctimer;
-	donpcevent instance_npcname("oct_boss_foot", instance_id())+"::OnCall";
+	donpcevent instance_npcname("oct_boss_foot")+"::OnCall";
 	end;
 OnDisable:
 	stopnpctimer;
-	killmonster "1@cash",instance_npcname("oct_boss_foot", instance_id())+"::OnMyMobDead"; // Not in official script.
-	disablenpc instance_npcname("oct_boss_foot", instance_id());
+	killmonster instance_mapname("1@cash"),instance_npcname("oct_boss_foot")+"::OnMyMobDead"; // Not in official script.
+	disablenpc instance_npcname("oct_boss_foot");
 	end;
 OnMyMobDead:
 	end;
@@ -686,17 +674,17 @@ OnMyMobDead:
 1@cash,198,116,0	script	oct_boss_warp	45,2,2,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname("oct_boss_warp", instance_id());
+	disablenpc instance_npcname("oct_boss_warp");
 	end;
 OnTouch:
-	warp "1@cash",210,172;
+	warp instance_mapname("1@cash"),210,172;
 	end;
 }
 
 1@cash,190,208,0	script	oct_exit_1	45,2,2,{
 	end;
 OnInstanceInit:
-	disablenpc instance_npcname(strnpcinfo(0), instance_id());
+	disablenpc instance_npcname(strnpcinfo(0));
 	end;
 OnTouch:
 	mes "Do you want to go out from the octopus dungeon?";
@@ -718,4 +706,4 @@ OnTouch:
 1@cash,209,100,0	warp	oct_door5	2,2,1@cash,250,111
 1@cash,244,118,0	warp	oct_door6	2,2,1@cash,199,100
 1@cash,209,83,0	warp	oct_door7	2,2,1@cash,252,46
-1@cash,246,53,0	warp	oct_door8	2,2,1@cash,203,83
+1@cash,246,53,0	warp	oct_door8	2,2,1@cash,203,83

+ 8 - 5
src/map/atcommand.c

@@ -21,6 +21,7 @@
 #include "clif.h"
 #include "chrif.h"
 #include "duel.h"
+#include "instance.h"
 #include "intif.h"
 #include "itemdb.h"
 #include "log.h"
@@ -3724,6 +3725,9 @@ ACMD_FUNC(reload) {
 	} else if (strstr(command, "packetdb") || strncmp(message, "packetdb", 4) == 0) {
 		packetdb_readdb();
 		clif_displaymessage(fd, msg_txt(sd,1477)); // Packet database has been reloaded.
+	} else if (strstr(command, "instancedb") || strncmp(message, "instancedb", 4) == 0) {
+		instance_readdb();
+		clif_displaymessage(fd, msg_txt(sd,516)); // Instance database has been reloaded.
 	}
 
 
@@ -3945,8 +3949,6 @@ ACMD_FUNC(mapinfo) {
 		strcat(atcmd_output, msg_txt(sd,1097)); // GuildLock |
 	if (map[m_id].flag.loadevent)
 		strcat(atcmd_output, msg_txt(sd,1098)); // Loadevent |
-	if (map[m_id].flag.src4instance)
-		strcat(atcmd_output, msg_txt(sd,1099)); // Src4instance |
 	if (map[m_id].flag.chmautojoin)
 		strcat(atcmd_output, msg_txt(sd,1100)); // Chmautojoin |
 	if (map[m_id].flag.nousecart)
@@ -7653,7 +7655,7 @@ ACMD_FUNC(mapflag) {
 		checkflag(nogo);				checkflag(nobaseexp);
 		checkflag(nojobexp);			checkflag(nomobloot);			checkflag(nomvploot);	checkflag(nightenabled);
 		checkflag(restricted);			checkflag(nodrop);				checkflag(novending);	checkflag(loadevent);
-		checkflag(nochat);				checkflag(partylock);			checkflag(guildlock);	checkflag(src4instance);
+		checkflag(nochat);				checkflag(partylock);			checkflag(guildlock);
 		clif_displaymessage(sd->fd," ");
 		clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
 		clif_displaymessage(sd->fd,msg_txt(sd,1313)); // Type "@mapflag available" to list the available mapflags.
@@ -7673,7 +7675,7 @@ ACMD_FUNC(mapflag) {
 	setflag(nogo);				setflag(nobaseexp);
 	setflag(nojobexp);			setflag(nomobloot);			setflag(nomvploot);			setflag(nightenabled);
 	setflag(restricted);		setflag(nodrop);			setflag(novending);			setflag(loadevent);
-	setflag(nochat);			setflag(partylock);			setflag(guildlock);			setflag(src4instance);
+	setflag(nochat);			setflag(partylock);			setflag(guildlock);
 
 	clif_displaymessage(sd->fd,msg_txt(sd,1314)); // Invalid flag name or flag.
 	clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
@@ -7685,7 +7687,7 @@ ACMD_FUNC(mapflag) {
 	clif_displaymessage(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,");
 	clif_displaymessage(sd->fd,"fog, fireworks, sakura, leaves, nogo, nobaseexp, nojobexp, nomobloot,");
 	clif_displaymessage(sd->fd,"nomvploot, nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock,");
-	clif_displaymessage(sd->fd,"guildlock, src4instance");
+	clif_displaymessage(sd->fd,"guildlock");
 
 #undef checkflag
 #undef setflag
@@ -9130,6 +9132,7 @@ void atcommand_basecommands(void) {
 		ACMD_DEF2("reloadquestdb", reload),
 		ACMD_DEF2("reloadmsgconf", reload),
 		ACMD_DEF2("reloadpacketdb", reload),
+		ACMD_DEF2("reloadinstancedb", reload),
 		ACMD_DEF(partysharelvl),
 		ACMD_DEF(mapinfo),
 		ACMD_DEF(dye),

+ 67 - 88
src/map/clif.c

@@ -9186,10 +9186,6 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 	if( !(sd->sc.option&OPTION_INVISIBLE) ) { // increment the number of pvp players on the map
 		map[sd->bl.m].users_pvp++;
 	}
-	if( map[sd->bl.m].instance_id ) {
-		instance[map[sd->bl.m].instance_id].users++;
-		instance_check_idle(map[sd->bl.m].instance_id);
-	}
 	sd->state.debug_remove_map = 0; // temporary state to track double remove_map's [FlavioJS]
 
 	// reset the callshop flag if the player changes map
@@ -15267,99 +15263,82 @@ void clif_font(struct map_session_data *sd)
 
 
 /*==========================================
- * Instancing Window
+ * Notifies party members of instance change
  *------------------------------------------*/
-int clif_instance(int instance_id, int type, int flag)
+void clif_instance_create(struct map_session_data *sd, const char *name, int num, int flag)
 {
-	struct map_session_data *sd;
-	struct party_data *p;
-	unsigned char buf[255];
+#if PACKETVER >= 20071128
+	unsigned char buf[65];
 
-	if( (p = party_search(instance[instance_id].party_id)) == NULL || (sd = party_getavailablesd(p)) == NULL )
-		return 0;
+	nullpo_retv(sd);
 
-	switch( type )
-	{
-	case 1:
-		// S 0x2cb <Instance name>.61B <Standby Position>.W
-		// Required to start the instancing information window on Client
-		// This window re-appear each "refresh" of client automatically until type 4 is send to client.
-		WBUFW(buf,0) = 0x02CB;
-		memcpy(WBUFP(buf,2),instance[instance_id].name,INSTANCE_NAME_LENGTH);
-		WBUFW(buf,63) = flag;
-		clif_send(buf,packet_len(0x02CB),&sd->bl,PARTY);
-		break;
-	case 2:
-		// S 0x2cc <Standby Position>.W
-		// To announce Instancing queue creation if no maps available
-		WBUFW(buf,0) = 0x02CC;
-		WBUFW(buf,2) = flag;
-		clif_send(buf,packet_len(0x02CC),&sd->bl,PARTY);
-		break;
-	case 3:
-	case 4:
-		// S 0x2cd <Instance Name>.61B <Instance Remaining Time>.L <Instance Noplayers close time>.L
-		WBUFW(buf,0) = 0x02CD;
-		memcpy(WBUFP(buf,2),instance[instance_id].name,61);
-		if( type == 3 )
-		{
-			WBUFL(buf,63) = (uint32)instance[instance_id].progress_timeout;
-			WBUFL(buf,67) = 0;
-		}
-		else
-		{
-			WBUFL(buf,63) = 0;
-			WBUFL(buf,67) = (uint32)instance[instance_id].idle_timeout;
-		}
-		clif_send(buf,packet_len(0x02CD),&sd->bl,PARTY);
-		break;
-	case 5:
-		// S 0x2ce <Message ID>.L
-		// 0 = Notification (EnterLimitDate update?)
-		// 1 = The Memorial Dungeon expired; it has been destroyed
-		// 2 = The Memorial Dungeon's entry time limit expired; it has been destroyed
-		// 3 = The Memorial Dungeon has been removed.
-		// 4 = Create failure (removes the instance window)
-		WBUFW(buf,0) = 0x02CE;
-		WBUFL(buf,2) = flag;
-		//WBUFL(buf,6) = EnterLimitDate;
-		clif_send(buf,packet_len(0x02CE),&sd->bl,PARTY);
-		break;
-	}
-	return 0;
+	WBUFW(buf,0) = 0x2cb;
+	safestrncpy( WBUFP(buf,2), name, 62 );
+	WBUFW(buf,63) = num;
+	if(flag) // A timer has changed or been added
+		clif_send(buf,packet_len(0x2cb),&sd->bl,PARTY);
+	else	// No notification
+		clif_send(buf,packet_len(0x2cb),&sd->bl,SELF);
+#endif
+
+	return;
 }
 
-void clif_instance_join(int fd, int instance_id)
-{
-	if( instance[instance_id].idle_timer != INVALID_TIMER ) {
-		WFIFOHEAD(fd,packet_len(0x02CD));
-		WFIFOW(fd,0) = 0x02CD;
-		memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
-		WFIFOL(fd,63) = 0;
-		WFIFOL(fd,67) = (uint32)instance[instance_id].idle_timeout;
-		WFIFOSET(fd,packet_len(0x02CD));
-	} else if( instance[instance_id].progress_timer != INVALID_TIMER ) {
-		WFIFOHEAD(fd,packet_len(0x02CD));
-		WFIFOW(fd,0) = 0x02CD;
-		memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
-		WFIFOL(fd,63) = (uint32)instance[instance_id].progress_timeout;;
-		WFIFOL(fd,67) = 0;
-		WFIFOSET(fd,packet_len(0x02CD));
-	} else {
-		WFIFOHEAD(fd,packet_len(0x02CB));
-		WFIFOW(fd,0) = 0x02CB;
-		memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
-		WFIFOW(fd,63) = 0;
-		WFIFOSET(fd,packet_len(0x02CB));
-	}
+void clif_instance_changewait(struct map_session_data *sd, int num, int flag)
+{
+#if PACKETVER >= 20071128
+	unsigned char buf[4];
+
+	nullpo_retv(sd);
+
+	WBUFW(buf,0) = 0x2cc;
+	WBUFW(buf,2) = num;
+	if(flag) // A timer has changed or been added
+		clif_send(buf,packet_len(0x2cc),&sd->bl,PARTY);
+	else	// No notification
+		clif_send(buf,packet_len(0x2cc),&sd->bl,SELF);
+#endif
+
+	return;
 }
 
-void clif_instance_leave(int fd)
+void clif_instance_status(struct map_session_data *sd, const char *name, unsigned int limit1, unsigned int limit2, int flag)
 {
-	WFIFOHEAD(fd,packet_len(0x02CE));
-	WFIFOW(fd,0) = 0x02ce;
-	WFIFOL(fd,2) = 4;
-	WFIFOSET(fd,packet_len(0x02CE));
+#if PACKETVER >= 20071128
+	unsigned char buf[71];
+
+	nullpo_retv(sd);
+
+	WBUFW(buf,0) = 0x2cd;
+	safestrncpy( WBUFP(buf,2), name, 62 );
+	WBUFL(buf,63) = limit1;
+	WBUFL(buf,67) = limit2;
+	if(flag) // A timer has changed or been added
+		clif_send(buf,packet_len(0x2cd),&sd->bl,PARTY);
+	else	// No notification
+		clif_send(buf,packet_len(0x2cd),&sd->bl,SELF);
+#endif
+
+	return;
+}
+
+void clif_instance_changestatus(struct map_session_data *sd, int type, unsigned int limit, int flag)
+{
+#if PACKETVER >= 20071128
+	unsigned char buf[10];
+
+	nullpo_retv(sd);
+
+	WBUFW(buf,0) = 0x2ce;
+	WBUFL(buf,2) = type;
+	WBUFL(buf,6) = limit;
+	if(flag) // A timer has changed or been added
+		clif_send(buf,packet_len(0x2ce),&sd->bl,PARTY);
+	else	// No notification
+		clif_send(buf,packet_len(0x2ce),&sd->bl,SELF);
+#endif
+
+	return;
 }
 
 

+ 4 - 3
src/map/clif.h

@@ -570,9 +570,10 @@ void clif_sendbgemblem_area(struct map_session_data *sd);
 void clif_sendbgemblem_single(int fd, struct map_session_data *sd);
 
 // Instancing
-int clif_instance(int instance_id, int type, int flag);
-void clif_instance_join(int fd, int instance_id);
-void clif_instance_leave(int fd);
+void clif_instance_create(struct map_session_data *sd, const char *name, int num, int flag);
+void clif_instance_changewait(struct map_session_data *sd, int num, int flag);
+void clif_instance_status(struct map_session_data *sd, const char *name, unsigned int limit1, unsigned int limit2, int flag);
+void clif_instance_changestatus(struct map_session_data *sd, int type, unsigned int limit, int flag);
 
 // Custom Fonts
 void clif_font(struct map_session_data *sd);

+ 561 - 344
src/map/instance.c

@@ -24,465 +24,682 @@
 #include <stdarg.h>
 #include <time.h>
 
-int instance_start = 0; // To keep the last index + 1 of normal map inserted in the map[ARRAY]
-struct s_instance instance[MAX_INSTANCE];
+#define MAX_INSTANCE_DB		15	// Max number of instance types
+#define INSTANCE_INTERVAL	60000	// Interval used to check when an instance is to be destroyed (ms)
+#define INSTANCE_LIMIT		300000	// Idle timer before instance is destroyed (ms) : 5 Minute Default
 
+int instance_start = 0; // To keep the last index + 1 of normal map inserted in the map[ARRAY]
 
-/// Checks whether given instance id is valid or not.
-static bool instance_is_valid(int instance_id)
+struct instance_data instance_data[MAX_INSTANCE_DATA];
+
+static struct instance_db{
+	short type;
+	char name[61];
+	int limit;
+	struct {
+		char mapname[MAP_NAME_LENGTH_EXT];
+		short x, y;
+	} enter;
+	char mapname[MAX_MAP_PER_INSTANCE][MAP_NAME_LENGTH_EXT];
+} instance_db[MAX_INSTANCE_DB];
+
+static struct {
+	int id[MAX_INSTANCE_DATA];
+	int count;
+	int timer;
+} instance_wait;
+
+/*==========================================
+ * Searches for an instance ID in the database
+ *------------------------------------------*/
+static struct instance_db *instance_searchtype_db(short instance_type)
 {
-	if( instance_id < 1 || instance_id >= ARRAYLENGTH(instance) )
-	{// out of range
-		return false;
-	}
+	int i;
 
-	if( instance[instance_id].state == INSTANCE_FREE )
-	{// uninitialized/freed instance slot
-		return false;
+	for(i=0; i < MAX_INSTANCE_DB; i++) {
+		if(instance_db[i].type == instance_type)
+			return &instance_db[i];
 	}
 
-	return true;
+	return NULL;
 }
 
-
-/*--------------------------------------
- * name : instance name
- * Return value could be
- * -4 = already exists | -3 = no free instances | -2 = party not found | -1 = invalid type
- * On success return instance_id
- *--------------------------------------*/
-int instance_create(int party_id, const char *name)
+/*==========================================
+ * Searches for an instance name in the database
+ *------------------------------------------*/
+static struct instance_db *instance_searchname_db(const char *instance_name)
 {
 	int i;
-	struct party_data* p;
 
-	if( ( p = party_search(party_id) ) == NULL )
-	{
-		ShowError("instance_create: party %d not found for instance '%s'.\n", party_id, name);
-		return -2;
+	for(i=0; i < MAX_INSTANCE_DB; i++) {
+		if(strcmp(instance_db[i].name, instance_name) == 0)
+			return &instance_db[i];
 	}
 
-	if( p->instance_id )
-		return -4; // Party already instancing
-
-	// Searching a Free Instance
-	// 0 is ignored as this mean "no instance" on maps
-	ARR_FIND(1, MAX_INSTANCE, i, instance[i].state == INSTANCE_FREE);
-	if( i == MAX_INSTANCE )
-	{
-		ShowError("instance_create: no free instances, consider increasing MAX_INSTANCE.\n");
-		return -3;
-	}
+	return NULL;
+}
 
-	instance[i].state = INSTANCE_IDLE;
-	instance[i].instance_id = i;
-	instance[i].idle_timer = INVALID_TIMER;
-	instance[i].idle_timeout = instance[i].idle_timeoutval = 0;
-	instance[i].progress_timer = INVALID_TIMER;
-	instance[i].progress_timeout = 0;
-	instance[i].users = 0;
-	instance[i].party_id = party_id;
-	instance[i].vars = idb_alloc(DB_OPT_RELEASE_DATA);
-
-	safestrncpy( instance[i].name, name, sizeof(instance[i].name) );
-	memset( instance[i].map, 0x00, sizeof(instance[i].map) );
-	p->instance_id = i;
+/*==========================================
+ * Deletes an instance timer (Destroys instance)
+ *------------------------------------------*/
+static int instance_delete_timer(int tid, unsigned int tick, int id, intptr_t data)
+{
+	instance_destroy(id);
 
-	clif_instance(i, 1, 0); // Start instancing window
-	ShowInfo("[Instance] Created: %s.\n", name);
-	return i;
+	return 0;
 }
 
-/*--------------------------------------
- * Add a map to the instance using src map "name"
- *--------------------------------------*/
-int instance_add_map(const char *name, int instance_id, bool usebasename)
+/*==========================================
+ * Create subscription timer for party
+ *------------------------------------------*/
+static int instance_subscription_timer(int tid, unsigned int tick, int id, intptr_t data)
 {
-	int16 m = map_mapname2mapid(name);
-	int i, im = -1;
-	size_t num_cell, size;
+	int i, ret;
+	int instance_id = instance_wait.id[0];
+	struct party_data *p;
 
-	if( m < 0 )
-		return -1; // source map not found
+	if(instance_wait.count == 0 || instance_id <= 0)
+		return 0;
 
-	if( !instance_is_valid(instance_id) )
-	{
-		ShowError("instance_add_map: trying to attach '%s' map to non-existing instance %d.\n", name, instance_id);
-		return -1;
-	}
-	if( instance[instance_id].num_map >= MAX_MAP_PER_INSTANCE )
-	{
-		ShowError("instance_add_map: trying to add '%s' map to instance %d (%s) failed. Please increase MAX_MAP_PER_INSTANCE.\n", name, instance_id, instance[instance_id].name);
-		return -2;
-	}
-	if( map[m].instance_id != 0 )
-	{ // Source map already belong to a Instance.
-		ShowError("instance_add_map: trying to instance already instanced map %s.\n", name);
-		return -4;
-	}
+	// Check that maps have been added
+	ret = instance_addmap(instance_id);
 
-	ARR_FIND( instance_start, map_num, i, !map[i].name[0] ); // Searching for a Free Map
-	if( i < map_num ) im = i; // Unused map found (old instance)
-	else if( map_num - 1 >= MAX_MAP_PER_SERVER )
-	{ // No more free maps
-		ShowError("instance_add_map: no more free space to create maps on this server.\n");
-		return -5;
-	}
-	else im = map_num++; // Using next map index
+	// If no maps are created, tell party to wait
+	if(ret == 0 && ( p = party_search( instance_data[instance_id].party_id ) ) != NULL)
+		clif_instance_changewait( party_getavailablesd( p ), 0xffff, 1 );
 
-	memcpy( &map[im], &map[m], sizeof(struct map_data) ); // Copy source map
-	snprintf(map[im].name, MAP_NAME_LENGTH, (usebasename ? "%.3d#%s" : "%.3d%s"), instance_id, name); // Generate Name for Instance Map
-	map[im].index = mapindex_addmap(-1, map[im].name); // Add map index
+	instance_wait.count--;
+	memmove(&instance_wait.id[0],&instance_wait.id[1],sizeof(instance_wait.id[0])*instance_wait.count);
+	memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));
 
-	if( !map[im].index )
-	{
-		map[im].name[0] = '\0';
-		ShowError("instance_add_map: no more free map indexes.\n");
-		return -3; // No free map index
+	for(i = 0; i < instance_wait.count; i++) {
+		if(	instance_data[instance_wait.id[i]].state == INSTANCE_IDLE &&
+			( p = party_search( instance_data[instance_wait.id[i]].party_id ) ) != NULL
+		){
+			clif_instance_changewait( party_getavailablesd( p ), i + 1, 1 );
+		}
 	}
 
-	// Reallocate cells
-	num_cell = map[im].xs * map[im].ys;
-	CREATE( map[im].cell, struct mapcell, num_cell );
-	memcpy( map[im].cell, map[m].cell, num_cell * sizeof(struct mapcell) );
+	if(instance_wait.count)
+		instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
+	else
+		instance_wait.timer = -1;
 
-	size = map[im].bxs * map[im].bys * sizeof(struct block_list*);
-	map[im].block = (struct block_list**)aCalloc(size, 1);
-	map[im].block_mob = (struct block_list**)aCalloc(size, 1);
+	return 0;
+}
+
+/*==========================================
+ * Adds timer back to party entering instance
+ *------------------------------------------*/
+static int instance_startkeeptimer(struct instance_data *im, short instance_id)
+{
+	struct instance_db *db;
+	struct party_data *p;
+
+	nullpo_retr(0, im);
 
-	memset(map[im].npc, 0x00, sizeof(map[i].npc));
-	map[im].npc_num = 0;
+	// No timer
+	if(im->keep_timer != -1)
+		return 1;
 
-	memset(map[im].moblist, 0x00, sizeof(map[im].moblist));
-	map[im].mob_delete_timer = INVALID_TIMER;
+	if((db = instance_searchtype_db(im->type)) == NULL)
+		return 1;
 
-	map[im].m = im;
-	map[im].instance_id = instance_id;
-	map[im].instance_src_map = m;
-	map[m].flag.src4instance = 1; // Flag this map as a src map for instances
+	// Add timer
+	im->keep_limit = (unsigned int)time(NULL) + db->limit;
+	im->keep_timer = add_timer(gettick()+db->limit*1000, instance_delete_timer, instance_id, 0);
 
-	instance[instance_id].map[instance[instance_id].num_map++] = im; // Attach to actual instance
-	map_addmap2db(&map[im]);
+	// Notify party of the added instance timer
+	if( ( p = party_search( im->party_id ) ) != NULL )
+		clif_instance_status( party_getavailablesd( p ), db->name, im->keep_limit, im->idle_limit, 1 );
 
-	return im;
+	return 0;
 }
 
-/*--------------------------------------
- * m : source map of this instance
- * party_id : source party of this instance
- * type : result (0 = map id | 1 = instance id)
- *--------------------------------------*/
-int instance_map2imap(int16 m, int instance_id)
+/*==========================================
+ * Creates idle timer
+ * Default before instance destroy is 5 minutes
+ *------------------------------------------*/
+static int instance_startidletimer(struct instance_data *im, short instance_id)
 {
- 	int i;
+	struct instance_db *db;
+	struct party_data *p;
 
-	if( !instance_is_valid(instance_id) )
-	{
-		return -1;
+	nullpo_retr(1, im);
+
+	// No current timer
+	if(im->idle_timer != -1)
+		return 1;
+
+	// Add the timer
+	im->idle_limit = (unsigned int)time(NULL) + INSTANCE_LIMIT/1000;
+	im->idle_timer = add_timer(gettick()+INSTANCE_LIMIT, instance_delete_timer, instance_id, 0);
+
+	// Notify party of added instance timer
+	if( ( p = party_search( im->party_id ) ) != NULL &&
+		( db = instance_searchtype_db( im->type ) ) != NULL
+		){
+		clif_instance_status( party_getavailablesd( p ), db->name, im->keep_limit, im->idle_limit, 1 );
 	}
 
-	for( i = 0; i < instance[instance_id].num_map; i++ )
- 	{
-		if( instance[instance_id].map[i] && map[instance[instance_id].map[i]].instance_src_map == m )
-			return instance[instance_id].map[i];
- 	}
- 	return -1;
+	return 0;
 }
 
-/*--------------------------------------
- * m : source map
- * instance_id : where to search
- * result : mapid of map "m" in this instance
- *--------------------------------------*/
-int instance_mapid2imapid(int16 m, int instance_id)
+/*==========================================
+ * Delete the idle timer
+ *------------------------------------------*/
+static int instance_stopidletimer(struct instance_data *im)
 {
-	if( map[m].flag.src4instance == 0 )
-		return m; // not instances found for this map
-	else if( map[m].instance_id )
-	{ // This map is a instance, not a src map instance
-		ShowError("map_instance_mapid2imapid: already instanced (%d / %d)\n", m, instance_id);
-		return -1;
-	}
+	struct party_data *p;
 
-	if( !instance_is_valid(instance_id) )
-		return -1;
+	nullpo_retr(0, im);
+	
+	// No timer
+	if(im->idle_timer == -1)
+		return 1;
+
+	// Delete the timer - Party has returned or instance is destroyed
+	im->idle_limit = 0;
+	delete_timer(im->idle_timer, instance_delete_timer);
+	im->idle_timer = -1;
 
-	return instance_map2imap(m, instance_id);
+	// Notify the party
+	if( ( p = party_search( im->party_id ) ) != NULL )
+		clif_instance_changestatus( party_getavailablesd( p ), 0, im->idle_limit, 1 );
+
+	return 0;
 }
 
-/*--------------------------------------
- * map_instance_map_npcsub
- * Used on Init instance. Duplicates each script on source map
- *--------------------------------------*/
-int instance_map_npcsub(struct block_list* bl, va_list args)
+/*==========================================
+ * Run the OnInstanceInit events for duplicated NPCs
+ *------------------------------------------*/
+static int instance_npcinit(struct block_list *bl, va_list ap)
 {
-	struct npc_data* nd = (struct npc_data*)bl;
-	int16 m = va_arg(args, int); // Destination Map
+	struct npc_data* nd;
+
+	nullpo_retr(0, bl);
+	nullpo_retr(0, ap);
+	nullpo_retr(0, nd = (struct npc_data *)bl);
 
-	npc_duplicate4instance(nd, m);
-	return 1;
+	return npc_instanceinit(nd);
 }
 
-/*--------------------------------------
- * Init all map on the instance. Npcs are created here
- *--------------------------------------*/
-void instance_init(int instance_id)
+/*==========================================
+ * Add an NPC to an instance
+ *------------------------------------------*/
+static int instance_addnpc_sub(struct block_list *bl, va_list ap)
+{
+	struct npc_data* nd;
+
+	nullpo_retr(0, bl);
+	nullpo_retr(0, ap);
+	nullpo_retr(0, nd = (struct npc_data *)bl);
+
+	return npc_duplicate4instance(nd, va_arg(ap, int));
+}
+
+// Separate function used for reloading
+void instance_addnpc(struct instance_data *im)
 {
 	int i;
 
-	if( !instance_is_valid(instance_id) )
-		return; // nothing to do
+	// First add the NPCs
+	for(i = 0; i < im->cnt_map; i++)
+		map_foreachinarea(instance_addnpc_sub, im->map[i].src_m, 0, 0, map[im->map[i].src_m].xs, map[im->map[i].src_m].ys, BL_NPC, im->map[i].m);
 
-	for( i = 0; i < instance[instance_id].num_map; i++ )
-		map_foreachinmap(instance_map_npcsub, map[instance[instance_id].map[i]].instance_src_map, BL_NPC, instance[instance_id].map[i]);
+	// Now run their OnInstanceInit
+	for(i = 0; i < im->cnt_map; i++)
+		map_foreachinarea(instance_npcinit, im->map[i].m, 0, 0, map[im->map[i].m].xs, map[im->map[i].m].ys, BL_NPC, im->map[i].m);
 
-	instance[instance_id].state = INSTANCE_BUSY;
-	ShowInfo("[Instance] Initialized %s.\n", instance[instance_id].name);
 }
 
 /*--------------------------------------
- * Used on instance deleting process.
- * Warps all players on each instance map to its save points.
+ * name : instance name
+ * Return value could be
+ * -4 = already exists | -3 = no free instances | -2 = party not found | -1 = invalid type
+ * On success return instance_id
  *--------------------------------------*/
-int instance_del_load(struct map_session_data* sd, va_list args)
+int instance_create(int party_id, const char *name)
 {
-	int16 m = va_arg(args,int);
-	if( !sd || sd->bl.m != m )
-		return 0;
+	short i;
+	struct instance_db *db = instance_searchname_db(name);
+	struct party_data *p = party_search(party_id);
 
-	pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT);
-	return 1;
-}
+	if(db == NULL)
+		return -1;
 
-/* for npcs behave differently when being unloaded within a instance */
-int instance_cleanup_sub(struct block_list *bl, va_list ap) {
-	nullpo_ret(bl);
-
-	switch(bl->type) {
-		case BL_PC:
-			map_quit((struct map_session_data *) bl);
-			break;
-		case BL_NPC:
-			npc_unload((struct npc_data *)bl,true);
-			break;
-		case BL_MOB:
-			unit_free(bl,CLR_OUTSIGHT);
-			break;
-		case BL_PET:
-			//There is no need for this, the pet is removed together with the player. [Skotlex]
-			break;
-		case BL_ITEM:
-			map_clearflooritem(bl);
-			break;
-		case BL_SKILL:
-			skill_delunit((struct skill_unit *) bl);
-			break;
-	}
+	if( p == NULL )
+		return -2;
+
+	if( p->instance_id )
+		return -3; // Party already instancing
+
+	// Searching a Free Instance
+	// 0 is ignored as this mean "no instance" on maps
+	ARR_FIND(1, MAX_INSTANCE_DB, i, instance_data[i].state == INSTANCE_FREE);
+	if( i >= MAX_INSTANCE_DB )
+		return -4;
 
-	return 1;
+	instance_data[i].type = db->type;
+	instance_data[i].state = INSTANCE_IDLE;
+	instance_data[i].party_id = p->party.party_id;
+	instance_data[i].keep_limit = 0;
+	instance_data[i].keep_timer = -1;
+	instance_data[i].idle_limit = 0;
+	instance_data[i].idle_timer = -1;
+	instance_data[i].vars = idb_alloc(DB_OPT_RELEASE_DATA);
+	memset(instance_data[i].map, 0, sizeof(instance_data[i].map));
+
+	p->instance_id = i;
+
+	instance_wait.id[instance_wait.count++] = p->instance_id;
+
+	clif_instance_create( party_getavailablesd( p ), name, instance_wait.count, 1);
+
+	instance_subscription_timer(0,0,0,0);
+
+	ShowInfo("[Instance] Created: %s.\n", name);
+
+	return 0;
 }
 
 /*--------------------------------------
- * Removes a simple instance map
+ * Adds maps to the instance
  *--------------------------------------*/
-void instance_del_map(int16 m)
+int instance_addmap(short instance_id)
 {
-	int i;
-	if( m <= 0 || !map[m].instance_id )
-	{
-		ShowError("Tried to remove non-existing instance map (%d)\n", m);
-		return;
-	}
+	int i, m;
+	int cnt_map = 0;
+	struct instance_data *im;
+	struct instance_db *db;
+	struct party_data *p;
 
-	map_foreachpc(instance_del_load, m);
-	map_foreachinmap(instance_cleanup_sub, m, BL_ALL);
-
-	if( map[m].mob_delete_timer != INVALID_TIMER )
-		delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
-
-	mapindex_removemap( map[m].index );
-
-	// Free memory
-	aFree(map[m].cell);
-	aFree(map[m].block);
-	aFree(map[m].block_mob);
-
-	// Remove from instance
-	for( i = 0; i < instance[map[m].instance_id].num_map; i++ )
-	{
-		if( instance[map[m].instance_id].map[i] == m )
-		{
-			instance[map[m].instance_id].num_map--;
-			for( ; i < instance[map[m].instance_id].num_map; i++ )
-				instance[map[m].instance_id].map[i] = instance[map[m].instance_id].map[i+1];
-			i = -1;
-			break;
+	if(instance_id <= 0)
+		return 0;
+
+	im = &instance_data[instance_id];
+
+	// If the instance isn't idle, we can't do anything
+	if(im->state != INSTANCE_IDLE)
+		return 0;
+
+	if((db = instance_searchtype_db(im->type)) == NULL)
+		return 0;
+
+	// Set to busy, update timers
+	im->state = INSTANCE_BUSY;
+	im->idle_limit = (unsigned int)time(NULL) + INSTANCE_LIMIT/1000;
+	im->idle_timer = add_timer(gettick()+INSTANCE_LIMIT, instance_delete_timer, instance_id, 0);
+
+	// Add the maps
+	for(i = 0; i < MAX_MAP_PER_INSTANCE; i++) {
+		if(strlen(db->mapname[i]) < 1)
+			continue;
+		else if( (m = map_addinstancemap(db->mapname[i], instance_id)) < 0) {
+			// An error occured adding a map
+			ShowError("instance_addmap: No maps added to instance %d.\n",instance_id);
+			return 0;
+		} else {
+			im->map[cnt_map].m = m;
+			im->map[cnt_map].src_m = map_mapname2mapid(db->mapname[i]);
+			cnt_map++;
 		}
 	}
-	if( i == instance[map[m].instance_id].num_map )
-		ShowError("map_instance_del: failed to remove %s from instance list (%s): %d\n", map[m].name, instance[map[m].instance_id].name, m);
 
-	map_removemapdb(&map[m]);
-	memset(&map[m], 0x00, sizeof(map[0]));
+	im->cnt_map = cnt_map;
 
-	/* for it is default and makes it not try to delete a non-existent timer since we did not delete this entry. */
-	map[m].mob_delete_timer = INVALID_TIMER;
+	// Create NPCs on all maps
+	instance_addnpc(im);
+
+	// Inform party members of the created instance
+	if( (p = party_search( im->party_id ) ) != NULL )
+		clif_instance_status( party_getavailablesd( p ), db->name, im->keep_limit, im->idle_limit, 1);
+
+	return cnt_map;
 }
 
-/*--------------------------------------
- * Timer to destroy instance by process or idle
- *--------------------------------------*/
-int instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data)
+
+/*==========================================
+ * Returns an instance map ID using a map name
+ * name : source map
+ * instance_id : where to search
+ * result : mapid of map "name" in this instance
+ *------------------------------------------*/
+int instance_mapname2mapid(const char *name, short instance_id)
 {
-	instance_destroy(id);
-	return 0;
+	struct instance_data *im;
+	int m = map_mapname2mapid(name);
+	char iname[12];
+	int i;
+
+	if(m < 0) {
+		ShowError("instance_mapname2mapid: map name %s does not exist.\n",name);
+		return m;
+	}
+
+	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
+		return m;
+
+	im = &instance_data[instance_id];
+	if(im->state != INSTANCE_BUSY)
+		return m;
+
+	for(i = 0; i < MAX_MAP_PER_INSTANCE; i++)
+		if(im->map[i].src_m == m) {
+			snprintf(iname, sizeof(iname), ((strchr(name,'@') == NULL)?"%.3d#%s":"%.3d%s"), instance_id, name);
+			return mapindex_name2id(iname);
+		}
+
+	return m;
 }
 
-/*--------------------------------------
+/*==========================================
  * Removes a instance, all its maps and npcs.
- *--------------------------------------*/
-void instance_destroy(int instance_id)
+ *------------------------------------------*/
+int instance_destroy(short instance_id)
 {
-	int last = 0, type;
+	struct instance_data *im;
 	struct party_data *p;
-	time_t now = time(NULL);
+	int i, type = 0, count = 0;
+	unsigned int now = (unsigned int)time(NULL);
+
+	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
+		return 1;
+
+	im = &instance_data[instance_id];
+
+	if(im->state == INSTANCE_FREE)
+		return 1;
+
+	if(im->state == INSTANCE_IDLE) {
+		for(i = 0; i < instance_wait.count; i++) {
+			if(instance_wait.id[i] == instance_id) {
+				instance_wait.count--;
+				memmove(&instance_wait.id[i],&instance_wait.id[i+1],sizeof(instance_wait.id[0])*(instance_wait.count-i));
+				memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));
+
+				for(i = 0; i < instance_wait.count; i++)
+					if(instance_data[instance_wait.id[i]].state == INSTANCE_IDLE)
+						if((p = party_search(instance_data[instance_wait.id[i]].party_id)) != NULL)
+							clif_instance_changewait( party_getavailablesd( p ), i+1, 1);
+
+				if(instance_wait.count)
+					instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
+				else
+					instance_wait.timer = -1;
+				type = 0;
+				break;
+			}
+		}
+	} else {
+		if(im->keep_limit && im->keep_limit <= now)
+			type = 1;
+		else if(im->idle_limit && im->idle_limit <= now)
+			type = 2;
+		else
+			type = 3;
 
-	if( !instance_is_valid(instance_id) )
-		return; // nothing to do
+		for(i = 0; i < MAX_MAP_PER_INSTANCE; i++)
+			count += map_delinstancemap(im->map[i].m);
+	}
 
-	if( instance[instance_id].progress_timeout && instance[instance_id].progress_timeout <= now )
-		type = 1;
-	else if( instance[instance_id].idle_timeout && instance[instance_id].idle_timeout <= now )
-		type = 2;
-	else
-		type = 3;
+	if(im->keep_timer != -1) {
+		delete_timer(im->keep_timer, instance_delete_timer);
+		im->keep_timer = -1;
+	}
+	if(im->idle_timer != -1) {
+		delete_timer(im->idle_timer, instance_delete_timer);
+		im->idle_timer = -1;
+	}
 
-	clif_instance(instance_id, 5, type); // Report users this instance has been destroyed
+	if((p = party_search(im->party_id))) {
+		p->instance_id = 0;
 
-	while( instance[instance_id].num_map && last != instance[instance_id].map[0] )
-	{ // Remove all maps from instance
-		last = instance[instance_id].map[0];
-		instance_del_map( instance[instance_id].map[0] );
+		if(type)
+			clif_instance_changestatus( party_getavailablesd( p ), type, 0, 1 );
+		else
+			clif_instance_changewait( party_getavailablesd( p ), 0xffff, 1 );
 	}
 
-	if( instance[instance_id].vars )
-		db_destroy(instance[instance_id].vars);
+	if( im->vars ) {
+		db_destroy(im->vars);
+		im->vars = NULL;
+	}
+
+	im->type = 0;
+	im->state = INSTANCE_FREE;
+	im->party_id = 0;
+	im->keep_limit = 0;
+	im->idle_limit = 0;
+	ShowInfo("[Instance] Destroyed %d.\n", instance_data[i].map);
 
-	if( instance[instance_id].progress_timer != INVALID_TIMER )
-		delete_timer( instance[instance_id].progress_timer, instance_destroy_timer);
-	if( instance[instance_id].idle_timer != INVALID_TIMER )
-		delete_timer( instance[instance_id].idle_timer, instance_destroy_timer);
+	memset(instance_data[i].map, 0, sizeof(instance_data[i].map));
 
-	instance[instance_id].vars = NULL;
+	return 0;
+}
 
-	if( instance[instance_id].party_id && (p = party_search(instance[instance_id].party_id)) != NULL )
-		p->instance_id = 0; // Update Party information
+/*==========================================
+ * Allows a user to enter an instance
+ *------------------------------------------*/
+int instance_enter(struct map_session_data *sd, const char *name)
+{
+	struct instance_data *im;
+	struct instance_db *db = instance_searchname_db(name);
+	struct party_data *p;
+	int m;
 
-	ShowInfo("[Instance] Destroyed %s.\n", instance[instance_id].name);
-	memset( &instance[instance_id], 0x00, sizeof(instance[0]) );
+	nullpo_retr(-1, sd);
 
-	instance[instance_id].state = INSTANCE_FREE;
+	if(db == NULL)
+		return 1;
+
+	// Character must be in instance party
+	if(sd->status.party_id == 0)
+		return 2;
+	if((p = party_search(sd->status.party_id)) == NULL)
+		return 2;
+
+	// Party must have an instance
+	if(p->instance_id == 0)
+		return 3;
+
+	im = &instance_data[p->instance_id];
+	if(im->party_id != p->party.party_id)
+		return 3;
+	if(im->state != INSTANCE_BUSY)
+		return 3;
+	if(im->type != db->type)
+		return 3;
+
+	// Does the instance match?
+	if((m = instance_mapname2mapid(db->enter.mapname, p->instance_id)) < 0)
+		return 4;
+
+	if(pc_setpos(sd, m, db->enter.x, db->enter.y, 0))
+		return 4;
+
+	// If there was an idle timer, let's stop it
+	instance_stopidletimer(im);
+
+	// Now we start the instance timer
+	instance_startkeeptimer(im, p->instance_id);
+
+	return 0;
 }
 
-/*--------------------------------------
- * Checks if there are users in the instance or not to start idle timer
- *--------------------------------------*/
-void instance_check_idle(int instance_id)
+/*==========================================
+ * Request some info about the instance
+ *------------------------------------------*/
+int instance_reqinfo(struct map_session_data *sd, short instance_id)
+{
+	struct instance_data *im;
+	struct instance_db *db;
+	int i;
+
+	nullpo_retr(1, sd);
+
+	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
+		return 1;
+
+	im = &instance_data[instance_id];
+
+	if((db = instance_searchtype_db(im->type)) == NULL)
+		return 1;
+
+	// Say it's created if instance is not busy
+	if(im->state == INSTANCE_IDLE) {
+		for(i = 0; i < instance_wait.count; i++) {
+			if(instance_wait.id[i] == instance_id) {
+				clif_instance_create(sd, db->name, i+1, 0);
+				break;
+			}
+		}
+	} else if(im->state == INSTANCE_BUSY) // Give info on the instance if busy
+		clif_instance_status(sd, db->name, im->keep_limit, im->idle_limit, 0);
+
+	return 0;
+}
+
+/*==========================================
+ * Add players to the instance (for timers)
+ *------------------------------------------*/
+int instance_addusers(short instance_id)
 {
-	bool idle = true;
-	time_t now = time(NULL);
+	struct instance_data *im;
 
-	if( !instance_is_valid(instance_id) || instance[instance_id].idle_timeoutval == 0 )
-		return;
+	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
+		return 1;
 
-	if( instance[instance_id].users )
-		idle = false;
+	im = &instance_data[instance_id];
+	if(im->state != INSTANCE_BUSY)
+		return 1;
 
-	if( instance[instance_id].idle_timer != INVALID_TIMER && !idle )
-	{
-		delete_timer(instance[instance_id].idle_timer, instance_destroy_timer);
-		instance[instance_id].idle_timer = INVALID_TIMER;
-		instance[instance_id].idle_timeout = 0;
-		clif_instance(instance_id, 3, 0); // Notify instance users normal instance expiration
-	}
-	else if( instance[instance_id].idle_timer == INVALID_TIMER && idle )
-	{
-		instance[instance_id].idle_timeout = now + instance[instance_id].idle_timeoutval;
-		instance[instance_id].idle_timer = add_timer( gettick() + (unsigned int)instance[instance_id].idle_timeoutval * 1000, instance_destroy_timer, instance_id, 0);
-		clif_instance(instance_id, 4, 0); // Notify instance users it will be destroyed of no user join it again in "X" time
-	}
+	// Stop the idle timer if we had one
+	instance_stopidletimer(im);
+
+	// Start the instance keep timer
+	instance_startkeeptimer(im, instance_id);
+
+	return 0;
 }
 
-/*--------------------------------------
- * Set instance Timers
- *--------------------------------------*/
-void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout)
+/*==========================================
+ * Delete players from the instance (for timers)
+ *------------------------------------------*/
+int instance_delusers(short instance_id)
 {
-	time_t now = time(0);
+	struct instance_data *im;
+	int i, idle = 0;
 
-	if( !instance_is_valid(instance_id) )
-		return;
+	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
+		return 1;
 
-	if( instance[instance_id].progress_timer != INVALID_TIMER )
-		delete_timer( instance[instance_id].progress_timer, instance_destroy_timer);
-	if( instance[instance_id].idle_timer != INVALID_TIMER )
-		delete_timer( instance[instance_id].idle_timer, instance_destroy_timer);
+	im = &instance_data[instance_id];
+	if(im->state != INSTANCE_BUSY)
+		return 1;
 
-	if( progress_timeout )
-	{
-		instance[instance_id].progress_timeout = now + progress_timeout;
-		instance[instance_id].progress_timer = add_timer( gettick() + progress_timeout * 1000, instance_destroy_timer, instance_id, 0);
-	}
-	else
-	{
-		instance[instance_id].progress_timeout = 0;
-		instance[instance_id].progress_timer = INVALID_TIMER;
-	}
+	// If no one is in the instance, start the idle timer
+	for(i = 0; im->map[i].m && i < MAX_MAP_PER_INSTANCE; i++)
+		if(map[im->map[i].m].users > 1) // We check this before the actual map.users are updated, hence the 1
+			idle++;
 
-	if( idle_timeout )
-	{
-		instance[instance_id].idle_timeoutval = idle_timeout;
-		instance[instance_id].idle_timer = INVALID_TIMER;
-		instance_check_idle(instance_id);
-	}
-	else
-	{
-		instance[instance_id].idle_timeoutval = 0;
-		instance[instance_id].idle_timeout = 0;
-		instance[instance_id].idle_timer = INVALID_TIMER;
-	}
+	if(!idle) // If idle wasn't added to, we know no one was in the instance
+		instance_startidletimer(im, instance_id);
+
+	return 0;
+}
 
-	if( instance[instance_id].idle_timer == INVALID_TIMER && instance[instance_id].progress_timer != INVALID_TIMER )
-		clif_instance(instance_id, 3, 0);
+/*==========================================
+ * Read the instance_db.txt file
+ *------------------------------------------*/
+static bool instance_readdb_sub(char* str[], int columns, int current)
+{
+	int i, type, k=0;
+
+	type=atoi(str[0]);
+
+	instance_db[type].type=type;
+	safestrncpy(instance_db[type].name, str[1], 24);
+	instance_db[type].limit=atoi(str[2]);
+	safestrncpy(instance_db[type].enter.mapname, str[3], MAP_NAME_LENGTH);
+	instance_db[type].enter.x=atoi(str[4]);
+	instance_db[type].enter.y=atoi(str[5]);
+
+	//Instance maps
+	for(i=6; i<columns; i++)
+		if(strlen(str[i])) {
+			safestrncpy(instance_db[type].mapname[k], str[i], MAP_NAME_LENGTH);
+			k++;
+		}
+
+	return true;
 }
 
-/*--------------------------------------
- * Checks if sd in on a instance and should be kicked from it
- *--------------------------------------*/
-void instance_check_kick(struct map_session_data *sd)
+void instance_readdb(void)
 {
-	int16 m = sd->bl.m;
 
-	clif_instance_leave(sd->fd);
-	if( map[m].instance_id )
-	{ // User was on the instance map
-		if( map[m].save.map )
-			pc_setpos(sd, map[m].save.map, map[m].save.x, map[m].save.y, CLR_TELEPORT);
-		else
-			pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
-	}
+	memset(&instance_db, 0, sizeof(instance_db));
+	sv_readdb(db_path, DBPATH"instance_db.txt", ',', 7, 7+MAX_MAP_PER_INSTANCE, MAX_INSTANCE_DB, &instance_readdb_sub);
+
 }
 
-void do_final_instance(void)
+/*==========================================
+ * Reloads the instance in runtime (reloadscript)
+ *------------------------------------------*/
+void do_reload_instance(void)
 {
+	struct instance_data *im;
+	struct instance_db *db;
+	struct s_mapiterator* iter;
+	struct map_session_data *sd;
 	int i;
 
-	for( i = 1; i < MAX_INSTANCE; i++ )
-		instance_destroy(i);
+	for( i = 1; i < MAX_INSTANCE_DATA; i++ ) {
+		im = &instance_data[i];
+		if(!im->cnt_map)
+			continue;
+		else {
+			// First we load the NPCs again
+			instance_addnpc(im);
+
+			// Create new keep timer
+			if((db = instance_searchtype_db(im->type)) != NULL)
+				im->keep_limit = (unsigned int)time(NULL) + db->limit;
+		}
+	}
+
+	// Reset player to instance beginning
+	iter = mapit_getallusers();
+	for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
+		if(sd && map[sd->bl.m].instance_id) {
+			struct party_data *p;
+			if(!(p = party_search(sd->status.party_id)) || p->instance_id != map[sd->bl.m].instance_id) // Someone not in party is on instance map
+				continue;
+			im = &instance_data[p->instance_id];
+			if((db = instance_searchtype_db(im->type)) != NULL && !instance_enter(sd,db->name)) { // All good
+				clif_displaymessage(sd->fd, msg_txt(sd,515)); // Instance has been reloaded
+				instance_reqinfo(sd,p->instance_id);
+			} else // Something went wrong
+				ShowError("do_reload_instance: Error setting character at instance start: character_id=%d instance=%s.\n",sd->status.char_id,db->name);
+		}
+	mapit_free(iter);
 }
 
 void do_init_instance(void)
 {
-	memset(instance, 0x00, sizeof(instance));
-	add_timer_func_list(instance_destroy_timer, "instance_destroy_timer");
+	instance_readdb();
+	memset(instance_data, 0, sizeof(instance_data));
+	memset(&instance_wait, 0, sizeof(instance_wait));
+	instance_wait.timer = -1;
+
+	add_timer_func_list(instance_delete_timer,"instance_delete_timer");
+	add_timer_func_list(instance_subscription_timer,"instance_subscription_timer");
+}
+
+void do_final_instance(void)
+{
+	int i;
+
+	for( i = 1; i < MAX_INSTANCE_DATA; i++ )
+		instance_destroy(i);
 }

+ 26 - 29
src/map/instance.h

@@ -4,48 +4,45 @@
 #ifndef _INSTANCE_H_
 #define _INSTANCE_H_
 
-#define MAX_MAP_PER_INSTANCE 10
-#define MAX_INSTANCE 500
+#define MAX_INSTANCE_DATA	300	// Essentially how many instances we can create, but instance creation is primarily decided by MAX_MAP_PER_SERVER	
+#define MAX_MAP_PER_INSTANCE 	10	// Max number of maps per instance
 
 #define INSTANCE_NAME_LENGTH (60+1)
 
 typedef enum instance_state { INSTANCE_FREE, INSTANCE_IDLE, INSTANCE_BUSY } instance_state;
 
-struct s_instance {
-	char name[INSTANCE_NAME_LENGTH]; // Instance Name - required for clif functions.
-	instance_state state;
-	short instance_id;
+struct instance_data {
+	short type, cnt_map;
+	int state;
 	int party_id;
-
-	int map[MAX_MAP_PER_INSTANCE];
-	int num_map;
-	int users;
+	unsigned int keep_limit;
+	int keep_timer;
+	unsigned int idle_limit;
+	int idle_timer;
 
 	struct DBMap* vars; // Instance Variable for scripts
-
-	int progress_timer;
-	time_t progress_timeout;
-
-	int idle_timer;
-	time_t idle_timeout, idle_timeoutval;
+	struct {
+		int m;
+		int src_m;
+	} map[MAX_MAP_PER_INSTANCE];
 };
 
 extern int instance_start;
-extern struct s_instance instance[MAX_INSTANCE];
+extern struct instance_data instance_data[MAX_INSTANCE_DATA];
 
 int instance_create(int party_id, const char *name);
-int instance_add_map(const char *name, int instance_id, bool usebasename);
-void instance_del_map(int16 m);
-int instance_map2imap(int16 m, int instance_id);
-int instance_mapid2imapid(int16 m, int instance_id);
-void instance_destroy(int instance_id);
-void instance_init(int instance_id);
-
-void instance_check_idle(int instance_id);
-void instance_check_kick(struct map_session_data *sd);
-void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout);
-
-void do_final_instance(void);
+int instance_destroy(short instance_id);
+int instance_enter(struct map_session_data *sd, const char *name);
+int instance_reqinfo(struct map_session_data *sd, short instance_id);
+int instance_addusers(short instance_id);
+int instance_delusers(short instance_id);
+int instance_mapname2mapid(const char *name, short instance_id);
+int instance_addmap(short instance_id);
+
+void instance_addnpc(struct instance_data *im);
+void instance_readdb(void);
+void do_reload_instance(void);
 void do_init_instance(void);
+void do_final_instance(void);
 
 #endif

+ 140 - 1
src/map/map.c

@@ -1700,6 +1700,9 @@ int map_quit(struct map_session_data *sd) {
 
 	if (sd->state.permanent_speed == 1) sd->state.permanent_speed = 0; // Remove lock so speed is set back to normal at login.
 
+	if( map[sd->bl.m].instance_id )
+		instance_delusers(map[sd->bl.m].instance_id);
+
 	if( sd->ed ) {
 		elemental_clean_effect(sd->ed);
 		unit_remove_map(&sd->ed->bl,CLR_TELEPORT);
@@ -2171,6 +2174,142 @@ bool map_addnpc(int16 m,struct npc_data *nd)
 	return true;
 }
 
+/*==========================================
+ * Add an instance map
+ *------------------------------------------*/
+int map_addinstancemap(const char *name, int id)
+{
+	int src_m = map_mapname2mapid(name);
+	int dst_m = -1, i;
+	size_t size;
+
+	if(src_m < 0)
+		return -1;
+
+	if(strlen(name) > 20) {
+		// against buffer overflow
+		ShowError("map_addisntancemap: can't add long map name \"%s\"\n", name);
+		return -2;
+	}
+
+	for(i = instance_start; i < MAX_MAP_PER_SERVER; i++) {
+		if(!map[i].name[0])
+			break;
+	}
+	if(i < map_num) // Destination map value overwrites another
+		dst_m = i;
+	else if(i < MAX_MAP_PER_SERVER) // Destination map value increments to new map
+		dst_m = map_num++;
+	else {
+		// Out of bounds
+		ShowError("map_addinstancemap failed. map_num(%d) > map_max(%d)\n",map_num, MAX_MAP_PER_SERVER);
+		return -3;
+	}
+
+	// Copy the map
+	memcpy(&map[dst_m], &map[src_m], sizeof(struct map_data));
+
+	// Alter the name
+	snprintf(map[dst_m].name, sizeof(map[dst_m].name), ((strchr(name,'@') == NULL)?"%.3d#%s":"%.3d%s"), id, name);
+	map[dst_m].name[MAP_NAME_LENGTH-1] = '\0';
+
+	map[dst_m].m = dst_m;
+	map[dst_m].instance_id = id;
+	map[dst_m].users = 0;
+
+	memset(map[dst_m].npc, 0, sizeof(map[dst_m].npc));
+	map[dst_m].npc_num = 0;
+
+	size = map[dst_m].bxs * map[dst_m].bys * sizeof(struct block_list*);
+	map[dst_m].block = (struct block_list **)aCalloc(1,size);
+	map[dst_m].block_mob = (struct block_list **)aCalloc(1,size);
+
+	map[dst_m].index = mapindex_addmap(-1, map[dst_m].name);
+
+	map_addmap2db(&map[dst_m]);
+
+	return dst_m;
+}
+
+/*==========================================
+ * Set player to save point when they leave
+ *------------------------------------------*/
+static int map_instancemap_leave(struct block_list *bl, va_list ap)
+{
+	struct map_session_data* sd;
+
+	nullpo_retr(0, bl);
+	nullpo_retr(0, sd = (struct map_session_data *)bl);
+
+	pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, 3);
+
+	return 1;
+}
+
+/*==========================================
+ * Remove all units from instance
+ *------------------------------------------*/
+static int map_instancemap_clean(struct block_list *bl, va_list ap)
+{
+	nullpo_retr(0, bl);
+	switch(bl->type) {
+		case BL_PC:
+			map_quit((struct map_session_data *) bl);
+			break;
+		case BL_NPC:
+			npc_unload((struct npc_data *)bl,true);
+			break;
+		case BL_MOB:
+			unit_free(bl,CLR_OUTSIGHT);
+			break;
+		case BL_PET:
+			//There is no need for this, the pet is removed together with the player. [Skotlex]
+			break;
+		case BL_ITEM:
+			map_clearflooritem(bl);
+			break;
+		case BL_SKILL:
+			skill_delunit((struct skill_unit *) bl);
+			break;
+	}
+
+	return 1;
+}
+
+/*==========================================
+ * Deleting an instance map
+ *------------------------------------------*/
+int map_delinstancemap(int m)
+{
+	if(m < 0)
+		return 0;
+	if(map[m].instance_id == 0)
+		return 0;
+
+	// Kick everyone out
+	map_foreachinmap(map_instancemap_leave, m, BL_PC);
+
+	// Do the unit cleanup
+	map_foreachinmap(map_instancemap_clean, m, BL_ALL);
+
+	if( map[m].mob_delete_timer != INVALID_TIMER )
+		delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
+
+	mapindex_removemap( map[m].index );
+
+	// Free memory
+	aFree(map[m].block);
+	aFree(map[m].block_mob);
+
+	map_removemapdb(&map[m]);
+	memset(&map[m], 0x00, sizeof(map[0]));
+
+	// Make delete timers invalid to avoid errors
+	map[m].mob_delete_timer = INVALID_TIMER;
+
+	return 1;
+}
+
 /*=========================================
  * Dynamic Mobs [Wizputer]
  *-----------------------------------------*/
@@ -3086,7 +3225,7 @@ int map_readallmaps (void)
 
 	// finished map loading
 	ShowInfo("Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps."CL_CLL"\n",map_num);
-	instance_start = map_num; // Next Map Index will be instances
+	instance_start = map_num + 1; // Next Map Index will be instances
 
 	if (maps_removed)
 		ShowNotice("Maps removed: '"CL_WHITE"%d"CL_RESET"'\n",maps_removed);

+ 7 - 4
src/map/map.h

@@ -37,7 +37,7 @@ void map_msg_reload(void);
 #define AREA_SIZE battle_config.area_size
 #define DAMAGELOG_SIZE 30
 #define LOOTITEM_SIZE 10
-#define MAX_MOBSKILL 50	//Max 128, see mob skill_idx type if need this higher
+#define MAX_MOBSKILL 50		//Max 128, see mob skill_idx type if need this higher
 #define MAX_MOB_LIST_PER_MAP 128
 #define MAX_EVENTQUEUE 2
 #define MAX_EVENTTIMER 32
@@ -46,9 +46,9 @@ void map_msg_reload(void);
 #define MAX_FLOORITEM START_ACCOUNT_NUM
 #define MAX_LEVEL 160
 #define MAX_DROP_PER_MAP 48
-#define MAX_IGNORE_LIST 20 // official is 14
+#define MAX_IGNORE_LIST 20 	// official is 14
 #define MAX_VENDING 12
-#define MAX_MAP_SIZE 512*512 // Wasn't there something like this already? Can't find it.. [Shinryo]
+#define MAX_MAP_SIZE 512*512 	// Wasn't there something like this already? Can't find it.. [Shinryo]
 
 // Added definitions for WoESE objects. [L0ne_W0lf]
 enum MOBID {
@@ -573,7 +573,6 @@ struct map_data {
 		unsigned nochat :1;
 		unsigned partylock :1;
 		unsigned guildlock :1;
-		unsigned src4instance : 1; // To flag this map when it's used as a src map for instances
 		unsigned reset :1; // [Daegaladh]
 		unsigned chmautojoin : 1; //prevent to auto join map channel
 		unsigned nousecart : 1;	//prevent open up cart @FIXME client side only atm
@@ -684,6 +683,10 @@ int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data);
 void map_clearflooritem(struct block_list* bl);
 int map_addflooritem(struct item *item_data,int amount,int16 m,int16 x,int16 y,int first_charid,int second_charid,int third_charid,int flags);
 
+// instances
+int map_addinstancemap(const char*,int);
+int map_delinstancemap(int);
+
 // player to map session
 void map_addnickdb(int charid, const char* nick);
 void map_delnickdb(int charid, const char* nick);

+ 68 - 61
src/map/npc.c

@@ -2579,15 +2579,11 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
 	type = dnd->subtype;
 
 	// get placement
-	if( (type==SHOP || type==CASHSHOP || type==SCRIPT) && strcmp(w1, "-") == 0 )
-	{// floating shop/chashshop/script
+	if( (type==SHOP || type==CASHSHOP || type==SCRIPT) && strcmp(w1, "-") == 0 ) {// floating shop/chashshop/script
 		x = y = dir = 0;
 		m = -1;
-	}
-	else
-	{
-		if( sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 )// <map name>,<x>,<y>,<facing>
-		{
+	} else {
+		if( sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 ) { // <map name>,<x>,<y>,<facing>
 			ShowError("npc_parse_duplicate: Invalid placement format for duplicate in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
 			return end;// next line, try to continue
 		}
@@ -2601,8 +2597,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
 	if( type == WARP && sscanf(w4, "%d,%d", &xs, &ys) == 2 );// <spanx>,<spany>
 	else if( type == SCRIPT && sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3);// <sprite id>,<triggerX>,<triggerY>
 	else if( type != WARP ) class_ = atoi(w4);// <sprite id>
-	else
-	{
+	else {
 		ShowError("npc_parse_duplicate: Invalid span format for duplicate warp in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4);
 		return end;// next line, try to continue
 	}
@@ -2620,56 +2615,51 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
 	nd->src_id = src_id;
 	nd->bl.type = BL_NPC;
 	nd->subtype = (enum npc_subtype)type;
-	switch( type )
-	{
-	case SCRIPT:
-		++npc_script;
-		nd->u.scr.xs = xs;
-		nd->u.scr.ys = ys;
-		nd->u.scr.script = dnd->u.scr.script;
-		nd->u.scr.label_list = dnd->u.scr.label_list;
-		nd->u.scr.label_list_num = dnd->u.scr.label_list_num;
-		break;
+	switch( type ) {
+		case SCRIPT:
+			++npc_script;
+			nd->u.scr.xs = xs;
+			nd->u.scr.ys = ys;
+			nd->u.scr.script = dnd->u.scr.script;
+			nd->u.scr.label_list = dnd->u.scr.label_list;
+			nd->u.scr.label_list_num = dnd->u.scr.label_list_num;
+			break;
 
-	case SHOP:
-	case CASHSHOP:
-		++npc_shop;
-		nd->u.shop.shop_item = dnd->u.shop.shop_item;
-		nd->u.shop.count = dnd->u.shop.count;
-		break;
+		case SHOP:
+		case CASHSHOP:
+			++npc_shop;
+			nd->u.shop.shop_item = dnd->u.shop.shop_item;
+			nd->u.shop.count = dnd->u.shop.count;
+			break;
 
-	case WARP:
-		++npc_warp;
-		if( !battle_config.warp_point_debug )
-			nd->class_ = WARP_CLASS;
-		else
-			nd->class_ = WARP_DEBUG_CLASS;
-		nd->u.warp.xs = xs;
-		nd->u.warp.ys = ys;
-		nd->u.warp.mapindex = dnd->u.warp.mapindex;
-		nd->u.warp.x = dnd->u.warp.x;
-		nd->u.warp.y = dnd->u.warp.y;
-		break;
+		case WARP:
+			++npc_warp;
+			if( !battle_config.warp_point_debug )
+				nd->class_ = WARP_CLASS;
+			else
+				nd->class_ = WARP_DEBUG_CLASS;
+			nd->u.warp.xs = xs;
+			nd->u.warp.ys = ys;
+			nd->u.warp.mapindex = dnd->u.warp.mapindex;
+			nd->u.warp.x = dnd->u.warp.x;
+			nd->u.warp.y = dnd->u.warp.y;
+			break;
 	}
 
 	//Add the npc to its location
-	if( m >= 0 )
-	{
+	if( m >= 0 ) {
 		map_addnpc(m, nd);
 		status_change_init(&nd->bl);
 		unit_dataset(&nd->bl);
 		nd->ud.dir = dir;
 		npc_setcells(nd);
 		map_addblock(&nd->bl);
-		if( class_ >= 0 )
-		{
+		if( class_ >= 0 ) {
 			status_set_viewdata(&nd->bl, nd->class_);
 			if( map[nd->bl.m].users )
 				clif_spawn(&nd->bl);
 		}
-	}
-	else
-	{
+	} else {
 		// we skip map_addnpc, but still add it to the list of ID's
 		map_addiddb(&nd->bl);
 	}
@@ -2688,6 +2678,9 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch
 		npc_timerevent_export(nd, i);
 	}
 
+	if(!strcmp(filepath,"INSTANCING")) //Instance NPCs will use this for commands
+		nd->instance_id = map[m].instance_id;
+
 	nd->u.scr.timerid = INVALID_TIMER;
 
 	return end;
@@ -2700,21 +2693,27 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
 		return 1;
 
 	snprintf(newname, ARRAYLENGTH(newname), "dup_%d_%d", map[m].instance_id, snd->bl.id);
-	if( npc_name2id(newname) != NULL )
-	{ // Name already in use
+	if( npc_name2id(newname) != NULL ) { // Name already in use
 		ShowError("npc_duplicate4instance: the npcname (%s) is already in use while trying to duplicate npc %s in instance %d.\n", newname, snd->exname, map[m].instance_id);
 		return 1;
 	}
 
-	if( snd->subtype == WARP )
-	{ // Adjust destination, if instanced
+	if( snd->subtype == WARP ) { // Adjust destination, if instanced
 		struct npc_data *wnd = NULL; // New NPC
-		int dm = map_mapindex2mapid(snd->u.warp.mapindex), im;
+		struct instance_data *im = &instance_data[map[m].instance_id];
+		int dm = map_mapindex2mapid(snd->u.warp.mapindex), imap = 0, i;
 		if( dm < 0 ) return 1;
 
-		im = instance_mapid2imapid(dm, map[m].instance_id);
-		if( im == -1 )
-		{
+		for(i = 0; i < MAX_MAP_PER_INSTANCE; i++)
+			if(im->map[i].m && map_mapname2mapid(map[im->map[i].src_m].name) == dm) {
+				imap = map_mapname2mapid(map[m].name);
+				break; // Instance map matches destination, update to instance map
+			}
+
+		if(!imap)
+			imap = map_mapname2mapid(map[dm].name);
+	
+		if( imap == -1 ) {
 			ShowError("npc_duplicate4instance: warp (%s) leading to instanced map (%s), but instance map is not attached to current instance.\n", map[dm].name, snd->exname);
 			return 1;
 		}
@@ -2730,7 +2729,7 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
 		safestrncpy(wnd->exname, newname, ARRAYLENGTH(wnd->exname));
 		wnd->class_ = WARP_CLASS;
 		wnd->speed = 200;
-		wnd->u.warp.mapindex = map_id2index(im);
+		wnd->u.warp.mapindex = map_id2index(imap);
 		wnd->u.warp.x = snd->u.warp.x;
 		wnd->u.warp.y = snd->u.warp.y;
 		wnd->u.warp.xs = snd->u.warp.xs;
@@ -2745,9 +2744,7 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
 		if( map[wnd->bl.m].users )
 			clif_spawn(&wnd->bl);
 		strdb_put(npcname_db, wnd->exname, wnd);
-	}
-	else
-	{
+	} else {
 		static char w1[50], w2[50], w3[50], w4[50];
 		const char* stat_buf = "- call from instancing subsystem -\n";
 
@@ -2766,6 +2763,19 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) {
 	return 0;
 }
 
+int npc_instanceinit(struct npc_data* nd)
+{
+	struct event_data *ev;
+	char evname[EVENT_NAME_LENGTH];
+
+	snprintf(evname, ARRAYLENGTH(evname), "%s::OnInstanceInit", nd->exname);
+
+	if( ( ev = (struct event_data*)strdb_get(ev_db, evname) ) )
+		run_script(nd->u.scr.script,ev->pos,0,nd->bl.id);
+
+	return 0;
+}
+
 //Set mapcell CELL_NPC to trigger event later
 void npc_setcells(struct npc_data* nd)
 {
@@ -3772,14 +3782,11 @@ int npc_reload(void) {
 		"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
 		npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
 
-	do_final_instance();
-
-	for( i = 0; i < ARRAYLENGTH(instance); ++i )
-		instance_init(instance[i].instance_id);
-
 	//Re-read the NPC Script Events cache.
 	npc_read_event_script();
 
+	do_reload_instance();
+
 	/* refresh guild castle flags on both woe setups */
 	npc_event_doall("OnAgitInit");
 	npc_event_doall("OnAgitInit2");

+ 4 - 6
src/map/npc.h

@@ -29,19 +29,16 @@ struct npc_data {
 	struct view_data *vd;
 	struct status_change sc; //They can't have status changes, but.. they want the visual opt values.
 	struct npc_data *master_nd;
-	short class_;
-	short speed;
+	short class_,speed,instance_id;
 	char name[NAME_LENGTH+1];// display name
 	char exname[NAME_LENGTH+1];// unique npc name
-	int chat_id;
-	int touching_id;
+	int chat_id,touching_id;
 	unsigned int next_walktime;
 
 	unsigned size : 2;
 
 	struct status_data status;
-	unsigned int level;
-	unsigned int stat_point;
+	unsigned int level,stat_point;
 
 	void* chatdb; // pointer to a npc_parse struct (see npc_chat.c)
 	char* path;/* path dir */
@@ -169,6 +166,7 @@ void npc_read_event_script(void);
 int npc_script_event(struct map_session_data* sd, enum npce_event type);
 
 int npc_duplicate4instance(struct npc_data *snd, int16 m);
+int npc_instanceinit(struct npc_data* nd);
 int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int points);
 
 extern struct npc_data* fake_nd;

+ 14 - 6
src/map/party.c

@@ -320,7 +320,7 @@ int party_recv_info(struct party* sp, int char_id)
 		clif_party_option(p,sd,0x100);
 		clif_party_info(p,NULL);
 		if( p->instance_id != 0 )
-			clif_instance_join(sd->fd, p->instance_id);
+			instance_reqinfo(sd,p->instance_id);
 	}
 	if( char_id != 0 )// requester
 	{
@@ -439,7 +439,7 @@ void party_member_joined(struct map_session_data *sd)
 	{
 		p->data[i].sd = sd;
 		if( p->instance_id )
-			clif_instance_join(sd->fd,p->instance_id);
+			instance_reqinfo(sd,p->instance_id);
 	}
 	else
 		sd->status.party_id = 0; //He does not belongs to the party really?
@@ -498,7 +498,7 @@ int party_member_added(int party_id,int account_id,int char_id, int flag)
 	clif_charnameupdate(sd); //Update char name's display [Skotlex]
 
 	if( p->instance_id )
-		clif_instance_join(sd->fd, p->instance_id);
+		instance_reqinfo(sd,p->instance_id);
 
 	return 0;
 }
@@ -575,8 +575,16 @@ int party_member_withdraw(int party_id, int account_id, int char_id)
 		sd->status.party_id = 0;
 		clif_charnameupdate(sd); //Update name display [Skotlex]
 		//TODO: hp bars should be cleared too
-		if( p->instance_id )
-			instance_check_kick(sd);
+		if( p->instance_id ) {
+			int16 m = sd->bl.m;
+
+			if( map[m].instance_id ) { // User was on the instance map
+				if( map[m].save.map )
+					pc_setpos(sd, map[m].save.map, map[m].save.x, map[m].save.y, CLR_TELEPORT);
+				else
+					pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
+			}
+		}
 	}
 
 	return 0;
@@ -594,7 +602,7 @@ int party_broken(int party_id)
 
 	if( p->instance_id )
 	{
-		instance[p->instance_id].party_id = 0;
+		instance_data[p->instance_id].party_id = 0;
 		instance_destroy( p->instance_id );
 	}
 

+ 8 - 17
src/map/pc.c

@@ -4757,39 +4757,30 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *target)
  *------------------------------------------*/
 int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype)
 {
-	struct party_data *p;
 	int16 m;
 
 	nullpo_ret(sd);
 
-	if( !mapindex || !mapindex_id2name(mapindex) )
-	{
+	if( !mapindex || !mapindex_id2name(mapindex) ) {
 		ShowDebug("pc_setpos: Passed mapindex(%d) is invalid!\n", mapindex);
 		return 1;
 	}
 
-	if( pc_isdead(sd) )
-	{ //Revive dead people before warping them
+	if( pc_isdead(sd) ) { //Revive dead people before warping them
 		pc_setstand(sd);
 		pc_setrestartvalue(sd,1);
 	}
 
 	m = map_mapindex2mapid(mapindex);
-	if( map[m].flag.src4instance && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
-	{
-		// Request the mapid of this src map into the instance of the party
-		int im = instance_map2imap(m, p->instance_id);
-		if( im < 0 )
-			; // Player will enter the src map for instances
-		else
-		{ // Changes destiny to the instance map, not the source map
-			m = im;
-			mapindex = map_id2index(m);
-		}
-	}
 
 	sd->state.changemap = (sd->mapindex != mapindex);
 	sd->state.warping = 1;
+
+	if(sd->status.party_id && map[sd->bl.m].instance_id && sd->state.changemap && !map[m].instance_id) {
+		struct party_data *p;
+		if((p = party_search(sd->status.party_id)) != NULL && p->instance_id )
+			instance_delusers(p->instance_id);
+	}
 	if( sd->state.changemap ) { // Misc map-changing settings
 		int i;
 		sd->state.pmap = sd->bl.m;

+ 189 - 329
src/map/script.c

@@ -345,6 +345,7 @@ struct {
  *------------------------------------------*/
 const char* parse_subexpr(const char* p,int limit);
 int run_func(struct script_state *st);
+int script_instancegetid(struct script_state *st);
 
 enum {
 	MF_NOMEMO,	//0
@@ -2565,12 +2566,15 @@ void get_val(struct script_state* st, struct script_data* data)
 			}
 			break;
 		case '\'':
-				if (st->instance_id) {
-					data->u.str = (char*)idb_get(instance[st->instance_id].vars,reference_getuid(data));
-				} else {
+			{
+				int instance_id = script_instancegetid(st);
+				if( instance_id )
+					data->u.str = (char*)idb_get(instance_data[instance_id].vars,reference_getuid(data));
+				else {
 					ShowWarning("script:get_val: cannot access instance variable '%s', defaulting to \"\"\n", name);
 					data->u.str = NULL;
 				}
+			}
 			break;
 		default:
 			data->u.str = pc_readglobalreg_str(sd, name);
@@ -2630,12 +2634,15 @@ void get_val(struct script_state* st, struct script_data* data)
 			}
 			break;
 		case '\'':
-				if( st->instance_id )
-					data->u.num = (int)idb_iget(instance[st->instance_id].vars,reference_getuid(data));
+			{
+				int instance_id = script_instancegetid(st);
+				if( instance_id )
+					data->u.num = (int)idb_iget(instance_data[instance_id].vars,reference_getuid(data));
 				else {
 					ShowWarning("script:get_val: cannot access instance variable '%s', defaulting to 0\n", name);
 					data->u.num = 0;
 				}
+			}
 			break;
 		default:
 			data->u.num = pc_readglobalreg(sd, name);
@@ -2668,8 +2675,7 @@ static int set_reg(struct script_state* st, TBL_PC* sd, int num, const char* nam
 {
 	char prefix = name[0];
 
-	if( is_string_variable(name) )
-	{// string variable
+	if( is_string_variable(name) ) {// string variable
 		const char* str = (const char*)value;
 		switch (prefix) {
 		case '@':
@@ -2691,17 +2697,18 @@ static int set_reg(struct script_state* st, TBL_PC* sd, int num, const char* nam
 			}
 			return 1;
 		case '\'':
-			if( st->instance_id ) {
-				idb_remove(instance[st->instance_id].vars, num);
-				if( str[0] ) idb_put(instance[st->instance_id].vars, num, aStrdup(str));
-			}
+			{
+				int instance_id = script_instancegetid(st);
+				if( instance_id ) {
+					idb_remove(instance_data[instance_id].vars, num);
+					if( str[0] ) idb_put(instance_data[instance_id].vars, num, aStrdup(str));
+				}
 			return 1;
+			}
 		default:
 			return pc_setglobalreg_str(sd, name, str);
 		}
-	}
-	else
-	{// integer variable
+	} else {// integer variable
 		int val = (int)__64BPRTSIZE(value);
 		if(str_data[num&0x00ffffff].type == C_PARAM)
 		{
@@ -2739,12 +2746,15 @@ static int set_reg(struct script_state* st, TBL_PC* sd, int num, const char* nam
 			}
 			return 1;
 		case '\'':
-			if( st->instance_id ) {
-				idb_remove(instance[st->instance_id].vars, num);
-				if( val != 0 )
-					idb_iput(instance[st->instance_id].vars, num, val);
-			}
+			{
+				int instance_id = script_instancegetid(st);
+				if( instance_id ) {
+					idb_remove(instance_data[instance_id].vars, num);
+					if( val != 0 )
+						idb_iput(instance_data[instance_id].vars, num, val);
+				}
 			return 1;
+			}
 		default:
 			return pc_setglobalreg(sd, name, val);
 		}
@@ -3665,14 +3675,9 @@ void run_script_main(struct script_state *st)
 	int gotocount = script_config.check_gotocount;
 	TBL_PC *sd;
 	struct script_stack *stack=st->stack;
-	struct npc_data *nd;
 
 	script_attach_state(st);
 
-	nd = map_id2nd(st->oid);
-	if( nd && map[nd->bl.m].instance_id > 0 )
-		st->instance_id = map[nd->bl.m].instance_id;
-
 	if(st->state == RERUNLINE) {
 		run_func(st);
 		if(st->state == GOTO)
@@ -8815,34 +8820,28 @@ BUILDIN_FUNC(monster)
 	struct map_session_data* sd;
 	int16 m;
 
-	if (script_hasdata(st, 8))
-	{
+	if (script_hasdata(st, 8)) {
 		event = script_getstr(st, 8);
 		check_event(st, event);
 	}
 
-	if (script_hasdata(st, 9))
-	{
+	if (script_hasdata(st, 9)) {
 		size = script_getnum(st, 9);
-		if (size > 3)
-		{
+		if (size > 3) {
 			ShowWarning("buildin_monster: Attempted to spawn non-existing size %d for monster class %d\n", size, class_);
 			return 1;
 		}
 	}
 
-	if (script_hasdata(st, 10))
-	{
+	if (script_hasdata(st, 10)) {
 		ai = script_getnum(st, 10);
-		if (ai > 4)
-		{
+		if (ai > 4) {
 			ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
 			return 1;
 		}
 	}
 
-	if (class_ >= 0 && !mobdb_checkid(class_))
-	{
+	if (class_ >= 0 && !mobdb_checkid(class_)) {
 		ShowWarning("buildin_monster: Attempted to spawn non-existing monster class %d\n", class_);
 		return 1;
 	}
@@ -8852,17 +8851,7 @@ BUILDIN_FUNC(monster)
 	if (sd && strcmp(mapn, "this") == 0)
 		m = sd->bl.m;
 	else
-	{
 		m = map_mapname2mapid(mapn);
-		if (map[m].flag.src4instance && st->instance_id)
-		{ // Try to redirect to the instance map, not the src map
-			if ((m = instance_mapid2imapid(m, st->instance_id)) < 0)
-			{
-				ShowError("buildin_monster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
-				return 1;
-			}
-		}
-	}
 
 	mob_once_spawn(sd, m, x, y, str, class_, amount, event, size, ai);
 	return 0;
@@ -8922,27 +8911,22 @@ BUILDIN_FUNC(areamonster)
 	struct map_session_data* sd;
 	int16 m;
 
-	if (script_hasdata(st,10))
-	{
+	if (script_hasdata(st,10)) {
 		event = script_getstr(st, 10);
 		check_event(st, event);
 	}
 
-	if (script_hasdata(st, 11))
-	{
+	if (script_hasdata(st, 11)) {
 		size = script_getnum(st, 11);
-		if (size > 3)
-		{
+		if (size > 3) {
 			ShowWarning("buildin_monster: Attempted to spawn non-existing size %d for monster class %d\n", size, class_);
 			return 1;
 		}
 	}
 
-	if (script_hasdata(st, 12))
-	{
+	if (script_hasdata(st, 12)) {
 		ai = script_getnum(st, 12);
-		if (ai > 4)
-		{
+		if (ai > 4) {
 			ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
 			return 1;
 		}
@@ -8953,17 +8937,7 @@ BUILDIN_FUNC(areamonster)
 	if (sd && strcmp(mapn, "this") == 0)
 		m = sd->bl.m;
 	else
-	{
 		m = map_mapname2mapid(mapn);
-		if (map[m].flag.src4instance && st->instance_id)
-		{ // Try to redirect to the instance map, not the src map
-			if ((m = instance_mapid2imapid(m, st->instance_id)) < 0)
-			{
-				ShowError("buildin_areamonster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
-				return 1;
-			}
-		}
-	}
 
 	mob_once_spawn_area(sd, m, x0, y0, x1, y1, str, class_, amount, event, size, ai);
 	return 0;
@@ -9018,9 +8992,6 @@ BUILDIN_FUNC(killmonster)
 	if( (m=map_mapname2mapid(mapname))<0 )
 		return 0;
 
-	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
-		return 0;
-
 	if( script_hasdata(st,4) ) {
 		if ( script_getnum(st,4) == 1 ) {
 			map_foreachinmap(buildin_killmonster_sub, m, BL_MOB, event ,allflag);
@@ -9059,9 +9030,6 @@ BUILDIN_FUNC(killmonsterall)
 	if( (m = map_mapname2mapid(mapname))<0 )
 		return 0;
 
-	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
-		return 0;
-
 	if( script_hasdata(st,3) ) {
 		if ( script_getnum(st,3) == 1 ) {
 			map_foreachinmap(buildin_killmonsterall_sub,m,BL_MOB);
@@ -11569,12 +11537,6 @@ BUILDIN_FUNC(mobcount)	// Added by RoVeRT
 		return 0;
 	}
 
-	if( map[m].flag.src4instance && map[m].instance_id == 0 && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
-	{
-		script_pushint(st,-1);
-		return 0;
-	}
-
 	script_pushint(st,map_foreachinmap(buildin_mobcount_sub, m, BL_MOB, event));
 
 	return 0;
@@ -16475,249 +16437,130 @@ BUILDIN_FUNC(bg_get_data)
 }
 
 /*==========================================
- * Instancing Script Commands
+ * Instancing System
  *------------------------------------------*/
-
-BUILDIN_FUNC(instance_create)
-{
-	const char *name;
-	int party_id, res;
-
-	name = script_getstr(st, 2);
-	party_id = script_getnum(st, 3);
-
-	res = instance_create(party_id, name);
-	if( res == -4 ) // Already exists
-	{
-		script_pushint(st, -1);
-		return 0;
-	}
-	else if( res < 0 )
-	{
-		const char *err;
-		switch(res)
-		{
-		case -3: err = "No free instances"; break;
-		case -2: err = "Invalid party ID"; break;
-		case -1: err = "Invalid type"; break;
-		default: err = "Unknown"; break;
-		}
-		ShowError("buildin_instance_create: %s [%d].\n", err, res);
-		script_pushint(st, -2);
-		return 0;
-	}
-
-	script_pushint(st, res);
-	return 0;
-}
-
-BUILDIN_FUNC(instance_destroy)
+//Returns an Instance ID
+//Checks NPC first, then if player is attached we check party
+int script_instancegetid(struct script_state* st)
 {
-	int instance_id;
-	struct map_session_data *sd;
-	struct party_data *p;
-
-	if( script_hasdata(st, 2) )
-		instance_id = script_getnum(st, 2);
-	else if( st->instance_id )
-		instance_id = st->instance_id;
-	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
-		instance_id = p->instance_id;
-	else return 0;
+	short instance_id = 0;	
 
-	if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
-	{
-		ShowError("buildin_instance_destroy: Trying to destroy invalid instance %d.\n", instance_id);
-		return 0;
+	struct npc_data *nd;
+	if( (nd = map_id2nd(st->oid)) && nd->instance_id > 0 )
+		instance_id = nd->instance_id;
+	else {
+		struct map_session_data *sd;
+		struct party_data *p;
+		if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
+			instance_id = p->instance_id;
 	}
 
-	instance_destroy(instance_id);
-	return 0;
+	return instance_id;
 }
 
-BUILDIN_FUNC(instance_attachmap)
+/*==========================================
+ * Creates the instance
+ * Returns Instance ID if created successfully
+ *------------------------------------------*/
+BUILDIN_FUNC(instance_create)
 {
-	const char *name;
-	int16 m;
-	int instance_id;
-	bool usebasename = false;
-
-	name = script_getstr(st,2);
-	instance_id = script_getnum(st,3);
-	if( script_hasdata(st,4) && script_getnum(st,4) > 0)
-		usebasename = true;
 
-	if( (m = instance_add_map(name, instance_id, usebasename)) < 0 ) // [Saithis]
-	{
-		ShowError("buildin_instance_attachmap: instance creation failed (%s): %d\n", name, m);
-		script_pushconststr(st, "");
-		return 0;
-	}
-	script_pushconststr(st, map[m].name);
-
-	return 0;
-}
-
-BUILDIN_FUNC(instance_detachmap)
-{
 	struct map_session_data *sd;
-	struct party_data *p;
-	const char *str;
-	int16 m;
-	int instance_id;
+	int res;
 
-	str = script_getstr(st, 2);
-	if( script_hasdata(st, 3) )
-		instance_id = script_getnum(st, 3);
-	else if( st->instance_id )
-		instance_id = st->instance_id;
-	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
-		instance_id = p->instance_id;
-	else return 0;
+	if((sd = script_rid2sd(st)) == NULL)
+		return -1;
 
-	if( (m = map_mapname2mapid(str)) < 0 || (m = instance_map2imap(m,instance_id)) < 0 )
-	{
-		ShowError("buildin_instance_detachmap: Trying to detach invalid map %s\n", str);
-		return 0;
+	if(!sd->status.party_id) {
+		ShowError("script:instance_create: attempting to start an instance with no attached party.\n");
+		return -1;
 	}
 
-	instance_del_map(m);
-	return 0;
-}
-
-BUILDIN_FUNC(instance_attach)
-{
-	int instance_id;
-
-	instance_id = script_getnum(st, 2);
-	if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
-		return 0;
-
-	st->instance_id = instance_id;
-	return 0;
-}
-
-BUILDIN_FUNC(instance_id)
-{
-	int instance_id;
-
-	if( script_hasdata(st, 2) )
-	{
-		struct map_session_data *sd;
-		struct party_data *p;
-		int type;
-		type = script_getnum(st, 2);
-		if( type == 0 )
-			instance_id = st->instance_id;
-		else if( type == 1 && (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL )
-			instance_id = p->instance_id;
-		else
-			instance_id = 0;
+	res = instance_create(sd->status.party_id, script_getstr(st, 2));
+	if( res < 0 ) {
+		const char *err;
+		switch(res) {
+			case -4: err = "No free instances"; break;
+			case -2: err = "Invalid party ID"; break;
+			case -1: err = "Invalid type"; break;
+			default: err = "Unknown"; break;
+		}
+		ShowError("script:instance_create: %s [%d].\n", err, res);
 	}
-	else
-		instance_id = st->instance_id;
 
-	script_pushint(st, instance_id);
+	script_pushint(st, res);
 	return 0;
 }
 
-BUILDIN_FUNC(instance_set_timeout)
+/*==========================================
+ * Destroys an instance (unofficial)
+ * Officially instances are only destroyed by timeout
+ *
+ * instance_destroy {<instance_id>};
+ *------------------------------------------*/
+BUILDIN_FUNC(instance_destroy)
 {
-	int progress_timeout, idle_timeout;
-	int instance_id;
-	struct map_session_data *sd;
-	struct party_data *p;
-
-	progress_timeout = script_getnum(st, 2);
-	idle_timeout = script_getnum(st, 3);
-
-	if( script_hasdata(st, 4) )
-		instance_id = script_getnum(st, 4);
-	else if( st->instance_id )
-		instance_id = st->instance_id;
-	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
-		instance_id = p->instance_id;
-	else return 0;
-
-	if( instance_id > 0 )
-		instance_set_timeout(instance_id, progress_timeout, idle_timeout);
+	short instance_id;
 
-	return 0;
-}
-
-BUILDIN_FUNC(instance_init)
-{
-	int instance_id = script_getnum(st, 2);
+	if( script_hasdata(st,2) )
+		instance_id = script_getnum(st,2);
+	else
+		instance_id = script_instancegetid(st);
 
-	if( instance[instance_id].state != INSTANCE_IDLE )
-	{
-		ShowError("instance_init: instance already initialized.\n");
+	if( instance_id <= 0 || instance_id >= MAX_MAP_PER_SERVER ) {
+		ShowError("script:instance_destroy: Trying to destroy invalid instance %d.\n", instance_id);
 		return 0;
 	}
 
-	instance_init(instance_id);
+	instance_destroy(instance_id);
 	return 0;
 }
 
-BUILDIN_FUNC(instance_announce)
+/*==========================================
+ * Warps player to instance
+ * Results:
+ *	0: Success
+ *	1: Instance not in DB
+ *	2: Character not in party
+ *	3: Party doesn't have instance
+ *	4: Instance doesn't match with party
+ *------------------------------------------*/
+BUILDIN_FUNC(instance_enter)
 {
-	int         instance_id = script_getnum(st,2);
-	const char *mes         = script_getstr(st,3);
-	int         flag        = script_getnum(st,4);
-	const char *fontColor   = script_hasdata(st,5) ? script_getstr(st,5) : NULL;
-	int         fontType    = script_hasdata(st,6) ? script_getnum(st,6) : 0x190; // default fontType (FW_NORMAL)
-	int         fontSize    = script_hasdata(st,7) ? script_getnum(st,7) : 12;    // default fontSize
-	int         fontAlign   = script_hasdata(st,8) ? script_getnum(st,8) : 0;     // default fontAlign
-	int         fontY       = script_hasdata(st,9) ? script_getnum(st,9) : 0;     // default fontY
-
-	int i;
 	struct map_session_data *sd;
-	struct party_data *p;
-
-	if( instance_id == 0 )
-	{
-		if( st->instance_id )
-			instance_id = st->instance_id;
-		else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
-			instance_id = p->instance_id;
-		else return 0;
-	}
-
-	if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
-		return 0;
-
-	for( i = 0; i < instance[instance_id].num_map; i++ )
-		map_foreachinmap(buildin_announce_sub, instance[instance_id].map[i], BL_PC,
-			mes, strlen(mes)+1, flag&0xf0, fontColor, fontType, fontSize, fontAlign, fontY);
 
+	if((sd = script_rid2sd(st)) != NULL)
+		script_pushint(st,instance_enter(sd,script_getstr(st, 2)));
+	else
+		return 1;
 	return 0;
+
 }
 
+/*==========================================
+ * Returns the name of a duplicated NPC
+ *
+ * instance_npcname <npc_name>{,<instance_id};
+ * <npc_name> is the full name of an NPC
+ *------------------------------------------*/
 BUILDIN_FUNC(instance_npcname)
 {
 	const char *str;
-	int instance_id = 0;
+	short instance_id = 0;
 
-	struct map_session_data *sd;
-	struct party_data *p;
 	struct npc_data *nd;
 
-	str = script_getstr(st, 2);
-	if( script_hasdata(st, 3) )
-		instance_id = script_getnum(st, 3);
-	else if( st->instance_id )
-		instance_id = st->instance_id;
-	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
-		instance_id = p->instance_id;
-
-	if( instance_id && (nd = npc_name2id(str)) != NULL )
- 	{
+	str = script_getstr(st,2);
+	if( script_hasdata(st,3) )
+		instance_id = script_getnum(st,3);
+	else
+		instance_id = script_instancegetid(st);
+
+	if( instance_id && (nd = npc_name2id(str)) != NULL ) {
 		static char npcname[NAME_LENGTH];
 		snprintf(npcname, sizeof(npcname), "dup_%d_%d", instance_id, nd->bl.id);
  		script_pushconststr(st,npcname);
-	}
-	else
-	{
+	} else {
 		ShowError("script:instance_npcname: invalid instance NPC (instance_id: %d, NPC name: \"%s\".)\n", instance_id, str);
 		st->state = END;
 		return 1;
@@ -16726,62 +16569,88 @@ BUILDIN_FUNC(instance_npcname)
 	return 0;
 }
 
-BUILDIN_FUNC(has_instance)
+/*==========================================
+ * Returns the name of a duplicated map
+ *
+ * instance_mapname <map_name>{,<instance_id};
+ *------------------------------------------*/
+BUILDIN_FUNC(instance_mapname)
 {
-	struct map_session_data *sd;
-	struct party_data *p;
  	const char *str;
+	char iname[12];
 	int16 m;
-	int instance_id = 0;
+	short instance_id = 0;
 
- 	str = script_getstr(st, 2);
-	if( script_hasdata(st, 3) )
-		instance_id = script_getnum(st, 3);
-	else if( st->instance_id )
-		instance_id = st->instance_id;
-	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
-		instance_id = p->instance_id;
+ 	str = script_getstr(st,2);
+	if( script_hasdata(st,3) )
+		instance_id = script_getnum(st,3);
+	else
+		instance_id = script_instancegetid(st);
 
-	if( !instance_id || (m = map_mapname2mapid(str)) < 0 || (m = instance_map2imap(m, instance_id)) < 0 )
-	{
+	// Build the instance mapname
+	snprintf(iname, sizeof(iname), ((strchr(str,'@') == NULL)?"%.3d#%s":"%.3d%s"), instance_id, str);
+
+	// Check that instance mapname is a valid map
+	if( !instance_id || (m = map_mapname2mapid(iname)) < 0 )
 		script_pushconststr(st, "");
-		return 0;
+	else
+		script_pushconststr(st, map[m].name);
+
+	return 0;
+}
+
+/*==========================================
+ * Returns an Instance ID
+ *------------------------------------------*/
+BUILDIN_FUNC(instance_id)
+{
+	short instance_id;
+
+	instance_id = script_instancegetid(st);
+
+	if(!instance_id) {
+		ShowError("script:instance_id: No instance attached to NPC or player");
+		script_pushint(st, 0);
+		return 1;
 	}
 
-	script_pushconststr(st, map[m].name);
+	script_pushint(st, instance_id);
+		
 	return 0;
 }
 
+/*==========================================
+ * Warps all players inside an instance
+ *
+ * instance_warpall <map_name>,<x>,<y>{,<instance_id>};
+ *------------------------------------------*/
 BUILDIN_FUNC(instance_warpall)
 {
+	struct party_data *p;
 	struct map_session_data *pl_sd;
 	int16 m, i;
-	int instance_id;
+	short instance_id;
 	const char *mapn;
 	int x, y;
 	unsigned short mapindex;
-	struct party_data *p = NULL;
 
 	mapn = script_getstr(st,2);
 	x    = script_getnum(st,3);
 	y    = script_getnum(st,4);
 	if( script_hasdata(st,5) )
 		instance_id = script_getnum(st,5);
-	else if( st->instance_id )
-		instance_id = st->instance_id;
-	else if( (pl_sd = script_rid2sd(st)) != NULL && pl_sd->status.party_id && (p = party_search(pl_sd->status.party_id)) != NULL && p->instance_id )
-		instance_id = p->instance_id;
-	else return 0;
+	else
+		instance_id = script_instancegetid(st);
 
-	if( (m = map_mapname2mapid(mapn)) < 0 || (map[m].flag.src4instance && (m = instance_mapid2imapid(m, instance_id)) < 0) )
+	if( !instance_id || (m = map_mapname2mapid(mapn)) < 0 || (m = instance_mapname2mapid(map[m].name,instance_id)) < 0)
 		return 0;
 
-	if( !(p = party_search(instance[instance_id].party_id)) )
+	if( !(p = party_search(instance_data[instance_id].party_id)) )
 		return 0;
 
 	mapindex = map_id2index(m);
 	for( i = 0; i < MAX_PARTY; i++ )
-		if( (pl_sd = p->data[i].sd) && map[pl_sd->bl.m].instance_id == st->instance_id ) pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
+		if( (pl_sd = p->data[i].sd) && map[pl_sd->bl.m].instance_id == instance_id ) pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT);
 
 	return 0;
 }
@@ -16806,39 +16675,39 @@ BUILDIN_FUNC(instance_check_party)
 	min = script_hasdata(st,4) ? script_getnum(st,4) : 1; // Minimum Level needed to join the Instance.
 	max  = script_hasdata(st,5) ? script_getnum(st,5) : MAX_LEVEL; // Maxium Level allowed to join the Instance.
 
-	if( min < 1 || min > MAX_LEVEL){
-		ShowError("instance_check_party: Invalid min level, %d\n", min);
-		return 0;
-	}else if(  max < 1 || max > MAX_LEVEL){
-		ShowError("instance_check_party: Invalid max level, %d\n", max);
-		return 0;
+	if( min < 1 || min > MAX_LEVEL) {
+		ShowError("script:check_party: Invalid min level, %d\n", min);
+		return 1;
+	} else if(  max < 1 || max > MAX_LEVEL) {
+		ShowError("script:check_party: Invalid max level, %d\n", max);
+		return 1;
 	}
 
 	if( script_hasdata(st,2) )
 		party_id = script_getnum(st,2);
 	else return 0;
 
-	if( !(p = party_search(party_id)) ){
+	if( !(p = party_search(party_id)) ) {
 		script_pushint(st, 0); // Returns false if party does not exist.
 		return 0;
 	}
 
 	for( i = 0; i < MAX_PARTY; i++ )
 		if( (pl_sd = p->data[i].sd) )
-			if(map_id2bl(pl_sd->bl.id)){
-				if(pl_sd->status.base_level < min){
+			if(map_id2bl(pl_sd->bl.id)) {
+				if(pl_sd->status.base_level < min) {
 					script_pushint(st, 0);
 					return 0;
-				}else if(pl_sd->status.base_level > max){
+				} else if(pl_sd->status.base_level > max) {
 					script_pushint(st, 0);
 					return 0;
 				}
 					c++;
 			}
 
-	if(c < amount){
+	if(c < amount)
 		script_pushint(st, 0); // Not enough Members in the Party to join Instance.
-	}else
+	else
 		script_pushint(st, 1);
 
 	return 0;
@@ -16911,15 +16780,11 @@ BUILDIN_FUNC(areamobuseskill)
 	int16 m;
 	int range,mobid,skill_id,skill_lv,casttime,emotion,target,cancel;
 
-	if( (m = map_mapname2mapid(script_getstr(st,2))) < 0 )
-	{
+	if( (m = map_mapname2mapid(script_getstr(st,2))) < 0 ) {
 		ShowError("areamobuseskill: invalid map name.\n");
 		return 0;
 	}
 
-	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
-		return 0;
-
 	center.m = m;
 	center.x = script_getnum(st,3);
 	center.y = script_getnum(st,4);
@@ -18123,17 +17988,12 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(bg_updatescore,"sii"),
 
 	// Instancing
-	BUILDIN_DEF(instance_create,"si"),
+	BUILDIN_DEF(instance_create,"s"),
 	BUILDIN_DEF(instance_destroy,"?"),
-	BUILDIN_DEF(instance_attachmap,"si?"),
-	BUILDIN_DEF(instance_detachmap,"s?"),
-	BUILDIN_DEF(instance_attach,"i"),
-	BUILDIN_DEF(instance_id,"?"),
-	BUILDIN_DEF(instance_set_timeout,"ii?"),
-	BUILDIN_DEF(instance_init,"i"),
-	BUILDIN_DEF(instance_announce,"isi?????"),
+	BUILDIN_DEF(instance_id,""),
+	BUILDIN_DEF(instance_enter,"s"),
 	BUILDIN_DEF(instance_npcname,"s?"),
-	BUILDIN_DEF(has_instance,"s?"),
+	BUILDIN_DEF(instance_mapname,"s?"),
 	BUILDIN_DEF(instance_warpall,"sii?"),
 	BUILDIN_DEF(instance_check_party,"i???"),
 	/**

+ 0 - 1
src/map/script.h

@@ -126,7 +126,6 @@ struct script_state {
 	struct sleep_data {
 		int tick,timer,charid;
 	} sleep;
-	int instance_id;
 	//For backing up purposes
 	struct script_state *bk_st;
 	int bk_npcid;

+ 3 - 11
src/map/unit.c

@@ -2109,8 +2109,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
 		status_change_end(bl, SC_TINDER_BREAKER2, INVALID_TIMER);
 		status_change_end(bl, SC_HIDING, INVALID_TIMER);
 		// Ensure the bl is a PC; if so, we'll handle the removal of cloaking and cloaking exceed later
-		if ( bl->type != BL_PC )
-		{
+		if ( bl->type != BL_PC ) {
 			status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
 			status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
 		}
@@ -2165,8 +2164,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
 				npc_touchnext_areanpc(sd,true);
 
 			// Check if warping and not changing the map.
-			if ( sd->state.warping && !sd->state.changemap )
-			{
+			if ( sd->state.warping && !sd->state.changemap ) {
 				status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
 				status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
 			}
@@ -2192,8 +2190,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
 
 			if( map[bl->m].users <= 0 || sd->state.debug_remove_map )
 			{// this is only place where map users is decreased, if the mobs were removed too soon then this function was executed too many times [FlavioJS]
-				if( sd->debug_file == NULL || !(sd->state.debug_remove_map) )
-				{
+				if( sd->debug_file == NULL || !(sd->state.debug_remove_map) ) {
 					sd->debug_file = "";
 					sd->debug_line = 0;
 					sd->debug_func = "";
@@ -2215,11 +2212,6 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
 			{// decrement the number of active pvp players on the map
 				--map[bl->m].users_pvp;
 			}
-			if( map[bl->m].instance_id )
-			{
-				instance[map[bl->m].instance_id].users--;
-				instance_check_idle(map[bl->m].instance_id);
-			}
 			sd->state.debug_remove_map = 1; // temporary state to track double remove_map's [FlavioJS]
 			sd->debug_file = file;
 			sd->debug_line = line;

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio