mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
fix(Core/SAI): SMARTCAST_COMBAT_MOVE prevents movement on successful cast (#23913)
This commit is contained in:
@@ -858,7 +858,7 @@ void SmartAI::AttackStart(Unit* who)
|
||||
return;
|
||||
}
|
||||
|
||||
if (who && me->Attack(who, me->IsWithinMeleeRange(who)))
|
||||
if (who && me->Attack(who, me->IsWithinMeleeRange(who) || _currentRangeMode))
|
||||
{
|
||||
if (!me->HasUnitState(UNIT_STATE_NO_COMBAT_MOVEMENT))
|
||||
{
|
||||
@@ -870,7 +870,7 @@ void SmartAI::AttackStart(Unit* who)
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
}
|
||||
|
||||
me->GetMotionMaster()->MoveChase(who);
|
||||
me->GetMotionMaster()->MoveChase(who, _attackDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -941,6 +941,35 @@ void SmartAI::PassengerBoarded(Unit* who, int8 seatId, bool apply)
|
||||
void SmartAI::InitializeAI()
|
||||
{
|
||||
GetScript()->OnInitialize(me);
|
||||
|
||||
for (SmartScriptHolder const& event : GetScript()->GetEvents())
|
||||
{
|
||||
if (event.GetActionType() != SMART_ACTION_CAST)
|
||||
continue;
|
||||
|
||||
if (!(event.action.cast.castFlags & SMARTCAST_MAIN_SPELL))
|
||||
continue;
|
||||
|
||||
SetMainSpell(event.action.cast.spell);
|
||||
break;
|
||||
}
|
||||
|
||||
// Fallback: use first SMARTCAST_COMBAT_MOVE if no MAIN_SPELL found
|
||||
if (!_currentRangeMode)
|
||||
{
|
||||
for (SmartScriptHolder const& event : GetScript()->GetEvents())
|
||||
{
|
||||
if (event.GetActionType() != SMART_ACTION_CAST)
|
||||
continue;
|
||||
|
||||
if (!(event.action.cast.castFlags & SMARTCAST_COMBAT_MOVE))
|
||||
continue;
|
||||
|
||||
SetMainSpell(event.action.cast.spell);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!me->isDead())
|
||||
{
|
||||
mJustReset = true;
|
||||
@@ -1083,6 +1112,20 @@ void SmartAI::SetCurrentRangeMode(bool on, float range)
|
||||
me->GetMotionMaster()->MoveChase(victim, _attackDistance);
|
||||
}
|
||||
|
||||
void SmartAI::SetMainSpell(uint32 spellId)
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!spellInfo)
|
||||
return;
|
||||
|
||||
float maxRange = spellInfo->GetMaxRange(false);
|
||||
if (maxRange <= NOMINAL_MELEE_RANGE)
|
||||
return;
|
||||
|
||||
_attackDistance = std::max(maxRange - NOMINAL_MELEE_RANGE, 0.0f);
|
||||
_currentRangeMode = true;
|
||||
}
|
||||
|
||||
void SmartAI::DistanceYourself(float range)
|
||||
{
|
||||
Unit* victim = me->GetVictim();
|
||||
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
void SetAutoAttack(bool on) { mCanAutoAttack = on; }
|
||||
void SetCombatMovement(bool on, bool stopOrStartMovement);
|
||||
void SetCurrentRangeMode(bool on, float range = 0.f);
|
||||
void SetMainSpell(uint32 spellId);
|
||||
void DistanceYourself(float range);
|
||||
void SetFollow(Unit* target, float dist = 0.0f, float angle = 0.0f, uint32 credit = 0, uint32 end = 0, uint32 creditType = 0, bool aliveState = true);
|
||||
void StopFollow(bool complete);
|
||||
|
||||
@@ -707,7 +707,6 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
continue;
|
||||
}
|
||||
|
||||
// Let us not try to cast spell if we know it is going to fail anyway. Stick to chasing and continue.
|
||||
if (distanceToTarget > spellMaxRange && isWithinLOSInMap)
|
||||
{
|
||||
failedSpellCast = true;
|
||||
@@ -745,12 +744,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
|
||||
if (e.action.cast.castFlags & SMARTCAST_COMBAT_MOVE)
|
||||
{
|
||||
// If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed unless target is outside spell range, out of mana, or LOS.
|
||||
if (result == SPELL_FAILED_OUT_OF_RANGE || result == SPELL_CAST_OK)
|
||||
// if we are just out of range, we only chase until we are back in spell range.
|
||||
if (result == SPELL_FAILED_OUT_OF_RANGE)
|
||||
CAST_AI(SmartAI, me->AI())->SetCurrentRangeMode(true, std::max(spellMaxRange - NOMINAL_MELEE_RANGE, 0.0f));
|
||||
else // move into melee on any other fail
|
||||
// if spell fail for any other reason, we chase to melee range, or stay where we are if spellcast was successful.
|
||||
else if (result != SPELL_CAST_OK)
|
||||
CAST_AI(SmartAI, me->AI())->SetCurrentRangeMode(false, 0.f);
|
||||
}
|
||||
|
||||
|
||||
@@ -207,6 +207,8 @@ public:
|
||||
void AddCreatureSummon(ObjectGuid const& guid);
|
||||
void RemoveCreatureSummon(ObjectGuid const& guid);
|
||||
|
||||
SmartAIEventList const& GetEvents() const { return mEvents; }
|
||||
|
||||
private:
|
||||
void IncPhase(uint32 p);
|
||||
void DecPhase(uint32 p);
|
||||
|
||||
@@ -1932,16 +1932,17 @@ enum SmartEventFlags
|
||||
|
||||
enum SmartCastFlags
|
||||
{
|
||||
SMARTCAST_INTERRUPT_PREVIOUS = 0x001, // Interrupt any spell casting
|
||||
SMARTCAST_TRIGGERED = 0x002, // Triggered (this makes spell cost zero mana and have no cast time)
|
||||
//CAST_FORCE_CAST = 0x004, // Forces cast even if creature is out of mana or out of range
|
||||
//CAST_NO_MELEE_IF_OOM = 0x008, // Prevents creature from entering melee if out of mana or out of range
|
||||
//CAST_FORCE_TARGET_SELF = 0x010, // Forces the target to cast this spell on itself
|
||||
SMARTCAST_AURA_NOT_PRESENT = 0x020, // Only casts the spell if the target does not have an aura from the spell
|
||||
SMARTCAST_COMBAT_MOVE = 0x040, // Prevents combat movement if cast successful. Allows movement on range, OOM, LOS
|
||||
SMARTCAST_THREATLIST_NOT_SINGLE = 0x080, // Only cast if the source's threatlist is higher than one. This includes pets (see Skeram's True Fulfillment)
|
||||
SMARTCAST_TARGET_POWER_MANA = 0x100, // Only cast if the target has power type mana (e.g. Mana Drain)
|
||||
SMARTCAST_ENABLE_COMBAT_MOVE_ON_LOS = 0x200,
|
||||
SMARTCAST_INTERRUPT_PREVIOUS = 0x001, // Interrupt any spell casting
|
||||
SMARTCAST_TRIGGERED = 0x002, // Triggered (this makes spell cost zero mana and have no cast time)
|
||||
//CAST_FORCE_CAST = 0x004, // Forces cast even if creature is out of mana or out of range
|
||||
//CAST_NO_MELEE_IF_OOM = 0x008, // Prevents creature from entering melee if out of mana or out of range
|
||||
//CAST_FORCE_TARGET_SELF = 0x010, // Forces the target to cast this spell on itself
|
||||
SMARTCAST_AURA_NOT_PRESENT = 0x020, // Only casts the spell if the target does not have an aura from the spell
|
||||
SMARTCAST_COMBAT_MOVE = 0x040, // Prevents combat movement if cast successful. Allows movement on range, OOM, LOS
|
||||
SMARTCAST_THREATLIST_NOT_SINGLE = 0x080, // Only cast if the source's threatlist is higher than one. This includes pets (see Skeram's True Fulfillment)
|
||||
SMARTCAST_TARGET_POWER_MANA = 0x100, // Only cast if the target has power type mana (e.g. Mana Drain)
|
||||
SMARTCAST_ENABLE_COMBAT_MOVE_ON_LOS = 0x200, // Allows combat movement when not in line of sight
|
||||
SMARTCAST_MAIN_SPELL = 0x400, // Sets this spell's max range as the creature's chase distance on spawn
|
||||
};
|
||||
|
||||
enum SmartFollowType
|
||||
|
||||
Reference in New Issue
Block a user