Core/Creatures: Implemented CREATURE_STATIC_FLAG_4_NO_MELEE_APPROACH and fixed CREATURE_STATIC_FLAG_NO_MELEE_FLEE implementation (should cause fleeing from melee range)
Port From (https://github.com/TrinityCore/TrinityCore/commit/a748fddfa47216e1f516303e3bca9b5a86823748)
This commit is contained in:
@@ -290,7 +290,7 @@ namespace Framework.Constants
|
||||
CombatPing = 0x00020000,
|
||||
Aquatic = 0x00040000, // Aka Water Only, CreatureTemplateMovement.Ground = 0
|
||||
Amphibious = 0x00080000, // CreatureTemplateMovement.Swim = 1
|
||||
NoMelee = 0x00100000, // Prevents Melee(Does Not Prevent Chasing, Does Not Make Creature Passive). Not Sure What 'Flee' Means But Another Flag Is Named NoMeleeApproach
|
||||
NoMeleeFlee = 0x00100000, // "No Melee (Flee)" Prevents melee (moves as-if feared, does not make creature passive)
|
||||
VisibleToGhosts = 0x00200000, // CreatureTypeFlagVisibleToGhosts
|
||||
PvpEnabling = 0x00400000, // Old UnitFlagPvpEnabling, Now UnitBytes2OffsetPvpFlag From UnitFieldBytes2
|
||||
DoNotPlayWoundAnim = 0x00800000, // CreatureTypeFlagDoNotPlayWoundAnim
|
||||
@@ -390,7 +390,7 @@ namespace Framework.Constants
|
||||
DealsTripleDamageToPcControlledPets = 0x00000040,
|
||||
NoNpcDamageBelow85ptc = 0x00000080,
|
||||
ObeysTauntDiminishingReturns = 0x00000100, // CreatureFlagExtraObeysTauntDiminishingReturns
|
||||
NoMeleeApproach = 0x00000200,
|
||||
NoMeleeApproach = 0x00000200, // "No Melee (Approach)" Prevents melee (chases into melee range, does not make creature passive)
|
||||
UpdateCreatureRecordWhenInstanceChangesDifficulty = 0x00000400, // Used Only By Snobold Vassal
|
||||
CannotDaze = 0x00000800, // "Cannot Daze (Combat Stun)"
|
||||
FlatHonorAward = 0x00001000,
|
||||
|
||||
@@ -27,9 +27,9 @@ namespace Game.AI
|
||||
protected TaskScheduler _scheduler = new();
|
||||
protected InstanceScript _instanceScript;
|
||||
|
||||
public CreatureAI(Creature _creature) : base(_creature)
|
||||
public CreatureAI(Creature creature) : base(creature)
|
||||
{
|
||||
me = _creature;
|
||||
me = creature;
|
||||
_moveInLOSLocked = false;
|
||||
}
|
||||
|
||||
@@ -514,6 +514,21 @@ namespace Game.AI
|
||||
// called when the corpse of this creature gets removed
|
||||
public virtual void CorpseRemoved(long respawnDelay) { }
|
||||
|
||||
public override void AttackStart(Unit victim)
|
||||
{
|
||||
if (victim != null && me.Attack(victim, true))
|
||||
{
|
||||
// Clear distracted state on attacking
|
||||
if (me.HasUnitState(UnitState.Distracted))
|
||||
{
|
||||
me.ClearUnitState(UnitState.Distracted);
|
||||
me.GetMotionMaster().Clear();
|
||||
}
|
||||
|
||||
me.StartDefaultCombatMovement(victim);
|
||||
}
|
||||
}
|
||||
|
||||
/// == Gossip system ================================
|
||||
|
||||
// Called when the dialog status between a player and the creature is requested.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using Framework.Constants;
|
||||
using Game.Entities;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
|
||||
namespace Game.AI
|
||||
{
|
||||
@@ -92,28 +93,34 @@ namespace Game.AI
|
||||
|
||||
public class CritterAI : PassiveAI
|
||||
{
|
||||
public CritterAI(Creature c) : base(c)
|
||||
TimeTracker _evadeTimer;
|
||||
|
||||
public CritterAI(Creature creature) : base(creature)
|
||||
{
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
_evadeTimer = new();
|
||||
me.SetCanMelee(false, true);
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit who)
|
||||
{
|
||||
if (!me.HasUnitState(UnitState.Fleeing))
|
||||
me.SetControlled(true, UnitState.Fleeing);
|
||||
me.StartDefaultCombatMovement(who);
|
||||
_evadeTimer.Reset(TimeSpan.FromMilliseconds(WorldConfig.GetIntValue(WorldCfg.CreatureFamilyFleeDelay)));
|
||||
}
|
||||
|
||||
public override void MovementInform(MovementGeneratorType type, uint id)
|
||||
public override void UpdateAI(uint diff)
|
||||
{
|
||||
if (type == MovementGeneratorType.TimedFleeing)
|
||||
EnterEvadeMode(EvadeReason.Other);
|
||||
}
|
||||
if (me.IsEngaged())
|
||||
{
|
||||
if (!me.IsInCombat())
|
||||
{
|
||||
EnterEvadeMode(EvadeReason.NoHostiles);
|
||||
return;
|
||||
}
|
||||
|
||||
public override void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
if (me.HasUnitState(UnitState.Fleeing))
|
||||
me.SetControlled(false, UnitState.Fleeing);
|
||||
base.EnterEvadeMode(why);
|
||||
_evadeTimer.Update(diff);
|
||||
if (_evadeTimer.Passed())
|
||||
EnterEvadeMode(EvadeReason.Other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Game.AI
|
||||
public void DoStartMovement(Unit target, float distance = 0.0f, float angle = 0.0f)
|
||||
{
|
||||
if (target != null)
|
||||
me.GetMotionMaster().MoveChase(target, distance, angle);
|
||||
me.StartDefaultCombatMovement(target, distance, angle);
|
||||
}
|
||||
|
||||
//Start no movement on victim
|
||||
|
||||
@@ -618,7 +618,7 @@ namespace Game.AI
|
||||
if (_canCombatMove)
|
||||
{
|
||||
SetRun(_run);
|
||||
me.GetMotionMaster().MoveChase(who);
|
||||
me.StartDefaultCombatMovement(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -830,7 +830,7 @@ namespace Game.AI
|
||||
}))
|
||||
{
|
||||
SetRun(_run);
|
||||
me.GetMotionMaster().MoveChase(me.GetVictim());
|
||||
me.StartDefaultCombatMovement(me.GetVictim());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1515,7 +1515,7 @@ namespace Game.AI
|
||||
if (creature != null)
|
||||
if (IsSmart(creature) && creature.GetVictim() != null)
|
||||
if (((SmartAI)creature.GetAI()).CanCombatMove())
|
||||
creature.GetMotionMaster().MoveChase(creature.GetVictim(), attackDistance, attackAngle);
|
||||
creature.StartDefaultCombatMovement(creature.GetVictim(), attackDistance, attackAngle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2602,6 +2602,47 @@ namespace Game.Entities
|
||||
Global.WorldMgr.SendGlobalMessage(packet, null, (enemy_team == Team.Alliance ? Team.Horde : Team.Alliance));
|
||||
}
|
||||
|
||||
public void SetCanMelee(bool canMelee, bool fleeFromMelee = false)
|
||||
{
|
||||
bool wasFleeingFromMelee = HasFlag(CreatureStaticFlags.NoMeleeFlee);
|
||||
|
||||
_staticFlags.ApplyFlag(CreatureStaticFlags.NoMeleeFlee, !canMelee && fleeFromMelee);
|
||||
_staticFlags.ApplyFlag(CreatureStaticFlags4.NoMeleeApproach, !canMelee && !fleeFromMelee);
|
||||
|
||||
if (wasFleeingFromMelee == HasFlag(CreatureStaticFlags.NoMeleeFlee))
|
||||
return;
|
||||
|
||||
Unit victim = GetVictim();
|
||||
if (victim == null)
|
||||
return;
|
||||
|
||||
var currentMovement = GetMotionMaster().GetCurrentMovementGenerator();
|
||||
if (currentMovement == null)
|
||||
return;
|
||||
|
||||
var canChangeMovement = new Func<bool>(() =>
|
||||
{
|
||||
if (wasFleeingFromMelee)
|
||||
return currentMovement.GetMovementGeneratorType() == MovementGeneratorType.Fleeing && !HasUnitFlag(UnitFlags.Fleeing);
|
||||
|
||||
return currentMovement.GetMovementGeneratorType() == MovementGeneratorType.Chase;
|
||||
})();
|
||||
|
||||
if (!canChangeMovement)
|
||||
return;
|
||||
|
||||
GetMotionMaster().Remove(currentMovement);
|
||||
StartDefaultCombatMovement(victim);
|
||||
}
|
||||
|
||||
public void StartDefaultCombatMovement(Unit victim, float? range = null, float? angle = null)
|
||||
{
|
||||
if (!HasFlag(CreatureStaticFlags.NoMeleeFlee) || IsSummon())
|
||||
GetMotionMaster().MoveChase(victim, range.GetValueOrDefault(0), angle.GetValueOrDefault(0));
|
||||
else
|
||||
GetMotionMaster().MoveFleeing(victim);
|
||||
}
|
||||
|
||||
public override bool HasSpell(uint spellId)
|
||||
{
|
||||
return m_spells.Contains(spellId);
|
||||
@@ -3376,9 +3417,7 @@ namespace Game.Entities
|
||||
public override SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = WeaponAttackType.BaseAttack) { return m_meleeDamageSchoolMask; }
|
||||
public void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = (SpellSchoolMask)(1 << (int)school); }
|
||||
|
||||
public bool CanMelee() { return !_staticFlags.HasFlag(CreatureStaticFlags.NoMelee); }
|
||||
|
||||
public void SetCanMelee(bool canMelee) { _staticFlags.ApplyFlag(CreatureStaticFlags.NoMelee, !canMelee); }
|
||||
public bool CanMelee() { return !_staticFlags.HasFlag(CreatureStaticFlags.NoMeleeFlee) && !_staticFlags.HasFlag(CreatureStaticFlags4.NoMeleeApproach); }
|
||||
|
||||
public bool CanIgnoreLineOfSightWhenCastingOnMe() { return _staticFlags.HasFlag(CreatureStaticFlags4.IgnoreLosWhenCastingOnMe); }
|
||||
|
||||
|
||||
@@ -1391,14 +1391,17 @@ namespace Game.Entities
|
||||
if (caster == null)
|
||||
caster = GetAttackerForHelper();
|
||||
GetMotionMaster().MoveFleeing(caster, TimeSpan.FromMilliseconds(fearAuras.Empty() ? WorldConfig.GetIntValue(WorldCfg.CreatureFamilyFleeDelay) : 0)); // caster == NULL processed in MoveFleeing
|
||||
SetUnitFlag(UnitFlags.Fleeing);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveUnitFlag(UnitFlags.Fleeing);
|
||||
if (IsAlive())
|
||||
{
|
||||
GetMotionMaster().Remove(MovementGeneratorType.Fleeing);
|
||||
if (GetVictim() != null)
|
||||
SetTarget(GetVictim().GetGUID());
|
||||
Unit victim = GetVictim();
|
||||
if (victim != null)
|
||||
SetTarget(victim.GetGUID());
|
||||
if (!IsPlayer() && !IsInCombat())
|
||||
GetMotionMaster().MoveTargetedHome();
|
||||
}
|
||||
|
||||
@@ -32,8 +32,6 @@ namespace Game.Movement
|
||||
if (owner == null || !owner.IsAlive())
|
||||
return;
|
||||
|
||||
// TODO: UNIT_FIELD_FLAGS should not be handled by generators
|
||||
owner.SetUnitFlag(UnitFlags.Fleeing);
|
||||
_path = null;
|
||||
SetTargetLocation(owner);
|
||||
}
|
||||
@@ -83,16 +81,15 @@ namespace Game.Movement
|
||||
{
|
||||
if (owner.IsPlayer())
|
||||
{
|
||||
owner.RemoveUnitFlag(UnitFlags.Fleeing);
|
||||
owner.ClearUnitState(UnitState.FleeingMove);
|
||||
owner.StopMoving();
|
||||
}
|
||||
else
|
||||
{
|
||||
owner.RemoveUnitFlag(UnitFlags.Fleeing);
|
||||
owner.ClearUnitState(UnitState.FleeingMove);
|
||||
if (owner.GetVictim() != null)
|
||||
owner.SetTarget(owner.GetVictim().GetGUID());
|
||||
Unit victim = owner.GetVictim();
|
||||
if (victim != null)
|
||||
owner.SetTarget(victim.GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,7 +217,6 @@ namespace Game.Movement
|
||||
if (!active)
|
||||
return;
|
||||
|
||||
owner.RemoveUnitFlag(UnitFlags.Fleeing);
|
||||
Unit victim = owner.GetVictim();
|
||||
if (victim != null)
|
||||
{
|
||||
|
||||
@@ -563,7 +563,6 @@ namespace Game.Movement
|
||||
}
|
||||
|
||||
public void MoveChase(Unit target, float dist, float angle = 0.0f) { MoveChase(target, new ChaseRange(dist), new ChaseAngle(angle)); }
|
||||
public void MoveChase(Unit target, float dist) { MoveChase(target, new ChaseRange(dist)); }
|
||||
public void MoveChase(Unit target, ChaseRange? dist = null, ChaseAngle? angle = null)
|
||||
{
|
||||
// Ignore movement request if target not exist
|
||||
|
||||
Reference in New Issue
Block a user