Core/SAI: Implement quest source for SAI

Port From (https://github.com/TrinityCore/TrinityCore/commit/1b4c4d216478c57a562247815dfba0e5d2c9f192)
This commit is contained in:
hondacrx
2021-03-08 14:17:23 -05:00
parent ee97dc7b32
commit 8ada9c99e7
4 changed files with 100 additions and 41 deletions
+22 -8
View File
@@ -101,11 +101,11 @@ namespace Game.AI
} }
break; break;
} }
case SmartScriptType.Spell: case SmartScriptType.Quest:
{ {
if (!Global.SpellMgr.HasSpellInfo((uint)temp.entryOrGuid, Difficulty.None)) if (Global.ObjectMgr.GetQuestTemplate((uint)temp.entryOrGuid) == null)
{ {
Log.outError(LogFilter.Sql, "SmartAIMgr.LoadSmartAIFromDB: Scene id ({0}) does not exist, skipped loading.", temp.entryOrGuid); Log.outError(LogFilter.Sql, $"SmartAIMgr.LoadSmartAIFromDB: Quest id ({temp.entryOrGuid}) does not exist, skipped loading.");
continue; continue;
} }
break; break;
@@ -817,6 +817,18 @@ namespace Game.AI
return false; return false;
} }
break; break;
case SmartEvents.QuestObjCompletion:
if (Global.ObjectMgr.GetQuestObjective(e.Event.questObjective.id) == null)
{
Log.outError(LogFilter.Sql, $"SmartAIMgr: Event SMART_EVENT_QUEST_OBJ_COPLETETION using invalid objective id {e.Event.questObjective.id}, skipped.");
return false;
}
break;
case SmartEvents.QuestAccepted:
case SmartEvents.QuestCompletion:
case SmartEvents.QuestFail:
case SmartEvents.QuestRewarded:
break;
case SmartEvents.Link: case SmartEvents.Link:
case SmartEvents.GoLootStateChanged: case SmartEvents.GoLootStateChanged:
case SmartEvents.GoEventInform: case SmartEvents.GoEventInform:
@@ -834,11 +846,6 @@ namespace Game.AI
case SmartEvents.Evade: case SmartEvents.Evade:
case SmartEvents.ReachedHome: case SmartEvents.ReachedHome:
case SmartEvents.Reset: case SmartEvents.Reset:
case SmartEvents.QuestAccepted:
case SmartEvents.QuestObjCompletion:
case SmartEvents.QuestCompletion:
case SmartEvents.QuestRewarded:
case SmartEvents.QuestFail:
case SmartEvents.JustSummoned: case SmartEvents.JustSummoned:
case SmartEvents.WaypointStart: case SmartEvents.WaypointStart:
case SmartEvents.WaypointReached: case SmartEvents.WaypointReached:
@@ -1823,6 +1830,9 @@ namespace Game.AI
[FieldOffset(16)] [FieldOffset(16)]
public Quest quest; public Quest quest;
[FieldOffset(16)]
public QuestObjective questObjective;
[FieldOffset(16)] [FieldOffset(16)]
public Emote emote; public Emote emote;
@@ -1987,6 +1997,10 @@ namespace Game.AI
{ {
public uint questId; public uint questId;
} }
public struct QuestObjective
{
public uint id;
}
public struct Emote public struct Emote
{ {
public uint emoteId; public uint emoteId;
+35 -32
View File
@@ -2879,12 +2879,6 @@ namespace Game.AI
} }
break; break;
} }
case SmartTargets.SpellTarget:
{
if (spellTemplate != null)
targets.Add(spellTemplate.m_targets.GetUnitTarget());
break;
}
case SmartTargets.Position: case SmartTargets.Position:
default: default:
break; break;
@@ -3077,6 +3071,20 @@ namespace Game.AI
ProcessAction(e, unit, var0, var1, bvar, spell, gob); ProcessAction(e, unit, var0, var1, bvar, spell, gob);
break; break;
} }
case SmartEvents.QuestAccepted:
case SmartEvents.QuestCompletion:
case SmartEvents.QuestFail:
case SmartEvents.QuestRewarded:
{
ProcessAction(e, unit);
break;
}
case SmartEvents.QuestObjCompletion:
{
if (var0 == (e.Event.questObjective.id))
ProcessAction(e, unit);
break;
}
//no params //no params
case SmartEvents.Aggro: case SmartEvents.Aggro:
case SmartEvents.Death: case SmartEvents.Death:
@@ -3087,11 +3095,6 @@ namespace Game.AI
case SmartEvents.AiInit: case SmartEvents.AiInit:
case SmartEvents.TransportAddplayer: case SmartEvents.TransportAddplayer:
case SmartEvents.TransportRemovePlayer: case SmartEvents.TransportRemovePlayer:
case SmartEvents.QuestAccepted:
case SmartEvents.QuestObjCompletion:
case SmartEvents.QuestCompletion:
case SmartEvents.QuestRewarded:
case SmartEvents.QuestFail:
case SmartEvents.JustSummoned: case SmartEvents.JustSummoned:
case SmartEvents.Reset: case SmartEvents.Reset:
case SmartEvents.JustCreated: case SmartEvents.JustCreated:
@@ -3694,18 +3697,18 @@ namespace Game.AI
} }
} }
void FillScript(List<SmartScriptHolder> e, WorldObject obj, AreaTriggerRecord at, SceneTemplate scene, Spell spell = null) void FillScript(List<SmartScriptHolder> e, WorldObject obj, AreaTriggerRecord at, SceneTemplate scene, Quest quest)
{ {
if (e.Empty()) if (e.Empty())
{ {
if (obj != null) if (obj != null)
Log.outDebug(LogFilter.ScriptsAi, "SmartScript: EventMap for Entry {0} is empty but is using SmartScript.", obj.GetEntry()); Log.outDebug(LogFilter.ScriptsAi, $"SmartScript: EventMap for Entry {obj.GetEntry()} is empty but is using SmartScript.");
if (at != null) if (at != null)
Log.outDebug(LogFilter.ScriptsAi, "SmartScript: EventMap for AreaTrigger {0} is empty but is using SmartScript.", at.Id); Log.outDebug(LogFilter.ScriptsAi, $"SmartScript: EventMap for AreaTrigger {at.Id} is empty but is using SmartScript.");
if (scene != null) if (scene != null)
Log.outDebug(LogFilter.ScriptsAi, "SmartScript: EventMap for SceneId {0} is empty but is using SmartScript.", scene.SceneId); Log.outDebug(LogFilter.ScriptsAi, $"SmartScript: EventMap for SceneId {scene.SceneId} is empty but is using SmartScript.");
if (spell != null) if (quest != null)
Log.outDebug(LogFilter.ScriptsAi, "SmartScript: EventMap for SpellId {0} is empty but is using SmartScript.", spell.GetSpellInfo().Id); Log.outDebug(LogFilter.ScriptsAi, $"SmartScript: EventMap for Quest {quest.Id} is empty but is using SmartScript.");
return; return;
} }
foreach (var holder in e) foreach (var holder in e)
@@ -3753,34 +3756,34 @@ namespace Game.AI
e = Global.SmartAIMgr.GetScript(-((int)me.GetSpawnId()), mScriptType); e = Global.SmartAIMgr.GetScript(-((int)me.GetSpawnId()), mScriptType);
if (e.Empty()) if (e.Empty())
e = Global.SmartAIMgr.GetScript((int)me.GetEntry(), mScriptType); e = Global.SmartAIMgr.GetScript((int)me.GetEntry(), mScriptType);
FillScript(e, me, null, null); FillScript(e, me, null, null, null);
} }
else if (go != null) else if (go != null)
{ {
e = Global.SmartAIMgr.GetScript(-((int)go.GetSpawnId()), mScriptType); e = Global.SmartAIMgr.GetScript(-((int)go.GetSpawnId()), mScriptType);
if (e.Empty()) if (e.Empty())
e = Global.SmartAIMgr.GetScript((int)go.GetEntry(), mScriptType); e = Global.SmartAIMgr.GetScript((int)go.GetEntry(), mScriptType);
FillScript(e, go, null, null); FillScript(e, go, null, null, null);
} }
else if (trigger != null) else if (trigger != null)
{ {
e = Global.SmartAIMgr.GetScript((int)trigger.Id, mScriptType); e = Global.SmartAIMgr.GetScript((int)trigger.Id, mScriptType);
FillScript(e, null, trigger, null); FillScript(e, null, trigger, null, null);
} }
else if (areaTrigger != null) else if (areaTrigger != null)
{ {
e = Global.SmartAIMgr.GetScript((int)areaTrigger.GetEntry(), mScriptType); e = Global.SmartAIMgr.GetScript((int)areaTrigger.GetEntry(), mScriptType);
FillScript(e, areaTrigger, null, null); FillScript(e, areaTrigger, null, null, null);
} }
else if (sceneTemplate != null) else if (sceneTemplate != null)
{ {
e = Global.SmartAIMgr.GetScript((int)sceneTemplate.SceneId, mScriptType); e = Global.SmartAIMgr.GetScript((int)sceneTemplate.SceneId, mScriptType);
FillScript(e, null, null, sceneTemplate); FillScript(e, null, null, sceneTemplate, null);
} }
else if (spellTemplate != null) else if (quest != null)
{ {
e = Global.SmartAIMgr.GetScript((int)spellTemplate.GetSpellInfo().Id, mScriptType); e = Global.SmartAIMgr.GetScript((int)quest.Id, mScriptType);
FillScript(e, null, null, null, spellTemplate); FillScript(e, null, null, null, quest);
} }
} }
@@ -3870,17 +3873,17 @@ namespace Game.AI
InstallEvents(); InstallEvents();
} }
public void OnInitialize(Spell spell) public void OnInitialize(Quest qst)
{ {
if (spell != null) if (qst != null)
{ {
mScriptType = SmartScriptType.Spell; mScriptType = SmartScriptType.Quest;
spellTemplate = spell; quest = qst;
Log.outDebug(LogFilter.ScriptsAi, "SmartScript.OnInitialize: Spell id {0}", spell.GetSpellInfo().Id); Log.outDebug(LogFilter.ScriptsAi, $"SmartScript.OnInitialize: source is Quest with id {qst.Id}");
} }
else else
{ {
Log.outError(LogFilter.ScriptsAi, "SmartScript.OnInitialize: !WARNING! Initialized Spell is Null."); Log.outError(LogFilter.ScriptsAi, "SmartScript.OnInitialize: !WARNING! Initialized quest is Null.");
return; return;
} }
@@ -4207,7 +4210,7 @@ namespace Game.AI
AreaTriggerRecord trigger; AreaTriggerRecord trigger;
AreaTrigger areaTrigger; AreaTrigger areaTrigger;
SceneTemplate sceneTemplate; SceneTemplate sceneTemplate;
Spell spellTemplate; Quest quest;
SmartScriptType mScriptType; SmartScriptType mScriptType;
uint mEventPhase; uint mEventPhase;
+1 -1
View File
@@ -780,7 +780,7 @@ namespace Game.Scripting
public virtual void OnSceneComplete(Player player, uint sceneInstanceID, SceneTemplate sceneTemplate) { } public virtual void OnSceneComplete(Player player, uint sceneInstanceID, SceneTemplate sceneTemplate) { }
} }
class QuestScript : ScriptObject public class QuestScript : ScriptObject
{ {
public QuestScript(string name) : base(name) public QuestScript(string name) : base(name)
{ {
+42
View File
@@ -86,4 +86,46 @@ namespace Scripts.Smart
smartScript.ProcessEventsFor(SmartEvents.SceneComplete, player); smartScript.ProcessEventsFor(SmartEvents.SceneComplete, player);
} }
} }
[Script]
class SmartQuest : QuestScript
{
public SmartQuest() : base("SmartQuest") { }
// Called when a quest status change
public override void OnQuestStatusChange(Player player, Quest quest, QuestStatus oldStatus, QuestStatus newStatus)
{
SmartScript smartScript = new SmartScript();
smartScript.OnInitialize(quest);
switch (newStatus)
{
case QuestStatus.Incomplete:
smartScript.ProcessEventsFor(SmartEvents.QuestAccepted, player);
break;
case QuestStatus.Complete:
smartScript.ProcessEventsFor(SmartEvents.QuestCompletion, player);
break;
case QuestStatus.Failed:
smartScript.ProcessEventsFor(SmartEvents.QuestFail, player);
break;
case QuestStatus.Rewarded:
smartScript.ProcessEventsFor(SmartEvents.QuestRewarded, player);
break;
case QuestStatus.None:
default:
break;
}
}
// Called when a quest objective data change
public override void OnQuestObjectiveChange(Player player, Quest quest, QuestObjective objective, int oldAmount, int newAmount)
{
if (player.IsQuestObjectiveComplete(objective))
{
SmartScript smartScript = new SmartScript();
smartScript.OnInitialize(quest);
smartScript.ProcessEventsFor(SmartEvents.QuestObjCompletion, player, objective.Id);
}
}
}
} }