Misc updates/fixes
This commit is contained in:
@@ -109,33 +109,32 @@ namespace Game.AI
|
||||
|
||||
public class CasterAI : CombatAI
|
||||
{
|
||||
float _attackDist;
|
||||
float _attackDistance;
|
||||
|
||||
public CasterAI(Creature c)
|
||||
: base(c)
|
||||
public CasterAI(Creature creature) : base(creature)
|
||||
{
|
||||
_attackDist = SharedConst.MeleeRange;
|
||||
_attackDistance = SharedConst.MeleeRange;
|
||||
}
|
||||
|
||||
public override void InitializeAI()
|
||||
{
|
||||
base.InitializeAI();
|
||||
|
||||
_attackDist = 30.0f;
|
||||
_attackDistance = 30.0f;
|
||||
foreach (var id in Spells)
|
||||
{
|
||||
AISpellInfoType info = GetAISpellInfo(id, me.GetMap().GetDifficultyID());
|
||||
if (info != null && info.condition == AICondition.Combat && _attackDist > info.maxRange)
|
||||
_attackDist = info.maxRange;
|
||||
if (info != null && info.condition == AICondition.Combat && _attackDistance > info.maxRange)
|
||||
_attackDistance = info.maxRange;
|
||||
}
|
||||
|
||||
if (_attackDist == 30.0f)
|
||||
_attackDist = SharedConst.MeleeRange;
|
||||
if (_attackDistance == 30.0f)
|
||||
_attackDistance = SharedConst.MeleeRange;
|
||||
}
|
||||
|
||||
public override void AttackStart(Unit victim)
|
||||
{
|
||||
AttackStartCaster(victim, _attackDist);
|
||||
AttackStartCaster(victim, _attackDistance);
|
||||
}
|
||||
|
||||
public override void JustEngagedWith(Unit victim)
|
||||
@@ -198,18 +197,19 @@ namespace Game.AI
|
||||
{
|
||||
float _minRange;
|
||||
|
||||
public ArcherAI(Creature c) : base(c)
|
||||
public ArcherAI(Creature creature) : base(creature)
|
||||
{
|
||||
if (me.m_spells[0] == 0)
|
||||
Log.outError(LogFilter.ScriptsAi, "ArcherAI set for creature (entry = {0}) with spell1=0. AI will do nothing", me.GetEntry());
|
||||
if (creature.m_spells[0] == 0)
|
||||
Log.outError(LogFilter.ScriptsAi, $"ArcherAI set for creature with spell1=0. AI will do nothing ({me.GetGUID()})");
|
||||
|
||||
var spellInfo = Global.SpellMgr.GetSpellInfo(me.m_spells[0], me.GetMap().GetDifficultyID());
|
||||
var spellInfo = Global.SpellMgr.GetSpellInfo(creature.m_spells[0], creature.GetMap().GetDifficultyID());
|
||||
_minRange = spellInfo != null ? spellInfo.GetMinRange(false) : 0;
|
||||
|
||||
if (_minRange == 0)
|
||||
_minRange = SharedConst.MeleeRange;
|
||||
me.m_CombatDistance = spellInfo != null ? spellInfo.GetMaxRange(false) : 0;
|
||||
me.m_SightDistance = me.m_CombatDistance;
|
||||
|
||||
creature.m_CombatDistance = spellInfo != null ? spellInfo.GetMaxRange(false) : 0;
|
||||
creature.m_SightDistance = creature.m_CombatDistance;
|
||||
}
|
||||
|
||||
public override void AttackStart(Unit who)
|
||||
@@ -248,23 +248,21 @@ namespace Game.AI
|
||||
{
|
||||
float _minRange;
|
||||
|
||||
public TurretAI(Creature c)
|
||||
: base(c)
|
||||
public TurretAI(Creature creature) : base(creature)
|
||||
{
|
||||
if (me.m_spells[0] == 0)
|
||||
Log.outError(LogFilter.Server, "TurretAI set for creature (entry = {0}) with spell1=0. AI will do nothing", me.GetEntry());
|
||||
if (creature.m_spells[0] == 0)
|
||||
Log.outError(LogFilter.Server, $"TurretAI set for creature with spell1=0. AI will do nothing ({creature.GetGUID()})");
|
||||
|
||||
var spellInfo = Global.SpellMgr.GetSpellInfo(me.m_spells[0], me.GetMap().GetDifficultyID());
|
||||
var spellInfo = Global.SpellMgr.GetSpellInfo(creature.m_spells[0], creature.GetMap().GetDifficultyID());
|
||||
_minRange = spellInfo != null ? spellInfo.GetMinRange(false) : 0;
|
||||
me.m_CombatDistance = spellInfo != null ? spellInfo.GetMaxRange(false) : 0;
|
||||
me.m_SightDistance = me.m_CombatDistance;
|
||||
creature.m_CombatDistance = spellInfo != null ? spellInfo.GetMaxRange(false) : 0;
|
||||
creature.m_SightDistance = creature.m_CombatDistance;
|
||||
}
|
||||
|
||||
public override bool CanAIAttack(Unit victim)
|
||||
{
|
||||
// todo use one function to replace it
|
||||
if (!me.IsWithinCombatRange(victim, me.m_CombatDistance)
|
||||
|| (_minRange != 0 && me.IsWithinCombatRange(victim, _minRange)))
|
||||
if (!me.IsWithinCombatRange(victim, me.m_CombatDistance) || (_minRange != 0 && me.IsWithinCombatRange(victim, _minRange)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,11 @@ namespace Game.AI
|
||||
_moveInLOSLocked = false;
|
||||
}
|
||||
|
||||
public void Talk(uint id, WorldObject whisperTarget = null)
|
||||
{
|
||||
Global.CreatureTextMgr.SendChat(me, (byte)id, whisperTarget);
|
||||
}
|
||||
|
||||
public override void OnCharmed(bool isNew)
|
||||
{
|
||||
if (isNew && !me.IsCharmed() && !me.LastCharmerGUID.IsEmpty())
|
||||
@@ -56,27 +61,20 @@ namespace Game.AI
|
||||
if (lastCharmer != null)
|
||||
me.EngageWithTarget(lastCharmer);
|
||||
}
|
||||
me.LastCharmerGUID.Clear();
|
||||
|
||||
if (!me.IsInCombat())
|
||||
EnterEvadeMode(EvadeReason.NoHostiles);
|
||||
me.LastCharmerGUID.Clear();
|
||||
}
|
||||
|
||||
base.OnCharmed(isNew);
|
||||
}
|
||||
|
||||
public void Talk(uint id, WorldObject whisperTarget = null)
|
||||
{
|
||||
Global.CreatureTextMgr.SendChat(me, (byte)id, whisperTarget);
|
||||
}
|
||||
|
||||
public void DoZoneInCombat(Creature creature = null)
|
||||
{
|
||||
if (!creature)
|
||||
creature = me;
|
||||
|
||||
Map map = creature.GetMap();
|
||||
if (!map.IsDungeon()) //use IsDungeon instead of Instanceable, in case Battlegrounds will be instantiated
|
||||
if (!map.IsDungeon()) // use IsDungeon instead of Instanceable, in case Battlegrounds will be instantiated
|
||||
{
|
||||
Log.outError(LogFilter.Server, "DoZoneInCombat call for map that isn't an instance (creature entry = {0})", creature.IsTypeId(TypeId.Unit) ? creature.ToCreature().GetEntry() : 0);
|
||||
return;
|
||||
@@ -219,7 +217,7 @@ namespace Game.AI
|
||||
if (!_EnterEvadeMode(why))
|
||||
return;
|
||||
|
||||
Log.outDebug(LogFilter.Unit, "Creature {0} enters evade mode.", me.GetEntry());
|
||||
Log.outDebug(LogFilter.Unit, $"CreatureAI::EnterEvadeMode: entering evade mode (why: {why}) ({me.GetGUID()})");
|
||||
|
||||
if (me.GetVehicle() == null) // otherwise me will be in evade mode forever
|
||||
{
|
||||
@@ -374,12 +372,10 @@ namespace Game.AI
|
||||
}
|
||||
alreadyChecked.Add(next);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (outOfBounds.Contains(next))
|
||||
hasOutOfBoundsNeighbor = true;
|
||||
}
|
||||
else if (outOfBounds.Contains(next))
|
||||
hasOutOfBoundsNeighbor = true;
|
||||
}
|
||||
|
||||
if (fill || hasOutOfBoundsNeighbor)
|
||||
{
|
||||
var pos = new Position(startPosition.GetPositionX() + front.Key * SharedConst.BoundaryVisualizeStepSize, startPosition.GetPositionY() + front.Value * SharedConst.BoundaryVisualizeStepSize, spawnZ);
|
||||
|
||||
@@ -29,9 +29,9 @@ namespace Game.AI
|
||||
|
||||
public GameObject me;
|
||||
|
||||
public GameObjectAI(GameObject gameObject)
|
||||
public GameObjectAI(GameObject go)
|
||||
{
|
||||
me = gameObject;
|
||||
me = go;
|
||||
_scheduler = new TaskScheduler();
|
||||
_events = new EventMap();
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Game.AI
|
||||
return;
|
||||
}
|
||||
|
||||
Log.outDebug(LogFilter.Unit, "Guard entry: {0} enters evade mode.", me.GetEntry());
|
||||
Log.outTrace(LogFilter.ScriptsAi, $"GuardAI::EnterEvadeMode: {me.GetGUID()} enters evade mode.");
|
||||
|
||||
me.RemoveAllAuras();
|
||||
me.CombatStop(true);
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace Game.AI
|
||||
{
|
||||
public class PassiveAI : CreatureAI
|
||||
{
|
||||
public PassiveAI(Creature c) : base(c)
|
||||
public PassiveAI(Creature creature) : base(creature)
|
||||
{
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
creature.SetReactState(ReactStates.Passive);
|
||||
}
|
||||
|
||||
public override void UpdateAI(uint diff)
|
||||
@@ -41,9 +41,9 @@ namespace Game.AI
|
||||
|
||||
public class PossessedAI : CreatureAI
|
||||
{
|
||||
public PossessedAI(Creature c) : base(c)
|
||||
public PossessedAI(Creature creature) : base(creature)
|
||||
{
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
creature.SetReactState(ReactStates.Passive);
|
||||
}
|
||||
|
||||
public override void AttackStart(Unit target)
|
||||
@@ -99,7 +99,7 @@ namespace Game.AI
|
||||
{
|
||||
public NullCreatureAI(Creature creature) : base(creature)
|
||||
{
|
||||
me.SetReactState(ReactStates.Passive);
|
||||
creature.SetReactState(ReactStates.Passive);
|
||||
}
|
||||
|
||||
public override void MoveInLineOfSight(Unit unit) { }
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Game.AI
|
||||
List<ObjectGuid> _allySet = new();
|
||||
uint _updateAlliesTimer;
|
||||
|
||||
public PetAI(Creature c) : base(c)
|
||||
public PetAI(Creature creature) : base(creature)
|
||||
{
|
||||
UpdateAllies();
|
||||
}
|
||||
@@ -60,7 +60,7 @@ namespace Game.AI
|
||||
|
||||
if (NeedToStop())
|
||||
{
|
||||
Log.outDebug(LogFilter.Server, "Pet AI stopped attacking [{0}]", me.GetGUID().ToString());
|
||||
Log.outTrace(LogFilter.ScriptsAi, $"PetAI::UpdateAI: AI stopped attacking {me.GetGUID()}");
|
||||
StopAttack();
|
||||
return;
|
||||
}
|
||||
@@ -528,26 +528,28 @@ namespace Game.AI
|
||||
|
||||
public override void ReceiveEmote(Player player, TextEmotes emoteId)
|
||||
{
|
||||
if (!me.GetOwnerGUID().IsEmpty() && me.GetOwnerGUID() == player.GetGUID())
|
||||
switch (emoteId)
|
||||
{
|
||||
case TextEmotes.Cower:
|
||||
if (me.IsPet() && me.ToPet().IsPetGhoul())
|
||||
me.HandleEmoteCommand(Emote.OneshotOmnicastGhoul);
|
||||
break;
|
||||
case TextEmotes.Angry:
|
||||
if (me.IsPet() && me.ToPet().IsPetGhoul())
|
||||
me.HandleEmoteCommand(Emote.StateStun);
|
||||
break;
|
||||
case TextEmotes.Glare:
|
||||
if (me.IsPet() && me.ToPet().IsPetGhoul())
|
||||
me.HandleEmoteCommand(Emote.StateStun);
|
||||
break;
|
||||
case TextEmotes.Soothe:
|
||||
if (me.IsPet() && me.ToPet().IsPetGhoul())
|
||||
me.HandleEmoteCommand(Emote.OneshotOmnicastGhoul);
|
||||
break;
|
||||
}
|
||||
if (me.GetOwnerGUID() != player.GetGUID())
|
||||
return;
|
||||
|
||||
switch (emoteId)
|
||||
{
|
||||
case TextEmotes.Cower:
|
||||
if (me.IsPet() && me.ToPet().IsPetGhoul())
|
||||
me.HandleEmoteCommand(Emote.OneshotOmnicastGhoul);
|
||||
break;
|
||||
case TextEmotes.Angry:
|
||||
if (me.IsPet() && me.ToPet().IsPetGhoul())
|
||||
me.HandleEmoteCommand(Emote.StateStun);
|
||||
break;
|
||||
case TextEmotes.Glare:
|
||||
if (me.IsPet() && me.ToPet().IsPetGhoul())
|
||||
me.HandleEmoteCommand(Emote.StateStun);
|
||||
break;
|
||||
case TextEmotes.Soothe:
|
||||
if (me.IsPet() && me.ToPet().IsPetGhoul())
|
||||
me.HandleEmoteCommand(Emote.OneshotOmnicastGhoul);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool NeedToStop()
|
||||
@@ -595,17 +597,17 @@ namespace Game.AI
|
||||
if (player)
|
||||
group = player.GetGroup();
|
||||
|
||||
//only pet and owner/not in group.ok
|
||||
// only pet and owner/not in group.ok
|
||||
if (_allySet.Count == 2 && !group)
|
||||
return;
|
||||
|
||||
//owner is in group; group members filled in already (no raid . subgroupcount = whole count)
|
||||
// owner is in group; group members filled in already (no raid . subgroupcount = whole count)
|
||||
if (group && !group.IsRaidGroup() && _allySet.Count == (group.GetMembersCount() + 2))
|
||||
return;
|
||||
|
||||
_allySet.Clear();
|
||||
_allySet.Add(me.GetGUID());
|
||||
if (group) //add group
|
||||
if (group) // add group
|
||||
{
|
||||
for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next())
|
||||
{
|
||||
@@ -619,7 +621,7 @@ namespace Game.AI
|
||||
_allySet.Add(target.GetGUID());
|
||||
}
|
||||
}
|
||||
else //remove group
|
||||
else // remove group
|
||||
_allySet.Add(owner.GetGUID());
|
||||
}
|
||||
|
||||
@@ -631,12 +633,12 @@ namespace Game.AI
|
||||
base.OnCharmed(isNew);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quick access to set all flags to FALSE
|
||||
/// </summary>
|
||||
void ClearCharmInfoFlags()
|
||||
{
|
||||
// Quick access to set all flags to FALSE
|
||||
|
||||
CharmInfo ci = me.GetCharmInfo();
|
||||
|
||||
if (ci != null)
|
||||
{
|
||||
ci.SetIsAtStay(false);
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace Game.AI
|
||||
|
||||
public TotemAI(Creature creature) : base(creature)
|
||||
{
|
||||
Cypher.Assert(creature.IsTotem(), $"TotemAI: AI assigned to a no-totem creature ({creature.GetGUID()})!");
|
||||
_victimGuid = ObjectGuid.Empty;
|
||||
}
|
||||
|
||||
@@ -51,8 +52,7 @@ namespace Game.AI
|
||||
Unit victim = !_victimGuid.IsEmpty() ? Global.ObjAccessor.GetUnit(me, _victimGuid) : null;
|
||||
|
||||
// Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
|
||||
if (victim == null || !victim.IsTargetableForAttack() || !me.IsWithinDistInMap(victim, max_range) ||
|
||||
me.IsFriendlyTo(victim) || !me.CanSeeOrDetect(victim))
|
||||
if (victim == null || !victim.IsTargetableForAttack() || !me.IsWithinDistInMap(victim, max_range) || me.IsFriendlyTo(victim) || !me.CanSeeOrDetect(victim))
|
||||
{
|
||||
var u_check = new NearestAttackableUnitInObjectRangeCheck(me, me.GetCharmerOrOwnerOrSelf(), max_range);
|
||||
var checker = new UnitLastSearcher(me, u_check);
|
||||
|
||||
Reference in New Issue
Block a user