From 00570591031eb6fc99c7c26ba58a2a7efb144e7f Mon Sep 17 00:00:00 2001 From: Haru Date: Mon, 5 Sep 2016 00:04:37 +0200 Subject: Reimplement getiteminfo/setiteminfo in a safer and more maintainable way Signed-off-by: Haru --- src/map/itemdb.h | 3 - src/map/script.c | 171 ++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 113 insertions(+), 61 deletions(-) (limited to 'src/map') diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 35cd154cb..0ab6ef65b 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -454,7 +454,6 @@ struct item_data { uint16 nameid; char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH]; - //Do not add stuff between value_buy and view_id (see how getiteminfo works) int value_buy; int value_sell; int type; @@ -474,8 +473,6 @@ struct item_data { int elvmax;/* maximum level for this item */ int delay; -//Lupus: I rearranged order of these fields due to compatibility with ITEMINFO script command -// some script commands should be revised as well... uint64 class_base[3]; ///< Specifies if the base can wear this item (split in 3 indexes per type: 1-1, 2-1, 2-2) unsigned class_upper : 6; ///< Specifies if the upper-type can equip it (bitfield, 0x01: normal, 0x02: upper, 0x04: baby normal, 0x08: third normal, 0x10: third upper, 0x20: third baby) struct { diff --git a/src/map/script.c b/src/map/script.c index ff6263b4b..914bee75c 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -13982,43 +13982,70 @@ BUILDIN(getitemslots) return true; } -// TODO: add matk here if needed/once we get rid of RENEWAL +// TODO: add matk here if needed /*========================================== * Returns some values of an item [Lupus] * Price, Weight, etc... - * getiteminfo(itemID,n), where n - * 0 value_buy; - * 1 value_sell; - * 2 type; - * 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc.. - * if = 0, then monsters don't drop it at all (rare or a quest item) - * if = -1, then this item is sold in NPC shops only - * 4 sex; - * 5 equip; - * 6 weight; - * 7 atk; - * 8 def; - * 9 range; - * 10 slot; - * 11 look; - * 12 elv; - * 13 wlv; - * 14 view id *------------------------------------------*/ BUILDIN(getiteminfo) { - int item_id,n; - struct item_data *i_data; + int item_id = script_getnum(st, 2); + int n = script_getnum(st, 3); + struct item_data *it = itemdb->exists(item_id); - item_id = script_getnum(st,2); - n = script_getnum(st,3); - i_data = itemdb->exists(item_id); + if (it == NULL) { + script_pushint(st, -1); + return true; + } - if (i_data && n>=0 && n<=14) { - int *item_arr = (int*)&i_data->value_buy; - script_pushint(st,item_arr[n]); - } else { + switch (n) { + case 0: + script_pushint(st, it->value_buy); + break; + case 1: + script_pushint(st, it->value_sell); + break; + case 2: + script_pushint(st, it->type); + break; + case 3: + script_pushint(st, it->maxchance); + break; + case 4: + script_pushint(st, it->sex); + break; + case 5: + script_pushint(st, it->equip); + break; + case 6: + script_pushint(st, it->weight); + break; + case 7: + script_pushint(st, it->atk); + break; + case 8: + script_pushint(st, it->def); + break; + case 9: + script_pushint(st, it->range); + break; + case 10: + script_pushint(st, it->slot); + break; + case 11: + script_pushint(st, it->look); + break; + case 12: + script_pushint(st, it->elv); + break; + case 13: + script_pushint(st, it->wlv); + break; + case 14: + script_pushint(st, it->view_id); + break; + default: script_pushint(st,-1); } return true; @@ -14211,43 +14238,71 @@ BUILDIN(setequipoption) /*========================================== * Set some values of an item [Lupus] * Price, Weight, etc... - * setiteminfo(itemID,n,Value), where n - * 0 value_buy; - * 1 value_sell; - * 2 type; - * 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc.. - * if = 0, then monsters don't drop it at all (rare or a quest item) - * if = -1, then this item is sold in NPC shops only - * 4 sex; - * 5 equip; - * 6 weight; - * 7 atk; - * 8 def; - * 9 range; - * 10 slot; - * 11 look; - * 12 elv; - * 13 wlv; - * 14 view id - * Returns Value or -1 if the wrong field's been set *------------------------------------------*/ BUILDIN(setiteminfo) { - int item_id,n,value; - struct item_data *i_data; + // TODO: Validate data in a similar way as during database load + int item_id = script_getnum(st, 2); + int n = script_getnum(st, 3); + int value = script_getnum(st,4); + struct item_data *it = itemdb->exists(item_id); - item_id = script_getnum(st,2); - n = script_getnum(st,3); - value = script_getnum(st,4); - i_data = itemdb->exists(item_id); + if (it == NULL) { + script_pushint(st, -1); + return true; + } - if (i_data && n>=0 && n<=14) { - int *item_arr = (int*)&i_data->value_buy; - item_arr[n] = value; - script_pushint(st,value); - } else { + switch (n) { + case 0: + it->value_buy = value; + break; + case 1: + it->value_sell = value; + break; + case 2: + it->type = value; + break; + case 3: + it->maxchance = value; + break; + case 4: + it->sex = value; + break; + case 5: + it->equip = value; + break; + case 6: + it->weight = value; + break; + case 7: + it->atk = value; + break; + case 8: + it->def = value; + break; + case 9: + it->range = value; + break; + case 10: + it->slot = value; + break; + case 11: + it->look = value; + break; + case 12: + it->elv = value; + break; + case 13: + it->wlv = value; + break; + case 14: + it->view_id = value; + break; + default: script_pushint(st,-1); + return true; } + script_pushint(st,value); return true; } -- cgit v1.2.3-60-g2f50