aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorVincent-Michael <Vincent_Michael@gmx.de>2013-08-09 20:02:21 +0200
committerVincent-Michael <Vincent_Michael@gmx.de>2013-08-09 20:02:21 +0200
commit99aa4649d2f293672256c78b96eeff5be8e3a16c (patch)
tree822dc07f26dc020a947463df47d18baa2be5a2e5 /src/server
parent80d7c093ebdf17b24390426c7b09c0b8a732949e (diff)
parent8aff3945f275b2285413ffadef616da1eb513faa (diff)
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Conflicts: src/server/scripts/CMakeLists.txt
Diffstat (limited to 'src/server')
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp10
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp5
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h11
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h3
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp19
-rw-r--r--src/server/game/Scripting/ScriptLoader.h1
-rw-r--r--src/server/scripts/CMakeLists.txt3
-rw-r--r--src/server/scripts/Pet/CMakeLists.txt20
-rw-r--r--src/server/scripts/Pet/pet_dk.cpp133
-rw-r--r--src/server/scripts/Pet/pet_hunter.cpp146
-rw-r--r--src/server/scripts/Pet/pet_mage.cpp83
-rw-r--r--src/server/scripts/Pet/pet_priest.cpp92
-rw-r--r--src/server/scripts/Pet/pet_shaman.cpp153
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp58
-rw-r--r--src/server/scripts/World/npcs_special.cpp446
15 files changed, 723 insertions, 460 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 1a445435d4e..261c4166a15 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -250,9 +250,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
if (IsUnit(*itr))
{
- (*itr)->SendPlaySound(e.action.sound.sound, e.action.sound.range > 0 ? true : false);
+ (*itr)->SendPlaySound(e.action.sound.sound, e.action.sound.onlySelf > 0 ? true : false);
TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SOUND: target: %s (GuidLow: %u), sound: %u, onlyself: %u",
- (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), e.action.sound.sound, e.action.sound.range);
+ (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), e.action.sound.sound, e.action.sound.onlySelf);
}
}
@@ -1131,13 +1131,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_SET_VISIBILITY:
{
if (me)
- me->SetVisible(e.action.visibility.state ? true : false);
+ me->SetVisible(e.action.visibility.state);
break;
}
case SMART_ACTION_SET_ACTIVE:
{
- if (GetBaseObject())
- GetBaseObject()->setActive(true);
+ if (WorldObject* baseObj = GetBaseObject())
+ baseObj->setActive(e.action.active.state);
break;
}
case SMART_ACTION_ATTACK_START:
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index fe78c4fce06..f26d3bb328a 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -621,11 +621,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_SOUND:
if (!IsSoundValid(e, e.action.sound.sound))
return false;
- if (e.action.sound.range > TEXT_RANGE_WORLD)
- {
- TC_LOG_ERROR(LOG_FILTER_SQL, "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Text Range %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.sound.range);
- return false;
- }
break;
case SMART_ACTION_SET_EMOTE_STATE:
case SMART_ACTION_PLAY_EMOTE:
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index ede8101b522..cf208aa91df 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -386,7 +386,7 @@ enum SMART_ACTION
SMART_ACTION_TALK = 1, // groupID from creature_text, duration to wait before TEXT_OVER event is triggered
SMART_ACTION_SET_FACTION = 2, // FactionId (or 0 for default)
SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL = 3, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to demorph)
- SMART_ACTION_SOUND = 4, // SoundId, TextRange
+ SMART_ACTION_SOUND = 4, // SoundId, onlySelf
SMART_ACTION_PLAY_EMOTE = 5, // EmoteId
SMART_ACTION_FAIL_QUEST = 6, // QuestID
SMART_ACTION_ADD_QUEST = 7, // QuestID
@@ -430,7 +430,7 @@ enum SMART_ACTION
SMART_ACTION_SET_DATA = 45, // Field, Data (only creature @todo)
SMART_ACTION_MOVE_FORWARD = 46, // distance
SMART_ACTION_SET_VISIBILITY = 47, // on/off
- SMART_ACTION_SET_ACTIVE = 48, // No Params
+ SMART_ACTION_SET_ACTIVE = 48, // on/off
SMART_ACTION_ATTACK_START = 49, //
SMART_ACTION_SUMMON_GO = 50, // GameObjectID, DespawnTime in ms,
SMART_ACTION_KILL_UNIT = 51, //
@@ -520,7 +520,7 @@ struct SmartAction
struct
{
uint32 sound;
- uint32 range;
+ uint32 onlySelf;
} sound;
struct
@@ -728,6 +728,11 @@ struct SmartAction
} summonGO;
struct
+ {
+ uint32 state;
+ } active;
+
+ struct
{
uint32 id;
} taxi;
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 209d2527e0d..10ccd6a77f3 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -907,6 +907,9 @@ namespace Trinity
AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid) : _source(obj), _refUnit(funit), _range(range), _raid(raid) {}
bool operator()(Unit* u)
{
+ if (G3D::fuzzyEq(_range, 0))
+ return false;
+
if (_raid)
{
if (!_refUnit->IsInRaidWith(u))
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index 6d12a073824..d55ada7d090 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -623,6 +623,13 @@ void AddSC_kezan();
// Events
void AddSC_event_childrens_week();
+// Pets
+void AddSC_deathknight_pet_scripts();
+void AddSC_hunter_pet_scripts();
+void AddSC_mage_pet_scripts();
+void AddSC_priest_pet_scripts();
+void AddSC_shaman_pet_scripts();
+
// battlegrounds
// outdoor pvp
@@ -651,6 +658,7 @@ void AddScripts()
AddNorthrendScripts();
AddMaelstromScripts();
AddEventScripts();
+ AddPetScripts();
AddBattlegroundScripts();
AddOutdoorPvPScripts();
AddCustomScripts();
@@ -1299,6 +1307,17 @@ void AddEventScripts()
#endif
}
+void AddPetScripts()
+{
+#ifdef SCRIPTS
+ AddSC_deathknight_pet_scripts();
+ AddSC_hunter_pet_scripts();
+ AddSC_mage_pet_scripts();
+ AddSC_priest_pet_scripts();
+ AddSC_shaman_pet_scripts();
+#endif
+}
+
void AddOutdoorPvPScripts()
{
#ifdef SCRIPTS
diff --git a/src/server/game/Scripting/ScriptLoader.h b/src/server/game/Scripting/ScriptLoader.h
index 5e1b829798e..7edba0445c4 100644
--- a/src/server/game/Scripting/ScriptLoader.h
+++ b/src/server/game/Scripting/ScriptLoader.h
@@ -29,6 +29,7 @@ void AddOutlandScripts();
void AddNorthrendScripts();
void AddMaelstromScripts();
void AddEventScripts();
+void AddPetScripts();
void AddBattlegroundScripts();
void AddOutdoorPvPScripts();
void AddCustomScripts();
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index 55abbec3025..5a483ccea33 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -37,8 +37,9 @@ if(SCRIPTS)
include(Kalimdor/CMakeLists.txt)
include(Outland/CMakeLists.txt)
include(Northrend/CMakeLists.txt)
- include(Events/CMakeLists.txt)
include(Maelstrom/CMakeLists.txt)
+ include(Events/CMakeLists.txt)
+ include(Pet/CMakeLists.txt)
endif()
message(STATUS "SCRIPT PREPARATION COMPLETE")
diff --git a/src/server/scripts/Pet/CMakeLists.txt b/src/server/scripts/Pet/CMakeLists.txt
new file mode 100644
index 00000000000..b4a8eea77d8
--- /dev/null
+++ b/src/server/scripts/Pet/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+set(scripts_STAT_SRCS
+ ${scripts_STAT_SRCS}
+ Pet/pet_dk.cpp
+ Pet/pet_hunter.cpp
+ Pet/pet_mage.cpp
+ Pet/pet_priest.cpp
+ Pet/pet_shaman.cpp
+)
+
+message(" -> Prepared: Pet")
diff --git a/src/server/scripts/Pet/pet_dk.cpp b/src/server/scripts/Pet/pet_dk.cpp
new file mode 100644
index 00000000000..aac2eb0f89e
--- /dev/null
+++ b/src/server/scripts/Pet/pet_dk.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Ordered alphabetically using scriptname.
+ * Scriptnames of files in this file should be prefixed with "npc_pet_dk_".
+ */
+
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "CombatAI.h"
+#include "GridNotifiers.h"
+
+enum DeathKnightSpells
+{
+ SPELL_DK_SUMMON_GARGOYLE_1 = 49206,
+ SPELL_DK_SUMMON_GARGOYLE_2 = 50514,
+ SPELL_DK_DISMISS_GARGOYLE = 50515,
+ SPELL_DK_SANCTUARY = 54661
+};
+
+class npc_pet_dk_ebon_gargoyle : public CreatureScript
+{
+ public:
+ npc_pet_dk_ebon_gargoyle() : CreatureScript("npc_pet_dk_ebon_gargoyle") { }
+
+ struct npc_pet_dk_ebon_gargoyleAI : CasterAI
+ {
+ npc_pet_dk_ebon_gargoyleAI(Creature* creature) : CasterAI(creature) { }
+
+ void InitializeAI() OVERRIDE
+ {
+ CasterAI::InitializeAI();
+ uint64 ownerGuid = me->GetOwnerGUID();
+ if (!ownerGuid)
+ return;
+
+ // Not needed to be despawned now
+ _despawnTimer = 0;
+ // Find victim of Summon Gargoyle spell
+ std::list<Unit*> targets;
+ Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 30.0f);
+ Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targets, u_check);
+ me->VisitNearbyObject(30.0f, searcher);
+ for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
+ if ((*iter)->GetAura(SPELL_DK_SUMMON_GARGOYLE_1, ownerGuid))
+ {
+ me->Attack((*iter), false);
+ break;
+ }
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ // Stop Feeding Gargoyle when it dies
+ if (Unit* owner = me->GetOwner())
+ owner->RemoveAurasDueToSpell(SPELL_DK_SUMMON_GARGOYLE_2);
+ }
+
+ // Fly away when dismissed
+ void SpellHit(Unit* source, SpellInfo const* spell) OVERRIDE
+ {
+ if (spell->Id != SPELL_DK_DISMISS_GARGOYLE || !me->IsAlive())
+ return;
+
+ Unit* owner = me->GetOwner();
+ if (!owner || owner != source)
+ return;
+
+ // Stop Fighting
+ me->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, true);
+
+ // Sanctuary
+ me->CastSpell(me, SPELL_DK_SANCTUARY, true);
+ me->SetReactState(REACT_PASSIVE);
+
+ //! HACK: Creature's can't have MOVEMENTFLAG_FLYING
+ // Fly Away
+ me->SetCanFly(true);
+ me->SetSpeed(MOVE_FLIGHT, 0.75f, true);
+ me->SetSpeed(MOVE_RUN, 0.75f, true);
+ float x = me->GetPositionX() + 20 * std::cos(me->GetOrientation());
+ float y = me->GetPositionY() + 20 * std::sin(me->GetOrientation());
+ float z = me->GetPositionZ() + 40;
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MovePoint(0, x, y, z);
+
+ // Despawn as soon as possible
+ _despawnTimer = 4 * IN_MILLISECONDS;
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (_despawnTimer > 0)
+ {
+ if (_despawnTimer > diff)
+ _despawnTimer -= diff;
+ else
+ me->DespawnOrUnsummon();
+ return;
+ }
+
+ CasterAI::UpdateAI(diff);
+ }
+
+ private:
+ uint32 _despawnTimer;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_pet_dk_ebon_gargoyleAI(creature);
+ }
+};
+
+void AddSC_deathknight_pet_scripts()
+{
+ new npc_pet_dk_ebon_gargoyle();
+}
diff --git a/src/server/scripts/Pet/pet_hunter.cpp b/src/server/scripts/Pet/pet_hunter.cpp
new file mode 100644
index 00000000000..80551be9131
--- /dev/null
+++ b/src/server/scripts/Pet/pet_hunter.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Ordered alphabetically using scriptname.
+ * Scriptnames of files in this file should be prefixed with "npc_pet_hun_".
+ */
+
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+
+enum HunterSpells
+{
+ SPELL_HUNTER_CRIPPLING_POISON = 30981, // Viper
+ SPELL_HUNTER_DEADLY_POISON = 34655, // Venomous Snake
+ SPELL_HUNTER_MIND_NUMBING_POISON = 25810 // Viper
+};
+
+enum HunterCreatures
+{
+ NPC_HUNTER_VIPER = 19921
+};
+
+class npc_pet_hunter_snake_trap : public CreatureScript
+{
+ public:
+ npc_pet_hunter_snake_trap() : CreatureScript("npc_pet_hunter_snake_trap") { }
+
+ struct npc_pet_hunter_snake_trapAI : public ScriptedAI
+ {
+ npc_pet_hunter_snake_trapAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE { }
+
+ void Reset() OVERRIDE
+ {
+ _spellTimer = 0;
+
+ CreatureTemplate const* Info = me->GetCreatureTemplate();
+
+ _isViper = Info->Entry == NPC_HUNTER_VIPER ? true : false;
+
+ me->SetMaxHealth(uint32(107 * (me->getLevel() - 40) * 0.025f));
+ // Add delta to make them not all hit the same time
+ uint32 delta = (rand() % 7) * 100;
+ me->SetStatFloatValue(UNIT_FIELD_BASEATTACKTIME, float(Info->baseattacktime + delta));
+ me->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER, float(Info->attackpower));
+
+ // Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target
+ if (!me->GetVictim() && me->IsSummon())
+ if (Unit* Owner = me->ToTempSummon()->GetSummoner())
+ if (Owner->getAttackerForHelper())
+ AttackStart(Owner->getAttackerForHelper());
+ }
+
+ // Redefined for random target selection:
+ void MoveInLineOfSight(Unit* who) OVERRIDE
+ {
+ if (!me->GetVictim() && me->CanCreatureAttack(who))
+ {
+ if (me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ float attackRadius = me->GetAttackDistance(who);
+ if (me->IsWithinDistInMap(who, attackRadius) && me->IsWithinLOSInMap(who))
+ {
+ if (!(rand() % 5))
+ {
+ me->setAttackTimer(BASE_ATTACK, (rand() % 10) * 100);
+ _spellTimer = (rand() % 10) * 100;
+ AttackStart(who);
+ }
+ }
+ }
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->GetVictim()->HasBreakableByDamageCrowdControlAura(me))
+ {
+ me->InterruptNonMeleeSpells(false);
+ return;
+ }
+
+ if (_spellTimer <= diff)
+ {
+ if (_isViper) // Viper
+ {
+ if (urand(0, 2) == 0) //33% chance to cast
+ {
+ uint32 spell;
+ if (urand(0, 1) == 0)
+ spell = SPELL_HUNTER_MIND_NUMBING_POISON;
+ else
+ spell = SPELL_HUNTER_CRIPPLING_POISON;
+
+ DoCastVictim(spell);
+ }
+
+ _spellTimer = 3000;
+ }
+ else // Venomous Snake
+ {
+ if (urand(0, 2) == 0) // 33% chance to cast
+ DoCastVictim(SPELL_HUNTER_DEADLY_POISON);
+ _spellTimer = 1500 + (rand() % 5) * 100;
+ }
+ }
+ else
+ _spellTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ bool _isViper;
+ uint32 _spellTimer;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_pet_hunter_snake_trapAI(creature);
+ }
+};
+
+void AddSC_hunter_pet_scripts()
+{
+ new npc_pet_hunter_snake_trap();
+}
diff --git a/src/server/scripts/Pet/pet_mage.cpp b/src/server/scripts/Pet/pet_mage.cpp
new file mode 100644
index 00000000000..85247b29f84
--- /dev/null
+++ b/src/server/scripts/Pet/pet_mage.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Ordered alphabetically using scriptname.
+ * Scriptnames of files in this file should be prefixed with "npc_pet_mag_".
+ */
+
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "CombatAI.h"
+#include "Pet.h"
+
+enum MageSpells
+{
+ SPELL_MAGE_CLONE_ME = 45204,
+ SPELL_MAGE_MASTERS_THREAT_LIST = 58838
+};
+
+class npc_pet_mage_mirror_image : public CreatureScript
+{
+ public:
+ npc_pet_mage_mirror_image() : CreatureScript("npc_pet_mage_mirror_image") { }
+
+ struct npc_pet_mage_mirror_imageAI : CasterAI
+ {
+ npc_pet_mage_mirror_imageAI(Creature* creature) : CasterAI(creature) { }
+
+ void InitializeAI() OVERRIDE
+ {
+ CasterAI::InitializeAI();
+ Unit* owner = me->GetOwner();
+ if (!owner)
+ return;
+ // Inherit Master's Threat List (not yet implemented)
+ owner->CastSpell((Unit*)NULL, SPELL_MAGE_MASTERS_THREAT_LIST, true);
+ // here mirror image casts on summoner spell (not present in client dbc) 49866
+ // here should be auras (not present in client dbc): 35657, 35658, 35659, 35660 selfcasted by mirror images (stats related?)
+ // Clone Me!
+ owner->CastSpell(me, SPELL_MAGE_CLONE_ME, false);
+ }
+
+ // Do not reload Creature templates on evade mode enter - prevent visual lost
+ void EnterEvadeMode() OVERRIDE
+ {
+ if (me->IsInEvadeMode() || !me->IsAlive())
+ return;
+
+ Unit* owner = me->GetCharmerOrOwner();
+
+ me->CombatStop(true);
+ if (owner && !me->HasUnitState(UNIT_STATE_FOLLOW))
+ {
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle(), MOTION_SLOT_ACTIVE);
+ }
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_pet_mage_mirror_imageAI(creature);
+ }
+};
+
+void AddSC_mage_pet_scripts()
+{
+ new npc_pet_mage_mirror_image();
+}
diff --git a/src/server/scripts/Pet/pet_priest.cpp b/src/server/scripts/Pet/pet_priest.cpp
new file mode 100644
index 00000000000..4b565aaec10
--- /dev/null
+++ b/src/server/scripts/Pet/pet_priest.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Ordered alphabetically using scriptname.
+ * Scriptnames of files in this file should be prefixed with "npc_pet_pri_".
+ */
+
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "PassiveAI.h"
+#include "PetAI.h"
+
+enum PriestSpells
+{
+ SPELL_PRIEST_GLYPH_OF_SHADOWFIEND = 58228,
+ SPELL_PRIEST_GLYPH_OF_SHADOWFIEND_MANA = 58227,
+ SPELL_PRIEST_LIGHTWELL_CHARGES = 59907
+};
+
+class npc_pet_pri_lightwell : public CreatureScript
+{
+ public:
+ npc_pet_pri_lightwell() : CreatureScript("npc_pet_pri_lightwell") { }
+
+ struct npc_pet_pri_lightwellAI : public PassiveAI
+ {
+ npc_pet_pri_lightwellAI(Creature* creature) : PassiveAI(creature)
+ {
+ DoCast(me, SPELL_PRIEST_LIGHTWELL_CHARGES, false);
+ }
+
+ void EnterEvadeMode() OVERRIDE
+ {
+ if (!me->IsAlive())
+ return;
+
+ me->DeleteThreatList();
+ me->CombatStop(true);
+ me->ResetPlayerDamageReq();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_pet_pri_lightwellAI(creature);
+ }
+};
+
+class npc_pet_pri_shadowfiend : public CreatureScript
+{
+ public:
+ npc_pet_pri_shadowfiend() : CreatureScript("npc_pet_pri_shadowfiend") { }
+
+ struct npc_pet_pri_shadowfiendAI : public PetAI
+ {
+ npc_pet_pri_shadowfiendAI(Creature* creature) : PetAI(creature) { }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ if (me->IsSummon())
+ if (Unit* owner = me->ToTempSummon()->GetSummoner())
+ if (owner->HasAura(SPELL_PRIEST_GLYPH_OF_SHADOWFIEND))
+ owner->CastSpell(owner, SPELL_PRIEST_GLYPH_OF_SHADOWFIEND_MANA, true);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_pet_pri_shadowfiendAI(creature);
+ }
+};
+
+void AddSC_priest_pet_scripts()
+{
+ new npc_pet_pri_lightwell();
+ new npc_pet_pri_shadowfiend();
+}
diff --git a/src/server/scripts/Pet/pet_shaman.cpp b/src/server/scripts/Pet/pet_shaman.cpp
new file mode 100644
index 00000000000..c770be86692
--- /dev/null
+++ b/src/server/scripts/Pet/pet_shaman.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Ordered alphabetically using scriptname.
+ * Scriptnames of files in this file should be prefixed with "npc_pet_sha_".
+ */
+
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+
+enum ShamanSpells
+{
+ SPELL_SHAMAN_ANGEREDEARTH = 36213,
+ SPELL_SHAMAN_FIREBLAST = 57984,
+ SPELL_SHAMAN_FIRENOVA = 12470,
+ SPELL_SHAMAN_FIRESHIELD = 13376
+};
+
+enum ShamanEvents
+{
+ // Earth Elemental
+ EVENT_SHAMAN_ANGEREDEARTH = 1,
+ // Fire Elemental
+ EVENT_SHAMAN_FIRENOVA = 1,
+ EVENT_SHAMAN_FIRESHIELD = 2,
+ EVENT_SHAMAN_FIREBLAST = 3
+};
+
+class npc_pet_shaman_earth_elemental : public CreatureScript
+{
+ public:
+ npc_pet_shaman_earth_elemental() : CreatureScript("npc_pet_shaman_earth_elemental") { }
+
+ struct npc_pet_shaman_earth_elementalAI : public ScriptedAI
+ {
+ npc_pet_shaman_earth_elementalAI(Creature* creature) : ScriptedAI(creature) { }
+
+
+ void Reset() OVERRIDE
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_SHAMAN_ANGEREDEARTH, 0);
+ me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (_events.ExecuteEvent() == EVENT_SHAMAN_ANGEREDEARTH)
+ {
+ DoCastVictim(SPELL_SHAMAN_ANGEREDEARTH);
+ _events.ScheduleEvent(EVENT_SHAMAN_ANGEREDEARTH, urand(5000, 20000));
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_pet_shaman_earth_elementalAI(creature);
+ }
+};
+
+class npc_pet_shaman_fire_elemental : public CreatureScript
+{
+ public:
+ npc_pet_shaman_fire_elemental() : CreatureScript("npc_pet_shaman_fire_elemental") { }
+
+ struct npc_pet_shaman_fire_elementalAI : public ScriptedAI
+ {
+ npc_pet_shaman_fire_elementalAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() OVERRIDE
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_SHAMAN_FIRENOVA, urand(5000, 20000));
+ _events.ScheduleEvent(EVENT_SHAMAN_FIREBLAST, urand(5000, 20000));
+ _events.ScheduleEvent(EVENT_SHAMAN_FIRESHIELD, 0);
+ me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SHAMAN_FIRENOVA:
+ DoCastVictim(SPELL_SHAMAN_FIRENOVA);
+ _events.ScheduleEvent(EVENT_SHAMAN_FIRENOVA, urand(5000, 20000));
+ break;
+ case EVENT_SHAMAN_FIRESHIELD:
+ DoCastVictim(SPELL_SHAMAN_FIRESHIELD);
+ _events.ScheduleEvent(EVENT_SHAMAN_FIRESHIELD, 2000);
+ break;
+ case EVENT_SHAMAN_FIREBLAST:
+ DoCastVictim(SPELL_SHAMAN_FIREBLAST);
+ _events.ScheduleEvent(EVENT_SHAMAN_FIREBLAST, urand(5000, 20000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_pet_shaman_fire_elementalAI(creature);
+ }
+};
+
+void AddSC_shaman_pet_scripts()
+{
+ new npc_pet_shaman_earth_elemental();
+ new npc_pet_shaman_fire_elemental();
+}
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index 10cc62a8a91..ca94f871d03 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -1785,6 +1785,63 @@ class spell_q12847_summon_soul_moveto_bunny : public SpellScriptLoader
}
};
+enum BearFlankMaster
+{
+ SPELL_BEAR_FLANK_MASTER = 56565,
+ SPELL_CREATE_BEAR_FLANK = 56566,
+ SPELL_BEAR_FLANK_FAIL = 56569
+};
+
+class spell_q13011_bear_flank_master : public SpellScriptLoader
+{
+ public:
+ spell_q13011_bear_flank_master() : SpellScriptLoader("spell_q13011_bear_flank_master") { }
+
+ class spell_q13011_bear_flank_master_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q13011_bear_flank_master_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_BEAR_FLANK_MASTER) ||
+ !sSpellMgr->GetSpellInfo(SPELL_CREATE_BEAR_FLANK))
+ return false;
+ return true;
+ }
+
+ bool Load() OVERRIDE
+ {
+ return GetCaster()->GetTypeId() == TYPEID_UNIT;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ bool failed = RAND(0, 1); // 50% chance
+ Creature* creature = GetCaster()->ToCreature();
+ if (Player* player = GetHitPlayer())
+ {
+ if (failed)
+ {
+ player->CastSpell(creature, SPELL_BEAR_FLANK_FAIL);
+ creature->AI()->Talk(0, player->GetGUID());
+ }
+ else
+ player->CastSpell(player, SPELL_CREATE_BEAR_FLANK);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q13011_bear_flank_master_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_q13011_bear_flank_master_SpellScript();
+ }
+};
+
class spell_q13086_cannons_target : public SpellScriptLoader
{
public:
@@ -1863,5 +1920,6 @@ void AddSC_quest_spell_scripts()
new spell_q13291_q13292_q13239_q13261_frostbrood_skytalon_grab_decoy();
new spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon();
new spell_q12847_summon_soul_moveto_bunny();
+ new spell_q13011_bear_flank_master();
new spell_q13086_cannons_target();
}
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index b236c277251..1348e433de3 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -49,9 +49,7 @@ EndContentData */
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "World.h"
-#include "PetAI.h"
#include "PassiveAI.h"
-#include "CombatAI.h"
#include "GameEventMgr.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
@@ -1596,124 +1594,6 @@ public:
};
-/*####
-## npc_snake_trap_serpents
-####*/
-
-enum SnakeTrapSerpents
-{
- SPELL_MIND_NUMBING_POISON = 25810, // Viper
- SPELL_DEADLY_POISON = 34655, // Venomous Snake
- SPELL_CRIPPLING_POISON = 30981, // Viper
-
- NPC_VIPER = 19921
-};
-
-class npc_snake_trap : public CreatureScript
-{
-public:
- npc_snake_trap() : CreatureScript("npc_snake_trap_serpents") { }
-
- struct npc_snake_trap_serpentsAI : public ScriptedAI
- {
- npc_snake_trap_serpentsAI(Creature* creature) : ScriptedAI(creature) {}
-
- uint32 SpellTimer;
- bool IsViper;
-
- void EnterCombat(Unit* /*who*/) OVERRIDE {}
-
- void Reset() OVERRIDE
- {
- SpellTimer = 0;
-
- CreatureTemplate const* Info = me->GetCreatureTemplate();
-
- IsViper = Info->Entry == NPC_VIPER ? true : false;
-
- me->SetMaxHealth(uint32(107 * (me->getLevel() - 40) * 0.025f));
- //Add delta to make them not all hit the same time
- uint32 delta = (rand() % 7) * 100;
- me->SetStatFloatValue(UNIT_FIELD_BASEATTACKTIME, float(Info->baseattacktime + delta));
- me->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER, float(Info->attackpower));
-
- // Start attacking attacker of owner on first ai update after spawn - move in line of sight may choose better target
- if (!me->GetVictim() && me->IsSummon())
- if (Unit* Owner = me->ToTempSummon()->GetSummoner())
- if (Owner->getAttackerForHelper())
- AttackStart(Owner->getAttackerForHelper());
- }
-
- //Redefined for random target selection:
- void MoveInLineOfSight(Unit* who) OVERRIDE
-
- {
- if (!me->GetVictim() && me->CanCreatureAttack(who))
- {
- if (me->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
- return;
-
- float attackRadius = me->GetAttackDistance(who);
- if (me->IsWithinDistInMap(who, attackRadius) && me->IsWithinLOSInMap(who))
- {
- if (!(rand() % 5))
- {
- me->setAttackTimer(BASE_ATTACK, (rand() % 10) * 100);
- SpellTimer = (rand() % 10) * 100;
- AttackStart(who);
- }
- }
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (me->GetVictim()->HasBreakableByDamageCrowdControlAura(me))
- {
- me->InterruptNonMeleeSpells(false);
- return;
- }
-
- if (SpellTimer <= diff)
- {
- if (IsViper) //Viper
- {
- if (urand(0, 2) == 0) //33% chance to cast
- {
- uint32 spell;
- if (urand(0, 1) == 0)
- spell = SPELL_MIND_NUMBING_POISON;
- else
- spell = SPELL_CRIPPLING_POISON;
-
- DoCastVictim(spell);
- }
-
- SpellTimer = 3000;
- }
- else //Venomous Snake
- {
- if (urand(0, 2) == 0) //33% chance to cast
- DoCastVictim(SPELL_DEADLY_POISON);
- SpellTimer = 1500 + (rand() % 5) * 100;
- }
- }
- else
- SpellTimer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_snake_trap_serpentsAI(creature);
- }
-};
-
#define SAY_RANDOM_MOJO0 "Now that's what I call froggy-style!"
#define SAY_RANDOM_MOJO1 "Your lily pad or mine?"
#define SAY_RANDOM_MOJO2 "This won't take long, did it?"
@@ -1815,172 +1695,6 @@ public:
}
};
-class npc_mirror_image : public CreatureScript
-{
-public:
- npc_mirror_image() : CreatureScript("npc_mirror_image") { }
-
- struct npc_mirror_imageAI : CasterAI
- {
- npc_mirror_imageAI(Creature* creature) : CasterAI(creature) {}
-
- void InitializeAI() OVERRIDE
- {
- CasterAI::InitializeAI();
- Unit* owner = me->GetOwner();
- if (!owner)
- return;
- // Inherit Master's Threat List (not yet implemented)
- owner->CastSpell((Unit*)NULL, 58838, true);
- // here mirror image casts on summoner spell (not present in client dbc) 49866
- // here should be auras (not present in client dbc): 35657, 35658, 35659, 35660 selfcasted by mirror images (stats related?)
- // Clone Me!
- owner->CastSpell(me, 45204, false);
- }
-
- // Do not reload Creature templates on evade mode enter - prevent visual lost
- void EnterEvadeMode() OVERRIDE
- {
- if (me->IsInEvadeMode() || !me->IsAlive())
- return;
-
- Unit* owner = me->GetCharmerOrOwner();
-
- me->CombatStop(true);
- if (owner && !me->HasUnitState(UNIT_STATE_FOLLOW))
- {
- me->GetMotionMaster()->Clear(false);
- me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle(), MOTION_SLOT_ACTIVE);
- }
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_mirror_imageAI(creature);
- }
-};
-
-class npc_ebon_gargoyle : public CreatureScript
-{
-public:
- npc_ebon_gargoyle() : CreatureScript("npc_ebon_gargoyle") { }
-
- struct npc_ebon_gargoyleAI : CasterAI
- {
- npc_ebon_gargoyleAI(Creature* creature) : CasterAI(creature) {}
-
- uint32 despawnTimer;
-
- void InitializeAI() OVERRIDE
- {
- CasterAI::InitializeAI();
- uint64 ownerGuid = me->GetOwnerGUID();
- if (!ownerGuid)
- return;
- // Not needed to be despawned now
- despawnTimer = 0;
- // Find victim of Summon Gargoyle spell
- std::list<Unit*> targets;
- Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 30);
- Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targets, u_check);
- me->VisitNearbyObject(30, searcher);
- for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
- if ((*iter)->GetAura(49206, ownerGuid))
- {
- me->Attack((*iter), false);
- break;
- }
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- // Stop Feeding Gargoyle when it dies
- if (Unit* owner = me->GetOwner())
- owner->RemoveAurasDueToSpell(50514);
- }
-
- // Fly away when dismissed
- void SpellHit(Unit* source, SpellInfo const* spell) OVERRIDE
- {
- if (spell->Id != 50515 || !me->IsAlive())
- return;
-
- Unit* owner = me->GetOwner();
-
- if (!owner || owner != source)
- return;
-
- // Stop Fighting
- me->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, true);
- // Sanctuary
- me->CastSpell(me, 54661, true);
- me->SetReactState(REACT_PASSIVE);
-
- //! HACK: Creature's can't have MOVEMENTFLAG_FLYING
- // Fly Away
- me->SetCanFly(true);
- me->SetSpeed(MOVE_FLIGHT, 0.75f, true);
- me->SetSpeed(MOVE_RUN, 0.75f, true);
- float x = me->GetPositionX() + 20 * std::cos(me->GetOrientation());
- float y = me->GetPositionY() + 20 * std::sin(me->GetOrientation());
- float z = me->GetPositionZ() + 40;
- me->GetMotionMaster()->Clear(false);
- me->GetMotionMaster()->MovePoint(0, x, y, z);
-
- // Despawn as soon as possible
- despawnTimer = 4 * IN_MILLISECONDS;
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (despawnTimer > 0)
- {
- if (despawnTimer > diff)
- despawnTimer -= diff;
- else
- me->DespawnOrUnsummon();
- return;
- }
- CasterAI::UpdateAI(diff);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_ebon_gargoyleAI(creature);
- }
-};
-
-class npc_lightwell : public CreatureScript
-{
- public:
- npc_lightwell() : CreatureScript("npc_lightwell") { }
-
- struct npc_lightwellAI : public PassiveAI
- {
- npc_lightwellAI(Creature* creature) : PassiveAI(creature)
- {
- DoCast(me, 59907, false);
- }
-
- void EnterEvadeMode() OVERRIDE
- {
- if (!me->IsAlive())
- return;
-
- me->DeleteThreatList();
- me->CombatStop(true);
- me->ResetPlayerDamageReq();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_lightwellAI(creature);
- }
-};
-
enum TrainingDummy
{
NPC_ADVANCED_TARGET_DUMMY = 2674,
@@ -2065,159 +1779,6 @@ public:
};
/*######
-# npc_shadowfiend
-######*/
-#define GLYPH_OF_SHADOWFIEND_MANA 58227
-#define GLYPH_OF_SHADOWFIEND 58228
-
-class npc_shadowfiend : public CreatureScript
-{
- public:
- npc_shadowfiend() : CreatureScript("npc_shadowfiend") { }
-
- struct npc_shadowfiendAI : public PetAI
- {
- npc_shadowfiendAI(Creature* creature) : PetAI(creature) {}
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- if (me->IsSummon())
- if (Unit* owner = me->ToTempSummon()->GetSummoner())
- if (owner->HasAura(GLYPH_OF_SHADOWFIEND))
- owner->CastSpell(owner, GLYPH_OF_SHADOWFIEND_MANA, true);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_shadowfiendAI(creature);
- }
-};
-
-/*######
-# npc_fire_elemental
-######*/
-
-enum FireElemental
-{
- SPELL_FIRENOVA = 12470,
- SPELL_FIRESHIELD = 13376,
- 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() OVERRIDE
- {
- 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(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- if (FireShield_Timer <= diff)
- {
- DoCastVictim(SPELL_FIRESHIELD);
- FireShield_Timer = 2 * IN_MILLISECONDS;
- }
- else
- FireShield_Timer -= diff;
-
- if (FireBlast_Timer <= diff)
- {
- DoCastVictim(SPELL_FIREBLAST);
- FireBlast_Timer = 5000 + rand() % 15000; // 5-20 sec cd
- }
- else
- FireBlast_Timer -= diff;
-
- if (FireNova_Timer <= diff)
- {
- DoCastVictim(SPELL_FIRENOVA);
- FireNova_Timer = 5000 + rand() % 15000; // 5-20 sec cd
- }
- else
- FireNova_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_fire_elementalAI(creature);
- }
-};
-
-/*######
-# npc_earth_elemental
-######*/
-
-enum EarthElemental
-{
- 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() OVERRIDE
- {
- AngeredEarth_Timer = 0;
- me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (AngeredEarth_Timer <= diff)
- {
- DoCastVictim(SPELL_ANGEREDEARTH);
- AngeredEarth_Timer = 5000 + rand() % 15000; // 5-20 sec cd
- }
- else
- AngeredEarth_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_earth_elementalAI(creature);
- }
-};
-
-/*######
# npc_wormhole
######*/
@@ -2987,19 +2548,12 @@ void AddSC_npcs_special()
new npc_steam_tonk();
new npc_tonk_mine();
new npc_brewfest_reveler();
- new npc_snake_trap();
- new npc_mirror_image();
- new npc_ebon_gargoyle();
- new npc_lightwell();
new npc_mojo();
new npc_training_dummy();
- new npc_shadowfiend();
new npc_wormhole();
new npc_pet_trainer();
new npc_locksmith();
new npc_experience();
- new npc_fire_elemental();
- new npc_earth_elemental();
new npc_firework();
new npc_spring_rabbit();
}