Example #1
1
void TotemAI::UpdateAI(const uint32 /*diff*/)
{
    if (i_totem.GetTotemType() != TOTEM_ACTIVE)
        return;

    i_totem.SetSelection(0);

    if (!i_totem.isAlive() || i_totem.IsNonMeleeSpellCasted(false))
        return;

    // Search spell
    SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_totem.GetSpell());
    if (!spellInfo)
        return;

    // Get spell rangy
    SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
    float max_range = SpellMgr::GetSpellMaxRange(srange);

    // SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems

    // pointer to appropriate target if found any
    Unit* victim = i_victimGuid ? i_totem.GetMap()->GetUnit(i_victimGuid) : NULL;

    if (!max_range)
        victim = &i_totem;

    // Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
    if (!victim || (!SpellMgr::SpellIgnoreLOS(spellInfo, 0) && !i_totem.IsWithinLOSInMap(victim)) ||
            !victim->isTargetableForAttack() || !i_totem.IsWithinDistInMap(victim, max_range) ||
            (i_totem.IsFriendlyTo(victim) && victim != &i_totem) || !victim->isVisibleForOrDetect(&i_totem, &i_totem, false))
    {
        victim = NULL;

        Looking4group::NearestAttackableUnitInObjectRangeCheck u_check(&i_totem, &i_totem, max_range);
        Looking4group::UnitLastSearcher<Looking4group::NearestAttackableUnitInObjectRangeCheck> checker(victim, u_check);

        Cell::VisitAllObjects(m_creature, checker, max_range);
    }

    // If have target
    if (victim)
    {
        //this should prevent target-type totems from attacking from unattackable zones and attacking while being unattackable
        if ((i_totem.isInSanctuary() || victim->isInSanctuary()) && victim->GetCharmerOrOwnerPlayerOrPlayerItself())
            return;
        // remember
        i_victimGuid = victim->GetGUID();

        // attack
        i_totem.CastSpell(victim, i_totem.GetSpell(), false, NULL, NULL, i_totem.GetOwner()->GetGUID());
    }
    else
        i_victimGuid = 0;

    //i_totem.SetFacingToObject(&i_totem);
}
Example #2
1
        void HandleForceCast(SpellEffIndex effIndex)
        {
            PreventHitDefaultEffect(effIndex);

            Unit* caster = GetCaster();
            Unit* target = GetHitUnit();

            uint32 triggered_spell_id = GetSpellInfo()->Effects[effIndex].TriggerSpell;

            if (caster && target)
                target->CastSpell(target, triggered_spell_id, true, NULL, NULL, caster->GetGUID());
        }
Example #3
1
 void HandleDummy(SpellEffIndex /* effIndex */)
 {
     Unit* caster = GetCaster();
     if (Unit* target = GetHitUnit())
     {
         uint32 count = target->GetDiseasesByCaster(caster->GetGUID());
         int32 bp = int32(count * caster->CountPctFromMaxHealth(int32(GetSpellInfo()->Effects[EFFECT_0].DamageMultiplier)));
         // Improved Death Strike
         if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_DEATHKNIGHT, ICON_ID_IMPROVED_DEATH_STRIKE, 0))
             AddPctN(bp, caster->CalculateSpellDamage(caster, aurEff->GetSpellInfo(), 2));
         caster->CastCustomSpell(caster, SPELL_DEATH_STRIKE_HEAL, &bp, NULL, NULL, false);
     }
 }
Example #4
1
void PetAI::UpdateAllies()
{
    Unit* owner = me->GetCharmerOrOwner();
    Group* group = NULL;

    m_updateAlliesTimer = 10*IN_MILLISECONDS;                //update friendly targets every 10 seconds, lesser checks increase performance

    if (!owner)
        return;
    else if (owner->GetTypeId() == TYPEID_PLAYER)
        group = owner->ToPlayer()->GetGroup();

    //only pet and owner/not in group->ok
    if (m_AllySet.size() == 2 && !group)
        return;
    //owner is in group; group members filled in already (no raid -> subgroupcount = whole count)
    if (group && !group->isRaidGroup() && m_AllySet.size() == (group->GetMembersCount() + 2))
        return;

    m_AllySet.clear();
    m_AllySet.insert(me->GetGUID());
    if (group)                                              //add group
    {
        for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
        {
            Player* Target = itr->getSource();
            if (!Target || !group->SameSubGroup((Player*)owner, Target))
                continue;

            if (Target->GetGUID() == owner->GetGUID())
                continue;

            m_AllySet.insert(Target->GetGUID());
        }
    }
    else                                                    //remove group
        m_AllySet.insert(owner->GetGUID());
}
Example #5
1
 void JustDied(Unit* killer)
 {
     if (HasEscortState(STATE_ESCORT_ESCORTING))
     {
         //killer = me when player got to far from creature
         if (killer == me)
         {
             Unit* pTemp = Unit::GetUnit(*me, GetPlayerForEscort()->GetGUID());
             if (pTemp)
                 me->MonsterWhisper(WHISPER_TOO_FAR, pTemp->GetGUID());
         }
         else me->Say(SAY_DIE1, LANG_UNIVERSAL, GetPlayerForEscort()->GetGUID());
     }
     else me->Say(SAY_DIE2, LANG_UNIVERSAL, 0);
 }
