Example #1
0
            void ChangeDamage(SpellEffIndex /*effIndex*/)
            {
                Unit* caster = GetCaster();
                int32 damage = GetHitDamage();

                if (caster->HasAura(SPELL_PALADIN_DIVINE_PURPOSE_PROC))
                    damage *= 7.5;  // 7.5*30% = 225%
                else
                {
                    switch (caster->GetPower(POWER_HOLY_POWER))
                    {
                        case 0: // 1 Holy Power
                            // same damage
                            break;
                        case 1: // 2 Holy Power
                            damage *= 3;    // 3*30 = 90%
                            break;
                        case 2: // 3 Holy Power
                            damage *= 7.5;  // 7.5*30% = 225%
                            break;
                    }
                }

                SetHitDamage(damage);
            }
Example #2
0
            void HandleEffect(SpellEffIndex effIndex)
            {
                Unit* caster = GetCaster();
                if (Unit* target = GetHitUnit())
                {
                    SpellInfo const* spellInfo = GetSpellInfo();
                    int32 rageUsed = std::min<int32>(300 - spellInfo->CalcPowerCost(caster, SpellSchoolMask(spellInfo->SchoolMask)), caster->GetPower(POWER_RAGE));
                    int32 newRage = std::max<int32>(0, caster->GetPower(POWER_RAGE) - rageUsed);

                    // Sudden Death rage save
                    if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_GENERIC, WARRIOR_ICON_ID_SUDDEN_DEATH, EFFECT_0))
                    {
                        int32 ragesave = aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue() * 10;
                        newRage = std::max(newRage, ragesave);
                    }

                    caster->SetPower(POWER_RAGE, uint32(newRage));
                    // Glyph of Execution bonus
                    if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_WARRIOR_GLYPH_OF_EXECUTION, EFFECT_0))
                        rageUsed += aurEff->GetAmount() * 10;


                    int32 bp = GetEffectValue() + int32(rageUsed * spellInfo->Effects[effIndex].DamageMultiplier + caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.2f);
                    caster->CastCustomSpell(target, SPELL_WARRIOR_EXECUTE, &bp, NULL, NULL, true, NULL, NULL, GetOriginalCaster()->GetGUID());
                }
            }
Example #3
0
    void UpdateAI(const uint32 diff)
    {
        //Return since we have no target
        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
            return;

        //ShadowVolley_Timer
        if (ShadowVolley_Timer < diff)
        {
            DoCast(m_creature->getVictim(), SPELL_SHADOWVOLLEY);
            ShadowVolley_Timer = 4000 + rand()%2000;
        }else ShadowVolley_Timer -= diff;

        //Cleave_Timer
        if (Cleave_Timer < diff)
        {
            DoCast(m_creature->getVictim(),SPELL_CLEAVE);
            Cleave_Timer = 8000 + rand()%4000;
        }else Cleave_Timer -= diff;

        //ThunderClap_Timer
        if (ThunderClap_Timer < diff)
        {
            DoCast(m_creature->getVictim(),SPELL_THUNDERCLAP);
            ThunderClap_Timer = 10000 + rand()%4000;
        }else ThunderClap_Timer -= diff;

        //VoidBolt_Timer
        if (VoidBolt_Timer < diff)
        {
            DoCast(m_creature->getVictim(),SPELL_VOIDBOLT);
            VoidBolt_Timer = 15000 + rand()%3000;
        }else VoidBolt_Timer -= diff;

        //MarkOfKazzak_Timer
        if (MarkOfKazzak_Timer < diff)
        {
            Unit* victim = SelectUnit(SELECT_TARGET_RANDOM, 0);
            if(victim->GetPower(POWER_MANA))
            {
                DoCast(victim, SPELL_MARKOFKAZZAK);
                MarkOfKazzak_Timer = 20000;
            }
        }else MarkOfKazzak_Timer -= diff;

        //Enrage_Timer
        if (Enrage_Timer < diff)
        {
            DoCast(m_creature,SPELL_ENRAGE);
            Enrage_Timer = 30000;
        }else Enrage_Timer -= diff;

        if(Twisted_Reflection_Timer < diff)
        {
            DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_TWISTEDREFLECTION);
            Twisted_Reflection_Timer = 15000;
        }else Twisted_Reflection_Timer -= diff;

        DoMeleeAttackIfReady();
    }
Example #4
0
            void HandleBeforeCast()
            {
                Unit* caster = GetCaster();

                if(caster)
                {
                    int32 Rage_val = 0;
                    PlayerSpellMap const& sp_list = caster->ToPlayer()->GetSpellMap();

                    // Retrieves max rage to retain
                    for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
                    {
                        if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled)
                            continue;

                        SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
                        if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo->SpellIconID == 139)
                        {
                            Rage_val += caster->CalculateSpellDamage(caster, spellInfo, EFFECT_0);
                        }
                    }

                    // Check and update (do not forget the * 10 on each SetPower with POWER_RAGE)
                    if (caster->GetPower(POWER_RAGE) > Rage_val * 10)
                    {
                        Rage_val *= sWorld->getRate(RATE_POWER_RAGE_INCOME);

                        caster->SetPower(POWER_RAGE, Rage_val * 10);
                    }
                }
            }
