viewing paste Unknown #6327 | Diff

Posted on the
  1. Index: src/map/clif.c
  2. ===================================================================
  3. --- src/map/clif.c	(revision 17368)
  4. +++ src/map/clif.c	(working copy)
  5. @@ -9185,10 +9185,10 @@
  6.  	if( !(sd->sc.option&OPTION_INVISIBLE) ) { // increment the number of pvp players on the map
  7.  		map[sd->bl.m].users_pvp++;
  8.  	}
  9. -	if( map[sd->bl.m].instance_id ) {
  10. +/*	if( map[sd->bl.m].instance_id ) {
  11.  		instance[map[sd->bl.m].instance_id].users++;
  12.  		instance_check_idle(map[sd->bl.m].instance_id);
  13. -	}
  14. +	}*/
  15.  	sd->state.debug_remove_map = 0; // temporary state to track double remove_map's [FlavioJS]
  16.  
  17.  	// reset the callshop flag if the player changes map
  18. @@ -15264,102 +15264,95 @@
  19.  
  20.  
  21.  /*==========================================
  22. - * Instancing Window
  23. + * Notifies party members of instance change
  24.   *------------------------------------------*/
  25. -int clif_instance(int instance_id, int type, int flag)
  26. +void clif_instance_create(struct map_session_data *sd, const char *name, int num, int flag)
  27.  {
  28. -	struct map_session_data *sd;
  29. -	struct party_data *p;
  30. -	unsigned char buf[255];
  31. +#if PACKETVER >= 20071128
  32. +	unsigned char buf[65];
  33.  
  34. -	if( (p = party_search(instance[instance_id].party_id)) == NULL || (sd = party_getavailablesd(p)) == NULL )
  35. -		return 0;
  36. +	nullpo_retv(sd);
  37.  
  38. -	switch( type )
  39. -	{
  40. -	case 1:
  41. -		// S 0x2cb <Instance name>.61B <Standby Position>.W
  42. -		// Required to start the instancing information window on Client
  43. -		// This window re-appear each "refresh" of client automatically until type 4 is send to client.
  44. -		WBUFW(buf,0) = 0x02CB;
  45. -		memcpy(WBUFP(buf,2),instance[instance_id].name,INSTANCE_NAME_LENGTH);
  46. -		WBUFW(buf,63) = flag;
  47. -		clif_send(buf,packet_len(0x02CB),&sd->bl,PARTY);
  48. -		break;
  49. -	case 2:
  50. -		// S 0x2cc <Standby Position>.W
  51. -		// To announce Instancing queue creation if no maps available
  52. -		WBUFW(buf,0) = 0x02CC;
  53. -		WBUFW(buf,2) = flag;
  54. -		clif_send(buf,packet_len(0x02CC),&sd->bl,PARTY);
  55. -		break;
  56. -	case 3:
  57. -	case 4:
  58. -		// S 0x2cd <Instance Name>.61B <Instance Remaining Time>.L <Instance Noplayers close time>.L
  59. -		WBUFW(buf,0) = 0x02CD;
  60. -		memcpy(WBUFP(buf,2),instance[instance_id].name,61);
  61. -		if( type == 3 )
  62. -		{
  63. -			WBUFL(buf,63) = (uint32)instance[instance_id].progress_timeout;
  64. -			WBUFL(buf,67) = 0;
  65. -		}
  66. -		else
  67. -		{
  68. -			WBUFL(buf,63) = 0;
  69. -			WBUFL(buf,67) = (uint32)instance[instance_id].idle_timeout;
  70. -		}
  71. -		clif_send(buf,packet_len(0x02CD),&sd->bl,PARTY);
  72. -		break;
  73. -	case 5:
  74. -		// S 0x2ce <Message ID>.L
  75. -		// 0 = Notification (EnterLimitDate update?)
  76. -		// 1 = The Memorial Dungeon expired; it has been destroyed
  77. -		// 2 = The Memorial Dungeon's entry time limit expired; it has been destroyed
  78. -		// 3 = The Memorial Dungeon has been removed.
  79. -		// 4 = Create failure (removes the instance window)
  80. -		WBUFW(buf,0) = 0x02CE;
  81. -		WBUFL(buf,2) = flag;
  82. -		//WBUFL(buf,6) = EnterLimitDate;
  83. -		clif_send(buf,packet_len(0x02CE),&sd->bl,PARTY);
  84. -		break;
  85. +	WBUFW(buf,0) = 0x2cb;
  86. +	memcpy(WBUFP(buf,2),name,61);
  87. +	WBUFB(buf,62) = '\0';	// \0 terminal
  88. +	WBUFW(buf,63) = num;
  89. +	if(flag) {	// A timer has changed or been added
  90. +		clif_send(buf,packet_len(0x2cb),&sd->bl,PARTY);
  91. +	} else {	// No notification
  92. +		memcpy(WFIFOP(sd->fd,0),buf,packet_len(0x2cb));
  93. +		WFIFOSET(sd->fd,packet_len(0x2cb));
  94.  	}
  95. -	return 0;
  96. +#endif
  97. +
  98. +	return;
  99.  }
  100.  
  101. -void clif_instance_join(int fd, int instance_id)
  102. +void clif_instance_changewait(struct map_session_data *sd, int num, int flag)
  103.  {
  104. -	if( instance[instance_id].idle_timer != INVALID_TIMER ) {
  105. -		WFIFOHEAD(fd,packet_len(0x02CD));
  106. -		WFIFOW(fd,0) = 0x02CD;
  107. -		memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
  108. -		WFIFOL(fd,63) = 0;
  109. -		WFIFOL(fd,67) = (uint32)instance[instance_id].idle_timeout;
  110. -		WFIFOSET(fd,packet_len(0x02CD));
  111. -	} else if( instance[instance_id].progress_timer != INVALID_TIMER ) {
  112. -		WFIFOHEAD(fd,packet_len(0x02CD));
  113. -		WFIFOW(fd,0) = 0x02CD;
  114. -		memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
  115. -		WFIFOL(fd,63) = (uint32)instance[instance_id].progress_timeout;;
  116. -		WFIFOL(fd,67) = 0;
  117. -		WFIFOSET(fd,packet_len(0x02CD));
  118. -	} else {
  119. -		WFIFOHEAD(fd,packet_len(0x02CB));
  120. -		WFIFOW(fd,0) = 0x02CB;
  121. -		memcpy(WFIFOP(fd,2),instance[instance_id].name,61);
  122. -		WFIFOW(fd,63) = 0;
  123. -		WFIFOSET(fd,packet_len(0x02CB));
  124. +#if PACKETVER >= 20071128
  125. +	unsigned char buf[4];
  126. +
  127. +	nullpo_retv(sd);
  128. +
  129. +	WBUFW(buf,0) = 0x2cc;
  130. +	WBUFW(buf,2) = num;
  131. +	if(flag) {	// A timer has changed or been added
  132. +		clif_send(buf,packet_len(0x2cc),&sd->bl,PARTY);
  133. +	} else {	// No notification
  134. +		memcpy(WFIFOP(sd->fd,0),buf,packet_len(0x2cc));
  135. +		WFIFOSET(sd->fd,packet_len(0x2cc));
  136.  	}
  137. +#endif
  138. +
  139. +	return;
  140.  }
  141.  
  142. -void clif_instance_leave(int fd)
  143. +void clif_instance_status(struct map_session_data *sd, const char *name, unsigned int limit1, unsigned int limit2, int flag)
  144.  {
  145. -	WFIFOHEAD(fd,packet_len(0x02CE));
  146. -	WFIFOW(fd,0) = 0x02ce;
  147. -	WFIFOL(fd,2) = 4;
  148. -	WFIFOSET(fd,packet_len(0x02CE));
  149. +#if PACKETVER >= 20071128
  150. +	unsigned char buf[71];
  151. +
  152. +	nullpo_retv(sd);
  153. +
  154. +	WBUFW(buf,0) = 0x2cd;
  155. +	memcpy(WBUFP(buf,2),name,61);
  156. +	WBUFB(buf,62) = '\0';	// \0 terminal
  157. +	WBUFL(buf,63) = limit1;
  158. +	WBUFL(buf,67) = limit2;
  159. +	if(flag) {	// A timer has changed or been added
  160. +		clif_send(buf,packet_len(0x2cd),&sd->bl,PARTY);
  161. +	} else {	// No notification
  162. +		memcpy(WFIFOP(sd->fd,0),buf,packet_len(0x2cd));
  163. +		WFIFOSET(sd->fd,packet_len(0x2cd));
  164. +	}
  165. +#endif
  166. +
  167. +	return;
  168.  }
  169.  
  170. +void clif_instance_changestatus(struct map_session_data *sd, int type, unsigned int limit, int flag)
  171. +{
  172. +#if PACKETVER >= 20071128
  173. +	unsigned char buf[10];
  174.  
  175. +	nullpo_retv(sd);
  176. +
  177. +	WBUFW(buf,0) = 0x2ce;
  178. +	WBUFL(buf,2) = type;
  179. +	WBUFL(buf,6) = limit;
  180. +	if(flag) {	// A timer has changed or been added
  181. +		clif_send(buf,packet_len(0x2ce),&sd->bl,PARTY);
  182. +	} else {	// No notification
  183. +		memcpy(WFIFOP(sd->fd,0),buf,packet_len(0x2ce));
  184. +		WFIFOSET(sd->fd,packet_len(0x2ce));
  185. +	}
  186. +#endif
  187. +
  188. +	return;
  189. +}
  190. +
  191. +
  192.  /// Notifies clients about item picked up by a party member (ZC_ITEM_PICKUP_PARTY).
  193.  /// 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
  194.  void clif_party_show_picker(struct map_session_data * sd, struct item * item_data)
  195. Index: src/map/clif.h
  196. ===================================================================
  197. --- src/map/clif.h	(revision 17368)
  198. +++ src/map/clif.h	(working copy)
  199. @@ -570,9 +570,10 @@
  200.  void clif_sendbgemblem_single(int fd, struct map_session_data *sd);
  201.  
  202.  // Instancing
  203. -int clif_instance(int instance_id, int type, int flag);
  204. -void clif_instance_join(int fd, int instance_id);
  205. -void clif_instance_leave(int fd);
  206. +void clif_instance_create(struct map_session_data *sd, const char *name, int num, int flag);
  207. +void clif_instance_changewait(struct map_session_data *sd, int num, int flag);
  208. +void clif_instance_status(struct map_session_data *sd, const char *name, unsigned int limit1, unsigned int limit2, int flag);
  209. +void clif_instance_changestatus(struct map_session_data *sd, int type, unsigned int limit, int flag);
  210.  
  211.  // Custom Fonts
  212.  void clif_font(struct map_session_data *sd);
  213. Index: src/map/instance.c
  214. ===================================================================
  215. --- src/map/instance.c	(revision 17368)
  216. +++ src/map/instance.c	(working copy)
  217. @@ -24,465 +24,685 @@
  218.  #include <stdarg.h>
  219.  #include <time.h>
  220.  
  221. +#define MAX_INSTANCE_DB		15	// Max number of instance types
  222. +#define INSTANCE_INTERVAL	60000	// Interval used to check when an instance is to be destroyed (ms)
  223. +#define INSTANCE_LIMIT		30000	// Idle timer before instance is destroyed (ms)
  224. +
  225.  int instance_start = 0; // To keep the last index + 1 of normal map inserted in the map[ARRAY]
  226. -struct s_instance instance[MAX_INSTANCE];
  227.  
  228. +struct instance_data instance_data[MAX_INSTANCE_DATA];
  229.  
  230. -/// Checks whether given instance id is valid or not.
  231. -static bool instance_is_valid(int instance_id)
  232. +static struct instance_db{
  233. +	short type;
  234. +	char name[61];
  235. +	int limit;
  236. +	struct {
  237. +		char mapname[MAP_NAME_LENGTH_EXT];
  238. +		short x, y;
  239. +	} enter;
  240. +	char mapname[MAX_MAP_PER_INSTANCE][MAP_NAME_LENGTH_EXT];
  241. +} instance_db[MAX_INSTANCE_DB];
  242. +
  243. +static struct {
  244. +	int id[MAX_INSTANCE_DATA];
  245. +	int count;
  246. +	int timer;
  247. +} instance_wait;
  248. +
  249. +/*==========================================
  250. + * Searches for an instance ID in the database
  251. + *------------------------------------------*/
  252. +static struct instance_db *instance_searchtype_db(short instance_type)
  253.  {
  254. -	if( instance_id < 1 || instance_id >= ARRAYLENGTH(instance) )
  255. -	{// out of range
  256. -		return false;
  257. -	}
  258. +	int i;
  259.  
  260. -	if( instance[instance_id].state == INSTANCE_FREE )
  261. -	{// uninitialized/freed instance slot
  262. -		return false;
  263. +	for(i=0; i < MAX_INSTANCE_DB; i++) {
  264. +		if(instance_db[i].type == instance_type)
  265. +			return &instance_db[i];
  266.  	}
  267.  
  268. -	return true;
  269. +	return NULL;
  270.  }
  271.  
  272. -
  273. -/*--------------------------------------
  274. - * name : instance name
  275. - * Return value could be
  276. - * -4 = already exists | -3 = no free instances | -2 = party not found | -1 = invalid type
  277. - * On success return instance_id
  278. - *--------------------------------------*/
  279. -int instance_create(int party_id, const char *name)
  280. +/*==========================================
  281. + * Searches for an instance name in the database
  282. + *------------------------------------------*/
  283. +static struct instance_db *instance_searchname_db(const char *instance_name)
  284.  {
  285.  	int i;
  286. -	struct party_data* p;
  287.  
  288. -	if( ( p = party_search(party_id) ) == NULL )
  289. -	{
  290. -		ShowError("instance_create: party %d not found for instance '%s'.\n", party_id, name);
  291. -		return -2;
  292. +	for(i=0; i < MAX_INSTANCE_DB; i++) {
  293. +		if(strcmp(instance_db[i].name, instance_name) == 0)
  294. +			return &instance_db[i];
  295.  	}
  296.  
  297. -	if( p->instance_id )
  298. -		return -4; // Party already instancing
  299. +	return NULL;
  300. +}
  301.  
  302. -	// Searching a Free Instance
  303. -	// 0 is ignored as this mean "no instance" on maps
  304. -	ARR_FIND(1, MAX_INSTANCE, i, instance[i].state == INSTANCE_FREE);
  305. -	if( i == MAX_INSTANCE )
  306. -	{
  307. -		ShowError("instance_create: no free instances, consider increasing MAX_INSTANCE.\n");
  308. -		return -3;
  309. -	}
  310. +/*==========================================
  311. + * Deletes an instance timer (Destroys instance)
  312. + *------------------------------------------*/
  313. +static int instance_delete_timer(int tid, unsigned int tick, int id, intptr_t data)
  314. +{
  315. +	instance_destroy(id);
  316.  
  317. -	instance[i].state = INSTANCE_IDLE;
  318. -	instance[i].instance_id = i;
  319. -	instance[i].idle_timer = INVALID_TIMER;
  320. -	instance[i].idle_timeout = instance[i].idle_timeoutval = 0;
  321. -	instance[i].progress_timer = INVALID_TIMER;
  322. -	instance[i].progress_timeout = 0;
  323. -	instance[i].users = 0;
  324. -	instance[i].party_id = party_id;
  325. -	instance[i].vars = idb_alloc(DB_OPT_RELEASE_DATA);
  326. -
  327. -	safestrncpy( instance[i].name, name, sizeof(instance[i].name) );
  328. -	memset( instance[i].map, 0x00, sizeof(instance[i].map) );
  329. -	p->instance_id = i;
  330. -
  331. -	clif_instance(i, 1, 0); // Start instancing window
  332. -	ShowInfo("[Instance] Created: %s.\n", name);
  333. -	return i;
  334. +	return 0;
  335.  }
  336.  
  337. -/*--------------------------------------
  338. - * Add a map to the instance using src map "name"
  339. - *--------------------------------------*/
  340. -int instance_add_map(const char *name, int instance_id, bool usebasename)
  341. +/*==========================================
  342. + * Create subscription timer for party
  343. + *------------------------------------------*/
  344. +static int instance_subscription_timer(int tid, unsigned int tick, int id, intptr_t data)
  345.  {
  346. -	int16 m = map_mapname2mapid(name);
  347. -	int i, im = -1;
  348. -	size_t num_cell, size;
  349. +	int i, j, ret;
  350. +	int instance_id = instance_wait.id[0];
  351. +	struct party_data *p;
  352.  
  353. -	if( m < 0 )
  354. -		return -1; // source map not found
  355. +	if(instance_wait.count == 0)
  356. +		return 0;
  357. +	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
  358. +		return 0;
  359.  
  360. -	if( !instance_is_valid(instance_id) )
  361. -	{
  362. -		ShowError("instance_add_map: trying to attach '%s' map to non-existing instance %d.\n", name, instance_id);
  363. -		return -1;
  364. -	}
  365. -	if( instance[instance_id].num_map >= MAX_MAP_PER_INSTANCE )
  366. -	{
  367. -		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);
  368. -		return -2;
  369. -	}
  370. -	if( map[m].instance_id != 0 )
  371. -	{ // Source map already belong to a Instance.
  372. -		ShowError("instance_add_map: trying to instance already instanced map %s.\n", name);
  373. -		return -4;
  374. -	}
  375. +	// Check that maps have been added
  376. +	ret = instance_addmap(instance_id);
  377.  
  378. -	ARR_FIND( instance_start, map_num, i, !map[i].name[0] ); // Searching for a Free Map
  379. -	if( i < map_num ) im = i; // Unused map found (old instance)
  380. -	else if( map_num - 1 >= MAX_MAP_PER_SERVER )
  381. -	{ // No more free maps
  382. -		ShowError("instance_add_map: no more free space to create maps on this server.\n");
  383. -		return -5;
  384. +	// If no maps are created, tell party to wait
  385. +	if(ret == 0) {
  386. +		if((p = party_search(instance_data[instance_id - 1].party_id)) != NULL) {
  387. +			for(i = 0; i < MAX_PARTY; i++) {
  388. +				if(p->data[i].sd) {
  389. +					clif_instance_changewait(p->data[i].sd, 0xffff, 1);
  390. +					break;
  391. +				}
  392. +			}
  393. +		}
  394.  	}
  395. -	else im = map_num++; // Using next map index
  396.  
  397. -	memcpy( &map[im], &map[m], sizeof(struct map_data) ); // Copy source map
  398. -	snprintf(map[im].name, MAP_NAME_LENGTH, (usebasename ? "%.3d#%s" : "%.3d%s"), instance_id, name); // Generate Name for Instance Map
  399. -	map[im].index = mapindex_addmap(-1, map[im].name); // Add map index
  400. +	instance_wait.count--;
  401. +	memmove(&instance_wait.id[0],&instance_wait.id[1],sizeof(instance_wait.id[0])*instance_wait.count);
  402. +	memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));
  403.  
  404. -	if( !map[im].index )
  405. -	{
  406. -		map[im].name[0] = '\0';
  407. -		ShowError("instance_add_map: no more free map indexes.\n");
  408. -		return -3; // No free map index
  409. +	for(i = 0; i < instance_wait.count; i++) {
  410. +		if(instance_data[instance_wait.id[i]-1].state == INSTANCE_IDLE) {
  411. +			if((p = party_search(instance_data[instance_wait.id[i]-1].party_id)) != NULL) {
  412. +				for(j = 0; j < MAX_PARTY; j++) {
  413. +					if(p->data[j].sd) {
  414. +						clif_instance_changewait(p->data[j].sd, i+1, 1);
  415. +						break;
  416. +					}
  417. +				}
  418. +			}
  419. +		}
  420.  	}
  421.  
  422. -	// Reallocate cells
  423. -	num_cell = map[im].xs * map[im].ys;
  424. -	CREATE( map[im].cell, struct mapcell, num_cell );
  425. -	memcpy( map[im].cell, map[m].cell, num_cell * sizeof(struct mapcell) );
  426. +	if(instance_wait.count)
  427. +		instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
  428. +	else
  429. +		instance_wait.timer = -1;
  430.  
  431. -	size = map[im].bxs * map[im].bys * sizeof(struct block_list*);
  432. -	map[im].block = (struct block_list**)aCalloc(size, 1);
  433. -	map[im].block_mob = (struct block_list**)aCalloc(size, 1);
  434. +	return 0;
  435. +}
  436.  
  437. -	memset(map[im].npc, 0x00, sizeof(map[i].npc));
  438. -	map[im].npc_num = 0;
  439. +/*==========================================
  440. + * Adds timer back to party entering instance
  441. + *------------------------------------------*/
  442. +static int instance_startkeeptimer(struct instance_data *im, int instance_id)
  443. +{
  444. +	struct instance_db *db;
  445. +	struct party_data *p;
  446. +	int i;
  447.  
  448. -	memset(map[im].moblist, 0x00, sizeof(map[im].moblist));
  449. -	map[im].mob_delete_timer = INVALID_TIMER;
  450. +	nullpo_retr(0, im);
  451.  
  452. -	map[im].m = im;
  453. -	map[im].instance_id = instance_id;
  454. -	map[im].instance_src_map = m;
  455. -	map[m].flag.src4instance = 1; // Flag this map as a src map for instances
  456. +	// No timer
  457. +	if(im->keep_timer != -1)
  458. +		return 1;
  459.  
  460. -	instance[instance_id].map[instance[instance_id].num_map++] = im; // Attach to actual instance
  461. -	map_addmap2db(&map[im]);
  462. +	if((db = instance_searchtype_db(im->type)) == NULL)
  463. +		return 1;
  464.  
  465. -	return im;
  466. +	// Add timer
  467. +	im->keep_limit = (unsigned int)time(NULL) + db->limit;
  468. +	im->keep_timer = add_timer(gettick()+db->limit*1000, instance_delete_timer, instance_id, 0);
  469. +
  470. +	// Notify party of the added instance timer
  471. +	if((p = party_search(im->party_id)) != NULL) {
  472. +		for(i = 0; i < MAX_PARTY; i++) {
  473. +			if(p->data[i].sd) {
  474. +				clif_instance_status(p->data[i].sd, db->name, im->keep_limit, im->idle_limit, 1);
  475. +				break;
  476. +			}
  477. +		}
  478. +	}
  479. +
  480. +	return 0;
  481.  }
  482.  
  483. -/*--------------------------------------
  484. - * m : source map of this instance
  485. - * party_id : source party of this instance
  486. - * type : result (0 = map id | 1 = instance id)
  487. - *--------------------------------------*/
  488. -int instance_map2imap(int16 m, int instance_id)
  489. +/*==========================================
  490. + * Creates idle timer
  491. + * Default before instance destroy is 5 minutes
  492. + *------------------------------------------*/
  493. +static int instance_startidletimer(struct instance_data *im, int instance_id)
  494.  {
  495. - 	int i;
  496. +	struct instance_db *db;
  497. +	struct party_data *p;
  498. +	int i;
  499.  
  500. -	if( !instance_is_valid(instance_id) )
  501. -	{
  502. -		return -1;
  503. +	nullpo_retr(1, im);
  504. +
  505. +	// No current timer
  506. +	if(im->idle_timer != -1)
  507. +		return 1;
  508. +
  509. +	// Add the timer
  510. +	im->idle_limit = (unsigned int)time(NULL) + INSTANCE_LIMIT;
  511. +	im->idle_timer = add_timer(gettick()+INSTANCE_LIMIT, instance_delete_timer, instance_id, 0);
  512. +
  513. +	// Notify party of added instance timer
  514. +	if((p = party_search(im->party_id)) && (db = instance_searchtype_db(im->type))) {
  515. +		for(i = 0; i < MAX_PARTY; i++) {
  516. +			if(p->data[i].sd) {
  517. +				clif_instance_status(p->data[i].sd, db->name, im->keep_limit, im->idle_limit, 1);
  518. +				break;
  519. +			}
  520. +		}
  521.  	}
  522.  
  523. -	for( i = 0; i < instance[instance_id].num_map; i++ )
  524. - 	{
  525. -		if( instance[instance_id].map[i] && map[instance[instance_id].map[i]].instance_src_map == m )
  526. -			return instance[instance_id].map[i];
  527. - 	}
  528. - 	return -1;
  529. +	return 0;
  530.  }
  531.  
  532. -/*--------------------------------------
  533. - * m : source map
  534. - * instance_id : where to search
  535. - * result : mapid of map "m" in this instance
  536. - *--------------------------------------*/
  537. -int instance_mapid2imapid(int16 m, int instance_id)
  538. +/*==========================================
  539. + * Delete the idle timer
  540. + *------------------------------------------*/
  541. +static int instance_stopidletimer(struct instance_data *im)
  542.  {
  543. -	if( map[m].flag.src4instance == 0 )
  544. -		return m; // not instances found for this map
  545. -	else if( map[m].instance_id )
  546. -	{ // This map is a instance, not a src map instance
  547. -		ShowError("map_instance_mapid2imapid: already instanced (%d / %d)\n", m, instance_id);
  548. -		return -1;
  549. +	struct party_data *p;
  550. +	int i;
  551. +
  552. +	nullpo_retr(0, im);
  553. +	
  554. +	// No timer
  555. +	if(im->idle_timer == -1)
  556. +		return 1;
  557. +
  558. +	// Delete the timer - Party has returned or instance is destroyed
  559. +	im->idle_limit = 0;
  560. +	delete_timer(im->idle_timer, instance_delete_timer);
  561. +	im->idle_timer = -1;
  562. +
  563. +	// Notify the party
  564. +	if((p = party_search(im->party_id)) != NULL) {
  565. +		for(i = 0; i < MAX_PARTY; i++) {
  566. +			if(p->data[i].sd) {
  567. +				clif_instance_changestatus(p->data[i].sd, 0, im->idle_limit, 1);
  568. +				break;
  569. +			}
  570. +		}
  571.  	}
  572.  
  573. -	if( !instance_is_valid(instance_id) )
  574. -		return -1;
  575. -
  576. -	return instance_map2imap(m, instance_id);
  577. +	return 0;
  578.  }
  579.  
  580. -/*--------------------------------------
  581. - * map_instance_map_npcsub
  582. - * Used on Init instance. Duplicates each script on source map
  583. - *--------------------------------------*/
  584. -int instance_map_npcsub(struct block_list* bl, va_list args)
  585. +/*==========================================
  586. + * Add an NPC to an instance
  587. + *------------------------------------------*/
  588. +static int instance_addnpc(struct block_list *bl, va_list ap)
  589.  {
  590. -	struct npc_data* nd = (struct npc_data*)bl;
  591. -	int16 m = va_arg(args, int); // Destination Map
  592. +	struct npc_data* nd;
  593.  
  594. -	npc_duplicate4instance(nd, m);
  595. -	return 1;
  596. +	nullpo_retr(0, bl);
  597. +	nullpo_retr(0, ap);
  598. +	nullpo_retr(0, nd = (struct npc_data *)bl);
  599. +
  600. +	return npc_duplicate4instance(nd, va_arg(ap, int));
  601.  }
  602.  
  603.  /*--------------------------------------
  604. - * Init all map on the instance. Npcs are created here
  605. + * name : instance name
  606. + * Return value could be
  607. + * -4 = already exists | -3 = no free instances | -2 = party not found | -1 = invalid type
  608. + * On success return instance_id
  609.   *--------------------------------------*/
  610. -void instance_init(int instance_id)
  611. +int instance_create(int party_id, const char *name)
  612.  {
  613.  	int i;
  614. +	struct instance_db *db = instance_searchname_db(name);
  615. +	struct party_data *p = party_search(party_id);
  616.  
  617. -	if( !instance_is_valid(instance_id) )
  618. -		return; // nothing to do
  619. +	if(db == NULL) {
  620. +		ShowError("instance_create: map %s not found in instance database.\n", name);
  621. +		return -1;
  622. +	}
  623.  
  624. -	for( i = 0; i < instance[instance_id].num_map; i++ )
  625. -		map_foreachinmap(instance_map_npcsub, map[instance[instance_id].map[i]].instance_src_map, BL_NPC, instance[instance_id].map[i]);
  626. +	if( p == NULL ) {
  627. +		ShowError("instance_create: party %d not found for instance '%s'.\n", party_id, name);
  628. +		return -2;
  629. +	}
  630.  
  631. -	instance[instance_id].state = INSTANCE_BUSY;
  632. -	ShowInfo("[Instance] Initialized %s.\n", instance[instance_id].name);
  633. +	if( p->instance_id )
  634. +		return -4; // Party already instancing
  635. +
  636. +	// Searching a Free Instance
  637. +	// 0 is ignored as this mean "no instance" on maps
  638. +	ARR_FIND(1, MAX_INSTANCE_DB, i, instance_data[i].state == INSTANCE_FREE);
  639. +	if( i >= MAX_INSTANCE_DB )
  640. +		return -3;
  641. +
  642. +	// Checks that there aren't more than MAX_INSTANCE_DATA instances of that map
  643. +	if(instance_wait.count >= MAX_INSTANCE_DATA) {
  644. +		ShowError("instance_create: no free instances, consider increasing MAX_INSTANCE_DATA.\n");
  645. +		return -3;
  646. +	}
  647. +
  648. +	instance_data[i].type = db->type;
  649. +	instance_data[i].state = INSTANCE_IDLE;
  650. +	instance_data[i].party_id = p->party.party_id;
  651. +	instance_data[i].keep_limit = 0;
  652. +	instance_data[i].keep_timer = -1;
  653. +	instance_data[i].idle_limit = 0;
  654. +	instance_data[i].idle_timer = -1;
  655. +	instance_data[i].users = 0;
  656. +	memset(instance_data[i].map, 0, sizeof(instance_data[i].map));
  657. +
  658. +	//Always start at instance ID of 1
  659. +	p->instance_id = i + 1;
  660. +
  661. +	instance_wait.id[instance_wait.count++] = p->instance_id;
  662. +	if(instance_wait.timer == -1)
  663. +		instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
  664. +
  665. +	for(i = 0; i < MAX_PARTY; i++) {
  666. +		if(p->data[i].sd) {
  667. +			clif_instance_create(p->data[i].sd, name, instance_wait.count, 1);
  668. +			break;
  669. +		}
  670. +	}
  671. +
  672. +	ShowInfo("[Instance] Created: %s.\n", name);
  673. +
  674. +	return i;
  675.  }
  676.  
  677.  /*--------------------------------------
  678. - * Used on instance deleting process.
  679. - * Warps all players on each instance map to its save points.
  680. + * Adds maps to the instance
  681.   *--------------------------------------*/
  682. -int instance_del_load(struct map_session_data* sd, va_list args)
  683. +int instance_addmap(int instance_id)
  684.  {
  685. -	int16 m = va_arg(args,int);
  686. -	if( !sd || sd->bl.m != m )
  687. +	int i, m;
  688. +	int cnt_map = 0, cnt_npc = 0;
  689. +	struct instance_data *im;
  690. +	struct instance_db *db;
  691. +	struct party_data *p;
  692. +
  693. +	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
  694.  		return 0;
  695.  
  696. -	pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_OUTSIGHT);
  697. -	return 1;
  698. -}
  699. +	im = &instance_data[instance_id-1];
  700.  
  701. -/* for npcs behave differently when being unloaded within a instance */
  702. -int instance_cleanup_sub(struct block_list *bl, va_list ap) {
  703. -	nullpo_ret(bl);
  704. +	// If the instance isn't idle, we can't do anything
  705. +	if(im->state != INSTANCE_IDLE)
  706. +		return 0;
  707.  
  708. -	switch(bl->type) {
  709. -		case BL_PC:
  710. -			map_quit((struct map_session_data *) bl);
  711. +	if((db = instance_searchtype_db(im->type)) == NULL)
  712. +		return 0;
  713. +
  714. +	// Set to busy, update timers
  715. +	im->state = INSTANCE_BUSY;
  716. +	im->idle_limit = (unsigned int)time(NULL) + INSTANCE_LIMIT;
  717. +	im->idle_timer = add_timer(gettick()+INSTANCE_LIMIT*1000, instance_delete_timer, instance_id, 0);
  718. +
  719. +	// Add the maps
  720. +	for(i = 0; i < MAX_MAP_PER_INSTANCE; i++) {
  721. +		m = map_addinstancemap(db->mapname[i], instance_id);
  722. +		if(m < 0)
  723. +			continue;
  724. +		im->map[cnt_map].m = m;
  725. +		im->map[cnt_map].src_m = map_mapname2mapid(db->mapname[i]);
  726. +		im->cnt_map++;
  727. +	}
  728. +
  729. +	// Create NPCs on all maps
  730. +	for(i = 0; i < cnt_map; i++) 
  731. +		cnt_npc += map_foreachinarea(instance_addnpc, 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);
  732. +
  733. +	// Inform party members of the created instance
  734. +	if((p = party_search(im->party_id)) != NULL) {
  735. +		for(i = 0; i < MAX_PARTY; i++) {
  736. +			clif_instance_status(p->data[i].sd, db->name, im->keep_limit, im->idle_limit, 1);
  737.  			break;
  738. -		case BL_NPC:
  739. -			npc_unload((struct npc_data *)bl,true);
  740. -			break;
  741. -		case BL_MOB:
  742. -			unit_free(bl,CLR_OUTSIGHT);
  743. -			break;
  744. -		case BL_PET:
  745. -			//There is no need for this, the pet is removed together with the player. [Skotlex]
  746. -			break;
  747. -		case BL_ITEM:
  748. -			map_clearflooritem(bl);
  749. -			break;
  750. -		case BL_SKILL:
  751. -			skill_delunit((struct skill_unit *) bl);
  752. -			break;
  753. +		}
  754.  	}
  755.  
  756. -	return 1;
  757. +	return cnt_map;
  758.  }
  759.  
  760.  /*--------------------------------------
  761. - * Removes a simple instance map
  762. + * name : source map
  763. + * instance_id : where to search
  764. + * result : mapid of map "name" in this instance
  765.   *--------------------------------------*/
  766. -void instance_del_map(int16 m)
  767. +int instance_mapname2mapid(const char *name, int instance_id)
  768.  {
  769. +	struct instance_data *im;
  770. +	int m = map_mapname2mapid(name);
  771.  	int i;
  772. -	if( m <= 0 || !map[m].instance_id )
  773. -	{
  774. -		ShowError("Tried to remove non-existing instance map (%d)\n", m);
  775. -		return;
  776. +
  777. +	if(instance_id <= 0 || instance_id > MAX_MAP_PER_SERVER)
  778. +		return m;
  779. +
  780. +	im = &instance_data[instance_id-1];
  781. +	if(im->state != INSTANCE_BUSY)
  782. +		return m;
  783. +
  784. +	for(i = 0; i < MAX_MAP_PER_INSTANCE; i++) {
  785. +		if(im->map[i].src_m == m)
  786. +			return im->map[i].m;
  787.  	}
  788.  
  789. -	map_foreachpc(instance_del_load, m);
  790. -	map_foreachinmap(instance_cleanup_sub, m, BL_ALL);
  791. +	return m;
  792. +}
  793.  
  794. -	if( map[m].mob_delete_timer != INVALID_TIMER )
  795. -		delete_timer(map[m].mob_delete_timer, map_removemobs_timer);
  796. +/*==========================================
  797. + * Removes a instance, all its maps and npcs.
  798. + *------------------------------------------*/
  799. +int instance_destroy(int instance_id)
  800. +{
  801. +	struct instance_data *im;
  802. +	struct party_data *p;
  803. +	int i, j, type = 0, count = 0;
  804. +	unsigned int now = (unsigned int)time(NULL);
  805.  
  806. -	mapindex_removemap( map[m].index );
  807. +	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
  808. +		return 1;
  809.  
  810. -	// Free memory
  811. -	aFree(map[m].cell);
  812. -	aFree(map[m].block);
  813. -	aFree(map[m].block_mob);
  814. +	im = &instance_data[instance_id-1];
  815.  
  816. -	// Remove from instance
  817. -	for( i = 0; i < instance[map[m].instance_id].num_map; i++ )
  818. -	{
  819. -		if( instance[map[m].instance_id].map[i] == m )
  820. -		{
  821. -			instance[map[m].instance_id].num_map--;
  822. -			for( ; i < instance[map[m].instance_id].num_map; i++ )
  823. -				instance[map[m].instance_id].map[i] = instance[map[m].instance_id].map[i+1];
  824. -			i = -1;
  825. -			break;
  826. +	if(im->state == INSTANCE_FREE) {
  827. +		return 1;
  828. +	}
  829. +
  830. +	if(im->state == INSTANCE_IDLE) {
  831. +		for(i = 0; i < instance_wait.count; i++) {
  832. +			if(instance_wait.id[i] == instance_id) {
  833. +				instance_wait.count--;
  834. +				memmove(&instance_wait.id[i],&instance_wait.id[i+1],sizeof(instance_wait.id[0])*(instance_wait.count-i));
  835. +				memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));
  836. +
  837. +				for(i = 0; i < instance_wait.count; i++) {
  838. +					if(instance_data[instance_wait.id[i]-1].state == INSTANCE_IDLE) {
  839. +						if((p = party_search(instance_data[instance_wait.id[i]-1].party_id)) != NULL) {
  840. +							for(j = 0; j < MAX_PARTY; j++) {
  841. +								if(p->data[j].sd) {
  842. +									clif_instance_changewait(p->data[j].sd, i+1, 1);
  843. +									break;
  844. +								}
  845. +							}
  846. +						}
  847. +					}
  848. +				}
  849. +
  850. +				if(instance_wait.count)
  851. +					instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
  852. +				else
  853. +					instance_wait.timer = -1;
  854. +				type = 0;
  855. +				break;
  856. +			}
  857.  		}
  858.  	}
  859. -	if( i == instance[map[m].instance_id].num_map )
  860. -		ShowError("map_instance_del: failed to remove %s from instance list (%s): %d\n", map[m].name, instance[map[m].instance_id].name, m);
  861. +	else {
  862. +		if(im->keep_limit && im->keep_limit <= now)
  863. +			type = 1;
  864. +		else if(im->idle_limit && im->idle_limit <= now)
  865. +			type = 2;
  866. +		else
  867. +			type = 3;
  868.  
  869. -	map_removemapdb(&map[m]);
  870. -	memset(&map[m], 0x00, sizeof(map[0]));
  871. +		for(i = 0; i < MAX_MAP_PER_INSTANCE; i++)
  872. +			count += map_delinstancemap(im->map[i].m);
  873. +	}
  874.  
  875. -	/* for it is default and makes it not try to delete a non-existent timer since we did not delete this entry. */
  876. -	map[m].mob_delete_timer = INVALID_TIMER;
  877. +	if(im->keep_timer != -1) {
  878. +		delete_timer(im->keep_timer, instance_delete_timer);
  879. +		im->keep_timer = -1;
  880. +	}
  881. +	if(im->idle_timer != -1) {
  882. +		delete_timer(im->idle_timer, instance_delete_timer);
  883. +		im->idle_timer = -1;
  884. +	}
  885. +
  886. +	if((p = party_search(im->party_id))) {
  887. +		p->instance_id = 0;
  888. +		for(j = 0; j < MAX_PARTY; j++) {
  889. +			if(p->data[j].sd) {
  890. +				if(type)
  891. +					clif_instance_changestatus(p->data[j].sd, type, 0, 1);
  892. +				else
  893. +					clif_instance_changewait(p->data[j].sd, 0xffff, 1);
  894. +				break;
  895. +			}
  896. +		}
  897. +	}
  898. +
  899. +	im->type = 0;
  900. +	im->state = INSTANCE_FREE;
  901. +	im->party_id = 0;
  902. +	im->keep_limit = 0;
  903. +	im->idle_limit = 0;
  904. +	im->users = 0;
  905. +	ShowInfo("[Instance] Destroyed %d.\n", instance_data[i].map);
  906. +
  907. +	memset(instance_data[i].map, 0, sizeof(instance_data[i].map));
  908. +
  909. +	return 0;
  910.  }
  911.  
  912. -/*--------------------------------------
  913. - * Timer to destroy instance by process or idle
  914. - *--------------------------------------*/
  915. -int instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data)
  916. +/*==========================================
  917. + * Allows a user to enter an instance
  918. + *------------------------------------------*/
  919. +int instance_enter(struct map_session_data *sd, const char *name)
  920.  {
  921. -	instance_destroy(id);
  922. +	struct instance_data *im;
  923. +	struct instance_db *db = instance_searchname_db(name);
  924. +	struct party_data *p;
  925. +	int m;
  926. +
  927. +	nullpo_retr(-1, sd);
  928. +
  929. +	if(db == NULL)
  930. +		return -1;
  931. +
  932. +	// Character must be in instance party
  933. +	if(sd->status.party_id == 0)
  934. +		return -2;
  935. +	if((p = party_search(sd->status.party_id)) == NULL)
  936. +		return -2;
  937. +
  938. +	// Party must have an instance
  939. +	if(p->instance_id == 0)
  940. +		return -3;
  941. +
  942. +	im = &instance_data[p->instance_id-1];
  943. +	if(im->party_id != p->party.party_id)
  944. +		return -3;
  945. +	if(im->state != INSTANCE_BUSY)
  946. +		return -3;
  947. +	if(im->type != db->type)
  948. +		return -3;
  949. +
  950. +	// Does the instance match?
  951. +	if((m = instance_mapname2mapid(db->enter.mapname, p->instance_id)) < 0)
  952. +		return -4;
  953. +	if(pc_setpos(sd, m, db->enter.x, db->enter.y, 0))
  954. +		return -4;
  955. +
  956. +	// If there was an idle timer, let's stop it
  957. +	instance_stopidletimer(im);
  958. +
  959. +	// Now we start the instance timer
  960. +	instance_startkeeptimer(im, p->instance_id);
  961. +
  962.  	return 0;
  963.  }
  964.  
  965. -/*--------------------------------------
  966. - * Removes a instance, all its maps and npcs.
  967. - *--------------------------------------*/
  968. -void instance_destroy(int instance_id)
  969. +/*==========================================
  970. + * Request some info about the instance
  971. + *------------------------------------------*/
  972. +int instance_reqinfo(struct map_session_data *sd, int instance_id)
  973.  {
  974. -	int last = 0, type;
  975. -	struct party_data *p;
  976. -	time_t now = time(NULL);
  977. +	struct instance_data *im;
  978. +	struct instance_db *db;
  979. +	int i;
  980.  
  981. -	if( !instance_is_valid(instance_id) )
  982. -		return; // nothing to do
  983. +	nullpo_retr(1, sd);
  984.  
  985. -	if( instance[instance_id].progress_timeout && instance[instance_id].progress_timeout <= now )
  986. -		type = 1;
  987. -	else if( instance[instance_id].idle_timeout && instance[instance_id].idle_timeout <= now )
  988. -		type = 2;
  989. -	else
  990. -		type = 3;
  991. +	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
  992. +		return 1;
  993.  
  994. -	clif_instance(instance_id, 5, type); // Report users this instance has been destroyed
  995. +	im = &instance_data[instance_id-1];
  996.  
  997. -	while( instance[instance_id].num_map && last != instance[instance_id].map[0] )
  998. -	{ // Remove all maps from instance
  999. -		last = instance[instance_id].map[0];
  1000. -		instance_del_map( instance[instance_id].map[0] );
  1001. +	if((db = instance_searchtype_db(im->type)) == NULL)
  1002. +		return 1;
  1003. +
  1004. +	// Say it's created if instance is not busy
  1005. +	if(im->state == INSTANCE_IDLE) {
  1006. +		for(i = 0; i < instance_wait.count; i++) {
  1007. +			if(instance_wait.id[i] == instance_id) {
  1008. +				clif_instance_create(sd, db->name, i+1, 0);
  1009. +				break;
  1010. +			}
  1011. +		}
  1012.  	}
  1013. +	// Give info on the instance if busy
  1014. +	else if(im->state == INSTANCE_BUSY)
  1015. +		clif_instance_status(sd, db->name, im->keep_limit, im->idle_limit, 0);
  1016.  
  1017. -	if( instance[instance_id].vars )
  1018. -		db_destroy(instance[instance_id].vars);
  1019. +	return 0;
  1020. +}
  1021.  
  1022. -	if( instance[instance_id].progress_timer != INVALID_TIMER )
  1023. -		delete_timer( instance[instance_id].progress_timer, instance_destroy_timer);
  1024. -	if( instance[instance_id].idle_timer != INVALID_TIMER )
  1025. -		delete_timer( instance[instance_id].idle_timer, instance_destroy_timer);
  1026. +/*==========================================
  1027. + * Add players to the instance (for timers)
  1028. + *------------------------------------------*/
  1029. +int instance_addusers(int instance_id)
  1030. +{
  1031. +	struct instance_data *im;
  1032.  
  1033. -	instance[instance_id].vars = NULL;
  1034. +	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
  1035. +		return 1;
  1036.  
  1037. -	if( instance[instance_id].party_id && (p = party_search(instance[instance_id].party_id)) != NULL )
  1038. -		p->instance_id = 0; // Update Party information
  1039. +	im = &instance_data[instance_id-1];
  1040. +	if(im->state != INSTANCE_BUSY)
  1041. +		return 1;
  1042.  
  1043. -	ShowInfo("[Instance] Destroyed %s.\n", instance[instance_id].name);
  1044. -	memset( &instance[instance_id], 0x00, sizeof(instance[0]) );
  1045. +	// Increment the amount of players in instance
  1046. +	im->users++;
  1047.  
  1048. -	instance[instance_id].state = INSTANCE_FREE;
  1049. +	// Stop the idle timer if we had one
  1050. +	instance_stopidletimer(im);
  1051. +
  1052. +	// Start the instance keep timer
  1053. +	instance_startkeeptimer(im, instance_id);
  1054. +
  1055. +	return 0;
  1056.  }
  1057.  
  1058. -/*--------------------------------------
  1059. - * Checks if there are users in the instance or not to start idle timer
  1060. - *--------------------------------------*/
  1061. -void instance_check_idle(int instance_id)
  1062. +/*==========================================
  1063. + * Delete players from the instance (for timers)
  1064. + *------------------------------------------*/
  1065. +int instance_delusers(int instance_id)
  1066.  {
  1067. -	bool idle = true;
  1068. -	time_t now = time(NULL);
  1069. +	struct instance_data *im;
  1070.  
  1071. -	if( !instance_is_valid(instance_id) || instance[instance_id].idle_timeoutval == 0 )
  1072. -		return;
  1073. +	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
  1074. +		return 1;
  1075.  
  1076. -	if( instance[instance_id].users )
  1077. -		idle = false;
  1078. +	im = &instance_data[instance_id-1];
  1079. +	if(im->state != INSTANCE_BUSY)
  1080. +		return 1;
  1081.  
  1082. -	if( instance[instance_id].idle_timer != INVALID_TIMER && !idle )
  1083. -	{
  1084. -		delete_timer(instance[instance_id].idle_timer, instance_destroy_timer);
  1085. -		instance[instance_id].idle_timer = INVALID_TIMER;
  1086. -		instance[instance_id].idle_timeout = 0;
  1087. -		clif_instance(instance_id, 3, 0); // Notify instance users normal instance expiration
  1088. -	}
  1089. -	else if( instance[instance_id].idle_timer == INVALID_TIMER && idle )
  1090. -	{
  1091. -		instance[instance_id].idle_timeout = now + instance[instance_id].idle_timeoutval;
  1092. -		instance[instance_id].idle_timer = add_timer( gettick() + (unsigned int)instance[instance_id].idle_timeoutval * 1000, instance_destroy_timer, instance_id, 0);
  1093. -		clif_instance(instance_id, 4, 0); // Notify instance users it will be destroyed of no user join it again in "X" time
  1094. -	}
  1095. +	// Increment the amount of players in instance
  1096. +	im->users--;
  1097. +
  1098. +	// If no one is in the instance, start the idle timer
  1099. +	if(im->users <= 0)
  1100. +		instance_startidletimer(im, instance_id);
  1101. +
  1102. +	return 0;
  1103.  }
  1104.  
  1105.  /*--------------------------------------
  1106. - * Set instance Timers
  1107. + * Read the instance database
  1108.   *--------------------------------------*/
  1109. -void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout)
  1110. +static int read_instance_db(void)
  1111.  {
  1112. -	time_t now = time(0);
  1113. +	int i = 0, j, k;
  1114. +	FILE *fp;
  1115. +	char line[1024],*p;
  1116.  
  1117. -	if( !instance_is_valid(instance_id) )
  1118. -		return;
  1119. +	memset(&instance_db, 0, sizeof(instance_db));
  1120.  
  1121. -	if( instance[instance_id].progress_timer != INVALID_TIMER )
  1122. -		delete_timer( instance[instance_id].progress_timer, instance_destroy_timer);
  1123. -	if( instance[instance_id].idle_timer != INVALID_TIMER )
  1124. -		delete_timer( instance[instance_id].idle_timer, instance_destroy_timer);
  1125. +	sprintf(line, "%s/"DBPATH"instance_db.txt", db_path);
  1126.  
  1127. -	if( progress_timeout )
  1128. -	{
  1129. -		instance[instance_id].progress_timeout = now + progress_timeout;
  1130. -		instance[instance_id].progress_timer = add_timer( gettick() + progress_timeout * 1000, instance_destroy_timer, instance_id, 0);
  1131. +	fp=fopen(line,"r");
  1132. +	if(fp==NULL){
  1133. +		ShowError("can't read %s/"DBPATH"instance_db.txt\n", db_path);
  1134. +		return 1;
  1135.  	}
  1136. -	else
  1137. -	{
  1138. -		instance[instance_id].progress_timeout = 0;
  1139. -		instance[instance_id].progress_timer = INVALID_TIMER;
  1140. -	}
  1141. +	while(fgets(line,1020,fp)){
  1142. +		char *split[6+MAX_MAP_PER_INSTANCE];
  1143. +		if(line[0] == '\0' || line[0] == '\r' || line[0] == '\n')
  1144. +			continue;
  1145. +		if(line[0]=='/' && line[1]=='/')
  1146. +			continue;
  1147. +		memset(split,0,sizeof(split));
  1148. +		for(j=0,p=line;j<6+MAX_MAP_PER_INSTANCE && p;j++){
  1149. +			split[j]=p;
  1150. +			p=strchr(p,',');
  1151. +			if(p) *p++=0;
  1152. +		}
  1153. +		if(j < 6+MAX_MAP_PER_INSTANCE)
  1154. +			continue;
  1155.  
  1156. -	if( idle_timeout )
  1157. -	{
  1158. -		instance[instance_id].idle_timeoutval = idle_timeout;
  1159. -		instance[instance_id].idle_timer = INVALID_TIMER;
  1160. -		instance_check_idle(instance_id);
  1161. +		instance_db[i].type = (short)atoi(split[0]);
  1162. +		strncpy(instance_db[i].name,split[1],61);
  1163. +		instance_db[i].limit = atoi(split[2]);
  1164. +		strncpy(instance_db[i].enter.mapname,split[3],24);
  1165. +		instance_db[i].enter.x = (short)atoi(split[4]);
  1166. +		instance_db[i].enter.y = (short)atoi(split[5]);
  1167. +
  1168. +		for(k = 0; k < MAX_MAP_PER_INSTANCE; k++) {
  1169. +			strncpy(instance_db[i].mapname[k],split[6+k],24);
  1170. +			instance_db[i].mapname[k][MAP_NAME_LENGTH] = '\0';
  1171. +		}
  1172. +
  1173. +		// force \0 terminal
  1174. +		instance_db[i].name[60] = '\0';
  1175. +		instance_db[i].enter.mapname[MAP_NAME_LENGTH] = '\0';
  1176. +
  1177. +		if(++i >= MAX_INSTANCE_DB)
  1178. +			break;
  1179.  	}
  1180. -	else
  1181. -	{
  1182. -		instance[instance_id].idle_timeoutval = 0;
  1183. -		instance[instance_id].idle_timeout = 0;
  1184. -		instance[instance_id].idle_timer = INVALID_TIMER;
  1185. -	}
  1186. +	fclose(fp);
  1187. +	ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",i, line);
  1188.  
  1189. -	if( instance[instance_id].idle_timer == INVALID_TIMER && instance[instance_id].progress_timer != INVALID_TIMER )
  1190. -		clif_instance(instance_id, 3, 0);
  1191. +	return 0;
  1192.  }
  1193.  
  1194. -/*--------------------------------------
  1195. - * Checks if sd in on a instance and should be kicked from it
  1196. - *--------------------------------------*/
  1197. -void instance_check_kick(struct map_session_data *sd)
  1198. +void do_init_instance(void)
  1199.  {
  1200. -	int16 m = sd->bl.m;
  1201. +	read_instance_db();
  1202. +	memset(instance_data, 0, sizeof(instance_data));
  1203. +	memset(&instance_wait, 0, sizeof(instance_wait));
  1204. +	instance_wait.timer = -1;
  1205.  
  1206. -	clif_instance_leave(sd->fd);
  1207. -	if( map[m].instance_id )
  1208. -	{ // User was on the instance map
  1209. -		if( map[m].save.map )
  1210. -			pc_setpos(sd, map[m].save.map, map[m].save.x, map[m].save.y, CLR_TELEPORT);
  1211. -		else
  1212. -			pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
  1213. -	}
  1214. +	add_timer_func_list(instance_delete_timer,"instance_delete_timer");
  1215. +	add_timer_func_list(instance_subscription_timer,"instance_subscription_timer");
  1216.  }
  1217.  
  1218.  void do_final_instance(void)
  1219.  {
  1220.  	int i;
  1221.  
  1222. -	for( i = 1; i < MAX_INSTANCE; i++ )
  1223. +	for( i = 1; i < MAX_INSTANCE_DATA; i++ )
  1224.  		instance_destroy(i);
  1225.  }
  1226. -
  1227. -void do_init_instance(void)
  1228. -{
  1229. -	memset(instance, 0x00, sizeof(instance));
  1230. -	add_timer_func_list(instance_destroy_timer, "instance_destroy_timer");
  1231. -}
  1232. Index: src/map/instance.h
  1233. ===================================================================
  1234. --- src/map/instance.h	(revision 17368)
  1235. +++ src/map/instance.h	(working copy)
  1236. @@ -4,48 +4,43 @@
  1237.  #ifndef _INSTANCE_H_
  1238.  #define _INSTANCE_H_
  1239.  
  1240. -#define MAX_MAP_PER_INSTANCE 10
  1241. -#define MAX_INSTANCE 500
  1242. +#define MAX_INSTANCE_DATA	50	
  1243. +#define MAX_MAP_PER_INSTANCE 	8	// Max number of maps per instance
  1244.  
  1245.  #define INSTANCE_NAME_LENGTH (60+1)
  1246.  
  1247.  typedef enum instance_state { INSTANCE_FREE, INSTANCE_IDLE, INSTANCE_BUSY } instance_state;
  1248.  
  1249. -struct s_instance {
  1250. -	char name[INSTANCE_NAME_LENGTH]; // Instance Name - required for clif functions.
  1251. -	instance_state state;
  1252. -	short instance_id;
  1253. +struct instance_data {
  1254. +	short type, cnt_map;
  1255. +	int state;
  1256.  	int party_id;
  1257. -
  1258. -	int map[MAX_MAP_PER_INSTANCE];
  1259. -	int num_map;
  1260. +	unsigned int keep_limit;
  1261. +	int keep_timer;
  1262. +	unsigned int idle_limit;
  1263. +	int idle_timer;
  1264.  	int users;
  1265.  
  1266.  	struct DBMap* vars; // Instance Variable for scripts
  1267. -
  1268. -	int progress_timer;
  1269. -	time_t progress_timeout;
  1270. -
  1271. -	int idle_timer;
  1272. -	time_t idle_timeout, idle_timeoutval;
  1273. +	struct {
  1274. +		int m;
  1275. +		int src_m;
  1276. +	} map[MAX_MAP_PER_INSTANCE];
  1277.  };
  1278.  
  1279.  extern int instance_start;
  1280. -extern struct s_instance instance[MAX_INSTANCE];
  1281. +extern struct instance_data instance_data[MAX_INSTANCE_DATA];
  1282.  
  1283.  int instance_create(int party_id, const char *name);
  1284. -int instance_add_map(const char *name, int instance_id, bool usebasename);
  1285. -void instance_del_map(int16 m);
  1286. -int instance_map2imap(int16 m, int instance_id);
  1287. -int instance_mapid2imapid(int16 m, int instance_id);
  1288. -void instance_destroy(int instance_id);
  1289. -void instance_init(int instance_id);
  1290. +int instance_destroy(int instance_id);
  1291. +int instance_enter(struct map_session_data *sd, const char *name);
  1292. +int instance_reqinfo(struct map_session_data *sd, int instance_id);
  1293. +int instance_addusers(int instance_id);
  1294. +int instance_delusers(int instance_id);
  1295. +int instance_mapname2mapid(const char *name, int instance_id);
  1296. +int instance_addmap(int instance_id);
  1297.  
  1298. -void instance_check_idle(int instance_id);
  1299. -void instance_check_kick(struct map_session_data *sd);
  1300. -void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsigned int idle_timeout);
  1301. -
  1302. +void do_init_instance(void);
  1303.  void do_final_instance(void);
  1304. -void do_init_instance(void);
  1305.  
  1306.  #endif
  1307. Index: src/map/map.c
  1308. ===================================================================
  1309. --- src/map/map.c	(revision 17368)
  1310. +++ src/map/map.c	(working copy)
  1311. @@ -2170,6 +2170,133 @@
  1312.  	return true;
  1313.  }
  1314.  
  1315. +/*==========================================
  1316. + * Add an instance map
  1317. + *------------------------------------------*/
  1318. +int map_addinstancemap(const char *name, int id)
  1319. +{
  1320. +	int src_m = map_mapname2mapid(name);
  1321. +	int dst_m = -1, i;
  1322. +	size_t size;
  1323. +
  1324. +	if(src_m < 0)
  1325. +		return -1;
  1326. +
  1327. +	if(strlen(name) > 20) {
  1328. +		// against buffer overflow
  1329. +		printf("map_addmdmap: can't add long map name \"%s\"\n", name);
  1330. +		return -1;
  1331. +	}
  1332. +
  1333. +	for(i = instance_start; i < MAX_MAP_PER_SERVER; i++) {
  1334. +		if(!map[i].name[0])
  1335. +			break;
  1336. +	}
  1337. +	if(i < map_num) // Destination map value overwrites another
  1338. +		dst_m = i;
  1339. +	else if(i < MAX_MAP_PER_SERVER) // Destination map value increments to new map
  1340. +		dst_m = map_num++;
  1341. +	else {
  1342. +		// Out of bounds
  1343. +		printf("map_addmdmap failed. map_num(%d) > map_max(%d)\n",map_num, MAX_MAP_PER_SERVER);
  1344. +		return -1;
  1345. +	}
  1346. +
  1347. +	// Copy the map
  1348. +	memcpy(&map[dst_m], &map[src_m], sizeof(struct map_data));
  1349. +
  1350. +	// Alter the name
  1351. +	snprintf(map[dst_m].name, sizeof(map[dst_m].name), "%03d%s", id, name);
  1352. +	map[dst_m].name[MAP_NAME_LENGTH-1] = '\0';
  1353. +
  1354. +	map[dst_m].m = dst_m;
  1355. +	map[dst_m].instance_id = id;
  1356. +	map[dst_m].users = 0;
  1357. +
  1358. +	memset(map[dst_m].npc, 0, sizeof(map[dst_m].npc));
  1359. +	map[dst_m].npc_num = 0;
  1360. +
  1361. +	size = map[dst_m].bxs * map[dst_m].bys * sizeof(struct block_list*);
  1362. +	map[dst_m].block = (struct block_list **)aCalloc(1,size);
  1363. +	map[dst_m].block_mob = (struct block_list **)aCalloc(1,size);
  1364. +
  1365. +	map_addmap2db(&map[dst_m]);
  1366. +
  1367. +	return dst_m;
  1368. +}
  1369. +
  1370. +/*==========================================
  1371. + * Set player to save point when they leave
  1372. + *------------------------------------------*/
  1373. +static int map_instancemap_leave(struct block_list *bl, va_list ap)
  1374. +{
  1375. +	struct map_session_data* sd;
  1376. +
  1377. +	nullpo_retr(0, bl);
  1378. +	nullpo_retr(0, sd = (struct map_session_data *)bl);
  1379. +
  1380. +	pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, 3);
  1381. +
  1382. +	return 1;
  1383. +}
  1384. +
  1385. +/*==========================================
  1386. + * Remove all units from instance
  1387. + *------------------------------------------*/
  1388. +static int map_instancemap_clean(struct block_list *bl, va_list ap)
  1389. +{
  1390. +	nullpo_retr(0, bl);
  1391. +	switch(bl->type) {
  1392. +		case BL_PC:
  1393. +			map_quit((struct map_session_data *) bl);
  1394. +			break;
  1395. +		case BL_NPC:
  1396. +			npc_unload((struct npc_data *)bl,true);
  1397. +			break;
  1398. +		case BL_MOB:
  1399. +			unit_free(bl,CLR_OUTSIGHT);
  1400. +			break;
  1401. +		case BL_PET:
  1402. +			//There is no need for this, the pet is removed together with the player. [Skotlex]
  1403. +			break;
  1404. +		case BL_ITEM:
  1405. +			map_clearflooritem(bl);
  1406. +			break;
  1407. +		case BL_SKILL:
  1408. +			skill_delunit((struct skill_unit *) bl);
  1409. +			break;
  1410. +	}
  1411. +
  1412. +	return 1;
  1413. +}
  1414. +
  1415. +/*==========================================
  1416. + * Deleting an instance map
  1417. + *------------------------------------------*/
  1418. +int map_delinstancemap(int m)
  1419. +{
  1420. +	if(m < 0)
  1421. +		return 0;
  1422. +	if(map[m].instance_id == 0)
  1423. +		return 0;
  1424. +
  1425. +	// Kick everyone out
  1426. +	map_foreachinarea(map_instancemap_leave, m, 0, 0, map[m].xs, map[m].ys, BL_PC);
  1427. +
  1428. +	// Do the unit cleanup
  1429. +	map_foreachinarea(map_instancemap_clean, m, 0, 0, map[m].xs, map[m].ys, BL_ALL);
  1430. +
  1431. +	if(map[m].block)
  1432. +		aFree(map[m].block);
  1433. +	if(map[m].block_mob)
  1434. +		aFree(map[m].block_mob);
  1435. +
  1436. +	map_removemapdb(&map[m]);
  1437. +	memset(&map[m], 0x00, sizeof(map[0]));
  1438. +
  1439. +	return 1;
  1440. +}
  1441. +
  1442.  /*=========================================
  1443.   * Dynamic Mobs [Wizputer]
  1444.   *-----------------------------------------*/
  1445. Index: src/map/map.h
  1446. ===================================================================
  1447. --- src/map/map.h	(revision 17368)
  1448. +++ src/map/map.h	(working copy)
  1449. @@ -37,7 +37,7 @@
  1450.  #define AREA_SIZE battle_config.area_size
  1451.  #define DAMAGELOG_SIZE 30
  1452.  #define LOOTITEM_SIZE 10
  1453. -#define MAX_MOBSKILL 50	//Max 128, see mob skill_idx type if need this higher
  1454. +#define MAX_MOBSKILL 50		//Max 128, see mob skill_idx type if need this higher
  1455.  #define MAX_MOB_LIST_PER_MAP 128
  1456.  #define MAX_EVENTQUEUE 2
  1457.  #define MAX_EVENTTIMER 32
  1458. @@ -46,9 +46,9 @@
  1459.  #define MAX_FLOORITEM START_ACCOUNT_NUM
  1460.  #define MAX_LEVEL 160
  1461.  #define MAX_DROP_PER_MAP 48
  1462. -#define MAX_IGNORE_LIST 20 // official is 14
  1463. +#define MAX_IGNORE_LIST 20 	// official is 14
  1464.  #define MAX_VENDING 12
  1465. -#define MAX_MAP_SIZE 512*512 // Wasn't there something like this already? Can't find it.. [Shinryo]
  1466. +#define MAX_MAP_SIZE 512*512 	// Wasn't there something like this already? Can't find it.. [Shinryo]
  1467.  
  1468.  // Added definitions for WoESE objects. [L0ne_W0lf]
  1469.  enum MOBID {
  1470. @@ -684,6 +684,10 @@
  1471.  void map_clearflooritem(struct block_list* bl);
  1472.  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);
  1473.  
  1474. +// instances
  1475. +int map_addinstancemap(const char*,int);
  1476. +int map_delinstancemap(int);
  1477. +
  1478.  // player to map session
  1479.  void map_addnickdb(int charid, const char* nick);
  1480.  void map_delnickdb(int charid, const char* nick);
  1481. Index: src/map/npc.c
  1482. ===================================================================
  1483. --- src/map/npc.c	(revision 17368)
  1484. +++ src/map/npc.c	(working copy)
  1485. @@ -2712,7 +2712,7 @@
  1486.  		int dm = map_mapindex2mapid(snd->u.warp.mapindex), im;
  1487.  		if( dm < 0 ) return 1;
  1488.  
  1489. -		im = instance_mapid2imapid(dm, map[m].instance_id);
  1490. +		im = instance_mapname2mapid(map[m].name, map[m].instance_id);
  1491.  		if( im == -1 )
  1492.  		{
  1493.  			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);
  1494. @@ -3774,9 +3774,6 @@
  1495.  
  1496.  	do_final_instance();
  1497.  
  1498. -	for( i = 0; i < ARRAYLENGTH(instance); ++i )
  1499. -		instance_init(instance[i].instance_id);
  1500. -
  1501.  	//Re-read the NPC Script Events cache.
  1502.  	npc_read_event_script();
  1503.  
  1504. Index: src/map/party.c
  1505. ===================================================================
  1506. --- src/map/party.c	(revision 17368)
  1507. +++ src/map/party.c	(working copy)
  1508. @@ -320,7 +320,7 @@
  1509.  		clif_party_option(p,sd,0x100);
  1510.  		clif_party_info(p,NULL);
  1511.  		if( p->instance_id != 0 )
  1512. -			clif_instance_join(sd->fd, p->instance_id);
  1513. +			instance_reqinfo(sd,p->instance_id);
  1514.  	}
  1515.  	if( char_id != 0 )// requester
  1516.  	{
  1517. @@ -439,7 +439,7 @@
  1518.  	{
  1519.  		p->data[i].sd = sd;
  1520.  		if( p->instance_id )
  1521. -			clif_instance_join(sd->fd,p->instance_id);
  1522. +			instance_reqinfo(sd,p->instance_id);
  1523.  	}
  1524.  	else
  1525.  		sd->status.party_id = 0; //He does not belongs to the party really?
  1526. @@ -498,7 +498,7 @@
  1527.  	clif_charnameupdate(sd); //Update char name's display [Skotlex]
  1528.  
  1529.  	if( p->instance_id )
  1530. -		clif_instance_join(sd->fd, p->instance_id);
  1531. +		instance_reqinfo(sd,p->instance_id);
  1532.  
  1533.  	return 0;
  1534.  }
  1535. @@ -575,8 +575,16 @@
  1536.  		sd->status.party_id = 0;
  1537.  		clif_charnameupdate(sd); //Update name display [Skotlex]
  1538.  		//TODO: hp bars should be cleared too
  1539. -		if( p->instance_id )
  1540. -			instance_check_kick(sd);
  1541. +		if( p->instance_id ) {
  1542. +			int16 m = sd->bl.m;
  1543. +
  1544. +			if( map[m].instance_id ) { // User was on the instance map
  1545. +				if( map[m].save.map )
  1546. +					pc_setpos(sd, map[m].save.map, map[m].save.x, map[m].save.y, CLR_TELEPORT);
  1547. +				else
  1548. +					pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
  1549. +			}
  1550. +		}
  1551.  	}
  1552.  
  1553.  	return 0;
  1554. @@ -594,7 +602,7 @@
  1555.  
  1556.  	if( p->instance_id )
  1557.  	{
  1558. -		instance[p->instance_id].party_id = 0;
  1559. +		instance_data[p->instance_id].party_id = 0;
  1560.  		instance_destroy( p->instance_id );
  1561.  	}
  1562.  
  1563. Index: src/map/pc.c
  1564. ===================================================================
  1565. --- src/map/pc.c	(revision 17368)
  1566. +++ src/map/pc.c	(working copy)
  1567. @@ -4777,11 +4777,10 @@
  1568.  	if( map[m].flag.src4instance && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  1569.  	{
  1570.  		// Request the mapid of this src map into the instance of the party
  1571. -		int im = instance_map2imap(m, p->instance_id);
  1572. +		int im = instance_mapname2mapid(map[m].name, p->instance_id);
  1573.  		if( im < 0 )
  1574.  			; // Player will enter the src map for instances
  1575. -		else
  1576. -		{ // Changes destiny to the instance map, not the source map
  1577. +		else { // Changes destination to the instance map, not the source map
  1578.  			m = im;
  1579.  			mapindex = map_id2index(m);
  1580.  		}
  1581. Index: src/map/script.c
  1582. ===================================================================
  1583. --- src/map/script.c	(revision 17368)
  1584. +++ src/map/script.c	(working copy)
  1585. @@ -2566,7 +2566,7 @@
  1586.  			break;
  1587.  		case '\'':
  1588.  				if (st->instance_id) {
  1589. -					data->u.str = (char*)idb_get(instance[st->instance_id].vars,reference_getuid(data));
  1590. +					data->u.str = (char*)idb_get(instance_data[st->instance_id].vars,reference_getuid(data));
  1591.  				} else {
  1592.  					ShowWarning("script:get_val: cannot access instance variable '%s', defaulting to \"\"\n", name);
  1593.  					data->u.str = NULL;
  1594. @@ -2631,7 +2631,7 @@
  1595.  			break;
  1596.  		case '\'':
  1597.  				if( st->instance_id )
  1598. -					data->u.num = (int)idb_iget(instance[st->instance_id].vars,reference_getuid(data));
  1599. +					data->u.num = (int)idb_iget(instance_data[st->instance_id].vars,reference_getuid(data));
  1600.  				else {
  1601.  					ShowWarning("script:get_val: cannot access instance variable '%s', defaulting to 0\n", name);
  1602.  					data->u.num = 0;
  1603. @@ -2692,8 +2692,8 @@
  1604.  			return 1;
  1605.  		case '\'':
  1606.  			if( st->instance_id ) {
  1607. -				idb_remove(instance[st->instance_id].vars, num);
  1608. -				if( str[0] ) idb_put(instance[st->instance_id].vars, num, aStrdup(str));
  1609. +				idb_remove(instance_data[st->instance_id].vars, num);
  1610. +				if( str[0] ) idb_put(instance_data[st->instance_id].vars, num, aStrdup(str));
  1611.  			}
  1612.  			return 1;
  1613.  		default:
  1614. @@ -2740,9 +2740,9 @@
  1615.  			return 1;
  1616.  		case '\'':
  1617.  			if( st->instance_id ) {
  1618. -				idb_remove(instance[st->instance_id].vars, num);
  1619. +				idb_remove(instance_data[st->instance_id].vars, num);
  1620.  				if( val != 0 )
  1621. -					idb_iput(instance[st->instance_id].vars, num, val);
  1622. +					idb_iput(instance_data[st->instance_id].vars, num, val);
  1623.  			}
  1624.  			return 1;
  1625.  		default:
  1626. @@ -8856,7 +8856,7 @@
  1627.  		m = map_mapname2mapid(mapn);
  1628.  		if (map[m].flag.src4instance && st->instance_id)
  1629.  		{ // Try to redirect to the instance map, not the src map
  1630. -			if ((m = instance_mapid2imapid(m, st->instance_id)) < 0)
  1631. +			if ((m = instance_mapname2mapid(map[m].name, st->instance_id)) < 0)
  1632.  			{
  1633.  				ShowError("buildin_monster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
  1634.  				return 1;
  1635. @@ -8957,7 +8957,7 @@
  1636.  		m = map_mapname2mapid(mapn);
  1637.  		if (map[m].flag.src4instance && st->instance_id)
  1638.  		{ // Try to redirect to the instance map, not the src map
  1639. -			if ((m = instance_mapid2imapid(m, st->instance_id)) < 0)
  1640. +			if ((m = instance_mapname2mapid(map[m].name, st->instance_id)) < 0)
  1641.  			{
  1642.  				ShowError("buildin_areamonster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn);
  1643.  				return 1;
  1644. @@ -9018,7 +9018,7 @@
  1645.  	if( (m=map_mapname2mapid(mapname))<0 )
  1646.  		return 0;
  1647.  
  1648. -	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
  1649. +	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapname2mapid(map[m].name, st->instance_id)) < 0 )
  1650.  		return 0;
  1651.  
  1652.  	if( script_hasdata(st,4) ) {
  1653. @@ -9059,7 +9059,7 @@
  1654.  	if( (m = map_mapname2mapid(mapname))<0 )
  1655.  		return 0;
  1656.  
  1657. -	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
  1658. +	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapname2mapid(map[m].name, st->instance_id)) < 0 )
  1659.  		return 0;
  1660.  
  1661.  	if( script_hasdata(st,3) ) {
  1662. @@ -11569,7 +11569,7 @@
  1663.  		return 0;
  1664.  	}
  1665.  
  1666. -	if( map[m].flag.src4instance && map[m].instance_id == 0 && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
  1667. +	if( map[m].flag.src4instance && map[m].instance_id == 0 && st->instance_id && (m = instance_mapname2mapid(map[m].name, st->instance_id)) < 0 )
  1668.  	{
  1669.  		script_pushint(st,-1);
  1670.  		return 0;
  1671. @@ -16487,23 +16487,20 @@
  1672.  	party_id = script_getnum(st, 3);
  1673.  
  1674.  	res = instance_create(party_id, name);
  1675. -	if( res == -4 ) // Already exists
  1676. -	{
  1677. +	if( res == -4 ) { // Already exists
  1678.  		script_pushint(st, -1);
  1679.  		return 0;
  1680. -	}
  1681. -	else if( res < 0 )
  1682. -	{
  1683. +	} else if( res < 0 ) {
  1684.  		const char *err;
  1685. -		switch(res)
  1686. -		{
  1687. -		case -3: err = "No free instances"; break;
  1688. -		case -2: err = "Invalid party ID"; break;
  1689. -		case -1: err = "Invalid type"; break;
  1690. -		default: err = "Unknown"; break;
  1691. +		switch(res) {
  1692. +			case -3: err = "No free instances"; break;
  1693. +			case -2: err = "Invalid party ID"; break;
  1694. +			case -1: err = "Invalid type"; break;
  1695. +			default: err = "Unknown"; break;
  1696.  		}
  1697.  		ShowError("buildin_instance_create: %s [%d].\n", err, res);
  1698.  		script_pushint(st, -2);
  1699. +
  1700.  		return 0;
  1701.  	}
  1702.  
  1703. @@ -16525,8 +16522,7 @@
  1704.  		instance_id = p->instance_id;
  1705.  	else return 0;
  1706.  
  1707. -	if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
  1708. -	{
  1709. +	if( instance_id <= instance_start || instance_id >= MAX_MAP_PER_SERVER ) {
  1710.  		ShowError("buildin_instance_destroy: Trying to destroy invalid instance %d.\n", instance_id);
  1711.  		return 0;
  1712.  	}
  1713. @@ -16535,68 +16531,6 @@
  1714.  	return 0;
  1715.  }
  1716.  
  1717. -BUILDIN_FUNC(instance_attachmap)
  1718. -{
  1719. -	const char *name;
  1720. -	int16 m;
  1721. -	int instance_id;
  1722. -	bool usebasename = false;
  1723. -
  1724. -	name = script_getstr(st,2);
  1725. -	instance_id = script_getnum(st,3);
  1726. -	if( script_hasdata(st,4) && script_getnum(st,4) > 0)
  1727. -		usebasename = true;
  1728. -
  1729. -	if( (m = instance_add_map(name, instance_id, usebasename)) < 0 ) // [Saithis]
  1730. -	{
  1731. -		ShowError("buildin_instance_attachmap: instance creation failed (%s): %d\n", name, m);
  1732. -		script_pushconststr(st, "");
  1733. -		return 0;
  1734. -	}
  1735. -	script_pushconststr(st, map[m].name);
  1736. -
  1737. -	return 0;
  1738. -}
  1739. -
  1740. -BUILDIN_FUNC(instance_detachmap)
  1741. -{
  1742. -	struct map_session_data *sd;
  1743. -	struct party_data *p;
  1744. -	const char *str;
  1745. -	int16 m;
  1746. -	int instance_id;
  1747. -
  1748. -	str = script_getstr(st, 2);
  1749. -	if( script_hasdata(st, 3) )
  1750. -		instance_id = script_getnum(st, 3);
  1751. -	else if( st->instance_id )
  1752. -		instance_id = st->instance_id;
  1753. -	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  1754. -		instance_id = p->instance_id;
  1755. -	else return 0;
  1756. -
  1757. -	if( (m = map_mapname2mapid(str)) < 0 || (m = instance_map2imap(m,instance_id)) < 0 )
  1758. -	{
  1759. -		ShowError("buildin_instance_detachmap: Trying to detach invalid map %s\n", str);
  1760. -		return 0;
  1761. -	}
  1762. -
  1763. -	instance_del_map(m);
  1764. -	return 0;
  1765. -}
  1766. -
  1767. -BUILDIN_FUNC(instance_attach)
  1768. -{
  1769. -	int instance_id;
  1770. -
  1771. -	instance_id = script_getnum(st, 2);
  1772. -	if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
  1773. -		return 0;
  1774. -
  1775. -	st->instance_id = instance_id;
  1776. -	return 0;
  1777. -}
  1778. -
  1779.  BUILDIN_FUNC(instance_id)
  1780.  {
  1781.  	int instance_id;
  1782. @@ -16621,78 +16555,6 @@
  1783.  	return 0;
  1784.  }
  1785.  
  1786. -BUILDIN_FUNC(instance_set_timeout)
  1787. -{
  1788. -	int progress_timeout, idle_timeout;
  1789. -	int instance_id;
  1790. -	struct map_session_data *sd;
  1791. -	struct party_data *p;
  1792. -
  1793. -	progress_timeout = script_getnum(st, 2);
  1794. -	idle_timeout = script_getnum(st, 3);
  1795. -
  1796. -	if( script_hasdata(st, 4) )
  1797. -		instance_id = script_getnum(st, 4);
  1798. -	else if( st->instance_id )
  1799. -		instance_id = st->instance_id;
  1800. -	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  1801. -		instance_id = p->instance_id;
  1802. -	else return 0;
  1803. -
  1804. -	if( instance_id > 0 )
  1805. -		instance_set_timeout(instance_id, progress_timeout, idle_timeout);
  1806. -
  1807. -	return 0;
  1808. -}
  1809. -
  1810. -BUILDIN_FUNC(instance_init)
  1811. -{
  1812. -	int instance_id = script_getnum(st, 2);
  1813. -
  1814. -	if( instance[instance_id].state != INSTANCE_IDLE )
  1815. -	{
  1816. -		ShowError("instance_init: instance already initialized.\n");
  1817. -		return 0;
  1818. -	}
  1819. -
  1820. -	instance_init(instance_id);
  1821. -	return 0;
  1822. -}
  1823. -
  1824. -BUILDIN_FUNC(instance_announce)
  1825. -{
  1826. -	int         instance_id = script_getnum(st,2);
  1827. -	const char *mes         = script_getstr(st,3);
  1828. -	int         flag        = script_getnum(st,4);
  1829. -	const char *fontColor   = script_hasdata(st,5) ? script_getstr(st,5) : NULL;
  1830. -	int         fontType    = script_hasdata(st,6) ? script_getnum(st,6) : 0x190; // default fontType (FW_NORMAL)
  1831. -	int         fontSize    = script_hasdata(st,7) ? script_getnum(st,7) : 12;    // default fontSize
  1832. -	int         fontAlign   = script_hasdata(st,8) ? script_getnum(st,8) : 0;     // default fontAlign
  1833. -	int         fontY       = script_hasdata(st,9) ? script_getnum(st,9) : 0;     // default fontY
  1834. -
  1835. -	int i;
  1836. -	struct map_session_data *sd;
  1837. -	struct party_data *p;
  1838. -
  1839. -	if( instance_id == 0 )
  1840. -	{
  1841. -		if( st->instance_id )
  1842. -			instance_id = st->instance_id;
  1843. -		else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  1844. -			instance_id = p->instance_id;
  1845. -		else return 0;
  1846. -	}
  1847. -
  1848. -	if( instance_id <= 0 || instance_id >= MAX_INSTANCE )
  1849. -		return 0;
  1850. -
  1851. -	for( i = 0; i < instance[instance_id].num_map; i++ )
  1852. -		map_foreachinmap(buildin_announce_sub, instance[instance_id].map[i], BL_PC,
  1853. -			mes, strlen(mes)+1, flag&0xf0, fontColor, fontType, fontSize, fontAlign, fontY);
  1854. -
  1855. -	return 0;
  1856. -}
  1857. -
  1858.  BUILDIN_FUNC(instance_npcname)
  1859.  {
  1860.  	const char *str;
  1861. @@ -16723,9 +16585,64 @@
  1862.  		return 1;
  1863.  	}
  1864.  
  1865. +	unsigned char *name;
  1866. +	char *str = conv_str(st,& (st->stack->stack_data[st->start+2]));
  1867. +	int id = script_getmemorialid(st);
  1868. +
  1869. +	if(id > 0) {
  1870. +		name = (unsigned char *)aCalloc(strlen(str) + 5, sizeof(unsigned char));
  1871. +		sprintf(name, "%s#%03d", str, id);
  1872. +	} else {
  1873. +		name = (unsigned char *)aStrdup(str);
  1874. +	}
  1875. +
  1876. +	push_str(st->stack,C_STR,name);
  1877. +
  1878.  	return 0;
  1879. +
  1880. +	return 0;
  1881.  }
  1882.  
  1883. +/*==========================================
  1884. + * ƒƒ‚ƒŠƒAƒ‹ƒ_ƒ“ƒWƒ‡ƒ“MAP–ŒŽæ“Ÿ
  1885. + *------------------------------------------
  1886. + */
  1887. +int buildin_getmdmapname(struct script_state *st)
  1888. +{
  1889. +	char *str = conv_str(st,& (st->stack->stack_data[st->start+2]));
  1890. +	int id = script_getmemorialid(st);
  1891. +	int m = memorial_mapname2mapid(str, id);
  1892. +
  1893. +	if(m < 0)
  1894. +		push_str(st->stack,C_CONSTSTR,"");
  1895. +	else
  1896. +		push_str(st->stack,C_STR,(unsigned char *)aStrdup(map[m].name));
  1897. +
  1898. +	return 0;
  1899. +}
  1900. +
  1901. +/*==========================================
  1902. + * ƒƒ‚ƒŠƒAƒ‹ƒ_ƒ“ƒWƒ‡ƒ“NPC–ŒŽæ“Ÿ
  1903. + *------------------------------------------
  1904. + */
  1905. +int buildin_getmdnpcname(struct script_state *st)
  1906. +{
  1907. +	unsigned char *name;
  1908. +	char *str = conv_str(st,& (st->stack->stack_data[st->start+2]));
  1909. +	int id = script_getmemorialid(st);
  1910. +
  1911. +	if(id > 0) {
  1912. +		name = (unsigned char *)aCalloc(strlen(str) + 5, sizeof(unsigned char));
  1913. +		sprintf(name, "%s#%03d", str, id);
  1914. +	} else {
  1915. +		name = (unsigned char *)aStrdup(str);
  1916. +	}
  1917. +
  1918. +	push_str(st->stack,C_STR,name);
  1919. +
  1920. +	return 0;
  1921. +}
  1922. +
  1923.  BUILDIN_FUNC(has_instance)
  1924.  {
  1925.  	struct map_session_data *sd;
  1926. @@ -16742,7 +16659,7 @@
  1927.  	else if( (sd = script_rid2sd(st)) != NULL && sd->status.party_id && (p = party_search(sd->status.party_id)) != NULL && p->instance_id )
  1928.  		instance_id = p->instance_id;
  1929.  
  1930. -	if( !instance_id || (m = map_mapname2mapid(str)) < 0 || (m = instance_map2imap(m, instance_id)) < 0 )
  1931. +	if( !instance_id || (m = map_mapname2mapid(str)) < 0 || (m = instance_mapname2mapid(map[m].name, instance_id)) < 0 )
  1932.  	{
  1933.  		script_pushconststr(st, "");
  1934.  		return 0;
  1935. @@ -16773,10 +16690,10 @@
  1936.  		instance_id = p->instance_id;
  1937.  	else return 0;
  1938.  
  1939. -	if( (m = map_mapname2mapid(mapn)) < 0 || (map[m].flag.src4instance && (m = instance_mapid2imapid(m, instance_id)) < 0) )
  1940. +	if( (m = map_mapname2mapid(mapn)) < 0 || (map[m].flag.src4instance && (m = instance_mapname2mapid(map[m].name, st->instance_id)) < 0) )
  1941.  		return 0;
  1942.  
  1943. -	if( !(p = party_search(instance[instance_id].party_id)) )
  1944. +	if( !(p = party_search(instance_data[instance_id].party_id)) )
  1945.  		return 0;
  1946.  
  1947.  	mapindex = map_id2index(m);
  1948. @@ -16917,7 +16834,7 @@
  1949.  		return 0;
  1950.  	}
  1951.  
  1952. -	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapid2imapid(m, st->instance_id)) < 0 )
  1953. +	if( map[m].flag.src4instance && st->instance_id && (m = instance_mapname2mapid(map[m].name, st->instance_id)) < 0 )
  1954.  		return 0;
  1955.  
  1956.  	center.m = m;
  1957. @@ -18125,13 +18042,7 @@
  1958.  	// Instancing
  1959.  	BUILDIN_DEF(instance_create,"si"),
  1960.  	BUILDIN_DEF(instance_destroy,"?"),
  1961. -	BUILDIN_DEF(instance_attachmap,"si?"),
  1962. -	BUILDIN_DEF(instance_detachmap,"s?"),
  1963. -	BUILDIN_DEF(instance_attach,"i"),
  1964.  	BUILDIN_DEF(instance_id,"?"),
  1965. -	BUILDIN_DEF(instance_set_timeout,"ii?"),
  1966. -	BUILDIN_DEF(instance_init,"i"),
  1967. -	BUILDIN_DEF(instance_announce,"isi?????"),
  1968.  	BUILDIN_DEF(instance_npcname,"s?"),
  1969.  	BUILDIN_DEF(has_instance,"s?"),
  1970.  	BUILDIN_DEF(instance_warpall,"sii?"),
  1971. Index: src/map/unit.c
  1972. ===================================================================
  1973. --- src/map/unit.c	(revision 17368)
  1974. +++ src/map/unit.c	(working copy)
  1975. @@ -2206,11 +2206,8 @@
  1976.  			{// decrement the number of active pvp players on the map
  1977.  				--map[bl->m].users_pvp;
  1978.  			}
  1979. -			if( map[bl->m].instance_id )
  1980. -			{
  1981. -				instance[map[bl->m].instance_id].users--;
  1982. -				instance_check_idle(map[bl->m].instance_id);
  1983. -			}
  1984. +			if(map[sd->bl.m].instance_id)
  1985. +				instance_delusers(map[sd->bl.m].instance_id);
  1986.  			sd->state.debug_remove_map = 1; // temporary state to track double remove_map's [FlavioJS]
  1987.  			sd->debug_file = file;
  1988.  			sd->debug_line = line;
Viewed 232 times, submitted by unknown.