Example #6
1
void
TotemAI::UpdateAI(const uint32 /*diff*/)
{
    if (me->ToTotem()->GetTotemType() != TOTEM_ACTIVE)
        return;

    if (!me->isAlive() || me->IsNonMeleeSpellCasted(false))
        return;

    // Search spell
    SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(me->ToTotem()->GetSpell());
    if (!spellInfo)
        return;

    // Get spell range
    float max_range = spellInfo->GetMaxRange(false);

    // SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems

    // pointer to appropriate target if found any
    Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(*me, i_victimGuid) : NULL;

    // Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
    if (!victim ||
            !victim->isTargetableForAttack() || !me->IsWithinDistInMap(victim, max_range) ||
            me->IsFriendlyTo(victim) || !me->canSeeOrDetect(victim))
    {
        victim = NULL;
        Skyfire::NearestAttackableUnitInObjectRangeCheck u_check(me, me, max_range);
        Skyfire::UnitLastSearcher<Skyfire::NearestAttackableUnitInObjectRangeCheck> checker(me, victim, u_check);
        me->VisitNearbyObject(max_range, checker);
    }

    // If have target
    if (victim)
    {
        // remember
        i_victimGuid = victim->GetGUID();

        // attack
        me->SetInFront(victim);                         // client change orientation by self
        me->CastSpell(victim, me->ToTotem()->GetSpell(), false);
    }
    else
        i_victimGuid = 0;
}
Example #7
1
/*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 << uint64(pet->GetGUID());                     // 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 #8
1
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)
    {
        if(pet)
            *data << uint64(pet->GetGUID());
        else
            *data << uint64(0);
    }

    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 #9
1
    void UpdateAI(const uint32 diff)
    {
        //Check if we have a target
        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
            return;

        //No instance
        if (!pInst)
            return;

        switch (pInst->GetData(DATA_CTHUN_PHASE))
        {
        case 0:
        {
            //BeamTimer
            if (BeamTimer < diff)
            {
                //SPELL_GREEN_BEAM
                Unit* target = NULL;
                target = SelectUnit(SELECT_TARGET_RANDOM,0);
                if (target)
                {
                    m_creature->InterruptNonMeleeSpells(false);
                    DoCast(target,SPELL_GREEN_BEAM);

                    //Correctly update our target
                    m_creature->SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID());
                }

                //Beam every 3 seconds
                BeamTimer = 3000;
            } else BeamTimer -= diff;

            //ClawTentacleTimer
            if (ClawTentacleTimer < diff)
            {
                Unit* target = NULL;
                target = SelectUnit(SELECT_TARGET_RANDOM,0);
                if (target)
                {
                    Creature* Spawned = NULL;

                    //Spawn claw tentacle on the random target
                    Spawned = (Creature*)m_creature->SummonCreature(MOB_CLAW_TENTACLE,target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,500);

                    if (Spawned)
                        Spawned->AI()->AttackStart(target);
                }

                //One claw tentacle every 12.5 seconds
                ClawTentacleTimer = 12500;
            } else ClawTentacleTimer -= diff;

            //EyeTentacleTimer
            if (EyeTentacleTimer < diff)
            {
                //Spawn the 8 Eye Tentacles in the corret spots
                SpawnEyeTentacle(0, 20);                //south
                SpawnEyeTentacle(10, 10);               //south west
                SpawnEyeTentacle(20, 0);                //west
                SpawnEyeTentacle(10, -10);              //north west

                SpawnEyeTentacle(0, -20);               //north
                SpawnEyeTentacle(-10, -10);             //north east
                SpawnEyeTentacle(-20, 0);               // east
                SpawnEyeTentacle(-10, 10);              // south east

                //No point actually putting a timer here since
                //These shouldn't trigger agian until after phase shifts
                EyeTentacleTimer = 45000;
            } else EyeTentacleTimer -= diff;

            //PhaseTimer
            if (PhaseTimer < diff)
            {
                //Switch to Dark Beam
                pInst->SetData(DATA_CTHUN_PHASE, 1);

                m_creature->InterruptNonMeleeSpells(false);

                //Select random target for dark beam to start on
                Unit* target = NULL;
                target = SelectUnit(SELECT_TARGET_RANDOM,0);

                if (target)
                {
                    //Correctly update our target
                    m_creature->SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID());

                    //Face our target
                    DarkGlareAngle = m_creature->GetAngle(target);
                    DarkGlareTickTimer = 1000;
                    DarkGlareTick = 0;
                    ClockWise = rand()%2;
                }

                //Add red coloration to C'thun
                DoCast(m_creature,SPELL_RED_COLORATION);

                //Freeze animation
                m_creature->setEmoteState(53);

                //Darkbeam for 35 seconds
                PhaseTimer = 35000;
            } else PhaseTimer -= diff;

        }
        break;
        case 1:
        {
            //EyeTentacleTimer
            if (DarkGlareTick < 35)
                if (DarkGlareTickTimer < diff)
                {
                    //Remove any target
                    m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);

                    //Set angle and cast
                    if (ClockWise)
                        m_creature->SetOrientation(DarkGlareAngle + ((float)DarkGlareTick*PI/35));
                    else m_creature->SetOrientation(DarkGlareAngle - ((float)DarkGlareTick*PI/35));

                    m_creature->StopMoving();

                    //Actual dark glare cast, maybe something missing here?
                    m_creature->CastSpell(m_creature, SPELL_DARK_GLARE, false);

                    //Increase tick
                    DarkGlareTick++;

                    //1 second per tick
                    DarkGlareTickTimer = 1000;
                } else DarkGlareTickTimer -= diff;

            //PhaseTimer
            if (PhaseTimer < diff)
            {
                //Switch to Eye Beam
                pInst->SetData(DATA_CTHUN_PHASE, 0);

                BeamTimer = 3000;
                EyeTentacleTimer = 45000;               //Always spawns 5 seconds before Dark Beam
                ClawTentacleTimer = 12500;              //4 per Eye beam phase (unsure if they spawn durring Dark beam)

                m_creature->InterruptNonMeleeSpells(false);

                //Remove Red coloration from c'thun
                m_creature->RemoveAurasDueToSpell(SPELL_RED_COLORATION);

                //Freeze animation
                m_creature->setEmoteState(0);
                m_creature->SetUInt32Value(UNIT_FIELD_FLAGS, 0);

                //Eye Beam for 50 seconds
                PhaseTimer = 50000;
            } else PhaseTimer -= diff;
        }
        break;

        //Transition phase
        case 2:
        {
            //Remove any target
            m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
            m_creature->SetHealth(0);
        }

        //Dead phase
        case 5:
        {
            m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NONE, NULL, false);
        }
        }
    }
Example #10
1
void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 eventId, Unit* actionInvoker)
{
    switch (action.type)
    {
    case ACTION_T_TEXT:
    {
        if (!action.text.TextId1)
            return;

        int32 temp = action.text.TextId1;

        if (action.text.TextId2 && action.text.TextId3)
            temp = RAND(action.text.TextId1, action.text.TextId2, action.text.TextId3);
        else if (action.text.TextId2 && urand(0, 1))
            temp = action.text.TextId2;

        if (temp)
        {
            Unit* target = NULL;

            if (actionInvoker)
            {
                if (actionInvoker->GetTypeId() == TYPEID_PLAYER)
                    target = actionInvoker;
                else if (Unit* owner = actionInvoker->GetOwner())
                {
                    if (owner->GetTypeId() == TYPEID_PLAYER)
                        target = owner;
                }
            }
            else
            {
                target = me->getVictim();
                if (target && target->GetTypeId() != TYPEID_PLAYER)
                    if (Unit* owner = target->GetOwner())
                        if (owner->GetTypeId() == TYPEID_PLAYER)
                            target = owner;
            }

            DoScriptText(temp, me, target);
        }
        break;
    }
    case ACTION_T_SET_FACTION:
    {
        if (action.set_faction.factionId)
            me->setFaction(action.set_faction.factionId);
        else
        {
            if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(me->GetEntry()))
            {
                //if no id provided, assume reset and then use default
                if (me->getFaction() != ci->faction_A)
                    me->setFaction(ci->faction_A);
            }
        }
        break;
    }
    case ACTION_T_MORPH_TO_ENTRY_OR_MODEL:
    {
        if (action.morph.creatureId || action.morph.modelId)
        {
            //set model based on entry from creature_template
            if (action.morph.creatureId)
            {
                if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(action.morph.creatureId))
                {
                    uint32 display_id = sObjectMgr->ChooseDisplayId(0, ci);
                    me->SetDisplayId(display_id);
                }
            }
            //if no param1, then use value from param2 (modelId)
            else
                me->SetDisplayId(action.morph.modelId);
        }
        else
            me->DeMorph();
        break;
    }
    case ACTION_T_SOUND:
        me->PlayDirectSound(action.sound.soundId);
        break;
    case ACTION_T_EMOTE:
        me->HandleEmoteCommand(action.emote.emoteId);
        break;
    case ACTION_T_RANDOM_SOUND:
    {
        int32 temp = GetRandActionParam(rnd, action.random_sound.soundId1, action.random_sound.soundId2, action.random_sound.soundId3);
        if (temp >= 0)
            me->PlayDirectSound(temp);
        break;
    }
    case ACTION_T_RANDOM_EMOTE:
    {
        int32 temp = GetRandActionParam(rnd, action.random_emote.emoteId1, action.random_emote.emoteId2, action.random_emote.emoteId3);
        if (temp >= 0)
            me->HandleEmoteCommand(temp);
        break;
    }
    case ACTION_T_CAST:
    {
        Unit* target = GetTargetByType(action.cast.target, actionInvoker);
        Unit* caster = me;

        if (!target)
            return;

        if (action.cast.castFlags & CAST_FORCE_TARGET_SELF)
            caster = target;

        //Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered
        bool canCast = !caster->IsNonMeleeSpellCasted(false) || (action.cast.castFlags & (CAST_TRIGGERED | CAST_INTERRUPT_PREVIOUS));

        // If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them
        if (action.cast.castFlags & CAST_AURA_NOT_PRESENT)
        {
            if (target->HasAura(action.cast.spellId))
                return;
        }

        if (canCast)
        {
            const SpellInfo* tSpell = sSpellMgr->GetSpellInfo(action.cast.spellId);

            //Verify that spell exists
            if (tSpell)
            {
                //Check if cannot cast spell
                if (!(action.cast.castFlags & (CAST_FORCE_TARGET_SELF | CAST_FORCE_CAST)) &&
                        !CanCast(target, tSpell, (action.cast.castFlags & CAST_TRIGGERED)))
                {
                    //Melee current victim if flag not set
                    switch(me->GetMotionMaster()->GetCurrentMovementGeneratorType())
                    {
                    case CHASE_MOTION_TYPE:
                    case FOLLOW_MOTION_TYPE:
                        m_AttackDistance = 0.0f;
                        m_AttackAngle = 0.0f;

                        me->GetMotionMaster()->Clear(false);
                        break;
                    }
                }
                else
                {
                    //Interrupt any previous spell
                    if (caster->IsNonMeleeSpellCasted(false) && action.cast.castFlags & CAST_INTERRUPT_PREVIOUS)
                        caster->InterruptNonMeleeSpells(false);

                    caster->CastSpell(target, action.cast.spellId, (action.cast.castFlags & CAST_TRIGGERED));
                }
            }
            else
                sLog->outErrorDb("CreatureEventAI: event %d creature %d attempt to cast spell that doesn't exist %d", eventId, me->GetEntry(), action.cast.spellId);
        }
        break;
    }
    case ACTION_T_SUMMON:
    {
        Unit* target = GetTargetByType(action.summon.target, actionInvoker);

        Creature* creature = NULL;

        if (action.summon.duration)
            creature = me->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, action.summon.duration);
        else
            creature = me->SummonCreature(action.summon.creatureId, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);

        if (!creature)
            sLog->outErrorDb("CreatureEventAI: failed to spawn creature %u. Spawn event %d is on creature %d", action.summon.creatureId, eventId, me->GetEntry());
        else if (action.summon.target != TARGET_T_SELF && target)
            creature->AI()->AttackStart(target);
        break;
    }
    case ACTION_T_THREAT_SINGLE_PCT:
        if (Unit* target = GetTargetByType(action.threat_single_pct.target, actionInvoker))
            me->getThreatManager().modifyThreatPercent(target, action.threat_single_pct.percent);
        break;
    case ACTION_T_THREAT_ALL_PCT:
    {
        std::list<HostileReference*>& threatList = me->getThreatManager().getThreatList();
        for (std::list<HostileReference*>::iterator i = threatList.begin(); i != threatList.end(); ++i)
            if (Unit* Temp = Unit::GetUnit(*me, (*i)->getUnitGuid()))
                me->getThreatManager().modifyThreatPercent(Temp, action.threat_all_pct.percent);
        break;
    }
    case ACTION_T_QUEST_EVENT:
        if (Unit* target = GetTargetByType(action.quest_event.target, actionInvoker))
            if (target->GetTypeId() == TYPEID_PLAYER)
                target->ToPlayer()->AreaExploredOrEventHappens(action.quest_event.questId);
        break;
    case ACTION_T_CAST_EVENT:
        if (Unit* target = GetTargetByType(action.cast_event.target, actionInvoker))
            if (target->GetTypeId() == TYPEID_PLAYER)
                target->ToPlayer()->CastedCreatureOrGO(action.cast_event.creatureId, me->GetGUID(), action.cast_event.spellId);
        break;
    case ACTION_T_SET_UNIT_FIELD:
    {
        Unit* target = GetTargetByType(action.set_unit_field.target, actionInvoker);

        // not allow modify important for integrity object fields
        if (action.set_unit_field.field < OBJECT_END || action.set_unit_field.field >= UNIT_END)
            return;

        if (target)
            target->SetUInt32Value(action.set_unit_field.field, action.set_unit_field.value);

        break;
    }
    case ACTION_T_SET_UNIT_FLAG:
        if (Unit* target = GetTargetByType(action.unit_flag.target, actionInvoker))
            target->SetFlag(UNIT_FIELD_FLAGS, action.unit_flag.value);
        break;
    case ACTION_T_REMOVE_UNIT_FLAG:
        if (Unit* target = GetTargetByType(action.unit_flag.target, actionInvoker))
            target->RemoveFlag(UNIT_FIELD_FLAGS, action.unit_flag.value);
        break;
    case ACTION_T_AUTO_ATTACK:
        m_MeleeEnabled = action.auto_attack.state != 0;
        break;
    case ACTION_T_COMBAT_MOVEMENT:
        // ignore no affect case
        if (m_CombatMovementEnabled == (action.combat_movement.state != 0))
            return;

        m_CombatMovementEnabled = action.combat_movement.state != 0;

        //Allow movement (create new targeted movement gen only if idle)
        if (m_CombatMovementEnabled)
        {
            Unit* victim = me->getVictim();
            if (me->isInCombat() && victim)
            {
                if (action.combat_movement.melee)
                {
                    me->AddUnitState(UNIT_STATE_MELEE_ATTACKING);
                    me->SendMeleeAttackStart(victim);
                }
                if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == IDLE_MOTION_TYPE)
                    me->GetMotionMaster()->MoveChase(victim, m_AttackDistance, m_AttackAngle); // Targeted movement generator will start melee automatically, no need to send it explicitly
            }
        }
        else
        {
            if (me->isInCombat())
            {
                Unit* victim = me->getVictim();
                if (action.combat_movement.melee && victim)
                {
                    me->ClearUnitState(UNIT_STATE_MELEE_ATTACKING);
                    me->SendMeleeAttackStop(victim);
                }
                if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
                    me->GetMotionMaster()->MoveIdle();
            }
        }
        break;
    case ACTION_T_SET_PHASE:
        m_Phase = action.set_phase.phase;
        break;
    case ACTION_T_INC_PHASE:
    {
        int32 new_phase = int32(m_Phase)+action.set_inc_phase.step;
        if (new_phase < 0)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d decrease m_Phase under 0. CreatureEntry = %d", eventId, me->GetEntry());
            m_Phase = 0;
        }
        else if (new_phase >= MAX_PHASE)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d incremented m_Phase above %u. m_Phase mask cannot be used with phases past %u. CreatureEntry = %d", eventId, MAX_PHASE-1, MAX_PHASE-1, me->GetEntry());
            m_Phase = MAX_PHASE-1;
        }
        else
            m_Phase = new_phase;

        break;
    }
    case ACTION_T_EVADE:
        EnterEvadeMode();
        break;
    case ACTION_T_FLEE_FOR_ASSIST:
        me->DoFleeToGetAssistance();
        break;
    case ACTION_T_QUEST_EVENT_ALL:
        if (actionInvoker && actionInvoker->GetTypeId() == TYPEID_PLAYER)
        {
            if (Unit* Temp = Unit::GetUnit(*me, actionInvoker->GetGUID()))
                if (Temp->GetTypeId() == TYPEID_PLAYER)
                    Temp->ToPlayer()->GroupEventHappens(action.quest_event_all.questId, me);
        }
        break;
    case ACTION_T_CAST_EVENT_ALL:
    {
        std::list<HostileReference*>& threatList = me->getThreatManager().getThreatList();
        for (std::list<HostileReference*>::iterator i = threatList.begin(); i != threatList.end(); ++i)
            if (Unit* Temp = Unit::GetUnit(*me, (*i)->getUnitGuid()))
                if (Temp->GetTypeId() == TYPEID_PLAYER)
                    Temp->ToPlayer()->CastedCreatureOrGO(action.cast_event_all.creatureId, me->GetGUID(), action.cast_event_all.spellId);
        break;
    }
    case ACTION_T_REMOVEAURASFROMSPELL:
        if (Unit* target = GetTargetByType(action.remove_aura.target, actionInvoker))
            target->RemoveAurasDueToSpell(action.remove_aura.spellId);
        break;
    case ACTION_T_RANGED_MOVEMENT:
        m_AttackDistance = (float)action.ranged_movement.distance;
        m_AttackAngle = action.ranged_movement.angle/180.0f*M_PI;

        if (m_CombatMovementEnabled)
        {
            me->GetMotionMaster()->MoveChase(me->getVictim(), m_AttackDistance, m_AttackAngle);
        }
        break;
    case ACTION_T_RANDOM_PHASE:
        m_Phase = GetRandActionParam(rnd, action.random_phase.phase1, action.random_phase.phase2, action.random_phase.phase3);
        break;
    case ACTION_T_RANDOM_PHASE_RANGE:
        if (action.random_phase_range.phaseMin <= action.random_phase_range.phaseMax)
            m_Phase = urand(action.random_phase_range.phaseMin, action.random_phase_range.phaseMax);
        else
            sLog->outErrorDb("CreatureEventAI: ACTION_T_RANDOM_PHASE_RANGE cannot have Param2 < Param1. Event = %d. CreatureEntry = %d", eventId, me->GetEntry());
        break;
    case ACTION_T_SUMMON_ID:
    {
        Unit* target = GetTargetByType(action.summon_id.target, actionInvoker);

        CreatureEventAI_Summon_Map::const_iterator i = sEventAIMgr->GetCreatureEventAISummonMap().find(action.summon_id.spawnId);
        if (i == sEventAIMgr->GetCreatureEventAISummonMap().end())
        {
            sLog->outErrorDb("CreatureEventAI: failed to spawn creature %u. Summon map index %u does not exist. EventID %d. CreatureID %d", action.summon_id.creatureId, action.summon_id.spawnId, eventId, me->GetEntry());
            return;
        }

        Creature* creature = NULL;
        if ((*i).second.SpawnTimeSecs)
            creature = me->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, (*i).second.SpawnTimeSecs);
        else
            creature = me->SummonCreature(action.summon_id.creatureId, (*i).second.position_x, (*i).second.position_y, (*i).second.position_z, (*i).second.orientation, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);

        if (!creature)
            sLog->outErrorDb("CreatureEventAI: failed to spawn creature %u. EventId %d.Creature %d", action.summon_id.creatureId, eventId, me->GetEntry());
        else if (action.summon_id.target != TARGET_T_SELF && target)
            creature->AI()->AttackStart(target);

        break;
    }
    case ACTION_T_KILLED_MONSTER:
        //first attempt player who tapped creature
        if (Player* player = me->GetLootRecipient())
            player->RewardPlayerAndGroupAtEvent(action.killed_monster.creatureId, player);    // player as param is a hacky solution not to use GUID
        else
        {
            //if not available, use actionInvoker
            if (Unit* target = GetTargetByType(action.killed_monster.target, actionInvoker))
                if (Player* player2 = target->GetCharmerOrOwnerPlayerOrPlayerItself())
                    player2->RewardPlayerAndGroupAtEvent(action.killed_monster.creatureId, player2);
        }
        break;
    case ACTION_T_SET_INST_DATA:
    {
        InstanceScript* instance = (InstanceScript*)me->GetInstanceScript();
        if (!instance)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d attempt to set instance data without instance script. Creature %d", eventId, me->GetEntry());
            return;
        }

        instance->SetData(action.set_inst_data.field, action.set_inst_data.value);
        break;
    }
    case ACTION_T_SET_INST_DATA64:
    {
        Unit* target = GetTargetByType(action.set_inst_data64.target, actionInvoker);
        if (!target)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 but Target == NULL. Creature %d", eventId, me->GetEntry());
            return;
        }

        InstanceScript* instance = (InstanceScript*)me->GetInstanceScript();
        if (!instance)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d attempt to set instance data64 without instance script. Creature %d", eventId, me->GetEntry());
            return;
        }

        instance->SetData64(action.set_inst_data64.field, target->GetGUID());
        break;
    }
    case ACTION_T_UPDATE_TEMPLATE:
        if (me->GetEntry() == action.update_template.creatureId)
        {
            sLog->outErrorDb("CreatureEventAI: Event %d ACTION_T_UPDATE_TEMPLATE call with param1 == current entry. Creature %d", eventId, me->GetEntry());
            return;
        }

        me->UpdateEntry(action.update_template.creatureId, action.update_template.team ? HORDE : ALLIANCE);
        break;
    case ACTION_T_DIE:
        if (me->isDead())
        {
            sLog->outErrorDb("CreatureEventAI: Event %d ACTION_T_DIE on dead creature. Creature %d", eventId, me->GetEntry());
            return;
        }
        me->Kill(me);
        break;
    case ACTION_T_ZONE_COMBAT_PULSE:
    {
        me->SetInCombatWithZone();
        break;
    }
    case ACTION_T_CALL_FOR_HELP:
    {
        me->CallForHelp((float)action.call_for_help.radius);
        break;
    }
    break;

    case ACTION_T_MOVE_RANDOM_POINT: //dosen't work in combat
    {
        float x, y, z;
        me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, (float)action.raw.param1);
        me->GetMotionMaster()->MovePoint(0, x, y, z);
        break;
    }
    case ACTION_T_SET_STAND_STATE:
        me->SetStandState(UnitStandStateType(action.raw.param1));
        break;
    case ACTION_T_SET_PHASE_MASK:
        me->SetPhaseMask(action.raw.param1, true);
        break;
    case ACTION_T_SET_VISIBILITY:
        me->SetVisible(bool(action.raw.param1));
        break;
    case ACTION_T_SET_ACTIVE:
        me->setActive(action.raw.param1 ? true : false);
        break;
    case ACTION_T_SET_AGGRESSIVE:
        me->SetReactState(ReactStates(action.raw.param1));
        break;
    case ACTION_T_ATTACK_START_PULSE:
        AttackStart(me->SelectNearestTarget((float)action.raw.param1));
        break;
    case ACTION_T_SUMMON_GO:
    {
        GameObject* object = NULL;

        float x, y, z;
        me->GetPosition(x, y, z);
        object = me->SummonGameObject(action.raw.param1, x, y, z, 0, 0, 0, 0, 0, action.raw.param2);
        if (!object)
        {
            sLog->outErrorDb("TSCR: EventAI failed to spawn object %u. Spawn event %d is on creature %d", action.raw.param1, eventId, me->GetEntry());
        }
        break;
    }

    case ACTION_T_SET_SHEATH:
    {
        me->SetSheath(SheathState(action.set_sheath.sheath));
        break;
    }
    case ACTION_T_FORCE_DESPAWN:
    {
        me->DespawnOrUnsummon(action.forced_despawn.msDelay);
        break;
    }
    case ACTION_T_SET_INVINCIBILITY_HP_LEVEL:
    {
        if (action.invincibility_hp_level.is_percent)
            m_InvinceabilityHpLevel = me->CountPctFromMaxHealth(action.invincibility_hp_level.hp_level);
        else
            m_InvinceabilityHpLevel = action.invincibility_hp_level.hp_level;
        break;
    }
    case ACTION_T_MOUNT_TO_ENTRY_OR_MODEL:
    {
        if (action.mount.creatureId || action.mount.modelId)
        {
            // set model based on entry from creature_template
            if (action.mount.creatureId)
            {
                if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(action.mount.creatureId))
                {
                    uint32 display_id = sObjectMgr->ChooseDisplayId(0, cInfo);
                    me->Mount(display_id);
                }
            }
            //if no param1, then use value from param2 (modelId)
            else
                me->Mount(action.mount.modelId);
        }
        else
            me->Dismount();

        break;
    }
    }
}
Example #11
0
    void SelectNearestCrystal()
    {
        if (Crystals.empty())
            return;

        //float ShortestDistance = 0;
        CrystalGUID = 0;
        Unit* pCrystal = NULL;
        Unit* CrystalChosen = NULL;
        //for (uint8 i =  0; i < CRYSTALS_NUMBER; ++i)
        for (std::list<uint64>::const_iterator itr = Crystals.begin(); itr != Crystals.end(); ++itr)
        {
            pCrystal = NULL;
            //pCrystal = Unit::GetUnit(*me, FelCrystals[i]);
            pCrystal = Unit::GetUnit(*me, *itr);
            if (pCrystal && pCrystal->isAlive())
            {
                // select nearest
                if (!CrystalChosen || me->GetDistanceOrder(pCrystal, CrystalChosen, false))
                {
                    CrystalGUID = pCrystal->GetGUID();
                    CrystalChosen = pCrystal;               // Store a copy of pCrystal so we don't need to recreate a pointer to closest crystal for the movement and yell.
                }
            }
        }
        if (CrystalChosen)
        {
            DoScriptText(SAY_ENERGY, me);
            DoScriptText(EMOTE_CRYSTAL, me);

            CrystalChosen->CastSpell(CrystalChosen, SPELL_FEL_CRYSTAL_COSMETIC, true);

            float x, y, z;                                  // coords that we move to, close to the crystal.
            CrystalChosen->GetClosePoint(x, y, z, me->GetObjectSize(), CONTACT_DISTANCE);

            me->RemoveUnitMovementFlag(MOVEFLAG_WALK_MODE);
            me->GetMotionMaster()->MovePoint(1, x, y, z);
            DrainingCrystal = true;
        }
    }
Example #12
0
 void HandleDummy(SpellEffIndex /*effIndex*/)
 {
     Unit* caster = GetCaster();
     if (Unit* unitTarget = GetHitUnit())
     {
         int32 bp = CalculatePctN(GetHitDamage(), GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID()));
         caster->CastCustomSpell(unitTarget, DK_SPELL_SCOURGE_STRIKE_TRIGGERED, &bp, NULL, NULL, true);
     }
 }
