diff --git a/apps/openmw-mp/Script/Functions/World.cpp b/apps/openmw-mp/Script/Functions/World.cpp index 30888257d..b8403155a 100644 --- a/apps/openmw-mp/Script/Functions/World.cpp +++ b/apps/openmw-mp/Script/Functions/World.cpp @@ -79,6 +79,11 @@ double WorldFunctions::GetObjectScale(unsigned int i) noexcept return readEvent->worldObjects.at(i).scale; } +bool WorldFunctions::GetObjectState(unsigned int i) noexcept +{ + return readEvent->worldObjects.at(i).objectState; +} + int WorldFunctions::GetObjectDoorState(unsigned int i) noexcept { return readEvent->worldObjects.at(i).doorState; @@ -193,6 +198,11 @@ void WorldFunctions::SetObjectScale(double scale) noexcept tempWorldObject.scale = scale; } +void WorldFunctions::SetObjectState(bool objectState) noexcept +{ + tempWorldObject.objectState = objectState; +} + void WorldFunctions::SetObjectDoorState(int doorState) noexcept { tempWorldObject.doorState = doorState; @@ -292,6 +302,12 @@ void WorldFunctions::SendObjectScale() noexcept mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_SCALE)->Send(writeEvent.guid); } +void WorldFunctions::SendObjectState() noexcept +{ + mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_STATE)->setEvent(&writeEvent); + mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_STATE)->Send(writeEvent.guid); +} + void WorldFunctions::SendDoorState() noexcept { mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_DOOR_STATE)->setEvent(&writeEvent); diff --git a/apps/openmw-mp/Script/Functions/World.hpp b/apps/openmw-mp/Script/Functions/World.hpp index 37e226944..e278494b2 100644 --- a/apps/openmw-mp/Script/Functions/World.hpp +++ b/apps/openmw-mp/Script/Functions/World.hpp @@ -15,6 +15,7 @@ {"GetObjectCharge", WorldFunctions::GetObjectCharge},\ {"GetObjectGoldValue", WorldFunctions::GetObjectGoldValue},\ {"GetObjectScale", WorldFunctions::GetObjectScale},\ + {"GetObjectState", WorldFunctions::GetObjectState},\ {"GetObjectDoorState", WorldFunctions::GetObjectDoorState},\ {"GetObjectLockLevel", WorldFunctions::GetObjectLockLevel},\ {"GetObjectPosX", WorldFunctions::GetObjectPosX},\ @@ -40,6 +41,7 @@ {"SetObjectCharge", WorldFunctions::SetObjectCharge},\ {"SetObjectGoldValue", WorldFunctions::SetObjectGoldValue},\ {"SetObjectScale", WorldFunctions::SetObjectScale},\ + {"SetObjectState", WorldFunctions::SetObjectState},\ {"SetObjectDoorState", WorldFunctions::SetObjectDoorState},\ {"SetObjectLockLevel", WorldFunctions::SetObjectLockLevel},\ {"SetObjectDisarmState", WorldFunctions::SetObjectDisarmState},\ @@ -60,6 +62,7 @@ {"SendObjectLock", WorldFunctions::SendObjectLock},\ {"SendObjectTrap", WorldFunctions::SendObjectTrap},\ {"SendObjectScale", WorldFunctions::SendObjectScale},\ + {"SendObjectState", WorldFunctions::SendObjectState},\ {"SendDoorState", WorldFunctions::SendDoorState},\ {"SendContainer", WorldFunctions::SendContainer},\ \ @@ -84,6 +87,7 @@ public: static int GetObjectCharge(unsigned int i) noexcept; static int GetObjectGoldValue(unsigned int i) noexcept; static double GetObjectScale(unsigned int i) noexcept; + static bool GetObjectState(unsigned int i) noexcept; static int GetObjectDoorState(unsigned int i) noexcept; static int GetObjectLockLevel(unsigned int i) noexcept; static double GetObjectPosX(unsigned int i) noexcept; @@ -109,6 +113,7 @@ public: static void SetObjectCharge(int charge) noexcept; static void SetObjectGoldValue(int goldValue) noexcept; static void SetObjectScale(double scale) noexcept; + static void SetObjectState(bool objectState) noexcept; static void SetObjectDoorState(int doorState) noexcept; static void SetObjectLockLevel(int lockLevel) noexcept; static void SetObjectDisarmState(bool disarmState) noexcept; @@ -129,6 +134,7 @@ public: static void SendObjectLock() noexcept; static void SendObjectTrap() noexcept; static void SendObjectScale() noexcept; + static void SendObjectState() noexcept; static void SendDoorState() noexcept; static void SendContainer() noexcept; diff --git a/apps/openmw/mwmp/WorldEvent.cpp b/apps/openmw/mwmp/WorldEvent.cpp index e7141f459..c7f304ec1 100644 --- a/apps/openmw/mwmp/WorldEvent.cpp +++ b/apps/openmw/mwmp/WorldEvent.cpp @@ -333,6 +333,28 @@ void WorldEvent::scaleObjects(MWWorld::CellStore* cellStore) } } +void WorldEvent::setObjectStates(MWWorld::CellStore* cellStore) +{ + for (const auto &worldObject : worldObjects) + { + LOG_APPEND(Log::LOG_VERBOSE, "- cellRef: %s, %i, %i, state: %s", worldObject.refId.c_str(), worldObject.refNumIndex, + worldObject.mpNum, worldObject.objectState ? "true" : "false"); + + MWWorld::Ptr ptrFound = cellStore->searchExact(worldObject.refNumIndex, worldObject.mpNum); + + if (ptrFound) + { + LOG_APPEND(Log::LOG_VERBOSE, "-- Found %s, %i, %i", ptrFound.getCellRef().getRefId().c_str(), + ptrFound.getCellRef().getRefNum(), ptrFound.getCellRef().getMpNum()); + + if (worldObject.objectState) + MWBase::Environment::get().getWorld()->enable(ptrFound); + else + MWBase::Environment::get().getWorld()->disable(ptrFound); + } + } +} + void WorldEvent::moveObjects(MWWorld::CellStore* cellStore) { for (const auto &worldObject : worldObjects) @@ -630,6 +652,18 @@ void WorldEvent::addObjectScale(const MWWorld::Ptr& ptr, float scale) addObject(worldObject); } +void WorldEvent::addObjectState(const MWWorld::Ptr& ptr, bool objectState) +{ + cell = *ptr.getCell()->getCell(); + + mwmp::WorldObject worldObject; + worldObject.refId = ptr.getCellRef().getRefId(); + worldObject.refNumIndex = ptr.getCellRef().getRefNum().mIndex; + worldObject.mpNum = ptr.getCellRef().getMpNum(); + worldObject.objectState = objectState; + addObject(worldObject); +} + void WorldEvent::addObjectAnimPlay(const MWWorld::Ptr& ptr, std::string group, int mode) { cell = *ptr.getCell()->getCell(); @@ -759,6 +793,12 @@ void WorldEvent::sendObjectScale() mwmp::Main::get().getNetworking()->getWorldPacket(ID_OBJECT_SCALE)->Send(); } +void WorldEvent::sendObjectState() +{ + mwmp::Main::get().getNetworking()->getWorldPacket(ID_OBJECT_STATE)->setEvent(this); + mwmp::Main::get().getNetworking()->getWorldPacket(ID_OBJECT_STATE)->Send(); +} + void WorldEvent::sendObjectAnimPlay() { mwmp::Main::get().getNetworking()->getWorldPacket(ID_OBJECT_ANIM_PLAY)->setEvent(this); diff --git a/apps/openmw/mwmp/WorldEvent.hpp b/apps/openmw/mwmp/WorldEvent.hpp index 7ed6bd435..fb9650644 100644 --- a/apps/openmw/mwmp/WorldEvent.hpp +++ b/apps/openmw/mwmp/WorldEvent.hpp @@ -26,6 +26,7 @@ namespace mwmp void lockObjects(MWWorld::CellStore* cellStore); void triggerTrapObjects(MWWorld::CellStore* cellStore); void scaleObjects(MWWorld::CellStore* cellStore); + void setObjectStates(MWWorld::CellStore* cellStore); void moveObjects(MWWorld::CellStore* cellStore); void rotateObjects(MWWorld::CellStore* cellStore); void animateObjects(MWWorld::CellStore* cellStore); @@ -46,6 +47,7 @@ namespace mwmp void addObjectLock(const MWWorld::Ptr& ptr, int lockLevel); void addObjectTrap(const MWWorld::Ptr& ptr, const ESM::Position& pos, bool isDisarmed); void addObjectScale(const MWWorld::Ptr& ptr, float scale); + void addObjectState(const MWWorld::Ptr& ptr, bool objectState); void addObjectAnimPlay(const MWWorld::Ptr& ptr, std::string group, int mode); void addDoorState(const MWWorld::Ptr& ptr, int state); void addMusicPlay(std::string filename); @@ -61,6 +63,7 @@ namespace mwmp void sendObjectLock(); void sendObjectTrap(); void sendObjectScale(); + void sendObjectState(); void sendObjectAnimPlay(); void sendDoorState(); void sendMusicPlay(); diff --git a/apps/openmw/mwmp/processors/ProcessorInitializer.cpp b/apps/openmw/mwmp/processors/ProcessorInitializer.cpp index 42e053f55..987fd1795 100644 --- a/apps/openmw/mwmp/processors/ProcessorInitializer.cpp +++ b/apps/openmw/mwmp/processors/ProcessorInitializer.cpp @@ -132,6 +132,7 @@ void ProcessorInitializer() WorldProcessor::AddProcessor(new ProcessorObjectRotate()); WorldProcessor::AddProcessor(new ProcessorObjectScale()); WorldProcessor::AddProcessor(new ProcessorObjectSpawn()); + WorldProcessor::AddProcessor(new ProcessorObjectState()); WorldProcessor::AddProcessor(new ProcessorObjectTrap()); WorldProcessor::AddProcessor(new ProcessorScriptLocalShort()); WorldProcessor::AddProcessor(new ProcessorScriptLocalFloat()); diff --git a/apps/openmw/mwmp/processors/world/ProcessorObjectState.hpp b/apps/openmw/mwmp/processors/world/ProcessorObjectState.hpp index 34e02e425..1619fce09 100644 --- a/apps/openmw/mwmp/processors/world/ProcessorObjectState.hpp +++ b/apps/openmw/mwmp/processors/world/ProcessorObjectState.hpp @@ -17,7 +17,7 @@ namespace mwmp { BaseObjectProcessor::Do(packet, event); - //event.setObjectStates(ptrCellStore); + event.setObjectStates(ptrCellStore); } }; } diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 35fd9e63c..08c6a7284 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -18,6 +18,7 @@ #include #include "../mwmp/Main.hpp" #include "../mwmp/Networking.hpp" +#include "../mwmp/LocalPlayer.hpp" #include "../mwmp/WorldEvent.hpp" /* End of tes3mp addition @@ -582,12 +583,46 @@ namespace MWScript { MWWorld::Ptr ref = getReferenceImp (id, false); MWBase::Environment::get().getWorld()->enable (ref); + + /* + Start of tes3mp addition + + Send an ID_OBJECT_STATE packet whenever an object is enabled, as long as + the player has finished character generation + */ + if (mwmp::Main::get().getLocalPlayer()->hasFinishedCharGen()) + { + mwmp::WorldEvent *worldEvent = mwmp::Main::get().getNetworking()->getWorldEvent(); + worldEvent->reset(); + worldEvent->addObjectState(ref, true); + worldEvent->sendObjectState(); + } + /* + End of tes3mp addition + */ } void InterpreterContext::disable (const std::string& id) { MWWorld::Ptr ref = getReferenceImp (id, false); MWBase::Environment::get().getWorld()->disable (ref); + + /* + Start of tes3mp addition + + Send an ID_OBJECT_STATE packet whenever an object is disabled, as long as + the player has finished character generation + */ + if (mwmp::Main::get().getLocalPlayer()->hasFinishedCharGen()) + { + mwmp::WorldEvent *worldEvent = mwmp::Main::get().getNetworking()->getWorldEvent(); + worldEvent->reset(); + worldEvent->addObjectState(ref, false); + worldEvent->sendObjectState(); + } + /* + End of tes3mp addition + */ } int InterpreterContext::getMemberShort (const std::string& id, const std::string& name, diff --git a/components/openmw-mp/Base/BaseEvent.hpp b/components/openmw-mp/Base/BaseEvent.hpp index 464fe22ff..6adb60b7a 100644 --- a/components/openmw-mp/Base/BaseEvent.hpp +++ b/components/openmw-mp/Base/BaseEvent.hpp @@ -32,6 +32,7 @@ namespace mwmp ESM::Position position; + bool objectState; int doorState; int lockLevel; float scale; diff --git a/components/openmw-mp/Packets/World/PacketObjectState.cpp b/components/openmw-mp/Packets/World/PacketObjectState.cpp index 8754f37c2..499acb506 100644 --- a/components/openmw-mp/Packets/World/PacketObjectState.cpp +++ b/components/openmw-mp/Packets/World/PacketObjectState.cpp @@ -8,3 +8,9 @@ PacketObjectState::PacketObjectState(RakNet::RakPeerInterface *peer) : WorldPack packetID = ID_OBJECT_STATE; hasCellData = true; } + +void PacketObjectState::Object(WorldObject &worldObject, bool send) +{ + WorldPacket::Object(worldObject, send); + RW(worldObject.objectState, send); +} diff --git a/components/openmw-mp/Packets/World/PacketObjectState.hpp b/components/openmw-mp/Packets/World/PacketObjectState.hpp index f598fb874..1fb2f2c90 100644 --- a/components/openmw-mp/Packets/World/PacketObjectState.hpp +++ b/components/openmw-mp/Packets/World/PacketObjectState.hpp @@ -9,6 +9,8 @@ namespace mwmp { public: PacketObjectState(RakNet::RakPeerInterface *peer); + + virtual void Object(WorldObject &worldObject, bool send); }; }