itemdb.cpp 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059
  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. switch(id->type) {
  449. case IT_WEAPON:
  450. case IT_ARMOR:
  451. case IT_PETEGG:
  452. case IT_PETARMOR:
  453. case IT_SHADOWGEAR:
  454. return false;
  455. default:
  456. return true;
  457. }
  458. }
  459. /*==========================================
  460. * Trade Restriction functions [Skotlex]
  461. *------------------------------------------*/
  462. bool itemdb_isdropable_sub(struct item_data *item, int gmlv, int unused) {
  463. return (item && (!(item->flag.trade_restriction&1) || gmlv >= item->gm_lv_trade_override));
  464. }
  465. bool itemdb_cantrade_sub(struct item_data* item, int gmlv, int gmlv2) {
  466. return (item && (!(item->flag.trade_restriction&2) || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
  467. }
  468. bool itemdb_canpartnertrade_sub(struct item_data* item, int gmlv, int gmlv2) {
  469. return (item && (item->flag.trade_restriction&4 || gmlv >= item->gm_lv_trade_override || gmlv2 >= item->gm_lv_trade_override));
  470. }
  471. bool itemdb_cansell_sub(struct item_data* item, int gmlv, int unused) {
  472. return (item && (!(item->flag.trade_restriction&8) || gmlv >= item->gm_lv_trade_override));
  473. }
  474. bool itemdb_cancartstore_sub(struct item_data* item, int gmlv, int unused) {
  475. return (item && (!(item->flag.trade_restriction&16) || gmlv >= item->gm_lv_trade_override));
  476. }
  477. bool itemdb_canstore_sub(struct item_data* item, int gmlv, int unused) {
  478. return (item && (!(item->flag.trade_restriction&32) || gmlv >= item->gm_lv_trade_override));
  479. }
  480. bool itemdb_canguildstore_sub(struct item_data* item, int gmlv, int unused) {
  481. return (item && (!(item->flag.trade_restriction&64) || gmlv >= item->gm_lv_trade_override));
  482. }
  483. bool itemdb_canmail_sub(struct item_data* item, int gmlv, int unused) {
  484. return (item && (!(item->flag.trade_restriction&128) || gmlv >= item->gm_lv_trade_override));
  485. }
  486. bool itemdb_canauction_sub(struct item_data* item, int gmlv, int unused) {
  487. return (item && (!(item->flag.trade_restriction&256) || gmlv >= item->gm_lv_trade_override));
  488. }
  489. bool itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, bool (*func)(struct item_data*, int, int))
  490. {
  491. struct item_data* item_data = itemdb_search(item->nameid);
  492. int i;
  493. if (!func(item_data, gmlv, gmlv2))
  494. return false;
  495. if(item_data->slot == 0 || itemdb_isspecial(item->card[0]))
  496. return true;
  497. for(i = 0; i < item_data->slot; i++) {
  498. if (!item->card[i]) continue;
  499. if (!func(itemdb_search(item->card[i]), gmlv, gmlv2))
  500. return false;
  501. }
  502. return true;
  503. }
  504. bool itemdb_ishatched_egg(struct item* item) {
  505. if (item && item->card[0] == CARD0_PET && item->attribute == 1)
  506. return true;
  507. return false;
  508. }
  509. /** Specifies if item-type should drop unidentified.
  510. * @param nameid ID of item
  511. */
  512. char itemdb_isidentified(unsigned short nameid) {
  513. int type=itemdb_type(nameid);
  514. switch (type) {
  515. case IT_WEAPON:
  516. case IT_ARMOR:
  517. case IT_PETARMOR:
  518. case IT_SHADOWGEAR:
  519. return 0;
  520. default:
  521. return 1;
  522. }
  523. }
  524. /** Search by name for the override flags available items (Give item another sprite)
  525. * Structure: <nameid>,<sprite>
  526. */
  527. static bool itemdb_read_itemavail(char* str[], int columns, int current) {
  528. unsigned short nameid, sprite;
  529. struct item_data *id;
  530. nameid = atoi(str[0]);
  531. if( ( id = itemdb_exists(nameid) ) == NULL )
  532. {
  533. ShowWarning("itemdb_read_itemavail: Invalid item id %hu.\n", nameid);
  534. return false;
  535. }
  536. sprite = atoi(str[1]);
  537. if( sprite > 0 )
  538. {
  539. id->flag.available = 1;
  540. id->view_id = sprite;
  541. }
  542. else
  543. {
  544. id->flag.available = 0;
  545. }
  546. return true;
  547. }
  548. static int itemdb_group_free(DBKey key, DBData *data, va_list ap);
  549. static int itemdb_group_free2(DBKey key, DBData *data);
  550. static bool itemdb_read_group(char* str[], int columns, int current) {
  551. int group_id = -1;
  552. unsigned int j, prob = 1;
  553. uint8 rand_group = 1;
  554. struct s_item_group_random *random = NULL;
  555. struct s_item_group_db *group = NULL;
  556. struct s_item_group_entry entry;
  557. memset(&entry, 0, sizeof(entry));
  558. entry.amount = 1;
  559. entry.bound = BOUND_NONE;
  560. str[0] = trim(str[0]);
  561. if( ISDIGIT(str[0][0]) ){
  562. group_id = atoi(str[0]);
  563. }else{
  564. // Try to parse group id as constant
  565. script_get_constant(str[0], &group_id);
  566. }
  567. // Check the group id
  568. if( group_id < 0 ){
  569. ShowWarning( "itemdb_read_group: Invalid group ID '%s'\n", str[0] );
  570. return false;
  571. }
  572. // Remove from DB
  573. if( strcmpi( str[1], "clear" ) == 0 ){
  574. DBData data;
  575. if( itemdb_group->remove( itemdb_group, db_ui2key(group_id), &data ) ){
  576. itemdb_group_free2(db_ui2key(group_id), &data);
  577. ShowNotice( "itemdb_read_group: Item Group '%s' has been cleared.\n", str[0] );
  578. return true;
  579. }else{
  580. ShowWarning( "itemdb_read_group: Item Group '%s' has not been cleared, because it did not exist.\n", str[0] );
  581. return false;
  582. }
  583. }
  584. if( columns < 3 ){
  585. ShowError("itemdb_read_group: Insufficient columns (found %d, need at least 3).\n", columns);
  586. return false;
  587. }
  588. // Checking sub group
  589. prob = atoi(str[2]);
  590. if( columns > 4 ){
  591. rand_group = atoi(str[4]);
  592. if( rand_group < 0 || rand_group > MAX_ITEMGROUP_RANDGROUP ){
  593. ShowWarning( "itemdb_read_group: Invalid sub group '%d' for group '%s'\n", rand_group, str[0] );
  594. return false;
  595. }
  596. }else{
  597. rand_group = 1;
  598. }
  599. if( rand_group != 0 && prob < 1 ){
  600. ShowWarning( "itemdb_read_group: Random item must have a probability. Group '%s'\n", str[0] );
  601. return false;
  602. }
  603. // Check item
  604. str[1] = trim(str[1]);
  605. // Check if the item can be found by id
  606. if( ( entry.nameid = atoi(str[1]) ) <= 0 || !itemdb_exists( entry.nameid ) ){
  607. // Otherwise look it up by name
  608. struct item_data *id = itemdb_searchname(str[1]);
  609. if( id ){
  610. // Found the item with a name lookup
  611. entry.nameid = id->nameid;
  612. }else{
  613. ShowWarning( "itemdb_read_group: Non-existant item '%s'\n", str[1] );
  614. return false;
  615. }
  616. }
  617. if( columns > 3 ) entry.amount = cap_value(atoi(str[3]),1,MAX_AMOUNT);
  618. if( columns > 5 ) entry.isAnnounced= atoi(str[5]) > 0;
  619. if( columns > 6 ) entry.duration = cap_value(atoi(str[6]),0,UINT16_MAX);
  620. if( columns > 7 ) entry.GUID = atoi(str[7]) > 0;
  621. if( columns > 8 ) entry.bound = cap_value(atoi(str[8]),BOUND_NONE,BOUND_MAX-1);
  622. if( columns > 9 ) entry.isNamed = atoi(str[9]) > 0;
  623. if (!(group = (struct s_item_group_db *) uidb_get(itemdb_group, group_id))) {
  624. CREATE(group, struct s_item_group_db, 1);
  625. group->id = group_id;
  626. uidb_put(itemdb_group, group->id, group);
  627. }
  628. // Must item (rand_group == 0), place it here
  629. if (!rand_group) {
  630. RECREATE(group->must, struct s_item_group_entry, group->must_qty+1);
  631. group->must[group->must_qty++] = entry;
  632. // If 'must' item isn't set as random item, skip the next process
  633. if (!prob) {
  634. return true;
  635. }
  636. rand_group = 0;
  637. }
  638. else
  639. rand_group -= 1;
  640. random = &group->random[rand_group];
  641. RECREATE(random->data, struct s_item_group_entry, random->data_qty+prob);
  642. // Put the entry to its rand_group
  643. for (j = random->data_qty; j < random->data_qty+prob; j++)
  644. random->data[j] = entry;
  645. random->data_qty += prob;
  646. return true;
  647. }
  648. /** Read item forbidden by mapflag (can't equip item)
  649. * Structure: <nameid>,<mode>
  650. */
  651. static bool itemdb_read_noequip(char* str[], int columns, int current) {
  652. unsigned short nameid;
  653. int flag;
  654. struct item_data *id;
  655. nameid = atoi(str[0]);
  656. flag = atoi(str[1]);
  657. if( ( id = itemdb_exists(nameid) ) == NULL )
  658. {
  659. ShowWarning("itemdb_read_noequip: Invalid item id %hu.\n", nameid);
  660. return false;
  661. }
  662. if (flag >= 0)
  663. id->flag.no_equip |= flag;
  664. else
  665. id->flag.no_equip &= ~abs(flag);
  666. return true;
  667. }
  668. /** Reads item trade restrictions [Skotlex]
  669. * Structure: <nameid>,<mask>,<gm level>
  670. */
  671. static bool itemdb_read_itemtrade(char* str[], int columns, int current) {
  672. unsigned short nameid, flag, gmlv;
  673. struct item_data *id;
  674. nameid = atoi(str[0]);
  675. if( ( id = itemdb_exists(nameid) ) == NULL )
  676. {
  677. //ShowWarning("itemdb_read_itemtrade: Invalid item id %d.\n", nameid);
  678. //return false;
  679. // FIXME: item_trade.txt contains items, which are commented in item database.
  680. return true;
  681. }
  682. flag = atoi(str[1]);
  683. gmlv = atoi(str[2]);
  684. if( flag > 511 ) {//Check range
  685. ShowWarning("itemdb_read_itemtrade: Invalid trading mask %hu for item id %hu.\n", flag, nameid);
  686. return false;
  687. }
  688. if( gmlv < 1 )
  689. {
  690. ShowWarning("itemdb_read_itemtrade: Invalid override GM level %hu for item id %hu.\n", gmlv, nameid);
  691. return false;
  692. }
  693. id->flag.trade_restriction = flag;
  694. id->gm_lv_trade_override = gmlv;
  695. return true;
  696. }
  697. /** Reads item delay amounts [Paradox924X]
  698. * Structure: <nameid>,<delay>{,<delay sc group>}
  699. */
  700. static bool itemdb_read_itemdelay(char* str[], int columns, int current) {
  701. unsigned short nameid;
  702. int delay;
  703. struct item_data *id;
  704. nameid = atoi(str[0]);
  705. if( ( id = itemdb_exists(nameid) ) == NULL )
  706. {
  707. ShowWarning("itemdb_read_itemdelay: Invalid item id %hu.\n", nameid);
  708. return false;
  709. }
  710. delay = atoi(str[1]);
  711. if( delay < 0 )
  712. {
  713. ShowWarning("itemdb_read_itemdelay: Invalid delay %d for item id %hu.\n", delay, nameid);
  714. return false;
  715. }
  716. id->delay = delay;
  717. if (columns == 2)
  718. id->delay_sc = SC_NONE;
  719. else if( ISDIGIT(str[2][0]) )
  720. id->delay_sc = atoi(str[2]);
  721. else{ // Try read sc group id from const db
  722. int constant;
  723. if( !script_get_constant(trim(str[2]), &constant) ){
  724. ShowWarning("itemdb_read_itemdelay: Invalid sc group \"%s\" for item id %hu.\n", str[2], nameid);
  725. return false;
  726. }
  727. id->delay_sc = (short)constant;
  728. }
  729. return true;
  730. }
  731. /** Reads item stacking restrictions
  732. * Structure: <item id>,<stack limit amount>,<type>
  733. */
  734. static bool itemdb_read_stack(char* fields[], int columns, int current) {
  735. unsigned short nameid, amount;
  736. unsigned int type;
  737. struct item_data* id;
  738. nameid = (unsigned short)strtoul(fields[0], NULL, 10);
  739. if( ( id = itemdb_exists(nameid) ) == NULL )
  740. {
  741. ShowWarning("itemdb_read_stack: Unknown item id '%hu'.\n", nameid);
  742. return false;
  743. }
  744. if( !itemdb_isstackable2(id) )
  745. {
  746. ShowWarning("itemdb_read_stack: Item id '%hu' is not stackable.\n", nameid);
  747. return false;
  748. }
  749. amount = (unsigned short)strtoul(fields[1], NULL, 10);
  750. type = strtoul(fields[2], NULL, 10);
  751. if( !amount )
  752. {// ignore
  753. return true;
  754. }
  755. id->stack.amount = amount;
  756. id->stack.inventory = (type&1)!=0;
  757. id->stack.cart = (type&2)!=0;
  758. id->stack.storage = (type&4)!=0;
  759. id->stack.guildstorage = (type&8)!=0;
  760. return true;
  761. }
  762. /** Reads items allowed to be sold in buying stores
  763. * <nameid>
  764. */
  765. static bool itemdb_read_buyingstore(char* fields[], int columns, int current) {
  766. unsigned short nameid;
  767. struct item_data* id;
  768. nameid = atoi(fields[0]);
  769. if( ( id = itemdb_exists(nameid) ) == NULL )
  770. {
  771. ShowWarning("itemdb_read_buyingstore: Invalid item id %hu.\n", nameid);
  772. return false;
  773. }
  774. if( !itemdb_isstackable2(id) )
  775. {
  776. ShowWarning("itemdb_read_buyingstore: Non-stackable item id %hu cannot be enabled for buying store.\n", nameid);
  777. return false;
  778. }
  779. id->flag.buyingstore = true;
  780. return true;
  781. }
  782. /** Item usage restriction (item_nouse.txt)
  783. * <nameid>,<flag>,<override>
  784. */
  785. static bool itemdb_read_nouse(char* fields[], int columns, int current) {
  786. unsigned short nameid, flag, override;
  787. struct item_data* id;
  788. nameid = atoi(fields[0]);
  789. if( ( id = itemdb_exists(nameid) ) == NULL ) {
  790. ShowWarning("itemdb_read_nouse: Invalid item id %hu.\n", nameid);
  791. return false;
  792. }
  793. flag = atoi(fields[1]);
  794. override = atoi(fields[2]);
  795. id->item_usage.flag = flag;
  796. id->item_usage.override = override;
  797. return true;
  798. }
  799. /** Misc Item flags
  800. * <item_id>,<flag>
  801. * &1 - As dead branch item
  802. * &2 - As item container
  803. * &4 - GUID item, cannot be stacked even same or stackable item
  804. */
  805. static bool itemdb_read_flag(char* fields[], int columns, int current) {
  806. unsigned short nameid = atoi(fields[0]);
  807. uint16 flag;
  808. bool set;
  809. struct item_data *id;
  810. if (!(id = itemdb_exists(nameid))) {
  811. ShowError("itemdb_read_flag: Invalid item id %hu\n", nameid);
  812. return true;
  813. }
  814. flag = abs(atoi(fields[1]));
  815. set = atoi(fields[1]) > 0;
  816. if (flag&1) id->flag.dead_branch = set ? 1 : 0;
  817. if (flag&2) id->flag.group = set ? 1 : 0;
  818. if (flag&4 && itemdb_isstackable2(id)) id->flag.guid = set ? 1 : 0;
  819. if (flag&8) id->flag.bindOnEquip = true;
  820. if (flag&16) id->flag.broadcast = 1;
  821. if (flag&32) id->flag.delay_consume = 2;
  822. if( flag & 64 ){
  823. id->flag.dropEffect = 1;
  824. }else if( flag & 128 ){
  825. id->flag.dropEffect = 2;
  826. }else if( flag & 256 ){
  827. id->flag.dropEffect = 3;
  828. }else if( flag & 512 ){
  829. id->flag.dropEffect = 4;
  830. }else if( flag & 1024 ){
  831. id->flag.dropEffect = 5;
  832. }else if( flag & 2048 ){
  833. id->flag.dropEffect = 6;
  834. }
  835. return true;
  836. }
  837. /**
  838. * @return: amount of retrieved entries.
  839. **/
  840. static int itemdb_combo_split_atoi (char *str, int *val) {
  841. int i;
  842. for (i=0; i<MAX_ITEMS_PER_COMBO; i++) {
  843. if (!str) break;
  844. val[i] = atoi(str);
  845. str = strchr(str,':');
  846. if (str)
  847. *str++=0;
  848. }
  849. if( i == 0 ) //No data found.
  850. return 0;
  851. return i;
  852. }
  853. /**
  854. * <combo{:combo{:combo:{..}}}>,<{ script }>
  855. **/
  856. static void itemdb_read_combos(const char* basedir, bool silent) {
  857. uint32 lines = 0, count = 0;
  858. char line[1024];
  859. char path[256];
  860. FILE* fp;
  861. sprintf(path, "%s/%s", basedir, "item_combo_db.txt");
  862. if ((fp = fopen(path, "r")) == NULL) {
  863. if(silent==0) ShowError("itemdb_read_combos: File not found \"%s\".\n", path);
  864. return;
  865. }
  866. // process rows one by one
  867. while(fgets(line, sizeof(line), fp)) {
  868. char *str[2], *p;
  869. lines++;
  870. if (line[0] == '/' && line[1] == '/')
  871. continue;
  872. memset(str, 0, sizeof(str));
  873. p = line;
  874. p = trim(p);
  875. if (*p == '\0')
  876. continue;// empty line
  877. if (!strchr(p,','))
  878. {
  879. /* is there even a single column? */
  880. ShowError("itemdb_read_combos: Insufficient columns in line %d of \"%s\", skipping.\n", lines, path);
  881. continue;
  882. }
  883. str[0] = p;
  884. p = strchr(p,',');
  885. *p = '\0';
  886. p++;
  887. str[1] = p;
  888. p = strchr(p,',');
  889. p++;
  890. if (str[1][0] != '{') {
  891. ShowError("itemdb_read_combos(#1): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
  892. continue;
  893. }
  894. /* no ending key anywhere (missing \}\) */
  895. if ( str[1][strlen(str[1])-1] != '}' ) {
  896. ShowError("itemdb_read_combos(#2): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
  897. continue;
  898. } else {
  899. int items[MAX_ITEMS_PER_COMBO];
  900. int v = 0, retcount = 0;
  901. struct item_data * id = NULL;
  902. int idx = 0;
  903. if((retcount = itemdb_combo_split_atoi(str[0], items)) < 2) {
  904. ShowError("itemdb_read_combos: line %d of \"%s\" doesn't have enough items to make for a combo (min:2), skipping.\n", lines, path);
  905. continue;
  906. }
  907. /* validate */
  908. for(v = 0; v < retcount; v++) {
  909. if( !itemdb_exists(items[v]) ) {
  910. ShowError("itemdb_read_combos: line %d of \"%s\" contains unknown item ID %d, skipping.\n", lines, path,items[v]);
  911. break;
  912. }
  913. }
  914. /* failed at some item */
  915. if( v < retcount )
  916. continue;
  917. id = itemdb_exists(items[0]);
  918. idx = id->combos_count;
  919. /* first entry, create */
  920. if( id->combos == NULL ) {
  921. CREATE(id->combos, struct item_combo*, 1);
  922. id->combos_count = 1;
  923. } else {
  924. RECREATE(id->combos, struct item_combo*, ++id->combos_count);
  925. }
  926. CREATE(id->combos[idx],struct item_combo,1);
  927. id->combos[idx]->nameid = (unsigned short*)aMalloc( retcount * sizeof(unsigned short) );
  928. id->combos[idx]->count = retcount;
  929. id->combos[idx]->script = parse_script(str[1], path, lines, 0);
  930. id->combos[idx]->id = count;
  931. id->combos[idx]->isRef = false;
  932. /* populate ->nameid field */
  933. for( v = 0; v < retcount; v++ ) {
  934. id->combos[idx]->nameid[v] = items[v];
  935. }
  936. /* populate the children to refer to this combo */
  937. for( v = 1; v < retcount; v++ ) {
  938. struct item_data * it;
  939. int index;
  940. it = itemdb_exists(items[v]);
  941. index = it->combos_count;
  942. if( it->combos == NULL ) {
  943. CREATE(it->combos, struct item_combo*, 1);
  944. it->combos_count = 1;
  945. } else {
  946. RECREATE(it->combos, struct item_combo*, ++it->combos_count);
  947. }
  948. CREATE(it->combos[index],struct item_combo,1);
  949. /* we copy previously alloc'd pointers and just set it to reference */
  950. memcpy(it->combos[index],id->combos[idx],sizeof(struct item_combo));
  951. /* we flag this way to ensure we don't double-dealloc same data */
  952. it->combos[index]->isRef = true;
  953. }
  954. uidb_put(itemdb_combo,id->combos[idx]->id,id->combos[idx]);
  955. }
  956. count++;
  957. }
  958. fclose(fp);
  959. ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n",count,path);
  960. return;
  961. }
  962. /**
  963. * Process Roulette items
  964. */
  965. bool itemdb_parse_roulette_db(void)
  966. {
  967. int i, j;
  968. uint32 count = 0;
  969. // retrieve all rows from the item database
  970. if (SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", roulette_table)) {
  971. Sql_ShowDebug(mmysql_handle);
  972. return false;
  973. }
  974. for (i = 0; i < MAX_ROULETTE_LEVEL; i++)
  975. rd.items[i] = 0;
  976. for (i = 0; i < MAX_ROULETTE_LEVEL; i++) {
  977. int k, limit = MAX_ROULETTE_COLUMNS - i;
  978. for (k = 0; k < limit && SQL_SUCCESS == Sql_NextRow(mmysql_handle); k++) {
  979. char* data;
  980. unsigned short item_id, amount;
  981. int level, flag;
  982. Sql_GetData(mmysql_handle, 1, &data, NULL); level = atoi(data);
  983. Sql_GetData(mmysql_handle, 2, &data, NULL); item_id = atoi(data);
  984. Sql_GetData(mmysql_handle, 3, &data, NULL); amount = atoi(data);
  985. Sql_GetData(mmysql_handle, 4, &data, NULL); flag = atoi(data);
  986. if (!itemdb_exists(item_id)) {
  987. ShowWarning("itemdb_parse_roulette_db: Unknown item ID '%hu' in level '%d'\n", item_id, level);
  988. continue;
  989. }
  990. if (amount < 1 || amount > MAX_AMOUNT){
  991. ShowWarning("itemdb_parse_roulette_db: Unsupported amount '%hu' for item ID '%hu' in level '%d'\n", amount, item_id, level);
  992. continue;
  993. }
  994. if (flag < 0 || flag > 1) {
  995. ShowWarning("itemdb_parse_roulette_db: Unsupported flag '%d' for item ID '%hu' in level '%d'\n", flag, item_id, level);
  996. continue;
  997. }
  998. j = rd.items[i];
  999. RECREATE(rd.nameid[i], unsigned short, ++rd.items[i]);
  1000. RECREATE(rd.qty[i], unsigned short, rd.items[i]);
  1001. RECREATE(rd.flag[i], int, rd.items[i]);
  1002. rd.nameid[i][j] = item_id;
  1003. rd.qty[i][j] = amount;
  1004. rd.flag[i][j] = flag;
  1005. ++count;
  1006. }
  1007. }
  1008. // free the query result
  1009. Sql_FreeResult(mmysql_handle);
  1010. for (i = 0; i < MAX_ROULETTE_LEVEL; i++) {
  1011. int limit = MAX_ROULETTE_COLUMNS - i;
  1012. if (rd.items[i] == limit)
  1013. continue;
  1014. if (rd.items[i] > limit) {
  1015. ShowWarning("itemdb_parse_roulette_db: level %d has %d items, only %d supported, capping...\n", i + 1, rd.items[i], limit);
  1016. rd.items[i] = limit;
  1017. continue;
  1018. }
  1019. /** this scenario = rd.items[i] < limit **/
  1020. ShowWarning("itemdb_parse_roulette_db: Level %d has %d items, %d are required. Filling with Apples...\n", i + 1, rd.items[i], limit);
  1021. rd.items[i] = limit;
  1022. RECREATE(rd.nameid[i], unsigned short, rd.items[i]);
  1023. RECREATE(rd.qty[i], unsigned short, rd.items[i]);
  1024. RECREATE(rd.flag[i], int, rd.items[i]);
  1025. for (j = 0; j < MAX_ROULETTE_COLUMNS - i; j++) {
  1026. if (rd.qty[i][j])
  1027. continue;
  1028. rd.nameid[i][j] = ITEMID_APPLE;
  1029. rd.qty[i][j] = 1;
  1030. rd.flag[i][j] = 0;
  1031. }
  1032. }
  1033. ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, roulette_table);
  1034. return true;
  1035. }
  1036. /**
  1037. * Free Roulette items
  1038. */
  1039. static void itemdb_roulette_free(void) {
  1040. int i;
  1041. for (i = 0; i < MAX_ROULETTE_LEVEL; i++) {
  1042. if (rd.nameid[i])
  1043. aFree(rd.nameid[i]);
  1044. if (rd.qty[i])
  1045. aFree(rd.qty[i]);
  1046. if (rd.flag[i])
  1047. aFree(rd.flag[i]);
  1048. rd.nameid[i] = NULL;
  1049. rd.qty[i] = NULL;
  1050. rd.flag[i] = NULL;
  1051. rd.items[i] = 0;
  1052. }
  1053. }
  1054. /*======================================
  1055. * Applies gender restrictions according to settings. [Skotlex]
  1056. *======================================*/
  1057. static char itemdb_gendercheck(struct item_data *id)
  1058. {
  1059. if (id->nameid == WEDDING_RING_M) //Grom Ring
  1060. return 1;
  1061. if (id->nameid == WEDDING_RING_F) //Bride Ring
  1062. return 0;
  1063. if (id->look == W_MUSICAL && id->type == IT_WEAPON) //Musical instruments are always male-only
  1064. return 1;
  1065. if (id->look == W_WHIP && id->type == IT_WEAPON) //Whips are always female-only
  1066. return 0;
  1067. return (battle_config.ignore_items_gender) ? 2 : id->sex;
  1068. }
  1069. /**
  1070. * [RRInd]
  1071. * For backwards compatibility, in Renewal mode, MATK from weapons comes from the atk slot
  1072. * We use a ':' delimiter which, if not found, assumes the weapon does not provide any matk.
  1073. **/
  1074. static void itemdb_re_split_atoi(char *str, int *val1, int *val2) {
  1075. int i, val[2];
  1076. for (i=0; i<2; i++) {
  1077. if (!str) break;
  1078. val[i] = atoi(str);
  1079. str = strchr(str,':');
  1080. if (str)
  1081. *str++=0;
  1082. }
  1083. if( i == 0 ) {
  1084. *val1 = *val2 = 0;
  1085. return;//no data found
  1086. }
  1087. if( i == 1 ) {//Single Value
  1088. *val1 = val[0];
  1089. *val2 = 0;
  1090. return;
  1091. }
  1092. //We assume we have 2 values.
  1093. *val1 = val[0];
  1094. *val2 = val[1];
  1095. return;
  1096. }
  1097. /**
  1098. * Processes one itemdb entry
  1099. */
  1100. static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt) {
  1101. /*
  1102. +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
  1103. | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
  1104. +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
  1105. | 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 |
  1106. +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
  1107. */
  1108. unsigned short nameid;
  1109. struct item_data* id;
  1110. if( atoi(str[0]) <= 0 || atoi(str[0]) >= MAX_ITEMID || atoi(str[0]) == dummy_item->nameid )
  1111. {
  1112. ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", atoi(str[0]), line, source);
  1113. return false;
  1114. }
  1115. nameid = atoi(str[0]);
  1116. //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
  1117. if (!(id = itemdb_exists(nameid))) {
  1118. // Checks if the Itemname is already taken by another id
  1119. if( itemdb_searchname1(str[1], true) != NULL )
  1120. ShowWarning("itemdb_parse_dbrow: Duplicate item name for \"%s\"\n", str[1]);
  1121. // Adds a new Item ID
  1122. id = itemdb_create_item(nameid);
  1123. }
  1124. safestrncpy(id->name, str[1], sizeof(id->name));
  1125. safestrncpy(id->jname, str[2], sizeof(id->jname));
  1126. id->type = atoi(str[3]);
  1127. if( id->type < 0 || id->type == IT_UNKNOWN || id->type == IT_UNKNOWN2 || ( id->type > IT_SHADOWGEAR && id->type < IT_CASH ) || id->type >= IT_MAX )
  1128. {// catch invalid item types
  1129. ShowWarning("itemdb_parse_dbrow: Invalid item type %d for item %hu. IT_ETC will be used.\n", id->type, nameid);
  1130. id->type = IT_ETC;
  1131. }
  1132. if (id->type == IT_DELAYCONSUME)
  1133. { //Items that are consumed only after target confirmation
  1134. id->type = IT_USABLE;
  1135. id->flag.delay_consume = 1;
  1136. } else //In case of an itemdb reload and the item type changed.
  1137. id->flag.delay_consume = 0;
  1138. //When a particular price is not given, we should base it off the other one
  1139. //(it is important to make a distinction between 'no price' and 0z)
  1140. if ( str[4][0] )
  1141. id->value_buy = atoi(str[4]);
  1142. else
  1143. id->value_buy = atoi(str[5]) * 2;
  1144. if ( str[5][0] )
  1145. id->value_sell = atoi(str[5]);
  1146. else
  1147. id->value_sell = id->value_buy / 2;
  1148. /*
  1149. if ( !str[4][0] && !str[5][0])
  1150. {
  1151. ShowWarning("itemdb_parse_dbrow: No buying/selling price defined for item %hu (%s), using 20/10z\n", nameid, id->jname);
  1152. id->value_buy = 20;
  1153. id->value_sell = 10;
  1154. } else
  1155. */
  1156. if (id->value_buy/124. < id->value_sell/75.)
  1157. 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",
  1158. id->value_buy, id->value_sell, nameid, id->jname);
  1159. id->weight = atoi(str[6]);
  1160. #ifdef RENEWAL
  1161. itemdb_re_split_atoi(str[7],&id->atk,&id->matk);
  1162. #else
  1163. id->atk = atoi(str[7]);
  1164. #endif
  1165. id->def = atoi(str[8]);
  1166. id->range = atoi(str[9]);
  1167. id->slot = atoi(str[10]);
  1168. if (id->slot > MAX_SLOTS)
  1169. {
  1170. 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);
  1171. id->slot = MAX_SLOTS;
  1172. }
  1173. itemdb_jobid2mapid(id->class_base, (uint64)strtoull(str[11],NULL,0));
  1174. id->class_upper = atoi(str[12]);
  1175. id->sex = atoi(str[13]);
  1176. id->equip = atoi(str[14]);
  1177. if (!id->equip && itemdb_isequip2(id))
  1178. {
  1179. ShowWarning("Item %hu (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
  1180. id->type = IT_ETC;
  1181. }
  1182. if( id->type != IT_SHADOWGEAR && id->equip&EQP_SHADOW_GEAR )
  1183. {
  1184. ShowWarning("Item %hu (%s) have invalid equipment slot! Making it an etc item.\n", nameid, id->jname);
  1185. id->type = IT_ETC;
  1186. }
  1187. id->wlv = cap_value(atoi(str[15]), REFINE_TYPE_ARMOR, REFINE_TYPE_MAX);
  1188. itemdb_re_split_atoi(str[16],&id->elv,&id->elvmax);
  1189. id->flag.no_refine = atoi(str[17]) ? 0 : 1; //FIXME: verify this
  1190. id->look = atoi(str[18]);
  1191. id->flag.available = 1;
  1192. id->view_id = 0;
  1193. id->sex = itemdb_gendercheck(id); //Apply gender filtering.
  1194. if (id->script) {
  1195. script_free_code(id->script);
  1196. id->script = NULL;
  1197. }
  1198. if (id->equip_script) {
  1199. script_free_code(id->equip_script);
  1200. id->equip_script = NULL;
  1201. }
  1202. if (id->unequip_script) {
  1203. script_free_code(id->unequip_script);
  1204. id->unequip_script = NULL;
  1205. }
  1206. if (*str[19])
  1207. id->script = parse_script(str[19], source, line, scriptopt);
  1208. if (*str[20])
  1209. id->equip_script = parse_script(str[20], source, line, scriptopt);
  1210. if (*str[21])
  1211. id->unequip_script = parse_script(str[21], source, line, scriptopt);
  1212. if (!id->nameid) {
  1213. id->nameid = nameid;
  1214. uidb_put(itemdb, nameid, id);
  1215. }
  1216. return true;
  1217. }
  1218. /**
  1219. * Read item from item db
  1220. * item_db2 overwriting item_db
  1221. */
  1222. static int itemdb_readdb(void){
  1223. const char* filename[] = {
  1224. DBPATH"item_db.txt",
  1225. DBIMPORT"/item_db.txt"
  1226. };
  1227. int fi;
  1228. for( fi = 0; fi < ARRAYLENGTH(filename); ++fi ) {
  1229. uint32 lines = 0, count = 0;
  1230. char line[1024];
  1231. char path[256];
  1232. FILE* fp;
  1233. sprintf(path, "%s/%s", db_path, filename[fi]);
  1234. fp = fopen(path, "r");
  1235. if( fp == NULL ) {
  1236. ShowWarning("itemdb_readdb: File not found \"%s\", skipping.\n", path);
  1237. continue;
  1238. }
  1239. // process rows one by one
  1240. while(fgets(line, sizeof(line), fp))
  1241. {
  1242. char *str[32], *p;
  1243. int i;
  1244. lines++;
  1245. if(line[0] == '/' && line[1] == '/')
  1246. continue;
  1247. memset(str, 0, sizeof(str));
  1248. p = strstr(line,"//");
  1249. if( p != nullptr ){
  1250. *p = '\0';
  1251. }
  1252. p = line;
  1253. while( ISSPACE(*p) )
  1254. ++p;
  1255. if( *p == '\0' )
  1256. continue;// empty line
  1257. for( i = 0; i < 19; ++i )
  1258. {
  1259. str[i] = p;
  1260. p = strchr(p,',');
  1261. if( p == NULL )
  1262. break;// comma not found
  1263. *p = '\0';
  1264. ++p;
  1265. }
  1266. if( p == NULL )
  1267. {
  1268. ShowError("itemdb_readdb: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1269. continue;
  1270. }
  1271. // Script
  1272. if( *p != '{' )
  1273. {
  1274. ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1275. continue;
  1276. }
  1277. str[19] = p + 1;
  1278. p = strstr(p+1,"},");
  1279. if( p == NULL )
  1280. {
  1281. ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1282. continue;
  1283. }
  1284. *p = '\0';
  1285. p += 2;
  1286. // OnEquip_Script
  1287. if( *p != '{' )
  1288. {
  1289. ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1290. continue;
  1291. }
  1292. str[20] = p + 1;
  1293. p = strstr(p+1,"},");
  1294. if( p == NULL )
  1295. {
  1296. ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1297. continue;
  1298. }
  1299. *p = '\0';
  1300. p += 2;
  1301. // OnUnequip_Script (last column)
  1302. if( *p != '{' )
  1303. {
  1304. ShowError("itemdb_readdb: Invalid format (OnUnequip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1305. continue;
  1306. }
  1307. str[21] = p;
  1308. p = &str[21][strlen(str[21]) - 2];
  1309. if ( *p != '}' ) {
  1310. /* lets count to ensure it's not something silly e.g. a extra space at line ending */
  1311. int v, lcurly = 0, rcurly = 0;
  1312. for( v = 0; v < strlen(str[21]); v++ ) {
  1313. if( str[21][v] == '{' )
  1314. lcurly++;
  1315. else if (str[21][v] == '}') {
  1316. rcurly++;
  1317. p = &str[21][v];
  1318. }
  1319. }
  1320. if( lcurly != rcurly ) {
  1321. ShowError("itemdb_readdb: Mismatching curly braces in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi(str[0]));
  1322. continue;
  1323. }
  1324. }
  1325. str[21] = str[21] + 1; //skip the first left curly
  1326. *p = '\0'; //null the last right curly
  1327. if (!itemdb_parse_dbrow(str, path, lines, SCRIPT_IGNORE_EXTERNAL_BRACKETS))
  1328. continue;
  1329. count++;
  1330. }
  1331. fclose(fp);
  1332. ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, path);
  1333. }
  1334. return 0;
  1335. }
  1336. /**
  1337. * Read item_db table
  1338. */
  1339. static int itemdb_read_sqldb(void) {
  1340. const char* item_db_name[] = {
  1341. item_table,
  1342. item2_table
  1343. };
  1344. int fi;
  1345. for( fi = 0; fi < ARRAYLENGTH(item_db_name); ++fi ) {
  1346. uint32 lines = 0, count = 0;
  1347. // retrieve all rows from the item database
  1348. if( SQL_ERROR == Sql_Query(mmysql_handle, "SELECT * FROM `%s`", item_db_name[fi]) ) {
  1349. Sql_ShowDebug(mmysql_handle);
  1350. continue;
  1351. }
  1352. // process rows one by one
  1353. while( SQL_SUCCESS == Sql_NextRow(mmysql_handle) ) {// wrap the result into a TXT-compatible format
  1354. char* str[22];
  1355. char dummy[256] = "";
  1356. int i;
  1357. ++lines;
  1358. for( i = 0; i < 22; ++i ) {
  1359. Sql_GetData(mmysql_handle, i, &str[i], NULL);
  1360. if( str[i] == NULL )
  1361. str[i] = dummy; // get rid of NULL columns
  1362. }
  1363. if (!itemdb_parse_dbrow(str, item_db_name[fi], lines, SCRIPT_IGNORE_EXTERNAL_BRACKETS))
  1364. continue;
  1365. ++count;
  1366. }
  1367. // free the query result
  1368. Sql_FreeResult(mmysql_handle);
  1369. ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, item_db_name[fi]);
  1370. }
  1371. return 0;
  1372. }
  1373. /** Check if the item is restricted by item_noequip.txt
  1374. * @param id Item that will be checked
  1375. * @param m Map ID
  1376. * @return true: can't be used; false: can be used
  1377. */
  1378. bool itemdb_isNoEquip(struct item_data *id, uint16 m) {
  1379. if (!id->flag.no_equip)
  1380. return false;
  1381. struct map_data *mapdata = map_getmapdata(m);
  1382. if ((id->flag.no_equip&1 && !mapdata_flag_vs2(mapdata)) || // Normal
  1383. (id->flag.no_equip&2 && mapdata->flag[MF_PVP]) || // PVP
  1384. (id->flag.no_equip&4 && mapdata_flag_gvg2_no_te(mapdata)) || // GVG
  1385. (id->flag.no_equip&8 && mapdata->flag[MF_BATTLEGROUND]) || // Battleground
  1386. (id->flag.no_equip&16 && mapdata_flag_gvg2_te(mapdata)) || // WOE:TE
  1387. (id->flag.no_equip&(mapdata->zone) && mapdata->flag[MF_RESTRICTED]) // Zone restriction
  1388. )
  1389. return true;
  1390. return false;
  1391. }
  1392. /**
  1393. * Check if item is available in spellbook_db or not
  1394. * @param nameid
  1395. * @return True if item is spellbook; False if not
  1396. */
  1397. bool itemdb_is_spellbook2(unsigned short nameid) {
  1398. unsigned char i;
  1399. if (!nameid || !itemdb_exists(nameid) || !skill_spellbook_count)
  1400. return false;
  1401. ARR_FIND(0, MAX_SKILL_SPELLBOOK_DB, i, skill_spellbook_db[i].nameid == nameid);
  1402. return i == MAX_SKILL_SPELLBOOK_DB ? false : true;
  1403. }
  1404. /**
  1405. * Retrieves random option data
  1406. */
  1407. struct s_random_opt_data* itemdb_randomopt_exists(short id) {
  1408. return ((struct s_random_opt_data*)uidb_get(itemdb_randomopt, id));
  1409. }
  1410. /** Random option
  1411. * <ID>,<{Script}>
  1412. */
  1413. static bool itemdb_read_randomopt(const char* basedir, bool silent) {
  1414. uint32 lines = 0, count = 0;
  1415. char line[1024];
  1416. char path[256];
  1417. FILE* fp;
  1418. sprintf(path, "%s/%s", basedir, "item_randomopt_db.txt");
  1419. if ((fp = fopen(path, "r")) == NULL) {
  1420. if (silent == 0) ShowError("itemdb_read_randomopt: File not found \"%s\".\n", path);
  1421. return false;
  1422. }
  1423. while (fgets(line, sizeof(line), fp)) {
  1424. char *str[2], *p;
  1425. lines++;
  1426. if (line[0] == '/' && line[1] == '/') // Ignore comments
  1427. continue;
  1428. memset(str, 0, sizeof(str));
  1429. p = line;
  1430. p = trim(p);
  1431. if (*p == '\0')
  1432. continue;// empty line
  1433. if (!strchr(p, ','))
  1434. {
  1435. ShowError("itemdb_read_randomopt: Insufficient columns in line %d of \"%s\", skipping.\n", lines, path);
  1436. continue;
  1437. }
  1438. str[0] = p;
  1439. p = strchr(p, ',');
  1440. *p = '\0';
  1441. p++;
  1442. str[1] = p;
  1443. if (str[1][0] != '{') {
  1444. ShowError("itemdb_read_randomopt(#1): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
  1445. continue;
  1446. }
  1447. /* no ending key anywhere (missing \}\) */
  1448. if (str[1][strlen(str[1]) - 1] != '}') {
  1449. ShowError("itemdb_read_randomopt(#2): Invalid format (Script column) in line %d of \"%s\", skipping.\n", lines, path);
  1450. continue;
  1451. }
  1452. else {
  1453. int id = -1;
  1454. struct s_random_opt_data *data;
  1455. struct script_code *code;
  1456. str[0] = trim(str[0]);
  1457. if (ISDIGIT(str[0][0])) {
  1458. id = atoi(str[0]);
  1459. }
  1460. else {
  1461. script_get_constant(str[0], &id);
  1462. }
  1463. if (id < 0) {
  1464. ShowError("itemdb_read_randomopt: Invalid Random Option ID '%s' in line %d of \"%s\", skipping.\n", str[0], lines, path);
  1465. continue;
  1466. }
  1467. if ((data = itemdb_randomopt_exists(id)) == NULL) {
  1468. CREATE(data, struct s_random_opt_data, 1);
  1469. uidb_put(itemdb_randomopt, id, data);
  1470. }
  1471. data->id = id;
  1472. if ((code = parse_script(str[1], path, lines, 0)) == NULL) {
  1473. ShowWarning("itemdb_read_randomopt: Invalid script on option ID #%d.\n", id);
  1474. continue;
  1475. }
  1476. if (data->script) {
  1477. script_free_code(data->script);
  1478. data->script = NULL;
  1479. }
  1480. data->script = code;
  1481. }
  1482. count++;
  1483. }
  1484. fclose(fp);
  1485. ShowStatus("Done reading '" CL_WHITE "%u" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, path);
  1486. return true;
  1487. }
  1488. /**
  1489. * Clear Item Random Option Group from memory
  1490. * @author [Cydh]
  1491. **/
  1492. static int itemdb_randomopt_group_free(DBKey key, DBData *data, va_list ap) {
  1493. struct s_random_opt_group *g = (struct s_random_opt_group *)db_data2ptr(data);
  1494. if (!g)
  1495. return 0;
  1496. if (g->entries)
  1497. aFree(g->entries);
  1498. g->entries = NULL;
  1499. aFree(g);
  1500. return 1;
  1501. }
  1502. /**
  1503. * Get Item Random Option Group from itemdb_randomopt_group MapDB
  1504. * @param id Random Option Group
  1505. * @return Random Option Group data or NULL if not found
  1506. * @author [Cydh]
  1507. **/
  1508. struct s_random_opt_group *itemdb_randomopt_group_exists(int id) {
  1509. return (struct s_random_opt_group *)uidb_get(itemdb_randomopt_group, id);
  1510. }
  1511. /**
  1512. * Read Item Random Option Group from db file
  1513. * @author [Cydh]
  1514. **/
  1515. static bool itemdb_read_randomopt_group(char* str[], int columns, int current) {
  1516. int id = 0, i;
  1517. unsigned short rate = (unsigned short)strtoul(str[1], NULL, 10);
  1518. struct s_random_opt_group *g = NULL;
  1519. if (!script_get_constant(str[0], &id)) {
  1520. ShowError("itemdb_read_randomopt_group: Invalid ID for Random Option Group '%s'.\n", str[0]);
  1521. return false;
  1522. }
  1523. if ((columns-2)%3 != 0) {
  1524. ShowError("itemdb_read_randomopt_group: Invalid column entries '%d'.\n", columns);
  1525. return false;
  1526. }
  1527. if (!(g = (struct s_random_opt_group *)uidb_get(itemdb_randomopt_group, id))) {
  1528. CREATE(g, struct s_random_opt_group, 1);
  1529. g->id = id;
  1530. g->total = 0;
  1531. g->entries = NULL;
  1532. uidb_put(itemdb_randomopt_group, g->id, g);
  1533. }
  1534. RECREATE(g->entries, struct s_random_opt_group_entry, g->total + rate);
  1535. for (i = g->total; i < (g->total + rate); i++) {
  1536. int j, k;
  1537. memset(&g->entries[i].option, 0, sizeof(g->entries[i].option));
  1538. for (j = 0, k = 2; k < columns && j < MAX_ITEM_RDM_OPT; k+=3) {
  1539. int randid = 0;
  1540. if (!script_get_constant(str[k], &randid) || !itemdb_randomopt_exists(randid)) {
  1541. ShowError("itemdb_read_randomopt_group: Invalid random group id '%s' in column %d!\n", str[k], k+1);
  1542. continue;
  1543. }
  1544. g->entries[i].option[j].id = randid;
  1545. g->entries[i].option[j].value = (short)strtoul(str[k+1], NULL, 10);
  1546. g->entries[i].option[j].param = (char)strtoul(str[k+2], NULL, 10);
  1547. j++;
  1548. }
  1549. }
  1550. g->total += rate;
  1551. return true;
  1552. }
  1553. /**
  1554. * Read all item-related databases
  1555. */
  1556. static void itemdb_read(void) {
  1557. int i;
  1558. const char* dbsubpath[] = {
  1559. "",
  1560. "/" DBIMPORT,
  1561. };
  1562. if (db_use_sqldbs)
  1563. itemdb_read_sqldb();
  1564. else
  1565. itemdb_readdb();
  1566. for(i=0; i<ARRAYLENGTH(dbsubpath); i++){
  1567. uint8 n1 = (uint8)(strlen(db_path)+strlen(dbsubpath[i])+1);
  1568. uint8 n2 = (uint8)(strlen(db_path)+strlen(DBPATH)+strlen(dbsubpath[i])+1);
  1569. char* dbsubpath1 = (char*)aMalloc(n1+1);
  1570. char* dbsubpath2 = (char*)aMalloc(n2+1);
  1571. if(i==0) {
  1572. safesnprintf(dbsubpath1,n1,"%s%s",db_path,dbsubpath[i]);
  1573. safesnprintf(dbsubpath2,n2,"%s/%s%s",db_path,DBPATH,dbsubpath[i]);
  1574. }
  1575. else {
  1576. safesnprintf(dbsubpath1,n1,"%s%s",db_path,dbsubpath[i]);
  1577. safesnprintf(dbsubpath2,n1,"%s%s",db_path,dbsubpath[i]);
  1578. }
  1579. sv_readdb(dbsubpath1, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail, i > 0);
  1580. sv_readdb(dbsubpath2, "item_stack.txt", ',', 3, 3, -1, &itemdb_read_stack, i > 0);
  1581. sv_readdb(dbsubpath1, "item_nouse.txt", ',', 3, 3, -1, &itemdb_read_nouse, i > 0);
  1582. sv_readdb(dbsubpath2, "item_group_db.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1583. sv_readdb(dbsubpath2, "item_bluebox.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1584. sv_readdb(dbsubpath2, "item_violetbox.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1585. sv_readdb(dbsubpath2, "item_cardalbum.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1586. sv_readdb(dbsubpath1, "item_findingore.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1587. sv_readdb(dbsubpath2, "item_giftbox.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1588. sv_readdb(dbsubpath2, "item_misc.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1589. #ifdef RENEWAL
  1590. sv_readdb(dbsubpath2, "item_package.txt", ',', 2, 10, -1, &itemdb_read_group, i > 0);
  1591. #endif
  1592. itemdb_read_combos(dbsubpath2,i > 0); //TODO change this to sv_read ? id#script ?
  1593. itemdb_read_randomopt(dbsubpath2, i > 0);
  1594. sv_readdb(dbsubpath2, "item_noequip.txt", ',', 2, 2, -1, &itemdb_read_noequip, i > 0);
  1595. sv_readdb(dbsubpath2, "item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade, i > 0);
  1596. sv_readdb(dbsubpath2, "item_delay.txt", ',', 2, 3, -1, &itemdb_read_itemdelay, i > 0);
  1597. sv_readdb(dbsubpath2, "item_buyingstore.txt", ',', 1, 1, -1, &itemdb_read_buyingstore, i > 0);
  1598. sv_readdb(dbsubpath2, "item_flag.txt", ',', 2, 2, -1, &itemdb_read_flag, i > 0);
  1599. sv_readdb(dbsubpath2, "item_randomopt_group.txt", ',', 5, 2+5*MAX_ITEM_RDM_OPT, -1, &itemdb_read_randomopt_group, i > 0);
  1600. aFree(dbsubpath1);
  1601. aFree(dbsubpath2);
  1602. }
  1603. }
  1604. /*==========================================
  1605. * Initialize / Finalize
  1606. *------------------------------------------*/
  1607. /**
  1608. * Destroys the item_data.
  1609. */
  1610. static void destroy_item_data(struct item_data* self) {
  1611. if( self == NULL )
  1612. return;
  1613. // free scripts
  1614. if( self->script )
  1615. script_free_code(self->script);
  1616. if( self->equip_script )
  1617. script_free_code(self->equip_script);
  1618. if( self->unequip_script )
  1619. script_free_code(self->unequip_script);
  1620. if( self->combos_count ) {
  1621. int i;
  1622. for( i = 0; i < self->combos_count; i++ ) {
  1623. if( !self->combos[i]->isRef ) {
  1624. aFree(self->combos[i]->nameid);
  1625. if (self->combos[i]->script)
  1626. script_free_code(self->combos[i]->script);
  1627. }
  1628. aFree(self->combos[i]);
  1629. }
  1630. aFree(self->combos);
  1631. }
  1632. #if defined(DEBUG)
  1633. // trash item
  1634. memset(self, 0xDD, sizeof(struct item_data));
  1635. #endif
  1636. // free self
  1637. aFree(self);
  1638. }
  1639. /**
  1640. * @see DBApply
  1641. */
  1642. static int itemdb_final_sub(DBKey key, DBData *data, va_list ap)
  1643. {
  1644. struct item_data *id = (struct item_data *)db_data2ptr(data);
  1645. destroy_item_data(id);
  1646. return 0;
  1647. }
  1648. /** NOTE:
  1649. * In some OSs, like Raspbian, we aren't allowed to pass 0 in va_list.
  1650. * So, itemdb_group_free2 is useful in some cases.
  1651. * NB : We keeping that funciton cause that signature is needed for some iterator..
  1652. */
  1653. static int itemdb_group_free(DBKey key, DBData *data, va_list ap) {
  1654. return itemdb_group_free2(key,data);
  1655. }
  1656. /** (ARM)
  1657. * Adaptation of itemdb_group_free. This function enables to compile rAthena on Raspbian OS.
  1658. */
  1659. static inline int itemdb_group_free2(DBKey key, DBData *data) {
  1660. struct s_item_group_db *group = (struct s_item_group_db *)db_data2ptr(data);
  1661. uint8 j;
  1662. if (!group)
  1663. return 0;
  1664. if (group->must_qty)
  1665. aFree(group->must);
  1666. group->must_qty = 0;
  1667. for (j = 0; j < MAX_ITEMGROUP_RANDGROUP; j++) {
  1668. if (!group->random[j].data_qty || !(&group->random[j]))
  1669. continue;
  1670. aFree(group->random[j].data);
  1671. group->random[j].data_qty = 0;
  1672. }
  1673. aFree(group);
  1674. return 0;
  1675. }
  1676. static int itemdb_randomopt_free(DBKey key, DBData *data, va_list ap) {
  1677. struct s_random_opt_data *opt = (struct s_random_opt_data *)db_data2ptr(data);
  1678. if (!opt)
  1679. return 0;
  1680. if (opt->script)
  1681. script_free_code(opt->script);
  1682. opt->script = NULL;
  1683. aFree(opt);
  1684. return 1;
  1685. }
  1686. /**
  1687. * Reload Item DB
  1688. */
  1689. void itemdb_reload(void) {
  1690. struct s_mapiterator* iter;
  1691. struct map_session_data* sd;
  1692. itemdb_group->clear(itemdb_group, itemdb_group_free);
  1693. itemdb_randomopt->clear(itemdb_randomopt, itemdb_randomopt_free);
  1694. itemdb_randomopt_group->clear(itemdb_randomopt_group, itemdb_randomopt_group_free);
  1695. itemdb->clear(itemdb, itemdb_final_sub);
  1696. db_clear(itemdb_combo);
  1697. if (battle_config.feature_roulette)
  1698. itemdb_roulette_free();
  1699. // read new data
  1700. itemdb_read();
  1701. cashshop_reloaddb();
  1702. if (battle_config.feature_roulette)
  1703. itemdb_parse_roulette_db();
  1704. mob_reload_itemmob_data();
  1705. // readjust itemdb pointer cache for each player
  1706. iter = mapit_geteachpc();
  1707. for( sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data*)mapit_next(iter) ) {
  1708. memset(sd->item_delay, 0, sizeof(sd->item_delay)); // reset item delays
  1709. if( sd->combos.count ) { // clear combo bonuses
  1710. aFree(sd->combos.bonus);
  1711. aFree(sd->combos.id);
  1712. aFree(sd->combos.pos);
  1713. sd->combos.bonus = nullptr;
  1714. sd->combos.id = nullptr;
  1715. sd->combos.pos = nullptr;
  1716. sd->combos.count = 0;
  1717. }
  1718. pc_setinventorydata(sd);
  1719. pc_check_available_item(sd, ITMCHK_ALL); // Check for invalid(ated) items.
  1720. pc_load_combo(sd); // Check to see if new combos are available
  1721. status_calc_pc(sd, SCO_FORCE); //
  1722. }
  1723. mapit_free(iter);
  1724. }
  1725. /**
  1726. * Finalizing Item DB
  1727. */
  1728. void do_final_itemdb(void) {
  1729. db_destroy(itemdb_combo);
  1730. itemdb_group->destroy(itemdb_group, itemdb_group_free);
  1731. itemdb_randomopt->destroy(itemdb_randomopt, itemdb_randomopt_free);
  1732. itemdb_randomopt_group->destroy(itemdb_randomopt_group, itemdb_randomopt_group_free);
  1733. itemdb->destroy(itemdb, itemdb_final_sub);
  1734. destroy_item_data(dummy_item);
  1735. if (battle_config.feature_roulette)
  1736. itemdb_roulette_free();
  1737. }
  1738. /**
  1739. * Initializing Item DB
  1740. */
  1741. void do_init_itemdb(void) {
  1742. itemdb = uidb_alloc(DB_OPT_BASE);
  1743. itemdb_combo = uidb_alloc(DB_OPT_BASE);
  1744. itemdb_group = uidb_alloc(DB_OPT_BASE);
  1745. itemdb_randomopt = uidb_alloc(DB_OPT_BASE);
  1746. itemdb_randomopt_group = uidb_alloc(DB_OPT_BASE);
  1747. itemdb_create_dummy();
  1748. itemdb_read();
  1749. if (battle_config.feature_roulette)
  1750. itemdb_parse_roulette_db();
  1751. }