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
+53 -13
View File
@@ -243,7 +243,7 @@ namespace Game.Entities
updateData.BuildPacket(out UpdateObject packet);
target.SendPacket(packet);
}
public void BuildMovementUpdate(WorldPacket data, CreateObjectBits flags, Player target)
{
List<uint> PauseTimes = null;
@@ -402,7 +402,7 @@ namespace Game.Entities
if (flags.CombatVictim)
data.WritePackedGuid(ToUnit().GetVictim().GetGUID()); // CombatVictim
if (flags.ServerTime)
data.WriteUInt32(GameTime.GetGameTimeMS());
@@ -816,11 +816,11 @@ 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; }
public abstract void BuildValuesCreate(WorldPacket data, Player target);
public abstract void BuildValuesUpdate(WorldPacket data, Player target);
@@ -1163,7 +1163,7 @@ namespace Game.Entities
}
public SmoothPhasing GetSmoothPhasing() { return _smoothPhasing; }
public bool CanSeeOrDetect(WorldObject obj, bool ignoreStealth = false, bool distanceCheck = false, bool checkAlert = false)
{
if (this == obj)
@@ -1504,7 +1504,7 @@ namespace Game.Entities
BattleField bf = Global.BattleFieldMgr.GetBattlefieldToZoneId(map, GetZoneId());
if (bf != null)
return bf;
return Global.OutdoorPvPMgr.GetOutdoorPvPToZoneId(map, GetZoneId());
}
}
@@ -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)))
@@ -2928,7 +2931,7 @@ namespace Game.Entities
{
return GetPhaseShift().CanSee(obj.GetPhaseShift());
}
public static bool InSamePhase(WorldObject a, WorldObject b)
{
return a != null && b != null && a.InSamePhase(b);
@@ -3056,7 +3059,7 @@ namespace Game.Entities
public void SetIsNewObject(bool enable) { _isNewObject = enable; }
public bool IsDestroyedObject() { return _isDestroyedObject; }
public void SetDestroyedObject(bool destroyed) { _isDestroyedObject = destroyed; }
public bool IsCreature() { return GetTypeId() == TypeId.Unit; }
public bool IsPlayer() { return GetTypeId() == TypeId.Player; }
public bool IsGameObject() { return GetTypeId() == TypeId.GameObject; }
@@ -3066,7 +3069,7 @@ namespace Game.Entities
public bool IsAreaTrigger() { return GetTypeId() == TypeId.AreaTrigger; }
public bool IsConversation() { return GetTypeId() == TypeId.Conversation; }
public bool IsSceneObject() { return GetTypeId() == TypeId.SceneObject; }
public Creature ToCreature() { return IsCreature() ? (this as Creature) : null; }
public Player ToPlayer() { return IsPlayer() ? (this as Player) : null; }
public GameObject ToGameObject() { return IsGameObject() ? (this as GameObject) : null; }
@@ -3678,7 +3681,7 @@ namespace Game.Entities
dist = MathF.Sqrt((pos.posX - destx) * (pos.posX - destx) + (pos.posY - desty) * (pos.posY - desty));
}
}
// check dynamic collision
col = GetMap().GetObjectHitPos(GetPhaseShift(), pos.posX, pos.posY, pos.posZ + halfHeight, destx, desty, destz + halfHeight, out destx, out desty, out destz, -0.5f);
@@ -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();