Core/SAI: Add SMART_ACTION_BECOME_PERSONAL_CLONE_FOR_PLAYER
Port From (https://github.com/TrinityCore/TrinityCore/commit/f383c0ea214cc4da2d02b81e26297d77ff59c7ed)
This commit is contained in:
@@ -397,6 +397,7 @@ namespace Framework.Constants
|
|||||||
SetUninteractible = 146, // 0/1
|
SetUninteractible = 146, // 0/1
|
||||||
ActivateGameobject = 147, // GameObjectActions
|
ActivateGameobject = 147, // GameObjectActions
|
||||||
AddToStoredTargetList = 148, // varID
|
AddToStoredTargetList = 148, // varID
|
||||||
|
BecomePersonalCloneForPlayer = 149, // summonType 1-8, duration in ms
|
||||||
End
|
End
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -925,9 +925,9 @@ namespace Game.AI
|
|||||||
GetScript().ProcessEventsFor(SmartEvents.FollowCompleted, player);
|
GetScript().ProcessEventsFor(SmartEvents.FollowCompleted, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTimedActionList(SmartScriptHolder e, uint entry, Unit invoker)
|
public void SetTimedActionList(SmartScriptHolder e, uint entry, Unit invoker, uint startFromEventId = 0)
|
||||||
{
|
{
|
||||||
GetScript().SetTimedActionList(e, entry, invoker);
|
GetScript().SetTimedActionList(e, entry, invoker, startFromEventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnGameEvent(bool start, ushort eventId)
|
public override void OnGameEvent(bool start, ushort eventId)
|
||||||
|
|||||||
@@ -1588,6 +1588,15 @@ namespace Game.AI
|
|||||||
case SmartActions.DespawnSpawngroup:
|
case SmartActions.DespawnSpawngroup:
|
||||||
case SmartActions.AddToStoredTargetList:
|
case SmartActions.AddToStoredTargetList:
|
||||||
break;
|
break;
|
||||||
|
case SmartActions.BecomePersonalCloneForPlayer:
|
||||||
|
{
|
||||||
|
if (e.Action.becomePersonalClone.type < (uint)TempSummonType.TimedOrDeadDespawn || e.Action.becomePersonalClone.type > (uint)TempSummonType.ManualDespawn)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} uses incorrect TempSummonType {e.Action.becomePersonalClone.type}, skipped.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
Log.outError(LogFilter.ScriptsAi, "SmartAIMgr: Not handled action_type({0}), event_type({1}), Entry {2} SourceType {3} Event {4}, skipped.", e.GetActionType(), e.GetEventType(), e.EntryOrGuid, e.GetScriptType(), e.EventId);
|
Log.outError(LogFilter.ScriptsAi, "SmartAIMgr: Not handled action_type({0}), event_type({1}), Entry {2} SourceType {3} Event {4}, skipped.", e.GetActionType(), e.GetEventType(), e.EntryOrGuid, e.GetScriptType(), e.EventId);
|
||||||
return false;
|
return false;
|
||||||
@@ -2619,6 +2628,9 @@ namespace Game.AI
|
|||||||
[FieldOffset(4)]
|
[FieldOffset(4)]
|
||||||
public AddToStoredTargets addToStoredTargets;
|
public AddToStoredTargets addToStoredTargets;
|
||||||
|
|
||||||
|
[FieldOffset(4)]
|
||||||
|
public BecomePersonalClone becomePersonalClone;
|
||||||
|
|
||||||
[FieldOffset(4)]
|
[FieldOffset(4)]
|
||||||
public Raw raw;
|
public Raw raw;
|
||||||
|
|
||||||
@@ -3162,6 +3174,11 @@ namespace Game.AI
|
|||||||
{
|
{
|
||||||
public uint id;
|
public uint id;
|
||||||
}
|
}
|
||||||
|
public struct BecomePersonalClone
|
||||||
|
{
|
||||||
|
public uint type;
|
||||||
|
public uint duration;
|
||||||
|
}
|
||||||
public struct Raw
|
public struct Raw
|
||||||
{
|
{
|
||||||
public uint param1;
|
public uint param1;
|
||||||
|
|||||||
@@ -2466,6 +2466,27 @@ namespace Game.AI
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SmartActions.BecomePersonalCloneForPlayer:
|
||||||
|
{
|
||||||
|
foreach (WorldObject target in targets)
|
||||||
|
{
|
||||||
|
if (!IsPlayer(target))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ObjectGuid privateObjectOwner = target.GetGUID();
|
||||||
|
Creature summon = GetBaseObject().SummonPersonalClone((TempSummonType)e.Action.becomePersonalClone.type, e.Action.becomePersonalClone.duration, 0, 0, privateObjectOwner);
|
||||||
|
if (summon != null)
|
||||||
|
{
|
||||||
|
if (IsSmart(summon))
|
||||||
|
((SmartAI)summon.GetAI()).SetTimedActionList(e, (uint)e.EntryOrGuid, target.ToUnit(), e.EventId + 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// action list will continue on personal clones
|
||||||
|
_timedActionList.RemoveAll(script => { return script.EventId > e.EventId; });
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
Log.outError(LogFilter.Sql, "SmartScript.ProcessAction: Entry {0} SourceType {1}, Event {2}, Unhandled Action type {3}", e.EntryOrGuid, e.GetScriptType(), e.EventId, e.GetActionType());
|
Log.outError(LogFilter.Sql, "SmartScript.ProcessAction: Entry {0} SourceType {1}, Event {2}, Unhandled Action type {3}", e.EntryOrGuid, e.GetScriptType(), e.EventId, e.GetActionType());
|
||||||
break;
|
break;
|
||||||
@@ -3879,15 +3900,17 @@ namespace Game.AI
|
|||||||
bool needCleanup = true;
|
bool needCleanup = true;
|
||||||
if (!_timedActionList.Empty())
|
if (!_timedActionList.Empty())
|
||||||
{
|
{
|
||||||
foreach (var holder in _timedActionList)
|
for (int i = 0; i < _timedActionList.Count; ++i)
|
||||||
{
|
{
|
||||||
if (holder.EnableTimed)
|
SmartScriptHolder scriptHolder = _timedActionList[i];
|
||||||
|
if (scriptHolder.EnableTimed)
|
||||||
{
|
{
|
||||||
UpdateTimer(holder, diff);
|
UpdateTimer(scriptHolder, diff);
|
||||||
needCleanup = false;
|
needCleanup = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needCleanup)
|
if (needCleanup)
|
||||||
_timedActionList.Clear();
|
_timedActionList.Clear();
|
||||||
|
|
||||||
@@ -4129,7 +4152,7 @@ namespace Game.AI
|
|||||||
return searcher.GetTarget();
|
return searcher.GetTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTimedActionList(SmartScriptHolder e, uint entry, Unit invoker)
|
public void SetTimedActionList(SmartScriptHolder e, uint entry, Unit invoker, uint startFromEventId = 0)
|
||||||
{
|
{
|
||||||
// Do NOT allow to start a new actionlist if a previous one is already running, unless explicitly allowed. We need to always finish the current actionlist
|
// Do NOT allow to start a new actionlist if a previous one is already running, unless explicitly allowed. We need to always finish the current actionlist
|
||||||
if (e.Action.timedActionList.allowOverride == 0 && !_timedActionList.Empty())
|
if (e.Action.timedActionList.allowOverride == 0 && !_timedActionList.Empty())
|
||||||
@@ -4140,6 +4163,8 @@ namespace Game.AI
|
|||||||
if (_timedActionList.Empty())
|
if (_timedActionList.Empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
_timedActionList.RemoveAll(script => { return script.EventId < startFromEventId; });
|
||||||
|
|
||||||
mTimedActionListInvoker = invoker != null ? invoker.GetGUID() : ObjectGuid.Empty;
|
mTimedActionListInvoker = invoker != null ? invoker.GetGUID() : ObjectGuid.Empty;
|
||||||
for (var i = 0; i < _timedActionList.Count; ++i)
|
for (var i = 0; i < _timedActionList.Count; ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1442,6 +1442,22 @@ namespace Game.Entities
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TempSummon SummonPersonalClone(TempSummonType despawnType = TempSummonType.ManualDespawn, uint despawnTime = 0, uint vehId = 0, uint spellId = 0, ObjectGuid privateObjectOwner = default)
|
||||||
|
{
|
||||||
|
Map map = GetMap();
|
||||||
|
if (map != null)
|
||||||
|
{
|
||||||
|
TempSummon summon = map.SummonCreature(GetEntry(), GetPosition(), null, despawnTime, this, spellId, vehId, privateObjectOwner);
|
||||||
|
if (summon != null)
|
||||||
|
{
|
||||||
|
summon.SetTempSummonType(despawnType);
|
||||||
|
return summon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public GameObject SummonGameObject(uint entry, float x, float y, float z, float ang, Quaternion rotation, uint respawnTime, GameObjectSummonType summonType = GameObjectSummonType.TimedOrCorpseDespawn)
|
public GameObject SummonGameObject(uint entry, float x, float y, float z, float ang, Quaternion rotation, uint respawnTime, GameObjectSummonType summonType = GameObjectSummonType.TimedOrCorpseDespawn)
|
||||||
{
|
{
|
||||||
if (x == 0 && y == 0 && z == 0)
|
if (x == 0 && y == 0 && z == 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user