diff options
Diffstat (limited to 'src')
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; |
