Browse Source

Adjusts a few checks for item tradability (#4995)

* Follow up to bfb6972.
* Adds a new return array for script command inventorylist: `@inventorylist_tradable`
* Adjusts script command countitem to not count rental items.
Aleos 5 years ago
parent
commit
7cc59c6708
4 changed files with 28 additions and 10 deletions
  1. 3 1
      doc/script_commands.txt
  2. 18 0
      src/map/pc.cpp
  3. 1 0
      src/map/pc.hpp
  4. 6 9
      src/map/script.cpp

+ 3 - 1
doc/script_commands.txt

@@ -2910,6 +2910,7 @@ recreate these items perfectly if they are destroyed. Here's what you get:
 @inventorylist_option_id5[]        - fifth array of random option IDs
 @inventorylist_option_id5[]        - fifth array of random option IDs
 @inventorylist_option_value5[]     - fifth array of random option values
 @inventorylist_option_value5[]     - fifth array of random option values
 @inventorylist_option_parameter5[] - fifth array of random option parameters
 @inventorylist_option_parameter5[] - fifth array of random option parameters
+@inventorylist_tradable            - Returns if an item is tradable or not (Pass item_trade.txt, bound, and rental restrictions).
 
 
 This could be handy to save/restore a character's inventory, since no other
 This could be handy to save/restore a character's inventory, since no other
 command returns such a complete set of data, and could also be the only way to
 command returns such a complete set of data, and could also be the only way to
@@ -4798,8 +4799,9 @@ for special cases such as removing a status change or resetting a variable or st
 of the player.
 of the player.
 
 
 This command can not be used to rent stackable items. Rental items cannot be
 This command can not be used to rent stackable items. Rental items cannot be
-dropped, traded, sold to NPCs, or placed in guild storage. (i.e. trade mask 75)
+dropped, traded, or placed in guild storage. (i.e. trade mask 67)
 Note: 'delitem' in an NPC script can still remove rental items.
 Note: 'delitem' in an NPC script can still remove rental items.
+Note: 'countitem' will not count any item with a rental timer.
 
 
 ---------------------------------------
 ---------------------------------------
 
 

+ 18 - 0
src/map/pc.cpp

@@ -916,6 +916,24 @@ bool pc_can_give_bounded_items(struct map_session_data *sd)
 	return pc_has_permission(sd, PC_PERM_TRADE_BOUNDED);
 	return pc_has_permission(sd, PC_PERM_TRADE_BOUNDED);
 }
 }
 
 