Example #13
0
        void UpdateAI(const uint32 uiDiff)
        {
            if (!UpdateVictim())
                return;

            if (!m_bIsPhaseTwo)
            {
                if (m_uiShadowWordPain_Timer <= uiDiff)
                {
                    DoCast(me->getVictim(), SPELL_SHADOWWORDPAIN);
                    m_uiShadowWordPain_Timer = 15000;
                }
                else
                    m_uiShadowWordPain_Timer -= uiDiff;

                if (m_uiMark_Timer <= uiDiff)
                {
                    Unit* pMarkedTarget = SelectTarget(SELECT_TARGET_RANDOM, 0);

                    if (pMarkedTarget)
                    {
                        DoCast(pMarkedTarget, SPELL_MARK);
                        MarkedTargetGUID = pMarkedTarget->GetGUID();
                    }
                    else
                        sLog->outError("TSCR: boss_arlokk could not accuire pMarkedTarget.");

                    m_uiMark_Timer = 15000;
                }
                else
                    m_uiMark_Timer -= uiDiff;
            }
            else
            {
                //Cleave_Timer
                if (m_uiCleave_Timer <= uiDiff)
                {
                    DoCast(me->getVictim(), SPELL_CLEAVE);
                    m_uiCleave_Timer = 16000;
                }
                else
                    m_uiCleave_Timer -= uiDiff;

                //Gouge_Timer
                if (m_uiGouge_Timer <= uiDiff)
                {
                    DoCast(me->getVictim(), SPELL_GOUGE);

                    DoModifyThreatPercent(me->getVictim(), -80);

                    m_uiGouge_Timer = 17000+rand()%10000;
                }
                else
                    m_uiGouge_Timer -= uiDiff;
            }

            if (m_uiSummonCount <= 30)
            {
                if (m_uiSummon_Timer <= uiDiff)
                {
                    DoSummonPhanters();
                    m_uiSummon_Timer = 5000;
                }
                else
                    m_uiSummon_Timer -= uiDiff;
            }

            if (m_uiVanish_Timer <= uiDiff)
            {
                //Invisble Model
                me->SetDisplayId(MODEL_ID_BLANK);
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);

                me->AttackStop();
                DoResetThreat();

                m_bIsVanished = true;

                m_uiVanish_Timer = 45000;
                m_uiVisible_Timer = 6000;
            }
            else
                m_uiVanish_Timer -= uiDiff;

            if (m_bIsVanished)
            {
                if (m_uiVisible_Timer <= uiDiff)
                {
                    //The Panther Model
                    me->SetDisplayId(MODEL_ID_PANTHER);
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);

                    const CreatureTemplate *cinfo = me->GetCreatureInfo();
                    me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35)));
                    me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35)));
                    me->UpdateDamagePhysical(BASE_ATTACK);

                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                        AttackStart(target);

                    m_bIsPhaseTwo = true;
                    m_bIsVanished = false;
                }
                else
                    m_uiVisible_Timer -= uiDiff;
            }
            else
                DoMeleeAttackIfReady();
        }
