forked from mirror/openmw-tes3mp
[General] Implement ActorDeath packet, part 1
ActorDeath packets are sent for dead actors before their StatsDynamic packets. They contain the actor's deathReason in a manner similar to that of PlayerDeath packets. A future commit will replace the deathReason with a variable named killer which will be an mwmp::Target.
This commit is contained in:
parent
15bfa30070
commit
7ffdb18bf9
14 changed files with 90 additions and 5 deletions
|
@ -113,10 +113,10 @@ source_group(tes3mp-server FILES ${SERVER} ${SERVER_HEADER})
|
|||
set(PROCESSORS_ACTOR
|
||||
processors/actor/ProcessorActorAnimFlags.hpp processors/actor/ProcessorActorAnimPlay.hpp
|
||||
processors/actor/ProcessorActorAttack.hpp processors/actor/ProcessorActorCellChange.hpp
|
||||
processors/actor/ProcessorActorEquipment.hpp processors/actor/ProcessorActorInteraction.hpp
|
||||
processors/actor/ProcessorActorList.hpp processors/actor/ProcessorActorPosition.hpp
|
||||
processors/actor/ProcessorActorSpeech.hpp processors/actor/ProcessorActorStatsDynamic.hpp
|
||||
processors/actor/ProcessorActorTest.hpp
|
||||
processors/actor/ProcessorActorDeath.hpp processors/actor/ProcessorActorEquipment.hpp
|
||||
processors/actor/ProcessorActorInteraction.hpp processors/actor/ProcessorActorList.hpp
|
||||
processors/actor/ProcessorActorPosition.hpp processors/actor/ProcessorActorSpeech.hpp
|
||||
processors/actor/ProcessorActorStatsDynamic.hpp processors/actor/ProcessorActorTest.hpp
|
||||
)
|
||||
|
||||
source_group(tes3mp-server\\processors\\actor FILES ${PROCESSORS_ACTOR})
|
||||
|
|
|
@ -168,6 +168,11 @@ double ActorFunctions::GetActorEquipmentItemEnchantmentCharge(unsigned int i, un
|
|||
return readActorList->baseActors.at(i).equipmentItems[slot].enchantmentCharge;
|
||||
}
|
||||
|
||||
const char *ActorFunctions::GetActorDeathReason(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).deathReason.c_str();
|
||||
}
|
||||
|
||||
bool ActorFunctions::DoesActorHavePosition(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).hasPositionData;
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
{"GetActorEquipmentItemCharge", ActorFunctions::GetActorEquipmentItemCharge},\
|
||||
{"GetActorEquipmentItemEnchantmentCharge", ActorFunctions::GetActorEquipmentItemEnchantmentCharge},\
|
||||
\
|
||||
{"GetActorDeathReason", ActorFunctions::GetActorDeathReason},\
|
||||
\
|
||||
{"DoesActorHavePosition", ActorFunctions::DoesActorHavePosition},\
|
||||
{"DoesActorHaveStatsDynamic", ActorFunctions::DoesActorHaveStatsDynamic},\
|
||||
\
|
||||
|
@ -315,6 +317,14 @@ public:
|
|||
*/
|
||||
static double GetActorEquipmentItemEnchantmentCharge(unsigned int i, unsigned short slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the death reason of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The death reason.
|
||||
*/
|
||||
static const char *GetActorDeathReason(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Check whether there is any positional data for the actor at a certain index in
|
||||
* the read actor list.
|
||||
|
|
|
@ -340,6 +340,7 @@ public:
|
|||
{"OnObjectTrap", Function<void, unsigned short, const char*>()},
|
||||
{"OnActorList", Function<void, unsigned short, const char*>()},
|
||||
{"OnActorEquipment", Function<void, unsigned short, const char*>()},
|
||||
{"OnActorDeath", Function<void, unsigned short, const char*>()},
|
||||
{"OnActorCellChange", Function<void, unsigned short, const char*>()},
|
||||
{"OnActorTest", Function<void, unsigned short, const char*>()},
|
||||
{"OnPlayerSendMessage", Function<bool, unsigned short, const char*>()},
|
||||
|
|
|
@ -19,7 +19,11 @@ namespace mwmp
|
|||
Cell *serverCell = CellController::get()->getCell(&actorList.cell);
|
||||
|
||||
if (serverCell != nullptr && *serverCell->getAuthority() == actorList.guid)
|
||||
{
|
||||
Script::Call<Script::CallbackIdentity("OnActorDeath")>(player.getId(), actorList.cell.getDescription().c_str());
|
||||
|
||||
serverCell->sendToLoaded(&packet, &actorList);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -540,6 +540,8 @@ namespace MWClass
|
|||
Start of tes3mp addition
|
||||
|
||||
If the attacker was the LocalPlayer or LocalActor, record their target and send a packet with it
|
||||
|
||||
If the victim was a LocalActor who died, record their attacker as the deathReason
|
||||
*/
|
||||
mwmp::Attack *localAttack = MechanicsHelper::getLocalAttack(attacker);
|
||||
|
||||
|
@ -553,6 +555,14 @@ namespace MWClass
|
|||
|
||||
localAttack->shouldSend = true;
|
||||
}
|
||||
|
||||
if (mwmp::Main::get().getCellController()->isLocalActor(ptr))
|
||||
{
|
||||
if (getCreatureStats(ptr).isDead())
|
||||
{
|
||||
mwmp::Main::get().getCellController()->getLocalActor(ptr)->deathReason = attacker.getClass().getName(attacker);
|
||||
}
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
|
|
@ -953,6 +953,8 @@ namespace MWClass
|
|||
|
||||
If the victim was the LocalPlayer, check whether packets should be sent about
|
||||
their new dynamic stats and position
|
||||
|
||||
If the victim was a LocalActor who died, record their attacker as the deathReason
|
||||
*/
|
||||
mwmp::Attack *localAttack = MechanicsHelper::getLocalAttack(attacker);
|
||||
|
||||
|
@ -978,6 +980,13 @@ namespace MWClass
|
|||
mwmp::Main::get().getLocalPlayer()->deathReason = attacker.getClass().getName(attacker);
|
||||
}
|
||||
}
|
||||
else if (mwmp::Main::get().getCellController()->isLocalActor(ptr))
|
||||
{
|
||||
if (getCreatureStats(ptr).isDead())
|
||||
{
|
||||
mwmp::Main::get().getCellController()->getLocalActor(ptr)->deathReason = attacker.getClass().getName(attacker);
|
||||
}
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
|
|
@ -32,6 +32,7 @@ void ActorList::reset()
|
|||
animPlayActors.clear();
|
||||
speechActors.clear();
|
||||
statsDynamicActors.clear();
|
||||
deathActors.clear();
|
||||
equipmentActors.clear();
|
||||
attackActors.clear();
|
||||
cellChangeActors.clear();
|
||||
|
@ -73,6 +74,11 @@ void ActorList::addStatsDynamicActor(LocalActor localActor)
|
|||
statsDynamicActors.push_back(localActor);
|
||||
}
|
||||
|
||||
void ActorList::addDeathActor(LocalActor localActor)
|
||||
{
|
||||
deathActors.push_back(localActor);
|
||||
}
|
||||
|
||||
void ActorList::addEquipmentActor(LocalActor localActor)
|
||||
{
|
||||
equipmentActors.push_back(localActor);
|
||||
|
@ -138,6 +144,16 @@ void ActorList::sendStatsDynamicActors()
|
|||
}
|
||||
}
|
||||
|
||||
void ActorList::sendDeathActors()
|
||||
{
|
||||
if (deathActors.size() > 0)
|
||||
{
|
||||
baseActors = deathActors;
|
||||
Main::get().getNetworking()->getActorPacket(ID_ACTOR_DEATH)->setActorList(this);
|
||||
Main::get().getNetworking()->getActorPacket(ID_ACTOR_DEATH)->Send();
|
||||
}
|
||||
}
|
||||
|
||||
void ActorList::sendEquipmentActors()
|
||||
{
|
||||
if (equipmentActors.size() > 0)
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace mwmp
|
|||
void addAnimPlayActor(LocalActor localActor);
|
||||
void addSpeechActor(LocalActor localActor);
|
||||
void addStatsDynamicActor(LocalActor localActor);
|
||||
void addDeathActor(LocalActor localActor);
|
||||
void addEquipmentActor(LocalActor localActor);
|
||||
void addAttackActor(LocalActor localActor);
|
||||
void addCellChangeActor(LocalActor localActor);
|
||||
|
@ -35,6 +36,7 @@ namespace mwmp
|
|||
void sendAnimPlayActors();
|
||||
void sendSpeechActors();
|
||||
void sendStatsDynamicActors();
|
||||
void sendDeathActors();
|
||||
void sendEquipmentActors();
|
||||
void sendAttackActors();
|
||||
void sendCellChangeActors();
|
||||
|
@ -49,6 +51,7 @@ namespace mwmp
|
|||
std::vector<BaseActor> animPlayActors;
|
||||
std::vector<BaseActor> speechActors;
|
||||
std::vector<BaseActor> statsDynamicActors;
|
||||
std::vector<BaseActor> deathActors;
|
||||
std::vector<BaseActor> equipmentActors;
|
||||
std::vector<BaseActor> attackActors;
|
||||
std::vector<BaseActor> cellChangeActors;
|
||||
|
|
|
@ -93,6 +93,7 @@ void Cell::updateLocal(bool forceUpdate)
|
|||
actorList->sendAnimFlagsActors();
|
||||
actorList->sendAnimPlayActors();
|
||||
actorList->sendSpeechActors();
|
||||
actorList->sendDeathActors();
|
||||
actorList->sendStatsDynamicActors();
|
||||
actorList->sendEquipmentActors();
|
||||
actorList->sendAttackActors();
|
||||
|
@ -370,6 +371,11 @@ void Cell::initializeLocalActor(const MWWorld::Ptr& ptr)
|
|||
actor->cell = *store->getCell();
|
||||
actor->setPtr(ptr);
|
||||
|
||||
// Note that this actor was already dead when we were given control over it,
|
||||
// to avoid sending an ActorDeath packet
|
||||
if (ptr.getClass().getCreatureStats(ptr).isDead())
|
||||
actor->wasDead = true;
|
||||
|
||||
std::string mapIndex = Main::get().getCellController()->generateMapIndex(ptr);
|
||||
localActors[mapIndex] = actor;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ LocalActor::LocalActor()
|
|||
wasForceJumping = false;
|
||||
wasForceMoveJumping = false;
|
||||
wasFlying = false;
|
||||
wasDead = false;
|
||||
|
||||
attack.type = Attack::MELEE;
|
||||
attack.shouldSend = false;
|
||||
|
@ -179,6 +180,22 @@ void LocalActor::updateStatsDynamic(bool forceUpdate)
|
|||
creatureStats.mDead = ptrCreatureStats->isDead();
|
||||
|
||||
mwmp::Main::get().getNetworking()->getActorList()->addStatsDynamicActor(*this);
|
||||
|
||||
if (creatureStats.mDead && !wasDead)
|
||||
{
|
||||
if (deathReason.empty())
|
||||
deathReason = "suicide";
|
||||
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Sending ID_ACTOR_DEATH about %s-%i-%i to server",
|
||||
refId.c_str(), refNumIndex, mpNum);
|
||||
LOG_APPEND(Log::LOG_INFO, "- deathReason was %s", deathReason.c_str());
|
||||
|
||||
mwmp::Main::get().getNetworking()->getActorList()->addDeathActor(*this);
|
||||
|
||||
deathReason = "";
|
||||
}
|
||||
|
||||
wasDead = creatureStats.mDead;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ namespace mwmp
|
|||
MWWorld::Ptr getPtr();
|
||||
void setPtr(const MWWorld::Ptr& newPtr);
|
||||
|
||||
bool wasDead;
|
||||
|
||||
private:
|
||||
MWWorld::Ptr ptr;
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ namespace mwmp
|
|||
Animation animation;
|
||||
Attack attack;
|
||||
|
||||
std::string deathReason;
|
||||
|
||||
bool hasAiTarget;
|
||||
Target aiTarget;
|
||||
unsigned int aiAction;
|
||||
|
|
|
@ -11,5 +11,5 @@ PacketActorDeath::PacketActorDeath(RakNet::RakPeerInterface *peer) : ActorPacket
|
|||
|
||||
void PacketActorDeath::Actor(BaseActor &actor, bool send)
|
||||
{
|
||||
// Placeholder to be filled in later
|
||||
RW(actor.deathReason, send);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue