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