1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-05 18:49:40 +00:00

[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.
This commit is contained in:
David Cernat 2019-12-06 11:40:07 +02:00
parent f43ba7fba2
commit cd444f8707
3 changed files with 20 additions and 4 deletions

View file

@ -57,7 +57,7 @@ LocalActor::~LocalActor()
void LocalActor::update(bool forceUpdate) void LocalActor::update(bool forceUpdate)
{ {
updateStatsDynamic(forceUpdate); updateStatsDynamic(forceUpdate);
updateEquipment(forceUpdate); updateEquipment(forceUpdate, false);
if (forceUpdate || !creatureStats.mDead) 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)) if (!ptr.getClass().hasInventoryStore(ptr))
return; return;
@ -205,6 +205,7 @@ void LocalActor::updateEquipment(bool forceUpdate)
equipmentChanged = true; equipmentChanged = true;
MWWorld::InventoryStore &invStore = ptr.getClass().getInventoryStore(ptr); MWWorld::InventoryStore &invStore = ptr.getClass().getInventoryStore(ptr);
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; slot++) for (int slot = 0; slot < MWWorld::InventoryStore::Slots; slot++)
{ {
auto &item = equipmentItems[slot]; auto &item = equipmentItems[slot];
@ -235,7 +236,11 @@ void LocalActor::updateEquipment(bool forceUpdate)
if (equipmentChanged) if (equipmentChanged)
{ {
mwmp::Main::get().getNetworking()->getActorList()->addEquipmentActor(*this); if (sendImmediately)
sendEquipment();
else
mwmp::Main::get().getNetworking()->getActorList()->addEquipmentActor(*this);
equipmentChanged = false; 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) void LocalActor::sendDeath(char newDeathState)
{ {
deathState = newDeathState; deathState = newDeathState;

View file

@ -22,9 +22,10 @@ namespace mwmp
void updateAnimPlay(); void updateAnimPlay();
void updateSpeech(); void updateSpeech();
void updateStatsDynamic(bool forceUpdate); void updateStatsDynamic(bool forceUpdate);
void updateEquipment(bool forceUpdate); void updateEquipment(bool forceUpdate, bool sendImmediately = false);
void updateAttackOrCast(); void updateAttackOrCast();
void sendEquipment();
void sendDeath(char newDeathState); void sendDeath(char newDeathState);
MWWorld::Ptr getPtr(); MWWorld::Ptr getPtr();

View file

@ -249,6 +249,7 @@ void ObjectList::editContainers(MWWorld::CellStore* cellStore)
{ {
MWWorld::InventoryStore& invStore = ptrFound.getClass().getInventoryStore(ptrFound); MWWorld::InventoryStore& invStore = ptrFound.getClass().getInventoryStore(ptrFound);
invStore.autoEquip(ptrFound); invStore.autoEquip(ptrFound);
mwmp::Main::get().getCellController()->getLocalActor(ptrFound)->updateEquipment(true, true);
} }
// If this container was open for us, update its view // If this container was open for us, update its view