diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index bbffea50d8..fe6caeaaf6 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -2385,6 +2385,38 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } break; } + case SMART_ACTION_SET_MOVEMENT_SPEED: + { + uint32 speedInteger = e.action.movementSpeed.speedInteger; + uint32 speedFraction = e.action.movementSpeed.speedFraction; + float speed = float(speedInteger) + float(speedFraction) / std::pow(10, std::floor(std::log10(float(speedFraction ? speedFraction : 1)) + 1)); + + for (WorldObject* target : targets) + if (IsCreature(target)) + target->ToCreature()->SetSpeed(UnitMoveType(e.action.movementSpeed.movementType), speed); + + break; + } + case SMART_ACTION_OVERRIDE_LIGHT: + { + if (WorldObject* obj = GetBaseObject()) + { + obj->GetMap()->SetZoneOverrideLight(e.action.overrideLight.zoneId, e.action.overrideLight.overrideLightId, e.action.overrideLight.transitionMilliseconds); + TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_OVERRIDE_LIGHT: %s sets zone override light (zoneId: %u, overrideLightId: %u, transitionMilliseconds: %u)", + obj->GetGUID().ToString().c_str(), e.action.overrideLight.zoneId, e.action.overrideLight.overrideLightId, e.action.overrideLight.transitionMilliseconds); + } + break; + } + case SMART_ACTION_OVERRIDE_WEATHER: + { + if (WorldObject* obj = GetBaseObject()) + { + obj->GetMap()->SetZoneWeather(e.action.overrideWeather.zoneId, (WeatherState)e.action.overrideWeather.weatherId, float(e.action.overrideWeather.intensity)); + TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_OVERRIDE_WEATHER: %s sets zone weather (zoneId: %u, weatherId: %u, intensity: %u)", + obj->GetGUID().ToString().c_str(), e.action.overrideWeather.zoneId, e.action.overrideWeather.weatherId, e.action.overrideWeather.intensity); + } + break; + } default: TC_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); break; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 3308b892b8..f25c8bf8bc 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -1554,6 +1554,68 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; } break; + case SMART_ACTION_SET_MOVEMENT_SPEED: + { + if (e.action.movementSpeed.movementType >= MAX_MOVE_TYPE) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %u SourceType %u Event %u Action %u uses invalid movementType %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.movementSpeed.movementType); + return false; + } + + if (!e.action.movementSpeed.speedInteger && !e.action.movementSpeed.speedFraction) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %u SourceType %u Event %u Action %u uses speed 0, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); + return false; + } + + break; + } + case SMART_ACTION_OVERRIDE_LIGHT: + { + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(e.action.overrideLight.zoneId); + if (!areaEntry) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent zoneId %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.overrideLight.zoneId); + return false; + } + + if (areaEntry->ParentAreaID != 0) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses subzone (ID: %u) instead of zone, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.overrideLight.zoneId); + return false; + } + + if (!sLightStore.LookupEntry(e.action.overrideLight.areaLightId)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent areaLightId %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.overrideLight.areaLightId); + return false; + } + + if (e.action.overrideLight.overrideLightId && !sLightStore.LookupEntry(e.action.overrideLight.overrideLightId)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent overrideLightId %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.overrideLight.overrideLightId); + return false; + } + + break; + } + case SMART_ACTION_OVERRIDE_WEATHER: + { + AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(e.action.overrideWeather.zoneId); + if (!areaEntry) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent zoneId %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.overrideWeather.zoneId); + return false; + } + + if (areaEntry->ParentAreaID != 0) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses subzone (ID: %u) instead of zone, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.overrideWeather.zoneId); + return false; + } + + break; + } case SMART_ACTION_START_CLOSEST_WAYPOINT: case SMART_ACTION_FOLLOW: case SMART_ACTION_SET_ORIENTATION: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index fd4afa59fc..154bec7935 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -586,7 +586,12 @@ enum SMART_ACTION SMART_ACTION_RESPAWN_BY_SPAWNID = 133, // spawnType, spawnId SMART_ACTION_INVOKER_CAST = 134, // spellID, castFlags SMART_ACTION_PLAY_CINEMATIC = 135, - SMART_ACTION_END = 136 + SMART_ACTION_SET_MOVEMENT_SPEED = 136, // movementType, speedInteger, speedFraction + SMART_ACTION_PLAY_SPELL_VISUAL_KIT = 137, // spellVisualKitId (RESERVED, PENDING CHERRYPICK) + SMART_ACTION_OVERRIDE_LIGHT = 138, // zoneId, overrideLightID, transitionMilliseconds + SMART_ACTION_OVERRIDE_WEATHER = 139, // zoneId, weatherId, intensity + + SMART_ACTION_END = 140 }; struct SmartAction @@ -1165,6 +1170,29 @@ struct SmartAction //! Note for any new future actions //! All parameters must have type uint32 + struct + { + uint32 movementType; + uint32 speedInteger; + uint32 speedFraction; + } movementSpeed; + + struct + { + uint32 zoneId; + uint32 areaLightId; + uint32 overrideLightId; + uint32 transitionMilliseconds; + } overrideLight; + + struct + { + uint32 zoneId; + uint32 weatherId; + uint32 intensity; + } overrideWeather; + + struct { uint32 param1; diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 4d4b61b884..86d5d60a32 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -133,7 +133,8 @@ TC_GAME_API extern DBCStorage sMountTypeStore; //TC_GAME_API extern DBCStorage sNameGenStore; -- use GetRandomCharacterName instead TC_GAME_API extern DBCStorage sNumTalentsAtLevelStore; TC_GAME_API extern DBCStorage sPhaseStore; -TC_GAME_API extern DBCStorage sPhaseGroupStore; +TC_GAME_API extern DBCStorage sPhaseGroupStore; +TC_GAME_API extern DBCStorage sLightStore; //TC_GAME_API extern DBCStorage sMapDifficultyStore; -- use GetMapDifficultyData insteed TC_GAME_API extern MapDifficultyMap sMapDifficultyMap; TC_GAME_API extern DBCStorage sMovieStore; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 0985a18a08..a605052490 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -66,7 +66,7 @@ static uint16 const holetab_v[4] = { 0x000F, 0x00F0, 0x0F00, 0xF000 }; GridState* si_GridStates[MAX_GRID_STATE]; ZoneDynamicInfo::ZoneDynamicInfo() : MusicId(0), DefaultWeather(nullptr), WeatherId(WEATHER_STATE_FINE), - WeatherGrade(0.0f), OverrideLightId(0), LightFadeInTime(0) { } +Intensity(0.0f) { } Map::~Map() { @@ -324,7 +324,7 @@ m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), m_VisibilityNotifyPeriod(DEFAULT_VISIBILITY_NOTIFY_PERIOD), m_activeNonPlayersIter(m_activeNonPlayers.end()), _transportsUpdateIter(_transports.end()), i_gridExpiry(expiry), -i_scriptLock(false), _respawnCheckTimer(0), _defaultLight(DBCManager::GetDefaultMapLight(id)) +i_scriptLock(false), _respawnCheckTimer(0) { if (_parent) { @@ -4749,12 +4749,12 @@ void Map::SendZoneDynamicInfo(uint32 zoneId, Player* player) const SendZoneWeather(itr->second, player); - if (uint32 overrideLightId = itr->second.OverrideLightId) + for (ZoneDynamicInfo::LightOverride const& lightOverride : itr->second.LightOverrides) { WorldPackets::Misc::OverrideLight overrideLight; - overrideLight.AreaLightID = _defaultLight; - overrideLight.OverrideLightID = overrideLightId; - overrideLight.TransitionMilliseconds = itr->second.LightFadeInTime; + overrideLight.AreaLightID = lightOverride.AreaLightId; + overrideLight.OverrideLightID = lightOverride.OverrideLightId; + overrideLight.TransitionMilliseconds = lightOverride.TransitionMilliseconds; player->SendDirectMessage(overrideLight.Write()); } } @@ -4775,7 +4775,7 @@ void Map::SendZoneWeather(ZoneDynamicInfo const& zoneDynamicInfo, Player* player { if (WeatherState weatherId = zoneDynamicInfo.WeatherId) { - WorldPackets::Misc::Weather weather(weatherId, zoneDynamicInfo.WeatherGrade); + WorldPackets::Misc::Weather weather(weatherId, zoneDynamicInfo.Intensity); player->SendDirectMessage(weather.Write()); } else if (zoneDynamicInfo.DefaultWeather) @@ -4817,16 +4817,16 @@ Weather* Map::GetOrGenerateZoneDefaultWeather(uint32 zoneId) return info.DefaultWeather.get(); } -void Map::SetZoneWeather(uint32 zoneId, WeatherState weatherId, float weatherGrade) +void Map::SetZoneWeather(uint32 zoneId, WeatherState weatherId, float intensity) { ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId]; info.WeatherId = weatherId; - info.WeatherGrade = weatherGrade; + info.Intensity = intensity; Map::PlayerList const& players = GetPlayers(); if (!players.isEmpty()) { - WorldPackets::Misc::Weather weather(weatherId, weatherGrade); + WorldPackets::Misc::Weather weather(weatherId, intensity); weather.Write(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) @@ -4836,19 +4836,31 @@ void Map::SetZoneWeather(uint32 zoneId, WeatherState weatherId, float weatherGra } } -void Map::SetZoneOverrideLight(uint32 zoneId, uint32 lightId, uint32 fadeInTime) +void Map::SetZoneOverrideLight(uint32 zoneId, uint32 areaLightId, uint32 overrideLightId, uint32 transitionMilliseconds) { ZoneDynamicInfo& info = _zoneDynamicInfo[zoneId]; - info.OverrideLightId = lightId; - info.LightFadeInTime = fadeInTime; - Map::PlayerList const& players = GetPlayers(); + // client can support only one override for each light (zone independent) + info.LightOverrides.erase(std::remove_if(info.LightOverrides.begin(), info.LightOverrides.end(), [areaLightId](ZoneDynamicInfo::LightOverride const& lightOverride) + { + return lightOverride.AreaLightId == areaLightId; + }), info.LightOverrides.end()); + // set new override (if any) + if (overrideLightId) + { + ZoneDynamicInfo::LightOverride& lightOverride = info.LightOverrides.emplace_back(); + lightOverride.AreaLightId = areaLightId; + lightOverride.OverrideLightId = overrideLightId; + lightOverride.TransitionMilliseconds = transitionMilliseconds; + } + + Map::PlayerList const& players = GetPlayers(); if (!players.isEmpty()) { WorldPackets::Misc::OverrideLight overrideLight; - overrideLight.AreaLightID = _defaultLight; - overrideLight.OverrideLightID = lightId; - overrideLight.TransitionMilliseconds = fadeInTime; + overrideLight.AreaLightID = areaLightId; + overrideLight.OverrideLightID = overrideLightId; + overrideLight.TransitionMilliseconds = transitionMilliseconds; overrideLight.Write(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 9568db9f04..8c79f42365 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -273,9 +273,15 @@ struct ZoneDynamicInfo uint32 MusicId; std::unique_ptr DefaultWeather; WeatherState WeatherId; - float WeatherGrade; - uint32 OverrideLightId; - uint32 LightFadeInTime; + float Intensity; + + struct LightOverride + { + uint32 AreaLightId; + uint32 OverrideLightId; + uint32 TransitionMilliseconds; + }; + std::vector LightOverrides; }; #pragma pack(pop) @@ -643,8 +649,8 @@ class TC_GAME_API Map : public GridRefManager void SetZoneMusic(uint32 zoneId, uint32 musicId); Weather* GetOrGenerateZoneDefaultWeather(uint32 zoneId); - void SetZoneWeather(uint32 zoneId, WeatherState weatherId, float weatherGrade); - void SetZoneOverrideLight(uint32 zoneId, uint32 lightId, uint32 fadeInTime); + void SetZoneWeather(uint32 zoneId, WeatherState weatherId, float intensity); + void SetZoneOverrideLight(uint32 zoneId, uint32 areaLightId, uint32 overrideLightId, uint32 transitionMilliseconds); void UpdateAreaDependentAuras(); @@ -909,7 +915,6 @@ class TC_GAME_API Map : public GridRefManager ZoneDynamicInfoMap _zoneDynamicInfo; IntervalTimer _weatherUpdateTimer; - uint32 _defaultLight; template inline ObjectGuidGeneratorBase& GetGuidSequenceGenerator() diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index 4268abcfa0..0c61b23db7 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -344,6 +344,7 @@ enum EncounterActions enum MiscData { + LIGHT_DEFAULT = 2488, LIGHT_SNOWSTORM = 2490, LIGHT_SOULSTORM = 2508, LIGHT_FOG = 2509, @@ -518,7 +519,7 @@ class boss_the_lich_king : public CreatureScript Cell::VisitGridObjects(me, worker, 333.0f); // Reset any light override - me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, 0, 5000); + me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, 0, 5000); if (!ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING))) me->SummonCreature(NPC_HIGHLORD_TIRION_FORDRING_LK, TirionSpawn, TEMPSUMMON_MANUAL_DESPAWN); @@ -532,7 +533,7 @@ class boss_the_lich_king : public CreatureScript me->GetMotionMaster()->MoveFall(); if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f)) frostmourne->DespawnOrUnsummon(); - me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_FOG, 5000); + me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, LIGHT_FOG, 5000); me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_FOG, 0.0f); } @@ -601,7 +602,7 @@ class boss_the_lich_king : public CreatureScript me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FINAL); break; case ACTION_RESTORE_LIGHT: - me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, 0, 5000); + me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, 0, 5000); break; case ACTION_BREAK_FROSTMOURNE: me->CastSpell((Unit*)nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE, TRIGGERED_IGNORE_CAST_IN_PROGRESS); @@ -736,7 +737,7 @@ class boss_the_lich_king : public CreatureScript { summon->CastSpell((Unit*)nullptr, SPELL_BROKEN_FROSTMOURNE, true); - me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_SOULSTORM, 10000); + me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, LIGHT_SOULSTORM, 10000); me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_BLACKSNOW, 0.5f); events.ScheduleEvent(EVENT_OUTRO_SOUL_BARRAGE, 5000, 0, PHASE_OUTRO); @@ -791,7 +792,7 @@ class boss_the_lich_king : public CreatureScript { if (spell->Id == REMORSELESS_WINTER_1 || spell->Id == REMORSELESS_WINTER_2) { - me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_SNOWSTORM, 5000); + me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, LIGHT_SNOWSTORM, 5000); me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_LIGHT_SNOW, 0.5f); summons.DespawnEntry(NPC_SHADOW_TRAP); } diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index dff90309a4..5f7fb0edae 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -305,7 +305,7 @@ enum AreaIds enum MiscData { // Lights - LIGHT_GET_DEFAULT_FOR_MAP = 0, + LIGHT_DEFAULT = 1773, LIGHT_OBSCURE_SPACE = 1822, LIGHT_CHANGE_DIMENSIONS = 1823, LIGHT_ARCANE_RUNES = 1824, @@ -583,7 +583,7 @@ public: instance->SetBossState(DATA_MALYGOS_EVENT, FAIL); instance->SetBossState(DATA_MALYGOS_EVENT, NOT_STARTED); - me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_GET_DEFAULT_FOR_MAP, 1*IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_DEFAULT, 0, 1 * IN_MILLISECONDS); if (!summons.empty()) { @@ -701,7 +701,7 @@ public: me->SetDisableGravity(true); if (Creature* alexstraszaBunny = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ALEXSTRASZA_BUNNY_GUID))) me->SetFacingToObject(alexstraszaBunny); - me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_ARCANE_RUNES, 5 * IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_DEFAULT, LIGHT_ARCANE_RUNES, 5 * IN_MILLISECONDS); events.ScheduleEvent(EVENT_FLY_OUT_OF_PLATFORM, 18 * IN_MILLISECONDS, 0, PHASE_TWO); break; case POINT_SURGE_OF_POWER_P_TWO: @@ -713,7 +713,7 @@ public: } break; case POINT_DESTROY_PLATFORM_P_TWO: - me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_OBSCURE_SPACE, 1 * IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_DEFAULT, LIGHT_OBSCURE_SPACE, 1 * IN_MILLISECONDS); DoCast(me, SPELL_DESTROY_PLATFORM_CHANNEL); events.ScheduleEvent(EVENT_MOVE_TO_P_THREE_POINT, 11*IN_MILLISECONDS, 0, PHASE_TWO); break; @@ -911,7 +911,7 @@ public: } break; case EVENT_LIGHT_DIMENSION_CHANGE: - me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_CHANGE_DIMENSIONS, 2 * IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_DEFAULT, LIGHT_CHANGE_DIMENSIONS, 2 * IN_MILLISECONDS); break; case EVENT_DELAY_MOVE_TO_DESTROY_P: me->GetMotionMaster()->MovePoint(POINT_DESTROY_PLATFORM_P_TWO, MalygosPositions[0]); @@ -921,7 +921,7 @@ public: me->GetMotionMaster()->MovePoint(POINT_IDLE_P_THREE, MalygosPositions[4]); break; case EVENT_START_P_THREE: - me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_OBSCURE_ARCANE_RUNES, 1 * IN_MILLISECONDS); + me->GetMap()->SetZoneOverrideLight(AREA_EYE_OF_ETERNITY, LIGHT_DEFAULT, LIGHT_OBSCURE_ARCANE_RUNES, 1 * IN_MILLISECONDS); DoCast(me, SPELL_CLEAR_ALL_DEBUFFS); DoCast(me, SPELL_IMMUNE_CURSES); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);