diff --git a/apps/openmw-mp/Script/Functions/Objects.cpp b/apps/openmw-mp/Script/Functions/Objects.cpp index 4e5860c99..119d00a40 100644 --- a/apps/openmw-mp/Script/Functions/Objects.cpp +++ b/apps/openmw-mp/Script/Functions/Objects.cpp @@ -154,6 +154,16 @@ int ObjectFunctions::GetObjectLockLevel(unsigned int index) noexcept return readObjectList->baseObjects.at(index).lockLevel; } +const char* ObjectFunctions::GetObjectTrapSpellId(unsigned int index) noexcept +{ + return readObjectList->baseObjects.at(index).trapSpellId.c_str(); +} + +unsigned int ObjectFunctions::GetObjectTrapAction(unsigned int index) noexcept +{ + return readObjectList->baseObjects.at(index).trapAction; +} + unsigned int ObjectFunctions::GetObjectDialogueChoiceType(unsigned int index) noexcept { return readObjectList->baseObjects.at(index).dialogueChoiceType; @@ -505,6 +515,16 @@ void ObjectFunctions::SetObjectLockLevel(int lockLevel) noexcept tempObject.lockLevel = lockLevel; } +void ObjectFunctions::SetObjectTrapSpellId(const char* trapSpellId) noexcept +{ + tempObject.trapSpellId = trapSpellId; +} + +void ObjectFunctions::SetObjectTrapAction(unsigned int trapAction) noexcept +{ + tempObject.trapAction = trapAction; +} + void ObjectFunctions::SetObjectDialogueChoiceType(unsigned int dialogueChoiceType) noexcept { tempObject.dialogueChoiceType = dialogueChoiceType; @@ -530,11 +550,6 @@ void ObjectFunctions::SetObjectLastGoldRestockDay(int lastGoldRestockDay) noexce tempObject.lastGoldRestockDay = lastGoldRestockDay; } -void ObjectFunctions::SetObjectDisarmState(bool disarmState) noexcept -{ - tempObject.isDisarmed = disarmState; -} - void ObjectFunctions::SetObjectDroppedByPlayerState(bool droppedByPlayer) noexcept { tempObject.droppedByPlayer = droppedByPlayer; @@ -1006,6 +1021,14 @@ void ObjectFunctions::SetObjectRefNumIndex(int refNum) noexcept SetObjectRefNum(refNum); } +void ObjectFunctions::SetObjectDisarmState(bool disarmState) noexcept +{ + if (disarmState) + tempObject.trapAction = mwmp::BaseObjectList::TRAP_ACTION::DISARM; + else + tempObject.trapAction = mwmp::BaseObjectList::TRAP_ACTION::TRIGGER; +} + void ObjectFunctions::AddWorldObject() noexcept { AddObject(); diff --git a/apps/openmw-mp/Script/Functions/Objects.hpp b/apps/openmw-mp/Script/Functions/Objects.hpp index 73ae9d7cb..c90c2931b 100644 --- a/apps/openmw-mp/Script/Functions/Objects.hpp +++ b/apps/openmw-mp/Script/Functions/Objects.hpp @@ -31,6 +31,8 @@ {"GetObjectState", ObjectFunctions::GetObjectState},\ {"GetObjectDoorState", ObjectFunctions::GetObjectDoorState},\ {"GetObjectLockLevel", ObjectFunctions::GetObjectLockLevel},\ + {"GetObjectTrapSpellId", ObjectFunctions::GetObjectTrapSpellId},\ + {"GetObjectTrapAction", ObjectFunctions::GetObjectTrapAction},\ {"GetObjectDialogueChoiceType", ObjectFunctions::GetObjectDialogueChoiceType},\ {"GetObjectDialogueChoiceTopic", ObjectFunctions::GetObjectDialogueChoiceTopic},\ {"GetObjectGoldPool", ObjectFunctions::GetObjectGoldPool},\ @@ -107,12 +109,13 @@ {"SetObjectScale", ObjectFunctions::SetObjectScale},\ {"SetObjectState", ObjectFunctions::SetObjectState},\ {"SetObjectLockLevel", ObjectFunctions::SetObjectLockLevel},\ + {"SetObjectTrapSpellId", ObjectFunctions::SetObjectTrapSpellId},\ + {"SetObjectTrapAction", ObjectFunctions::SetObjectTrapAction},\ {"SetObjectDialogueChoiceType", ObjectFunctions::SetObjectDialogueChoiceType},\ {"SetObjectDialogueChoiceTopic", ObjectFunctions::SetObjectDialogueChoiceTopic},\ {"SetObjectGoldPool", ObjectFunctions::SetObjectGoldPool},\ {"SetObjectLastGoldRestockHour", ObjectFunctions::SetObjectLastGoldRestockHour},\ {"SetObjectLastGoldRestockDay", ObjectFunctions::SetObjectLastGoldRestockDay},\ - {"SetObjectDisarmState", ObjectFunctions::SetObjectDisarmState},\ {"SetObjectDroppedByPlayerState", ObjectFunctions::SetObjectDroppedByPlayerState},\ {"SetObjectPosition", ObjectFunctions::SetObjectPosition},\ {"SetObjectRotation", ObjectFunctions::SetObjectRotation},\ @@ -184,6 +187,7 @@ {"SetEventAction", ObjectFunctions::SetEventAction},\ {"SetEventConsoleCommand", ObjectFunctions::SetEventConsoleCommand},\ {"SetObjectRefNumIndex", ObjectFunctions::SetObjectRefNumIndex},\ + {"SetObjectDisarmState", ObjectFunctions::SetObjectDisarmState},\ {"AddWorldObject", ObjectFunctions::AddWorldObject} class ObjectFunctions @@ -396,6 +400,22 @@ public: */ static int GetObjectLockLevel(unsigned int index) noexcept; + /** + * \brief Get the object trap spell ID of the object at a certain index in the read object list. + * + * \param index The index of the object. + * \return The trap spell ID. + */ + static const char* GetObjectTrapSpellId(unsigned int index) noexcept; + + /** + * \brief Get the trap action for the object at a certain index in the read object list. + * + * \param index The index of the object. + * \return The trap action. + */ + static unsigned int GetObjectTrapAction(unsigned int index) noexcept; + /** * \brief Get the dialogue choice type for the object at a certain index in the read object list. * @@ -1011,6 +1031,22 @@ public: */ static void SetObjectLockLevel(int lockLevel) noexcept; + /** + * \brief Set the trap spell ID of the temporary object stored on the server. + * + * \param trapSpellId The trap spell ID. + * \return void + */ + static void SetObjectTrapSpellId(const char* trapSpellId) noexcept; + + /** + * \brief Set the trap disarm state of the temporary object stored on the server. + * + * \param disarmState The disarmState. + * \return void + */ + static void SetObjectTrapAction(unsigned int trapAction) noexcept; + /** * \brief Set the dialogue choice type of the temporary object stored on the server. * @@ -1051,14 +1087,6 @@ public: */ static void SetObjectLastGoldRestockDay(int day) noexcept; - /** - * \brief Set the disarm state of the temporary object stored on the server. - * - * \param disarmState The disarmState. - * \return void - */ - static void SetObjectDisarmState(bool disarmState) noexcept; - /** * \brief Set the droppedByPlayer state of the temporary object stored on the server. * @@ -1555,6 +1583,7 @@ public: static void SetEventAction(unsigned char action) noexcept; static void SetEventConsoleCommand(const char* consoleCommand) noexcept; static void SetObjectRefNumIndex(int refNum) noexcept; + static void SetObjectDisarmState(bool disarmState) noexcept; static void AddWorldObject() noexcept; }; diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index f7d63c4a9..3577d2839 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -219,7 +219,7 @@ namespace MWClass mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); objectList->reset(); objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; - objectList->addObjectTrap(ptr, ptr.getRefData().getPosition(), true); + objectList->addObjectTrap(ptr, ptr.getCellRef().getTrap(), mwmp::BaseObjectList::TRAP_ACTION::DISARM, ptr.getRefData().getPosition()); objectList->sendObjectTrap(); /* End of tes3mp addition diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index f61f246e9..9ed9d2f19 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -206,7 +206,7 @@ namespace MWClass mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); objectList->reset(); objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; - objectList->addObjectTrap(ptr, ptr.getRefData().getPosition(), true); + objectList->addObjectTrap(ptr, ptr.getCellRef().getTrap(), mwmp::BaseObjectList::TRAP_ACTION::DISARM, ptr.getRefData().getPosition()); objectList->sendObjectTrap(); /* End of tes3mp addition diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index 577cdc269..25676e7c2 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -161,7 +161,7 @@ namespace MWMechanics mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); objectList->reset(); objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; - objectList->addObjectTrap(trap, trap.getRefData().getPosition(), true); + objectList->addObjectTrap(trap, trap.getCellRef().getTrap(), mwmp::BaseObjectList::TRAP_ACTION::DISARM, trap.getRefData().getPosition()); objectList->sendObjectTrap(); /* End of tes3mp addition diff --git a/apps/openmw/mwmp/ObjectList.cpp b/apps/openmw/mwmp/ObjectList.cpp index 8136f9377..86575d944 100644 --- a/apps/openmw/mwmp/ObjectList.cpp +++ b/apps/openmw/mwmp/ObjectList.cpp @@ -652,7 +652,8 @@ void ObjectList::triggerTrapObjects(MWWorld::CellStore* cellStore) { for (const auto &baseObject : baseObjects) { - LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum); + LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i, trapSpellId: %s, trapAction: %i", + baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum, baseObject.trapSpellId.c_str(), baseObject.trapAction); MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId); @@ -661,15 +662,33 @@ void ObjectList::triggerTrapObjects(MWWorld::CellStore* cellStore) LOG_APPEND(TimedLog::LOG_VERBOSE, "-- Found %s %i-%i", ptrFound.getCellRef().getRefId().c_str(), ptrFound.getCellRef().getRefNum(), ptrFound.getCellRef().getMpNum()); - if (!baseObject.isDisarmed) + if (baseObject.trapAction == mwmp::BaseObjectList::TRAP_ACTION::SET_TRAP) { - MWMechanics::CastSpell cast(ptrFound, ptrFound); - cast.mHitPosition = baseObject.position.asVec3(); - cast.cast(ptrFound.getCellRef().getTrap()); + if (!baseObject.trapSpellId.empty() && !RecordHelper::doesRecordIdExist(baseObject.trapSpellId)) + { + LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "-- Ignored attempt to set invalid spell %s as trap", baseObject.refId.c_str()); + ptrFound.getCellRef().setTrap(""); + } + else + { + ptrFound.getCellRef().setTrap(baseObject.trapSpellId); + } } + else + { + if (baseObject.trapAction == mwmp::BaseObjectList::TRAP_ACTION::DISARM) + { + MWBase::Environment::get().getSoundManager()->playSound3D(ptrFound, "Disarm Trap", 1.0f, 1.0f); + } + else if (baseObject.trapAction == mwmp::BaseObjectList::TRAP_ACTION::TRIGGER) + { + MWMechanics::CastSpell cast(ptrFound, ptrFound); + cast.mHitPosition = baseObject.trapTriggerPosition.asVec3(); + cast.cast(baseObject.trapSpellId); + } - ptrFound.getCellRef().setTrap(""); - MWBase::Environment::get().getSoundManager()->playSound3D(ptrFound, "Disarm Trap", 1.0f, 1.0f); + ptrFound.getCellRef().setTrap(""); + } } } } @@ -1376,13 +1395,14 @@ void ObjectList::addObjectMiscellaneous(const MWWorld::Ptr& ptr, unsigned int go addBaseObject(baseObject); } -void ObjectList::addObjectTrap(const MWWorld::Ptr& ptr, const ESM::Position& pos, bool isDisarmed) +void ObjectList::addObjectTrap(const MWWorld::Ptr& ptr, std::string trapSpellId, unsigned int trapAction, const ESM::Position& trapTriggerPosition) { cell = *ptr.getCell()->getCell(); mwmp::BaseObject baseObject = getBaseObjectFromPtr(ptr); - baseObject.isDisarmed = isDisarmed; - baseObject.position = pos; + baseObject.trapAction = trapAction; + baseObject.trapSpellId = trapSpellId; + baseObject.trapTriggerPosition = trapTriggerPosition; addBaseObject(baseObject); } diff --git a/apps/openmw/mwmp/ObjectList.hpp b/apps/openmw/mwmp/ObjectList.hpp index 8fceed8cb..d8fac9893 100644 --- a/apps/openmw/mwmp/ObjectList.hpp +++ b/apps/openmw/mwmp/ObjectList.hpp @@ -65,7 +65,7 @@ namespace mwmp void addObjectLock(const MWWorld::Ptr& ptr, int lockLevel); void addObjectDialogueChoice(const MWWorld::Ptr& ptr, std::string dialogueChoice); void addObjectMiscellaneous(const MWWorld::Ptr& ptr, unsigned int goldPool, float lastGoldRestockHour, int lastGoldRestockDay); - void addObjectTrap(const MWWorld::Ptr& ptr, const ESM::Position& pos, bool isDisarmed); + void addObjectTrap(const MWWorld::Ptr& ptr, std::string trapSpellId, unsigned int trapAction, const ESM::Position& trapTriggerPosition); void addObjectScale(const MWWorld::Ptr& ptr, float scale); void addObjectSound(const MWWorld::Ptr& ptr, std::string soundId, float volume, float pitch); void addObjectState(const MWWorld::Ptr& ptr, bool objectState); diff --git a/apps/openmw/mwworld/actiontrap.cpp b/apps/openmw/mwworld/actiontrap.cpp index f80a6b84e..5d160cb7f 100644 --- a/apps/openmw/mwworld/actiontrap.cpp +++ b/apps/openmw/mwworld/actiontrap.cpp @@ -69,7 +69,7 @@ namespace MWWorld else pos = actor.getRefData().getPosition(); - objectList->addObjectTrap(mTrapSource, pos, false); + objectList->addObjectTrap(mTrapSource, mSpellId, mwmp::BaseObjectList::TRAP_ACTION::TRIGGER, pos); objectList->sendObjectTrap(); /* End of tes3mp addition diff --git a/components/openmw-mp/Base/BaseObject.hpp b/components/openmw-mp/Base/BaseObject.hpp index 94175a63d..2bcc106ba 100644 --- a/components/openmw-mp/Base/BaseObject.hpp +++ b/components/openmw-mp/Base/BaseObject.hpp @@ -67,7 +67,10 @@ namespace mwmp std::string animGroup; int animMode; - bool isDisarmed; + std::string trapSpellId; + unsigned int trapAction; + ESM::Position trapTriggerPosition; + bool droppedByPlayer; Target activatingActor; @@ -112,6 +115,13 @@ namespace mwmp REQUEST = 3 }; + enum TRAP_ACTION + { + SET_TRAP = 0, + DISARM = 1, + TRIGGER = 2 + }; + enum CONTAINER_SUBACTION { NONE = 0, diff --git a/components/openmw-mp/Packets/Object/PacketObjectTrap.cpp b/components/openmw-mp/Packets/Object/PacketObjectTrap.cpp index 36b884862..865436ac4 100644 --- a/components/openmw-mp/Packets/Object/PacketObjectTrap.cpp +++ b/components/openmw-mp/Packets/Object/PacketObjectTrap.cpp @@ -12,8 +12,9 @@ PacketObjectTrap::PacketObjectTrap(RakNet::RakPeerInterface *peer) : ObjectPacke void PacketObjectTrap::Object(BaseObject &baseObject, bool send) { ObjectPacket::Object(baseObject, send); - RW(baseObject.isDisarmed, send); + RW(baseObject.trapSpellId, send, true); + RW(baseObject.trapAction, send); - if (!baseObject.isDisarmed) - RW(baseObject.position, send); + if (baseObject.trapAction == mwmp::BaseObjectList::TRAP_ACTION::TRIGGER) + RW(baseObject.trapTriggerPosition, send); }