From dfe2303d6ff10a66d9e170a24f454ec6cabce370 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Sat, 26 Feb 2022 18:33:10 -0500 Subject: [PATCH] Core/Conditions: Implemented many more UnitCondition types Port From (https://github.com/TrinityCore/TrinityCore/commit/bf357312e0c4d0a68a95379ecdcbed817b136c31) --- Source/Framework/Constants/CliDBConst.cs | 90 +++++++------- Source/Game/Conditions/ConditionManager.cs | 132 ++++++++++++++------- 2 files changed, 131 insertions(+), 91 deletions(-) diff --git a/Source/Framework/Constants/CliDBConst.cs b/Source/Framework/Constants/CliDBConst.cs index d85cc418c..415bdfaf6 100644 --- a/Source/Framework/Constants/CliDBConst.cs +++ b/Source/Framework/Constants/CliDBConst.cs @@ -2177,20 +2177,20 @@ namespace Framework.Constants DamageFrostPct = 28, // NYI Damage (Frost) {$Relative Op} {#Frost Damage %}% DamageShadowPct = 29, // NYI Damage (Shadow) {$Relative Op} {#Shadow Damage %}% DamageArcanePct = 30, // NYI Damage (Arcane) {$Relative Op} {#Arcane Damage %}% - InCombat = 31, // NYI In combat? {$Yes/No}{=1} - IsMoving = 32, // NYI Is moving? {$Yes/No}{=1} - IsCasting = 33, // NYI Is casting? {$Yes/No}{=1} - IsCastingSpell = 34, // NYI Is casting spell? {$Yes/No}{=1} - IsChanneling = 35, // NYI Is channeling? {$Yes/No}{=1} - IsChannelingSpell = 36, // NYI Is channeling spell? {$Yes/No}{=1} - NumberOfMeleeAttackers = 37, // NYI Number of melee attackers {$Relative Op} {#Attackers} - IsAttackingMe = 38, // NYI Is attacking me? {$Yes/No}{=1} - Range = 39, // NYI Range {$Relative Op} {#Yards} - InMeleeRange = 40, // NYI In melee range? {$Yes/No}{=1} + InCombat = 31, // In combat? {$Yes/No}{=1} + IsMoving = 32, // Is moving? {$Yes/No}{=1} + IsCasting = 33, // Is casting? {$Yes/No}{=1} + IsCastingSpell = 34, // Is casting spell? {$Yes/No}{=1} + IsChanneling = 35, // Is channeling? {$Yes/No}{=1} + IsChannelingSpell = 36, // Is channeling spell? {$Yes/No}{=1} + NumberOfMeleeAttackers = 37, // Number of melee attackers {$Relative Op} {#Attackers} + IsAttackingMe = 38, // Is attacking me? {$Yes/No}{=1} + Range = 39, // Range {$Relative Op} {#Yards} + InMeleeRange = 40, // In melee range? {$Yes/No}{=1} PursuitTime = 41, // NYI Pursuit time {$Relative Op} {#Seconds} - HasHarmfulAuraCanceledByDamage = 42, // NYI Has harmful aura canceled by damage? {$Yes/No}{=1} - HasHarmfulAuraWithPeriodicDamage = 43, // NYI Has harmful aura with periodic damage? {$Yes/No}{=1} - NumberOfEnemies = 44, // NYI Number of enemies {$Relative Op} {#Enemies} + HasHarmfulAuraCanceledByDamage = 42, // Has harmful aura canceled by damage? {$Yes/No}{=1} + HasHarmfulAuraWithPeriodicDamage = 43, // Has harmful aura with periodic damage? {$Yes/No}{=1} + NumberOfEnemies = 44, // Number of enemies {$Relative Op} {#Enemies} NumberOfFriends = 45, // NYI Number of friends {$Relative Op} {#Friends} ThreatPhysicalPct = 46, // NYI Threat (Physical) {$Relative Op} {#Physical Threat %}% ThreatHolyPct = 47, // NYI Threat (Holy) {$Relative Op} {#Holy Threat %}% @@ -2200,48 +2200,48 @@ namespace Framework.Constants ThreatShadowPct = 51, // NYI Threat (Shadow) {$Relative Op} {#Shadow Threat %}% ThreatArcanePct = 52, // NYI Threat (Arcane) {$Relative Op} {#Arcane Threat %}% IsInterruptible = 53, // NYI Is interruptible? {$Yes/No}{=1} - NumberOfAttackers = 54, // NYI Number of attackers {$Relative Op} {#Attackers} - NumberOfRangedAttackers = 55, // NYI Number of ranged attackers {$Relative Op} {#Ranged Attackers} - CreatureType = 56, // NYI Creature type {$Is/Is Not} "{CreatureType}" - IsMeleeAttacking = 57, // NYI Is melee-attacking? {$Yes/No}{=1} - IsRangedAttacking = 58, // NYI Is ranged-attacking? {$Yes/No}{=1} - Health = 59, // NYI Health {$Relative Op} {#HP} HP - SpellKnown = 60, // NYI Spell known? {$Yes/No} "{Spell}" - HasHarmfulAuraEffect = 61, // NYI Has harmful aura effect? {$Yes/No} "{#Spell Aura}" + NumberOfAttackers = 54, // Number of attackers {$Relative Op} {#Attackers} + NumberOfRangedAttackers = 55, // Number of ranged attackers {$Relative Op} {#Ranged Attackers} + CreatureType = 56, // Creature type {$Is/Is Not} "{CreatureType}" + IsMeleeAttacking = 57, // Is melee-attacking? {$Yes/No}{=1} + IsRangedAttacking = 58, // Is ranged-attacking? {$Yes/No}{=1} + Health = 59, // Health {$Relative Op} {#HP} HP + SpellKnown = 60, // Spell known? {$Yes/No} "{Spell}" + HasHarmfulAuraEffect = 61, // Has harmful aura effect? {$Yes/No} "{#Spell Aura}" IsImmuneToAreaOfEffect = 62, // NYI Is immune to area-of-effect? {$Yes/No}{=1} - IsPlayer = 63, // NYI Is player? {$Yes/No}{=1} + IsPlayer = 63, // Is player? {$Yes/No}{=1} DamageMagicPct = 64, // NYI Damage (Magic) {$Relative Op} {#Magic Damage %}% DamageTotalPct = 65, // NYI Damage (Total) {$Relative Op} {#Damage %}% ThreatMagicPct = 66, // NYI Threat (Magic) {$Relative Op} {#Magic Threat %}% ThreatTotalPct = 67, // NYI Threat (Total) {$Relative Op} {#Threat %}% - HasCritter = 68, // NYI Has critter? {$Yes/No}{=1} - HasTotemInSlot1 = 69, // NYI Has totem in slot 1? {$Yes/No}{=1} - HasTotemInSlot2 = 70, // NYI Has totem in slot 2? {$Yes/No}{=1} - HasTotemInSlot3 = 71, // NYI Has totem in slot 3? {$Yes/No}{=1} - HasTotemInSlot4 = 72, // NYI Has totem in slot 4? {$Yes/No}{=1} + HasCritter = 68, // Has critter? {$Yes/No}{=1} + HasTotemInSlot1 = 69, // Has totem in slot 1? {$Yes/No}{=1} + HasTotemInSlot2 = 70, // Has totem in slot 2? {$Yes/No}{=1} + HasTotemInSlot3 = 71, // Has totem in slot 3? {$Yes/No}{=1} + HasTotemInSlot4 = 72, // Has totem in slot 4? {$Yes/No}{=1} HasTotemInSlot5 = 73, // NYI Has totem in slot 5? {$Yes/No}{=1} - Creature = 74, // NYI Creature {$Is/Is Not} "{Creature}" + Creature = 74, // Creature {$Is/Is Not} "{Creature}" StringID = 75, // NYI String ID {$Is/Is Not} "{StringID}" - HasAura = 76, // NYI Has aura? {$Yes/No} {Spell} - IsEnemy = 77, // NYI Is enemy? {$Yes/No}{=1} - IsSpecMelee = 78, // NYI Is spec - melee? {$Yes/No}{=1} - IsSpecTank = 79, // NYI Is spec - tank? {$Yes/No}{=1} - IsSpecRanged = 80, // NYI Is spec - ranged? {$Yes/No}{=1} - IsSpecHealer = 81, // NYI Is spec - healer? {$Yes/No}{=1} - IsPlayerControlledNPC = 82, // NYI Is player controlled NPC? {$Yes/No}{=1} - IsDying = 83, // NYI Is dying? {$Yes/No}{=1} + HasAura = 76, // Has aura? {$Yes/No} {Spell} + IsEnemy = 77, // Is enemy? {$Yes/No}{=1} + IsSpecMelee = 78, // Is spec - melee? {$Yes/No}{=1} + IsSpecTank = 79, // Is spec - tank? {$Yes/No}{=1} + IsSpecRanged = 80, // Is spec - ranged? {$Yes/No}{=1} + IsSpecHealer = 81, // Is spec - healer? {$Yes/No}{=1} + IsPlayerControlledNPC = 82, // Is player controlled NPC? {$Yes/No}{=1} + IsDying = 83, // Is dying? {$Yes/No}{=1} PathFailCount = 84, // NYI Path fail count {$Relative Op} {#Path Fail Count} - IsMounted = 85, // NYI Is mounted? {$Yes/No}{=1} + IsMounted = 85, // Is mounted? {$Yes/No}{=1} Label = 86, // NYI Label {$Is/Is Not} "{Label}" - IsMySummon = 87, // NYI - IsSummoner = 88, // NYI - IsMyTarget = 89, // NYI - Sex = 90, // NYI Sex {$Is/Is Not} "{UnitSex}" - LevelWithinContentTuning = 91, // NYI Level is within {$Is/Is Not} {ContentTuning} + IsMySummon = 87, // + IsSummoner = 88, // + IsMyTarget = 89, // + Sex = 90, // Sex {$Is/Is Not} "{UnitSex}" + LevelWithinContentTuning = 91, // Level is within {$Is/Is Not} {ContentTuning} - IsFlying = 93, // NYI Is flying? {$Yes/No}{=1} - IsHovering = 94, // NYI Is hovering? {$Yes/No}{=1} - HasHelpfulAuraEffect = 95, // NYI Has helpful aura effect? {$Yes/No} "{#Spell Aura}" + IsFlying = 93, // Is flying? {$Yes/No}{=1} + IsHovering = 94, // Is hovering? {$Yes/No}{=1} + HasHelpfulAuraEffect = 95, // Has helpful aura effect? {$Yes/No} "{#Spell Aura}" HasHelpfulAuraSchool = 96, // Has helpful aura school? {$Yes/No} "{Resistances}" } diff --git a/Source/Game/Conditions/ConditionManager.cs b/Source/Game/Conditions/ConditionManager.cs index 9b8fc7af2..24fb99308 100644 --- a/Source/Game/Conditions/ConditionManager.cs +++ b/Source/Game/Conditions/ConditionManager.cs @@ -2434,33 +2434,44 @@ namespace Game case UnitConditionVariable.DamageArcanePct: break; case UnitConditionVariable.InCombat: - break; + return unit.IsInCombat() ? 1 : 0; case UnitConditionVariable.IsMoving: - break; + return unit.HasUnitMovementFlag(MovementFlag.Forward | MovementFlag.Backward | MovementFlag.StrafeLeft | MovementFlag.StrafeRight) ? 1:0; case UnitConditionVariable.IsCasting: - break; - case UnitConditionVariable.IsCastingSpell: - break; + case UnitConditionVariable.IsCastingSpell: // this is supposed to return spell id by client code but data always has 0 or 1 + return unit.GetCurrentSpell(CurrentSpellTypes.Generic) != null ? 1 : 0; case UnitConditionVariable.IsChanneling: - break; - case UnitConditionVariable.IsChannelingSpell: - break; + case UnitConditionVariable.IsChannelingSpell: // this is supposed to return spell id by client code but data always has 0 or 1 + return unit.GetChannelSpellId() != 0 ? 1 : 0; case UnitConditionVariable.NumberOfMeleeAttackers: - break; + return unit.GetAttackers().Count(attacker => + { + float distance = Math.Max(unit.GetCombatReach() + attacker.GetCombatReach() + 1.3333334f, 5.0f); + if (unit.HasUnitFlag(UnitFlags.PlayerControlled) || attacker.HasUnitFlag(UnitFlags.PlayerControlled)) + distance += 1.0f; + return unit.GetExactDistSq(attacker) < distance * distance; + }); case UnitConditionVariable.IsAttackingMe: - break; + return (otherUnit != null && unit.GetTarget() == otherUnit.GetGUID()) ? 1:0; case UnitConditionVariable.Range: - break; + return otherUnit ? (int)unit.GetExactDist(otherUnit) : 0; case UnitConditionVariable.InMeleeRange: - break; + if (otherUnit) + { + float distance = Math.Max(unit.GetCombatReach() + otherUnit.GetCombatReach() + 1.3333334f, 5.0f); + if (unit.HasUnitFlag(UnitFlags.PlayerControlled) || otherUnit.HasUnitFlag(UnitFlags.PlayerControlled)) + distance += 1.0f; + return (unit.GetExactDistSq(otherUnit) < distance * distance) ? 1 : 0; + } + return 0; case UnitConditionVariable.PursuitTime: break; case UnitConditionVariable.HasHarmfulAuraCanceledByDamage: - break; + return unit.HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags.Damage) ? 1 : 0; case UnitConditionVariable.HasHarmfulAuraWithPeriodicDamage: - break; + return unit.HasAuraType(AuraType.PeriodicDamage) ? 1 : 0; case UnitConditionVariable.NumberOfEnemies: - break; + return unit.GetThreatManager().GetThreatListSize(); case UnitConditionVariable.NumberOfFriends: break; case UnitConditionVariable.ThreatPhysicalPct: @@ -2480,25 +2491,51 @@ namespace Game case UnitConditionVariable.IsInterruptible: break; case UnitConditionVariable.NumberOfAttackers: - break; + return unit.GetAttackers().Count; case UnitConditionVariable.NumberOfRangedAttackers: - break; + return unit.GetAttackers().Count(attacker => + { + float distance = Math.Max(unit.GetCombatReach() + attacker.GetCombatReach() + 1.3333334f, 5.0f); + if (unit.HasUnitFlag(UnitFlags.PlayerControlled) || attacker.HasUnitFlag(UnitFlags.PlayerControlled)) + distance += 1.0f; + return unit.GetExactDistSq(attacker) >= distance * distance; + }); case UnitConditionVariable.CreatureType: - break; + return (int)unit.GetCreatureType(); case UnitConditionVariable.IsMeleeAttacking: - break; + { + Unit target = Global.ObjAccessor.GetUnit(unit, unit.GetTarget()); + if (target != null) + { + float distance = Math.Max(unit.GetCombatReach() + target.GetCombatReach() + 1.3333334f, 5.0f); + if (unit.HasUnitFlag(UnitFlags.PlayerControlled) || target.HasUnitFlag(UnitFlags.PlayerControlled)) + distance += 1.0f; + return (unit.GetExactDistSq(target) < distance * distance) ? 1 : 0; + } + return 0; + } case UnitConditionVariable.IsRangedAttacking: - break; + { + Unit target = Global.ObjAccessor.GetUnit(unit, unit.GetTarget()); + if (target != null) + { + float distance = Math.Max(unit.GetCombatReach() + target.GetCombatReach() + 1.3333334f, 5.0f); + if (unit.HasUnitFlag(UnitFlags.PlayerControlled) || target.HasUnitFlag(UnitFlags.PlayerControlled)) + distance += 1.0f; + return (unit.GetExactDistSq(target) >= distance * distance) ? 1 : 0; + } + return 0; + } case UnitConditionVariable.Health: - break; + return (int)unit.GetHealth(); case UnitConditionVariable.SpellKnown: - break; + return unit.HasSpell((uint)value) ? value : 0; case UnitConditionVariable.HasHarmfulAuraEffect: - break; + return (value >= 0 && value < (int)AuraType.Total && unit.GetAuraEffectsByType((AuraType)value).Any(aurEff => aurEff.GetBase().GetApplicationOfTarget(unit.GetGUID()).GetFlags().HasFlag(AuraFlags.Negative))) ? 1 : 0; case UnitConditionVariable.IsImmuneToAreaOfEffect: break; case UnitConditionVariable.IsPlayer: - break; + return unit.IsPlayer() ? 1 : 0; case UnitConditionVariable.DamageMagicPct: break; case UnitConditionVariable.DamageTotalPct: @@ -2510,57 +2547,60 @@ namespace Game case UnitConditionVariable.HasCritter: return unit.GetCritterGUID().IsEmpty() ? 0 : 1; case UnitConditionVariable.HasTotemInSlot1: - break; + return unit.m_SummonSlot[(int)SummonSlot.Totem].IsEmpty() ? 0 : 1; case UnitConditionVariable.HasTotemInSlot2: - break; + return unit.m_SummonSlot[(int)SummonSlot.Totem2].IsEmpty() ? 0 : 1; case UnitConditionVariable.HasTotemInSlot3: - break; + return unit.m_SummonSlot[(int)SummonSlot.Totem3].IsEmpty() ? 0 : 1; case UnitConditionVariable.HasTotemInSlot4: - break; + return unit.m_SummonSlot[(int)SummonSlot.Totem4].IsEmpty() ? 0 : 1; case UnitConditionVariable.HasTotemInSlot5: break; case UnitConditionVariable.Creature: - break; + return (int)unit.GetEntry(); case UnitConditionVariable.StringID: break; case UnitConditionVariable.HasAura: - break; + return unit.HasAura((uint)value) ? value : 0; case UnitConditionVariable.IsEnemy: - break; + return (otherUnit && unit.GetReactionTo(otherUnit) <= ReputationRank.Hostile) ? 1 : 0; case UnitConditionVariable.IsSpecMelee: - break; + return (unit.IsPlayer() && CliDB.ChrSpecializationStorage.LookupByKey(unit.ToPlayer().GetPrimarySpecialization()).Flags.HasFlag(ChrSpecializationFlag.Melee)) ? 1 : 0; case UnitConditionVariable.IsSpecTank: - break; + return (unit.IsPlayer() && CliDB.ChrSpecializationStorage.LookupByKey(unit.ToPlayer().GetPrimarySpecialization()).Role == 0) ? 1 : 0; case UnitConditionVariable.IsSpecRanged: - break; + return (unit.IsPlayer() && CliDB.ChrSpecializationStorage.LookupByKey(unit.ToPlayer().GetPrimarySpecialization()).Flags.HasFlag(ChrSpecializationFlag.Ranged)) ? 1 : 0; case UnitConditionVariable.IsSpecHealer: - break; + return (unit.IsPlayer() && CliDB.ChrSpecializationStorage.LookupByKey(unit.ToPlayer().GetPrimarySpecialization()).Role == 1) ? 1 : 0; case UnitConditionVariable.IsPlayerControlledNPC: - break; + return unit.IsCreature() && unit.HasUnitFlag(UnitFlags.PlayerControlled) ? 1 : 0; case UnitConditionVariable.IsDying: - break; + return unit.GetHealth() == 0 ? 1 : 0; case UnitConditionVariable.PathFailCount: break; case UnitConditionVariable.IsMounted: - break; + return unit.GetMountDisplayId() != 0 ? 1 : 0; case UnitConditionVariable.Label: break; case UnitConditionVariable.IsMySummon: - break; + return (otherUnit && (otherUnit.GetCharmerGUID() == unit.GetGUID() || otherUnit.GetCreatorGUID() == unit.GetGUID())) ? 1 : 0; case UnitConditionVariable.IsSummoner: - break; + return (otherUnit && (unit.GetCharmerGUID() == otherUnit.GetGUID() || unit.GetCreatorGUID() == otherUnit.GetGUID())) ? 1 : 0; case UnitConditionVariable.IsMyTarget: - break; + return (otherUnit && unit.GetTarget() == otherUnit.GetGUID()) ? 1 : 0; case UnitConditionVariable.Sex: - break; + return (int)unit.GetGender(); case UnitConditionVariable.LevelWithinContentTuning: - break; + var levelRange = Global.DB2Mgr.GetContentTuningData((uint)value, 0); + if (levelRange.HasValue) + return unit.GetLevel() >= levelRange.Value.MinLevel && unit.GetLevel() <= levelRange.Value.MaxLevel ? value : 0; + return 0; case UnitConditionVariable.IsFlying: - break; + return unit.IsFlying() ? 1 : 0; case UnitConditionVariable.IsHovering: - break; + return unit.IsHovering() ? 1 : 0; case UnitConditionVariable.HasHelpfulAuraEffect: - break; + return (value >= 0 && value < (int)AuraType.Total && unit.GetAuraEffectsByType((AuraType)value).Any(aurEff => !aurEff.GetBase().GetApplicationOfTarget(unit.GetGUID()).GetFlags().HasFlag(AuraFlags.Negative))) ? 1 : 0; case UnitConditionVariable.HasHelpfulAuraSchool: return unit.GetAuraApplication(aurApp => {