From d93b67ef212aebc317c93da8c6e65ee32076b21c Mon Sep 17 00:00:00 2001 From: David Cernat Date: Thu, 26 Jul 2018 22:37:04 +0300 Subject: [PATCH] [General] Sync soul refIds for items and add related script functions --- apps/openmw-mp/Script/Functions/Items.cpp | 18 +++++++- apps/openmw-mp/Script/Functions/Items.hpp | 19 +++++--- apps/openmw-mp/Script/Functions/Objects.cpp | 21 +++++++++ apps/openmw-mp/Script/Functions/Objects.hpp | 43 ++++++++++++++++++- apps/openmw/mwgui/container.cpp | 1 + apps/openmw/mwmechanics/actors.cpp | 11 ----- apps/openmw/mwmp/LocalPlayer.cpp | 9 +++- apps/openmw/mwmp/ObjectList.cpp | 16 +++++-- apps/openmw/mwscript/containerextensions.cpp | 2 + components/openmw-mp/Base/BaseObject.hpp | 5 ++- components/openmw-mp/Base/BaseStructs.hpp | 4 +- .../Packets/Object/PacketContainer.cpp | 3 +- .../Packets/Object/PacketObjectPlace.cpp | 1 + .../Packets/Player/PacketPlayerInventory.cpp | 1 + 14 files changed, 126 insertions(+), 28 deletions(-) diff --git a/apps/openmw-mp/Script/Functions/Items.cpp b/apps/openmw-mp/Script/Functions/Items.cpp index 3e3f73a4a..0fa9fee00 100644 --- a/apps/openmw-mp/Script/Functions/Items.cpp +++ b/apps/openmw-mp/Script/Functions/Items.cpp @@ -31,7 +31,8 @@ unsigned int ItemFunctions::GetInventoryChangesSize(unsigned short pid) noexcept return player->inventoryChanges.count; } -void ItemFunctions::EquipItem(unsigned short pid, unsigned short slot, const char *refId, unsigned int count, int charge, double enchantmentCharge) noexcept +void ItemFunctions::EquipItem(unsigned short pid, unsigned short slot, const char *refId, unsigned int count, + int charge, double enchantmentCharge) noexcept { Player *player; GET_PLAYER(pid, player,); @@ -53,7 +54,8 @@ void ItemFunctions::UnequipItem(unsigned short pid, unsigned short slot) noexcep ItemFunctions::EquipItem(pid, slot, "", 0, -1, -1); } -void ItemFunctions::AddItem(unsigned short pid, const char* refId, unsigned int count, int charge, double enchantmentCharge) noexcept +void ItemFunctions::AddItem(unsigned short pid, const char* refId, unsigned int count, int charge, + double enchantmentCharge, const char* soul) noexcept { Player *player; GET_PLAYER(pid, player, ); @@ -63,6 +65,7 @@ void ItemFunctions::AddItem(unsigned short pid, const char* refId, unsigned int item.count = count; item.charge = charge; item.enchantmentCharge = enchantmentCharge; + item.soul = soul; player->inventoryChanges.items.push_back(item); player->inventoryChanges.action = InventoryChanges::ADD; @@ -159,6 +162,17 @@ double ItemFunctions::GetInventoryItemEnchantmentCharge(unsigned short pid, unsi return player->inventoryChanges.items.at(index).enchantmentCharge; } +const char *ItemFunctions::GetInventoryItemSoul(unsigned short pid, unsigned int index) noexcept +{ + Player *player; + GET_PLAYER(pid, player, ""); + + if (index >= player->inventoryChanges.count) + return "invalid"; + + return player->inventoryChanges.items.at(index).soul.c_str(); +} + void ItemFunctions::SendEquipment(unsigned short pid) noexcept { Player *player; diff --git a/apps/openmw-mp/Script/Functions/Items.hpp b/apps/openmw-mp/Script/Functions/Items.hpp index 64464839b..6a819ec0d 100644 --- a/apps/openmw-mp/Script/Functions/Items.hpp +++ b/apps/openmw-mp/Script/Functions/Items.hpp @@ -1,7 +1,3 @@ -// -// Created by koncord on 30.08.16. -// - #ifndef OPENMW_ITEMAPI_HPP #define OPENMW_ITEMAPI_HPP @@ -28,6 +24,7 @@ {"GetInventoryItemCount", ItemFunctions::GetInventoryItemCount},\ {"GetInventoryItemCharge", ItemFunctions::GetInventoryItemCharge},\ {"GetInventoryItemEnchantmentCharge", ItemFunctions::GetInventoryItemEnchantmentCharge},\ + {"GetInventoryItemSoul", ItemFunctions::GetInventoryItemSoul},\ \ {"SendEquipment", ItemFunctions::SendEquipment},\ {"SendInventoryChanges", ItemFunctions::SendInventoryChanges} @@ -95,9 +92,11 @@ public: * \param count The count of the item. * \param charge The charge of the item. * \param enchantmentCharge The enchantment charge of the item. + * \param soul The soul of the item. * \return void */ - static void AddItem(unsigned short pid, const char* refId, unsigned int count, int charge, double enchantmentCharge = -1) noexcept; + static void AddItem(unsigned short pid, const char* refId, unsigned int count, int charge, + double enchantmentCharge, const char* soul) noexcept; /** * \brief Remove an item from a player's inventory. @@ -197,6 +196,16 @@ public: */ static double GetInventoryItemEnchantmentCharge(unsigned short pid, unsigned int index) noexcept; + /** + * \brief Get the soul of the item at a certain index in a player's latest inventory + * changes. + * + * \param pid The player ID whose inventory changes should be used. + * \param index The index of the inventory item. + * \return The soul. + */ + static const char *GetInventoryItemSoul(unsigned short pid, unsigned int index) noexcept; + /** * \brief Send a PlayerEquipment packet with a player's equipment. * diff --git a/apps/openmw-mp/Script/Functions/Objects.cpp b/apps/openmw-mp/Script/Functions/Objects.cpp index f5cd97faf..93a91dce6 100644 --- a/apps/openmw-mp/Script/Functions/Objects.cpp +++ b/apps/openmw-mp/Script/Functions/Objects.cpp @@ -114,6 +114,11 @@ double ObjectFunctions::GetObjectEnchantmentCharge(unsigned int index) noexcept return readObjectList->baseObjects.at(index).enchantmentCharge; } +const char *ObjectFunctions::GetObjectSoul(unsigned int index) noexcept +{ + return readObjectList->baseObjects.at(index).soul.c_str(); +} + int ObjectFunctions::GetObjectGoldValue(unsigned int index) noexcept { return readObjectList->baseObjects.at(index).goldValue; @@ -278,6 +283,12 @@ double ObjectFunctions::GetContainerItemEnchantmentCharge(unsigned int objectInd .containerItems.at(itemIndex).enchantmentCharge; } +const char *ObjectFunctions::GetContainerItemSoul(unsigned int objectIndex, unsigned int itemIndex) noexcept +{ + return readObjectList->baseObjects.at(objectIndex) + .containerItems.at(itemIndex).soul.c_str(); +} + int ObjectFunctions::GetContainerItemActionCount(unsigned int objectIndex, unsigned int itemIndex) noexcept { return readObjectList->baseObjects.at(objectIndex) @@ -334,6 +345,11 @@ void ObjectFunctions::SetObjectEnchantmentCharge(double enchantmentCharge) noexc tempObject.enchantmentCharge = enchantmentCharge; } +void ObjectFunctions::SetObjectSoul(const char* soul) noexcept +{ + tempObject.soul = soul; +} + void ObjectFunctions::SetObjectGoldValue(int goldValue) noexcept { tempObject.goldValue = goldValue; @@ -440,6 +456,11 @@ void ObjectFunctions::SetContainerItemEnchantmentCharge(double enchantmentCharge tempContainerItem.enchantmentCharge = enchantmentCharge; } +void ObjectFunctions::SetContainerItemSoul(const char* soul) noexcept +{ + tempContainerItem.soul = soul; +} + void ObjectFunctions::SetContainerItemActionCountByIndex(unsigned int objectIndex, unsigned int itemIndex, int actionCount) noexcept { writeObjectList.baseObjects.at(objectIndex).containerItems.at(itemIndex).actionCount = actionCount; diff --git a/apps/openmw-mp/Script/Functions/Objects.hpp b/apps/openmw-mp/Script/Functions/Objects.hpp index d73723b79..95ef01deb 100644 --- a/apps/openmw-mp/Script/Functions/Objects.hpp +++ b/apps/openmw-mp/Script/Functions/Objects.hpp @@ -23,6 +23,7 @@ {"GetObjectCount", ObjectFunctions::GetObjectCount},\ {"GetObjectCharge", ObjectFunctions::GetObjectCharge},\ {"GetObjectEnchantmentCharge", ObjectFunctions::GetObjectEnchantmentCharge},\ + {"GetObjectSoul" , ObjectFunctions::GetObjectSoul},\ {"GetObjectGoldValue", ObjectFunctions::GetObjectGoldValue},\ {"GetObjectScale", ObjectFunctions::GetObjectScale},\ {"GetObjectState", ObjectFunctions::GetObjectState},\ @@ -58,6 +59,7 @@ {"GetContainerItemCount", ObjectFunctions::GetContainerItemCount},\ {"GetContainerItemCharge", ObjectFunctions::GetContainerItemCharge},\ {"GetContainerItemEnchantmentCharge", ObjectFunctions::GetContainerItemEnchantmentCharge},\ + {"GetContainerItemSoul", ObjectFunctions::GetContainerItemSoul},\ {"GetContainerItemActionCount", ObjectFunctions::GetContainerItemActionCount},\ \ {"DoesObjectHaveContainer", ObjectFunctions::DoesObjectHaveContainer},\ @@ -72,6 +74,7 @@ {"SetObjectCount", ObjectFunctions::SetObjectCount},\ {"SetObjectCharge", ObjectFunctions::SetObjectCharge},\ {"SetObjectEnchantmentCharge", ObjectFunctions::SetObjectEnchantmentCharge},\ + {"SetObjectSoul", ObjectFunctions::SetObjectSoul},\ {"SetObjectGoldValue", ObjectFunctions::SetObjectGoldValue},\ {"SetObjectScale", ObjectFunctions::SetObjectScale},\ {"SetObjectState", ObjectFunctions::SetObjectState},\ @@ -94,6 +97,7 @@ {"SetContainerItemCount", ObjectFunctions::SetContainerItemCount},\ {"SetContainerItemCharge", ObjectFunctions::SetContainerItemCharge},\ {"SetContainerItemEnchantmentCharge", ObjectFunctions::SetContainerItemEnchantmentCharge},\ + {"SetContainerItemSoul", ObjectFunctions::SetContainerItemSoul},\ \ {"SetContainerItemActionCountByIndex", ObjectFunctions::SetContainerItemActionCountByIndex},\ \ @@ -142,7 +146,7 @@ public: static void ReadReceivedObjectList() noexcept; /** - * \brief Clear the data from the last object list sent by the server. + * \brief Clear the data from the object list stored on the server. * * \return void */ @@ -277,6 +281,14 @@ public: */ static double GetObjectEnchantmentCharge(unsigned int index) noexcept; + /** + * \brief Get the soul of the object at a certain index in the read object list. + * + * \param index The index of the object. + * \return The soul. + */ + static const char *GetObjectSoul(unsigned int index) noexcept; + /** * \brief Get the gold value of the object at a certain index in the read object list. * @@ -543,6 +555,16 @@ public: */ static double GetContainerItemEnchantmentCharge(unsigned int objectIndex, unsigned int itemIndex) noexcept; + /** + * \brief Get the soul of the container item at a certain itemIndex in the container changes + * of the object at a certain objectIndex in the read object list. + * + * \param objectIndex The index of the object. + * \param itemIndex The index of the container item. + * \return The soul. + */ + static const char *GetContainerItemSoul(unsigned int objectIndex, unsigned int itemIndex) noexcept; + /** * \brief Get the action count of the container item at a certain itemIndex in the container * changes of the object at a certain objectIndex in the read object list. @@ -661,6 +683,14 @@ public: */ static void SetObjectEnchantmentCharge(double enchantmentCharge) noexcept; + /** + * \brief Set the soul of the temporary object stored on the server. + * + * \param refId The soul. + * \return void + */ + static void SetObjectSoul(const char* soul) noexcept; + /** * \brief Set the gold value of the temporary object stored on the server. * @@ -841,6 +871,14 @@ public: */ static void SetContainerItemEnchantmentCharge(double enchantmentCharge) noexcept; + /** + * \brief Set the soul of the temporary container item stored on the server. + * + * \param refId The soul. + * \return void + */ + static void SetContainerItemSoul(const char* soul) noexcept; + /** * \brief Set the action count of the container item at a certain itemIndex in the container * changes of the object at a certain objectIndex in the object list stored on the server. @@ -857,7 +895,8 @@ public: static void SetContainerItemActionCountByIndex(unsigned int objectIndex, unsigned int itemIndex, int actionCount) noexcept; /** - * \brief Add a copy of the server's temporary object to the server's temporary object list. + * \brief Add a copy of the server's temporary object to the server's currently stored object + * list. * * In the process, the server's temporary object will automatically be cleared so a new * one can be set up. diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index b69660074..1f1fa092a 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -174,6 +174,7 @@ namespace MWGui containerItem.charge = itemPtr.getCellRef().getCharge(); containerItem.enchantmentCharge = itemPtr.getCellRef().getEnchantmentCharge(); + containerItem.soul = itemPtr.getCellRef().getSoul(); baseObject.containerItems.push_back(containerItem); objectList->addObject(baseObject); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 143eb382a..3ff39ded6 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -250,17 +250,6 @@ namespace MWMechanics if (caster == getPlayer()) MWBase::Environment::get().getWindowManager()->messageBox("#{sSoultrapSuccess}"); - /* - Start of tes3mp addition - - Include a messagebox notifying players that soul gems filled by players are not synced yet - */ - if (caster == getPlayer()) - MWBase::Environment::get().getWindowManager()->messageBox("Soul gems filled by players are not synchronized in multiplayer yet and their souls will not show up for other players."); - /* - End of tes3mp addition - */ - const ESM::Static* fx = MWBase::Environment::get().getWorld()->getStore().get() .search("VFX_Soul_Trap"); if (fx) diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index 50cd7b59c..04acfbb55 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -488,9 +488,9 @@ void LocalPlayer::updateEquipment(bool forceUpdate) equipmentIndexChanges.push_back(slot); item.refId = it->getCellRef().getRefId(); + item.count = it->getRefData().getCount(); item.charge = it->getCellRef().getCharge(); item.enchantmentCharge = it->getCellRef().getEnchantmentCharge(); - item.count = it->getRefData().getCount(); } } else if (!item.refId.empty()) @@ -524,11 +524,12 @@ void LocalPlayer::updateInventory(bool forceUpdate) auto setItem = [](Item &item, const MWWorld::Ptr &iter) { item.refId = iter.getCellRef().getRefId(); - if (item.refId.find("$dynamic") != string::npos) // skip generated items (self enchanted for e.g.) + if (item.refId.find("$dynamic") != string::npos) return true; item.count = iter.getRefData().getCount(); item.charge = iter.getCellRef().getCharge(); item.enchantmentCharge = iter.getCellRef().getEnchantmentCharge(); + item.soul = iter.getCellRef().getSoul(); return false; }; @@ -683,6 +684,9 @@ void LocalPlayer::addItems() if (item.enchantmentCharge != -1) itemPtr.getCellRef().setEnchantmentCharge(item.enchantmentCharge); + + if (!item.soul.empty()) + itemPtr.getCellRef().setSoul(item.soul); } catch (std::exception&) { @@ -1370,6 +1374,7 @@ void LocalPlayer::sendInventory() item.count = iter.getRefData().getCount(); item.charge = iter.getCellRef().getCharge(); item.enchantmentCharge = iter.getCellRef().getEnchantmentCharge(); + item.soul = iter.getCellRef().getSoul(); inventoryChanges.items.push_back(item); } diff --git a/apps/openmw/mwmp/ObjectList.cpp b/apps/openmw/mwmp/ObjectList.cpp index 4eb6de0d2..2e55c9e5f 100644 --- a/apps/openmw/mwmp/ObjectList.cpp +++ b/apps/openmw/mwmp/ObjectList.cpp @@ -78,6 +78,7 @@ void ObjectList::addContainerItem(mwmp::BaseObject& baseObject, const MWWorld::P containerItem.count = itemPtr.getRefData().getCount(); containerItem.charge = itemPtr.getCellRef().getCharge(); containerItem.enchantmentCharge = itemPtr.getCellRef().getEnchantmentCharge(); + containerItem.soul = itemPtr.getCellRef().getSoul(); containerItem.actionCount = actionCount; LOG_APPEND(Log::LOG_VERBOSE, "--- Adding container item %s", containerItem.refId.c_str()); @@ -174,6 +175,9 @@ void ObjectList::editContainers(MWWorld::CellStore* cellStore) if (containerItem.enchantmentCharge > -1) newPtr.getCellRef().setEnchantmentCharge(containerItem.enchantmentCharge); + if (!containerItem.soul.empty()) + newPtr.getCellRef().setSoul(containerItem.soul); + containerStore.add(newPtr, containerItem.count, ownerPtr, true); } @@ -186,7 +190,8 @@ void ObjectList::editContainers(MWWorld::CellStore* cellStore) if (Misc::StringUtils::ciEqual(itemPtr.getCellRef().getRefId(), containerItem.refId)) { if (itemPtr.getCellRef().getCharge() == containerItem.charge && - itemPtr.getCellRef().getEnchantmentCharge() == containerItem.enchantmentCharge) + itemPtr.getCellRef().getEnchantmentCharge() == containerItem.enchantmentCharge && + Misc::StringUtils::ciEqual(itemPtr.getCellRef().getSoul(), containerItem.soul)) { // Store the sound of the first item in a TAKE_ALL if (isLocalTakeAll && takeAllSound.empty()) @@ -327,8 +332,9 @@ void ObjectList::placeObjects(MWWorld::CellStore* cellStore) for (const auto &baseObject : baseObjects) { - LOG_APPEND(Log::LOG_VERBOSE, "- cellRef: %s %i-%i, count: %i, charge: %i, enchantmentCharge: %i", baseObject.refId.c_str(), - baseObject.refNum, baseObject.mpNum, baseObject.count, baseObject.charge, baseObject.enchantmentCharge); + LOG_APPEND(Log::LOG_VERBOSE, "- cellRef: %s %i-%i, count: %i, charge: %i, enchantmentCharge: %i, soul: %s", + baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum, baseObject.count, baseObject.charge, + baseObject.enchantmentCharge, baseObject.soul.c_str()); // Ignore generic dynamic refIds because they could be anything on other clients if (baseObject.refId.find("$dynamic") != string::npos) @@ -354,6 +360,9 @@ void ObjectList::placeObjects(MWWorld::CellStore* cellStore) if (baseObject.enchantmentCharge > -1) newPtr.getCellRef().setEnchantmentCharge(baseObject.enchantmentCharge); + if (!baseObject.soul.empty()) + newPtr.getCellRef().setSoul(baseObject.soul); + newPtr.getCellRef().setGoldValue(baseObject.goldValue); newPtr = world->placeObject(newPtr, cellStore, baseObject.position); @@ -896,6 +905,7 @@ void ObjectList::addObjectPlace(const MWWorld::Ptr& ptr, bool droppedByPlayer) baseObject.mpNum = 0; baseObject.charge = ptr.getCellRef().getCharge(); baseObject.enchantmentCharge = ptr.getCellRef().getEnchantmentCharge(); + baseObject.soul = ptr.getCellRef().getSoul(); baseObject.droppedByPlayer = droppedByPlayer; baseObject.hasContainer = ptr.getClass().hasContainerStore(ptr); diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index fb9c523f9..a5ae0649a 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -139,6 +139,7 @@ namespace MWScript containerItem.count = count; containerItem.charge = -1; containerItem.enchantmentCharge = -1; + containerItem.soul = ""; baseObject.containerItems.push_back(containerItem); objectList->addObject(baseObject); @@ -267,6 +268,7 @@ namespace MWScript containerItem.actionCount = count; containerItem.charge = -1; containerItem.enchantmentCharge = -1; + containerItem.soul = ""; baseObject.containerItems.push_back(containerItem); objectList->addObject(baseObject); diff --git a/components/openmw-mp/Base/BaseObject.hpp b/components/openmw-mp/Base/BaseObject.hpp index 885083b25..01e229200 100644 --- a/components/openmw-mp/Base/BaseObject.hpp +++ b/components/openmw-mp/Base/BaseObject.hpp @@ -13,12 +13,14 @@ namespace mwmp int count; int charge; double enchantmentCharge; + std::string soul; int actionCount; inline bool operator==(const ContainerItem& rhs) { - return refId == rhs.refId && count == rhs.count && charge == rhs.charge && enchantmentCharge == rhs.enchantmentCharge; + return refId == rhs.refId && count == rhs.count && charge == rhs.charge && + enchantmentCharge == rhs.enchantmentCharge && soul == rhs.soul; } }; @@ -30,6 +32,7 @@ namespace mwmp int count; int charge; double enchantmentCharge; + std::string soul; int goldValue; ESM::Position position; diff --git a/components/openmw-mp/Base/BaseStructs.hpp b/components/openmw-mp/Base/BaseStructs.hpp index 6ee08d243..8baa29fe0 100644 --- a/components/openmw-mp/Base/BaseStructs.hpp +++ b/components/openmw-mp/Base/BaseStructs.hpp @@ -36,10 +36,12 @@ namespace mwmp int count; int charge; float enchantmentCharge; + std::string soul; inline bool operator==(const Item& rhs) { - return refId == rhs.refId && count == rhs.count && charge == rhs.charge && enchantmentCharge == rhs.enchantmentCharge; + return refId == rhs.refId && count == rhs.count && charge == rhs.charge && + enchantmentCharge == rhs.enchantmentCharge && soul == rhs.soul; } }; diff --git a/components/openmw-mp/Packets/Object/PacketContainer.cpp b/components/openmw-mp/Packets/Object/PacketContainer.cpp index 55049b8bf..30168240c 100644 --- a/components/openmw-mp/Packets/Object/PacketContainer.cpp +++ b/components/openmw-mp/Packets/Object/PacketContainer.cpp @@ -46,10 +46,11 @@ void PacketContainer::Packet(RakNet::BitStream *bs, bool send) if (send) containerItem = baseObject.containerItems.at(j); - RW(containerItem.refId, send); + RW(containerItem.refId, send, true); RW(containerItem.count, send); RW(containerItem.charge, send); RW(containerItem.enchantmentCharge, send); + RW(containerItem.soul, send, true); RW(containerItem.actionCount, send); if (!send) diff --git a/components/openmw-mp/Packets/Object/PacketObjectPlace.cpp b/components/openmw-mp/Packets/Object/PacketObjectPlace.cpp index a9d3820ac..3b6a48e6a 100644 --- a/components/openmw-mp/Packets/Object/PacketObjectPlace.cpp +++ b/components/openmw-mp/Packets/Object/PacketObjectPlace.cpp @@ -15,6 +15,7 @@ void PacketObjectPlace::Object(BaseObject &baseObject, bool send) RW(baseObject.count, send); RW(baseObject.charge, send); RW(baseObject.enchantmentCharge, send); + RW(baseObject.soul, send, true); RW(baseObject.goldValue, send); RW(baseObject.position, send); RW(baseObject.droppedByPlayer, send); diff --git a/components/openmw-mp/Packets/Player/PacketPlayerInventory.cpp b/components/openmw-mp/Packets/Player/PacketPlayerInventory.cpp index 698f8dfac..40424ee09 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerInventory.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerInventory.cpp @@ -37,6 +37,7 @@ void PacketPlayerInventory::Packet(RakNet::BitStream *bs, bool send) RW(item.count, send); RW(item.charge, send); RW(item.enchantmentCharge, send); + RW(item.soul, send, true); if (!send) player->inventoryChanges.items.push_back(item);