[General] Expand ObjectTrap packet, allowing server to set new traps

This commit is contained in:
David Cernat 2022-07-04 21:49:12 +03:00
parent 2ea011821f
commit 2ccb541850
10 changed files with 116 additions and 33 deletions

View File

@ -154,6 +154,16 @@ int ObjectFunctions::GetObjectLockLevel(unsigned int index) noexcept
return readObjectList->baseObjects.at(index).lockLevel; 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 unsigned int ObjectFunctions::GetObjectDialogueChoiceType(unsigned int index) noexcept
{ {
return readObjectList->baseObjects.at(index).dialogueChoiceType; return readObjectList->baseObjects.at(index).dialogueChoiceType;
@ -505,6 +515,16 @@ void ObjectFunctions::SetObjectLockLevel(int lockLevel) noexcept
tempObject.lockLevel = lockLevel; 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 void ObjectFunctions::SetObjectDialogueChoiceType(unsigned int dialogueChoiceType) noexcept
{ {
tempObject.dialogueChoiceType = dialogueChoiceType; tempObject.dialogueChoiceType = dialogueChoiceType;
@ -530,11 +550,6 @@ void ObjectFunctions::SetObjectLastGoldRestockDay(int lastGoldRestockDay) noexce
tempObject.lastGoldRestockDay = lastGoldRestockDay; tempObject.lastGoldRestockDay = lastGoldRestockDay;
} }
void ObjectFunctions::SetObjectDisarmState(bool disarmState) noexcept
{
tempObject.isDisarmed = disarmState;
}
void ObjectFunctions::SetObjectDroppedByPlayerState(bool droppedByPlayer) noexcept void ObjectFunctions::SetObjectDroppedByPlayerState(bool droppedByPlayer) noexcept
{ {
tempObject.droppedByPlayer = droppedByPlayer; tempObject.droppedByPlayer = droppedByPlayer;
@ -1006,6 +1021,14 @@ void ObjectFunctions::SetObjectRefNumIndex(int refNum) noexcept
SetObjectRefNum(refNum); 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 void ObjectFunctions::AddWorldObject() noexcept
{ {
AddObject(); AddObject();

View File

@ -31,6 +31,8 @@
{"GetObjectState", ObjectFunctions::GetObjectState},\ {"GetObjectState", ObjectFunctions::GetObjectState},\
{"GetObjectDoorState", ObjectFunctions::GetObjectDoorState},\ {"GetObjectDoorState", ObjectFunctions::GetObjectDoorState},\
{"GetObjectLockLevel", ObjectFunctions::GetObjectLockLevel},\ {"GetObjectLockLevel", ObjectFunctions::GetObjectLockLevel},\
{"GetObjectTrapSpellId", ObjectFunctions::GetObjectTrapSpellId},\
{"GetObjectTrapAction", ObjectFunctions::GetObjectTrapAction},\
{"GetObjectDialogueChoiceType", ObjectFunctions::GetObjectDialogueChoiceType},\ {"GetObjectDialogueChoiceType", ObjectFunctions::GetObjectDialogueChoiceType},\
{"GetObjectDialogueChoiceTopic", ObjectFunctions::GetObjectDialogueChoiceTopic},\ {"GetObjectDialogueChoiceTopic", ObjectFunctions::GetObjectDialogueChoiceTopic},\
{"GetObjectGoldPool", ObjectFunctions::GetObjectGoldPool},\ {"GetObjectGoldPool", ObjectFunctions::GetObjectGoldPool},\
@ -107,12 +109,13 @@
{"SetObjectScale", ObjectFunctions::SetObjectScale},\ {"SetObjectScale", ObjectFunctions::SetObjectScale},\
{"SetObjectState", ObjectFunctions::SetObjectState},\ {"SetObjectState", ObjectFunctions::SetObjectState},\
{"SetObjectLockLevel", ObjectFunctions::SetObjectLockLevel},\ {"SetObjectLockLevel", ObjectFunctions::SetObjectLockLevel},\
{"SetObjectTrapSpellId", ObjectFunctions::SetObjectTrapSpellId},\
{"SetObjectTrapAction", ObjectFunctions::SetObjectTrapAction},\
{"SetObjectDialogueChoiceType", ObjectFunctions::SetObjectDialogueChoiceType},\ {"SetObjectDialogueChoiceType", ObjectFunctions::SetObjectDialogueChoiceType},\
{"SetObjectDialogueChoiceTopic", ObjectFunctions::SetObjectDialogueChoiceTopic},\ {"SetObjectDialogueChoiceTopic", ObjectFunctions::SetObjectDialogueChoiceTopic},\
{"SetObjectGoldPool", ObjectFunctions::SetObjectGoldPool},\ {"SetObjectGoldPool", ObjectFunctions::SetObjectGoldPool},\
{"SetObjectLastGoldRestockHour", ObjectFunctions::SetObjectLastGoldRestockHour},\ {"SetObjectLastGoldRestockHour", ObjectFunctions::SetObjectLastGoldRestockHour},\
{"SetObjectLastGoldRestockDay", ObjectFunctions::SetObjectLastGoldRestockDay},\ {"SetObjectLastGoldRestockDay", ObjectFunctions::SetObjectLastGoldRestockDay},\
{"SetObjectDisarmState", ObjectFunctions::SetObjectDisarmState},\
{"SetObjectDroppedByPlayerState", ObjectFunctions::SetObjectDroppedByPlayerState},\ {"SetObjectDroppedByPlayerState", ObjectFunctions::SetObjectDroppedByPlayerState},\
{"SetObjectPosition", ObjectFunctions::SetObjectPosition},\ {"SetObjectPosition", ObjectFunctions::SetObjectPosition},\
{"SetObjectRotation", ObjectFunctions::SetObjectRotation},\ {"SetObjectRotation", ObjectFunctions::SetObjectRotation},\
@ -184,6 +187,7 @@
{"SetEventAction", ObjectFunctions::SetEventAction},\ {"SetEventAction", ObjectFunctions::SetEventAction},\
{"SetEventConsoleCommand", ObjectFunctions::SetEventConsoleCommand},\ {"SetEventConsoleCommand", ObjectFunctions::SetEventConsoleCommand},\
{"SetObjectRefNumIndex", ObjectFunctions::SetObjectRefNumIndex},\ {"SetObjectRefNumIndex", ObjectFunctions::SetObjectRefNumIndex},\
{"SetObjectDisarmState", ObjectFunctions::SetObjectDisarmState},\
{"AddWorldObject", ObjectFunctions::AddWorldObject} {"AddWorldObject", ObjectFunctions::AddWorldObject}
class ObjectFunctions class ObjectFunctions
@ -396,6 +400,22 @@ public:
*/ */
static int GetObjectLockLevel(unsigned int index) noexcept; 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. * \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; 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. * \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; 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. * \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 SetEventAction(unsigned char action) noexcept;
static void SetEventConsoleCommand(const char* consoleCommand) noexcept; static void SetEventConsoleCommand(const char* consoleCommand) noexcept;
static void SetObjectRefNumIndex(int refNum) noexcept; static void SetObjectRefNumIndex(int refNum) noexcept;
static void SetObjectDisarmState(bool disarmState) noexcept;
static void AddWorldObject() noexcept; static void AddWorldObject() noexcept;
}; };

View File

@ -219,7 +219,7 @@ namespace MWClass
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset(); objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; 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(); objectList->sendObjectTrap();
/* /*
End of tes3mp addition End of tes3mp addition

View File

@ -206,7 +206,7 @@ namespace MWClass
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset(); objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; 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(); objectList->sendObjectTrap();
/* /*
End of tes3mp addition End of tes3mp addition

View File

@ -161,7 +161,7 @@ namespace MWMechanics
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset(); objectList->reset();
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; 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(); objectList->sendObjectTrap();
/* /*
End of tes3mp addition End of tes3mp addition

View File

@ -652,7 +652,8 @@ void ObjectList::triggerTrapObjects(MWWorld::CellStore* cellStore)
{ {
for (const auto &baseObject : baseObjects) 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); 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(), LOG_APPEND(TimedLog::LOG_VERBOSE, "-- Found %s %i-%i", ptrFound.getCellRef().getRefId().c_str(),
ptrFound.getCellRef().getRefNum(), ptrFound.getCellRef().getMpNum()); ptrFound.getCellRef().getRefNum(), ptrFound.getCellRef().getMpNum());
if (!baseObject.isDisarmed) if (baseObject.trapAction == mwmp::BaseObjectList::TRAP_ACTION::SET_TRAP)
{
if (!baseObject.trapSpellId.empty() && !RecordHelper::doesRecordIdExist<ESM::Spell>(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); MWMechanics::CastSpell cast(ptrFound, ptrFound);
cast.mHitPosition = baseObject.position.asVec3(); cast.mHitPosition = baseObject.trapTriggerPosition.asVec3();
cast.cast(ptrFound.getCellRef().getTrap()); cast.cast(baseObject.trapSpellId);
} }
ptrFound.getCellRef().setTrap(""); ptrFound.getCellRef().setTrap("");
MWBase::Environment::get().getSoundManager()->playSound3D(ptrFound, "Disarm Trap", 1.0f, 1.0f); }
} }
} }
} }
@ -1376,13 +1395,14 @@ void ObjectList::addObjectMiscellaneous(const MWWorld::Ptr& ptr, unsigned int go
addBaseObject(baseObject); 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(); cell = *ptr.getCell()->getCell();
mwmp::BaseObject baseObject = getBaseObjectFromPtr(ptr); mwmp::BaseObject baseObject = getBaseObjectFromPtr(ptr);
baseObject.isDisarmed = isDisarmed; baseObject.trapAction = trapAction;
baseObject.position = pos; baseObject.trapSpellId = trapSpellId;
baseObject.trapTriggerPosition = trapTriggerPosition;
addBaseObject(baseObject); addBaseObject(baseObject);
} }

View File

@ -65,7 +65,7 @@ namespace mwmp
void addObjectLock(const MWWorld::Ptr& ptr, int lockLevel); void addObjectLock(const MWWorld::Ptr& ptr, int lockLevel);
void addObjectDialogueChoice(const MWWorld::Ptr& ptr, std::string dialogueChoice); void addObjectDialogueChoice(const MWWorld::Ptr& ptr, std::string dialogueChoice);
void addObjectMiscellaneous(const MWWorld::Ptr& ptr, unsigned int goldPool, float lastGoldRestockHour, int lastGoldRestockDay); 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 addObjectScale(const MWWorld::Ptr& ptr, float scale);
void addObjectSound(const MWWorld::Ptr& ptr, std::string soundId, float volume, float pitch); void addObjectSound(const MWWorld::Ptr& ptr, std::string soundId, float volume, float pitch);
void addObjectState(const MWWorld::Ptr& ptr, bool objectState); void addObjectState(const MWWorld::Ptr& ptr, bool objectState);

View File

@ -69,7 +69,7 @@ namespace MWWorld
else else
pos = actor.getRefData().getPosition(); pos = actor.getRefData().getPosition();
objectList->addObjectTrap(mTrapSource, pos, false); objectList->addObjectTrap(mTrapSource, mSpellId, mwmp::BaseObjectList::TRAP_ACTION::TRIGGER, pos);
objectList->sendObjectTrap(); objectList->sendObjectTrap();
/* /*
End of tes3mp addition End of tes3mp addition

View File

@ -67,7 +67,10 @@ namespace mwmp
std::string animGroup; std::string animGroup;
int animMode; int animMode;
bool isDisarmed; std::string trapSpellId;
unsigned int trapAction;
ESM::Position trapTriggerPosition;
bool droppedByPlayer; bool droppedByPlayer;
Target activatingActor; Target activatingActor;
@ -112,6 +115,13 @@ namespace mwmp
REQUEST = 3 REQUEST = 3
}; };
enum TRAP_ACTION
{
SET_TRAP = 0,
DISARM = 1,
TRIGGER = 2
};
enum CONTAINER_SUBACTION enum CONTAINER_SUBACTION
{ {
NONE = 0, NONE = 0,

View File

@ -12,8 +12,9 @@ PacketObjectTrap::PacketObjectTrap(RakNet::RakPeerInterface *peer) : ObjectPacke
void PacketObjectTrap::Object(BaseObject &baseObject, bool send) void PacketObjectTrap::Object(BaseObject &baseObject, bool send)
{ {
ObjectPacket::Object(baseObject, send); ObjectPacket::Object(baseObject, send);
RW(baseObject.isDisarmed, send); RW(baseObject.trapSpellId, send, true);
RW(baseObject.trapAction, send);
if (!baseObject.isDisarmed) if (baseObject.trapAction == mwmp::BaseObjectList::TRAP_ACTION::TRIGGER)
RW(baseObject.position, send); RW(baseObject.trapTriggerPosition, send);
} }