mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 22:56:44 +00:00 
			
		
		
		
	[General] Implement OnObjectHit packet, part 1
ObjectHit is now sent when an NPC hits a non-actor object.
This commit is contained in:
		
							parent
							
								
									0e0ac7a60f
								
							
						
					
					
						commit
						2973cc4f4d
					
				
					 12 changed files with 226 additions and 14 deletions
				
			
		|  | @ -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}) | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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. | ||||
|  |  | |||
|  | @ -189,6 +189,7 @@ public: | |||
|             {"OnContainer",              Callback<unsigned short, const char*>()}, | ||||
|             {"OnDoorState",              Callback<unsigned short, const char*>()}, | ||||
|             {"OnObjectActivate",         Callback<unsigned short, const char*>()}, | ||||
|             {"OnObjectHit",              Callback<unsigned short, const char*>()}, | ||||
|             {"OnObjectPlace",            Callback<unsigned short, const char*>()}, | ||||
|             {"OnObjectState",            Callback<unsigned short, const char*>()}, | ||||
|             {"OnObjectSpawn",            Callback<unsigned short, const char*>()}, | ||||
|  |  | |||
|  | @ -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()); | ||||
|  |  | |||
							
								
								
									
										25
									
								
								apps/openmw-mp/processors/object/ProcessorObjectHit.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								apps/openmw-mp/processors/object/ProcessorObjectHit.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -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<Script::CallbackIdentity("OnObjectHit")>(player.getId(), objectList.cell.getDescription().c_str()); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| #endif //OPENMW_PROCESSOROBJECTHIT_HPP
 | ||||
|  | @ -18,8 +18,10 @@ | |||
| */ | ||||
| #include <components/openmw-mp/TimedLog.hpp> | ||||
| #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; | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -51,6 +51,7 @@ namespace mwmp | |||
|         void addRequestedContainers(MWWorld::CellStore* cellStore, const std::vector<BaseObject>& 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(); | ||||
|  |  | |||
|  | @ -63,6 +63,7 @@ namespace mwmp | |||
|         bool droppedByPlayer; | ||||
| 
 | ||||
|         Target activatingActor; | ||||
|         Target hittingActor; | ||||
| 
 | ||||
|         bool isSummon; | ||||
|         int summonEffectId; | ||||
|  |  | |||
|  | @ -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); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue