From 6b5c3ed04f7150ee1cf4496cde344ba990724d32 Mon Sep 17 00:00:00 2001 From: UltraNix <80540499+UltraNix@users.noreply.github.com> Date: Tue, 17 Aug 2021 20:36:30 +0200 Subject: [PATCH] fix(Core/Spells): Always melee attack target when charge is over. (#7316) * fix(Core/Spells): Always melee attack target when charge is over. Fixed #7266 * Update src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp --- src/server/game/Movement/MotionMaster.cpp | 6 ++--- src/server/game/Movement/MotionMaster.h | 2 +- .../PointMovementGenerator.cpp | 5 ++++ .../PointMovementGenerator.h | 7 +++-- src/server/game/Spells/SpellEffects.cpp | 26 +++++++++---------- 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 63b7f1ed9..5621f4ca4 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -580,7 +580,7 @@ void MotionMaster::MoveFall(uint32 id /*=0*/, bool addFlagForNPC) Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); } -void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id, const Movement::PointsArray* path, bool generatePath, float orientation /* = 0.0f*/) +void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id, const Movement::PointsArray* path, bool generatePath, float orientation /* = 0.0f*/, ObjectGuid targetGUID /*= ObjectGuid::Empty*/) { // Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE if (_owner->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE)) @@ -592,12 +592,12 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id, if (_owner->GetTypeId() == TYPEID_PLAYER) { LOG_DEBUG("movement.motionmaster", "Player (%s) charge point (X: %f Y: %f Z: %f)", _owner->GetGUID().ToString().c_str(), x, y, z); - Mutate(new PointMovementGenerator(id, x, y, z, speed, orientation, path, generatePath, generatePath), MOTION_SLOT_CONTROLLED); + Mutate(new PointMovementGenerator(id, x, y, z, speed, orientation, path, generatePath, generatePath, targetGUID), MOTION_SLOT_CONTROLLED); } else { LOG_DEBUG("movement.motionmaster", "Creature (%s) charge point (X: %f Y: %f Z: %f)", _owner->GetGUID().ToString().c_str(), x, y, z); - Mutate(new PointMovementGenerator(id, x, y, z, speed, orientation, path, generatePath, generatePath), MOTION_SLOT_CONTROLLED); + Mutate(new PointMovementGenerator(id, x, y, z, speed, orientation, path, generatePath, generatePath, targetGUID), MOTION_SLOT_CONTROLLED); } } diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index 7baabcb51..1fe105d6f 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -207,7 +207,7 @@ public: void MoveTakeoff(uint32 id, Position const& pos, float speed = 0.0f); void MoveTakeoff(uint32 id, float x, float y, float z, float speed = 0.0f); // pussywizard: added for easy calling by passing 3 floats x, y, z - void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, const Movement::PointsArray* path = nullptr, bool generatePath = false, float orientation = 0.0f); + void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, const Movement::PointsArray* path = nullptr, bool generatePath = false, float orientation = 0.0f, ObjectGuid targetGUID = ObjectGuid::Empty); void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ); void MoveJumpTo(float angle, float speedXY, float speedZ); void MoveJump(Position const& pos, float speedXY, float speedZ, uint32 id = 0) diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index 55c9f608a..e1c0cf4a0 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -139,6 +139,11 @@ void PointMovementGenerator::DoFinalize(T* unit) if (id == EVENT_CHARGE) { unit->ClearUnitState(UNIT_STATE_CHARGING); + + if (Unit* target = ObjectAccessor::GetUnit(*unit, _chargeTargetGUID)) + { + unit->Attack(target, true); + } } if (unit->movespline->Finalized()) diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index 19bea4e2d..d5ee6d4a8 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -14,8 +14,10 @@ template class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementGenerator > { public: - PointMovementGenerator(uint32 _id, float _x, float _y, float _z, float _speed = 0.0f, float orientation = 0.0f, const Movement::PointsArray* _path = nullptr, bool generatePath = false, bool forceDestination = false) : id(_id), - i_x(_x), i_y(_y), i_z(_z), speed(_speed), i_orientation(orientation), _generatePath(generatePath), _forceDestination(forceDestination) + PointMovementGenerator(uint32 _id, float _x, float _y, float _z, float _speed = 0.0f, float orientation = 0.0f, const Movement::PointsArray* _path = nullptr, + bool generatePath = false, bool forceDestination = false, ObjectGuid chargeTargetGUID = ObjectGuid::Empty) + : id(_id), i_x(_x), i_y(_y), i_z(_z), speed(_speed), i_orientation(orientation), _generatePath(generatePath), _forceDestination(forceDestination), + _chargeTargetGUID(chargeTargetGUID) { if (_path) m_precomputedPath = *_path; @@ -42,6 +44,7 @@ private: Movement::PointsArray m_precomputedPath; bool _generatePath; bool _forceDestination; + ObjectGuid _chargeTargetGUID; }; class AssistanceMovementGenerator : public PointMovementGenerator diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 781d6e05e..e8496a1df 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5042,9 +5042,16 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) if( m_caster->GetTypeId() == TYPEID_PLAYER ) m_caster->ToPlayer()->SetFallInformation(time(nullptr), m_caster->GetPositionZ()); + ObjectGuid targetGUID = ObjectGuid::Empty; + if (!m_spellInfo->IsPositive() && m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->GetTarget() == unitTarget->GetGUID()) + { + targetGUID = unitTarget->GetGUID(); + } + if (m_pathFinder) { - m_caster->GetMotionMaster()->MoveCharge(m_pathFinder->GetEndPosition().x, m_pathFinder->GetEndPosition().y, m_pathFinder->GetEndPosition().z, 42.0f, EVENT_CHARGE, &m_pathFinder->GetPath()); + m_caster->GetMotionMaster()->MoveCharge(m_pathFinder->GetEndPosition().x, m_pathFinder->GetEndPosition().y, m_pathFinder->GetEndPosition().z, + 42.0f, EVENT_CHARGE, &m_pathFinder->GetPath(), false, 0.f, targetGUID); if (m_caster->GetTypeId() == TYPEID_PLAYER) { @@ -5063,7 +5070,8 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) m_caster->GetFirstCollisionPosition(pos, dist, angle); } - m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ + Z_OFFSET_FIND_HEIGHT); + m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ + Z_OFFSET_FIND_HEIGHT, SPEED_CHARGE, EVENT_CHARGE, + nullptr, false, 0.f, targetGUID); if (m_caster->GetTypeId() == TYPEID_PLAYER) { @@ -5072,19 +5080,9 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) } } - if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET) + if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET && m_caster->ToPlayer()) { - if (!unitTarget) - return; - - if (m_caster->ToPlayer()) - { - sScriptMgr->AnticheatSetSkipOnePacketForASH(m_caster->ToPlayer(), true); - } - - // not all charge effects used in negative spells - if (!m_spellInfo->IsPositive() && m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->GetTarget() == unitTarget->GetGUID()) - m_caster->Attack(unitTarget, true); + sScriptMgr->AnticheatSetSkipOnePacketForASH(m_caster->ToPlayer(), true); } }