instance.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include "../common/cbasetypes.h"
  4. #include "../common/socket.h"
  5. #include "../common/timer.h"
  6. #include "../common/nullpo.h"
  7. #include "../common/showmsg.h"
  8. #include "../common/strlib.h"
  9. #include "../common/db.h"
  10. #include "../common/malloc.h"
  11. #include "clif.h"
  12. #include "guild.h"
  13. #include "instance.h"
  14. #include "map.h"
  15. #include "npc.h"
  16. #include "party.h"
  17. #include "pc.h"
  18. #include <stdlib.h>
  19. #define INSTANCE_INTERVAL 60000 // Interval used to check when an instance is to be destroyed (ms)
  20. int instance_start = 0; // To keep the last index + 1 of normal map inserted in the map[ARRAY]
  21. struct instance_data instance_data[MAX_INSTANCE_DATA];
  22. struct eri *instance_maps_ers = NULL; ///< Array of maps per instance
  23. static DBMap *InstanceDB; /// Instance DB: struct instance_db, key: id
  24. static DBMap *InstanceNameDB; /// instance id, key: name
  25. static struct {
  26. int id[MAX_INSTANCE_DATA];
  27. int count;
  28. int timer;
  29. } instance_wait;
  30. /*==========================================
  31. * Searches for an instance ID in the database
  32. *------------------------------------------*/
  33. struct instance_db *instance_searchtype_db(unsigned short instance_id) {
  34. return (struct instance_db *)uidb_get(InstanceDB,instance_id);
  35. }
  36. static uint16 instance_name2id(const char *instance_name) {
  37. return (uint16)strdb_uiget(InstanceNameDB,instance_name);
  38. }
  39. /*==========================================
  40. * Searches for an instance name in the database
  41. *------------------------------------------*/
  42. struct instance_db *instance_searchname_db(const char *instance_name) {
  43. uint16 id = instance_name2id(instance_name);
  44. if (id == 0)
  45. return NULL;
  46. return (struct instance_db *)uidb_get(InstanceDB,id);
  47. }
  48. /**
  49. * Search for a sd of an Instance
  50. * @param instance_id: Instance ID
  51. * @param sd: Player data to attach
  52. * @param target: Target display type
  53. */
  54. void instance_getsd(unsigned short instance_id, struct map_session_data **sd, enum send_target *target) {
  55. switch(instance_data[instance_id].mode) {
  56. case IM_NONE:
  57. (*sd) = NULL;
  58. (*target) = SELF;
  59. break;
  60. case IM_GUILD:
  61. (*sd) = guild_getavailablesd(guild_search(instance_data[instance_id].owner_id));
  62. (*target) = GUILD;
  63. break;
  64. case IM_PARTY:
  65. (*sd) = party_getavailablesd(party_search(instance_data[instance_id].owner_id));
  66. (*target) = PARTY;
  67. break;
  68. case IM_CHAR:
  69. (*sd) = map_charid2sd(instance_data[instance_id].owner_id);
  70. (*target) = SELF;
  71. break;
  72. }
  73. return;
  74. }
  75. /*==========================================
  76. * Deletes an instance timer (Destroys instance)
  77. *------------------------------------------*/
  78. static int instance_delete_timer(int tid, unsigned int tick, int id, intptr_t data)
  79. {
  80. instance_destroy(id);
  81. return 0;
  82. }
  83. /*==========================================
  84. * Create subscription timer
  85. *------------------------------------------*/
  86. static int instance_subscription_timer(int tid, unsigned int tick, int id, intptr_t data)
  87. {
  88. int i, ret;
  89. unsigned short instance_id = instance_wait.id[0];
  90. struct map_session_data *sd = NULL;
  91. struct party_data *p = NULL;
  92. struct guild *g = NULL;
  93. enum instance_mode mode;
  94. if(instance_wait.count == 0 || instance_id == 0)
  95. return 0;
  96. // Check that maps have been added
  97. ret = instance_addmap(instance_id);
  98. mode = instance_data[instance_id].mode;
  99. switch(mode) {
  100. case IM_NONE:
  101. break;
  102. case IM_CHAR:
  103. if (ret == 0 && (sd = map_charid2sd(instance_data[instance_id].owner_id)) != NULL) // If no maps are created, tell player to wait
  104. clif_instance_changewait(instance_id, 0xffff);
  105. break;
  106. case IM_PARTY:
  107. if (ret == 0 && (p = party_search(instance_data[instance_id].owner_id)) != NULL) // If no maps are created, tell party to wait
  108. clif_instance_changewait(instance_id, 0xffff);
  109. break;
  110. case IM_GUILD:
  111. if (ret == 0 && (g = guild_search(instance_data[instance_id].owner_id)) != NULL) // If no maps are created, tell guild to wait
  112. clif_instance_changewait(instance_id, 0xffff);
  113. break;
  114. default:
  115. return 0;
  116. }
  117. instance_wait.count--;
  118. memmove(&instance_wait.id[0],&instance_wait.id[1],sizeof(instance_wait.id[0])*instance_wait.count);
  119. memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));
  120. for(i = 0; i < instance_wait.count; i++) {
  121. if( instance_data[instance_wait.id[i]].state == INSTANCE_IDLE &&
  122. ((mode == IM_CHAR && sd != NULL) || (mode == IM_GUILD && g != NULL) || (mode == IM_PARTY && p != NULL))
  123. ){
  124. clif_instance_changewait(instance_id, i + 1);
  125. }
  126. }
  127. if(instance_wait.count)
  128. instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
  129. else
  130. instance_wait.timer = INVALID_TIMER;
  131. return 0;
  132. }
  133. /*==========================================
  134. * Adds timer back to members entering instance
  135. *------------------------------------------*/
  136. static int instance_startkeeptimer(struct instance_data *im, unsigned short instance_id)
  137. {
  138. struct instance_db *db;
  139. nullpo_retr(0, im);
  140. // No timer
  141. if(im->keep_timer != INVALID_TIMER)
  142. return 1;
  143. if((db = instance_searchtype_db(im->type)) == NULL)
  144. return 1;
  145. // Add timer
  146. im->keep_limit = (unsigned int)time(NULL) + db->limit;
  147. im->keep_timer = add_timer(gettick()+db->limit*1000, instance_delete_timer, instance_id, 0);
  148. switch(im->mode) {
  149. case IM_NONE:
  150. break;
  151. case IM_CHAR:
  152. if (map_charid2sd(im->owner_id) != NULL) // Notify player of the added instance timer
  153. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  154. break;
  155. case IM_PARTY:
  156. if (party_search(im->owner_id) != NULL) // Notify party of the added instance timer
  157. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  158. break;
  159. case IM_GUILD:
  160. if (guild_search(im->owner_id) != NULL) // Notify guild of the added instance timer
  161. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  162. break;
  163. default:
  164. return 1;
  165. }
  166. return 0;
  167. }
  168. /*==========================================
  169. * Creates idle timer
  170. * Default before instance destroy is 5 minutes
  171. *------------------------------------------*/
  172. static int instance_startidletimer(struct instance_data *im, unsigned short instance_id)
  173. {
  174. struct instance_db *db;
  175. nullpo_retr(1, im);
  176. // No current timer
  177. if(im->idle_timer != INVALID_TIMER)
  178. return 1;
  179. if ((db = instance_searchtype_db(im->type)) == NULL)
  180. return 1;
  181. // Add the timer
  182. im->idle_limit = (unsigned int)time(NULL) + db->timeout;
  183. im->idle_timer = add_timer(gettick() + db->timeout * 1000, instance_delete_timer, instance_id, 0);
  184. switch(im->mode) {
  185. case IM_NONE:
  186. break;
  187. case IM_CHAR:
  188. if (map_charid2sd(im->owner_id) != NULL && instance_searchtype_db(im->type) != NULL) // Notify player of added instance timer
  189. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  190. break;
  191. case IM_PARTY:
  192. if (party_search(im->owner_id) != NULL && instance_searchtype_db(im->type) != NULL) // Notify party of added instance timer
  193. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  194. break;
  195. case IM_GUILD:
  196. if (guild_search(im->owner_id) != NULL && instance_searchtype_db(im->type) != NULL) // Notify guild of added instance timer
  197. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  198. break;
  199. default:
  200. return 1;
  201. }
  202. return 0;
  203. }
  204. /*==========================================
  205. * Delete the idle timer
  206. *------------------------------------------*/
  207. static int instance_stopidletimer(struct instance_data *im, unsigned short instance_id)
  208. {
  209. nullpo_retr(0, im);
  210. // No timer
  211. if(im->idle_timer == INVALID_TIMER)
  212. return 1;
  213. // Delete the timer - Party has returned or instance is destroyed
  214. im->idle_limit = 0;
  215. delete_timer(im->idle_timer, instance_delete_timer);
  216. im->idle_timer = INVALID_TIMER;
  217. switch(im->mode) {
  218. case IM_NONE:
  219. break;
  220. case IM_CHAR:
  221. if (map_charid2sd(im->owner_id) != NULL) // Notify the player
  222. clif_instance_changestatus(instance_id, 0, im->idle_limit);
  223. break;
  224. case IM_PARTY:
  225. if (party_search(im->owner_id) != NULL) // Notify the party
  226. clif_instance_changestatus(instance_id, 0, im->idle_limit);
  227. break;
  228. case IM_GUILD:
  229. if (guild_search(im->owner_id) != NULL) // Notify the guild
  230. clif_instance_changestatus(instance_id, 0, im->idle_limit);
  231. break;
  232. default:
  233. return 1;
  234. }
  235. return 0;
  236. }
  237. /*==========================================
  238. * Run the OnInstanceInit events for duplicated NPCs
  239. *------------------------------------------*/
  240. static int instance_npcinit(struct block_list *bl, va_list ap)
  241. {
  242. struct npc_data* nd;
  243. nullpo_retr(0, bl);
  244. nullpo_retr(0, ap);
  245. nullpo_retr(0, nd = (struct npc_data *)bl);
  246. return npc_instanceinit(nd);
  247. }
  248. /*==========================================
  249. * Run the OnInstanceDestroy events for duplicated NPCs
  250. *------------------------------------------*/
  251. static int instance_npcdestroy(struct block_list *bl, va_list ap)
  252. {
  253. struct npc_data* nd;
  254. nullpo_retr(0, bl);
  255. nullpo_retr(0, ap);
  256. nullpo_retr(0, nd = (struct npc_data *)bl);
  257. return npc_instancedestroy(nd);
  258. }
  259. /*==========================================
  260. * Add an NPC to an instance
  261. *------------------------------------------*/
  262. static int instance_addnpc_sub(struct block_list *bl, va_list ap)
  263. {
  264. struct npc_data* nd;
  265. nullpo_retr(0, bl);
  266. nullpo_retr(0, ap);
  267. nullpo_retr(0, nd = (struct npc_data *)bl);
  268. return npc_duplicate4instance(nd, va_arg(ap, int));
  269. }
  270. // Separate function used for reloading
  271. void instance_addnpc(struct instance_data *im)
  272. {
  273. int i;
  274. // First add the NPCs
  275. for(i = 0; i < im->cnt_map; i++)
  276. map_foreachinarea(instance_addnpc_sub, im->map[i]->src_m, 0, 0, map[im->map[i]->src_m].xs, map[im->map[i]->src_m].ys, BL_NPC, im->map[i]->m);
  277. // Now run their OnInstanceInit
  278. for(i = 0; i < im->cnt_map; i++)
  279. map_foreachinarea(instance_npcinit, im->map[i]->m, 0, 0, map[im->map[i]->m].xs, map[im->map[i]->m].ys, BL_NPC, im->map[i]->m);
  280. }
  281. /*--------------------------------------
  282. * name : instance name
  283. * Return value could be
  284. * -4 = no free instances | -3 = already exists | -2 = character/party/guild not found | -1 = invalid type
  285. * On success return instance_id
  286. *--------------------------------------*/
  287. int instance_create(int owner_id, const char *name, enum instance_mode mode) {
  288. struct instance_db *db = instance_searchname_db(name);
  289. struct map_session_data *sd = NULL;
  290. struct party_data *p = NULL;
  291. struct guild *g = NULL;
  292. unsigned short i;
  293. nullpo_retr(-1, db);
  294. switch(mode) {
  295. case IM_NONE:
  296. break;
  297. case IM_CHAR:
  298. if ((sd = map_charid2sd(owner_id)) == NULL) {
  299. ShowError("instance_create: character %d not found for instance '%s'.\n", owner_id, name);
  300. return -2;
  301. }
  302. if (sd->instance_id)
  303. return -3; // Player already instancing
  304. break;
  305. case IM_PARTY:
  306. if ((p = party_search(owner_id)) == NULL) {
  307. ShowError("instance_create: party %d not found for instance '%s'.\n", owner_id, name);
  308. return -2;
  309. }
  310. if (p->instance_id)
  311. return -3; // Party already instancing
  312. break;
  313. case IM_GUILD:
  314. if ((g = guild_search(owner_id)) == NULL) {
  315. ShowError("instance_create: guild %d not found for instance '%s'.\n", owner_id, name);
  316. return -2;
  317. }
  318. if (g->instance_id)
  319. return -3; // Guild already instancing
  320. break;
  321. default:
  322. ShowError("instance_create: unknown mode %u for owner_id %d and name %s.\n", mode, owner_id, name);
  323. return -2;
  324. }
  325. // Searching a Free Instance
  326. // 0 is ignored as this means "no instance" on maps
  327. ARR_FIND(1, MAX_INSTANCE_DATA, i, instance_data[i].state == INSTANCE_FREE);
  328. if( i >= MAX_INSTANCE_DATA )
  329. return -4;
  330. instance_data[i].type = db->id;
  331. instance_data[i].state = INSTANCE_IDLE;
  332. instance_data[i].owner_id = owner_id;
  333. instance_data[i].mode = mode;
  334. instance_data[i].keep_limit = 0;
  335. instance_data[i].keep_timer = INVALID_TIMER;
  336. instance_data[i].idle_limit = 0;
  337. instance_data[i].idle_timer = INVALID_TIMER;
  338. instance_data[i].regs.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
  339. instance_data[i].regs.arrays = NULL;
  340. instance_data[i].cnt_map = 0;
  341. switch(mode) {
  342. case IM_CHAR:
  343. sd->instance_id = i;
  344. break;
  345. case IM_PARTY:
  346. p->instance_id = i;
  347. break;
  348. case IM_GUILD:
  349. g->instance_id = i;
  350. break;
  351. }
  352. instance_wait.id[instance_wait.count++] = i;
  353. clif_instance_create(i, instance_wait.count);
  354. instance_subscription_timer(0,0,0,0);
  355. ShowInfo("[Instance] Created: %s (%hu).\n", name, i);
  356. return i;
  357. }
  358. /*--------------------------------------
  359. * Adds maps to the instance
  360. *--------------------------------------*/
  361. int instance_addmap(unsigned short instance_id) {
  362. int i, m;
  363. struct instance_data *im;
  364. struct instance_db *db;
  365. struct s_instance_map *entry;
  366. if (instance_id == 0)
  367. return 0;
  368. im = &instance_data[instance_id];
  369. // If the instance isn't idle, we can't do anything
  370. if (im->state != INSTANCE_IDLE)
  371. return 0;
  372. if ((db = instance_searchtype_db(im->type)) == NULL)
  373. return 0;
  374. // Set to busy, update timers
  375. im->state = INSTANCE_BUSY;
  376. im->idle_limit = (unsigned int)time(NULL) + db->timeout;
  377. im->idle_timer = add_timer(gettick() + db->timeout * 1000, instance_delete_timer, instance_id, 0);
  378. // Add the maps
  379. if (db->maplist_count > MAX_MAP_PER_INSTANCE) {
  380. ShowError("instance_addmap: Too many maps (%d) created for a single instance '%s' (%hu).\n", db->maplist_count, StringBuf_Value(db->name), instance_id);
  381. return 0;
  382. }
  383. // Add initial map
  384. if ((m = map_addinstancemap(StringBuf_Value(db->enter.mapname), instance_id)) < 0) {
  385. ShowError("instance_addmap: Failed to create initial map for instance '%s' (%hu).\n", StringBuf_Value(db->name), instance_id);
  386. return 0;
  387. }
  388. entry = ers_alloc(instance_maps_ers, struct s_instance_map);
  389. entry->m = m;
  390. entry->src_m = map_mapname2mapid(StringBuf_Value(db->enter.mapname));
  391. RECREATE(im->map, struct s_instance_map *, im->cnt_map + 1);
  392. im->map[im->cnt_map++] = entry;
  393. // Add extra maps (if any)
  394. for(i = 0; i < db->maplist_count; i++) {
  395. if(strlen(StringBuf_Value(db->maplist[i])) < 1)
  396. continue;
  397. else if( (m = map_addinstancemap(StringBuf_Value(db->maplist[i]), instance_id)) < 0) {
  398. // An error occured adding a map
  399. ShowError("instance_addmap: No maps added to instance '%s' (%hu).\n", StringBuf_Value(db->name), instance_id);
  400. return 0;
  401. } else {
  402. entry = ers_alloc(instance_maps_ers, struct s_instance_map);
  403. entry->m = m;
  404. entry->src_m = map_mapname2mapid(StringBuf_Value(db->maplist[i]));
  405. RECREATE(im->map, struct s_instance_map *, im->cnt_map + 1);
  406. im->map[im->cnt_map++] = entry;
  407. }
  408. }
  409. // Create NPCs on all maps
  410. instance_addnpc(im);
  411. switch(im->mode) {
  412. case IM_NONE:
  413. break;
  414. case IM_CHAR:
  415. if (map_charid2sd(im->owner_id) != NULL) // Inform player of the created instance
  416. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  417. break;
  418. case IM_PARTY:
  419. if (party_search(im->owner_id) != NULL) // Inform party members of the created instance
  420. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  421. break;
  422. case IM_GUILD:
  423. if (guild_search(im->owner_id) != NULL) // Inform guild members of the created instance
  424. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  425. break;
  426. default:
  427. return 0;
  428. }
  429. return im->cnt_map;
  430. }
  431. /*==========================================
  432. * Returns an instance map ID using a map name
  433. * name : source map
  434. * instance_id : where to search
  435. * result : mapid of map "name" in this instance
  436. *------------------------------------------*/
  437. int16 instance_mapname2mapid(const char *name, unsigned short instance_id)
  438. {
  439. struct instance_data *im;
  440. int16 m = map_mapname2mapid(name);
  441. char iname[MAP_NAME_LENGTH];
  442. int i;
  443. if(m < 0) {
  444. ShowError("instance_mapname2mapid: map name %s does not exist.\n",name);
  445. return m;
  446. }
  447. strcpy(iname,name);
  448. if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
  449. return m;
  450. im = &instance_data[instance_id];
  451. if(im->state != INSTANCE_BUSY)
  452. return m;
  453. for(i = 0; i < im->cnt_map; i++)
  454. if(im->map[i]->src_m == m) {
  455. char alt_name[MAP_NAME_LENGTH];
  456. if((strchr(iname,'@') == NULL) && strlen(iname) > 8) {
  457. memmove(iname, iname+(strlen(iname)-9), strlen(iname));
  458. snprintf(alt_name, sizeof(alt_name),"%hu#%s", instance_id, iname);
  459. } else
  460. snprintf(alt_name, sizeof(alt_name),"%.3hu%s", instance_id, iname);
  461. return map_mapname2mapid(alt_name);
  462. }
  463. return m;
  464. }
  465. /*==========================================
  466. * Removes a instance, all its maps and npcs.
  467. *------------------------------------------*/
  468. int instance_destroy(unsigned short instance_id)
  469. {
  470. struct instance_data *im;
  471. struct map_session_data *sd = NULL;
  472. struct party_data *p = NULL;
  473. struct guild *g = NULL;
  474. int i, type = 0;
  475. unsigned int now = (unsigned int)time(NULL);
  476. enum instance_mode mode;
  477. if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
  478. return 1;
  479. im = &instance_data[instance_id];
  480. if(im->state == INSTANCE_FREE)
  481. return 1;
  482. mode = im->mode;
  483. switch(mode) {
  484. case IM_NONE:
  485. break;
  486. case IM_CHAR:
  487. sd = map_charid2sd(im->owner_id);
  488. break;
  489. case IM_PARTY:
  490. p = party_search(im->owner_id);
  491. break;
  492. case IM_GUILD:
  493. g = guild_search(im->owner_id);
  494. break;
  495. }
  496. if(im->state == INSTANCE_IDLE) {
  497. for(i = 0; i < instance_wait.count; i++) {
  498. if(instance_wait.id[i] == instance_id) {
  499. instance_wait.count--;
  500. memmove(&instance_wait.id[i],&instance_wait.id[i+1],sizeof(instance_wait.id[0])*(instance_wait.count-i));
  501. memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));
  502. for(i = 0; i < instance_wait.count; i++)
  503. if(instance_data[instance_wait.id[i]].state == INSTANCE_IDLE)
  504. if ((mode == IM_CHAR && sd) || (mode == IM_PARTY && p) || (mode == IM_GUILD && g))
  505. clif_instance_changewait(instance_id, i + 1);
  506. if(instance_wait.count)
  507. instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
  508. else
  509. instance_wait.timer = INVALID_TIMER;
  510. type = 0;
  511. break;
  512. }
  513. }
  514. } else {
  515. if(im->keep_limit && im->keep_limit <= now)
  516. type = 1;
  517. else if(im->idle_limit && im->idle_limit <= now)
  518. type = 2;
  519. else
  520. type = 3;
  521. // Run OnInstanceDestroy on all NPCs in the instance
  522. for(i = 0; i < im->cnt_map; i++){
  523. map_foreachinarea(instance_npcdestroy, im->map[i]->m, 0, 0, map[im->map[i]->m].xs, map[im->map[i]->m].ys, BL_NPC, im->map[i]->m);
  524. }
  525. for(i = 0; i < im->cnt_map; i++) {
  526. map_delinstancemap(im->map[i]->m);
  527. ers_free(instance_maps_ers, im->map[i]);
  528. }
  529. im->cnt_map = 0;
  530. aFree(im->map);
  531. im->map = NULL;
  532. }
  533. if(im->keep_timer != INVALID_TIMER) {
  534. delete_timer(im->keep_timer, instance_delete_timer);
  535. im->keep_timer = INVALID_TIMER;
  536. }
  537. if(im->idle_timer != INVALID_TIMER) {
  538. delete_timer(im->idle_timer, instance_delete_timer);
  539. im->idle_timer = INVALID_TIMER;
  540. }
  541. if (mode == IM_CHAR && sd)
  542. sd->instance_id = 0;
  543. else if (mode == IM_PARTY && p)
  544. p->instance_id = 0;
  545. else if (mode == IM_GUILD && g)
  546. g->instance_id = 0;
  547. if (mode != IM_NONE) {
  548. if(type)
  549. clif_instance_changestatus(instance_id, type, 0);
  550. else
  551. clif_instance_changewait(instance_id, 0xffff);
  552. }
  553. if( im->regs.vars ) {
  554. db_destroy(im->regs.vars);
  555. im->regs.vars = NULL;
  556. }
  557. if( im->regs.arrays )
  558. instance_data[instance_id].regs.arrays->destroy(instance_data[instance_id].regs.arrays, script_free_array_db);
  559. ShowInfo("[Instance] Destroyed %hu.\n", instance_id);
  560. memset(&instance_data[instance_id], 0, sizeof(instance_data[instance_id]));
  561. return 0;
  562. }
  563. /*==========================================
  564. * Warp a user into instance
  565. *------------------------------------------*/
  566. enum e_instance_enter instance_enter(struct map_session_data *sd, unsigned short instance_id, const char *name, short x, short y)
  567. {
  568. struct instance_data *im = NULL;
  569. struct instance_db *db = NULL;
  570. struct party_data *p = NULL;
  571. struct guild *g = NULL;
  572. enum instance_mode mode;
  573. int16 m;
  574. nullpo_retr(IE_OTHER, sd);
  575. if( (db = instance_searchname_db(name)) == NULL ){
  576. ShowError( "instance_enter: Unknown instance \"%s\".\n", name );
  577. return IE_OTHER;
  578. }
  579. // If one of the two coordinates was not given or is below zero, we use the entry point from the database
  580. if( x < 0 || y < 0 ){
  581. x = db->enter.x;
  582. y = db->enter.y;
  583. }
  584. // Check if it is a valid instance
  585. if( instance_id == 0 ){
  586. // im will stay NULL and by default party checks will be used
  587. mode = IM_PARTY;
  588. }else{
  589. im = &instance_data[instance_id];
  590. mode = im->mode;
  591. }
  592. switch(mode) {
  593. case IM_NONE:
  594. break;
  595. case IM_CHAR:
  596. if (sd->instance_id == 0) // Player must have an instance
  597. return IE_NOINSTANCE;
  598. if (im->owner_id != sd->status.char_id)
  599. return IE_OTHER;
  600. break;
  601. case IM_PARTY:
  602. if (sd->status.party_id == 0) // Character must be in instance party
  603. return IE_NOMEMBER;
  604. if ((p = party_search(sd->status.party_id)) == NULL)
  605. return IE_NOMEMBER;
  606. if (p->instance_id == 0 || im == NULL) // Party must have an instance
  607. return IE_NOINSTANCE;
  608. if (im->owner_id != p->party.party_id)
  609. return IE_OTHER;
  610. break;
  611. case IM_GUILD:
  612. if (sd->status.guild_id == 0) // Character must be in instance guild
  613. return IE_NOMEMBER;
  614. if ((g = guild_search(sd->status.guild_id)) == NULL)
  615. return IE_NOMEMBER;
  616. if (g->instance_id == 0) // Guild must have an instance
  617. return IE_NOINSTANCE;
  618. if (im->owner_id != g->guild_id)
  619. return IE_OTHER;
  620. break;
  621. }
  622. if (im->state != INSTANCE_BUSY)
  623. return IE_OTHER;
  624. if (im->type != db->id)
  625. return IE_OTHER;
  626. // Does the instance match?
  627. if ((m = instance_mapname2mapid(StringBuf_Value(db->enter.mapname), instance_id)) < 0)
  628. return IE_OTHER;
  629. if (pc_setpos(sd, map_id2index(m), x, y, CLR_OUTSIGHT))
  630. return IE_OTHER;
  631. // If there was an idle timer, let's stop it
  632. instance_stopidletimer(im, instance_id);
  633. // Now we start the instance timer
  634. instance_startkeeptimer(im, instance_id);
  635. return IE_OK;
  636. }
  637. /*==========================================
  638. * Request some info about the instance
  639. *------------------------------------------*/
  640. int instance_reqinfo(struct map_session_data *sd, unsigned short instance_id)
  641. {
  642. struct instance_data *im;
  643. nullpo_retr(1, sd);
  644. if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
  645. return 1;
  646. im = &instance_data[instance_id];
  647. if(instance_searchtype_db(im->type) == NULL)
  648. return 1;
  649. // Say it's created if instance is not busy
  650. if(im->state == INSTANCE_IDLE) {
  651. int i;
  652. for(i = 0; i < instance_wait.count; i++) {
  653. if(instance_wait.id[i] == instance_id) {
  654. clif_instance_create(instance_id, i + 1);
  655. break;
  656. }
  657. }
  658. } else if(im->state == INSTANCE_BUSY) // Give info on the instance if busy
  659. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  660. return 0;
  661. }
  662. /*==========================================
  663. * Add players to the instance (for timers)
  664. *------------------------------------------*/
  665. int instance_addusers(unsigned short instance_id)
  666. {
  667. struct instance_data *im;
  668. if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
  669. return 1;
  670. im = &instance_data[instance_id];
  671. if(im->state != INSTANCE_BUSY)
  672. return 1;
  673. // Stop the idle timer if we had one
  674. instance_stopidletimer(im, instance_id);
  675. // Start the instance keep timer
  676. instance_startkeeptimer(im, instance_id);
  677. return 0;
  678. }
  679. /*==========================================
  680. * Delete players from the instance (for timers)
  681. *------------------------------------------*/
  682. int instance_delusers(unsigned short instance_id)
  683. {
  684. struct instance_data *im;
  685. int i, idle = 0;
  686. if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
  687. return 1;
  688. im = &instance_data[instance_id];
  689. if(im->state != INSTANCE_BUSY)
  690. return 1;
  691. // If no one is in the instance, start the idle timer
  692. for(i = 0; i < im->cnt_map && im->map[i]->m; i++)
  693. if(map[im->map[i]->m].users > 1) // We check this before the actual map.users are updated, hence the 1
  694. idle++;
  695. if(!idle) // If idle wasn't added to, we know no one was in the instance
  696. instance_startidletimer(im, instance_id);
  697. return 0;
  698. }
  699. static bool instance_db_free_sub(struct instance_db *db);
  700. /*==========================================
  701. * Read the instance_db.txt file
  702. *------------------------------------------*/
  703. static bool instance_readdb_sub(char* str[], int columns, int current)
  704. {
  705. uint8 i;
  706. char *ptr;
  707. int id = strtol(str[0], &ptr, 10);
  708. struct instance_db *db;
  709. bool isNew = false;
  710. if (!id || id > USHRT_MAX || *ptr) {
  711. ShowError("instance_readdb_sub: Cannot add instance with ID '%d'. Valid IDs are 1 ~ %d, skipping...\n", id, USHRT_MAX);
  712. return false;
  713. }
  714. if (mapindex_name2id(str[4]) == 0) {
  715. ShowError("instance_readdb_sub: Invalid map '%s' as entrance map, skipping...\n", str[4]);
  716. return false;
  717. }
  718. if (!(db = (struct instance_db *)uidb_get(InstanceDB, id))) {
  719. CREATE(db, struct instance_db, 1);
  720. db->id = id;
  721. db->name = StringBuf_Malloc();
  722. db->enter.mapname = StringBuf_Malloc();
  723. isNew = true;
  724. } else {
  725. StringBuf_Clear(db->name);
  726. StringBuf_Clear(db->enter.mapname);
  727. if (db->maplist_count) {
  728. for (i = 0; i < db->maplist_count; i++)
  729. StringBuf_Free(db->maplist[i]);
  730. aFree(db->maplist);
  731. db->maplist = NULL;
  732. }
  733. }
  734. StringBuf_AppendStr(db->name, str[1]);
  735. db->limit = strtol(str[2], &ptr, 10);
  736. if (*ptr) {
  737. ShowError("instance_readdb_sub: TimeLimit must be an integer value for instance '%d', skipping...\n", id);
  738. instance_db_free_sub(db);
  739. return false;
  740. }
  741. db->timeout = strtol(str[3], &ptr, 10);
  742. if (*ptr) {
  743. ShowError("instance_readdb_sub: IdleTimeOut must be an integer value for instance '%d', skipping...\n", id);
  744. instance_db_free_sub(db);
  745. return false;
  746. }
  747. StringBuf_AppendStr(db->enter.mapname, str[4]);
  748. db->enter.x = (short)strtol(str[5], &ptr, 10);
  749. if (*ptr) {
  750. ShowError("instance_readdb_sub: EnterX must be an integer value for instance '%d', skipping...\n", id);
  751. instance_db_free_sub(db);
  752. return false;
  753. }
  754. db->enter.y = (short)strtol(str[6], &ptr, 10);
  755. if (*ptr) {
  756. ShowError("instance_readdb_sub: EnterY must be an integer value for instance '%d', skipping...\n", id);
  757. instance_db_free_sub(db);
  758. return false;
  759. }
  760. //Instance maps
  761. for (i = 7; i < columns; i++) {
  762. if (strlen(str[i])) {
  763. if (mapindex_name2id(str[i]) == 0) {
  764. ShowWarning("instance_readdb_sub: Invalid map '%s' in maplist, skipping...\n", str[i]);
  765. continue;
  766. }
  767. RECREATE(db->maplist, StringBuf *, db->maplist_count+1);
  768. db->maplist[db->maplist_count] = StringBuf_Malloc();
  769. StringBuf_AppendStr(db->maplist[db->maplist_count], str[i]);
  770. db->maplist_count++;
  771. }
  772. }
  773. if (isNew) {
  774. uidb_put(InstanceDB, id, db);
  775. strdb_uiput(InstanceNameDB, StringBuf_Value(db->name), id);
  776. }
  777. return true;
  778. }
  779. /**
  780. * Free InstanceDB single entry
  781. * @param db Instance Db entry
  782. **/
  783. static bool instance_db_free_sub(struct instance_db *db) {
  784. if (!db)
  785. return 1;
  786. StringBuf_Free(db->name);
  787. StringBuf_Free(db->enter.mapname);
  788. if (db->maplist_count) {
  789. uint8 i;
  790. for (i = 0; i < db->maplist_count; i++)
  791. StringBuf_Free(db->maplist[i]);
  792. aFree(db->maplist);
  793. }
  794. aFree(db);
  795. return 0;
  796. }
  797. /**
  798. * Free InstanceDB entries
  799. **/
  800. static int instance_db_free(DBKey key, DBData *data, va_list ap) {
  801. struct instance_db *db = (struct instance_db *)db_data2ptr(data);
  802. return instance_db_free_sub(db);
  803. }
  804. /**
  805. * Read instance_db.txt files
  806. **/
  807. void instance_readdb(void) {
  808. const char* filename[] = { DBPATH"instance_db.txt", "import/instance_db.txt"};
  809. int f;
  810. for (f = 0; f<ARRAYLENGTH(filename); f++) {
  811. sv_readdb(db_path, filename[f], ',', 7, 7+MAX_MAP_PER_INSTANCE, -1, &instance_readdb_sub, f);
  812. }
  813. }
  814. /**
  815. * Reload Instance DB
  816. **/
  817. void instance_reload(void) {
  818. InstanceDB->clear(InstanceDB, instance_db_free);
  819. db_clear(InstanceNameDB);
  820. instance_readdb();
  821. }
  822. /*==========================================
  823. * Reloads the instance in runtime (reloadscript)
  824. *------------------------------------------*/
  825. void do_reload_instance(void)
  826. {
  827. struct instance_data *im;
  828. struct instance_db *db = NULL;
  829. struct s_mapiterator* iter;
  830. struct map_session_data *sd;
  831. unsigned short i;
  832. for( i = 1; i < MAX_INSTANCE_DATA; i++ ) {
  833. im = &instance_data[i];
  834. if(!im->cnt_map)
  835. continue;
  836. else {
  837. // First we load the NPCs again
  838. instance_addnpc(im);
  839. // Create new keep timer
  840. if((db = instance_searchtype_db(im->type)) != NULL)
  841. im->keep_limit = (unsigned int)time(NULL) + db->limit;
  842. }
  843. }
  844. // Reset player to instance beginning
  845. iter = mapit_getallusers();
  846. for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
  847. if(sd && map[sd->bl.m].instance_id) {
  848. struct party_data *p = NULL;
  849. struct guild *g = NULL;
  850. unsigned short instance_id;
  851. im = &instance_data[map[sd->bl.m].instance_id];
  852. switch (im->mode) {
  853. case IM_NONE:
  854. continue;
  855. case IM_CHAR:
  856. if (sd->instance_id != map[sd->bl.m].instance_id) // Someone who is not instance owner is on instance map
  857. continue;
  858. instance_id = sd->instance_id;
  859. break;
  860. case IM_PARTY:
  861. if ((!(p = party_search(sd->status.party_id)) || p->instance_id != map[sd->bl.m].instance_id)) // Someone not in party is on instance map
  862. continue;
  863. instance_id = p->instance_id;
  864. break;
  865. case IM_GUILD:
  866. if (!(g = guild_search(sd->status.guild_id)) || g->instance_id != map[sd->bl.m].instance_id) // Someone not in guild is on instance map
  867. continue;
  868. instance_id = g->instance_id;
  869. break;
  870. default:
  871. ShowError("do_reload_instance: Unexpected instance mode for instance %s (id=%u, mode=%u).\n", (db) ? StringBuf_Value(db->name) : "Unknown", map[sd->bl.m].instance_id, (unsigned short)im->mode);
  872. continue;
  873. }
  874. if((db = instance_searchtype_db(im->type)) != NULL && !instance_enter(sd, instance_id, StringBuf_Value(db->name), -1, -1)) { // All good
  875. clif_displaymessage(sd->fd, msg_txt(sd,515)); // Instance has been reloaded
  876. instance_reqinfo(sd,instance_id);
  877. } else // Something went wrong
  878. ShowError("do_reload_instance: Error setting character at instance start: character_id=%d instance=%s.\n",sd->status.char_id,StringBuf_Value(db->name));
  879. }
  880. mapit_free(iter);
  881. }
  882. void do_init_instance(void) {
  883. InstanceDB = uidb_alloc(DB_OPT_BASE);
  884. InstanceNameDB = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA,0);
  885. instance_readdb();
  886. memset(instance_data, 0, sizeof(instance_data));
  887. memset(&instance_wait, 0, sizeof(instance_wait));
  888. instance_wait.timer = -1;
  889. instance_maps_ers = ers_new(sizeof(struct s_instance_map),"instance.c::instance_maps_ers", ERS_OPT_NONE);
  890. add_timer_func_list(instance_delete_timer,"instance_delete_timer");
  891. add_timer_func_list(instance_subscription_timer,"instance_subscription_timer");
  892. }
  893. void do_final_instance(void) {
  894. int i;
  895. ers_destroy(instance_maps_ers);
  896. for( i = 1; i < MAX_INSTANCE_DATA; i++ )
  897. instance_destroy(i);
  898. InstanceDB->destroy(InstanceDB, instance_db_free);
  899. db_destroy(InstanceNameDB);
  900. }