Core/SAI: Add a warning when a boolean value is outside of [0,1] range

Port From (https://github.com/TrinityCore/TrinityCore/commit/a85e77b47a66591944d1af56741fa0ddd317fd87)
This commit is contained in:
hondacrx
2022-05-28 17:44:46 -04:00
parent 750fd7f885
commit 06da4c2dfd
+159 -31
View File
@@ -23,6 +23,7 @@ using Game.Movement;
using Game.Spells; using Game.Spells;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Game.AI namespace Game.AI
@@ -503,24 +504,37 @@ namespace Game.AI
return false; return false;
} }
break; break;
case SmartTargets.PlayerRange:
case SmartTargets.Self:
case SmartTargets.Victim:
case SmartTargets.HostileSecondAggro: case SmartTargets.HostileSecondAggro:
case SmartTargets.HostileLastAggro: case SmartTargets.HostileLastAggro:
case SmartTargets.HostileRandom: case SmartTargets.HostileRandom:
case SmartTargets.HostileRandomNotTop: case SmartTargets.HostileRandomNotTop:
case SmartTargets.Position: TC_SAI_IS_BOOLEAN_VALID(e, e.Target.hostilRandom.playerOnly);
case SmartTargets.None: break;
case SmartTargets.OwnerOrSummoner: case SmartTargets.Farthest:
case SmartTargets.ThreatList: TC_SAI_IS_BOOLEAN_VALID(e, e.Target.farthest.playerOnly);
TC_SAI_IS_BOOLEAN_VALID(e, e.Target.farthest.isInLos);
break;
case SmartTargets.ClosestGameobject: case SmartTargets.ClosestGameobject:
case SmartTargets.ClosestCreature: case SmartTargets.ClosestCreature:
TC_SAI_IS_BOOLEAN_VALID(e, e.Target.closest.dead);
break;
case SmartTargets.ClosestEnemy: case SmartTargets.ClosestEnemy:
TC_SAI_IS_BOOLEAN_VALID(e, e.Target.closestAttackable.playerOnly);
break;
case SmartTargets.ClosestFriendly: case SmartTargets.ClosestFriendly:
TC_SAI_IS_BOOLEAN_VALID(e, e.Target.closestFriendly.playerOnly);
break;
case SmartTargets.OwnerOrSummoner:
TC_SAI_IS_BOOLEAN_VALID(e, e.Target.owner.useCharmerOrOwner);
break;
case SmartTargets.PlayerRange:
case SmartTargets.Self:
case SmartTargets.Victim:
case SmartTargets.Position:
case SmartTargets.None:
case SmartTargets.ThreatList:
case SmartTargets.Stored: case SmartTargets.Stored:
case SmartTargets.LootRecipients: case SmartTargets.LootRecipients:
case SmartTargets.Farthest:
case SmartTargets.VehiclePassenger: case SmartTargets.VehiclePassenger:
case SmartTargets.ClosestUnspawnedGameobject: case SmartTargets.ClosestUnspawnedGameobject:
break; break;
@@ -633,6 +647,7 @@ namespace Game.AI
Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} uses hostilityMode with invalid value {e.Event.los.hostilityMode} (max allowed value {LOSHostilityMode.End - 1}), skipped."); Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} uses hostilityMode with invalid value {e.Event.los.hostilityMode} (max allowed value {LOSHostilityMode.End - 1}), skipped.");
return false; return false;
} }
TC_SAI_IS_BOOLEAN_VALID(e, e.Event.los.playerOnly);
break; break;
case SmartEvents.Respawn: case SmartEvents.Respawn:
if (e.Event.respawn.type == (uint)SmartRespawnCondition.Map && CliDB.MapStorage.LookupByKey(e.Event.respawn.map) == null) if (e.Event.respawn.type == (uint)SmartRespawnCondition.Map && CliDB.MapStorage.LookupByKey(e.Event.respawn.map) == null)
@@ -675,6 +690,8 @@ namespace Game.AI
if (e.Event.kill.creature != 0 && !IsCreatureValid(e, e.Event.kill.creature)) if (e.Event.kill.creature != 0 && !IsCreatureValid(e, e.Event.kill.creature))
return false; return false;
TC_SAI_IS_BOOLEAN_VALID(e, e.Event.kill.playerOnly);
break; break;
case SmartEvents.VictimCasting: case SmartEvents.VictimCasting:
if (e.Event.targetCasting.spellId > 0 && !Global.SpellMgr.HasSpellInfo(e.Event.targetCasting.spellId, Difficulty.None)) if (e.Event.targetCasting.spellId > 0 && !Global.SpellMgr.HasSpellInfo(e.Event.targetCasting.spellId, Difficulty.None))
@@ -914,6 +931,9 @@ namespace Game.AI
return false; return false;
} }
break; break;
case SmartEvents.Charmed:
TC_SAI_IS_BOOLEAN_VALID(e, e.Event.charm.onRemove);
break;
case SmartEvents.QuestObjCompletion: case SmartEvents.QuestObjCompletion:
if (Global.ObjectMgr.GetQuestObjective(e.Event.questObjective.id) == null) if (Global.ObjectMgr.GetQuestObjective(e.Event.questObjective.id) == null)
{ {
@@ -932,7 +952,6 @@ namespace Game.AI
case SmartEvents.TimedEventTriggered: case SmartEvents.TimedEventTriggered:
case SmartEvents.InstancePlayerEnter: case SmartEvents.InstancePlayerEnter:
case SmartEvents.TransportRelocate: case SmartEvents.TransportRelocate:
case SmartEvents.Charmed:
case SmartEvents.CharmedTarget: case SmartEvents.CharmedTarget:
case SmartEvents.CorpseRemoved: case SmartEvents.CorpseRemoved:
case SmartEvents.AiInit: case SmartEvents.AiInit:
@@ -968,6 +987,8 @@ namespace Game.AI
switch (e.GetActionType()) switch (e.GetActionType())
{ {
case SmartActions.Talk: case SmartActions.Talk:
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.talk.useTalkTarget);
goto case SmartActions.SimpleTalk;
case SmartActions.SimpleTalk: case SmartActions.SimpleTalk:
{ {
if (!IsTextValid(e, e.Action.talk.textGroupId)) if (!IsTextValid(e, e.Action.talk.textGroupId))
@@ -1009,6 +1030,8 @@ namespace Game.AI
case SmartActions.Sound: case SmartActions.Sound:
if (!IsSoundValid(e, e.Action.sound.soundId)) if (!IsSoundValid(e, e.Action.sound.soundId))
return false; return false;
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.sound.onlySelf);
break; break;
case SmartActions.SetEmoteState: case SmartActions.SetEmoteState:
case SmartActions.PlayEmote: case SmartActions.PlayEmote:
@@ -1029,9 +1052,14 @@ namespace Game.AI
if (e.Action.spellVisualKit.spellVisualKitId != 0 && !IsSpellVisualKitValid(e, e.Action.spellVisualKit.spellVisualKitId)) if (e.Action.spellVisualKit.spellVisualKitId != 0 && !IsSpellVisualKitValid(e, e.Action.spellVisualKit.spellVisualKitId))
return false; return false;
break; break;
case SmartActions.FailQuest:
case SmartActions.OfferQuest: case SmartActions.OfferQuest:
if (e.Action.quest.questId == 0 || !IsQuestValid(e, e.Action.quest.questId)) if (!IsQuestValid(e, e.Action.questOffer.questId))
return false;
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.questOffer.directAdd);
break;
case SmartActions.FailQuest:
if (!IsQuestValid(e, e.Action.quest.questId))
return false; return false;
break; break;
case SmartActions.ActivateTaxi: case SmartActions.ActivateTaxi:
@@ -1066,6 +1094,8 @@ namespace Game.AI
return false; return false;
if (e.Action.randomSound.sound4 != 0 && !IsSoundValid(e, e.Action.randomSound.sound4)) if (e.Action.randomSound.sound4 != 0 && !IsSoundValid(e, e.Action.randomSound.sound4))
return false; return false;
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.randomSound.onlySelf);
break; break;
case SmartActions.Cast: case SmartActions.Cast:
{ {
@@ -1141,6 +1171,8 @@ namespace Game.AI
case SmartActions.RemoveAurasFromSpell: case SmartActions.RemoveAurasFromSpell:
if (e.Action.removeAura.spell != 0 && !IsSpellValid(e, e.Action.removeAura.spell)) if (e.Action.removeAura.spell != 0 && !IsSpellValid(e, e.Action.removeAura.spell))
return false; return false;
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.removeAura.onlyOwnedAuras);
break; break;
case SmartActions.RandomPhase: case SmartActions.RandomPhase:
{ {
@@ -1178,6 +1210,8 @@ namespace Game.AI
Log.outError(LogFilter.ScriptsAi, $"SmartAIMgr: {e} uses incorrect TempSummonType {e.Action.summonCreature.type}, skipped."); Log.outError(LogFilter.ScriptsAi, $"SmartAIMgr: {e} uses incorrect TempSummonType {e.Action.summonCreature.type}, skipped.");
return false; return false;
} }
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.summonCreature.attackInvoker);
break; break;
case SmartActions.CallKilledmonster: case SmartActions.CallKilledmonster:
if (!IsCreatureValid(e, e.Action.killedMonster.creature)) if (!IsCreatureValid(e, e.Action.killedMonster.creature))
@@ -1192,6 +1226,8 @@ namespace Game.AI
case SmartActions.UpdateTemplate: case SmartActions.UpdateTemplate:
if (e.Action.updateTemplate.creature != 0 && !IsCreatureValid(e, e.Action.updateTemplate.creature)) if (e.Action.updateTemplate.creature != 0 && !IsCreatureValid(e, e.Action.updateTemplate.creature))
return false; return false;
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.updateTemplate.updateLevel);
break; break;
case SmartActions.SetSheath: case SmartActions.SetSheath:
if (e.Action.setSheath.sheath != 0 && e.Action.setSheath.sheath >= (uint)SheathState.Max) if (e.Action.setSheath.sheath != 0 && e.Action.setSheath.sheath >= (uint)SheathState.Max)
@@ -1244,6 +1280,8 @@ namespace Game.AI
case SmartActions.WpStop: case SmartActions.WpStop:
if (e.Action.wpStop.quest != 0 && !IsQuestValid(e, e.Action.wpStop.quest)) if (e.Action.wpStop.quest != 0 && !IsQuestValid(e, e.Action.wpStop.quest))
return false; return false;
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.wpStop.fail);
break; break;
case SmartActions.WpStart: case SmartActions.WpStart:
{ {
@@ -1262,6 +1300,9 @@ namespace Game.AI
Log.outError(LogFilter.ScriptsAi, $"SmartAIMgr: {e} uses invalid React State {e.Action.wpStart.reactState}, skipped."); Log.outError(LogFilter.ScriptsAi, $"SmartAIMgr: {e} uses invalid React State {e.Action.wpStart.reactState}, skipped.");
return false; return false;
} }
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.wpStart.run);
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.wpStart.repeat);
break; break;
} }
case SmartActions.CreateTimedEvent: case SmartActions.CreateTimedEvent:
@@ -1457,6 +1498,8 @@ namespace Game.AI
Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} does not specify pause duration"); Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} does not specify pause duration");
return false; return false;
} }
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.pauseMovement.force);
break; break;
} }
case SmartActions.SetMovementSpeed: case SmartActions.SetMovementSpeed:
@@ -1535,6 +1578,103 @@ namespace Game.AI
} }
break; break;
} }
case SmartActions.AutoAttack:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.autoAttack.attack);
break;
}
case SmartActions.AllowCombatMovement:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.combatMove.move);
break;
}
case SmartActions.CallForHelp:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.callHelp.withEmote);
break;
}
case SmartActions.SetVisibility:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.visibility.state);
break;
}
case SmartActions.SetActive:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.active.state);
break;
}
case SmartActions.SetRun:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.setRun.run);
break;
}
case SmartActions.SetDisableGravity:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.setDisableGravity.disable);
break;
}
case SmartActions.SetCanFly:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.setFly.fly);
break;
}
case SmartActions.SetSwim:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.setSwim.swim);
break;
}
case SmartActions.SetCounter:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.setCounter.reset);
break;
}
case SmartActions.CallTimedActionlist:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.timedActionList.allowOverride);
break;
}
case SmartActions.InterruptSpell:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.interruptSpellCasting.withDelayed);
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.interruptSpellCasting.withInstant);
break;
}
case SmartActions.FleeForAssist:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.fleeAssist.withEmote);
break;
}
case SmartActions.MoveToPos:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.moveToPos.transport);
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.moveToPos.disablePathfinding);
break;
}
case SmartActions.SetRoot:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.setRoot.root);
break;
}
case SmartActions.DisableEvade:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.disableEvade.disable);
break;
}
case SmartActions.LoadEquipment:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.loadEquipment.force);
break;
}
case SmartActions.SetHover:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.setHover.enable);
break;
}
case SmartActions.Evade:
{
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.evade.toRespawnPosition);
break;
}
case SmartActions.CreateConversation: case SmartActions.CreateConversation:
{ {
if (Global.ConversationDataStorage.GetConversationTemplate(e.Action.conversation.id) == null) if (Global.ConversationDataStorage.GetConversationTemplate(e.Action.conversation.id) == null)
@@ -1549,12 +1689,9 @@ namespace Game.AI
case SmartActions.Follow: case SmartActions.Follow:
case SmartActions.SetOrientation: case SmartActions.SetOrientation:
case SmartActions.StoreTargetList: case SmartActions.StoreTargetList:
case SmartActions.Evade:
case SmartActions.FleeForAssist:
case SmartActions.CombatStop: case SmartActions.CombatStop:
case SmartActions.Die: case SmartActions.Die:
case SmartActions.SetInCombatWithZone: case SmartActions.SetInCombatWithZone:
case SmartActions.SetActive:
case SmartActions.WpResume: case SmartActions.WpResume:
case SmartActions.KillUnit: case SmartActions.KillUnit:
case SmartActions.SetInvincibilityHpLevel: case SmartActions.SetInvincibilityHpLevel:
@@ -1563,22 +1700,13 @@ namespace Game.AI
case SmartActions.ThreatAllPct: case SmartActions.ThreatAllPct:
case SmartActions.ThreatSinglePct: case SmartActions.ThreatSinglePct:
case SmartActions.SetInstData64: case SmartActions.SetInstData64:
case SmartActions.AutoAttack:
case SmartActions.AllowCombatMovement:
case SmartActions.CallForHelp:
case SmartActions.SetData: case SmartActions.SetData:
case SmartActions.SetVisibility:
case SmartActions.AttackStop: case SmartActions.AttackStop:
case SmartActions.WpPause: case SmartActions.WpPause:
case SmartActions.SetDisableGravity:
case SmartActions.SetCanFly:
case SmartActions.SetRun:
case SmartActions.SetSwim:
case SmartActions.ForceDespawn: case SmartActions.ForceDespawn:
case SmartActions.SetUnitFlag: case SmartActions.SetUnitFlag:
case SmartActions.RemoveUnitFlag: case SmartActions.RemoveUnitFlag:
case SmartActions.Playmovie: case SmartActions.Playmovie:
case SmartActions.MoveToPos:
case SmartActions.CloseGossip: case SmartActions.CloseGossip:
case SmartActions.TriggerTimedEvent: case SmartActions.TriggerTimedEvent:
case SmartActions.RemoveTimedEvent: case SmartActions.RemoveTimedEvent:
@@ -1587,7 +1715,6 @@ namespace Game.AI
case SmartActions.ActivateGobject: case SmartActions.ActivateGobject:
case SmartActions.CallScriptReset: case SmartActions.CallScriptReset:
case SmartActions.SetRangedMovement: case SmartActions.SetRangedMovement:
case SmartActions.CallTimedActionlist:
case SmartActions.SetNpcFlag: case SmartActions.SetNpcFlag:
case SmartActions.AddNpcFlag: case SmartActions.AddNpcFlag:
case SmartActions.RemoveNpcFlag: case SmartActions.RemoveNpcFlag:
@@ -1595,7 +1722,6 @@ namespace Game.AI
case SmartActions.RandomMove: case SmartActions.RandomMove:
case SmartActions.SetUnitFieldBytes1: case SmartActions.SetUnitFieldBytes1:
case SmartActions.RemoveUnitFieldBytes1: case SmartActions.RemoveUnitFieldBytes1:
case SmartActions.InterruptSpell:
case SmartActions.SendGoCustomAnim: case SmartActions.SendGoCustomAnim:
case SmartActions.SetDynamicFlag: case SmartActions.SetDynamicFlag:
case SmartActions.AddDynamicFlag: case SmartActions.AddDynamicFlag:
@@ -1607,24 +1733,18 @@ namespace Game.AI
case SmartActions.SendTargetToTarget: case SmartActions.SendTargetToTarget:
case SmartActions.SetHomePos: case SmartActions.SetHomePos:
case SmartActions.SetHealthRegen: case SmartActions.SetHealthRegen:
case SmartActions.SetRoot:
case SmartActions.SetGoFlag: case SmartActions.SetGoFlag:
case SmartActions.AddGoFlag: case SmartActions.AddGoFlag:
case SmartActions.RemoveGoFlag: case SmartActions.RemoveGoFlag:
case SmartActions.SummonCreatureGroup: case SmartActions.SummonCreatureGroup:
case SmartActions.MoveOffset: case SmartActions.MoveOffset:
case SmartActions.SetCorpseDelay: case SmartActions.SetCorpseDelay:
case SmartActions.DisableEvade:
case SmartActions.SetSightDist: case SmartActions.SetSightDist:
case SmartActions.Flee: case SmartActions.Flee:
case SmartActions.AddThreat: case SmartActions.AddThreat:
case SmartActions.LoadEquipment:
case SmartActions.TriggerRandomTimedEvent: case SmartActions.TriggerRandomTimedEvent:
case SmartActions.SetCounter:
case SmartActions.RemoveAllGameobjects: case SmartActions.RemoveAllGameobjects:
case SmartActions.SpawnSpawngroup: case SmartActions.SpawnSpawngroup:
case SmartActions.DespawnSpawngroup:
case SmartActions.SetHover:
case SmartActions.AddToStoredTargetList: case SmartActions.AddToStoredTargetList:
break; break;
case SmartActions.BecomePersonalCloneForPlayer: case SmartActions.BecomePersonalCloneForPlayer:
@@ -1944,6 +2064,12 @@ namespace Game.AI
SmartEvents.SummonedUnitDies => SmartScriptTypeMaskId.Creature + SmartScriptTypeMaskId.Gameobject, SmartEvents.SummonedUnitDies => SmartScriptTypeMaskId.Creature + SmartScriptTypeMaskId.Gameobject,
_ => 0, _ => 0,
}; };
public static void TC_SAI_IS_BOOLEAN_VALID(SmartScriptHolder e, uint value, [CallerArgumentExpression("value")] string valueName = null)
{
if (value > 1)
Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} uses param {valueName} of type Boolean with value {value}, valid values are 0 or 1, skipped.");
}
} }
public class SmartScriptHolder : IComparer<SmartScriptHolder> public class SmartScriptHolder : IComparer<SmartScriptHolder>
@@ -3419,10 +3545,12 @@ namespace Game.AI
public struct ClosestAttackable public struct ClosestAttackable
{ {
public uint maxDist; public uint maxDist;
public uint playerOnly;
} }
public struct ClosestFriendly public struct ClosestFriendly
{ {
public uint maxDist; public uint maxDist;
public uint playerOnly;
} }
public struct Owner public struct Owner
{ {