rendered paste bodyIndex: scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp===================================================================--- scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp (revision 315)+++ scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp (working copy)@@ -26,6 +26,9 @@ #define SPELL_WHIRLWIND 40653 #define SPELL_CHAOS_BLAST 37675 // #define SPELL_INSIDIOUS_WHISPER 37676 // useless - dummy effect that can't be implemented+#define SPELL_WIPEWHIRLWIND 37641+#define INNER_DEMON_ID 21857 // Temporary summon 5 demons in random players with aura+#define INNER_DEMON_AURA 37713 // Demonic Alignment aura #define SAY_AGGRO "Finally my banishment ends!" #define SAY_SWITCH_TO_DEMON "Be gone trifling elf. I'm in control now."@@ -58,6 +61,26 @@ #define DEMON_FORM 21845 +// BANISH PHASE+#define GREEN_BEAM 38909+#define BANISH_EFFECT 37833++float add1SPlace[4] =+{+ 364.219208, -448.394073, 29.515247, 0.170111+};++float add2SPlace[4] =+{+ 375.948334, -426.4744335, 29.524292, 4.982298+};++float add3SPlace[4] =+{+ 396.755188, -433.087402, 30.189342, 3.782232+};++ //Original Leotheras the Blind AI struct MANGOS_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI {@@ -65,33 +88,68 @@ { pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL; Demon = 0;+ initialize(); EnterEvadeMode(); } + Creature *add1;+ Creature *add2;+ Creature *add3;+ ScriptedInstance *pInstance; uint32 Whirlwind_Timer; uint32 ChaosBlast_Timer; uint32 Switch_Timer;+ uint32 Wipe_Timer;+ uint32 Wipe_Whirlwind_Timer; bool DemonForm; bool IsFinalForm; bool InCombat;+ + bool spawned;+ bool relased;+ bool channeling[3]; + bool add1Dead;+ bool add2Dead;+ bool add3Dead;+ uint64 Demon;+ + + void initialize()+ {+ relased = false;+ spawned = false;+ relased = false;+ for(uint8 i = 0; i < 3; ++i)+ channeling[i] = false; + add1Dead = false;+ add2Dead = false;+ add3Dead = false;++ add1 = NULL;+ add2 = NULL;+ add3 = NULL;+ }+ void Reset() {- Whirlwind_Timer = 20000;+ Whirlwind_Timer = 20000; ChaosBlast_Timer = 1000; Switch_Timer = 45000;+ Wipe_Timer = 600000;+ Wipe_Whirlwind_Timer = 15000; DemonForm = false; IsFinalForm = false; InCombat = false;-+ m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF);-+ //m_creature->RemoveAllAuras(); //m_creature->DeleteThreatList(); //m_creature->CombatStop();@@ -105,6 +163,11 @@ void StartEvent() {+ if(!relased)+ {+ m_creature->CombatStop();+ return;+ } DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_AGGRO); @@ -174,6 +237,9 @@ if(pInstance) pInstance->SetData(DATA_LEOTHERASTHEBLINDEVENT, 0);+ + // ustawia wskazniki add1,add2,add3 na NULl, spawned = false itd. (bez tego po respawnie nie było by addów)+ initialize(); } void AttackStart(Unit *who)@@ -185,7 +251,7 @@ { //Begin melee attack if we are within range DoStartMeleeAttack(who);-+ if(!InCombat) StartEvent(); }@@ -211,9 +277,10 @@ } } }-+// VICTIMSTATE_DODGE void UpdateAI(const uint32 diff) {+ banishPhase(); //Return since we have no target if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() ) return;@@ -237,6 +304,13 @@ DoPlaySoundToSet(m_creature, SOUND_SWITCH_TO_DEMON); DemonForm = true; + Unit* Spawn = NULL;+ Spawn = m_creature->SummonCreature(INNER_DEMON_ID, m_creature->getVictim()->GetPositionX(), m_creature->getVictim()->GetPositionY(), m_creature->getVictim()->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 600000);+ Spawn = m_creature->SummonCreature(INNER_DEMON_ID, m_creature->getVictim()->GetPositionX(), m_creature->getVictim()->GetPositionY(), m_creature->getVictim()->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 600000);+ Spawn = m_creature->SummonCreature(INNER_DEMON_ID, m_creature->getVictim()->GetPositionX(), m_creature->getVictim()->GetPositionY(), m_creature->getVictim()->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 600000);+ Spawn = m_creature->SummonCreature(INNER_DEMON_ID, m_creature->getVictim()->GetPositionX(), m_creature->getVictim()->GetPositionY(), m_creature->getVictim()->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 600000);+ Spawn = m_creature->SummonCreature(INNER_DEMON_ID, m_creature->getVictim()->GetPositionX(), m_creature->getVictim()->GetPositionY(), m_creature->getVictim()->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 600000);+ Switch_Timer = 60000; }else Switch_Timer -= diff; @@ -260,8 +334,25 @@ Switch_Timer = 45000; }else Switch_Timer -= diff;- } + //WIPE after 10 minutes+ if(Wipe_Timer < diff)+ { + const CreatureInfo *cinfo = m_creature->GetCreatureInfo();+ m_creature->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg * 10));+ m_creature->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg * 10));+ m_c reature->UpdateDamagePhysical(BASE_ATTACK); + Wipe_Timer = 60000; + if(Wipe_Whirlwind_Timer < diff)+ {+ DoCast(m_creature, SPELL_WIPEWHIRLWIND);+ Wipe_Whirlwind_Timer = 20000;+ ResetThreat();+ }else Wipe_Whirlwind_Timer -=diff; + }else Wipe_Timer -=diff;++ }+ if(!IsFinalForm && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 15) { //at this point he divides himself in two parts@@ -284,6 +375,154 @@ m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF); } }++ void ResetThreat()+ { + std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();+ std::list<HostilReference*>::iterator i = m_threatlist.begin();+ for(i = m_threatlist.begin(); i != m_threatlist.end(); ++i)+ {+ Unit* pUnit = NULL;+ pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());+ if(pUnit)+ {+ m_creature->getThreatManager().modifyThreatPercent(pUnit, -100);+ }+ }+ }++ void banishPhase()+ {+ // Banish Phase by Krz (just educational code ^_^)+ // ---------- BANISH PHASE START ----------+ if(!spawned)+ {+ m_creature->ApplySpellImmune(BANISH_EFFECT,IMMUNITY_MECHANIC,MECHANIC_BANISH,false); // żeby mógł rzucić banisha - Ustawione na true podczas relase+ add1 = m_creature->SummonCreature(21806, add1SPlace[0], add1SPlace[1],add1SPlace[2],add1SPlace[3],TEMPSUMMON_CORPSE_TIMED_DESPAWN,1000);+ add2 = m_creature->SummonCreature(21806, add2SPlace[0], add2SPlace[1],add2SPlace[2],add2SPlace[3],TEMPSUMMON_CORPSE_TIMED_DESPAWN,1000);+ add3 = m_creature->SummonCreature(21806, add3SPlace[0], add3SPlace[1],add3SPlace[2],add3SPlace[3],TEMPSUMMON_CORPSE_TIMED_DESPAWN,1000);+ + m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON); // DemonModel - Blizzlike banishment+ DoCast(m_creature, BANISH_EFFECT); // selfCast banisha + spawned = true;+ }++ // Zacznš castować tylko gdy nie sš w combacie (jak wejdš w combat to channeling[] = false, żeby w razie gdy zabijš cel to powrócš i znów wycastujš ten channeling spell+ if(!add1 == NULL)+ {+ // odwróci je w stronę blinda - Visual bug... trzeba się odsunšc i wrócić, to wtedy będš odwrócone -_-+ if(add1->GetPositionX() == add1SPlace[0] &&+ add1->GetPositionY() == add1SPlace[1] &&+ add1->GetPositionZ() == add1SPlace[2] &&+ add1->GetOrientation() != add1SPlace[3] )+ add1->SetOrientation(add1SPlace[3]);++ /* Unit *target = add1->getVictim();+ if(target) <- test, żeby addy castowały shocka tylko jak cel castuje ( pozniej przerobie na random.target@threatlist ale chcialem sprawdzic czy zadziala wykrywanie casta+ if(target->m_currentSpells[3] || target->m_currentSpells[2] || target->m_currentSpells[1])//->getState() == 2 && target)//->getState() == 2 && target)+ add1->CastSpell(add1->getVictim(), 39076, false);+*/+ + if(!channeling[0] && !add1->isInCombat())+ {+ add1->CastSpell(m_creature,GREEN_BEAM,false);+ channeling[0] = true;+ }+ if(add1->isInCombat() && channeling[0] == true)+ {+ channeling[0] = false;+ add1->InterruptSpell(CURRENT_CHANNELED_SPELL, true);+ + if(!add2 == NULL)+ if(!add2->isInCombat())+ add2->getThreatManager().addThreat(add1->getVictim(),1);+ if(!add3 == NULL)+ if(!add3->isInCombat())+ add3->getThreatManager().addThreat(add1->getVictim(),1);+ }+ if(add1->GetHealth() == 0)+ {+ add1Dead = true;+ add1 = NULL;+ }+ }+ if(!add2 == NULL)+ {+ if(add2->GetPositionX() == add2SPlace[0] &&+ add2->GetPositionY() == add2SPlace[1] &&+ add2->GetPositionZ() == add2SPlace[2] &&+ add2->GetOrientation() != add2SPlace[3] )+ add2->SetOrientation(add2SPlace[3]);++ if(!channeling[1] && !add2->isInCombat())+ {+ add2->CastSpell(m_creature,GREEN_BEAM,false);+ channeling[1] = true;+ }+ if(add2->isInCombat() && channeling[1] == true)+ {+ channeling[1] = false;+ add2->InterruptSpell(CURRENT_CHANNELED_SPELL, true);+ + if(!add1 == NULL)+ if(!add1->isInCombat())+ add1->getThreatManager().addThreat(add2->getVictim(),1);+ if(!add3 == NULL)+ if(!add3->isInCombat())+ add3->getThreatManager().addThreat(add2->getVictim(),1);+ }+ if(add2->GetHealth() == 0)+ {+ add2Dead = true;+ add2 = NULL;+ }+ }+ if(!add3 == NULL)+ {+ if(add3->GetPositionX() == add3SPlace[0] &&+ add3->GetPositionY() == add3SPlace[1] &&+ add3->GetPositionZ() == add3SPlace[2] &&+ add3->GetOrientation() != add3SPlace[3] )+ add3->SetOrientation(add3SPlace[3]);++ if(!channeling[2] && !add3->isInCombat())+ {+ add3->CastSpell(m_creature,GREEN_BEAM,false);+ channeling[2] = true;+ }+ if(add3->isInCombat() && channeling[2] == true)+ {+ channeling[2] = false;+ add3->InterruptSpell(CURRENT_CHANNELED_SPELL, true);++ //zaatakuja wszystkie gdy 1 wejdzie w combat+ if(!add1 == NULL)+ if(!add1->isInCombat())+ add1->getThreatManager().addThreat(add3->getVictim(),1);+ if(!add2 == NULL)+ if(!add2->isInCombat())+ add2->getThreatManager().addThreat(add3->getVictim(),1);+ + }+ if(add3->GetHealth() == 0)+ {+ add3Dead = true;+ add3 = NULL;+ }+ }+ + if(add1Dead && add2Dead && add3Dead)+ {+ m_creature->RemoveAllAuras();+ m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF);+ m_creature->ApplySpellImmune(37546,IMMUNITY_MECHANIC,MECHANIC_BANISH,true);+ relased = true;+ add1Dead = false;+ add2Dead = false;+ add3Dead = false;+ }+// ---------- BANISH PHASE END ----------+ } }; //Leotheras the Blind Demon Form AI