Skip to content

Commit

Permalink
fix: store item indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
dudantas committed Aug 30, 2023
1 parent e29bd67 commit 0761e77
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1935,7 +1935,7 @@ void Player::onCloseContainer(const Container* container) {
}

void Player::onSendContainer(const Container* container) {
if (!client) {
if (!client || !container) {
return;
}

Expand Down
13 changes: 11 additions & 2 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,12 @@ Thing* Game::internalGetThing(Player* player, const Position &pos, int32_t index
}

uint8_t slot = pos.z;
return parentContainer->getItemByIndex(player->getContainerIndex(fromCid) + slot);
auto containerIndex = player->getContainerIndex(fromCid) + slot;
if (parentContainer->isStoreInboxFiltered()) {
return parentContainer->getFilteredItemByIndex(containerIndex);
}

return parentContainer->getItemByIndex(containerIndex);
} else if (pos.y == 0x20 || pos.y == 0x21) {
// '0x20' -> From depot.
// '0x21' -> From inbox.
Expand Down Expand Up @@ -1853,7 +1858,7 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder,
return retMaxCount;
}

// looting analyser from this point forward
// Actor related actions
if (fromCylinder && actor && toCylinder) {
if (!fromCylinder->getContainer() || !actor->getPlayer() || !toCylinder->getContainer()) {
return ret;
Expand All @@ -1870,9 +1875,13 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder,
return ret;
}

// Looting analyser
if (it.isCorpse && toCylinder->getContainer()->getTopParent() == player && item->getIsLootTrackeable()) {
player->sendLootStats(item, static_cast<uint8_t>(item->getItemCount()));
}

player->onSendContainer(toCylinder->getContainer());
player->onSendContainer(fromCylinder->getContainer());
}
}