Example #5
0
            void HandleEffect(SpellEffIndex /*effIndex*/)
            {
                Unit* caster = GetCaster();
                if (GetHitUnit())
                {
                    SpellInfo const* spellInfo = GetSpellInfo();
                    int32 rageUsed = std::min<int32>(200 - spellInfo->CalcPowerCost(caster, SpellSchoolMask(spellInfo->SchoolMask)), caster->GetPower(POWER_RAGE));
                    int32 newRage = std::max<int32>(0, caster->GetPower(POWER_RAGE) - rageUsed);

                    // Sudden Death rage save
                    if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_GENERIC, ICON_ID_SUDDEN_DEATH, EFFECT_0))
                    {
                        int32 ragesave = aurEff->GetSpellInfo()->Effects[EFFECT_0].CalcValue() * 10;
                        newRage = std::max(newRage, ragesave);
                    }

                    caster->SetPower(POWER_RAGE, uint32(newRage));

                    /// Formula taken from the DBC: "${10+$AP*0.437*$m1/100}"
                    int32 baseDamage = int32(10 + caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.437f * GetEffectValue() / 100.0f);
                    /// Formula taken from the DBC: "${$ap*0.874*$m1/100-1} = 20 rage"
                    int32 moreDamage = int32(rageUsed * (caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.874f * GetEffectValue() / 100.0f - 1) / 200);
                    SetHitDamage(baseDamage + moreDamage);
                }
            }
Example #6
0
    void OnLoad()
    {
        if (_unit->IsSummon())
        {
            Summon* s = TO< Summon* >(_unit);
            Unit* owner = s->GetOwner();

            owner->CastSpell(_unit, 45204, true);   // clone me
            owner->CastSpell(_unit, 58838, true);   // inherit threat list

            // Mage mirror image spell
            if (_unit->GetCreatedBySpell() == 58833)
            {
                _unit->SetMaxHealth(2500);
                _unit->SetHealth(2500);
                _unit->SetMaxPower(POWER_TYPE_MANA, owner->GetMaxPower(POWER_TYPE_MANA));
                _unit->SetPower(POWER_TYPE_MANA, owner->GetPower(POWER_TYPE_MANA));

                SpellRange* range = NULL;

                AI_Spell sp1;

                sp1.entryId = 59638;
                sp1.spell = dbcSpell.LookupEntryForced(sp1.entryId);
                sp1.spellType = STYPE_DAMAGE;
                sp1.agent = AGENT_SPELL;
                sp1.spelltargetType = TTYPE_SINGLETARGET;
                sp1.cooldown = 0;
                sp1.cooldowntime = 0;
                sp1.Misc2 = 0;
                sp1.procCount = 0;
                sp1.procChance = 100;
                range = dbcSpellRange.LookupEntry(sp1.spell->rangeIndex);
                sp1.minrange = GetMinRange(range);
                sp1.maxrange = GetMaxRange(range);

                _unit->GetAIInterface()->addSpellToList(&sp1);

                AI_Spell sp2;
                sp2.entryId = 59637;
                sp2.spell = dbcSpell.LookupEntryForced(sp2.entryId);
                sp2.spellType = STYPE_DAMAGE;
                sp2.agent = AGENT_SPELL;
                sp2.spelltargetType = TTYPE_SINGLETARGET;
                sp2.cooldown = 0;
                sp2.cooldowntime = 0;
                sp2.Misc2 = 0;
                sp2.procCount = 0;
                sp2.procChance = 100;
                range = dbcSpellRange.LookupEntry(sp2.spell->rangeIndex);
                sp2.minrange = GetMinRange(range);
                sp2.maxrange = GetMaxRange(range);

                _unit->GetAIInterface()->addSpellToList(&sp2);
            }
        }
    }
Example #7
0
            void HandleOnCast()
            {
                Unit* caster = GetCaster();

                if(caster && caster->GetPower(POWER_RAGE) > 0)
                {
                    float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);

                    // Formula taken from the DBC: "${10+$AP*0.437*$m1/100}"
                    damage = int32(10 + ap * 0.437);

                    // Normalized rage (-10 because the execute base cost is not yet applied)
                    uint32 powerAfterBaseCost = caster->GetPower(POWER_RAGE) /10 -10;

                    uint32 extraRage = powerAfterBaseCost > 20 ? 20 : powerAfterBaseCost;
                    uint32 newPowerAmount = powerAfterBaseCost - extraRage;

                    // Sudden Death rage saving
                    if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_WARRIOR, WARRIOR_ICON_ID_SUDDEN_DEATH, EFFECT_0))
                    {
                        if(newPowerAmount < 10)
                        {
                            newPowerAmount = aurEff->GetAmount();
                        }
                    }

                    // Enter if there is extra rage to add as bonus damage
                    if(extraRage > 0)
                    {
                        // Add bonus damage
                        // Formula taken from the DBC: "${$ap*0.874*$m1/100-1} = 20 rage"
                        damage += int32 (ap * 0.874 * extraRage / 10 - 1);
                    }

                    // For remaining at the desidered rage when the warrior will use the base execute cost (10)
                    newPowerAmount += 10;

                    newPowerAmount *= sWorld->getRate(RATE_POWER_RAGE_INCOME);

                    // Sets new rage
                    caster->SetPower(POWER_RAGE, newPowerAmount * 10);
                }
            }
Example #8
0
            void OnPeriodic(AuraEffect const* aurEff)
            {
                Unit* target = GetTarget();

                if (target->GetPower(POWER_MANA) == 0)
                {
                    target->CastSpell(target, SPELL_MARK_DAMAGE, true, NULL, aurEff);
                    // Remove aura
                    SetDuration(0);
                }
            }
