Core/SAI: Implemented new action SMART_ACTION_COMPLETE_QUEST
Port From (https://github.com/TrinityCore/TrinityCore/commit/3429871a07c1c1ebe2bd94cb771ef187cb46fd46)
This commit is contained in:
@@ -251,7 +251,7 @@ namespace Framework.Constants
|
|||||||
SummonCreature = 12, // Creatureid, Summontype, Duration In Ms, Storageid, Attackinvoker, flags(SmartActionSummonCreatureFlags)
|
SummonCreature = 12, // Creatureid, Summontype, Duration In Ms, Storageid, Attackinvoker, flags(SmartActionSummonCreatureFlags)
|
||||||
ThreatSinglePct = 13, // Threat%
|
ThreatSinglePct = 13, // Threat%
|
||||||
ThreatAllPct = 14, // Threat%
|
ThreatAllPct = 14, // Threat%
|
||||||
CallAreaexploredoreventhappens = 15, // Questid
|
CallAreaexploredoreventhappens = 15, // UNUSED, DO NOT REUSE
|
||||||
SetIngamePhaseGroup = 16, // phaseGroupId, apply
|
SetIngamePhaseGroup = 16, // phaseGroupId, apply
|
||||||
SetEmoteState = 17, // Emoteid
|
SetEmoteState = 17, // Emoteid
|
||||||
SetUnitFlag = 18, // UNUSED, DO NOT REUSE
|
SetUnitFlag = 18, // UNUSED, DO NOT REUSE
|
||||||
@@ -262,7 +262,7 @@ namespace Framework.Constants
|
|||||||
IncEventPhase = 23, // Value (May Be Negative To Decrement Phase, Should Not Be 0)
|
IncEventPhase = 23, // Value (May Be Negative To Decrement Phase, Should Not Be 0)
|
||||||
Evade = 24, // No Params
|
Evade = 24, // No Params
|
||||||
FleeForAssist = 25, // With Emote
|
FleeForAssist = 25, // With Emote
|
||||||
CallGroupeventhappens = 26, // Questid
|
CallGroupeventhappens = 26, // UNUSED, DO NOT REUSE
|
||||||
CombatStop = 27, //
|
CombatStop = 27, //
|
||||||
RemoveAurasFromSpell = 28, // Spellid, 0 Removes All Auras
|
RemoveAurasFromSpell = 28, // Spellid, 0 Removes All Auras
|
||||||
Follow = 29, // Distance (0 = Default), Angle (0 = Default), Endcreatureentry, Credit, Credittype (0monsterkill, 1event)
|
Follow = 29, // Distance (0 = Default), Angle (0 = Default), Endcreatureentry, Credit, Credittype (0monsterkill, 1event)
|
||||||
@@ -388,6 +388,7 @@ namespace Framework.Constants
|
|||||||
BecomePersonalCloneForPlayer = 149, // summonType 1-8, duration in ms
|
BecomePersonalCloneForPlayer = 149, // summonType 1-8, duration in ms
|
||||||
TriggerGameEvent = 150, // eventId, useSaiTargetAsGameEventSource
|
TriggerGameEvent = 150, // eventId, useSaiTargetAsGameEventSource
|
||||||
DoAction = 151,
|
DoAction = 151,
|
||||||
|
CompleteQuest = 152, // QuestId. Regular quests with objectives can't be completed with this action (only quests with QUEST_FLAGS_COMPLETION_EVENT, QUEST_FLAGS_COMPLETION_AREA_TRIGGER or QUEST_FLAGS_TRACKING_EVENT)
|
||||||
End
|
End
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -284,7 +284,6 @@ namespace Game.AI
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SmartEvents.VictimCasting:
|
case SmartEvents.VictimCasting:
|
||||||
case SmartEvents.IsBehindTarget:
|
|
||||||
if (temp.Event.minMaxRepeat.min == 0 && temp.Event.minMaxRepeat.max == 0 && !temp.Event.event_flags.HasAnyFlag(SmartEventFlags.NotRepeatable) && temp.SourceType != SmartScriptType.TimedActionlist)
|
if (temp.Event.minMaxRepeat.min == 0 && temp.Event.minMaxRepeat.max == 0 && !temp.Event.event_flags.HasAnyFlag(SmartEventFlags.NotRepeatable) && temp.SourceType != SmartScriptType.TimedActionlist)
|
||||||
{
|
{
|
||||||
temp.Event.event_flags |= SmartEventFlags.NotRepeatable;
|
temp.Event.event_flags |= SmartEventFlags.NotRepeatable;
|
||||||
@@ -696,7 +695,6 @@ namespace Game.AI
|
|||||||
SmartActions.SummonCreature => Marshal.SizeOf(typeof(SmartAction.SummonCreature)),
|
SmartActions.SummonCreature => Marshal.SizeOf(typeof(SmartAction.SummonCreature)),
|
||||||
SmartActions.ThreatSinglePct => Marshal.SizeOf(typeof(SmartAction.ThreatPCT)),
|
SmartActions.ThreatSinglePct => Marshal.SizeOf(typeof(SmartAction.ThreatPCT)),
|
||||||
SmartActions.ThreatAllPct => Marshal.SizeOf(typeof(SmartAction.ThreatPCT)),
|
SmartActions.ThreatAllPct => Marshal.SizeOf(typeof(SmartAction.ThreatPCT)),
|
||||||
SmartActions.CallAreaexploredoreventhappens => Marshal.SizeOf(typeof(SmartAction.Quest)),
|
|
||||||
SmartActions.SetIngamePhaseGroup => Marshal.SizeOf(typeof(SmartAction.IngamePhaseGroup)),
|
SmartActions.SetIngamePhaseGroup => Marshal.SizeOf(typeof(SmartAction.IngamePhaseGroup)),
|
||||||
SmartActions.SetEmoteState => Marshal.SizeOf(typeof(SmartAction.Emote)),
|
SmartActions.SetEmoteState => Marshal.SizeOf(typeof(SmartAction.Emote)),
|
||||||
SmartActions.AutoAttack => Marshal.SizeOf(typeof(SmartAction.AutoAttack)),
|
SmartActions.AutoAttack => Marshal.SizeOf(typeof(SmartAction.AutoAttack)),
|
||||||
@@ -705,7 +703,6 @@ namespace Game.AI
|
|||||||
SmartActions.IncEventPhase => Marshal.SizeOf(typeof(SmartAction.IncEventPhase)),
|
SmartActions.IncEventPhase => Marshal.SizeOf(typeof(SmartAction.IncEventPhase)),
|
||||||
SmartActions.Evade => Marshal.SizeOf(typeof(SmartAction.Evade)),
|
SmartActions.Evade => Marshal.SizeOf(typeof(SmartAction.Evade)),
|
||||||
SmartActions.FleeForAssist => Marshal.SizeOf(typeof(SmartAction.FleeAssist)),
|
SmartActions.FleeForAssist => Marshal.SizeOf(typeof(SmartAction.FleeAssist)),
|
||||||
SmartActions.CallGroupeventhappens => Marshal.SizeOf(typeof(SmartAction.Quest)),
|
|
||||||
SmartActions.CombatStop => 0,
|
SmartActions.CombatStop => 0,
|
||||||
SmartActions.RemoveAurasFromSpell => Marshal.SizeOf(typeof(SmartAction.RemoveAura)),
|
SmartActions.RemoveAurasFromSpell => Marshal.SizeOf(typeof(SmartAction.RemoveAura)),
|
||||||
SmartActions.Follow => Marshal.SizeOf(typeof(SmartAction.Follow)),
|
SmartActions.Follow => Marshal.SizeOf(typeof(SmartAction.Follow)),
|
||||||
@@ -816,6 +813,7 @@ namespace Game.AI
|
|||||||
SmartActions.BecomePersonalCloneForPlayer => Marshal.SizeOf(typeof(SmartAction.BecomePersonalClone)),
|
SmartActions.BecomePersonalCloneForPlayer => Marshal.SizeOf(typeof(SmartAction.BecomePersonalClone)),
|
||||||
SmartActions.TriggerGameEvent => Marshal.SizeOf(typeof(SmartAction.TriggerGameEvent)),
|
SmartActions.TriggerGameEvent => Marshal.SizeOf(typeof(SmartAction.TriggerGameEvent)),
|
||||||
SmartActions.DoAction => Marshal.SizeOf(typeof(SmartAction.DoAction)),
|
SmartActions.DoAction => Marshal.SizeOf(typeof(SmartAction.DoAction)),
|
||||||
|
SmartActions.CompleteQuest => Marshal.SizeOf(typeof(SmartAction.Quest)),
|
||||||
_ => Marshal.SizeOf(typeof(SmartAction.Raw)),
|
_ => Marshal.SizeOf(typeof(SmartAction.Raw)),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1572,23 +1570,6 @@ namespace Game.AI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SmartActions.CallAreaexploredoreventhappens:
|
|
||||||
case SmartActions.CallGroupeventhappens:
|
|
||||||
Quest qid = Global.ObjectMgr.GetQuestTemplate(e.Action.quest.questId);
|
|
||||||
if (qid != null)
|
|
||||||
{
|
|
||||||
if (!qid.HasFlag(QuestFlags.CompletionEvent) && !qid.HasFlag(QuestFlags.CompletionAreaTrigger))
|
|
||||||
{
|
|
||||||
Log.outError(LogFilter.ScriptsAi, $"SmartAIMgr: {e} Flags for Quest entry {e.Action.quest.questId} does not include QUEST_FLAGS_COMPLETION_EVENT or QUEST_FLAGS_COMPLETION_AREA_TRIGGER, skipped.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.outError(LogFilter.ScriptsAi, $"SmartAIMgr: {e} uses non-existent Quest entry {e.Action.quest.questId}, skipped.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SmartActions.SetEventPhase:
|
case SmartActions.SetEventPhase:
|
||||||
if (e.Action.setEventPhase.phase >= (uint)SmartPhase.Max)
|
if (e.Action.setEventPhase.phase >= (uint)SmartPhase.Max)
|
||||||
{
|
{
|
||||||
@@ -2215,7 +2196,25 @@ namespace Game.AI
|
|||||||
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.triggerGameEvent.useSaiTargetAsGameEventSource);
|
TC_SAI_IS_BOOLEAN_VALID(e, e.Action.triggerGameEvent.useSaiTargetAsGameEventSource);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SmartActions.CompleteQuest:
|
||||||
|
Quest quest = Global.ObjectMgr.GetQuestTemplate(e.Action.quest.questId);
|
||||||
|
if (quest != null)
|
||||||
|
{
|
||||||
|
if (!quest.HasFlag(QuestFlags.CompletionEvent) && !quest.HasFlag(QuestFlags.CompletionAreaTrigger) && !quest.HasFlag(QuestFlags.TrackingEvent))
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} Flags for Quest entry {e.Action.quest.questId} does not include QUEST_FLAGS_COMPLETION_EVENT or QUEST_FLAGS_COMPLETION_AREA_TRIGGER or QUEST_FLAGS_TRACKING_EVENT, skipped.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Sql, $"SmartAIMgr: {e} uses non-existent Quest entry {e.Action.quest.questId}, skipped.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
// No longer supported
|
// No longer supported
|
||||||
|
case SmartActions.CallAreaexploredoreventhappens:
|
||||||
|
case SmartActions.CallGroupeventhappens:
|
||||||
case SmartActions.SetUnitFlag:
|
case SmartActions.SetUnitFlag:
|
||||||
case SmartActions.RemoveUnitFlag:
|
case SmartActions.RemoveUnitFlag:
|
||||||
case SmartActions.InstallAITemplate:
|
case SmartActions.InstallAITemplate:
|
||||||
|
|||||||
@@ -413,34 +413,6 @@ namespace Game.AI
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SmartActions.CallAreaexploredoreventhappens:
|
|
||||||
{
|
|
||||||
foreach (var target in targets)
|
|
||||||
{
|
|
||||||
// Special handling for vehicles
|
|
||||||
if (IsUnit(target))
|
|
||||||
{
|
|
||||||
Vehicle vehicle = target.ToUnit().GetVehicleKit();
|
|
||||||
if (vehicle != null)
|
|
||||||
{
|
|
||||||
foreach (var seat in vehicle.Seats)
|
|
||||||
{
|
|
||||||
Player player = Global.ObjAccessor.GetPlayer(target, seat.Value.Passenger.Guid);
|
|
||||||
if (player != null)
|
|
||||||
player.AreaExploredOrEventHappens(e.Action.quest.questId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsPlayer(target))
|
|
||||||
{
|
|
||||||
target.ToPlayer().AreaExploredOrEventHappens(e.Action.quest.questId);
|
|
||||||
Log.outDebug(LogFilter.ScriptsAi, "SmartScript.ProcessAction. SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: {0} credited quest {1}",
|
|
||||||
target.GetGUID().ToString(), e.Action.quest.questId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SmartActions.Cast:
|
case SmartActions.Cast:
|
||||||
{
|
{
|
||||||
if (targets.Empty())
|
if (targets.Empty())
|
||||||
@@ -714,33 +686,6 @@ namespace Game.AI
|
|||||||
Log.outDebug(LogFilter.ScriptsAi, "SmartScript.ProcessAction. SMART_ACTION_FLEE_FOR_ASSIST: Creature {0} DoFleeToGetAssistance", _me.GetGUID().ToString());
|
Log.outDebug(LogFilter.ScriptsAi, "SmartScript.ProcessAction. SMART_ACTION_FLEE_FOR_ASSIST: Creature {0} DoFleeToGetAssistance", _me.GetGUID().ToString());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SmartActions.CallGroupeventhappens:
|
|
||||||
{
|
|
||||||
if (unit == null)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// If invoker was pet or charm
|
|
||||||
Player playerCharmed = unit.GetCharmerOrOwnerPlayerOrPlayerItself();
|
|
||||||
if (playerCharmed != null && GetBaseObject() != null)
|
|
||||||
{
|
|
||||||
playerCharmed.GroupEventHappens(e.Action.quest.questId, GetBaseObject());
|
|
||||||
Log.outDebug(LogFilter.ScriptsAi, "SmartScript.ProcessAction: SMART_ACTION_CALL_GROUPEVENTHAPPENS: Player {0}, group credit for quest {1}",
|
|
||||||
unit.GetGUID().ToString(), e.Action.quest.questId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special handling for vehicles
|
|
||||||
Vehicle vehicle = unit.GetVehicleKit();
|
|
||||||
if (vehicle != null)
|
|
||||||
{
|
|
||||||
foreach (var seat in vehicle.Seats)
|
|
||||||
{
|
|
||||||
Player passenger = Global.ObjAccessor.GetPlayer(unit, seat.Value.Passenger.Guid);
|
|
||||||
if (passenger != null)
|
|
||||||
passenger.GroupEventHappens(e.Action.quest.questId, GetBaseObject());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SmartActions.CombatStop:
|
case SmartActions.CombatStop:
|
||||||
{
|
{
|
||||||
if (_me == null)
|
if (_me == null)
|
||||||
@@ -2586,6 +2531,34 @@ namespace Game.AI
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SmartActions.CompleteQuest:
|
||||||
|
{
|
||||||
|
uint questId = e.Action.quest.questId;
|
||||||
|
Quest quest = Global.ObjectMgr.GetQuestTemplate(questId);
|
||||||
|
if (quest == null)
|
||||||
|
break;
|
||||||
|
|
||||||
|
foreach (WorldObject target in targets)
|
||||||
|
{
|
||||||
|
Player player = target?.ToPlayer();
|
||||||
|
if (player == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QuestStatus questStatus = player.GetQuestStatus(questId);
|
||||||
|
if (questStatus == QuestStatus.Rewarded)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (quest.HasFlag(QuestFlags.CompletionEvent) || quest.HasFlag(QuestFlags.CompletionAreaTrigger))
|
||||||
|
{
|
||||||
|
if (questStatus == QuestStatus.Incomplete)
|
||||||
|
player.AreaExploredOrEventHappens(questId);
|
||||||
|
}
|
||||||
|
else if (quest.HasFlag(QuestFlags.TrackingEvent)) // Check if the quest is used as a serverside flag
|
||||||
|
player.CompleteQuest(questId);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|||||||
@@ -3374,11 +3374,17 @@ namespace Game.Spells
|
|||||||
if (quest == null)
|
if (quest == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ushort logSlot = player.FindQuestSlot(questId);
|
QuestStatus questStatus = player.GetQuestStatus(questId);
|
||||||
if (logSlot < SharedConst.MaxQuestLogSize)
|
if (questStatus == QuestStatus.Rewarded)
|
||||||
player.AreaExploredOrEventHappens(questId);
|
return;
|
||||||
else if (quest.HasFlag(QuestFlags.TrackingEvent)) // Check if the quest is used as a serverside flag.
|
|
||||||
player.SetRewardedQuest(questId); // If so, set status to rewarded without broadcasting it to client.
|
if (quest.HasFlag(QuestFlags.CompletionEvent) || quest.HasFlag(QuestFlags.CompletionAreaTrigger))
|
||||||
|
{
|
||||||
|
if (questStatus == QuestStatus.Incomplete)
|
||||||
|
player.AreaExploredOrEventHappens(questId);
|
||||||
|
}
|
||||||
|
else if (quest.HasFlag(QuestFlags.TrackingEvent)) // Check if the quest is used as a serverside flag
|
||||||
|
player.CompleteQuest(questId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user