Core/Objects: Implement FindNearestCreatureWithOptions helper function

Port From (https://github.com/TrinityCore/TrinityCore/commit/9ab0679781ba65bc278203ee01d1169114c64033)
This commit is contained in:
hondacrx
2023-01-05 03:02:26 -05:00
parent 40db25f49c
commit 23c3084f00
3 changed files with 109 additions and 34 deletions
+44 -4
View File
@@ -816,7 +816,7 @@ namespace Game.Entities
public override string GetDebugInfo()
{
return $"{base.GetDebugInfo()}\n{GetGUID()} Entry: {GetEntry()}\nName: { GetName()}";
return $"{base.GetDebugInfo()}\n{GetGUID()} Entry: {GetEntry()}\nName: {GetName()}";
}
public virtual Loot GetLootForPlayer(Player player) { return null; }
@@ -1664,10 +1664,13 @@ namespace Game.Entities
return searcher.GetTarget();
}
public Creature FindNearestCreatureWithAura(uint entry, uint spellId, float range, bool alive = true)
public Creature FindNearestCreatureWithOptions(float range, FindCreatureOptions options)
{
var checker = new NearestCreatureEntryWithLiveStateAndAuraInObjectRangeCheck(this, entry, spellId, alive, range);
var checker = new NearestCreatureEntryWithLiveStateAndAuraInObjectRangeCheck(this, range, options);
var searcher = new CreatureLastSearcher(this, checker);
if (options.IgnorePhases)
searcher.i_phaseShift = PhasingHandler.GetAlwaysVisiblePhaseShift();
Cell.VisitAllObjects(this, searcher, range);
return searcher.GetTarget();
}
@@ -2627,7 +2630,7 @@ namespace Game.Entities
Unit unitOrOwner = unit;
GameObject go = ToGameObject();
if (go?.GetGoType() == GameObjectTypes.Trap)
unitOrOwner = go.GetOwner();
unitOrOwner = go.GetOwner();
// ignore immunity flags when assisting
if (unitOrOwner != null && unitTarget != null && !(isPositiveSpell && bySpell.HasAttribute(SpellAttr6.CanAssistImmunePc)))
@@ -4043,4 +4046,41 @@ namespace Game.Entities
player.SendPacket(i_message);
}
}
public struct FindCreatureOptions
{
public FindCreatureOptions SetCreatureId(uint creatureId) { CreatureId = creatureId; return this; }
public FindCreatureOptions SetIsAlive(bool isAlive) { IsAlive = isAlive; return this; }
public FindCreatureOptions SetIsInCombat(bool isInCombat) { IsInCombat = isInCombat; return this; }
public FindCreatureOptions SetIsSummon(bool isSummon) { IsSummon = isSummon; return this; }
public FindCreatureOptions SetIgnorePhases(bool ignorePhases) { IgnorePhases = ignorePhases; return this; }
public FindCreatureOptions SetIgnoreNotOwnedPrivateObjects(bool ignoreNotOwnedPrivateObjects) { IgnoreNotOwnedPrivateObjects = ignoreNotOwnedPrivateObjects; return this; }
public FindCreatureOptions SetIgnorePrivateObjects(bool ignorePrivateObjects) { IgnorePrivateObjects = ignorePrivateObjects; return this; }
public FindCreatureOptions SetHasAura(uint spellId) { AuraSpellId = spellId; return this; }
public FindCreatureOptions SetOwner(ObjectGuid ownerGuid) { OwnerGuid = ownerGuid; return this; }
public FindCreatureOptions SetCharmer(ObjectGuid charmerGuid) { CharmerGuid = charmerGuid; return this; }
public FindCreatureOptions SetCreator(ObjectGuid creatorGuid) { CreatorGuid = creatorGuid; return this; }
public FindCreatureOptions SetDemonCreator(ObjectGuid demonCreatorGuid) { DemonCreatorGuid = demonCreatorGuid; return this; }
public FindCreatureOptions SetPrivateObjectOwner(ObjectGuid privateObjectOwnerGuid) { PrivateObjectOwnerGuid = privateObjectOwnerGuid; return this; }
public uint? CreatureId;
public bool? IsAlive;
public bool? IsInCombat;
public bool? IsSummon;
public bool IgnorePhases;
public bool IgnoreNotOwnedPrivateObjects;
public bool IgnorePrivateObjects;
public uint? AuraSpellId;
public ObjectGuid? OwnerGuid;
public ObjectGuid? CharmerGuid;
public ObjectGuid? CreatorGuid;
public ObjectGuid? DemonCreatorGuid;
public ObjectGuid? PrivateObjectOwnerGuid;
}
}
+44 -21
View File
@@ -1713,7 +1713,7 @@ namespace Game.Maps
public class CreatureLastSearcher : Notifier
{
PhaseShift i_phaseShift;
internal PhaseShift i_phaseShift;
Creature i_object;
ICheck<Creature> i_check;
@@ -2433,37 +2433,60 @@ namespace Game.Maps
float i_range;
}
public class NearestCreatureEntryWithLiveStateAndAuraInObjectRangeCheck : ICheck<Creature>
public class NearestCreatureEntryWithOptionsInObjectRangeCheck : ICheck<Creature>
{
WorldObject i_obj;
uint i_entry;
uint i_spellId;
bool i_alive;
FindCreatureOptions i_args;
float i_range;
public NearestCreatureEntryWithLiveStateAndAuraInObjectRangeCheck(WorldObject obj, uint entry, uint spellId, bool alive, float range)
public NearestCreatureEntryWithOptionsInObjectRangeCheck(WorldObject obj, float range, FindCreatureOptions args)
{
i_obj = obj;
i_entry = entry;
i_spellId = spellId;
i_alive = alive;
i_args = args;
i_range = range;
}
public bool Invoke(Creature u)
{
if (u.GetDeathState() != DeathState.Dead
&& u.GetEntry() == i_entry
&& u.HasAura(i_spellId)
&& u.IsAlive() == i_alive
&& u.GetGUID() != i_obj.GetGUID()
&& i_obj.IsWithinDistInMap(u, i_range)
&& u.CheckPrivateObjectOwnerVisibility(i_obj))
{
i_range = i_obj.GetDistance(u); // use found unit range as new range limit for next check
return true;
}
return false;
if (u.GetDeathState() == DeathState.Dead) // Despawned
return false;
if (u.GetGUID() == i_obj.GetGUID())
return false;
if (!i_obj.IsWithinDistInMap(u, i_range))
return false;
if (i_args.CreatureId.HasValue && u.GetEntry() != i_args.CreatureId)
return false;
if (i_args.IsAlive.HasValue && u.IsAlive() != i_args.IsAlive)
return false;
if (i_args.IsSummon.HasValue && u.IsSummon() != i_args.IsSummon)
return false;
if (i_args.IsInCombat.HasValue && u.IsInCombat() != i_args.IsInCombat)
return false;
if ((i_args.OwnerGuid.HasValue && u.GetOwnerGUID() != i_args.OwnerGuid)
|| (i_args.CharmerGuid.HasValue && u.GetCharmerGUID() != i_args.CharmerGuid)
|| (i_args.CreatorGuid.HasValue && u.GetCreatorGUID() != i_args.CreatorGuid)
|| (i_args.DemonCreatorGuid.HasValue && u.GetDemonCreatorGUID() != i_args.DemonCreatorGuid)
|| (i_args.PrivateObjectOwnerGuid.HasValue && u.GetPrivateObjectOwner() != i_args.PrivateObjectOwnerGuid))
return false;
if (i_args.IgnorePrivateObjects && u.IsPrivateObject())
return false;
if (i_args.IgnoreNotOwnedPrivateObjects && !u.CheckPrivateObjectOwnerVisibility(i_obj))
return false;
if (i_args.AuraSpellId.HasValue && !u.HasAura((uint)i_args.AuraSpellId))
return false;
i_range = i_obj.GetDistance(u); // use found unit range as new range limit for next check
return true;
}
}
+12
View File
@@ -33,6 +33,13 @@ namespace Game
public class PhasingHandler
{
public static PhaseShift EmptyPhaseShift = new();
public static PhaseShift AlwaysVisible;
static PhasingHandler()
{
AlwaysVisible = new();
InitDbPhaseShift(AlwaysVisible, PhaseUseFlagsValues.AlwaysVisible, 0, 0);
}
public static PhaseFlags GetPhaseFlags(uint phaseId)
{
@@ -500,6 +507,11 @@ namespace Game
partyMemberPhases.List.Add(new PartyMemberPhase((uint)pair.Value.Flags, pair.Key));
}
public static PhaseShift GetAlwaysVisiblePhaseShift()
{
return AlwaysVisible;
}
public static void InitDbPhaseShift(PhaseShift phaseShift, PhaseUseFlagsValues phaseUseFlags, uint phaseId, uint phaseGroupId)
{
phaseShift.ClearPhases();