summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2020-01-30 07:18:03 +0300
committerAndrei Karas <akaras@inbox.ru>2020-02-09 21:30:38 +0300
commitf1dd964511896963e987004c1d21750a003c760c (patch)
tree69573fe295fc2dbe0ffa7c7636047393823048a0
parent3daa68bc406ab062190774f55ea21769a73f825b (diff)
downloadhercules-f1dd964511896963e987004c1d21750a003c760c.tar.gz
hercules-f1dd964511896963e987004c1d21750a003c760c.tar.bz2
hercules-f1dd964511896963e987004c1d21750a003c760c.tar.xz
hercules-f1dd964511896963e987004c1d21750a003c760c.zip
Add expanded barter shop packets
-rw-r--r--src/map/clif.c107
-rw-r--r--src/map/clif.h2
-rw-r--r--src/map/packets.h3
-rw-r--r--src/map/packets_struct.h57
4 files changed, 168 insertions, 1 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 4418b2311..30b01d7f0 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -23214,6 +23214,111 @@ static void clif_parse_npc_expanded_barter_closed(int fd, struct map_session_dat
{
}
+#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106 || PACKETVER_ZERO_NUM >= 20191127
+#define NEXT_EXPANDED_BARTER_ITEM(var, count) \
+ var = (struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub *)((char*)item + \
+ sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub) + \
+ count * sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2))
+#endif
+
+static void clif_npc_expanded_barter_open(struct map_session_data *sd, struct npc_data *nd)
+{
+#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106 || PACKETVER_ZERO_NUM >= 20191127
+ nullpo_retv(sd);
+ nullpo_retv(nd);
+ struct npc_item_list *shop = nd->u.scr.shop->item;
+ const int shop_size = nd->u.scr.shop->items;
+
+ int items_count = 0;
+ int currencies_count = 0;
+ struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN *packet = (struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN*)&packet_buf[0];
+ STATIC_ASSERT(sizeof(packet_buf) > sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN), "packet_buf size too small");
+ int buf_left = sizeof(packet_buf) - sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN);
+ packet->packetType = HEADER_ZC_NPC_EXPANDED_BARTER_OPEN;
+ struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub *item = &packet->items[0];
+
+ for (int i = 0; i < shop_size && buf_left >= sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub); i++) {
+ if (shop[i].nameid) {
+ struct item_data *id = itemdb->exists(shop[i].nameid);
+ if (id == NULL)
+ continue;
+
+ item->nameid = shop[i].nameid;
+ item->type = itemtype(id->type);
+ item->amount = shop[i].qty;
+ item->weight = id->weight * 10;
+ item->index = i;
+ item->zeny = shop[i].value;
+ item->currency_count = 0;
+ buf_left -= sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub);
+ items_count ++;
+ int count = shop[i].value2;
+ if (buf_left < sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2) * count) {
+ NEXT_EXPANDED_BARTER_ITEM(item, 0);
+ break;
+ }
+ for (int j = 0; j < count; j ++) {
+ struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2 *packet_currency = &item->currencies[j];
+ struct npc_barter_currency *currency = &shop[i].currency[j];
+ struct item_data *id2 = itemdb->exists(currency->nameid);
+ if (id2 == NULL)
+ continue;
+ packet_currency->nameid = currency->nameid;
+ if (currency->refine == -1)
+ packet_currency->refine_level = 0;
+ else
+ packet_currency->refine_level = currency->refine;
+ packet_currency->amount = currency->amount;
+ packet_currency->type = itemtype(id2->type);
+ currencies_count ++;
+ item->currency_count ++;
+ }
+ NEXT_EXPANDED_BARTER_ITEM(item, item->currency_count);
+ }
+ }
+
+ packet->items_count = items_count;
+ packet->packetLength = sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN) +
+ sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub) * items_count +
+ sizeof(struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2) * currencies_count;
+ clif->send(packet, packet->packetLength, &sd->bl, SELF);
+#endif
+}
+
+#undef NEXT_EXPANDED_BARTER_ITEM
+
+static void clif_parse_npc_expanded_barter_purchase(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+static void clif_parse_npc_expanded_barter_purchase(int fd, struct map_session_data *sd)
+{
+#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828
+ if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ return;
+
+ const struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE *const p = RP2PTR(fd);
+ int count = (p->packetLength - sizeof(struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE)) / sizeof p->list[0];
+ struct barteritemlist item_list;
+
+ Assert_retv(count >= 0 && count <= sd->status.inventorySize);
+
+ VECTOR_INIT(item_list);
+ VECTOR_ENSURE(item_list, count, 1);
+
+ for (int i = 0; i < count; i++) {
+ struct barter_itemlist_entry entry = { 0 };
+ entry.addId = p->list[i].itemId;
+ entry.addAmount = p->list[i].amount;
+ entry.removeIndex = -1;
+ entry.shopIndex = p->list[i].shopIndex;
+ VECTOR_PUSH(item_list, entry);
+ }
+
+ int response = npc->expanded_barter_buylist(sd, &item_list);
+ clif->npc_buy_result(sd, response);
+
+ VECTOR_CLEAR(item_list);
+#endif
+}
+
static void clif_parse_clientVersion(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
static void clif_parse_clientVersion(int fd, struct map_session_data *sd)
{
@@ -24771,6 +24876,8 @@ void clif_defaults(void)
clif->npc_barter_open = clif_npc_barter_open;
clif->pNPCBarterClosed = clif_parse_NPCBarterClosed;
clif->pNPCBarterPurchase = clif_parse_NPCBarterPurchase;
+ clif->npc_expanded_barter_open = clif_npc_expanded_barter_open;
+ clif->pNPCExpandedBarterPurchase = clif_parse_npc_expanded_barter_purchase;
clif->pNPCExpandedBarterClosed = clif_parse_npc_expanded_barter_closed;
clif->pClientVersion = clif_parse_clientVersion;
clif->pPing = clif_parse_ping;
diff --git a/src/map/clif.h b/src/map/clif.h
index d0afa0987..252dfefe1 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -1664,6 +1664,8 @@ struct clif_interface {
void (*pNPCBarterClosed) (int fd, struct map_session_data *sd);
void (*pNPCBarterPurchase) (int fd, struct map_session_data *sd);
void (*pNPCExpandedBarterClosed) (int fd, struct map_session_data *sd);
+ void (*pNPCExpandedBarterPurchase) (int fd, struct map_session_data *sd);
+ void (*npc_expanded_barter_open) (struct map_session_data *sd, struct npc_data *nd);
void (*pClientVersion) (int fd, struct map_session_data *sd);
void (*pPing) (int fd, struct map_session_data *sd);
void (*ping) (struct map_session_data *sd);
diff --git a/src/map/packets.h b/src/map/packets.h
index ac35d0dcb..1e6dc71bc 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -1984,7 +1984,8 @@ packet(0x96e,clif->ackmergeitems);
#endif
#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828
- packet(0x0b12,clif->pNPCExpandedBarterClosed);
+ packet(0x0b57,clif->pNPCExpandedBarterPurchase);
+ packet(0x0b58,clif->pNPCExpandedBarterClosed);
#endif
#if PACKETVER >= 20191224
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index b7376f972..f00d5765d 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -3795,6 +3795,63 @@ struct PACKET_CZ_NPC_EXPANDED_BARTER_CLOSE {
DEFINE_PACKET_HEADER(CZ_NPC_EXPANDED_BARTER_CLOSE, 0x0b58);
#endif
+#if PACKETVER_MAIN_NUM >= 20191120 || PACKETVER_RE_NUM >= 20191106 || PACKETVER_ZERO_NUM >= 20191127
+struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2 {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+ uint32 nameid;
+#else
+ uint16 nameid;
+#endif
+ uint16 refine_level;
+ uint32 amount;
+ uint16 type;
+} __attribute__((packed));
+
+struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+ uint32 nameid;
+#else
+ uint16 nameid;
+#endif
+ uint16 type;
+ uint32 amount;
+ uint32 weight;
+ uint32 index;
+ uint32 zeny;
+ uint32 currency_count;
+ struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub2 currencies[];
+} __attribute__((packed));
+
+struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN {
+ int16 packetType;
+ int16 packetLength;
+ int32 items_count;
+ struct PACKET_ZC_NPC_EXPANDED_BARTER_OPEN_sub items[];
+} __attribute__((packed));
+
+DEFINE_PACKET_HEADER(ZC_NPC_EXPANDED_BARTER_OPEN, 0x0b56);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190904 || PACKETVER_RE_NUM >= 20190904 || PACKETVER_ZERO_NUM >= 20190828
+struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE_sub {
+#if PACKETVER_MAIN_NUM >= 20181121 || PACKETVER_RE_NUM >= 20180704 || PACKETVER_ZERO_NUM >= 20181114
+ uint32 itemId;
+#else
+ uint16 itemId;
+#endif
+ uint32 shopIndex;
+ uint32 amount;
+} __attribute__((packed));
+
+struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE {
+ int16 packetType;
+ int16 packetLength;
+ struct PACKET_CZ_NPC_EXPANDED_BARTER_PURCHASE_sub list[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_NPC_EXPANDED_BARTER_PURCHASE, 0x0b57);
+#endif
+
+
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#pragma pack(pop)
#endif // not NetBSD < 6 / Solaris