diff options
-rw-r--r-- | src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp | 701 |
1 files changed, 350 insertions, 351 deletions
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp index b63b34cc0be..bd2c05b3c01 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp @@ -130,454 +130,453 @@ const Position PosSummonDead[POS_DEAD] = {2664.8f, -3340.7f, 268.23f, 3.7f}, }; -const float PosGroundLiveSide[4] = {2691.2f, -3387.0f, 267.68f, 1.52f}; -const float PosGroundDeadSide[4] = {2693.5f, -3334.6f, 267.68f, 4.67f}; -const float PosPlatform[4] = {2640.5f, -3360.6f, 285.26f, 0.0f}; +float const PosGroundLiveSide[4] = {2691.2f, -3387.0f, 267.68f, 1.52f}; +float const PosGroundDeadSide[4] = {2693.5f, -3334.6f, 267.68f, 4.67f}; +float const PosPlatform[4] = {2640.5f, -3360.6f, 285.26f, 0.0f}; // Predicate function to check that the r efzr unit is NOT on the same side as the source. -struct NotOnSameSide : public std::unary_function<Unit *, bool> { - bool m_inLiveSide; - NotOnSameSide(Unit *pSource) : m_inLiveSide(IN_LIVE_SIDE(pSource)) {} - bool operator() (const Unit *pTarget) { - return (m_inLiveSide != IN_LIVE_SIDE(pTarget)); +struct NotOnSameSide : public std::unary_function<Unit*, bool> +{ + NotOnSameSide(Unit* source) : _onLiveSide(IN_LIVE_SIDE(source)) {} + + bool operator() (Unit const* target) + { + return (_onLiveSide != IN_LIVE_SIDE(target)); } + + private: + bool _onLiveSide; }; class boss_gothik : public CreatureScript { -public: - boss_gothik() : CreatureScript("boss_gothik") { } + public: + boss_gothik() : CreatureScript("boss_gothik") { } - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_gothikAI (pCreature); - } + struct boss_gothikAI : public BossAI + { + boss_gothikAI(Creature* creature) : BossAI(creature, BOSS_GOTHIK) {} - struct boss_gothikAI : public BossAI - { - boss_gothikAI(Creature *c) : BossAI(c, BOSS_GOTHIK) {} + uint32 waveCount; + typedef std::vector<Creature*> TriggerVct; + TriggerVct liveTrigger, deadTrigger; + bool mergedSides; + bool phaseTwo; + bool thirtyPercentReached; - uint32 waveCount; - typedef std::vector<Creature*> TriggerVct; - TriggerVct liveTrigger, deadTrigger; - bool mergedSides; - bool phaseTwo; - bool thirtyPercentReached; + std::vector<uint64> LiveTriggerGUID; + std::vector<uint64> DeadTriggerGUID; - std::vector<uint64> LiveTriggerGUID; - std::vector<uint64> DeadTriggerGUID; + void Reset() + { + LiveTriggerGUID.clear(); + DeadTriggerGUID.clear(); - void Reset() - { - LiveTriggerGUID.clear(); - DeadTriggerGUID.clear(); - - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE); - me->SetReactState(REACT_PASSIVE); - if (instance) - instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE); - _Reset(); - mergedSides = false; - phaseTwo = false; - thirtyPercentReached = false; - } + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + me->SetReactState(REACT_PASSIVE); + if (instance) + instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE); + _Reset(); + mergedSides = false; + phaseTwo = false; + thirtyPercentReached = false; + } - void EnterCombat(Unit * /*who*/) - { - for (uint32 i = 0; i < POS_LIVE; ++i) - if (Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonLive[i])) - LiveTriggerGUID.push_back(trigger->GetGUID()); - for (uint32 i = 0; i < POS_DEAD; ++i) - if (Creature *trigger = DoSummon(WORLD_TRIGGER, PosSummonDead[i])) - DeadTriggerGUID.push_back(trigger->GetGUID()); - - if (LiveTriggerGUID.size() < POS_LIVE || DeadTriggerGUID.size() < POS_DEAD) + void EnterCombat(Unit * /*who*/) { - sLog->outError("Script Gothik: cannot summon triggers!"); - EnterEvadeMode(); - return; - } + for (uint32 i = 0; i < POS_LIVE; ++i) + if (Creature* trigger = DoSummon(WORLD_TRIGGER, PosSummonLive[i])) + LiveTriggerGUID.push_back(trigger->GetGUID()); + for (uint32 i = 0; i < POS_DEAD; ++i) + if (Creature* trigger = DoSummon(WORLD_TRIGGER, PosSummonDead[i])) + DeadTriggerGUID.push_back(trigger->GetGUID()); + + if (LiveTriggerGUID.size() < POS_LIVE || DeadTriggerGUID.size() < POS_DEAD) + { + sLog->outError("Script Gothik: cannot summon triggers!"); + EnterEvadeMode(); + return; + } - _EnterCombat(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_DISABLE_MOVE); - waveCount = 0; - events.ScheduleEvent(EVENT_SUMMON, 30000); - DoTeleportTo(PosPlatform); - DoScriptText(SAY_SPEECH, me); - if (instance) - instance->SetData(DATA_GOTHIK_GATE, GO_STATE_READY); - } + _EnterCombat(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + waveCount = 0; + events.ScheduleEvent(EVENT_SUMMON, 30000); + DoTeleportTo(PosPlatform); + DoScriptText(SAY_SPEECH, me); + if (instance) + instance->SetData(DATA_GOTHIK_GATE, GO_STATE_READY); + } - void JustSummoned(Creature *summon) - { - if (summon->GetEntry() == WORLD_TRIGGER) - summon->setActive(true); - else if (!mergedSides) + void JustSummoned(Creature* summon) { - summon->AI()->DoAction(me->HasReactState(REACT_PASSIVE) ? 1 : 0); - summon->AI()->EnterEvadeMode(); + if (summon->GetEntry() == WORLD_TRIGGER) + summon->setActive(true); + else if (!mergedSides) + { + summon->AI()->DoAction(me->HasReactState(REACT_PASSIVE) ? 1 : 0); + summon->AI()->EnterEvadeMode(); + } + else + { + summon->AI()->DoAction(0); + summon->AI()->DoZoneInCombat(); + } + summons.Summon(summon); } - else + + void SummonedCreatureDespawn(Creature *summon) { - summon->AI()->DoAction(0); - summon->AI()->DoZoneInCombat(); + summons.Despawn(summon); } - summons.Summon(summon); - } - void SummonedCreatureDespawn(Creature *summon) - { - summons.Despawn(summon); - } - - void KilledUnit(Unit* /*victim*/) - { - if (!(rand()%5)) - DoScriptText(SAY_KILL, me); - } + void KilledUnit(Unit* /*victim*/) + { + if (!(rand()%5)) + DoScriptText(SAY_KILL, me); + } - void JustDied(Unit* /*Killer*/) - { - LiveTriggerGUID.clear(); - DeadTriggerGUID.clear(); - _JustDied(); - DoScriptText(SAY_DEATH, me); - if (instance) - instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE); - } + void JustDied(Unit* /*Killer*/) + { + LiveTriggerGUID.clear(); + DeadTriggerGUID.clear(); + _JustDied(); + DoScriptText(SAY_DEATH, me); + if (instance) + instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE); + } - void DoGothikSummon(uint32 entry) - { - if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) + void DoGothikSummon(uint32 entry) { - switch (entry) + if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL) { - case MOB_LIVE_TRAINEE: - { - if (Creature *LiveTrigger0 = Unit::GetCreature(*me, LiveTriggerGUID[0])) - DoSummon(MOB_LIVE_TRAINEE, LiveTrigger0, 1); - if (Creature *LiveTrigger1 = Unit::GetCreature(*me, LiveTriggerGUID[1])) - DoSummon(MOB_LIVE_TRAINEE, LiveTrigger1, 1); - if (Creature *LiveTrigger2 = Unit::GetCreature(*me, LiveTriggerGUID[2])) - DoSummon(MOB_LIVE_TRAINEE, LiveTrigger2, 1); - break; - } - case MOB_LIVE_KNIGHT: - { - if (Creature *LiveTrigger3 = Unit::GetCreature(*me, LiveTriggerGUID[3])) - DoSummon(MOB_LIVE_KNIGHT, LiveTrigger3, 1); - if (Creature *LiveTrigger5 = Unit::GetCreature(*me, LiveTriggerGUID[5])) - DoSummon(MOB_LIVE_KNIGHT, LiveTrigger5, 1); - break; - } - case MOB_LIVE_RIDER: + switch (entry) { - if (Creature *LiveTrigger4 = Unit::GetCreature(*me, LiveTriggerGUID[4])) - DoSummon(MOB_LIVE_RIDER, LiveTrigger4, 1); - break; + case MOB_LIVE_TRAINEE: + { + if (Creature* liveTrigger = Unit::GetCreature(*me, LiveTriggerGUID[0])) + DoSummon(MOB_LIVE_TRAINEE, liveTrigger, 1); + if (Creature* liveTrigger1 = Unit::GetCreature(*me, LiveTriggerGUID[1])) + DoSummon(MOB_LIVE_TRAINEE, liveTrigger1, 1); + if (Creature* liveTrigger2 = Unit::GetCreature(*me, LiveTriggerGUID[2])) + DoSummon(MOB_LIVE_TRAINEE, liveTrigger2, 1); + break; + } + case MOB_LIVE_KNIGHT: + { + if (Creature* liveTrigger3 = Unit::GetCreature(*me, LiveTriggerGUID[3])) + DoSummon(MOB_LIVE_KNIGHT, liveTrigger3, 1); + if (Creature* liveTrigger5 = Unit::GetCreature(*me, LiveTriggerGUID[5])) + DoSummon(MOB_LIVE_KNIGHT, liveTrigger5, 1); + break; + } + case MOB_LIVE_RIDER: + { + if (Creature* liveTrigger4 = Unit::GetCreature(*me, LiveTriggerGUID[4])) + DoSummon(MOB_LIVE_RIDER, liveTrigger4, 1); + break; + } } } - } - else - { - switch(entry) + else { - case MOB_LIVE_TRAINEE: - { - if (Creature *LiveTrigger0 = Unit::GetCreature(*me, LiveTriggerGUID[4])) - DoSummon(MOB_LIVE_TRAINEE, LiveTrigger0, 1); - if (Creature *LiveTrigger1 = Unit::GetCreature(*me, LiveTriggerGUID[4])) - DoSummon(MOB_LIVE_TRAINEE, LiveTrigger1, 1); - break; - } - case MOB_LIVE_KNIGHT: + switch(entry) { - if (Creature *LiveTrigger5 = Unit::GetCreature(*me, LiveTriggerGUID[4])) - DoSummon(MOB_LIVE_KNIGHT, LiveTrigger5, 1); - break; - } - case MOB_LIVE_RIDER: - { - if (Creature *LiveTrigger4 = Unit::GetCreature(*me, LiveTriggerGUID[4])) - DoSummon(MOB_LIVE_RIDER, LiveTrigger4, 1); - break; + case MOB_LIVE_TRAINEE: + { + if (Creature* liveTrigger = Unit::GetCreature(*me, LiveTriggerGUID[4])) + DoSummon(MOB_LIVE_TRAINEE, liveTrigger, 1); + if (Creature* liveTrigger2 = Unit::GetCreature(*me, LiveTriggerGUID[4])) + DoSummon(MOB_LIVE_TRAINEE, liveTrigger2, 1); + break; + } + case MOB_LIVE_KNIGHT: + { + if (Creature* liveTrigger5 = Unit::GetCreature(*me, LiveTriggerGUID[4])) + DoSummon(MOB_LIVE_KNIGHT, liveTrigger5, 1); + break; + } + case MOB_LIVE_RIDER: + { + if (Creature* liveTrigger4 = Unit::GetCreature(*me, LiveTriggerGUID[4])) + DoSummon(MOB_LIVE_RIDER, liveTrigger4, 1); + break; + } } } } - } - bool CheckGroupSplitted() - { - bool checklife = false; - bool checkdead = false; - - Map* pMap = me->GetMap(); - if (pMap && pMap->IsDungeon()) + bool CheckGroupSplitted() { - Map::PlayerList const &PlayerList = pMap->GetPlayers(); - if (!PlayerList.isEmpty()) + bool checklife = false; + bool checkdead = false; + + Map* map = me->GetMap(); + if (map && map->IsDungeon()) { - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + Map::PlayerList const &PlayerList = map->GetPlayers(); + if (!PlayerList.isEmpty()) { - if (i->getSource() && i->getSource()->isAlive() && - i->getSource()->GetPositionX() <= POS_X_NORTH && - i->getSource()->GetPositionX() >= POS_X_SOUTH && - i->getSource()->GetPositionY() <= POS_Y_GATE && - i->getSource()->GetPositionY() >= POS_Y_EAST) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { - checklife = true; - } - else if (i->getSource() && i->getSource()->isAlive() && - i->getSource()->GetPositionX() <= POS_X_NORTH && - i->getSource()->GetPositionX() >= POS_X_SOUTH && - i->getSource()->GetPositionY() >= POS_Y_GATE && - i->getSource()->GetPositionY() <= POS_Y_WEST) - { - checkdead = true; - } + if (i->getSource() && i->getSource()->isAlive() && + i->getSource()->GetPositionX() <= POS_X_NORTH && + i->getSource()->GetPositionX() >= POS_X_SOUTH && + i->getSource()->GetPositionY() <= POS_Y_GATE && + i->getSource()->GetPositionY() >= POS_Y_EAST) + { + checklife = true; + } + else if (i->getSource() && i->getSource()->isAlive() && + i->getSource()->GetPositionX() <= POS_X_NORTH && + i->getSource()->GetPositionX() >= POS_X_SOUTH && + i->getSource()->GetPositionY() >= POS_Y_GATE && + i->getSource()->GetPositionY() <= POS_Y_WEST) + { + checkdead = true; + } - if (checklife && checkdead) - return true; + if (checklife && checkdead) + return true; + } } } - } - return false; - } - - void SpellHit(Unit * /*caster*/, const SpellEntry *spell) - { - uint32 spellId = 0; - switch(spell->Id) - { - case SPELL_INFORM_LIVE_TRAINEE: spellId = SPELL_INFORM_DEAD_TRAINEE; break; - case SPELL_INFORM_LIVE_KNIGHT: spellId = SPELL_INFORM_DEAD_KNIGHT; break; - case SPELL_INFORM_LIVE_RIDER: spellId = SPELL_INFORM_DEAD_RIDER; break; + return false; } - if (spellId && me->isInCombat()) + + void SpellHit(Unit* /*caster*/, SpellEntry const* spell) { - me->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST); - if (Creature *pRandomDeadTrigger = Unit::GetCreature(*me, DeadTriggerGUID[rand() % POS_DEAD])) - me->CastSpell(pRandomDeadTrigger, spellId, true); + uint32 spellId = 0; + switch(spell->Id) + { + case SPELL_INFORM_LIVE_TRAINEE: spellId = SPELL_INFORM_DEAD_TRAINEE; break; + case SPELL_INFORM_LIVE_KNIGHT: spellId = SPELL_INFORM_DEAD_KNIGHT; break; + case SPELL_INFORM_LIVE_RIDER: spellId = SPELL_INFORM_DEAD_RIDER; break; + } + if (spellId && me->isInCombat()) + { + me->HandleEmoteCommand(EMOTE_ONESHOT_SPELLCAST); + if (Creature *pRandomDeadTrigger = Unit::GetCreature(*me, DeadTriggerGUID[rand() % POS_DEAD])) + me->CastSpell(pRandomDeadTrigger, spellId, true); + } } - } - void SpellHitTarget(Unit *pTarget, const SpellEntry *spell) - { - if (!me->isInCombat()) - return; - - switch(spell->Id) + void SpellHitTarget(Unit* target, SpellEntry const* spell) { - case SPELL_INFORM_DEAD_TRAINEE: - DoSummon(MOB_DEAD_TRAINEE, pTarget, 0); - break; - case SPELL_INFORM_DEAD_KNIGHT: - DoSummon(MOB_DEAD_KNIGHT, pTarget, 0); - break; - case SPELL_INFORM_DEAD_RIDER: - DoSummon(MOB_DEAD_RIDER, pTarget, 1.0f); - DoSummon(MOB_DEAD_HORSE, pTarget, 1.0f); - break; + if (!me->isInCombat()) + return; + + switch(spell->Id) + { + case SPELL_INFORM_DEAD_TRAINEE: + DoSummon(MOB_DEAD_TRAINEE, target, 0); + break; + case SPELL_INFORM_DEAD_KNIGHT: + DoSummon(MOB_DEAD_KNIGHT, target, 0); + break; + case SPELL_INFORM_DEAD_RIDER: + DoSummon(MOB_DEAD_RIDER, target, 1.0f); + DoSummon(MOB_DEAD_HORSE, target, 1.0f); + break; + } } - } - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim() || !CheckInRoom()) - return; + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim() || !CheckInRoom()) + return; - events.Update(diff); + events.Update(diff); - if (!thirtyPercentReached && HealthBelowPct(30) && phaseTwo) - { - thirtyPercentReached = true; - if (instance) - instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE); - } + if (!thirtyPercentReached && HealthBelowPct(30) && phaseTwo) + { + thirtyPercentReached = true; + if (instance) + instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE); + } - if (me->HasUnitState(UNIT_STAT_CASTING)) - return; + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) - { - switch(eventId) + while (uint32 eventId = events.ExecuteEvent()) { - case EVENT_SUMMON: - if (waves[waveCount].entry) - { - if ((waves[waveCount].mode == 2) && (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)) - DoGothikSummon(waves[waveCount].entry); - else if ((waves[waveCount].mode == 0) && (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)) - DoGothikSummon(waves[waveCount].entry); - else if (waves[waveCount].mode == 1) - DoGothikSummon(waves[waveCount].entry); - - // if group is not splitted, open gate and merge both sides at ~ 2 minutes (wave 11) - if (waveCount == 11) + switch(eventId) + { + case EVENT_SUMMON: + if (waves[waveCount].entry) { - if (!CheckGroupSplitted()) + if ((waves[waveCount].mode == 2) && (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)) + DoGothikSummon(waves[waveCount].entry); + else if ((waves[waveCount].mode == 0) && (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)) + DoGothikSummon(waves[waveCount].entry); + else if (waves[waveCount].mode == 1) + DoGothikSummon(waves[waveCount].entry); + + // if group is not splitted, open gate and merge both sides at ~ 2 minutes (wave 11) + if (waveCount == 11) { - if (instance) - instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE); - summons.DoAction(0, 0); - summons.DoZoneInCombat(); - mergedSides = true; + if (!CheckGroupSplitted()) + { + if (instance) + instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE); + summons.DoAction(0, 0); + summons.DoZoneInCombat(); + mergedSides = true; + } } - } - if (waves[waveCount].mode == 1) - events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); - else if ((waves[waveCount].mode == 2) && (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)) - events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); - else if ((waves[waveCount].mode == 0) && (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)) - events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); - else - events.ScheduleEvent(EVENT_SUMMON, 0); + if (waves[waveCount].mode == 1) + events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); + else if ((waves[waveCount].mode == 2) && (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)) + events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); + else if ((waves[waveCount].mode == 0) && (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)) + events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time); + else + events.ScheduleEvent(EVENT_SUMMON, 0); - ++waveCount; - } - else - { - phaseTwo = true; - DoScriptText(SAY_TELEPORT, me); - DoTeleportTo(PosGroundLiveSide); - me->SetReactState(REACT_AGGRESSIVE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); - summons.DoAction(0, 0); - summons.DoZoneInCombat(); - events.ScheduleEvent(EVENT_BOLT, 1000); - events.ScheduleEvent(EVENT_HARVEST, urand(3000, 15000)); - events.ScheduleEvent(EVENT_TELEPORT, 20000); - } - break; - case EVENT_BOLT: - DoCast(me->getVictim(), RAID_MODE(SPELL_SHADOW_BOLT, H_SPELL_SHADOW_BOLT)); - events.ScheduleEvent(EVENT_BOLT, 1000); - break; - case EVENT_HARVEST: - DoCast(me->getVictim(), SPELL_HARVEST_SOUL, true); - events.ScheduleEvent(EVENT_HARVEST, urand(20000, 25000)); - break; - case EVENT_TELEPORT: - if (!thirtyPercentReached) - { - me->AttackStop(); - if (IN_LIVE_SIDE(me)) - { - DoTeleportTo(PosGroundDeadSide); + ++waveCount; } else { + phaseTwo = true; + DoScriptText(SAY_TELEPORT, me); DoTeleportTo(PosGroundLiveSide); + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + summons.DoAction(0, 0); + summons.DoZoneInCombat(); + events.ScheduleEvent(EVENT_BOLT, 1000); + events.ScheduleEvent(EVENT_HARVEST, urand(3000, 15000)); + events.ScheduleEvent(EVENT_TELEPORT, 20000); } - - me->getThreatManager().resetAggro(NotOnSameSide(me)); - if (Unit *pTarget = SelectTarget(SELECT_TARGET_NEAREST, 0)) + break; + case EVENT_BOLT: + DoCast(me->getVictim(), RAID_MODE(SPELL_SHADOW_BOLT, H_SPELL_SHADOW_BOLT)); + events.ScheduleEvent(EVENT_BOLT, 1000); + break; + case EVENT_HARVEST: + DoCast(me->getVictim(), SPELL_HARVEST_SOUL, true); + events.ScheduleEvent(EVENT_HARVEST, urand(20000, 25000)); + break; + case EVENT_TELEPORT: + if (!thirtyPercentReached) { - me->getThreatManager().addThreat(pTarget, 100.0f); - AttackStart(pTarget); - } + me->AttackStop(); + if (IN_LIVE_SIDE(me)) + DoTeleportTo(PosGroundDeadSide); + else + DoTeleportTo(PosGroundLiveSide); + + me->getThreatManager().resetAggro(NotOnSameSide(me)); + if (Unit *pTarget = SelectTarget(SELECT_TARGET_NEAREST, 0)) + { + me->getThreatManager().addThreat(pTarget, 100.0f); + AttackStart(pTarget); + } - events.ScheduleEvent(EVENT_TELEPORT, 20000); - } - break; + events.ScheduleEvent(EVENT_TELEPORT, 20000); + } + break; + } } + + DoMeleeAttackIfReady(); } + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const + { + return new boss_gothikAI(creature); } - }; - }; class mob_gothik_minion : public CreatureScript { -public: - mob_gothik_minion() : CreatureScript("mob_gothik_minion") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new mob_gothik_minionAI (pCreature); - } - - struct mob_gothik_minionAI : public CombatAI - { - mob_gothik_minionAI(Creature *c) : CombatAI(c) - { - liveSide = IN_LIVE_SIDE(me); - } + public: + mob_gothik_minion() : CreatureScript("mob_gothik_minion") { } - bool liveSide; - bool gateClose; - - bool isOnSameSide(const Unit *pWho) const + struct mob_gothik_minionAI : public CombatAI { - return (liveSide == IN_LIVE_SIDE(pWho)); - } + mob_gothik_minionAI(Creature* creature) : CombatAI(creature) + { + liveSide = IN_LIVE_SIDE(me); + } - void DoAction(const int32 param) - { - gateClose = param; - } + bool liveSide; + bool gateClose; - void DamageTaken(Unit *attacker, uint32 &damage) - { - if (gateClose && !isOnSameSide(attacker)) - damage = 0; - } + bool isOnSameSide(Unit const* who) const + { + return (liveSide == IN_LIVE_SIDE(who)); + } - void JustDied(Unit * /*killer*/) - { - if (me->isSummon()) - if (Unit* owner = me->ToTempSummon()->GetSummoner()) - CombatAI::JustDied(owner); - } + void DoAction(int32 const param) + { + gateClose = param; + } - void EnterEvadeMode() - { - if (!gateClose) + void DamageTaken(Unit* attacker, uint32 &damage) { - CombatAI::EnterEvadeMode(); - return; + if (gateClose && !isOnSameSide(attacker)) + damage = 0; } - if (!_EnterEvadeMode()) - return; + void JustDied(Unit* /*killer*/) + { + if (me->isSummon()) + if (Unit* owner = me->ToTempSummon()->GetSummoner()) + CombatAI::JustDied(owner); + } - Map* pMap = me->GetMap(); - if (pMap->IsDungeon()) + void EnterEvadeMode() { - Map::PlayerList const &PlayerList = pMap->GetPlayers(); - if (!PlayerList.isEmpty()) + if (!gateClose) { - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + CombatAI::EnterEvadeMode(); + return; + } + + if (!_EnterEvadeMode()) + return; + + Map* map = me->GetMap(); + if (map->IsDungeon()) + { + Map::PlayerList const &PlayerList = map->GetPlayers(); + if (!PlayerList.isEmpty()) { - if (i->getSource() && i->getSource()->isAlive() && isOnSameSide(i->getSource())) + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { - AttackStart(i->getSource()); - return; + if (i->getSource() && i->getSource()->isAlive() && isOnSameSide(i->getSource())) + { + AttackStart(i->getSource()); + return; + } } } } - } - me->GetMotionMaster()->MoveIdle(); - Reset(); - } + me->GetMotionMaster()->MoveIdle(); + Reset(); + } - void UpdateAI(const uint32 diff) - { - if (gateClose && (!isOnSameSide(me) || (me->getVictim() && !isOnSameSide(me->getVictim())))) + void UpdateAI(uint32 const diff) { - EnterEvadeMode(); - return; + if (gateClose && (!isOnSameSide(me) || (me->getVictim() && !isOnSameSide(me->getVictim())))) + { + EnterEvadeMode(); + return; + } + + CombatAI::UpdateAI(diff); } + }; - CombatAI::UpdateAI(diff); + CreatureAI* GetAI(Creature* creature) const + { + return new mob_gothik_minionAI(creature); } - }; - }; void AddSC_boss_gothik() |