瀏覽代碼

Adds script commands to count rental items (#5080)

* Fixes #5047.
* Adds script commands rentalcountitem, rentalcountitem2, and rentalcountitem3.
* Adjusts Malangdo Culvert and Octopus Cave script to utilize script command rentalcountitem.
Thanks to @reunite-ro and @attackjom!
Aleos 4 年之前
父節點
當前提交
dbe27fe510
共有 4 個文件被更改,包括 96 次插入13 次删除
  1. 27 1
      doc/script_commands.txt
  2. 1 1
      npc/re/instances/MalangdoCulvert.txt
  3. 2 2
      npc/re/instances/OctopusCave.txt
  4. 66 9
      src/map/script.cpp

+ 27 - 1
doc/script_commands.txt

@@ -4801,7 +4801,7 @@ of the player.
 This command can not be used to rent stackable items. Rental items cannot be
 dropped, traded, or placed in guild storage. (i.e. trade mask 67)
 Note: 'delitem' in an NPC script can still remove rental items.
-Note: 'countitem' will not count any item with a rental timer.
+Note: 'countitem' will not count any item with a rental timer. Use 'rentalcountitem' instead.
 
 ---------------------------------------
 
@@ -5032,6 +5032,32 @@ If player is not in a guild or storage is open, 'guildstoragecountitem2' will re
 
 ---------------------------------------
 
+*rentalcountitem(<item id>{,<accountID>})
+*rentalcountitem("<item name>"{,<accountID>})
+
+This function will return the number of rental items for the specified item ID that the
+invoking character has in the inventory.
+
+---------------------------------------
+
+*rentalcountitem2(<item id>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<accountID>})
+*rentalcountitem2("<item name>",<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>{,<accountID>})
+*rentalcountitem3(<item id>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,<RandomIDArray>,<RandomValueArray>,<RandomParamArray>{,<accountID>})
+*rentalcountitem3("<item name>",<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,<RandomIDArray>,<RandomValueArray>,<RandomParamArray>{,<accountID>})
+
+Expanded version of 'rentalcountitem' function, used for created/carded/forged items.
+
+This function will return the number of rental items for the specified item ID and
+other parameters that the invoking character has in the inventory.
+See 'getitem2' for an explanation of the expanded parameters.
+
+'rentalcountitem3' is advance version of 'rentalcountitem2' that also use Item Random Option as criteria.
+<RandomIDArray>    : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.txt
+<RandomValueArray> : Array variable of item random option's value.
+<RandomParamArray> : Array variable of item random option's param.
+
+---------------------------------------
+
 *countbound({<bound type>{,<char_id>}})
 
 This function will return the number of bounded items in the character's

+ 1 - 1
npc/re/instances/MalangdoCulvert.txt

@@ -377,7 +377,7 @@ mal_in01,160,34,4	script	Missing, the Cleaner	545,{
 		set in_canal_n,1;
 		close;
 	}
