[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.
pull/399/head
David Cernat 7 years ago
parent ec1311fcb7
commit f80f3bd484

@ -62,6 +62,43 @@ void WorldEvent::addObject(WorldObject worldObject)
worldObjects.push_back(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) void WorldEvent::editContainers(MWWorld::CellStore* cellStore)
{ {
bool isLocalEvent = guid == Main::get().getLocalPlayer()->guid; 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; MWWorld::CellRefList<ESM::Container> *containerList = cellStore->getContainers();
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) for (auto &container : containerList->mList)
{ {
mwmp::ContainerItem containerItem; mwmp::WorldObject worldObject;
containerItem.refId = itemPtr.getCellRef().getRefId(); worldObject.refId = container.mRef.getRefId();
containerItem.count = itemPtr.getRefData().getCount(); worldObject.refNumIndex = container.mRef.getRefNum().mIndex;
containerItem.charge = itemPtr.getCellRef().getCharge(); worldObject.mpNum = container.mRef.getMpNum();
containerItem.enchantmentCharge = itemPtr.getCellRef().getEnchantmentCharge();
containerItem.actionCount = actionCount;
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<WorldObject>& 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) if (ptrFound)
{ {
addContainerItem(worldObject, itemPtr, itemPtr.getRefData().getCount()); 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) 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(); mwmp::Main::get().getNetworking()->getWorldPacket(ID_SCRIPT_GLOBAL_SHORT)->Send();
} }
void WorldEvent::sendCellContainers(MWWorld::CellStore* cellStore) void WorldEvent::sendContainer()
{ {
reset(); LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Sending ID_CONTAINER");
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);
}
mwmp::Main::get().getNetworking()->getWorldPacket(ID_CONTAINER)->setEvent(this); mwmp::Main::get().getNetworking()->getWorldPacket(ID_CONTAINER)->setEvent(this);
mwmp::Main::get().getNetworking()->getWorldPacket(ID_CONTAINER)->Send(); mwmp::Main::get().getNetworking()->getWorldPacket(ID_CONTAINER)->Send();

@ -16,7 +16,11 @@ namespace mwmp
virtual ~WorldEvent(); virtual ~WorldEvent();
void reset(); void reset();
void addObject(WorldObject worldObject); 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); void editContainers(MWWorld::CellStore* cellStore);
@ -41,9 +45,8 @@ namespace mwmp
void playMusic(); void playMusic();
void playVideo(); void playVideo();
WorldObject getWorldObject(const MWWorld::Ptr& ptr); void addAllContainers(MWWorld::CellStore* cellStore);
void addContainerItem(mwmp::WorldObject& worldObject, const MWWorld::Ptr& itemPtr, int actionCount); void addRequestedContainers(MWWorld::CellStore* cellStore, const std::vector<WorldObject>& requestObjects);
void addEntireContainer(const MWWorld::Ptr& ptr);
void addObjectPlace(const MWWorld::Ptr& ptr, bool droppedByPlayer = false); void addObjectPlace(const MWWorld::Ptr& ptr, bool droppedByPlayer = false);
void addObjectSpawn(const MWWorld::Ptr& ptr); void addObjectSpawn(const MWWorld::Ptr& ptr);
@ -78,8 +81,7 @@ namespace mwmp
void sendScriptLocalFloat(); void sendScriptLocalFloat();
void sendScriptMemberShort(); void sendScriptMemberShort();
void sendScriptGlobalShort(); void sendScriptGlobalShort();
void sendContainer();
void sendCellContainers(MWWorld::CellStore* cellStore);
private: private:
Networking *getNetworking(); Networking *getNetworking();

@ -21,10 +21,36 @@ namespace mwmp
// If we've received a request for information, comply with it // If we've received a request for information, comply with it
if (event.action == mwmp::BaseEvent::REQUEST) 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 // Otherwise, edit containers based on the information received
else else
{
LOG_APPEND(Log::LOG_VERBOSE, "- Editing container contents to match those of packet", event.worldObjectCount);
event.editContainers(ptrCellStore); event.editContainers(ptrCellStore);
}
} }
}; };

Loading…
Cancel
Save