viewing paste Unknown #6383 | Diff

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