instance.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  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. static 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_id2sd(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_id2sd(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_id2sd(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_id2sd(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_id2sd(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. * Add an NPC to an instance
  250. *------------------------------------------*/
  251. static int instance_addnpc_sub(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_duplicate4instance(nd, va_arg(ap, int));
  258. }
  259. // Separate function used for reloading
  260. void instance_addnpc(struct instance_data *im)
  261. {
  262. int i;
  263. // First add the NPCs
  264. for(i = 0; i < im->cnt_map; i++)
  265. 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);
  266. // Now run their OnInstanceInit
  267. for(i = 0; i < im->cnt_map; i++)
  268. 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);
  269. }
  270. /*--------------------------------------
  271. * name : instance name
  272. * Return value could be
  273. * -4 = no free instances | -3 = already exists | -2 = character/party/guild not found | -1 = invalid type
  274. * On success return instance_id
  275. *--------------------------------------*/
  276. int instance_create(int owner_id, const char *name, enum instance_mode mode) {
  277. struct instance_db *db = instance_searchname_db(name);
  278. struct map_session_data *sd = NULL;
  279. struct party_data *p = NULL;
  280. struct guild *g = NULL;
  281. unsigned short i;
  282. nullpo_retr(-1, db);
  283. switch(mode) {
  284. case IM_NONE:
  285. break;
  286. case IM_CHAR:
  287. if ((sd = map_id2sd(owner_id)) == NULL) {
  288. ShowError("instance_create: character %d not found for instance '%s'.\n", owner_id, name);
  289. return -2;
  290. }
  291. if (sd->instance_id)
  292. return -3; // Player already instancing
  293. break;
  294. case IM_PARTY:
  295. if ((p = party_search(owner_id)) == NULL) {
  296. ShowError("instance_create: party %d not found for instance '%s'.\n", owner_id, name);
  297. return -2;
  298. }
  299. if (p->instance_id)
  300. return -3; // Party already instancing
  301. break;
  302. case IM_GUILD:
  303. if ((g = guild_search(owner_id)) == NULL) {
  304. ShowError("instance_create: guild %d not found for instance '%s'.\n", owner_id, name);
  305. return -2;
  306. }
  307. if (g->instance_id)
  308. return -3; // Guild already instancing
  309. break;
  310. default:
  311. ShowError("instance_create: unknown mode %u for owner_id %d and name %s.\n", mode, owner_id, name);
  312. return -2;
  313. }
  314. // Searching a Free Instance
  315. // 0 is ignored as this means "no instance" on maps
  316. ARR_FIND(1, MAX_INSTANCE_DATA, i, instance_data[i].state == INSTANCE_FREE);
  317. if( i >= MAX_INSTANCE_DATA )
  318. return -4;
  319. instance_data[i].type = db->id;
  320. instance_data[i].state = INSTANCE_IDLE;
  321. instance_data[i].owner_id = owner_id;
  322. instance_data[i].mode = mode;
  323. instance_data[i].keep_limit = 0;
  324. instance_data[i].keep_timer = INVALID_TIMER;
  325. instance_data[i].idle_limit = 0;
  326. instance_data[i].idle_timer = INVALID_TIMER;
  327. instance_data[i].regs.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
  328. instance_data[i].regs.arrays = NULL;
  329. instance_data[i].cnt_map = 0;
  330. switch(mode) {
  331. case IM_CHAR:
  332. sd->instance_id = i;
  333. break;
  334. case IM_PARTY:
  335. p->instance_id = i;
  336. break;
  337. case IM_GUILD:
  338. g->instance_id = i;
  339. break;
  340. }
  341. instance_wait.id[instance_wait.count++] = i;
  342. clif_instance_create(i, instance_wait.count);
  343. instance_subscription_timer(0,0,0,0);
  344. ShowInfo("[Instance] Created: %s (%hu).\n", name, i);
  345. return i;
  346. }
  347. /*--------------------------------------
  348. * Adds maps to the instance
  349. *--------------------------------------*/
  350. int instance_addmap(unsigned short instance_id) {
  351. int i, m;
  352. struct instance_data *im;
  353. struct instance_db *db;
  354. struct s_instance_map *entry;
  355. if (instance_id == 0)
  356. return 0;
  357. im = &instance_data[instance_id];
  358. // If the instance isn't idle, we can't do anything
  359. if (im->state != INSTANCE_IDLE)
  360. return 0;
  361. if ((db = instance_searchtype_db(im->type)) == NULL)
  362. return 0;
  363. // Set to busy, update timers
  364. im->state = INSTANCE_BUSY;
  365. im->idle_limit = (unsigned int)time(NULL) + db->timeout;
  366. im->idle_timer = add_timer(gettick() + db->timeout * 1000, instance_delete_timer, instance_id, 0);
  367. // Add the maps
  368. if (db->maplist_count > MAX_MAP_PER_INSTANCE) {
  369. ShowError("instance_addmap: Too many maps (%d) created for a single instance '%s' (%hu).\n", db->maplist_count, StringBuf_Value(db->name), instance_id);
  370. return 0;
  371. }
  372. // Add initial map
  373. if ((m = map_addinstancemap(StringBuf_Value(db->enter.mapname), instance_id)) < 0) {
  374. ShowError("instance_addmap: Failed to create initial map for instance '%s' (%hu).\n", StringBuf_Value(db->name), instance_id);
  375. return 0;
  376. }
  377. entry = ers_alloc(instance_maps_ers, struct s_instance_map);
  378. entry->m = m;
  379. entry->src_m = map_mapname2mapid(StringBuf_Value(db->enter.mapname));
  380. RECREATE(im->map, struct s_instance_map *, im->cnt_map + 1);
  381. im->map[im->cnt_map++] = entry;
  382. // Add extra maps (if any)
  383. for(i = 0; i < db->maplist_count; i++) {
  384. if(strlen(StringBuf_Value(db->maplist[i])) < 1)
  385. continue;
  386. else if( (m = map_addinstancemap(StringBuf_Value(db->maplist[i]), instance_id)) < 0) {
  387. // An error occured adding a map
  388. ShowError("instance_addmap: No maps added to instance '%s' (%hu).\n", StringBuf_Value(db->name), instance_id);
  389. return 0;
  390. } else {
  391. entry = ers_alloc(instance_maps_ers, struct s_instance_map);
  392. entry->m = m;
  393. entry->src_m = map_mapname2mapid(StringBuf_Value(db->maplist[i]));
  394. RECREATE(im->map, struct s_instance_map *, im->cnt_map + 1);
  395. im->map[im->cnt_map++] = entry;
  396. }
  397. }
  398. // Create NPCs on all maps
  399. instance_addnpc(im);
  400. switch(im->mode) {
  401. case IM_NONE:
  402. break;
  403. case IM_CHAR:
  404. if (map_id2sd(im->owner_id) != NULL) // Inform player of the created instance
  405. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  406. break;
  407. case IM_PARTY:
  408. if (party_search(im->owner_id) != NULL) // Inform party members of the created instance
  409. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  410. break;
  411. case IM_GUILD:
  412. if (guild_search(im->owner_id) != NULL) // Inform guild members of the created instance
  413. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  414. break;
  415. default:
  416. return 0;
  417. }
  418. return im->cnt_map;
  419. }
  420. /*==========================================
  421. * Returns an instance map ID using a map name
  422. * name : source map
  423. * instance_id : where to search
  424. * result : mapid of map "name" in this instance
  425. *------------------------------------------*/
  426. int instance_mapname2mapid(const char *name, unsigned short instance_id)
  427. {
  428. struct instance_data *im;
  429. int m = map_mapname2mapid(name);
  430. char iname[MAP_NAME_LENGTH];
  431. int i;
  432. if(m < 0) {
  433. ShowError("instance_mapname2mapid: map name %s does not exist.\n",name);
  434. return m;
  435. }
  436. strcpy(iname,name);
  437. if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
  438. return m;
  439. im = &instance_data[instance_id];
  440. if(im->state != INSTANCE_BUSY)
  441. return m;
  442. for(i = 0; i < im->cnt_map; i++)
  443. if(im->map[i]->src_m == m) {
  444. char alt_name[MAP_NAME_LENGTH];
  445. if((strchr(iname,'@') == NULL) && strlen(iname) > 8) {
  446. memmove(iname, iname+(strlen(iname)-9), strlen(iname));
  447. snprintf(alt_name, sizeof(alt_name),"%hu#%s", instance_id, iname);
  448. } else
  449. snprintf(alt_name, sizeof(alt_name),"%.3hu%s", instance_id, iname);
  450. return map_mapname2mapid(alt_name);
  451. }
  452. return m;
  453. }
  454. /*==========================================
  455. * Removes a instance, all its maps and npcs.
  456. *------------------------------------------*/
  457. int instance_destroy(unsigned short instance_id)
  458. {
  459. struct instance_data *im;
  460. struct map_session_data *sd = NULL;
  461. struct party_data *p = NULL;
  462. struct guild *g = NULL;
  463. int i, type = 0;
  464. unsigned int now = (unsigned int)time(NULL);
  465. enum instance_mode mode;
  466. if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
  467. return 1;
  468. im = &instance_data[instance_id];
  469. if(im->state == INSTANCE_FREE)
  470. return 1;
  471. mode = im->mode;
  472. if(im->state == INSTANCE_IDLE) {
  473. for(i = 0; i < instance_wait.count; i++) {
  474. if(instance_wait.id[i] == instance_id) {
  475. instance_wait.count--;
  476. memmove(&instance_wait.id[i],&instance_wait.id[i+1],sizeof(instance_wait.id[0])*(instance_wait.count-i));
  477. memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));
  478. for(i = 0; i < instance_wait.count; i++)
  479. if(instance_data[instance_wait.id[i]].state == INSTANCE_IDLE)
  480. if ((mode == IM_CHAR && sd != NULL) || (mode == IM_PARTY && p != NULL) || (mode == IM_GUILD && g != NULL))
  481. clif_instance_changewait(instance_id, i + 1);
  482. if(instance_wait.count)
  483. instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
  484. else
  485. instance_wait.timer = INVALID_TIMER;
  486. type = 0;
  487. break;
  488. }
  489. }
  490. } else {
  491. if(im->keep_limit && im->keep_limit <= now)
  492. type = 1;
  493. else if(im->idle_limit && im->idle_limit <= now)
  494. type = 2;
  495. else
  496. type = 3;
  497. for(i = 0; i < im->cnt_map; i++) {
  498. map_delinstancemap(im->map[i]->m);
  499. ers_free(instance_maps_ers, im->map[i]);
  500. }
  501. }
  502. if(im->keep_timer != INVALID_TIMER) {
  503. delete_timer(im->keep_timer, instance_delete_timer);
  504. im->keep_timer = INVALID_TIMER;
  505. }
  506. if(im->idle_timer != INVALID_TIMER) {
  507. delete_timer(im->idle_timer, instance_delete_timer);
  508. im->idle_timer = INVALID_TIMER;
  509. }
  510. if (mode == IM_CHAR)
  511. sd->instance_id = 0;
  512. else if (mode == IM_PARTY)
  513. p->instance_id = 0;
  514. else if (mode == IM_GUILD)
  515. g->instance_id = 0;
  516. if (mode != IM_NONE) {
  517. if(type)
  518. clif_instance_changestatus(instance_id, type, 0);
  519. else
  520. clif_instance_changewait(instance_id, 0xffff);
  521. }
  522. if( im->regs.vars ) {
  523. db_destroy(im->regs.vars);
  524. im->regs.vars = NULL;
  525. }
  526. if( im->regs.arrays )
  527. instance_data[instance_id].regs.arrays->destroy(instance_data[instance_id].regs.arrays, script_free_array_db);
  528. ShowInfo("[Instance] Destroyed %hu.\n", instance_id);
  529. memset(&instance_data[instance_id], 0, sizeof(instance_data[instance_id]));
  530. return 0;
  531. }
  532. /*==========================================
  533. * Allows a user to enter an instance
  534. *------------------------------------------*/
  535. int instance_enter(struct map_session_data *sd, unsigned short instance_id)
  536. {
  537. struct instance_db *db = instance_searchtype_db(instance_data[instance_id].type);
  538. nullpo_retr(-1, sd);
  539. if (db == NULL)
  540. return 2;
  541. return instance_enter_position(sd, instance_id, db->enter.x, db->enter.y);
  542. }
  543. /*==========================================
  544. * Warp a user into instance
  545. *------------------------------------------*/
  546. int instance_enter_position(struct map_session_data *sd, unsigned short instance_id, short x, short y)
  547. {
  548. struct instance_data *im = &instance_data[instance_id];
  549. struct party_data *p = NULL;
  550. struct guild *g = NULL;
  551. int16 m;
  552. nullpo_retr(-1, sd);
  553. switch(instance_data[instance_id].mode) {
  554. case IM_NONE:
  555. break;
  556. case IM_CHAR:
  557. if (sd->instance_id == 0) // Player must have an instance
  558. return 2;
  559. if (im->owner_id != sd->status.account_id)
  560. return 3;
  561. break;
  562. case IM_PARTY:
  563. if (sd->status.party_id == 0) // Character must be in instance party
  564. return 1;
  565. if ((p = party_search(sd->status.party_id)) == NULL)
  566. return 1;
  567. if (p->instance_id == 0) // Party must have an instance
  568. return 2;
  569. if (im->owner_id != p->party.party_id)
  570. return 3;
  571. break;
  572. case IM_GUILD:
  573. if (sd->status.guild_id == 0) // Character must be in instance guild
  574. return 1;
  575. if ((g = guild_search(sd->status.guild_id)) == NULL)
  576. return 1;
  577. if (g->instance_id == 0) // Guild must have an instance
  578. return 2;
  579. if (im->owner_id != g->guild_id)
  580. return 3;
  581. break;
  582. }
  583. if (im->state != INSTANCE_BUSY)
  584. return 3;
  585. // Does the instance match?
  586. if ((m = instance_mapname2mapid(map_mapid2mapname(im->map[0]->m), instance_id)) < 0)
  587. return 3;
  588. if (pc_setpos(sd, map_id2index(m), x, y, CLR_OUTSIGHT))
  589. return 3;
  590. // If there was an idle timer, let's stop it
  591. instance_stopidletimer(im, instance_id);
  592. // Now we start the instance timer
  593. instance_startkeeptimer(im, instance_id);
  594. return 0;
  595. }
  596. /*==========================================
  597. * Request some info about the instance
  598. *------------------------------------------*/
  599. int instance_reqinfo(struct map_session_data *sd, unsigned short instance_id)
  600. {
  601. struct instance_data *im;
  602. nullpo_retr(1, sd);
  603. if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
  604. return 1;
  605. im = &instance_data[instance_id];
  606. if(instance_searchtype_db(im->type) == NULL)
  607. return 1;
  608. // Say it's created if instance is not busy
  609. if(im->state == INSTANCE_IDLE) {
  610. int i;
  611. for(i = 0; i < instance_wait.count; i++) {
  612. if(instance_wait.id[i] == instance_id) {
  613. clif_instance_create(instance_id, i + 1);
  614. break;
  615. }
  616. }
  617. } else if(im->state == INSTANCE_BUSY) // Give info on the instance if busy
  618. clif_instance_status(instance_id, im->keep_limit, im->idle_limit);
  619. return 0;
  620. }
  621. /*==========================================
  622. * Add players to the instance (for timers)
  623. *------------------------------------------*/
  624. int instance_addusers(unsigned short instance_id)
  625. {
  626. struct instance_data *im;
  627. if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
  628. return 1;
  629. im = &instance_data[instance_id];
  630. if(im->state != INSTANCE_BUSY)
  631. return 1;
  632. // Stop the idle timer if we had one
  633. instance_stopidletimer(im, instance_id);
  634. // Start the instance keep timer
  635. instance_startkeeptimer(im, instance_id);
  636. return 0;
  637. }
  638. /*==========================================
  639. * Delete players from the instance (for timers)
  640. *------------------------------------------*/
  641. int instance_delusers(unsigned short instance_id)
  642. {
  643. struct instance_data *im;
  644. int i, idle = 0;
  645. if(instance_id == 0 || instance_id > MAX_INSTANCE_DATA)
  646. return 1;
  647. im = &instance_data[instance_id];
  648. if(im->state != INSTANCE_BUSY)
  649. return 1;
  650. // If no one is in the instance, start the idle timer
  651. for(i = 0; im->map[i]->m && i > im->cnt_map; i++)
  652. if(map[im->map[i]->m].users > 1) // We check this before the actual map.users are updated, hence the 1
  653. idle++;
  654. if(!idle) // If idle wasn't added to, we know no one was in the instance
  655. instance_startidletimer(im, instance_id);
  656. return 0;
  657. }
  658. static bool instance_db_free_sub(struct instance_db *db);
  659. /*==========================================
  660. * Read the instance_db.txt file
  661. *------------------------------------------*/
  662. static bool instance_readdb_sub(char* str[], int columns, int current)
  663. {
  664. uint8 i;
  665. int id = atoi(str[0]);
  666. struct instance_db *db;
  667. bool isNew = false;
  668. if (!id || id > USHRT_MAX) {
  669. ShowError("instance_readdb_sub: Cannot add instance with ID '%d'. Valid ID is 1 ~ %d.\n", id, USHRT_MAX);
  670. return false;
  671. }
  672. if (mapindex_name2id(str[4]) == 0) {
  673. ShowError("instance_readdb_sub: Invalid map '%s' as entrance map.\n", str[4]);
  674. return false;
  675. }
  676. if (!(db = (struct instance_db *)uidb_get(InstanceDB, id))) {
  677. CREATE(db, struct instance_db, 1);
  678. db->id = id;
  679. db->name = StringBuf_Malloc();
  680. db->enter.mapname = StringBuf_Malloc();
  681. isNew = true;
  682. }
  683. else {
  684. StringBuf_Clear(db->name);
  685. StringBuf_Clear(db->enter.mapname);
  686. if (db->maplist_count) {
  687. for (i = 0; i < db->maplist_count; i++)
  688. StringBuf_Free(db->maplist[i]);
  689. aFree(db->maplist);
  690. db->maplist = NULL;
  691. }
  692. }
  693. StringBuf_AppendStr(db->name, str[1]);
  694. db->limit = atoi(str[2]);
  695. db->timeout = atoi(str[3]);
  696. StringBuf_AppendStr(db->enter.mapname, str[4]);
  697. db->enter.x = atoi(str[5]);
  698. db->enter.y = atoi(str[6]);
  699. //Instance maps
  700. for (i = 7; i < columns; i++) {
  701. if (strlen(str[i])) {
  702. if (mapindex_name2id(str[i]) == 0) {
  703. ShowWarning("instance_readdb_sub: Invalid map '%s' in maplist, skipping...\n", str[i]);
  704. continue;
  705. }
  706. RECREATE(db->maplist, StringBuf *, db->maplist_count+1);
  707. db->maplist[db->maplist_count] = StringBuf_Malloc();
  708. StringBuf_AppendStr(db->maplist[db->maplist_count], str[i]);
  709. db->maplist_count++;
  710. }
  711. }
  712. if (isNew) {
  713. uidb_put(InstanceDB, id, db);
  714. strdb_uiput(InstanceNameDB, StringBuf_Value(db->name), id);
  715. }
  716. return true;
  717. }
  718. /**
  719. * Free InstanceDB single entry
  720. * @param db Instance Db entry
  721. **/
  722. static bool instance_db_free_sub(struct instance_db *db) {
  723. if (!db)
  724. return 1;
  725. StringBuf_Free(db->name);
  726. StringBuf_Free(db->enter.mapname);
  727. if (db->maplist_count) {
  728. uint8 i;
  729. for (i = 0; i < db->maplist_count; i++)
  730. StringBuf_Free(db->maplist[i]);
  731. aFree(db->maplist);
  732. }
  733. aFree(db);
  734. return 0;
  735. }
  736. /**
  737. * Free InstanceDB entries
  738. **/
  739. static int instance_db_free(DBKey key, DBData *data, va_list ap) {
  740. struct instance_db *db = (struct instance_db *)db_data2ptr(data);
  741. return instance_db_free_sub(db);
  742. }
  743. /**
  744. * Read instance_db.txt files
  745. **/
  746. void instance_readdb(void) {
  747. const char* filename[] = { DBPATH"instance_db.txt", "import/instance_db.txt"};
  748. int f;
  749. for (f = 0; f<ARRAYLENGTH(filename); f++) {
  750. sv_readdb(db_path, filename[f], ',', 7, 7+MAX_MAP_PER_INSTANCE, -1, &instance_readdb_sub, f);
  751. }
  752. }
  753. /**
  754. * Reload Instance DB
  755. **/
  756. void instance_reload(void) {
  757. InstanceDB->clear(InstanceDB, instance_db_free);
  758. db_clear(InstanceNameDB);
  759. instance_readdb();
  760. }
  761. /*==========================================
  762. * Reloads the instance in runtime (reloadscript)
  763. *------------------------------------------*/
  764. void do_reload_instance(void)
  765. {
  766. struct instance_data *im;
  767. struct instance_db *db;
  768. struct s_mapiterator* iter;
  769. struct map_session_data *sd;
  770. unsigned short i;
  771. for( i = 1; i < MAX_INSTANCE_DATA; i++ ) {
  772. im = &instance_data[i];
  773. if(!im->cnt_map)
  774. continue;
  775. else {
  776. // First we load the NPCs again
  777. instance_addnpc(im);
  778. // Create new keep timer
  779. if((db = instance_searchtype_db(im->type)) != NULL)
  780. im->keep_limit = (unsigned int)time(NULL) + db->limit;
  781. }
  782. }
  783. // Reset player to instance beginning
  784. iter = mapit_getallusers();
  785. for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
  786. if(sd && map[sd->bl.m].instance_id) {
  787. struct party_data *p = NULL;
  788. struct guild *g = NULL;
  789. if (instance_data[map[sd->bl.m].instance_id].mode == IM_PARTY && (!(p = party_search(sd->status.party_id)) || p->instance_id != map[sd->bl.m].instance_id)) // Someone not in party is on instance map
  790. continue;
  791. if (instance_data[map[sd->bl.m].instance_id].mode == IM_GUILD && (!(g = guild_search(sd->status.guild_id)) || g->instance_id != map[sd->bl.m].instance_id)) // Someone not in guild is on instance map
  792. continue;
  793. im = &instance_data[p->instance_id];
  794. if((db = instance_searchtype_db(im->type)) != NULL && !instance_enter(sd, i)) { // All good
  795. clif_displaymessage(sd->fd, msg_txt(sd,515)); // Instance has been reloaded
  796. instance_reqinfo(sd,p->instance_id);
  797. } else // Something went wrong
  798. ShowError("do_reload_instance: Error setting character at instance start: character_id=%d instance=%s.\n",sd->status.char_id,StringBuf_Value(db->name));
  799. }
  800. mapit_free(iter);
  801. }
  802. void do_init_instance(void) {
  803. InstanceDB = uidb_alloc(DB_OPT_BASE);
  804. InstanceNameDB = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA,0);
  805. instance_readdb();
  806. memset(instance_data, 0, sizeof(instance_data));
  807. memset(&instance_wait, 0, sizeof(instance_wait));
  808. instance_wait.timer = -1;
  809. instance_maps_ers = ers_new(sizeof(struct s_instance_map),"instance.c::instance_maps_ers", ERS_OPT_NONE);
  810. add_timer_func_list(instance_delete_timer,"instance_delete_timer");
  811. add_timer_func_list(instance_subscription_timer,"instance_subscription_timer");
  812. }
  813. void do_final_instance(void) {
  814. int i;
  815. ers_destroy(instance_maps_ers);
  816. for( i = 1; i < MAX_INSTANCE_DATA; i++ )
  817. instance_destroy(i);
  818. InstanceDB->destroy(InstanceDB, instance_db_free);
  819. db_destroy(InstanceNameDB);
  820. }