Example #9
0
    void UpdateAI(const uint32 diff)
    {
        //Return since we have no target
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if(CleaveTimer < diff)
        {
            if(m_creature->getVictim())
                DoCast(m_creature->getVictim(), SPELL_CLEAVE);
            CleaveTimer = 6000+rand()%15000;
        }else CleaveTimer -= diff;

        if(WarStompTimer < diff)
        {
            DoCast(m_creature, SPELL_WARSTOMP);
            WarStompTimer = 60000;
        }else WarStompTimer -= diff;

        if(m_creature->HasAura(SPELL_MARK))
            m_creature->RemoveAurasDueToSpell(SPELL_MARK);

        if(MarkBlastTimer < diff)
        {
            std::list<HostileReference *> t_list = m_creature->getThreatManager().getThreatList();
            for(std::list<HostileReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
            {
                Unit *target = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid());

                if (target && target->GetTypeId() == TYPEID_PLAYER && target->getPowerType() == POWER_MANA)
                    if(target->HasAura(SPELL_MARK))
                        if((target->GetPower(POWER_MANA)*100) / target->GetMaxPower(POWER_MANA) <= 1)
                            target->CastSpell(target, SPELL_MARK2, true);
            }
            MarkBlastTimer = 1000;
        }MarkBlastTimer -= diff;

        if(MarkTimer < diff)
        {
            CastMark();
            MarkTimer = BaseMarkTimer - MarkCount * 10000;
            if(MarkCount < 6)
                ++MarkCount;
            else
                MarkTimer = 5000;

        }else MarkTimer -= diff;

        DoMeleeAttackIfReady();
    }
Example #10
0
        void ChangeDamage(SpellEffIndex effIndex)
        {
            Unit* caster = GetCaster();
            Unit* target = GetHitUnit();

            if (!target)
                return;

            int32 rageUsed = std::min<int32>(300 - GetSpellInfo()->CalcPowerCost(caster, SpellSchoolMask(GetSpellInfo()->SchoolMask)), caster->GetPower(POWER_RAGE));
            int32 newRage = std::max<int32>(0, caster->GetPower(POWER_RAGE) - rageUsed);
            // Sudden Death rage refund
            if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_GENERIC, ICON_ID_SUDDEN_DEATH, EFFECT_0))
            {
                int32 ragesave = aurEff->GetAmount() * 10;
                newRage = std::max(newRage, ragesave);
            }
            caster->SetPower(POWER_RAGE, uint32(newRage));
            // DBC formula: ap * 0.874 * 100 / 100 - rageUsed
            int32 rageBonus = ((caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.874f) * 1000) / (1000 - rageUsed);
            int32 totalDamage = (GetHitDamage() + rageBonus);
            SetHitDamage(totalDamage);
        }
Example #11
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        switch(m_uiPhase)
        {
            case PHASE_ATTACKING:
                if (m_uiCheckoutMana_Timer <= uiDiff)
                {
                    m_uiCheckoutMana_Timer = 1500;
                    if (m_creature->GetPower(POWER_MANA) * 100 / m_creature->GetMaxPower(POWER_MANA) > 75.0f)
                    {
                        DoCastSpellIfCan(m_creature, SPELL_ENERGIZE);
                        DoScriptText(EMOTE_ENERGIZING, m_creature);
                        m_uiPhase = PHASE_ENERGIZING;
                        return;
                    }
                }
                else
                    m_uiCheckoutMana_Timer -= uiDiff;

                if (m_uiSummonManaFiends_Timer <= uiDiff)
                {
                    DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_1, CAST_TRIGGERED);
                    DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_2, CAST_TRIGGERED);
                    DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_3, CAST_TRIGGERED);
                    m_uiSummonManaFiends_Timer = 90000;
                }
                else
                    m_uiSummonManaFiends_Timer -= uiDiff;

                if (m_uiManaDrain_Timer <= uiDiff)
                {
                    m_uiManaDrain_Timer = urand(2000, 6000);
                    // choose random target with mana
                    std::list<Unit*> lTargets;
                    ThreatList const& threatlist = m_creature->getThreatManager().getThreatList();
                    if (threatlist.empty())
                        return;

                    for (ThreatList::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
                    {
                        Unit* pUnit = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid());

                        if (pUnit && pUnit->isAlive() && pUnit->GetPower(POWER_MANA))
                            lTargets.push_back(pUnit);
                    }

                    if (lTargets.empty())
                        return;

                    std::list<Unit*>::iterator itr = lTargets.begin();
                    std::advance(itr, urand(0, lTargets.size()-1));

                    DoCastSpellIfCan(*itr, SPELL_DRAIN_MANA);
                }
                else
                    m_uiManaDrain_Timer -= uiDiff;

                if (m_uiTrample_Timer <= uiDiff)
                {
                    DoCastSpellIfCan(m_creature->getVictim(), SPELL_TRAMPLE);
                    m_uiTrample_Timer = 15000;
                }
                else
                    m_uiTrample_Timer -= uiDiff;

                DoMeleeAttackIfReady();
                break;
            case PHASE_ENERGIZING:
                if (m_uiCheckoutMana_Timer <= uiDiff)
                {
                    m_uiCheckoutMana_Timer = 1500;
                    if (m_creature->GetPower(POWER_MANA) == m_creature->GetMaxPower(POWER_MANA))
                    {
                        m_creature->RemoveAurasDueToSpell(SPELL_ENERGIZE);
                        DoCastSpellIfCan(m_creature, SPELL_ARCANE_ERUPTION);
                        DoScriptText(EMOTE_MANA_FULL, m_creature);
                        m_uiPhase = PHASE_ATTACKING;
                        return;
                    }
                }
                else
                    m_uiCheckoutMana_Timer -= uiDiff;
                break;
        }
    }
