itemdb.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include "../common/nullpo.h"
  4. #include "../common/malloc.h"
  5. #include "../common/showmsg.h"
  6. #include "../common/strlib.h"
  7. #include "itemdb.h"
  8. #include "map.h"
  9. #include "battle.h" // struct battle_config
  10. #include "script.h" // item script processing
  11. #include "pc.h" // W_MUSICAL, W_WHIP
  12. #include "storage.h"
  13. #include "npc.h"
  14. #include "clif.h"
  15. #include "mob.h"
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. // 32k array entries (the rest goes to the db)
  20. #define MAX_ITEMDB 0x8000
  21. static struct item_data* itemdb_array[MAX_ITEMDB];
  22. static DBMap* itemdb_other;// int nameid -> struct item_data*
  23. static struct item_group itemgroup_db[MAX_ITEMGROUP];
  24. struct item_data dummy_item; //This is the default dummy item used for non-existant items. [Skotlex]
  25. /*==========================================
  26. * 名前で検索用
  27. *------------------------------------------*/
  28. // name = item alias, so we should find items aliases first. if not found then look for "jname" (full name)
  29. static int itemdb_searchname_sub(DBKey key,void *data,va_list ap)
  30. {
  31. struct item_data *item=(struct item_data *)data,**dst,**dst2;
  32. char *str;
  33. str=va_arg(ap,char *);
  34. dst=va_arg(ap,struct item_data **);
  35. dst2=va_arg(ap,struct item_data **);
  36. if(item == &dummy_item) return 0;
  37. //Absolute priority to Aegis code name.
  38. if (*dst != NULL) return 0;
  39. if( strcmpi(item->name,str)==0 )
  40. *dst=item;
  41. //Second priority to Client displayed name.
  42. if (*dst2 != NULL) return 0;
  43. if( strcmpi(item->jname,str)==0 )
  44. *dst2=item;
  45. return 0;
  46. }
  47. /*==========================================
  48. * 名前で検索
  49. *------------------------------------------*/
  50. struct item_data* itemdb_searchname(const char *str)
  51. {
  52. struct item_data* item;
  53. struct item_data* item2=NULL;
  54. int i;
  55. for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
  56. {
  57. item = itemdb_array[i];
  58. if( item == NULL )
  59. continue;
  60. // Absolute priority to Aegis code name.
  61. if( strcasecmp(item->name,str) == 0 )
  62. return item;
  63. //Second priority to Client displayed name.
  64. if( strcasecmp(item->jname,str) == 0 )
  65. item2 = item;
  66. }
  67. item = NULL;
  68. itemdb_other->foreach(itemdb_other,itemdb_searchname_sub,str,&item,&item2);
  69. return item?item:item2;
  70. }
  71. static int itemdb_searchname_array_sub(DBKey key,void * data,va_list ap)
  72. {
  73. struct item_data *item=(struct item_data *)data;
  74. char *str;
  75. str=va_arg(ap,char *);
  76. if (item == &dummy_item)
  77. return 1; //Invalid item.
  78. if(stristr(item->jname,str))
  79. return 0;
  80. if(stristr(item->name,str))
  81. return 0;
  82. return strcmpi(item->jname,str);
  83. }
  84. /*==========================================
  85. * Founds up to N matches. Returns number of matches [Skotlex]
  86. *------------------------------------------*/
  87. int itemdb_searchname_array(struct item_data** data, int size, const char *str)
  88. {
  89. struct item_data* item;
  90. int i;
  91. int count=0;
  92. // Search in the array
  93. for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
  94. {
  95. item = itemdb_array[i];
  96. if( item == NULL )
  97. continue;
  98. if( stristr(item->jname,str) || stristr(item->name,str) )
  99. {
  100. if( count < size )
  101. data[count] = item;
  102. ++count;
  103. }
  104. }
  105. // search in the db
  106. if( count >= size )
  107. {
  108. data = NULL;
  109. size = 0;
  110. }
  111. else
  112. {
  113. data -= count;
  114. size -= count;
  115. }
  116. return count + itemdb_other->getall(itemdb_other,(void**)data,size,itemdb_searchname_array_sub,str);
  117. }
  118. /*==========================================
  119. * 箱系アイテム検索
  120. *------------------------------------------*/
  121. int itemdb_searchrandomid(int group)
  122. {
  123. if(group<1 || group>=MAX_ITEMGROUP) {
  124. ShowError("itemdb_searchrandomid: Invalid group id %d\n", group);
  125. return UNKNOWN_ITEM_ID;
  126. }
  127. if (itemgroup_db[group].qty)
  128. return itemgroup_db[group].nameid[rand()%itemgroup_db[group].qty];
  129. ShowError("itemdb_searchrandomid: No item entries for group id %d\n", group);
  130. return UNKNOWN_ITEM_ID;
  131. }
  132. /*==========================================
  133. * Calculates total item-group related bonuses for the given item
  134. *------------------------------------------*/
  135. int itemdb_group_bonus(struct map_session_data* sd, int itemid)
  136. {
  137. int bonus = 0, i, j;
  138. for (i=0; i < MAX_ITEMGROUP; i++) {
  139. if (!sd->itemgrouphealrate[i])
  140. continue;
  141. ARR_FIND( 0, itemgroup_db[i].qty, j, itemgroup_db[i].nameid[j] == itemid );
  142. if( j < itemgroup_db[i].qty )
  143. bonus += sd->itemgrouphealrate[i];
  144. }
  145. return bonus;
  146. }
  147. /// Searches for the item_data.
  148. /// Returns the item_data or NULL if it does not exist.
  149. struct item_data* itemdb_exists(int nameid)
  150. {
  151. struct item_data* item;
  152. if( nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array) )
  153. return itemdb_array[nameid];
  154. item = (struct item_data*)idb_get(itemdb_other,nameid);
  155. if( item == &dummy_item )
  156. return NULL;// dummy data, doesn't exist
  157. return item;
  158. }
  159. /*==========================================
  160. * Converts the jobid from the format in itemdb
  161. * to the format used by the map server. [Skotlex]
  162. *------------------------------------------*/
  163. static void itemdb_jobid2mapid(unsigned int *bclass, unsigned int jobmask)
  164. {
  165. int i;
  166. bclass[0]= bclass[1]= bclass[2]= 0;
  167. //Base classes
  168. if (jobmask & 1<<JOB_NOVICE)
  169. { //Both Novice/Super-Novice are counted with the same ID
  170. bclass[0] |= 1<<MAPID_NOVICE;
  171. bclass[1] |= 1<<MAPID_NOVICE;
  172. }
  173. for (i = JOB_NOVICE+1; i <= JOB_THIEF; i++)
  174. {
  175. if (jobmask & 1<<i)
  176. bclass[0] |= 1<<(MAPID_NOVICE+i);
  177. }
  178. //2-1 classes
  179. if (jobmask & 1<<JOB_KNIGHT)
  180. bclass[1] |= 1<<MAPID_SWORDMAN;
  181. if (jobmask & 1<<JOB_PRIEST)
  182. bclass[1] |= 1<<MAPID_ACOLYTE;
  183. if (jobmask & 1<<JOB_WIZARD)
  184. bclass[1] |= 1<<MAPID_MAGE;
  185. if (jobmask & 1<<JOB_BLACKSMITH)
  186. bclass[1] |= 1<<MAPID_MERCHANT;
  187. if (jobmask & 1<<JOB_HUNTER)
  188. bclass[1] |= 1<<MAPID_ARCHER;
  189. if (jobmask & 1<<JOB_ASSASSIN)
  190. bclass[1] |= 1<<MAPID_THIEF;
  191. //2-2 classes
  192. if (jobmask & 1<<JOB_CRUSADER)
  193. bclass[2] |= 1<<MAPID_SWORDMAN;
  194. if (jobmask & 1<<JOB_MONK)
  195. bclass[2] |= 1<<MAPID_ACOLYTE;
  196. if (jobmask & 1<<JOB_SAGE)
  197. bclass[2] |= 1<<MAPID_MAGE;
  198. if (jobmask & 1<<JOB_ALCHEMIST)
  199. bclass[2] |= 1<<MAPID_MERCHANT;
  200. if (jobmask & 1<<JOB_BARD)
  201. bclass[2] |= 1<<MAPID_ARCHER;
  202. // Bard/Dancer share the same slot now.
  203. // if (jobmask & 1<<JOB_DANCER)
  204. // bclass[2] |= 1<<MAPID_ARCHER;
  205. if (jobmask & 1<<JOB_ROGUE)
  206. bclass[2] |= 1<<MAPID_THIEF;
  207. //Special classes that don't fit above.
  208. if (jobmask & 1<<21) //Taekwon boy
  209. bclass[0] |= 1<<MAPID_TAEKWON;
  210. if (jobmask & 1<<22) //Star Gladiator
  211. bclass[1] |= 1<<MAPID_TAEKWON;
  212. if (jobmask & 1<<23) //Soul Linker
  213. bclass[2] |= 1<<MAPID_TAEKWON;
  214. if (jobmask & 1<<JOB_GUNSLINGER)
  215. bclass[0] |= 1<<MAPID_GUNSLINGER;
  216. if (jobmask & 1<<JOB_NINJA)
  217. bclass[0] |= 1<<MAPID_NINJA;
  218. }
  219. static void create_dummy_data(void)
  220. {
  221. memset(&dummy_item, 0, sizeof(struct item_data));
  222. dummy_item.nameid=500;
  223. dummy_item.weight=1;
  224. dummy_item.value_sell=1;
  225. dummy_item.type=IT_ETC; //Etc item
  226. safestrncpy(dummy_item.name,"UNKNOWN_ITEM",sizeof(dummy_item.name));
  227. safestrncpy(dummy_item.jname,"UNKNOWN_ITEM",sizeof(dummy_item.jname));
  228. dummy_item.view_id=UNKNOWN_ITEM_ID;
  229. }
  230. static void* create_item_data(DBKey key, va_list args)
  231. {
  232. struct item_data *id;
  233. CREATE(id, struct item_data, 1);
  234. id->nameid=key.i;
  235. id->weight=1;
  236. id->type=IT_ETC;
  237. return id;
  238. }
  239. /*==========================================
  240. * Loads (and creates if not found) an item from the db.
  241. *------------------------------------------*/
  242. struct item_data* itemdb_load(int nameid)
  243. {
  244. struct item_data *id;
  245. DBKey key;
  246. if( nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array) )
  247. {
  248. id = itemdb_array[nameid];
  249. if( id == NULL )
  250. {
  251. key.i = nameid;
  252. id = itemdb_array[nameid] = (struct item_data*)create_item_data(key, NULL);
  253. }
  254. return id;
  255. }
  256. id = (struct item_data*)idb_ensure(itemdb_other, nameid, create_item_data);
  257. if( id == &dummy_item )
  258. {// Remove dummy_item, replace by real data.
  259. key.i = nameid;
  260. id = (struct item_data*)create_item_data(key, NULL);
  261. idb_put(itemdb_other, nameid, id);
  262. }
  263. return id;
  264. }
  265. static void* return_dummy_data(DBKey key, va_list args)
  266. {
  267. ShowWarning("itemdb_search: Item ID %d does not exists in the item_db. Using dummy data.\n", key.i);
  268. dummy_item.nameid = key.i;
  269. return &dummy_item;
  270. }
  271. /*==========================================
  272. * Loads an item from the db. If not found, it will return the dummy item.
  273. *------------------------------------------*/
  274. struct item_data* itemdb_search(int nameid)
  275. {
  276. if( nameid >= 0 && nameid < ARRAYLENGTH(itemdb_array) )
  277. {
  278. DBKey key;
  279. if( itemdb_array[nameid] )
  280. return itemdb_array[nameid];
  281. key.i = nameid;
  282. return (struct item_data*)return_dummy_data(key, NULL);
  283. }
  284. return (struct item_data*)idb_ensure(itemdb_other,nameid,return_dummy_data);
  285. }
  286. /*==========================================
  287. * Returns if given item is a player-equippable piece.
  288. *------------------------------------------*/
  289. int itemdb_isequip(int nameid)
  290. {
  291. int type=itemdb_type(nameid);
  292. switch (type) {
  293. case IT_WEAPON:
  294. case IT_ARMOR:
  295. case IT_AMMO:
  296. return 1;
  297. default:
  298. return 0;
  299. }
  300. }
  301. /*==========================================
  302. * Alternate version of itemdb_isequip
  303. *------------------------------------------*/
  304. int itemdb_isequip2(struct item_data *data)
  305. {
  306. nullpo_retr(0, data);
  307. switch(data->type) {
  308. case IT_WEAPON:
  309. case IT_ARMOR:
  310. case IT_AMMO:
  311. return 1;
  312. default:
  313. return 0;
  314. }
  315. }
  316. /*==========================================
  317. * Returns if given item's type is stackable.
  318. *------------------------------------------*/
  319. int itemdb_isstackable(int nameid)
  320. {
  321. int type=itemdb_type(nameid);
  322. switch(type) {
  323. case IT_WEAPON:
  324. case IT_ARMOR:
  325. case IT_PETEGG:
  326. case IT_PETARMOR:
  327. return 0;
  328. default:
  329. return 1;
  330. }
  331. }
  332. /*==========================================
  333. * Alternate version of itemdb_isstackable
  334. *------------------------------------------*/
  335. int itemdb_isstackable2(struct item_data *data)
  336. {
  337. nullpo_retr(0, data);
  338. switch(data->type) {
  339. case IT_WEAPON:
  340. case IT_ARMOR:
  341. case IT_PETEGG:
  342. case IT_PETARMOR:
  343. return 0;
  344. default:
  345. return 1;
  346. }
  347. }
  348. /*==========================================
  349. * Trade Restriction functions [Skotlex]
  350. *------------------------------------------*/
  351. int itemdb_isdropable_sub(struct item_data *item, int gmlv, int unused)
  352. {
  353. return (item && (!(item->flag.trade_restriction&1) || gmlv >= item->gm_lv_trade_override));
  354. }
  355. int itemdb_cantrade_sub(struct item_data* item, int gmlv, int gmlv2)
  356. {
  357. return (item && (!(item->flag.trade_restriction&2) || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
  358. }
  359. int itemdb_canpartnertrade_sub(struct item_data* item, int gmlv, int gmlv2)
  360. {
  361. return (item && (item->flag.trade_restriction&4 || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
  362. }
  363. int itemdb_cansell_sub(struct item_data* item, int gmlv, int unused)
  364. {
  365. return (item && (!(item->flag.trade_restriction&8) || gmlv >= item->gm_lv_trade_override));
  366. }
  367. int itemdb_cancartstore_sub(struct item_data* item, int gmlv, int unused)
  368. {
  369. return (item && (!(item->flag.trade_restriction&16) || gmlv >= item->gm_lv_trade_override));
  370. }
  371. int itemdb_canstore_sub(struct item_data* item, int gmlv, int unused)
  372. {
  373. return (item && (!(item->flag.trade_restriction&32) || gmlv >= item->gm_lv_trade_override));
  374. }
  375. int itemdb_canguildstore_sub(struct item_data* item, int gmlv, int unused)
  376. {
  377. return (item && (!(item->flag.trade_restriction&64) || gmlv >= item->gm_lv_trade_override));
  378. }
  379. int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(struct item_data*, int, int))
  380. {
  381. struct item_data* item_data = itemdb_search(item->nameid);
  382. int i;
  383. if (!func(item_data, gmlv, gmlv2))
  384. return 0;
  385. if(item_data->slot == 0 || itemdb_isspecial(item->card[0]))
  386. return 1;
  387. for(i = 0; i < item_data->slot; i++) {
  388. if (!item->card[i]) continue;
  389. if (!func(itemdb_search(item->card[i]), gmlv, gmlv2))
  390. return 0;
  391. }
  392. return 1;
  393. }
  394. /*==========================================
  395. * Specifies if item-type should drop unidentified.
  396. *------------------------------------------*/
  397. int itemdb_isidentified(int nameid)
  398. {
  399. int type=itemdb_type(nameid);
  400. switch (type) {
  401. case IT_WEAPON:
  402. case IT_ARMOR:
  403. case IT_PETARMOR:
  404. return 0;
  405. default:
  406. return 1;
  407. }
  408. }
  409. /*==========================================
  410. * アイテム使用可能フラグのオーバーライド
  411. *------------------------------------------*/
  412. static int itemdb_read_itemavail (void)
  413. {
  414. FILE *fp;
  415. int nameid, j, k, ln = 0;
  416. char line[1024], *str[10], *p;
  417. struct item_data *id;
  418. sprintf(line, "%s/item_avail.txt", db_path);
  419. if ((fp = fopen(line,"r")) == NULL) {
  420. ShowError("can't read %s\n", line);
  421. return -1;
  422. }
  423. while(fgets(line, sizeof(line), fp))
  424. {
  425. if (line[0] == '/' && line[1] == '/')
  426. continue;
  427. memset(str, 0, sizeof(str));
  428. for (j = 0, p = line; j < 2 && p; j++) {
  429. str[j] = p;
  430. p = strchr(p, ',');
  431. if(p) *p++ = 0;
  432. }
  433. if (j < 2 || str[0] == NULL ||
  434. (nameid = atoi(str[0])) < 0 || !(id = itemdb_exists(nameid)))
  435. continue;
  436. k = atoi(str[1]);
  437. if (k > 0) {
  438. id->flag.available = 1;
  439. id->view_id = k;
  440. } else
  441. id->flag.available = 0;
  442. ln++;
  443. }
  444. fclose(fp);
  445. ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, "item_avail.txt");
  446. return 0;
  447. }
  448. /*==========================================
  449. * read item group data
  450. *------------------------------------------*/
  451. static void itemdb_read_itemgroup_sub(const char* filename)
  452. {
  453. FILE *fp;
  454. char line[1024];
  455. int ln=0;
  456. int groupid,j,k,nameid;
  457. char *str[3],*p;
  458. char w1[1024], w2[1024];
  459. if( (fp=fopen(filename,"r"))==NULL ){
  460. ShowError("can't read %s\n", filename);
  461. return;
  462. }
  463. while(fgets(line, sizeof(line), fp))
  464. {
  465. ln++;
  466. if(line[0]=='/' && line[1]=='/')
  467. continue;
  468. if(strstr(line,"import")) {
  469. if (sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2 &&
  470. strcmpi(w1, "import") == 0) {
  471. itemdb_read_itemgroup_sub(w2);
  472. continue;
  473. }
  474. }
  475. memset(str,0,sizeof(str));
  476. for(j=0,p=line;j<3 && p;j++){
  477. str[j]=p;
  478. p=strchr(p,',');
  479. if(p) *p++=0;
  480. }
  481. if(str[0]==NULL)
  482. continue;
  483. if (j<3) {
  484. if (j>1) //Or else it barks on blank lines...
  485. ShowWarning("itemdb_read_itemgroup: Insufficient fields for entry at %s:%d\n", filename, ln);
  486. continue;
  487. }
  488. groupid = atoi(str[0]);
  489. if (groupid < 0 || groupid >= MAX_ITEMGROUP) {
  490. ShowWarning("itemdb_read_itemgroup: Invalid group %d in %s:%d\n", groupid, filename, ln);
  491. continue;
  492. }
  493. nameid = atoi(str[1]);
  494. if (!itemdb_exists(nameid)) {
  495. ShowWarning("itemdb_read_itemgroup: Non-existant item %d in %s:%d\n", nameid, filename, ln);
  496. continue;
  497. }
  498. k = atoi(str[2]);
  499. if (itemgroup_db[groupid].qty+k >= MAX_RANDITEM) {
  500. ShowWarning("itemdb_read_itemgroup: Group %d is full (%d entries) in %s:%d\n", groupid, MAX_RANDITEM, filename, ln);
  501. continue;
  502. }
  503. for(j=0;j<k;j++)
  504. itemgroup_db[groupid].nameid[itemgroup_db[groupid].qty++] = nameid;
  505. }
  506. fclose(fp);
  507. return;
  508. }
  509. static void itemdb_read_itemgroup(void)
  510. {
  511. char path[256];
  512. snprintf(path, 255, "%s/item_group_db.txt", db_path);
  513. memset(&itemgroup_db, 0, sizeof(itemgroup_db));
  514. itemdb_read_itemgroup_sub(path);
  515. ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n", "item_group_db.txt");
  516. return;
  517. }
  518. /*==========================================
  519. * 装備制限ファイル読み出し
  520. *------------------------------------------*/
  521. static int itemdb_read_noequip(void)
  522. {
  523. FILE *fp;
  524. char line[1024];
  525. int ln=0;
  526. int nameid,j;
  527. char *str[32],*p;
  528. struct item_data *id;
  529. sprintf(line, "%s/item_noequip.txt", db_path);
  530. if( (fp=fopen(line,"r"))==NULL ){
  531. ShowError("can't read %s\n", line);
  532. return -1;
  533. }
  534. while(fgets(line, sizeof(line), fp))
  535. {
  536. if(line[0]=='/' && line[1]=='/')
  537. continue;
  538. memset(str,0,sizeof(str));
  539. for(j=0,p=line;j<2 && p;j++){
  540. str[j]=p;
  541. p=strchr(p,',');
  542. if(p) *p++=0;
  543. }
  544. if(str[0]==NULL)
  545. continue;
  546. nameid=atoi(str[0]);
  547. if(nameid<=0 || !(id=itemdb_exists(nameid)))
  548. continue;
  549. id->flag.no_equip=atoi(str[1]);
  550. ln++;
  551. }
  552. fclose(fp);
  553. if (ln > 0) {
  554. ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,"item_noequip.txt");
  555. }
  556. return 0;
  557. }
  558. /*==========================================
  559. * Reads item trade restrictions [Skotlex]
  560. *------------------------------------------*/
  561. static int itemdb_read_itemtrade(void)
  562. {
  563. FILE *fp;
  564. int nameid, j, flag, gmlv, ln = 0;
  565. char line[1024], *str[10], *p;
  566. struct item_data *id;
  567. sprintf(line, "%s/item_trade.txt", db_path);
  568. if ((fp = fopen(line,"r")) == NULL) {
  569. ShowError("can't read %s\n", line);
  570. return -1;
  571. }
  572. while(fgets(line, sizeof(line), fp))
  573. {
  574. if (line[0] == '/' && line[1] == '/')
  575. continue;
  576. memset(str, 0, sizeof(str));
  577. for (j = 0, p = line; j < 3 && p; j++) {
  578. str[j] = p;
  579. p = strchr(p, ',');
  580. if(p) *p++ = 0;
  581. }
  582. if (j < 3 || str[0] == NULL ||
  583. (nameid = atoi(str[0])) < 0 || !(id = itemdb_exists(nameid)))
  584. continue;
  585. flag = atoi(str[1]);
  586. gmlv = atoi(str[2]);
  587. if (flag > 0 && flag < 128 && gmlv > 0) { //Check range
  588. id->flag.trade_restriction = flag;
  589. id->gm_lv_trade_override = gmlv;
  590. ln++;
  591. }
  592. }
  593. fclose(fp);
  594. ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, "item_trade.txt");
  595. return 0;
  596. }
  597. /*======================================
  598. * Applies gender restrictions according to settings. [Skotlex]
  599. *======================================*/
  600. static int itemdb_gendercheck(struct item_data *id)
  601. {
  602. if (id->nameid == WEDDING_RING_M) //Grom Ring
  603. return 1;
  604. if (id->nameid == WEDDING_RING_F) //Bride Ring
  605. return 0;
  606. if (id->look == W_MUSICAL && id->type == IT_WEAPON) //Musical instruments are always male-only
  607. return 1;
  608. if (id->look == W_WHIP && id->type == IT_WEAPON) //Whips are always female-only
  609. return 0;
  610. return (battle_config.ignore_items_gender) ? 2 : id->sex;
  611. }
  612. /*==========================================
  613. * processes one itemdb entry
  614. *------------------------------------------*/
  615. static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt, int db)
  616. {
  617. /*
  618. +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
  619. | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
  620. +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
  621. | id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script | equip_script | unequip_script |
  622. +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
  623. */
  624. int nameid;
  625. struct item_data* id;
  626. nameid = atoi(str[0]);
  627. if( nameid <= 0 )
  628. {
  629. ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source);
  630. return false;
  631. }
  632. //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
  633. id = itemdb_load(nameid);
  634. safestrncpy(id->name, str[1], sizeof(id->name));
  635. safestrncpy(id->jname, str[2], sizeof(id->jname));
  636. if(db == 1)
  637. id->flag.db2 = 1;
  638. id->type = atoi(str[3]);
  639. if (id->type == IT_DELAYCONSUME)
  640. { //Items that are consumed only after target confirmation
  641. id->type = IT_USABLE;
  642. id->flag.delay_consume = 1;
  643. } else //In case of an itemdb reload and the item type changed.
  644. id->flag.delay_consume = 0;
  645. //When a particular price is not given, we should base it off the other one
  646. //(it is important to make a distinction between 'no price' and 0z)
  647. if ( str[4][0] )
  648. id->value_buy = atoi(str[4]);
  649. else
  650. id->value_buy = atoi(str[5]) * 2;
  651. if ( str[5][0] )
  652. id->value_sell = atoi(str[5]);
  653. else
  654. id->value_sell = id->value_buy / 2;
  655. /*
  656. if ( !str[4][0] && !str[5][0])
  657. {
  658. ShowWarning("itemdb_parse_dbrow: No buying/selling price defined for item %d (%s), using 20/10z\n", nameid, id->jname);
  659. id->value_buy = 20;
  660. id->value_sell = 10;
  661. } else
  662. */
  663. if (id->value_buy/124. < id->value_sell/75.)
  664. ShowWarning("itemdb_parse_dbrow: Buying/Selling [%d/%d] price of item %d (%s) allows Zeny making exploit through buying/selling at discounted/overcharged prices!\n",
  665. id->value_buy, id->value_sell, nameid, id->jname);
  666. id->weight = atoi(str[6]);
  667. id->atk = atoi(str[7]);
  668. id->def = atoi(str[8]);
  669. id->range = atoi(str[9]);
  670. id->slot = atoi(str[10]);
  671. if (id->slot > MAX_SLOTS)
  672. {
  673. ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", nameid, id->jname, id->slot, MAX_SLOTS, MAX_SLOTS);
  674. id->slot = MAX_SLOTS;
  675. }
  676. itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0));
  677. id->class_upper = atoi(str[12]);
  678. id->sex = atoi(str[13]);
  679. id->equip = atoi(str[14]);
  680. if (!id->equip && itemdb_isequip2(id))
  681. {
  682. ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
  683. id->type = IT_ETC;
  684. }
  685. id->wlv = atoi(str[15]);
  686. id->elv = atoi(str[16]);
  687. id->flag.no_refine = atoi(str[17]) ? 0 : 1; //FIXME: verify this
  688. id->look = atoi(str[18]);
  689. id->flag.available = 1;
  690. id->flag.value_notdc = 0;
  691. id->flag.value_notoc = 0;
  692. id->view_id = 0;
  693. id->sex = itemdb_gendercheck(id); //Apply gender filtering.
  694. if (id->script)
  695. {
  696. script_free_code(id->script);
  697. id->script = NULL;
  698. }
  699. if (id->equip_script)
  700. {
  701. script_free_code(id->equip_script);
  702. id->equip_script = NULL;
  703. }
  704. if (id->unequip_script)
  705. {
  706. script_free_code(id->unequip_script);
  707. id->unequip_script = NULL;
  708. }
  709. if (*str[19])
  710. id->script = parse_script(str[19], source, line, scriptopt);
  711. if (*str[20])
  712. id->equip_script = parse_script(str[20], source, line, scriptopt);
  713. if (*str[21])
  714. id->unequip_script = parse_script(str[21], source, line, scriptopt);
  715. return true;
  716. }
  717. /*==========================================
  718. * アイテムデータベースの読み込み
  719. *------------------------------------------*/
  720. static int itemdb_readdb(void)
  721. {
  722. const char* filename[] = { "item_db.txt", "item_db2.txt" };
  723. int fi;
  724. for( fi = 0; fi < ARRAYLENGTH(filename); ++fi )
  725. {
  726. uint32 lines = 0, count = 0;
  727. char line[1024];
  728. char path[256];
  729. FILE* fp;
  730. sprintf(path, "%s/%s", db_path, filename[fi]);
  731. fp = fopen(path, "r");
  732. if( fp == NULL )
  733. {
  734. ShowWarning("itemdb_readdb: File not found \"%s\", skipping.\n", path);
  735. continue;
  736. }
  737. // process rows one by one
  738. while(fgets(line, sizeof(line), fp))
  739. {
  740. char *str[32], *p;
  741. int i;
  742. lines++;
  743. if(line[0] == '/' && line[1] == '/')
  744. continue;
  745. memset(str, 0, sizeof(str));
  746. p = line;
  747. while( ISSPACE(*p) )
  748. ++p;
  749. if( *p == '\0' )
  750. continue;// empty line
  751. for( i = 0; i < 19; ++i )
  752. {
  753. str[i] = p;
  754. p = strchr(p,',');
  755. if( p == NULL )
  756. break;// comma not found
  757. *p = '\0';
  758. ++p;
  759. }
  760. if( p == NULL )
  761. {
  762. ShowError("itemdb_readdb: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  763. continue;
  764. }
  765. // Script
  766. if( *p != '{' )
  767. {
  768. ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  769. continue;
  770. }
  771. str[19] = p;
  772. p = strstr(p+1,"},");
  773. if( p == NULL )
  774. {
  775. ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  776. continue;
  777. }
  778. p[1] = '\0';
  779. p += 2;
  780. // OnEquip_Script
  781. if( *p != '{' )
  782. {
  783. ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  784. continue;
  785. }
  786. str[20] = p;
  787. p = strstr(p+1,"},");
  788. if( p == NULL )
  789. {
  790. ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  791. continue;
  792. }
  793. p[1] = '\0';
  794. p += 2;
  795. // OnUnequip_Script (last column)
  796. if( *p != '{' )
  797. {
  798. ShowError("itemdb_readdb: Invalid format (OnUnequip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  799. continue;
  800. }
  801. str[21] = p;
  802. if (!itemdb_parse_dbrow(str, path, lines, 0, fi))
  803. continue;
  804. count++;
  805. }
  806. fclose(fp);
  807. ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename[fi]);
  808. }
  809. return 0;
  810. }
  811. #ifndef TXT_ONLY
  812. /*======================================
  813. * item_db table reading
  814. *======================================*/
  815. static int itemdb_read_sqldb(void)
  816. {
  817. const char* item_db_name[] = { item_db_db, item_db2_db };
  818. int fi;
  819. for( fi = 0; fi < ARRAYLENGTH(item_db_name); ++fi )
  820. {
  821. uint32 lines = 0, count = 0;
  822. // retrieve all rows from the item database
  823. if( SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", item_db_name[fi]) )
  824. {
  825. Sql_ShowDebug(mmysql_handle);
  826. continue;
  827. }
  828. // process rows one by one
  829. while( SQL_SUCCESS == Sql_NextRow(mmysql_handle) )
  830. {// wrap the result into a TXT-compatible format
  831. char* str[22];
  832. char* dummy = "";
  833. int i;
  834. ++lines;
  835. for( i = 0; i < 22; ++i )
  836. {
  837. Sql_GetData(mmysql_handle, i, &str[i], NULL);
  838. if( str[i] == NULL ) str[i] = dummy; // get rid of NULL columns
  839. }
  840. if (!itemdb_parse_dbrow(str, item_db_name[fi], lines, SCRIPT_IGNORE_EXTERNAL_BRACKETS, fi))
  841. continue;
  842. ++count;
  843. }
  844. // free the query result
  845. Sql_FreeResult(mmysql_handle);
  846. ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, item_db_name[fi]);
  847. }
  848. return 0;
  849. }
  850. #endif /* not TXT_ONLY */
  851. /*====================================
  852. * read all item-related databases
  853. *------------------------------------*/
  854. static void itemdb_read(void)
  855. {
  856. #ifndef TXT_ONLY
  857. if (db_use_sqldbs)
  858. itemdb_read_sqldb();
  859. else
  860. #endif
  861. itemdb_readdb();
  862. itemdb_read_itemgroup();
  863. itemdb_read_itemavail();
  864. itemdb_read_noequip();
  865. itemdb_read_itemtrade();
  866. }
  867. /*==========================================
  868. * Initialize / Finalize
  869. *------------------------------------------*/
  870. /// Destroys the item_data.
  871. static void destroy_item_data(struct item_data* self, int free_self)
  872. {
  873. if( self == NULL )
  874. return;
  875. // free scripts
  876. if( self->script )
  877. script_free_code(self->script);
  878. if( self->equip_script )
  879. script_free_code(self->equip_script);
  880. if( self->unequip_script )
  881. script_free_code(self->unequip_script);
  882. #if defined(DEBUG)
  883. // trash item
  884. memset(self, 0xDD, sizeof(struct item_data));
  885. #endif
  886. // free self
  887. if( free_self )
  888. aFree(self);
  889. }
  890. /*==========================================
  891. * This comment shall be a monument to cake.
  892. * The cake is NOT a lie in eAthena.
  893. * We are so awesome we have our own cake.
  894. * Please spam Cyxult with endless PMs to get your cake.
  895. *------------------------------------------*/
  896. static int itemdb_final_sub(DBKey key,void *data,va_list ap)
  897. {
  898. struct item_data *id = (struct item_data *)data;
  899. if( id != &dummy_item )
  900. destroy_item_data(id, 1);
  901. return 0;
  902. }
  903. //Uncomment this if you're an elitist jerk who thinks this code is unecessary
  904. //#define I_HATE_KEVIN
  905. #ifndef I_HATE_KEVIN
  906. int itemdb_reload_check_npc(DBKey key,void * data,va_list ap)
  907. {
  908. struct npc_data * nd = (struct npc_data *)data;
  909. int offset = 0, i = 0;
  910. if(nd->subtype != SHOP && nd->subtype != CASHSHOP)
  911. return 0;
  912. while(i < nd->u.shop.count)
  913. {
  914. if(itemdb_exists(nd->u.shop.shop_item[i].nameid) == NULL)
  915. {
  916. nd->u.shop.count--;
  917. //Shift array to left, overwriting old data
  918. for(offset = i; offset+1 < nd->u.shop.count; offset++);
  919. {
  920. nd->u.shop.shop_item[offset].nameid = nd->u.shop.shop_item[offset+1].nameid;
  921. nd->u.shop.shop_item[offset].value = nd->u.shop.shop_item[offset+1].value;
  922. }
  923. }
  924. //increment counter if we didn't delete something
  925. else
  926. i++;
  927. }
  928. //Resize array
  929. RECREATE(nd->u.shop.shop_item, struct npc_item_list, nd->u.shop.count);
  930. return 0;
  931. }
  932. static int itemdb_reload_check(DBKey key,void *data,va_list ap)
  933. {
  934. int i;
  935. struct map_session_data *sd = (struct map_session_data *)data;
  936. struct storage * stor;
  937. struct item_data * id;
  938. struct npc_data * nd;
  939. if(sd->npc_shopid)
  940. {
  941. nd = (struct npc_data*)map_id2bl(sd->npc_shopid);
  942. clif_buylist(sd, nd);
  943. }
  944. //First, handle all items in inventories/equiped, cart, and storage
  945. for(i = 0; i < MAX_INVENTORY; i++)
  946. {
  947. if(!sd->status.inventory[i].nameid)
  948. continue;
  949. id = itemdb_exists(sd->status.inventory[i].nameid);
  950. if(id == NULL)
  951. {
  952. sd->inventory_data[i] = NULL;
  953. pc_delitem(sd, i, sd->status.inventory[i].amount, 4);
  954. }
  955. else
  956. {
  957. sd->inventory_data[i] = id;
  958. }
  959. }
  960. //Delete nonexistant items from cart
  961. for(i = 0; i < MAX_CART; i++)
  962. {
  963. if(!sd->status.cart[i].nameid)
  964. continue;
  965. id = itemdb_exists(sd->status.cart[i].nameid);
  966. if(id == NULL)
  967. {
  968. sd->inventory_data[i] = NULL;
  969. pc_cart_delitem(sd, i, sd->status.cart[i].amount, 0);
  970. }
  971. }
  972. //Delete storage
  973. if((stor = account2storage2(sd->status.account_id)))
  974. {
  975. //If storage isn't found, it will be deleted whenever storage is loaded again
  976. if(stor)
  977. {
  978. for(i = 0; i < MAX_STORAGE; i++)
  979. {
  980. if(!sd->status.inventory[i].nameid)
  981. continue;
  982. if(itemdb_exists(sd->status.inventory[i].nameid) == NULL)
  983. storage_delitem(sd, stor, i, stor->storage_[i].amount);
  984. }
  985. }
  986. }
  987. return 0;
  988. }
  989. //Cleanup mob db drop tables
  990. void itemdb_foreach_mobdb(void)
  991. {
  992. int i = 0, j = 0;
  993. struct item_data * id;
  994. s_mob_db * mdb;
  995. for(i=0; i < MAX_MOB_DB; i++)
  996. {
  997. mdb = mob_db(i);
  998. if(mdb == mob_dummy)
  999. continue;
  1000. for(j=0; j < MAX_MOB_DROP; j++)
  1001. {
  1002. id = itemdb_exists(mdb->dropitem[j].nameid);
  1003. if(id == NULL)
  1004. {
  1005. mdb->dropitem[j].nameid = 0;
  1006. mdb->dropitem[j].p = 0;
  1007. }
  1008. }
  1009. }
  1010. }
  1011. #endif
  1012. void itemdb_reload(int flag)
  1013. {
  1014. do_final_itemdb();
  1015. do_init_itemdb();
  1016. if(flag)
  1017. {
  1018. //Update ALL items on the server
  1019. map_foreachpc(itemdb_reload_check);
  1020. npc_foreach(itemdb_reload_check_npc);
  1021. itemdb_foreach_mobdb();
  1022. }
  1023. }
  1024. void do_final_itemdb(void)
  1025. {
  1026. int i;
  1027. for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
  1028. if( itemdb_array[i] )
  1029. destroy_item_data(itemdb_array[i], 1);
  1030. itemdb_other->destroy(itemdb_other, itemdb_final_sub);
  1031. destroy_item_data(&dummy_item, 0);
  1032. }
  1033. int do_init_itemdb(void)
  1034. {
  1035. memset(itemdb_array, 0, sizeof(itemdb_array));
  1036. itemdb_other = idb_alloc(DB_OPT_BASE);
  1037. create_dummy_data(); //Dummy data item.
  1038. itemdb_read();
  1039. return 0;
  1040. }