diff options
Diffstat (limited to 'src/server/scripts')
36 files changed, 842 insertions, 248 deletions
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index ae3250ad7b7..bcef7ac9ba9 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -81,8 +81,13 @@ public: return false; } - // No SQL injection - LoginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'", expansion, accountId); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_EXPANSION); + + stmt->setUInt8(0, uint8(expansion)); + stmt->setUInt32(1, accountId); + + LoginDatabase.Execute(stmt); + handler->PSendSysMessage(LANG_ACCOUNT_ADDON, expansion); return true; } @@ -242,17 +247,25 @@ public: } std::string param = (char*)args; - if (param == "on") - { - LoginDatabase.PExecute("UPDATE account SET locked = '1' WHERE id = '%d'", handler->GetSession()->GetAccountId()); - handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED); - return true; - } - if (param == "off") + if (!param.empty()) { - LoginDatabase.PExecute("UPDATE account SET locked = '0' WHERE id = '%d'", handler->GetSession()->GetAccountId()); - handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPDATE_ACCOUNT_LOCK); + + if (param == "on") + { + stmt->setBool(0, true); // locked + handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED); + } + else if (param == "off") + { + stmt->setBool(0, false); // unlocked + handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED); + } + + stmt->setUInt32(1, handler->GetSession()->GetAccountId()); + + LoginDatabase.Execute(stmt); return true; } diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 28bc17a7450..c32abb9537b 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -1129,7 +1129,12 @@ public: uint16 drunkMod = drunklevel * 0xFFFF / 100; - handler->GetSession()->GetPlayer()->SetDrunkValue(drunkMod); + Player* target = handler->getSelectedPlayer(); + if (!target) + target = handler->GetSession()->GetPlayer(); + + if (target) + target->SetDrunkValue(drunkMod); return true; } diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index b9ac21cc040..a5aa2a516f3 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -552,15 +552,13 @@ public: handler->PSendSysMessage(LANG_NPCINFO_PHASEMASK, target->GetPhaseMask()); handler->PSendSysMessage(LANG_NPCINFO_ARMOR, target->GetArmor()); handler->PSendSysMessage(LANG_NPCINFO_POSITION, float(target->GetPositionX()), float(target->GetPositionY()), float(target->GetPositionZ())); + handler->PSendSysMessage(LANG_NPCINFO_AIINFO, target->GetAIName().c_str(), target->GetScriptName().c_str()); - if ((npcflags & UNIT_NPC_FLAG_VENDOR)) - { + if (npcflags & UNIT_NPC_FLAG_VENDOR) handler->SendSysMessage(LANG_NPCINFO_VENDOR); - } - if ((npcflags & UNIT_NPC_FLAG_TRAINER)) - { + + if (npcflags & UNIT_NPC_FLAG_TRAINER) handler->SendSysMessage(LANG_NPCINFO_TRAINER); - } return true; } diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp index ebd30aa2f5d..8179c9fccaa 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter2.cpp @@ -248,7 +248,7 @@ public: me->Mount(MODEL_DEATH_KNIGHT_MOUNT); break; case 10: - me->Unmount(); + me->Dismount(); break; } } @@ -378,7 +378,7 @@ public: void EnterCombat(Unit* /*who*/) { DoScriptText(SAY_TREE2, me); - me->Unmount(); + me->Dismount(); uiStage = 0; } diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp index 18316d67cd4..3ee71ce3609 100644 --- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter5.cpp @@ -526,13 +526,13 @@ public: NPCChangeTarget(uiOrbazGUID); NPCChangeTarget(uiThassarianGUID); - me->Unmount(); + me->Dismount(); me->CastSpell(me, SPELL_THE_MIGHT_OF_MOGRAINE, true); // need to fix, on player only if (Creature* temp = Unit::GetCreature(*me, uiKoltiraGUID)) - temp->Unmount(); + temp->Dismount(); if (Creature* temp = Unit::GetCreature(*me, uiThassarianGUID)) - temp->Unmount(); + temp->Dismount(); bIsBattle = true; break; diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp index f45c943b0f1..7dc357f692a 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp @@ -149,7 +149,7 @@ class boss_mandokir : public CreatureScript if (!CombatStart) { //At combat Start Mandokir is mounted so we must unmount it first - me->Unmount(); + me->Dismount(); //And summon his raptor me->SummonCreature(14988, me->getVictim()->GetPositionX(), me->getVictim()->GetPositionY(), me->getVictim()->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 35000); diff --git a/src/server/scripts/EasternKingdoms/blasted_lands.cpp b/src/server/scripts/EasternKingdoms/blasted_lands.cpp index 048fd8dfd2a..38a577b9ba9 100644 --- a/src/server/scripts/EasternKingdoms/blasted_lands.cpp +++ b/src/server/scripts/EasternKingdoms/blasted_lands.cpp @@ -72,6 +72,13 @@ public: /*###### ## npc_fallen_hero_of_horde ######*/ + +enum HeroesOfOld +{ + QUEST_HEROES_OF_OLD = 2702, + NPC_THUND_SPLITHOOF = 7750, +}; + #define GOSSIP_H_F1 "Why are you here?" #define GOSSIP_H_F2 "Continue story..." @@ -159,6 +166,14 @@ public: return true; } + bool OnQuestAccept(Player* /*player*/, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_HEROES_OF_OLD) + creature->SummonCreature(NPC_THUND_SPLITHOOF, -10630.3f, -2987.05f, 28.96f, 4.54f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 9000000); + + return true; + } + }; void AddSC_blasted_lands() diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp index 1a43472365a..798ea3925dc 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_mal_ganis.cpp @@ -34,7 +34,8 @@ enum Spells H_SPELL_MIND_BLAST = 58850, SPELL_SLEEP = 52721, //Puts an enemy to sleep for up to 10 sec. Any damage caused will awaken the target. H_SPELL_SLEEP = 58849, - SPELL_VAMPIRIC_TOUCH = 52723 //Heals the caster for half the damage dealt by a melee attack. + SPELL_VAMPIRIC_TOUCH = 52723, //Heals the caster for half the damage dealt by a melee attack. + SPELL_KILL_CREDIT = 58630 // Non-existing spell as encounter credit, created in spell_dbc }; enum Yells @@ -237,9 +238,8 @@ public: { instance->SetData(DATA_MAL_GANIS_EVENT, DONE); - // give achievement credit to players. criteria use spell 58630 which doesn't exist. - if (instance) - instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, 58630); + // give achievement credit and LFG rewards to players. criteria use spell 58630 which doesn't exist, but it was created in spell_dbc + DoCast(me, SPELL_KILL_CREDIT); } } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp index 82f16dd7784..7cbb1b91755 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp @@ -582,7 +582,7 @@ public: { Unit* pJaina = GetClosestCreatureWithEntry(me, NPC_JAINA, 50.0f); if (!pJaina) - pJaina = pJaina = me->SummonCreature(NPC_JAINA, 1895.48f, 1292.66f, 143.706f, 0.023475f, TEMPSUMMON_DEAD_DESPAWN, 180000); + pJaina = me->SummonCreature(NPC_JAINA, 1895.48f, 1292.66f, 143.706f, 0.023475f, TEMPSUMMON_DEAD_DESPAWN, 180000); if (pJaina) uiJainaGUID = pJaina->GetGUID(); bStepping = false; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp index 1f0342b3804..65ae3287381 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.cpp @@ -498,7 +498,7 @@ public: } void DoUnmount() { - me->Unmount(); + me->Dismount(); me->SetSpeed(MOVE_RUN, SPEED_RUN); } void EnterCombat(Unit* /*who*/) diff --git a/src/server/scripts/Kalimdor/desolace.cpp b/src/server/scripts/Kalimdor/desolace.cpp index 71372f1d9e4..5badc7fe725 100644 --- a/src/server/scripts/Kalimdor/desolace.cpp +++ b/src/server/scripts/Kalimdor/desolace.cpp @@ -25,6 +25,9 @@ EndScriptData */ /* ContentData npc_aged_dying_ancient_kodo +go_iruxos +npc_dalinda_malem +go_demon_portal EndContentData */ #include "ScriptPCH.h" @@ -168,22 +171,28 @@ public: }; /*###### -## go_iruxos. Quest 5381 +## go_iruxos +## Hand of Iruxos ######*/ +enum +{ + QUEST_HAND_IRUXOS = 5381, + NPC_DEMON_SPIRIT = 11876, +}; + class go_iruxos : public GameObjectScript { -public: - go_iruxos() : GameObjectScript("go_iruxos") { } + public: + go_iruxos() : GameObjectScript("go_iruxos") { } - bool OnGossipHello(Player* player, GameObject* /*pGO*/) - { - if (player->GetQuestStatus(5381) == QUEST_STATUS_INCOMPLETE) - player->SummonCreature(11876, player->GetInnPosX(), player->GetInnPosY(), player->GetInnPosZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); + bool OnGossipHello(Player* player, GameObject* go) + { + if (player->GetQuestStatus(QUEST_HAND_IRUXOS) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_SPIRIT, 25.0f, true)) + player->SummonCreature(NPC_DEMON_SPIRIT, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); return true; - } - + } }; /*###### @@ -254,7 +263,34 @@ public: DoMeleeAttackIfReady(); } }; +}; + +/*###### +## go_demon_portal +######*/ +enum DemonPortal +{ + NPC_DEMON_GUARDIAN = 11937, + + QUEST_PORTAL_OF_THE_LEGION = 5581, +}; + +class go_demon_portal : public GameObjectScript +{ + public: + go_demon_portal() : GameObjectScript("go_demon_portal") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (player->GetQuestStatus(QUEST_PORTAL_OF_THE_LEGION) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_GUARDIAN, 5.0f, true)) + { + if (Creature* guardian = player->SummonCreature(NPC_DEMON_GUARDIAN, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_DEAD_DESPAWN, 0)) + guardian->AI()->AttackStart(player); + } + + return true; + } }; void AddSC_desolace() @@ -262,4 +298,5 @@ void AddSC_desolace() new npc_aged_dying_ancient_kodo(); new go_iruxos(); new npc_dalinda(); + new go_demon_portal(); } diff --git a/src/server/scripts/Kalimdor/durotar.cpp b/src/server/scripts/Kalimdor/durotar.cpp index 1f64353901c..d6d2d633890 100644 --- a/src/server/scripts/Kalimdor/durotar.cpp +++ b/src/server/scripts/Kalimdor/durotar.cpp @@ -400,7 +400,7 @@ class npc_troll_volunteer : public CreatureScript DoCast(me, SPELL_TURNIN); DoCast(me, SPELL_QUEST_CREDIT); me->RemoveAurasDueToSpell(SPELL_MOUNTING_CHECK); - me->Unmount(); + me->Dismount(); Talk(SAY_VOLUNTEER_END); me->GetMotionMaster()->MovePoint(POINT_URUZIN, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ()); } @@ -447,7 +447,7 @@ class spell_mount_check : public SpellScriptLoader target->Mount(mountid); } else if (!owner->IsMounted() && target->IsMounted()) - target->Unmount(); + target->Dismount(); target->SetSpeed(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN)); target->SetSpeed(MOVE_WALK, owner->GetSpeedRate(MOVE_WALK)); diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp index 545dc79453d..e0892ffb009 100644 --- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp @@ -91,49 +91,50 @@ public: struct boss_anub_arakAI : public ScriptedAI { - boss_anub_arakAI(Creature* c) : ScriptedAI(c), lSummons(me) + boss_anub_arakAI(Creature* creature) : ScriptedAI(creature), Summons(me) { - instance = c->GetInstanceScript(); + instance = creature->GetInstanceScript(); } InstanceScript* instance; - bool bChanneling; - bool bGuardianSummoned; - bool bVenomancerSummoned; - bool bDatterSummoned; - uint8 uiPhase; - uint32 uiUndergroundPhase; - uint32 uiCarrionBeetlesTimer; - uint32 uiLeechingSwarmTimer; - uint32 uiPoundTimer; - uint32 uiSubmergeTimer; - uint32 uiUndergroundTimer; - uint32 uiVenomancerTimer; - uint32 uiDatterTimer; - - uint32 uiImpaleTimer; - uint32 uiImpalePhase; - uint64 uiImpaleTarget; - - SummonList lSummons; + bool Channeling; + bool GuardianSummoned; + bool VenomancerSummoned; + bool DatterSummoned; + uint8 Phase; + uint32 UndergroundPhase; + uint32 CarrionBeetlesTimer; + uint32 LeechingSwarmTimer; + uint32 PoundTimer; + uint32 SubmergeTimer; + uint32 UndergroundTimer; + uint32 VenomancerTimer; + uint32 DatterTimer; + uint32 DelayTimer; + + uint32 ImpaleTimer; + uint32 ImpalePhase; + uint64 ImpaleTarget; + + SummonList Summons; void Reset() { - uiCarrionBeetlesTimer = 8*IN_MILLISECONDS; - uiLeechingSwarmTimer = 20*IN_MILLISECONDS; - uiImpaleTimer = 9*IN_MILLISECONDS; - uiPoundTimer = 15*IN_MILLISECONDS; + CarrionBeetlesTimer = 8*IN_MILLISECONDS; + LeechingSwarmTimer = 20*IN_MILLISECONDS; + ImpaleTimer = 9*IN_MILLISECONDS; + PoundTimer = 15*IN_MILLISECONDS; - uiPhase = PHASE_MELEE; - uiUndergroundPhase = 0; - bChanneling = false; - uiImpalePhase = IMPALE_PHASE_TARGET; + Phase = PHASE_MELEE; + UndergroundPhase = 0; + Channeling = false; + ImpalePhase = IMPALE_PHASE_TARGET; me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); me->RemoveAura(SPELL_SUBMERGE); - lSummons.DespawnAll(); + Summons.DespawnAll(); if (instance) { @@ -147,13 +148,13 @@ public: Position targetPos; target->GetPosition(&targetPos); - if (TempSummon* pImpaleTarget = me->SummonCreature(CREATURE_IMPALE_TARGET, targetPos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 6*IN_MILLISECONDS)) + if (TempSummon* impaleTarget = me->SummonCreature(CREATURE_IMPALE_TARGET, targetPos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 6*IN_MILLISECONDS)) { - uiImpaleTarget = pImpaleTarget->GetGUID(); - pImpaleTarget->SetReactState(REACT_PASSIVE); - pImpaleTarget->SetDisplayId(DISPLAY_INVISIBLE); - pImpaleTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); - return pImpaleTarget; + ImpaleTarget = impaleTarget->GetGUID(); + impaleTarget->SetReactState(REACT_PASSIVE); + impaleTarget->SetDisplayId(DISPLAY_INVISIBLE); + impaleTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE|UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); + return impaleTarget; } return NULL; @@ -162,11 +163,15 @@ public: void EnterCombat(Unit* /*who*/) { DoScriptText(SAY_AGGRO, me); + DelayTimer = 0; if (instance) - { - instance->SetData(DATA_ANUBARAK_EVENT, IN_PROGRESS); instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT); - } + } + + void DelayEventStart() + { + if (instance) + instance->SetData(DATA_ANUBARAK_EVENT, IN_PROGRESS); } void UpdateAI(const uint32 diff) @@ -174,41 +179,45 @@ public: if (!UpdateVictim()) return; - switch (uiPhase) + if (DelayTimer && DelayTimer > 5000) + DelayEventStart(); + else DelayTimer+=diff; + + switch (Phase) { case PHASE_UNDERGROUND: - if (uiImpaleTimer <= diff) + if (ImpaleTimer <= diff) { - switch (uiImpalePhase) + switch (ImpalePhase) { case IMPALE_PHASE_TARGET: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) { - if (Creature* pImpaleTarget = DoSummonImpaleTarget(target)) - pImpaleTarget->CastSpell(pImpaleTarget, SPELL_IMPALE_SHAKEGROUND, true); - uiImpaleTimer = 3*IN_MILLISECONDS; - uiImpalePhase = IMPALE_PHASE_ATTACK; + if (Creature* impaleTarget = DoSummonImpaleTarget(target)) + impaleTarget->CastSpell(impaleTarget, SPELL_IMPALE_SHAKEGROUND, true); + ImpaleTimer = 3*IN_MILLISECONDS; + ImpalePhase = IMPALE_PHASE_ATTACK; } break; case IMPALE_PHASE_ATTACK: - if (Creature* pImpaleTarget = Unit::GetCreature(*me, uiImpaleTarget)) + if (Creature* impaleTarget = Unit::GetCreature(*me, ImpaleTarget)) { - pImpaleTarget->CastSpell(pImpaleTarget, SPELL_IMPALE_SPIKE, false); - pImpaleTarget->RemoveAurasDueToSpell(SPELL_IMPALE_SHAKEGROUND); + impaleTarget->CastSpell(impaleTarget, SPELL_IMPALE_SPIKE, false); + impaleTarget->RemoveAurasDueToSpell(SPELL_IMPALE_SHAKEGROUND); } - uiImpalePhase = IMPALE_PHASE_DMG; - uiImpaleTimer = 1*IN_MILLISECONDS; + ImpalePhase = IMPALE_PHASE_DMG; + ImpaleTimer = 1*IN_MILLISECONDS; break; case IMPALE_PHASE_DMG: - if (Creature* pImpaleTarget = Unit::GetCreature(*me, uiImpaleTarget)) - me->CastSpell(pImpaleTarget, DUNGEON_MODE(SPELL_IMPALE_DMG, SPELL_IMPALE_DMG_H), true); - uiImpalePhase = IMPALE_PHASE_TARGET; - uiImpaleTimer = 9*IN_MILLISECONDS; + if (Creature* impaleTarget = Unit::GetCreature(*me, ImpaleTarget)) + me->CastSpell(impaleTarget, DUNGEON_MODE(SPELL_IMPALE_DMG, SPELL_IMPALE_DMG_H), true); + ImpalePhase = IMPALE_PHASE_TARGET; + ImpaleTimer = 9*IN_MILLISECONDS; break; } - } else uiImpaleTimer -= diff; + } else ImpaleTimer -= diff; - if (!bGuardianSummoned) + if (!GuardianSummoned) { for (uint8 i = 0; i < 2; ++i) { @@ -218,14 +227,14 @@ public: DoZoneInCombat(Guardian); } } - bGuardianSummoned = true; + GuardianSummoned = true; } - if (!bVenomancerSummoned) + if (!VenomancerSummoned) { - if (uiVenomancerTimer <= diff) + if (VenomancerTimer <= diff) { - if (uiUndergroundPhase > 1) + if (UndergroundPhase > 1) { for (uint8 i = 0; i < 2; ++i) { @@ -235,16 +244,16 @@ public: DoZoneInCombat(Venomancer); } } - bVenomancerSummoned = true; + VenomancerSummoned = true; } - } else uiVenomancerTimer -= diff; + } else VenomancerTimer -= diff; } - if (!bDatterSummoned) + if (!DatterSummoned) { - if (uiDatterTimer <= diff) + if (DatterTimer <= diff) { - if (uiUndergroundPhase > 2) + if (UndergroundPhase > 2) { for (uint8 i = 0; i < 2; ++i) { @@ -254,71 +263,74 @@ public: DoZoneInCombat(Datter); } } - bDatterSummoned = true; + DatterSummoned = true; } - } else uiDatterTimer -= diff; + } else DatterTimer -= diff; + + if(me->HasAura(SPELL_LEECHING_SWARM)) + me->RemoveAurasDueToSpell(SPELL_LEECHING_SWARM); } - if (uiUndergroundTimer <= diff) + if (UndergroundTimer <= diff) { me->RemoveAura(SPELL_SUBMERGE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); - uiPhase = PHASE_MELEE; - } else uiUndergroundTimer -= diff; + Phase = PHASE_MELEE; + } else UndergroundTimer -= diff; break; case PHASE_MELEE: - if (((uiUndergroundPhase == 0 && HealthBelowPct(75)) - || (uiUndergroundPhase == 1 && HealthBelowPct(50)) - || (uiUndergroundPhase == 2 && HealthBelowPct(25))) + if (((UndergroundPhase == 0 && HealthBelowPct(75)) + || (UndergroundPhase == 1 && HealthBelowPct(50)) + || (UndergroundPhase == 2 && HealthBelowPct(25))) && !me->HasUnitState(UNIT_STAT_CASTING)) { - bGuardianSummoned = false; - bVenomancerSummoned = false; - bDatterSummoned = false; + GuardianSummoned = false; + VenomancerSummoned = false; + DatterSummoned = false; - uiUndergroundTimer = 40*IN_MILLISECONDS; - uiVenomancerTimer = 25*IN_MILLISECONDS; - uiDatterTimer = 32*IN_MILLISECONDS; + UndergroundTimer = 40*IN_MILLISECONDS; + VenomancerTimer = 25*IN_MILLISECONDS; + DatterTimer = 32*IN_MILLISECONDS; - uiImpalePhase = 0; - uiImpaleTimer = 9*IN_MILLISECONDS; + ImpalePhase = 0; + ImpaleTimer = 9*IN_MILLISECONDS; DoCast(me, SPELL_SUBMERGE, false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE); - uiPhase = PHASE_UNDERGROUND; - ++uiUndergroundPhase; + Phase = PHASE_UNDERGROUND; + ++UndergroundPhase; } - if (bChanneling == true) + if (Channeling == true) { for (uint8 i = 0; i < 8; ++i) DoCast(me->getVictim(), SPELL_SUMMON_CARRION_BEETLES, true); - bChanneling = false; + Channeling = false; } - else if (uiCarrionBeetlesTimer <= diff) + else if (CarrionBeetlesTimer <= diff) { - bChanneling = true; + Channeling = true; DoCastVictim(SPELL_CARRION_BEETLES); - uiCarrionBeetlesTimer = 25*IN_MILLISECONDS; - } else uiCarrionBeetlesTimer -= diff; + CarrionBeetlesTimer = 25*IN_MILLISECONDS; + } else CarrionBeetlesTimer -= diff; - if (uiLeechingSwarmTimer <= diff) + if (LeechingSwarmTimer <= diff) { DoCast(me, SPELL_LEECHING_SWARM, true); - uiLeechingSwarmTimer = 19*IN_MILLISECONDS; - } else uiLeechingSwarmTimer -= diff; + LeechingSwarmTimer = 19*IN_MILLISECONDS; + } else LeechingSwarmTimer -= diff; - if (uiPoundTimer <= diff) + if (PoundTimer <= diff) { if (Unit* target = me->getVictim()) { if (Creature* pImpaleTarget = DoSummonImpaleTarget(target)) me->CastSpell(pImpaleTarget, DUNGEON_MODE(SPELL_POUND, SPELL_POUND_H), false); } - uiPoundTimer = 16500; - } else uiPoundTimer -= diff; + PoundTimer = 16500; + } else PoundTimer -= diff; DoMeleeAttackIfReady(); break; @@ -328,7 +340,7 @@ public: void JustDied(Unit* /*killer*/) { DoScriptText(SAY_DEATH, me); - lSummons.DespawnAll(); + Summons.DespawnAll(); if (instance) instance->SetData(DATA_ANUBARAK_EVENT, DONE); } @@ -342,7 +354,7 @@ public: void JustSummoned(Creature* summon) { - lSummons.Summon(summon); + Summons.Summon(summon); } }; diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp index fd84c1eec8a..f73e9779248 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_black_knight.cpp @@ -54,8 +54,10 @@ enum eSpells SPELL_BLACK_KNIGHT_RES = 67693, - SPELL_LEAP = 67749, - SPELL_LEAP_H = 67880 + SPELL_LEAP = 67749, + SPELL_LEAP_H = 67880, + + SPELL_KILL_CREDIT = 68663 }; enum eModels @@ -288,6 +290,8 @@ public: void JustDied(Unit* /*killer*/) { + DoCast(me, SPELL_KILL_CREDIT); + if (instance) instance->SetData(BOSS_BLACK_KNIGHT, DONE); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp index 2fbe381fed5..2f6a01e73d7 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp @@ -839,7 +839,8 @@ public: if (target && me->IsInRange(target, 5.0f, 30.0f, false)) { DoCast(target, SPELL_MULTI_SHOT); - } else + } + else { Map::PlayerList const& players = me->GetMap()->GetPlayers(); if (me->GetMap()->IsDungeon() && !players.isEmpty()) @@ -849,7 +850,7 @@ public: Player* player = itr->getSource(); if (player && !player->isGameMaster() && me->IsInRange(player, 5.0f, 30.0f, false)) { - DoCast(target, SPELL_MULTI_SHOT); + DoCast(player, SPELL_MULTI_SHOT); break; } } diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp index e552341fd1e..d877bbd0842 100644 --- a/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp +++ b/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp @@ -237,7 +237,8 @@ public: for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (Player* player = i->getSource()) player->DeMorph(); - instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, SPELL_ACHIEVEMENT_CHECK); + + DoCast(me, SPELL_ACHIEVEMENT_CHECK); instance->SetData(DATA_THARON_JA_EVENT, DONE); } diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp index eacb800f15a..1e29ec55dc8 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp @@ -215,7 +215,6 @@ class mob_corrupted_soul_fragment : public CreatureScript if (Creature* bronjahm = ObjectAccessor::GetCreature(*me, BronjahmGUID)) me->CastSpell(bronjahm, SPELL_CONSUME_SOUL, true); - summ->GetMotionMaster()->MoveIdle(); summ->UnSummon(); } } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index 29c3276467b..25610341a2f 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -341,7 +341,7 @@ class boss_sindragosa : public CreatureScript { if (uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(_isThirdPhase ? SPELL_FROST_BREATH_P2 : SPELL_FROST_BREATH_P1, me)) { - if (player->GetQuestStatus(QUEST_FROST_INFUSION) != QUEST_STATUS_REWARDED && spellId == spell->Id) + if (player->GetQuestStatus(QUEST_FROST_INFUSION) == QUEST_STATUS_INCOMPLETE && spellId == spell->Id) { if (Item* shadowsEdge = player->GetWeaponForAttack(BASE_ATTACK, true)) { diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp index 16c258af756..e63d50b0133 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp @@ -289,6 +289,7 @@ public: void JustDied(Unit* /*killer*/) { _JustDied(); + DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur } void LeaveCombat() diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp index f3384b7ec15..4dcd2618895 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp @@ -144,8 +144,8 @@ public: void JustDied(Unit* /*killer*/) { _JustDied(); - Talk(SAY_DEATH); + DoCast(me, SPELL_DEATH_SPELL, true); // we cast the spell as triggered or the summon effect does not occur } private: bool firstCoreEnergize; diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp index f8839aa0028..b9799103214 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp @@ -50,6 +50,12 @@ enum Drakes NPC_ETERNOS = 27659 }; +enum Says +{ + SAY_VAROS = 0, + SAY_UROM = 1 +}; + class npc_oculus_drake : public CreatureScript { public: @@ -174,7 +180,38 @@ public: }; +class npc_image_belgaristrasz : public CreatureScript +{ +public: + npc_image_belgaristrasz() : CreatureScript("npc_image_belgaristrasz") { } + + struct npc_image_belgaristraszAI : public ScriptedAI + { + npc_image_belgaristraszAI(Creature* creature) : ScriptedAI(creature) {} + + void IsSummonedBy(Unit* summoner) + { + if (summoner->GetEntry() == NPC_VAROS) + { + Talk(SAY_VAROS); + me->DespawnOrUnsummon(60000); + } + if (summoner->GetEntry() == NPC_UROM) + { + Talk(SAY_UROM); + me->DespawnOrUnsummon(60000); + } + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_image_belgaristraszAI(creature); + } +}; + void AddSC_oculus() { new npc_oculus_drake(); + new npc_image_belgaristrasz(); } diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.h b/src/server/scripts/Northrend/Nexus/Oculus/oculus.h index e04f2c8aab9..dab2821b5e5 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.h +++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.h @@ -71,6 +71,7 @@ enum OculusWorldStates enum OculusSpells { - SPELL_CENTRIFUGE_SHIELD = 50053 + SPELL_CENTRIFUGE_SHIELD = 50053, + SPELL_DEATH_SPELL = 50415 }; #endif diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp index e7d8b070e53..13c174a9607 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp @@ -526,7 +526,7 @@ class boss_freya : public CreatureScript { uint8 n = 0; - // Handling recieved data + // Handling received data for (uint8 i = 0; i < 5; ++i) // We have created "instances" for keeping informations about last 6 death lashers - needed because of respawning { deforestation[i][0] = deforestation[(i + 1)][0]; // Time @@ -590,7 +590,7 @@ class boss_freya : public CreatureScript waveCount++; } - void JustDied(Unit* who) + void JustDied(Unit* /*who*/) { //! Freya's chest is dynamically spawned on death by different spells. const uint32 summonSpell[2][4] = diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp index dc2d34326a7..3712bd748a5 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp @@ -173,7 +173,11 @@ public: DoScriptText(YELL_DEAD_2, me); if (instance) + { + // Ingvar has MOB_INGVAR_UNDEAD id in this moment, so we have to update encounter state for his original id + instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, MOB_INGVAR_HUMAN, me); instance->SetData(DATA_INGVAR_EVENT, DONE); + } } void KilledUnit(Unit* /*victim*/) diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp index 7b459e7410d..f31271b825e 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp @@ -218,7 +218,7 @@ public: void JustReachedHome() { me->SetFlying(false); - me->Unmount(); + me->Dismount(); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE); if (Unit::GetCreature((*me), m_uiGraufGUID) == NULL) me->SummonCreature(CREATURE_GRAUF, Location[0].GetPositionX(), Location[0].GetPositionY(), Location[0].GetPositionZ(), 3.0f); @@ -285,7 +285,7 @@ public: { Phase = SKADI; me->SetFlying(false); - me->Unmount(); + me->Dismount(); if (Creature* pGrauf = me->SummonCreature(CREATURE_GRAUF, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3*IN_MILLISECONDS)) { pGrauf->GetMotionMaster()->MoveFall(0); diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp index 4f837870612..5965c352975 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp @@ -303,9 +303,7 @@ class boss_warchief_kargath_bladefist : public CreatureScript if (resetcheck_timer <= diff) { - uint32 tempx, tempy; - tempx = uint32(me->GetPositionX()); - tempy = uint32(me->GetPositionY()); + uint32 tempx = uint32(me->GetPositionX()); if (tempx > 255 || tempx < 205) { EnterEvadeMode(); diff --git a/src/server/scripts/Outland/blades_edge_mountains.cpp b/src/server/scripts/Outland/blades_edge_mountains.cpp index f94a7d2725c..87304a3f721 100644 --- a/src/server/scripts/Outland/blades_edge_mountains.cpp +++ b/src/server/scripts/Outland/blades_edge_mountains.cpp @@ -30,6 +30,7 @@ npc_daranelle npc_overseer_nuaar npc_saikkal_the_elder go_legion_obelisk +go_thunderspike EndContentData */ #include "ScriptPCH.h" @@ -537,9 +538,30 @@ public: }; /*###### -## AddSC +## go_thunderspike ######*/ +enum TheThunderspike +{ + NPC_GOR_GRIMGUT = 21319, + QUEST_THUNDERSPIKE = 10526, +}; + +class go_thunderspike : public GameObjectScript +{ + public: + go_thunderspike() : GameObjectScript("go_thunderspike") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (player->GetQuestStatus(QUEST_THUNDERSPIKE) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_GOR_GRIMGUT, 25.0f, true)) + if (Creature* gorGrimgut = go->SummonCreature(NPC_GOR_GRIMGUT, -2413.4f, 6914.48f, 25.01f, 3.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000)) + gorGrimgut->AI()->AttackStart(player); + + return true; + } +}; + void AddSC_blades_edge_mountains() { new mobs_bladespire_ogre(); @@ -550,4 +572,5 @@ void AddSC_blades_edge_mountains() new go_legion_obelisk(); new npc_bloodmaul_brutebane(); new npc_ogre_brute(); + new go_thunderspike(); } diff --git a/src/server/scripts/Outland/nagrand.cpp b/src/server/scripts/Outland/nagrand.cpp index c556253ecf1..bae3aa65b98 100644 --- a/src/server/scripts/Outland/nagrand.cpp +++ b/src/server/scripts/Outland/nagrand.cpp @@ -573,7 +573,7 @@ public: { Talk(SAY_KUR_MORE); - if (Creature* temp = me->SummonCreature(NPC_KUR_MURK_PUTRIFIER, kurenaiAmbushB[0], kurenaiAmbushB[1], kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000)) + if (me->SummonCreature(NPC_KUR_MURK_PUTRIFIER, kurenaiAmbushB[0], kurenaiAmbushB[1], kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000)) Talk(SAY_KUR_MORE_TWO); me->SummonCreature(NPC_KUR_MURK_PUTRIFIER, kurenaiAmbushB[0]-2.5f, kurenaiAmbushB[1]-2.5f, kurenaiAmbushB[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000); diff --git a/src/server/scripts/Outland/netherstorm.cpp b/src/server/scripts/Outland/netherstorm.cpp index 5f2626c0039..e5ee8d19c59 100644 --- a/src/server/scripts/Outland/netherstorm.cpp +++ b/src/server/scripts/Outland/netherstorm.cpp @@ -29,6 +29,7 @@ go_manaforge_control_console npc_commander_dawnforge npc_bessy npc_maxx_a_million +go_captain_tyralius_prison EndContentData */ #include "ScriptPCH.h" @@ -1046,6 +1047,36 @@ public: } }; +/*###### +## go_captain_tyralius_prison +######*/ + +enum CaptainTyralius +{ + NPC_CAPTAIN_TYRALIUS = 20787, + SAY_FREE = 0, +}; + +class go_captain_tyralius_prison : public GameObjectScript +{ + public: + go_captain_tyralius_prison() : GameObjectScript("go_captain_tyralius_prison") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (Creature* tyralius = go->FindNearestCreature(NPC_CAPTAIN_TYRALIUS, 1.0f)) + { + go->UseDoorOrButton(); + + player->KilledMonsterCredit(NPC_CAPTAIN_TYRALIUS, 0); + + tyralius->AI()->Talk(SAY_FREE); + tyralius->ForcedDespawn(8000); + } + return true; + } +}; + void AddSC_netherstorm() { new go_manaforge_control_console(); @@ -1056,4 +1087,5 @@ void AddSC_netherstorm() new mob_phase_hunter(); new npc_bessy(); new npc_maxx_a_million_escort(); + new go_captain_tyralius_prison(); } diff --git a/src/server/scripts/Outland/shadowmoon_valley.cpp b/src/server/scripts/Outland/shadowmoon_valley.cpp index 610cf684a77..ecbdb921567 100644 --- a/src/server/scripts/Outland/shadowmoon_valley.cpp +++ b/src/server/scripts/Outland/shadowmoon_valley.cpp @@ -635,26 +635,31 @@ public: # npc_karynaku ####*/ -enum eKarynaku +enum Karynaku { QUEST_ALLY_OF_NETHER = 10870, + QUEST_ZUHULED_THE_WACK = 10866, - TAXI_PATH_ID = 649 + NPC_ZUHULED_THE_WACKED = 11980, + + TAXI_PATH_ID = 649, }; class npc_karynaku : public CreatureScript { -public: - npc_karynaku() : CreatureScript("npc_karynaku") { } + public: + npc_karynaku() : CreatureScript("npc_karynaku") { } - bool OnQuestAccept(Player* player, Creature* /*creature*/, Quest const* quest) - { - if (quest->GetQuestId() == QUEST_ALLY_OF_NETHER) - player->ActivateTaxiPathTo(TAXI_PATH_ID); //player->ActivateTaxiPathTo(649); + bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) + { + if (quest->GetQuestId() == QUEST_ALLY_OF_NETHER) + player->ActivateTaxiPathTo(TAXI_PATH_ID); - return true; - } + if (quest->GetQuestId() == QUEST_ZUHULED_THE_WACK) + creature->SummonCreature(NPC_ZUHULED_THE_WACKED, -4204.94f, 316.397f, 122.508f, 1.309f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000); + return true; + } }; /*#### diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 260b0c57563..298e9b6410e 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -26,6 +26,8 @@ #include "SpellAuraEffects.h" #include "SkillDiscovery.h" #include "GridNotifiers.h" +#include "Group.h" +#include "LFGMgr.h" class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader { @@ -564,6 +566,9 @@ class spell_creature_permanent_feign_death : public SpellScriptLoader Unit* target = GetTarget(); target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); + + if (target->GetTypeId() == TYPEID_UNIT) + target->ToCreature()->SetReactState(REACT_PASSIVE); } void Register() @@ -1419,6 +1424,53 @@ public: } }; +class spell_gen_luck_of_the_draw : public SpellScriptLoader +{ + public: + spell_gen_luck_of_the_draw() : SpellScriptLoader("spell_gen_luck_of_the_draw") { } + + class spell_gen_luck_of_the_draw_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_luck_of_the_draw_AuraScript); + + // cheap hax to make it have update calls + void CalcPeriodic(AuraEffect const* /*effect*/, bool& isPeriodic, int32& amplitude) + { + isPeriodic = true; + amplitude = 5 * IN_MILLISECONDS; + } + + void Update(AuraEffect* /*effect*/) + { + if (GetUnitOwner()->GetTypeId() != TYPEID_PLAYER) + return; + + LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*(sLFGMgr->GetSelectedDungeons(GetUnitOwner()->GetGUID()).begin())); + Group* group = GetUnitOwner()->ToPlayer()->GetGroup(); + Map const* map = GetUnitOwner()->GetMap(); + if (group && group->isLFGGroup()) + if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true)) + if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId)) + if (dungeon->map == map->GetId() && dungeon->difficulty == map->GetDifficulty()) + if (randomDungeon && randomDungeon->type == LFG_TYPE_RANDOM) + return; // in correct dungeon + + Remove(AURA_REMOVE_BY_DEFAULT); + } + + void Register() + { + DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_gen_luck_of_the_draw_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_luck_of_the_draw_AuraScript::Update, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_gen_luck_of_the_draw_AuraScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -1451,4 +1503,5 @@ void AddSC_generic_spell_scripts() new spell_gen_vehicle_scaling(); new spell_gen_oracle_wolvar_reputation(); new spell_gen_damage_reduction_aura(); + new spell_gen_luck_of_the_draw(); } diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp index 3b2cc5f5e00..ecdbd582b76 100644 --- a/src/server/scripts/Spells/spell_quest.cpp +++ b/src/server/scripts/Spells/spell_quest.cpp @@ -1026,6 +1026,54 @@ public: } }; +// http://old01.wowhead.com/quest=9452 - Red Snapper - Very Tasty! +enum RedSnapperVeryTasty +{ + SPELL_CAST_NET = 29866, + ITEM_RED_SNAPPER = 23614, + NPC_ANGRY_MURLOC = 17102, +}; + +class spell_q9452_cast_net: public SpellScriptLoader +{ + public: + spell_q9452_cast_net() : SpellScriptLoader("spell_q9452_cast_net") { } + + class spell_q9452_cast_net_SpellScript : public SpellScript + { + PrepareSpellScript(spell_q9452_cast_net_SpellScript) + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Player* caster = GetCaster()->ToPlayer(); + + if (!caster) + return; + + switch (urand(0, 2)) + { + case 0: case 1: + caster->AddItem(ITEM_RED_SNAPPER, 1); + break; + case 2: + if (Creature* murloc = caster->SummonCreature(NPC_ANGRY_MURLOC, caster->GetPositionX()+5, caster->GetPositionY(), caster->GetPositionZ(), 0.0f, TEMPSUMMON_MANUAL_DESPAWN, 120000)) + murloc->AI()->AttackStart(caster); + break; + } + } + + void Register() + { + OnEffectHit += SpellEffectFn(spell_q9452_cast_net_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_q9452_cast_net_SpellScript(); + } +}; + void AddSC_quest_spell_scripts() { new spell_q55_sacred_cleansing(); @@ -1050,4 +1098,5 @@ void AddSC_quest_spell_scripts() new spell_q12805_lifeblood_dummy(); new spell_q13280_13283_plant_battle_standard(); new spell_q14112_14145_chum_the_water(); + new spell_q9452_cast_net(); } diff --git a/src/server/scripts/World/areatrigger_scripts.cpp b/src/server/scripts/World/areatrigger_scripts.cpp index 517746dac55..9e3e64f1860 100644 --- a/src/server/scripts/World/areatrigger_scripts.cpp +++ b/src/server/scripts/World/areatrigger_scripts.cpp @@ -29,6 +29,9 @@ at_legion_teleporter 4560 Teleporter TO Invasion Point: Cataclysm at_stormwright_shelf q12741 at_last_rites q12019 at_sholazar_waygate q12548 +at_nats_landing q11209 +at_bring_your_orphan_to q910 q910 q1800 q1479 q1687 q1558 q10951 q10952 +at_brewfest EndContentData */ #include "ScriptPCH.h" @@ -257,6 +260,166 @@ class AreaTrigger_at_sholazar_waygate : public AreaTriggerScript } }; +/*###### +## at_nats_landing +######*/ + +enum NatsLanding +{ + QUEST_NATS_BARGAIN = 11209, + SPELL_FISH_PASTE = 42644, + NPC_LURKING_SHARK = 23928 +}; + +class AreaTrigger_at_nats_landing : public AreaTriggerScript +{ + public: + AreaTrigger_at_nats_landing() : AreaTriggerScript("at_nats_landing") { } + + bool OnTrigger(Player* player, AreaTriggerEntry const* trigger) + { + if (!player->isAlive() || !player->HasAura(SPELL_FISH_PASTE)) + return false; + + if (player->GetQuestStatus(QUEST_NATS_BARGAIN) == QUEST_STATUS_INCOMPLETE) + { + if (!player->FindNearestCreature(NPC_LURKING_SHARK, 20.0f)) + { + if (Creature* shark = player->SummonCreature(NPC_LURKING_SHARK, -4246.243f, -3922.356f, -7.488f, 5.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 100000)) + shark->AI()->AttackStart(player); + + return false; + } + } + return true; + } +}; + +/*###### +## at_bring_your_orphan_to +######*/ + +enum BringYourOrphanTo +{ + QUEST_DOWN_AT_THE_DOCKS = 910, + QUEST_GATEWAY_TO_THE_FRONTIER = 911, + QUEST_LORDAERON_THRONE_ROOM = 1800, + QUEST_BOUGHT_OF_ETERNALS = 1479, + QUEST_SPOOKY_LIGHTHOUSE = 1687, + QUEST_STONEWROUGHT_DAM = 1558, + QUEST_DARK_PORTAL_H = 10951, + QUEST_DARK_PORTAL_A = 10952, + + AT_DOWN_AT_THE_DOCKS = 3551, + AT_GATEWAY_TO_THE_FRONTIER = 3549, + AT_LORDAERON_THRONE_ROOM = 3547, + AT_BOUGHT_OF_ETERNALS = 3546, + AT_SPOOKY_LIGHTHOUSE = 3552, + AT_STONEWROUGHT_DAM = 3548, + AT_DARK_PORTAL = 4356, + + AURA_ORPHAN_OUT = 58818, +}; + +class AreaTrigger_at_bring_your_orphan_to : public AreaTriggerScript +{ + public: + AreaTrigger_at_bring_your_orphan_to() : AreaTriggerScript("at_bring_your_orphan_to") { } + + bool OnTrigger(Player* player, AreaTriggerEntry const* trigger) + { + uint32 questId = 0; + + if (player->isDead() || !player->HasAura(AURA_ORPHAN_OUT)) + return false; + + switch (trigger->id) + { + case AT_DOWN_AT_THE_DOCKS: + questId = QUEST_DOWN_AT_THE_DOCKS; + break; + case AT_GATEWAY_TO_THE_FRONTIER: + questId = QUEST_GATEWAY_TO_THE_FRONTIER; + break; + case AT_LORDAERON_THRONE_ROOM: + questId = QUEST_LORDAERON_THRONE_ROOM; + break; + case AT_BOUGHT_OF_ETERNALS: + questId = QUEST_BOUGHT_OF_ETERNALS; + break; + case AT_SPOOKY_LIGHTHOUSE: + questId = QUEST_SPOOKY_LIGHTHOUSE; + break; + case AT_STONEWROUGHT_DAM: + questId = QUEST_STONEWROUGHT_DAM; + break; + case AT_DARK_PORTAL: + questId = player->GetTeam() == ALLIANCE ? QUEST_DARK_PORTAL_A : QUEST_DARK_PORTAL_H; + break; + } + + if (questId && player->GetQuestStatus(questId) == QUEST_STATUS_INCOMPLETE) + player->AreaExploredOrEventHappens(questId); + + return true; + } +}; + +/*###### +## at_brewfest +######*/ + +enum Brewfest +{ + NPC_TAPPER_SWINDLEKEG = 24711, + NPC_IPFELKOFER_IRONKEG = 24710, + + AT_BREWFEST_DUROTAR = 4829, + AT_BREWFEST_DUN_MOROGH = 4820, + + SAY_WELCOME = 4, + + AREATRIGGER_TALK_COOLDOWN = 5, // in seconds +}; + +class AreaTrigger_at_brewfest : public AreaTriggerScript +{ + public: + AreaTrigger_at_brewfest() : AreaTriggerScript("at_brewfest") + { + // Initialize for cooldown + _triggerTimes[AT_BREWFEST_DUROTAR] = _triggerTimes[AT_BREWFEST_DUN_MOROGH] = 0; + } + + bool OnTrigger(Player* player, AreaTriggerEntry const* trigger) + { + uint32 triggerId = trigger->id; + // Second trigger happened too early after first, skip for now + if (sWorld->GetGameTime() - _triggerTimes[triggerId] < AREATRIGGER_TALK_COOLDOWN) + return false; + + switch (triggerId) + { + case AT_BREWFEST_DUROTAR: + if (Creature* tapper = player->FindNearestCreature(NPC_TAPPER_SWINDLEKEG, 20.0f)) + tapper->AI()->Talk(SAY_WELCOME, player->GetGUID()); + break; + case AT_BREWFEST_DUN_MOROGH: + if (Creature* ipfelkofer = player->FindNearestCreature(NPC_IPFELKOFER_IRONKEG, 20.0f)) + ipfelkofer->AI()->Talk(SAY_WELCOME, player->GetGUID()); + break; + default: + break; + } + + _triggerTimes[triggerId] = sWorld->GetGameTime(); + return false; + } + + private: + std::map<uint32, time_t> _triggerTimes; +}; + void AddSC_areatrigger_scripts() { new AreaTrigger_at_coilfang_waterfall(); @@ -265,4 +428,7 @@ void AddSC_areatrigger_scripts() new AreaTrigger_at_scent_larkorwi(); new AreaTrigger_at_last_rites(); new AreaTrigger_at_sholazar_waygate(); + new AreaTrigger_at_nats_landing(); + new AreaTrigger_at_bring_your_orphan_to(); + new AreaTrigger_at_brewfest(); } diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index 3bb969977b6..e93dd2751e6 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -16,13 +16,6 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: GO_Scripts -SD%Complete: 100 -SDComment: Quest support: 4285, 4287, 4288(crystal pylons), 4296, 6481, 10990, 10991, 10992, Field_Repair_Bot->Teaches spell 22704. Barov_journal->Teaches spell 26089, 12843, 12982, 2936. Soulwell -SDCategory: Game Objects -EndScriptData */ - /* ContentData go_cat_figurine (the "trap" version of GO, two different exist) go_northern_crystal_pylon @@ -47,6 +40,16 @@ go_jotunheim_cage go_table_theka go_soulwell go_bashir_crystalforge +go_ethereal_teleport_pad +go_soulwell +go_dragonflayer_cage +go_tadpole_cage +go_black_cage +go_amberpine_outhouse +go_hive_pod +go_gjalerbron_cage +go_large_gjalerbron_cage +go_veil_skith_cage EndContentData */ #include "ScriptPCH.h" @@ -922,6 +925,32 @@ public: }; /*###### +## go_ethereal_teleport_pad +######*/ + +enum eEtherealTeleportPad +{ + NPC_IMAGE_WIND_TRADER = 20518, + ITEM_TELEPORTER_POWER_PACK = 28969, +}; + +class go_ethereal_teleport_pad : public GameObjectScript +{ +public: + go_ethereal_teleport_pad() : GameObjectScript("go_ethereal_teleport_pad") { } + + bool OnGossipHello(Player* player, GameObject* pGO) + { + if (!player->HasItemCount(ITEM_TELEPORTER_POWER_PACK, 1)) + return false; + + pGO->SummonCreature(NPC_IMAGE_WIND_TRADER, pGO->GetPositionX(), pGO->GetPositionY(), pGO->GetPositionZ(), pGO->GetAngle(player), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); + + return true; + } +}; + +/*###### ## go_soulwell ######*/ @@ -1152,6 +1181,7 @@ public: /*###### ## Quest 1126: Hive in the Tower +## go_hive_pod ######*/ enum eHives @@ -1251,6 +1281,42 @@ class go_large_gjalerbron_cage : public GameObjectScript } }; +/*######## +#### go_veil_skith_cage +#####*/ + +enum MissingFriends +{ + QUEST_MISSING_FRIENDS = 10852, + NPC_CAPTIVE_CHILD = 22314, + SAY_FREE_0 = 0, +}; + +class go_veil_skith_cage : public GameObjectScript +{ + public: + go_veil_skith_cage() : GameObjectScript("go_veil_skith_cage") { } + + bool OnGossipHello(Player* player, GameObject* go) + { + if (player->GetQuestStatus(QUEST_MISSING_FRIENDS) == QUEST_STATUS_INCOMPLETE) + { + std::list<Creature*> childrenList; + GetCreatureListWithEntryInGrid(childrenList, go, NPC_CAPTIVE_CHILD, INTERACTION_DISTANCE); + for (std::list<Creature*>::const_iterator itr = childrenList.begin(); itr != childrenList.end(); ++itr) + { + go->UseDoorOrButton(); + player->KilledMonsterCredit(NPC_CAPTIVE_CHILD, (*itr)->GetGUID()); + (*itr)->ForcedDespawn(5000); + (*itr)->GetMotionMaster()->MovePoint(1, go->GetPositionX()+5, go->GetPositionY(), go->GetPositionZ()); + (*itr)->AI()->Talk(SAY_FREE_0); + (*itr)->GetMotionMaster()->Clear(); + } + } + return false; + } +}; + void AddSC_go_scripts() { new go_cat_figurine; @@ -1282,6 +1348,7 @@ void AddSC_go_scripts() new go_jotunheim_cage; new go_table_theka; new go_inconspicuous_landmark; + new go_ethereal_teleport_pad; new go_soulwell; new go_tadpole_cage; new go_dragonflayer_cage; @@ -1291,4 +1358,5 @@ void AddSC_go_scripts() new go_massive_seaforium_charge; new go_gjalerbron_cage; new go_large_gjalerbron_cage; + new go_veil_skith_cage; } diff --git a/src/server/scripts/World/item_scripts.cpp b/src/server/scripts/World/item_scripts.cpp index 4099c03384c..9bfa77271f5 100644 --- a/src/server/scripts/World/item_scripts.cpp +++ b/src/server/scripts/World/item_scripts.cpp @@ -24,7 +24,6 @@ SDCategory: Items EndScriptData */ /* ContentData -item_draenei_fishing_net(i23654) Hacklike implements chance to spawn item or creature item_nether_wraith_beacon(i31742) Summons creatures for quest Becoming a Spellfire Tailor (q10832) item_flying_machine(i34060, i34061) Engineering crafted flying machines item_gor_dreks_ointment(i30175) Protecting Our Own(q10488) @@ -81,45 +80,6 @@ public: }; /*##### -# item_draenei_fishing_net -#####*/ - -class item_draenei_fishing_net : public ItemScript -{ -public: - item_draenei_fishing_net() : ItemScript("item_draenei_fishing_net") { } - - //This is just a hack and should be removed from here. - //Creature/Item are in fact created before spell are sucessfully casted, without any checks at all to ensure proper/expected behavior. - bool OnUse(Player* player, Item* /*pItem*/, SpellCastTargets const& /*targets*/) - { - if (player->GetQuestStatus(9452) == QUEST_STATUS_INCOMPLETE) - { - if (urand(0, 99) < 35) - { - Creature* Murloc = player->SummonCreature(17102, player->GetPositionX(), player->GetPositionY()+20, player->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); - if (Murloc) - Murloc->AI()->AttackStart(player); - } - else - { - ItemPosCountVec dest; - uint32 itemId = 23614; - InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, 1); - if (msg == EQUIP_ERR_OK) - { - if (Item* item = player->StoreNewItem(dest, itemId, true)) - player->SendNewItem(item, 1, false, true); - } - else - player->SendEquipError(msg, NULL, NULL, itemId); - } - } - return false; - } -}; - -/*##### # item_nether_wraith_beacon #####*/ @@ -452,7 +412,6 @@ public: void AddSC_item_scripts() { new item_only_for_flight(); - new item_draenei_fishing_net(); new item_nether_wraith_beacon(); new item_gor_dreks_ointment(); new item_incendiary_explosives(); diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp index deb1e702ab9..03fc07c9582 100644 --- a/src/server/scripts/World/npcs_special.cpp +++ b/src/server/scripts/World/npcs_special.cpp @@ -1623,46 +1623,44 @@ public: ## npc_winter_reveler ####*/ +enum WinterReveler +{ + SPELL_MISTLETOE_DEBUFF = 26218, + SPELL_CREATE_MISTLETOE = 26206, + SPELL_CREATE_HOLLY = 26207, + SPELL_CREATE_SNOWFLAKES = 45036, +}; + class npc_winter_reveler : public CreatureScript { -public: - npc_winter_reveler() : CreatureScript("npc_winter_reveler") { } + public: + npc_winter_reveler() : CreatureScript("npc_winter_reveler") { } - struct npc_winter_revelerAI : public ScriptedAI - { - npc_winter_revelerAI(Creature* c) : ScriptedAI(c) {} - void ReceiveEmote(Player* player, uint32 emote) + struct npc_winter_revelerAI : public ScriptedAI { - if (!IsHolidayActive(HOLIDAY_FEAST_OF_WINTER_VEIL)) - return; - //TODO: check auralist. - if (player->HasAura(26218)) - return; + npc_winter_revelerAI(Creature* c) : ScriptedAI(c) {} - if (emote == TEXT_EMOTE_KISS) + void ReceiveEmote(Player* player, uint32 emote) { - me->CastSpell(me, 26218, false); - player->CastSpell(player, 26218, false); - switch (urand(0, 2)) + if (player->HasAura(SPELL_MISTLETOE_DEBUFF)) + return; + + if (!IsHolidayActive(HOLIDAY_FEAST_OF_WINTER_VEIL)) + return; + + if (emote == TEXT_EMOTE_KISS) { - case 0: - me->CastSpell(player, 26207, false); - break; - case 1: - me->CastSpell(player, 26206, false); - break; - case 2: - me->CastSpell(player, 45036, false); - break; + uint32 spellId = RAND<uint32>(SPELL_CREATE_MISTLETOE, SPELL_CREATE_HOLLY, SPELL_CREATE_SNOWFLAKES); + me->CastSpell(player, spellId, false); + me->CastSpell(player, SPELL_MISTLETOE_DEBUFF, false); } } - } - }; + }; - CreatureAI* GetAI(Creature* creature) const - { - return new npc_winter_revelerAI(creature); - } + CreatureAI* GetAI(Creature* creature) const + { + return new npc_winter_revelerAI(creature); + } }; /*#### @@ -1678,8 +1676,6 @@ public: #define C_VIPER 19921 -#define RAND 5 - class npc_snake_trap : public CreatureScript { public: @@ -1726,7 +1722,7 @@ public: float attackRadius = me->GetAttackDistance(who); if (me->IsWithinDistInMap(who, attackRadius) && me->IsWithinLOSInMap(who)) { - if (!(rand() % RAND)) + if (!(rand() % 5)) { me->setAttackTimer(BASE_ATTACK, (rand() % 10) * 100); SpellTimer = (rand() % 10) * 100; @@ -2174,6 +2170,121 @@ public: }; /*###### +# npc_fire_elemental +######*/ +#define SPELL_FIRENOVA 12470 +#define SPELL_FIRESHIELD 13376 +#define SPELL_FIREBLAST 57984 + +class npc_fire_elemental : public CreatureScript +{ +public: + npc_fire_elemental() : CreatureScript("npc_fire_elemental") { } + + struct npc_fire_elementalAI : public ScriptedAI + { + npc_fire_elementalAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 FireNova_Timer; + uint32 FireShield_Timer; + uint32 FireBlast_Timer; + + void Reset() + { + FireNova_Timer = 5000 + rand() % 15000; // 5-20 sec cd + FireBlast_Timer = 5000 + rand() % 15000; // 5-20 sec cd + FireShield_Timer = 0; + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + if (FireShield_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_FIRESHIELD); + FireShield_Timer = 2 * IN_MILLISECONDS; + } + else + FireShield_Timer -= diff; + + if (FireBlast_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_FIREBLAST); + FireBlast_Timer = 5000 + rand() % 15000; // 5-20 sec cd + } + else + FireBlast_Timer -= diff; + + if (FireNova_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_FIRENOVA); + FireNova_Timer = 5000 + rand() % 15000; // 5-20 sec cd + } + else + FireNova_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI *GetAI(Creature* creature) const + { + return new npc_fire_elementalAI(creature); + } +}; + +/*###### +# npc_earth_elemental +######*/ +#define SPELL_ANGEREDEARTH 36213 + +class npc_earth_elemental : public CreatureScript +{ +public: + npc_earth_elemental() : CreatureScript("npc_earth_elemental") { } + + struct npc_earth_elementalAI : public ScriptedAI + { + npc_earth_elementalAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 AngeredEarth_Timer; + + void Reset() + { + AngeredEarth_Timer = 0; + me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + if (AngeredEarth_Timer <= diff) + { + DoCast(me->getVictim(), SPELL_ANGEREDEARTH); + AngeredEarth_Timer = 5000 + rand() % 15000; // 5-20 sec cd + } + else + AngeredEarth_Timer -= diff; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI *GetAI(Creature* creature) const + { + return new npc_earth_elementalAI(creature); + } +}; + +/*###### # npc_wormhole ######*/ @@ -2683,5 +2794,7 @@ void AddSC_npcs_special() new npc_locksmith; new npc_tabard_vendor; new npc_experience; + new npc_fire_elemental; + new npc_earth_elemental; } |
