From 420dab10e173ebe53ef16ee9794f3d56ee4b5b43 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sun, 28 Jan 2018 17:00:14 +0200 Subject: [PATCH] [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". --- apps/openmw-mp/Script/Functions/World.cpp | 1 + apps/openmw/mwbase/world.hpp | 11 +++++++++++ apps/openmw/mwgui/hud.cpp | 2 +- apps/openmw/mwmp/WorldEvent.cpp | 12 +++++++++--- apps/openmw/mwmp/WorldEvent.hpp | 2 +- apps/openmw/mwworld/worldimp.hpp | 12 +++++++++++- components/openmw-mp/Base/BaseEvent.hpp | 1 + .../openmw-mp/Packets/World/PacketObjectPlace.cpp | 1 + 8 files changed, 36 insertions(+), 6 deletions(-) diff --git a/apps/openmw-mp/Script/Functions/World.cpp b/apps/openmw-mp/Script/Functions/World.cpp index 4423d1d05..1fbbf297e 100644 --- a/apps/openmw-mp/Script/Functions/World.cpp +++ b/apps/openmw-mp/Script/Functions/World.cpp @@ -289,6 +289,7 @@ void WorldFunctions::SetContainerItemEnchantmentCharge(double enchantmentCharge) void WorldFunctions::AddWorldObject() noexcept { + tempWorldObject.droppedByPlayer = false; writeEvent.worldObjects.push_back(tempWorldObject); tempWorldObject = emptyWorldObject; diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 222199211..bc4beda7c 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -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; diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index 0b34141c2..1bf0b7984 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -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 diff --git a/apps/openmw/mwmp/WorldEvent.cpp b/apps/openmw/mwmp/WorldEvent.cpp index 3ba14ef2b..5ad38bf87 100644 --- a/apps/openmw/mwmp/WorldEvent.cpp +++ b/apps/openmw/mwmp/WorldEvent.cpp @@ -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 diff --git a/apps/openmw/mwmp/WorldEvent.hpp b/apps/openmw/mwmp/WorldEvent.hpp index a9b1b4429..783744b24 100644 --- a/apps/openmw/mwmp/WorldEvent.hpp +++ b/apps/openmw/mwmp/WorldEvent.hpp @@ -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); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index f3728a29d..229ad2da8 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -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. diff --git a/components/openmw-mp/Base/BaseEvent.hpp b/components/openmw-mp/Base/BaseEvent.hpp index 081f189c0..0bed7eb6c 100644 --- a/components/openmw-mp/Base/BaseEvent.hpp +++ b/components/openmw-mp/Base/BaseEvent.hpp @@ -51,6 +51,7 @@ namespace mwmp std::string varName; bool isDisarmed; + bool droppedByPlayer; Target master; bool hasMaster; diff --git a/components/openmw-mp/Packets/World/PacketObjectPlace.cpp b/components/openmw-mp/Packets/World/PacketObjectPlace.cpp index 031913074..17657dfb6 100644 --- a/components/openmw-mp/Packets/World/PacketObjectPlace.cpp +++ b/components/openmw-mp/Packets/World/PacketObjectPlace.cpp @@ -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); }