forked from mirror/openmw-tes3mp
[Client] Make it possible to reply to requests about specific containers
Previously, a Container packet with a REQUEST action always made the client respond with the contents of all the containers in that cell. The previous behavior now only happens for requests that have no WorldObjects attached, while requests that have WorldObjects attached get a reply with the contents of those specific containers.
This commit is contained in:
parent
ec1311fcb7
commit
f80f3bd484
3 changed files with 108 additions and 58 deletions
|
@ -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<ESM::Container> *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;
|
||||
|
||||
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)
|
||||
for (auto &container : containerList->mList)
|
||||
{
|
||||
addContainerItem(worldObject, itemPtr, itemPtr.getRefData().getCount());
|
||||
}
|
||||
mwmp::WorldObject worldObject;
|
||||
worldObject.refId = container.mRef.getRefId();
|
||||
worldObject.refNumIndex = container.mRef.getRefNum().mIndex;
|
||||
worldObject.mpNum = container.mRef.getMpNum();
|
||||
|
||||
addObject(worldObject);
|
||||
MWWorld::ContainerStore& containerStore = container.mClass->getContainerStore(MWWorld::Ptr(&container, 0));
|
||||
|
||||
for (const auto itemPtr : containerStore)
|
||||
{
|
||||
addContainerItem(worldObject, itemPtr, 0);
|
||||
}
|
||||
|
||||
addObject(worldObject);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldEvent::addRequestedContainers(MWWorld::CellStore* cellStore, const std::vector<WorldObject>& requestObjects)
|
||||
{
|
||||
for (const auto &worldObject : requestObjects)
|
||||
{
|
||||
LOG_APPEND(Log::LOG_VERBOSE, "- cellRef: %s, %i, %i", worldObject.refId.c_str(),
|
||||
worldObject.refNumIndex, worldObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(worldObject.refNumIndex, worldObject.mpNum);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
if (ptrFound.getClass().hasContainerStore(ptrFound))
|
||||
addEntireContainer(ptrFound);
|
||||
else
|
||||
LOG_APPEND(Log::LOG_VERBOSE, "-- Object lacks container store", ptrFound.getCellRef().getRefId().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<ESM::Container> *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();
|
||||
|
|
|
@ -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<WorldObject>& 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();
|
||||
|
|
|
@ -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<WorldObject> 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);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue