diff options
-rw-r--r-- | src/game/UnitAI.cpp | 138 | ||||
-rw-r--r-- | src/scripts/northrend/naxxramas/boss_heigan.cpp | 24 | ||||
-rw-r--r-- | src/scripts/northrend/naxxramas/boss_kelthuzad.cpp | 2 | ||||
-rw-r--r-- | src/scripts/northrend/naxxramas/boss_maexxna.cpp | 124 | ||||
-rw-r--r-- | src/scripts/world/mob_generic_creature.cpp | 33 |
5 files changed, 150 insertions, 171 deletions
diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp index 1938491060e..cb8335fac04 100644 --- a/src/game/UnitAI.cpp +++ b/src/game/UnitAI.cpp @@ -120,69 +120,49 @@ struct TargetDistanceOrder : public std::binary_function<const Unit *, const Uni Unit* UnitAI::SelectTarget(SelectAggroTarget targetType, uint32 position, float dist, bool playerOnly, int32 aura) { - if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) - { - std::list<HostilReference*> &m_threatlist = me->getThreatManager().getThreatList(); - if(position >= m_threatlist.size()) - return NULL; + const std::list<HostilReference *> &threatlist = me->getThreatManager().getThreatList(); + std::list<Unit*> targetList; - std::list<Unit*> targetList; - for (std::list<HostilReference*>::iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) - if(SelectTargetHelper(me, (*itr)->getTarget(), playerOnly, dist, aura)) - targetList.push_back((*itr)->getTarget()); + if (position >= threatlist.size()) + return NULL; - if(position >= targetList.size()) - return NULL; + for (std::list<HostilReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) + if (SelectTargetHelper(me, (*itr)->getTarget(), playerOnly, dist, aura)) + targetList.push_back((*itr)->getTarget()); + + if (position >= targetList.size()) + return NULL; + if (targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) targetList.sort(TargetDistanceOrder(me)); - if(targetType == SELECT_TARGET_NEAREST) - { - std::list<Unit*>::iterator i = targetList.begin(); - advance(i, position); - return *i; - } - else - { - std::list<Unit*>::reverse_iterator i = targetList.rbegin(); - advance(i, position); - return *i; - } - } - else + switch(targetType) { - std::list<HostilReference*> m_threatlist = me->getThreatManager().getThreatList(); - std::list<HostilReference*>::iterator i; - while(position < m_threatlist.size()) - { - if(targetType == SELECT_TARGET_BOTTOMAGGRO) + case SELECT_TARGET_NEAREST: + case SELECT_TARGET_TOPAGGRO: { - i = m_threatlist.end(); - advance(i, - (int32)position - 1); + std::list<Unit*>::iterator itr = targetList.begin(); + advance(itr, position); + return *itr; } - else + break; + + case SELECT_TARGET_FARTHEST: + case SELECT_TARGET_BOTTOMAGGRO: { - i = m_threatlist.begin(); - if(targetType == SELECT_TARGET_TOPAGGRO) - advance(i, position); - else // random - { - //advance(i, position + rand()%(m_threatlist.size() - position)); - //if we use "random, 1", usually we want random except current victim - advance(i, rand()%m_threatlist.size()); - if(position && (*i)->getTarget() == me->getVictim()) - { - m_threatlist.erase(i); - continue; - } - } + std::list<Unit*>::reverse_iterator ritr = targetList.rbegin(); + advance(ritr, position); + return *ritr; } + break; - if(SelectTargetHelper(me, (*i)->getTarget(), playerOnly, dist, aura)) - return (*i)->getTarget(); - else - m_threatlist.erase(i); - } + case SELECT_TARGET_RANDOM: + { + std::list<Unit*>::iterator itr = targetList.begin(); + advance(itr, urand(position, targetList.size()-1)); + return *itr; + } + break; } return NULL; @@ -190,47 +170,33 @@ Unit* UnitAI::SelectTarget(SelectAggroTarget targetType, uint32 position, float void UnitAI::SelectTargetList(std::list<Unit*> &targetList, uint32 num, SelectAggroTarget targetType, float dist, bool playerOnly, int32 aura) { - if(targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) - { - std::list<HostilReference*> &m_threatlist = me->getThreatManager().getThreatList(); - if(m_threatlist.empty()) - return; + const std::list<HostilReference*> &threatlist = me->getThreatManager().getThreatList(); + + if (threatlist.empty()) + return; - for (std::list<HostilReference*>::iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) - if(SelectTargetHelper(me, (*itr)->getTarget(), playerOnly, dist, aura)) - targetList.push_back((*itr)->getTarget()); + for (std::list<HostilReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) + if (SelectTargetHelper(me, (*itr)->getTarget(), playerOnly, dist, aura)) + targetList.push_back((*itr)->getTarget()); + if (targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) + { targetList.sort(TargetDistanceOrder(me)); - targetList.resize(num); - if(targetType == SELECT_TARGET_FARTHEST) - targetList.reverse(); } - else - { - std::list<HostilReference*> m_threatlist = me->getThreatManager().getThreatList(); - std::list<HostilReference*>::iterator i; - while(!m_threatlist.empty() && num) - { - if(targetType == SELECT_TARGET_BOTTOMAGGRO) - { - i = m_threatlist.end(); - --i; - } - else - { - i = m_threatlist.begin(); - if(targetType == SELECT_TARGET_RANDOM) - advance(i, rand()%m_threatlist.size()); - } - if(SelectTargetHelper(me, (*i)->getTarget(), playerOnly, dist, aura)) - { - targetList.push_back((*i)->getTarget()); - --num; - } - m_threatlist.erase(i); + if (targetType == SELECT_TARGET_FARTHEST || targetType == SELECT_TARGET_BOTTOMAGGRO) + targetList.reverse(); + + if (targetType == SELECT_TARGET_RANDOM) + { + while (num > targetList.size()) { + std::list<Unit*>::iterator itr = targetList.begin(); + advance(itr, urand(0, targetList.size()-1)); + targetList.erase(itr); } } + else + targetList.resize(num); } float UnitAI::DoGetSpellMaxRange(uint32 spellId, bool positive) diff --git a/src/scripts/northrend/naxxramas/boss_heigan.cpp b/src/scripts/northrend/naxxramas/boss_heigan.cpp index d653e10d37a..15b45038f63 100644 --- a/src/scripts/northrend/naxxramas/boss_heigan.cpp +++ b/src/scripts/northrend/naxxramas/boss_heigan.cpp @@ -41,9 +41,6 @@ enum Phases PHASE_DANCE, }; -//Spell by eye stalks -#define SPELL_MIND_FLAY 26143 - struct TRINITY_DLL_DECL boss_heiganAI : public BossAI { boss_heiganAI(Creature *c) : BossAI(c, BOSS_HEIGAN) {} @@ -78,10 +75,10 @@ struct TRINITY_DLL_DECL boss_heiganAI : public BossAI eruptSection = 3; if (phase == PHASE_FIGHT) { - events.ScheduleEvent(EVENT_DISRUPT, 0); - events.ScheduleEvent(EVENT_FEVER, 20000); - events.ScheduleEvent(EVENT_PHASE, 85000); - events.ScheduleEvent(EVENT_ERUPT, 10000); + events.ScheduleEvent(EVENT_DISRUPT, urand(10000, 25000)); + events.ScheduleEvent(EVENT_FEVER, urand(15000, 20000)); + events.ScheduleEvent(EVENT_PHASE, 90000); + events.ScheduleEvent(EVENT_ERUPT, 15000); } else { @@ -90,7 +87,7 @@ struct TRINITY_DLL_DECL boss_heiganAI : public BossAI me->NearTeleportTo(x, y, z, o); DoCastAOE(SPELL_PLAGUE_CLOUD); events.ScheduleEvent(EVENT_PHASE, 45000); - events.ScheduleEvent(EVENT_ERUPT, 5000); + events.ScheduleEvent(EVENT_ERUPT, 8000); } } @@ -107,15 +104,16 @@ struct TRINITY_DLL_DECL boss_heiganAI : public BossAI { case EVENT_DISRUPT: DoCastAOE(SPELL_SPELL_DISRUPTION); - events.ScheduleEvent(EVENT_DISRUPT, 5000); - return; + events.ScheduleEvent(EVENT_DISRUPT, urand(5000, 10000)); + break; case EVENT_FEVER: DoCastAOE(SPELL_DECREPIT_FEVER); - events.ScheduleEvent(EVENT_FEVER, 20000); - return; + events.ScheduleEvent(EVENT_FEVER, urand(20000, 25000)); + break; case EVENT_PHASE: + // TODO : Add missing texts for both phase switches EnterPhase(phase == PHASE_FIGHT ? PHASE_DANCE : PHASE_FIGHT); - return; + break; case EVENT_ERUPT: instance->SetData(DATA_HEIGAN_ERUPT, eruptSection); TeleportCheaters(); diff --git a/src/scripts/northrend/naxxramas/boss_kelthuzad.cpp b/src/scripts/northrend/naxxramas/boss_kelthuzad.cpp index c7199661acb..ee05b5ef455 100644 --- a/src/scripts/northrend/naxxramas/boss_kelthuzad.cpp +++ b/src/scripts/northrend/naxxramas/boss_kelthuzad.cpp @@ -298,7 +298,7 @@ struct TRINITY_DLL_DECL boss_kelthuzadAI : public BossAI events.RepeatEvent(urand(10000,45000)); break; case EVENT_BLAST: - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true)) + if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 0, true)) DoCast(pTarget, SPELL_FROST_BLAST); if (rand()%2) DoScriptText(SAY_FROST_BLAST, m_creature); diff --git a/src/scripts/northrend/naxxramas/boss_maexxna.cpp b/src/scripts/northrend/naxxramas/boss_maexxna.cpp index 3238ffababa..8f874e4fcfd 100644 --- a/src/scripts/northrend/naxxramas/boss_maexxna.cpp +++ b/src/scripts/northrend/naxxramas/boss_maexxna.cpp @@ -18,22 +18,33 @@ #include "ScriptedPch.h" #include "naxxramas.h" +#include "SpellId.h" -#define SPELL_WEB_WRAP 28622 -#define SPELL_WEB_SPRAY RAID_MODE(29484,54125) -#define SPELL_POISON_SHOCK RAID_MODE(28741,54122) -#define SPELL_NECROTIC_POISON RAID_MODE(54121,28776) -#define SPELL_FRENZY RAID_MODE(54123,54124) +enum Spells +{ + SPELL_WEB_WRAP = SPELL_WEB_WRAP_28622, + SPELL_WEB_SPRAY_10 = SPELL_WEB_SPRAY_29484, + SPELL_WEB_SPRAY_25 = SPELL_WEB_SPRAY_54125, + SPELL_POISON_SHOCK_10 = SPELL_POISON_SHOCK_28741, + SPELL_POISON_SHOCK_25 = SPELL_POISON_SHOCK_54122, + SPELL_NECROTIC_POISON_10 = SPELL_NECROTIC_POISON_28776, + SPELL_NECROTIC_POISON_25 = SPELL_NECROTIC_POISON_54121, + SPELL_FRENZY_10 = SPELL_FRENZY_54123, + SPELL_FRENZY_25 = SPELL_FRENZY_54124, +}; -#define MOB_WEB_WRAP 16486 -#define MOB_SPIDERLING 17055 +enum Creatures +{ + MOB_WEB_WRAP = 16486, + MOB_SPIDERLING = 17055, +}; #define MAX_POS_WRAP 3 -const float PosWrap[MAX_POS_WRAP][3] = +const Position PosWrap[MAX_POS_WRAP] = { - {3546.796, -3869.082, 296.450}, - {3531.271, -3847.424, 299.450}, - {3497.067, -3843.384, 302.384}, + {3546.796, -3869.082, 296.450, 0.0}, + {3531.271, -3847.424, 299.450, 0.0}, + {3497.067, -3843.384, 302.384, 0.0}, }; enum Events @@ -44,6 +55,7 @@ enum Events EVENT_POISON, EVENT_WRAP, EVENT_SUMMON, + EVENT_FRENZY, }; struct TRINITY_DLL_DECL boss_maexxnaAI : public BossAI @@ -58,9 +70,9 @@ struct TRINITY_DLL_DECL boss_maexxnaAI : public BossAI enraged = false; events.ScheduleEvent(EVENT_WRAP, 20000); events.ScheduleEvent(EVENT_SPRAY, 40000); - events.ScheduleEvent(EVENT_SHOCK, 10000); - events.ScheduleEvent(EVENT_POISON, 5000); - events.ScheduleEvent(EVENT_SUMMON, 40000); + events.ScheduleEvent(EVENT_SHOCK, urand(5000,10000)); + events.ScheduleEvent(EVENT_POISON, urand(10000,15000)); + events.ScheduleEvent(EVENT_SUMMON, 30000); } void UpdateAI(const uint32 diff) @@ -68,6 +80,12 @@ struct TRINITY_DLL_DECL boss_maexxnaAI : public BossAI if (!UpdateVictim() || !CheckInRoom()) return; + if (!enraged && HealthBelowPct(30)) + { + enraged = true; + events.ScheduleEvent(EVENT_FRENZY, 0); // will be cast immediately + } + events.Update(diff); while(uint32 eventId = events.ExecuteEvent()) @@ -75,52 +93,69 @@ struct TRINITY_DLL_DECL boss_maexxnaAI : public BossAI switch(eventId) { case EVENT_WRAP: + // TODO : Add missing text for (uint8 i = 0; i < RAID_MODE(1,2); ++i) { if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 0, true, -SPELL_WEB_WRAP)) { - pTarget->RemoveAura(SPELL_WEB_SPRAY); + pTarget->RemoveAura(RAID_MODE(SPELL_WEB_SPRAY_10,SPELL_WEB_SPRAY_25)); uint8 pos = rand()%MAX_POS_WRAP; - pTarget->GetMotionMaster()->MoveJump(PosWrap[pos][0], PosWrap[pos][1], PosWrap[pos][2], 20, 20); - if (Creature *wrap = DoSummon(MOB_WEB_WRAP, pTarget, 0, 60000)) - { + pTarget->GetMotionMaster()->MoveJump(PosWrap[pos].GetPositionX(), PosWrap[pos].GetPositionY(), PosWrap[pos].GetPositionZ(), 20, 20); + if (Creature *wrap = DoSummon(MOB_WEB_WRAP, PosWrap[pos], 0, TEMPSUMMON_CORPSE_DESPAWN)) wrap->AI()->SetGUID(pTarget->GetGUID()); - wrap->GetMotionMaster()->MoveJump(PosWrap[pos][0], PosWrap[pos][1], PosWrap[pos][2], 20, 20); - } } } events.ScheduleEvent(EVENT_WRAP, 40000); - return; + break; case EVENT_SPRAY: - DoCastAOE(SPELL_WEB_SPRAY); + DoCastAOE(RAID_MODE(SPELL_WEB_SPRAY_10,SPELL_WEB_SPRAY_25)); events.ScheduleEvent(EVENT_SPRAY, 40000); - return; + break; case EVENT_SHOCK: - DoCastAOE(SPELL_POISON_SHOCK); - events.ScheduleEvent(EVENT_SHOCK, 10000); - return; + DoCastAOE(RAID_MODE(SPELL_POISON_SHOCK_10,SPELL_POISON_SHOCK_25)); + events.ScheduleEvent(EVENT_SHOCK, urand(10000,20000)); + break; case EVENT_POISON: - DoCast(me->getVictim(), SPELL_NECROTIC_POISON); - events.ScheduleEvent(EVENT_POISON, 30000); - return; + DoCast(me->getVictim(), RAID_MODE(SPELL_NECROTIC_POISON_10,SPELL_NECROTIC_POISON_25)); + events.ScheduleEvent(EVENT_POISON, urand(10000, 20000)); + break; + case EVENT_FRENZY: + DoCast(me, RAID_MODE(SPELL_FRENZY_10,SPELL_FRENZY_25), true); + events.ScheduleEvent(EVENT_FRENZY, 600000); + break; case EVENT_SUMMON: - { + // TODO : Add missing text uint8 amount = urand(8,10); for (uint8 i = 0; i < amount; ++i) - DoSummon(MOB_SPIDERLING, me); + DoSummon(MOB_SPIDERLING, me, 0, TEMPSUMMON_CORPSE_DESPAWN); events.ScheduleEvent(EVENT_SUMMON, 40000); break; - } } } - if (!enraged && HealthBelowPct(30)) - { - DoCast(me, SPELL_FRENZY); - enraged = true; - } - else - DoMeleeAttackIfReady(); + DoMeleeAttackIfReady(); + } +}; + +struct TRINITY_DLL_DECL mob_webwrapAI : public NullCreatureAI +{ + mob_webwrapAI(Creature *c) : NullCreatureAI(c), victimGUID(0) {} + + uint64 victimGUID; + + void SetGUID(const uint64 &guid, int32 param) + { + victimGUID = guid; + if (me->m_spells[0] && victimGUID) + if (Unit *victim = Unit::GetUnit(*me, victimGUID)) + victim->CastSpell(victim, me->m_spells[0], true, NULL, NULL, me->GetGUID()); + } + + void JustDied(Unit *killer) + { + if (me->m_spells[0] && victimGUID) + if (Unit *victim = Unit::GetUnit(*me, victimGUID)) + victim->RemoveAurasDueToSpell(me->m_spells[0], me->GetGUID()); } }; @@ -129,6 +164,11 @@ CreatureAI* GetAI_boss_maexxna(Creature* pCreature) return new boss_maexxnaAI (pCreature); } +CreatureAI* GetAI_mob_webwrap(Creature* pCreature) +{ + return new mob_webwrapAI (pCreature); +} + void AddSC_boss_maexxna() { Script *newscript; @@ -137,5 +177,11 @@ void AddSC_boss_maexxna() newscript->Name = "boss_maexxna"; newscript->GetAI = &GetAI_boss_maexxna; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_webwrap"; + newscript->GetAI = &GetAI_mob_webwrap; + newscript->RegisterSelf(); + } diff --git a/src/scripts/world/mob_generic_creature.cpp b/src/scripts/world/mob_generic_creature.cpp index 75e79cd46b4..8316d5e48ba 100644 --- a/src/scripts/world/mob_generic_creature.cpp +++ b/src/scripts/world/mob_generic_creature.cpp @@ -1,3 +1,4 @@ + /* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * 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 @@ -196,28 +197,6 @@ struct TRINITY_DLL_DECL trigger_deathAI : public NullCreatureAI } }; -struct TRINITY_DLL_DECL mob_webwrapAI : public NullCreatureAI -{ - mob_webwrapAI(Creature *c) : NullCreatureAI(c), victimGUID(0) {} - - uint64 victimGUID; - - void SetGUID(const uint64 &guid, int32 param) - { - victimGUID = guid; - if (me->m_spells[0] && victimGUID) - if (Unit *victim = Unit::GetUnit(*me, victimGUID)) - victim->CastSpell(victim, me->m_spells[0], true, NULL, NULL, me->GetGUID()); - } - - void JustDied(Unit *killer) - { - if (me->m_spells[0] && victimGUID) - if (Unit *victim = Unit::GetUnit(*me, victimGUID)) - victim->RemoveAurasDueToSpell(me->m_spells[0], me->GetGUID()); - } -}; - CreatureAI* GetAI_trigger_periodic(Creature* pCreature) { return new trigger_periodicAI (pCreature); @@ -228,11 +207,6 @@ CreatureAI* GetAI_trigger_death(Creature* pCreature) return new trigger_deathAI (pCreature); } -CreatureAI* GetAI_mob_webwrap(Creature* pCreature) -{ - return new mob_webwrapAI (pCreature); -} - void AddSC_generic_creature() { Script *newscript; @@ -250,10 +224,5 @@ void AddSC_generic_creature() newscript->Name = "trigger_death"; newscript->GetAI = &GetAI_trigger_death; newscript->RegisterSelf();*/ - - newscript = new Script; - newscript->Name = "mob_webwrap"; - newscript->GetAI = &GetAI_mob_webwrap; - newscript->RegisterSelf(); } |