Przeglądaj źródła

* 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 <cydh@pservero.com>

Cydh Ramdh 8 lat temu
rodzic
commit
8da71a126d
5 zmienionych plików z 44 dodań i 26 usunięć
  1. 11 10
      doc/script_commands.txt
  2. 19 9
      src/map/itemdb.c
  3. 7 6
      src/map/script.c
  4. 4 0
      src/map/script_constants.h
  5. 3 1
      src/map/status.c

+ 11 - 10
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 <flag> 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 <GID> 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(<equipment indice>,<index>,<type>{,<char id>});
+*getequiprandomoption(<equipment index>,<index>,<type>{,<char id>});
 
 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(<equipment indice>,<index>,<id>,<value>,<param>{,<char id>});
+*setrandomoption(<equipment slot>,<index>,<id>,<value>,<param>{,<char id>});
 
-Sets <index+1>th random option for equipment equipped at <equipment indice>
+Sets <index+1>th random option for equipment equipped at <equipment slot>
 to <id>, <value> and <param>.
 
-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).
 

+ 19 - 9
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;
 }
 

+ 7 - 6
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(<equipment indice>,<index>,<type>{,<char id>});
+* getequiprandomoption(<equipment slot>,<index>,<type>{,<char id>});
 * @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(<equipment indice>,<index>,<id>,<value>,<param>{,<char id>});
+* setrandomoption(<equipment slot>,<index>,<id>,<value>,<param>{,<char id>});
 * @author [secretdataz]
 */
 BUILDIN_FUNC(setrandomoption) {

+ 4 - 0
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_ */

+ 3 - 1
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]) {