summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/common/inter-server.conf1
-rw-r--r--doc/script_commands.txt2
-rw-r--r--sql-files/main.sql10
-rw-r--r--sql-files/upgrades/2018-12-29--07-51.sql29
-rw-r--r--sql-files/upgrades/index.txt1
-rw-r--r--src/map/clif.c1
-rw-r--r--src/map/clif.h1
-rw-r--r--src/map/map.c2
-rw-r--r--src/map/map.h1
-rw-r--r--src/map/npc.c158
-rw-r--r--src/map/npc.h10
-rw-r--r--src/map/script.c102
12 files changed, 260 insertions, 58 deletions
diff --git a/conf/common/inter-server.conf b/conf/common/inter-server.conf
index 1e738c587..cbeb6617d 100644
--- a/conf/common/inter-server.conf
+++ b/conf/common/inter-server.conf
@@ -117,6 +117,7 @@ inter_configuration: {
autotrade_merchants_db: "autotrade_merchants"
autotrade_data_db: "autotrade_data"
npc_market_data_db: "npc_market_data"
+ npc_barter_data_db: "npc_barter_data"
}
}
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index a545357aa..26a4fbfb8 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -9967,8 +9967,10 @@ currency_id and currency_amount can be used only with shop type NST_BARTER
---------------------------------------
*stopselling(<Item_ID>)
+*stopselling(<Item_ID>{, <currency_id>, <currency_amount>})
attempts to remove <Item_ID> from the current shop list.
+currency_id and currency_amount can be used only with shop type NST_BARTER
---------------------------------------
diff --git a/sql-files/main.sql b/sql-files/main.sql
index f322d1cda..a08ec60ba 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -924,6 +924,7 @@ INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1528180320); -- 2018-06-0
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1532403228); -- 2018-07-24--03-23.sql
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1535865732); -- 2018-09-01--05-22.sql
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1544738447); -- 2018-12-14--01-02.sql
+INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1546059075); -- 2018-12-29--07-51.sql
--
-- Table structure for table `storage`
@@ -1012,3 +1013,12 @@ CREATE TABLE IF NOT EXISTS `rodex_mail` (
KEY `send_date` (`send_date`),
KEY `expire_date` (`expire_date`)
) ENGINE=MyISAM;
+
+CREATE TABLE IF NOT EXISTS `npc_barter_data` (
+ `name` VARCHAR(24) NOT NULL DEFAULT '',
+ `itemId` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ `amount` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ `priceId` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ `priceAmount` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ PRIMARY KEY (`name`, `itemid`, `priceId`, `priceAmount`)
+) ENGINE=MyISAM;
diff --git a/sql-files/upgrades/2018-12-29--07-51.sql b/sql-files/upgrades/2018-12-29--07-51.sql
new file mode 100644
index 000000000..641179399
--- /dev/null
+++ b/sql-files/upgrades/2018-12-29--07-51.sql
@@ -0,0 +1,29 @@
+#1546059075
+
+-- This file is part of Hercules.
+-- http://herc.ws - http://github.com/HerculesWS/Hercules
+--
+-- Copyright (C) 2013-2015 Hercules Dev Team
+--
+-- Hercules is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+CREATE TABLE IF NOT EXISTS `npc_barter_data` (
+ `name` VARCHAR(24) NOT NULL DEFAULT '',
+ `itemId` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ `amount` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ `priceId` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ `priceAmount` INT(11) UNSIGNED NOT NULL DEFAULT '0',
+ PRIMARY KEY (`name`, `itemid`, `priceId`, `priceAmount`)
+) ENGINE=MyISAM;
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1546059075);
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index ed892df12..3a2fc4c33 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -51,3 +51,4 @@
2018-07-24--03-23.sql
2018-09-01--05-22.sql
2018-12-14--01-02.sql
+2018-12-29--07-51.sql
diff --git a/src/map/clif.c b/src/map/clif.c
index 2eb60e2e3..eba2ddce3 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -22278,6 +22278,7 @@ static void clif_parse_NPCBarterPurchase(int fd, struct map_session_data *sd)
entry.addId = p->list[i].itemId;
entry.addAmount = p->list[i].amount;
entry.removeIndex = p->list[i].invIndex - 2;
+ entry.shopIndex = p->list[i].shopIndex;
VECTOR_PUSH(item_list, entry);
}
diff --git a/src/map/clif.h b/src/map/clif.h
index 3ed6e8ea1..1aee11c33 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -669,6 +669,7 @@ struct barter_itemlist_entry {
int addId;
int addAmount;
int removeIndex;
+ int shopIndex;
};
VECTOR_STRUCT_DECL(barteritemlist, struct barter_itemlist_entry);
diff --git a/src/map/map.c b/src/map/map.c
index 93e86f80b..6212493c8 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -4479,6 +4479,7 @@ static bool inter_config_read_database_names(const char *filename, const struct
libconfig->setting_lookup_mutable_string(setting, "autotrade_merchants_db", map->autotrade_merchants_db, sizeof(map->autotrade_merchants_db));
libconfig->setting_lookup_mutable_string(setting, "autotrade_data_db", map->autotrade_data_db, sizeof(map->autotrade_data_db));
libconfig->setting_lookup_mutable_string(setting, "npc_market_data_db", map->npc_market_data_db, sizeof(map->npc_market_data_db));
+ libconfig->setting_lookup_mutable_string(setting, "npc_barter_data_db", map->npc_barter_data_db, sizeof(map->npc_barter_data_db));
if (!mapreg->config_read(filename, setting, imported))
retval = false;
@@ -6742,6 +6743,7 @@ int do_init(int argc, char *argv[])
npc->event_do_oninit( false ); // Init npcs (OnInit)
npc->market_fromsql(); /* after OnInit */
+ npc->barter_fromsql(); /* after OnInit */
if (battle_config.pk_mode)
ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n");
diff --git a/src/map/map.h b/src/map/map.h
index 4267c2c88..d31ff4839 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -1167,6 +1167,7 @@ struct map_interface {
char autotrade_merchants_db[32];
char autotrade_data_db[32];
char npc_market_data_db[32];
+ char npc_barter_data_db[32];
char default_codepage[32];
char default_lang_str[64];
diff --git a/src/map/npc.c b/src/map/npc.c
index 7f003c321..7e1dab1b2 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -1585,11 +1585,11 @@ static void npc_market_fromsql(void)
if( !(nd = npc->name2id(name)) ) {
ShowError("npc_market_fromsql: NPC '%s' not found! skipping...\n",name);
- npc->market_delfromsql_sub(name, USHRT_MAX);
+ npc->market_delfromsql_sub(name, INT_MAX);
continue;
} else if (nd->subtype != SCRIPT || !nd->u.scr.shop || !nd->u.scr.shop->items || nd->u.scr.shop->type != NST_MARKET) {
ShowError("npc_market_fromsql: NPC '%s' is not proper for market, skipping...\n",name);
- npc->market_delfromsql_sub(name, USHRT_MAX);
+ npc->market_delfromsql_sub(name, INT_MAX);
continue;
}
@@ -1611,10 +1611,10 @@ static void npc_market_fromsql(void)
/**
* Saves persistent NPC Market Data into SQL
**/
-static void npc_market_tosql(struct npc_data *nd, unsigned short index)
+static void npc_market_tosql(struct npc_data *nd, int index)
{
nullpo_retv(nd);
- Assert_retv(index < nd->u.scr.shop->items);
+ Assert_retv(index >= 0 && index < nd->u.scr.shop->items);
if (SQL_ERROR == SQL->Query(map->mysql_handle, "REPLACE INTO `%s` VALUES ('%s','%d','%u')",
map->npc_market_data_db, nd->exname, nd->u.scr.shop->item[index].nameid, nd->u.scr.shop->item[index].qty))
Sql_ShowDebug(map->mysql_handle);
@@ -1622,9 +1622,9 @@ static void npc_market_tosql(struct npc_data *nd, unsigned short index)
/**
* Removes persistent NPC Market Data from SQL
*/
-static void npc_market_delfromsql_sub(const char *npcname, unsigned short index)
+static void npc_market_delfromsql_sub(const char *npcname, int index)
{
- if( index == USHRT_MAX ) {
+ if (index == INT_MAX ) {
if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `name`='%s'", map->npc_market_data_db, npcname) )
Sql_ShowDebug(map->mysql_handle);
} else {
@@ -1636,12 +1636,115 @@ static void npc_market_delfromsql_sub(const char *npcname, unsigned short index)
/**
* Removes persistent NPC Market Data from SQL
**/
-static void npc_market_delfromsql(struct npc_data *nd, unsigned short index)
+static void npc_market_delfromsql(struct npc_data *nd, int index)
{
nullpo_retv(nd);
- Assert_retv(index == USHRT_MAX || index < nd->u.scr.shop->items);
- npc->market_delfromsql_sub(nd->exname, index == USHRT_MAX ? index : nd->u.scr.shop->item[index].nameid);
+ Assert_retv(index == INT_MAX || (index >= 0 && index < nd->u.scr.shop->items));
+ npc->market_delfromsql_sub(nd->exname, index == INT_MAX ? index : nd->u.scr.shop->item[index].nameid);
}
+
+/**
+ * Loads persistent NPC Barter Data from SQL
+ **/
+static void npc_barter_fromsql(void)
+{
+ struct SqlStmt *stmt = SQL->StmtMalloc(map->mysql_handle);
+ char name[NAME_LENGTH + 1];
+ int itemid;
+ int amount;
+ int removeId;
+ int removeAmount;
+
+ if (SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `name`, `itemId`, `amount`, `priceId`, `priceAmount` FROM `%s`", map->npc_barter_data_db)
+ || SQL_ERROR == SQL->StmtExecute(stmt)
+ ) {
+ SqlStmt_ShowDebug(stmt);
+ SQL->StmtFree(stmt);
+ return;
+ }
+
+ SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &name, sizeof name, NULL, NULL);
+ SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &itemid, sizeof itemid, NULL, NULL);
+ SQL->StmtBindColumn(stmt, 2, SQLDT_UINT32, &amount, sizeof amount, NULL, NULL);
+ SQL->StmtBindColumn(stmt, 3, SQLDT_INT, &removeId, sizeof removeId, NULL, NULL);
+ SQL->StmtBindColumn(stmt, 4, SQLDT_INT, &removeAmount, sizeof removeAmount, NULL, NULL);
+
+ while (SQL_SUCCESS == SQL->StmtNextRow(stmt)) {
+ struct npc_data *nd = NULL;
+ unsigned short i;
+
+ if (!(nd = npc->name2id(name))) {
+ ShowError("npc_barter_fromsql: NPC '%s' not found! skipping...\n",name);
+ npc->barter_delfromsql_sub(name, INT_MAX, 0, 0);
+ continue;
+ } else if (nd->subtype != SCRIPT || !nd->u.scr.shop || !nd->u.scr.shop->items || nd->u.scr.shop->type != NST_BARTER) {
+ ShowError("npc_barter_fromsql: NPC '%s' is not proper for barter, skipping...\n",name);
+ npc->barter_delfromsql_sub(name, INT_MAX, 0, 0);
+ continue;
+ }
+
+ for (i = 0; i < nd->u.scr.shop->items; i++) {
+ struct npc_item_list *const item = &nd->u.scr.shop->item[i];
+ if (item->nameid == itemid && item->value == removeId && item->value2 == removeAmount) {
+ item->qty = amount;
+ break;
+ }
+ }
+
+ if (i == nd->u.scr.shop->items) {
+ ShowError("npc_barter_fromsql: NPC '%s' does not sell item %d (qty %d), deleting...\n", name, itemid, amount);
+ npc->barter_delfromsql_sub(name, itemid, removeId, removeAmount);
+ continue;
+ }
+ }
+ SQL->StmtFree(stmt);
+}
+
+/**
+ * Saves persistent NPC Barter Data into SQL
+ **/
+static void npc_barter_tosql(struct npc_data *nd, int index)
+{
+ nullpo_retv(nd);
+ Assert_retv(index >= 0 && index < nd->u.scr.shop->items);
+ const struct npc_item_list *const item = &nd->u.scr.shop->item[index];
+ if (SQL_ERROR == SQL->Query(map->mysql_handle, "REPLACE INTO `%s` VALUES ('%s', '%d', '%u', '%u', '%d')",
+ map->npc_barter_data_db, nd->exname, item->nameid, item->qty, item->value, item->value2)) {
+ Sql_ShowDebug(map->mysql_handle);
+ }
+}
+
+/**
+ * Removes persistent NPC Barter Data from SQL
+ */
+static void npc_barter_delfromsql_sub(const char *npcname, int itemId, int itemId2, int amount2)
+{
+ if (itemId == INT_MAX) {
+ if (SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `name`='%s'", map->npc_barter_data_db, npcname))
+ Sql_ShowDebug(map->mysql_handle);
+ } else {
+ if (SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `name`='%s' AND `itemId`='%d' AND `priceId`='%d' AND `priceAmount`='%d' LIMIT 1",
+ map->npc_barter_data_db, npcname, itemId, itemId2, amount2)) {
+ Sql_ShowDebug(map->mysql_handle);
+ }
+ }
+}
+
+/**
+ * Removes persistent NPC Barter Data from SQL
+ **/
+static void npc_barter_delfromsql(struct npc_data *nd, int index)
+{
+ nullpo_retv(nd);
+ if (index == INT_MAX) {
+ npc->barter_delfromsql_sub(nd->exname, INT_MAX, 0, 0);
+ } else {
+ Assert_retv(index >= 0 && index < nd->u.scr.shop->items);
+ const struct npc_item_list *const item = &nd->u.scr.shop->item[index];
+ npc->barter_delfromsql_sub(nd->exname, item->nameid, item->value, item->value2);
+ }
+}
+
/**
* Judges whether to allow and spawn a trader's window.
**/
@@ -2151,20 +2254,23 @@ static int npc_barter_buylist(struct map_session_data *sd, struct barteritemlist
if (n < 0 || n >= sd->status.inventorySize)
return 11; // wrong inventory index
+ int removeId = sd->status.inventory[n].nameid;
+ const int j = entry->shopIndex;
+ if (j < 0 || j >= shop_size)
+ return 13; // no such item in shop
+ if (entry->addId != shop[j].nameid && entry->addId != itemdb_viewid(shop[j].nameid))
+ return 13; // no such item in shop
+ if (removeId != shop[j].value && removeId != itemdb_viewid(shop[j].value))
+ return 13; // no such item in shop
+ entry->addId = shop[j].nameid; // item_avail replacement
+ removeId = shop[j].value; // item_avail replacement
+
if (!itemdb->exists(entry->addId))
return 13; // item no longer in itemdb
- const int removeId = sd->status.inventory[n].nameid;
- int j = shop_size;
- // find this entry in the shop's sell list
- ARR_FIND(0, shop_size, j, (entry->addId == shop[j].nameid || entry->addId == itemdb_viewid(shop[j].nameid)) &&
- (removeId == shop[j].value || removeId == itemdb_viewid(shop[j].value)));
- if (j == shop_size)
- return 13; // no such item in shop
-
const int removeAmount = shop[j].value2;
- if (entry->addAmount > (int)shop[j].qty)
+ if ((int)shop[j].qty != -1 && entry->addAmount > (int)shop[j].qty)
return 14; // not enough item amount in shop
if (removeAmount * entry->addAmount > sd->status.inventory[n].amount)
@@ -2219,12 +2325,13 @@ static int npc_barter_buylist(struct map_session_data *sd, struct barteritemlist
struct barter_itemlist_entry *entry = &VECTOR_INDEX(*item_list, i);
const int shopIdx = npc_market_qty[i];
- if (entry->addAmount > (int)shop[shopIdx].qty) /* wohoo someone tampered with the packet. */
- return 14;
-
- shop[shopIdx].qty -= entry->addAmount;
+ if ((int)shop[shopIdx].qty != -1) {
+ if (entry->addAmount > (int)shop[shopIdx].qty) /* wohoo someone tampered with the packet. */
+ return 14;
+ shop[shopIdx].qty -= entry->addAmount;
+ }
- // TODO: save to sql
+ npc->barter_tosql(nd, shopIdx);
if (itemdb_type(entry->addId) == IT_PETEGG) {
pet->create_egg(sd, entry->addId);
@@ -5125,6 +5232,7 @@ static int npc_reload(void)
// OnInit -> OnInterIfInit -> OnInterIfInitOnce -> OnAgitInit -> OnAgitInit2
npc->event_do_oninit( true );
npc->market_fromsql();
+ npc->barter_fromsql();
// Execute rest of the startup events if connected to char-server. [Lance]
// Executed when connection is established with char-server in chrif_connectack
if( !intif->CheckForCharServer() ) {
@@ -5437,6 +5545,10 @@ void npc_defaults(void)
npc->market_tosql = npc_market_tosql;
npc->market_delfromsql = npc_market_delfromsql;
npc->market_delfromsql_sub = npc_market_delfromsql_sub;
+ npc->barter_fromsql = npc_barter_fromsql;
+ npc->barter_tosql = npc_barter_tosql;
+ npc->barter_delfromsql = npc_barter_delfromsql;
+ npc->barter_delfromsql_sub = npc_barter_delfromsql_sub;
npc->db_checkid = npc_db_checkid;
npc->refresh = npc_refresh;
}
diff --git a/src/map/npc.h b/src/map/npc.h
index bd16938a3..d455a395b 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -313,9 +313,13 @@ struct npc_interface {
int (*barter_buylist) (struct map_session_data *sd, struct barteritemlist *item_list);
bool (*trader_open) (struct map_session_data *sd, struct npc_data *nd);
void (*market_fromsql) (void);
- void (*market_tosql) (struct npc_data *nd, unsigned short index);
- void (*market_delfromsql) (struct npc_data *nd, unsigned short index);
- void (*market_delfromsql_sub) (const char *npcname, unsigned short index);
+ void (*market_tosql) (struct npc_data *nd, int index);
+ void (*market_delfromsql) (struct npc_data *nd, int index);
+ void (*market_delfromsql_sub) (const char *npcname, int index);
+ void (*barter_fromsql) (void);
+ void (*barter_tosql) (struct npc_data *nd, int index);
+ void (*barter_delfromsql) (struct npc_data *nd, int index);
+ void (*barter_delfromsql_sub) (const char *npcname, int itemId, int itemId2, int amount2);
bool (*db_checkid) (const int id);
void (*refresh) (struct npc_data* nd);
/**
diff --git a/src/map/script.c b/src/map/script.c
index d372d485e..841e21169 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -23889,12 +23889,36 @@ static BUILDIN(sellitem)
return false;
}
- if( !nd->u.scr.shop )
- npc->trader_update(nd->src_id?nd->src_id:nd->bl.id);
- else {/* no need to run this if its empty */
- for( i = 0; i < nd->u.scr.shop->items; i++ ) {
- if( nd->u.scr.shop->item[i].nameid == id )
- break;
+ if (!nd->u.scr.shop) {
+ npc->trader_update(nd->src_id ? nd->src_id : nd->bl.id);
+ if (nd->u.scr.shop->type == NST_BARTER) {
+ if (!script_hasdata(st, 5)) {
+ ShowError("buildin_sellitem: invalid number of parameters for barter-type shop!\n");
+ return false;
+ }
+ value = script_getnum(st, 4);
+ value2 = script_getnum(st, 5);
+ }
+ } else {/* no need to run this if its empty */
+ if (nd->u.scr.shop->type == NST_BARTER) {
+ if (!script_hasdata(st, 5)) {
+ ShowError("buildin_sellitem: invalid number of parameters for barter-type shop!\n");
+ return false;
+ }
+ value = script_getnum(st, 4);
+ value2 = script_getnum(st, 5);
+ for (i = 0; i < nd->u.scr.shop->items; i++) {
+ const struct npc_item_list *const item = &nd->u.scr.shop->item[i];
+ if (item->nameid == id && item->value == value && item->value2 == value2) {
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < nd->u.scr.shop->items; i++) {
+ if (nd->u.scr.shop->item[i].nameid == id) {
+ break;
+ }
+ }
}
}
@@ -23917,33 +23941,28 @@ static BUILDIN(sellitem)
}
if (nd->u.scr.shop->type == NST_BARTER) {
- if (!script_hasdata(st, 5)) {
- ShowError("buildin_sellitem: invalid number of parameters for barter-type shop!\n");
- return false;
- }
qty = script_getnum(st, 3);
- value = script_getnum(st, 4);
- value2 = script_getnum(st, 5);
- if (qty <= 0 || value <= 0 || value2 <= 0) {
+ if (qty < -1 || value <= 0 || value2 <= 0) {
ShowError("buildin_sellitem: invalid parameters for barter-type shop!\n");
return false;
}
}
- if( i != nd->u.scr.shop->items ) {
+ if (i != nd->u.scr.shop->items) {
nd->u.scr.shop->item[i].value = value;
nd->u.scr.shop->item[i].qty = qty;
if (nd->u.scr.shop->type == NST_MARKET) /* has been manually updated, make it reflect on sql */
npc->market_tosql(nd, i);
- // TODO: saving barter shop to sql
+ else if (nd->u.scr.shop->type == NST_BARTER) /* has been manually updated, make it reflect on sql */
+ npc->barter_tosql(nd, i);
} else {
- for( i = 0; i < nd->u.scr.shop->items; i++ ) {
- if( nd->u.scr.shop->item[i].nameid == 0 )
+ for (i = 0; i < nd->u.scr.shop->items; i++) {
+ if (nd->u.scr.shop->item[i].nameid == 0)
break;
}
- if( i == nd->u.scr.shop->items ) {
- if( nd->u.scr.shop->items == USHRT_MAX ) {
+ if (i == nd->u.scr.shop->items) {
+ if (nd->u.scr.shop->items == USHRT_MAX) {
ShowWarning("buildin_sellitem: Can't add %s (%s/%s), shop list is full!\n", it->name, nd->exname, nd->path);
return false;
}
@@ -23970,37 +23989,55 @@ static BUILDIN(sellitem)
static BUILDIN(stopselling)
{
struct npc_data *nd;
- int i, id = script_getnum(st,2);
+ int i, id = script_getnum(st, 2);
- if( !(nd = map->id2nd(st->oid)) || !nd->u.scr.shop ) {
+ if (!(nd = map->id2nd(st->oid)) || !nd->u.scr.shop) {
ShowWarning("buildin_stopselling: trying to run without a proper NPC!\n");
return false;
}
- for( i = 0; i < nd->u.scr.shop->items; i++ ) {
- if( nd->u.scr.shop->item[i].nameid == id )
- break;
+ if (nd->u.scr.shop->type == NST_BARTER) {
+ if (!script_hasdata(st, 4)) {
+ ShowError("buildin_stopselling: called with wrong number of arguments\n");
+ return false;
+ }
+ const int id2 = script_getnum(st, 3);
+ const int amount2 = script_getnum(st, 4);
+ for (i = 0; i < nd->u.scr.shop->items; i++) {
+ const struct npc_item_list *const item = &nd->u.scr.shop->item[i];
+ if (item->nameid == id && item->value == id2 && item->value2 == amount2) {
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < nd->u.scr.shop->items; i++) {
+ if (nd->u.scr.shop->item[i].nameid == id) {
+ break;
+ }
+ }
}
- if( i != nd->u.scr.shop->items ) {
+ if (i != nd->u.scr.shop->items) {
int cursor;
if (nd->u.scr.shop->type == NST_MARKET)
- npc->market_delfromsql(nd,i);
- // TODO: remove barter shop from sql
+ npc->market_delfromsql(nd, i);
+ if (nd->u.scr.shop->type == NST_BARTER)
+ npc->barter_delfromsql(nd, i);
nd->u.scr.shop->item[i].nameid = 0;
nd->u.scr.shop->item[i].value = 0;
nd->u.scr.shop->item[i].value2 = 0;
nd->u.scr.shop->item[i].qty = 0;
- for( i = 0, cursor = 0; i < nd->u.scr.shop->items; i++ ) {
- if( nd->u.scr.shop->item[i].nameid == 0 )
+ for (i = 0, cursor = 0; i < nd->u.scr.shop->items; i++) {
+ if (nd->u.scr.shop->item[i].nameid == 0)
continue;
- if( cursor != i ) {
+ if (cursor != i) {
nd->u.scr.shop->item[cursor].nameid = nd->u.scr.shop->item[i].nameid;
nd->u.scr.shop->item[cursor].value = nd->u.scr.shop->item[i].value;
+ nd->u.scr.shop->item[cursor].value2 = nd->u.scr.shop->item[i].value2;
nd->u.scr.shop->item[cursor].qty = nd->u.scr.shop->item[i].qty;
}
@@ -24066,7 +24103,8 @@ static BUILDIN(tradertype)
nd->u.scr.shop->item[i].value = 0;
nd->u.scr.shop->item[i].qty = 0;
}
- npc->market_delfromsql(nd,USHRT_MAX);
+ npc->market_delfromsql(nd, INT_MAX);
+ npc->barter_delfromsql(nd, INT_MAX);
}
#if PACKETVER < 20131223
@@ -25651,7 +25689,7 @@ static void script_parse_builtin(void)
/* New Shop Support */
BUILDIN_DEF(openshop,"?"),
BUILDIN_DEF(sellitem,"i???"),
- BUILDIN_DEF(stopselling,"i"),
+ BUILDIN_DEF(stopselling,"i??"),
BUILDIN_DEF(setcurrency,"i?"),
BUILDIN_DEF(tradertype,"i"),
BUILDIN_DEF(purchaseok,""),