mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-29 23:06:45 +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