Skip to content

Commit

Permalink
feat: add again remove reward containers if is empty
Browse files Browse the repository at this point in the history
  • Loading branch information
dudantas committed Sep 16, 2023
1 parent 75d84a5 commit 59bc66f
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 2 deletions.
21 changes: 21 additions & 0 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -803,12 +803,33 @@ void Player::closeContainer(uint8_t cid) {
OpenContainer openContainer = it->second;
Container* container = openContainer.container;

if (container && container->isAnyKindOfRewardChest() && !hasOtherRewardContainerOpen(container)) {
removeEmptyRewards();
}
openContainers.erase(it);
if (container && container->getID() == ITEM_BROWSEFIELD) {
container->decrementReferenceCounter();
}
}

void Player::removeEmptyRewards() {
std::erase_if(rewardMap, [this](const auto &rewardBag) {
auto [id, reward] = rewardBag;
if (reward->empty()) {
getRewardChest()->removeItem(reward);
reward->decrementReferenceCounter();
return true;
}
return false;
});
}

bool Player::hasOtherRewardContainerOpen(const Container* container) const {
return std::ranges::any_of(openContainers.begin(), openContainers.end(), [container](const auto &containerPair) {
return containerPair.second.container != container && containerPair.second.container->isAnyKindOfRewardContainer();
});
}

void Player::setContainerIndex(uint8_t cid, uint16_t index) {
auto it = openContainers.find(cid);
if (it == openContainers.end()) {
Expand Down
3 changes: 3 additions & 0 deletions src/creatures/players/player.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2898,4 +2898,7 @@ class Player final : public Creature, public Cylinder, public Bankable {
void updateDamageReductionFromItemImbuement(std::array<double_t, COMBAT_COUNT> &combatReductionMap, Item* item, uint16_t combatTypeIndex) const;
void updateDamageReductionFromItemAbility(std::array<double_t, COMBAT_COUNT> &combatReductionMap, const Item* item, uint16_t combatTypeIndex) const;
double_t calculateDamageReduction(double_t currentTotal, int16_t resistance) const;

void removeEmptyRewards();
bool hasOtherRewardContainerOpen(const Container* container) const;
};
4 changes: 2 additions & 2 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2716,7 +2716,7 @@ ReturnValue Game::collectRewardChestItems(Player* player, uint32_t maxMoveItems
if (limitMove) {
lootedItemsMessage = fmt::format("You can only collect {} items at a time. {} of {} objects were picked up.", maxMoveItems, movedRewardItems, rewardCount);
player->sendTextMessage(MESSAGE_EVENT_ADVANCE, lootedItemsMessage);
return RETURNVALUE_NOERROR;
return RETURNVALUE_NOTPOSSIBLE;
}

ObjectCategory_t category = getObjectCategory(item);
Expand All @@ -2729,7 +2729,7 @@ ReturnValue Game::collectRewardChestItems(Player* player, uint32_t maxMoveItems
player->sendTextMessage(MESSAGE_EVENT_ADVANCE, lootedItemsMessage);

if (movedRewardItems == 0) {
return RETURNVALUE_NOTPOSSIBLE;
return RETURNVALUE_NOTENOUGHROOM;
}

return RETURNVALUE_NOERROR;
Expand Down
23 changes: 23 additions & 0 deletions src/items/containers/container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,29 @@ bool Container::isHoldingItemWithId(const uint16_t id) const {
return false;
}

bool Container::isInsideContainerWithId(const uint16_t id) const {
auto nextParent = parent;
while (nextParent != nullptr && nextParent->getContainer()) {
if (nextParent->getContainer()->getID() == id) {
return true;
}
nextParent = nextParent->getRealParent();
}
return false;
}

bool Container::isAnyKindOfRewardChest() const {
return getID() == ITEM_REWARD_CHEST || getID() == ITEM_REWARD_CONTAINER && parent && parent->getContainer() && parent->getContainer()->getID() == ITEM_REWARD_CHEST || isBrowseFieldAndHoldsRewardChest();
}

bool Container::isAnyKindOfRewardContainer() const {
return getID() == ITEM_REWARD_CHEST || getID() == ITEM_REWARD_CONTAINER || isHoldingItemWithId(ITEM_REWARD_CONTAINER) || isInsideContainerWithId(ITEM_REWARD_CONTAINER);
}

bool Container::isBrowseFieldAndHoldsRewardChest() const {
return getID() == ITEM_BROWSEFIELD && isHoldingItemWithId(ITEM_REWARD_CHEST);
}

void Container::onAddContainerItem(Item* item) {
SpectatorHashSet spectators;
g_game().map.getSpectators(spectators, getPosition(), false, true, 2, 2, 2, 2);
Expand Down
5 changes: 5 additions & 0 deletions src/items/containers/container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ class Container : public Item, public Cylinder {

virtual void removeItem(Thing* thing, bool sendUpdateToClient = false);

bool isAnyKindOfRewardChest() const;
bool isAnyKindOfRewardContainer() const;
bool isBrowseFieldAndHoldsRewardChest() const;
bool isInsideContainerWithId(const uint16_t id) const;

protected:
std::ostringstream &getContentDescription(std::ostringstream &os, bool oldProtocol) const;

Expand Down
5 changes: 5 additions & 0 deletions src/lua/creature/actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ ReturnValue Actions::internalUseItem(Player* player, const Position &pos, uint8_

// reward chest
if (container->getRewardChest() != nullptr && container->getParent()) {
RewardChest* playerRewardChest = player->getRewardChest();
if (!player->hasOtherRewardContainerOpen(dynamic_cast<const Container*>(container->getParent()))) {
player->removeEmptyRewards();
}

RewardChest* playerRewardChest = player->getRewardChest();
if (playerRewardChest->empty()) {
return RETURNVALUE_REWARDCHESTISEMPTY;
Expand Down

0 comments on commit 59bc66f

Please sign in to comment.