Example #14
0
    void UpdateAI(const uint32 diff)
    {
        if(!m_creature->SelectHostilTarget())
            return;

        if(m_creature->getVictim() && m_creature->isAlive())
        {
            //Check for Frost Bolt
            if(FrostBolt_Timer < diff)
            {
                DoCast(m_creature->getVictim(),SPELL_FROST_BOLT);

                if(rand()%2 == 0)
                {
                    DoYell(SAY_FROST,LANG_UNIVERSAL,NULL);
                    DoPlaySoundToSet(m_creature,SOUND_FROST);
                }
                //Cast again on time
                FrostBolt_Timer = (rand()%60)*1000;
            }
            else FrostBolt_Timer -= diff;

            //Check for Frost Bolt Nova
            if(FrostBoltNova_Timer < diff)
            {
                DoCast(m_creature->getVictim(),SPELL_FROST_BOLT_NOVA);

                if(rand()%2 == 0)
                {
                    DoYell(SAY_FROST,LANG_UNIVERSAL,NULL);
                    DoPlaySoundToSet(m_creature,SOUND_FROST);
                }

                FrostBoltNova_Timer = 15000;
            }
            else FrostBoltNova_Timer -= diff;

            //Check for Chains Of Kelthuzad
            if(ChainsOfKelthuzad_Timer < diff)
            {
                DoCast(m_creature->getVictim(),SPELL_CHAINS_OF_KELTHUZAD);

                if(rand()%2 == 0)
                    if(rand()%2 == 0)
                    {
                        DoYell(SAY_CHAIN1,LANG_UNIVERSAL,NULL);
                        DoPlaySoundToSet(m_creature,SOUND_CHAIN1);
                    }
                    else
                    {
                        DoYell(SAY_CHAIN2,LANG_UNIVERSAL,NULL);
                        DoPlaySoundToSet(m_creature,SOUND_CHAIN2);
                    }

                //cast again on time
                ChainsOfKelthuzad_Timer = (rand()%30+30)*1000;
            }
            else ChainsOfKelthuzad_Timer -= diff;

            //Check for Mana Detonation
            if(ManaDetonation_Timer < diff)
            {
                //time to cast
                //DoCast(m_creature->getVictim(),SPELL_MANA_DETONATION);

                if(rand()%2 == 0)
                {
                    DoYell(SAY_SPECIAL1,LANG_UNIVERSAL,NULL);
                    DoPlaySoundToSet(m_creature,SOUND_SPECIAL1);
                }
                ManaDetonation_Timer = 20000;
            }
            else ManaDetonation_Timer -= diff;

            //Check for Shadow Fissure
            if(ShadowFisure_Timer < diff)
            {
                DoCast(m_creature->getVictim(),SPELL_SHADOW_FISURE);

                if(rand()%2 == 0)
                {
                    DoYell(SAY_SPECIAL2,LANG_UNIVERSAL,NULL);
                    DoPlaySoundToSet(m_creature,SOUND_SPECIAL2);
                }

                ShadowFisure_Timer = 25000;
            }
            else ShadowFisure_Timer -= diff;

            //Check for Frost Blast
            if(FrostBlast_Timer < diff)
            {
                //time to cast
                //DoCast(m_creature->getVictim(),SPELL_FROST_BLAST);

                if(rand()%2 == 0)
                {
                    DoYell(SAY_FROST,LANG_UNIVERSAL,NULL);
                    DoPlaySoundToSet(m_creature,SOUND_FROST);
                }

                FrostBlast_Timer = (rand()%30+30)*1000;
            }
            else FrostBlast_Timer -= diff;

            //start phase 3 when we are 40% health
            if(!Phase3 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 40)
            {
                Phase3 = true;
                switch(rand()%2)
                {
                case 1:
                    DoYell(SAY_REINFORCEMENTS1,LANG_UNIVERSAL,NULL);
                    DoPlaySoundToSet(m_creature,SOUND_REINFORCEMENTS1);
                    break;
                case 2:
                    DoYell(SAY_REINFORCEMENTS2,LANG_UNIVERSAL,NULL);
                    DoPlaySoundToSet(m_creature,SOUND_REINFORCEMENTS2);
                    break;
                }
                //here Lich King should respond to KelThuzad but I don't know which creature to make talk
                //so for now just make Kelthuzad says it.
                DoPlaySoundToSet(m_creature,SOUND_LICH_NAXX_SUMMON);
            }

            if(Phase3 && (GuardiansOfIcecrown_Count < 5))
                if(GuardiansOfIcecrown_Timer < diff)
                {
                    //Summon a Guardian of Icecrown in a random alcove (Creature # 16441)
                    //uint32 TimeToWalk;
                    Unit* pUnit = NULL;
                    float Walk_Pos_X;
                    float Walk_Pos_Y;
                    float Walk_Pos_Z;
                    switch(rand()%6)
                    {
                    case 0:
                        pUnit = m_creature->SummonCreature(16441,ADDX_LEFT_FAR,ADDY_LEFT_FAR,ADDZ_LEFT_FAR,ADDO_LEFT_FAR,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,1000);
                        //Setting walk position
                        Walk_Pos_X = WALKX_LEFT_FAR;
                        Walk_Pos_Y = WALKY_LEFT_FAR;
                        Walk_Pos_Z = WALKZ_LEFT_FAR;
                        break;
                    case 1:
                        pUnit = m_creature->SummonCreature(16441,ADDX_LEFT_MIDDLE,ADDY_LEFT_MIDDLE,ADDZ_LEFT_MIDDLE,ADDO_LEFT_MIDDLE,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,1000);
                        //Start moving guardian towards the center of the room
                        Walk_Pos_X = WALKX_LEFT_MIDDLE;
                        Walk_Pos_Y = WALKY_LEFT_MIDDLE;
                        Walk_Pos_Z = WALKZ_LEFT_MIDDLE;
                        break;
                    case 2:
                        pUnit = m_creature->SummonCreature(16441,ADDX_LEFT_NEAR,ADDY_LEFT_NEAR,ADDZ_LEFT_NEAR,ADDO_LEFT_NEAR,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,1000);
                        //Start moving guardian towards the center of the room
                        Walk_Pos_X = WALKX_LEFT_NEAR;
                        Walk_Pos_Y = WALKY_LEFT_NEAR;
                        Walk_Pos_Z = WALKZ_LEFT_NEAR;
                        break;
                    case 3:

                        pUnit = m_creature->SummonCreature(16441,ADDX_RIGHT_FAR,ADDY_RIGHT_FAR,ADDZ_RIGHT_FAR,ADDO_RIGHT_FAR,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,1000);
                        //Start moving guardian towards the center of the room
                        Walk_Pos_X = WALKX_RIGHT_FAR;
                        Walk_Pos_Y = WALKY_RIGHT_FAR;
                        Walk_Pos_Z = WALKZ_RIGHT_FAR;
                        break;
                    case 4:
                        pUnit = m_creature->SummonCreature(16441,ADDX_RIGHT_MIDDLE,ADDY_RIGHT_MIDDLE,ADDZ_RIGHT_MIDDLE,ADDO_RIGHT_MIDDLE,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,1000);
                        //Start moving guardian towards the center of the room
                        Walk_Pos_X = WALKX_RIGHT_MIDDLE;
                        Walk_Pos_Y = WALKY_RIGHT_MIDDLE;
                        Walk_Pos_Z = WALKZ_RIGHT_MIDDLE;
                        break;
                    case 5:
                        pUnit = m_creature->SummonCreature(16441,ADDX_RIGHT_NEAR,ADDY_RIGHT_NEAR,ADDZ_RIGHT_NEAR,ADDO_RIGHT_NEAR,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,1000);
                        //Start moving guardian towards the center of the room
                        Walk_Pos_X = WALKX_RIGHT_NEAR;
                        Walk_Pos_Y = WALKY_RIGHT_NEAR;
                        Walk_Pos_Z = WALKZ_RIGHT_NEAR;
                        break;
                    }

                    if (pUnit)
                    {
                        //if we find no one to figth walk to the center
                        if(!pUnit->isInCombat())
                            pUnit->SendMonsterMoveWithSpeed(Walk_Pos_X,Walk_Pos_Y,Walk_Pos_Z,MOVEMENTFLAG_WALK_MODE);

                        //Safe storing of creatures
                        GuardiansOfIcecrown[GuardiansOfIcecrown_Count] = pUnit->GetGUID();

                        //Update guardian count
                        GuardiansOfIcecrown_Count++;

                    }
                    //5 seconds until summoning next guardian
                    GuardiansOfIcecrown_Timer = 5000;
                }
                else GuardiansOfIcecrown_Timer -= diff;

            DoMeleeAttackIfReady();
        }
    }
        void UpdateAI(const uint32 uiDiff)
        {
            if (!UpdateVictim())
                return;

            switch (m_uiStage)
            {
            case 0:
                if (m_uiFerociousButtTimer <= uiDiff)
                {
                    DoCastVictim(RAID_MODE(SPELL_FEROCIOUS_BUTT_10_N, SPELL_FEROCIOUS_BUTT_25_N, SPELL_FEROCIOUS_BUTT_10_H, SPELL_FEROCIOUS_BUTT_25_H));
                    m_uiFerociousButtTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
                } else m_uiFerociousButtTimer -= uiDiff;

                if (m_uiArticBreathTimer <= uiDiff)
                {
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                        DoCast(target, RAID_MODE(SPELL_ARCTIC_BREATH_10_N, SPELL_ARCTIC_BREATH_25_N, SPELL_ARCTIC_BREATH_10_H, SPELL_ARCTIC_BREATH_25_H));
                    m_uiArticBreathTimer = urand(25*IN_MILLISECONDS, 40*IN_MILLISECONDS);
                } else m_uiArticBreathTimer -= uiDiff;

                if (m_uiWhirlTimer <= uiDiff)
                {
                    DoCastAOE(RAID_MODE(SPELL_WHIRL_10_N, SPELL_WHIRL_25_N, SPELL_WHIRL_10_H, SPELL_WHIRL_25_H));
                    m_uiWhirlTimer = urand(15*IN_MILLISECONDS, 30*IN_MILLISECONDS);
                } else m_uiWhirlTimer -= uiDiff;

                if (m_uiMassiveCrashTimer <= uiDiff)
                {
                    me->GetMotionMaster()->MoveJump(ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 10.0f, 20.0f); // 1: Middle of the room
                    m_uiStage = 7; //Invalid (Do nothing more than move)
                    m_uiMassiveCrashTimer = 30*IN_MILLISECONDS;
                } else m_uiMassiveCrashTimer -= uiDiff;

                DoMeleeAttackIfReady();
                break;
            case 1:
                DoCastAOE(RAID_MODE(SPELL_MASSIVE_CRASH_10_N, SPELL_MASSIVE_CRASH_25_N, SPELL_MASSIVE_CRASH_10_H, SPELL_MASSIVE_CRASH_25_H));
                m_uiStage = 2;
                break;
            case 2:
                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0, true))
                {
                    m_uiTrampleTargetGUID = target->GetGUID();
                    me->SetTarget(m_uiTrampleTargetGUID);
                    DoScriptText(SAY_TRAMPLE_STARE, me, target);
                    m_bTrampleCasted = false;
                    SetCombatMovement(false);
                    me->GetMotionMaster()->MoveIdle();
                    me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    m_uiTrampleTimer = 4*IN_MILLISECONDS;
                    m_uiStage = 3;
                } else m_uiStage = 6;
                break;
            case 3:
                if (m_uiTrampleTimer <= uiDiff)
                {
                    if (Unit* target = Unit::GetPlayer(*me, m_uiTrampleTargetGUID))
                    {
                        m_bTrampleCasted = false;
                        m_bMovementStarted = true;
                        m_fTrampleTargetX = target->GetPositionX();
                        m_fTrampleTargetY = target->GetPositionY();
                        m_fTrampleTargetZ = target->GetPositionZ();
                        me->GetMotionMaster()->MoveJump(2*me->GetPositionX()-m_fTrampleTargetX,
                                                        2*me->GetPositionY()-m_fTrampleTargetY,
                                                        me->GetPositionZ(),
                                                        10.0f, 20.0f); // 2: Hop Backwards
                        m_uiStage = 7; //Invalid (Do nothing more than move)
                    } else m_uiStage = 6;
                } else m_uiTrampleTimer -= uiDiff;
                break;
            case 4:
                DoScriptText(SAY_TRAMPLE_START, me);
                me->GetMotionMaster()->MoveCharge(m_fTrampleTargetX, m_fTrampleTargetY, m_fTrampleTargetZ+2, 42, 1);
                me->SetTarget(0);
                m_uiStage = 5;
                break;
            case 5:
                if (m_bMovementFinish)
                {
                    if (m_uiTrampleTimer <= uiDiff) DoCastAOE(SPELL_TRAMPLE);
                    m_bMovementFinish = false;
                    m_uiStage = 6;
                    return;
                }
                if (m_uiTrampleTimer <= uiDiff)
                {
                    Map::PlayerList const &lPlayers = me->GetMap()->GetPlayers();
                    for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
                    {
                        if (Unit* player = itr->getSource())
                            if (player->isAlive() && player->IsWithinDistInMap(me, 6.0f))
                            {
                                DoCastAOE(SPELL_TRAMPLE);
                                m_uiTrampleTimer = IN_MILLISECONDS;
                                break;
                            }
                    }
                } else m_uiTrampleTimer -= uiDiff;
                break;
            case 6:
                if (!m_bTrampleCasted)
                {
                    DoCast(me, SPELL_STAGGERED_DAZE);
                    DoScriptText(SAY_TRAMPLE_FAIL, me);
                }
                m_bMovementStarted = false;
                me->GetMotionMaster()->MovementExpired();
                me->GetMotionMaster()->MoveChase(me->getVictim());
                SetCombatMovement(true);
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                m_uiStage = 0;
                break;
            }
        }