Core/SAI: Added support for StringIds to creature and gameobject targets
Port From (https://github.com/TrinityCore/TrinityCore/commit/2ce40684595a0e49a7b2355012c2806952698ce4)
This commit is contained in:
@@ -244,16 +244,18 @@ namespace Game.AI
|
||||
temp.Action.raw.param5 = result.Read<uint>(20);
|
||||
temp.Action.raw.param6 = result.Read<uint>(21);
|
||||
temp.Action.raw.param7 = result.Read<uint>(22);
|
||||
temp.Action.param_string = result.Read<string>(23);
|
||||
|
||||
temp.Target.type = (SmartTargets)result.Read<byte>(23);
|
||||
temp.Target.raw.param1 = result.Read<uint>(24);
|
||||
temp.Target.raw.param2 = result.Read<uint>(25);
|
||||
temp.Target.raw.param3 = result.Read<uint>(26);
|
||||
temp.Target.raw.param4 = result.Read<uint>(27);
|
||||
temp.Target.x = result.Read<float>(28);
|
||||
temp.Target.y = result.Read<float>(29);
|
||||
temp.Target.z = result.Read<float>(30);
|
||||
temp.Target.o = result.Read<float>(31);
|
||||
temp.Target.type = (SmartTargets)result.Read<byte>(24);
|
||||
temp.Target.raw.param1 = result.Read<uint>(25);
|
||||
temp.Target.raw.param2 = result.Read<uint>(26);
|
||||
temp.Target.raw.param3 = result.Read<uint>(27);
|
||||
temp.Target.raw.param4 = result.Read<uint>(28);
|
||||
temp.Target.param_string = result.Read<string>(29);
|
||||
temp.Target.x = result.Read<float>(30);
|
||||
temp.Target.y = result.Read<float>(31);
|
||||
temp.Target.z = result.Read<float>(32);
|
||||
temp.Target.o = result.Read<float>(33);
|
||||
|
||||
//check target
|
||||
if (!IsTargetValid(temp))
|
||||
@@ -657,6 +659,22 @@ namespace Game.AI
|
||||
Log.outWarn(LogFilter.Sql, $"SmartAIMgr: {e} has unused event_param{index + 1} with value {value}, it should be 0.");
|
||||
}
|
||||
|
||||
bool eventUsesStringParam()
|
||||
{
|
||||
switch (e.GetEventType())
|
||||
{
|
||||
case SmartEvents.SceneTrigger:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eventUsesStringParam() && !e.Event.param_string.IsEmpty())
|
||||
Log.outWarn(LogFilter.Sql, $"SmartAIMgr: {e} has unused event_param_string with value {e.Event.param_string}, it should be NULL.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -834,6 +852,22 @@ namespace Game.AI
|
||||
Log.outWarn(LogFilter.Sql, $"SmartAIMgr: {e} has unused action_param{index + 1} with value {value}, it should be 0.");
|
||||
}
|
||||
|
||||
bool actionUsesStringParam()
|
||||
{
|
||||
switch (e.GetActionType())
|
||||
{
|
||||
case SmartActions.CrossCast:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
if (!actionUsesStringParam() && !e.Action.param_string.IsEmpty())
|
||||
Log.outWarn(LogFilter.Sql, $"SmartAIMgr: {e} has unused action_param_string with value {e.Action.param_string}, it should be NULL.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -901,6 +935,27 @@ namespace Game.AI
|
||||
Log.outWarn(LogFilter.Sql, $"SmartAIMgr: {e} has unused target_param{index + 1} with value {value}, it must be 0, skipped.");
|
||||
}
|
||||
|
||||
bool targetUsesStringParam()
|
||||
{
|
||||
switch (e.GetTargetType())
|
||||
{
|
||||
case SmartTargets.CreatureRange:
|
||||
case SmartTargets.CreatureDistance:
|
||||
case SmartTargets.GameobjectRange:
|
||||
case SmartTargets.GameobjectDistance:
|
||||
case SmartTargets.ClosestCreature:
|
||||
case SmartTargets.ClosestGameobject:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!targetUsesStringParam() && !e.Target.param_string.IsEmpty())
|
||||
Log.outWarn(LogFilter.Sql, $"SmartAIMgr: {e} has unused target_param_string with value {e.Target.param_string}, it should be NULL.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3172,6 +3227,9 @@ namespace Game.AI
|
||||
[FieldOffset(4)]
|
||||
public Raw raw;
|
||||
|
||||
[FieldOffset(32)]
|
||||
public string param_string;
|
||||
|
||||
#region Stucts
|
||||
public struct Talk
|
||||
{
|
||||
@@ -3241,6 +3299,7 @@ namespace Game.AI
|
||||
public uint targetParam1;
|
||||
public uint targetParam2;
|
||||
public uint targetParam3;
|
||||
public uint targetParam4;
|
||||
}
|
||||
public struct SummonCreature
|
||||
{
|
||||
@@ -3807,6 +3866,9 @@ namespace Game.AI
|
||||
[FieldOffset(20)]
|
||||
public Raw raw;
|
||||
|
||||
[FieldOffset(36)]
|
||||
public string param_string;
|
||||
|
||||
#region Structs
|
||||
public struct HostilRandom
|
||||
{
|
||||
|
||||
@@ -1575,7 +1575,7 @@ namespace Game.AI
|
||||
if (targets.Empty())
|
||||
break;
|
||||
|
||||
List<WorldObject> casters = GetTargets(CreateSmartEvent(SmartEvents.UpdateIc, 0, 0, 0, 0, 0, 0, SmartActions.None, 0, 0, 0, 0, 0, 0, 0, (SmartTargets)e.Action.crossCast.targetType, e.Action.crossCast.targetParam1, e.Action.crossCast.targetParam2, e.Action.crossCast.targetParam3, 0, 0), unit);
|
||||
List<WorldObject> casters = GetTargets(CreateSmartEvent(SmartEvents.UpdateIc, 0, 0, 0, 0, 0, 0, SmartActions.None, 0, 0, 0, 0, 0, 0, 0, (SmartTargets)e.Action.crossCast.targetType, e.Action.crossCast.targetParam1, e.Action.crossCast.targetParam2, e.Action.crossCast.targetParam3, e.Action.crossCast.targetParam4, e.Action.param_string, 0), unit);
|
||||
|
||||
CastSpellExtraArgs args = new();
|
||||
if (e.Action.crossCast.castFlags.HasAnyFlag((uint)SmartCastFlags.Triggered))
|
||||
@@ -2515,7 +2515,7 @@ namespace Game.AI
|
||||
|
||||
SmartScriptHolder CreateSmartEvent(SmartEvents e, SmartEventFlags event_flags, uint event_param1, uint event_param2, uint event_param3, uint event_param4, uint event_param5,
|
||||
SmartActions action, uint action_param1, uint action_param2, uint action_param3, uint action_param4, uint action_param5, uint action_param6, uint action_param7,
|
||||
SmartTargets t, uint target_param1, uint target_param2, uint target_param3, uint target_param4, uint phaseMask)
|
||||
SmartTargets t, uint target_param1, uint target_param2, uint target_param3, uint target_param4, string targetParamString, uint phaseMask)
|
||||
{
|
||||
SmartScriptHolder script = new();
|
||||
script.Event.type = e;
|
||||
@@ -2542,6 +2542,7 @@ namespace Game.AI
|
||||
script.Target.raw.param2 = target_param2;
|
||||
script.Target.raw.param3 = target_param3;
|
||||
script.Target.raw.param4 = target_param4;
|
||||
script.Target.param_string = targetParamString;
|
||||
|
||||
script.SourceType = SmartScriptType.Creature;
|
||||
InitTimer(script);
|
||||
@@ -2694,18 +2695,9 @@ namespace Game.AI
|
||||
break;
|
||||
}
|
||||
|
||||
List<WorldObject> units = GetWorldObjectsInDist(e.Target.unitRange.maxDist);
|
||||
foreach (var obj in units)
|
||||
{
|
||||
if (!IsCreature(obj))
|
||||
continue;
|
||||
|
||||
if (_me != null && _me == obj)
|
||||
continue;
|
||||
|
||||
if ((e.Target.unitRange.creature == 0 || obj.ToCreature().GetEntry() == e.Target.unitRange.creature) && refObj.IsInRange(obj, e.Target.unitRange.minDist, e.Target.unitRange.maxDist))
|
||||
targets.Add(obj);
|
||||
}
|
||||
List<Creature> creatures = refObj.GetCreatureListWithOptionsInGrid(e.Target.unitRange.maxDist,
|
||||
new FindCreatureOptions() { CreatureId = e.Target.unitRange.creature != 0 ? e.Target.unitRange.creature : null, StringId = !e.Target.param_string.IsEmpty() ? e.Target.param_string : null, });
|
||||
targets.AddRange(creatures.Where(target => !refObj.IsWithinDist(target, e.Target.unitRange.minDist)));
|
||||
|
||||
if (e.Target.unitRange.maxSize != 0)
|
||||
targets.RandomResize(e.Target.unitRange.maxSize);
|
||||
@@ -2713,42 +2705,19 @@ namespace Game.AI
|
||||
}
|
||||
case SmartTargets.CreatureDistance:
|
||||
{
|
||||
List<WorldObject> units = GetWorldObjectsInDist(e.Target.unitDistance.dist);
|
||||
foreach (var obj in units)
|
||||
{
|
||||
if (!IsCreature(obj))
|
||||
continue;
|
||||
if (baseObject == null)
|
||||
break;
|
||||
|
||||
if (_me != null && _me == obj)
|
||||
continue;
|
||||
List<Creature> creatures = baseObject.GetCreatureListWithOptionsInGrid(e.Target.unitDistance.dist,
|
||||
new FindCreatureOptions() { CreatureId = e.Target.unitDistance.creature != 0 ? e.Target.unitDistance.creature : null, StringId = !e.Target.param_string.IsEmpty() ? e.Target.param_string : null });
|
||||
|
||||
if (e.Target.unitDistance.creature == 0 || obj.ToCreature().GetEntry() == e.Target.unitDistance.creature)
|
||||
targets.Add(obj);
|
||||
}
|
||||
targets.Clear();
|
||||
targets.AddRange(creatures);
|
||||
|
||||
if (e.Target.unitDistance.maxSize != 0)
|
||||
targets.RandomResize(e.Target.unitDistance.maxSize);
|
||||
break;
|
||||
}
|
||||
case SmartTargets.GameobjectDistance:
|
||||
{
|
||||
List<WorldObject> units = GetWorldObjectsInDist(e.Target.goDistance.dist);
|
||||
foreach (var obj in units)
|
||||
{
|
||||
if (!IsGameObject(obj))
|
||||
continue;
|
||||
|
||||
if (_go != null && _go == obj)
|
||||
continue;
|
||||
|
||||
if (e.Target.goDistance.entry == 0 || obj.ToGameObject().GetEntry() == e.Target.goDistance.entry)
|
||||
targets.Add(obj);
|
||||
}
|
||||
|
||||
if (e.Target.goDistance.maxSize != 0)
|
||||
targets.RandomResize(e.Target.goDistance.maxSize);
|
||||
break;
|
||||
}
|
||||
case SmartTargets.GameobjectRange:
|
||||
{
|
||||
WorldObject refObj = baseObject;
|
||||
@@ -2761,23 +2730,29 @@ namespace Game.AI
|
||||
break;
|
||||
}
|
||||
|
||||
List<WorldObject> units = GetWorldObjectsInDist(e.Target.goRange.maxDist);
|
||||
foreach (var obj in units)
|
||||
{
|
||||
if (!IsGameObject(obj))
|
||||
continue;
|
||||
|
||||
if (_go != null && _go == obj)
|
||||
continue;
|
||||
|
||||
if ((e.Target.goRange.entry == 0 || obj.ToGameObject().GetEntry() == e.Target.goRange.entry) && refObj.IsInRange(obj, e.Target.goRange.minDist, e.Target.goRange.maxDist))
|
||||
targets.Add(obj);
|
||||
}
|
||||
List<GameObject> gameObjects = refObj.GetGameObjectListWithOptionsInGrid(e.Target.goRange.maxDist,
|
||||
new FindGameObjectOptions() { GameObjectId = e.Target.goRange.entry != 0 ? e.Target.goRange.entry : null, StringId = !e.Target.param_string.IsEmpty() ? e.Target.param_string : null });
|
||||
targets.AddRange(gameObjects.Where(target => !refObj.IsWithinDist(target, e.Target.goRange.minDist)));
|
||||
|
||||
if (e.Target.goRange.maxSize != 0)
|
||||
targets.RandomResize(e.Target.goRange.maxSize);
|
||||
break;
|
||||
}
|
||||
case SmartTargets.GameobjectDistance:
|
||||
{
|
||||
if (baseObject == null)
|
||||
break;
|
||||
|
||||
List<GameObject> gameObjects = baseObject.GetGameObjectListWithOptionsInGrid(e.Target.goDistance.dist,
|
||||
new FindGameObjectOptions() { GameObjectId = e.Target.goDistance.entry != 0 ? e.Target.goDistance.entry : null, StringId = !e.Target.param_string.IsEmpty() ? e.Target.param_string : null });
|
||||
|
||||
targets.Clear();
|
||||
targets.AddRange(gameObjects);
|
||||
|
||||
if (e.Target.goDistance.maxSize != 0)
|
||||
targets.RandomResize(e.Target.goDistance.maxSize);
|
||||
break;
|
||||
}
|
||||
case SmartTargets.CreatureGuid:
|
||||
{
|
||||
if (scriptTrigger == null && baseObject == null)
|
||||
@@ -2808,20 +2783,21 @@ namespace Game.AI
|
||||
}
|
||||
case SmartTargets.PlayerRange:
|
||||
{
|
||||
List<WorldObject> units = GetWorldObjectsInDist(e.Target.playerRange.maxDist);
|
||||
if (!units.Empty() && baseObject != null)
|
||||
foreach (var obj in units)
|
||||
if (IsPlayer(obj) && baseObject.IsInRange(obj, e.Target.playerRange.minDist, e.Target.playerRange.maxDist))
|
||||
targets.Add(obj);
|
||||
if (baseObject == null)
|
||||
break;
|
||||
|
||||
List<Player> players = baseObject.GetPlayerListInGrid(e.Target.playerRange.maxDist);
|
||||
targets.AddRange(players.Where(target => !baseObject.IsWithinDist(target, e.Target.playerRange.minDist)));
|
||||
|
||||
break;
|
||||
}
|
||||
case SmartTargets.PlayerDistance:
|
||||
{
|
||||
List<WorldObject> units = GetWorldObjectsInDist(e.Target.playerDistance.dist);
|
||||
foreach (var obj in units)
|
||||
if (IsPlayer(obj))
|
||||
targets.Add(obj);
|
||||
if (baseObject == null)
|
||||
break;
|
||||
|
||||
List<Player> players = baseObject.GetPlayerListInGrid(e.Target.playerDistance.dist);
|
||||
targets.AddRange(players);
|
||||
break;
|
||||
}
|
||||
case SmartTargets.Stored:
|
||||
@@ -2854,7 +2830,9 @@ namespace Game.AI
|
||||
break;
|
||||
}
|
||||
|
||||
Creature target = refObj.FindNearestCreature(e.Target.unitClosest.entry, e.Target.unitClosest.dist != 0 ? e.Target.unitClosest.dist : 100, e.Target.unitClosest.dead == 0);
|
||||
Creature target = refObj.FindNearestCreatureWithOptions(e.Target.unitClosest.dist != 0 ? e.Target.unitClosest.dist : 100,
|
||||
new FindCreatureOptions() { CreatureId = e.Target.unitClosest.entry, StringId = !e.Target.param_string.IsEmpty() ? e.Target.param_string : null, IsAlive = e.Target.unitClosest.dead == 0 });
|
||||
|
||||
if (target != null)
|
||||
targets.Add(target);
|
||||
break;
|
||||
@@ -2871,7 +2849,9 @@ namespace Game.AI
|
||||
break;
|
||||
}
|
||||
|
||||
GameObject target = refObj.FindNearestGameObject(e.Target.goClosest.entry, e.Target.goClosest.dist != 0 ? e.Target.goClosest.dist : 100);
|
||||
GameObject target = refObj.FindNearestGameObjectWithOptions(e.Target.goClosest.dist != 0 ? e.Target.goClosest.dist : 100,
|
||||
new FindGameObjectOptions() { GameObjectId = e.Target.goClosest.entry, StringId = !e.Target.param_string.IsEmpty() ? e.Target.param_string : null });
|
||||
|
||||
if (target != null)
|
||||
targets.Add(target);
|
||||
break;
|
||||
@@ -3010,19 +2990,6 @@ namespace Game.AI
|
||||
return targets;
|
||||
}
|
||||
|
||||
List<WorldObject> GetWorldObjectsInDist(float dist)
|
||||
{
|
||||
List<WorldObject> targets = new();
|
||||
WorldObject obj = GetBaseObject();
|
||||
if (obj == null)
|
||||
return targets;
|
||||
|
||||
var u_check = new AllWorldObjectsInRange(obj, dist);
|
||||
var searcher = new WorldObjectListSearcher(obj, targets, u_check);
|
||||
Cell.VisitAllObjects(obj, searcher, dist);
|
||||
return targets;
|
||||
}
|
||||
|
||||
void ProcessEvent(SmartScriptHolder e, Unit unit = null, uint var0 = 0, uint var1 = 0, bool bvar = false, SpellInfo spell = null, GameObject gob = null, string varString = "")
|
||||
{
|
||||
if (!e.Active && e.GetEventType() != SmartEvents.Link)
|
||||
|
||||
Reference in New Issue
Block a user