diff options
Diffstat (limited to 'src/server/scripts')
| -rw-r--r-- | src/server/scripts/CMakeLists.txt | 28 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_lookup.cpp | 97 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_wp.cpp | 2 | ||||
| -rw-r--r-- | src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp | 187 | ||||
| -rw-r--r-- | src/server/scripts/EasternKingdoms/silverpine_forest.cpp | 18 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp | 4 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp | 117 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/wintergrasp.cpp | 2 | ||||
| -rw-r--r-- | src/server/scripts/World/boss_emerald_dragons.cpp | 310 | ||||
| -rw-r--r-- | src/server/scripts/World/npc_taxi.cpp | 8 |
10 files changed, 428 insertions, 345 deletions
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index 59dfc0f990f..8e636ee1208 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -9,18 +9,11 @@ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # Enable precompiled headers when using the GCC compiler. -if( USE_SCRIPTPCH ) - include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ) -endif() -if( USE_SCRIPTPCH AND MSVC ) - set(scripts_STAT_SRCS - PrecompiledHeaders/ScriptPCH.cpp - PrecompiledHeaders/ScriptPCH.h - ) -endif() +if (USE_SCRIPTPCH) + set(scripts_STAT_PCH_HDR PrecompiledHeaders/ScriptPCH.h) + set(scripts_STAT_PCH_SRC PrecompiledHeaders/ScriptPCH.cpp) +endif () message(STATUS "SCRIPT PREPARATIONS") include(Spells/CMakeLists.txt) @@ -148,15 +141,14 @@ include_directories( ${MYSQL_INCLUDE_DIR} ) -add_library(scripts STATIC ${scripts_STAT_SRCS}) +add_library(scripts STATIC + ${scripts_STAT_SRCS} + ${scripts_STAT_PCH_SRC} +) add_dependencies(scripts revision.h) # Generate precompiled header -if( USE_SCRIPTPCH ) - if(CMAKE_COMPILER_IS_GNUCXX) - add_precompiled_header(scripts ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders/ScriptPCH.h) - elseif(MSVC) - add_native_precompiled_header(scripts ${CMAKE_CURRENT_SOURCE_DIR}/PrecompiledHeaders/ScriptPCH) - endif() +if (USE_SCRIPTPCH) + add_cxx_pch(scripts ${scripts_STAT_PCH_HDR} ${scripts_STAT_PCH_SRC}) endif() diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp index 8f7e3ed3247..9889b4752c8 100644 --- a/src/server/scripts/Commands/cs_lookup.cpp +++ b/src/server/scripts/Commands/cs_lookup.cpp @@ -1156,109 +1156,72 @@ public: return true; } - static bool HandleLookupMapCommand(ChatHandler* /*handler*/, char const* args) + static bool HandleLookupMapCommand(ChatHandler* handler, char const* args) { if (!*args) return false; - /* + std::string namePart = args; std::wstring wNamePart; - // converting string that we try to find to lower case if (!Utf8toWStr(namePart, wNamePart)) return false; wstrToLower(wNamePart); - bool found = false; + uint32 counter = 0; + uint32 maxResults = sWorld->getIntConfig(CONFIG_MAX_RESULTS_LOOKUP_COMMANDS); + uint8 locale = handler->GetSession() ? handler->GetSession()->GetSessionDbcLocale() : sWorld->GetDefaultDbcLocale(); // search in Map.dbc for (uint32 id = 0; id < sMapStore.GetNumRows(); id++) { - MapEntry const* MapInfo = sMapStore.LookupEntry(id); - if (MapInfo) + if (MapEntry const* mapInfo = sMapStore.LookupEntry(id)) { - uint8 locale = handler->GetSession() ? handler->GetSession()->GetSessionDbcLocale() : sWorld->GetDefaultDbcLocale(); - - std::string name = MapInfo->name[locale]; + std::string name = mapInfo->name[locale]; if (name.empty()) continue; - if (!Utf8FitTo(name, wNamePart)) + if (Utf8FitTo(name, wNamePart) && locale < TOTAL_LOCALES) { - locale = LOCALE_enUS; - for (; locale < TOTAL_LOCALES; locale++) + if (maxResults && counter == maxResults) { - if (handler->GetSession() && locale == handler->GetSession()->GetSessionDbcLocale()) - continue; - - name = MapInfo->name[locale]; - if (name.empty()) - continue; - - if (Utf8FitTo(name, wNamePart)) - break; + handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults); + return true; } - } - if (locale < TOTAL_LOCALES) - { - // send map in "id - [name][Continent][Instance/Battleground/Arena][Raid reset time:][Heroic reset time:][Mountable]" format std::ostringstream ss; + ss << id << " - [" << name << ']'; - if (handler->GetSession()) - ss << id << " - |cffffffff|Hmap:" << id << "|h[" << name << ']'; - else // console - ss << id << " - [" << name << ']'; - - if (MapInfo->IsContinent()) + if (mapInfo->IsContinent()) ss << handler->GetTrinityString(LANG_CONTINENT); - switch (MapInfo->map_type) + switch (mapInfo->map_type) { - case MAP_INSTANCE: ss << handler->GetTrinityString(LANG_INSTANCE); break; - case MAP_BATTLEGROUND: ss << handler->GetTrinityString(LANG_BATTLEGROUND); break; - case MAP_ARENA: ss << handler->GetTrinityString(LANG_ARENA); break; + case MAP_INSTANCE: + ss << handler->GetTrinityString(LANG_INSTANCE); + break; + case MAP_RAID: + ss << handler->GetTrinityString(LANG_RAID); + break; + case MAP_BATTLEGROUND: + ss << handler->GetTrinityString(LANG_BATTLEGROUND); + break; + case MAP_ARENA: + ss << handler->GetTrinityString(LANG_ARENA); + break; } - if (MapInfo->IsRaid()) - ss << handler->GetTrinityString(LANG_RAID); - - if (MapInfo->SupportsHeroicMode()) - ss << handler->GetTrinityString(LANG_HEROIC); - - uint32 ResetTimeRaid = MapInfo->resetTimeRaid; - - std::string ResetTimeRaidStr; - if (ResetTimeRaid) - ResetTimeRaidStr = secsToTimeString(ResetTimeRaid, true, false); - - uint32 ResetTimeHeroic = MapInfo->resetTimeHeroic; - std::string ResetTimeHeroicStr; - if (ResetTimeHeroic) - ResetTimeHeroicStr = secsToTimeString(ResetTimeHeroic, true, false); - - if (MapInfo->IsMountAllowed()) - ss << handler->GetTrinityString(LANG_MOUNTABLE); - - if (ResetTimeRaid && !ResetTimeHeroic) - handler->PSendSysMessage(ss.str().c_str(), ResetTimeRaidStr.c_str()); - else if (!ResetTimeRaid && ResetTimeHeroic) - handler->PSendSysMessage(ss.str().c_str(), ResetTimeHeroicStr.c_str()); - else if (ResetTimeRaid && ResetTimeHeroic) - handler->PSendSysMessage(ss.str().c_str(), ResetTimeRaidStr.c_str(), ResetTimeHeroicStr.c_str()); - else - handler->SendSysMessage(ss.str().c_str()); + handler->SendSysMessage(ss.str().c_str()); - if (!found) - found = true; + ++counter; } } } - if (!found) + if (!counter) handler->SendSysMessage(LANG_COMMAND_NOMAPFOUND); - */ + return true; } diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index e3cd185e4a3..10a18c3ed36 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -941,7 +941,7 @@ public: { wpCreature->SetDisplayId(target->GetDisplayId()); wpCreature->SetObjectScale(0.5f); - wpCreature->SetLevel(point > STRONG_MAX_LEVEL ? STRONG_MAX_LEVEL : point); + wpCreature->SetLevel(std::min<uint32>(point, STRONG_MAX_LEVEL)); } } while (result->NextRow()); diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp b/src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp index b2b4083f9c6..cef95b607c7 100644 --- a/src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp +++ b/src/server/scripts/EasternKingdoms/AlteracValley/alterac_valley.cpp @@ -24,8 +24,8 @@ enum Spells SPELL_CLEAVE = 40504, SPELL_DEMORALIZING_SHOUT = 23511, SPELL_ENRAGE = 8599, - SPELL_WHIRLWIND1 = 15589, - SPELL_WHIRLWIND2 = 13736, + SPELL_WHIRLWIND = 13736, + SPELL_NORTH_MARSHAL = 45828, SPELL_SOUTH_MARSHAL = 45829, SPELL_STONEHEARTH_MARSHAL = 45830, @@ -48,38 +48,55 @@ enum Creatures NPC_WEST_FROSTWOLF_WARMASTER = 14777 }; +enum Events +{ + EVENT_CHARGE_TARGET = 1, + EVENT_CLEAVE = 2, + EVENT_DEMORALIZING_SHOUT = 3, + EVENT_WHIRLWIND = 4, + EVENT_ENRAGE = 5, + EVENT_CHECK_RESET = 6 +}; + +struct SpellPair +{ + uint32 npcEntry; + uint32 spellId; +}; + +uint8 const MAX_SPELL_PAIRS = 8; +SpellPair const _auraPairs[MAX_SPELL_PAIRS] = +{ + { NPC_NORTH_MARSHAL, SPELL_NORTH_MARSHAL }, + { NPC_SOUTH_MARSHAL, SPELL_SOUTH_MARSHAL }, + { NPC_STONEHEARTH_MARSHAL, SPELL_STONEHEARTH_MARSHAL }, + { NPC_ICEWING_MARSHAL, SPELL_ICEWING_MARSHAL }, + { NPC_EAST_FROSTWOLF_WARMASTER, SPELL_EAST_FROSTWOLF_WARMASTER }, + { NPC_WEST_FROSTWOLF_WARMASTER, SPELL_WEST_FROSTWOLF_WARMASTER }, + { NPC_TOWER_POINT_WARMASTER, SPELL_TOWER_POINT_WARMASTER }, + { NPC_ICEBLOOD_WARMASTER, SPELL_ICEBLOOD_WARMASTER } +}; + class mob_av_marshal_or_warmaster : public CreatureScript { public: - - mob_av_marshal_or_warmaster() - : CreatureScript("mob_av_marshal_or_warmaster") {} + mob_av_marshal_or_warmaster() : CreatureScript("mob_av_marshal_or_warmaster") { } struct mob_av_marshal_or_warmasterAI : public ScriptedAI { - mob_av_marshal_or_warmasterAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 ChargeTimer; - uint32 CleaveTimer; - uint32 DemoralizingShoutTimer; - uint32 Whirlwind1Timer; - uint32 Whirlwind2Timer; - uint32 EnrageTimer; - uint32 ResetTimer; - - bool bHasAura; + mob_av_marshal_or_warmasterAI(Creature* creature) : ScriptedAI(creature) { } void Reset() { - ChargeTimer = urand(2 * IN_MILLISECONDS, 12 * IN_MILLISECONDS); - CleaveTimer = urand(1 * IN_MILLISECONDS, 11 * IN_MILLISECONDS); - DemoralizingShoutTimer = urand(2 * IN_MILLISECONDS, 2 * IN_MILLISECONDS); - Whirlwind1Timer = urand(1 * IN_MILLISECONDS, 12 * IN_MILLISECONDS); - Whirlwind2Timer = urand(5 * IN_MILLISECONDS, 20 * IN_MILLISECONDS); - EnrageTimer = urand(5 * IN_MILLISECONDS, 20 * IN_MILLISECONDS); - ResetTimer = 5 * IN_MILLISECONDS; - - bHasAura = false; + events.Reset(); + events.ScheduleEvent(EVENT_CHARGE_TARGET, urand(2 * IN_MILLISECONDS, 12 * IN_MILLISECONDS)); + events.ScheduleEvent(EVENT_CLEAVE, urand(1 * IN_MILLISECONDS, 11 * IN_MILLISECONDS)); + events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, 2000); + events.ScheduleEvent(EVENT_WHIRLWIND, urand(5 * IN_MILLISECONDS, 20 * IN_MILLISECONDS)); + events.ScheduleEvent(EVENT_ENRAGE, urand(5 * IN_MILLISECONDS, 20 * IN_MILLISECONDS)); + events.ScheduleEvent(EVENT_CHECK_RESET, 5000); + + _hasAura = false; } void JustRespawned() @@ -87,90 +104,70 @@ class mob_av_marshal_or_warmaster : public CreatureScript Reset(); } - void UpdateAI(const uint32 diff) + void UpdateAI(uint32 const diff) { - if (!bHasAura) + // I have a feeling this isn't blizzlike, but owell, I'm only passing by and cleaning up. + if (!_hasAura) { - switch (me->GetEntry()) - { - case NPC_NORTH_MARSHAL: - DoCast(me, SPELL_NORTH_MARSHAL); - break; - case NPC_SOUTH_MARSHAL: - DoCast(me, SPELL_SOUTH_MARSHAL); - break; - case NPC_STONEHEARTH_MARSHAL: - DoCast(me, SPELL_STONEHEARTH_MARSHAL); - break; - case NPC_ICEWING_MARSHAL: - DoCast(me, SPELL_ICEWING_MARSHAL); - break; - case NPC_EAST_FROSTWOLF_WARMASTER: - DoCast(me, SPELL_EAST_FROSTWOLF_WARMASTER); - break; - case NPC_WEST_FROSTWOLF_WARMASTER: - DoCast(me, SPELL_WEST_FROSTWOLF_WARMASTER); - break; - case NPC_ICEBLOOD_WARMASTER: - DoCast(me, SPELL_ICEBLOOD_WARMASTER); - break; - case NPC_TOWER_POINT_WARMASTER: - DoCast(me, SPELL_TOWER_POINT_WARMASTER); - break; - } + for (uint8 i = 0; i < MAX_SPELL_PAIRS; ++i) + if (_auraPairs[i].npcEntry == me->GetEntry()) + DoCast(me, _auraPairs[i].spellId); - bHasAura = true; + _hasAura = true; } if (!UpdateVictim()) return; - if (ChargeTimer <= diff) - { - DoCast(me->getVictim(), SPELL_CHARGE); - ChargeTimer = urand(10 * IN_MILLISECONDS, 25 * IN_MILLISECONDS); - } else ChargeTimer -= diff; - - if (CleaveTimer <= diff) - { - DoCast(me->getVictim(), SPELL_CLEAVE); - CleaveTimer = urand(10 * IN_MILLISECONDS, 16 * IN_MILLISECONDS); - } else CleaveTimer -= diff; - - if (DemoralizingShoutTimer <= diff) - { - DoCast(me->getVictim(), SPELL_DEMORALIZING_SHOUT); - DemoralizingShoutTimer = urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS); - } else DemoralizingShoutTimer -= diff; + events.Update(diff); - if (Whirlwind1Timer <= diff) - { - DoCast(me->getVictim(), SPELL_WHIRLWIND1); - Whirlwind1Timer = urand(6 * IN_MILLISECONDS, 20 * IN_MILLISECONDS); - } else Whirlwind1Timer -= diff; - - if (Whirlwind2Timer <= diff) - { - DoCast(me->getVictim(), SPELL_WHIRLWIND2); - Whirlwind2Timer = urand(10 * IN_MILLISECONDS, 25 * IN_MILLISECONDS); - } else Whirlwind2Timer -= diff; - - if (EnrageTimer <= diff) - { - DoCast(me->getVictim(), SPELL_ENRAGE); - EnrageTimer = urand(10 * IN_MILLISECONDS, 30 * IN_MILLISECONDS); - }else EnrageTimer -= diff; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - // check if creature is not outside of building - if (ResetTimer <= diff) + while (uint32 eventId = events.ExecuteEvent()) { - if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50) - EnterEvadeMode(); - ResetTimer = 5 * IN_MILLISECONDS; - } else ResetTimer -= diff; + switch (eventId) + { + case EVENT_CHARGE_TARGET: + DoCast(me->getVictim(), SPELL_CHARGE); + events.ScheduleEvent(EVENT_CHARGE, urand(10 * IN_MILLISECONDS, 25 * IN_MILLISECONDS)); + break; + case EVENT_CLEAVE: + DoCast(me->getVictim(), SPELL_CLEAVE); + events.ScheduleEvent(EVENT_CLEAVE, urand(10 * IN_MILLISECONDS, 16 * IN_MILLISECONDS)); + break; + case EVENT_DEMORALIZING_SHOUT: + DoCast(me, SPELL_DEMORALIZING_SHOUT); + events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS)); + break; + case EVENT_WHIRLWIND: + DoCast(me, SPELL_WHIRLWIND); + events.ScheduleEvent(EVENT_WHIRLWIND, urand(10 * IN_MILLISECONDS, 25 * IN_MILLISECONDS)); + break; + case EVENT_ENRAGE: + DoCast(me, SPELL_ENRAGE); + events.ScheduleEvent(EVENT_ENRAGE, urand(10 * IN_MILLISECONDS, 30 * IN_MILLISECONDS)); + break; + case EVENT_CHECK_RESET: + { + Position const& _homePosition = me->GetHomePosition(); + if (me->GetDistance2d(_homePosition.GetPositionX(), _homePosition.GetPositionY()) > 50.0f) + { + EnterEvadeMode(); + return; + } + events.ScheduleEvent(EVENT_CHECK_RESET, 5000); + break; + } + } + } DoMeleeAttackIfReady(); } + + private: + EventMap events; + bool _hasAura; }; CreatureAI* GetAI(Creature* creature) const diff --git a/src/server/scripts/EasternKingdoms/silverpine_forest.cpp b/src/server/scripts/EasternKingdoms/silverpine_forest.cpp index c52e69787d4..b2cd3b16e7b 100644 --- a/src/server/scripts/EasternKingdoms/silverpine_forest.cpp +++ b/src/server/scripts/EasternKingdoms/silverpine_forest.cpp @@ -232,18 +232,16 @@ public: { Unit* target = NULL; if (PlayerGUID) - { - if (Unit* player = Unit::GetPlayer(*me, PlayerGUID)->ToUnit()) - target = RAND((Unit*)me, player); - } else + if (Player* player = Unit::GetPlayer(*me, PlayerGUID)) + if (player->isAlive() && RAND(0, 1)) + target = player; + + if (!target) target = me; - if (target) - { - summoned->setFaction(168); - summoned->AddThreat(target, 32.0f); - summoned->AI()->AttackStart(target); - } + summoned->setFaction(168); + summoned->AddThreat(target, 32.0f); + summoned->AI()->AttackStart(target); } } diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index 82739c0026a..1d0b0fd6ee6 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -1375,7 +1375,7 @@ class spell_halion_combustion_consumption : public SpellScriptLoader public: spell_halion_combustion_consumption_AuraScript(uint32 spellID) : AuraScript(), _markSpell(spellID) { } - bool Validate(SpellEntry const* /*spell*/) + bool Validate(SpellInfo const* /*spell*/) { if (!sSpellMgr->GetSpellInfo(_markSpell)) return false; @@ -1434,7 +1434,7 @@ class spell_halion_marks : public SpellScriptLoader spell_halion_marks_AuraScript(uint32 summonSpell, uint32 removeSpell) : AuraScript(), _summonSpellId(summonSpell), _removeSpellId(removeSpell) { } - bool Validate(SpellEntry const* /*spell*/) + bool Validate(SpellInfo const* /*spell*/) { if (!sSpellMgr->GetSpellInfo(_summonSpellId)) return false; diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp index c694aa88338..e587a864fd6 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp @@ -143,17 +143,10 @@ public: } } } - - switch (near_f) - { - case 1: return 1; - case 2: return 2; - case 3: return 3; - default: return 0; - } + return near_f > 0 && near_f < 4 ? near_f : 0; } - void UpdateAI(const uint32 /*diff*/) + void UpdateAI(uint32 const /* diff */) { if (fm_Type == 0) fm_Type = GetForgeMasterType(); @@ -239,9 +232,115 @@ class spell_fixate : public SpellScriptLoader return new spell_fixate_SpellScript(); } }; + +enum EnslavedProtoDrake +{ + TYPE_PROTODRAKE_AT = 28, + DATA_PROTODRAKE_MOVE = 6, + + PATH_PROTODRAKE = 125946, + + EVENT_REND = 1, + EVENT_FLAME_BREATH = 2, + EVENT_KNOCKAWAY = 3, + + SPELL_REND = 43931, + SPELL_FLAME_BREATH = 50653, + SPELL_KNOCK_AWAY = 49722, + + POINT_LAST = 5, +}; + +const Position protodrakeCheckPos = {206.24f, -190.28f, 200.11f, 0.f}; + +class npc_enslaved_proto_drake : public CreatureScript +{ +public: + npc_enslaved_proto_drake() : CreatureScript("npc_enslaved_proto_drake") { } + + struct npc_enslaved_proto_drakeAI : public ScriptedAI + { + npc_enslaved_proto_drakeAI(Creature* creature) : ScriptedAI(creature) + { + _setData = false; + } + + void Reset() + { + _events.Reset(); + _events.ScheduleEvent(EVENT_REND, urand(2000, 3000)); + _events.ScheduleEvent(EVENT_FLAME_BREATH, urand(5500, 7000)); + _events.ScheduleEvent(EVENT_KNOCKAWAY, urand(3500, 6000)); + } + + void MovementInform(uint32 type, uint32 id) + { + if (type == WAYPOINT_MOTION_TYPE && id == POINT_LAST) + { + me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + } + } + + void SetData(uint32 type, uint32 data) + { + if (type == TYPE_PROTODRAKE_AT && data == DATA_PROTODRAKE_MOVE && !_setData && me->GetDistance(protodrakeCheckPos) < 5.0f) + { + _setData = true; + me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + me->GetMotionMaster()->MovePath(PATH_PROTODRAKE, false); + } + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventid = _events.ExecuteEvent()) + { + switch (eventid) + { + case EVENT_REND: + DoCast(SPELL_REND); + _events.ScheduleEvent(EVENT_REND, urand(15000, 20000)); + break; + case EVENT_FLAME_BREATH: + DoCast(SPELL_FLAME_BREATH); + _events.ScheduleEvent(EVENT_FLAME_BREATH, urand(11000, 12000)); + break; + case EVENT_KNOCKAWAY: + DoCast(SPELL_KNOCK_AWAY); + _events.ScheduleEvent(EVENT_KNOCKAWAY, urand(7000, 8500)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + bool _setData; + EventMap _events; + + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_enslaved_proto_drakeAI(creature); + } +}; + void AddSC_utgarde_keep() { new npc_dragonflayer_forge_master(); + new npc_enslaved_proto_drake(); new spell_ticking_time_bomb(); new spell_fixate(); } diff --git a/src/server/scripts/Northrend/wintergrasp.cpp b/src/server/scripts/Northrend/wintergrasp.cpp index d4a3f83ab70..b7901f1a44a 100644 --- a/src/server/scripts/Northrend/wintergrasp.cpp +++ b/src/server/scripts/Northrend/wintergrasp.cpp @@ -560,7 +560,7 @@ public: if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG)) if (Player* target = GetExplTargetUnit()->ToPlayer()) // check if we are in Wintergrasp at all, SotA uses same teleport spells - if ((target->GetZoneId() == 4197) && target->GetTeamId() != wg->GetDefenderTeam() || target->HasAura(SPELL_WINTERGRASP_TELEPORT_TRIGGER)) + if ((target->GetZoneId() == 4197 && target->GetTeamId() != wg->GetDefenderTeam()) || target->HasAura(SPELL_WINTERGRASP_TELEPORT_TRIGGER)) return SPELL_FAILED_BAD_TARGETS; return SPELL_CAST_OK; } diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp index abb20130ef8..65677959135 100644 --- a/src/server/scripts/World/boss_emerald_dragons.cpp +++ b/src/server/scripts/World/boss_emerald_dragons.cpp @@ -22,6 +22,7 @@ #include "SpellScript.h" #include "Spell.h" #include "SpellAuraEffects.h" +#include "PassiveAI.h" // // Emerald Dragon NPCs and IDs (kept here for reference) @@ -91,14 +92,12 @@ struct emerald_dragonAI : public WorldBossAI { emerald_dragonAI(Creature* creature) : WorldBossAI(creature) { -// me->m_CombatDistance = 12.0f; -// me->m_SightDistance = 60.0f; } void Reset() { - _Reset(); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE); + WorldBossAI::Reset(); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_AGGRESSIVE); DoCast(me, SPELL_MARK_OF_NATURE_AURA, true); events.ScheduleEvent(EVENT_TAIL_SWEEP, 4000); @@ -109,7 +108,8 @@ struct emerald_dragonAI : public WorldBossAI // Target killed during encounter, mark them as suspectible for Aura Of Nature void KilledUnit(Unit* who) { - who->CastSpell(who, SPELL_MARK_OF_NATURE, true); + if (who->GetTypeId() == TYPEID_PLAYER) + who->CastSpell(who, SPELL_MARK_OF_NATURE, true); } // Execute and reschedule base events shared between all Emerald Dragons @@ -216,109 +216,6 @@ class npc_dream_fog : public CreatureScript }; /* - * --- Spell: Dream Fog - */ - -class DreamFogTargetSelector -{ - public: - DreamFogTargetSelector() { } - - bool operator()(WorldObject* object) const - { - return object->ToUnit() && object->ToUnit()->HasAura(SPELL_SLEEP); - } -}; - -class spell_dream_fog_sleep : public SpellScriptLoader -{ - public: - spell_dream_fog_sleep() : SpellScriptLoader("spell_dream_fog_sleep") { } - - class spell_dream_fog_sleep_SpellScript : public SpellScript - { - PrepareSpellScript(spell_dream_fog_sleep_SpellScript); - - void FilterTargets(std::list<WorldObject*>& unitList) - { - unitList.remove_if(DreamFogTargetSelector()); - } - - void Register() - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dream_fog_sleep_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_dream_fog_sleep_SpellScript(); - } -}; - -/* - * --- Spell: Mark of Nature - */ - -class MarkOfNatureTargetSelector -{ - public: - MarkOfNatureTargetSelector() { } - - bool operator()(WorldObject* object) const - { - if (Unit* unit = object->ToUnit()) - // return anyone that isn't tagged or already under the influence of Aura of Nature - return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE)); - return true; - } -}; - -class spell_mark_of_nature : public SpellScriptLoader -{ - public: - spell_mark_of_nature() : SpellScriptLoader("spell_mark_of_nature") { } - - class spell_mark_of_nature_SpellScript : public SpellScript - { - PrepareSpellScript(spell_mark_of_nature_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) - { - if (!sSpellMgr->GetSpellInfo(SPELL_MARK_OF_NATURE)) - return false; - if (!sSpellMgr->GetSpellInfo(SPELL_AURA_OF_NATURE)) - return false; - return true; - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove_if(MarkOfNatureTargetSelector()); - } - - void HandleEffect(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - - if (GetHitUnit()) - GetHitUnit()->CastSpell(GetHitUnit(), SPELL_AURA_OF_NATURE, true); - } - - void Register() - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_mark_of_nature_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); - } - }; - - SpellScript* GetSpellScript() const - { - return new spell_mark_of_nature_SpellScript(); - } -}; - -/* * --- * --- Dragonspecific scripts and handling: YSONDRE * --- @@ -355,7 +252,6 @@ class boss_ysondre : public CreatureScript void Reset() { _stage = 1; - _Reset(); emerald_dragonAI::Reset(); events.ScheduleEvent(EVENT_LIGHTNING_WAVE, 12000); } @@ -394,7 +290,7 @@ class boss_ysondre : public CreatureScript } private: - uint8 _stage; + uint8 _stage; }; CreatureAI* GetAI(Creature* creature) const @@ -409,8 +305,6 @@ class boss_ysondre : public CreatureScript * --- * * TODO: - * - NPC helper for spirit shades(?) - * - Spirit shade NPC moves towards Lethon and heals him if close enough (each shade heals for 15000 HP) * - Spell: Shadow bolt whirl casts needs custom handling (spellscript) */ @@ -424,7 +318,12 @@ enum LethonSpells { SPELL_DRAW_SPIRIT = 24811, SPELL_SHADOW_BOLT_WHIRL = 24834, - SPELL_SPIRIT_SHADE_VISUAL = 24908, + SPELL_DARK_OFFERING = 24804, +}; + +enum LethonCreatures +{ + NPC_SPIRIT_SHADE = 15261, }; class boss_lethon : public CreatureScript @@ -441,7 +340,6 @@ class boss_lethon : public CreatureScript void Reset() { _stage = 1; - _Reset(); emerald_dragonAI::Reset(); events.ScheduleEvent(EVENT_SHADOW_BOLT_WHIRL, 10000); } @@ -462,12 +360,22 @@ class boss_lethon : public CreatureScript } } + void SpellHitTarget(Unit* target, SpellInfo const* spell) + { + if (spell->Id == SPELL_DRAW_SPIRIT && target->GetTypeId() == TYPEID_PLAYER) + { + Position targetPos; + target->GetPosition(&targetPos); + me->GetMap()->SummonCreature(NPC_SPIRIT_SHADE, targetPos, NULL, 50000, (Unit*)this); + } + } + void ExecuteEvent(uint32 const eventId) { switch (eventId) { case EVENT_SHADOW_BOLT_WHIRL: - DoCast(me, SPELL_SHADOW_BOLT_WHIRL, true); + me->CastSpell((Unit*)NULL, SPELL_SHADOW_BOLT_WHIRL, false); events.ScheduleEvent(EVENT_SHADOW_BOLT_WHIRL, urand(15000, 30000)); break; default: @@ -477,7 +385,7 @@ class boss_lethon : public CreatureScript } private: - uint8 _stage; + uint8 _stage; }; CreatureAI* GetAI(Creature* creature) const @@ -486,6 +394,42 @@ class boss_lethon : public CreatureScript } }; +class npc_spirit_shade : public CreatureScript +{ + public: + npc_spirit_shade() : CreatureScript("npc_spirit_shade") { } + + struct npc_spirit_shadeAI : public PassiveAI + { + npc_spirit_shadeAI(Creature* creature) : PassiveAI(creature), _summonerGuid(0) + { + } + + void IsSummonedBy(Unit* summoner) + { + _summonerGuid = summoner->GetGUID(); + me->GetMotionMaster()->MoveFollow(summoner, 0.0f, 0.0f); + } + + void MovementInform(uint32 moveType, uint32 data) + { + if (moveType == FOLLOW_MOTION_TYPE && data == _summonerGuid) + { + me->CastSpell((Unit*)NULL, SPELL_DARK_OFFERING, false); + me->DespawnOrUnsummon(1000); + } + } + + private: + uint64 _summonerGuid; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_spirit_shadeAI(creature); + } +}; + /* * --- * --- Dragonspecific scripts and handling: EMERISS @@ -519,7 +463,6 @@ class boss_emeriss : public CreatureScript void Reset() { _stage = 1; - _Reset(); emerald_dragonAI::Reset(); events.ScheduleEvent(EVENT_VOLATILE_INFECTION, 12000); } @@ -562,7 +505,7 @@ class boss_emeriss : public CreatureScript } private: - uint8 _stage; + uint8 _stage; }; CreatureAI* GetAI(Creature* creature) const @@ -607,10 +550,6 @@ class boss_taerar : public CreatureScript { boss_taerarAI(Creature* creature) : emerald_dragonAI(creature) { - _stage = 1; - _shades = 0; - _banished = false; - _banishedTimer = 0; } void Reset() @@ -622,7 +561,6 @@ class boss_taerar : public CreatureScript _banished = false; _banishedTimer = 0; - _Reset(); emerald_dragonAI::Reset(); events.ScheduleEvent(EVENT_ARCANE_BLAST, 12000); events.ScheduleEvent(EVENT_BELLOWING_ROAR, 30000); @@ -655,11 +593,11 @@ class boss_taerar : public CreatureScript uint32 count = sizeof(TaerarShadeSpells) / sizeof(uint32); for (uint32 i = 0; i < count; ++i) - DoCastVictim(TaerarShadeSpells[i], true); + DoCast(me->getVictim(), TaerarShadeSpells[i], true); _shades += count; DoCast(SPELL_SHADE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); me->SetReactState(REACT_PASSIVE); ++_stage; @@ -696,7 +634,7 @@ class boss_taerar : public CreatureScript { _banished = false; - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); me->RemoveAurasDueToSpell(SPELL_SHADE); me->SetReactState(REACT_AGGRESSIVE); } @@ -714,10 +652,10 @@ class boss_taerar : public CreatureScript } private: - bool _banished; // used for shades activation testing - uint32 _banishedTimer; // counter for banishment timeout - uint8 _shades; // keep track of how many shades are dead - uint8 _stage; // check which "shade phase" we're at (75-50-25 percentage counters) + bool _banished; // used for shades activation testing + uint32 _banishedTimer; // counter for banishment timeout + uint8 _shades; // keep track of how many shades are dead + uint8 _stage; // check which "shade phase" we're at (75-50-25 percentage counters) }; CreatureAI* GetAI(Creature* creature) const @@ -726,18 +664,122 @@ class boss_taerar : public CreatureScript } }; +/* + * --- Spell: Dream Fog + */ + +class DreamFogTargetSelector +{ + public: + DreamFogTargetSelector() { } + + bool operator()(WorldObject* object) + { + if (Unit* unit = object->ToUnit()) + return unit->HasAura(SPELL_SLEEP); + return true; + } +}; + +class spell_dream_fog_sleep : public SpellScriptLoader +{ + public: + spell_dream_fog_sleep() : SpellScriptLoader("spell_dream_fog_sleep") { } + + class spell_dream_fog_sleep_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dream_fog_sleep_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(DreamFogTargetSelector()); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dream_fog_sleep_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_dream_fog_sleep_SpellScript(); + } +}; + +/* + * --- Spell: Mark of Nature + */ + +class MarkOfNatureTargetSelector +{ + public: + MarkOfNatureTargetSelector() { } + + bool operator()(WorldObject* object) + { + // return those not tagged or already under the influence of Aura of Nature + if (Unit* unit = object->ToUnit()) + return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE)); + return true; + } +}; + +class spell_mark_of_nature : public SpellScriptLoader +{ + public: + spell_mark_of_nature() : SpellScriptLoader("spell_mark_of_nature") { } + + class spell_mark_of_nature_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mark_of_nature_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_MARK_OF_NATURE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_AURA_OF_NATURE)) + return false; + return true; + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(MarkOfNatureTargetSelector()); + } + + void HandleEffect(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_AURA_OF_NATURE, true); + } + + void Register() + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_mark_of_nature_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_mark_of_nature_SpellScript(); + } +}; + void AddSC_emerald_dragons() { // helper NPC scripts new npc_dream_fog(); - - // dragon spellscripts - new spell_dream_fog_sleep(); - new spell_mark_of_nature(); + new npc_spirit_shade(); // dragons new boss_ysondre(); new boss_taerar(); new boss_emeriss(); new boss_lethon(); + + // dragon spellscripts + new spell_dream_fog_sleep(); + new spell_mark_of_nature(); }; diff --git a/src/server/scripts/World/npc_taxi.cpp b/src/server/scripts/World/npc_taxi.cpp index efdd4da73d6..18f776e7171 100644 --- a/src/server/scripts/World/npc_taxi.cpp +++ b/src/server/scripts/World/npc_taxi.cpp @@ -51,8 +51,6 @@ EndScriptData #define GOSSIP_TARIOLSTRASZ2 "Can you spare a drake to travel to Lord Of Afrasastrasz, in the middle of the temple?" #define GOSSIP_TORASTRASZA1 "I would like to see Lord Of Afrasastrasz, in the middle of the temple." #define GOSSIP_TORASTRASZA2 "Yes, Please. I would like to return to the ground floor of the temple." -#define GOSSIP_CAMILLE1 "I need to fly to the Windrunner Official business!" -#define GOSSIP_CAMILLE2 "<The riding bat for the special task is necessary to me.>" #define GOSSIP_CRIMSONWING "<Ride the gryphons to Survey Alcaz Island>" #define GOSSIP_THRICESTAR1 "Do you think I could take a ride on one of those flying machines?" #define GOSSIP_THRICESTAR2 "Kara, I need to be flown out the Dens of Dying to find Bixie." @@ -159,12 +157,6 @@ public: // top -> ground player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_TORASTRASZA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 22); break; - case 23816: // Howling Fjord - Bat Handler Camille - if (!player->GetQuestRewardStatus(11229)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CAMILLE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 23); - if (player->GetQuestStatus(11170) == QUEST_STATUS_INCOMPLETE) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CAMILLE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 24); - break; case 23704: // Dustwallow Marsh - Cassa Crimsonwing if (player->GetQuestStatus(11142) == QUEST_STATUS_INCOMPLETE) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_CRIMSONWING, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+25); |
