Core/SAI: Add storedTargetId param to summon actions
Port From (https://github.com/TrinityCore/TrinityCore/commit/80437d3c79853c27ffa60b1988d1459586d18cbb)
This commit is contained in:
@@ -136,8 +136,9 @@ namespace Framework.Constants
|
|||||||
None = 0,
|
None = 0,
|
||||||
PersonalSpawn = 1,
|
PersonalSpawn = 1,
|
||||||
PreferUnit = 2,
|
PreferUnit = 2,
|
||||||
|
AttackInvoker = 4,
|
||||||
|
|
||||||
All = PersonalSpawn | PreferUnit,
|
All = PersonalSpawn | PreferUnit | AttackInvoker,
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SmartEvents
|
public enum SmartEvents
|
||||||
@@ -249,7 +250,7 @@ namespace Framework.Constants
|
|||||||
ActivateGobject = 9, //
|
ActivateGobject = 9, //
|
||||||
RandomEmote = 10, // Emoteid1, Emoteid2, Emoteid3...
|
RandomEmote = 10, // Emoteid1, Emoteid2, Emoteid3...
|
||||||
Cast = 11, // Spellid, Castflags, TriggeredFlags
|
Cast = 11, // Spellid, Castflags, TriggeredFlags
|
||||||
SummonCreature = 12, // Creatureid, Summontype, Duration In Ms, Storageid, Attackinvoker, flags(SmartActionSummonCreatureFlags)
|
SummonCreature = 12, // reatureID, summonType, duration in ms, stored target id, flags(SmartActionSummonCreatureFlags), count, createdBySpell
|
||||||
ThreatSinglePct = 13, // Threat%
|
ThreatSinglePct = 13, // Threat%
|
||||||
ThreatAllPct = 14, // Threat%
|
ThreatAllPct = 14, // Threat%
|
||||||
CallAreaexploredoreventhappens = 15, // UNUSED, DO NOT REUSE
|
CallAreaexploredoreventhappens = 15, // UNUSED, DO NOT REUSE
|
||||||
@@ -287,7 +288,7 @@ namespace Framework.Constants
|
|||||||
SetVisibility = 47, // On/Off
|
SetVisibility = 47, // On/Off
|
||||||
SetActive = 48, // No Params
|
SetActive = 48, // No Params
|
||||||
AttackStart = 49, //
|
AttackStart = 49, //
|
||||||
SummonGo = 50, // Gameobjectid, Despawntime In Ms,
|
SummonGo = 50, // GameObjectID, DespawnTime in s, summon type, stored target id
|
||||||
KillUnit = 51, //
|
KillUnit = 51, //
|
||||||
ActivateTaxi = 52, // Taxiid
|
ActivateTaxi = 52, // Taxiid
|
||||||
WpStart = 53, // Run/Walk, Pathid, Canrepeat, Quest, Despawntime
|
WpStart = 53, // Run/Walk, Pathid, Canrepeat, Quest, Despawntime
|
||||||
@@ -344,7 +345,7 @@ namespace Framework.Constants
|
|||||||
SetGoFlag = 104, // UNUSED, DO NOT REUSE
|
SetGoFlag = 104, // UNUSED, DO NOT REUSE
|
||||||
AddGoFlag = 105, // UNUSED, DO NOT REUSE
|
AddGoFlag = 105, // UNUSED, DO NOT REUSE
|
||||||
RemoveGoFlag = 106, // UNUSED, DO NOT REUSE
|
RemoveGoFlag = 106, // UNUSED, DO NOT REUSE
|
||||||
SummonCreatureGroup = 107, // Group, Attackinvoker
|
SummonCreatureGroup = 107, // Group, attackInvoker, stored target id
|
||||||
SetPower = 108, // PowerType, newPower
|
SetPower = 108, // PowerType, newPower
|
||||||
AddPower = 109, // PowerType, newPower
|
AddPower = 109, // PowerType, newPower
|
||||||
RemovePower = 110, // PowerType, newPower
|
RemovePower = 110, // PowerType, newPower
|
||||||
|
|||||||
@@ -1633,7 +1633,22 @@ namespace Game.AI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.summonCreature.attackInvoker);
|
if (e.Action.summonCreature.createdBySpell != 0)
|
||||||
|
{
|
||||||
|
if (!IsSpellValid(e, e.Action.summonCreature.createdBySpell))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool propertiesFound = Global.SpellMgr.GetSpellInfo(e.Action.summonCreature.createdBySpell, Difficulty.None).GetEffects().Any(spellEffectInfo =>
|
||||||
|
{
|
||||||
|
return spellEffectInfo.IsEffect(SpellEffectName.Summon) && CliDB.SummonPropertiesStorage.HasRecord((uint)spellEffectInfo.MiscValueB);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!propertiesFound)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} Spell {e.Action.summonCreature.createdBySpell} is not a summon creature spell.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SmartActions.CallKilledmonster:
|
case SmartActions.CallKilledmonster:
|
||||||
if (!IsCreatureValid(e, e.Action.killedMonster.creature))
|
if (!IsCreatureValid(e, e.Action.killedMonster.creature))
|
||||||
@@ -3376,10 +3391,10 @@ namespace Game.AI
|
|||||||
public uint creature;
|
public uint creature;
|
||||||
public uint type;
|
public uint type;
|
||||||
public uint duration;
|
public uint duration;
|
||||||
public uint storageID;
|
public uint storedTargetId;
|
||||||
public uint attackInvoker;
|
|
||||||
public uint flags; // SmartActionSummonCreatureFlags
|
public uint flags; // SmartActionSummonCreatureFlags
|
||||||
public uint count;
|
public uint count;
|
||||||
|
public uint createdBySpell;
|
||||||
}
|
}
|
||||||
public struct ThreatPCT
|
public struct ThreatPCT
|
||||||
{
|
{
|
||||||
@@ -3512,6 +3527,7 @@ namespace Game.AI
|
|||||||
public uint entry;
|
public uint entry;
|
||||||
public uint despawnTime;
|
public uint despawnTime;
|
||||||
public uint summonType;
|
public uint summonType;
|
||||||
|
public uint storedTargetId;
|
||||||
}
|
}
|
||||||
public struct Active
|
public struct Active
|
||||||
{
|
{
|
||||||
@@ -3686,6 +3702,7 @@ namespace Game.AI
|
|||||||
{
|
{
|
||||||
public uint group;
|
public uint group;
|
||||||
public uint attackInvoker;
|
public uint attackInvoker;
|
||||||
|
public uint storedTargetId;
|
||||||
}
|
}
|
||||||
public struct Power
|
public struct Power
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1129,6 +1129,8 @@ namespace Game.AI
|
|||||||
{
|
{
|
||||||
SmartActionSummonCreatureFlags flags = (SmartActionSummonCreatureFlags)e.Action.summonCreature.flags;
|
SmartActionSummonCreatureFlags flags = (SmartActionSummonCreatureFlags)e.Action.summonCreature.flags;
|
||||||
bool preferUnit = flags.HasAnyFlag(SmartActionSummonCreatureFlags.PreferUnit);
|
bool preferUnit = flags.HasAnyFlag(SmartActionSummonCreatureFlags.PreferUnit);
|
||||||
|
bool attackInvoker = flags.HasFlag(SmartActionSummonCreatureFlags.AttackInvoker);
|
||||||
|
|
||||||
WorldObject summoner = preferUnit ? unit : GetBaseObjectOrUnitInvoker(unit);
|
WorldObject summoner = preferUnit ? unit : GetBaseObjectOrUnitInvoker(unit);
|
||||||
if (summoner == null)
|
if (summoner == null)
|
||||||
break;
|
break;
|
||||||
@@ -1138,6 +1140,44 @@ namespace Game.AI
|
|||||||
privateObjectOwner = summoner.IsPrivateObject() ? summoner.GetPrivateObjectOwner() : summoner.GetGUID();
|
privateObjectOwner = summoner.IsPrivateObject() ? summoner.GetPrivateObjectOwner() : summoner.GetGUID();
|
||||||
uint spawnsCount = Math.Max(e.Action.summonCreature.count, 1u);
|
uint spawnsCount = Math.Max(e.Action.summonCreature.count, 1u);
|
||||||
|
|
||||||
|
if (e.Action.summonCreature.storedTargetId != 0)
|
||||||
|
ClearTargetList(e.Action.summonCreature.storedTargetId);
|
||||||
|
|
||||||
|
SummonPropertiesRecord summonProperties()
|
||||||
|
{
|
||||||
|
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(e.Action.summonCreature.createdBySpell, Difficulty.None);
|
||||||
|
if (spellInfo != null)
|
||||||
|
{
|
||||||
|
foreach (SpellEffectInfo spellEffectInfo in spellInfo.GetEffects())
|
||||||
|
{
|
||||||
|
if (spellEffectInfo.IsEffect(SpellEffectName.Summon))
|
||||||
|
{
|
||||||
|
var summonProps = CliDB.SummonPropertiesStorage.LookupByKey(spellEffectInfo.MiscValueB);
|
||||||
|
if (summonProps != null)
|
||||||
|
return summonProps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoSummon(float x, float y, float z, float o, Unit attackTarget)
|
||||||
|
{
|
||||||
|
for (uint counter = 0; counter < spawnsCount; counter++)
|
||||||
|
{
|
||||||
|
TempSummon summon = summoner.GetMap().SummonCreature(e.Action.summonCreature.creature, new Position(x, y, z, o), summonProperties(), TimeSpan.FromMilliseconds(e.Action.summonCreature.duration), summoner, e.Action.summonCreature.createdBySpell, 0, privateObjectOwner);
|
||||||
|
if (summon != null)
|
||||||
|
{
|
||||||
|
summon.SetTempSummonType((TempSummonType)e.Action.summonCreature.type);
|
||||||
|
if (e.Action.summonCreature.storedTargetId != 0)
|
||||||
|
AddToStoredTargetList([summon], e.Action.summonCreature.storedTargetId);
|
||||||
|
if (attackInvoker && attackTarget != null)
|
||||||
|
summon.GetAI().AttackStart(attackTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float x, y, z, o;
|
float x, y, z, o;
|
||||||
foreach (var target in targets)
|
foreach (var target in targets)
|
||||||
{
|
{
|
||||||
@@ -1146,25 +1186,13 @@ namespace Game.AI
|
|||||||
y += e.Target.y;
|
y += e.Target.y;
|
||||||
z += e.Target.z;
|
z += e.Target.z;
|
||||||
o += e.Target.o;
|
o += e.Target.o;
|
||||||
for (uint counter = 0; counter < spawnsCount; counter++)
|
DoSummon(x, y, z, o, target.ToUnit());
|
||||||
{
|
|
||||||
Creature summon = summoner.SummonCreature(e.Action.summonCreature.creature, x, y, z, o, (TempSummonType)e.Action.summonCreature.type, TimeSpan.FromMilliseconds(e.Action.summonCreature.duration), privateObjectOwner);
|
|
||||||
if (summon != null)
|
|
||||||
if (e.Action.summonCreature.attackInvoker != 0)
|
|
||||||
summon.GetAI().AttackStart(target.ToUnit());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.GetTargetType() != SmartTargets.Position)
|
if (e.GetTargetType() != SmartTargets.Position)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (uint counter = 0; counter < spawnsCount; counter++)
|
DoSummon(e.Target.x, e.Target.y, e.Target.z, e.Target.o, unit);
|
||||||
{
|
|
||||||
Creature summon = summoner.SummonCreature(e.Action.summonCreature.creature, e.Target.x, e.Target.y, e.Target.z, e.Target.o, (TempSummonType)e.Action.summonCreature.type, TimeSpan.FromMilliseconds(e.Action.summonCreature.duration), privateObjectOwner);
|
|
||||||
if (summon != null)
|
|
||||||
if (unit != null && e.Action.summonCreature.attackInvoker != 0)
|
|
||||||
summon.GetAI().AttackStart(unit);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SmartActions.SummonGo:
|
case SmartActions.SummonGo:
|
||||||
@@ -1173,18 +1201,25 @@ namespace Game.AI
|
|||||||
if (summoner == null)
|
if (summoner == null)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (e.Action.summonGO.storedTargetId != 0)
|
||||||
|
ClearTargetList(e.Action.summonGO.storedTargetId);
|
||||||
|
|
||||||
foreach (var target in targets)
|
foreach (var target in targets)
|
||||||
{
|
{
|
||||||
Position pos = target.GetPositionWithOffset(new Position(e.Target.x, e.Target.y, e.Target.z, e.Target.o));
|
Position pos = target.GetPositionWithOffset(new Position(e.Target.x, e.Target.y, e.Target.z, e.Target.o));
|
||||||
Quaternion rot = Quaternion.CreateFromRotationMatrix(Extensions.fromEulerAnglesZYX(pos.GetOrientation(), 0f, 0f));
|
Quaternion rot = Quaternion.CreateFromRotationMatrix(Extensions.fromEulerAnglesZYX(pos.GetOrientation(), 0f, 0f));
|
||||||
summoner.SummonGameObject(e.Action.summonGO.entry, pos, rot, TimeSpan.FromSeconds(e.Action.summonGO.despawnTime), (GameObjectSummonType)e.Action.summonGO.summonType);
|
GameObject summon = summoner.SummonGameObject(e.Action.summonGO.entry, pos, rot, TimeSpan.FromSeconds(e.Action.summonGO.despawnTime), (GameObjectSummonType)e.Action.summonGO.summonType);
|
||||||
|
if (e.Action.summonGO.storedTargetId != 0 && summon != null)
|
||||||
|
AddToStoredTargetList([summon], e.Action.summonGO.storedTargetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.GetTargetType() != SmartTargets.Position)
|
if (e.GetTargetType() != SmartTargets.Position)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Quaternion _rot = Quaternion.CreateFromRotationMatrix(Extensions.fromEulerAnglesZYX(e.Target.o, 0f, 0f));
|
Quaternion rot1 = Quaternion.CreateFromRotationMatrix(Extensions.fromEulerAnglesZYX(e.Target.o, 0f, 0f));
|
||||||
summoner.SummonGameObject(e.Action.summonGO.entry, new Position(e.Target.x, e.Target.y, e.Target.z, e.Target.o), _rot, TimeSpan.FromSeconds(e.Action.summonGO.despawnTime), (GameObjectSummonType)e.Action.summonGO.summonType);
|
GameObject summon1 = summoner.SummonGameObject(e.Action.summonGO.entry, new Position(e.Target.x, e.Target.y, e.Target.z, e.Target.o), rot1, TimeSpan.FromSeconds(e.Action.summonGO.despawnTime), (GameObjectSummonType)e.Action.summonGO.summonType);
|
||||||
|
if (e.Action.summonGO.storedTargetId != 0 && summon1 != null)
|
||||||
|
AddToStoredTargetList([summon1], e.Action.summonGO.storedTargetId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SmartActions.KillUnit:
|
case SmartActions.KillUnit:
|
||||||
@@ -1946,7 +1981,7 @@ namespace Game.AI
|
|||||||
{
|
{
|
||||||
SmartAI ai = (SmartAI)creatureTarget.GetAI();
|
SmartAI ai = (SmartAI)creatureTarget.GetAI();
|
||||||
if (ai != null)
|
if (ai != null)
|
||||||
ai.GetScript().StoreTargetList(new List<WorldObject>(storedTargets), e.Action.sendTargetToTarget.id); // store a copy of target list
|
ai.GetScript().StoreTargetList(storedTargets, e.Action.sendTargetToTarget.id); // store a copy of target list
|
||||||
else
|
else
|
||||||
Log.outError(LogFilter.Sql, "SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartAI, skipping");
|
Log.outError(LogFilter.Sql, "SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartAI, skipping");
|
||||||
}
|
}
|
||||||
@@ -1957,7 +1992,7 @@ namespace Game.AI
|
|||||||
{
|
{
|
||||||
SmartGameObjectAI ai = (SmartGameObjectAI)gameObject.GetAI();
|
SmartGameObjectAI ai = (SmartGameObjectAI)gameObject.GetAI();
|
||||||
if (ai != null)
|
if (ai != null)
|
||||||
ai.GetScript().StoreTargetList(new List<WorldObject>(storedTargets), e.Action.sendTargetToTarget.id); // store a copy of target list
|
ai.GetScript().StoreTargetList(storedTargets, e.Action.sendTargetToTarget.id); // store a copy of target list
|
||||||
else
|
else
|
||||||
Log.outError(LogFilter.Sql, "SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartGameObjectAI, skipping");
|
Log.outError(LogFilter.Sql, "SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartGameObjectAI, skipping");
|
||||||
}
|
}
|
||||||
@@ -2052,6 +2087,9 @@ namespace Game.AI
|
|||||||
foreach (var summon in summonList)
|
foreach (var summon in summonList)
|
||||||
if (unit == null && e.Action.creatureGroup.attackInvoker != 0)
|
if (unit == null && e.Action.creatureGroup.attackInvoker != 0)
|
||||||
summon.GetAI().AttackStart(unit);
|
summon.GetAI().AttackStart(unit);
|
||||||
|
|
||||||
|
if (e.Action.creatureGroup.storedTargetId != 0)
|
||||||
|
StoreTargetList(summonList.Cast<WorldObject>().ToList(), e.Action.creatureGroup.storedTargetId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SmartActions.SetPower:
|
case SmartActions.SetPower:
|
||||||
@@ -4442,6 +4480,11 @@ namespace Game.AI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearTargetList(uint id)
|
||||||
|
{
|
||||||
|
_storedTargets.Remove(id);
|
||||||
|
}
|
||||||
|
|
||||||
void StoreTargetList(List<WorldObject> targets, uint id)
|
void StoreTargetList(List<WorldObject> targets, uint id)
|
||||||
{
|
{
|
||||||
// insert or replace
|
// insert or replace
|
||||||
|
|||||||
Reference in New Issue
Block a user