Example #12
0
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
{
    DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
    uint64 Guid;
    recv_data >> Guid;

    Player *player = sObjectMgr.GetPlayer(Guid);
    if(!player)
    {
        WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
        data << uint8(0);                                   // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
        data.appendPackGUID(Guid);
        data << uint32(GROUP_UPDATE_FLAG_STATUS);
        data << uint16(MEMBER_STATUS_OFFLINE);
        SendPacket(&data);
        return;
    }

    Unit *pet = player->GetCharmOrPet();

    WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
    data << uint8(0);                                       // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
    data << player->GetPackGUID();

    uint32 mask1 = 0x00040BFF;                              // common mask, real flags used 0x000040BFF
    if(pet)
        mask1 = 0xFFFFFFFF;                                 // for hunters and other classes with pets

    Powers powerType = player->getPowerType();
    data << uint32(mask1);                                  // group update mask
    data << uint16(MEMBER_STATUS_ONLINE);                   // member's online status
    data << uint32(player->GetHealth());                    // GROUP_UPDATE_FLAG_CUR_HP
    data << uint32(player->GetMaxHealth());                 // GROUP_UPDATE_FLAG_MAX_HP
    data << uint8(powerType);                               // GROUP_UPDATE_FLAG_POWER_TYPE
    data << uint16(player->GetPower(powerType));            // GROUP_UPDATE_FLAG_CUR_POWER
    data << uint16(player->GetMaxPower(powerType));         // GROUP_UPDATE_FLAG_MAX_POWER
    data << uint16(player->getLevel());                     // GROUP_UPDATE_FLAG_LEVEL
    data << uint16(player->GetZoneId());                    // GROUP_UPDATE_FLAG_ZONE
    data << uint16(player->GetPositionX());                 // GROUP_UPDATE_FLAG_POSITION
    data << uint16(player->GetPositionY());                 // GROUP_UPDATE_FLAG_POSITION

    uint64 auramask = 0;
    size_t maskPos = data.wpos();
    data << uint64(auramask);                               // placeholder
    for(uint8 i = 0; i < MAX_AURAS; ++i)
    {
        if(uint32 aura = player->GetVisibleAura(i))
        {
            auramask |= (uint64(1) << i);
            data << uint32(aura);
            data << uint8(1);
        }
    }
    data.put<uint64>(maskPos, auramask);                    // GROUP_UPDATE_FLAG_AURAS

    if(pet)
    {
        Powers petpowertype = pet->getPowerType();
        data << pet->GetObjectGuid();                       // GROUP_UPDATE_FLAG_PET_GUID
        data << pet->GetName();                             // GROUP_UPDATE_FLAG_PET_NAME
        data << uint16(pet->GetDisplayId());                // GROUP_UPDATE_FLAG_PET_MODEL_ID
        data << uint32(pet->GetHealth());                   // GROUP_UPDATE_FLAG_PET_CUR_HP
        data << uint32(pet->GetMaxHealth());                // GROUP_UPDATE_FLAG_PET_MAX_HP
        data << uint8(petpowertype);                        // GROUP_UPDATE_FLAG_PET_POWER_TYPE
        data << uint16(pet->GetPower(petpowertype));        // GROUP_UPDATE_FLAG_PET_CUR_POWER
        data << uint16(pet->GetMaxPower(petpowertype));     // GROUP_UPDATE_FLAG_PET_MAX_POWER

        uint64 petauramask = 0;
        size_t petMaskPos = data.wpos();
        data << uint64(petauramask);                        // placeholder
        for(uint8 i = 0; i < MAX_AURAS; ++i)
        {
            if(uint32 petaura = pet->GetVisibleAura(i))
            {
                petauramask |= (uint64(1) << i);
                data << uint32(petaura);
                data << uint8(1);
            }
        }
        data.put<uint64>(petMaskPos, petauramask);          // GROUP_UPDATE_FLAG_PET_AURAS
        data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
    }
    else
    {
        data << uint8(0);                                   // GROUP_UPDATE_FLAG_PET_NAME
        data << uint64(0);                                  // GROUP_UPDATE_FLAG_PET_AURAS
    }

    SendPacket(&data);
}
Example #13
0
void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data)
{
    uint32 mask = player->GetGroupUpdateFlag();

    if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)                // if update power type, update current/max power also
        mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER);

    if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)            // same for pets
        mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER);

    uint32 byteCount = 0;
    for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
        if (mask & (1 << i))
            byteCount += GroupUpdateLength[i];

    data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
    *data << player->GetPackGUID();
    *data << uint32(mask);

    if (mask & GROUP_UPDATE_FLAG_STATUS)
    {
        if (player)
        {
            if (player->IsPvP())
                *data << uint16(MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP);
            else
                *data << uint16(MEMBER_STATUS_ONLINE);
        }
        else
            *data << uint16(MEMBER_STATUS_OFFLINE);
    }

    if (mask & GROUP_UPDATE_FLAG_CUR_HP)
        *data << uint32(player->GetHealth());

    if (mask & GROUP_UPDATE_FLAG_MAX_HP)
        *data << uint32(player->GetMaxHealth());

    Powers powerType = player->getPowerType();
    if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)
        *data << uint8(powerType);

    if (mask & GROUP_UPDATE_FLAG_CUR_POWER)
        *data << uint16(player->GetPower(powerType));

    if (mask & GROUP_UPDATE_FLAG_MAX_POWER)
        *data << uint16(player->GetMaxPower(powerType));

    if (mask & GROUP_UPDATE_FLAG_LEVEL)
        *data << uint16(player->getLevel());

    if (mask & GROUP_UPDATE_FLAG_ZONE)
        *data << uint16(player->GetZoneId());

    if (mask & GROUP_UPDATE_FLAG_POSITION)
        *data << uint16(player->GetPositionX()) << uint16(player->GetPositionY());

    if (mask & GROUP_UPDATE_FLAG_AURAS)
    {
        const uint64& auramask = player->GetAuraUpdateMask();
        *data << uint64(auramask);
        for(uint32 i = 0; i < MAX_AURAS; ++i)
        {
            if(auramask & (uint64(1) << i))
            {
                *data << uint32(player->GetVisibleAura(i));
                *data << uint8(1);
            }
        }
    }

    Unit *pet = player->GetCharmOrPet();
    if (mask & GROUP_UPDATE_FLAG_PET_GUID)
        *data << (pet ? pet->GetObjectGuid() : ObjectGuid());

    if (mask & GROUP_UPDATE_FLAG_PET_NAME)
    {
        if(pet)
            *data << pet->GetName();
        else
            *data << uint8(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID)
    {
        if(pet)
            *data << uint16(pet->GetDisplayId());
        else
            *data << uint16(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)
    {
        if(pet)
            *data << uint32(pet->GetHealth());
        else
            *data << uint32(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)
    {
        if(pet)
            *data << uint32(pet->GetMaxHealth());
        else
            *data << uint32(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
    {
        if(pet)
            *data << uint8(pet->getPowerType());
        else
            *data << uint8(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER)
    {
        if(pet)
            *data << uint16(pet->GetPower(pet->getPowerType()));
        else
            *data << uint16(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER)
    {
        if(pet)
            *data << uint16(pet->GetMaxPower(pet->getPowerType()));
        else
            *data << uint16(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_AURAS)
    {
        if(pet)
        {
            const uint64& auramask = pet->GetAuraUpdateMask();
            *data << uint64(auramask);
            for(uint32 i = 0; i < MAX_AURAS; ++i)
            {
                if(auramask & (uint64(1) << i))
                {
                    *data << uint32(pet->GetVisibleAura(i));
                    *data << uint8(1);
                }
            }
        }
        else
            *data << uint64(0);
    }

    if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
    {
        *data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
    }
}
Example #14
0
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
{
    DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
    ObjectGuid guid;
    recv_data >> guid;

    Player * player = HashMapHolder<Player>::Find(guid);
    if(!player)
    {
        WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
        data << uint8(0);                                   // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
        data << guid.WriteAsPacked();
        data << uint32(GROUP_UPDATE_FLAG_STATUS);
        data << uint16(MEMBER_STATUS_OFFLINE);
        SendPacket(&data);
        return;
    }

    Unit *pet = player->GetCharmOrPet();

    WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
    data << uint8(0);                                       // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
    data << player->GetPackGUID();

    uint32 mask1 = 0x00040BFF;                              // common mask, real flags used 0x000040BFF
    if(pet)
        mask1 = 0xFFFFFFFF;                                 // for hunters and other classes with pets

    Powers powerType = player->getPowerType();
    data << uint32(mask1);                                  // group update mask
    data << uint16(MEMBER_STATUS_ONLINE);                   // member's online status
    data << uint32(player->GetHealth());                    // GROUP_UPDATE_FLAG_CUR_HP
    data << uint32(player->GetMaxHealth());                 // GROUP_UPDATE_FLAG_MAX_HP
    data << uint8(powerType);                               // GROUP_UPDATE_FLAG_POWER_TYPE
    data << uint16(player->GetPower(powerType));            // GROUP_UPDATE_FLAG_CUR_POWER
    data << uint16(player->GetMaxPower(powerType));         // GROUP_UPDATE_FLAG_MAX_POWER
    data << uint16(player->getLevel());                     // GROUP_UPDATE_FLAG_LEVEL

    //verify player coordinates and zoneid to send to teammates
    uint16 iZoneId = 0;
    uint16 iCoordX = 0;
    uint16 iCoordY = 0;

    if (player->IsInWorld())
    {
        iZoneId = player->GetZoneId();
        iCoordX = player->GetPositionX();
        iCoordY = player->GetPositionY();
    }
    else if (player->IsBeingTeleported())               // Player is in teleportation
    {
        WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination
        iZoneId = sTerrainMgr.GetZoneId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z);
        iCoordX = loc.coord_x;
        iCoordY = loc.coord_y;
    }
    else
    {
        //unknown player status.
    }

    data << uint16(iZoneId);                              // GROUP_UPDATE_FLAG_ZONE
    data << uint16(iCoordX);                              // GROUP_UPDATE_FLAG_POSITION
    data << uint16(iCoordY);                              // GROUP_UPDATE_FLAG_POSITION

    uint64 auramask = 0;
    size_t maskPos = data.wpos();
    data << uint64(auramask);                               // placeholder
    for(uint8 i = 0; i < MAX_AURAS; ++i)
    {
        if(uint32 aura = player->GetVisibleAura(i))
        {
            auramask |= (uint64(1) << i);
            data << uint32(aura);
            data << uint8(1);
        }
    }
    data.put<uint64>(maskPos, auramask);                    // GROUP_UPDATE_FLAG_AURAS

    if(pet)
    {
        Powers petpowertype = pet->getPowerType();
        data << pet->GetObjectGuid();                       // GROUP_UPDATE_FLAG_PET_GUID
        data << pet->GetName();                             // GROUP_UPDATE_FLAG_PET_NAME
        data << uint16(pet->GetDisplayId());                // GROUP_UPDATE_FLAG_PET_MODEL_ID
        data << uint32(pet->GetHealth());                   // GROUP_UPDATE_FLAG_PET_CUR_HP
        data << uint32(pet->GetMaxHealth());                // GROUP_UPDATE_FLAG_PET_MAX_HP
        data << uint8(petpowertype);                        // GROUP_UPDATE_FLAG_PET_POWER_TYPE
        data << uint16(pet->GetPower(petpowertype));        // GROUP_UPDATE_FLAG_PET_CUR_POWER
        data << uint16(pet->GetMaxPower(petpowertype));     // GROUP_UPDATE_FLAG_PET_MAX_POWER

        uint64 petauramask = 0;
        size_t petMaskPos = data.wpos();
        data << uint64(petauramask);                        // placeholder
        for(uint8 i = 0; i < MAX_AURAS; ++i)
        {
            if(uint32 petaura = pet->GetVisibleAura(i))
            {
                petauramask |= (uint64(1) << i);
                data << uint32(petaura);
                data << uint8(1);
            }
        }
        data.put<uint64>(petMaskPos, petauramask);          // GROUP_UPDATE_FLAG_PET_AURAS
        data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
    }
    else
    {
        data << uint8(0);                                   // GROUP_UPDATE_FLAG_PET_NAME
        data << uint64(0);                                  // GROUP_UPDATE_FLAG_PET_AURAS
    }

    SendPacket(&data);
}
    void UpdateAI(const uint32 uiDiff)
    {
        // Return since we have no target
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        // Supreme mode - Causes Kazzak to cast his Shadowbolt every second.
        if (m_uiSupremeTimer < uiDiff && !m_bSupremeMode)
            m_bSupremeMode = true;
        else if (!m_bSupremeMode)
            m_uiSupremeTimer -= uiDiff;

        // Shadowbolt Volley
        if (m_uiShadowVolleyTimer < uiDiff)
        {
            DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOW_VOLLEY);
            if (m_bSupremeMode)
                m_uiShadowVolleyTimer = 1000;
            else
                m_uiShadowVolleyTimer = urand(4000,20000);
        }
        else
            m_uiShadowVolleyTimer -= uiDiff;

        // Cleave
        if (m_uiCleaveTimer < uiDiff)
        {
            DoCastSpellIfCan(m_creature->getVictim(),SPELL_CLEAVE);
            m_uiCleaveTimer = urand(8000,12000);
        }
        else
            m_uiCleaveTimer -= uiDiff;

        // Thunder Clap
        if (m_uiThunderClapTimer < uiDiff)
        {
            DoCastSpellIfCan(m_creature->getVictim(), SPELL_THUNDERCLAP);
            m_uiThunderClapTimer = urand(10000,14000);
        }
        else
            m_uiThunderClapTimer -= uiDiff;

        // Void Bolt
        if (m_uiVoidBoltTimer < uiDiff)
        {
            DoCastSpellIfCan(m_creature->getVictim(), SPELL_VOIDBOLT);
            m_uiVoidBoltTimer = urand(15000,28000);
        }
        else
            m_uiVoidBoltTimer -= uiDiff;

        // Mark of Kazzak
        if (m_uiMarkOfKazzakTimer < uiDiff)
        {
            Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0);
            if (pTarget && pTarget->getPowerType() == POWER_MANA && pTarget->GetPower(POWER_MANA) > 1000)
            {
                DoCastSpellIfCan(pTarget, SPELL_MARK_OF_KAZZAK);
                m_uiMarkOfKazzakTimer = 20000;
            }
        }
        else
            m_uiMarkOfKazzakTimer -= uiDiff;

        // Mark of Kazzak - Explode the target when does not have more mana
        ThreatList const& tMarkList = m_creature->getThreatManager().getThreatList();
        for (ThreatList::const_iterator iter = tMarkList.begin(); iter != tMarkList.end(); ++iter)
        {
            Unit* pMarked = m_creature->GetMap()->GetUnit((*iter)->getUnitGuid());
            if (pMarked && pMarked->HasAura(SPELL_MARK_OF_KAZZAK, EFFECT_INDEX_0) && pMarked->GetPower(POWER_MANA) < 250)
            {
                pMarked->RemoveAurasDueToSpell(SPELL_MARK_OF_KAZZAK);
                pMarked->CastSpell(pMarked, SPELL_MARK_OF_KAZZAK_EXP, false);
                break;
            }
        }

        // Twisted Reflection
        if (m_uiTwistedReflectionTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                DoCastSpellIfCan(pTarget, SPELL_TWISTEDREFLECTION);

            m_uiTwistedReflectionTimer = 15000;
        }
        else
            m_uiTwistedReflectionTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }
Example #16
0
    void UpdateAI(const uint32 diff)
    {
        //Return since we have no target
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        //ShadowVolley_Timer
        if (ShadowVolley_Timer < diff)
        {
            DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOWVOLLEY);
            ShadowVolley_Timer = urand(4000, 6000);
        }else ShadowVolley_Timer -= diff;

        //Cleave_Timer
        if (Cleave_Timer < diff)
        {
            DoCastSpellIfCan(m_creature->getVictim(),SPELL_CLEAVE);
            Cleave_Timer = urand(8000, 12000);
        }else Cleave_Timer -= diff;

        //ThunderClap_Timer
        if (ThunderClap_Timer < diff)
        {
            DoCastSpellIfCan(m_creature->getVictim(),SPELL_THUNDERCLAP);
            ThunderClap_Timer = urand(10000, 14000);
        }else ThunderClap_Timer -= diff;

        //VoidBolt_Timer
        if (VoidBolt_Timer < diff)
        {
            DoCastSpellIfCan(m_creature->getVictim(),SPELL_VOIDBOLT);
            VoidBolt_Timer = urand(15000, 18000);
        }else VoidBolt_Timer -= diff;

        //MarkOfKazzak_Timer
        if (MarkOfKazzak_Timer < diff)
        {
            Unit* victim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0);
            if (victim->GetPower(POWER_MANA))
            {
                DoCastSpellIfCan(victim, SPELL_MARKOFKAZZAK);
                MarkOfKazzak_Timer = 20000;
            }
        }else MarkOfKazzak_Timer -= diff;

        //Enrage_Timer
        if (Enrage_Timer < diff)
        {
            DoScriptText(EMOTE_GENERIC_FRENZY, m_creature);
            DoCastSpellIfCan(m_creature,SPELL_ENRAGE);
            Enrage_Timer = 30000;
        }else Enrage_Timer -= diff;

        if (Twisted_Reflection_Timer < diff)
        {
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                DoCastSpellIfCan(pTarget, SPELL_TWISTEDREFLECTION);

            Twisted_Reflection_Timer = 15000;
        }else Twisted_Reflection_Timer -= diff;

        DoMeleeAttackIfReady();
    }
Example #17
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (!m_pInstance || m_pInstance->GetData(TYPE_KELTHUZAD) != IN_PROGRESS)
            return;

        if (m_uiPhase == PHASE_INTRO)
        {
            if (m_uiIntroPackCount < 7)
            {
                if (m_uiSummonIntroTimer < uiDiff)
                {
                    if (!m_uiIntroPackCount)
                        DoScriptText(SAY_SUMMON_MINIONS, m_creature);

                    SummonIntroCreatures(m_uiIntroPackCount);
                    ++m_uiIntroPackCount;
                    m_uiSummonIntroTimer = 2000;
                }
                else
                    m_uiSummonIntroTimer -= uiDiff;
            }
            else
            {
                if (m_uiPhase1Timer < uiDiff)
                {
                    m_uiPhase = PHASE_NORMAL;
                    DespawnIntroCreatures();

                    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    SetCombatMovement(true);
                    m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());

                    DoScriptText(EMOTE_PHASE2, m_creature);

                    switch(urand(0, 2))
                    {
                        case 0: DoScriptText(SAY_AGGRO1, m_creature); break;
                        case 1: DoScriptText(SAY_AGGRO2, m_creature); break;
                        case 2: DoScriptText(SAY_AGGRO3, m_creature); break;
                    };
                }
                else
                    m_uiPhase1Timer -= uiDiff;

                if (m_uiSoldierCount < MAX_SOLDIER_COUNT)
                {
                    if (m_uiSoldierTimer < uiDiff)
                    {
                        SummonMob(NPC_SOLDIER_FROZEN);
                        ++m_uiSoldierCount;
                        m_uiSoldierTimer = 3000;
                    }
                    else
                        m_uiSoldierTimer -= uiDiff;
                }

                if (m_uiAbominationCount < MAX_ABOMINATION_COUNT)
                {
                    if (m_uiAbominationTimer < uiDiff)
                    {
                        SummonMob(NPC_UNSTOPPABLE_ABOM);
                        ++m_uiAbominationCount;
                        m_uiAbominationTimer = 25000;
                    }
                    else
                        m_uiAbominationTimer -= uiDiff;
                }

                if (m_uiBansheeCount < MAX_BANSHEE_COUNT)
                {
                    if (m_uiBansheeTimer < uiDiff)
                    {
                        SummonMob(NPC_SOUL_WEAVER);
                        ++m_uiBansheeCount;
                        m_uiBansheeTimer = 25000;
                    }
                    else
                        m_uiBansheeTimer -= uiDiff;
                }
            }
        }
        else // normal or guardian phase
        {
            if (m_uiFrostBoltTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FROST_BOLT : SPELL_FROST_BOLT_H) == CAST_OK)
                    m_uiFrostBoltTimer = urand(1000, 60000);
            }
            else
                m_uiFrostBoltTimer -= uiDiff;

            if (m_uiFrostBoltNovaTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FROST_BOLT_NOVA : SPELL_FROST_BOLT_NOVA_H) == CAST_OK)
                    m_uiFrostBoltNovaTimer = 15000;
            }
            else
                m_uiFrostBoltNovaTimer -= uiDiff;
               
            if (m_uiManaDetonationTimer < uiDiff)
            {
                Unit* pTarget;
                uint8 counter = 0;
                do
                {
                    counter++;
                    if (counter >= 25)
                    {
                        break;
                        pTarget = NULL;
                    }
                    else
                        pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0);
                }
                while(pTarget->getPowerType() != POWER_MANA);

                if (pTarget)
                {
                    if (DoCastSpellIfCan(pTarget, SPELL_MANA_DETONATION) == CAST_OK)
                    {
                        if (urand(0, 1))
                            DoScriptText(SAY_SPECIAL1_MANA_DET, m_creature);

                        m_uiManaDetonationTargetGUID = pTarget->GetGUID();
                        m_uiManaDetonationMana = m_bIsRegularMode ? urand(2500,4000) : urand(3500,5500);
                        uint32 newMana = pTarget->GetPower(POWER_MANA) - m_uiManaDetonationMana; 
                        uint32 mana = newMana < 0 ? 0 : newMana;
                        m_uiManaDetonationMana *= 1+(urand(2,m_bIsRegularMode?5:9)/10.f); // random increase damage output, not blizzlike
                        pTarget->SetPower(POWER_MANA, mana);
                        
                        m_uiManaDetonationTimer = 20000;
                        m_uiManaDetonationEndTimer = 5000;
                        m_bManaDetonationActive = true;
                    }
                }
            }
            else
                m_uiManaDetonationTimer -= uiDiff;

            if (m_bManaDetonationActive)
                if (m_uiManaDetonationEndTimer < uiDiff)
                {
                    if (Player* pTarget = m_creature->GetMap()->GetPlayer(m_uiManaDetonationTargetGUID))
                    {
                        Map *map = m_creature->GetMap();
                        Map::PlayerList const &PlayerList = map->GetPlayers();
                        if (!PlayerList.isEmpty())
                            for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                            {
                                if(i->getSource()->isDead() || i->getSource() == pTarget || i->getSource()->isGameMaster()) // no dmg on dead, self and GMs
                                    continue;
                                if (pTarget->GetDistance2d(i->getSource()) < 15.f)
                                    i->getSource()->DealDamage(i->getSource(), m_uiManaDetonationMana, NULL, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, NULL, true);
                            }
                    }
                    m_bManaDetonationActive = false;
                }
                else
                    m_uiManaDetonationEndTimer -= uiDiff;

            
            if (m_uiShadowFissureTimer < uiDiff)
            {
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    if(DoCastSpellIfCan(pTarget, SPELL_SHADOW_FISSURE) == CAST_OK)
                    {
                        m_fFissureX = pTarget->GetPositionX();
                        m_fFissureY = pTarget->GetPositionY();

                        if (urand(0, 1))
                            DoScriptText(SAY_SPECIAL3_MANA_DET, m_creature);

                        m_uiShadowFissureTimer = 25000;
                        m_uiShadowFissureActiveTimer = 5000;
                        m_bShadowFissureActive = true;
                    }
            }
            else
                m_uiShadowFissureTimer -= uiDiff;

            if(m_bShadowFissureActive)
                if(m_uiShadowFissureActiveTimer < uiDiff)
                {   
                    // hack for shadow fissure damage, shadow fissure spell does not give damage to players
                    Map::PlayerList const& pPlayers = m_creature->GetMap()->GetPlayers();
                    if (!pPlayers.isEmpty())
                        for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr)
                            if(itr->getSource() && !itr->getSource()->isGameMaster() && (itr->getSource()->GetDistance2d(m_fFissureX,m_fFissureY) < 4.0f))
                                m_creature->DealDamage(itr->getSource(),itr->getSource()->GetHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                    m_bShadowFissureActive = false;
                }
                else 
                    m_uiShadowFissureActiveTimer -= uiDiff;

            if (m_uiFrostBlastTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0), SPELL_FROST_BLAST) == CAST_OK)
                {
                    if (urand(0, 1))
                        DoScriptText(SAY_FROST_BLAST, m_creature);

                    m_uiFrostBlastTimer = urand(30000, 60000);
                }
            }
            else
                m_uiFrostBlastTimer -= uiDiff;
                
            if (!m_bIsRegularMode)
            {
                if (m_uiChainsTimer < uiDiff)
                {
                    m_lChainsTargets.clear();
                    if (SpellEntry* TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_CHAINS_OF_KELTHUZAD_TARGET))
                    {
                        TempSpell->EffectApplyAuraName[0]=SPELL_AURA_MOD_CHARM;
                        uint8 uiChainsTargetsCount = 0;
                        for (uint8 i=0; i<25; ++i)
                        {
                            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                            {
                                if (pTarget->GetTypeId() == TYPEID_PLAYER && !pTarget->HasAura(SPELL_CHAINS_OF_KELTHUZAD_TARGET, EFFECT_INDEX_0))
                                {
                                    m_creature->InterruptNonMeleeSpells(false);
                                    m_creature->CastCustomSpell(pTarget, TempSpell, NULL, NULL, NULL, true);
                                    ((Player*)pTarget)->SetClientControl(pTarget, 0);
                                    m_lChainsTargets.insert(pTarget->GetGUID());
                                    pTarget->setFaction(14);
                                    ++uiChainsTargetsCount;
                                }
                                if (uiChainsTargetsCount>=3)
                                    break;
                            }
                        }
                        m_uiChainsEndTimer = 20000;
                        m_uiChainsTargetsCastTimer = 3500;
                        DoResetThreat();
                    }
                
                    //DoCastSpellIfCan(pTarget, SPELL_CHAINS_OF_KELTHUZAD);
                    DoScriptText(urand(0, 1) ? SAY_CHAIN1 : SAY_CHAIN2, m_creature);
                    m_uiChainsTimer = urand(60000, 90000);
                }
                else
                    m_uiChainsTimer -= uiDiff;

                if (!m_lChainsTargets.empty())
                {
                    if (m_uiChainsTargetsCastTimer < uiDiff)
                    {
                        for (std::set<uint64>::iterator itr = m_lChainsTargets.begin(); itr != m_lChainsTargets.end(); ++itr)
                            if (Unit* pUnit = m_creature->GetMap()->GetUnit(*itr))
                            {
                                if (pUnit->isDead())
                                    continue;
                            
                                if (pUnit->getClass() == CLASS_PRIEST || pUnit->getClass() == CLASS_SHAMAN ||  pUnit->getClass() == CLASS_MAGE ||
                                    pUnit->getClass() == CLASS_WARLOCK) // healer classes heal kelthuzad
                                {
                                    int32 amount = urand(11000,19000);
                                    pUnit->CastCustomSpell(m_creature, 36983, &amount, NULL, NULL, false);
                                }
                                else // other classes melee players
                                    if (Unit* pVictim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
                                    {
                                        pUnit->GetMotionMaster()->MoveChase(pVictim);
                                        pUnit->Attack(pVictim,true);
                                    }
                            }
                        m_uiChainsTargetsCastTimer = 4500;
                    }
                    else
                        m_uiChainsTargetsCastTimer -= uiDiff;

                    if (m_uiChainsEndTimer < uiDiff)
                    {
                        for(std::set<uint64>::iterator itr = m_lChainsTargets.begin(); itr != m_lChainsTargets.end(); ++itr)
                            if (Player* pPlayer = m_creature->GetMap()->GetPlayer(*itr))
                            {
                                pPlayer->setFactionForRace(pPlayer->getRace());
                                pPlayer->SetClientControl(pPlayer, 1);
                            }
                        m_lChainsTargets.clear();
                    }
                    else
                        m_uiChainsEndTimer -= uiDiff;
                }
            }

            if (m_uiPhase == PHASE_NORMAL)
            {
                if (m_creature->GetHealthPercent() < 45.0f)
                {
                    m_uiPhase = PHASE_GUARDIANS;
                    DoScriptText(SAY_REQUEST_AID, m_creature);

                    // here Lich King should respond to Kel'Thuzad but I don't know which creature to make talk
                    // so for now just make Kel'Thuzad says it.
                    DoScriptText(SAY_ANSWER_REQUEST, m_creature);
                }
            }
            else if (m_uiPhase == PHASE_GUARDIANS && m_uiGuardiansCount < m_uiGuardiansCountMax)
            {
                if (m_uiGuardiansTimer < uiDiff)
                {
                    // Summon a Guardian of Icecrown in a random alcove
                    SummonMob(NPC_GUARDIAN);
                    m_uiGuardiansTimer = 5000;
                }
                else
                    m_uiGuardiansTimer -= uiDiff;
            }

            DoMeleeAttackIfReady();
        }
    }