From 8da71a126d800c4b4d36ce8937491098925d27d2 Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Tue, 16 Aug 2016 11:14:33 +0700 Subject: [PATCH] * Fixed memory leaks from item random options, follow up f296409ada211a0aa89863db4d9603054845cf65 * Clean up doc and array index check for `getequiprandomoption`, `setrandomoption`, follow up 8deabb157ae9e58db86d0383c34dba7211780b6a * Exported CARD0_FORGE, CARD0_FORGE, and CARD0_PET for `getequipcardid` result. * Add `SCSTART_` references in `sc_start` doc. Signed-off-by: Cydh Ramdh --- doc/script_commands.txt | 21 +++++++++++---------- src/map/itemdb.c | 28 +++++++++++++++++++--------- src/map/script.c | 13 +++++++------ src/map/script_constants.h | 4 ++++ src/map/status.c | 4 +++- 5 files changed, 44 insertions(+), 26 deletions(-) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index b73105ec1c8..336c1a1ea08 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -2850,7 +2850,7 @@ See the sample in 'doc/sample/getiteminfo.txt'. Returns value from equipped item slot in the indicated slot (0, 1, 2, or 3). -This function returns CARD ID, 255,254,-255 (for card 0, if the item is produced). +This function returns CARD ID, CARD0_FORGE, CARD0_CREATE, or CARD0_PET (for card 0, if the item is produced). It's useful for when you want to check whether an item contains cards or if it's signed. --------------------------------------- @@ -5169,10 +5169,11 @@ This is used primarily in item scripts. When used in an NPC script, a flag MUST be defined for the rate to work. Optional value is how the status change start will be handled (a bitmask). - 1: Status change cannot be avoided. - 2: Tick cannot be reduced by stats (default). - 4: sc_data loaded, so no value will be altered. - 8: Rate cannot be reduced. + SCSTART_NOAVOID : Status change cannot be avoided. + SCSTART_NOTICKDEF : Tick cannot be reduced by stats (default). + SCSTART_LOADED : sc_data loaded, so no value will be altered. + SCSTART_NORATEDEF : Rate cannot be reduced. + SCSTART_NOICON : Status icon won't be sent to client If a is given, the status change will be invoked on the specified character instead of the one attached to the script. This can only be defined after setting @@ -9185,11 +9186,11 @@ This script command is intended for using in random option scripts. --------------------------------------- -*getequiprandomoption(,,{,}); +*getequiprandomoption(,,{,}); Returns value of an attribute of a random option on an equipped item. -For valid equipment indices, see `getequipid` command reference. +See 'getequipid' for a full list of valid equipment slots. index parameter can be 0 to MAX_ITEM_RDM_OPT-1 (default 0-4). @@ -9197,12 +9198,12 @@ For valid attribute types, see `getrandomoptinfo` command reference. --------------------------------------- -*setrandomoption(,,,,{,}); +*setrandomoption(,,,,{,}); -Sets th random option for equipment equipped at +Sets th random option for equipment equipped at to , and . -For valid equipment indices, see `getequipid` command reference. +See 'getequipid' for a full list of valid equipment slots. index parameter can be 0 to MAX_ITEM_RDM_OPT-1 (default 0-4). diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 86056428823..3b037f9be4e 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -1608,7 +1608,7 @@ static bool itemdb_read_randomopt(const char* basedir, bool silent) { continue; } else { - int id; + int id = -1; struct s_random_opt_data *data; struct script_code *code; @@ -1620,16 +1620,24 @@ static bool itemdb_read_randomopt(const char* basedir, bool silent) { script_get_constant(str[0], &id); } + if (id < 0) { + ShowError("itemdb_read_randomopt: Invalid Random Option ID '%s' in line %d of \"%s\", skipping.\n", str[0], lines, path); + continue; + } + if ((data = itemdb_randomopt_exists(id)) == NULL) { - data = malloc(sizeof(struct s_random_opt_data)); - memset(data, 0, sizeof(struct s_random_opt_data)); + CREATE(data, struct s_random_opt_data, 1); uidb_put(itemdb_randomopt, id, data); } data->id = id; - if ((code = parse_script(str[1], "item_randomopt_db.txt", 0, 0)) == NULL) { + if ((code = parse_script(str[1], path, lines, 0)) == NULL) { ShowWarning("itemdb_read_randomopt: Invalid script on option ID #%d.\n", id); continue; } + if (data->script) { + script_free_code(data->script); + data->script = NULL; + } data->script = code; } count++; @@ -1764,11 +1772,13 @@ static int itemdb_group_free(DBKey key, DBData *data, va_list ap) { } static int itemdb_randomopt_free(DBKey key, DBData *data, va_list ap) { - struct s_random_opt_data *opt = (struct s_random_opt_data *)db_data2ptr(data); - if (!opt) - return 0; - if (opt->script) - script_free_code(opt->script); + struct s_random_opt_data *opt = (struct s_random_opt_data *)db_data2ptr(data); + if (!opt) + return 0; + if (opt->script) + script_free_code(opt->script); + opt->script = NULL; + aFree(opt); return 1; } diff --git a/src/map/script.c b/src/map/script.c index 3ebcd6473aa..eed20473185 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -21538,7 +21538,7 @@ BUILDIN_FUNC(getrandomoptinfo) { struct map_session_data *sd; int val; int param = script_getnum(st, 2); - if ((sd = script_rid2sd(st)) != NULL && current_equip_item_index && current_equip_item_index > -1 && sd->status.inventory[current_equip_item_index].option[current_equip_opt_index].id) { + if ((sd = script_rid2sd(st)) != NULL && current_equip_item_index != -1 && current_equip_opt_index != -1 && sd->status.inventory[current_equip_item_index].option[current_equip_opt_index].id) { switch (param) { case ROA_ID: val = sd->status.inventory[current_equip_item_index].option[current_equip_opt_index].id; @@ -21564,7 +21564,7 @@ BUILDIN_FUNC(getrandomoptinfo) { /** * Retrieves a random option on an equipped item. -* getequiprandomoption(,,{,}); +* getequiprandomoption(,,{,}); * @author [secretdataz] */ BUILDIN_FUNC(getequiprandomoption) { @@ -21574,9 +21574,10 @@ BUILDIN_FUNC(getequiprandomoption) { int pos = script_getnum(st, 2); int index = script_getnum(st, 3); int type = script_getnum(st, 4); - if (!script_charid2sd(5, sd)) + if (!script_charid2sd(5, sd)) { script_pushint(st, -1); return SCRIPT_CMD_FAILURE; + } if (index < 0 || index >= MAX_ITEM_RDM_OPT) { ShowError("buildin_getequiprandomoption: Invalid random option index %d.\n", index); script_pushint(st, -1); @@ -21595,10 +21596,10 @@ BUILDIN_FUNC(getequiprandomoption) { val = sd->status.inventory[i].option[index].id; break; case ROA_VALUE: - val = sd->status.inventory[i].option->value; + val = sd->status.inventory[i].option[index].value; break; case ROA_PARAM: - val = sd->status.inventory[i].option->param; + val = sd->status.inventory[i].option[index].param; break; default: ShowWarning("buildin_getequiprandomoption: Invalid attribute type %d (Max %d).\n", type, MAX_ITEM_RDM_OPT); @@ -21612,7 +21613,7 @@ BUILDIN_FUNC(getequiprandomoption) { /** * Adds a random option on a random option slot on an equipped item and overwrites * existing random option in the process. -* setrandomoption(,,,,{,}); +* setrandomoption(,,,,{,}); * @author [secretdataz] */ BUILDIN_FUNC(setrandomoption) { diff --git a/src/map/script_constants.h b/src/map/script_constants.h index cfd6b71d70f..3f6d766d371 100644 --- a/src/map/script_constants.h +++ b/src/map/script_constants.h @@ -3123,6 +3123,10 @@ export_constant(ROA_VALUE); export_constant(ROA_PARAM); + export_constant(CARD0_FORGE); + export_constant(CARD0_CREATE); + export_constant(CARD0_PET); + #undef export_constant #endif /* _SCRIPT_CONSTANTS_H_ */ diff --git a/src/map/status.c b/src/map/status.c index f1c3fa6c516..4a7470c6b4b 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -3455,6 +3455,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) for (i = 0; i < EQI_MAX; i++) { current_equip_item_index = index = sd->equip_index[i]; current_equip_combo_pos = 0; + current_equip_opt_index = -1; + if (index < 0) continue; if (i == EQI_AMMO) @@ -3487,7 +3489,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) return 1; } } - current_equip_opt_index = 0; + current_equip_opt_index = -1; } if (sc->count && sc->data[SC_ITEMSCRIPT]) {