Core/Conditions: Initial support for UnitCondition.db2

Port From (https://github.com/TrinityCore/TrinityCore/commit/72286dc5e4fa5db2aff012d9cd496a8a6fc514c3)
This commit is contained in:
hondacrx
2022-02-26 17:32:19 -05:00
parent 3aad3e7e97
commit 26deeb7a1e
5 changed files with 387 additions and 8 deletions
+117
View File
@@ -2128,6 +2128,123 @@ namespace Framework.Constants
Orphan = 6
}
[Flags]
public enum UnitConditionFlags
{
LogicOr = 0x1
}
public enum UnitConditionOp
{
EqualTo = 1,
NotEqualTo = 2,
LessThan = 3,
LessThanOrEqualTo = 4,
GreaterThan = 5,
GreaterThanOrEqualTo = 6
}
public enum UnitConditionVariable
{
None = 0, // - NONE -
Race = 1, // Race {$Is/Is Not} "{ChrRaces}"
Class = 2, // Class {$Is/Is Not} "{ChrClasses}"
Level = 3, // Level {$Relative Op} "{#Level}"
IsSelf = 4, // Is self? {$Yes/No}{=1}
IsMyPet = 5, // Is my pet? {$Yes/No}{=1}
IsMaster = 6, // Is master? {$Yes/No}{=1}
IsTarget = 7, // Is target? {$Yes/No}{=1}
CanAssist = 8, // Can assist? {$Yes/No}{=1}
CanAttack = 9, // Can attack? {$Yes/No}{=1}
HasPet = 10, // Has pet? {$Yes/No}{=1}
HasWeapon = 11, // Has weapon? {$Yes/No}{=1}
HealthPct = 12, // Health {$Relative Op} {#Health %}%
ManaPct = 13, // Mana {$Relative Op} {#Mana %}%
RagePct = 14, // Rage {$Relative Op} {#Rage %}%
EnergyPct = 15, // Energy {$Relative Op} {#Energy %}%
ComboPoints = 16, // Combo Points {$Relative Op} {#Points}
HasHelpfulAuraSpell = 17, // Has helpful aura spell? {$Yes/No} "{Spell}"
HasHelpfulAuraDispelType = 18, // Has helpful aura dispel type? {$Yes/No} "{SpellDispelType}"
HasHelpfulAuraMechanic = 19, // Has helpful aura mechanic? {$Yes/No} "{SpellMechanic}"
HasHarmfulAuraSpell = 20, // Has harmful aura spell? {$Yes/No} "{Spell}"
HasHarmfulAuraDispelType = 21, // Has harmful aura dispel type? {$Yes/No} "{SpellDispelType}"
HasHarmfulAuraMechanic = 22, // Has harmful aura mechanic? {$Yes/No} "{SpellMechanic}"
HasHarmfulAuraSchool = 23, // Has harmful aura school? {$Yes/No} "{Resistances}"
DamagePhysicalPct = 24, // NYI Damage (Physical) {$Relative Op} {#Physical Damage %}%
DamageHolyPct = 25, // NYI Damage (Holy) {$Relative Op} {#Holy Damage %}%
DamageFirePct = 26, // NYI Damage (Fire) {$Relative Op} {#Fire Damage %}%
DamageNaturePct = 27, // NYI Damage (Nature) {$Relative Op} {#Nature Damage %}%
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}
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}
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 %}%
ThreatFirePct = 48, // NYI Threat (Fire) {$Relative Op} {#Fire Threat %}%
ThreatNaturePct = 49, // NYI Threat (Nature) {$Relative Op} {#Nature Threat %}%
ThreatFrostPct = 50, // NYI Threat (Frost) {$Relative Op} {#Frost Threat %}%
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}"
IsImmuneToAreaOfEffect = 62, // NYI Is immune to area-of-effect? {$Yes/No}{=1}
IsPlayer = 63, // NYI 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}
HasTotemInSlot5 = 73, // NYI Has totem in slot 5? {$Yes/No}{=1}
Creature = 74, // NYI 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}
PathFailCount = 84, // NYI Path fail count {$Relative Op} {#Path Fail Count}
IsMounted = 85, // NYI 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}
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}"
HasHelpfulAuraSchool = 96, // Has helpful aura school? {$Yes/No} "{Resistances}"
}
public enum WorldStateExpressionValueType
{
Constant = 1,
+252
View File
@@ -2366,6 +2366,258 @@ namespace Game
return finalResult;
}
static int GetUnitConditionVariable(Unit unit, Unit otherUnit, UnitConditionVariable variable, int value)
{
switch (variable)
{
case UnitConditionVariable.Race:
return (int)unit.GetRace();
case UnitConditionVariable.Class:
return (int)unit.GetClass();
case UnitConditionVariable.Level:
return (int)unit.GetLevel();
case UnitConditionVariable.IsSelf:
return unit == otherUnit ? 1 : 0;
case UnitConditionVariable.IsMyPet:
return (otherUnit != null && unit.GetCharmerOrOwnerGUID() == otherUnit.GetGUID()) ? 1 : 0;
case UnitConditionVariable.IsMaster:
return (otherUnit && otherUnit.GetCharmerOrOwnerGUID() == unit.GetGUID()) ? 1 : 0;
case UnitConditionVariable.IsTarget:
return (otherUnit && otherUnit.GetTarget() == unit.GetGUID()) ? 1 : 0;
case UnitConditionVariable.CanAssist:
return (otherUnit && unit.IsValidAssistTarget(otherUnit)) ? 1 : 0;
case UnitConditionVariable.CanAttack:
return (otherUnit && unit.IsValidAttackTarget(otherUnit)) ? 1 : 0;
case UnitConditionVariable.HasPet:
return (!unit.GetCharmedGUID().IsEmpty() || !unit.GetMinionGUID().IsEmpty()) ? 1 : 0;
case UnitConditionVariable.HasWeapon:
Player player = unit.ToPlayer();
if (player != null)
return (player.GetWeaponForAttack(WeaponAttackType.BaseAttack) || player.GetWeaponForAttack(WeaponAttackType.OffAttack)) ? 1 : 0;
return (unit.GetVirtualItemId(0) != 0 || unit.GetVirtualItemId(1) != 0) ? 1 : 0;
case UnitConditionVariable.HealthPct:
return (int)unit.GetHealthPct();
case UnitConditionVariable.ManaPct:
return (int)unit.GetPowerPct(PowerType.Mana);
case UnitConditionVariable.RagePct:
return (int)unit.GetPowerPct(PowerType.Rage);
case UnitConditionVariable.EnergyPct:
return (int)unit.GetPowerPct(PowerType.Energy);
case UnitConditionVariable.ComboPoints:
return unit.GetPower(PowerType.ComboPoints);
case UnitConditionVariable.HasHelpfulAuraSpell:
return unit.GetAuraApplication((uint)value, aurApp => !aurApp.GetFlags().HasFlag(AuraFlags.Negative)) != null ? value : 0;
case UnitConditionVariable.HasHelpfulAuraDispelType:
return unit.GetAuraApplication(aurApp => !aurApp.GetFlags().HasFlag(AuraFlags.Negative) && (int)aurApp.GetBase().GetSpellInfo().Dispel == value) != null ? value : 0;
case UnitConditionVariable.HasHelpfulAuraMechanic:
return unit.GetAuraApplication(aurApp => !aurApp.GetFlags().HasFlag(AuraFlags.Negative) && (aurApp.GetBase().GetSpellInfo().GetSpellMechanicMaskByEffectMask(aurApp.GetEffectMask()) & (1 << value)) != 0) != null ? value : 0;
case UnitConditionVariable.HasHarmfulAuraSpell:
return unit.GetAuraApplication((uint)value, aurApp => aurApp.GetFlags().HasFlag(AuraFlags.Negative)) != null ? value : 0;
case UnitConditionVariable.HasHarmfulAuraDispelType:
return unit.GetAuraApplication(aurApp => aurApp.GetFlags().HasFlag(AuraFlags.Negative) && (int)aurApp.GetBase().GetSpellInfo().Dispel == value) != null ? value : 0;
case UnitConditionVariable.HasHarmfulAuraMechanic:
return unit.GetAuraApplication(aurApp => aurApp.GetFlags().HasFlag(AuraFlags.Negative) && (aurApp.GetBase().GetSpellInfo().GetSpellMechanicMaskByEffectMask(aurApp.GetEffectMask()) & (1 << value)) != 0) != null ? value : 0;
case UnitConditionVariable.HasHarmfulAuraSchool:
return unit.GetAuraApplication(aurApp => aurApp.GetFlags().HasFlag(AuraFlags.Negative) && ((int)aurApp.GetBase().GetSpellInfo().GetSchoolMask() & (1 << value)) != 0) != null ? value : 0;
case UnitConditionVariable.DamagePhysicalPct:
break;
case UnitConditionVariable.DamageHolyPct:
break;
case UnitConditionVariable.DamageFirePct:
break;
case UnitConditionVariable.DamageNaturePct:
break;
case UnitConditionVariable.DamageFrostPct:
break;
case UnitConditionVariable.DamageShadowPct:
break;
case UnitConditionVariable.DamageArcanePct:
break;
case UnitConditionVariable.InCombat:
break;
case UnitConditionVariable.IsMoving:
break;
case UnitConditionVariable.IsCasting:
break;
case UnitConditionVariable.IsCastingSpell:
break;
case UnitConditionVariable.IsChanneling:
break;
case UnitConditionVariable.IsChannelingSpell:
break;
case UnitConditionVariable.NumberOfMeleeAttackers:
break;
case UnitConditionVariable.IsAttackingMe:
break;
case UnitConditionVariable.Range:
break;
case UnitConditionVariable.InMeleeRange:
break;
case UnitConditionVariable.PursuitTime:
break;
case UnitConditionVariable.HasHarmfulAuraCanceledByDamage:
break;
case UnitConditionVariable.HasHarmfulAuraWithPeriodicDamage:
break;
case UnitConditionVariable.NumberOfEnemies:
break;
case UnitConditionVariable.NumberOfFriends:
break;
case UnitConditionVariable.ThreatPhysicalPct:
break;
case UnitConditionVariable.ThreatHolyPct:
break;
case UnitConditionVariable.ThreatFirePct:
break;
case UnitConditionVariable.ThreatNaturePct:
break;
case UnitConditionVariable.ThreatFrostPct:
break;
case UnitConditionVariable.ThreatShadowPct:
break;
case UnitConditionVariable.ThreatArcanePct:
break;
case UnitConditionVariable.IsInterruptible:
break;
case UnitConditionVariable.NumberOfAttackers:
break;
case UnitConditionVariable.NumberOfRangedAttackers:
break;
case UnitConditionVariable.CreatureType:
break;
case UnitConditionVariable.IsMeleeAttacking:
break;
case UnitConditionVariable.IsRangedAttacking:
break;
case UnitConditionVariable.Health:
break;
case UnitConditionVariable.SpellKnown:
break;
case UnitConditionVariable.HasHarmfulAuraEffect:
break;
case UnitConditionVariable.IsImmuneToAreaOfEffect:
break;
case UnitConditionVariable.IsPlayer:
break;
case UnitConditionVariable.DamageMagicPct:
break;
case UnitConditionVariable.DamageTotalPct:
break;
case UnitConditionVariable.ThreatMagicPct:
break;
case UnitConditionVariable.ThreatTotalPct:
break;
case UnitConditionVariable.HasCritter:
return unit.GetCritterGUID().IsEmpty() ? 0 : 1;
case UnitConditionVariable.HasTotemInSlot1:
break;
case UnitConditionVariable.HasTotemInSlot2:
break;
case UnitConditionVariable.HasTotemInSlot3:
break;
case UnitConditionVariable.HasTotemInSlot4:
break;
case UnitConditionVariable.HasTotemInSlot5:
break;
case UnitConditionVariable.Creature:
break;
case UnitConditionVariable.StringID:
break;
case UnitConditionVariable.HasAura:
break;
case UnitConditionVariable.IsEnemy:
break;
case UnitConditionVariable.IsSpecMelee:
break;
case UnitConditionVariable.IsSpecTank:
break;
case UnitConditionVariable.IsSpecRanged:
break;
case UnitConditionVariable.IsSpecHealer:
break;
case UnitConditionVariable.IsPlayerControlledNPC:
break;
case UnitConditionVariable.IsDying:
break;
case UnitConditionVariable.PathFailCount:
break;
case UnitConditionVariable.IsMounted:
break;
case UnitConditionVariable.Label:
break;
case UnitConditionVariable.IsMySummon:
break;
case UnitConditionVariable.IsSummoner:
break;
case UnitConditionVariable.IsMyTarget:
break;
case UnitConditionVariable.Sex:
break;
case UnitConditionVariable.LevelWithinContentTuning:
break;
case UnitConditionVariable.IsFlying:
break;
case UnitConditionVariable.IsHovering:
break;
case UnitConditionVariable.HasHelpfulAuraEffect:
break;
case UnitConditionVariable.HasHelpfulAuraSchool:
return unit.GetAuraApplication(aurApp =>
{
return !aurApp.GetFlags().HasFlag(AuraFlags.Negative) && ((int)aurApp.GetBase().GetSpellInfo().GetSchoolMask() & (1 << value)) != 0;
}) != null ? value : 0;
default:
break;
}
return 0;
}
public static bool IsUnitMeetingCondition(Unit unit, Unit otherUnit, UnitConditionRecord condition)
{
for (int i = 0; i < condition.Variable.Length; ++i)
{
if (condition.Variable[i] == 0)
break;
int unitValue = GetUnitConditionVariable(unit, otherUnit, (UnitConditionVariable)condition.Variable[i], condition.Value[i]);
bool meets = false;
switch ((UnitConditionOp)condition.Op[i])
{
case UnitConditionOp.EqualTo:
meets = unitValue == condition.Value[i];
break;
case UnitConditionOp.NotEqualTo:
meets = unitValue != condition.Value[i];
break;
case UnitConditionOp.LessThan:
meets = unitValue < condition.Value[i];
break;
case UnitConditionOp.LessThanOrEqualTo:
meets = unitValue <= condition.Value[i];
break;
case UnitConditionOp.GreaterThan:
meets = unitValue > condition.Value[i];
break;
case UnitConditionOp.GreaterThanOrEqualTo:
meets = unitValue >= condition.Value[i];
break;
default:
break;
}
if (condition.GetFlags().HasFlag(UnitConditionFlags.LogicOr))
{
if (meets)
return true;
}
else if (!meets)
return false;
}
return !condition.GetFlags().HasFlag(UnitConditionFlags.LogicOr);
}
static int EvalSingleValue(ByteBuffer buffer, Player player)
{
WorldStateExpressionValueType valueType = (WorldStateExpressionValueType)buffer.ReadUInt8();
+1 -1
View File
@@ -725,7 +725,7 @@ namespace Game.DataStorage
public static DB6Storage<UiMapLinkRecord> UiMapLinkStorage;
public static DB6Storage<UiMapXMapArtRecord> UiMapXMapArtStorage;
public static DB6Storage<UISplashScreenRecord> UISplashScreenStorage;
public static DB6Storage<UnitConditionRecord> sUnitConditionStorage;
public static DB6Storage<UnitConditionRecord> UnitConditionStorage;
public static DB6Storage<UnitPowerBarRecord> UnitPowerBarStorage;
public static DB6Storage<VehicleRecord> VehicleStorage;
public static DB6Storage<VehicleSeatRecord> VehicleSeatStorage;
+3 -1
View File
@@ -101,7 +101,9 @@ namespace Game.DataStorage
public byte[] Variable = new byte[8];
public sbyte[] Op = new sbyte[8];
public int[] Value = new int[8];
};
public UnitConditionFlags GetFlags() { return (UnitConditionFlags)Flags; }
}
public sealed class UnitPowerBarRecord
{
+14 -6
View File
@@ -3222,21 +3222,29 @@ namespace Game.Spells
return false;
}
public uint GetSpellXSpellVisualId(WorldObject caster = null)
public uint GetSpellXSpellVisualId(WorldObject caster = null, WorldObject viewer = null)
{
foreach (SpellXSpellVisualRecord visual in _visuals)
{
PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(visual.CasterPlayerConditionID);
if (playerCondition == null || (caster && caster.GetTypeId() == TypeId.Player && ConditionManager.IsPlayerMeetingCondition(caster.ToPlayer(), playerCondition)))
return visual.Id;
var playerCondition = CliDB.PlayerConditionStorage.LookupByKey(visual.CasterPlayerConditionID);
if (playerCondition != null)
if (!caster || !caster.IsPlayer() || !ConditionManager.IsPlayerMeetingCondition(caster.ToPlayer(), playerCondition))
continue;
var unitCondition = CliDB.UnitConditionStorage.LookupByKey(visual.CasterUnitConditionID);
if (unitCondition != null)
if (!caster || !caster.IsUnit() || !ConditionManager.IsUnitMeetingCondition(caster.ToUnit(), viewer.ToUnit(), unitCondition))
continue;
return visual.Id;
}
return 0;
}
public uint GetSpellVisual(WorldObject caster = null)
public uint GetSpellVisual(WorldObject caster = null, WorldObject viewer = null)
{
var visual = CliDB.SpellXSpellVisualStorage.LookupByKey(GetSpellXSpellVisualId(caster));
var visual = CliDB.SpellXSpellVisualStorage.LookupByKey(GetSpellXSpellVisualId(caster, viewer));
if (visual != null)
{
//if (visual.LowViolenceSpellVisualID && forPlayer.GetViolenceLevel() operator 2)