From cd444f8707a9028471ebc8d5ff16ace1001334de Mon Sep 17 00:00:00 2001 From: David Cernat Date: Fri, 6 Dec 2019 11:40:07 +0200 Subject: [PATCH] [Client] Send actor equipment after Container packet causes autoEquip Previously, a Container packet with a SET action for an actor would clear their entire InventoryStore, also clearing all of their equipment slots. The actor's authority would then autoEquip new equipment for the actor, but that new equipment would not actually get sent to the other players. As a result, they would see the actor fighting with hand-to-hand attacks, while also not actually wearing anything despite being rendered as wearing the same clothes and armor as before. This commit makes the actor's authority resend the actor's equipment as soon as the Container packet has caused the autoEquip to happen. --- apps/openmw/mwmp/LocalActor.cpp | 20 +++++++++++++++++--- apps/openmw/mwmp/LocalActor.hpp | 3 ++- apps/openmw/mwmp/ObjectList.cpp | 1 + 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwmp/LocalActor.cpp b/apps/openmw/mwmp/LocalActor.cpp index 19202001c..2212ed8ea 100644 --- a/apps/openmw/mwmp/LocalActor.cpp +++ b/apps/openmw/mwmp/LocalActor.cpp @@ -57,7 +57,7 @@ LocalActor::~LocalActor() void LocalActor::update(bool forceUpdate) { updateStatsDynamic(forceUpdate); - updateEquipment(forceUpdate); + updateEquipment(forceUpdate, false); if (forceUpdate || !creatureStats.mDead) { @@ -196,7 +196,7 @@ void LocalActor::updateStatsDynamic(bool forceUpdate) } } -void LocalActor::updateEquipment(bool forceUpdate) +void LocalActor::updateEquipment(bool forceUpdate, bool sendImmediately) { if (!ptr.getClass().hasInventoryStore(ptr)) return; @@ -205,6 +205,7 @@ void LocalActor::updateEquipment(bool forceUpdate) equipmentChanged = true; MWWorld::InventoryStore &invStore = ptr.getClass().getInventoryStore(ptr); + for (int slot = 0; slot < MWWorld::InventoryStore::Slots; slot++) { auto &item = equipmentItems[slot]; @@ -235,7 +236,11 @@ void LocalActor::updateEquipment(bool forceUpdate) if (equipmentChanged) { - mwmp::Main::get().getNetworking()->getActorList()->addEquipmentActor(*this); + if (sendImmediately) + sendEquipment(); + else + mwmp::Main::get().getNetworking()->getActorList()->addEquipmentActor(*this); + equipmentChanged = false; } } @@ -254,6 +259,15 @@ void LocalActor::updateAttackOrCast() } } +void LocalActor::sendEquipment() +{ + ActorList actorList; + actorList.cell = cell; + actorList.addActor(*this); + Main::get().getNetworking()->getActorPacket(ID_ACTOR_EQUIPMENT)->setActorList(&actorList); + Main::get().getNetworking()->getActorPacket(ID_ACTOR_EQUIPMENT)->Send(); +} + void LocalActor::sendDeath(char newDeathState) { deathState = newDeathState; diff --git a/apps/openmw/mwmp/LocalActor.hpp b/apps/openmw/mwmp/LocalActor.hpp index 59dce27cf..2d4279409 100644 --- a/apps/openmw/mwmp/LocalActor.hpp +++ b/apps/openmw/mwmp/LocalActor.hpp @@ -22,9 +22,10 @@ namespace mwmp void updateAnimPlay(); void updateSpeech(); void updateStatsDynamic(bool forceUpdate); - void updateEquipment(bool forceUpdate); + void updateEquipment(bool forceUpdate, bool sendImmediately = false); void updateAttackOrCast(); + void sendEquipment(); void sendDeath(char newDeathState); MWWorld::Ptr getPtr(); diff --git a/apps/openmw/mwmp/ObjectList.cpp b/apps/openmw/mwmp/ObjectList.cpp index 5e3959213..c94de9d46 100644 --- a/apps/openmw/mwmp/ObjectList.cpp +++ b/apps/openmw/mwmp/ObjectList.cpp @@ -249,6 +249,7 @@ void ObjectList::editContainers(MWWorld::CellStore* cellStore) { MWWorld::InventoryStore& invStore = ptrFound.getClass().getInventoryStore(ptrFound); invStore.autoEquip(ptrFound); + mwmp::Main::get().getCellController()->getLocalActor(ptrFound)->updateEquipment(true, true); } // If this container was open for us, update its view