I open boss_kalecgos.CPP, I only changed SPELL_SPECTRAL_BLAST=44866.But the latter did not know how to fix kalecgos' portal
Code:
[/COLOR]/* * This file is part of the OregonCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. *//* ScriptDataSDName: Boss_KalecgosSD%Complete: 95SDComment:SDCategory: Sunwell_PlateauEndScriptData */#include "ScriptMgr.h"#include "ScriptedCreature.h"#include "sunwell_plateau.h"enum Yells{ //Kalecgos 龙形态 SAY_EVIL_AGGRO = -1580000, SAY_EVIL_SPELL1 = -1580001, SAY_EVIL_SPELL2 = -1580002, SAY_EVIL_SLAY1 = -1580003, SAY_EVIL_SLAY2 = -1580004, SAY_EVIL_ENRAGE = -1580005, //Kalecgos 人形态 SAY_GOOD_AGGRO = -1580006, SAY_GOOD_NEAR_DEATH = -1580007, SAY_GOOD_NEAR_DEATH2 = -1580008, SAY_GOOD_PLRWIN = -1580009, //Sathrovarr SAY_SATH_AGGRO = -1580010, SAY_SATH_DEATH = -1580011, SAY_SATH_SPELL1 = -1580012, SAY_SATH_SPELL2 = -1580013, SAY_SATH_SLAY1 = -1580014, SAY_SATH_SLAY2 = -1580015, SAY_SATH_ENRAGE = -1580016,};enum Spells{ AURA_SUNWELL_RADIANCE = 45769, AURA_SPECTRAL_EXHAUSTION = 44867, AURA_SPECTRAL_REALM = 46021, AURA_SPECTRAL_INVISIBILITY = 44801, AURA_DEMONIC_VISUAL = 44800, SPELL_SPECTRAL_BLAST = 44866, SPELL_TELEPORT_SPECTRAL = 46019, SPELL_ARCANE_BUFFET = 45018, SPELL_FROST_BREATH = 44799, SPELL_TAIL_LASH = 45122, SPELL_BANISH = 44836, SPELL_TRANSFORM_KALEC = 44670, SPELL_ENRAGE = 44807, SPELL_CORRUPTION_STRIKE = 45029, SPELL_AGONY_CURSE = 45032, SPELL_SHADOW_BOLT = 45031, SPELL_HEROIC_STRIKE = 45026, SPELL_REVITALIZE = 45027};enum SWPActions{ DO_ENRAGE = 1, DO_BANISH = 2,};#define GO_FAILED "You are unable to use this currently."#define EMOTE_UNABLE_TO_FIND "is unable to find Kalecgos"#define FLY_X 1679#define FLY_Y 900#define FLY_Z 82#define CENTER_X 1705#define CENTER_Y 930#define RADIUS 30#define DRAGON_REALM_Z 53.079f#define DEMON_REALM_Z -74.558f#define MAX_PLAYERS_IN_SPECTRAL_REALM 0 //在此之上,传送对象将无法工作,0禁用检查uint32 WildMagic[] = { 44978, 45001, 45002, 45004, 45006, 45010 };struct boss_kalecgosAI : public ScriptedAI{ boss_kalecgosAI(Creature* c) : ScriptedAI(c) { pInstance = (ScriptedInstance*)c->GetInstanceData(); SathGUID = 0; bJustReset = false; me->setActive(true); SpellEntry* TempSpell = GET_SPELL(SPELL_SPECTRAL_BLAST); if (TempSpell) TempSpell->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ENEMY; } ScriptedInstance* pInstance; uint32 ArcaneBuffetTimer; uint32 FrostBreathTimer; uint32 WildMagicTimer; uint32 SpectralBlastTimer; uint32 TailLashTimer; uint32 CheckTimer; uint32 TalkTimer; uint32 TalkSequence; uint32 ResetTimer; bool isFriendly; bool isEnraged; bool isBanished; bool bJustReset; uint64 SathGUID; void Reset() { if (pInstance) { SathGUID = pInstance->GetData64(DATA_SATHROVARR); pInstance->SetData(DATA_KALECGOS_EVENT, NOT_STARTED); } if (Creature* Sath = Unit::GetCreature(*me, SathGUID)) Sath->AI()->EnterEvadeMode(); me->SetFaction(14); if (!bJustReset) //在创建时首次重置 { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); me->SetLevitate(false); me->SetVisible(true); me->SetStandState(UNIT_STAND_STATE_SLEEP); } me->SetHealth(me->GetMaxHealth());//不知道为什么它不在闪避时重置生命值… ArcaneBuffetTimer = 8000; FrostBreathTimer = 15000; WildMagicTimer = 10000; TailLashTimer = 25000; SpectralBlastTimer = urand(20000, 25000); CheckTimer = 1000; ResetTimer = 30000; TalkTimer = 0; TalkSequence = 0; isFriendly = false; isEnraged = false; isBanished = false; } void EnterEvadeMode() { bJustReset = true; me->SetVisible(false); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); ScriptedAI::EnterEvadeMode(); } void DoAction(const int32 param) { switch (param) { case DO_ENRAGE: isEnraged = true; me->CastSpell(me, SPELL_ENRAGE, true); break; case DO_BANISH: isBanished = true; me->CastSpell(me, SPELL_BANISH, true); break; } } void UpdateAI(const uint32 diff) { if (TalkTimer) { if (!TalkSequence) { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); me->InterruptNonMeleeSpells(true); me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(); ++TalkSequence; } if (TalkTimer <= diff) { if (isFriendly) GoodEnding(); else BadEnding(); ++TalkSequence; } else TalkTimer -= diff; } else { if (bJustReset) { if (ResetTimer <= diff) { me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->SetLevitate(false); me->SetVisible(true); me->SetStandState(UNIT_STAND_STATE_SLEEP); ResetTimer = 10000; bJustReset = false; } else ResetTimer -= diff; return; } if (!UpdateVictim()) return; if (CheckTimer <= diff) { if (me->GetDistance(CENTER_X, CENTER_Y, DRAGON_REALM_Z) >= 75) { me->AI()->EnterEvadeMode(); return; } if (HealthBelowPct(10) && !isEnraged) { if (Creature* Sath = Unit::GetCreature(*me, SathGUID)) Sath->AI()->DoAction(DO_ENRAGE); DoAction(DO_ENRAGE); } if (!isBanished && (me->GetHealth() * 100) / me->GetMaxHealth() < 1) { if (Creature* Sath = Unit::GetCreature(*me, SathGUID)) { if (Sath->HasAura(SPELL_BANISH, 0)) { Sath->DealDamage(Sath, Sath->GetHealth()); return; } else DoAction(DO_BANISH); } else { error_log("OSCR: Didn't find Shathrowar. Kalecgos event reseted."); EnterEvadeMode(); return; } } CheckTimer = 1000; } else CheckTimer -= diff; if (ArcaneBuffetTimer <= diff) { DoCastAOE(SPELL_ARCANE_BUFFET); ArcaneBuffetTimer = 8000; } else ArcaneBuffetTimer -= diff; if (FrostBreathTimer <= diff) { DoCastAOE(SPELL_FROST_BREATH); FrostBreathTimer = 15000; } else FrostBreathTimer -= diff; if (TailLashTimer <= diff) { DoCastAOE(SPELL_TAIL_LASH); TailLashTimer = 15000; } else TailLashTimer -= diff; if (WildMagicTimer <= diff) { DoCastAOE(WildMagic[rand() % 6]); WildMagicTimer = 20000; } else WildMagicTimer -= diff; if (SpectralBlastTimer <= diff) { ThreatContainer::StorageType const& m_threatlist = me->getThreatManager().getThreatList(); std::list<Unit*> targetList; for (ThreatContainer::StorageType::const_iterator itr = m_threatlist.begin(); itr!= m_threatlist.end(); ++itr) { Unit* target = (*itr)->getTarget(); if (target && target->GetTypeId() == TYPEID_PLAYER && target->GetGUID() != me->GetVictim()->GetGUID() && target->GetPositionZ() > me->GetPositionZ() - 5 && !target->HasAura(AURA_SPECTRAL_EXHAUSTION)) { targetList.push_back(target); } } if (targetList.empty()) { SpectralBlastTimer = 1000; return; } std::list<Unit*>::const_iterator i = targetList.begin(); advance(i, rand() % targetList.size()); if ((*i)) { (*i)->CastSpell((*i), SPELL_SPECTRAL_BLAST, true); SpectralBlastTimer = 20000 + rand() % 5000; } else SpectralBlastTimer = 1000; } else SpectralBlastTimer -= diff; DoMeleeAttackIfReady(); } } void MoveInLineOfSight(Unit* who) { if (bJustReset)//boss 是隐形的,不要攻击 return; if (!me->GetVictim() && who->isTargetableForAttack() && (me->IsHostileTo(who))) { float attackRadius = me->GetAttackDistance(who); if (me->IsWithinDistInMap(who, attackRadius)) AttackStart(who); } } void DamageTaken(Unit* done_by, uint32& damage) { if (damage >= me->GetHealth() && done_by != me) damage = 0; } void EnterCombat(Unit* /*who*/) { me->SetStandState(UNIT_STAND_STATE_STAND); DoScriptText(SAY_EVIL_AGGRO, me); DoZoneInCombat(); if (pInstance) pInstance->SetData(DATA_KALECGOS_EVENT, IN_PROGRESS); } void KilledUnit(Unit* /*victim*/) { DoScriptText(RAND(SAY_EVIL_SLAY1, SAY_EVIL_SLAY2), me); } void MovementInform(uint32 type, uint32 /*id*/) { if (type != POINT_MOTION_TYPE) return; me->SetVisible(false); if (isFriendly) { me->setDeathState(JUST_DIED); Map::PlayerList const& players = me->GetMap()->GetPlayers(); if (!players.isEmpty()) { for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { Player* pPlayer = itr->GetSource(); if (pPlayer) ((InstanceMap*)me->GetMap())->PermBindAllPlayers(pPlayer); } } } else { me->GetMotionMaster()->MoveTargetedHome(); TalkTimer = 1000; } } void GoodEnding() { switch (TalkSequence) { case 1: me->SetFaction(35); TalkTimer = 1000; break; case 2: DoScriptText(SAY_GOOD_PLRWIN, me); TalkTimer = 10000; break; case 3: me->SetLevitate(true); me->GetMotionMaster()->MovePoint(0, FLY_X, FLY_Y, FLY_Z); TalkTimer = 600000; break; default: break; } } void BadEnding() { switch (TalkSequence) { case 1: DoScriptText(SAY_EVIL_ENRAGE, me); TalkTimer = 3000; break; case 2: me->SetLevitate(true); me->GetMotionMaster()->MovePoint(0, FLY_X, FLY_Y, FLY_Z); TalkTimer = 15000; break; case 3: EnterEvadeMode(); break; default: break; } }};struct boss_sathrovarrAI : public ScriptedAI{ boss_sathrovarrAI(Creature* c) : ScriptedAI(c) { pInstance = (ScriptedInstance*)c->GetInstanceData(); KalecGUID = 0; KalecgosGUID = 0; } ScriptedInstance* pInstance; uint32 CorruptionStrikeTimer; uint32 AgonyCurseTimer; uint32 ShadowBoltTimer; uint32 CheckTimer; uint32 ResetThreat; uint64 KalecGUID; uint64 KalecgosGUID; bool isEnraged; bool isBanished; void Reset() { me->SetHealth(me->GetMaxHealth());//不知道为什么它不在闪避时重置生命值.. me->setActive(true); if (pInstance) { KalecgosGUID = pInstance->GetData64(DATA_KALECGOS_DRAGON); pInstance->SetData(DATA_KALECGOS_EVENT, NOT_STARTED); } if (KalecGUID) { if (Creature* Kalec = Unit::GetCreature(*me, KalecGUID)) Kalec->setDeathState(JUST_DIED); KalecGUID = 0; } ShadowBoltTimer = 7000 + rand() % 3 * 1000; AgonyCurseTimer = 20000; CorruptionStrikeTimer = 13000; CheckTimer = 1000; ResetThreat = 1000; isEnraged = false; isBanished = false; me->CastSpell(me, AURA_DEMONIC_VISUAL, true); } void EnterCombat(Unit* /*who*/) { if (Creature* Kalec = me->SummonCreature(MOB_KALEC, me->GetPositionX() + 10, me->GetPositionY() + 5, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0)) { KalecGUID = Kalec->GetGUID(); me->CombatStart(Kalec); me->AddThreat(Kalec, 100.0f); Kalec->setActive(true); } DoScriptText(SAY_SATH_AGGRO, me); } void DamageTaken(Unit* done_by, uint32& damage) { if (damage >= me->GetHealth() && done_by != me) damage = 0; } void KilledUnit(Unit* pTarget) { if (pTarget->GetGUID() == KalecGUID) { TeleportAllPlayersBack(); if (Creature* Kalecgos = Unit::GetCreature(*me, KalecgosGUID)) { CAST_AI(boss_kalecgosAI, Kalecgos->AI())->TalkTimer = 1; CAST_AI(boss_kalecgosAI, Kalecgos->AI())->isFriendly = false; } EnterEvadeMode(); return; } DoScriptText(RAND(SAY_SATH_SLAY1, SAY_SATH_SLAY2), me); } void JustDied(Unit* /*killer*/) { DoScriptText(SAY_SATH_DEATH, me); me->GetMap()->CreatureRelocation(me, me->GetPositionX(), me->GetPositionY(), DRAGON_REALM_Z, me->GetOrientation()); TeleportAllPlayersBack(); if (Creature* Kalecgos = Unit::GetCreature(*me, KalecgosGUID)) { CAST_AI(boss_kalecgosAI, Kalecgos->AI())->TalkTimer = 1; CAST_AI(boss_kalecgosAI, Kalecgos->AI())->isFriendly = true; } if (pInstance) pInstance->SetData(DATA_KALECGOS_EVENT, DONE); } void TeleportAllPlayersBack() { Map* map = me->GetMap(); if (!map->IsDungeon()) return; Map::PlayerList const &playerList = map->GetPlayers(); Position homePos = me->GetHomePosition(); for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr) { Player* player = itr->GetSource(); if (player->IsInDist(&homePos, 50.0f) && player->GetPositionZ() <= DEMON_REALM_Z + 10.f) { player->RemoveAura(AURA_SPECTRAL_REALM, 0); player->TeleportTo(me->GetMap()->GetId(), player->GetPositionX(), player->GetPositionY(), DRAGON_REALM_Z + 5, player->GetOrientation()); } } } void DoAction(const int32 param) { switch (param) { case DO_ENRAGE: isEnraged = true; me->CastSpell(me, SPELL_ENRAGE, true); break; case DO_BANISH: isBanished = true; me->CastSpell(me, SPELL_BANISH, true); break; } } void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (CheckTimer <= diff) { Creature* Kalec = Unit::GetCreature(*me, KalecGUID); if (!Kalec || (Kalec && !Kalec->IsAlive())) { if (Creature* Kalecgos = Unit::GetCreature(*me, KalecgosGUID)) Kalecgos->AI()->EnterEvadeMode(); return; } if (HealthBelowPct(10) && !isEnraged) { if (Creature* Kalecgos = Unit::GetCreature(*me, KalecgosGUID)) Kalecgos->AI()->DoAction(DO_ENRAGE); DoAction(DO_ENRAGE); } Creature* Kalecgos = Unit::GetCreature(*me, KalecgosGUID); if (Kalecgos) { if (!Kalecgos->IsInCombat()) { me->AI()->EnterEvadeMode(); return; } } if (!isBanished && HealthBelowPct(1)) { if (Kalecgos) { if (Kalecgos->HasAura(SPELL_BANISH, 0)) { me->DealDamage(me, me->GetHealth()); return; } else DoAction(DO_BANISH); } else { me->MonsterTextEmote(EMOTE_UNABLE_TO_FIND, 0); EnterEvadeMode(); return; } } CheckTimer = 1000; } else CheckTimer -= diff; if (ResetThreat <= diff) { ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList(); for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) { if (Unit* pUnit = Unit::GetUnit(*me, (*itr)->getUnitGuid())) if (pUnit->GetPositionZ() > me->GetPositionZ() + 5) me->getThreatManager().modifyThreatPercent(pUnit, -100); } ResetThreat = 1000; } else ResetThreat -= diff; if (ShadowBoltTimer <= diff) { if (!(rand() % 5))DoScriptText(SAY_SATH_SPELL1, me); DoCast(me, SPELL_SHADOW_BOLT); ShadowBoltTimer = 7000 + (rand() % 3000); } else ShadowBoltTimer -= diff; if (AgonyCurseTimer <= diff) { Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); if (!pTarget) pTarget = me->GetVictim(); DoCast(pTarget, SPELL_AGONY_CURSE); AgonyCurseTimer = 20000; } else AgonyCurseTimer -= diff; if (CorruptionStrikeTimer <= diff) { if (!(rand() % 5))DoScriptText(SAY_SATH_SPELL2, me); DoCastVictim( SPELL_CORRUPTION_STRIKE); CorruptionStrikeTimer = 13000; } else CorruptionStrikeTimer -= diff; DoMeleeAttackIfReady(); }};struct boss_kalecAI : public ScriptedAI{ ScriptedInstance* pInstance; uint32 RevitalizeTimer; uint32 HeroicStrikeTimer; uint32 YellTimer; uint32 YellSequence; uint64 SathGUID; bool isEnraged; // 如果恶魔被激怒 boss_kalecAI(Creature* c) : ScriptedAI(c) { pInstance = (ScriptedInstance*)c->GetInstanceData(); } void Reset() { if (pInstance) SathGUID = pInstance->GetData64(DATA_SATHROVARR); RevitalizeTimer = 5000; HeroicStrikeTimer = 3000; YellTimer = 5000; YellSequence = 0; isEnraged = false; } void DamageTaken(Unit* done_by, uint32& damage) { if (done_by->GetGUID() != SathGUID) damage = 0; else if (isEnraged) damage *= 3; } void UpdateAI(const uint32 diff) { if (!UpdateVictim()) return; if (YellTimer <= diff) { switch (YellSequence) { case 0: DoScriptText(SAY_GOOD_AGGRO, me); ++YellSequence; break; case 1: if ((me->GetHealth() * 100) / me->GetMaxHealth() < 50) { DoScriptText(SAY_GOOD_NEAR_DEATH, me); ++YellSequence; } break; case 2: if ((me->GetHealth() * 100) / me->GetMaxHealth() < 10) { DoScriptText(SAY_GOOD_NEAR_DEATH2, me); ++YellSequence; } break; default: break; } YellTimer = 5000; } if (RevitalizeTimer <= diff) { DoCast(me, SPELL_REVITALIZE); RevitalizeTimer = 5000; } else RevitalizeTimer -= diff; if (HeroicStrikeTimer <= diff) { DoCastVictim( SPELL_HEROIC_STRIKE); HeroicStrikeTimer = 2000; } else HeroicStrikeTimer -= diff; DoMeleeAttackIfReady(); }};bool GOkalecgos_teleporter(Player* pPlayer, GameObject* pGo){ int32 SpectralPlayers = 0; Map* pMap = pGo->GetMap(); if (!pMap->IsDungeon()) return true; Map::PlayerList const& PlayerList = pMap->GetPlayers(); for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) { if (i->GetSource() && i->GetSource()->GetPositionZ() < DEMON_REALM_Z + 5) ++SpectralPlayers; } if (pPlayer->HasAura(AURA_SPECTRAL_EXHAUSTION, 0) || (MAX_PLAYERS_IN_SPECTRAL_REALM && SpectralPlayers >= MAX_PLAYERS_IN_SPECTRAL_REALM)) pPlayer->GetSession()->SendNotification(GO_FAILED); else pPlayer->CastSpell(pPlayer, SPELL_TELEPORT_SPECTRAL, true); return true;}CreatureAI* GetAI_boss_kalecgos(Creature* pCreature){ return new boss_kalecgosAI (pCreature);}CreatureAI* GetAI_boss_Sathrovarr(Creature* pCreature){ return new boss_sathrovarrAI (pCreature);}CreatureAI* GetAI_boss_kalec(Creature* pCreature){ return new boss_kalecAI (pCreature);}void AddSC_boss_kalecgos(){ Script* newscript; newscript = new Script; newscript->Name = "boss_kalecgos"; newscript->GetAI = &GetAI_boss_kalecgos; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "boss_sathrovarr"; newscript->GetAI = &GetAI_boss_Sathrovarr; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "boss_kalec"; newscript->GetAI = &GetAI_boss_kalec; newscript->RegisterSelf(); newscript = new Script; newscript->Name = "kalecgos_teleporter"; newscript->pGOHello = &GOkalecgos_teleporter; newscript->RegisterSelf();}[COLOR=#333333]