-	if (countitem(6436) == 0) {
+	if (rentalcountitem(6436) == 0) {
 		mes "[Missing, the Cleaner]";
 		mes "You don't look like you have Seagod Protection. I can't open door at the moment!";
 		close;

+ 2 - 2
npc/re/instances/OctopusCave.txt

@@ -83,7 +83,7 @@ mal_dun01,151,235,5	script	Starfish	551,{
 				close;
 			}
 			if (.@playtime == 2) erasequest 4197;
-			if (countitem(6442)) {
+			if (rentalcountitem(6442)) {
 				if (instance_create(.@md_name$) < 0) {
 					mes "[Starfish]";
 					mes "Party name is... "+getpartyname(.@party_id)+".";
@@ -118,7 +118,7 @@ mal_dun01,153,237,5	script	Weird Entrance	844,{
 	next;
 	switch(select("Go in.:Stop.")) {
 	case 1:
-		if (countitem(6442)) {
+		if (rentalcountitem(6442)) {
 			switch(instance_enter("Octopus Cave")) {
 			case IE_OTHER:
 				mes "[Starfish]";

+ 66 - 9
src/map/script.cpp

@@ -6923,9 +6923,10 @@ static int script_getitem_randomoption(struct script_state *st, struct map_sessi
  * @param random_option: If the struct command has random option arguments
  * @param st: Script state (required for random options)
  * @param sd: Player data (required for random options)
+ * @param rental: Whether or not to count rental items
  * @return Total count of item being searched
  */
-int script_countitem_sub(struct item *items, struct item_data *id, int size, bool expanded, bool random_option, struct script_state *st, struct map_session_data *sd) {
+static int script_countitem_sub(struct item *items, struct item_data *id, int size, bool expanded, bool random_option, struct script_state *st, struct map_session_data *sd = nullptr, bool rental = false) {
 	nullpo_retr(-1, items);
 	nullpo_retr(-1, st);
 
@@ -6935,11 +6936,15 @@ int script_countitem_sub(struct item *items, struct item_data *id, int size, boo
 		unsigned short nameid = id->nameid;
 
 		for (int i = 0; i < size; i++) {
-			if (&items[i] && items[i].nameid == nameid && items[i].expire_time == 0)
-				count += items[i].amount;
+			item *itm = &items[i];
+
+			if (itm == nullptr || itm->nameid == 0 || itm->amount < 1 || (!rental && itm->expire_time > 0))
+				continue;
+			if (itm->nameid == nameid)
+				count += itm->amount;
 		}
 	} else { // For expanded functions
-		struct item it;
+		item it;
 
 		memset(&it, 0, sizeof(it));
 
@@ -6965,9 +6970,9 @@ int script_countitem_sub(struct item *items, struct item_data *id, int size, boo
 		}
 
 		for (int i = 0; i < size; i++) {
-			struct item *itm = &items[i];
+			item *itm = &items[i];
 
-			if (!itm || !itm->nameid || itm->amount < 1 || items[i].expire_time > 0)
+			if (itm == nullptr || itm->nameid == 0 || itm->amount < 1 || (!rental && items[i].expire_time > 0))
 				continue;
 			if (itm->nameid != it.nameid || itm->identify != it.identify || itm->refine != it.refine || itm->attribute != it.attribute)
 				continue;
@@ -7073,7 +7078,7 @@ BUILDIN_FUNC(cartcountitem)
 		return SCRIPT_CMD_FAILURE;
 	}
 
-	int count = script_countitem_sub(sd->cart.u.items_cart, id, MAX_CART, (aid > 3) ? true : false, false, st, nullptr);
+	int count = script_countitem_sub(sd->cart.u.items_cart, id, MAX_CART, (aid > 3) ? true : false, false, st);
 	if (count < 0) {
 		st->state = END;
 		return SCRIPT_CMD_FAILURE;
@@ -7117,7 +7122,7 @@ BUILDIN_FUNC(storagecountitem)
 		return SCRIPT_CMD_SUCCESS;
 	}
 
-	int count = script_countitem_sub(sd->storage.u.items_storage, id, MAX_STORAGE, (aid > 3) ? true : false, false, st, nullptr);
+	int count = script_countitem_sub(sd->storage.u.items_storage, id, MAX_STORAGE, (aid > 3) ? true : false, false, st);
 	if (count < 0) {
 		st->state = END;
 		return SCRIPT_CMD_FAILURE;
@@ -7165,7 +7170,7 @@ BUILDIN_FUNC(guildstoragecountitem)
 
 	gstor->lock = true;
 
-	int count = script_countitem_sub(gstor->u.items_guild, id, MAX_GUILD_STORAGE, (aid > 3) ? true : false, false, st, nullptr);
+	int count = script_countitem_sub(gstor->u.items_guild, id, MAX_GUILD_STORAGE, (aid > 3) ? true : false, false, st);
 
 	storage_guild_storageclose(sd);
 	gstor->lock = false;
@@ -7179,6 +7184,53 @@ BUILDIN_FUNC(guildstoragecountitem)
 	return SCRIPT_CMD_SUCCESS;
 }
 
+/**
+ * Returns number of rental items in inventory
+ * rentalcountitem(<nameID>{,<accountID>})
+ * rentalcountitem2(<nameID>,<Identified>,<Refine>,<Attribute>,<Card0>,<Card1>,<Card2>,<Card3>{,<accountID>})
+ * rentalcountitem3(<item id>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,<RandomIDArray>,<RandomValueArray>,<RandomParamArray>{,<accountID>})
+ * rentalcountitem3("<item name>",<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,<RandomIDArray>,<RandomValueArray>,<RandomParamArray>{,<accountID>})
+ */
+BUILDIN_FUNC(rentalcountitem)
+{
+	char *command = (char *)script_getfuncname(st);
+	int aid = 3;
+	bool random_option = false;
+
+	if (command[strlen(command) - 1] == '2')
+		aid = 10;
+	else if (command[strlen(command) - 1] == '3') {
+		aid = 13;
+		random_option = true;
+	}
+
+	map_session_data *sd;
+
+	if (!script_accid2sd(aid, sd))
+		return SCRIPT_CMD_FAILURE;
+
+	item_data *id;
+
+	if (script_isstring(st, 2)) // item name
+		id = itemdb_searchname(script_getstr(st, 2));
+	else // item id
+		id = itemdb_exists(script_getnum(st, 2));
+
+	if (!id) {
+		ShowError("buildin_%s: Invalid item '%s'.\n", command, script_getstr(st, 2)); // returns string, regardless of what it was
+		script_pushint(st, 0);
+		return SCRIPT_CMD_FAILURE;
+	}
+
+	int count = script_countitem_sub(sd->inventory.u.items_inventory, id, MAX_INVENTORY, (aid > 3) ? true : false, random_option, st, sd, true);
+	if (count < 0) {
+		st->state = END;
+		return SCRIPT_CMD_FAILURE;
+	}
+	script_pushint(st, count);
+	return SCRIPT_CMD_SUCCESS;
+}
+
 /*==========================================
  * Check if item with this amount can fit in inventory
  * Checking : weight, stack amount >(MAX_AMOUNT), slots amount >(MAX_INVENTORY)
@@ -25310,6 +25362,11 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(cloakoffnpc, "s?"),
 	BUILDIN_DEF(cloakonnpc, "s?"),
 	BUILDIN_DEF(isnpccloaked, "s?"),
+
+	BUILDIN_DEF(rentalcountitem, "v?"),
+	BUILDIN_DEF2(rentalcountitem, "rentalcountitem2", "viiiiiii?"),
+	BUILDIN_DEF2(rentalcountitem, "rentalcountitem3", "viiiiiiirrr?"),
+
 #include "../custom/script_def.inc"
 
 	{NULL,NULL,NULL},