diff --git a/apps/openmw-mp/Inventory.cpp b/apps/openmw-mp/Inventory.cpp index 299412a08..87e18cfa0 100644 --- a/apps/openmw-mp/Inventory.cpp +++ b/apps/openmw-mp/Inventory.cpp @@ -33,7 +33,7 @@ void Inventory::Init(LuaState &lua) ); } -Inventory::Inventory(NetActor *actor) : netActor(actor), equipmentChanged(false), inventoryChanged(mwmp::InventoryChanges::Type::None) +Inventory::Inventory(NetActor *actor) : netActor(actor), equipmentChanged(false), inventoryChanged(false) { printf("Inventory::Inventory()\n"); } @@ -85,13 +85,6 @@ void Inventory::update() inventoryChanged = 0;*/ } - -void Inventory::InitializeInventoryChanges() -{ - netActor->getNetCreature()->inventoryChanges.items.clear(); - netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::Type::Set; -} - int Inventory::getChangesSize() const { return netActor->getNetCreature()->inventoryChanges.items.size(); @@ -121,10 +114,8 @@ void Inventory::unequipItem( unsigned short slot) void Inventory::addItem(const std::string &refId, unsigned int count, int charge, float enchantmentCharge) { - if (inventoryChanged == mwmp::InventoryChanges::Type::Remove) - return; - if (inventoryChanged == mwmp::InventoryChanges::Type::None) - InitializeInventoryChanges(); + if(!inventoryChanged) + resetInventoryFlag(); mwmp::Item item; item.refId = refId; @@ -132,29 +123,24 @@ void Inventory::addItem(const std::string &refId, unsigned int count, int charge item.charge = charge; item.enchantmentCharge = enchantmentCharge; - netActor->getNetCreature()->inventoryChanges.items.push_back(item); - netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::Type::Add; - if (inventoryChanged == mwmp::InventoryChanges::Type::None && netActor->isPlayer()) + netActor->getNetCreature()->inventoryChanges.items.emplace_back(item, mwmp::InventoryChanges::Action::Add); + if (netActor->isPlayer()) netActor->toPlayer()->addToUpdateQueue(); - inventoryChanged = netActor->getNetCreature()->inventoryChanges.action; + inventoryChanged = true; } void Inventory::removeItem(const std::string &refId, unsigned short count) { - if (inventoryChanged == mwmp::InventoryChanges::Type::Add) - return; - if (inventoryChanged == mwmp::InventoryChanges::Type::None) - InitializeInventoryChanges(); - + if(!inventoryChanged) + resetInventoryFlag(); mwmp::Item item; item.refId = refId; item.count = count; - netActor->getNetCreature()->inventoryChanges.items.push_back(item); - netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::Type::Remove; - if (inventoryChanged == mwmp::InventoryChanges::Type::None && netActor->isPlayer()) + netActor->getNetCreature()->inventoryChanges.items.emplace_back(item, mwmp::InventoryChanges::Action::Remove); + if (netActor->isPlayer()) netActor->toPlayer()->addToUpdateQueue(); - inventoryChanged = netActor->getNetCreature()->inventoryChanges.action; + inventoryChanged = true; } bool Inventory::hasItemEquipped(const std::string &refId) const @@ -173,7 +159,7 @@ std::tuple Inventory::getEquipmentItem(unsigned s std::tuple Inventory::getInventoryItem(unsigned int slot) const { - const auto &item = netActor->getNetCreature()->inventoryChanges.items.at(slot); + const auto &item = netActor->getNetCreature()->inventoryChanges.items.at(slot).first; return make_tuple(item.refId, item.count, item.charge, item.enchantmentCharge); } @@ -189,15 +175,14 @@ bool Inventory::isEquipmentChanged() return equipmentChanged; } -void Inventory::resetInventoryFlag() -{ - inventoryChanged = mwmp::InventoryChanges::Type::None; -} - -mwmp::InventoryChanges::Type Inventory::inventoryChangeType() +bool Inventory::isInventoryChanged() { return inventoryChanged; } +void Inventory::resetInventoryFlag() +{ + inventoryChanged = false; - + netActor->getNetCreature()->inventoryChanges.items.clear(); +} diff --git a/apps/openmw-mp/Inventory.hpp b/apps/openmw-mp/Inventory.hpp index 78f5a035c..1d2d78809 100644 --- a/apps/openmw-mp/Inventory.hpp +++ b/apps/openmw-mp/Inventory.hpp @@ -16,7 +16,7 @@ public: static void Init(LuaState &lua); bool isEquipmentChanged(); void resetEquipmentFlag(); - mwmp::InventoryChanges::Type inventoryChangeType(); + bool isInventoryChanged(); void resetInventoryFlag(); public: explicit Inventory(NetActor *netActor); @@ -49,15 +49,11 @@ public: */ std::tuple getEquipmentItem(unsigned short slot) const; - -private: - void InitializeInventoryChanges(); - private: // not controlled pointer NetActor *netActor; bool equipmentChanged; - mwmp::InventoryChanges::Type inventoryChanged; + bool inventoryChanged; }; diff --git a/apps/openmw-mp/Player.cpp b/apps/openmw-mp/Player.cpp index 7f7b193e7..6ed464870 100644 --- a/apps/openmw-mp/Player.cpp +++ b/apps/openmw-mp/Player.cpp @@ -219,7 +219,7 @@ void Player::update() inventory.resetEquipmentFlag(); } - if (inventory.inventoryChangeType() != mwmp::InventoryChanges::Type::None) + if (inventory.isInventoryChanged()) { auto packet = plPCtrl->GetPacket(ID_PLAYER_INVENTORY); packet->setPlayer(this); diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index 5cfc2fdd4..050e5f65f 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -498,7 +498,7 @@ void LocalPlayer::updateInventory(bool forceUpdate) if (setItem(item, *result)) continue; - if (item == itemOld) + if (item == itemOld.first) break; } if (result == ptrInventory.end()) @@ -518,7 +518,9 @@ void LocalPlayer::updateInventory(bool forceUpdate) auto items = inventoryChanges.items; - if (find(items.begin(), items.end(), item) == items.end()) + if (find_if(items.begin(), items.end(), [&item](const std::pair &a) { + return item == a.first; + }) == items.end()) { invChanged = true; break; @@ -648,27 +650,25 @@ void LocalPlayer::updateAnimFlags(bool forceUpdate) } } -void LocalPlayer::addItems() +void LocalPlayer::addItem(const Item &item) { MWWorld::Ptr ptrPlayer = getPlayerPtr(); MWWorld::ContainerStore &ptrStore = ptrPlayer.getClass().getContainerStore(ptrPlayer); - for (const auto &item : inventoryChanges.items) + try { - try - { - MWWorld::Ptr itemPtr = *ptrStore.add(item.refId, item.count, ptrPlayer); - if (item.charge != -1) - itemPtr.getCellRef().setCharge(item.charge); + MWWorld::Ptr itemPtr = *ptrStore.add(item.refId, item.count, ptrPlayer); + if (item.charge != -1) + itemPtr.getCellRef().setCharge(item.charge); - if (item.enchantmentCharge != -1) - itemPtr.getCellRef().setEnchantmentCharge(item.enchantmentCharge); - } - catch (std::exception&) - { - LOG_APPEND(Log::LOG_INFO, "- Ignored addition of invalid inventory item %s", item.refId.c_str()); - } + if (item.enchantmentCharge != -1.0f) + itemPtr.getCellRef().setEnchantmentCharge(item.enchantmentCharge); } + catch (std::exception&) + { + LOG_APPEND(Log::LOG_INFO, "- Ignored addition of invalid inventory item %s", item.refId.c_str()); + } + } void LocalPlayer::addSpells() @@ -730,13 +730,12 @@ void LocalPlayer::addTopics() } } -void LocalPlayer::removeItems() +void LocalPlayer::removeItem(const Item &item) { MWWorld::Ptr ptrPlayer = getPlayerPtr(); MWWorld::ContainerStore &ptrStore = ptrPlayer.getClass().getContainerStore(ptrPlayer); - for (const auto &item : inventoryChanges.items) - ptrStore.remove(item.refId, item.count, ptrPlayer); + ptrStore.remove(item.refId, item.count, ptrPlayer); } void LocalPlayer::removeSpells() @@ -985,7 +984,11 @@ void LocalPlayer::setInventory() ptrStore.clear(); // Proceed by adding items - addItems(); + for(const auto &item : inventoryChanges.items) + { + if(item.second == InventoryChanges::Action::Set) + addItem(item.first); + } // Don't automatically setEquipment() here, or the player could end // up getting a new set of their starting clothes, or other items @@ -1180,10 +1183,9 @@ void LocalPlayer::sendInventory() item.charge = iter.getCellRef().getCharge(); item.enchantmentCharge = iter.getCellRef().getEnchantmentCharge(); - inventoryChanges.items.push_back(item); + inventoryChanges.items.emplace_back(item, InventoryChanges::Action::Set); } - inventoryChanges.action = InventoryChanges::Type::Set; getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->Send(); } diff --git a/apps/openmw/mwmp/LocalPlayer.hpp b/apps/openmw/mwmp/LocalPlayer.hpp index 442260bd0..604951214 100644 --- a/apps/openmw/mwmp/LocalPlayer.hpp +++ b/apps/openmw/mwmp/LocalPlayer.hpp @@ -38,12 +38,12 @@ namespace mwmp void updateDeadState(bool forceUpdate = false); void updateAnimFlags(bool forceUpdate = false); - void addItems(); + void addItem(const Item &item); void addSpells(); void addJournalItems(); void addTopics(); - void removeItems(); + void removeItem(const Item &item); void removeSpells(); void closeInventoryWindows(); diff --git a/apps/openmw/mwmp/processors/player/ProcessorPlayerInventory.hpp b/apps/openmw/mwmp/processors/player/ProcessorPlayerInventory.hpp index 1e913a912..4741ae25d 100644 --- a/apps/openmw/mwmp/processors/player/ProcessorPlayerInventory.hpp +++ b/apps/openmw/mwmp/processors/player/ProcessorPlayerInventory.hpp @@ -29,12 +29,19 @@ namespace mwmp { LocalPlayer &localPlayer = static_cast(*player); - if (localPlayer.inventoryChanges.action == InventoryChanges::Type::Add) - localPlayer.addItems(); - else if (localPlayer.inventoryChanges.action == InventoryChanges::Type::Remove) - localPlayer.removeItems(); - else // InventoryChanges::SET - localPlayer.setInventory(); + for (const auto &item : localPlayer.inventoryChanges.items) + { + if (item.second == InventoryChanges::Action::Add) + localPlayer.addItem(item.first); + else if (item.second == InventoryChanges::Action::Remove) + localPlayer.removeItem(item.first); + else // InventoryChanges::SET + { + // found set flag, clear and reset inventory + localPlayer.setInventory(); + break; + } + } } } }; diff --git a/components/openmw-mp/Base/BasePlayer.hpp b/components/openmw-mp/Base/BasePlayer.hpp index 38c7ca42c..7bf9483de 100644 --- a/components/openmw-mp/Base/BasePlayer.hpp +++ b/components/openmw-mp/Base/BasePlayer.hpp @@ -240,7 +240,6 @@ namespace mwmp BasePlayer(RakNet::RakNetGUID guid) : guid(guid) { - inventoryChanges.action = InventoryChanges::Type::None; spellbookChanges.action = SpellbookChanges::Type::None; useCreatureName = false; isWerewolf = false; diff --git a/components/openmw-mp/Base/BaseStructs.hpp b/components/openmw-mp/Base/BaseStructs.hpp index 531f395a2..ddb0e062b 100644 --- a/components/openmw-mp/Base/BaseStructs.hpp +++ b/components/openmw-mp/Base/BaseStructs.hpp @@ -22,15 +22,14 @@ namespace mwmp struct InventoryChanges { - std::vector items; - enum class Type: int8_t + enum class Action: int8_t { None = -1, Set = 0, Add, Remove }; - Type action; // 0 - Clear and set in entirety, 1 - Add item, 2 - Remove item + std::vector> items; }; struct Target diff --git a/components/openmw-mp/Packets/Player/PacketPlayerInventory.cpp b/components/openmw-mp/Packets/Player/PacketPlayerInventory.cpp index 0a8aa32f3..1092eb102 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerInventory.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerInventory.cpp @@ -17,8 +17,6 @@ void PacketPlayerInventory::Packet(RakNet::BitStream *bs, bool send) { PlayerPacket::Packet(bs, send); - RW(player->inventoryChanges.action, send); - uint32_t count; if (send) @@ -34,9 +32,10 @@ void PacketPlayerInventory::Packet(RakNet::BitStream *bs, bool send) for (auto &&item : player->inventoryChanges.items) { - RW(item.refId, send, true); - RW(item.count, send); - RW(item.charge, send); - RW(item.enchantmentCharge, send); + RW(item.first.refId, send, true); + RW(item.first.count, send); + RW(item.first.charge, send); + RW(item.first.enchantmentCharge, send); + RW(item.second, send, true); // compress byte to bits } }