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.PlayerDistance:
break;
case SmartTargets.ActionInvoker:
if (!NotNULL(e, e.Event.friendlyHealthPct.radius))
return false;
break;
default:
Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} uses invalid target_type {e.GetTargetType()}, skipped.");
return false;
@@ -2303,6 +2307,7 @@ namespace Game.AI
public uint maxHpPct;
public uint repeatMin;
public uint repeatMax;
public uint radius;
}
public struct Distance
{
+30 -20
View File
@@ -3614,7 +3614,7 @@ namespace Game.AI
if (_me == null || !_me.IsEngaged())
return;
List<WorldObject> targets;
Unit unitTarget = null;
switch (e.GetTargetType())
{
@@ -3625,30 +3625,29 @@ namespace Game.AI
case SmartTargets.ClosestPlayer:
case SmartTargets.PlayerRange:
case SmartTargets.PlayerDistance:
targets = GetTargets(e);
{
var targets = GetTargets(e);
foreach (WorldObject target in targets)
{
if (IsUnit(target) && _me.IsFriendlyTo(target.ToUnit()) && target.ToUnit().IsAlive() && target.ToUnit().IsInCombat())
{
uint healthPct = (uint)target.ToUnit().GetHealthPct();
if (healthPct > e.Event.friendlyHealthPct.maxHpPct || healthPct < e.Event.friendlyHealthPct.minHpPct)
continue;
unitTarget = target.ToUnit();
break;
}
}
}
break;
case SmartTargets.ActionInvoker:
unitTarget = DoSelectLowestHpPercentFriendly((float)e.Event.friendlyHealthPct.radius, e.Event.friendlyHealthPct.minHpPct, e.Event.friendlyHealthPct.maxHpPct);
break;
default:
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())
{
uint healthPct = (uint)target.ToUnit().GetHealthPct();
if (healthPct > e.Event.friendlyHealthPct.maxHpPct || healthPct < e.Event.friendlyHealthPct.minHpPct)
continue;
unitTarget = target.ToUnit();
break;
}
}
if (unitTarget == null)
return;
@@ -4180,6 +4179,17 @@ namespace Game.AI
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)
{
if (_me == null)
+28
View File
@@ -1859,6 +1859,34 @@ namespace Game.Maps
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 FriendlyBelowHpPctEntryInRange(Unit obj, uint entry, float range, byte pct, bool excludeSelf)