From 4db64e172135d9860a83d2f1c0d5a75c28053f9a Mon Sep 17 00:00:00 2001 From: David Cernat Date: Fri, 28 Jul 2017 20:49:26 +0300 Subject: [PATCH] [Client] Synchronize spellcasting for non-bipedal creatures --- apps/openmw/mwmechanics/character.cpp | 30 +++++++++++++++++++ apps/openmw/mwmp/DedicatedPlayer.cpp | 1 + apps/openmw/mwmp/LocalActor.cpp | 1 + apps/openmw/mwmp/MechanicsHelper.cpp | 8 ++++- components/openmw-mp/Base/BaseStructs.hpp | 1 + .../Packets/Actor/PacketActorAttack.cpp | 2 ++ 6 files changed, 42 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index f44883184..b77a57157 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1038,9 +1038,39 @@ bool CharacterController::updateCreatureState() const std::string spellid = stats.getSpells().getSelectedSpell(); if (!spellid.empty() && MWBase::Environment::get().getWorld()->startSpellCast(mPtr)) { + /* + Start of tes3mp addition + + If this mPtr belongs to a LocalPlayer or LocalActor, get their Attack and prepare + it for sending + */ + mwmp::Attack *localAttack = MechanicsHelper::getLocalAttack(mPtr); + + if (localAttack) + { + MechanicsHelper::resetAttack(localAttack); + localAttack->type = mwmp::Attack::MAGIC; + localAttack->pressed = true; + localAttack->shouldSend = true; + } + /* + End of tes3mp addition + */ + MWMechanics::CastSpell cast(mPtr, NULL); cast.playSpellCastingEffects(spellid); + /* + Start of tes3mp addition + + Mark the attack as instant if there is no spellcast animation + */ + if (!mAnimation->hasAnimation("spellcast")) + localAttack->instant = true; + /* + End of tes3mp addition + */ + if (!mAnimation->hasAnimation("spellcast")) MWBase::Environment::get().getWorld()->castSpell(mPtr); // No "release" text key to use, so cast immediately else diff --git a/apps/openmw/mwmp/DedicatedPlayer.cpp b/apps/openmw/mwmp/DedicatedPlayer.cpp index 66ca293ec..f5f8d3bfd 100644 --- a/apps/openmw/mwmp/DedicatedPlayer.cpp +++ b/apps/openmw/mwmp/DedicatedPlayer.cpp @@ -46,6 +46,7 @@ DedicatedPlayer::DedicatedPlayer(RakNet::RakNetGUID guid) : BasePlayer(guid) attack.pressed = 0; creatureStats.mDead = false; movementFlags = 0; + attack.instant = false; } DedicatedPlayer::~DedicatedPlayer() { diff --git a/apps/openmw/mwmp/LocalActor.cpp b/apps/openmw/mwmp/LocalActor.cpp index 6ada82ff0..e2bc97150 100644 --- a/apps/openmw/mwmp/LocalActor.cpp +++ b/apps/openmw/mwmp/LocalActor.cpp @@ -33,6 +33,7 @@ LocalActor::LocalActor() attack.type = Attack::MELEE; attack.shouldSend = false; + attack.instant = false; creatureStats.mDead = false; } diff --git a/apps/openmw/mwmp/MechanicsHelper.cpp b/apps/openmw/mwmp/MechanicsHelper.cpp index ace4dc93e..9092eec9c 100644 --- a/apps/openmw/mwmp/MechanicsHelper.cpp +++ b/apps/openmw/mwmp/MechanicsHelper.cpp @@ -201,8 +201,14 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker) attack.success); } } - else + else if (attack.type == attack.MAGIC) { + if (attack.instant) + { + MWBase::Environment::get().getWorld()->castSpell(attacker); + attack.instant = false; + } + LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "SpellId: %s", attack.spellId.c_str()); LOG_APPEND(Log::LOG_VERBOSE, " - success: %d", attack.success); } diff --git a/components/openmw-mp/Base/BaseStructs.hpp b/components/openmw-mp/Base/BaseStructs.hpp index 45af6a44e..951ba4222 100644 --- a/components/openmw-mp/Base/BaseStructs.hpp +++ b/components/openmw-mp/Base/BaseStructs.hpp @@ -50,6 +50,7 @@ namespace mwmp bool block; bool pressed; + bool instant; bool knockdown; bool shouldSend; diff --git a/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp b/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp index a0ec2676d..4ca89cdf9 100644 --- a/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp +++ b/components/openmw-mp/Packets/Actor/PacketActorAttack.cpp @@ -23,4 +23,6 @@ void PacketActorAttack::Actor(BaseActor &actor, bool send) RW(actor.attack.pressed, send); RW(actor.attack.knockdown, send); RW(actor.attack.block, send); + + RW(actor.attack.instant, send); }