itemdb.cpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067
  1. // Copyright (c) rAthena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include "itemdb.hpp"
  4. #include <stdlib.h>
  5. #include "../common/malloc.hpp"
  6. #include "../common/nullpo.hpp"
  7. #include "../common/random.hpp"
  8. #include "../common/showmsg.hpp"
  9. #include "../common/strlib.hpp"
  10. #include "../common/utils.hpp"
  11. #include "battle.hpp" // struct battle_config
  12. #include "cashshop.hpp"
  13. #include "clif.hpp"
  14. #include "intif.hpp"
  15. #include "log.hpp"
  16. #include "mob.hpp"
  17. #include "pc.hpp"
  18. #include "status.hpp"
  19. static DBMap *itemdb; /// Item DB
  20. static DBMap *itemdb_combo; /// Item Combo DB
  21. static DBMap *itemdb_group; /// Item Group DB
  22. static DBMap *itemdb_randomopt; /// Random option DB
  23. static DBMap *itemdb_randomopt_group; /// Random option group DB
  24. struct item_data *dummy_item; /// This is the default dummy item used for non-existant items. [Skotlex]
  25. struct s_roulette_db rd;
  26. /**
  27. * Check if combo exists
  28. * @param combo_id
  29. * @return NULL if not exist, or struct item_combo*
  30. */
  31. struct item_combo *itemdb_combo_exists(unsigned short combo_id) {
  32. return (struct item_combo *)uidb_get(itemdb_combo, combo_id);
  33. }
  34. /**
  35. * Check if item group exists
  36. * @param group_id
  37. * @return NULL if not exist, or s_item_group_db *
  38. */
  39. struct s_item_group_db *itemdb_group_exists(unsigned short group_id) {
  40. return (struct s_item_group_db *)uidb_get(itemdb_group, group_id);
  41. }
  42. /**
  43. * Check if an item exists in a group
  44. * @param group_id: Item Group ID
  45. * @param nameid: Item to check for in group
  46. * @return True if item is in group, else false
  47. */
  48. bool itemdb_group_item_exists(unsigned short group_id, unsigned short nameid)
  49. {
  50. struct s_item_group_db *group = (struct s_item_group_db *)uidb_get(itemdb_group, group_id);
  51. unsigned short i, j;
  52. if (!group)
  53. return false;
  54. for (i = 0; i < MAX_ITEMGROUP_RANDGROUP; i++) {
  55. for (j = 0; j < group->random[i].data_qty; j++)
  56. if (group->random[i].data[j].nameid == nameid)
  57. return true;
  58. }
  59. return false;
  60. }
  61. /**
  62. * Check if an item exists from a group in a player's inventory
  63. * @param group_id: Item Group ID
  64. * @return Item's index if found or -1 otherwise
  65. */
  66. int16 itemdb_group_item_exists_pc(struct map_session_data *sd, unsigned short group_id)
  67. {
  68. struct s_item_group_db *group = (struct s_item_group_db *)uidb_get(itemdb_group, group_id);
  69. if (!group)
  70. return -1;
  71. for (int i = 0; i < MAX_ITEMGROUP_RANDGROUP; i++) {
  72. for (int j = 0; j < group->random[i].data_qty; j++) {
  73. int16 item_position = pc_search_inventory(sd, group->random[i].data[j].nameid);
  74. if (item_position != -1)
  75. return item_position;
  76. }
  77. }
  78. return -1;
  79. }
  80. /**
  81. * Search for item name
  82. * name = item alias, so we should find items aliases first. if not found then look for "jname" (full name)
  83. * @see DBApply
  84. */
  85. static int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap)
  86. {
  87. struct item_data *item = (struct item_data *)db_data2ptr(data), **dst, **dst2;
  88. char *str;
  89. str = va_arg(ap,char *);
  90. dst = va_arg(ap,struct item_data **);
  91. dst2 = va_arg(ap,struct item_data **);
  92. //Absolute priority to Aegis code name.
  93. if (dst != NULL && strcmpi(item->name, str) == 0)
  94. *dst = item;
  95. //Second priority to Client displayed name.
  96. if (dst2 != NULL && strcmpi(item->jname, str) == 0)
  97. *dst2 = item;
  98. return 0;
  99. }
  100. /*==========================================
  101. * Return item data from item name. (lookup)
  102. * @param str Item Name
  103. * @param aegis_only
  104. * @return item data
  105. *------------------------------------------*/
  106. static struct item_data* itemdb_searchname1(const char *str, bool aegis_only)
  107. {
  108. struct item_data *item = NULL, * item2 = NULL;
  109. if( !aegis_only )
  110. itemdb->foreach(itemdb, itemdb_searchname_sub, str, &item, &item2);
  111. else
  112. itemdb->foreach(itemdb, itemdb_searchname_sub, str, &item, NULL);
  113. return ((item) ? item : item2);
  114. }
  115. struct item_data* itemdb_searchname(const char *str)
  116. {
  117. return itemdb_searchname1(str, false);
  118. }
  119. struct item_data* itemdb_search_aegisname( const char *str ){
  120. return itemdb_searchname1( str, true );
  121. }
  122. /**
  123. * @see DBMatcher
  124. */
  125. static int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap)
  126. {
  127. struct item_data *item = (struct item_data *)db_data2ptr(&data);
  128. char *str = va_arg(ap,char *);
  129. if (stristr(item->jname,str))
  130. return 0;
  131. if (stristr(item->name,str))
  132. return 0;
  133. return strcmpi(item->jname,str);
  134. }
  135. /*==========================================
  136. * Founds up to N matches. Returns number of matches [Skotlex]
  137. * @param *data
  138. * @param size
  139. * @param str
  140. * @return Number of matches item
  141. *------------------------------------------*/
  142. int itemdb_searchname_array(struct item_data** data, int size, const char *str)
  143. {
  144. DBData *db_data[MAX_SEARCH];
  145. int i, count = 0, db_count;
  146. db_count = itemdb->getall(itemdb, (DBData**)&db_data, size, itemdb_searchname_array_sub, str);
  147. for (i = 0; i < db_count && count < size; i++)
  148. data[count++] = (struct item_data*)db_data2ptr(db_data[i]);
  149. return count;
  150. }
  151. /**
  152. * Return a random group entry from Item Group
  153. * @param group_id
  154. * @param sub_group: 0 is 'must' item group, random groups start from 1 to MAX_ITEMGROUP_RANDGROUP+1
  155. * @return Item group entry or NULL on fail
  156. */
  157. struct s_item_group_entry *itemdb_get_randgroupitem(uint16 group_id, uint8 sub_group) {
  158. struct s_item_group_db *group = (struct s_item_group_db *) uidb_get(itemdb_group, group_id);
  159. struct s_item_group_entry *list = NULL;
  160. uint16 qty = 0;
  161. if (!group) {
  162. ShowError("itemdb_get_randgroupitem: Invalid group id %d\n", group_id);
  163. return NULL;
  164. }
  165. if (sub_group > MAX_ITEMGROUP_RANDGROUP+1) {
  166. ShowError("itemdb_get_randgroupitem: Invalid sub_group %d\n", sub_group);
  167. return NULL;
  168. }
  169. if (sub_group == 0) {
  170. list = group->must;
  171. qty = group->must_qty;
  172. }
  173. else {
  174. list = group->random[sub_group-1].data;
  175. qty = group->random[sub_group-1].data_qty;
  176. }
  177. if (!qty) {
  178. ShowError("itemdb_get_randgroupitem: No item entries for group id %d and sub group %d\n", group_id, sub_group);
  179. return NULL;
  180. }
  181. return &list[rnd()%qty];
  182. }
  183. /**
  184. * Return a random Item ID from from Item Group
  185. * @param group_id
  186. * @param sub_group: 0 is 'must' item group, random groups start from 1 to MAX_ITEMGROUP_RANDGROUP+1
  187. * @return Item ID or UNKNOWN_ITEM_ID on fail
  188. */
  189. unsigned short itemdb_searchrandomid(uint16 group_id, uint8 sub_group) {
  190. struct s_item_group_entry *entry = itemdb_get_randgroupitem(group_id, sub_group);
  191. return entry ? entry->nameid : UNKNOWN_ITEM_ID;
  192. }
  193. /** [Cydh]
  194. * Gives item(s) to the player based on item group
  195. * @param sd: Player that obtains item from item group
  196. * @param group_id: The group ID of item that obtained by player
  197. * @param *group: struct s_item_group from itemgroup_db[group_id].random[idx] or itemgroup_db[group_id].must[sub_group][idx]
  198. */
  199. static void itemdb_pc_get_itemgroup_sub(struct map_session_data *sd, bool identify, struct s_item_group_entry *data) {
  200. uint16 i, get_amt = 0;
  201. struct item tmp;
  202. nullpo_retv(data);
  203. memset(&tmp, 0, sizeof(tmp));
  204. tmp.nameid = data->nameid;
  205. tmp.bound = data->bound;
  206. tmp.identify = identify ? identify : itemdb_isidentified(data->nameid);
  207. tmp.expire_time = (data->duration) ? (unsigned int)(time(NULL) + data->duration*60) : 0;
  208. if (data->isNamed) {
  209. tmp.card[0] = itemdb_isequip(data->nameid) ? CARD0_FORGE : CARD0_CREATE;
  210. tmp.card[1] = 0;
  211. tmp.card[2] = GetWord(sd->status.char_id, 0);
  212. tmp.card[3] = GetWord(sd->status.char_id, 1);
  213. }
  214. if (!itemdb_isstackable(data->nameid))
  215. get_amt = 1;
  216. else
  217. get_amt = data->amount;
  218. // Do loop for non-stackable item
  219. for (i = 0; i < data->amount; i += get_amt) {
  220. char flag = 0;
  221. tmp.unique_id = data->GUID ? pc_generate_unique_id(sd) : 0; // Generate GUID
  222. if ((flag = pc_additem(sd, &tmp, get_amt, LOG_TYPE_SCRIPT))) {
  223. clif_additem(sd, 0, 0, flag);
  224. if (pc_candrop(sd, &tmp))
  225. map_addflooritem(&tmp, tmp.amount, sd->bl.m, sd->bl.x,sd->bl.y, 0, 0, 0, 0, 0);
  226. }
  227. else if (!flag && data->isAnnounced)
  228. intif_broadcast_obtain_special_item(sd, data->nameid, sd->itemid, ITEMOBTAIN_TYPE_BOXITEM);
  229. }
  230. }
  231. /** [Cydh]
  232. * Find item(s) that will be obtained by player based on Item Group
  233. * @param group_id: The group ID that will be gained by player
  234. * @param nameid: The item that trigger this item group
  235. * @return val: 0:success, 1:no sd, 2:invalid item group
  236. */
  237. char itemdb_pc_get_itemgroup(uint16 group_id, bool identify, struct map_session_data *sd) {
  238. uint16 i = 0;
  239. struct s_item_group_db *group;
  240. nullpo_retr(1,sd);
  241. if (!(group = (struct s_item_group_db *) uidb_get(itemdb_group, group_id))) {
  242. ShowError("itemdb_pc_get_itemgroup: Invalid group id '%d' specified.\n",group_id);
  243. return 2;
  244. }
  245. // Get the 'must' item(s)
  246. if (group->must_qty) {
  247. for (i = 0; i < group->must_qty; i++)
  248. if (&group->must[i])
  249. itemdb_pc_get_itemgroup_sub(sd, identify, &group->must[i]);
  250. }
  251. // Get the 'random' item each random group
  252. for (i = 0; i < MAX_ITEMGROUP_RANDGROUP; i++) {
  253. uint16 rand;
  254. if (!(&group->random[i]) || !group->random[i].data_qty) //Skip empty random group
  255. continue;
  256. rand = rnd()%group->random[i].data_qty;
  257. if (!(&group->random[i].data[rand]) || !group->random[i].data[rand].nameid)
  258. continue;
  259. itemdb_pc_get_itemgroup_sub(sd, identify, &group->random[i].data[rand]);
  260. }
  261. return 0;
  262. }
  263. /** Searches for the item_data. Use this to check if item exists or not.
  264. * @param nameid
  265. * @return *item_data if item is exist, or NULL if not
  266. */
  267. struct item_data* itemdb_exists(unsigned short nameid) {
  268. return ((struct item_data*)uidb_get(itemdb,nameid));
  269. }
  270. /// Returns name type of ammunition [Cydh]
  271. const char *itemdb_typename_ammo (enum e_item_ammo ammo) {
  272. switch (ammo) {
  273. case AMMO_ARROW: return "Arrow";
  274. case AMMO_THROWABLE_DAGGER: return "Throwable Dagger";
  275. case AMMO_BULLET: return "Bullet";
  276. case AMMO_SHELL: return "Shell";
  277. case AMMO_GRENADE: return "Grenade";
  278. case AMMO_SHURIKEN: return "Shuriken";
  279. case AMMO_KUNAI: return "Kunai";
  280. case AMMO_CANNONBALL: return "Cannonball";
  281. case AMMO_THROWABLE_ITEM: return "Throwable Item/Sling Item";
  282. }
  283. return "Ammunition";
  284. }
  285. /// Returns human readable name for given item type.
  286. /// @param type Type id to retrieve name for ( IT_* ).
  287. const char* itemdb_typename(enum item_types type)
  288. {
  289. switch(type)
  290. {
  291. case IT_HEALING: return "Potion/Food";
  292. case IT_USABLE: return "Usable";
  293. case IT_ETC: return "Etc.";
  294. case IT_WEAPON: return "Weapon";
  295. case IT_ARMOR: return "Armor";
  296. case IT_CARD: return "Card";
  297. case IT_PETEGG: return "Pet Egg";
  298. case IT_PETARMOR: return "Pet Accessory";
  299. case IT_AMMO: return "Arrow/Ammunition";
  300. case IT_DELAYCONSUME: return "Delay-Consume Usable";
  301. case IT_SHADOWGEAR: return "Shadow Equipment";
  302. case IT_CASH: return "Cash Usable";
  303. }
  304. return "Unknown Type";
  305. }
  306. /**
  307. * Converts the jobmask from the format in itemdb to the format used by the map server.
  308. * @param bclass: Pointer to store itemdb format
  309. * @param jobmask: Job Mask to convert
  310. * @author: Skotlex
  311. */
  312. static void itemdb_jobid2mapid(uint64 *bclass, uint64 jobmask)
  313. {
  314. int i;
  315. bclass[0] = bclass[1] = bclass[2] = 0;
  316. //Base classes
  317. if (jobmask & 1ULL<<JOB_NOVICE) {
  318. //Both Novice/Super-Novice are counted with the same ID
  319. bclass[0] |= 1ULL<<MAPID_NOVICE;
  320. bclass[1] |= 1ULL<<MAPID_NOVICE;
  321. }
  322. for (i = JOB_NOVICE + 1; i <= JOB_THIEF; i++) {
  323. if (jobmask & 1ULL <<i)
  324. bclass[0] |= 1ULL<<(MAPID_NOVICE + i);
  325. }
  326. //2-1 classes
  327. if (jobmask & 1ULL<<JOB_KNIGHT)
  328. bclass[1] |= 1ULL<<MAPID_SWORDMAN;
  329. if (jobmask & 1ULL<<JOB_PRIEST)
  330. bclass[1] |= 1ULL<<MAPID_ACOLYTE;
  331. if (jobmask & 1ULL<<JOB_WIZARD)
  332. bclass[1] |= 1ULL<<MAPID_MAGE;
  333. if (jobmask & 1ULL<<JOB_BLACKSMITH)
  334. bclass[1] |= 1ULL<<MAPID_MERCHANT;
  335. if (jobmask & 1ULL<<JOB_HUNTER)
  336. bclass[1] |= 1ULL<<MAPID_ARCHER;
  337. if (jobmask & 1ULL<<JOB_ASSASSIN)
  338. bclass[1] |= 1ULL<<MAPID_THIEF;
  339. //2-2 classes
  340. if (jobmask & 1ULL<<JOB_CRUSADER)
  341. bclass[2] |= 1ULL<<MAPID_SWORDMAN;
  342. if (jobmask & 1ULL<<JOB_MONK)
  343. bclass[2] |= 1ULL<<MAPID_ACOLYTE;
  344. if (jobmask & 1ULL<<JOB_SAGE)
  345. bclass[2] |= 1ULL<<MAPID_MAGE;
  346. if (jobmask & 1ULL<<JOB_ALCHEMIST)
  347. bclass[2] |= 1ULL<<MAPID_MERCHANT;
  348. if (jobmask & 1ULL<<JOB_BARD)
  349. bclass[2] |= 1ULL<<MAPID_ARCHER;
  350. // Bard/Dancer share the same slot now.
  351. // if (jobmask & 1ULL<<JOB_DANCER)
  352. // bclass[2] |= 1ULL<<MAPID_ARCHER;
  353. if (jobmask & 1ULL<<JOB_ROGUE)
  354. bclass[2] |= 1ULL<<MAPID_THIEF;
  355. //Special classes that don't fit above.
  356. if (jobmask & 1ULL<<21) //Taekwon
  357. bclass[0] |= 1ULL<<MAPID_TAEKWON;
  358. if (jobmask & 1ULL<<22) //Star Gladiator
  359. bclass[1] |= 1ULL<<MAPID_TAEKWON;
  360. if (jobmask & 1ULL<<23) //Soul Linker
  361. bclass[2] |= 1ULL<<MAPID_TAEKWON;
  362. if (jobmask & 1ULL<<JOB_GUNSLINGER) { // Rebellion job can equip Gunslinger equips.
  363. bclass[0] |= 1ULL<<MAPID_GUNSLINGER;
  364. bclass[1] |= 1ULL<<MAPID_GUNSLINGER;
  365. }
  366. if (jobmask & 1ULL<<JOB_NINJA) { //Kagerou/Oboro jobs can equip Ninja equips. [Rytech]
  367. bclass[0] |= 1ULL<<MAPID_NINJA;
  368. bclass[1] |= 1ULL<<MAPID_NINJA;
  369. }
  370. if (jobmask & 1ULL<<26) //Bongun/Munak
  371. bclass[0] |= 1ULL<<MAPID_GANGSI;
  372. if (jobmask & 1ULL<<27) //Death Knight
  373. bclass[1] |= 1ULL<<MAPID_GANGSI;
  374. if (jobmask & 1ULL<<28) //Dark Collector
  375. bclass[2] |= 1ULL<<MAPID_GANGSI;
  376. if (jobmask & 1ULL<<29) //Kagerou / Oboro
  377. bclass[1] |= 1ULL<<MAPID_NINJA;
  378. if (jobmask & 1ULL<<30) //Rebellion
  379. bclass[1] |= 1ULL<<MAPID_GUNSLINGER;
  380. if (jobmask & 1ULL<<31) //Summoner
  381. bclass[0] |= 1ULL<<MAPID_SUMMONER;
  382. }
  383. /**
  384. * Create dummy item_data as dummy_item and dummy item group entry as dummy_itemgroup
  385. */
  386. static void itemdb_create_dummy(void) {
  387. CREATE(dummy_item, struct item_data, 1);
  388. memset(dummy_item, 0, sizeof(struct item_data));
  389. dummy_item->nameid = 500;
  390. dummy_item->weight = 1;
  391. dummy_item->value_sell = 1;
  392. dummy_item->type = IT_ETC; //Etc item
  393. safestrncpy(dummy_item->name, "UNKNOWN_ITEM", sizeof(dummy_item->name));
  394. safestrncpy(dummy_item->jname, "Unknown Item", sizeof(dummy_item->jname));
  395. dummy_item->view_id = UNKNOWN_ITEM_ID;
  396. }
  397. /**
  398. * Create new item data
  399. * @param nameid
  400. */
  401. static struct item_data *itemdb_create_item(unsigned short nameid) {
  402. struct item_data *id;
  403. CREATE(id, struct item_data, 1);
  404. memset(id, 0, sizeof(struct item_data));
  405. id->nameid = nameid;
  406. id->type = IT_ETC; //Etc item
  407. uidb_put(itemdb, nameid, id);
  408. return id;
  409. }
  410. /*==========================================
  411. * Loads an item from the db. If not found, it will return the dummy item.
  412. * @param nameid
  413. * @return *item_data or *dummy_item if item not found
  414. *------------------------------------------*/
  415. struct item_data* itemdb_search(unsigned short nameid) {
  416. struct item_data* id = NULL;
  417. if (nameid == dummy_item->nameid)
  418. id = dummy_item;
  419. else if (!(id = (struct item_data*)uidb_get(itemdb, nameid))) {
  420. ShowWarning("itemdb_search: Item ID %hu does not exists in the item_db. Using dummy data.\n", nameid);
  421. id = dummy_item;
  422. }
  423. return id;
  424. }
  425. /** Checks if item is equip type or not
  426. * @param id Item data
  427. * @return True if item is equip, false otherwise
  428. */
  429. bool itemdb_isequip2(struct item_data *id) {
  430. nullpo_ret(id);
  431. switch (id->type) {
  432. case IT_WEAPON:
  433. case IT_ARMOR:
  434. case IT_AMMO:
  435. case IT_SHADOWGEAR:
  436. return true;
  437. default:
  438. return false;
  439. }
  440. }
  441. /** Checks if item is stackable or not
  442. * @param id Item data
  443. * @return True if item is stackable, false otherwise
  444. */
  445. bool itemdb_isstackable2(struct item_data *id)
  446. {
  447. nullpo_ret(id);
  448. return id->isStackable();
  449. }
  450. /*==========================================
  451. * Trade Restriction functions [Skotlex]
  452. *------------------------------------------*/
  453. bool itemdb_isdropable_sub(struct item_data *item, int gmlv, int unused) {
  454. return (item && (!(item->flag.trade_restriction&1) || gmlv >= item->gm_lv_trade_override));
  455. }
  456. bool itemdb_cantrade_sub(struct item_data* item, int gmlv, int gmlv2) {
  457. return (item && (!(item->flag.trade_restriction&2) || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
  458. }
  459. bool itemdb_canpartnertrade_sub(struct item_data* item, int gmlv, int gmlv2) {
  460. return (item && (item->flag.trade_restriction&4 || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
  461. }
  462. bool itemdb_cansell_sub(struct item_data* item, int gmlv, int unused) {
  463. return (item && (!(item->flag.trade_restriction&8) || gmlv >= item->gm_lv_trade_override));
  464. }
  465. bool itemdb_cancartstore_sub(struct item_data* item, int gmlv, int unused) {
  466. return (item && (!(item->flag.trade_restriction&16) || gmlv >= item->gm_lv_trade_override));
  467. }
  468. bool itemdb_canstore_sub(struct item_data* item, int gmlv, int unused) {
  469. return (item && (!(item->flag.trade_restriction&32) || gmlv >= item->gm_lv_trade_override));
  470. }
  471. bool itemdb_canguildstore_sub(struct item_data* item, int gmlv, int unused) {
  472. return (item && (!(item->flag.trade_restriction&64) || gmlv >= item->gm_lv_trade_override));
  473. }
  474. bool itemdb_canmail_sub(struct item_data* item, int gmlv, int unused) {
  475. return (item && (!(item->flag.trade_restriction&128) || gmlv >= item->gm_lv_trade_override));
  476. }
  477. bool itemdb_canauction_sub(struct item_data* item, int gmlv, int unused) {
  478. return (item && (!(item->flag.trade_restriction&256) || gmlv >= item->gm_lv_trade_override));
  479. }
  480. bool itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, bool (*func)(struct item_data*, int, int))
  481. {
  482. struct item_data* item_data = itemdb_search(item->nameid);
  483. int i;
  484. if (!func(item_data, gmlv, gmlv2))
  485. return false;
  486. if(item_data->slot == 0 || itemdb_isspecial(item->card[0]))
  487. return true;
  488. for(i = 0; i < item_data->slot; i++) {
  489. if (!item->card[i]) continue;
  490. if (!func(itemdb_search(item->card[i]), gmlv, gmlv2))
  491. return false;
  492. }
  493. return true;
  494. }
  495. bool itemdb_ishatched_egg(struct item* item) {
  496. if (item && item->card[0] == CARD0_PET && item->attribute == 1)
  497. return true;
  498. return false;
  499. }
  500. /** Specifies if item-type should drop unidentified.
  501. * @param nameid ID of item
  502. */
  503. char itemdb_isidentified(unsigned short nameid) {
  504. int type=itemdb_type(nameid);
  505. switch (type) {
  506. case IT_WEAPON:
  507. case IT_ARMOR:
  508. case IT_PETARMOR:
  509. case IT_SHADOWGEAR:
  510. return 0;
  511. default:
  512. return 1;
  513. }
  514. }
  515. /** Search by name for the override flags available items (Give item another sprite)
  516. * Structure: <nameid>,<sprite>
  517. */
  518. static bool itemdb_read_itemavail(char* str[], int columns, int current) {
  519. unsigned short nameid, sprite;
  520. struct item_data *id;
  521. nameid = atoi(str[0]);
  522. if( ( id = itemdb_exists(nameid) ) == NULL )
  523. {
  524. ShowWarning("itemdb_read_itemavail: Invalid item id %hu.\n", nameid);
  525. return false;
  526. }
  527. sprite = atoi(str[1]);
  528. if( sprite > 0 )
  529. {
  530. id->flag.available = 1;
  531. id->view_id = sprite;
  532. }
  533. else
  534. {
  535. id->flag.available = 0;
  536. }
  537. return true;
  538. }
  539. static int itemdb_group_free(DBKey key, DBData *data, va_list ap);
  540. static int itemdb_group_free2(DBKey key, DBData *data);
  541. static bool itemdb_read_group(char* str[], int columns, int current) {
  542. int group_id = -1;
  543. unsigned int j, prob = 1;
  544. uint8 rand_group = 1;
  545. struct s_item_group_random *random = NULL;
  546. struct s_item_group_db *group = NULL;
  547. struct s_item_group_entry entry;
  548. memset(&entry, 0, sizeof(entry));
  549. entry.amount = 1;
  550. entry.bound = BOUND_NONE;
  551. str[0] = trim(str[0]);
  552. if( ISDIGIT(str[0][0]) ){
  553. group_id = atoi(str[0]);
  554. }else{
  555. // Try to parse group id as constant
  556. script_get_constant(str[0], &group_id);
  557. }
  558. // Check the group id
  559. if( group_id < 0 ){
  560. ShowWarning( "itemdb_read_group: Invalid group ID '%s'\n", str[0] );
  561. return false;
  562. }
  563. // Remove from DB
  564. if( strcmpi( str[1], "clear" ) == 0 ){
  565. DBData data;
  566. if( itemdb_group->remove( itemdb_group, db_ui2key(group_id), &data ) ){
  567. itemdb_group_free2(db_ui2key(group_id), &data);
  568. ShowNotice( "itemdb_read_group: Item Group '%s' has been cleared.\n", str[0] );
  569. return true;
  570. }else{
  571. ShowWarning( "itemdb_read_group: Item Group '%s' has not been cleared, because it did not exist.\n", str[0] );
  572. return false;
  573. }
  574. }
  575. if( columns < 3 ){
  576. ShowError("itemdb_read_group: Insufficient columns (found %d, need at least 3).\n", columns);
  577. return false;
  578. }
  579. // Checking sub group
  580. prob = atoi(str[2]);
  581. if( columns > 4 ){
  582. rand_group = atoi(str[4]);
  583. if( rand_group < 0 || rand_group > MAX_ITEMGROUP_RANDGROUP ){
  584. ShowWarning( "itemdb_read_group: Invalid sub group '%d' for group '%s'\n", rand_group, str[0] );
  585. return false;
  586. }
  587. }else{
  588. rand_group = 1;
  589. }
  590. if( rand_group != 0 && prob < 1 ){
  591. ShowWarning( "itemdb_read_group: Random item must have a probability. Group '%s'\n", str[0] );
  592. return false;
  593. }
  594. // Check item
  595. str[1] = trim(str[1]);
  596. // Check if the item can be found by id
  597. if( ( entry.nameid = atoi(str[1]) ) <= 0 || !itemdb_exists( entry.nameid ) ){
  598. // Otherwise look it up by name
  599. struct item_data *id = itemdb_searchname(str[1]);
  600. if( id ){
  601. // Found the item with a name lookup
  602. entry.nameid = id->nameid;
  603. }else{
  604. ShowWarning( "itemdb_read_group: Non-existant item '%s'\n", str[1] );
  605. return false;
  606. }
  607. }
  608. if( columns > 3 ) entry.amount = cap_value(atoi(str[3]),1,MAX_AMOUNT);
  609. if( columns > 5 ) entry.isAnnounced= atoi(str[5]) > 0;
  610. if( columns > 6 ) entry.duration = cap_value(atoi(str[6]),0,UINT16_MAX);
  611. if( columns > 7 ) entry.GUID = atoi(str[7]) > 0;
  612. if( columns > 8 ) entry.bound = cap_value(atoi(str[8]),BOUND_NONE,BOUND_MAX-1);
  613. if( columns > 9 ) entry.isNamed = atoi(str[9]) > 0;
  614. if (!(group = (struct s_item_group_db *) uidb_get(itemdb_group, group_id))) {
  615. CREATE(group, struct s_item_group_db, 1);
  616. group->id = group_id;
  617. uidb_put(itemdb_group, group->id, group);
  618. }
  619. // Must item (rand_group == 0), place it here
  620. if (!rand_group) {
  621. RECREATE(group->must, struct s_item_group_entry, group->must_qty+1);
  622. group->must[group->must_qty++] = entry;
  623. // If 'must' item isn't set as random item, skip the next process
  624. if (!prob) {
  625. return true;
  626. }
  627. rand_group = 0;
  628. }
  629. else
  630. rand_group -= 1;
  631. random = &group->random[rand_group];
  632. RECREATE(random->data, struct s_item_group_entry, random->data_qty+prob);
  633. // Put the entry to its rand_group
  634. for (j = random->data_qty; j < random->data_qty+prob; j++)
  635. random->data[j] = entry;
  636. random->data_qty += prob;
  637. return true;
  638. }
  639. /** Read item forbidden by mapflag (can't equip item)
  640. * Structure: <nameid>,<mode>
  641. */
  642. static bool itemdb_read_noequip(char* str[], int columns, int current) {
  643. unsigned short nameid;
  644. int flag;
  645. struct item_data *id;
  646. nameid = atoi(str[0]);
  647. flag = atoi(str[1]);
  648. if( ( id = itemdb_exists(nameid) ) == NULL )
  649. {
  650. ShowWarning("itemdb_read_noequip: Invalid item id %hu.\n", nameid);
  651. return false;
  652. }
  653. if (flag >= 0)
  654. id->flag.no_equip |= flag;
  655. else
  656. id->flag.no_equip &= ~abs(flag);
  657. return true;
  658. }
  659. /** Reads item trade restrictions [Skotlex]
  660. * Structure: <nameid>,<mask>,<gm level>
  661. */
  662. static bool itemdb_read_itemtrade(char* str[], int columns, int current) {
  663. unsigned short nameid, flag, gmlv;
  664. struct item_data *id;
  665. nameid = atoi(str[0]);
  666. if( ( id = itemdb_exists(nameid) ) == NULL )
  667. {
  668. //ShowWarning("itemdb_read_itemtrade: Invalid item id %d.\n", nameid);
  669. //return false;
  670. // FIXME: item_trade.txt contains items, which are commented in item database.
  671. return true;
  672. }
  673. flag = atoi(str[1]);
  674. gmlv = atoi(str[2]);
  675. if( flag > 511 ) {//Check range
  676. ShowWarning("itemdb_read_itemtrade: Invalid trading mask %hu for item id %hu.\n", flag, nameid);
  677. return false;
  678. }
  679. if( gmlv < 1 )
  680. {
  681. ShowWarning("itemdb_read_itemtrade: Invalid override GM level %hu for item id %hu.\n", gmlv, nameid);
  682. return false;
  683. }
  684. id->flag.trade_restriction = flag;
  685. id->gm_lv_trade_override = gmlv;
  686. return true;
  687. }
  688. /** Reads item delay amounts [Paradox924X]
  689. * Structure: <nameid>,<delay>{,<delay sc group>}
  690. */
  691. static bool itemdb_read_itemdelay(char* str[], int columns, int current) {
  692. unsigned short nameid;
  693. int delay;
  694. struct item_data *id;
  695. nameid = atoi(str[0]);
  696. if( ( id = itemdb_exists(nameid) ) == NULL )
  697. {
  698. ShowWarning("itemdb_read_itemdelay: Invalid item id %hu.\n", nameid);
  699. return false;
  700. }
  701. delay = atoi(str[1]);
  702. if( delay < 0 )
  703. {
  704. ShowWarning("itemdb_read_itemdelay: Invalid delay %d for item id %hu.\n", delay, nameid);
  705. return false;
  706. }
  707. id->delay = delay;
  708. if (columns == 2)
  709. id->delay_sc = SC_NONE;
  710. else if( ISDIGIT(str[2][0]) )
  711. id->delay_sc = atoi(str[2]);
  712. else{ // Try read sc group id from const db
  713. int constant;
  714. if( !script_get_constant(trim(str[2]), &constant) ){
  715. ShowWarning("itemdb_read_itemdelay: Invalid sc group \"%s\" for item id %hu.\n", str[2], nameid);
  716. return false;
  717. }
  718. id->delay_sc = (short)constant;
  719. }
  720. return true;
  721. }
  722. /** Reads item stacking restrictions
  723. * Structure: <item id>,<stack limit amount>,<type>
  724. */
  725. static bool itemdb_read_stack(char* fields[], int columns, int current) {
  726. unsigned short nameid, amount;
  727. unsigned int type;
  728. struct item_data* id;
  729. nameid = (unsigned short)strtoul(fields[0], NULL, 10);
  730. if( ( id = itemdb_exists(nameid) ) == NULL )
  731. {
  732. ShowWarning("itemdb_read_stack: Unknown item id '%hu'.\n", nameid);
  733. return false;
  734. }
  735. if( !itemdb_isstackable2(id) )
  736. {
  737. ShowWarning("itemdb_read_stack: Item id '%hu' is not stackable.\n", nameid);
  738. return false;
  739. }
  740. amount = (unsigned short)strtoul(fields[1], NULL, 10);
  741. type = strtoul(fields[2], NULL, 10);
  742. if( !amount )
  743. {// ignore
  744. return true;
  745. }
  746. id->stack.amount = amount;
  747. id->stack.inventory = (type&1)!=0;
  748. id->stack.cart = (type&2)!=0;
  749. id->stack.storage = (type&4)!=0;
  750. id->stack.guildstorage = (type&8)!=0;
  751. return true;
  752. }
  753. /** Reads items allowed to be sold in buying stores
  754. * <nameid>
  755. */
  756. static bool itemdb_read_buyingstore(char* fields[], int columns, int current) {
  757. unsigned short nameid;
  758. struct item_data* id;
  759. nameid = atoi(fields[0]);
  760. if( ( id = itemdb_exists(nameid) ) == NULL )
  761. {
  762. ShowWarning("itemdb_read_buyingstore: Invalid item id %hu.\n", nameid);
  763. return false;
  764. }
  765. if( !itemdb_isstackable2(id) )
  766. {
  767. ShowWarning("itemdb_read_buyingstore: Non-stackable item id %hu cannot be enabled for buying store.\n", nameid);
  768. return false;
  769. }
  770. id->flag.buyingstore = true;
  771. return true;
  772. }
  773. /** Item usage restriction (item_nouse.txt)
  774. * <nameid>,<flag>,<override>
  775. */
  776. static bool itemdb_read_nouse(char* fields[], int columns, int current) {
  777. unsigned short nameid, flag, override;
  778. struct item_data* id;
  779. nameid = atoi(fields[0]);
  780. if( ( id = itemdb_exists(nameid) ) == NULL ) {
  781. ShowWarning("itemdb_read_nouse: Invalid item id %hu.\n", nameid);
  782. return false;
  783. }
  784. flag = atoi(fields[1]);
  785. override = atoi(fields[2]);
  786. id->item_usage.flag = flag;
  787. id->item_usage.override = override;
  788. return true;
  789. }
  790. /** Misc Item flags
  791. * <item_id>,<flag>
  792. * &1 - As dead branch item
  793. * &2 - As item container
  794. * &4 - GUID item, cannot be stacked even same or stackable item
  795. */
  796. static bool itemdb_read_flag(char* fields[], int columns, int current) {
  797. unsigned short nameid = atoi(fields[0]);
  798. uint16 flag;
  799. bool set;
  800. struct item_data *id;
  801. if (!(id = itemdb_exists(nameid))) {
  802. ShowError("itemdb_read_flag: Invalid item id %hu\n", nameid);
  803. return true;
  804. }
  805. flag = abs(atoi(fields[1]));
  806. set = atoi(fields[1]) > 0;
  807. if (flag&1) id->flag.dead_branch = set ? 1 : 0;
  808. if (flag&2) id->flag.group = set ? 1 : 0;
  809. if (flag&4 && itemdb_isstackable2(id)) id->flag.guid = set ? 1 : 0;
  810. if (flag&8) id->flag.bindOnEquip = true;
  811. if (flag&16) id->flag.broadcast = 1;
  812. if (flag&32) id->flag.delay_consume = 2;
  813. if( flag & 64 ){
  814. id->flag.dropEffect = 1;
  815. }else if( flag & 128 ){
  816. id->flag.dropEffect = 2;
  817. }else if( flag & 256 ){
  818. id->flag.dropEffect = 3;
  819. }else if( flag & 512 ){
  820. id->flag.dropEffect = 4;
  821. }else if( flag & 1024 ){
  822. id->flag.dropEffect = 5;
  823. }else if( flag & 2048 ){
  824. id->flag.dropEffect = 6;
  825. }
  826. return true;
  827. }
  828. /**
  829. * @return: amount of retrieved entries.
  830. **/
  831. static int itemdb_combo_split_atoi (char *str, int *val) {
  832. int i;
  833. for (i=0; i<MAX_ITEMS_PER_COMBO; i++) {
  834. if (!str) break;
  835. val[i] = atoi(str);
  836. str = strchr(str,':');
  837. if (str)
  838. *str++=0;
  839. }
  840. if( i == 0 ) //No data found.
  841. return 0;
  842. return i;
  843. }
  844. /**
  845. * <combo{:combo{:combo:{..}}}>,<{ script }>
  846. **/
  847. static void itemdb_read_combos(const char* basedir, bool silent) {
  848. uint32 lines = 0, count = 0;
  849. char line[1024];
  850. char path[256];
  851. FILE* fp;
  852. sprintf(path, "%s/%s", basedir, "item_combo_db.txt");
  853. if ((fp = fopen(path, "r")) == NULL) {
  854. if(silent==0) ShowError("itemdb_read_combos: File not found \"%s\".\n", path);
  855. return;
  856. }
  857. // process rows one by one
  858. while(fgets(line, sizeof(line), fp)) {
  859. char *str[2], *p;
  860. lines++;
  861. if (line[0] == '/' && line[1] == '/')
  862. continue;
  863. memset(str, 0, sizeof(str));
  864. p = line;
  865. p = trim(p);
  866. if (*p == '\0')
  867. continue;// empty line
  868. if (!strchr(p,','))
  869. {
  870. /* is there even a single column? */
  871. ShowError("itemdb_read_combos: Insufficient columns in line %d of \"%s\", skipping.\n", lines, path);
  872. continue;
  873. }
  874. str[0] = p;
  875. p = strchr(p,',');
  876. *p = '\0';
  877. p++;
  878. str[1] = p;
  879. p = strchr(p,',');
  880. p++;
  881. if (str[1][0] != '{') {
  882. ShowError("itemdb_read_combos(#1): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
  883. continue;
  884. }
  885. /* no ending key anywhere (missing \}\) */
  886. if ( str[1][strlen(str[1])-1] != '}' ) {
  887. ShowError("itemdb_read_combos(#2): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
  888. continue;
  889. } else {
  890. int items[MAX_ITEMS_PER_COMBO];
  891. int v = 0, retcount = 0;
  892. struct item_data * id = NULL;
  893. int idx = 0;
  894. if((retcount = itemdb_combo_split_atoi(str[0], items)) < 2) {
  895. ShowError("itemdb_read_combos: line %d of \"%s\" doesn't have enough items to make for a combo (min:2), skipping.\n", lines, path);
  896. continue;
  897. }
  898. /* validate */
  899. for(v = 0; v < retcount; v++) {
  900. if( !itemdb_exists(items[v]) ) {
  901. ShowError("itemdb_read_combos: line %d of \"%s\" contains unknown item ID %d, skipping.\n", lines, path,items[v]);
  902. break;
  903. }
  904. }
  905. /* failed at some item */
  906. if( v < retcount )
  907. continue;
  908. id = itemdb_exists(items[0]);
  909. idx = id->combos_count;
  910. /* first entry, create */
  911. if( id->combos == NULL ) {
  912. CREATE(id->combos, struct item_combo*, 1);
  913. id->combos_count = 1;
  914. } else {
  915. RECREATE(id->combos, struct item_combo*, ++id->combos_count);
  916. }
  917. CREATE(id->combos[idx],struct item_combo,1);
  918. id->combos[idx]->nameid = (unsigned short*)aMalloc( retcount * sizeof(unsigned short) );
  919. id->combos[idx]->count = retcount;
  920. id->combos[idx]->script = parse_script(str[1], path, lines, 0);
  921. id->combos[idx]->id = count;
  922. id->combos[idx]->isRef = false;
  923. /* populate ->nameid field */
  924. for( v = 0; v < retcount; v++ ) {
  925. id->combos[idx]->nameid[v] = items[v];
  926. }
  927. /* populate the children to refer to this combo */
  928. for( v = 1; v < retcount; v++ ) {
  929. struct item_data * it;
  930. int index;
  931. it = itemdb_exists(items[v]);
  932. index = it->combos_count;
  933. if( it->combos == NULL ) {
  934. CREATE(it->combos, struct item_combo*, 1);
  935. it->combos_count = 1;
  936. } else {
  937. RECREATE(it->combos, struct item_combo*, ++it->combos_count);
  938. }
  939. CREATE(it->combos[index],struct item_combo,1);
  940. /* we copy previously alloc'd pointers and just set it to reference */
  941. memcpy(it->combos[index],id->combos[idx],sizeof(struct item_combo));
  942. /* we flag this way to ensure we don't double-dealloc same data */
  943. it->combos[index]->isRef = true;
  944. }
  945. uidb_put(itemdb_combo,id->combos[idx]->id,id->combos[idx]);
  946. }
  947. count++;
  948. }
  949. fclose(fp);
  950. ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n",count,path);
  951. return;
  952. }
  953. /**
  954. * Process Roulette items
  955. */
  956. bool itemdb_parse_roulette_db(void)
  957. {
  958. int i, j;
  959. uint32 count = 0;
  960. // retrieve all rows from the item database
  961. if (SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", roulette_table)) {
  962. Sql_ShowDebug(mmysql_handle);
  963. return false;
  964. }
  965. for (i = 0; i < MAX_ROULETTE_LEVEL; i++)
  966. rd.items[i] = 0;
  967. for (i = 0; i < MAX_ROULETTE_LEVEL; i++) {
  968. int k, limit = MAX_ROULETTE_COLUMNS - i;
  969. for (k = 0; k < limit && SQL_SUCCESS == Sql_NextRow(mmysql_handle); k++) {
  970. char* data;
  971. unsigned short item_id, amount;
  972. int level, flag;
  973. Sql_GetData(mmysql_handle, 1, &data, NULL); level = atoi(data);
  974. Sql_GetData(mmysql_handle, 2, &data, NULL); item_id = atoi(data);
  975. Sql_GetData(mmysql_handle, 3, &data, NULL); amount = atoi(data);
  976. Sql_GetData(mmysql_handle, 4, &data, NULL); flag = atoi(data);
  977. if (!itemdb_exists(item_id)) {
  978. ShowWarning("itemdb_parse_roulette_db: Unknown item ID '%hu' in level '%d'\n", item_id, level);
  979. continue;
  980. }
  981. if (amount < 1 || amount > MAX_AMOUNT){
  982. ShowWarning("itemdb_parse_roulette_db: Unsupported amount '%hu' for item ID '%hu' in level '%d'\n", amount, item_id, level);
  983. continue;
  984. }
  985. if (flag < 0 || flag > 1) {
  986. ShowWarning("itemdb_parse_roulette_db: Unsupported flag '%d' for item ID '%hu' in level '%d'\n", flag, item_id, level);
  987. continue;
  988. }
  989. j = rd.items[i];
  990. RECREATE(rd.nameid[i], unsigned short, ++rd.items[i]);
  991. RECREATE(rd.qty[i], unsigned short, rd.items[i]);
  992. RECREATE(rd.flag[i], int, rd.items[i]);
  993. rd.nameid[i][j] = item_id;
  994. rd.qty[i][j] = amount;
  995. rd.flag[i][j] = flag;
  996. ++count;
  997. }
  998. }
  999. // free the query result
  1000. Sql_FreeResult(mmysql_handle);
  1001. for (i = 0; i < MAX_ROULETTE_LEVEL; i++) {
  1002. int limit = MAX_ROULETTE_COLUMNS - i;
  1003. if (rd.items[i] == limit)
  1004. continue;
  1005. if (rd.items[i] > limit) {
  1006. ShowWarning("itemdb_parse_roulette_db: level %d has %d items, only %d supported, capping...\n", i + 1, rd.items[i], limit);
  1007. rd.items[i] = limit;
  1008. continue;
  1009. }
  1010. /** this scenario = rd.items[i] < limit **/
  1011. ShowWarning("itemdb_parse_roulette_db: Level %d has %d items, %d are required. Filling with Apples...\n", i + 1, rd.items[i], limit);
  1012. rd.items[i] = limit;
  1013. RECREATE(rd.nameid[i], unsigned short, rd.items[i]);
  1014. RECREATE(rd.qty[i], unsigned short, rd.items[i]);
  1015. RECREATE(rd.flag[i], int, rd.items[i]);
  1016. for (j = 0; j < MAX_ROULETTE_COLUMNS - i; j++) {
  1017. if (rd.qty[i][j])
  1018. continue;
  1019. rd.nameid[i][j] = ITEMID_APPLE;
  1020. rd.qty[i][j] = 1;
  1021. rd.flag[i][j] = 0;
  1022. }
  1023. }
  1024. ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, roulette_table);
  1025. return true;
  1026. }
  1027. /**
  1028. * Free Roulette items
  1029. */
  1030. static void itemdb_roulette_free(void) {
  1031. int i;
  1032. for (i = 0; i < MAX_ROULETTE_LEVEL; i++) {
  1033. if (rd.nameid[i])
  1034. aFree(rd.nameid[i]);
  1035. if (rd.qty[i])
  1036. aFree(rd.qty[i]);
  1037. if (rd.flag[i])
  1038. aFree(rd.flag[i]);
  1039. rd.nameid[i] = NULL;
  1040. rd.qty[i] = NULL;
  1041. rd.flag[i] = NULL;
  1042. rd.items[i] = 0;
  1043. }
  1044. }
  1045. /*======================================
  1046. * Applies gender restrictions according to settings. [Skotlex]
  1047. *======================================*/
  1048. static char itemdb_gendercheck(struct item_data *id)
  1049. {
  1050. if (id->nameid == WEDDING_RING_M) //Grom Ring
  1051. return 1;
  1052. if (id->nameid == WEDDING_RING_F) //Bride Ring
  1053. return 0;
  1054. if (id->look == W_MUSICAL && id->type == IT_WEAPON) //Musical instruments are always male-only
  1055. return 1;
  1056. if (id->look == W_WHIP && id->type == IT_WEAPON) //Whips are always female-only
  1057. return 0;
  1058. return (battle_config.ignore_items_gender) ? 2 : id->sex;
  1059. }
  1060. /**
  1061. * [RRInd]
  1062. * For backwards compatibility, in Renewal mode, MATK from weapons comes from the atk slot
  1063. * We use a ':' delimiter which, if not found, assumes the weapon does not provide any matk.
  1064. **/
  1065. static void itemdb_re_split_atoi(char *str, int *val1, int *val2) {
  1066. int i, val[2];
  1067. for (i=0; i<2; i++) {
  1068. if (!str) break;
  1069. val[i] = atoi(str);
  1070. str = strchr(str,':');
  1071. if (str)
  1072. *str++=0;
  1073. }
  1074. if( i == 0 ) {
  1075. *val1 = *val2 = 0;
  1076. return;//no data found
  1077. }
  1078. if( i == 1 ) {//Single Value
  1079. *val1 = val[0];
  1080. *val2 = 0;
  1081. return;
  1082. }
  1083. //We assume we have 2 values.
  1084. *val1 = val[0];
  1085. *val2 = val[1];
  1086. return;
  1087. }
  1088. /**
  1089. * Processes one itemdb entry
  1090. */
  1091. static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt) {
  1092. /*
  1093. +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
  1094. | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
  1095. +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
  1096. | 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 |
  1097. +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
  1098. */
  1099. unsigned short nameid;
  1100. struct item_data* id;
  1101. if( atoi(str[0]) <= 0 || atoi(str[0]) >= MAX_ITEMID || atoi(str[0]) == dummy_item->nameid )
  1102. {
  1103. ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", atoi(str[0]), line, source);
  1104. return false;
  1105. }
  1106. nameid = atoi(str[0]);
  1107. //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
  1108. if (!(id = itemdb_exists(nameid))) {
  1109. // Checks if the Itemname is already taken by another id
  1110. if( itemdb_searchname1(str[1], true) != NULL )
  1111. ShowWarning("itemdb_parse_dbrow: Duplicate item name for \"%s\"\n", str[1]);
  1112. // Adds a new Item ID
  1113. id = itemdb_create_item(nameid);
  1114. }
  1115. safestrncpy(id->name, str[1], sizeof(id->name));
  1116. safestrncpy(id->jname, str[2], sizeof(id->jname));
  1117. id->type = atoi(str[3]);
  1118. if( id->type < 0 || id->type == IT_UNKNOWN || id->type == IT_UNKNOWN2 || ( id->type > IT_SHADOWGEAR && id->type < IT_CASH ) || id->type >= IT_MAX )
  1119. {// catch invalid item types
  1120. ShowWarning("itemdb_parse_dbrow: Invalid item type %d for item %hu. IT_ETC will be used.\n", id->type, nameid);
  1121. id->type = IT_ETC;
  1122. }
  1123. if (id->type == IT_DELAYCONSUME)
  1124. { //Items that are consumed only after target confirmation
  1125. id->type = IT_USABLE;
  1126. id->flag.delay_consume = 1;
  1127. } else //In case of an itemdb reload and the item type changed.
  1128. id->flag.delay_consume = 0;
  1129. //When a particular price is not given, we should base it off the other one
  1130. //(it is important to make a distinction between 'no price' and 0z)
  1131. if ( str[4][0] )
  1132. id->value_buy = atoi(str[4]);
  1133. else
  1134. id->value_buy = atoi(str[5]) * 2;
  1135. if ( str[5][0] )
  1136. id->value_sell = atoi(str[5]);
  1137. else
  1138. id->value_sell = id->value_buy / 2;
  1139. /*
  1140. if ( !str[4][0] && !str[5][0])
  1141. {
  1142. ShowWarning("itemdb_parse_dbrow: No buying/selling price defined for item %hu (%s), using 20/10z\n", nameid, id->jname);
  1143. id->value_buy = 20;
  1144. id->value_sell = 10;
  1145. } else
  1146. */
  1147. if (id->value_buy/124. < id->value_sell/75.)
  1148. ShowWarning("itemdb_parse_dbrow: Buying/Selling [%d/%d] price of item %hu (%s) allows Zeny making exploit through buying/selling at discounted/overcharged prices!\n",
  1149. id->value_buy, id->value_sell, nameid, id->jname);
  1150. id->weight = atoi(str[6]);
  1151. #ifdef RENEWAL
  1152. itemdb_re_split_atoi(str[7],&id->atk,&id->matk);
  1153. #else
  1154. id->atk = atoi(str[7]);
  1155. #endif
  1156. id->def = atoi(str[8]);
  1157. id->range = atoi(str[9]);
  1158. id->slot = atoi(str[10]);
  1159. if (id->slot > MAX_SLOTS)
  1160. {
  1161. ShowWarning("itemdb_parse_dbrow: Item %hu (%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);
  1162. id->slot = MAX_SLOTS;
  1163. }
  1164. itemdb_jobid2mapid(id->class_base, (uint64)strtoull(str[11],NULL,0));
  1165. id->class_upper = atoi(str[12]);
  1166. id->sex = atoi(str[13]);
  1167. id->equip = atoi(str[14]);
  1168. if (!id->equip && itemdb_isequip2(id))
  1169. {
  1170. ShowWarning("Item %hu (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
  1171. id->type = IT_ETC;
  1172. }
  1173. if( id->type != IT_SHADOWGEAR && id->equip&EQP_SHADOW_GEAR )
  1174. {
  1175. ShowWarning("Item %hu (%s) have invalid equipment slot! Making it an etc item.\n", nameid, id->jname);
  1176. id->type = IT_ETC;
  1177. }
  1178. id->wlv = cap_value(atoi(str[15]), REFINE_TYPE_ARMOR, REFINE_TYPE_MAX);
  1179. itemdb_re_split_atoi(str[16],&id->elv,&id->elvmax);
  1180. id->flag.no_refine = atoi(str[17]) ? 0 : 1; //FIXME: verify this
  1181. id->look = atoi(str[18]);
  1182. id->flag.available = 1;
  1183. id->view_id = 0;
  1184. id->sex = itemdb_gendercheck(id); //Apply gender filtering.
  1185. if (id->script) {
  1186. script_free_code(id->script);
  1187. id->script = NULL;
  1188. }
  1189. if (id->equip_script) {
  1190. script_free_code(id->equip_script);
  1191. id->equip_script = NULL;
  1192. }
  1193. if (id->unequip_script) {
  1194. script_free_code(id->unequip_script);
  1195. id->unequip_script = NULL;
  1196. }
  1197. if (*str[19])
  1198. id->script = parse_script(str[19], source, line, scriptopt);
  1199. if (*str[20])
  1200. id->equip_script = parse_script(str[20], source, line, scriptopt);
  1201. if (*str[21])
  1202. id->unequip_script = parse_script(str[21], source, line, scriptopt);
  1203. if (!id->nameid) {
  1204. id->nameid = nameid;
  1205. uidb_put(itemdb, nameid, id);
  1206. }
  1207. return true;
  1208. }
  1209. /**
  1210. * Read item from item db
  1211. * item_db2 overwriting item_db
  1212. */
  1213. static int itemdb_readdb(void){
  1214. const char* filename[] = {
  1215. DBPATH"item_db.txt",
  1216. DBIMPORT"/item_db.txt"
  1217. };
  1218. int fi;
  1219. for( fi = 0; fi < ARRAYLENGTH(filename); ++fi ) {
  1220. uint32 lines = 0, count = 0;
  1221. char line[1024];
  1222. char path[256];
  1223. FILE* fp;
  1224. sprintf(path, "%s/%s", db_path, filename[fi]);
  1225. fp = fopen(path, "r");
  1226. if( fp == NULL ) {
  1227. ShowWarning("itemdb_readdb: File not found \"%s\", skipping.\n", path);
  1228. continue;
  1229. }
  1230. // process rows one by one
  1231. while(fgets(line, sizeof(line), fp))
  1232. {
  1233. char *str[32], *p;
  1234. int i;
  1235. lines++;
  1236. if(line[0] == '/' && line[1] == '/')
  1237. continue;
  1238. memset(str, 0, sizeof(str));
  1239. p = strstr(line,"//");
  1240. if( p != nullptr ){
  1241. *p = '\0';
  1242. }
  1243. p = line;
  1244. while( ISSPACE(*p) )
  1245. ++p;
  1246. if( *p == '\0' )
  1247. continue;// empty line
  1248. for( i = 0; i < 19; ++i )
  1249. {
  1250. str[i] = p;
  1251. p = strchr(p,',');
  1252. if( p == NULL )
  1253. break;// comma not found
  1254. *p = '\0';
  1255. ++p;
  1256. }
  1257. if( p == NULL )
  1258. {
  1259. ShowError("itemdb_readdb: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1260. continue;
  1261. }
  1262. // Script
  1263. if( *p != '{' )
  1264. {
  1265. ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1266. continue;
  1267. }
  1268. str[19] = p + 1;
  1269. p = strstr(p+1,"},");
  1270. if( p == NULL )
  1271. {
  1272. ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1273. continue;
  1274. }
  1275. *p = '\0';
  1276. p += 2;
  1277. // OnEquip_Script
  1278. if( *p != '{' )
  1279. {
  1280. ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1281. continue;
  1282. }
  1283. str[20] = p + 1;
  1284. p = strstr(p+1,"},");
  1285. if( p == NULL )
  1286. {
  1287. ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1288. continue;
  1289. }
  1290. *p = '\0';
  1291. p += 2;
  1292. // OnUnequip_Script (last column)
  1293. if( *p != '{' )
  1294. {
  1295. ShowError("itemdb_readdb: Invalid format (OnUnequip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1296. continue;
  1297. }
  1298. str[21] = p;
  1299. p = &str[21][strlen(str[21]) - 2];
  1300. if ( *p != '}' ) {
  1301. /* lets count to ensure it's not something silly e.g. a extra space at line ending */
  1302. int v, lcurly = 0, rcurly = 0;
  1303. for( v = 0; v < strlen(str[21]); v++ ) {
  1304. if( str[21][v] == '{' )
  1305. lcurly++;
  1306. else if (str[21][v] == '}') {
  1307. rcurly++;
  1308. p = &str[21][v];
  1309. }
  1310. }
  1311. if( lcurly != rcurly ) {
  1312. ShowError("itemdb_readdb: Mismatching curly braces in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1313. continue;
  1314. }
  1315. }
  1316. str[21] = str[21] + 1; //skip the first left curly
  1317. *p = '\0'; //null the last right curly
  1318. if (!itemdb_parse_dbrow(str, path, lines, SCRIPT_IGNORE_EXTERNAL_BRACKETS))
  1319. continue;
  1320. count++;
  1321. }
  1322. fclose(fp);
  1323. ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, path);
  1324. }
  1325. return 0;
  1326. }
  1327. /**
  1328. * Read item_db table
  1329. */
  1330. static int itemdb_read_sqldb(void) {
  1331. const char* item_db_name[] = {
  1332. item_table,
  1333. item2_table
  1334. };
  1335. int fi;
  1336. for( fi = 0; fi < ARRAYLENGTH(item_db_name); ++fi ) {
  1337. uint32 lines = 0, count = 0;
  1338. // retrieve all rows from the item database
  1339. if( SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", item_db_name[fi]) ) {
  1340. Sql_ShowDebug(mmysql_handle);
  1341. continue;
  1342. }
  1343. // process rows one by one
  1344. while( SQL_SUCCESS == Sql_NextRow(mmysql_handle) ) {// wrap the result into a TXT-compatible format
  1345. char* str[22];
  1346. char dummy[256] = "";
  1347. int i;
  1348. ++lines;
  1349. for( i = 0; i < 22; ++i ) {
  1350. Sql_GetData(mmysql_handle, i, &str[i], NULL);
  1351. if( str[i] == NULL )
  1352. str[i] = dummy; // get rid of NULL columns
  1353. }
  1354. if (!itemdb_parse_dbrow(str, item_db_name[fi], lines, SCRIPT_IGNORE_EXTERNAL_BRACKETS))
  1355. continue;
  1356. ++count;
  1357. }
  1358. // free the query result
  1359. Sql_FreeResult(mmysql_handle);
  1360. ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, item_db_name[fi]);
  1361. }
  1362. return 0;
  1363. }
  1364. /** Check if the item is restricted by item_noequip.txt
  1365. * @param id Item that will be checked
  1366. * @param m Map ID
  1367. * @return true: can't be used; false: can be used
  1368. */
  1369. bool itemdb_isNoEquip(struct item_data *id, uint16 m) {
  1370. if (!id->flag.no_equip)
  1371. return false;
  1372. struct map_data *mapdata = map_getmapdata(m);
  1373. if ((id->flag.no_equip&1 && !mapdata_flag_vs2(mapdata)) || // Normal
  1374. (id->flag.no_equip&2 && mapdata->flag[MF_PVP]) || // PVP
  1375. (id->flag.no_equip&4 && mapdata_flag_gvg2_no_te(mapdata)) || // GVG
  1376. (id->flag.no_equip&8 && mapdata->flag[MF_BATTLEGROUND]) || // Battleground
  1377. (id->flag.no_equip&16 && mapdata_flag_gvg2_te(mapdata)) || // WOE:TE
  1378. (id->flag.no_equip&(mapdata->zone) && mapdata->flag[MF_RESTRICTED]) // Zone restriction
  1379. )
  1380. return true;
  1381. return false;
  1382. }
  1383. /**
  1384. * Check if item is available in spellbook_db or not
  1385. * @param nameid
  1386. * @return True if item is spellbook; False if not
  1387. */
  1388. bool itemdb_is_spellbook2(unsigned short nameid) {
  1389. unsigned char i;
  1390. if (!nameid || !itemdb_exists(nameid) || !skill_spellbook_count)
  1391. return false;
  1392. ARR_FIND(0, MAX_SKILL_SPELLBOOK_DB, i, skill_spellbook_db[i].nameid == nameid);
  1393. return i == MAX_SKILL_SPELLBOOK_DB ? false : true;
  1394. }
  1395. /**
  1396. * Retrieves random option data
  1397. */
  1398. struct s_random_opt_data* itemdb_randomopt_exists(short id) {
  1399. return ((struct s_random_opt_data*)uidb_get(itemdb_randomopt, id));
  1400. }
  1401. /** Random option
  1402. * <ID>,<{Script}>
  1403. */
  1404. static bool itemdb_read_randomopt(const char* basedir, bool silent) {
  1405. uint32 lines = 0, count = 0;
  1406. char line[1024];
  1407. char path[256];
  1408. FILE* fp;
  1409. sprintf(path, "%s/%s", basedir, "item_randomopt_db.txt");
  1410. if ((fp = fopen(path, "r")) == NULL) {
  1411. if (silent == 0) ShowError("itemdb_read_randomopt: File not found \"%s\".\n", path);
  1412. return false;
  1413. }
  1414. while (fgets(line, sizeof(line), fp)) {
  1415. char *str[2], *p;
  1416. lines++;
  1417. if (line[0] == '/' && line[1] == '/') // Ignore comments
  1418. continue;
  1419. memset(str, 0, sizeof(str));
  1420. p = line;
  1421. p = trim(p);
  1422. if (*p == '\0')
  1423. continue;// empty line
  1424. if (!strchr(p, ','))
  1425. {
  1426. ShowError("itemdb_read_randomopt: Insufficient columns in line %d of \"%s\", skipping.\n", lines, path);
  1427. continue;
  1428. }
  1429. str[0] = p;
  1430. p = strchr(p, ',');
  1431. *p = '\0';
  1432. p++;
  1433. str[1] = p;
  1434. if (str[1][0] != '{') {
  1435. ShowError("itemdb_read_randomopt(#1): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
  1436. continue;
  1437. }
  1438. /* no ending key anywhere (missing \}\) */
  1439. if (str[1][strlen(str[1]) - 1] != '}') {
  1440. ShowError("itemdb_read_randomopt(#2): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
  1441. continue;
  1442. }
  1443. else {
  1444. int id = -1;
  1445. struct s_random_opt_data *data;
  1446. struct script_code *code;
  1447. str[0] = trim(str[0]);
  1448. if (ISDIGIT(str[0][0])) {
  1449. id = atoi(str[0]);
  1450. }
  1451. else {
  1452. script_get_constant(str[0], &id);
  1453. }
  1454. if (id < 0) {
  1455. ShowError("itemdb_read_randomopt: Invalid Random Option ID '%s' in line %d of \"%s\", skipping.\n", str[0], lines, path);
  1456. continue;
  1457. }
  1458. if ((data = itemdb_randomopt_exists(id)) == NULL) {
  1459. CREATE(data, struct s_random_opt_data, 1);
  1460. uidb_put(itemdb_randomopt, id, data);
  1461. }
  1462. data->id = id;
  1463. if ((code = parse_script(str[1], path, lines, 0)) == NULL) {
  1464. ShowWarning("itemdb_read_randomopt: Invalid script on option ID #%d.\n", id);
  1465. continue;
  1466. }
  1467. if (data->script) {
  1468. script_free_code(data->script);
  1469. data->script = NULL;
  1470. }
  1471. data->script = code;
  1472. }
  1473. count++;
  1474. }
  1475. fclose(fp);
  1476. ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, path);
  1477. return true;
  1478. }
  1479. /**
  1480. * Clear Item Random Option Group from memory
  1481. * @author [Cydh]
  1482. **/
  1483. static int itemdb_randomopt_group_free(DBKey key, DBData *data, va_list ap) {
  1484. struct s_random_opt_group *g = (struct s_random_opt_group *)db_data2ptr(data);
  1485. if (!g)
  1486. return 0;
  1487. if (g->entries)
  1488. aFree(g->entries);
  1489. g->entries = NULL;
  1490. aFree(g);
  1491. return 1;
  1492. }
  1493. /**
  1494. * Get Item Random Option Group from itemdb_randomopt_group MapDB
  1495. * @param id Random Option Group
  1496. * @return Random Option Group data or NULL if not found
  1497. * @author [Cydh]
  1498. **/
  1499. struct s_random_opt_group *itemdb_randomopt_group_exists(int id) {
  1500. return (struct s_random_opt_group *)uidb_get(itemdb_randomopt_group, id);
  1501. }
  1502. /**
  1503. * Read Item Random Option Group from db file
  1504. * @author [Cydh]
  1505. **/
  1506. static bool itemdb_read_randomopt_group(char* str[], int columns, int current) {
  1507. int id = 0, i;
  1508. unsigned short rate = (unsigned short)strtoul(str[1], NULL, 10);
  1509. struct s_random_opt_group *g = NULL;
  1510. if (!script_get_constant(str[0], &id)) {
  1511. ShowError("itemdb_read_randomopt_group: Invalid ID for Random Option Group '%s'.\n", str[0]);
  1512. return false;
  1513. }
  1514. if ((columns-2)%3 != 0) {
  1515. ShowError("itemdb_read_randomopt_group: Invalid column entries '%d'.\n", columns);
  1516. return false;
  1517. }
  1518. if (!(g = (struct s_random_opt_group *)uidb_get(itemdb_randomopt_group, id))) {
  1519. CREATE(g, struct s_random_opt_group, 1);
  1520. g->id = id;
  1521. g->total = 0;
  1522. g->entries = NULL;
  1523. uidb_put(itemdb_randomopt_group, g->id, g);
  1524. }
  1525. RECREATE(g->entries, struct s_random_opt_group_entry, g->total + rate);
  1526. for (i = g->total; i < (g->total + rate); i++) {
  1527. int j, k;
  1528. memset(&g->entries[i].option, 0, sizeof(g->entries[i].option));
  1529. for (j = 0, k = 2; k < columns && j < MAX_ITEM_RDM_OPT; k+=3) {
  1530. int randid = 0;
  1531. if (!script_get_constant(str[k], &randid) || !itemdb_randomopt_exists(randid)) {
  1532. ShowError("itemdb_read_randomopt_group: Invalid random group id '%s' in column %d!\n", str[k], k+1);
  1533. continue;
  1534. }
  1535. g->entries[i].option[j].id = randid;
  1536. g->entries[i].option[j].value = (short)strtoul(str[k+1], NULL, 10);
  1537. g->entries[i].option[j].param = (char)strtoul(str[k+2], NULL, 10);
  1538. j++;
  1539. }
  1540. }
  1541. g->total += rate;
  1542. return true;
  1543. }
  1544. /**
  1545. * Read all item-related databases
  1546. */
  1547. static void itemdb_read(void) {
  1548. int i;
  1549. const char* dbsubpath[] = {
  1550. "",
  1551. "/" DBIMPORT,
  1552. };
  1553. if (db_use_sqldbs)
  1554. itemdb_read_sqldb();
  1555. else
  1556. itemdb_readdb();
  1557. for(i=0; i<ARRAYLENGTH(dbsubpath); i++){
  1558. uint8 n1 = (uint8)(strlen(db_path)+strlen(dbsubpath[i])+1);
  1559. uint8 n2 = (uint8)(strlen(db_path)+strlen(DBPATH)+strlen(dbsubpath[i])+1);
  1560. char* dbsubpath1 = (char*)aMalloc(n1+1);
  1561. char* dbsubpath2 = (char*)aMalloc(n2+1);
  1562. if(i==0) {
  1563. safesnprintf(dbsubpath1,n1,"%s%s",db_path,dbsubpath[i]);
  1564. safesnprintf(dbsubpath2,n2,"%s/%s%s",db_path,DBPATH,dbsubpath[i]);
  1565. }
  1566. else {
  1567. safesnprintf(dbsubpath1,n1,"%s%s",db_path,dbsubpath[i]);
  1568. safesnprintf(dbsubpath2,n1,"%s%s",db_path,dbsubpath[i]);
  1569. }
  1570. sv_readdb(dbsubpath1, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail, i > 0);
  1571. sv_readdb(dbsubpath2, "item_stack.txt", ',', 3, 3, -1, &itemdb_read_stack, i > 0);
  1572. sv_readdb(dbsubpath1, "item_nouse.txt", ',', 3, 3, -1, &itemdb_read_nouse, i > 0);
  1573. sv_readdb(dbsubpath2, "item_group_db.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1574. sv_readdb(dbsubpath2, "item_bluebox.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1575. sv_readdb(dbsubpath2, "item_violetbox.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1576. sv_readdb(dbsubpath2, "item_cardalbum.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1577. sv_readdb(dbsubpath1, "item_findingore.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1578. sv_readdb(dbsubpath2, "item_giftbox.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1579. sv_readdb(dbsubpath2, "item_misc.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1580. #ifdef RENEWAL
  1581. sv_readdb(dbsubpath2, "item_package.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1582. #endif
  1583. itemdb_read_combos(dbsubpath2,i > 0); //TODO change this to sv_read ? id#script ?
  1584. itemdb_read_randomopt(dbsubpath2, i > 0);
  1585. sv_readdb(dbsubpath2, "item_noequip.txt", ',', 2, 2, -1, &itemdb_read_noequip, i > 0);
  1586. sv_readdb(dbsubpath2, "item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade, i > 0);
  1587. sv_readdb(dbsubpath2, "item_delay.txt", ',', 2, 3, -1, &itemdb_read_itemdelay, i > 0);
  1588. sv_readdb(dbsubpath2, "item_buyingstore.txt", ',', 1, 1, -1, &itemdb_read_buyingstore, i > 0);
  1589. sv_readdb(dbsubpath2, "item_flag.txt", ',', 2, 2, -1, &itemdb_read_flag, i > 0);
  1590. sv_readdb(dbsubpath2, "item_randomopt_group.txt", ',', 5, 2+5*MAX_ITEM_RDM_OPT, -1, &itemdb_read_randomopt_group, i > 0);
  1591. aFree(dbsubpath1);
  1592. aFree(dbsubpath2);
  1593. }
  1594. }
  1595. /*==========================================
  1596. * Initialize / Finalize
  1597. *------------------------------------------*/
  1598. /**
  1599. * Destroys the item_data.
  1600. */
  1601. static void destroy_item_data(struct item_data* self) {
  1602. if( self == NULL )
  1603. return;
  1604. // free scripts
  1605. if( self->script )
  1606. script_free_code(self->script);
  1607. if( self->equip_script )
  1608. script_free_code(self->equip_script);
  1609. if( self->unequip_script )
  1610. script_free_code(self->unequip_script);
  1611. if( self->combos_count ) {
  1612. int i;
  1613. for( i = 0; i < self->combos_count; i++ ) {
  1614. if( !self->combos[i]->isRef ) {
  1615. aFree(self->combos[i]->nameid);
  1616. if (self->combos[i]->script)
  1617. script_free_code(self->combos[i]->script);
  1618. }
  1619. aFree(self->combos[i]);
  1620. }
  1621. aFree(self->combos);
  1622. }
  1623. #if defined(DEBUG)
  1624. // trash item
  1625. memset(self, 0xDD, sizeof(struct item_data));
  1626. #endif
  1627. // free self
  1628. aFree(self);
  1629. }
  1630. /**
  1631. * @see DBApply
  1632. */
  1633. static int itemdb_final_sub(DBKey key, DBData *data, va_list ap)
  1634. {
  1635. struct item_data *id = (struct item_data *)db_data2ptr(data);
  1636. destroy_item_data(id);
  1637. return 0;
  1638. }
  1639. /** NOTE:
  1640. * In some OSs, like Raspbian, we aren't allowed to pass 0 in va_list.
  1641. * So, itemdb_group_free2 is useful in some cases.
  1642. * NB : We keeping that funciton cause that signature is needed for some iterator..
  1643. */
  1644. static int itemdb_group_free(DBKey key, DBData *data, va_list ap) {
  1645. return itemdb_group_free2(key,data);
  1646. }
  1647. /** (ARM)
  1648. * Adaptation of itemdb_group_free. This function enables to compile rAthena on Raspbian OS.
  1649. */
  1650. static inline int itemdb_group_free2(DBKey key, DBData *data) {
  1651. struct s_item_group_db *group = (struct s_item_group_db *)db_data2ptr(data);
  1652. uint8 j;
  1653. if (!group)
  1654. return 0;
  1655. if (group->must_qty)
  1656. aFree(group->must);
  1657. group->must_qty = 0;
  1658. for (j = 0; j < MAX_ITEMGROUP_RANDGROUP; j++) {
  1659. if (!group->random[j].data_qty || !(&group->random[j]))
  1660. continue;
  1661. aFree(group->random[j].data);
  1662. group->random[j].data_qty = 0;
  1663. }
  1664. aFree(group);
  1665. return 0;
  1666. }
  1667. static int itemdb_randomopt_free(DBKey key, DBData *data, va_list ap) {
  1668. struct s_random_opt_data *opt = (struct s_random_opt_data *)db_data2ptr(data);
  1669. if (!opt)
  1670. return 0;
  1671. if (opt->script)
  1672. script_free_code(opt->script);
  1673. opt->script = NULL;
  1674. aFree(opt);
  1675. return 1;
  1676. }
  1677. bool item_data::isStackable()
  1678. {
  1679. switch (this->type) {
  1680. case IT_WEAPON:
  1681. case IT_ARMOR:
  1682. case IT_PETEGG:
  1683. case IT_PETARMOR:
  1684. case IT_SHADOWGEAR:
  1685. return false;
  1686. }
  1687. return true;
  1688. }
  1689. int item_data::inventorySlotNeeded(int quantity)
  1690. {
  1691. return (this->flag.guid || !this->isStackable()) ? quantity : 1;
  1692. }
  1693. /**
  1694. * Reload Item DB
  1695. */
  1696. void itemdb_reload(void) {
  1697. struct s_mapiterator* iter;
  1698. struct map_session_data* sd;
  1699. itemdb_group->clear(itemdb_group, itemdb_group_free);
  1700. itemdb_randomopt->clear(itemdb_randomopt, itemdb_randomopt_free);
  1701. itemdb_randomopt_group->clear(itemdb_randomopt_group, itemdb_randomopt_group_free);
  1702. itemdb->clear(itemdb, itemdb_final_sub);
  1703. db_clear(itemdb_combo);
  1704. if (battle_config.feature_roulette)
  1705. itemdb_roulette_free();
  1706. // read new data
  1707. itemdb_read();
  1708. cashshop_reloaddb();
  1709. if (battle_config.feature_roulette)
  1710. itemdb_parse_roulette_db();
  1711. mob_reload_itemmob_data();
  1712. // readjust itemdb pointer cache for each player
  1713. iter = mapit_geteachpc();
  1714. for( sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data*)mapit_next(iter) ) {
  1715. memset(sd->item_delay, 0, sizeof(sd->item_delay)); // reset item delays
  1716. if( sd->combos.count ) { // clear combo bonuses
  1717. aFree(sd->combos.bonus);
  1718. aFree(sd->combos.id);
  1719. aFree(sd->combos.pos);
  1720. sd->combos.bonus = nullptr;
  1721. sd->combos.id = nullptr;
  1722. sd->combos.pos = nullptr;
  1723. sd->combos.count = 0;
  1724. }
  1725. pc_setinventorydata(sd);
  1726. pc_check_available_item(sd, ITMCHK_ALL); // Check for invalid(ated) items.
  1727. pc_load_combo(sd); // Check to see if new combos are available
  1728. status_calc_pc(sd, SCO_FORCE); //
  1729. }
  1730. mapit_free(iter);
  1731. }
  1732. /**
  1733. * Finalizing Item DB
  1734. */
  1735. void do_final_itemdb(void) {
  1736. db_destroy(itemdb_combo);
  1737. itemdb_group->destroy(itemdb_group, itemdb_group_free);
  1738. itemdb_randomopt->destroy(itemdb_randomopt, itemdb_randomopt_free);
  1739. itemdb_randomopt_group->destroy(itemdb_randomopt_group, itemdb_randomopt_group_free);
  1740. itemdb->destroy(itemdb, itemdb_final_sub);
  1741. destroy_item_data(dummy_item);
  1742. if (battle_config.feature_roulette)
  1743. itemdb_roulette_free();
  1744. }
  1745. /**
  1746. * Initializing Item DB
  1747. */
  1748. void do_init_itemdb(void) {
  1749. itemdb = uidb_alloc(DB_OPT_BASE);
  1750. itemdb_combo = uidb_alloc(DB_OPT_BASE);
  1751. itemdb_group = uidb_alloc(DB_OPT_BASE);
  1752. itemdb_randomopt = uidb_alloc(DB_OPT_BASE);
  1753. itemdb_randomopt_group = uidb_alloc(DB_OPT_BASE);
  1754. itemdb_create_dummy();
  1755. itemdb_read();
  1756. if (battle_config.feature_roulette)
  1757. itemdb_parse_roulette_db();
  1758. }