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
|
set(PROCESSORS_ACTOR
|
||||||
processors/actor/ProcessorActorAnimFlags.hpp processors/actor/ProcessorActorAnimPlay.hpp
|
processors/actor/ProcessorActorAnimFlags.hpp processors/actor/ProcessorActorAnimPlay.hpp
|
||||||
processors/actor/ProcessorActorAttack.hpp processors/actor/ProcessorActorCellChange.hpp
|
processors/actor/ProcessorActorAttack.hpp processors/actor/ProcessorActorCellChange.hpp
|
||||||
processors/actor/ProcessorActorEquipment.hpp processors/actor/ProcessorActorInteraction.hpp
|
processors/actor/ProcessorActorDeath.hpp processors/actor/ProcessorActorEquipment.hpp
|
||||||
processors/actor/ProcessorActorList.hpp processors/actor/ProcessorActorPosition.hpp
|
processors/actor/ProcessorActorInteraction.hpp processors/actor/ProcessorActorList.hpp
|
||||||
processors/actor/ProcessorActorSpeech.hpp processors/actor/ProcessorActorStatsDynamic.hpp
|
processors/actor/ProcessorActorPosition.hpp processors/actor/ProcessorActorSpeech.hpp
|
||||||
processors/actor/ProcessorActorTest.hpp
|
processors/actor/ProcessorActorStatsDynamic.hpp processors/actor/ProcessorActorTest.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(tes3mp-server\\processors\\actor FILES ${PROCESSORS_ACTOR})
|
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;
|
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
|
bool ActorFunctions::DoesActorHavePosition(unsigned int i) noexcept
|
||||||
{
|
{
|
||||||
return readActorList->baseActors.at(i).hasPositionData;
|
return readActorList->baseActors.at(i).hasPositionData;
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
{"GetActorEquipmentItemCharge", ActorFunctions::GetActorEquipmentItemCharge},\
|
{"GetActorEquipmentItemCharge", ActorFunctions::GetActorEquipmentItemCharge},\
|
||||||
{"GetActorEquipmentItemEnchantmentCharge", ActorFunctions::GetActorEquipmentItemEnchantmentCharge},\
|
{"GetActorEquipmentItemEnchantmentCharge", ActorFunctions::GetActorEquipmentItemEnchantmentCharge},\
|
||||||
\
|
\
|
||||||
|
{"GetActorDeathReason", ActorFunctions::GetActorDeathReason},\
|
||||||
|
\
|
||||||
{"DoesActorHavePosition", ActorFunctions::DoesActorHavePosition},\
|
{"DoesActorHavePosition", ActorFunctions::DoesActorHavePosition},\
|
||||||
{"DoesActorHaveStatsDynamic", ActorFunctions::DoesActorHaveStatsDynamic},\
|
{"DoesActorHaveStatsDynamic", ActorFunctions::DoesActorHaveStatsDynamic},\
|
||||||
\
|
\
|
||||||
|
@ -315,6 +317,14 @@ public:
|
||||||
*/
|
*/
|
||||||
static double GetActorEquipmentItemEnchantmentCharge(unsigned int i, unsigned short slot) noexcept;
|
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
|
* \brief Check whether there is any positional data for the actor at a certain index in
|
||||||
* the read actor list.
|
* the read actor list.
|
||||||
|
|
|
@ -340,6 +340,7 @@ public:
|
||||||
{"OnObjectTrap", Function<void, unsigned short, const char*>()},
|
{"OnObjectTrap", Function<void, unsigned short, const char*>()},
|
||||||
{"OnActorList", Function<void, unsigned short, const char*>()},
|
{"OnActorList", Function<void, unsigned short, const char*>()},
|
||||||
{"OnActorEquipment", 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*>()},
|
{"OnActorCellChange", Function<void, unsigned short, const char*>()},
|
||||||
{"OnActorTest", Function<void, unsigned short, const char*>()},
|
{"OnActorTest", Function<void, unsigned short, const char*>()},
|
||||||
{"OnPlayerSendMessage", Function<bool, unsigned short, const char*>()},
|
{"OnPlayerSendMessage", Function<bool, unsigned short, const char*>()},
|
||||||
|
|
|
@ -19,7 +19,11 @@ namespace mwmp
|
||||||
Cell *serverCell = CellController::get()->getCell(&actorList.cell);
|
Cell *serverCell = CellController::get()->getCell(&actorList.cell);
|
||||||
|
|
||||||
if (serverCell != nullptr && *serverCell->getAuthority() == actorList.guid)
|
if (serverCell != nullptr && *serverCell->getAuthority() == actorList.guid)
|
||||||
|
{
|
||||||
|
Script::Call<Script::CallbackIdentity("OnActorDeath")>(player.getId(), actorList.cell.getDescription().c_str());
|
||||||
|
|
||||||
serverCell->sendToLoaded(&packet, &actorList);
|
serverCell->sendToLoaded(&packet, &actorList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -540,6 +540,8 @@ namespace MWClass
|
||||||
Start of tes3mp addition
|
Start of tes3mp addition
|
||||||
|
|
||||||
If the attacker was the LocalPlayer or LocalActor, record their target and send a packet with it
|
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);
|
mwmp::Attack *localAttack = MechanicsHelper::getLocalAttack(attacker);
|
||||||
|
|
||||||
|
@ -553,6 +555,14 @@ namespace MWClass
|
||||||
|
|
||||||
localAttack->shouldSend = true;
|
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
|
End of tes3mp addition
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -953,6 +953,8 @@ namespace MWClass
|
||||||
|
|
||||||
If the victim was the LocalPlayer, check whether packets should be sent about
|
If the victim was the LocalPlayer, check whether packets should be sent about
|
||||||
their new dynamic stats and position
|
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);
|
mwmp::Attack *localAttack = MechanicsHelper::getLocalAttack(attacker);
|
||||||
|
|
||||||
|
@ -978,6 +980,13 @@ namespace MWClass
|
||||||
mwmp::Main::get().getLocalPlayer()->deathReason = attacker.getClass().getName(attacker);
|
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
|
End of tes3mp addition
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -32,6 +32,7 @@ void ActorList::reset()
|
||||||
animPlayActors.clear();
|
animPlayActors.clear();
|
||||||
speechActors.clear();
|
speechActors.clear();
|
||||||
statsDynamicActors.clear();
|
statsDynamicActors.clear();
|
||||||
|
deathActors.clear();
|
||||||
equipmentActors.clear();
|
equipmentActors.clear();
|
||||||
attackActors.clear();
|
attackActors.clear();
|
||||||
cellChangeActors.clear();
|
cellChangeActors.clear();
|
||||||
|
@ -73,6 +74,11 @@ void ActorList::addStatsDynamicActor(LocalActor localActor)
|
||||||
statsDynamicActors.push_back(localActor);
|
statsDynamicActors.push_back(localActor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActorList::addDeathActor(LocalActor localActor)
|
||||||
|
{
|
||||||
|
deathActors.push_back(localActor);
|
||||||
|
}
|
||||||
|
|
||||||
void ActorList::addEquipmentActor(LocalActor localActor)
|
void ActorList::addEquipmentActor(LocalActor localActor)
|
||||||
{
|
{
|
||||||
equipmentActors.push_back(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()
|
void ActorList::sendEquipmentActors()
|
||||||
{
|
{
|
||||||
if (equipmentActors.size() > 0)
|
if (equipmentActors.size() > 0)
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace mwmp
|
||||||
void addAnimPlayActor(LocalActor localActor);
|
void addAnimPlayActor(LocalActor localActor);
|
||||||
void addSpeechActor(LocalActor localActor);
|
void addSpeechActor(LocalActor localActor);
|
||||||
void addStatsDynamicActor(LocalActor localActor);
|
void addStatsDynamicActor(LocalActor localActor);
|
||||||
|
void addDeathActor(LocalActor localActor);
|
||||||
void addEquipmentActor(LocalActor localActor);
|
void addEquipmentActor(LocalActor localActor);
|
||||||
void addAttackActor(LocalActor localActor);
|
void addAttackActor(LocalActor localActor);
|
||||||
void addCellChangeActor(LocalActor localActor);
|
void addCellChangeActor(LocalActor localActor);
|
||||||
|
@ -35,6 +36,7 @@ namespace mwmp
|
||||||
void sendAnimPlayActors();
|
void sendAnimPlayActors();
|
||||||
void sendSpeechActors();
|
void sendSpeechActors();
|
||||||
void sendStatsDynamicActors();
|
void sendStatsDynamicActors();
|
||||||
|
void sendDeathActors();
|
||||||
void sendEquipmentActors();
|
void sendEquipmentActors();
|
||||||
void sendAttackActors();
|
void sendAttackActors();
|
||||||
void sendCellChangeActors();
|
void sendCellChangeActors();
|
||||||
|
@ -49,6 +51,7 @@ namespace mwmp
|
||||||
std::vector<BaseActor> animPlayActors;
|
std::vector<BaseActor> animPlayActors;
|
||||||
std::vector<BaseActor> speechActors;
|
std::vector<BaseActor> speechActors;
|
||||||
std::vector<BaseActor> statsDynamicActors;
|
std::vector<BaseActor> statsDynamicActors;
|
||||||
|
std::vector<BaseActor> deathActors;
|
||||||
std::vector<BaseActor> equipmentActors;
|
std::vector<BaseActor> equipmentActors;
|
||||||
std::vector<BaseActor> attackActors;
|
std::vector<BaseActor> attackActors;
|
||||||
std::vector<BaseActor> cellChangeActors;
|
std::vector<BaseActor> cellChangeActors;
|
||||||
|
|
|
@ -93,6 +93,7 @@ void Cell::updateLocal(bool forceUpdate)
|
||||||
actorList->sendAnimFlagsActors();
|
actorList->sendAnimFlagsActors();
|
||||||
actorList->sendAnimPlayActors();
|
actorList->sendAnimPlayActors();
|
||||||
actorList->sendSpeechActors();
|
actorList->sendSpeechActors();
|
||||||
|
actorList->sendDeathActors();
|
||||||
actorList->sendStatsDynamicActors();
|
actorList->sendStatsDynamicActors();
|
||||||
actorList->sendEquipmentActors();
|
actorList->sendEquipmentActors();
|
||||||
actorList->sendAttackActors();
|
actorList->sendAttackActors();
|
||||||
|
@ -370,6 +371,11 @@ void Cell::initializeLocalActor(const MWWorld::Ptr& ptr)
|
||||||
actor->cell = *store->getCell();
|
actor->cell = *store->getCell();
|
||||||
actor->setPtr(ptr);
|
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);
|
std::string mapIndex = Main::get().getCellController()->generateMapIndex(ptr);
|
||||||
localActors[mapIndex] = actor;
|
localActors[mapIndex] = actor;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ LocalActor::LocalActor()
|
||||||
wasForceJumping = false;
|
wasForceJumping = false;
|
||||||
wasForceMoveJumping = false;
|
wasForceMoveJumping = false;
|
||||||
wasFlying = false;
|
wasFlying = false;
|
||||||
|
wasDead = false;
|
||||||
|
|
||||||
attack.type = Attack::MELEE;
|
attack.type = Attack::MELEE;
|
||||||
attack.shouldSend = false;
|
attack.shouldSend = false;
|
||||||
|
@ -179,6 +180,22 @@ void LocalActor::updateStatsDynamic(bool forceUpdate)
|
||||||
creatureStats.mDead = ptrCreatureStats->isDead();
|
creatureStats.mDead = ptrCreatureStats->isDead();
|
||||||
|
|
||||||
mwmp::Main::get().getNetworking()->getActorList()->addStatsDynamicActor(*this);
|
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();
|
MWWorld::Ptr getPtr();
|
||||||
void setPtr(const MWWorld::Ptr& newPtr);
|
void setPtr(const MWWorld::Ptr& newPtr);
|
||||||
|
|
||||||
|
bool wasDead;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MWWorld::Ptr ptr;
|
MWWorld::Ptr ptr;
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@ namespace mwmp
|
||||||
Animation animation;
|
Animation animation;
|
||||||
Attack attack;
|
Attack attack;
|
||||||
|
|
||||||
|
std::string deathReason;
|
||||||
|
|
||||||
bool hasAiTarget;
|
bool hasAiTarget;
|
||||||
Target aiTarget;
|
Target aiTarget;
|
||||||
unsigned int aiAction;
|
unsigned int aiAction;
|
||||||
|
|
|
@ -11,5 +11,5 @@ PacketActorDeath::PacketActorDeath(RakNet::RakPeerInterface *peer) : ActorPacket
|
||||||
|
|
||||||
void PacketActorDeath::Actor(BaseActor &actor, bool send)
|
void PacketActorDeath::Actor(BaseActor &actor, bool send)
|
||||||
{
|
{
|
||||||
// Placeholder to be filled in later
|
RW(actor.deathReason, send);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue