viewing paste Unknown #6429 | Diff

Posted on the
  1. Index: src/map/atcommand.c
  2. ===================================================================
  3. --- src/map/atcommand.c	(revision 17385)
  4. +++ src/map/atcommand.c	(working copy)
  5. @@ -21,6 +21,7 @@
  6.  #include "clif.h"
  7.  #include "chrif.h"
  8.  #include "duel.h"
  9. +#include "instance.h"
  10.  #include "intif.h"
  11.  #include "itemdb.h"
  12.  #include "log.h"
  13. @@ -3724,6 +3725,9 @@
  14.  	} else if (strstr(command, "packetdb") || strncmp(message, "packetdb", 4) == 0) {
  15.  		packetdb_readdb();
  16.  		clif_displaymessage(fd, msg_txt(sd,1477)); // Packet database has been reloaded.
  17. +	} else if (strstr(command, "instancedb") || strncmp(message, "instancedb", 4) == 0) {
  18. +		instance_readdb();
  19. +		clif_displaymessage(fd, msg_txt(sd,516)); // Instance database has been reloaded.
  20.  	}
  21.  
  22.  
  23. @@ -3945,8 +3949,6 @@
  24.  		strcat(atcmd_output, msg_txt(sd,1097)); // GuildLock |
  25.  	if (map[m_id].flag.loadevent)
  26.  		strcat(atcmd_output, msg_txt(sd,1098)); // Loadevent |
  27. -	if (map[m_id].flag.src4instance)
  28. -		strcat(atcmd_output, msg_txt(sd,1099)); // Src4instance |
  29.  	if (map[m_id].flag.chmautojoin)
  30.  		strcat(atcmd_output, msg_txt(sd,1100)); // Chmautojoin |
  31.  	if (map[m_id].flag.nousecart)
  32. @@ -7653,7 +7655,7 @@
  33.  		checkflag(nogo);				checkflag(nobaseexp);
  34.  		checkflag(nojobexp);			checkflag(nomobloot);			checkflag(nomvploot);	checkflag(nightenabled);
  35.  		checkflag(restricted);			checkflag(nodrop);				checkflag(novending);	checkflag(loadevent);
  36. -		checkflag(nochat);				checkflag(partylock);			checkflag(guildlock);	checkflag(src4instance);
  37. +		checkflag(nochat);				checkflag(partylock);			checkflag(guildlock);
  38.  		clif_displaymessage(sd->fd," ");
  39.  		clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
  40.  		clif_displaymessage(sd->fd,msg_txt(sd,1313)); // Type "@mapflag available" to list the available mapflags.
  41. @@ -7673,7 +7675,7 @@
  42.  	setflag(nogo);				setflag(nobaseexp);
  43.  	setflag(nojobexp);			setflag(nomobloot);			setflag(nomvploot);			setflag(nightenabled);
  44.  	setflag(restricted);		setflag(nodrop);			setflag(novending);			setflag(loadevent);
  45. -	setflag(nochat);			setflag(partylock);			setflag(guildlock);			setflag(src4instance);
  46. +	setflag(nochat);			setflag(partylock);			setflag(guildlock);
  47.  
  48.  	clif_displaymessage(sd->fd,msg_txt(sd,1314)); // Invalid flag name or flag.
  49.  	clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
  50. @@ -7685,7 +7687,7 @@
  51.  	clif_displaymessage(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,");
  52.  	clif_displaymessage(sd->fd,"fog, fireworks, sakura, leaves, nogo, nobaseexp, nojobexp, nomobloot,");
  53.  	clif_displaymessage(sd->fd,"nomvploot, nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock,");
  54. -	clif_displaymessage(sd->fd,"guildlock, src4instance");
  55. +	clif_displaymessage(sd->fd,"guildlock");
  56.  
  57.  #undef checkflag
  58.  #undef setflag
  59. Index: src/map/clif.c
  60. ===================================================================
  61. --- src/map/clif.c	(revision 17385)
  62. +++ src/map/clif.c	(working copy)
  63. @@ -9186,10 +9186,6 @@
  64.  	if( !(sd->sc.option&OPTION_INVISIBLE) ) { // increment the number of pvp players on the map
  65.  		map[sd->bl.m].users_pvp++;
  66.  	}
  67. -	if( map[sd->bl.m].instance_id ) {
  68. -		instance[map[sd->bl.m].instance_id].users++;
  69. -		instance_check_idle(map[sd->bl.m].instance_id);
  70. -	}
  71.  	sd->state.debug_remove_map = 0; // temporary state to track double remove_map's [FlavioJS]
  72.  
  73.  	// reset the callshop flag if the player changes map
  74. @@ -15267,102 +15263,85 @@
  75.  
  76.  
  77.  /*==========================================
  78. - * Instancing Window
  79. + * Notifies party members of instance change
  80.   *------------------------------------------*/
  81. -int clif_instance(int instance_id, int type, int flag)
  82. +void clif_instance_create(struct map_session_data *sd, const char *name, int num, int flag)
  83.  {
  84. -	struct map_session_data *sd;
  85. -	struct party_data *p;
  86. -	unsigned char buf[255];
  87. +#if PACKETVER >= 20071128
  88. +	unsigned char buf[65];
  89.  
  90. -	if( (p = party_search(instance[instance_id].party_id)) == NULL || (sd = party_getavailablesd(p)) == NULL )
  91. -		return 0;
  92. +	nullpo_retv(sd);
  93.  
  94. -	switch( type )
  95. -	{
  96. -	case 1:
  97. -		// S 0x2cb <Instance name>.61B <Standby Position>.W
  98. -		// Required to start the instancing information window on Client
  99. -		// This window re-appear each "refresh" of client automatically until type 4 is send to client.
  100. -		WBUFW(buf,0) = 0x02CB;
  101. -		memcpy(WBUFP(buf,2),instance[instance_id].name,INSTANCE_NAME_LENGTH);
  102. -		WBUFW(buf,63) = flag;
  103. -		clif_send(buf,packet_len(0x02CB),&sd->bl,PARTY);
  104. -		break;
  105. -	case 2:
  106. -		// S 0x2cc <Standby Position>.W
  107. -		// To announce Instancing queue creation if no maps available
  108. -		WBUFW(buf,0) = 0x02CC;
  109. -		WBUFW(buf,2) = flag;
  110. -		clif_send(buf,packet_len(0x02CC),&sd->bl,PARTY);
  111. -		break;
  112. -	case 3:
  113. -	case 4:
  114. -		// S 0x2cd <Instance Name>.61B <Instance Remaining Time>.L <Instance Noplayers close time>.L
  115. -		WBUFW(buf,0) = 0x02CD;
  116. -		memcpy(WBUFP(buf,2),instance[instance_id].name,61);
  117. -		if( type == 3 )
  118. -		{
  119. -			WBUFL(buf,63) = (uint32)instance[instance_id].progress_timeout;
  120. -			WBUFL(buf,67) = 0;
  121. -		}
  122. -		else
  123. -		{
  124. -			WBUFL(buf,63) = 0;
  125. -			WBUFL(buf,67) = (uint32)instance[instance_id].idle_timeout;
  126. -		}
  127. -		clif_send(buf,packet_len(0x02CD),&sd->bl,PARTY);
  128. -		break;
  129. -	case 5:
  130. -		// S 0x2ce <Message ID>.L
  131. -		// 0 = Notification (EnterLimitDate update?)
  132. -		// 1 = The Memorial Dungeon expired; it has been destroyed
  133. -		// 2 = The Memorial Dungeon's entry time limit expired; it has been destroyed
  134. -		// 3 = The Memorial Dungeon has been removed.
  135. -		// 4 = Create failure (removes the instance window)
  136. -		WBUFW(buf,0) = 0x02CE;
  137. -		WBUFL(buf,2) = flag;
  138. -		//WBUFL(buf,6) = EnterLimitDate;
  139. -		clif_send(buf,packet_len(0x02CE),&sd->bl,PARTY);
  140. -		break;
  141. -	}
  142. -	return 0;
  143. +	WBUFW(buf,0) = 0x2cb;
  144. +	safestrncpy( WBUFP(buf,2), name, 62 );
  145. +	WBUFW(buf,63) = num;
  146. +	if(flag) // A timer has changed or been added
  147. +		clif_send(buf,packet_len(0x2cb),&sd->bl,PARTY);
  148. +	else	// No notification
  149. +		clif_send(buf,packet_len(0x2cb),&sd->bl,SELF);
  150. +#endif
  151. +
  152. +	return;
  153.  }
  154.  
  155. -void clif_instance_join(int fd, int instance_id)
  156. +void clif_instance_changewait(struct map_session_data *sd, int num, int flag)
  157.  {
  158. -	if( instance[instance_id].idle_timer != INVALID_TIMER ) {
  159. -		WFIFOHEAD(fd,packet_len(0x02CD));
  160. -		WFIFOW(fd,0) = 0x02CD;
  161. -		memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
  162. -		WFIFOL(fd,63) = 0;
  163. -		WFIFOL(fd,67) = (uint32)instance[instance_id].idle_timeout;
  164. -		WFIFOSET(fd,packet_len(0x02CD));
  165. -	} else if( instance[instance_id].progress_timer != INVALID_TIMER ) {
  166. -		WFIFOHEAD(fd,packet_len(0x02CD));
  167. -		WFIFOW(fd,0) = 0x02CD;
  168. -		memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
  169. -		WFIFOL(fd,63) = (uint32)instance[instance_id].progress_timeout;;
  170. -		WFIFOL(fd,67) = 0;
  171. -		WFIFOSET(fd,packet_len(0x02CD));
  172. -	} else {
  173. -		WFIFOHEAD(fd,packet_len(0x02CB));
  174. -		WFIFOW(fd,0) = 0x02CB;
  175. -		memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
  176. -		WFIFOW(fd,63) = 0;
  177. -		WFIFOSET(fd,packet_len(0x02CB));
  178. -	}
  179. +#if PACKETVER >= 20071128
  180. +	unsigned char buf[4];
  181. +
  182. +	nullpo_retv(sd);
  183. +
  184. +	WBUFW(buf,0) = 0x2cc;
  185. +	WBUFW(buf,2) = num;
  186. +	if(flag) // A timer has changed or been added
  187. +		clif_send(buf,packet_len(0x2cc),&sd->bl,PARTY);
  188. +	else	// No notification
  189. +		clif_send(buf,packet_len(0x2cc),&sd->bl,SELF);
  190. +#endif
  191. +
  192. +	return;
  193.  }
  194.  
  195. -void clif_instance_leave(int fd)
  196. +void clif_instance_status(struct map_session_data *sd, const char *name, unsigned int limit1, unsigned int limit2, int flag)
  197.  {
  198. -	WFIFOHEAD(fd,packet_len(0x02CE));
  199. -	WFIFOW(fd,0) = 0x02ce;
  200. -	WFIFOL(fd,2) = 4;
  201. -	WFIFOSET(fd,packet_len(0x02CE));
  202. +#if PACKETVER >= 20071128
  203. +	unsigned char buf[71];
  204. +
  205. +	nullpo_retv(sd);
  206. +
  207. +	WBUFW(buf,0) = 0x2cd;
  208. +	safestrncpy( WBUFP(buf,2), name, 62 );
  209. +	WBUFL(buf,63) = limit1;
  210. +	WBUFL(buf,67) = limit2;
  211. +	if(flag) // A timer has changed or been added
  212. +		clif_send(buf,packet_len(0x2cd),&sd->bl,PARTY);
  213. +	else	// No notification
  214. +		clif_send(buf,packet_len(0x2cd),&sd->bl,SELF);
  215. +#endif
  216. +
  217. +	return;
  218.  }
  219.  
  220. +void clif_instance_changestatus(struct map_session_data *sd, int type, unsigned int limit, int flag)
  221. +{
  222. +#if PACKETVER >= 20071128
  223. +	unsigned char buf[10];
  224.  
  225. +	nullpo_retv(sd);
  226. +
  227. +	WBUFW(buf,0) = 0x2ce;
  228. +	WBUFL(buf,2) = type;
  229. +	WBUFL(buf,6) = limit;
  230. +	if(flag) // A timer has changed or been added
  231. +		clif_send(buf,packet_len(0x2ce),&sd->bl,PARTY);
  232. +	else	// No notification
  233. +		clif_send(buf,packet_len(0x2ce),&sd->bl,SELF);
  234. +#endif
  235. +
  236. +	return;
  237. +}
  238. +
  239. +
  240.  /// Notifies clients about item picked up by a party member (ZC_ITEM_PICKUP_PARTY).
  241.  /// 02b8 <account id>.L <name id>.W <identified>.B <damaged>.B <refine>.B <card1>.W <card2>.W <card3>.W <card4>.W <equip location>.W <item type>.B
  242.  void clif_party_show_picker(struct map_session_data * sd, struct item * item_data)
  243. Index: src/map/clif.h
  244. ===================================================================
  245. --- src/map/clif.h	(revision 17385)
  246. +++ src/map/clif.h	(working copy)
  247. @@ -570,9 +570,10 @@
  248.  void clif_sendbgemblem_single(int fd, struct map_session_data *sd);
  249.  
  250.  // Instancing
  251. -int clif_instance(int instance_id, int type, int flag);
  252. -void clif_instance_join(int fd, int instance_id);
  253. -void clif_instance_leave(int fd);
  254. +void clif_instance_create(struct map_session_data *sd, const char *name, int num, int flag);
  255. +void clif_instance_changewait(struct map_session_data *sd, int num, int flag);
  256. +void clif_instance_status(struct map_session_data *sd, const char *name, unsigned int limit1, unsigned int limit2, int flag);
  257. +void clif_instance_changestatus(struct map_session_data *sd, int type, unsigned int limit, int flag);
  258.  
  259.  // Custom Fonts
  260.  void clif_font(struct map_session_data *sd);
  261. Index: src/map/instance.c
  262. ===================================================================
  263. --- src/map/instance.c	(revision 17385)
  264. +++ src/map/instance.c	(working copy)
  265. @@ -24,465 +24,682 @@
  266.  #include <stdarg.h>
  267.  #include <time.h>
  268.  
  269. +#define MAX_INSTANCE_DB		15	// Max number of instance types
  270. +#define INSTANCE_INTERVAL	60000	// Interval used to check when an instance is to be destroyed (ms)
  271. +#define INSTANCE_LIMIT		300000	// Idle timer before instance is destroyed (ms) : 5 Minute Default
  272. +
  273.  int instance_start = 0; // To keep the last index + 1 of normal map inserted in the map[ARRAY]
  274. -struct s_instance instance[MAX_INSTANCE];
  275.  
  276. +struct instance_data instance_data[MAX_INSTANCE_DATA];
  277.  
  278. -/// Checks whether given instance id is valid or not.
  279. -static bool instance_is_valid(int instance_id)
  280. +static struct instance_db{
  281. +	short type;
  282. +	char name[61];
  283. +	int limit;
  284. +	struct {
  285. +		char mapname[MAP_NAME_LENGTH_EXT];
  286. +		short x, y;
  287. +	} enter;
  288. +	char mapname[MAX_MAP_PER_INSTANCE][MAP_NAME_LENGTH_EXT];
  289. +} instance_db[MAX_INSTANCE_DB];
  290. +
  291. +static struct {
  292. +	int id[MAX_INSTANCE_DATA];
  293. +	int count;
  294. +	int timer;
  295. +} instance_wait;
  296. +
  297. +/*==========================================
  298. + * Searches for an instance ID in the database
  299. + *------------------------------------------*/
  300. +static struct instance_db *instance_searchtype_db(short instance_type)
  301.  {
  302. -	if( instance_id < 1 || instance_id >= ARRAYLENGTH(instance) )
  303. -	{// out of range
  304. -		return false;
  305. -	}
  306. +	int i;
  307.  
  308. -	if( instance[instance_id].state == INSTANCE_FREE )
  309. -	{// uninitialized/freed instance slot
  310. -		return false;
  311. +	for(i=0; i < MAX_INSTANCE_DB; i++) {
  312. +		if(instance_db[i].type == instance_type)
  313. +			return &instance_db[i];
  314.  	}
  315.  
  316. -	return true;
  317. +	return NULL;
  318.  }
  319.  
  320. -
  321. -/*--------------------------------------
  322. - * name : instance name
  323. - * Return value could be
  324. - * -4 = already exists | -3 = no free instances | -2 = party not found | -1 = invalid type
  325. - * On success return instance_id
  326. - *--------------------------------------*/
  327. -int instance_create(int party_id, const char *name)
  328. +/*==========================================
  329. + * Searches for an instance name in the database
  330. + *------------------------------------------*/
  331. +static struct instance_db *instance_searchname_db(const char *instance_name)
  332.  {
  333.  	int i;
  334. -	struct party_data* p;
  335.  
  336. -	if( ( p = party_search(party_id) ) == NULL )
  337. -	{
  338. -		ShowError("instance_create: party %d not found for instance '%s'.\n", party_id, name);
  339. -		return -2;
  340. +	for(i=0; i < MAX_INSTANCE_DB; i++) {
  341. +		if(strcmp(instance_db[i].name, instance_name) == 0)
  342. +			return &instance_db[i];
  343.  	}
  344.  
  345. -	if( p->instance_id )
  346. -		return -4; // Party already instancing
  347. +	return NULL;
  348. +}
  349.  
  350. -	// Searching a Free Instance
  351. -	// 0 is ignored as this mean "no instance" on maps
  352. -	ARR_FIND(1, MAX_INSTANCE, i, instance[i].state == INSTANCE_FREE);
  353. -	if( i == MAX_INSTANCE )
  354. -	{
  355. -		ShowError("instance_create: no free instances, consider increasing MAX_INSTANCE.\n");
  356. -		return -3;
  357. -	}
  358. +/*==========================================
  359. + * Deletes an instance timer (Destroys instance)
  360. + *------------------------------------------*/
  361. +static int instance_delete_timer(int tid, unsigned int tick, int id, intptr_t data)
  362. +{
  363. +	instance_destroy(id);
  364.  
  365. -	instance[i].state = INSTANCE_IDLE;
  366. -	instance[i].instance_id = i;
  367. -	instance[i].idle_timer = INVALID_TIMER;
  368. -	instance[i].idle_timeout = instance[i].idle_timeoutval = 0;
  369. -	instance[i].progress_timer = INVALID_TIMER;
  370. -	instance[i].progress_timeout = 0;
  371. -	instance[i].users = 0;
  372. -	instance[i].party_id = party_id;
  373. -	instance[i].vars = idb_alloc(DB_OPT_RELEASE_DATA);
  374. -
  375. -	safestrncpy( instance[i].name, name, sizeof(instance[i].name) );
  376. -	memset( instance[i].map, 0x00, sizeof(instance[i].map) );
  377. -	p->instance_id = i;
  378. -
  379. -	clif_instance(i, 1, 0); // Start instancing window
  380. -	ShowInfo("[Instance] Created: %s.\n", name);
  381. -	return i;
  382. +	return 0;
  383.  }
  384.  
  385. -/*--------------------------------------
  386. - * Add a map to the instance using src map "name"
  387. - *--------------------------------------*/
  388. -int instance_add_map(const char *name, int instance_id, bool usebasename)
  389. +/*==========================================
  390. + * Create subscription timer for party
  391. + *------------------------------------------*/
  392. +static int instance_subscription_timer(int tid, unsigned int tick, int id, intptr_t data)
  393.  {
  394. -	int16 m = map_mapname2mapid(name);
  395. -	int i, im = -1;
  396. -	size_t num_cell, size;
  397. +	int i, ret;
  398. +	int instance_id = instance_wait.id[0];
  399. +	struct party_data *p;
  400.  
  401. -	if( m < 0 )
  402. -		return -1; // source map not found
  403. +	if(instance_wait.count == 0 || instance_id <= 0)
  404. +		return 0;
  405.  
  406. -	if( !instance_is_valid(instance_id) )
  407. -	{
  408. -		ShowError("instance_add_map: trying to attach '%s' map to non-existing instance %d.\n", name, instance_id);
  409. -		return -1;
  410. -	}
  411. -	if( instance[instance_id].num_map >= MAX_MAP_PER_INSTANCE )
  412. -	{
  413. -		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);
  414. -		return -2;
  415. -	}
  416. -	if( map[m].instance_id != 0 )
  417. -	{ // Source map already belong to a Instance.
  418. -		ShowError("instance_add_map: trying to instance already instanced map %s.\n", name);
  419. -		return -4;
  420. -	}
  421. +	// Check that maps have been added
  422. +	ret = instance_addmap(instance_id);
  423.  
  424. -	ARR_FIND( instance_start, map_num, i, !map[i].name[0] ); // Searching for a Free Map
  425. -	if( i < map_num ) im = i; // Unused map found (old instance)
  426. -	else if( map_num - 1 >= MAX_MAP_PER_SERVER )
  427. -	{ // No more free maps
  428. -		ShowError("instance_add_map: no more free space to create maps on this server.\n");
  429. -		return -5;
  430. -	}
  431. -	else im = map_num++; // Using next map index
  432. +	// If no maps are created, tell party to wait
  433. +	if(ret == 0 && ( p = party_search( instance_data[instance_id].party_id ) ) != NULL)
  434. +		clif_instance_changewait( party_getavailablesd( p ), 0xffff, 1 );
  435.  
  436. -	memcpy( &map[im], &map[m], sizeof(struct map_data) ); // Copy source map
  437. -	snprintf(map[im].name, MAP_NAME_LENGTH, (usebasename ? "%.3d#%s" : "%.3d%s"), instance_id, name); // Generate Name for Instance Map
  438. -	map[im].index = mapindex_addmap(-1, map[im].name); // Add map index
  439. +	instance_wait.count--;
  440. +	memmove(&instance_wait.id[0],&instance_wait.id[1],sizeof(instance_wait.id[0])*instance_wait.count);
  441. +	memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));
  442.  
  443. -	if( !map[im].index )
  444. -	{
  445. -		map[im].name[0] = '\0';
  446. -		ShowError("instance_add_map: no more free map indexes.\n");
  447. -		return -3; // No free map index
  448. +	for(i = 0; i < instance_wait.count; i++) {
  449. +		if(	instance_data[instance_wait.id[i]].state == INSTANCE_IDLE &&
  450. +			( p = party_search( instance_data[instance_wait.id[i]].party_id ) ) != NULL
  451. +		){
  452. +			clif_instance_changewait( party_getavailablesd( p ), i + 1, 1 );
  453. +		}
  454.  	}
  455.  
  456. -	// Reallocate cells
  457. -	num_cell = map[im].xs * map[im].ys;
  458. -	CREATE( map[im].cell, struct mapcell, num_cell );
  459. -	memcpy( map[im].cell, map[m].cell, num_cell * sizeof(struct mapcell) );
  460. +	if(instance_wait.count)
  461. +		instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
  462. +	else
  463. +		instance_wait.timer = -1;
  464.  
  465. -	size = map[im].bxs * map[im].bys * sizeof(struct block_list*);
  466. -	map[im].block = (struct block_list**)aCalloc(size, 1);
  467. -	map[im].block_mob = (struct block_list**)aCalloc(size, 1);
  468. +	return 0;
  469. +}
  470.  
  471. -	memset(map[im].npc, 0x00, sizeof(map[i].npc));
  472. -	map[im].npc_num = 0;
  473. +/*==========================================
  474. + * Adds timer back to party entering instance
  475. + *------------------------------------------*/
  476. +static int instance_startkeeptimer(struct instance_data *im, short instance_id)
  477. +{
  478. +	struct instance_db *db;
  479. +	struct party_data *p;
  480.  
  481. -	memset(map[im].moblist, 0x00, sizeof(map[im].moblist));
  482. -	map[im].mob_delete_timer = INVALID_TIMER;
  483. +	nullpo_retr(0, im);
  484.  
  485. -	map[im].m = im;
  486. -	map[im].instance_id = instance_id;
  487. -	map[im].instance_src_map = m;
  488. -	map[m].flag.src4instance = 1; // Flag this map as a src map for instances
  489. +	// No timer
  490. +	if(im->keep_timer != -1)
  491. +		return 1;
  492.  
  493. -	instance[instance_id].map[instance[instance_id].num_map++] = im; // Attach to actual instance
  494. -	map_addmap2db(&map[im]);
  495. +	if((db = instance_searchtype_db(im->type)) == NULL)
  496. +		return 1;
  497.  
  498. -	return im;
  499. +	// Add timer
  500. +	im->keep_limit = (unsigned int)time(NULL) + db->limit;
  501. +	im->keep_timer = add_timer(gettick()+db->limit*1000, instance_delete_timer, instance_id, 0);
  502. +
  503. +	// Notify party of the added instance timer
  504. +	if( ( p = party_search( im->party_id ) ) != NULL )
  505. +		clif_instance_status( party_getavailablesd( p ), db->name, im->keep_limit, im->idle_limit, 1 );
  506. +
  507. +	return 0;
  508.  }
  509.  
  510. -/*--------------------------------------
  511. - * m : source map of this instance
  512. - * party_id : source party of this instance
  513. - * type : result (0 = map id | 1 = instance id)
  514. - *--------------------------------------*/
  515. -int instance_map2imap(int16 m, int instance_id)
  516. +/*==========================================
  517. + * Creates idle timer
  518. + * Default before instance destroy is 5 minutes
  519. + *------------------------------------------*/
  520. +static int instance_startidletimer(struct instance_data *im, short instance_id)
  521.  {
  522. - 	int i;
  523. +	struct instance_db *db;
  524. +	struct party_data *p;
  525.  
  526. -	if( !instance_is_valid(instance_id) )
  527. -	{
  528. -		return -1;
  529. +	nullpo_retr(1, im);
  530. +
  531. +	// No current timer
  532. +	if(im->idle_timer != -1)
  533. +		return 1;
  534. +
  535. +	// Add the timer
  536. +	im->idle_limit = (unsigned int)time(NULL) + INSTANCE_LIMIT;
  537. +	im->idle_timer = add_timer(gettick()+INSTANCE_LIMIT, instance_delete_timer, instance_id, 0);
  538. +
  539. +	// Notify party of added instance timer
  540. +	if( ( p = party_search( im->party_id ) ) != NULL &&
  541. +		( db = instance_searchtype_db( im->type ) ) != NULL
  542. +		){
  543. +		clif_instance_status( party_getavailablesd( p ), db->name, im->keep_limit, im->idle_limit, 1 );
  544.  	}
  545.  
  546. -	for( i = 0; i < instance[instance_id].num_map; i++ )
  547. - 	{
  548. -		if( instance[instance_id].map[i] && map[instance[instance_id].map[i]].instance_src_map == m )
  549. -			return instance[instance_id].map[i];
  550. - 	}
  551. - 	return -1;
  552. +	return 0;
  553.  }
  554.  
  555. -/*--------------------------------------
  556. - * m : source map
  557. - * instance_id : where to search
  558. - * result : mapid of map "m" in this instance
  559. - *--------------------------------------*/
  560. -int instance_mapid2imapid(int16 m, int instance_id)
  561. +/*==========================================
  562. + * Delete the idle timer
  563. + *------------------------------------------*/
  564. +static int instance_stopidletimer(struct instance_data *im)
  565.  {
  566. -	if( map[m].flag.src4instance == 0 )
  567. -		return m; // not instances found for this map
  568. -	else if( map[m].instance_id )
  569. -	{ // This map is a instance, not a src map instance
  570. -		ShowError("map_instance_mapid2imapid: already instanced (%d / %d)\n", m, instance_id);
  571. -		return -1;
  572. -	}
  573. +	struct party_data *p;
  574.  
  575. -	if( !instance_is_valid(instance_id) )
  576. -		return -1;
  577. +	nullpo_retr(0, im);
  578. +	
  579. +	// No timer
  580. +	if(im->idle_timer == -1)
  581. +		return 1;
  582.  
  583. -	return instance_map2imap(m, instance_id);
  584. +	// Delete the timer - Party has returned or instance is destroyed
  585. +	im->idle_limit = 0;
  586. +	delete_timer(im->idle_timer, instance_delete_timer);
  587. +	im->idle_timer = -1;
  588. +
  589. +	// Notify the party
  590. +	if( ( p = party_search( im->party_id ) ) != NULL )
  591. +		clif_instance_changestatus( party_getavailablesd( p ), 0, im->idle_limit, 1 );
  592. +
  593. +	return 0;
  594.  }
  595.  
  596. -/*--------------------------------------
  597. - * map_instance_map_npcsub
  598. - * Used on Init instance. Duplicates each script on source map
  599. - *--------------------------------------*/
  600. -int instance_map_npcsub(struct block_list* bl, va_list args)
  601. +/*==========================================
  602. + * Run the OnInstanceInit events for duplicated NPCs
  603. + *------------------------------------------*/
  604. +static int instance_npcinit(struct block_list *bl, va_list ap)
  605.  {
  606. -	struct npc_data* nd = (struct npc_data*)bl;
  607. -	int16 m = va_arg(args, int); // Destination Map
  608. +	struct npc_data* nd;
  609.  
  610. -	npc_duplicate4instance(nd, m);
  611. -	return 1;
  612. +	nullpo_retr(0, bl);
  613. +	nullpo_retr(0, ap);
  614. +	nullpo_retr(0, nd = (struct npc_data *)bl);
  615. +
  616. +	return npc_instanceinit(nd);
  617.  }
  618.  
  619. +/*==========================================
  620. + * Add an NPC to an instance
  621. + *------------------------------------------*/
  622. +static int instance_addnpc_sub(struct block_list *bl, va_list ap)
  623. +{
  624. +	struct npc_data* nd;
  625. +
  626. +	nullpo_retr(0, bl);
  627. +	nullpo_retr(0, ap);
  628. +	nullpo_retr(0, nd = (struct npc_data *)bl);
  629. +
  630. +	return npc_duplicate4instance(nd, va_arg(ap, int));
  631. +}
  632. +
  633. +// Separate function used for reloading
  634. +void instance_addnpc(struct instance_data *im)
  635. +{
  636. +	int i;
  637. +
  638. +	// First add the NPCs
  639. +	for(i = 0; i < im->cnt_map; i++)
  640. +		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);
  641. +
  642. +	// Now run their OnInstanceInit
  643. +	for(i = 0; i < im->cnt_map; i++)
  644. +		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);
  645. +
  646. +}
  647. +
  648.  /*--------------------------------------
  649. - * Init all map on the instance. Npcs are created here
  650. + * name : instance name
  651. + * Return value could be
  652. + * -4 = already exists | -3 = no free instances | -2 = party not found | -1 = invalid type
  653. + * On success return instance_id
  654.   *--------------------------------------*/
  655. -void instance_init(int instance_id)
  656. +int instance_create(int party_id, const char *name)
  657.  {
  658. -	int i;
  659. +	short i;
  660. +	struct instance_db *db = instance_searchname_db(name);
  661. +	struct party_data *p = party_search(party_id);
  662.  
  663. -	if( !instance_is_valid(instance_id) )
  664. -		return; // nothing to do
  665. +	if(db == NULL)
  666. +		return -1;
  667.  
  668. -	for( i = 0; i < instance[instance_id].num_map; i++ )
  669. -		map_foreachinmap(instance_map_npcsub, map[instance[instance_id].map[i]].instance_src_map, BL_NPC, instance[instance_id].map[i]);
  670. +	if( p == NULL )
  671. +		return -2;
  672.  
  673. -	instance[instance_id].state = INSTANCE_BUSY;
  674. -	ShowInfo("[Instance] Initialized %s.\n", instance[instance_id].name);
  675. +	if( p->instance_id )
  676. +		return -3; // Party already instancing
  677. +
  678. +	// Searching a Free Instance
  679. +	// 0 is ignored as this mean "no instance" on maps
  680. +	ARR_FIND(1, MAX_INSTANCE_DB, i, instance_data[i].state == INSTANCE_FREE);
  681. +	if( i >= MAX_INSTANCE_DB )
  682. +		return -4;
  683. +
  684. +	instance_data[i].type = db->type;
  685. +	instance_data[i].state = INSTANCE_IDLE;
  686. +	instance_data[i].party_id = p->party.party_id;
  687. +	instance_data[i].keep_limit = 0;
  688. +	instance_data[i].keep_timer = -1;
  689. +	instance_data[i].idle_limit = 0;
  690. +	instance_data[i].idle_timer = -1;
  691. +	instance_data[i].vars = idb_alloc(DB_OPT_RELEASE_DATA);
  692. +	memset(instance_data[i].map, 0, sizeof(instance_data[i].map));
  693. +
  694. +	p->instance_id = i;
  695. +
  696. +	instance_wait.id[instance_wait.count++] = p->instance_id;
  697. +
  698. +	clif_instance_create( party_getavailablesd( p ), name, instance_wait.count, 1);
  699. +
  700. +	instance_subscription_timer(0,0,0,0);
  701. +
  702. +	ShowInfo("[Instance] Created: %s.\n", name);
  703. +
  704. +	return 0;
  705.  }
  706.  
  707.  /*--------------------------------------
  708. - * Used on instance deleting process.
  709. - * Warps all players on each instance map to its save points.
  710. + * Adds maps to the instance
  711.   *--------------------------------------*/
  712. -int instance_del_load(struct map_session_data* sd, va_list args)
  713. +int instance_addmap(short instance_id)
  714.  {
  715. -	int16 m = va_arg(args,int);
  716. -	if( !sd || sd->bl.m != m )
  717. +	int i, m;
  718. +	int cnt_map = 0;
  719. +	struct instance_data *im;
  720. +	struct instance_db *db;
  721. +	struct party_data *p;
  722. +
  723. +	if(instance_id <= 0)
  724.  		return 0;
  725.  
  726. -	pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT);
  727. -	return 1;
  728. -}
  729. +	im = &instance_data[instance_id];
  730.  
  731. -/* for npcs behave differently when being unloaded within a instance */
  732. -int instance_cleanup_sub(struct block_list *bl, va_list ap) {
  733. -	nullpo_ret(bl);
  734. +	// If the instance isn't idle, we can't do anything
  735. +	if(im->state != INSTANCE_IDLE)
  736. +		return 0;
  737.  
  738. -	switch(bl->type) {
  739. -		case BL_PC:
  740. -			map_quit((struct map_session_data *) bl);
  741. -			break;
  742. -		case BL_NPC:
  743. -			npc_unload((struct npc_data *)bl,true);
  744. -			break;
  745. -		case BL_MOB:
  746. -			unit_free(bl,CLR_OUTSIGHT);
  747. -			break;
  748. -		case BL_PET:
  749. -			//There is no need for this, the pet is removed together with the player. [Skotlex]
  750. -			break;
  751. -		case BL_ITEM:
  752. -			map_clearflooritem(bl);
  753. -			break;
  754. -		case BL_SKILL:
  755. -			skill_delunit((struct skill_unit *) bl);
  756. -			break;
  757. +	if((db = instance_searchtype_db(im->type)) == NULL)
  758. +		return 0;
  759. +
  760. +	// Set to busy, update timers
  761. +	im->state = INSTANCE_BUSY;
  762. +	im->idle_limit = (unsigned int)time(NULL) + INSTANCE_LIMIT;
  763. +	im->idle_timer = add_timer(gettick()+INSTANCE_LIMIT, instance_delete_timer, instance_id, 0);
  764. +
  765. +	// Add the maps
  766. +	for(i = 0; i < MAX_MAP_PER_INSTANCE; i++) {
  767. +		if(strlen(db->mapname[i]) < 1)
  768. +			continue;
  769. +		else if( (m = map_addinstancemap(db->mapname[i], instance_id)) < 0) {
  770. +			// An error occured adding a map
  771. +			ShowError("instance_addmap: No maps added to instance %d.\n",instance_id);
  772. +			return 0;
  773. +		} else {
  774. +			im->map[cnt_map].m = m;
  775. +			im->map[cnt_map].src_m = map_mapname2mapid(db->mapname[i]);
  776. +			cnt_map++;
  777. +		}
  778.  	}
  779.  
  780. -	return 1;
  781. +	im->cnt_map = cnt_map;
  782. +
  783. +	// Create NPCs on all maps
  784. +	instance_addnpc(im);
  785. +
  786. +	// Inform party members of the created instance
  787. +	if( (p = party_search( im->party_id ) ) != NULL )
  788. +		clif_instance_status( party_getavailablesd( p ), db->name, im->keep_limit, im->idle_limit, 1);
  789. +
  790. +	return cnt_map;
  791.  }
  792.  
  793. -/*--------------------------------------
  794. - * Removes a simple instance map
  795. - *--------------------------------------*/
  796. -void instance_del_map(int16 m)
  797. +
  798. +/*==========================================
  799. + * Returns an instance map ID using a map name
  800. + * name : source map
  801. + * instance_id : where to search
  802. + * result : mapid of map "name" in this instance
  803. + *------------------------------------------*/
  804. +int instance_mapname2mapid(const char *name, short instance_id)
  805.  {
  806. +	struct instance_data *im;
  807. +	int m = map_mapname2mapid(name);
  808. +	char iname[12];
  809.  	int i;
  810. -	if( m <= 0 || !map[m].instance_id )
  811. -	{
  812. -		ShowError("Tried to remove non-existing instance map (%d)\n", m);
  813. -		return;
  814. +
  815. +	if(m < 0) {
  816. +		ShowError("instance_mapname2mapid: map name %s does not exist.\n",name);
  817. +		return m;
  818.  	}
  819.  
  820. -	map_foreachpc(instance_del_load, m);
  821. -	map_foreachinmap(instance_cleanup_sub, m, BL_ALL);
  822. +	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
  823. +		return m;
  824.  
  825. -	if( map[m].mob_delete_timer != INVALID_TIMER )
  826. -		delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
  827. +	im = &instance_data[instance_id];
  828. +	if(im->state != INSTANCE_BUSY)
  829. +		return m;
  830.  
  831. -	mapindex_removemap( map[m].index );
  832. +	for(i = 0; i < MAX_MAP_PER_INSTANCE; i++)
  833. +		if(im->map[i].src_m == m) {
  834. +			snprintf(iname, sizeof(iname), ((strchr(name,'@') == NULL)?"%.3d#%s":"%.3d%s"), instance_id, name);
  835. +			return mapindex_name2id(iname);
  836. +		}
  837.  
  838. -	// Free memory
  839. -	aFree(map[m].cell);
  840. -	aFree(map[m].block);
  841. -	aFree(map[m].block_mob);
  842. +	return m;
  843. +}
  844.  
  845. -	// Remove from instance
  846. -	for( i = 0; i < instance[map[m].instance_id].num_map; i++ )
  847. -	{
  848. -		if( instance[map[m].instance_id].map[i] == m )
  849. -		{
  850. -			instance[map[m].instance_id].num_map--;
  851. -			for( ; i < instance[map[m].instance_id].num_map; i++ )
  852. -				instance[map[m].instance_id].map[i] = instance[map[m].instance_id].map[i+1];
  853. -			i = -1;
  854. -			break;
  855. +/*==========================================
  856. + * Removes a instance, all its maps and npcs.
  857. + *------------------------------------------*/
  858. +int instance_destroy(short instance_id)
  859. +{
  860. +	struct instance_data *im;
  861. +	struct party_data *p;
  862. +	int i, type = 0, count = 0;
  863. +	unsigned int now = (unsigned int)time(NULL);
  864. +
  865. +	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
  866. +		return 1;
  867. +
  868. +	im = &instance_data[instance_id];
  869. +
  870. +	if(im->state == INSTANCE_FREE)
  871. +		return 1;
  872. +
  873. +	if(im->state == INSTANCE_IDLE) {
  874. +		for(i = 0; i < instance_wait.count; i++) {
  875. +			if(instance_wait.id[i] == instance_id) {
  876. +				instance_wait.count--;
  877. +				memmove(&instance_wait.id[i],&instance_wait.id[i+1],sizeof(instance_wait.id[0])*(instance_wait.count-i));
  878. +				memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));
  879. +
  880. +				for(i = 0; i < instance_wait.count; i++)
  881. +					if(instance_data[instance_wait.id[i]].state == INSTANCE_IDLE)
  882. +						if((p = party_search(instance_data[instance_wait.id[i]].party_id)) != NULL)
  883. +							clif_instance_changewait( party_getavailablesd( p ), i+1, 1);
  884. +
  885. +				if(instance_wait.count)
  886. +					instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
  887. +				else
  888. +					instance_wait.timer = -1;
  889. +				type = 0;
  890. +				break;
  891. +			}
  892.  		}
  893. +	} else {
  894. +		if(im->keep_limit && im->keep_limit <= now)
  895. +			type = 1;
  896. +		else if(im->idle_limit && im->idle_limit <= now)
  897. +			type = 2;
  898. +		else
  899. +			type = 3;
  900. +
  901. +		for(i = 0; i < MAX_MAP_PER_INSTANCE; i++)
  902. +			count += map_delinstancemap(im->map[i].m);
  903.  	}
  904. -	if( i == instance[map[m].instance_id].num_map )
  905. -		ShowError("map_instance_del: failed to remove %s from instance list (%s): %d\n", map[m].name, instance[map[m].instance_id].name, m);
  906.  
  907. -	map_removemapdb(&map[m]);
  908. -	memset(&map[m], 0x00, sizeof(map[0]));
  909. +	if(im->keep_timer != -1) {
  910. +		delete_timer(im->keep_timer, instance_delete_timer);
  911. +		im->keep_timer = -1;
  912. +	}
  913. +	if(im->idle_timer != -1) {
  914. +		delete_timer(im->idle_timer, instance_delete_timer);
  915. +		im->idle_timer = -1;
  916. +	}
  917.  
  918. -	/* for it is default and makes it not try to delete a non-existent timer since we did not delete this entry. */
  919. -	map[m].mob_delete_timer = INVALID_TIMER;
  920. +	if((p = party_search(im->party_id))) {
  921. +		p->instance_id = 0;
  922. +
  923. +		if(type)
  924. +			clif_instance_changestatus( party_getavailablesd( p ), type, 0, 1 );
  925. +		else
  926. +			clif_instance_changewait( party_getavailablesd( p ), 0xffff, 1 );
  927. +	}
  928. +
  929. +	if( im->vars ) {
  930. +		db_destroy(im->vars);
  931. +		im->vars = NULL;
  932. +	}
  933. +
  934. +	im->type = 0;
  935. +	im->state = INSTANCE_FREE;
  936. +	im->party_id = 0;
  937. +	im->keep_limit = 0;
  938. +	im->idle_limit = 0;
  939. +	ShowInfo("[Instance] Destroyed %d.\n", instance_data[i].map);
  940. +
  941. +	memset(instance_data[i].map, 0, sizeof(instance_data[i].map));
  942. +
  943. +	return 0;
  944.  }
  945.  
  946. -/*--------------------------------------
  947. - * Timer to destroy instance by process or idle
  948. - *--------------------------------------*/
  949. -int instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data)
  950. +/*==========================================
  951. + * Allows a user to enter an instance
  952. + *------------------------------------------*/
  953. +int instance_enter(struct map_session_data *sd, const char *name)
  954.  {
  955. -	instance_destroy(id);
  956. +	struct instance_data *im;
  957. +	struct instance_db *db = instance_searchname_db(name);
  958. +	struct party_data *p;
  959. +	int m;
  960. +
  961. +	nullpo_retr(-1, sd);
  962. +
  963. +	if(db == NULL)
  964. +		return 1;
  965. +
  966. +	// Character must be in instance party
  967. +	if(sd->status.party_id == 0)
  968. +		return 2;
  969. +	if((p = party_search(sd->status.party_id)) == NULL)
  970. +		return 2;
  971. +
  972. +	// Party must have an instance
  973. +	if(p->instance_id == 0)
  974. +		return 3;
  975. +
  976. +	im = &instance_data[p->instance_id];
  977. +	if(im->party_id != p->party.party_id)
  978. +		return 3;
  979. +	if(im->state != INSTANCE_BUSY)
  980. +		return 3;
  981. +	if(im->type != db->type)
  982. +		return 3;
  983. +
  984. +	// Does the instance match?
  985. +	if((m = instance_mapname2mapid(db->enter.mapname, p->instance_id)) < 0)
  986. +		return 4;
  987. +
  988. +	if(pc_setpos(sd, m, db->enter.x, db->enter.y, 0))
  989. +		return 4;
  990. +
  991. +	// If there was an idle timer, let's stop it
  992. +	instance_stopidletimer(im);
  993. +
  994. +	// Now we start the instance timer
  995. +	instance_startkeeptimer(im, p->instance_id);
  996. +
  997.  	return 0;
  998.  }
  999.  
  1000. -/*--------------------------------------
  1001. - * Removes a instance, all its maps and npcs.
  1002. - *--------------------------------------*/
  1003. -void instance_destroy(int instance_id)
  1004. +/*==========================================
  1005. + * Request some info about the instance
  1006. + *------------------------------------------*/
  1007. +int instance_reqinfo(struct map_session_data *sd, short instance_id)
  1008.  {
  1009. -	int last = 0, type;
  1010. -	struct party_data *p;
  1011. -	time_t now = time(NULL);
  1012. +	struct instance_data *im;
  1013. +	struct instance_db *db;
  1014. +	int i;
  1015.  
  1016. -	if( !instance_is_valid(instance_id) )
  1017. -		return; // nothing to do
  1018. +	nullpo_retr(1, sd);
  1019.  
  1020. -	if( instance[instance_id].progress_timeout && instance[instance_id].progress_timeout <= now )
  1021. -		type = 1;
  1022. -	else if( instance[instance_id].idle_timeout && instance[instance_id].idle_timeout <= now )
  1023. -		type = 2;
  1024. -	else
  1025. -		type = 3;
  1026. +	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
  1027. +		return 1;
  1028.  
  1029. -	clif_instance(instance_id, 5, type); // Report users this instance has been destroyed
  1030. +	im = &instance_data[instance_id];
  1031.  
  1032. -	while( instance[instance_id].num_map && last != instance[instance_id].map[0] )
  1033. -	{ // Remove all maps from instance
  1034. -		last = instance[instance_id].map[0];
  1035. -		instance_del_map( instance[instance_id].map[0] );
  1036. -	}
  1037. +	if((db = instance_searchtype_db(im->type)) == NULL)
  1038. +		return 1;
  1039.  
  1040. -	if( instance[instance_id].vars )
  1041. -		db_destroy(instance[instance_id].vars);
  1042. +	// Say it's created if instance is not busy
  1043. +	if(im->state == INSTANCE_IDLE) {
  1044. +		for(i = 0; i < instance_wait.count; i++) {
  1045. +			if(instance_wait.id[i] == instance_id) {
  1046. +				clif_instance_create(sd, db->name, i+1, 0);
  1047. +				break;
  1048. +			}
  1049. +		}
  1050. +	} else if(im->state == INSTANCE_BUSY) // Give info on the instance if busy
  1051. +		clif_instance_status(sd, db->name, im->keep_limit, im->idle_limit, 0);
  1052.  
  1053. -	if( instance[instance_id].progress_timer != INVALID_TIMER )
  1054. -		delete_timer( instance[instance_id].progress_timer, instance_destroy_timer);
  1055. -	if( instance[instance_id].idle_timer != INVALID_TIMER )
  1056. -		delete_timer( instance[instance_id].idle_timer, instance_destroy_timer);
  1057. +	return 0;
  1058. +}
  1059.  
  1060. -	instance[instance_id].vars = NULL;
  1061. +/*==========================================
  1062. + * Add players to the instance (for timers)
  1063. + *------------------------------------------*/
  1064. +int instance_addusers(short instance_id)
  1065. +{
  1066. +	struct instance_data *im;
  1067.  
  1068. -	if( instance[instance_id].party_id && (p = party_search(instance[instance_id].party_id)) != NULL )
  1069. -		p->instance_id = 0; // Update Party information
  1070. +	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
  1071. +		return 1;
  1072.  
  1073. -	ShowInfo("[Instance] Destroyed %s.\n", instance[instance_id].name);
  1074. -	memset( &instance[instance_id], 0x00, sizeof(instance[0]) );
  1075. +	im = &instance_data[instance_id];
  1076. +	if(im->state != INSTANCE_BUSY)
  1077. +		return 1;
  1078.  
  1079. -	instance[instance_id].state = INSTANCE_FREE;
  1080. +	// Stop the idle timer if we had one
  1081. +	instance_stopidletimer(im);
  1082. +
  1083. +	// Start the instance keep timer
  1084. +	instance_startkeeptimer(im, instance_id);
  1085. +
  1086. +	return 0;
  1087.  }
  1088.  
  1089. -/*--------------------------------------
  1090. - * Checks if there are users in the instance or not to start idle timer
  1091. - *--------------------------------------*/
  1092. -void instance_check_idle(int instance_id)
  1093. +/*==========================================
  1094. + * Delete players from the instance (for timers)
  1095. + *------------------------------------------*/
  1096. +int instance_delusers(short instance_id)
  1097.  {
  1098. -	bool idle = true;
  1099. -	time_t now = time(NULL);
  1100. +	struct instance_data *im;
  1101. +	int i, idle = 0;
  1102.  
  1103. -	if( !instance_is_valid(instance_id) || instance[instance_id].idle_timeoutval == 0 )
  1104. -		return;
  1105. +	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
  1106. +		return 1;
  1107.  
  1108. -	if( instance[instance_id].users )
  1109. -		idle = false;
  1110. +	im = &instance_data[instance_id];
  1111. +	if(im->state != INSTANCE_BUSY)
  1112. +		return 1;
  1113.  
  1114. -	if( instance[instance_id].idle_timer != INVALID_TIMER && !idle )
  1115. -	{
  1116. -		delete_timer(instance[instance_id].idle_timer, instance_destroy_timer);
  1117. -		instance[instance_id].idle_timer = INVALID_TIMER;
  1118. -		instance[instance_id].idle_timeout = 0;
  1119. -		clif_instance(instance_id, 3, 0); // Notify instance users normal instance expiration
  1120. -	}
  1121. -	else if( instance[instance_id].idle_timer == INVALID_TIMER && idle )
  1122. -	{
  1123. -		instance[instance_id].idle_timeout = now + instance[instance_id].idle_timeoutval;
  1124. -		instance[instance_id].idle_timer = add_timer( gettick() + (unsigned int)instance[instance_id].idle_timeoutval * 1000, instance_destroy_timer, instance_id, 0);
  1125. -		clif_instance(instance_id, 4, 0); // Notify instance users it will be destroyed of no user join it again in "X" time
  1126. -	}
  1127. +	// If no one is in the instance, start the idle timer
  1128. +	for(i = 0; im->map[i].m && i < MAX_MAP_PER_INSTANCE; i++)
  1129. +		if(map[im->map[i].m].users > 1) // We check this before the actual map.users are updated, hence the 1
  1130. +			idle++;
  1131. +
  1132. +	if(!idle) // If idle wasn't added to, we know no one was in the instance
  1133. +		instance_startidletimer(im, instance_id);
  1134. +
  1135. +	return 0;
  1136.  }
  1137.  
  1138. -/*--------------------------------------
  1139. - * Set instance Timers
  1140. - *--------------------------------------*/
  1141. -void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout)
  1142. +/*==========================================
  1143. + * Read the instance_db.txt file
  1144. + *------------------------------------------*/
  1145. +static bool instance_readdb_sub(char* str[], int columns, int current)
  1146.  {
  1147. -	time_t now = time(0);
  1148. +	int i, type, k=0;
  1149.  
  1150. -	if( !instance_is_valid(instance_id) )
  1151. -		return;
  1152. +	type=atoi(str[0]);
  1153.  
  1154. -	if( instance[instance_id].progress_timer != INVALID_TIMER )
  1155. -		delete_timer( instance[instance_id].progress_timer, instance_destroy_timer);
  1156. -	if( instance[instance_id].idle_timer != INVALID_TIMER )
  1157. -		delete_timer( instance[instance_id].idle_timer, instance_destroy_timer);
  1158. +	instance_db[type].type=type;
  1159. +	safestrncpy(instance_db[type].name, str[1], 24);
  1160. +	instance_db[type].limit=atoi(str[2]);
  1161. +	safestrncpy(instance_db[type].enter.mapname, str[3], MAP_NAME_LENGTH);
  1162. +	instance_db[type].enter.x=atoi(str[4]);
  1163. +	instance_db[type].enter.y=atoi(str[5]);
  1164.  
  1165. -	if( progress_timeout )
  1166. -	{
  1167. -		instance[instance_id].progress_timeout = now + progress_timeout;
  1168. -		instance[instance_id].progress_timer = add_timer( gettick() + progress_timeout * 1000, instance_destroy_timer, instance_id, 0);
  1169. -	}
  1170. -	else
  1171. -	{
  1172. -		instance[instance_id].progress_timeout = 0;
  1173. -		instance[instance_id].progress_timer = INVALID_TIMER;
  1174. -	}
  1175. +	//Instance maps
  1176. +	for(i=6; i<columns; i++)
  1177. +		if(strlen(str[i])) {
  1178. +			safestrncpy(instance_db[type].mapname[k], str[i], MAP_NAME_LENGTH);
  1179. +			k++;
  1180. +		}
  1181.  
  1182. -	if( idle_timeout )
  1183. -	{
  1184. -		instance[instance_id].idle_timeoutval = idle_timeout;
  1185. -		instance[instance_id].idle_timer = INVALID_TIMER;
  1186. -		instance_check_idle(instance_id);
  1187. -	}
  1188. -	else
  1189. -	{
  1190. -		instance[instance_id].idle_timeoutval = 0;
  1191. -		instance[instance_id].idle_timeout = 0;
  1192. -		instance[instance_id].idle_timer = INVALID_TIMER;
  1193. -	}
  1194. +	return true;
  1195. +}
  1196.  
  1197. -	if( instance[instance_id].idle_timer == INVALID_TIMER && instance[instance_id].progress_timer != INVALID_TIMER )
  1198. -		clif_instance(instance_id, 3, 0);
  1199. +void instance_readdb(void)
  1200. +{
  1201. +
  1202. +	memset(&instance_db, 0, sizeof(instance_db));
  1203. +	sv_readdb(db_path, DBPATH"instance_db.txt", ',', 7, 7+MAX_MAP_PER_INSTANCE, MAX_INSTANCE_DB, &instance_readdb_sub);
  1204. +
  1205.  }
  1206.  
  1207. -/*--------------------------------------
  1208. - * Checks if sd in on a instance and should be kicked from it
  1209. - *--------------------------------------*/
  1210. -void instance_check_kick(struct map_session_data *sd)
  1211. +/*==========================================
  1212. + * Reloads the instance in runtime (reloadscript)
  1213. + *------------------------------------------*/
  1214. +void do_reload_instance(void)
  1215.  {
  1216. -	int16 m = sd->bl.m;
  1217. +	struct instance_data *im;
  1218. +	struct instance_db *db;
  1219. +	struct s_mapiterator* iter;
  1220. +	struct map_session_data *sd;
  1221. +	int i;
  1222.  
  1223. -	clif_instance_leave(sd->fd);
  1224. -	if( map[m].instance_id )
  1225. -	{ // User was on the instance map
  1226. -		if( map[m].save.map )
  1227. -			pc_setpos(sd, map[m].save.map, map[m].save.x, map[m].save.y, CLR_TELEPORT);
  1228. -		else
  1229. -			pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
  1230. +	for( i = 1; i < MAX_INSTANCE_DATA; i++ ) {
  1231. +		im = &instance_data[i];
  1232. +		if(!im->cnt_map)
  1233. +			continue;
  1234. +		else {
  1235. +			// First we load the NPCs again
  1236. +			instance_addnpc(im);
  1237. +
  1238. +			// Create new keep timer
  1239. +			if((db = instance_searchtype_db(im->type)) != NULL)
  1240. +				im->keep_limit = (unsigned int)time(NULL) + db->limit;
  1241. +		}
  1242.  	}
  1243. +
  1244. +	// Reset player to instance beginning
  1245. +	iter = mapit_getallusers();
  1246. +	for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
  1247. +		if(sd && map[sd->bl.m].instance_id) {
  1248. +			struct party_data *p;
  1249. +			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
  1250. +				continue;
  1251. +			im = &instance_data[p->instance_id];
  1252. +			if((db = instance_searchtype_db(im->type)) != NULL && !instance_enter(sd,db->name)) { // All good
  1253. +				clif_displaymessage(sd->fd, msg_txt(sd,515)); // Instance has been reloaded
  1254. +				instance_reqinfo(sd,p->instance_id);
  1255. +			} else // Something went wrong
  1256. +				ShowError("do_reload_instance: Error setting character at instance start: character_id=%d instance=%s.\n",sd->status.char_id,db->name);
  1257. +		}
  1258. +	mapit_free(iter);
  1259.  }
  1260.  
  1261. +void do_init_instance(void)
  1262. +{
  1263. +	instance_readdb();
  1264. +	memset(instance_data, 0, sizeof(instance_data));
  1265. +	memset(&instance_wait, 0, sizeof(instance_wait));
  1266. +	instance_wait.timer = -1;
  1267. +
  1268. +	add_timer_func_list(instance_delete_timer,"instance_delete_timer");
  1269. +	add_timer_func_list(instance_subscription_timer,"instance_subscription_timer");
  1270. +}
  1271. +
  1272.  void do_final_instance(void)
  1273.  {
  1274.  	int i;
  1275.  
  1276. -	for( i = 1; i < MAX_INSTANCE; i++ )
  1277. +	for( i = 1; i < MAX_INSTANCE_DATA; i++ )
  1278.  		instance_destroy(i);
  1279.  }
  1280. -
  1281. -void do_init_instance(void)
  1282. -{
  1283. -	memset(instance, 0x00, sizeof(instance));
  1284. -	add_timer_func_list(instance_destroy_timer, "instance_destroy_timer");
  1285. -}
  1286. Index: src/map/instance.h
  1287. ===================================================================
  1288. --- src/map/instance.h	(revision 17385)
  1289. +++ src/map/instance.h	(working copy)
  1290. @@ -4,48 +4,45 @@
  1291.  #ifndef _INSTANCE_H_
  1292.  #define _INSTANCE_H_
  1293.  
  1294. -#define MAX_MAP_PER_INSTANCE 10
  1295. -#define MAX_INSTANCE 500
  1296. +#define MAX_INSTANCE_DATA	300	// Essentially how many instances we can create, but instance creation is primarily decided by MAX_MAP_PER_SERVER	
  1297. +#define MAX_MAP_PER_INSTANCE 	10	// Max number of maps per instance
  1298.  
  1299.  #define INSTANCE_NAME_LENGTH (60+1)
  1300.  
  1301.  typedef enum instance_state { INSTANCE_FREE, INSTANCE_IDLE, INSTANCE_BUSY } instance_state;
  1302.  
  1303. -struct s_instance {
  1304. -	char name[INSTANCE_NAME_LENGTH]; // Instance Name - required for clif functions.
  1305. -	instance_state state;
  1306. -	short instance_id;
  1307. +struct instance_data {
  1308. +	short type, cnt_map;
  1309. +	int state;
  1310.  	int party_id;
  1311. +	unsigned int keep_limit;
  1312. +	int keep_timer;
  1313. +	unsigned int idle_limit;
  1314. +	int idle_timer;
  1315.  
  1316. -	int map[MAX_MAP_PER_INSTANCE];
  1317. -	int num_map;
  1318. -	int users;
  1319. -
  1320.  	struct DBMap* vars; // Instance Variable for scripts
  1321. -
  1322. -	int progress_timer;
  1323. -	time_t progress_timeout;
  1324. -
  1325. -	int idle_timer;
  1326. -	time_t idle_timeout, idle_timeoutval;
  1327. +	struct {
  1328. +		int m;
  1329. +		int src_m;
  1330. +	} map[MAX_MAP_PER_INSTANCE];
  1331.  };
  1332.  
  1333.  extern int instance_start;
  1334. -extern struct s_instance instance[MAX_INSTANCE];
  1335. +extern struct instance_data instance_data[MAX_INSTANCE_DATA];
  1336.  
  1337.  int instance_create(int party_id, const char *name);
  1338. -int instance_add_map(const char *name, int instance_id, bool usebasename);
  1339. -void instance_del_map(int16 m);
  1340. -int instance_map2imap(int16 m, int instance_id);
  1341. -int instance_mapid2imapid(int16 m, int instance_id);
  1342. -void instance_destroy(int instance_id);
  1343. -void instance_init(int instance_id);
  1344. +int instance_destroy(short instance_id);
  1345. +int instance_enter(struct map_session_data *sd, const char *name);
  1346. +int instance_reqinfo(struct map_session_data *sd, short instance_id);
  1347. +int instance_addusers(short instance_id);
  1348. +int instance_delusers(short instance_id);
  1349. +int instance_mapname2mapid(const char *name, short instance_id);
  1350. +int instance_addmap(short instance_id);
  1351.  
  1352. -void instance_check_idle(int instance_id);
  1353. -void instance_check_kick(struct map_session_data *sd);
  1354. -void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout);
  1355. -
  1356. +void instance_addnpc(struct instance_data *im);
  1357. +void instance_readdb(void);
  1358. +void do_reload_instance(void);
  1359. +void do_init_instance(void);
  1360.  void do_final_instance(void);
  1361. -void do_init_instance(void);
  1362.  
  1363.  #endif
  1364. Index: src/map/map.c
  1365. ===================================================================
  1366. --- src/map/map.c	(revision 17385)
  1367. +++ src/map/map.c	(working copy)
  1368. @@ -1700,6 +1700,9 @@
  1369.  
  1370.  	if (sd->state.permanent_speed == 1) sd->state.permanent_speed = 0; // Remove lock so speed is set back to normal at login.
  1371.  
  1372. +	if( map[sd->bl.m].instance_id )
  1373. +		instance_delusers(map[sd->bl.m].instance_id);
  1374. +
  1375.  	if( sd->ed ) {
  1376.  		elemental_clean_effect(sd->ed);
  1377.  		unit_remove_map(&sd->ed->bl,CLR_TELEPORT);
  1378. @@ -2171,6 +2174,142 @@
  1379.  	return true;
  1380.  }
  1381.  
  1382. +/*==========================================
  1383. + * Add an instance map
  1384. + *------------------------------------------*/
  1385. +int map_addinstancemap(const char *name, int id)
  1386. +{
  1387. +	int src_m = map_mapname2mapid(name);
  1388. +	int dst_m = -1, i;
  1389. +	size_t size;
  1390. +
  1391. +	if(src_m < 0)
  1392. +		return -1;
  1393. +
  1394. +	if(strlen(name) > 20) {
  1395. +		// against buffer overflow
  1396. +		ShowError("map_addisntancemap: can't add long map name \"%s\"\n", name);
  1397. +		return -2;
  1398. +	}
  1399. +
  1400. +	for(i = instance_start; i < MAX_MAP_PER_SERVER; i++) {
  1401. +		if(!map[i].name[0])
  1402. +			break;
  1403. +	}
  1404. +	if(i < map_num) // Destination map value overwrites another
  1405. +		dst_m = i;
  1406. +	else if(i < MAX_MAP_PER_SERVER) // Destination map value increments to new map
  1407. +		dst_m = map_num++;
  1408. +	else {
  1409. +		// Out of bounds
  1410. +		ShowError("map_addinstancemap failed. map_num(%d) > map_max(%d)\n",map_num, MAX_MAP_PER_SERVER);
  1411. +		return -3;
  1412. +	}
  1413. +
  1414. +	// Copy the map
  1415. +	memcpy(&map[dst_m], &map[src_m], sizeof(struct map_data));
  1416. +
  1417. +	// Alter the name
  1418. +	snprintf(map[dst_m].name, sizeof(map[dst_m].name), ((strchr(name,'@') == NULL)?"%.3d#%s":"%.3d%s"), id, name);
  1419. +	map[dst_m].name[MAP_NAME_LENGTH-1] = '\0';
  1420. +
  1421. +	map[dst_m].m = dst_m;
  1422. +	map[dst_m].instance_id = id;
  1423. +	map[dst_m].users = 0;
  1424. +
  1425. +	memset(map[dst_m].npc, 0, sizeof(map[dst_m].npc));
  1426. +	map[dst_m].npc_num = 0;
  1427. +
  1428. +	size = map[dst_m].bxs * map[dst_m].bys * sizeof(struct block_list*);
  1429. +	map[dst_m].block = (struct block_list **)aCalloc(1,size);
  1430. +	map[dst_m].block_mob = (struct block_list **)aCalloc(1,size);
  1431. +
  1432. +	map[dst_m].index = mapindex_addmap(-1, map[dst_m].name);
  1433. +
  1434. +	map_addmap2db(&map[dst_m]);
  1435. +
  1436. +	return dst_m;
  1437. +}
  1438. +
  1439. +/*==========================================
  1440. + * Set player to save point when they leave
  1441. + *------------------------------------------*/
  1442. +static int map_instancemap_leave(struct block_list *bl, va_list ap)
  1443. +{
  1444. +	struct map_session_data* sd;
  1445. +
  1446. +	nullpo_retr(0, bl);
  1447. +	nullpo_retr(0, sd = (struct map_session_data *)bl);
  1448. +
  1449. +	pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, 3);
  1450. +
  1451. +	return 1;
  1452. +}
  1453. +
  1454. +/*==========================================
  1455. + * Remove all units from instance
  1456. + *------------------------------------------*/
  1457. +static int map_instancemap_clean(struct block_list *bl, va_list ap)
  1458. +{
  1459. +	nullpo_retr(0, bl);
  1460. +	switch(bl->type) {
  1461. +		case BL_PC:
  1462. +			map_quit((struct map_session_data *) bl);
  1463. +			break;
  1464. +		case BL_NPC:
  1465. +			npc_unload((struct npc_data *)bl,true);
  1466. +			break;
  1467. +		case BL_MOB:
  1468. +			unit_free(bl,CLR_OUTSIGHT);
  1469. +			break;
  1470. +		case BL_PET:
  1471. +			//There is no need for this, the pet is removed together with the player. [Skotlex]
  1472. +			break;
  1473. +		case BL_ITEM:
  1474. +			map_clearflooritem(bl);
  1475. +			break;
  1476. +		case BL_SKILL:
  1477. +			skill_delunit((struct skill_unit *) bl);
  1478. +			break;
  1479. +	}
  1480. +
  1481. +	return 1;
  1482. +}
  1483. +
  1484. +/*==========================================
  1485. + * Deleting an instance map
  1486. + *------------------------------------------*/
  1487. +int map_delinstancemap(int m)
  1488. +{
  1489. +	if(m < 0)
  1490. +		return 0;
  1491. +	if(map[m].instance_id == 0)
  1492. +		return 0;
  1493. +
  1494. +	// Kick everyone out
  1495. +	map_foreachinmap(map_instancemap_leave, m, BL_PC);
  1496. +
  1497. +	// Do the unit cleanup
  1498. +	map_foreachinmap(map_instancemap_clean, m, BL_ALL);
  1499. +
  1500. +	if( map[m].mob_delete_timer != INVALID_TIMER )
  1501. +		delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
  1502. +
  1503. +	mapindex_removemap( map[m].index );
  1504. +
  1505. +	// Free memory
  1506. +	aFree(map[m].block);
  1507. +	aFree(map[m].block_mob);
  1508. +
  1509. +	map_removemapdb(&map[m]);
  1510. +	memset(&map[m], 0x00, sizeof(map[0]));
  1511. +
  1512. +	// Make delete timers invalid to avoid errors
  1513. +	map[m].mob_delete_timer = INVALID_TIMER;
  1514. +
  1515. +	return 1;
  1516. +}
  1517. +
  1518.  /*=========================================
  1519.   * Dynamic Mobs [Wizputer]
  1520.   *-----------------------------------------*/
  1521. @@ -3086,7 +3225,7 @@
  1522.  
  1523.  	// finished map loading
  1524.  	ShowInfo("Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps."CL_CLL"\n",map_num);
  1525. -	instance_start = map_num; // Next Map Index will be instances
  1526. +	instance_start = map_num + 1; // Next Map Index will be instances
  1527.  
  1528.  	if (maps_removed)
  1529.  		ShowNotice("Maps removed: '"CL_WHITE"%d"CL_RESET"'\n",maps_removed);
  1530. Index: src/map/map.h
  1531. ===================================================================
  1532. --- src/map/map.h	(revision 17385)
  1533. +++ src/map/map.h	(working copy)
  1534. @@ -37,7 +37,7 @@
  1535.  #define AREA_SIZE battle_config.area_size
  1536.  #define DAMAGELOG_SIZE 30
  1537.  #define LOOTITEM_SIZE 10
  1538. -#define MAX_MOBSKILL 50	//Max 128, see mob skill_idx type if need this higher
  1539. +#define MAX_MOBSKILL 50		//Max 128, see mob skill_idx type if need this higher
  1540.  #define MAX_MOB_LIST_PER_MAP 128
  1541.  #define MAX_EVENTQUEUE 2
  1542.  #define MAX_EVENTTIMER 32
  1543. @@ -46,9 +46,9 @@
  1544.  #define MAX_FLOORITEM START_ACCOUNT_NUM
  1545.  #define MAX_LEVEL 160
  1546.  #define MAX_DROP_PER_MAP 48
  1547. -#define MAX_IGNORE_LIST 20 // official is 14
  1548. +#define MAX_IGNORE_LIST 20 	// official is 14
  1549.  #define MAX_VENDING 12
  1550. -#define MAX_MAP_SIZE 512*512 // Wasn't there something like this already? Can't find it.. [Shinryo]
  1551. +#define MAX_MAP_SIZE 512*512 	// Wasn't there something like this already? Can't find it.. [Shinryo]
  1552.  
  1553.  // Added definitions for WoESE objects. [L0ne_W0lf]
  1554.  enum MOBID {
  1555. @@ -573,7 +573,6 @@
  1556.  		unsigned nochat :1;
  1557.  		unsigned partylock :1;
  1558.  		unsigned guildlock :1;
  1559. -		unsigned src4instance : 1; // To flag this map when it's used as a src map for instances
  1560.  		unsigned reset :1; // [Daegaladh]
  1561.  		unsigned chmautojoin : 1; //prevent to auto join map channel
  1562.  		unsigned nousecart : 1;	//prevent open up cart @FIXME client side only atm
  1563. @@ -684,6 +683,10 @@
  1564.  void map_clearflooritem(struct block_list* bl);
  1565.  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);
  1566.  
  1567. +// instances
  1568. +int map_addinstancemap(const char*,int);
  1569. +int map_delinstancemap(int);
  1570. +
  1571.  // player to map session
  1572.  void map_addnickdb(int charid, const char* nick);
  1573.  void map_delnickdb(int charid, const char* nick);
  1574. Index: src/map/npc.c
  1575. ===================================================================
  1576. --- src/map/npc.c	(revision 17385)
  1577. +++ src/map/npc.c	(working copy)
  1578. @@ -2579,15 +2579,11 @@
  1579.  	type = dnd->subtype;
  1580.  
  1581.  	// get placement
  1582. -	if( (type==SHOP || type==CASHSHOP || type==SCRIPT) && strcmp(w1, "-") == 0 )
  1583. -	{// floating shop/chashshop/script
  1584. +	if( (type==SHOP || type==CASHSHOP || type==SCRIPT) && strcmp(w1, "-") == 0 ) {// floating shop/chashshop/script
  1585.  		x = y = dir = 0;
  1586.  		m = -1;
  1587. -	}
  1588. -	else
  1589. -	{
  1590. -		if( sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 )// <map name>,<x>,<y>,<facing>
  1591. -		{
  1592. +	} else {
  1593. +		if( sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 ) { // <map name>,<x>,<y>,<facing>
  1594.  			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);
  1595.  			return end;// next line, try to continue
  1596.  		}
  1597. @@ -2601,8 +2597,7 @@
  1598.  	if( type == WARP && sscanf(w4, "%d,%d", &xs, &ys) == 2 );// <spanx>,<spany>
  1599.  	else if( type == SCRIPT && sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3);// <sprite id>,<triggerX>,<triggerY>
  1600.  	else if( type != WARP ) class_ = atoi(w4);// <sprite id>
  1601. -	else
  1602. -	{
  1603. +	else {
  1604.  		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);
  1605.  		return end;// next line, try to continue
  1606.  	}
  1607. @@ -2620,56 +2615,51 @@
  1608.  	nd->src_id = src_id;
  1609.  	nd->bl.type = BL_NPC;
  1610.  	nd->subtype = (enum npc_subtype)type;
  1611. -	switch( type )
  1612. -	{
  1613. -	case SCRIPT:
  1614. -		++npc_script;
  1615. -		nd->u.scr.xs = xs;
  1616. -		nd->u.scr.ys = ys;
  1617. -		nd->u.scr.script = dnd->u.scr.script;
  1618. -		nd->u.scr.label_list = dnd->u.scr.label_list;
  1619. -		nd->u.scr.label_list_num = dnd->u.scr.label_list_num;
  1620. -		break;
  1621. +	switch( type ) {
  1622. +		case SCRIPT:
  1623. +			++npc_script;
  1624. +			nd->u.scr.xs = xs;
  1625. +			nd->u.scr.ys = ys;
  1626. +			nd->u.scr.script = dnd->u.scr.script;
  1627. +			nd->u.scr.label_list = dnd->u.scr.label_list;
  1628. +			nd->u.scr.label_list_num = dnd->u.scr.label_list_num;
  1629. +			break;
  1630.  
  1631. -	case SHOP:
  1632. -	case CASHSHOP:
  1633. -		++npc_shop;
  1634. -		nd->u.shop.shop_item = dnd->u.shop.shop_item;
  1635. -		nd->u.shop.count = dnd->u.shop.count;
  1636. -		break;
  1637. +		case SHOP:
  1638. +		case CASHSHOP:
  1639. +			++npc_shop;
  1640. +			nd->u.shop.shop_item = dnd->u.shop.shop_item;
  1641. +			nd->u.shop.count = dnd->u.shop.count;
  1642. +			break;
  1643.  
  1644. -	case WARP:
  1645. -		++npc_warp;
  1646. -		if( !battle_config.warp_point_debug )
  1647. -			nd->class_ = WARP_CLASS;
  1648. -		else
  1649. -			nd->class_ = WARP_DEBUG_CLASS;
  1650. -		nd->u.warp.xs = xs;
  1651. -		nd->u.warp.ys = ys;
  1652. -		nd->u.warp.mapindex = dnd->u.warp.mapindex;
  1653. -		nd->u.warp.x = dnd->u.warp.x;
  1654. -		nd->u.warp.y = dnd->u.warp.y;
  1655. -		break;
  1656. +		case WARP:
  1657. +			++npc_warp;
  1658. +			if( !battle_config.warp_point_debug )
  1659. +				nd->class_ = WARP_CLASS;
  1660. +			else
  1661. +				nd->class_ = WARP_DEBUG_CLASS;
  1662. +			nd->u.warp.xs = xs;
  1663. +			nd->u.warp.ys = ys;
  1664. +			nd->u.warp.mapindex = dnd->u.warp.mapindex;
  1665. +			nd->u.warp.x = dnd->u.warp.x;
  1666. +			nd->u.warp.y = dnd->u.warp.y;
  1667. +			break;
  1668.  	}
  1669.  
  1670.  	//Add the npc to its location
  1671. -	if( m >= 0 )
  1672. -	{
  1673. +	if( m >= 0 ) {
  1674.  		map_addnpc(m, nd);
  1675.  		status_change_init(&nd->bl);
  1676.  		unit_dataset(&nd->bl);
  1677.  		nd->ud.dir = dir;
  1678.  		npc_setcells(nd);
  1679.  		map_addblock(&nd->bl);
  1680. -		if( class_ >= 0 )
  1681. -		{
  1682. +		if( class_ >= 0 ) {
  1683.  			status_set_viewdata(&nd->bl, nd->class_);
  1684.  			if( map[nd->bl.m].users )
  1685.  				clif_spawn(&nd->bl);
  1686.  		}
  1687. -	}
  1688. -	else
  1689. -	{
  1690. +	} else {
  1691.  		// we skip map_addnpc, but still add it to the list of ID's
  1692.  		map_addiddb(&nd->bl);
  1693.  	}
  1694. @@ -2688,6 +2678,9 @@
  1695.  		npc_timerevent_export(nd, i);
  1696.  	}
  1697.  
  1698. +	if(!strcmp(filepath,"INSTANCING")) //Instance NPCs will use this for commands
  1699. +		nd->instance_id = map[m].instance_id;
  1700. +
  1701.  	nd->u.scr.timerid = INVALID_TIMER;
  1702.  
  1703.  	return end;
  1704. @@ -2700,21 +2693,27 @@
  1705.  		return 1;
  1706.  
  1707.  	snprintf(newname, ARRAYLENGTH(newname), "dup_%d_%d", map[m].instance_id, snd->bl.id);
  1708. -	if( npc_name2id(newname) != NULL )
  1709. -	{ // Name already in use
  1710. +	if( npc_name2id(newname) != NULL ) { // Name already in use
  1711.  		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);
  1712.  		return 1;
  1713.  	}
  1714.  
  1715. -	if( snd->subtype == WARP )
  1716. -	{ // Adjust destination, if instanced
  1717. +	if( snd->subtype == WARP ) { // Adjust destination, if instanced
  1718.  		struct npc_data *wnd = NULL; // New NPC
  1719. -		int dm = map_mapindex2mapid(snd->u.warp.mapindex), im;
  1720. +		struct instance_data *im = &instance_data[map[m].instance_id];
  1721. +		int dm = map_mapindex2mapid(snd->u.warp.mapindex), imap = 0, i;
  1722.  		if( dm < 0 ) return 1;
  1723.  
  1724. -		im = instance_mapid2imapid(dm, map[m].instance_id);
  1725. -		if( im == -1 )
  1726. -		{
  1727. +		for(i = 0; i < MAX_MAP_PER_INSTANCE; i++)
  1728. +			if(im->map[i].m && map_mapname2mapid(map[im->map[i].src_m].name) == dm) {
  1729. +				imap = map_mapname2mapid(map[m].name);
  1730. +				break; // Instance map matches destination, update to instance map
  1731. +			}
  1732. +
  1733. +		if(!imap)
  1734. +			imap = map_mapname2mapid(map[dm].name);
  1735. +	
  1736. +		if( imap == -1 ) {
  1737.  			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);
  1738.  			return 1;
  1739.  		}
  1740. @@ -2730,7 +2729,7 @@
  1741.  		safestrncpy(wnd->exname, newname, ARRAYLENGTH(wnd->exname));
  1742.  		wnd->class_ = WARP_CLASS;
  1743.  		wnd->speed = 200;
  1744. -		wnd->u.warp.mapindex = map_id2index(im);
  1745. +		wnd->u.warp.mapindex = map_id2index(imap);
  1746.  		wnd->u.warp.x = snd->u.warp.x;
  1747.  		wnd->u.warp.y = snd->u.warp.y;
  1748.  		wnd->u.warp.xs = snd->u.warp.xs;
  1749. @@ -2745,9 +2744,7 @@
  1750.  		if( map[wnd->bl.m].users )
  1751.  			clif_spawn(&wnd->bl);
  1752.  		strdb_put(npcname_db, wnd->exname, wnd);
  1753. -	}
  1754. -	else
  1755. -	{
  1756. +	} else {
  1757.  		static char w1[50], w2[50], w3[50], w4[50];
  1758.  		const char* stat_buf = "- call from instancing subsystem -\n";
  1759.  
  1760. @@ -2766,6 +2763,19 @@
  1761.  	return 0;
  1762.  }
  1763.  
  1764. +int npc_instanceinit(struct npc_data* nd)
  1765. +{
  1766. +	struct event_data *ev;
  1767. +	char evname[EVENT_NAME_LENGTH];
  1768. +
  1769. +	snprintf(evname, ARRAYLENGTH(evname), "%s::OnInstanceInit", nd->exname);
  1770. +
  1771. +	if( ( ev = (struct event_data*)strdb_get(ev_db, evname) ) )
  1772. +		run_script(nd->u.scr.script,ev->pos,0,nd->bl.id);
  1773. +
  1774. +	return 0;
  1775. +}
  1776. +
  1777.  //Set mapcell CELL_NPC to trigger event later
  1778.  void npc_setcells(struct npc_data* nd)
  1779.  {
  1780. @@ -3772,14 +3782,11 @@
  1781.  		"\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
  1782.  		npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
  1783.  
  1784. -	do_final_instance();
  1785. -
  1786. -	for( i = 0; i < ARRAYLENGTH(instance); ++i )
  1787. -		instance_init(instance[i].instance_id);
  1788. -
  1789.  	//Re-read the NPC Script Events cache.
  1790.  	npc_read_event_script();
  1791.  
  1792. +	do_reload_instance();
  1793. +
  1794.  	/* refresh guild castle flags on both woe setups */
  1795.  	npc_event_doall("OnAgitInit");
  1796.  	npc_event_doall("OnAgitInit2");
  1797. Index: src/map/npc.h
  1798. ===================================================================
  1799. --- src/map/npc.h	(revision 17385)
  1800. +++ src/map/npc.h	(working copy)
  1801. @@ -29,19 +29,16 @@
  1802.  	struct view_data *vd;
  1803.  	struct status_change sc; //They can't have status changes, but.. they want the visual opt values.
  1804.  	struct npc_data *master_nd;
  1805. -	short class_;
  1806. -	short speed;
  1807. +	short class_,speed,instance_id;
  1808.  	char name[NAME_LENGTH+1];// display name
  1809.  	char exname[NAME_LENGTH+1];// unique npc name
  1810. -	int chat_id;
  1811. -	int touching_id;
  1812. +	int chat_id,touching_id;
  1813.  	unsigned int next_walktime;
  1814.  
  1815.  	unsigned size : 2;
  1816.  
  1817.  	struct status_data status;
  1818. -	unsigned int level;
  1819. -	unsigned int stat_point;
  1820. +	unsigned int level,stat_point;
  1821.  
  1822.  	void* chatdb; // pointer to a npc_parse struct (see npc_chat.c)
  1823.  	char* path;/* path dir */
  1824. @@ -169,6 +166,7 @@
  1825.  int npc_script_event(struct map_session_data* sd, enum npce_event type);
  1826.  
  1827.  int npc_duplicate4instance(struct npc_data *snd, int16 m);
  1828. +int npc_instanceinit(struct npc_data* nd);
  1829.  int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int points);
  1830.  
  1831.  extern struct npc_data* fake_nd;
  1832. Index: src/map/party.c
  1833. ===================================================================
  1834. --- src/map/party.c	(revision 17385)
  1835. +++ src/map/party.c	(working copy)
  1836. @@ -320,7 +320,7 @@
  1837.  		clif_party_option(p,sd,0x100);
  1838.  		clif_party_info(p,NULL);
  1839.  		if( p->instance_id != 0 )
  1840. -			clif_instance_join(sd->fd, p->instance_id);
  1841. +			instance_reqinfo(sd,p->instance_id);
  1842.  	}
  1843.  	if( char_id != 0 )// requester
  1844.  	{
  1845. @@ -439,7 +439,7 @@
  1846.  	{
  1847.  		p->data[i].sd = sd;
  1848.  		if( p->instance_id )
  1849. -			clif_instance_join(sd->fd,p->instance_id);
  1850. +			instance_reqinfo(sd,p->instance_id);
  1851.  	}
  1852.  	else
  1853.  		sd->status.party_id = 0; //He does not belongs to the party really?
  1854. @@ -498,7 +498,7 @@
  1855.  	clif_charnameupdate(sd); //Update char name's display [Skotlex]
  1856.  
  1857.  	if( p->instance_id )
  1858. -		clif_instance_join(sd->fd, p->instance_id);
  1859. +		instance_reqinfo(sd,p->instance_id);
  1860.  
  1861.  	return 0;
  1862.  }
  1863. @@ -575,8 +575,16 @@
  1864.  		sd->status.party_id = 0;
  1865.  		clif_charnameupdate(sd); //Update name display [Skotlex]
  1866.  		//TODO: hp bars should be cleared too
  1867. -		if( p->instance_id )
  1868. -			instance_check_kick(sd);
  1869. +		if( p->instance_id ) {
  1870. +			int16 m = sd->bl.m;
  1871. +
  1872. +			if( map[m].instance_id ) { // User was on the instance map
  1873. +				if( map[m].save.map )
  1874. +					pc_setpos(sd, map[m].save.map, map[m].save.x, map[m].save.y, CLR_TELEPORT);
  1875. +				else
  1876. +					pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
  1877. +			}
  1878. +		}
  1879.  	}
  1880.  
  1881.  	return 0;
  1882. @@ -594,7 +602,7 @@
  1883.  
  1884.  	if( p->instance_id )
  1885.  	{
  1886. -		instance[p->instance_id].party_id = 0;
  1887. +		instance_data[p->instance_id].party_id = 0;
  1888.  		instance_destroy( p->instance_id );
  1889.  	}
  1890.  
  1891. Index: src/map/pc.c
  1892. ===================================================================
  1893. --- src/map/pc.c	(revision 17385)
  1894. +++ src/map/pc.c	(working copy)
  1895. @@ -4757,39 +4757,30 @@
  1896.   *------------------------------------------*/
  1897.  int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype)
  1898.  {
  1899. -	struct party_data *p;
  1900.  	int16 m;
  1901.  
  1902.  	nullpo_ret(sd);
  1903.  
  1904. -	if( !mapindex || !mapindex_id2name(mapindex) )
  1905. -	{
  1906. +	if( !mapindex || !mapindex_id2name(mapindex) ) {
  1907.  		ShowDebug("pc_setpos: Passed mapindex(%d) is invalid!\n", mapindex);
  1908.  		return 1;
  1909.  	}
  1910.  
  1911. -	if( pc_isdead(sd) )
  1912. -	{ //Revive dead people before warping them
  1913. +	if( pc_isdead(sd) ) { //Revive dead people before warping them
  1914.  		pc_setstand(sd);
  1915.  		pc_setrestartvalue(sd,1);
  1916.  	}
  1917.  
  1918.  	m = map_mapindex2mapid(mapindex);
  1919. -	if( map[m].flag.src4instance && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  1920. -	{
  1921. -		// Request the mapid of this src map into the instance of the party
  1922. -		int im = instance_map2imap(m, p->instance_id);
  1923. -		if( im < 0 )
  1924. -			; // Player will enter the src map for instances
  1925. -		else
  1926. -		{ // Changes destiny to the instance map, not the source map
  1927. -			m = im;
  1928. -			mapindex = map_id2index(m);
  1929. -		}
  1930. -	}
  1931.  
  1932.  	sd->state.changemap = (sd->mapindex != mapindex);
  1933.  	sd->state.warping = 1;
  1934. +
  1935. +	if(sd->status.party_id && map[sd->bl.m].instance_id && sd->state.changemap && !map[m].instance_id) {
  1936. +		struct party_data *p;
  1937. +		if((p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  1938. +			instance_delusers(p->instance_id);
  1939. +	}
  1940.  	if( sd->state.changemap ) { // Misc map-changing settings
  1941.  		int i;
  1942.  		sd->state.pmap = sd->bl.m;
  1943. Index: src/map/script.c
  1944. ===================================================================
  1945. --- src/map/script.c	(revision 17385)
  1946. +++ src/map/script.c	(working copy)
  1947. @@ -345,6 +345,7 @@
  1948.   *------------------------------------------*/
  1949.  const char* parse_subexpr(const char* p,int limit);
  1950.  int run_func(struct script_state *st);
  1951. +int script_instancegetid(struct script_state *st);
  1952.  
  1953.  enum {
  1954.  	MF_NOMEMO,	//0
  1955. @@ -2565,12 +2566,15 @@
  1956.  			}
  1957.  			break;
  1958.  		case '\'':
  1959. -				if (st->instance_id) {
  1960. -					data->u.str = (char*)idb_get(instance[st->instance_id].vars,reference_getuid(data));
  1961. -				} else {
  1962. +			{
  1963. +				int instance_id = script_instancegetid(st);
  1964. +				if( instance_id )
  1965. +					data->u.str = (char*)idb_get(instance_data[instance_id].vars,reference_getuid(data));
  1966. +				else {
  1967.  					ShowWarning("script:get_val: cannot access instance variable '%s', defaulting to \"\"\n", name);
  1968.  					data->u.str = NULL;
  1969.  				}
  1970. +			}
  1971.  			break;
  1972.  		default:
  1973.  			data->u.str = pc_readglobalreg_str(sd, name);
  1974. @@ -2630,12 +2634,15 @@
  1975.  			}
  1976.  			break;
  1977.  		case '\'':
  1978. -				if( st->instance_id )
  1979. -					data->u.num = (int)idb_iget(instance[st->instance_id].vars,reference_getuid(data));
  1980. +			{
  1981. +				int instance_id = script_instancegetid(st);
  1982. +				if( instance_id )
  1983. +					data->u.num = (int)idb_iget(instance_data[instance_id].vars,reference_getuid(data));
  1984.  				else {
  1985.  					ShowWarning("script:get_val: cannot access instance variable '%s', defaulting to 0\n", name);
  1986.  					data->u.num = 0;
  1987.  				}
  1988. +			}
  1989.  			break;
  1990.  		default:
  1991.  			data->u.num = pc_readglobalreg(sd, name);
  1992. @@ -2668,8 +2675,7 @@
  1993.  {
  1994.  	char prefix = name[0];
  1995.  
  1996. -	if( is_string_variable(name) )
  1997. -	{// string variable
  1998. +	if( is_string_variable(name) ) {// string variable
  1999.  		const char* str = (const char*)value;
  2000.  		switch (prefix) {
  2001.  		case '@':
  2002. @@ -2691,17 +2697,18 @@
  2003.  			}
  2004.  			return 1;
  2005.  		case '\'':
  2006. -			if( st->instance_id ) {
  2007. -				idb_remove(instance[st->instance_id].vars, num);
  2008. -				if( str[0] ) idb_put(instance[st->instance_id].vars, num, aStrdup(str));
  2009. +			{
  2010. +				int instance_id = script_instancegetid(st);
  2011. +				if( instance_id ) {
  2012. +					idb_remove(instance_data[instance_id].vars, num);
  2013. +					if( str[0] ) idb_put(instance_data[instance_id].vars, num, aStrdup(str));
  2014. +				}
  2015. +			return 1;
  2016.  			}
  2017. -			return 1;
  2018.  		default:
  2019.  			return pc_setglobalreg_str(sd, name, str);
  2020.  		}
  2021. -	}
  2022. -	else
  2023. -	{// integer variable
  2024. +	} else {// integer variable
  2025.  		int val = (int)__64BPRTSIZE(value);
  2026.  		if(str_data[num&0x00ffffff].type == C_PARAM)
  2027.  		{
  2028. @@ -2739,12 +2746,15 @@
  2029.  			}
  2030.  			return 1;
  2031.  		case '\'':
  2032. -			if( st->instance_id ) {
  2033. -				idb_remove(instance[st->instance_id].vars, num);
  2034. -				if( val != 0 )
  2035. -					idb_iput(instance[st->instance_id].vars, num, val);
  2036. +			{
  2037. +				int instance_id = script_instancegetid(st);
  2038. +				if( instance_id ) {
  2039. +					idb_remove(instance_data[instance_id].vars, num);
  2040. +					if( val != 0 )
  2041. +						idb_iput(instance_data[instance_id].vars, num, val);
  2042. +				}
  2043. +			return 1;
  2044.  			}
  2045. -			return 1;
  2046.  		default:
  2047.  			return pc_setglobalreg(sd, name, val);
  2048.  		}
  2049. @@ -3665,14 +3675,9 @@
  2050.  	int gotocount = script_config.check_gotocount;
  2051.  	TBL_PC *sd;
  2052.  	struct script_stack *stack=st->stack;
  2053. -	struct npc_data *nd;
  2054.  
  2055.  	script_attach_state(st);
  2056.  
  2057. -	nd = map_id2nd(st->oid);
  2058. -	if( nd && map[nd->bl.m].instance_id > 0 )
  2059. -		st->instance_id = map[nd->bl.m].instance_id;
  2060. -
  2061.  	if(st->state == RERUNLINE) {
  2062.  		run_func(st);
  2063.  		if(st->state == GOTO)
  2064. @@ -8815,34 +8820,28 @@
  2065.  	struct map_session_data* sd;
  2066.  	int16 m;
  2067.  
  2068. -	if (script_hasdata(st, 8))
  2069. -	{
  2070. +	if (script_hasdata(st, 8)) {
  2071.  		event = script_getstr(st, 8);
  2072.  		check_event(st, event);
  2073.  	}
  2074.  
  2075. -	if (script_hasdata(st, 9))
  2076. -	{
  2077. +	if (script_hasdata(st, 9)) {
  2078.  		size = script_getnum(st, 9);
  2079. -		if (size > 3)
  2080. -		{
  2081. +		if (size > 3) {
  2082.  			ShowWarning("buildin_monster: Attempted to spawn non-existing size %d for monster class %d\n", size, class_);
  2083.  			return 1;
  2084.  		}
  2085.  	}
  2086.  
  2087. -	if (script_hasdata(st, 10))
  2088. -	{
  2089. +	if (script_hasdata(st, 10)) {
  2090.  		ai = script_getnum(st, 10);
  2091. -		if (ai > 4)
  2092. -		{
  2093. +		if (ai > 4) {
  2094.  			ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
  2095.  			return 1;
  2096.  		}
  2097.  	}
  2098.  
  2099. -	if (class_ >= 0 && !mobdb_checkid(class_))
  2100. -	{
  2101. +	if (class_ >= 0 && !mobdb_checkid(class_)) {
  2102.  		ShowWarning("buildin_monster: Attempted to spawn non-existing monster class %d\n", class_);
  2103.  		return 1;
  2104.  	}
  2105. @@ -8852,17 +8851,7 @@
  2106.  	if (sd && strcmp(mapn, "this") == 0)
  2107.  		m = sd->bl.m;
  2108.  	else
  2109. -	{
  2110.  		m = map_mapname2mapid(mapn);
  2111. -		if (map[m].flag.src4instance && st->instance_id)
  2112. -		{ // Try to redirect to the instance map, not the src map
  2113. -			if ((m = instance_mapid2imapid(m, st->instance_id)) < 0)
  2114. -			{
  2115. -				ShowError("buildin_monster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
  2116. -				return 1;
  2117. -			}
  2118. -		}
  2119. -	}
  2120.  
  2121.  	mob_once_spawn(sd, m, x, y, str, class_, amount, event, size, ai);
  2122.  	return 0;
  2123. @@ -8922,27 +8911,22 @@
  2124.  	struct map_session_data* sd;
  2125.  	int16 m;
  2126.  
  2127. -	if (script_hasdata(st,10))
  2128. -	{
  2129. +	if (script_hasdata(st,10)) {
  2130.  		event = script_getstr(st, 10);
  2131.  		check_event(st, event);
  2132.  	}
  2133.  
  2134. -	if (script_hasdata(st, 11))
  2135. -	{
  2136. +	if (script_hasdata(st, 11)) {
  2137.  		size = script_getnum(st, 11);
  2138. -		if (size > 3)
  2139. -		{
  2140. +		if (size > 3) {
  2141.  			ShowWarning("buildin_monster: Attempted to spawn non-existing size %d for monster class %d\n", size, class_);
  2142.  			return 1;
  2143.  		}
  2144.  	}
  2145.  
  2146. -	if (script_hasdata(st, 12))
  2147. -	{
  2148. +	if (script_hasdata(st, 12)) {
  2149.  		ai = script_getnum(st, 12);
  2150. -		if (ai > 4)
  2151. -		{
  2152. +		if (ai > 4) {
  2153.  			ShowWarning("buildin_monster: Attempted to spawn non-existing ai %d for monster class %d\n", ai, class_);
  2154.  			return 1;
  2155.  		}
  2156. @@ -8953,17 +8937,7 @@
  2157.  	if (sd && strcmp(mapn, "this") == 0)
  2158.  		m = sd->bl.m;
  2159.  	else
  2160. -	{
  2161.  		m = map_mapname2mapid(mapn);
  2162. -		if (map[m].flag.src4instance && st->instance_id)
  2163. -		{ // Try to redirect to the instance map, not the src map
  2164. -			if ((m = instance_mapid2imapid(m, st->instance_id)) < 0)
  2165. -			{
  2166. -				ShowError("buildin_areamonster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
  2167. -				return 1;
  2168. -			}
  2169. -		}
  2170. -	}
  2171.  
  2172.  	mob_once_spawn_area(sd, m, x0, y0, x1, y1, str, class_, amount, event, size, ai);
  2173.  	return 0;
  2174. @@ -9018,9 +8992,6 @@
  2175.  	if( (m=map_mapname2mapid(mapname))<0 )
  2176.  		return 0;
  2177.  
  2178. -	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
  2179. -		return 0;
  2180. -
  2181.  	if( script_hasdata(st,4) ) {
  2182.  		if ( script_getnum(st,4) == 1 ) {
  2183.  			map_foreachinmap(buildin_killmonster_sub, m, BL_MOB, event ,allflag);
  2184. @@ -9059,9 +9030,6 @@
  2185.  	if( (m = map_mapname2mapid(mapname))<0 )
  2186.  		return 0;
  2187.  
  2188. -	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
  2189. -		return 0;
  2190. -
  2191.  	if( script_hasdata(st,3) ) {
  2192.  		if ( script_getnum(st,3) == 1 ) {
  2193.  			map_foreachinmap(buildin_killmonsterall_sub,m,BL_MOB);
  2194. @@ -11569,12 +11537,6 @@
  2195.  		return 0;
  2196.  	}
  2197.  
  2198. -	if( map[m].flag.src4instance && map[m].instance_id == 0 && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
  2199. -	{
  2200. -		script_pushint(st,-1);
  2201. -		return 0;
  2202. -	}
  2203. -
  2204.  	script_pushint(st,map_foreachinmap(buildin_mobcount_sub, m, BL_MOB, event));
  2205.  
  2206.  	return 0;
  2207. @@ -16475,59 +16437,78 @@
  2208.  }
  2209.  
  2210.  /*==========================================
  2211. - * Instancing Script Commands
  2212. + * Instancing System
  2213.   *------------------------------------------*/
  2214. +//Returns an Instance ID
  2215. +//Checks NPC first, then if player is attached we check party
  2216. +int script_instancegetid(struct script_state* st)
  2217. +{
  2218. +	short instance_id = 0;	
  2219.  
  2220. +	struct npc_data *nd;
  2221. +	if( (nd = map_id2nd(st->oid)) && nd->instance_id > 0 )
  2222. +		instance_id = nd->instance_id;
  2223. +	else {
  2224. +		struct map_session_data *sd;
  2225. +		struct party_data *p;
  2226. +		if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  2227. +			instance_id = p->instance_id;
  2228. +	}
  2229. +
  2230. +	return instance_id;
  2231. +}
  2232. +
  2233. +/*==========================================
  2234. + * Creates the instance
  2235. + * Returns Instance ID if created successfully
  2236. + *------------------------------------------*/
  2237.  BUILDIN_FUNC(instance_create)
  2238.  {
  2239. -	const char *name;
  2240. -	int party_id, res;
  2241.  
  2242. -	name = script_getstr(st, 2);
  2243. -	party_id = script_getnum(st, 3);
  2244. +	struct map_session_data *sd;
  2245. +	int res;
  2246.  
  2247. -	res = instance_create(party_id, name);
  2248. -	if( res == -4 ) // Already exists
  2249. -	{
  2250. -		script_pushint(st, -1);
  2251. -		return 0;
  2252. +	if((sd = script_rid2sd(st)) == NULL)
  2253. +		return -1;
  2254. +
  2255. +	if(!sd->status.party_id) {
  2256. +		ShowError("script:instance_create: attempting to start an instance with no attached party.\n");
  2257. +		return -1;
  2258.  	}
  2259. -	else if( res < 0 )
  2260. -	{
  2261. +
  2262. +	res = instance_create(sd->status.party_id, script_getstr(st, 2));
  2263. +	if( res < 0 ) {
  2264.  		const char *err;
  2265. -		switch(res)
  2266. -		{
  2267. -		case -3: err = "No free instances"; break;
  2268. -		case -2: err = "Invalid party ID"; break;
  2269. -		case -1: err = "Invalid type"; break;
  2270. -		default: err = "Unknown"; break;
  2271. +		switch(res) {
  2272. +			case -4: err = "No free instances"; break;
  2273. +			case -2: err = "Invalid party ID"; break;
  2274. +			case -1: err = "Invalid type"; break;
  2275. +			default: err = "Unknown"; break;
  2276.  		}
  2277. -		ShowError("buildin_instance_create: %s [%d].\n", err, res);
  2278. -		script_pushint(st, -2);
  2279. -		return 0;
  2280. +		ShowError("script:instance_create: %s [%d].\n", err, res);
  2281.  	}
  2282.  
  2283.  	script_pushint(st, res);
  2284.  	return 0;
  2285.  }
  2286.  
  2287. +/*==========================================
  2288. + * Destroys an instance (unofficial)
  2289. + * Officially instances are only destroyed by timeout
  2290. + *
  2291. + * instance_destroy {<instance_id>};
  2292. + *------------------------------------------*/
  2293.  BUILDIN_FUNC(instance_destroy)
  2294.  {
  2295. -	int instance_id;
  2296. -	struct map_session_data *sd;
  2297. -	struct party_data *p;
  2298. +	short instance_id;
  2299.  
  2300. -	if( script_hasdata(st, 2) )
  2301. -		instance_id = script_getnum(st, 2);
  2302. -	else if( st->instance_id )
  2303. -		instance_id = st->instance_id;
  2304. -	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  2305. -		instance_id = p->instance_id;
  2306. -	else return 0;
  2307. +	if( script_hasdata(st,2) )
  2308. +		instance_id = script_getnum(st,2);
  2309. +	else
  2310. +		instance_id = script_instancegetid(st);
  2311.  
  2312. -	if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
  2313. -	{
  2314. -		ShowError("buildin_instance_destroy: Trying to destroy invalid instance %d.\n", instance_id);
  2315. +	if( instance_id <= 0 || instance_id >= MAX_MAP_PER_SERVER ) {
  2316. +		ShowError("script:instance_destroy: Trying to destroy invalid instance %d.\n", instance_id);
  2317.  		return 0;
  2318.  	}
  2319.  
  2320. @@ -16535,189 +16516,51 @@
  2321.  	return 0;
  2322.  }
  2323.  
  2324. -BUILDIN_FUNC(instance_attachmap)
  2325. +/*==========================================
  2326. + * Warps player to instance
  2327. + * Results:
  2328. + *	0: Success
  2329. + *	1: Instance not in DB
  2330. + *	2: Character not in party
  2331. + *	3: Party doesn't have instance
  2332. + *	4: Instance doesn't match with party
  2333. + *------------------------------------------*/
  2334. +BUILDIN_FUNC(instance_enter)
  2335.  {
  2336. -	const char *name;
  2337. -	int16 m;
  2338. -	int instance_id;
  2339. -	bool usebasename = false;
  2340. -
  2341. -	name = script_getstr(st,2);
  2342. -	instance_id = script_getnum(st,3);
  2343. -	if( script_hasdata(st,4) && script_getnum(st,4) > 0)
  2344. -		usebasename = true;
  2345. -
  2346. -	if( (m = instance_add_map(name, instance_id, usebasename)) < 0 ) // [Saithis]
  2347. -	{
  2348. -		ShowError("buildin_instance_attachmap: instance creation failed (%s): %d\n", name, m);
  2349. -		script_pushconststr(st, "");
  2350. -		return 0;
  2351. -	}
  2352. -	script_pushconststr(st, map[m].name);
  2353. -
  2354. -	return 0;
  2355. -}
  2356. -
  2357. -BUILDIN_FUNC(instance_detachmap)
  2358. -{
  2359.  	struct map_session_data *sd;
  2360. -	struct party_data *p;
  2361. -	const char *str;
  2362. -	int16 m;
  2363. -	int instance_id;
  2364.  
  2365. -	str = script_getstr(st, 2);
  2366. -	if( script_hasdata(st, 3) )
  2367. -		instance_id = script_getnum(st, 3);
  2368. -	else if( st->instance_id )
  2369. -		instance_id = st->instance_id;
  2370. -	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  2371. -		instance_id = p->instance_id;
  2372. -	else return 0;
  2373. -
  2374. -	if( (m = map_mapname2mapid(str)) < 0 || (m = instance_map2imap(m,instance_id)) < 0 )
  2375. -	{
  2376. -		ShowError("buildin_instance_detachmap: Trying to detach invalid map %s\n", str);
  2377. -		return 0;
  2378. -	}
  2379. -
  2380. -	instance_del_map(m);
  2381. -	return 0;
  2382. -}
  2383. -
  2384. -BUILDIN_FUNC(instance_attach)
  2385. -{
  2386. -	int instance_id;
  2387. -
  2388. -	instance_id = script_getnum(st, 2);
  2389. -	if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
  2390. -		return 0;
  2391. -
  2392. -	st->instance_id = instance_id;
  2393. -	return 0;
  2394. -}
  2395. -
  2396. -BUILDIN_FUNC(instance_id)
  2397. -{
  2398. -	int instance_id;
  2399. -
  2400. -	if( script_hasdata(st, 2) )
  2401. -	{
  2402. -		struct map_session_data *sd;
  2403. -		struct party_data *p;
  2404. -		int type;
  2405. -		type = script_getnum(st, 2);
  2406. -		if( type == 0 )
  2407. -			instance_id = st->instance_id;
  2408. -		else if( type == 1 && (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL )
  2409. -			instance_id = p->instance_id;
  2410. -		else
  2411. -			instance_id = 0;
  2412. -	}
  2413. +	if((sd = script_rid2sd(st)) != NULL)
  2414. +		script_pushint(st,instance_enter(sd,script_getstr(st, 2)));
  2415.  	else
  2416. -		instance_id = st->instance_id;
  2417. -
  2418. -	script_pushint(st, instance_id);
  2419. +		return 1;
  2420.  	return 0;
  2421. -}
  2422.  
  2423. -BUILDIN_FUNC(instance_set_timeout)
  2424. -{
  2425. -	int progress_timeout, idle_timeout;
  2426. -	int instance_id;
  2427. -	struct map_session_data *sd;
  2428. -	struct party_data *p;
  2429. -
  2430. -	progress_timeout = script_getnum(st, 2);
  2431. -	idle_timeout = script_getnum(st, 3);
  2432. -
  2433. -	if( script_hasdata(st, 4) )
  2434. -		instance_id = script_getnum(st, 4);
  2435. -	else if( st->instance_id )
  2436. -		instance_id = st->instance_id;
  2437. -	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  2438. -		instance_id = p->instance_id;
  2439. -	else return 0;
  2440. -
  2441. -	if( instance_id > 0 )
  2442. -		instance_set_timeout(instance_id, progress_timeout, idle_timeout);
  2443. -
  2444. -	return 0;
  2445.  }
  2446.  
  2447. -BUILDIN_FUNC(instance_init)
  2448. -{
  2449. -	int instance_id = script_getnum(st, 2);
  2450. -
  2451. -	if( instance[instance_id].state != INSTANCE_IDLE )
  2452. -	{
  2453. -		ShowError("instance_init: instance already initialized.\n");
  2454. -		return 0;
  2455. -	}
  2456. -
  2457. -	instance_init(instance_id);
  2458. -	return 0;
  2459. -}
  2460. -
  2461. -BUILDIN_FUNC(instance_announce)
  2462. -{
  2463. -	int         instance_id = script_getnum(st,2);
  2464. -	const char *mes         = script_getstr(st,3);
  2465. -	int         flag        = script_getnum(st,4);
  2466. -	const char *fontColor   = script_hasdata(st,5) ? script_getstr(st,5) : NULL;
  2467. -	int         fontType    = script_hasdata(st,6) ? script_getnum(st,6) : 0x190; // default fontType (FW_NORMAL)
  2468. -	int         fontSize    = script_hasdata(st,7) ? script_getnum(st,7) : 12;    // default fontSize
  2469. -	int         fontAlign   = script_hasdata(st,8) ? script_getnum(st,8) : 0;     // default fontAlign
  2470. -	int         fontY       = script_hasdata(st,9) ? script_getnum(st,9) : 0;     // default fontY
  2471. -
  2472. -	int i;
  2473. -	struct map_session_data *sd;
  2474. -	struct party_data *p;
  2475. -
  2476. -	if( instance_id == 0 )
  2477. -	{
  2478. -		if( st->instance_id )
  2479. -			instance_id = st->instance_id;
  2480. -		else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  2481. -			instance_id = p->instance_id;
  2482. -		else return 0;
  2483. -	}
  2484. -
  2485. -	if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
  2486. -		return 0;
  2487. -
  2488. -	for( i = 0; i < instance[instance_id].num_map; i++ )
  2489. -		map_foreachinmap(buildin_announce_sub, instance[instance_id].map[i], BL_PC,
  2490. -			mes, strlen(mes)+1, flag&0xf0, fontColor, fontType, fontSize, fontAlign, fontY);
  2491. -
  2492. -	return 0;
  2493. -}
  2494. -
  2495. +/*==========================================
  2496. + * Returns the name of a duplicated NPC
  2497. + *
  2498. + * instance_npcname <npc_name>{,<instance_id};
  2499. + * <npc_name> is the full name of an NPC
  2500. + *------------------------------------------*/
  2501.  BUILDIN_FUNC(instance_npcname)
  2502.  {
  2503.  	const char *str;
  2504. -	int instance_id = 0;
  2505. +	short instance_id = 0;
  2506.  
  2507. -	struct map_session_data *sd;
  2508. -	struct party_data *p;
  2509.  	struct npc_data *nd;
  2510.  
  2511. -	str = script_getstr(st, 2);
  2512. -	if( script_hasdata(st, 3) )
  2513. -		instance_id = script_getnum(st, 3);
  2514. -	else if( st->instance_id )
  2515. -		instance_id = st->instance_id;
  2516. -	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  2517. -		instance_id = p->instance_id;
  2518. +	str = script_getstr(st,2);
  2519. +	if( script_hasdata(st,3) )
  2520. +		instance_id = script_getnum(st,3);
  2521. +	else
  2522. +		instance_id = script_instancegetid(st);
  2523.  
  2524. -	if( instance_id && (nd = npc_name2id(str)) != NULL )
  2525. - 	{
  2526. +	if( instance_id && (nd = npc_name2id(str)) != NULL ) {
  2527.  		static char npcname[NAME_LENGTH];
  2528.  		snprintf(npcname, sizeof(npcname), "dup_%d_%d", instance_id, nd->bl.id);
  2529.   		script_pushconststr(st,npcname);
  2530. -	}
  2531. -	else
  2532. -	{
  2533. +	} else {
  2534.  		ShowError("script:instance_npcname: invalid instance NPC (instance_id: %d, NPC name: \"%s\".)\n", instance_id, str);
  2535.  		st->state = END;
  2536.  		return 1;
  2537. @@ -16726,62 +16569,88 @@
  2538.  	return 0;
  2539.  }
  2540.  
  2541. -BUILDIN_FUNC(has_instance)
  2542. +/*==========================================
  2543. + * Returns the name of a duplicated map
  2544. + *
  2545. + * instance_mapname <map_name>{,<instance_id};
  2546. + *------------------------------------------*/
  2547. +BUILDIN_FUNC(instance_mapname)
  2548.  {
  2549. -	struct map_session_data *sd;
  2550. -	struct party_data *p;
  2551.   	const char *str;
  2552. +	char iname[12];
  2553.  	int16 m;
  2554. -	int instance_id = 0;
  2555. +	short instance_id = 0;
  2556.  
  2557. - 	str = script_getstr(st, 2);
  2558. -	if( script_hasdata(st, 3) )
  2559. -		instance_id = script_getnum(st, 3);
  2560. -	else if( st->instance_id )
  2561. -		instance_id = st->instance_id;
  2562. -	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  2563. -		instance_id = p->instance_id;
  2564. + 	str = script_getstr(st,2);
  2565. +	if( script_hasdata(st,3) )
  2566. +		instance_id = script_getnum(st,3);
  2567. +	else
  2568. +		instance_id = script_instancegetid(st);
  2569.  
  2570. -	if( !instance_id || (m = map_mapname2mapid(str)) < 0 || (m = instance_map2imap(m, instance_id)) < 0 )
  2571. -	{
  2572. +	// Build the instance mapname
  2573. +	snprintf(iname, sizeof(iname), ((strchr(str,'@') == NULL)?"%.3d#%s":"%.3d%s"), instance_id, str);
  2574. +
  2575. +	// Check that instance mapname is a valid map
  2576. +	if( !instance_id || (m = map_mapname2mapid(iname)) < 0 )
  2577.  		script_pushconststr(st, "");
  2578. -		return 0;
  2579. +	else
  2580. +		script_pushconststr(st, map[m].name);
  2581. +
  2582. +	return 0;
  2583. +}
  2584. +
  2585. +/*==========================================
  2586. + * Returns an Instance ID
  2587. + *------------------------------------------*/
  2588. +BUILDIN_FUNC(instance_id)
  2589. +{
  2590. +	short instance_id;
  2591. +
  2592. +	instance_id = script_instancegetid(st);
  2593. +
  2594. +	if(!instance_id) {
  2595. +		ShowError("script:instance_id: No instance attached to NPC or player");
  2596. +		script_pushint(st, 0);
  2597. +		return 1;
  2598.  	}
  2599.  
  2600. -	script_pushconststr(st, map[m].name);
  2601. +	script_pushint(st, instance_id);
  2602. +		
  2603.  	return 0;
  2604.  }
  2605.  
  2606. +/*==========================================
  2607. + * Warps all players inside an instance
  2608. + *
  2609. + * instance_warpall <map_name>,<x>,<y>{,<instance_id>};
  2610. + *------------------------------------------*/
  2611.  BUILDIN_FUNC(instance_warpall)
  2612.  {
  2613. +	struct party_data *p;
  2614.  	struct map_session_data *pl_sd;
  2615.  	int16 m, i;
  2616. -	int instance_id;
  2617. +	short instance_id;
  2618.  	const char *mapn;
  2619.  	int x, y;
  2620.  	unsigned short mapindex;
  2621. -	struct party_data *p = NULL;
  2622.  
  2623.  	mapn = script_getstr(st,2);
  2624.  	x    = script_getnum(st,3);
  2625.  	y    = script_getnum(st,4);
  2626.  	if( script_hasdata(st,5) )
  2627.  		instance_id = script_getnum(st,5);
  2628. -	else if( st->instance_id )
  2629. -		instance_id = st->instance_id;
  2630. -	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 )
  2631. -		instance_id = p->instance_id;
  2632. -	else return 0;
  2633. +	else
  2634. +		instance_id = script_instancegetid(st);
  2635.  
  2636. -	if( (m = map_mapname2mapid(mapn)) < 0 || (map[m].flag.src4instance && (m = instance_mapid2imapid(m, instance_id)) < 0) )
  2637. +	if( !instance_id || (m = map_mapname2mapid(mapn)) < 0 || (m = instance_mapname2mapid(map[m].name,instance_id)) < 0)
  2638.  		return 0;
  2639.  
  2640. -	if( !(p = party_search(instance[instance_id].party_id)) )
  2641. +	if( !(p = party_search(instance_data[instance_id].party_id)) )
  2642.  		return 0;
  2643.  
  2644.  	mapindex = map_id2index(m);
  2645.  	for( i = 0; i < MAX_PARTY; i++ )
  2646. -		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);
  2647. +		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);
  2648.  
  2649.  	return 0;
  2650.  }
  2651. @@ -16806,39 +16675,39 @@
  2652.  	min = script_hasdata(st,4) ? script_getnum(st,4) : 1; // Minimum Level needed to join the Instance.
  2653.  	max  = script_hasdata(st,5) ? script_getnum(st,5) : MAX_LEVEL; // Maxium Level allowed to join the Instance.
  2654.  
  2655. -	if( min < 1 || min > MAX_LEVEL){
  2656. -		ShowError("instance_check_party: Invalid min level, %d\n", min);
  2657. -		return 0;
  2658. -	}else if(  max < 1 || max > MAX_LEVEL){
  2659. -		ShowError("instance_check_party: Invalid max level, %d\n", max);
  2660. -		return 0;
  2661. +	if( min < 1 || min > MAX_LEVEL) {
  2662. +		ShowError("script:check_party: Invalid min level, %d\n", min);
  2663. +		return 1;
  2664. +	} else if(  max < 1 || max > MAX_LEVEL) {
  2665. +		ShowError("script:check_party: Invalid max level, %d\n", max);
  2666. +		return 1;
  2667.  	}
  2668.  
  2669.  	if( script_hasdata(st,2) )
  2670.  		party_id = script_getnum(st,2);
  2671.  	else return 0;
  2672.  
  2673. -	if( !(p = party_search(party_id)) ){
  2674. +	if( !(p = party_search(party_id)) ) {
  2675.  		script_pushint(st, 0); // Returns false if party does not exist.
  2676.  		return 0;
  2677.  	}
  2678.  
  2679.  	for( i = 0; i < MAX_PARTY; i++ )
  2680.  		if( (pl_sd = p->data[i].sd) )
  2681. -			if(map_id2bl(pl_sd->bl.id)){
  2682. -				if(pl_sd->status.base_level < min){
  2683. +			if(map_id2bl(pl_sd->bl.id)) {
  2684. +				if(pl_sd->status.base_level < min) {
  2685.  					script_pushint(st, 0);
  2686.  					return 0;
  2687. -				}else if(pl_sd->status.base_level > max){
  2688. +				} else if(pl_sd->status.base_level > max) {
  2689.  					script_pushint(st, 0);
  2690.  					return 0;
  2691.  				}
  2692.  					c++;
  2693.  			}
  2694.  
  2695. -	if(c < amount){
  2696. +	if(c < amount)
  2697.  		script_pushint(st, 0); // Not enough Members in the Party to join Instance.
  2698. -	}else
  2699. +	else
  2700.  		script_pushint(st, 1);
  2701.  
  2702.  	return 0;
  2703. @@ -16911,15 +16780,11 @@
  2704.  	int16 m;
  2705.  	int range,mobid,skill_id,skill_lv,casttime,emotion,target,cancel;
  2706.  
  2707. -	if( (m = map_mapname2mapid(script_getstr(st,2))) < 0 )
  2708. -	{
  2709. +	if( (m = map_mapname2mapid(script_getstr(st,2))) < 0 ) {
  2710.  		ShowError("areamobuseskill: invalid map name.\n");
  2711.  		return 0;
  2712.  	}
  2713.  
  2714. -	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
  2715. -		return 0;
  2716. -
  2717.  	center.m = m;
  2718.  	center.x = script_getnum(st,3);
  2719.  	center.y = script_getnum(st,4);
  2720. @@ -18123,17 +17988,12 @@
  2721.  	BUILDIN_DEF(bg_updatescore,"sii"),
  2722.  
  2723.  	// Instancing
  2724. -	BUILDIN_DEF(instance_create,"si"),
  2725. +	BUILDIN_DEF(instance_create,"s"),
  2726.  	BUILDIN_DEF(instance_destroy,"?"),
  2727. -	BUILDIN_DEF(instance_attachmap,"si?"),
  2728. -	BUILDIN_DEF(instance_detachmap,"s?"),
  2729. -	BUILDIN_DEF(instance_attach,"i"),
  2730. -	BUILDIN_DEF(instance_id,"?"),
  2731. -	BUILDIN_DEF(instance_set_timeout,"ii?"),
  2732. -	BUILDIN_DEF(instance_init,"i"),
  2733. -	BUILDIN_DEF(instance_announce,"isi?????"),
  2734. +	BUILDIN_DEF(instance_id,""),
  2735. +	BUILDIN_DEF(instance_enter,"s"),
  2736.  	BUILDIN_DEF(instance_npcname,"s?"),
  2737. -	BUILDIN_DEF(has_instance,"s?"),
  2738. +	BUILDIN_DEF(instance_mapname,"s?"),
  2739.  	BUILDIN_DEF(instance_warpall,"sii?"),
  2740.  	BUILDIN_DEF(instance_check_party,"i???"),
  2741.  	/**
  2742. Index: src/map/script.h
  2743. ===================================================================
  2744. --- src/map/script.h	(revision 17385)
  2745. +++ src/map/script.h	(working copy)
  2746. @@ -126,7 +126,6 @@
  2747.  	struct sleep_data {
  2748.  		int tick,timer,charid;
  2749.  	} sleep;
  2750. -	int instance_id;
  2751.  	//For backing up purposes
  2752.  	struct script_state *bk_st;
  2753.  	int bk_npcid;
  2754. Index: src/map/unit.c
  2755. ===================================================================
  2756. --- src/map/unit.c	(revision 17385)
  2757. +++ src/map/unit.c	(working copy)
  2758. @@ -2109,8 +2109,7 @@
  2759.  		status_change_end(bl, SC_TINDER_BREAKER2, INVALID_TIMER);
  2760.  		status_change_end(bl, SC_HIDING, INVALID_TIMER);
  2761.  		// Ensure the bl is a PC; if so, we'll handle the removal of cloaking and cloaking exceed later
  2762. -		if ( bl->type != BL_PC )
  2763. -		{
  2764. +		if ( bl->type != BL_PC ) {
  2765.  			status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
  2766.  			status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
  2767.  		}
  2768. @@ -2165,8 +2164,7 @@
  2769.  				npc_touchnext_areanpc(sd,true);
  2770.  
  2771.  			// Check if warping and not changing the map.
  2772. -			if ( sd->state.warping && !sd->state.changemap )
  2773. -			{
  2774. +			if ( sd->state.warping && !sd->state.changemap ) {
  2775.  				status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
  2776.  				status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
  2777.  			}
  2778. @@ -2192,8 +2190,7 @@
  2779.  
  2780.  			if( map[bl->m].users <= 0 || sd->state.debug_remove_map )
  2781.  			{// 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]
  2782. -				if( sd->debug_file == NULL || !(sd->state.debug_remove_map) )
  2783. -				{
  2784. +				if( sd->debug_file == NULL || !(sd->state.debug_remove_map) ) {
  2785.  					sd->debug_file = "";
  2786.  					sd->debug_line = 0;
  2787.  					sd->debug_func = "";
  2788. @@ -2215,11 +2212,6 @@
  2789.  			{// decrement the number of active pvp players on the map
  2790.  				--map[bl->m].users_pvp;
  2791.  			}
  2792. -			if( map[bl->m].instance_id )
  2793. -			{
  2794. -				instance[map[bl->m].instance_id].users--;
  2795. -				instance_check_idle(map[bl->m].instance_id);
  2796. -			}
  2797.  			sd->state.debug_remove_map = 1; // temporary state to track double remove_map's [FlavioJS]
  2798.  			sd->debug_file = file;
  2799.  			sd->debug_line = line;
  2800.  
Viewed 251 times, submitted by unknown.