mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-29 22:45:34 +00:00
[General] Track objects directly placed by players in ObjectPlace
This allows the OnPCDrop variable to get set correctly even when object placements have to go through the server first in order to gain a unique multiplayer index (mpNum). Among other things, this makes it possible to roll marijuana joints in the popular mod "Tribunal Code Patch".
This commit is contained in:
parent
595bc5a152
commit
420dab10e1
8 changed files with 36 additions and 6 deletions
|
@ -289,6 +289,7 @@ void WorldFunctions::SetContainerItemEnchantmentCharge(double enchantmentCharge)
|
|||
|
||||
void WorldFunctions::AddWorldObject() noexcept
|
||||
{
|
||||
tempWorldObject.droppedByPlayer = false;
|
||||
writeEvent.worldObjects.push_back(tempWorldObject);
|
||||
|
||||
tempWorldObject = emptyWorldObject;
|
||||
|
|
|
@ -249,6 +249,17 @@ namespace MWBase
|
|||
virtual MWWorld::Ptr getFacedObject() = 0;
|
||||
///< Return pointer to the object the player is looking at, if it is within activation range
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
This has been declared here so it can be accessed from places
|
||||
other than MWWorld::World
|
||||
*/
|
||||
virtual void PCDropped(const MWWorld::Ptr& item) = 0;
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
virtual float getDistanceToFacedObject() = 0;
|
||||
|
||||
virtual float getMaxActivationDistance() = 0;
|
||||
|
|
|
@ -74,7 +74,7 @@ namespace MWGui
|
|||
*/
|
||||
mwmp::WorldEvent *worldEvent = mwmp::Main::get().getNetworking()->getWorldEvent();
|
||||
worldEvent->reset();
|
||||
worldEvent->addObjectPlace(dropped);
|
||||
worldEvent->addObjectPlace(dropped, true);
|
||||
worldEvent->sendObjectPlace();
|
||||
/*
|
||||
End of tes3mp addition
|
||||
|
|
|
@ -158,6 +158,8 @@ void WorldEvent::editContainers(MWWorld::CellStore* cellStore)
|
|||
|
||||
void WorldEvent::placeObjects(MWWorld::CellStore* cellStore)
|
||||
{
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
|
||||
for (const auto &worldObject : worldObjects)
|
||||
{
|
||||
LOG_APPEND(Log::LOG_VERBOSE, "- cellRef: %s, %i, %i, count: %i, charge: %i, enchantmentCharge: %i", worldObject.refId.c_str(),
|
||||
|
@ -172,7 +174,7 @@ void WorldEvent::placeObjects(MWWorld::CellStore* cellStore)
|
|||
// Only create this object if it doesn't already exist
|
||||
if (!ptrFound)
|
||||
{
|
||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), worldObject.refId, 1);
|
||||
MWWorld::ManualRef ref(world->getStore(), worldObject.refId, 1);
|
||||
MWWorld::Ptr newPtr = ref.getPtr();
|
||||
|
||||
if (worldObject.count > 1)
|
||||
|
@ -185,10 +187,13 @@ void WorldEvent::placeObjects(MWWorld::CellStore* cellStore)
|
|||
newPtr.getCellRef().setEnchantmentCharge(worldObject.enchantmentCharge);
|
||||
|
||||
newPtr.getCellRef().setGoldValue(worldObject.goldValue);
|
||||
newPtr = MWBase::Environment::get().getWorld()->placeObject(newPtr, cellStore, worldObject.position);
|
||||
newPtr = world->placeObject(newPtr, cellStore, worldObject.position);
|
||||
|
||||
// Because gold automatically gets replaced with a new object, make sure we set the mpNum at the end
|
||||
newPtr.getCellRef().setMpNum(worldObject.mpNum);
|
||||
|
||||
if (guid == Main::get().getLocalPlayer()->guid && worldObject.droppedByPlayer)
|
||||
world->PCDropped(newPtr);
|
||||
}
|
||||
else
|
||||
LOG_APPEND(Log::LOG_VERBOSE, "-- Object already existed!");
|
||||
|
@ -608,7 +613,7 @@ void WorldEvent::playVideo()
|
|||
}
|
||||
}
|
||||
|
||||
void WorldEvent::addObjectPlace(const MWWorld::Ptr& ptr)
|
||||
void WorldEvent::addObjectPlace(const MWWorld::Ptr& ptr, bool droppedByPlayer)
|
||||
{
|
||||
if (ptr.getCellRef().getRefId().find("$dynamic") != string::npos)
|
||||
{
|
||||
|
@ -624,6 +629,7 @@ void WorldEvent::addObjectPlace(const MWWorld::Ptr& ptr)
|
|||
worldObject.mpNum = 0;
|
||||
worldObject.charge = ptr.getCellRef().getCharge();
|
||||
worldObject.enchantmentCharge = ptr.getCellRef().getEnchantmentCharge();
|
||||
worldObject.droppedByPlayer = droppedByPlayer;
|
||||
|
||||
// Make sure we send the RefData position instead of the CellRef one, because that's what
|
||||
// we actually see on this client
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace mwmp
|
|||
void playMusic();
|
||||
void playVideo();
|
||||
|
||||
void addObjectPlace(const MWWorld::Ptr& ptr);
|
||||
void addObjectPlace(const MWWorld::Ptr& ptr, bool droppedByPlayer = false);
|
||||
void addObjectSpawn(const MWWorld::Ptr& ptr);
|
||||
void addObjectSpawn(const MWWorld::Ptr& ptr, const MWWorld::Ptr& master);
|
||||
void addObjectDelete(const MWWorld::Ptr& ptr);
|
||||
|
|
|
@ -136,11 +136,21 @@ namespace MWWorld
|
|||
|
||||
MWWorld::Ptr getFacedObject(float maxDistance, bool ignorePlayer=true);
|
||||
|
||||
/*
|
||||
Start of tes3mp change (major)
|
||||
|
||||
This has been turned into a public method so it can be used in
|
||||
multiplayer's different approach to placing items
|
||||
*/
|
||||
void PCDropped(const Ptr& item);
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
|
||||
public: // FIXME
|
||||
void removeContainerScripts(const Ptr& reference) override;
|
||||
private:
|
||||
void addContainerScripts(const Ptr& reference, CellStore* cell);
|
||||
void PCDropped (const Ptr& item);
|
||||
|
||||
void processDoors(float duration);
|
||||
///< Run physics simulation and modify \a world accordingly.
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace mwmp
|
|||
std::string varName;
|
||||
|
||||
bool isDisarmed;
|
||||
bool droppedByPlayer;
|
||||
|
||||
Target master;
|
||||
bool hasMaster;
|
||||
|
|
|
@ -17,4 +17,5 @@ void PacketObjectPlace::Object(WorldObject &worldObject, bool send)
|
|||
RW(worldObject.enchantmentCharge, send);
|
||||
RW(worldObject.goldValue, send);
|
||||
RW(worldObject.position, send);
|
||||
RW(worldObject.droppedByPlayer, send);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue