Core/SAI: Implement SMART_TARGET_ACTION_INVOKER in SMART_EVENT_FRIENDLY_HEALTH_PCT

Port From (https://github.com/TrinityCore/TrinityCore/commit/902ed74c2adaf2dadcd38f1fb96963f7ec46df07)
This commit is contained in:
hondacrx
2022-03-11 17:54:05 -05:00
parent 7d1b910f24
commit 70ba25ad06
3 changed files with 63 additions and 20 deletions
@@ -818,6 +818,10 @@ namespace Game.AI
case SmartTargets.PlayerRange: case SmartTargets.PlayerRange:
case SmartTargets.PlayerDistance: case SmartTargets.PlayerDistance:
break; break;
case SmartTargets.ActionInvoker:
if (!NotNULL(e, e.Event.friendlyHealthPct.radius))
return false;
break;
default: default:
Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} uses invalid target_type {e.GetTargetType()}, skipped."); Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} uses invalid target_type {e.GetTargetType()}, skipped.");
return false; return false;
@@ -2303,6 +2307,7 @@ namespace Game.AI
public uint maxHpPct; public uint maxHpPct;
public uint repeatMin; public uint repeatMin;
public uint repeatMax; public uint repeatMax;
public uint radius;
} }
public struct Distance public struct Distance
{ {
+23 -13
View File
@@ -3614,7 +3614,7 @@ namespace Game.AI
if (_me == null || !_me.IsEngaged()) if (_me == null || !_me.IsEngaged())
return; return;
List<WorldObject> targets; Unit unitTarget = null;
switch (e.GetTargetType()) switch (e.GetTargetType())
{ {
@@ -3625,22 +3625,13 @@ namespace Game.AI
case SmartTargets.ClosestPlayer: case SmartTargets.ClosestPlayer:
case SmartTargets.PlayerRange: case SmartTargets.PlayerRange:
case SmartTargets.PlayerDistance: case SmartTargets.PlayerDistance:
targets = GetTargets(e); {
break; var targets = GetTargets(e);
default: foreach (WorldObject target in targets)
return;
}
if (targets == null)
return;
Unit unitTarget = null;
foreach (var target in targets)
{ {
if (IsUnit(target) && _me.IsFriendlyTo(target.ToUnit()) && target.ToUnit().IsAlive() && target.ToUnit().IsInCombat()) if (IsUnit(target) && _me.IsFriendlyTo(target.ToUnit()) && target.ToUnit().IsAlive() && target.ToUnit().IsInCombat())
{ {
uint healthPct = (uint)target.ToUnit().GetHealthPct(); uint healthPct = (uint)target.ToUnit().GetHealthPct();
if (healthPct > e.Event.friendlyHealthPct.maxHpPct || healthPct < e.Event.friendlyHealthPct.minHpPct) if (healthPct > e.Event.friendlyHealthPct.maxHpPct || healthPct < e.Event.friendlyHealthPct.minHpPct)
continue; continue;
@@ -3648,6 +3639,14 @@ namespace Game.AI
break; break;
} }
} }
}
break;
case SmartTargets.ActionInvoker:
unitTarget = DoSelectLowestHpPercentFriendly((float)e.Event.friendlyHealthPct.radius, e.Event.friendlyHealthPct.minHpPct, e.Event.friendlyHealthPct.maxHpPct);
break;
default:
return;
}
if (unitTarget == null) if (unitTarget == null)
return; return;
@@ -4180,6 +4179,17 @@ namespace Game.AI
return searcher.GetTarget(); return searcher.GetTarget();
} }
Unit DoSelectLowestHpPercentFriendly(float range, uint minHpPct, uint maxHpPct)
{
if (_me == null)
return null;
MostHPPercentMissingInRange u_check = new(_me, range, minHpPct, maxHpPct);
UnitLastSearcher searcher = new(_me, u_check);
Cell.VisitGridObjects(_me, searcher, range);
return searcher.GetTarget();
}
void DoFindFriendlyCC(List<Creature> creatures, float range) void DoFindFriendlyCC(List<Creature> creatures, float range)
{ {
if (_me == null) if (_me == null)
+28
View File
@@ -1859,6 +1859,34 @@ namespace Game.Maps
ulong i_hp; ulong i_hp;
} }
class MostHPPercentMissingInRange : ICheck<Unit>
{
Unit _obj;
float _range;
float _minHpPct;
float _maxHpPct;
float _hpPct;
public MostHPPercentMissingInRange(Unit obj, float range, uint minHpPct, uint maxHpPct)
{
_obj = obj;
_range = range;
_minHpPct = minHpPct;
_maxHpPct = maxHpPct;
_hpPct = 101.0f;
}
public bool Invoke(Unit u)
{
if (u.IsAlive() && u.IsInCombat() && !_obj.IsHostileTo(u) && _obj.IsWithinDistInMap(u, _range) && _minHpPct <= u.GetHealthPct() && u.GetHealthPct() <= _maxHpPct && u.GetHealthPct() < _hpPct)
{
_hpPct = u.GetHealthPct();
return true;
}
return false;
}
}
public class FriendlyBelowHpPctEntryInRange : ICheck<Unit> public class FriendlyBelowHpPctEntryInRange : ICheck<Unit>
{ {
public FriendlyBelowHpPctEntryInRange(Unit obj, uint entry, float range, byte pct, bool excludeSelf) public FriendlyBelowHpPctEntryInRange(Unit obj, uint entry, float range, byte pct, bool excludeSelf)