Expand Down
31 changes: 30 additions & 1 deletion src/items/containers/container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
Container::Container(uint16_t type) :
Container(type, items[type].maxItems) {
m_maxItems = static_cast<uint32_t>(g_configManager().getNumber(MAX_CONTAINER_ITEM));
if (getID() == ITEM_GOLD_POUCH || getID() == ITEM_STORE_INBOX) {
if (getID() == ITEM_GOLD_POUCH || isStoreInbox()) {
pagination = true;
m_maxItems = 2000;
maxSize = 32;
Expand Down Expand Up @@ -232,10 +232,39 @@ std::ostringstream &Container::getContentDescription(std::ostringstream &os, boo
return os;
}

std::deque<Item*> Container::getStoreInboxFilteredItems() const {
const auto enumName = getAttribute<std::string>(ItemAttribute_t::STORE_INBOX_CATEGORY);
ItemDeque storeInboxFilteredList;
if (isStoreInboxFiltered()) {
for (Item* item : getItemList()) {
auto attribute = item->getCustomAttribute("unWrapId");
uint16_t unWrapId = attribute ? static_cast<uint16_t>(attribute->getInteger()) : 0;
if (unWrapId != 0) {
const auto &itemType = Item::items.getItemType(unWrapId);
if (itemType.m_primaryType == asLowerCaseString(enumName)) {
storeInboxFilteredList.push_back(item);
}
}
}
}

return storeInboxFilteredList;
}

Item* Container::getFilteredItemByIndex(size_t index) const {
const auto &filteredItems = getStoreInboxFilteredItems();
if (index >= filteredItems.size()) {
return nullptr;
}

return filteredItems[index];
}

Item* Container::getItemByIndex(size_t index) const {
if (index >= size()) {
return nullptr;
}

return itemlist[index];
}

Expand Down
15 changes: 15 additions & 0 deletions src/items/containers/container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ class Container : public Item, public Cylinder {
bool hasParent() const;
void addItem(Item* item);
StashContainerList getStowableItems() const;
std::deque<Item*> getStoreInboxFilteredItems() const;
Item* getFilteredItemByIndex(size_t index) const;
Item* getItemByIndex(size_t index) const;
bool isHoldingItem(const Item* item) const;
bool isHoldingItemWithId(const uint16_t id) const;
Expand All @@ -131,6 +133,19 @@ class Container : public Item, public Cylinder {
return pagination;
}

bool isStoreInbox() const {
return getID() == ITEM_STORE_INBOX;
}

bool isStoreInboxFiltered() const {
auto attribute = getAttribute<std::string>(ItemAttribute_t::STORE_INBOX_CATEGORY);
if (isStoreInbox() && !attribute.empty() && attribute != "All") {
return true;
}

return false;
}

// cylinder implementations
virtual ReturnValue queryAdd(int32_t index, const Thing &thing, uint32_t count, uint32_t flags, Creature* actor = nullptr) const override;
ReturnValue queryMaxCount(int32_t index, const Thing &thing, uint32_t count, uint32_t &maxQueryCount, uint32_t flags) const override final;
Expand Down
2 changes: 1 addition & 1 deletion src/lua/functions/creatures/player/player_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1902,7 +1902,7 @@ int PlayerFunctions::luaPlayerSendUpdateContainer(lua_State* L) {
return 1;
}

Container* container = getUserdata<Container>(L, 2);
const auto container = getUserdata<Container>(L, 2);
if (!container) {
reportErrorFunc("Container is nullptr");
return 1;
Expand Down
49 changes: 25 additions & 24 deletions src/server/network/protocol/protocolgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,17 +218,16 @@ namespace {
* @param msg The network message to send the category to.
*/
template <typename T>
void sendContainerCategory(NetworkMessage &msg, uint8_t categoryType = 0) {
void sendContainerCategory(NetworkMessage &msg, std::deque<T> categories = {}, uint8_t categoryType = 0) {
msg.addByte(categoryType);

const uint8_t enumCount = magic_enum::enum_count<T>();
msg.addByte(enumCount - 1);

for (auto value : magic_enum::enum_values<T>()) {
g_logger().debug("Sendding category type '{}', categories total size '{}'", categoryType, categories.size());
msg.addByte(categories.size());
for (auto value : categories) {
if (value == T::All) {
continue;
}

g_logger().debug("Sendding category number '{}', category name '{}'", static_cast<uint8_t>(value), magic_enum::enum_name(value).data());
msg.addByte(static_cast<uint8_t>(value));
msg.addString(magic_enum::enum_name(value).data());
}
Expand Down Expand Up @@ -4254,21 +4253,7 @@ void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool h
msg.addString(container->getName());
}

const auto &enumName = container->getAttribute<std::string>(ItemAttribute_t::STORE_INBOX_CATEGORY);
uint32_t totalCountToSend = 0;
std::vector<Item*> itemsStoreInboxToSend;
if (container->getID() == ITEM_STORE_INBOX && enumName != "All") {
for (Item* item : container->getItemList()) {
uint16_t unWrapId = item->getCustomAttribute("unWrapId") ? static_cast<uint16_t>(item->getCustomAttribute("unWrapId")->getInteger()) : 0;
if (unWrapId != 0) {
const auto &itemType = Item::items.getItemType(unWrapId);
if (itemType.m_primaryType == asLowerCaseString(enumName)) {
itemsStoreInboxToSend.push_back(item);
totalCountToSend++;
}
}
}
}
const auto itemsStoreInboxToSend = container->getStoreInboxFilteredItems();

msg.addByte(container->capacity());

Expand All @@ -4283,8 +4268,8 @@ void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool h
msg.addByte(container->hasPagination() ? 0x01 : 0x00); // Pagination

uint32_t containerSize = container->size();
if (totalCountToSend != 0) {
containerSize = totalCountToSend;
if (!itemsStoreInboxToSend.empty()) {
containerSize = itemsStoreInboxToSend.size();
}
msg.add<uint16_t>(containerSize);
msg.add<uint16_t>(firstIndex);
Expand Down Expand Up @@ -4316,9 +4301,25 @@ void ProtocolGame::sendContainer(uint8_t cid, const Container* container, bool h

if (!oldProtocol) {
if (container->getID() == ITEM_STORE_INBOX) {
std::deque<StoreInboxCategory_t> validCategories;
for (const auto item : container->getItemList()) {
auto attribute = item->getCustomAttribute("unWrapId");
uint16_t unWrapId = attribute ? static_cast<uint16_t>(attribute->getInteger()) : 0;
if (unWrapId != 0) {
const auto &itemType = Item::items.getItemType(unWrapId);
auto category = magic_enum::enum_cast<StoreInboxCategory_t>(toPascalCase(itemType.m_primaryType));
g_logger().debug("Store unwrap item '{}', primary type {}", unWrapId, toPascalCase(itemType.m_primaryType));
if (category.has_value()) {
g_logger().debug("Adding valid category {}", static_cast<uint8_t>(category.value()));
validCategories.push_back(category.value());
}
}
}

const auto enumName = container->getAttribute<std::string>(ItemAttribute_t::STORE_INBOX_CATEGORY);
auto category = magic_enum::enum_cast<StoreInboxCategory_t>(enumName);
if (category.has_value()) {
sendContainerCategory<StoreInboxCategory_t>(msg, static_cast<uint8_t>(category.value()));
sendContainerCategory<StoreInboxCategory_t>(msg, validCategories, static_cast<uint8_t>(category.value()));
} else {
sendContainerCategory<StoreInboxCategory_t>(msg);
}
Expand Down

0 comments on commit 0761e77

Please sign in to comment.