OSDN Git Service

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