diff --git a/apps/openmw/mwmp/WorldEvent.cpp b/apps/openmw/mwmp/WorldEvent.cpp index 21450d177..f0a86aab5 100644 --- a/apps/openmw/mwmp/WorldEvent.cpp +++ b/apps/openmw/mwmp/WorldEvent.cpp @@ -62,6 +62,43 @@ void WorldEvent::addObject(WorldObject worldObject) worldObjects.push_back(worldObject); } +WorldObject WorldEvent::getWorldObject(const MWWorld::Ptr& ptr) +{ + mwmp::WorldObject worldObject; + worldObject.refId = ptr.getCellRef().getRefId(); + worldObject.refNumIndex = ptr.getCellRef().getRefNum().mIndex; + worldObject.mpNum = ptr.getCellRef().getMpNum(); + return worldObject; +} + +void WorldEvent::addContainerItem(mwmp::WorldObject& worldObject, const MWWorld::Ptr& itemPtr, int actionCount) +{ + mwmp::ContainerItem containerItem; + containerItem.refId = itemPtr.getCellRef().getRefId(); + containerItem.count = itemPtr.getRefData().getCount(); + containerItem.charge = itemPtr.getCellRef().getCharge(); + containerItem.enchantmentCharge = itemPtr.getCellRef().getEnchantmentCharge(); + containerItem.actionCount = actionCount; + + LOG_APPEND(Log::LOG_INFO, "- Adding container item %s", containerItem.refId.c_str()); + + worldObject.containerItems.push_back(containerItem); +} + +void WorldEvent::addEntireContainer(const MWWorld::Ptr& ptr) +{ + MWWorld::ContainerStore& containerStore = ptr.getClass().getContainerStore(ptr); + + mwmp::WorldObject worldObject = getWorldObject(ptr); + + for (const auto itemPtr : containerStore) + { + addContainerItem(worldObject, itemPtr, itemPtr.getRefData().getCount()); + } + + addObject(worldObject); +} + void WorldEvent::editContainers(MWWorld::CellStore* cellStore) { bool isLocalEvent = guid == Main::get().getLocalPlayer()->guid; @@ -678,39 +715,45 @@ void WorldEvent::playVideo() } } -WorldObject WorldEvent::getWorldObject(const MWWorld::Ptr& ptr) +void WorldEvent::addAllContainers(MWWorld::CellStore* cellStore) { - mwmp::WorldObject worldObject; - worldObject.refId = ptr.getCellRef().getRefId(); - worldObject.refNumIndex = ptr.getCellRef().getRefNum().mIndex; - worldObject.mpNum = ptr.getCellRef().getMpNum(); - return worldObject; -} + MWWorld::CellRefList *containerList = cellStore->getContainers(); -void WorldEvent::addContainerItem(mwmp::WorldObject& worldObject, const MWWorld::Ptr& itemPtr, int actionCount) -{ - mwmp::ContainerItem containerItem; - containerItem.refId = itemPtr.getCellRef().getRefId(); - containerItem.count = itemPtr.getRefData().getCount(); - containerItem.charge = itemPtr.getCellRef().getCharge(); - containerItem.enchantmentCharge = itemPtr.getCellRef().getEnchantmentCharge(); - containerItem.actionCount = actionCount; + for (auto &container : containerList->mList) + { + mwmp::WorldObject worldObject; + worldObject.refId = container.mRef.getRefId(); + worldObject.refNumIndex = container.mRef.getRefNum().mIndex; + worldObject.mpNum = container.mRef.getMpNum(); - worldObject.containerItems.push_back(containerItem); + MWWorld::ContainerStore& containerStore = container.mClass->getContainerStore(MWWorld::Ptr(&container, 0)); + + for (const auto itemPtr : containerStore) + { + addContainerItem(worldObject, itemPtr, 0); + } + + addObject(worldObject); + } } -void WorldEvent::addEntireContainer(const MWWorld::Ptr& ptr) +void WorldEvent::addRequestedContainers(MWWorld::CellStore* cellStore, const std::vector& requestObjects) { - MWWorld::ContainerStore& containerStore = ptr.getClass().getContainerStore(ptr); + for (const auto &worldObject : requestObjects) + { + LOG_APPEND(Log::LOG_VERBOSE, "- cellRef: %s, %i, %i", worldObject.refId.c_str(), + worldObject.refNumIndex, worldObject.mpNum); - mwmp::WorldObject worldObject = getWorldObject(ptr); + MWWorld::Ptr ptrFound = cellStore->searchExact(worldObject.refNumIndex, worldObject.mpNum); - for (const auto itemPtr : containerStore) - { - addContainerItem(worldObject, itemPtr, itemPtr.getRefData().getCount()); + if (ptrFound) + { + if (ptrFound.getClass().hasContainerStore(ptrFound)) + addEntireContainer(ptrFound); + else + LOG_APPEND(Log::LOG_VERBOSE, "-- Object lacks container store", ptrFound.getCellRef().getRefId().c_str()); + } } - - addObject(worldObject); } void WorldEvent::addObjectPlace(const MWWorld::Ptr& ptr, bool droppedByPlayer) @@ -1083,30 +1126,9 @@ void WorldEvent::sendScriptGlobalShort() mwmp::Main::get().getNetworking()->getWorldPacket(ID_SCRIPT_GLOBAL_SHORT)->Send(); } -void WorldEvent::sendCellContainers(MWWorld::CellStore* cellStore) +void WorldEvent::sendContainer() { - reset(); - cell = *cellStore->getCell(); - action = BaseEvent::SET; - - MWWorld::CellRefList *containerList = cellStore->getContainers(); - - for (auto &container : containerList->mList) - { - mwmp::WorldObject worldObject; - worldObject.refId = container.mRef.getRefId(); - worldObject.refNumIndex = container.mRef.getRefNum().mIndex; - worldObject.mpNum = container.mRef.getMpNum(); - - MWWorld::ContainerStore& containerStore = container.mClass->getContainerStore(MWWorld::Ptr(&container, 0)); - - for (const auto itemPtr : containerStore) - { - addContainerItem(worldObject, itemPtr, 0); - } - - addObject(worldObject); - } + LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Sending ID_CONTAINER"); mwmp::Main::get().getNetworking()->getWorldPacket(ID_CONTAINER)->setEvent(this); mwmp::Main::get().getNetworking()->getWorldPacket(ID_CONTAINER)->Send(); diff --git a/apps/openmw/mwmp/WorldEvent.hpp b/apps/openmw/mwmp/WorldEvent.hpp index 416a0efb8..7ef4e7dbf 100644 --- a/apps/openmw/mwmp/WorldEvent.hpp +++ b/apps/openmw/mwmp/WorldEvent.hpp @@ -16,7 +16,11 @@ namespace mwmp virtual ~WorldEvent(); void reset(); + void addObject(WorldObject worldObject); + WorldObject getWorldObject(const MWWorld::Ptr& ptr); + void addContainerItem(mwmp::WorldObject& worldObject, const MWWorld::Ptr& itemPtr, int actionCount); + void addEntireContainer(const MWWorld::Ptr& ptr); void editContainers(MWWorld::CellStore* cellStore); @@ -41,9 +45,8 @@ namespace mwmp void playMusic(); void playVideo(); - WorldObject getWorldObject(const MWWorld::Ptr& ptr); - void addContainerItem(mwmp::WorldObject& worldObject, const MWWorld::Ptr& itemPtr, int actionCount); - void addEntireContainer(const MWWorld::Ptr& ptr); + void addAllContainers(MWWorld::CellStore* cellStore); + void addRequestedContainers(MWWorld::CellStore* cellStore, const std::vector& requestObjects); void addObjectPlace(const MWWorld::Ptr& ptr, bool droppedByPlayer = false); void addObjectSpawn(const MWWorld::Ptr& ptr); @@ -78,8 +81,7 @@ namespace mwmp void sendScriptLocalFloat(); void sendScriptMemberShort(); void sendScriptGlobalShort(); - - void sendCellContainers(MWWorld::CellStore* cellStore); + void sendContainer(); private: Networking *getNetworking(); diff --git a/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp b/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp index fa6c5668f..bce080716 100644 --- a/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp +++ b/apps/openmw/mwmp/processors/world/ProcessorContainer.hpp @@ -21,10 +21,36 @@ namespace mwmp // If we've received a request for information, comply with it if (event.action == mwmp::BaseEvent::REQUEST) - event.sendCellContainers(ptrCellStore); + { + if (event.worldObjectCount == 0) + { + LOG_APPEND(Log::LOG_VERBOSE, "- Request had no objects attached, so we are sending all containers in the cell %s", + event.cell.getDescription().c_str()); + event.reset(); + event.cell = *ptrCellStore->getCell(); + event.action = event.action == mwmp::BaseEvent::SET; + event.addAllContainers(ptrCellStore); + event.sendContainer(); + } + else + { + LOG_APPEND(Log::LOG_VERBOSE, "- Request was for %i %s", event.worldObjectCount, event.worldObjectCount == 1 ? "object" : "objects"); + std::vector requestObjects = event.worldObjects; + event.reset(); + event.cell = *ptrCellStore->getCell(); + event.action = event.action == mwmp::BaseEvent::SET; + event.addRequestedContainers(ptrCellStore, requestObjects); + + if (event.worldObjects.size() > 0) + event.sendContainer(); + } + } // Otherwise, edit containers based on the information received else + { + LOG_APPEND(Log::LOG_VERBOSE, "- Editing container contents to match those of packet", event.worldObjectCount); event.editContainers(ptrCellStore); + } } };