Core: Combat/threat system rewrite
Port From (https://github.com/TrinityCore/TrinityCore/commit/34c7810fe507eca1b8b9389630db5d5d26d92e77)
This commit is contained in:
@@ -62,41 +62,42 @@ namespace Game.AI
|
||||
if (!creature)
|
||||
creature = me;
|
||||
|
||||
if (!creature.CanHaveThreatList())
|
||||
return;
|
||||
|
||||
Map map = creature.GetMap();
|
||||
if (!map.IsDungeon()) //use IsDungeon instead of Instanceable, in case Battlegrounds will be instantiated
|
||||
if (creature.CanHaveThreatList())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (!creature.HasReactState(ReactStates.Passive) && creature.GetVictim() == null)
|
||||
{
|
||||
Unit nearTarget = creature.SelectNearestTarget(maxRangeToNearestTarget);
|
||||
if (nearTarget != null)
|
||||
creature.GetAI().AttackStart(nearTarget);
|
||||
else if (creature.IsSummon())
|
||||
if (!map.IsDungeon()) //use IsDungeon instead of Instanceable, in case Battlegrounds will be instantiated
|
||||
{
|
||||
Unit summoner = creature.ToTempSummon().GetSummoner();
|
||||
if (summoner != null)
|
||||
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;
|
||||
}
|
||||
|
||||
if (!creature.HasReactState(ReactStates.Passive) && creature.GetVictim() == null)
|
||||
{
|
||||
Unit nearTarget = creature.SelectNearestTarget(maxRangeToNearestTarget);
|
||||
if (nearTarget != null)
|
||||
creature.GetAI().AttackStart(nearTarget);
|
||||
else if (creature.IsSummon())
|
||||
{
|
||||
Unit target = summoner.GetAttackerForHelper();
|
||||
if (target == null && summoner.CanHaveThreatList() && !summoner.GetThreatManager().IsThreatListEmpty())
|
||||
target = summoner.GetThreatManager().GetHostilTarget();
|
||||
if (target != null && (creature.IsFriendlyTo(summoner) || creature.IsHostileTo(target)))
|
||||
creature.GetAI().AttackStart(target);
|
||||
Unit summoner = creature.ToTempSummon().GetSummoner();
|
||||
if (summoner != null)
|
||||
{
|
||||
if (creature.IsFriendlyTo(summoner))
|
||||
{
|
||||
Unit target = summoner.GetAttackerForHelper();
|
||||
if (target != null && creature.IsHostileTo(target))
|
||||
creature.GetAI().AttackStart(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intended duplicated check, the code above this should select a victim
|
||||
// If it can't find a suitable attack target then we should error out.
|
||||
if (!creature.HasReactState(ReactStates.Passive) && creature.GetVictim() == null)
|
||||
{
|
||||
Log.outError(LogFilter.Server, "DoZoneInCombat called for creature that has empty threat list (creature entry = {0})", creature.GetEntry());
|
||||
return;
|
||||
// Intended duplicated check, the code above this should select a victim
|
||||
// If it can't find a suitable attack target then we should error out.
|
||||
if (!creature.HasReactState(ReactStates.Passive) && creature.GetVictim() == null)
|
||||
{
|
||||
Log.outError(LogFilter.Server, "DoZoneInCombat called for creature that has empty threat list (creature entry = {0})", creature.GetEntry());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var playerList = map.GetPlayers();
|
||||
@@ -104,17 +105,8 @@ namespace Game.AI
|
||||
return;
|
||||
|
||||
foreach (var player in playerList)
|
||||
{
|
||||
if (player.IsGameMaster())
|
||||
continue;
|
||||
|
||||
if (player.IsAlive())
|
||||
{
|
||||
creature.SetInCombatWith(player);
|
||||
player.SetInCombatWith(creature);
|
||||
creature.GetThreatManager().AddThreat(player, 0.0f, null, true, true);
|
||||
}
|
||||
}
|
||||
if (player != null && player.IsAlive())
|
||||
creature.EngageWithTarget(player);
|
||||
}
|
||||
|
||||
public virtual void MoveInLineOfSight_Safe(Unit who)
|
||||
@@ -247,11 +239,13 @@ namespace Game.AI
|
||||
|
||||
return me.GetVictim() != null;
|
||||
}
|
||||
else if (me.GetThreatManager().IsThreatListEmpty())
|
||||
else if (me.GetThreatManager().IsThreatListEmpty(true))
|
||||
{
|
||||
EnterEvadeMode(EvadeReason.NoHostiles);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
me.AttackStop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -56,8 +56,6 @@ namespace Game.AI
|
||||
me.GetMotionMaster().Clear();
|
||||
me.GetMotionMaster().MoveIdle();
|
||||
me.CombatStop();
|
||||
me.GetHostileRefManager().DeleteReferences();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -454,9 +452,9 @@ namespace Game.AI
|
||||
}
|
||||
}
|
||||
|
||||
me.ClearInPetCombat();
|
||||
me.RemoveUnitFlag(UnitFlags.PetInCombat); // on player pets, this flag indicates that we're actively going after a target - we're returning, so remove it
|
||||
}
|
||||
|
||||
|
||||
void DoAttack(Unit target, bool chase)
|
||||
{
|
||||
// Handles attack with or without chase and also resets flags
|
||||
@@ -464,12 +462,7 @@ namespace Game.AI
|
||||
|
||||
if (me.Attack(target, true))
|
||||
{
|
||||
// properly fix fake combat after pet is sent to attack
|
||||
Unit owner = me.GetOwner();
|
||||
if (owner != null)
|
||||
owner.AddUnitFlag(UnitFlags.PetInCombat);
|
||||
|
||||
me.AddUnitFlag(UnitFlags.PetInCombat);
|
||||
me.AddUnitFlag(UnitFlags.PetInCombat); // on player pets, this flag indicates we're actively going after a target - that's what we're doing, so set it
|
||||
|
||||
// Play sound to let the player know the pet is attacking something it picked on its own
|
||||
if (me.HasReactState(ReactStates.Aggressive) && !me.GetCharmInfo().IsCommandAttack())
|
||||
|
||||
@@ -188,12 +188,12 @@ namespace Game.AI
|
||||
|
||||
if (targetType == SelectAggroTarget.MaxDistance || targetType == SelectAggroTarget.MinDistance)
|
||||
{
|
||||
foreach (HostileReference refe in mgr.GetThreatList())
|
||||
foreach (ThreatReference refe in mgr.GetSortedThreatList())
|
||||
{
|
||||
if (!refe.IsOnline())
|
||||
continue;
|
||||
|
||||
targetList.Add(refe.GetTarget());
|
||||
targetList.Add(refe.GetVictim());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -202,12 +202,12 @@ namespace Game.AI
|
||||
if (currentVictim != null)
|
||||
targetList.Add(currentVictim);
|
||||
|
||||
foreach (HostileReference refe in mgr.GetThreatList())
|
||||
foreach (ThreatReference refe in mgr.GetSortedThreatList())
|
||||
{
|
||||
if (!refe.IsOnline())
|
||||
continue;
|
||||
|
||||
Unit thisTarget = refe.GetTarget();
|
||||
Unit thisTarget = refe.GetVictim();
|
||||
if (thisTarget != currentVictim)
|
||||
targetList.Add(thisTarget);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user