diff --git a/apps/openmw-mp/CMakeLists.txt b/apps/openmw-mp/CMakeLists.txt index ca354f37a..75d108242 100644 --- a/apps/openmw-mp/CMakeLists.txt +++ b/apps/openmw-mp/CMakeLists.txt @@ -116,14 +116,15 @@ set(PROCESSORS_OBJECT processors/object/ProcessorConsoleCommand.hpp processors/object/ProcessorContainer.hpp processors/object/ProcessorDoorState.hpp processors/object/ProcessorMusicPlay.hpp processors/object/ProcessorObjectActivate.hpp processors/object/ProcessorObjectAnimPlay.hpp - processors/object/ProcessorObjectDelete.hpp processors/object/ProcessorObjectLock.hpp - processors/object/ProcessorObjectMove.hpp processors/object/ProcessorObjectPlace.hpp - processors/object/ProcessorObjectRotate.hpp processors/object/ProcessorObjectScale.hpp - processors/object/ProcessorObjectSpawn.hpp processors/object/ProcessorObjectState.hpp - processors/object/ProcessorObjectTrap.hpp processors/object/ProcessorScriptLocalShort.hpp - processors/object/ProcessorScriptLocalFloat.hpp processors/object/ProcessorScriptMemberShort.hpp - processors/object/ProcessorScriptMemberFloat.hpp processors/object/ProcessorScriptGlobalShort.hpp - processors/object/ProcessorScriptGlobalFloat.hpp processors/object/ProcessorVideoPlay.hpp + processors/object/ProcessorObjectDelete.hpp processors/object/ProcessorObjectHit.hpp + processors/object/ProcessorObjectLock.hpp processors/object/ProcessorObjectMove.hpp + processors/object/ProcessorObjectPlace.hpp processors/object/ProcessorObjectRotate.hpp + processors/object/ProcessorObjectScale.hpp processors/object/ProcessorObjectSpawn.hpp + processors/object/ProcessorObjectState.hpp processors/object/ProcessorObjectTrap.hpp + processors/object/ProcessorScriptLocalShort.hpp processors/object/ProcessorScriptLocalFloat.hpp + processors/object/ProcessorScriptMemberShort.hpp processors/object/ProcessorScriptMemberFloat.hpp + processors/object/ProcessorScriptGlobalShort.hpp processors/object/ProcessorScriptGlobalFloat.hpp + processors/object/ProcessorVideoPlay.hpp ) source_group(tes3mp-server\\processors\\object FILES ${PROCESSORS_OBJECT}) diff --git a/apps/openmw-mp/Script/Functions/Objects.cpp b/apps/openmw-mp/Script/Functions/Objects.cpp index adf3e4b11..07094828d 100644 --- a/apps/openmw-mp/Script/Functions/Objects.cpp +++ b/apps/openmw-mp/Script/Functions/Objects.cpp @@ -184,6 +184,41 @@ const char *ObjectFunctions::GetObjectActivatingName(unsigned int index) noexcep return readObjectList->baseObjects.at(index).activatingActor.name.c_str(); } +bool ObjectFunctions::DoesObjectHavePlayerHitting(unsigned int index) noexcept +{ + return readObjectList->baseObjects.at(index).hittingActor.isPlayer; +} + +int ObjectFunctions::GetObjectHittingPid(unsigned int index) noexcept +{ + Player *player = Players::getPlayer(readObjectList->baseObjects.at(index).hittingActor.guid); + + if (player != nullptr) + return player->getId(); + + return -1; +} + +const char *ObjectFunctions::GetObjectHittingRefId(unsigned int index) noexcept +{ + return readObjectList->baseObjects.at(index).hittingActor.refId.c_str(); +} + +unsigned int ObjectFunctions::GetObjectHittingRefNum(unsigned int index) noexcept +{ + return readObjectList->baseObjects.at(index).hittingActor.refNum; +} + +unsigned int ObjectFunctions::GetObjectHittingMpNum(unsigned int index) noexcept +{ + return readObjectList->baseObjects.at(index).hittingActor.mpNum; +} + +const char *ObjectFunctions::GetObjectHittingName(unsigned int index) noexcept +{ + return readObjectList->baseObjects.at(index).hittingActor.name.c_str(); +} + bool ObjectFunctions::GetObjectSummonState(unsigned int index) noexcept { return readObjectList->baseObjects.at(index).isSummon; diff --git a/apps/openmw-mp/Script/Functions/Objects.hpp b/apps/openmw-mp/Script/Functions/Objects.hpp index 7d42c3f80..38f3b15b0 100644 --- a/apps/openmw-mp/Script/Functions/Objects.hpp +++ b/apps/openmw-mp/Script/Functions/Objects.hpp @@ -38,6 +38,13 @@ {"GetObjectActivatingMpNum", ObjectFunctions::GetObjectActivatingMpNum},\ {"GetObjectActivatingName", ObjectFunctions::GetObjectActivatingName},\ \ + {"DoesObjectHavePlayerHitting", ObjectFunctions::DoesObjectHavePlayerHitting},\ + {"GetObjectHittingPid", ObjectFunctions::GetObjectHittingPid},\ + {"GetObjectHittingRefId", ObjectFunctions::GetObjectHittingRefId},\ + {"GetObjectHittingRefNum", ObjectFunctions::GetObjectHittingRefNum},\ + {"GetObjectHittingMpNum", ObjectFunctions::GetObjectHittingMpNum},\ + {"GetObjectHittingName", ObjectFunctions::GetObjectHittingName},\ + \ {"GetObjectSummonState", ObjectFunctions::GetObjectSummonState},\ {"GetObjectSummonEffectId", ObjectFunctions::GetObjectSummonEffectId},\ {"GetObjectSummonSpellId", ObjectFunctions::GetObjectSummonSpellId},\ @@ -410,6 +417,60 @@ public: */ static const char *GetObjectActivatingName(unsigned int index) noexcept; + /** + * \brief Check whether the object at a certain index in the read object list has been + * hit by a player. + * + * \param index The index of the object. + * \return Whether the object has been hit by a player. + */ + static bool DoesObjectHavePlayerHitting(unsigned int index) noexcept; + + /** + * \brief Get the player ID of the player hitting the object at a certain index in the + * read object list. + * + * \param index The index of the object. + * \return The player ID of the hitting player. + */ + static int GetObjectHittingPid(unsigned int index) noexcept; + + /** + * \brief Get the refId of the actor hitting the object at a certain index in the read + * object list. + * + * \param index The index of the object. + * \return The refId of the hitting actor. + */ + static const char *GetObjectHittingRefId(unsigned int index) noexcept; + + /** + * \brief Get the refNum of the actor hitting the object at a certain index in the read + * object list. + * + * \param index The index of the object. + * \return The refNum of the hitting actor. + */ + static unsigned int GetObjectHittingRefNum(unsigned int index) noexcept; + + /** + * \brief Get the mpNum of the actor hitting the object at a certain index in the read + * object list. + * + * \param index The index of the object. + * \return The mpNum of the hitting actor. + */ + static unsigned int GetObjectHittingMpNum(unsigned int index) noexcept; + + /** + * \brief Get the name of the actor hitting the object at a certain index in the read + * object list. + * + * \param index The index of the object. + * \return The name of the hitting actor. + */ + static const char *GetObjectHittingName(unsigned int index) noexcept; + /** * \brief Check whether the object at a certain index in the read object list is a * summon. diff --git a/apps/openmw-mp/Script/ScriptFunctions.hpp b/apps/openmw-mp/Script/ScriptFunctions.hpp index 22bcd8927..342595e98 100644 --- a/apps/openmw-mp/Script/ScriptFunctions.hpp +++ b/apps/openmw-mp/Script/ScriptFunctions.hpp @@ -189,6 +189,7 @@ public: {"OnContainer", Callback()}, {"OnDoorState", Callback()}, {"OnObjectActivate", Callback()}, + {"OnObjectHit", Callback()}, {"OnObjectPlace", Callback()}, {"OnObjectState", Callback()}, {"OnObjectSpawn", Callback()}, diff --git a/apps/openmw-mp/processors/ProcessorInitializer.cpp b/apps/openmw-mp/processors/ProcessorInitializer.cpp index dfe982983..54dc336f8 100644 --- a/apps/openmw-mp/processors/ProcessorInitializer.cpp +++ b/apps/openmw-mp/processors/ProcessorInitializer.cpp @@ -61,6 +61,7 @@ #include "object/ProcessorObjectActivate.hpp" #include "object/ProcessorObjectAnimPlay.hpp" #include "object/ProcessorObjectDelete.hpp" +#include "object/ProcessorObjectHit.hpp" #include "object/ProcessorObjectPlace.hpp" #include "object/ProcessorObjectLock.hpp" #include "object/ProcessorObjectMove.hpp" @@ -143,6 +144,7 @@ void ProcessorInitializer() ObjectProcessor::AddProcessor(new ProcessorObjectActivate()); ObjectProcessor::AddProcessor(new ProcessorObjectAnimPlay()); ObjectProcessor::AddProcessor(new ProcessorObjectDelete()); + ObjectProcessor::AddProcessor(new ProcessorObjectHit()); ObjectProcessor::AddProcessor(new ProcessorObjectLock()); ObjectProcessor::AddProcessor(new ProcessorObjectMove()); ObjectProcessor::AddProcessor(new ProcessorObjectPlace()); diff --git a/apps/openmw-mp/processors/object/ProcessorObjectHit.hpp b/apps/openmw-mp/processors/object/ProcessorObjectHit.hpp new file mode 100644 index 000000000..cee07ca9f --- /dev/null +++ b/apps/openmw-mp/processors/object/ProcessorObjectHit.hpp @@ -0,0 +1,25 @@ +#ifndef OPENMW_PROCESSOROBJECTHIT_HPP +#define OPENMW_PROCESSOROBJECTHIT_HPP + +#include "../ObjectProcessor.hpp" + +namespace mwmp +{ + class ProcessorObjectHit : public ObjectProcessor + { + public: + ProcessorObjectHit() + { + BPP_INIT(ID_OBJECT_HIT) + } + + void Do(ObjectPacket &packet, Player &player, BaseObjectList &objectList) override + { + LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received %s from %s", strPacketID.c_str(), player.npc.mName.c_str()); + + Script::Call(player.getId(), objectList.cell.getDescription().c_str()); + } + }; +} + +#endif //OPENMW_PROCESSOROBJECTHIT_HPP diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 8360393b5..67f9a41e4 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -18,8 +18,10 @@ */ #include #include "../mwmp/Main.hpp" +#include "../mwmp/Networking.hpp" #include "../mwmp/LocalPlayer.hpp" #include "../mwmp/PlayerList.hpp" +#include "../mwmp/ObjectList.hpp" #include "../mwmp/CellController.hpp" #include "../mwmp/MechanicsHelper.hpp" /* @@ -612,8 +614,23 @@ namespace MWClass return; const MWWorld::Class &othercls = victim.getClass(); - if(!othercls.isActor()) // Can't hit non-actors - return; + /* + Start of tes3mp change (major) + + Send an ID_OBJECT_HIT packet when hitting non-actors instead of + just returning + */ + if(!othercls.isActor()) + { + mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); + objectList->reset(); + objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY; + objectList->addObjectHit(victim, ptr); + objectList->sendObjectHit(); + } + /* + End of tes3mp change (major) + */ MWMechanics::CreatureStats &otherstats = othercls.getCreatureStats(victim); if(otherstats.isDead()) // Can't hit dead actors return; diff --git a/apps/openmw/mwmp/ObjectList.cpp b/apps/openmw/mwmp/ObjectList.cpp index 84c3c6f2e..7f314ab9d 100644 --- a/apps/openmw/mwmp/ObjectList.cpp +++ b/apps/openmw/mwmp/ObjectList.cpp @@ -967,6 +967,35 @@ void ObjectList::addObjectActivate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& addObject(baseObject); } +void ObjectList::addObjectHit(const MWWorld::Ptr& ptr, const MWWorld::Ptr& hittingActor) +{ + cell = *ptr.getCell()->getCell(); + + mwmp::BaseObject baseObject; + + if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) + { + baseObject.isPlayer = true; + baseObject.guid = mwmp::Main::get().getLocalPlayer()->guid; + } + else if (mwmp::PlayerList::isDedicatedPlayer(ptr)) + { + baseObject.isPlayer = true; + baseObject.guid = mwmp::PlayerList::getPlayer(ptr)->guid; + } + else + { + baseObject.isPlayer = false; + baseObject.refId = ptr.getCellRef().getRefId(); + baseObject.refNum = ptr.getCellRef().getRefNum().mIndex; + baseObject.mpNum = ptr.getCellRef().getMpNum(); + } + + baseObject.hittingActor = MechanicsHelper::getTarget(hittingActor); + + addObject(baseObject); +} + void ObjectList::addObjectPlace(const MWWorld::Ptr& ptr, bool droppedByPlayer) { if (ptr.getCellRef().getRefId().find("$dynamic") != string::npos) @@ -1223,6 +1252,12 @@ void ObjectList::sendObjectActivate() mwmp::Main::get().getNetworking()->getObjectPacket(ID_OBJECT_ACTIVATE)->Send(); } +void ObjectList::sendObjectHit() +{ + mwmp::Main::get().getNetworking()->getObjectPacket(ID_OBJECT_HIT)->setObjectList(this); + mwmp::Main::get().getNetworking()->getObjectPacket(ID_OBJECT_HIT)->Send(); +} + void ObjectList::sendObjectPlace() { if (baseObjects.size() == 0) diff --git a/apps/openmw/mwmp/ObjectList.hpp b/apps/openmw/mwmp/ObjectList.hpp index bd28f8878..9431d4066 100644 --- a/apps/openmw/mwmp/ObjectList.hpp +++ b/apps/openmw/mwmp/ObjectList.hpp @@ -51,6 +51,7 @@ namespace mwmp void addRequestedContainers(MWWorld::CellStore* cellStore, const std::vector& requestObjects); void addObjectActivate(const MWWorld::Ptr& ptr, const MWWorld::Ptr& activatingActor); + void addObjectHit(const MWWorld::Ptr& ptr, const MWWorld::Ptr& hittingActor); 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, std::string spellId, int effectId, float duration); @@ -71,6 +72,7 @@ namespace mwmp void addScriptGlobalShort(std::string varName, int shortVal); void sendObjectActivate(); + void sendObjectHit(); void sendObjectPlace(); void sendObjectSpawn(); void sendObjectDelete(); diff --git a/components/openmw-mp/Base/BaseObject.hpp b/components/openmw-mp/Base/BaseObject.hpp index 8beb5439a..9f794f793 100644 --- a/components/openmw-mp/Base/BaseObject.hpp +++ b/components/openmw-mp/Base/BaseObject.hpp @@ -63,6 +63,7 @@ namespace mwmp bool droppedByPlayer; Target activatingActor; + Target hittingActor; bool isSummon; int summonEffectId; diff --git a/components/openmw-mp/Packets/Object/PacketObjectHit.cpp b/components/openmw-mp/Packets/Object/PacketObjectHit.cpp index 0585f761f..903d42062 100644 --- a/components/openmw-mp/Packets/Object/PacketObjectHit.cpp +++ b/components/openmw-mp/Packets/Object/PacketObjectHit.cpp @@ -9,8 +9,40 @@ PacketObjectHit::PacketObjectHit(RakNet::RakPeerInterface *peer) : ObjectPacket( hasCellData = true; } -void PacketObjectHit::Object(BaseObject &baseObject, bool send) +void PacketObjectHit::Packet(RakNet::BitStream *newBitstream, bool send) { - ObjectPacket::Object(baseObject, send); - // Placeholder + if (!PacketHeader(newBitstream, send)) + return; + + BaseObject baseObject; + for (unsigned int i = 0; i < objectList->baseObjectCount; i++) + { + if (send) + baseObject = objectList->baseObjects.at(i); + + RW(baseObject.isPlayer, send); + + if (baseObject.isPlayer) + RW(baseObject.guid, send); + else + Object(baseObject, send); + + RW(baseObject.hittingActor.isPlayer, send); + + if (baseObject.hittingActor.isPlayer) + { + RW(baseObject.hittingActor.guid, send); + } + else + { + RW(baseObject.hittingActor.refId, send, true); + RW(baseObject.hittingActor.refNum, send); + RW(baseObject.hittingActor.mpNum, send); + + RW(baseObject.hittingActor.name, send); + } + + if (!send) + objectList->baseObjects.push_back(baseObject); + } } diff --git a/components/openmw-mp/Packets/Object/PacketObjectHit.hpp b/components/openmw-mp/Packets/Object/PacketObjectHit.hpp index 9ddbbf8ed..69ac47c92 100644 --- a/components/openmw-mp/Packets/Object/PacketObjectHit.hpp +++ b/components/openmw-mp/Packets/Object/PacketObjectHit.hpp @@ -10,7 +10,7 @@ namespace mwmp public: PacketObjectHit(RakNet::RakPeerInterface *peer); - virtual void Object(BaseObject &baseObject, bool send); + virtual void Packet(RakNet::BitStream *newBitstream, bool send); }; }