diff --git a/src/ItemData.cc b/src/ItemData.cc index a72ff8cc..a0ff5d53 100644 --- a/src/ItemData.cc +++ b/src/ItemData.cc @@ -157,6 +157,12 @@ size_t ItemData::max_stack_size() const { return max_stack_size_for_item(this->data1[0], this->data1[1]); } +void ItemData::enforce_min_stack_size() { + if (this->stack_size() == 0) { + this->data1[5] = 1; + } +} + bool ItemData::is_common_consumable(uint32_t primary_identifier) { if (primary_identifier == 0x030200) { return false; diff --git a/src/ItemData.hh b/src/ItemData.hh index e0506969..900caaf8 100644 --- a/src/ItemData.hh +++ b/src/ItemData.hh @@ -147,6 +147,7 @@ struct ItemData { // 0x14 bytes bool is_stackable() const; size_t stack_size() const; size_t max_stack_size() const; + void enforce_min_stack_size(); static bool is_common_consumable(uint32_t primary_identifier); bool is_common_consumable() const; diff --git a/src/ItemNameIndex.cc b/src/ItemNameIndex.cc index 490af81a..735edcf4 100644 --- a/src/ItemNameIndex.cc +++ b/src/ItemNameIndex.cc @@ -397,9 +397,7 @@ ItemData ItemNameIndex::parse_item_description(Version version, const std::strin } } } - if (ret.stack_size() == 0) { - ret.data1[5] = 1; - } + ret.enforce_min_stack_size(); return ret; } diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index e9381538..09f8685d 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -2082,6 +2082,7 @@ void on_item_reward_request_bb(shared_ptr c, uint8_t, uint8_t, const voi ItemData item; item = cmd.item_data; + item.enforce_min_stack_size(); item.id = l->generate_item_id(c->lobby_client_id); c->character()->add_item(item); send_create_inventory_item_to_lobby(c, c->lobby_client_id, item); @@ -2433,6 +2434,7 @@ static void on_quest_exchange_item_bb(shared_ptr c, uint8_t, uint8_t, co // TODO: We probably should use an allow-list here to prevent the client // from creating arbitrary items if cheat mode is disabled. ItemData new_item = cmd.replace_item; + new_item.enforce_min_stack_size(); new_item.id = l->generate_item_id(c->lobby_client_id); p->add_item(new_item); send_create_inventory_item_to_lobby(c, c->lobby_client_id, new_item); @@ -2475,6 +2477,7 @@ static void on_photon_drop_exchange_for_item_bb(shared_ptr c, uint8_t, u // TODO: We probably should use an allow-list here to prevent the client // from creating arbitrary items if cheat mode is disabled. ItemData new_item = cmd.new_item; + new_item.enforce_min_stack_size(); new_item.id = l->generate_item_id(c->lobby_client_id); p->add_item(new_item); send_create_inventory_item_to_lobby(c, c->lobby_client_id, new_item); @@ -2556,6 +2559,7 @@ static void on_secret_lottery_ticket_exchange_bb(shared_ptr c, uint8_t, ItemData item = (s->secret_lottery_results.size() == 1) ? s->secret_lottery_results[0] : s->secret_lottery_results[random_object() % s->secret_lottery_results.size()]; + item.enforce_min_stack_size(); item.id = l->generate_item_id(c->lobby_client_id); p->add_item(item); send_create_inventory_item_to_lobby(c, c->lobby_client_id, item); @@ -2608,6 +2612,8 @@ static void on_quest_F95E_result_bb(shared_ptr c, uint8_t, uint8_t, cons item.data2d = 100; } else if (item.data1[0] == 0x00) { item.data1[4] |= 0x80; // Unidentified + } else { + item.enforce_min_stack_size(); } item.id = l->generate_item_id(0xFF); @@ -2643,6 +2649,7 @@ static void on_quest_F95F_result_bb(shared_ptr c, uint8_t, uint8_t, cons send_command_t(c, 0x60, 0x00, cmd_6xDB); ItemData new_item = result.second; + new_item.enforce_min_stack_size(); new_item.id = l->generate_item_id(c->lobby_client_id); p->add_item(new_item); send_create_inventory_item_to_lobby(c, c->lobby_client_id, new_item); @@ -2674,6 +2681,7 @@ static void on_momoka_item_exchange_bb(shared_ptr c, uint8_t, uint8_t, c // TODO: We probably should use an allow-list here to prevent the client // from creating arbitrary items if cheat mode is disabled. ItemData new_item = cmd.replace_item; + new_item.enforce_min_stack_size(); new_item.id = l->generate_item_id(c->lobby_client_id); p->add_item(new_item); send_create_inventory_item_to_lobby(c, c->lobby_client_id, new_item);