mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
[Client] Fix problems with NPC equipment sync
This commit is contained in:
parent
34378fbb4f
commit
6ac7ee8fcd
3 changed files with 68 additions and 15 deletions
|
@ -163,39 +163,39 @@ void DedicatedActor::setEquipment()
|
|||
return;
|
||||
|
||||
MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr);
|
||||
|
||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator it = invStore.getSlot(slot);
|
||||
|
||||
const string &dedicItem = equipedItems[slot].refId;
|
||||
std::string item = "";
|
||||
const string &packetRefId = equipedItems[slot].refId;
|
||||
int packetCharge = equipedItems[slot].charge;
|
||||
std::string storeRefId = "";
|
||||
bool equal = false;
|
||||
|
||||
if (it != invStore.end())
|
||||
{
|
||||
item = it->getCellRef().getRefId();
|
||||
if (!Misc::StringUtils::ciEqual(item, dedicItem)) // if other item equiped
|
||||
storeRefId = it->getCellRef().getRefId();
|
||||
|
||||
if (!Misc::StringUtils::ciEqual(storeRefId, packetRefId)) // if other item equiped
|
||||
{
|
||||
MWWorld::ContainerStore &store = ptr.getClass().getContainerStore(ptr);
|
||||
store.remove(item, store.count(item), ptr);
|
||||
invStore.unequipSlot(slot, ptr);
|
||||
}
|
||||
else
|
||||
equal = true;
|
||||
}
|
||||
|
||||
if (dedicItem.empty() || equal)
|
||||
if (packetRefId.empty() || equal)
|
||||
continue;
|
||||
|
||||
int count = equipedItems[slot].count;
|
||||
ptr.getClass().getContainerStore(ptr).add(dedicItem, count, ptr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it2 = invStore.begin(); it2 != invStore.end(); ++it2)
|
||||
if (hasItem(packetRefId, packetCharge))
|
||||
equipItem(packetRefId, packetCharge);
|
||||
else
|
||||
{
|
||||
if (::Misc::StringUtils::ciEqual(it2->getCellRef().getRefId(), dedicItem)) // equip item
|
||||
{
|
||||
boost::shared_ptr<MWWorld::Action> action = it2->getClass().use(*it2);
|
||||
action->execute(ptr);
|
||||
break;
|
||||
}
|
||||
ptr.getClass().getContainerStore(ptr).add(packetRefId, count, ptr);
|
||||
equipItem(packetRefId, packetCharge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -225,6 +225,36 @@ void DedicatedActor::playSound()
|
|||
}
|
||||
}
|
||||
|
||||
bool DedicatedActor::hasItem(std::string refId, int charge)
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it)
|
||||
{
|
||||
if (::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), refId) && it->getCellRef().getCharge() == charge)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DedicatedActor::equipItem(std::string refId, int charge)
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr);
|
||||
|
||||
for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it)
|
||||
{
|
||||
if (::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), refId) && it->getCellRef().getCharge() == charge)
|
||||
{
|
||||
boost::shared_ptr<MWWorld::Action> action = it->getClass().use(*it);
|
||||
action->execute(ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MWWorld::Ptr DedicatedActor::getPtr()
|
||||
{
|
||||
return ptr;
|
||||
|
|
|
@ -25,6 +25,9 @@ namespace mwmp
|
|||
void playAnimation();
|
||||
void playSound();
|
||||
|
||||
bool hasItem(std::string refId, int charge);
|
||||
void equipItem(std::string refId, int charge);
|
||||
|
||||
MWWorld::Ptr getPtr();
|
||||
void setPtr(const MWWorld::Ptr& newPtr);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "LocalPlayer.hpp"
|
||||
#include "DedicatedPlayer.hpp"
|
||||
#include "PlayerList.hpp"
|
||||
#include "CellController.hpp"
|
||||
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
|
||||
|
@ -23,6 +24,7 @@
|
|||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/containerstore.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
|
||||
using namespace mwmp;
|
||||
|
@ -108,6 +110,15 @@ void WorldEvent::editContainers(MWWorld::CellStore* cellStore)
|
|||
if (iter->getCellRef().getCharge() == containerItem.charge &&
|
||||
iter->getRefData().getCount() == containerItem.count)
|
||||
{
|
||||
// Is this an actor's container? If so, unequip this item if it was equipped
|
||||
if (ptrFound.getClass().isActor())
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = ptrFound.getClass().getInventoryStore(ptrFound);
|
||||
|
||||
if (invStore.isEquipped(*iter))
|
||||
invStore.unequipItemQuantity(*iter, ptrFound, containerItem.count);
|
||||
}
|
||||
|
||||
containerStore.remove(*iter, containerItem.actionCount, ownerPtr);
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +126,15 @@ void WorldEvent::editContainers(MWWorld::CellStore* cellStore)
|
|||
}
|
||||
}
|
||||
|
||||
// Was this a SET or ADD action on an actor's container, and are we the authority
|
||||
// over the actor? If so, autoequip the actor
|
||||
if ((action == BaseEvent::ADD || action == BaseEvent::SET) && ptrFound.getClass().isActor() &&
|
||||
mwmp::Main::get().getCellController()->isLocalActor(ptrFound))
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = ptrFound.getClass().getInventoryStore(ptrFound);
|
||||
invStore.autoEquip(ptrFound);
|
||||
}
|
||||
|
||||
// If we are in a container, and it happens to be this container, update its view
|
||||
if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Container))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue