From 8336f046b7e2c74ec2d2d07fca395d27749a4881 Mon Sep 17 00:00:00 2001 From: Vincent Stumpf Date: Wed, 27 Dec 2023 13:16:04 -0800 Subject: [PATCH] Allow default sell values in npc shop scripts (#8050) Fixes #6594 --- doc/script_commands.txt | 15 ++++++++--- src/map/script.cpp | 58 ++++++++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 14 deletions(-) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 3e97c9d69e..1ea3f1ec64 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7481,10 +7481,10 @@ This command lets you override the contents of an existing NPC shop or cashshop. current sell list will be wiped, and only the items specified with the price specified will be for sale. -The function returns 1 if shop was updated successfully, or 0 if not found. +The function returns 1 if shop was updated successfully, or 0 on failure. NOTES: - - That you cannot use -1 to specify default selling price! + - That you cannot use -1 to specify default selling price for cashshops, pointshops, or itemshops. - If the attached shop type is a market shop, notice that there is an extra parameter after price, . Make sure to not add duplicate items! For unlimited stock use -1. --------------------------------------- @@ -7496,10 +7496,10 @@ This command will add more items at the end of the selling list for the specified NPC shop or cashshop. If you specify an item already for sell, that item will appear twice on the sell list. -The function returns 1 if shop was updated successfully, or 0 if not found. +The function returns 1 if shop was updated successfully, or 0 on failure. NOTES: - - That you cannot use -1 to specify default selling price! + - That you cannot use -1 to specify default selling price for cashshops, pointshops, or itemshops. - If attached shop type is market shop, need an extra param after price, it's and make sure don't add duplication item! For unlimited stock use -1. @@ -7543,6 +7543,13 @@ Update an entry from a shop. If the price is 0 it won't be changed. May also be marketshop to update the stock quantity. For unlimited stock, use -1. For other shop types, the stock value has no effect. +If the price is -1, it sets it to the default buy price. + +The function returns 1 if shop was updated successfully, or 0 on failure. + +NOTES: + - That you cannot use -1 to specify default selling price for cashshops, pointshops, or itemshops. + --------------------------------------- *waitingroom "",{,""{,{,{,{,}}}}}; diff --git a/src/map/script.cpp b/src/map/script.cpp index becf9dc6ed..9d6c9c890b 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -17958,15 +17958,25 @@ BUILDIN_FUNC(npcshopitem) nd->u.shop.count = 0; for (n = 0, i = 3; n < amount; n++, i+=offs) { t_itemid nameid = script_getnum( st, i ); + std::shared_ptr id = item_db.find(nameid); - if( !item_db.exists( nameid ) ){ + if( !id ){ ShowError( "builtin_npcshopitem: Item ID %u does not exist.\n", nameid ); script_pushint( st, 0 ); return SCRIPT_CMD_FAILURE; } + int32 price = script_getnum(st, i + 1); + if (price < 0) { + if (nd->subtype == NPCTYPE_CASHSHOP || nd->subtype == NPCTYPE_POINTSHOP || nd->subtype == NPCTYPE_ITEMSHOP) { + ShowError("builtin_npcshopitem: Invalid price in shop '%s'.\n", nd->exname); + script_pushint(st, 0); + return SCRIPT_CMD_FAILURE; + } + price = id->value_buy; + } nd->u.shop.shop_item[n].nameid = nameid; - nd->u.shop.shop_item[n].value = script_getnum(st,i+1); + nd->u.shop.shop_item[n].value = price; #if PACKETVER >= 20131223 if (nd->subtype == NPCTYPE_MARKETSHOP) { nd->u.shop.shop_item[n].qty = script_getnum(st,i+2); @@ -18003,8 +18013,9 @@ BUILDIN_FUNC(npcshopadditem) for (int n = 0, i = 3; n < amount; n++, i += offs) { t_itemid nameid = script_getnum(st,i); uint16 j; + std::shared_ptr id = item_db.find(nameid); - if( !item_db.exists( nameid ) ){ + if( !id ){ ShowError( "builtin_npcshopadditem: Item ID %u does not exist.\n", nameid ); script_pushint( st, 0 ); return SCRIPT_CMD_FAILURE; @@ -18019,8 +18030,12 @@ BUILDIN_FUNC(npcshopadditem) nd->u.shop.count++; } - int32 stock = script_getnum( st, i + 2 ); + int32 price = script_getnum(st, i + 1); + if (price < 0) { + price = id->value_buy; + } + int32 stock = script_getnum(st, i + 2); if( stock < -1 ){ ShowError( "builtin_npcshopadditem: Invalid stock amount in marketshop '%s'.\n", nd->exname ); script_pushint( st, 0 ); @@ -18028,7 +18043,7 @@ BUILDIN_FUNC(npcshopadditem) } nd->u.shop.shop_item[j].nameid = nameid; - nd->u.shop.shop_item[j].value = script_getnum(st,i+1); + nd->u.shop.shop_item[j].value = price; nd->u.shop.shop_item[j].qty = stock; npc_market_tosql(nd->exname, &nd->u.shop.shop_item[j]); @@ -18043,15 +18058,24 @@ BUILDIN_FUNC(npcshopadditem) for (int n = nd->u.shop.count, i = 3, j = 0; j < amount; n++, i+=offs, j++) { t_itemid nameid = script_getnum( st, i ); + std::shared_ptr id = item_db.find(nameid); - if( !item_db.exists( nameid ) ){ + if( !id ){ ShowError( "builtin_npcshopadditem: Item ID %u does not exist.\n", nameid ); script_pushint( st, 0 ); return SCRIPT_CMD_FAILURE; } - + int32 price = script_getnum(st, i + 1); + if (price < 0) { + if (nd->subtype == NPCTYPE_CASHSHOP || nd->subtype == NPCTYPE_POINTSHOP || nd->subtype == NPCTYPE_ITEMSHOP) { + ShowError("builtin_npcshopadditem: Invalid price in shop '%s'.\n", nd->exname); + script_pushint(st, 0); + return SCRIPT_CMD_FAILURE; + } + price = id->value_buy; + } nd->u.shop.shop_item[n].nameid = nameid; - nd->u.shop.shop_item[n].value = script_getnum(st,i+1); + nd->u.shop.shop_item[n].value = price; nd->u.shop.count++; } @@ -23820,9 +23844,23 @@ BUILDIN_FUNC(npcshopupdate) { for (i = 0; i < nd->u.shop.count; i++) { if (nd->u.shop.shop_item[i].nameid == nameid) { - - if (price != 0) + if (price != 0) { + if (price < 0) { + if (nd->subtype == NPCTYPE_CASHSHOP || nd->subtype == NPCTYPE_POINTSHOP || nd->subtype == NPCTYPE_ITEMSHOP) { + ShowError("builtin_npcshopupdate: Invalid price in shop '%s'.\n", nd->exname); + script_pushint(st, 0); + return SCRIPT_CMD_FAILURE; + } + std::shared_ptr id = item_db.find(nameid); + if (!id) { + ShowError("buildin_npcshopupdate: Item ID %u does not exist.\n", nameid); + script_pushint(st, 0); + return SCRIPT_CMD_FAILURE; + } + price = id->value_buy; + } nd->u.shop.shop_item[i].value = price; + } #if PACKETVER >= 20131223 if (nd->subtype == NPCTYPE_MARKETSHOP) { nd->u.shop.shop_item[i].qty = stock;