[General] Synchronize death animations for players

This commit is contained in:
David Cernat 2019-11-29 12:52:47 +02:00
parent 47443e19cb
commit 16662d772b
6 changed files with 46 additions and 19 deletions

View File

@ -37,6 +37,7 @@
#include "../mwmp/LocalPlayer.hpp" #include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/LocalActor.hpp" #include "../mwmp/LocalActor.hpp"
#include "../mwmp/PlayerList.hpp" #include "../mwmp/PlayerList.hpp"
#include "../mwmp/DedicatedPlayer.hpp"
#include "../mwmp/CellController.hpp" #include "../mwmp/CellController.hpp"
#include "../mwmp/MechanicsHelper.hpp" #include "../mwmp/MechanicsHelper.hpp"
/* /*
@ -792,7 +793,8 @@ void CharacterController::playRandomDeath(float startpoint)
If this is a LocalActor or DedicatedActor whose death animation is supposed to be finished, If this is a LocalActor or DedicatedActor whose death animation is supposed to be finished,
set the startpoint to the animation's end set the startpoint to the animation's end
*/ */
if (mPtr.getClass().getCreatureStats(mPtr).isDeathAnimationFinished() && (mwmp::Main::get().getCellController()->isLocalActor(mPtr) || mwmp::Main::get().getCellController()->isDedicatedActor(mPtr))) if (mPtr.getClass().getCreatureStats(mPtr).isDeathAnimationFinished() &&
(mwmp::Main::get().getCellController()->isLocalActor(mPtr) || mwmp::Main::get().getCellController()->isDedicatedActor(mPtr)))
{ {
startpoint = 1.F; startpoint = 1.F;
} }
@ -807,7 +809,19 @@ void CharacterController::playRandomDeath(float startpoint)
MWBase::Environment::get().getWorld()->useDeathCamera(); MWBase::Environment::get().getWorld()->useDeathCamera();
} }
if(mHitState == CharState_SwimKnockDown && mAnimation->hasAnimation("swimdeathknockdown")) /*
Start tes3mp change (major)
If this is a DedicatedPlayer, use the deathState received from their PlayerDeath packet
*/
if (mwmp::PlayerList::isDedicatedPlayer(mPtr))
{
mDeathState = static_cast<CharacterState>(mwmp::PlayerList::getPlayer(mPtr)->deathState);
}
else if(mHitState == CharState_SwimKnockDown && mAnimation->hasAnimation("swimdeathknockdown"))
/*
End of tes3mp change (major)
*/
{ {
mDeathState = CharState_SwimDeathKnockDown; mDeathState = CharState_SwimDeathKnockDown;
} }
@ -832,6 +846,19 @@ void CharacterController::playRandomDeath(float startpoint)
mDeathState = chooseRandomDeathState(); mDeathState = chooseRandomDeathState();
} }
/*
Start of tes3mp addition
Send a PlayerDeath packet with the decided-upon death animation
*/
if (mPtr == getPlayer())
{
mwmp::Main::get().getLocalPlayer()->sendDeath(mDeathState);
}
/*
End of tes3mp addition
*/
// Do not interrupt scripted animation by death // Do not interrupt scripted animation by death
if (isPersistentAnimPlaying()) if (isPersistentAnimPlaying())
return; return;

View File

@ -256,22 +256,6 @@ void LocalPlayer::updateStatsDynamic(bool forceUpdate)
exchangeFullInfo = false; exchangeFullInfo = false;
getNetworking()->getPlayerPacket(ID_PLAYER_STATS_DYNAMIC)->setPlayer(this); getNetworking()->getPlayerPacket(ID_PLAYER_STATS_DYNAMIC)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_STATS_DYNAMIC)->Send(); getNetworking()->getPlayerPacket(ID_PLAYER_STATS_DYNAMIC)->Send();
static bool wasDead = false;
if (creatureStats.mDead && !wasDead)
{
if (MechanicsHelper::isEmptyTarget(killer))
killer = MechanicsHelper::getTarget(getPlayerPtr());
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_PLAYER_DEATH about myself to server");
getNetworking()->getPlayerPacket(ID_PLAYER_DEATH)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_DEATH)->Send();
MechanicsHelper::clearTarget(killer);
}
wasDead = creatureStats.mDead;
} }
} }
@ -1361,6 +1345,20 @@ void LocalPlayer::setSelectedSpell()
int(MWMechanics::getSpellSuccessChance(selectedSpellId, ptrPlayer))); int(MWMechanics::getSpellSuccessChance(selectedSpellId, ptrPlayer)));
} }
void LocalPlayer::sendDeath(char deathState)
{
if (MechanicsHelper::isEmptyTarget(killer))
killer = MechanicsHelper::getTarget(getPlayerPtr());
this->deathState = deathState;
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_PLAYER_DEATH about myself to server\n- deathState: %d", deathState);
getNetworking()->getPlayerPacket(ID_PLAYER_DEATH)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_DEATH)->Send();
MechanicsHelper::clearTarget(killer);
}
void LocalPlayer::sendClass() void LocalPlayer::sendClass()
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();

View File

@ -75,6 +75,7 @@ namespace mwmp
void setMarkLocation(); void setMarkLocation();
void setSelectedSpell(); void setSelectedSpell();
void sendDeath(char deathState);
void sendClass(); void sendClass();
void sendInventory(); void sendInventory();
void sendItemChange(const mwmp::Item& item, unsigned int action); void sendItemChange(const mwmp::Item& item, unsigned int action);

View File

@ -12,7 +12,6 @@ namespace mwmp
ProcessorPlayerDeath() ProcessorPlayerDeath()
{ {
BPP_INIT(ID_PLAYER_DEATH) BPP_INIT(ID_PLAYER_DEATH)
avoidReading = true;
} }
virtual void Do(PlayerPacket &packet, BasePlayer *player) virtual void Do(PlayerPacket &packet, BasePlayer *player)

View File

@ -252,6 +252,7 @@ namespace mwmp
std::string sound; std::string sound;
Animation animation; Animation animation;
char deathState;
bool resetStats; bool resetStats;
float scale; float scale;

View File

@ -12,6 +12,7 @@ void PacketPlayerDeath::Packet(RakNet::BitStream *bs, bool send)
{ {
PlayerPacket::Packet(bs, send); PlayerPacket::Packet(bs, send);
RW(player->deathState, send);
RW(player->killer.isPlayer, send); RW(player->killer.isPlayer, send);
if (player->killer.isPlayer) if (player->killer.isPlayer)