Core/SAI: Moved event_flags for difficulties to new field Difficulties

Port From (https://github.com/TrinityCore/TrinityCore/commit/b8ce70d528e2489832f4ffd8e6b35560937f6339)
This commit is contained in:
hondacrx
2024-02-02 14:32:13 -05:00
parent 52cd092335
commit 4e06ce4823
4 changed files with 86 additions and 70 deletions
+7 -6
View File
@@ -80,21 +80,22 @@ namespace Framework.Constants
Phase11Bit + Phase12Bit
}
[Flags]
public enum SmartEventFlags
{
NotRepeatable = 0x01, //Event can not repeat
Difficulty0 = 0x02, //Event only occurs in instance difficulty 0
Difficulty1 = 0x04, //Event only occurs in instance difficulty 1
Difficulty2 = 0x08, //Event only occurs in instance difficulty 2
Difficulty3 = 0x10, //Event only occurs in instance difficulty 3
Difficulty0_Deprecated = 0x02, //Event only occurs in instance difficulty 0
Difficulty1_Deprecated = 0x04, //Event only occurs in instance difficulty 1
Difficulty2_Deprecated = 0x08, //Event only occurs in instance difficulty 2
Difficulty3_Deprecated = 0x10, //Event only occurs in instance difficulty 3
Reserved5 = 0x20,
Reserved6 = 0x40,
DebugOnly = 0x80, //Event only occurs in debug build
DontReset = 0x100, //Event will not reset in SmartScript.OnReset()
WhileCharmed = 0x200, //Event occurs even if AI owner is charmed
DifficultyAll = (Difficulty0 | Difficulty1 | Difficulty2 | Difficulty3),
All = (NotRepeatable | DifficultyAll | Reserved5 | Reserved6 | DebugOnly | DontReset | WhileCharmed),
Deprecated = (Difficulty0_Deprecated | Difficulty1_Deprecated | Difficulty2_Deprecated | Difficulty3_Deprecated),
All = (NotRepeatable | Deprecated | Reserved5 | Reserved6 | DebugOnly | DontReset | WhileCharmed),
// Temp flags, used only at runtime, never stored in DB
TempIgnoreChanceRoll = 0x40000000, //Event occurs no matter what roll_chance_i(e.event.event_chance) returns.
@@ -11,7 +11,7 @@ namespace Framework.Database
PrepareStatement(WorldStatements.DEL_LINKED_RESPAWN_MASTER, "DELETE FROM linked_respawn WHERE linkedGuid = ? AND linkType = ?");
PrepareStatement(WorldStatements.REP_LINKED_RESPAWN, "REPLACE INTO linked_respawn (guid, linkedGuid, linkType) VALUES (?, ?, ?)");
PrepareStatement(WorldStatements.SEL_CREATURE_TEXT, "SELECT CreatureID, GroupID, ID, Text, Type, Language, Probability, Emote, Duration, Sound, SoundPlayType, BroadcastTextId, TextRange FROM creature_text");
PrepareStatement(WorldStatements.SEL_SMART_SCRIPTS, "SELECT entryorguid, source_type, id, link, event_type, event_phase_mask, event_chance, event_flags, event_param1, event_param2, event_param3, event_param4, event_param5, event_param_string, action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, action_param7, target_type, target_param1, target_param2, target_param3, target_param4, target_x, target_y, target_z, target_o FROM smart_scripts ORDER BY entryorguid, source_type, id, link");
PrepareStatement(WorldStatements.SEL_SMART_SCRIPTS, "SELECT entryorguid, source_type, id, link, Difficulties, event_type, event_phase_mask, event_chance, event_flags, event_param1, event_param2, event_param3, event_param4, event_param5, event_param_string, action_type, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, action_param7, target_type, target_param1, target_param2, target_param3, target_param4, target_x, target_y, target_z, target_o FROM smart_scripts ORDER BY entryorguid, source_type, id, link");
PrepareStatement(WorldStatements.DEL_GAMEOBJECT, "DELETE FROM gameobject WHERE guid = ?");
PrepareStatement(WorldStatements.DEL_EVENT_GAMEOBJECT, "DELETE FROM game_event_gameobject WHERE guid = ?");
PrepareStatement(WorldStatements.INS_GRAVEYARD_ZONE, "INSERT INTO graveyard_zone (ID, GhostZone) VALUES (?, ?)");
+64 -32
View File
@@ -1,6 +1,7 @@
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
using Framework.Collections;
using Framework.Constants;
using Framework.Database;
using Game.DataStorage;
@@ -55,7 +56,7 @@ namespace Game.AI
SmartScriptType source_type = (SmartScriptType)result.Read<byte>(1);
if (source_type >= SmartScriptType.Max)
{
Log.outError(LogFilter.Sql, "SmartAIMgr.LoadSmartAI: invalid source_type ({0}), skipped loading.", source_type);
Log.outError(LogFilter.Sql, "SmartAIMgr.LoadFromDB: invalid source_type ({0}), skipped loading.", source_type);
continue;
}
if (temp.EntryOrGuid >= 0)
@@ -65,7 +66,7 @@ namespace Game.AI
case SmartScriptType.Creature:
if (Global.ObjectMgr.GetCreatureTemplate((uint)temp.EntryOrGuid) == null)
{
Log.outError(LogFilter.Sql, "SmartAIMgr.LoadSmartAI: Creature entry ({0}) does not exist, skipped loading.", temp.EntryOrGuid);
Log.outError(LogFilter.Sql, "SmartAIMgr.LoadFromDB: Creature entry ({0}) does not exist, skipped loading.", temp.EntryOrGuid);
continue;
}
break;
@@ -74,7 +75,7 @@ namespace Game.AI
{
if (Global.ObjectMgr.GetGameObjectTemplate((uint)temp.EntryOrGuid) == null)
{
Log.outError(LogFilter.Sql, "SmartAIMgr.LoadSmartAI: GameObject entry ({0}) does not exist, skipped loading.", temp.EntryOrGuid);
Log.outError(LogFilter.Sql, "SmartAIMgr.LoadFromDB: GameObject entry ({0}) does not exist, skipped loading.", temp.EntryOrGuid);
continue;
}
break;
@@ -83,7 +84,7 @@ namespace Game.AI
{
if (CliDB.AreaTableStorage.LookupByKey((uint)temp.EntryOrGuid) == null)
{
Log.outError(LogFilter.Sql, "SmartAIMgr.LoadSmartAI: AreaTrigger entry ({0}) does not exist, skipped loading.", temp.EntryOrGuid);
Log.outError(LogFilter.Sql, "SmartAIMgr.LoadFromDB: AreaTrigger entry ({0}) does not exist, skipped loading.", temp.EntryOrGuid);
continue;
}
break;
@@ -101,7 +102,7 @@ namespace Game.AI
{
if (!Global.ObjectMgr.IsValidEvent((uint)temp.EntryOrGuid))
{
Log.outError(LogFilter.Sql, $"SmartAIMgr::LoadSmartAIFromDB: Event id ({temp.EntryOrGuid}) does not exist, skipped loading.");
Log.outError(LogFilter.Sql, $"SmartAIMgr::LoadFromDB: Event id ({temp.EntryOrGuid}) does not exist, skipped loading.");
continue;
}
break;
@@ -199,36 +200,60 @@ namespace Game.AI
temp.SourceType = source_type;
temp.EventId = result.Read<ushort>(2);
temp.Link = result.Read<ushort>(3);
temp.Event.type = (SmartEvents)result.Read<byte>(4);
temp.Event.event_phase_mask = result.Read<ushort>(5);
temp.Event.event_chance = result.Read<byte>(6);
temp.Event.event_flags = (SmartEventFlags)result.Read<ushort>(7);
temp.Event.raw.param1 = result.Read<uint>(8);
temp.Event.raw.param2 = result.Read<uint>(9);
temp.Event.raw.param3 = result.Read<uint>(10);
temp.Event.raw.param4 = result.Read<uint>(11);
temp.Event.raw.param5 = result.Read<uint>(12);
temp.Event.param_string = result.Read<string>(13);
bool invalidDifficulties = false;
foreach (string token in new StringArray(result.Read<string>(4), ' '))
{
if (!Enum.TryParse<Difficulty>(token, out Difficulty difficultyId))
{
invalidDifficulties = true;
Log.outError(LogFilter.Sql, $"SmartAIMgr::LoadFromDB: Invalid difficulties for entryorguid ({temp.EntryOrGuid}) source_type ({temp.GetScriptType()}) id ({temp.EventId}), skipped loading.");
break;
}
temp.Action.type = (SmartActions)result.Read<byte>(14);
temp.Action.raw.param1 = result.Read<uint>(15);
temp.Action.raw.param2 = result.Read<uint>(16);
temp.Action.raw.param3 = result.Read<uint>(17);
temp.Action.raw.param4 = result.Read<uint>(18);
temp.Action.raw.param5 = result.Read<uint>(19);
temp.Action.raw.param6 = result.Read<uint>(20);
temp.Action.raw.param7 = result.Read<uint>(21);
if (difficultyId != 0 && !CliDB.DifficultyStorage.ContainsKey(difficultyId))
{
invalidDifficulties = true;
Log.outError(LogFilter.Sql, $"SmartAIMgr::LoadFromDB: Invalid difficulty id ({difficultyId}) for entryorguid ({temp.EntryOrGuid}) source_type ({temp.GetScriptType()}) id ({temp.EventId}), skipped loading.");
break;
}
temp.Target.type = (SmartTargets)result.Read<byte>(22);
temp.Target.raw.param1 = result.Read<uint>(23);
temp.Target.raw.param2 = result.Read<uint>(24);
temp.Target.raw.param3 = result.Read<uint>(25);
temp.Target.raw.param4 = result.Read<uint>(26);
temp.Target.x = result.Read<float>(27);
temp.Target.y = result.Read<float>(28);
temp.Target.z = result.Read<float>(29);
temp.Target.o = result.Read<float>(30);
temp.Difficulties.Add(difficultyId);
}
if (invalidDifficulties)
continue;
temp.Event.type = (SmartEvents)result.Read<byte>(5);
temp.Event.event_phase_mask = result.Read<ushort>(6);
temp.Event.event_chance = result.Read<byte>(7);
temp.Event.event_flags = (SmartEventFlags)result.Read<ushort>(8);
temp.Event.raw.param1 = result.Read<uint>(9);
temp.Event.raw.param2 = result.Read<uint>(10);
temp.Event.raw.param3 = result.Read<uint>(11);
temp.Event.raw.param4 = result.Read<uint>(12);
temp.Event.raw.param5 = result.Read<uint>(13);
temp.Event.param_string = result.Read<string>(14);
temp.Action.type = (SmartActions)result.Read<byte>(15);
temp.Action.raw.param1 = result.Read<uint>(16);
temp.Action.raw.param2 = result.Read<uint>(17);
temp.Action.raw.param3 = result.Read<uint>(18);
temp.Action.raw.param4 = result.Read<uint>(19);
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.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);
//check target
if (!IsTargetValid(temp))
@@ -908,6 +933,11 @@ namespace Game.AI
Log.outError(LogFilter.ScriptsAi, "SmartAIMgr: EntryOrGuid {0} using event({1}) has invalid event flags ({2}), skipped.", e.EntryOrGuid, e.EventId, e.Event.event_flags);
return false;
}
if (e.Event.event_flags.HasFlag(SmartEventFlags.Deprecated))
{
Log.outError(LogFilter.Sql, $"SmartAIMgr: EntryOrGuid {e.EntryOrGuid} using event ({e.EventId}) has deprecated event flags ({e.Event.event_flags}), skipped.");
return false;
}
if (e.Link != 0 && e.Link == e.EventId)
{
Log.outError(LogFilter.Sql, "SmartAIMgr: EntryOrGuid {0} SourceType {1}, Event {2}, Event is linking self (infinite loop), skipped.", e.EntryOrGuid, e.GetScriptType(), e.EventId);
@@ -2434,6 +2464,8 @@ namespace Game.AI
public SmartScriptType SourceType;
public uint EventId;
public uint Link;
public List<Difficulty> Difficulties = new();
public SmartEvent Event;
public SmartAction Action;
public SmartTarget Target;
+14 -31
View File
@@ -3887,44 +3887,27 @@ namespace Game.AI
Log.outDebug(LogFilter.ScriptsAi, $"SmartScript: EventMap for Event {eventId} is empty but is using SmartScript.");
return;
}
foreach (var holder in e)
foreach (var scriptholder in e)
{
if (holder.Event.event_flags.HasAnyFlag(SmartEventFlags.DifficultyAll))//if has instance flag add only if in it
if (obj != null && !scriptholder.Difficulties.Empty())
{
if (!(obj != null && obj.GetMap().IsDungeon()))
continue;
// TODO: fix it for new maps and difficulties
switch (obj.GetMap().GetDifficultyID())
bool foundValidDifficulty = false;
foreach (Difficulty difficulty in scriptholder.Difficulties)
{
case Difficulty.Normal:
case Difficulty.Raid10N:
if (holder.Event.event_flags.HasAnyFlag(SmartEventFlags.Difficulty0))
_events.Add(holder);
if (difficulty == obj.GetMap().GetDifficultyID())
{
foundValidDifficulty = true;
break;
case Difficulty.Heroic:
case Difficulty.Raid25N:
if (holder.Event.event_flags.HasAnyFlag(SmartEventFlags.Difficulty1))
_events.Add(holder);
break;
case Difficulty.Raid10HC:
if (holder.Event.event_flags.HasAnyFlag(SmartEventFlags.Difficulty2))
_events.Add(holder);
break;
case Difficulty.Raid25HC:
if (holder.Event.event_flags.HasAnyFlag(SmartEventFlags.Difficulty3))
_events.Add(holder);
break;
default:
break;
}
}
if (!foundValidDifficulty)
continue;
}
_allEventFlags |= holder.Event.event_flags;
_events.Add(holder);//NOTE: 'world(0)' events still get processed in ANY instance mode
_allEventFlags |= scriptholder.Event.event_flags;
_events.Add(scriptholder);
}
}