aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/WorldDatabase.cpp2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp38
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp103
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h28
4 files changed, 97 insertions, 74 deletions
diff --git a/src/server/database/Database/Implementation/WorldDatabase.cpp b/src/server/database/Database/Implementation/WorldDatabase.cpp
index 4b262d914a0..1a5275f0a13 100644
--- a/src/server/database/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/database/Database/Implementation/WorldDatabase.cpp
@@ -27,7 +27,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_DEL_LINKED_RESPAWN_MASTER, "DELETE FROM linked_respawn WHERE linkedGuid = ? AND linkType = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_REP_LINKED_RESPAWN, "REPLACE INTO linked_respawn (guid, linkedGuid, linkType) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_CREATURE_TEXT, "SELECT CreatureID, GroupID, ID, Text, Type, Language, Probability, Emote, Duration, Sound, SoundPlayType, BroadcastTextId, TextRange FROM creature_text", CONNECTION_SYNCH);
- PrepareStatement(WORLD_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", CONNECTION_SYNCH);
+ PrepareStatement(WORLD_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", CONNECTION_SYNCH);
PrepareStatement(WORLD_DEL_GAMEOBJECT, "DELETE FROM gameobject WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_DEL_EVENT_GAMEOBJECT, "DELETE FROM game_event_gameobject WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_INS_GRAVEYARD_ZONE, "INSERT INTO graveyard_zone (ID, GhostZone) VALUES (?, ?)", CONNECTION_ASYNC);
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 561ec21655f..9433a4b8761 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -3934,38 +3934,24 @@ void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEn
continue;
#endif
- if (scriptholder.event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_ALL)//if has instance flag add only if in it
+ if (obj && scriptholder.Difficulties.size())
{
- if (!(obj && obj->GetMap()->IsDungeon()))
- continue;
-
- // TODO: fix it for new maps and difficulties
- switch (obj->GetMap()->GetDifficultyID())
+ bool foundValidDifficulty = false;
+ for (Difficulty difficulty : scriptholder.Difficulties)
{
- case DIFFICULTY_NORMAL:
- case DIFFICULTY_10_N:
- if (!(scriptholder.event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_0))
- continue;
- break;
- case DIFFICULTY_HEROIC:
- case DIFFICULTY_25_N:
- if (!(scriptholder.event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_1))
- continue;
- break;
- case DIFFICULTY_10_HC:
- if (!(scriptholder.event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_2))
- continue;
- break;
- case DIFFICULTY_25_HC:
- if (!(scriptholder.event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_3))
- continue;
- break;
- default:
+ if (difficulty == obj->GetMap()->GetDifficultyID())
+ {
+ foundValidDifficulty = true;
break;
+ }
}
+
+ if (!foundValidDifficulty)
+ continue;
}
+
mAllEventFlags |= scriptholder.event.event_flags;
- mEvents.push_back(scriptholder);//NOTE: 'world(0)' events still get processed in ANY instance mode
+ mEvents.push_back(scriptholder);
}
}
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index 5ab032a1ac6..10c3914d9a7 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -30,6 +30,7 @@
#include "ObjectMgr.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
+#include "StringConvert.h"
#include "Timer.h"
#include "UnitDefines.h"
#include "Util.h"
@@ -248,37 +249,65 @@ void SmartAIMgr::LoadSmartAIFromDB()
temp.source_type = source_type;
temp.event_id = fields[2].GetUInt16();
temp.link = fields[3].GetUInt16();
- temp.event.type = (SMART_EVENT)fields[4].GetUInt8();
- temp.event.event_phase_mask = fields[5].GetUInt16();
- temp.event.event_chance = fields[6].GetUInt8();
- temp.event.event_flags = fields[7].GetUInt16();
-
- temp.event.raw.param1 = fields[8].GetUInt32();
- temp.event.raw.param2 = fields[9].GetUInt32();
- temp.event.raw.param3 = fields[10].GetUInt32();
- temp.event.raw.param4 = fields[11].GetUInt32();
- temp.event.raw.param5 = fields[12].GetUInt32();
-
- temp.event.param_string = fields[13].GetString();
-
- temp.action.type = (SMART_ACTION)fields[14].GetUInt8();
- temp.action.raw.param1 = fields[15].GetUInt32();
- temp.action.raw.param2 = fields[16].GetUInt32();
- temp.action.raw.param3 = fields[17].GetUInt32();
- temp.action.raw.param4 = fields[18].GetUInt32();
- temp.action.raw.param5 = fields[19].GetUInt32();
- temp.action.raw.param6 = fields[20].GetUInt32();
- temp.action.raw.param7 = fields[21].GetUInt32();
-
- temp.target.type = (SMARTAI_TARGETS)fields[22].GetUInt8();
- temp.target.raw.param1 = fields[23].GetUInt32();
- temp.target.raw.param2 = fields[24].GetUInt32();
- temp.target.raw.param3 = fields[25].GetUInt32();
- temp.target.raw.param4 = fields[26].GetUInt32();
- temp.target.x = fields[27].GetFloat();
- temp.target.y = fields[28].GetFloat();
- temp.target.z = fields[29].GetFloat();
- temp.target.o = fields[30].GetFloat();
+
+ bool invalidDifficulties = false;
+ for (std::string_view token : Trinity::Tokenize(fields[4].GetStringView(), ',', false))
+ {
+ std::optional<std::underlying_type_t<Difficulty>> tokenValue = Trinity::StringTo<std::underlying_type_t<Difficulty>>(token);
+ if (!tokenValue.has_value())
+ {
+ invalidDifficulties = true;
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Invalid difficulties for entryorguid ({}) source_type ({}) id ({}), skipped loading.",
+ temp.entryOrGuid, temp.GetScriptType(), temp.event_id);
+ break;
+ }
+
+ Difficulty difficultyId = Difficulty(tokenValue.value());
+ if (difficultyId && !sDifficultyStore.LookupEntry(difficultyId))
+ {
+ invalidDifficulties = true;
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Invalid difficulty id ({}) for entryorguid ({}) source_type ({}) id ({}), skipped loading.",
+ difficultyId, temp.entryOrGuid, temp.GetScriptType(), temp.event_id);
+ break;
+ }
+
+ temp.Difficulties.push_back(difficultyId);
+ }
+
+ if (invalidDifficulties)
+ continue;
+
+ temp.event.type = (SMART_EVENT)fields[5].GetUInt8();
+ temp.event.event_phase_mask = fields[6].GetUInt16();
+ temp.event.event_chance = fields[7].GetUInt8();
+ temp.event.event_flags = fields[8].GetUInt16();
+
+ temp.event.raw.param1 = fields[9].GetUInt32();
+ temp.event.raw.param2 = fields[10].GetUInt32();
+ temp.event.raw.param3 = fields[11].GetUInt32();
+ temp.event.raw.param4 = fields[12].GetUInt32();
+ temp.event.raw.param5 = fields[13].GetUInt32();
+
+ temp.event.param_string = fields[14].GetString();
+
+ temp.action.type = (SMART_ACTION)fields[15].GetUInt8();
+ temp.action.raw.param1 = fields[16].GetUInt32();
+ temp.action.raw.param2 = fields[17].GetUInt32();
+ temp.action.raw.param3 = fields[18].GetUInt32();
+ temp.action.raw.param4 = fields[19].GetUInt32();
+ temp.action.raw.param5 = fields[20].GetUInt32();
+ temp.action.raw.param6 = fields[21].GetUInt32();
+ temp.action.raw.param7 = fields[22].GetUInt32();
+
+ temp.target.type = (SMARTAI_TARGETS)fields[23].GetUInt8();
+ temp.target.raw.param1 = fields[24].GetUInt32();
+ temp.target.raw.param2 = fields[25].GetUInt32();
+ temp.target.raw.param3 = fields[26].GetUInt32();
+ temp.target.raw.param4 = fields[27].GetUInt32();
+ temp.target.x = fields[28].GetFloat();
+ temp.target.y = fields[29].GetFloat();
+ temp.target.z = fields[30].GetFloat();
+ temp.target.o = fields[31].GetFloat();
//check target
if (!IsTargetValid(temp))
@@ -1079,19 +1108,25 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
if (e.action.type <= 0 || e.action.type >= SMART_ACTION_END)
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid {} using event({}) has invalid action type ({}), skipped.", e.entryOrGuid, e.event_id, e.GetActionType());
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid {} using event ({}) has invalid action type ({}), skipped.", e.entryOrGuid, e.event_id, e.GetActionType());
return false;
}
if (e.event.event_phase_mask > SMART_EVENT_PHASE_ALL)
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid {} using event({}) has invalid phase mask ({}), skipped.", e.entryOrGuid, e.event_id, e.event.event_phase_mask);
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid {} using event ({}) has invalid phase mask ({}), skipped.", e.entryOrGuid, e.event_id, e.event.event_phase_mask);
return false;
}
if (e.event.event_flags > SMART_EVENT_FLAGS_ALL)
{
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid {} using event({}) has invalid event flags ({}), skipped.", e.entryOrGuid, e.event_id, e.event.event_flags);
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid {} using event ({}) has invalid event flags ({}), skipped.", e.entryOrGuid, e.event_id, e.event.event_flags);
+ return false;
+ }
+
+ if (e.event.event_flags & SMART_EVENT_FLAGS_DEPRECATED)
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid {} using event ({}) has deprecated event flags ({}), skipped.", e.entryOrGuid, e.event_id, e.event.event_flags);
return false;
}
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 966b5fd2b0f..0409ec84385 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -18,6 +18,7 @@
#ifndef TRINITY_SMARTSCRIPTMGR_H
#define TRINITY_SMARTSCRIPTMGR_H
+#include "DBCEnums.h"
#include "Define.h"
#include "ObjectGuid.h"
#include "WaypointDefines.h"
@@ -1588,19 +1589,19 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] =
enum SmartEventFlags
{
- SMART_EVENT_FLAG_NOT_REPEATABLE = 0x001, //Event can not repeat
- SMART_EVENT_FLAG_DIFFICULTY_0 = 0x002, //Event only occurs in instance difficulty 0
- SMART_EVENT_FLAG_DIFFICULTY_1 = 0x004, //Event only occurs in instance difficulty 1
- SMART_EVENT_FLAG_DIFFICULTY_2 = 0x008, //Event only occurs in instance difficulty 2
- SMART_EVENT_FLAG_DIFFICULTY_3 = 0x010, //Event only occurs in instance difficulty 3
- SMART_EVENT_FLAG_RESERVED_5 = 0x020,
- SMART_EVENT_FLAG_RESERVED_6 = 0x040,
- SMART_EVENT_FLAG_DEBUG_ONLY = 0x080, //Event only occurs in debug build
- SMART_EVENT_FLAG_DONT_RESET = 0x100, //Event will not reset in SmartScript::OnReset()
- SMART_EVENT_FLAG_WHILE_CHARMED = 0x200, //Event occurs even if AI owner is charmed
-
- SMART_EVENT_FLAG_DIFFICULTY_ALL = (SMART_EVENT_FLAG_DIFFICULTY_0|SMART_EVENT_FLAG_DIFFICULTY_1|SMART_EVENT_FLAG_DIFFICULTY_2|SMART_EVENT_FLAG_DIFFICULTY_3),
- SMART_EVENT_FLAGS_ALL = (SMART_EVENT_FLAG_NOT_REPEATABLE|SMART_EVENT_FLAG_DIFFICULTY_ALL|SMART_EVENT_FLAG_RESERVED_5|SMART_EVENT_FLAG_RESERVED_6|SMART_EVENT_FLAG_DEBUG_ONLY|SMART_EVENT_FLAG_DONT_RESET|SMART_EVENT_FLAG_WHILE_CHARMED),
+ SMART_EVENT_FLAG_NOT_REPEATABLE = 0x001, // Event can not repeat
+ SMART_EVENT_FLAG_DIFFICULTY_0_DEPRECATED = 0x002, // UNUSED, DO NOT REUSE
+ SMART_EVENT_FLAG_DIFFICULTY_1_DEPRECATED = 0x004, // UNUSED, DO NOT REUSE
+ SMART_EVENT_FLAG_DIFFICULTY_2_DEPRECATED = 0x008, // UNUSED, DO NOT REUSE
+ SMART_EVENT_FLAG_DIFFICULTY_3_DEPRECATED = 0x010, // UNUSED, DO NOT REUSE
+ SMART_EVENT_FLAG_RESERVED_5 = 0x020,
+ SMART_EVENT_FLAG_RESERVED_6 = 0x040,
+ SMART_EVENT_FLAG_DEBUG_ONLY = 0x080, //Event only occurs in debug build
+ SMART_EVENT_FLAG_DONT_RESET = 0x100, //Event will not reset in SmartScript::OnReset()
+ SMART_EVENT_FLAG_WHILE_CHARMED = 0x200, //Event occurs even if AI owner is charmed
+
+ SMART_EVENT_FLAGS_DEPRECATED = (SMART_EVENT_FLAG_DIFFICULTY_0_DEPRECATED | SMART_EVENT_FLAG_DIFFICULTY_1_DEPRECATED | SMART_EVENT_FLAG_DIFFICULTY_2_DEPRECATED | SMART_EVENT_FLAG_DIFFICULTY_3_DEPRECATED),
+ SMART_EVENT_FLAGS_ALL = (SMART_EVENT_FLAG_NOT_REPEATABLE| SMART_EVENT_FLAGS_DEPRECATED | SMART_EVENT_FLAG_RESERVED_5 | SMART_EVENT_FLAG_RESERVED_6 | SMART_EVENT_FLAG_DEBUG_ONLY | SMART_EVENT_FLAG_DONT_RESET | SMART_EVENT_FLAG_WHILE_CHARMED),
// Temp flags, used only at runtime, never stored in DB
SMART_EVENT_FLAG_TEMP_IGNORE_CHANCE_ROLL = 0x40000000, //Event occurs no matter what roll_chance_i(e.event.event_chance) returns.
@@ -1628,6 +1629,7 @@ struct SmartScriptHolder
SmartScriptType source_type;
uint32 event_id;
uint32 link;
+ std::vector<Difficulty> Difficulties;
SmartEvent event;
SmartAction action;