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:
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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,30 +3625,29 @@ namespace Game.AI
|
|||||||
case SmartTargets.ClosestPlayer:
|
case SmartTargets.ClosestPlayer:
|
||||||
case SmartTargets.PlayerRange:
|
case SmartTargets.PlayerRange:
|
||||||
case SmartTargets.PlayerDistance:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
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)
|
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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user