From ab93b5ddc59fb203e0a18802a06a5fa27e0b484c Mon Sep 17 00:00:00 2001 From: David Cernat Date: Fri, 16 Aug 2019 05:50:07 +0300 Subject: [PATCH] [General] Use PlayerItemUse packets when using items through quick keys --- apps/openmw/mwgui/quickkeysmenu.cpp | 36 +++++++++++++++++-- apps/openmw/mwmp/LocalPlayer.cpp | 5 ++- apps/openmw/mwmp/LocalPlayer.hpp | 2 +- .../player/ProcessorPlayerItemUse.hpp | 17 +++++++++ components/openmw-mp/Base/BasePlayer.hpp | 2 ++ .../Packets/Player/PacketPlayerItemUse.cpp | 4 ++- 6 files changed, 60 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index 8bcf45ded..0991ab89f 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -463,6 +463,14 @@ namespace MWGui return; } + /* + Start of tes3mp change (major) + + Instead of unilaterally using an item, send an ID_PLAYER_ITEM_USE packet and let the server + decide if the item actually gets used + */ + + /* MWBase::Environment::get().getWindowManager()->useItem(item); MWWorld::ConstContainerStoreIterator rightHand = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); // change draw state only if the item is in player's right hand @@ -470,21 +478,43 @@ namespace MWGui { MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Weapon); } + */ + + bool shouldDraw = isWeapon || isTool; + mwmp::Main::get().getLocalPlayer()->sendItemUse(item, false, shouldDraw ? MWMechanics::DrawState_Weapon : MWMechanics::DrawState_Nothing); + /* + End of tes3mp change (major) + */ } else if (key->type == Type_MagicItem) { // equip, if it can be equipped + + /* + Start of tes3mp change (major) + + Instead of unilaterally using an item, send an ID_PLAYER_ITEM_USE packet and let the server + decide if the item actually gets used + */ if (!item.getClass().getEquipmentSlots(item).first.empty()) { + + /* MWBase::Environment::get().getWindowManager()->useItem(item); // make sure that item was successfully equipped if (!store.isEquipped(item)) return; - } + */ - store.setSelectedEnchantItem(it); - MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell); + mwmp::Main::get().getLocalPlayer()->sendItemUse(item, true, MWMechanics::DrawState_Spell); + } + + //store.setSelectedEnchantItem(it); + //MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell); + /* + End of tes3mp change (major) + */ } } else if (key->type == Type_Magic) diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index 91cae931d..bc7f0f63f 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -1675,7 +1675,7 @@ void LocalPlayer::sendSelectedSpell(const std::string& newSelectedSpellId) getNetworking()->getPlayerPacket(ID_PLAYER_MISCELLANEOUS)->Send(); } -void LocalPlayer::sendItemUse(const MWWorld::Ptr& itemPtr) +void LocalPlayer::sendItemUse(const MWWorld::Ptr& itemPtr, bool itemMagicState, char drawState) { usedItem.refId = itemPtr.getCellRef().getRefId(); usedItem.count = itemPtr.getRefData().getCount(); @@ -1683,6 +1683,9 @@ void LocalPlayer::sendItemUse(const MWWorld::Ptr& itemPtr) usedItem.enchantmentCharge = itemPtr.getCellRef().getEnchantmentCharge(); usedItem.soul = itemPtr.getCellRef().getSoul(); + usingItemMagic = itemMagicState; + itemUseDrawState = drawState; + getNetworking()->getPlayerPacket(ID_PLAYER_ITEM_USE)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_ITEM_USE)->Send(); } diff --git a/apps/openmw/mwmp/LocalPlayer.hpp b/apps/openmw/mwmp/LocalPlayer.hpp index c05a2f76d..2f44bab31 100644 --- a/apps/openmw/mwmp/LocalPlayer.hpp +++ b/apps/openmw/mwmp/LocalPlayer.hpp @@ -95,7 +95,7 @@ namespace mwmp void sendWerewolfState(bool isWerewolf); void sendMarkLocation(const ESM::Cell& newMarkCell, const ESM::Position& newMarkPosition); void sendSelectedSpell(const std::string& newSelectedSpellId); - void sendItemUse(const MWWorld::Ptr& itemPtr); + void sendItemUse(const MWWorld::Ptr& itemPtr, bool usingItemMagic = false, char itemUseDrawState = 0); void sendCellStates(); void clearCellStates(); diff --git a/apps/openmw/mwmp/processors/player/ProcessorPlayerItemUse.hpp b/apps/openmw/mwmp/processors/player/ProcessorPlayerItemUse.hpp index bb243633c..27b36f594 100644 --- a/apps/openmw/mwmp/processors/player/ProcessorPlayerItemUse.hpp +++ b/apps/openmw/mwmp/processors/player/ProcessorPlayerItemUse.hpp @@ -38,7 +38,24 @@ namespace mwmp MWWorld::Ptr itemPtr = MechanicsHelper::getItemPtrFromStore(player->usedItem, inventoryStore); if (itemPtr) + { MWBase::Environment::get().getWindowManager()->getInventoryWindow()->useItem(itemPtr); + + if (player->usingItemMagic) + { + MWWorld::ContainerStoreIterator storeIterator = inventoryStore.begin(); + for (; storeIterator != inventoryStore.end(); ++storeIterator) + { + if (*storeIterator == itemPtr) + break; + } + + inventoryStore.setSelectedEnchantItem(storeIterator); + } + + if (player->itemUseDrawState != MWMechanics::DrawState_Nothing) + playerPtr.getClass().getNpcStats(playerPtr).setDrawState(static_cast(player->itemUseDrawState)); + } else LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Cannot use non-existent item %s", player->usedItem.refId.c_str()); } diff --git a/components/openmw-mp/Base/BasePlayer.hpp b/components/openmw-mp/Base/BasePlayer.hpp index f49b7da70..63317b764 100644 --- a/components/openmw-mp/Base/BasePlayer.hpp +++ b/components/openmw-mp/Base/BasePlayer.hpp @@ -326,6 +326,8 @@ namespace mwmp std::string selectedSpellId; mwmp::Item usedItem; + bool usingItemMagic; + char itemUseDrawState; }; } diff --git a/components/openmw-mp/Packets/Player/PacketPlayerItemUse.cpp b/components/openmw-mp/Packets/Player/PacketPlayerItemUse.cpp index c0ff9e479..155488d32 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerItemUse.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerItemUse.cpp @@ -12,10 +12,12 @@ void PacketPlayerItemUse::Packet(RakNet::BitStream *bs, bool send) { PlayerPacket::Packet(bs, send); - RW(player->usedItem.refId, send, true); RW(player->usedItem.count, send); RW(player->usedItem.charge, send); RW(player->usedItem.enchantmentCharge, send); RW(player->usedItem.soul, send, true); + + RW(player->usingItemMagic, send); + RW(player->itemUseDrawState, send); }