summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map/clif.c19
-rw-r--r--src/map/npc.c42
-rw-r--r--src/map/npc.h4
3 files changed, 37 insertions, 28 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 5e0c6f568..9e0977cc4 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -15434,16 +15434,25 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
int len = RFIFOW(fd,2);
int points = RFIFOL(fd,4);
int count = RFIFOW(fd,8);
- unsigned short *item_list = NULL;
+ struct itemlist item_list = { 0 };
+ int i;
if( len < 10 || len != 10 + count * 4) {
ShowWarning("Player %d sent incorrect cash shop buy packet (len %d:%d)!\n", sd->status.char_id, len, 10 + count * 4);
return;
}
- item_list = aMalloc(sizeof(*item_list) * 2 * count);
- memcpy(item_list, RFIFOP(fd,10), sizeof(*item_list) * 2 * count);
- fail = npc->cashshop_buylist(sd,points,count,item_list);
- aFree(item_list);
+ VECTOR_INIT(item_list);
+ VECTOR_ENSURE(item_list, count, 1);
+ for (i = 0; i < count; i++) {
+ struct itemlist_entry entry = { 0 };
+
+ entry.amount = RFIFOW(fd, 10 + 4 * i);
+ entry.id = RFIFOW(fd, 10 + 4 * i + 2); // Nameid
+
+ VECTOR_PUSH(item_list, entry);
+ }
+ fail = npc->cashshop_buylist(sd, points, &item_list);
+ VECTOR_CLEAR(item_list);
#endif
}
diff --git a/src/map/npc.c b/src/map/npc.c
index 7ef0ba36a..793ca9a03 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -1386,8 +1386,9 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) {
/*==========================================
* Cash Shop Buy List
*------------------------------------------*/
-int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list) {
- int i, j, nameid, amount, new_, w, vt;
+int npc_cashshop_buylist(struct map_session_data *sd, int points, struct itemlist *item_list)
+{
+ int i, j, new_, w, vt;
struct npc_data *nd = NULL;
struct npc_item_list *shop = NULL;
unsigned short shop_size = 0;
@@ -1395,7 +1396,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
if( sd->state.trading )
return ERROR_TYPE_EXCHANGE;
- if( count <= 0 )
+ if (VECTOR_LENGTH(*item_list) <= 0)
return ERROR_TYPE_ITEM_ID;
if( points < 0 )
@@ -1421,24 +1422,23 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
vt = 0; // Global Value
// Validating Process ----------------------------------------------------
- for( i = 0; i < count; i++ ) {
- nameid = item_list[i*2+1];
- amount = item_list[i*2+0];
+ for (i = 0; i < VECTOR_LENGTH(*item_list); i++) {
+ struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i);
- if( !itemdb->exists(nameid) || amount <= 0 )
+ if (!itemdb->exists(entry->id) || entry->amount <= 0)
return ERROR_TYPE_ITEM_ID;
- ARR_FIND(0,shop_size,j,shop[j].nameid == nameid);
- if( j == shop_size || shop[j].value <= 0 )
+ ARR_FIND(0,shop_size,j,shop[j].nameid == entry->id);
+ if (j == shop_size || shop[j].value <= 0)
return ERROR_TYPE_ITEM_ID;
- if( !itemdb->isstackable(nameid) && amount > 1 ) {
+ if (!itemdb->isstackable(entry->id) && entry->amount > 1) {
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of non-stackable item %d!\n",
- sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid);
- amount = item_list[i*2+0] = 1;
+ sd->status.name, sd->status.account_id, sd->status.char_id, entry->amount, entry->id);
+ entry->amount = 1;
}
- switch( pc->checkadditem(sd,nameid,amount) ) {
+ switch (pc->checkadditem(sd, entry->id, entry->amount)) {
case ADDITEM_NEW:
new_++;
break;
@@ -1446,8 +1446,8 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
return ERROR_TYPE_INVENTORY_WEIGHT;
}
- vt += shop[j].value * amount;
- w += itemdb_weight(nameid) * amount;
+ vt += shop[j].value * entry->amount;
+ w += itemdb_weight(entry->id) * entry->amount;
}
if( w + sd->weight > sd->max_weight )
@@ -1468,18 +1468,16 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
pc->paycash(sd,vt,points);
}
// Delivery Process ----------------------------------------------------
- for( i = 0; i < count; i++ ) {
+ for (i = 0; i < VECTOR_LENGTH(*item_list); i++) {
+ struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i);
struct item item_tmp;
- nameid = item_list[i*2+1];
- amount = item_list[i*2+0];
-
memset(&item_tmp,0,sizeof(item_tmp));
- if( !pet->create_egg(sd,nameid) ) {
- item_tmp.nameid = nameid;
+ if (!pet->create_egg(sd, entry->id)) {
+ item_tmp.nameid = entry->id;
item_tmp.identify = 1;
- pc->additem(sd,&item_tmp,amount,LOG_TYPE_NPC);
+ pc->additem(sd, &item_tmp, entry->amount, LOG_TYPE_NPC);
}
}
diff --git a/src/map/npc.h b/src/map/npc.h
index be878933e..2731d51db 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -29,7 +29,9 @@
#include <pcre.h>
+/* Forward declarations */
struct hplugin_data_store;
+struct itemlist; // map/itemdb.h
struct view_data;
enum npc_parse_options {
@@ -230,7 +232,7 @@ struct npc_interface {
int (*click) (struct map_session_data *sd, struct npc_data *nd);
int (*scriptcont) (struct map_session_data *sd, int id, bool closing);
int (*buysellsel) (struct map_session_data *sd, int id, int type);
- int (*cashshop_buylist) (struct map_session_data *sd, int points, int count, unsigned short *item_list);
+ int (*cashshop_buylist) (struct map_session_data *sd, int points, struct itemlist *item_list);
int (*buylist_sub) (struct map_session_data *sd, int n, unsigned short *item_list, struct npc_data *nd);
int (*cashshop_buy) (struct map_session_data *sd, int nameid, int amount, int points);
int (*buylist) (struct map_session_data *sd, int n, unsigned short *item_list);