+/**
+ * Determine if an item in a player's inventory is tradeable based on several merits.
+ * Checks for item_trade, bound, and rental restrictions.
+ * @param sd: Player data
+ * @param index: Item inventory index
+ * @return True if the item can be traded or false otherwise
+ */
+bool pc_can_trade_item(map_session_data *sd, int index) {
+	if (sd && index >= 0) {
+		return (sd->inventory.u.items_inventory[index].expire_time == 0 &&
+			(sd->inventory.u.items_inventory[index].bound == 0 || pc_can_give_bounded_items(sd)) &&
+			itemdb_cantrade(&sd->inventory.u.items_inventory[index], pc_get_group_level(sd), pc_get_group_level(sd))
+			);
+	}
+
+	return false;
+}
+
 /*==========================================
 /*==========================================
  * Prepares character for saving.
  * Prepares character for saving.
  * @param sd
  * @param sd

+ 1 - 0
src/map/pc.hpp

@@ -1051,6 +1051,7 @@ int pc_get_group_id(struct map_session_data *sd);
 bool pc_can_sell_item(struct map_session_data* sd, struct item * item, enum npc_subtype shoptype);
 bool pc_can_sell_item(struct map_session_data* sd, struct item * item, enum npc_subtype shoptype);
 bool pc_can_give_items(struct map_session_data *sd);
 bool pc_can_give_items(struct map_session_data *sd);
 bool pc_can_give_bounded_items(struct map_session_data *sd);
 bool pc_can_give_bounded_items(struct map_session_data *sd);
+bool pc_can_trade_item(map_session_data *sd, int index);
 
 
 bool pc_can_use_command(struct map_session_data *sd, const char *command, AtCommandType type);
 bool pc_can_use_command(struct map_session_data *sd, const char *command, AtCommandType type);
 #define pc_has_permission(sd, permission) ( ((sd)->permissions&permission) != 0 )
 #define pc_has_permission(sd, permission) ( ((sd)->permissions&permission) != 0 )

+ 6 - 9
src/map/script.cpp

@@ -6935,7 +6935,7 @@ int script_countitem_sub(struct item *items, struct item_data *id, int size, boo
 		unsigned short nameid = id->nameid;
 		unsigned short nameid = id->nameid;
 
 
 		for (int i = 0; i < size; i++) {
 		for (int i = 0; i < size; i++) {
-			if (&items[i] && items[i].nameid == nameid)
+			if (&items[i] && items[i].nameid == nameid && items[i].expire_time == 0)
 				count += items[i].amount;
 				count += items[i].amount;
 		}
 		}
 	} else { // For expanded functions
 	} else { // For expanded functions
@@ -6967,7 +6967,7 @@ int script_countitem_sub(struct item *items, struct item_data *id, int size, boo
 		for (int i = 0; i < size; i++) {
 		for (int i = 0; i < size; i++) {
 			struct item *itm = &items[i];
 			struct item *itm = &items[i];
 
 
-			if (!itm || !itm->nameid || itm->amount < 1)
+			if (!itm || !itm->nameid || itm->amount < 1 || items[i].expire_time > 0)
 				continue;
 				continue;
 			if (itm->nameid != it.nameid || itm->identify != it.identify || itm->refine != it.refine || itm->attribute != it.attribute)
 			if (itm->nameid != it.nameid || itm->identify != it.identify || itm->refine != it.refine || itm->attribute != it.attribute)
 				continue;
 				continue;
@@ -7708,6 +7708,7 @@ BUILDIN_FUNC(rentitem2) {
 	it.card[2] = (short)c3;
 	it.card[2] = (short)c3;
 	it.card[3] = (short)c4;
 	it.card[3] = (short)c4;
 	it.expire_time = (unsigned int)(time(NULL) + seconds);
 	it.expire_time = (unsigned int)(time(NULL) + seconds);
+	it.bound = BOUND_NONE;
 
 
 	if (funcname[strlen(funcname)-1] == '3') {
 	if (funcname[strlen(funcname)-1] == '3') {
 		int res = script_getitem_randomoption(st, sd, &it, funcname, 11);
 		int res = script_getitem_randomoption(st, sd, &it, funcname, 11);
@@ -14058,6 +14059,7 @@ BUILDIN_FUNC(getinventorylist)
 				sprintf(randopt_var, "@inventorylist_option_parameter%d",k+1);
 				sprintf(randopt_var, "@inventorylist_option_parameter%d",k+1);
 				pc_setreg(sd,reference_uid(add_str(randopt_var), j),sd->inventory.u.items_inventory[i].option[k].param);
 				pc_setreg(sd,reference_uid(add_str(randopt_var), j),sd->inventory.u.items_inventory[i].option[k].param);
 			}
 			}
+			pc_setreg(sd,reference_uid(add_str("@inventorylist_tradable"), j),pc_can_trade_item(sd, i));
 			j++;
 			j++;
 		}
 		}
 	}
 	}
@@ -24062,13 +24064,8 @@ BUILDIN_FUNC(getequiptradability) {
 		return SCRIPT_CMD_FAILURE;
 		return SCRIPT_CMD_FAILURE;
 	}
 	}
 
 
-	if (i >= 0) {
-		bool tradable = (sd->inventory.u.items_inventory[i].expire_time == 0 &&
-			(!sd->inventory.u.items_inventory[i].bound || pc_can_give_bounded_items(sd)) &&
-			itemdb_cantrade(&sd->inventory.u.items_inventory[i], pc_get_group_level(sd), pc_get_group_level(sd))
-			);
-		script_pushint(st, tradable);
-	}
+	if (i >= 0)
+		script_pushint(st, pc_can_trade_item(sd, i));
 	else
 	else
 		script_pushint(st, false);
 		script_pushint(st, false);