diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index 368aaf9ea..08b9dd7f7 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -71,12 +71,16 @@ namespace MWGui Send an ID_OBJECT_PLACE packet every time an object is dropped into the world from the inventory screen + + Send an ID_PLAYER_INVENTORY packet about the item's removal */ mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); objectList->reset(); objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; objectList->addObjectPlace(dropped, true); objectList->sendObjectPlace(); + + mwmp::Main::get().getLocalPlayer()->sendItemChange(dropped, count, mwmp::InventoryChanges::REMOVE); /* End of tes3mp addition */ @@ -290,17 +294,6 @@ namespace MWGui WorldItemModel drop (mouseX, mouseY); mDragAndDrop->drop(&drop, NULL); - /* - Start of tes3mp addition - - Send an ID_PLAYER_INVENTORY packet every time a player loses an item - by dropping it in the world - */ - mwmp::Main::get().getLocalPlayer()->sendInventory(); - /* - End of tes3mp addition - */ - MWBase::Environment::get().getWindowManager()->changePointer("arrow"); } else diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index d0f17b211..b15f6594e 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -732,7 +732,11 @@ namespace MWGui objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; objectList->addObjectDelete(object); objectList->sendObjectDelete(); - mwmp::Main::get().getLocalPlayer()->sendInventory(); + + // If the item is gold, make sure we get the correct value + unsigned int itemCount = object.getClass().isGold(object) ? object.getCellRef().getGoldValue() : object.getRefData().getCount(); + + mwmp::Main::get().getLocalPlayer()->sendItemChange(object, itemCount, mwmp::InventoryChanges::ADD); /* End of tes3mp addition */ diff --git a/apps/openmw/mwgui/trainingwindow.cpp b/apps/openmw/mwgui/trainingwindow.cpp index f0d2eaf34..427c7f3fe 100644 --- a/apps/openmw/mwgui/trainingwindow.cpp +++ b/apps/openmw/mwgui/trainingwindow.cpp @@ -181,9 +181,9 @@ namespace MWGui /* Start of tes3mp addition - Send an ID_PLAYER_INVENTORY packet every time a player buys training + Send an ID_PLAYER_INVENTORY packet with the gold lost */ - mwmp::Main::get().getLocalPlayer()->sendInventory(); + mwmp::Main::get().getLocalPlayer()->sendItemChange(MWWorld::ContainerStore::sGoldId, price, mwmp::InventoryChanges::REMOVE); /* End of tes3mp addition */ diff --git a/apps/openmw/mwmechanics/enchanting.cpp b/apps/openmw/mwmechanics/enchanting.cpp index 5b2ff5ca8..3714d9a45 100644 --- a/apps/openmw/mwmechanics/enchanting.cpp +++ b/apps/openmw/mwmechanics/enchanting.cpp @@ -109,8 +109,8 @@ namespace MWMechanics Don't add the new item to the player's inventory and instead expect the server to add it - Before using the applyEnchantment() method, remove the old item and any money paid for - the enchantment and send the player's inventory to the server + Before using the applyEnchantment() method, send an ID_PLAYER_INVENTORY packet + removing the old item from the player's inventory The applyEnchantment() method is where the record of the newly enchanted will be sent to the server, causing the server to send back the player's inventory with the new item @@ -120,10 +120,10 @@ namespace MWMechanics store.remove(mOldItemPtr, 1, player); - if (!mSelfEnchanting) + if(!mSelfEnchanting) payForEnchantment(); - mwmp::Main::get().getLocalPlayer()->sendInventory(); + mwmp::Main::get().getLocalPlayer()->sendItemChange(mOldItemPtr, 1, mwmp::InventoryChanges::REMOVE); std::string newItemId = mOldItemPtr.getClass().applyEnchantment(mOldItemPtr, enchantmentPtr->mId, getGemCharge(), mNewItemName); /* @@ -337,6 +337,16 @@ namespace MWMechanics store.remove(MWWorld::ContainerStore::sGoldId, getEnchantPrice(), player); + /* + Start of tes3mp addition + + Send an ID_PLAYER_INVENTORY packet removing the gold from the player + */ + mwmp::Main::get().getLocalPlayer()->sendItemChange(MWWorld::ContainerStore::sGoldId, getEnchantPrice(), mwmp::InventoryChanges::REMOVE); + /* + End of tes3mp addition + */ + // add gold to NPC trading gold pool CreatureStats& enchanterStats = mEnchanter.getClass().getCreatureStats(mEnchanter); enchanterStats.setGoldPool(enchanterStats.getGoldPool() + getEnchantPrice()); diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index 6c4763f58..5ee43fdf3 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -1367,6 +1367,8 @@ void LocalPlayer::sendClass() void LocalPlayer::sendInventory() { + LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Sending entire inventory to server"); + MWWorld::Ptr ptrPlayer = getPlayerPtr(); MWWorld::InventoryStore &ptrInventory = ptrPlayer.getClass().getInventoryStore(ptrPlayer); mwmp::Item item; @@ -1393,12 +1395,59 @@ void LocalPlayer::sendInventory() inventoryChanges.items.push_back(item); } - inventoryChanges.count = (unsigned int) inventoryChanges.items.size(); inventoryChanges.action = InventoryChanges::SET; getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->Send(); } + +void LocalPlayer::sendItemChange(const MWWorld::Ptr& itemPtr, int count, unsigned int action) +{ + LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Sending item change for %s with action %i, count %i", + itemPtr.getCellRef().getRefId().c_str(), action, count); + + inventoryChanges.items.clear(); + + mwmp::Item item; + + if (itemPtr.getClass().isGold(itemPtr)) + item.refId = MWWorld::ContainerStore::sGoldId; + else + item.refId = itemPtr.getCellRef().getRefId(); + + item.count = count; + item.charge = itemPtr.getCellRef().getCharge(); + item.enchantmentCharge = itemPtr.getCellRef().getEnchantmentCharge(); + item.soul = itemPtr.getCellRef().getSoul(); + + inventoryChanges.items.push_back(item); + + inventoryChanges.action = action; + getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->setPlayer(this); + getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->Send(); +} + +void LocalPlayer::sendItemChange(const std::string& refId, int count, unsigned int action) +{ + LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Sending item change for %s with action %i, count %i", + refId.c_str(), action, count); + + inventoryChanges.items.clear(); + + mwmp::Item item; + item.refId = refId; + item.count = count; + item.charge = -1; + item.enchantmentCharge = -1; + item.soul = ""; + + inventoryChanges.items.push_back(item); + + inventoryChanges.action = action; + getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->setPlayer(this); + getNetworking()->getPlayerPacket(ID_PLAYER_INVENTORY)->Send(); +} + void LocalPlayer::sendSpellbook() { MWWorld::Ptr ptrPlayer = getPlayerPtr(); @@ -1418,13 +1467,6 @@ void LocalPlayer::sendSpellbook() getNetworking()->getPlayerPacket(ID_PLAYER_SPELLBOOK)->Send(); } -void LocalPlayer::sendCellStates() -{ - LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Sending ID_PLAYER_CELL_STATE to server"); - getNetworking()->getPlayerPacket(ID_PLAYER_CELL_STATE)->setPlayer(this); - getNetworking()->getPlayerPacket(ID_PLAYER_CELL_STATE)->Send(); -} - void LocalPlayer::sendSpellChange(std::string id, unsigned int action) { // Skip any bugged spells that somehow have clientside-only dynamic IDs @@ -1629,6 +1671,13 @@ void LocalPlayer::sendItemUse(const MWWorld::Ptr& itemPtr) getNetworking()->getPlayerPacket(ID_PLAYER_ITEM_USE)->Send(); } +void LocalPlayer::sendCellStates() +{ + LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Sending ID_PLAYER_CELL_STATE to server"); + getNetworking()->getPlayerPacket(ID_PLAYER_CELL_STATE)->setPlayer(this); + getNetworking()->getPlayerPacket(ID_PLAYER_CELL_STATE)->Send(); +} + void LocalPlayer::clearCellStates() { cellStateChanges.cellStates.clear(); diff --git a/apps/openmw/mwmp/LocalPlayer.hpp b/apps/openmw/mwmp/LocalPlayer.hpp index 43670001a..8cc72d1e1 100644 --- a/apps/openmw/mwmp/LocalPlayer.hpp +++ b/apps/openmw/mwmp/LocalPlayer.hpp @@ -71,8 +71,9 @@ namespace mwmp void sendClass(); void sendInventory(); + void sendItemChange(const MWWorld::Ptr& itemPtr, int count, unsigned int action); + void sendItemChange(const std::string& refId, int count, unsigned int action); void sendSpellbook(); - void sendCellStates(); void sendSpellChange(std::string id, unsigned int action); void sendQuickKey(unsigned short slot, int type, const std::string& itemId = ""); void sendJournalEntry(const std::string& quest, int index, const MWWorld::Ptr& actor); @@ -87,6 +88,7 @@ namespace mwmp void sendMarkLocation(const ESM::Cell& newMarkCell, const ESM::Position& newMarkPosition); void sendSelectedSpell(const std::string& newSelectedSpellId); void sendItemUse(const MWWorld::Ptr& itemPtr); + void sendCellStates(); void clearCellStates(); void clearCurrentContainer(); diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index a5ae0649a..3d8bed2ff 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -98,7 +98,7 @@ namespace MWScript Send an ID_PLAYER_INVENTORY packet every time a player gains an item through a script */ - mwmp::Main::get().getLocalPlayer()->sendInventory(); + mwmp::Main::get().getLocalPlayer()->sendItemChange(item, count, mwmp::InventoryChanges::ADD); /* End of tes3mp addition */ @@ -226,7 +226,7 @@ namespace MWScript if ((numRemoved > 0) && (ptr == MWMechanics::getPlayer())) { - mwmp::Main::get().getLocalPlayer()->sendInventory(); + mwmp::Main::get().getLocalPlayer()->sendItemChange(item, count, mwmp::InventoryChanges::REMOVE); /* End of tes3mp change (major) */ diff --git a/apps/openmw/mwworld/actiontake.cpp b/apps/openmw/mwworld/actiontake.cpp index aa3b41d38..7376347c6 100644 --- a/apps/openmw/mwworld/actiontake.cpp +++ b/apps/openmw/mwworld/actiontake.cpp @@ -37,7 +37,7 @@ namespace MWWorld Send an ID_OBJECT_DELETE packet every time an item is taken from the world by the player outside of the inventory screen - Send an ID_PLAYER_INVENTORY packet as well because of the item thus gained + Send an ID_PLAYER_INVENTORY packet as well with the item thus gained by the player */ mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); @@ -45,7 +45,11 @@ namespace MWWorld objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; objectList->addObjectDelete(getTarget()); objectList->sendObjectDelete(); - mwmp::Main::get().getLocalPlayer()->sendInventory(); + + // If the item is gold, make sure we get the correct value + unsigned int itemCount = getTarget().getClass().isGold(newitem) ? getTarget().getCellRef().getGoldValue() : getTarget().getRefData().getCount(); + + mwmp::Main::get().getLocalPlayer()->sendItemChange(getTarget(), itemCount, mwmp::InventoryChanges::ADD); /* End of tes3mp addition */