aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <none@none>2010-10-16 16:34:21 +0200
committerShauren <none@none>2010-10-16 16:34:21 +0200
commit4ce274dbcdeba8b9647bc445efda4a211b730a8e (patch)
tree81e12625d17b3d64a4c5caac3a9c13ca1126c3a7 /src
parent8154f7243cfa6221662615993b2bd17b75f06c38 (diff)
Scripts/Icecrown Citadel: Added Professor Putricide script
Scripts/Icecrown Citadel: Fixed Professor Putricide gate opening when both Rotface and Festergut are dead Scripts/Icecrown Citadel: Added script updating entries of NPCs at Light's Hammer depending on faction Scripts/Icecrown Citadel: Rotface should not pick main tank as target for Slime Spray (removed debugging code) Core/Spells/Conditions : Spell script target condition now accepts ConditionValue3 as affecting effect mask (only search targets with matching mask) --HG-- branch : trunk
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Conditions/ConditionMgr.cpp14
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp10
-rwxr-xr-xsrc/server/game/Miscellaneous/SharedDefines.h4
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp14
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp20
-rwxr-xr-xsrc/server/game/Spells/Spell.h2
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp40
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp1124
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp10
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h106
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp57
11 files changed, 1299 insertions, 102 deletions
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index a6626ca62b2..155d73569f2 100755
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -828,10 +828,17 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
spellProto->EffectImplicitTargetB[i] == TARGET_UNIT_CONE_ENTRY)
{
targetfound = true;
- break;
+ //break;
+ }
+ else if (cond->mConditionValue3 & (1 << i))
+ {
+ cond->mConditionValue3 &= ~(1 << i);
+ sLog.outErrorDb("SourceEntry %u in `condition` table does not have any implicit target TARGET_UNIT_NEARBY_ENTRY(38) or TARGET_DST_NEARBY_ENTRY (46)"
+ ",TARGET_UNIT_AREA_ENTRY_SRC(7), TARGET_UNIT_AREA_ENTRY_DST(8), TARGET_UNIT_CONE_ENTRY(60), TARGET_GAMEOBJECT_NEARBY_ENTRY(40)"
+ "TARGET_GAMEOBJECT_AREA_SRC(51), TARGET_GAMEOBJECT_AREA_DST(52) in effect %u", cond->mSourceEntry, uint32(i));
}
}
- if (!targetfound)
+ if (!targetfound && !cond->mConditionValue3) // cond->mConditionValue3 already errored up there
{
sLog.outErrorDb("SourceEntry %u in `condition` table does not have any implicit target TARGET_UNIT_NEARBY_ENTRY(38) or TARGET_DST_NEARBY_ENTRY (46)"
",TARGET_UNIT_AREA_ENTRY_SRC(7), TARGET_UNIT_AREA_ENTRY_DST(8), TARGET_UNIT_CONE_ENTRY(60), TARGET_GAMEOBJECT_NEARBY_ENTRY(40)"
@@ -1175,9 +1182,6 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
break;
}
}
-
- if (cond->mConditionValue3)
- sLog.outErrorDb("SpellTarget condition has useless data in value3 (%u)!", cond->mConditionValue3);
break;
}
case CONDITION_CREATURE_TARGET:
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 2e3737c6037..f4d3346145b 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -5701,6 +5701,16 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
target = triggeredByAura->GetCaster();
break;
}
+ // Gaseous Bloat (Professor Putricide add)
+ case 70215:
+ case 72858:
+ case 72859:
+ case 72860:
+ {
+ target = getVictim();
+ triggered_spell_id = 70701;
+ break;
+ }
}
break;
}
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index bf2de3b0930..5f49e7e60a7 100755
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -1004,10 +1004,10 @@ enum AuraState
AURA_STATE_DEADLY_POISON = 16, // T |
AURA_STATE_ENRAGE = 17, // C |
AURA_STATE_BLEEDING = 18, // T|
- //AURA_STATE_UNKNOWN19 = 19, // | not used
+ AURA_STATE_UNKNOWN19 = 19, // |
//AURA_STATE_UNKNOWN20 = 20, // c | only (45317 Suicide)
//AURA_STATE_UNKNOWN21 = 21, // | not used
- //AURA_STATE_UNKNOWN22 = 22, // C t| varius spells (63884, 50240)
+ AURA_STATE_UNKNOWN22 = 22, // C t| varius spells (63884, 50240)
AURA_STATE_HEALTH_ABOVE_75_PERCENT = 23, // C |
};
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 629f9b9850f..87baad480a7 100755
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -1316,6 +1316,20 @@ void AuraEffect::PeriodicTick(Unit * target, Unit * caster) const
}
}
}
+ if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_GENERIC)
+ {
+ switch (GetId())
+ {
+ case 70911: // Unbound Plague
+ case 72854: // Unbound Plague
+ case 72855: // Unbound Plague
+ case 72856: // Unbound Plague
+ damage *= uint32(pow(1.25f, int32(m_tickNumber)));
+ break;
+ default:
+ break;
+ }
+ }
}
else
damage = uint32(target->CountPctFromMaxHealth(damage));
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 0aed57b9c4e..819fe27606f 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1877,7 +1877,7 @@ void Spell::SearchGOAreaTarget(std::list<GameObject*> &TagGOMap, float radius, S
m_caster->GetMap()->VisitGrid(pos->m_positionX, pos->m_positionY, radius, searcher);
}
-WorldObject* Spell::SearchNearbyTarget(float range, SpellTargets TargetType)
+WorldObject* Spell::SearchNearbyTarget(float range, SpellTargets TargetType, SpellEffIndex effIndex)
{
switch(TargetType)
{
@@ -1888,9 +1888,9 @@ WorldObject* Spell::SearchNearbyTarget(float range, SpellTargets TargetType)
{
sLog.outDebug("Spell (ID: %u) (caster Entry: %u) does not have record in `conditions` for spell script target (ConditionSourceType 14)", m_spellInfo->Id, m_caster->GetEntry());
if (IsPositiveSpell(m_spellInfo->Id))
- return SearchNearbyTarget(range, SPELL_TARGETS_ALLY);
+ return SearchNearbyTarget(range, SPELL_TARGETS_ALLY, effIndex);
else
- return SearchNearbyTarget(range, SPELL_TARGETS_ENEMY);
+ return SearchNearbyTarget(range, SPELL_TARGETS_ENEMY, effIndex);
}
Creature* creatureScriptTarget = NULL;
@@ -1900,6 +1900,8 @@ WorldObject* Spell::SearchNearbyTarget(float range, SpellTargets TargetType)
{
if ((*i_spellST)->mConditionType != CONDITION_SPELL_SCRIPT_TARGET)
continue;
+ if ((*i_spellST)->mConditionValue3 && !((*i_spellST)->mConditionValue3 & (1 << uint32(effIndex))))
+ continue;
switch((*i_spellST)->mConditionValue1)
{
case SPELL_TARGET_TYPE_CONTROLLED:
@@ -2087,20 +2089,20 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
case TARGET_UNIT_NEARBY_ENEMY:
range = GetSpellMaxRange(m_spellInfo, false);
if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
- target = SearchNearbyTarget(range, SPELL_TARGETS_ENEMY);
+ target = SearchNearbyTarget(range, SPELL_TARGETS_ENEMY, SpellEffIndex(i));
break;
case TARGET_UNIT_NEARBY_ALLY:
case TARGET_UNIT_NEARBY_ALLY_UNK:
case TARGET_UNIT_NEARBY_RAID:
range = GetSpellMaxRange(m_spellInfo, true);
if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
- target = SearchNearbyTarget(range, SPELL_TARGETS_ALLY);
+ target = SearchNearbyTarget(range, SPELL_TARGETS_ALLY, SpellEffIndex(i));
break;
case TARGET_UNIT_NEARBY_ENTRY:
case TARGET_GAMEOBJECT_NEARBY_ENTRY:
range = GetSpellMaxRange(m_spellInfo, IsPositiveSpell(m_spellInfo->Id));
if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
- target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY);
+ target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY, SpellEffIndex(i));
break;
}
@@ -2303,7 +2305,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
float range = GetSpellMaxRange(m_spellInfo, IsPositiveSpell(m_spellInfo->Id));
if (modOwner) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
- if (WorldObject *target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY))
+ if (WorldObject *target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY, SpellEffIndex(i)))
m_targets.setDst(*target);
break;
}
@@ -2473,6 +2475,8 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
{
if ((*i_spellST)->mConditionType != CONDITION_SPELL_SCRIPT_TARGET)
continue;
+ if ((*i_spellST)->mConditionValue3 && !((*i_spellST)->mConditionValue3 & (1<<i)))
+ continue;
if ((*i_spellST)->mConditionValue1 == SPELL_TARGET_TYPE_CREATURE)
SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENTRY, (*i_spellST)->mConditionValue2);
else if ((*i_spellST)->mConditionValue1 == SPELL_TARGET_TYPE_CONTROLLED)
@@ -2568,6 +2572,8 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
{
if ((*i_spellST)->mConditionType != CONDITION_SPELL_SCRIPT_TARGET)
continue;
+ if ((*i_spellST)->mConditionValue3 && !((*i_spellST)->mConditionValue3 & (1<<i)))
+ continue;
if ((*i_spellST)->mConditionValue1 == SPELL_TARGET_TYPE_GAMEOBJECT)
SearchGOAreaTarget(gobjectList, radius, pushType, SPELL_TARGETS_GO, (*i_spellST)->mConditionValue2);
}
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 3509f0bffac..2a74e21f817 100755
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -660,7 +660,7 @@ class Spell
void SearchAreaTarget(std::list<Unit*> &unitList, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry = 0);
void SearchGOAreaTarget(std::list<GameObject*> &gobjectList, float radius, SpellNotifyPushType type, SpellTargets TargetType, uint32 entry = 0);
void SearchChainTarget(std::list<Unit*> &unitList, float radius, uint32 unMaxTargets, SpellTargets TargetType);
- WorldObject* SearchNearbyTarget(float range, SpellTargets TargetType);
+ WorldObject* SearchNearbyTarget(float range, SpellTargets TargetType, SpellEffIndex effIndex);
bool IsValidSingleTargetEffect(Unit const* target, Targets type) const;
bool IsValidSingleTargetSpell(Unit const* target) const;
bool IsValidDeadOrAliveTarget(Unit const* target) const;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 48d8faa4369..f18d53bc893 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3605,6 +3605,8 @@ void SpellMgr::LoadSpellCustomAttr()
case 64422: case 64688: // Sonic Screech
case 72373: // Shared Suffering
case 71904: // Chaos Bane
+ case 70492: case 72505: // Ooze Eruption
+ case 72624: case 72625: // Ooze Eruption
// ONLY SPELLS WITH SPELLFAMILY_GENERIC and EFFECT_SCHOOL_DAMAGE
mSpellCustomAttr[i] |= SPELL_ATTR_CU_SHARE_DAMAGE;
count++;
@@ -3882,6 +3884,44 @@ void SpellMgr::LoadSpellCustomAttr()
spellInfo->EffectSpellClassMask[0] = flag96(423937, 276955137, 2049);
count++;
break;
+ // this is here until targetAuraSpell and alike support SpellDifficulty.dbc
+ case 70459: // Ooze Eruption Search Effect
+ spellInfo->targetAuraSpell = 0;
+ count++;
+ break;
+ case 71413: // Green Ooze Summon
+ case 71414: // Orange Ooze Summon
+ spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST;
+ count++;
+ break;
+ // THIS IS HERE BECAUSE COOLDOWN ON CREATURE PROCS IS NOT IMPLEMENTED
+ case 71604: // Mutated Strength
+ case 72673: // Mutated Strength
+ case 72674: // Mutated Strength
+ case 72675: // Mutated Strength
+ spellInfo->Effect[1] = 0;
+ count++;
+ break;
+ case 70447: // Volatile Ooze Adhesive
+ case 72836: // Volatile Ooze Adhesive
+ case 72837: // Volatile Ooze Adhesive
+ case 72838: // Volatile Ooze Adhesive
+ case 70672: // Gaseous Bloat
+ case 72455: // Gaseous Bloat
+ case 72832: // Gaseous Bloat
+ case 72833: // Gaseous Bloat
+ spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ENEMY;
+ spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_TARGET_ENEMY;
+ spellInfo->EffectImplicitTargetB[2] = TARGET_UNIT_TARGET_ENEMY;
+ count++;
+ break;
+ case 70911: // Unbound Plague
+ case 72854: // Unbound Plague
+ case 72855: // Unbound Plague
+ case 72856: // Unbound Plague
+ spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ENEMY;
+ count++;
+ break;
default:
break;
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index f8ab37813ab..0ef0504ca39 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -15,32 +15,94 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
#include "icecrown_citadel.h"
enum eScriptTexts
{
// Festergut
- SAY_FESTERGUT_GASEOUS_BLIGHT = -1631080,
- SAY_FESTERGUT_DEATH = -1631090,
- SAY_ROTFACE_OOZE_FLOOD1 = -1631091,
- SAY_ROTFACE_OOZE_FLOOD2 = -1631092,
- SAY_ROTFACE_DEATH = -1631093,
+ SAY_FESTERGUT_GASEOUS_BLIGHT = -1631080,
+ SAY_FESTERGUT_DEATH = -1631090,
+
+ // Rotface
+ SAY_ROTFACE_OOZE_FLOOD1 = -1631091,
+ SAY_ROTFACE_OOZE_FLOOD2 = -1631092,
+ SAY_ROTFACE_DEATH = -1631093,
+
+ // Professor Putricide
+ SAY_AGGRO = -1631104,
+ EMOTE_UNSTABLE_EXPERIMENT = -1631105,
+ SAY_PHASE_TRANSITION_HEROIC = -1631106,
+ SAY_TRANSFORM_1 = -1631107,
+ SAY_TRANSFORM_2 = -1631108,
+ EMOTE_MALLEABLE_GOO = -1631109,
+ EMOTE_CHOKING_GAS_BOMB = -1631110,
+ SAY_KILL_1 = -1631111,
+ SAY_KILL_2 = -1631112,
+ SAY_BERSERK = -1631113,
+ SAY_DEATH = -1631114
};
enum eSpells
{
// Festergut
- SPELL_RELEASE_GAS_VISUAL = 69125,
- SPELL_GASEOUS_BLIGHT_LARGE = 69157,
- SPELL_GASEOUS_BLIGHT_MEDIUM = 69162,
- SPELL_GASEOUS_BLIGHT_SMALL = 69164,
- SPELL_MALLABLE_GOO_H = 70852,
+ SPELL_RELEASE_GAS_VISUAL = 69125,
+ SPELL_GASEOUS_BLIGHT_LARGE = 69157,
+ SPELL_GASEOUS_BLIGHT_MEDIUM = 69162,
+ SPELL_GASEOUS_BLIGHT_SMALL = 69164,
+ SPELL_MALLABLE_GOO_H = 70852,
// Rotface
- SPELL_VILE_GAS_H = 69240,
+ SPELL_VILE_GAS_H = 69240,
+
+ // Professor Putricide
+ SPELL_SLIME_PUDDLE_TRIGGER = 70341,
+ SPELL_MALLEABLE_GOO = 70852,
+ SPELL_UNSTABLE_EXPERIMENT = 70351,
+ SPELL_TEAR_GAS = 71617, // phase transition
+ SPELL_CREATE_CONCOCTION = 71621,
+ SPELL_GUZZLE_POTIONS = 71893,
+ SPELL_OOZE_TANK_PROTECTION = 71770, // protects the tank
+ SPELL_CHOKING_GAS_BOMB = 71255,
+ SPELL_OOZE_VARIABLE = 70352,
+ SPELL_GAS_VARIABLE = 70353,
+ SPELL_UNBOUND_PLAGUE = 70911,
+ SPELL_UNBOUND_PLAGUE_SEARCHER = 70917,
+ SPELL_PLAGUE_SICKNESS = 70953,
+ SPELL_UNBOUND_PLAGUE_PROTECTION = 70955,
+ SPELL_MUTATED_PLAGUE = 72451,
+
+ // Slime Puddle
+ SPELL_GROW_STACKER = 70345,
+ SPELL_SLIME_PUDDLE_AURA = 70343,
+
+ // Gas Cloud
+ SPELL_GASEOUS_BLOAT_PROC = 70215,
+ SPELL_GASEOUS_BLOAT = 70672,
+ SPELL_GASEOUS_BLOAT_PROTECTION = 70812,
+
+ // Volatile Ooze
+ SPELL_OOZE_ERUPTION = 70492,
+ SPELL_VOLATILE_OOZE_ADHESIVE = 70447,
+ SPELL_OOZE_ERUPTION_SEARCH_PERIODIC = 70457,
+ SPELL_VOLATILE_OOZE_PROTECTION = 70530,
+
+ // Choking Gas Bomb
+ SPELL_CHOKING_GAS_BOMB_PERIODIC = 71259,
+ SPELL_CHOKING_GAS_EXPLOSION_TRIGGER = 71280,
+
+ // Mutated Abomination vehicle
+ SPELL_ABOMINATION_VEHICLE_POWER_DRAIN = 70385,
+ SPELL_MUTATED_TRANSFORMATION = 70311,
+ SPELL_MUTATED_TRANSFORMATION_DAMAGE = 70405,
+ SPELL_MUTATED_TRANSFORMATION_NAME = 72401,
};
+#define SPELL_GASEOUS_BLOAT_HELPER RAID_MODE<uint32>(70672,72455,72832,72833)
+
enum eEvents
{
// Festergut
@@ -51,14 +113,29 @@ enum eEvents
EVENT_ROTFACE_DIES = 3,
EVENT_ROTFACE_VILE_GAS = 4,
EVENT_ROTFACE_OOZE_FLOOD = 5,
+
+ // Professor Putricide
+ EVENT_BERSERK = 6, // all phases
+ EVENT_SLIME_PUDDLE = 7, // all phases
+ EVENT_UNSTABLE_EXPERIMENT = 8, // P1 && P2
+ EVENT_TEAR_GAS = 9, // phase transition not heroic
+ EVENT_RESUME_ATTACK = 10,
+ EVENT_MALLEABLE_GOO = 11,
+ EVENT_CHOKING_GAS_BOMB = 12,
+ EVENT_UNBOUND_PLAGUE = 13,
+ EVENT_MUTATED_PLAGUE = 14,
+ EVENT_PHASE_TRANSITION = 15,
};
enum ePhases
{
PHASE_FESTERGUT = 1,
PHASE_ROTFACE = 2,
- PHASE_COMBAT = 3,
+ PHASE_COMBAT_1 = 4,
+ PHASE_COMBAT_2 = 5,
+ PHASE_COMBAT_3 = 6,
+ PHASE_MASK_COMBAT = (1 << PHASE_COMBAT_1) | (1 << PHASE_COMBAT_2) | (1 << PHASE_COMBAT_3),
PHASE_MASK_NOT_SELF = (1 << PHASE_FESTERGUT) | (1 << PHASE_ROTFACE)
};
@@ -66,13 +143,33 @@ enum ePoints
{
POINT_FESTERGUT = 366260,
POINT_ROTFACE = 366270,
+ POINT_TABLE = 366780,
};
static const Position festergutWatchPos = {4324.820f, 3166.03f, 389.3831f, 3.316126f}; //emote 432 (release gas)
-static const Position rotfaceWatchPos = {4390.371f, 3164.50f, 389.3890f, 5.497787f}; //emote 432 (release gas)
+static const Position rotfaceWatchPos = {4390.371f, 3164.50f, 389.3890f, 5.497787f}; //emote 432 (release ooze)
+static const Position tablePos = {4356.190f, 3262.90f, 389.4820f, 1.483530f};
static const uint32 oozeFloodSpells[4] = {69782, 69796, 69798, 69801};
+#define DATA_EXPERIMENT_STAGE 0
+#define EXPERIMENT_STATE_OOZE false
+#define EXPERIMENT_STATE_GAS true
+
+class StartMovementEvent : public BasicEvent
+{
+ public:
+ StartMovementEvent(Creature& owner) : BasicEvent(), m_owner(owner) { }
+ bool Execute(uint64 /*eventTime*/, uint32 /*diff*/)
+ {
+ m_owner.GetMotionMaster()->MoveChase(m_owner.getVictim());
+ return true;
+ }
+
+ private:
+ Creature& m_owner;
+};
+
class boss_professor_putricide : public CreatureScript
{
public:
@@ -81,7 +178,7 @@ class boss_professor_putricide : public CreatureScript
struct boss_professor_putricideAI : public BossAI
{
boss_professor_putricideAI(Creature* pCreature) : BossAI(pCreature, DATA_PROFESSOR_PUTRICIDE),
- fBaseSpeed(pCreature->GetSpeedRate(MOVE_RUN))
+ fBaseSpeed(pCreature->GetSpeedRate(MOVE_RUN)), bExperimentState(EXPERIMENT_STATE_OOZE)
{
ASSERT(instance);
phase = ePhases(0);
@@ -89,15 +186,184 @@ class boss_professor_putricide : public CreatureScript
void Reset()
{
+ if (!(events.GetPhaseMask() & PHASE_MASK_NOT_SELF))
+ instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, NOT_STARTED);
+ instance->SetData(DATA_NAUSEA___ACHIEVEMENT, uint32(true));
+
events.Reset();
summons.DespawnAll();
- _SetPhase(PHASE_COMBAT);
+ _SetPhase(PHASE_COMBAT_1);
+ bExperimentState = EXPERIMENT_STATE_OOZE;
me->SetReactState(REACT_DEFENSIVE);
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
}
+ void EnterCombat(Unit* /*who*/)
+ {
+ if (events.GetPhaseMask() & PHASE_MASK_NOT_SELF)
+ return;
+
+ _SetPhase(PHASE_COMBAT_1);
+ DoScriptText(SAY_AGGRO, me);
+ DoCast(me, SPELL_OOZE_TANK_PROTECTION, true);
+ DoZoneInCombat(me);
+
+ events.Reset();
+ events.ScheduleEvent(EVENT_BERSERK, 600000);
+ events.ScheduleEvent(EVENT_SLIME_PUDDLE, 10000);
+ events.ScheduleEvent(EVENT_UNSTABLE_EXPERIMENT, urand(25000, 30000));
+ if (IsHeroic())
+ events.ScheduleEvent(EVENT_UNBOUND_PLAGUE, 20000);
+
+ instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, IN_PROGRESS);
+ }
+
+ void JustReachedHome()
+ {
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ if (events.GetPhaseMask() & PHASE_MASK_COMBAT)
+ instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, FAIL);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ DoScriptText(RAND(SAY_KILL_1, SAY_KILL_2), me);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoScriptText(SAY_DEATH, me);
+ instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, DONE);
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ summons.Summon(summon);
+ switch (summon->GetEntry())
+ {
+ case NPC_GROWING_OOZE_PUDDLE:
+ summon->CastSpell(summon, SPELL_GROW_STACKER, true);
+ summon->CastSpell(summon, SPELL_SLIME_PUDDLE_AURA, true);
+ break;
+ case NPC_GAS_CLOUD:
+ // no possible aura seen in sniff adding the aurastate
+ summon->SetFlag(UNIT_FIELD_AURASTATE, 1 << (AURA_STATE_UNKNOWN22-1));
+ summon->CastSpell(summon, SPELL_GASEOUS_BLOAT_PROC, true);
+ // taunt immunity
+ summon->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_GASEOUS_BLOAT_PROTECTION))
+ {
+ summon->AI()->AttackStart(target);
+ summon->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_MAX_TARGETS, 1, target, false);
+ summon->clearUnitState(UNIT_STAT_CASTING);
+ summon->GetMotionMaster()->MoveIdle();
+ summon->m_Events.AddEvent(new StartMovementEvent(*summon), summon->m_Events.CalculateTime(3500));
+ }
+ return;
+ case NPC_VOLATILE_OOZE:
+ // no possible aura seen in sniff adding the aurastate
+ summon->SetFlag(UNIT_FIELD_AURASTATE, 1 << (AURA_STATE_UNKNOWN19-1));
+ summon->CastSpell(summon, SPELL_OOZE_ERUPTION_SEARCH_PERIODIC, true);
+ // taunt immunity
+ summon->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
+ summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_VOLATILE_OOZE_PROTECTION))
+ {
+ summon->AI()->AttackStart(target);
+ summon->CastCustomSpell(SPELL_VOLATILE_OOZE_ADHESIVE, SPELLVALUE_MAX_TARGETS, 1, target, false);
+ summon->clearUnitState(UNIT_STAT_CASTING);
+ summon->GetMotionMaster()->MoveIdle();
+ summon->m_Events.AddEvent(new StartMovementEvent(*summon), summon->m_Events.CalculateTime(3500));
+ }
+ return;
+ case NPC_CHOKING_GAS_BOMB:
+ summon->CastSpell(summon, SPELL_CHOKING_GAS_BOMB_PERIODIC, true);
+ summon->CastSpell(summon, SPELL_CHOKING_GAS_EXPLOSION_TRIGGER, true);
+ return;
+ default:
+ break;
+ }
+ if (me->isInCombat())
+ DoZoneInCombat(summon);
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/)
+ {
+ switch (phase)
+ {
+ case PHASE_COMBAT_1:
+ if (HealthAbovePct(80))
+ return;
+ me->SetReactState(REACT_PASSIVE);
+ DoAction(ACTION_CHANGE_PHASE);
+ break;
+ case PHASE_COMBAT_2:
+ if (HealthAbovePct(35))
+ return;
+ me->SetReactState(REACT_PASSIVE);
+ DoAction(ACTION_CHANGE_PHASE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+ switch (id)
+ {
+ case POINT_FESTERGUT:
+ me->SetSpeed(MOVE_RUN, fBaseSpeed, true);
+ DoAction(ACTION_FESTERGUT_GAS);
+ if (Creature* festergut = Unit::GetCreature(*me, instance->GetData64(DATA_FESTERGUT)))
+ festergut->CastSpell(festergut, SPELL_GASEOUS_BLIGHT_LARGE, false, NULL, NULL, festergut->GetGUID());
+ break;
+ case POINT_ROTFACE:
+ me->SetSpeed(MOVE_RUN, fBaseSpeed, true);
+ DoAction(ACTION_ROTFACE_OOZE);
+ events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25000, 0, PHASE_ROTFACE);
+ break;
+ case POINT_TABLE:
+ // stop attack
+ me->GetMotionMaster()->MoveIdle();
+ me->Attack(me->getVictim(), false);
+ me->SetSpeed(MOVE_RUN, fBaseSpeed, true);
+ if (GameObject* table = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_PUTRICIDE_TABLE)))
+ me->SetFacingToObject(table);
+ // operating on new phase already
+ switch (phase)
+ {
+ case PHASE_COMBAT_2:
+ {
+ SpellEntry const* spell = sSpellStore.LookupEntry(SPELL_CREATE_CONCOCTION);
+ spell = sSpellMgr.GetSpellForDifficultyFromSpell(spell, me);
+ DoCast(me, SPELL_CREATE_CONCOCTION);
+ events.ScheduleEvent(EVENT_PHASE_TRANSITION, GetSpellCastTime(spell)+100);
+ break;
+ }
+ case PHASE_COMBAT_3:
+ {
+ SpellEntry const* spell = sSpellStore.LookupEntry(SPELL_GUZZLE_POTIONS);
+ spell = sSpellMgr.GetSpellForDifficultyFromSpell(spell, me);
+ DoCast(me, SPELL_GUZZLE_POTIONS);
+ events.ScheduleEvent(EVENT_PHASE_TRANSITION, GetSpellCastTime(spell)+100);
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
void DoAction(const int32 action)
{
switch (action)
@@ -160,45 +426,87 @@ class boss_professor_putricide : public CreatureScript
}
case ACTION_ROTFACE_OOZE:
DoScriptText(RAND(SAY_ROTFACE_OOZE_FLOOD1, SAY_ROTFACE_OOZE_FLOOD2), me);
- if (Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE)))
- if (Creature* dummy = Unit::GetCreature(*me, oozeFloodDummy[oozeFloodStage]))
- dummy->CastSpell(dummy, oozeFloodSpells[oozeFloodStage], true, NULL, NULL, me->GetGUID()); // cast from self for LoS (with prof's GUID for logs)
+ if (Creature* dummy = Unit::GetCreature(*me, oozeFloodDummy[oozeFloodStage]))
+ dummy->CastSpell(dummy, oozeFloodSpells[oozeFloodStage], true, NULL, NULL, me->GetGUID()); // cast from self for LoS (with prof's GUID for logs)
if (++oozeFloodStage == 4)
oozeFloodStage = 0;
break;
case ACTION_ROTFACE_DEATH:
events.ScheduleEvent(EVENT_ROTFACE_DIES, 4500, 0, PHASE_ROTFACE);
break;
+ case ACTION_CHANGE_PHASE:
+ me->SetSpeed(MOVE_RUN, fBaseSpeed*2.0f, true);
+ events.DelayEvents(30000);
+ if (!IsHeroic())
+ {
+ DoCast(me, SPELL_TEAR_GAS);
+ events.ScheduleEvent(EVENT_TEAR_GAS, 2500);
+ }
+ else
+ {
+ DoScriptText(SAY_PHASE_TRANSITION_HEROIC, me);
+ DoCast(me, SPELL_UNSTABLE_EXPERIMENT, true);
+ DoCast(me, SPELL_UNSTABLE_EXPERIMENT, true);
+ // cast variables
+ if (Is25ManRaid())
+ {
+ std::list<Unit*> targetList;
+ {
+ const std::list<HostileReference*>& threatlist = me->getThreatManager().getThreatList();
+ for (std::list<HostileReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
+ if ((*itr)->getTarget()->GetTypeId() == TYPEID_PLAYER)
+ targetList.push_back((*itr)->getTarget());
+ }
+
+ size_t half = targetList.size()/2;
+ // half gets ooze variable
+ while (half < targetList.size())
+ {
+ std::list<Unit*>::iterator itr = targetList.begin();
+ advance(itr, urand(0, targetList.size()-1));
+ DoCast(*itr, SPELL_OOZE_VARIABLE);
+ targetList.erase(itr);
+ }
+ // and half gets gas
+ for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
+ DoCast(*itr, SPELL_GAS_VARIABLE);
+ }
+ me->GetMotionMaster()->MovePoint(POINT_TABLE, tablePos);
+ }
+ switch (phase)
+ {
+ case PHASE_COMBAT_1:
+ _SetPhase(PHASE_COMBAT_2);
+ events.ScheduleEvent(EVENT_MALLEABLE_GOO, urand(21000, 26000));
+ events.ScheduleEvent(EVENT_CHOKING_GAS_BOMB, urand(35000, 40000));
+ break;
+ case PHASE_COMBAT_2:
+ _SetPhase(PHASE_COMBAT_3);
+ events.ScheduleEvent(EVENT_MUTATED_PLAGUE, 25000);
+ events.CancelEvent(EVENT_UNSTABLE_EXPERIMENT);
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_MUTATED_TRANSFORMATION);
+ instance->DoRemoveAurasDueToSpellOnPlayers(71503); // SPELL_MUTATED_TRANSFORMATION2
+ break;
+ default:
+ break;
+ }
+ break;
default:
break;
}
}
- void JustReachedHome()
+ uint32 GetData(uint32 type)
{
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
- if (phase == PHASE_COMBAT)
- instance->SetBossState(DATA_PROFESSOR_PUTRICIDE, FAIL);
- }
-
- void MovementInform(uint32 type, uint32 id)
- {
- if (type != POINT_MOTION_TYPE)
- return;
- switch (id)
+ if (type == DATA_EXPERIMENT_STAGE)
{
- case POINT_FESTERGUT:
- me->SetSpeed(MOVE_RUN, fBaseSpeed, true);
- DoAction(ACTION_FESTERGUT_GAS);
- if (Creature* festergut = Unit::GetCreature(*me, instance->GetData64(DATA_FESTERGUT)))
- festergut->CastSpell(festergut, SPELL_GASEOUS_BLIGHT_LARGE, false, NULL, NULL, festergut->GetGUID());
- break;
- case POINT_ROTFACE:
- me->SetSpeed(MOVE_RUN, fBaseSpeed, true);
- DoAction(ACTION_ROTFACE_OOZE);
- events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25000, 0, PHASE_ROTFACE);
- break;
+ // ALSO MODIFIES!
+ uint32 ret = uint32(bExperimentState);
+ bExperimentState ^= true;
+ return ret;
}
+
+ return 0;
}
void UpdateAI(const uint32 diff)
@@ -236,10 +544,103 @@ class boss_professor_putricide : public CreatureScript
case EVENT_ROTFACE_OOZE_FLOOD:
DoAction(ACTION_ROTFACE_OOZE);
events.ScheduleEvent(EVENT_ROTFACE_OOZE_FLOOD, 25000, 0, PHASE_ROTFACE);
+ break;
+ case EVENT_BERSERK:
+ DoScriptText(SAY_BERSERK, me);
+ DoCast(me, SPELL_BERSERK2);
+ break;
+ case EVENT_SLIME_PUDDLE:
+ {
+ std::list<Unit*> targets;
+ SelectTargetList(targets, 2, SELECT_TARGET_RANDOM, 0.0f, true);
+ if (!targets.empty())
+ for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ DoCast(*itr, SPELL_SLIME_PUDDLE_TRIGGER);
+ events.ScheduleEvent(EVENT_SLIME_PUDDLE, 35000);
+ break;
+ }
+ case EVENT_UNSTABLE_EXPERIMENT:
+ DoScriptText(EMOTE_UNSTABLE_EXPERIMENT, me);
+ DoCast(me, SPELL_UNSTABLE_EXPERIMENT);
+ events.ScheduleEvent(EVENT_UNSTABLE_EXPERIMENT, urand(35000, 40000));
+ break;
+ case EVENT_TEAR_GAS:
+ me->GetMotionMaster()->MovePoint(POINT_TABLE, tablePos);
+ break;
+ case EVENT_RESUME_ATTACK:
+ me->SetReactState(REACT_DEFENSIVE);
+ AttackStart(me->getVictim());
+ // remove Tear Gas
+ instance->DoRemoveAurasDueToSpellOnPlayers(71615);
+ instance->DoRemoveAurasDueToSpellOnPlayers(71618);
+ break;
+ case EVENT_MALLEABLE_GOO:
+ if (Is25ManRaid())
+ {
+ std::list<Unit*> targets;
+ SelectTargetList(targets, 2, SELECT_TARGET_RANDOM, -7.0f, true);
+ if (!targets.empty())
+ {
+ DoScriptText(EMOTE_MALLEABLE_GOO, me);
+ for (std::list<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ DoCast(*itr, SPELL_MALLEABLE_GOO);
+ }
+ }
+ else
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, -7.0f, true))
+ {
+ DoScriptText(EMOTE_MALLEABLE_GOO, me);
+ DoCast(target, SPELL_MALLEABLE_GOO);
+ }
+ }
+ events.ScheduleEvent(EVENT_MALLEABLE_GOO, urand(25000, 30000));
+ break;
+ case EVENT_CHOKING_GAS_BOMB:
+ DoScriptText(EMOTE_CHOKING_GAS_BOMB, me);
+ DoCast(me, SPELL_CHOKING_GAS_BOMB);
+ events.ScheduleEvent(EVENT_CHOKING_GAS_BOMB, urand(35000, 40000));
+ break;
+ case EVENT_UNBOUND_PLAGUE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
+ {
+ me->CastCustomSpell(SPELL_UNBOUND_PLAGUE, SPELLVALUE_BASE_POINT0, 775, target);
+ DoCast(target, SPELL_UNBOUND_PLAGUE_SEARCHER);
+ }
+ events.ScheduleEvent(EVENT_UNBOUND_PLAGUE, 90000);
+ break;
+ case EVENT_MUTATED_PLAGUE:
+ DoCastVictim(SPELL_MUTATED_PLAGUE);
+ events.ScheduleEvent(EVENT_MUTATED_PLAGUE, 10000);
+ break;
+ case EVENT_PHASE_TRANSITION:
+ {
+ switch (phase)
+ {
+ case PHASE_COMBAT_2:
+ if (Creature* face = me->FindNearestCreature(NPC_TEAR_GAS_TARGET_STALKER, 50.0f))
+ me->SetFacingToObject(face);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
+ DoScriptText(SAY_TRANSFORM_1, me);
+ events.ScheduleEvent(EVENT_RESUME_ATTACK, 5500, 0, PHASE_COMBAT_2);
+ break;
+ case PHASE_COMBAT_3:
+ if (Creature* face = me->FindNearestCreature(NPC_TEAR_GAS_TARGET_STALKER, 50.0f))
+ me->SetFacingToObject(face);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
+ DoScriptText(SAY_TRANSFORM_2, me);
+ events.ScheduleEvent(EVENT_RESUME_ATTACK, 8500, 0, PHASE_COMBAT_3);
+ break;
+ default:
+ break;
+ }
+ }
default:
break;
}
}
+
+ DoMeleeAttackIfReady();
}
private:
@@ -250,9 +651,11 @@ class boss_professor_putricide : public CreatureScript
}
ePhases phase; // external of EventMap because event phase gets reset on evade
+ // Festergut & Rotface variables
const float fBaseSpeed;
uint64 oozeFloodDummy[4];
uint8 oozeFloodStage;
+ bool bExperimentState;
};
CreatureAI* GetAI(Creature* pCreature) const
@@ -261,6 +664,627 @@ class boss_professor_putricide : public CreatureScript
}
};
+class npc_volatile_ooze : public CreatureScript
+{
+ public:
+ npc_volatile_ooze() : CreatureScript("npc_volatile_ooze") { }
+
+ struct npc_volatile_oozeAI : public ScriptedAI
+ {
+ npc_volatile_oozeAI(Creature* pCreature) : ScriptedAI(pCreature)
+ {
+ uiNewTargetSelectTimer = 0;
+ }
+
+ void SpellHitTarget(Unit* /*pTarget*/, const SpellEntry* spell)
+ {
+ SpellEntry const* explode = sSpellStore.LookupEntry(SPELL_OOZE_ERUPTION);
+ explode = sSpellMgr.GetSpellForDifficultyFromSpell(explode, me);
+ if (explode->Id == spell->Id)
+ {
+ uiNewTargetSelectTimer = 5000;
+ DoStartNoMovement(me);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ if (!uiNewTargetSelectTimer)
+ return;
+
+ if (uiNewTargetSelectTimer <= diff)
+ {
+ uiNewTargetSelectTimer = 0;
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_VOLATILE_OOZE_PROTECTION))
+ {
+ AttackStart(target);
+ me->CastCustomSpell(SPELL_VOLATILE_OOZE_ADHESIVE, SPELLVALUE_MAX_TARGETS, 1, target, false);
+ }
+ else if (TempSummon* summ = me->ToTempSummon())
+ summ->UnSummon();
+ else
+ me->ForcedDespawn();
+ }
+ else
+ uiNewTargetSelectTimer -= diff;
+ }
+
+ private:
+ // no need to use EventMap for just one event
+ uint32 uiNewTargetSelectTimer;
+ };
+
+ CreatureAI* GetAI(Creature* pCreature) const
+ {
+ return new npc_volatile_oozeAI(pCreature);
+ }
+};
+
+class spell_putricide_gaseous_bloat : public SpellScriptLoader
+{
+ public:
+ spell_putricide_gaseous_bloat() : SpellScriptLoader("spell_putricide_gaseous_bloat") { }
+
+ class spell_putricide_gaseous_bloat_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_putricide_gaseous_bloat_SpellScript);
+
+ void ModAuraStack()
+ {
+ if (Aura* aur = GetHitAura())
+ aur->SetStackAmount(10);
+ }
+
+ void Register()
+ {
+ AfterHit += SpellHitFn(spell_putricide_gaseous_bloat_SpellScript::ModAuraStack);
+ }
+ };
+
+ class spell_putricide_gaseous_bloat_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_putricide_gaseous_bloat_AuraScript);
+
+ void HandleExtraEffect(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp)
+ {
+ if (aurApp->GetTarget())
+ aurApp->GetTarget()->RemoveAuraFromStack(GetSpellProto()->Id, aurApp->GetBase()->GetCasterGUID());
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_putricide_gaseous_bloat_AuraScript::HandleExtraEffect, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_putricide_gaseous_bloat_SpellScript();
+ }
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_putricide_gaseous_bloat_AuraScript();
+ }
+};
+
+class spell_putricide_expunged_gas : public SpellScriptLoader
+{
+ public:
+ spell_putricide_expunged_gas() : SpellScriptLoader("spell_putricide_expunged_gas") { }
+
+ class spell_putricide_expunged_gas_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_putricide_expunged_gas_SpellScript);
+
+ void CalcDamage(SpellEffIndex /*effIndex*/)
+ {
+ if (GetCaster()->GetTypeId() != TYPEID_UNIT)
+ return;
+
+ InstanceScript* instance = GetCaster()->GetInstanceScript();
+ if (!instance)
+ return;
+
+ Creature* professor = Unit::GetCreature(*GetCaster(), instance->GetData64(DATA_PROFESSOR_PUTRICIDE));
+ if (!professor)
+ return;
+
+ int32 dmg = 0;
+ ScriptedAI* professorAI = CAST_AI(ScriptedAI, professor->AI());
+ if (Aura* gasBloat = GetTargetUnit()->GetAura(professorAI->SPELL_GASEOUS_BLOAT_HELPER))
+ {
+ uint32 stack = gasBloat->GetStackAmount();
+ const int32 mod = professorAI->Is25ManRaid() ? 1500 : 1250;
+ for (uint8 i = 1; i < stack; ++i)
+ dmg += mod * stack;
+ }
+ else if (TempSummon* summ = GetCaster()->ToTempSummon())
+ summ->UnSummon();
+ else
+ GetCaster()->ToCreature()->ForcedDespawn();
+
+ SetHitDamage(dmg);
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_putricide_expunged_gas_SpellScript::CalcDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_putricide_expunged_gas_SpellScript();
+ }
+};
+
+class spell_putricide_slime_puddle : public SpellScriptLoader
+{
+ public:
+ spell_putricide_slime_puddle() : SpellScriptLoader("spell_putricide_slime_puddle") { }
+
+ class spell_putricide_slime_puddle_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_putricide_slime_puddle_AuraScript);
+
+ void HandleTriggerSpell(AuraEffect const* aurEff, AuraApplication const* aurApp)
+ {
+ PreventDefaultAction();
+ if (Unit* caster = aurApp->GetBase()->GetCaster())
+ {
+ int32 radiusMod = 4;
+ if (Aura* size = caster->GetAura(70347))
+ radiusMod += size->GetStackAmount();
+
+ uint32 triggerSpellId = GetSpellProto()->EffectTriggerSpell[aurEff->GetEffIndex()];
+ caster->CastCustomSpell(triggerSpellId, SPELLVALUE_RADIUS_MOD, radiusMod*100, caster, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_putricide_slime_puddle_AuraScript::HandleTriggerSpell, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_putricide_slime_puddle_AuraScript();
+ }
+};
+
+class spell_putricide_unstable_experiment : public SpellScriptLoader
+{
+ public:
+ spell_putricide_unstable_experiment() : SpellScriptLoader("spell_putricide_unstable_experiment") { }
+
+ class spell_putricide_unstable_experiment_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_putricide_unstable_experiment_SpellScript);
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ if (GetCaster()->GetTypeId() != TYPEID_UNIT)
+ return;
+
+ uint32 stage = GetCaster()->ToCreature()->AI()->GetData(DATA_EXPERIMENT_STAGE);
+ Creature* target = NULL;
+ std::list<Creature*> creList;
+ GetCreatureListWithEntryInGrid(creList, GetCaster(), NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER, 100.0f);
+ // 2 of them are spawned at green place - weird trick blizz
+ for (std::list<Creature*>::iterator itr = creList.begin(); itr != creList.end(); ++itr)
+ {
+ target = *itr;
+ std::list<Creature*> tmp;
+ GetCreatureListWithEntryInGrid(tmp, target, NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER, 1.0f);
+ if ((!stage && tmp.size() > 1) || (stage && tmp.size() == 1))
+ break;
+ }
+
+ GetCaster()->CastSpell(target, GetSpellInfo()->EffectBasePoints[stage]+1, true, NULL, NULL, GetCaster()->GetGUID());
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_putricide_unstable_experiment_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_putricide_unstable_experiment_SpellScript();
+ }
+};
+
+class spell_putricide_ooze_summon : public SpellScriptLoader
+{
+ public:
+ spell_putricide_ooze_summon() : SpellScriptLoader("spell_putricide_ooze_summon") { }
+
+ class spell_putricide_ooze_summon_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_putricide_ooze_summon_AuraScript);
+
+ void HandleTriggerSpell(AuraEffect const* aurEff, AuraApplication const* aurApp)
+ {
+ PreventDefaultAction();
+ if (Unit* caster = GetCaster())
+ {
+ uint32 triggerSpellId = GetSpellProto()->EffectTriggerSpell[aurEff->GetEffIndex()];
+ float x, y, z;
+ aurApp->GetTarget()->GetPosition(x, y, z);
+ z = aurApp->GetTarget()->GetMap()->GetHeight(x, y, z, true, 25.0f);
+ x += 10.0f * cosf(caster->GetOrientation());
+ y += 10.0f * sinf(caster->GetOrientation());
+ caster->CastSpell(x, y, z, triggerSpellId, true, NULL, NULL, GetCasterGUID(), caster);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_putricide_ooze_summon_AuraScript::HandleTriggerSpell, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_putricide_ooze_summon_AuraScript();
+ }
+};
+
+class spell_putricide_ooze_eruption_searcher : public SpellScriptLoader
+{
+ public:
+ spell_putricide_ooze_eruption_searcher() : SpellScriptLoader("spell_putricide_ooze_eruption_searcher") { }
+
+ class spell_putricide_ooze_eruption_searcher_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_putricide_ooze_eruption_searcher_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ SpellEntry const* adhesive = sSpellStore.LookupEntry(SPELL_VOLATILE_OOZE_ADHESIVE);
+ adhesive = sSpellMgr.GetSpellForDifficultyFromSpell(adhesive, GetCaster());
+ if (GetHitUnit()->HasAura(adhesive->Id))
+ {
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_OOZE_ERUPTION, true);
+ GetHitUnit()->RemoveAurasDueToSpell(adhesive->Id, GetCaster()->GetGUID());
+ }
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_putricide_ooze_eruption_searcher_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_putricide_ooze_eruption_searcher_SpellScript();
+ }
+};
+
+class spell_putricide_choking_gas_bomb : public SpellScriptLoader
+{
+ public:
+ spell_putricide_choking_gas_bomb() : SpellScriptLoader("spell_putricide_choking_gas_bomb") { }
+
+ class spell_putricide_choking_gas_bomb_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_putricide_choking_gas_bomb_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ uint32 skipIndex = urand(0, 2);
+ for (uint32 i = 0; i < 3; ++i)
+ {
+ if (i == skipIndex)
+ continue;
+
+ uint32 spellId = SpellMgr::CalculateSpellEffectAmount(GetSpellInfo(), uint8(i));
+ GetCaster()->CastSpell(GetCaster(), spellId, true, NULL, NULL, GetCaster()->GetGUID());
+ }
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_putricide_choking_gas_bomb_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_putricide_choking_gas_bomb_SpellScript();
+ }
+};
+
+class spell_putricide_unbound_plague : public SpellScriptLoader
+{
+ public:
+ spell_putricide_unbound_plague() : SpellScriptLoader("spell_putricide_unbound_plague") { }
+
+ class spell_putricide_unbound_plague_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_putricide_unbound_plague_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (!GetHitUnit())
+ return;
+
+ SpellEntry const* plague = sSpellStore.LookupEntry(SPELL_UNBOUND_PLAGUE);
+ SpellEntry const* searcher = sSpellStore.LookupEntry(SPELL_UNBOUND_PLAGUE_SEARCHER);
+ Creature* professor = NULL;
+ if (InstanceScript* instance = GetCaster()->GetInstanceScript())
+ {
+ professor = Unit::GetCreature(*GetCaster(), instance->GetData64(DATA_PROFESSOR_PUTRICIDE));
+ if (professor)
+ {
+ plague = sSpellMgr.GetSpellForDifficultyFromSpell(plague, professor);
+ searcher = sSpellMgr.GetSpellForDifficultyFromSpell(searcher, professor);
+ }
+ }
+
+ if (!GetHitUnit()->HasAura(plague->Id))
+ {
+ if (professor)
+ if (Aura* oldPlague = GetCaster()->GetAura(plague->Id, professor->GetGUID()))
+ if (Aura* newPlague = professor->AddAura(plague->Id, GetHitUnit()))
+ {
+ newPlague->SetMaxDuration(oldPlague->GetDuration());
+ newPlague->SetDuration(oldPlague->GetDuration());
+ oldPlague->Remove();
+ GetCaster()->RemoveAurasDueToSpell(searcher->Id);
+ GetCaster()->CastSpell(GetCaster(), SPELL_PLAGUE_SICKNESS, true);
+ GetCaster()->CastSpell(GetCaster(), SPELL_UNBOUND_PLAGUE_PROTECTION, true);
+ professor->CastSpell(GetHitUnit(), SPELL_UNBOUND_PLAGUE_SEARCHER, true);
+ }
+ }
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_putricide_unbound_plague_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_putricide_unbound_plague_SpellScript();
+ }
+};
+
+class spell_putricide_eat_ooze : public SpellScriptLoader
+{
+ public:
+ spell_putricide_eat_ooze() : SpellScriptLoader("spell_putricide_eat_ooze") { }
+
+ class spell_putricide_eat_ooze_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_putricide_eat_ooze_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Creature* target = GetCaster()->FindNearestCreature(NPC_GROWING_OOZE_PUDDLE, 15.0f))
+ {
+ if (Aura* grow = target->GetAura(GetEffectValue()))
+ {
+ if (grow->GetStackAmount() < 4)
+ {
+ target->RemoveAurasDueToSpell(SPELL_GROW_STACKER);
+ target->RemoveAura(grow);
+ if (TempSummon* summ = target->ToTempSummon())
+ summ->UnSummon();
+ else
+ target->ForcedDespawn();
+ }
+ else
+ grow->ModStackAmount(-4);
+ }
+ }
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_putricide_eat_ooze_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_putricide_eat_ooze_SpellScript();
+ }
+};
+
+class spell_putricide_mutated_plague : public SpellScriptLoader
+{
+ public:
+ spell_putricide_mutated_plague() : SpellScriptLoader("spell_putricide_mutated_plague") { }
+
+ class spell_putricide_mutated_plague_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_putricide_mutated_plague_AuraScript);
+
+ void HandleTriggerSpell(AuraEffect const* aurEff, AuraApplication const* aurApp)
+ {
+ PreventDefaultAction();
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+
+ uint32 triggerSpell = GetSpellProto()->EffectTriggerSpell[aurEff->GetEffIndex()];
+ SpellEntry const* spell = sSpellStore.LookupEntry(triggerSpell);
+ spell = sSpellMgr.GetSpellForDifficultyFromSpell(spell, caster);
+
+ int32 damage = SpellMgr::CalculateSpellEffectAmount(spell, 0, caster);
+ float multiplier = 2.0f;
+ if (aurApp->GetTarget()->GetMap()->GetSpawnMode() & 1)
+ multiplier = 3.0f;
+
+ damage *= int32(pow(multiplier, aurApp->GetBase()->GetStackAmount()));
+ damage *= 1.5;
+
+ aurApp->GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_BASE_POINT0, damage, aurApp->GetTarget(), true, NULL, aurEff, GetCasterGUID());
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/)
+ {
+ if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_STACK)
+ return;
+ uint32 healSpell = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), 0);
+ aurApp->GetTarget()->CastSpell(aurApp->GetTarget(), healSpell, true, NULL, NULL, GetCasterGUID());
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_putricide_mutated_plague_AuraScript::HandleTriggerSpell, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ OnEffectRemove += AuraEffectRemoveFn(spell_putricide_mutated_plague_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_putricide_mutated_plague_AuraScript();
+ }
+};
+
+class spell_putricide_mutation_init : public SpellScriptLoader
+{
+ public:
+ spell_putricide_mutation_init() : SpellScriptLoader("spell_putricide_mutation_init") { }
+
+ class spell_putricide_mutation_init_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_putricide_mutation_init_AuraScript);
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/)
+ {
+ uint32 spellId = 70311;
+ if (aurApp->GetTarget()->GetMap()->GetSpawnMode() & 1)
+ spellId = 71503;
+
+ aurApp->GetTarget()->CastSpell(aurApp->GetTarget(), spellId, true);
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_putricide_mutation_init_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_putricide_mutation_init_AuraScript();
+ }
+};
+
+class spell_putricide_mutated_transformation_dismiss : public SpellScriptLoader
+{
+ public:
+ spell_putricide_mutated_transformation_dismiss() : SpellScriptLoader("spell_putricide_mutated_transformation_dismiss") { }
+
+ class spell_putricide_mutated_transformation_dismiss_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_putricide_mutated_transformation_dismiss_AuraScript);
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraApplication const* aurApp, AuraEffectHandleModes /*mode*/)
+ {
+ if (Vehicle* veh = aurApp->GetTarget()->GetVehicleKit())
+ veh->RemoveAllPassengers();
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_putricide_mutated_transformation_dismiss_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_putricide_mutated_transformation_dismiss_AuraScript();
+ }
+};
+
+class spell_putricide_mutated_transformation : public SpellScriptLoader
+{
+ public:
+ spell_putricide_mutated_transformation() : SpellScriptLoader("spell_putricide_mutated_transformation") { }
+
+ class spell_putricide_mutated_transformation_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_putricide_mutated_transformation_SpellScript);
+
+ void HandleSummon(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ uint32 entry = GetSpellInfo()->EffectMiscValue[effIndex];
+ SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(GetSpellInfo()->EffectMiscValueB[effIndex]);
+ Unit* caster = GetOriginalCaster();
+ if (!caster)
+ return;
+
+ int32 duration = GetSpellDuration(GetSpellInfo());
+
+ Position pos;
+ caster->GetPosition(&pos);
+ TempSummon* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster);
+ if (!summon || !summon->IsVehicle())
+ return;
+
+ caster->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_NAME, true);
+ summon->CastSpell(summon, SPELL_ABOMINATION_VEHICLE_POWER_DRAIN, true);
+ summon->CastSpell(summon, SPELL_MUTATED_TRANSFORMATION_DAMAGE, true);
+ caster->EnterVehicle(summon->GetVehicleKit(), 0);
+
+ summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, GetSpellInfo()->Id);
+ summon->SetCreatorGUID(caster->GetGUID());
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_putricide_mutated_transformation_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_putricide_mutated_transformation_SpellScript();
+ }
+};
+
+class spell_putricide_regurgitated_ooze : public SpellScriptLoader
+{
+ public:
+ spell_putricide_regurgitated_ooze() : SpellScriptLoader("spell_putricide_regurgitated_ooze") { }
+
+ class spell_putricide_regurgitated_ooze_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_putricide_regurgitated_ooze_SpellScript);
+
+ // the only purpose of this hook is to fail the achievement
+ void ExtraEffect(SpellEffIndex /*effIndex*/)
+ {
+ if (InstanceScript* instance = GetCaster()->GetInstanceScript())
+ instance->SetData(DATA_NAUSEA___ACHIEVEMENT, uint32(false));
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_putricide_regurgitated_ooze_SpellScript::ExtraEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_putricide_regurgitated_ooze_SpellScript();
+ }
+};
+
// Stinky and Precious spell, it's here because its used for both (Festergut and Rotface "pets")
class spell_stinky_precious_decimate : public SpellScriptLoader
{
@@ -269,7 +1293,8 @@ class spell_stinky_precious_decimate : public SpellScriptLoader
class spell_stinky_precious_decimate_SpellScript : public SpellScript
{
- PrepareSpellScript(spell_stinky_precious_decimate_SpellScript)
+ PrepareSpellScript(spell_stinky_precious_decimate_SpellScript);
+
void HandleScript(SpellEffIndex /*effIndex*/)
{
if (GetHitUnit()->GetHealthPct() > float(GetEffectValue()))
@@ -295,5 +1320,20 @@ class spell_stinky_precious_decimate : public SpellScriptLoader
void AddSC_boss_professor_putricide()
{
new boss_professor_putricide();
+ new npc_volatile_ooze();
+ new spell_putricide_gaseous_bloat();
+ new spell_putricide_expunged_gas();
+ new spell_putricide_slime_puddle();
+ new spell_putricide_unstable_experiment();
+ new spell_putricide_ooze_summon();
+ new spell_putricide_ooze_eruption_searcher();
+ new spell_putricide_choking_gas_bomb();
+ new spell_putricide_unbound_plague();
+ new spell_putricide_eat_ooze();
+ new spell_putricide_mutated_plague();
+ new spell_putricide_mutation_init();
+ new spell_putricide_mutated_transformation_dismiss();
+ new spell_putricide_mutated_transformation();
+ new spell_putricide_regurgitated_ooze();
new spell_stinky_precious_decimate();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
index ca7ec22bd8e..d7ef1978da3 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
@@ -186,15 +186,13 @@ class boss_rotface : public CreatureScript
switch (eventId)
{
case EVENT_SLIME_SPRAY:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0/*1*/, 0.0f, true))
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
{
Position pos;
target->GetPosition(&pos);
- if (DoSummon(NPC_OOZE_SPRAY_STALKER, pos, 8000, TEMPSUMMON_TIMED_DESPAWN))
- {
- DoScriptText(EMOTE_SLIME_SPRAY, me);
- DoCastAOE(SPELL_SLIME_SPRAY);
- }
+ DoSummon(NPC_OOZE_SPRAY_STALKER, pos, 8000, TEMPSUMMON_TIMED_DESPAWN);
+ DoScriptText(EMOTE_SLIME_SPRAY, me);
+ DoCastAOE(SPELL_SLIME_SPRAY);
}
events.ScheduleEvent(EVENT_SLIME_SPRAY, 20000);
break;
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
index 9b838b6e5ab..5d3eee1499f 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
@@ -43,43 +43,73 @@ enum eData
DATA_BONED_ACHIEVEMENT = 13,
DATA_OOZE_DANCE_ACHIEVEMENT = 14,
+ DATA_PUTRICIDE_TABLE = 15,
+ DATA_NAUSEA___ACHIEVEMENT = 16,
};
#define MAX_ENCOUNTER 12
enum eCreatures
{
- NPC_LORD_MARROWGAR = 36612,
- NPC_COLDFLAME = 36672,
- NPC_BONE_SPIKE = 36619,
-
- NPC_LADY_DEATHWHISPER = 36855,
- NPC_CULT_FANATIC = 37890,
- NPC_DEFORMED_FANATIC = 38135,
- NPC_REANIMATED_FANATIC = 38009,
- NPC_CULT_ADHERENT = 37949,
- NPC_EMPOWERED_ADHERENT = 38136,
- NPC_REANIMATED_ADHERENT = 38010,
- NPC_VENGEFUL_SHADE = 38222,
-
- NPC_DEATHBRINGER_SAURFANG = 37813,
- NPC_BLOOD_BEAST = 38508,
- NPC_SE_JAINA_PROUDMOORE = 37188, // SE means Saurfang Event
- NPC_SE_MURADIN_BRONZEBEARD = 37200,
- NPC_SE_KING_VARIAN_WRYNN = 37879,
- NPC_SE_HIGH_OVERLORD_SAURFANG = 37187,
- NPC_SE_KOR_KRON_REAVER = 37920,
- NPC_SE_SKYBREAKER_MARINE = 37830,
-
- NPC_FESTERGUT = 36626,
- NPC_GAS_DUMMY = 36659,
-
- NPC_ROTFACE = 36627,
- NPC_OOZE_SPRAY_STALKER = 37986,
- NPC_PUDDLE_STALKER = 37013,
- NPC_UNSTABLE_EXPLOSION_STALKER = 38107,
-
- NPC_PROFESSOR_PUTRICIDE = 36678,
+ // At Light's Hammer
+ NPC_KOR_KRON_GENERAL = 37189,
+ NPC_ALLIANCE_COMMANDER = 37190,
+ NPC_TORTUNOK = 37992, // Druid Armor H
+ NPC_ALANA_MOONSTRIKE = 37999, // Druid Armor A
+ NPC_GERARDO_THE_SUAVE = 37993, // Hunter Armor H
+ NPC_TALAN_MOONSTRIKE = 37998, // Hunter Armor A
+ NPC_UVLUS_BANEFIRE = 38284, // Mage Armor H
+ NPC_MALFUS_GRIMFROST = 38283, // Mage Armor A
+ NPC_IKFIRUS_THE_VILE = 37991, // Rogue Armor H
+ NPC_YILI = 37997, // Rogue Armor A
+ NPC_VOL_GUK = 38841, // Shaman Armor H
+ NPC_JEDEBIA = 38840, // Shaman Armor A
+ NPC_HARAGG_THE_UNSEEN = 38181, // Warlock Armor H
+ NPC_NIBY_THE_ALMIGHTY = 38182, // Warlock Armor N
+
+ // Lord Marrowgar
+ NPC_LORD_MARROWGAR = 36612,
+ NPC_COLDFLAME = 36672,
+ NPC_BONE_SPIKE = 36619,
+
+ // Lady Deathwhisper
+ NPC_LADY_DEATHWHISPER = 36855,
+ NPC_CULT_FANATIC = 37890,
+ NPC_DEFORMED_FANATIC = 38135,
+ NPC_REANIMATED_FANATIC = 38009,
+ NPC_CULT_ADHERENT = 37949,
+ NPC_EMPOWERED_ADHERENT = 38136,
+ NPC_REANIMATED_ADHERENT = 38010,
+ NPC_VENGEFUL_SHADE = 38222,
+
+ // Deathbringer Saurfang
+ NPC_DEATHBRINGER_SAURFANG = 37813,
+ NPC_BLOOD_BEAST = 38508,
+ NPC_SE_JAINA_PROUDMOORE = 37188, // SE means Saurfang Event
+ NPC_SE_MURADIN_BRONZEBEARD = 37200,
+ NPC_SE_KING_VARIAN_WRYNN = 37879,
+ NPC_SE_HIGH_OVERLORD_SAURFANG = 37187,
+ NPC_SE_KOR_KRON_REAVER = 37920,
+ NPC_SE_SKYBREAKER_MARINE = 37830,
+
+ // Festergut
+ NPC_FESTERGUT = 36626,
+ NPC_GAS_DUMMY = 36659,
+
+ // Rotface
+ NPC_ROTFACE = 36627,
+ NPC_OOZE_SPRAY_STALKER = 37986,
+ NPC_PUDDLE_STALKER = 37013,
+ NPC_UNSTABLE_EXPLOSION_STALKER = 38107,
+
+ // Professor Putricide
+ NPC_PROFESSOR_PUTRICIDE = 36678,
+ NPC_ABOMINATION_WING_MAD_SCIENTIST_STALKER = 37824,
+ NPC_GROWING_OOZE_PUDDLE = 37690,
+ NPC_GAS_CLOUD = 37562,
+ NPC_VOLATILE_OOZE = 37697,
+ NPC_CHOKING_GAS_BOMB = 38159,
+ NPC_TEAR_GAS_TARGET_STALKER = 38317,
};
enum eGameobjects
@@ -103,18 +133,23 @@ enum eGameobjects
GO_DOODAD_ICECROWN_ORANGETUBES02 = 201617,
GO_DOODAD_ICECROWN_GREENTUBES02 = 201618,
GO_SCIENTIST_ENTRANCE = 201372,
+ GO_DRINK_ME = 201584,
};
enum eAchievementCriteria
{
- CRITERIA_BONED_10N = 12775,
- CRITERIA_BONED_25N = 12962,
- CRITERIA_BONED_10H = 13393,
- CRITERIA_BONED_25H = 13394,
+ CRITERIA_BONED_10N = 12775,
+ CRITERIA_BONED_25N = 12962,
+ CRITERIA_BONED_10H = 13393,
+ CRITERIA_BONED_25H = 13394,
CRITERIA_DANCES_WITH_OOZES_10N = 12984,
CRITERIA_DANCES_WITH_OOZES_25N = 12966,
CRITERIA_DANCES_WITH_OOZES_10H = 12985,
CRITERIA_DANCES_WITH_OOZES_25H = 12983,
+ CRITERIA_NAUSEA_10N = 12987,
+ CRITERIA_NAUSEA_25N = 12968,
+ CRITERIA_NAUSEA_10H = 12988,
+ CRITERIA_NAUSEA_25H = 12981,
};
enum ePutricideActions
@@ -125,6 +160,7 @@ enum ePutricideActions
ACTION_ROTFACE_COMBAT = -366270,
ACTION_ROTFACE_OOZE = -366271,
ACTION_ROTFACE_DEATH = -366272,
+ ACTION_CHANGE_PHASE = -366780
};
#endif // DEF_ICECROWN_CITADEL_H
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index 41917b96b9d..673ef17ae59 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -53,8 +53,10 @@ class instance_icecrown_citadel : public InstanceMapScript
uiFestergut = 0;
uiRotface = 0;
uiProfessorPutricide = 0;
+ uiPutricideTable;
isBonedEligible = true;
isOozeDanceEligible = true;
+ isNauseaEligible = true;
}
void OnCreatureCreate(Creature* creature, bool /*add*/)
@@ -70,6 +72,34 @@ class instance_icecrown_citadel : public InstanceMapScript
switch (creature->GetEntry())
{
+ case NPC_KOR_KRON_GENERAL:
+ if (TeamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_ALLIANCE_COMMANDER, ALLIANCE);
+ break;
+ case NPC_TORTUNOK:
+ if (TeamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_ALANA_MOONSTRIKE, ALLIANCE);
+ break;
+ case NPC_GERARDO_THE_SUAVE:
+ if (TeamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_TALAN_MOONSTRIKE, ALLIANCE);
+ break;
+ case NPC_UVLUS_BANEFIRE:
+ if (TeamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_MALFUS_GRIMFROST, ALLIANCE);
+ break;
+ case NPC_IKFIRUS_THE_VILE:
+ if (TeamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_YILI, ALLIANCE);
+ break;
+ case NPC_VOL_GUK:
+ if (TeamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_JEDEBIA, ALLIANCE);
+ break;
+ case NPC_HARAGG_THE_UNSEEN:
+ if (TeamInInstance == ALLIANCE)
+ creature->UpdateEntry(NPC_NIBY_THE_ALMIGHTY, ALLIANCE);
+ break;
case NPC_DEATHBRINGER_SAURFANG:
uiDeathbringerSaurfang = creature->GetGUID();
break;
@@ -160,6 +190,9 @@ class instance_icecrown_citadel : public InstanceMapScript
if (GetBossState(DATA_ROTFACE) == DONE)
HandleGameObject(uiPutricidePipes[1], true, pGo);
break;
+ case GO_DRINK_ME:
+ uiPutricideTable = pGo->GetGUID();
+ break;
default:
break;
}
@@ -183,6 +216,9 @@ class instance_icecrown_citadel : public InstanceMapScript
return uiRotface;
case DATA_PROFESSOR_PUTRICIDE:
return uiProfessorPutricide;
+ case DATA_PUTRICIDE_TABLE:
+ return uiPutricideTable;
+ break;
default:
break;
}
@@ -226,11 +262,12 @@ class instance_icecrown_citadel : public InstanceMapScript
if (state == DONE)
{
if (GetBossState(DATA_ROTFACE) == DONE)
- HandleGameObject(uiPutricideCollision, true);
- if (GetBossState(DATA_ROTFACE) == DONE)
{
+ HandleGameObject(uiPutricideCollision, true);
if (GameObject* pGo = instance->GetGameObject(uiPutricideGates[0]))
pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
+ if (GameObject* pGo = instance->GetGameObject(uiPutricideGates[1]))
+ pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
}
else
HandleGameObject(uiPutricideGates[0], false);
@@ -241,9 +278,10 @@ class instance_icecrown_citadel : public InstanceMapScript
if (state == DONE)
{
if (GetBossState(DATA_FESTERGUT) == DONE)
- HandleGameObject(uiPutricideCollision, true);
- if (GetBossState(DATA_FESTERGUT) == DONE)
{
+ HandleGameObject(uiPutricideCollision, true);
+ if (GameObject* pGo = instance->GetGameObject(uiPutricideGates[0]))
+ pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
if (GameObject* pGo = instance->GetGameObject(uiPutricideGates[1]))
pGo->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
}
@@ -273,6 +311,10 @@ class instance_icecrown_citadel : public InstanceMapScript
break;
case DATA_OOZE_DANCE_ACHIEVEMENT:
isOozeDanceEligible = data ? true : false;
+ break;
+ case DATA_NAUSEA___ACHIEVEMENT:
+ isNauseaEligible = data ? true : false;
+ break;
default:
break;
}
@@ -292,6 +334,11 @@ class instance_icecrown_citadel : public InstanceMapScript
case CRITERIA_DANCES_WITH_OOZES_10H:
case CRITERIA_DANCES_WITH_OOZES_25H:
return isOozeDanceEligible;
+ case CRITERIA_NAUSEA_10N:
+ case CRITERIA_NAUSEA_25N:
+ case CRITERIA_NAUSEA_10H:
+ case CRITERIA_NAUSEA_25H:
+ return isNauseaEligible;
default:
break;
}
@@ -353,8 +400,10 @@ class instance_icecrown_citadel : public InstanceMapScript
uint64 uiFestergut;
uint64 uiRotface;
uint64 uiProfessorPutricide;
+ uint64 uiPutricideTable;
bool isBonedEligible;
bool isOozeDanceEligible;
+ bool isNauseaEligible;
};
InstanceScript* GetInstanceScript(InstanceMap* pMap) const