|
@@ -2411,8 +2411,7 @@ static enum e_CASHSHOP_ACK npc_cashshop_process_payment(struct npc_data *nd, int
|
|
|
* @param item_list: List of items to purchase
|
|
|
* @return clif_cashshop_ack value to display
|
|
|
*/
|
|
|
-int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, struct PACKET_CZ_PC_BUY_CASH_POINT_ITEM_sub* item_list)
|
|
|
-{
|
|
|
+int npc_cashshop_buylist( struct map_session_data *sd, int points, std::vector<s_npc_buy_list>& item_list ){
|
|
|
int i, j, amount, new_, w, vt;
|
|
|
t_itemid nameid;
|
|
|
struct npc_data *nd = (struct npc_data *)map_id2bl(sd->npc_shopid);
|
|
@@ -2429,10 +2428,10 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, str
|
|
|
vt = 0; // Global Value
|
|
|
|
|
|
// Validating Process ----------------------------------------------------
|
|
|
- for( i = 0; i < count; i++ )
|
|
|
+ for( i = 0; i < item_list.size(); i++ )
|
|
|
{
|
|
|
- nameid = item_list[i].itemId;
|
|
|
- amount = item_list[i].amount;
|
|
|
+ nameid = item_list[i].nameid;
|
|
|
+ amount = item_list[i].qty;
|
|
|
id = itemdb_exists(nameid);
|
|
|
|
|
|
if( !id || amount <= 0 )
|
|
@@ -2442,12 +2441,12 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, str
|
|
|
if( j == nd->u.shop.count || nd->u.shop.shop_item[j].value <= 0 )
|
|
|
return ERROR_TYPE_ITEM_ID;
|
|
|
|
|
|
- nameid = item_list[i].itemId = nd->u.shop.shop_item[j].nameid; //item_avail replacement
|
|
|
+ nameid = item_list[i].nameid = nd->u.shop.shop_item[j].nameid; //item_avail replacement
|
|
|
|
|
|
if( !itemdb_isstackable2(id) && amount > 1 )
|
|
|
{
|
|
|
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %u!\n", sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
|
|
|
- amount = item_list[i].amount = 1;
|
|
|
+ amount = item_list[i].qty = 1;
|
|
|
}
|
|
|
|
|
|
if( nd->master_nd ) { // Script-controlled shops decide by themselves, what can be bought and for what price.
|
|
@@ -2468,7 +2467,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, str
|
|
|
}
|
|
|
|
|
|
if (nd->master_nd) //Script-based shops.
|
|
|
- return npc_buylist_sub(sd,count,(struct s_npc_buy_list*)item_list,nd->master_nd);
|
|
|
+ return npc_buylist_sub(sd,item_list,nd->master_nd);
|
|
|
|
|
|
if( w + sd->weight > sd->max_weight )
|
|
|
return ERROR_TYPE_INVENTORY_WEIGHT;
|
|
@@ -2480,9 +2479,9 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, str
|
|
|
return res;
|
|
|
|
|
|
// Delivery Process ----------------------------------------------------
|
|
|
- for( i = 0; i < count; i++ ) {
|
|
|
- nameid = item_list[i].itemId;
|
|
|
- amount = item_list[i].amount;
|
|
|
+ for( i = 0; i < item_list.size(); i++ ) {
|
|
|
+ nameid = item_list[i].nameid;
|
|
|
+ amount = item_list[i].qty;
|
|
|
|
|
|
if( !pet_create_egg(sd,nameid) ) {
|
|
|
struct item item_tmp;
|
|
@@ -2663,16 +2662,16 @@ int npc_cashshop_buy(struct map_session_data *sd, t_itemid nameid, int amount, i
|
|
|
* @param item_list: List of items
|
|
|
* @param nd: Attached NPC
|
|
|
*/
|
|
|
-static int npc_buylist_sub(struct map_session_data* sd, uint16 n, struct s_npc_buy_list *item_list, struct npc_data* nd) {
|
|
|
+static int npc_buylist_sub(struct map_session_data* sd, std::vector<s_npc_buy_list>& item_list, struct npc_data* nd) {
|
|
|
char npc_ev[EVENT_NAME_LENGTH];
|
|
|
- int i, key_nameid = 0, key_amount = 0;
|
|
|
+ int key_nameid = 0, key_amount = 0;
|
|
|
|
|
|
// discard old contents
|
|
|
script_cleararray_pc( sd, "@bought_nameid" );
|
|
|
script_cleararray_pc( sd, "@bought_quantity" );
|
|
|
|
|
|
// save list of bought items
|
|
|
- for (i = 0; i < n; i++) {
|
|
|
+ for( int i = 0; i < item_list.size(); i++ ){
|
|
|
script_setarray_pc( sd, "@bought_nameid", i, item_list[i].nameid, &key_nameid );
|
|
|
script_setarray_pc( sd, "@bought_quantity", i, item_list[i].qty, &key_amount );
|
|
|
}
|
|
@@ -2691,23 +2690,23 @@ static int npc_buylist_sub(struct map_session_data* sd, uint16 n, struct s_npc_b
|
|
|
* @param item_list: List of items
|
|
|
* @return result code for clif_parse_NpcBuyListSend/clif_npc_market_purchase_ack
|
|
|
*/
|
|
|
-e_purchase_result npc_buylist(struct map_session_data* sd, uint16 n, struct s_npc_buy_list *item_list) {
|
|
|
+e_purchase_result npc_buylist( struct map_session_data* sd, std::vector<s_npc_buy_list>& item_list ){
|
|
|
struct npc_data* nd;
|
|
|
struct npc_item_list *shop = NULL;
|
|
|
double z;
|
|
|
- int i,j,k,w,skill,new_;
|
|
|
+ int j,k,w,skill,new_;
|
|
|
uint8 market_index[MAX_INVENTORY];
|
|
|
|
|
|
nullpo_retr(e_purchase_result::PURCHASE_FAIL_COUNT, sd);
|
|
|
- nullpo_retr(e_purchase_result::PURCHASE_FAIL_COUNT, item_list);
|
|
|
|
|
|
nd = npc_checknear(sd,map_id2bl(sd->npc_shopid));
|
|
|
if( nd == NULL )
|
|
|
return e_purchase_result::PURCHASE_FAIL_COUNT;
|
|
|
if( nd->subtype != NPCTYPE_SHOP && nd->subtype != NPCTYPE_MARKETSHOP )
|
|
|
return e_purchase_result::PURCHASE_FAIL_COUNT;
|
|
|
- if (!item_list || !n)
|
|
|
+ if( item_list.empty() ){
|
|
|
return e_purchase_result::PURCHASE_FAIL_COUNT;
|
|
|
+ }
|
|
|
|
|
|
z = 0;
|
|
|
w = 0;
|
|
@@ -2717,7 +2716,7 @@ e_purchase_result npc_buylist(struct map_session_data* sd, uint16 n, struct s_np
|
|
|
|
|
|
memset(market_index, 0, sizeof(market_index));
|
|
|
// process entries in buy list, one by one
|
|
|
- for( i = 0; i < n; ++i ) {
|
|
|
+ for( int i = 0; i < item_list.size(); ++i ){
|
|
|
t_itemid nameid;
|
|
|
unsigned short amount;
|
|
|
int value;
|
|
@@ -2734,7 +2733,7 @@ e_purchase_result npc_buylist(struct map_session_data* sd, uint16 n, struct s_np
|
|
|
|
|
|
#if PACKETVER >= 20131223
|
|
|
if (nd->subtype == NPCTYPE_MARKETSHOP) {
|
|
|
- if (item_list[i].qty > shop[j].qty)
|
|
|
+ if (shop[j].qty >= 0 && item_list[i].qty > shop[j].qty)
|
|
|
return e_purchase_result::PURCHASE_FAIL_COUNT;
|
|
|
market_index[i] = j;
|
|
|
}
|
|
@@ -2778,7 +2777,7 @@ e_purchase_result npc_buylist(struct map_session_data* sd, uint16 n, struct s_np
|
|
|
}
|
|
|
|
|
|
if (nd->master_nd){ //Script-based shops.
|
|
|
- npc_buylist_sub(sd,n,item_list,nd->master_nd);
|
|
|
+ npc_buylist_sub(sd,item_list,nd->master_nd);
|
|
|
return e_purchase_result::PURCHASE_SUCCEED;
|
|
|
}
|
|
|
|
|
@@ -2792,17 +2791,20 @@ e_purchase_result npc_buylist(struct map_session_data* sd, uint16 n, struct s_np
|
|
|
|
|
|
pc_payzeny(sd, (int)z, LOG_TYPE_NPC, NULL);
|
|
|
|
|
|
- for( i = 0; i < n; ++i ) {
|
|
|
+ for( int i = 0; i < item_list.size(); ++i ) {
|
|
|
t_itemid nameid = item_list[i].nameid;
|
|
|
unsigned short amount = item_list[i].qty;
|
|
|
|
|
|
#if PACKETVER >= 20131223
|
|
|
if (nd->subtype == NPCTYPE_MARKETSHOP) {
|
|
|
j = market_index[i];
|
|
|
- if (amount > shop[j].qty)
|
|
|
- return e_purchase_result::PURCHASE_FAIL_MONEY;
|
|
|
- shop[j].qty -= amount;
|
|
|
- npc_market_tosql(nd->exname, &shop[j]);
|
|
|
+
|
|
|
+ if( shop[j].qty >= 0 ){
|
|
|
+ if (amount > shop[j].qty)
|
|
|
+ return e_purchase_result::PURCHASE_FAIL_COUNT;
|
|
|
+ shop[j].qty -= amount;
|
|
|
+ npc_market_tosql(nd->exname, &shop[j]);
|
|
|
+ }
|
|
|
}
|
|
|
#endif
|
|
|
|
|
@@ -3979,7 +3981,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
|
|
nd->u.shop.count = 0;
|
|
|
while ( p ) {
|
|
|
t_itemid nameid2;
|
|
|
- unsigned short qty = 0;
|
|
|
+ int32 qty = -1;
|
|
|
int value;
|
|
|
struct item_data* id;
|
|
|
bool skip = false;
|
|
@@ -3989,7 +3991,7 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
|
|
switch(type) {
|
|
|
case NPCTYPE_MARKETSHOP:
|
|
|
#if PACKETVER >= 20131223
|
|
|
- if (sscanf(p, ",%u:%11d:%6hu", &nameid2, &value, &qty) != 3) {
|
|
|
+ if (sscanf(p, ",%u:%11d:%11d", &nameid2, &value, &qty) != 3) {
|
|
|
ShowError("npc_parse_shop: (MARKETSHOP) Invalid item definition in file '%s', line '%d'. Ignoring the rest of the line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer, start - buffer), w1, w2, w3, w4);
|
|
|
skip = true;
|
|
|
}
|
|
@@ -4023,10 +4025,10 @@ static const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const
|
|
|
ShowWarning("npc_parse_shop: Item %s [%u] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) at file '%s', line '%d'.\n",
|
|
|
id->name.c_str(), nameid2, value, (int)(value*0.75), id->value_sell, (int)(id->value_sell*1.24), filepath, strline(buffer,start-buffer));
|
|
|
}
|
|
|
- if (type == NPCTYPE_MARKETSHOP && (!qty || qty > UINT16_MAX)) {
|
|
|
- ShowWarning("npc_parse_shop: Item %s [%u] is stocked with invalid value %d, changed to 1. File '%s', line '%d'.\n",
|
|
|
+ if (type == NPCTYPE_MARKETSHOP && qty < -1) {
|
|
|
+ ShowWarning("npc_parse_shop: Item %s [%u] is stocked with invalid value %hd, changed to unlimited (-1). File '%s', line '%d'.\n",
|
|
|
id->name.c_str(), nameid2, qty, filepath, strline(buffer,start-buffer));
|
|
|
- qty = 1;
|
|
|
+ qty = -1;
|
|
|
}
|
|
|
//for logs filters, atcommands and iteminfo script command
|
|
|
if( id->maxchance == 0 )
|
|
@@ -4626,7 +4628,7 @@ int npc_instancedestroy(struct npc_data* nd)
|
|
|
**/
|
|
|
void npc_market_tosql(const char *exname, struct npc_item_list *list) {
|
|
|
SqlStmt* stmt = SqlStmt_Malloc(mmysql_handle);
|
|
|
- if (SQL_ERROR == SqlStmt_Prepare(stmt, "REPLACE INTO `%s` (`name`,`nameid`,`price`,`amount`,`flag`) VALUES ('%s','%u','%d','%hu','%" PRIu8 "')",
|
|
|
+ if (SQL_ERROR == SqlStmt_Prepare(stmt, "REPLACE INTO `%s` (`name`,`nameid`,`price`,`amount`,`flag`) VALUES ('%s','%u','%d','%d','%" PRIu8 "')",
|
|
|
market_table, exname, list->nameid, list->value, list->qty, list->flag) ||
|
|
|
SQL_ERROR == SqlStmt_Execute(stmt))
|
|
|
SqlStmt_ShowDebug(stmt);
|
|
@@ -4709,7 +4711,7 @@ static int npc_market_checkall_sub(DBKey key, DBData *data, va_list ap) {
|
|
|
npc_market_tosql(nd->exname, &nd->u.shop.shop_item[j]);
|
|
|
}
|
|
|
else { // Removing "out-of-date" entry
|
|
|
- ShowError("npc_market_checkall_sub: NPC '%s' does not sell item %u (qty %hu), deleting...\n", nd->exname, list->nameid, list->qty);
|
|
|
+ ShowError("npc_market_checkall_sub: NPC '%s' does not sell item %u (qty %d), deleting...\n", nd->exname, list->nameid, list->qty);
|
|
|
npc_market_delfromsql(nd->exname, list->nameid);
|
|
|
}
|
|
|
}
|