void AssistanceMovementGenerator::Finalize(Unit &unit)
{
    ((Creature*)&unit)->SetNoCallAssistance(false);
    ((Creature*)&unit)->CallAssistance();
    if (unit.isAlive())
        unit.GetMotionMaster()->MoveSeekAssistanceDistract(sWorld.getConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY));
}
Example #2
1
    void FlameWreathEffect()
    {
        std::vector<Unit*> targets;
        std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();

        if (!t_list.size())
            return;

        //store the threat list in a different container
        for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
        {
            Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
            //only on alive players
            if (target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
                targets.push_back(target);
        }

        //cut down to size if we have more than 3 targets
        while(targets.size() > 3)
            targets.erase(targets.begin()+rand()%targets.size());

        uint32 i = 0;
        for(std::vector<Unit*>::iterator itr = targets.begin(); itr!= targets.end(); ++itr)
        {
            if (*itr)
            {
                FlameWreathTarget[i] = (*itr)->GetGUID();
                FWTargPosX[i] = (*itr)->GetPositionX();
                FWTargPosY[i] = (*itr)->GetPositionY();
                m_creature->CastSpell((*itr), SPELL_FLAME_WREATH, true);
                i++;
            }
        }
    }
Example #3
1
void WorldSession::HandlePetStopAttack(WorldPacket& recv_data)
{
    DEBUG_LOG("WORLD: Received opcode CMSG_PET_STOP_ATTACK");

    ObjectGuid petGuid;
    recv_data >> petGuid;

    Unit* pet = GetPlayer()->GetMap()->GetUnit(petGuid);    // pet or controlled creature/player
    if (!pet)
    {
        sLog.outError("%s doesn't exist.", petGuid.GetString().c_str());
        return;
    }

    if (GetPlayer()->GetObjectGuid() != pet->GetCharmerOrOwnerGuid())
    {
        sLog.outError("HandlePetStopAttack: %s isn't charm/pet of %s.", petGuid.GetString().c_str(), GetPlayer()->GetGuidStr().c_str());
        return;
    }

    if (!pet->isAlive())
        return;

    pet->AttackStop();
}
void TimedFleeingMovementGenerator::Finalize(Unit &owner)
{
    owner.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
    owner.clearUnitState(UNIT_STAT_FLEEING | UNIT_STAT_ROAMING);
    if (Unit* victim = owner.getVictim())
    {
        if (owner.isAlive())
        {
            owner.AttackStop();
            ((Creature*)&owner)->AI()->AttackStart(victim);
        }
    }
}
        void UpdateAI(uint32 diff)
        {
            if (!instance)
                return;

            if (CheckTimer <= diff)
            {
                Unit* vashj = Unit::GetUnit(*me, instance->GetData64(DATA_LADYVASHJ));

                if (vashj && vashj->isAlive())
                {
                    // start visual channel
                    if (!Casted || !vashj->HasAura(SPELL_MAGIC_BARRIER))
                    {
                        DoCast(vashj, SPELL_MAGIC_BARRIER, true);
                        Casted = true;
                    }
                }
                CheckTimer = 1000;
            } else CheckTimer -= diff;
        }
        Unit* GetHatefullStrikeTarget()
        {
            // Get all Targets in Meleerange
            const std::list<HostileReference *> &threatlist = me->getThreatManager().getThreatList();
            std::list<Unit*> targetList;

            for (std::list<HostileReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
            {
                HostileReference* ref = (*itr);
                if (ref->getTarget() && me->IsWithinMeleeRange(ref->getTarget()))
                    targetList.push_back(ref->getTarget());
            }

            // Get Target with most HP and not getVictim()
            uint32 MostHP = 0;
            Unit* pMostHPTarget = NULL;
            uint32 counter = 0;

            for(std::list<Unit*>::const_iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
            {
                counter++;

                //Only first 3 Targets in Threadlist
                if(counter > 3)
                    break;

                Unit *pTarget = (*itr);
                if (pTarget->isAlive() && pTarget->GetHealth() > MostHP)
                {
                    MostHP = pTarget->GetHealth();
                    pMostHPTarget = pTarget;
                }
            }

            if(pMostHPTarget)
                return pMostHPTarget;
            else
                return me->getVictim();
        }
Example #7
1
void WorldSession::HandlePetAction(WorldPacket& recv_data)
{
    ObjectGuid petGuid;
    uint32 data;
    ObjectGuid targetGuid;
    recv_data >> petGuid;
    recv_data >> data;
    recv_data >> targetGuid;

    uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data);
    uint8 flag = UNIT_ACTION_BUTTON_TYPE(data);             // delete = 0x07 CastSpell = C1

    DETAIL_LOG("HandlePetAction: %s flag is %u, spellid is %u, target %s.", petGuid.GetString().c_str(), uint32(flag), spellid, targetGuid.GetString().c_str());

    // used also for charmed creature/player
    Unit* pet = _player->GetMap()->GetUnit(petGuid);
    if (!pet)
    {
        sLog.outError("HandlePetAction: %s not exist.", petGuid.GetString().c_str());
        return;
    }

    if (GetPlayer()->GetObjectGuid() != pet->GetCharmerOrOwnerGuid())
    {
        sLog.outError("HandlePetAction: %s isn't controlled by %s.", petGuid.GetString().c_str(), GetPlayer()->GetGuidStr().c_str());
        return;
    }

    if (!pet->isAlive())
        return;

    if (pet->GetTypeId() == TYPEID_PLAYER)
    {
        // controller player can only do melee attack
        if (!(flag == ACT_COMMAND && spellid == COMMAND_ATTACK))
            return;
    }
    else if (((Creature*)pet)->IsPet())
    {
        // pet can have action bar disabled
        if (((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)
            return;
    }

    CharmInfo* charmInfo = pet->GetCharmInfo();
    if (!charmInfo)
    {
        sLog.outError("WorldSession::HandlePetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId());
        return;
    }

    switch (flag)
    {
    case ACT_COMMAND:                                   // 0x07
        switch (spellid)
        {
        case COMMAND_STAY:                          // flat=1792  // STAY
            pet->StopMoving();
            pet->GetMotionMaster()->Clear(false);
            pet->GetMotionMaster()->MoveIdle();
            charmInfo->SetCommandState(COMMAND_STAY);
            break;
        case COMMAND_FOLLOW:                        // spellid=1792  // FOLLOW
            pet->AttackStop();
            pet->GetMotionMaster()->MoveFollow(_player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
            charmInfo->SetCommandState(COMMAND_FOLLOW);
            break;
        case COMMAND_ATTACK:                        // spellid=1792  // ATTACK
        {
            Unit* TargetUnit = _player->GetMap()->GetUnit(targetGuid);
            if (!TargetUnit)
                return;

            // not let attack friendly units.
            if (GetPlayer()->IsFriendlyTo(TargetUnit))
                return;
            // Not let attack through obstructions
            if (!pet->IsWithinLOSInMap(TargetUnit))
                return;

            // This is true if pet has no target or has target but targets differs.
            if (pet->getVictim() != TargetUnit)
            {
                if (pet->getVictim())
                    pet->AttackStop();

                if (pet->hasUnitState(UNIT_STAT_CONTROLLED))
                {
                    pet->Attack(TargetUnit, true);
                    pet->SendPetAIReaction();
                }
                else
                {
                    pet->GetMotionMaster()->Clear();

                    if (((Creature*)pet)->AI())
                        ((Creature*)pet)->AI()->AttackStart(TargetUnit);

                    // 10% chance to play special pet attack talk, else growl
                    if (((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10))
                        pet->SendPetTalk((uint32)PET_TALK_ATTACK);
                    else
                    {
                        // 90% chance for pet and 100% chance for charmed creature
                        pet->SendPetAIReaction();
                    }
                }
            }
            break;
        }
        case COMMAND_ABANDON:                       // abandon (hunter pet) or dismiss (summoned pet)
            if (((Creature*)pet)->IsPet())
            {
                Pet* p = (Pet*)pet;
                if (p->getPetType() == HUNTER_PET)
                    p->Unsummon(PET_SAVE_AS_DELETED, _player);
                else
                    // dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
                    p->SetDeathState(CORPSE);
            }
            else                                    // charmed
                _player->Uncharm();
            break;
        default:
            sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid);
        }
        break;
    case ACT_REACTION:                                  // 0x6
        switch (spellid)
        {
        case REACT_PASSIVE:                         // passive
        case REACT_DEFENSIVE:                       // recovery
        case REACT_AGGRESSIVE:                      // activete
            charmInfo->SetReactState(ReactStates(spellid));
            break;
        }
        break;
    case ACT_DISABLED:                                  // 0x81    spell (disabled), ignore
    case ACT_PASSIVE:                                   // 0x01
    case ACT_ENABLED:                                   // 0xC1    spell
    {
        Unit* unit_target = NULL;
        if (targetGuid)
            unit_target = _player->GetMap()->GetUnit(targetGuid);

        // do not cast unknown spells
        SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
        if (!spellInfo)
        {
            sLog.outError("WORLD: unknown PET spell id %i", spellid);
            return;
        }

        if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
            return;

        for (int i = 0; i < MAX_EFFECT_INDEX; ++i)
        {
            if (spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)
                return;
        }

        // do not cast not learned spells
        if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo))
            return;

        pet->clearUnitState(UNIT_STAT_MOVING);

        Spell* spell = new Spell(pet, spellInfo, false);

        SpellCastResult result = spell->CheckPetCast(unit_target);

        // auto turn to target unless possessed
        if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
        {
            if (unit_target)
            {
                pet->SetInFront(unit_target);
                if (unit_target->GetTypeId() == TYPEID_PLAYER)
                    pet->SendCreateUpdateToPlayer((Player*)unit_target);
            }
            else if (Unit* unit_target2 = spell->m_targets.getUnitTarget())
            {
                pet->SetInFront(unit_target2);
                if (unit_target2->GetTypeId() == TYPEID_PLAYER)
                    pet->SendCreateUpdateToPlayer((Player*)unit_target2);
            }
            if (Unit* powner = pet->GetCharmerOrOwner())
                if (powner->GetTypeId() == TYPEID_PLAYER)
                    pet->SendCreateUpdateToPlayer((Player*)powner);
            result = SPELL_CAST_OK;
        }

        if (result == SPELL_CAST_OK)
        {
            ((Creature*)pet)->AddCreatureSpellCooldown(spellid);
            if (((Creature*)pet)->IsPet())
                ((Pet*)pet)->CheckLearning(spellid);

            unit_target = spell->m_targets.getUnitTarget();

            // 10% chance to play special pet attack talk, else growl
            // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
            if (((Creature*)pet)->IsPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10))
                pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
            else
            {
                pet->SendPetAIReaction();
            }

            if (unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
            {
                // This is true if pet has no target or has target but targets differs.
                if (pet->getVictim() != unit_target)
                {
                    if (pet->getVictim())
                        pet->AttackStop();
                    pet->GetMotionMaster()->Clear();
                    if (((Creature*)pet)->AI())
                        ((Creature*)pet)->AI()->AttackStart(unit_target);
                }
            }

            spell->prepare(&(spell->m_targets));
        }
        else
        {
            if (pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
                Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
            else
            {
                Unit* owner = pet->GetCharmerOrOwner();
                if (owner && owner->GetTypeId() == TYPEID_PLAYER)
                    Spell::SendCastResult((Player*)owner, spellInfo, 0, result, true);
            }

            if (!((Creature*)pet)->HasSpellCooldown(spellid))
                GetPlayer()->SendClearCooldown(spellid, pet);

            spell->finish(false);
            delete spell;
        }
        break;
    }
    default:
        sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid);
    }
}
Example #8
0
 void WaypointReached(uint32 i)
 {
     pos = i;
     if (i == 7 && pInstance)
     {
         Unit* target = Unit::GetUnit((*me), pInstance->GetData64(DATA_JAINAPROUDMOORE));
         if (target && target->isAlive())
             me->AddThreat(target, 0.0f);
     }
 }
Example #9
0
        void ActivateMinion(uint64 uiGuid, bool bFlag)
        {
            Unit* pMinion = Unit::GetUnit(*me, uiGuid);

            if (pMinion && pMinion->isAlive())
            {
                DoCast(pMinion, SPELL_AWAKEN_VAULT_WALKER, bFlag);
                pMinion->CastSpell(pMinion, SPELL_ARCHAEDAS_AWAKEN, true);
            }
        }
        void UpdateAI(const uint32 uiDiff)
        {
            if (m_bTargetDied || !UpdateVictim())
                return;

            if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
            {
                if (!target->isAlive())
                {
                    if (m_pInstance)
                    {
                        Unit* gormok = ObjectAccessor::GetCreature(*me, m_pInstance->GetData64(NPC_GORMOK));
                        if (gormok && gormok->isAlive())
                        {
                            SetCombatMovement(false);
                            m_bTargetDied = true;
                            me->GetMotionMaster()->MoveJump(gormok->GetPositionX(), gormok->GetPositionY(), gormok->GetPositionZ(), 15.0f, 15.0f);
                        }
                        else if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                        {
                            m_uiTargetGUID = target->GetGUID();
                            me->GetMotionMaster()->MoveJump(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 15.0f, 15.0f);
                        }
                    }
                }
            }

            if (m_uiFireBombTimer < uiDiff)
            {
                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                    DoCast(target, SPELL_FIRE_BOMB);
                m_uiFireBombTimer = 20000;
            }
            else m_uiFireBombTimer -= uiDiff;

            if (m_uiBatterTimer < uiDiff)
            {
                if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
                    DoCast(target, SPELL_BATTER);
                m_uiBatterTimer = 10000;
            }
            else m_uiBatterTimer -= uiDiff;

            if (m_uiHeadCrackTimer < uiDiff)
            {
                if (Unit* target = Unit::GetPlayer(*me, m_uiTargetGUID))
                    DoCast(target, SPELL_HEAD_CRACK);
                m_uiHeadCrackTimer = 35000;
            }
            else m_uiHeadCrackTimer -= uiDiff;

            DoMeleeAttackIfReady();
        }
        void EnterCombat(Unit* who)
        {
            if (!ghost && instance)
            {
                Talk(YELL_SKARVALD_AGGRO);

                Unit* dalronn = Unit::GetUnit(*me, instance->GetData64(DATA_DALRONN));
                if (dalronn && dalronn->isAlive() && !dalronn->GetVictim())
                    dalronn->getThreatManager().addThreat(who, 0.0f);

                instance->SetData(DATA_SKARVALD_DALRONN_EVENT, IN_PROGRESS);
            }
        }
Example #12
0
    void JustDied(Unit* Killer)
    {
        DoYell(SAY_DEATH,LANG_UNIVERSAL,NULL);
        DoPlaySoundToSet(m_creature,SOUND_DEATH);
        for(int i=0; i<5; i++)
            if(GuardiansOfIcecrown[i])
            {
                Unit* pUnit = Unit::GetUnit((*m_creature), GuardiansOfIcecrown[i]);
                if (!pUnit || !pUnit->isAlive())
                    continue;

                pUnit->CombatStop();
                float Walk_Pos_X;
                float Walk_Pos_Y;
                float Walk_Pos_Z;
                switch(rand()%6)
                {
                case 0:
                    Walk_Pos_X = ADDX_LEFT_FAR;
                    Walk_Pos_Y = ADDY_LEFT_FAR;
                    Walk_Pos_Z = ADDZ_LEFT_FAR;
                    break;
                case 1:
                    Walk_Pos_X = ADDX_LEFT_MIDDLE;
                    Walk_Pos_Y = ADDY_LEFT_MIDDLE;
                    Walk_Pos_Z = ADDZ_LEFT_MIDDLE;
                    break;
                case 2:
                    Walk_Pos_X = ADDX_LEFT_NEAR;
                    Walk_Pos_Y = ADDY_LEFT_NEAR;
                    Walk_Pos_Z = ADDZ_LEFT_NEAR;
                    break;
                case 3:
                    Walk_Pos_X = ADDX_RIGHT_FAR;
                    Walk_Pos_Y = ADDY_RIGHT_FAR;
                    Walk_Pos_Z = ADDZ_RIGHT_FAR;
                    break;
                case 4:
                    Walk_Pos_X = ADDX_RIGHT_MIDDLE;
                    Walk_Pos_Y = ADDY_RIGHT_MIDDLE;
                    Walk_Pos_Z = ADDZ_RIGHT_MIDDLE;
                    break;
                case 5:
                    Walk_Pos_X = ADDX_RIGHT_NEAR;
                    Walk_Pos_Y = ADDY_RIGHT_NEAR;
                    Walk_Pos_Z = ADDZ_RIGHT_NEAR;
                    break;
                }
                pUnit->SendMonsterMoveWithSpeed(Walk_Pos_X, Walk_Pos_Y, Walk_Pos_Z,MOVEMENTFLAG_WALK_MODE);
            }
    }
        void EnterCombat(Unit* who)
        {
            if (!ghost && instance)
            {
                Unit* skarvald = Unit::GetUnit(*me, instance->GetData64(DATA_SKARVALD));
                if (skarvald && skarvald->isAlive() && !skarvald->GetVictim())
                    skarvald->getThreatManager().addThreat(who, 0.0f);

                AggroYell_Timer = 5000;

                if (instance)
                    instance->SetData(DATA_SKARVALD_DALRONN_EVENT, IN_PROGRESS);
            }
        }
bool TimedFleeingMovementGenerator::Update(Unit & owner, const uint32 & time_diff)
{
    if( !owner.isAlive() )
        return false;

    if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
        return true;

    i_totalFleeTime.Update(time_diff);
    if (i_totalFleeTime.Passed())
        return false;

    // This calls grant-parent Update method hiden by FleeingMovementGenerator::Update(Creature &, const uint32 &) version
    // This is done instead of casting Unit& to Creature& and call parent method, then we can use Unit directly
    return MovementGeneratorMedium< Creature, FleeingMovementGenerator<Creature> >::Update(owner, time_diff);
}
Example #15
0
        void UpdateAI(uint32 diff)
        {
            // Random movement
            if (MovementTimer <= diff)
            {
                uint32 rndpos = rand()%8;
                me->GetMotionMaster()->MovePoint(1, SporebatWPPos[rndpos][0], SporebatWPPos[rndpos][1], SporebatWPPos[rndpos][2]);
                MovementTimer = 6000;
            } else MovementTimer -= diff;

            // toxic spores
            if (BoltTimer <= diff)
            {
                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                {
                    if (Creature* trig = me->SummonCreature(TOXIC_SPORES_TRIGGER, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 30000))
                    {
                        trig->setFaction(14);
                        trig->CastSpell(trig, SPELL_TOXIC_SPORES, true);
                    }
                }
                BoltTimer = 10000+rand()%5000;
            }
            else BoltTimer -= diff;

            // CheckTimer
            if (CheckTimer <= diff)
            {
                if (instance)
                {
                    // check if vashj is death
                    Unit* Vashj = Unit::GetUnit(*me, instance->GetData64(DATA_LADYVASHJ));
                    if (!Vashj || (Vashj && !Vashj->isAlive()) || (Vashj && CAST_AI(boss_lady_vashj::boss_lady_vashjAI, CAST_CRE(Vashj)->AI())->Phase != 3))
                    {
                        // remove
                        me->setDeathState(DEAD);
                        me->RemoveCorpse();
                        me->setFaction(35);
                    }
                }

                CheckTimer = 1000;
            } else CheckTimer -= diff;
        }
Example #16
0
 void MovementInform(uint32 type, uint32 id)
 {
     if (type == POINT_MOTION_TYPE && id == 1)
     {
         Unit* CrystalChosen = Unit::GetUnit(*me, CrystalGUID);
         if (CrystalChosen && CrystalChosen->isAlive())
         {
             // Make the crystal attackable
             // We also remove NON_ATTACKABLE in case the database has it set.
             CrystalChosen->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE);
             CrystalChosen->CastSpell(me, SPELL_MANA_RAGE, true);
             IsDraining = true;
         }
         else
         {
             // Make an error message in case something weird happened here
             sLog->outError("TSCR: Selin Fireheart unable to drain crystal as the crystal is either dead or despawned");
             DrainingCrystal = false;
         }
     }
 }
Example #17
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 #18
0
    void Reset()
    {
        if (instance)
        {
            //for (uint8 i = 0; i < CRYSTALS_NUMBER; ++i)
            for (std::list<uint64>::const_iterator itr = Crystals.begin(); itr != Crystals.end(); ++itr)
            {
                //Unit* pUnit = Unit::GetUnit(*me, FelCrystals[i]);
                Unit* pUnit = Unit::GetUnit(*me, *itr);
                if (pUnit)
                {
                    if (!pUnit->isAlive())
                        CAST_CRE(pUnit)->Respawn();      // Let the core handle setting death state, etc.

                    // Only need to set unselectable flag. You can't attack unselectable units so non_attackable flag is not necessary here.
                    pUnit->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                }
            }

            instance->HandleGameObject(instance->GetData64(DATA_SELIN_ENCOUNTER_DOOR), true);
            // Open the big encounter door. Close it in Aggro and open it only in JustDied(and here)
            // Small door opened after event are expected to be closed by default
            // Set Inst data for encounter
            instance->SetData(DATA_SELIN_EVENT, NOT_STARTED);
        } else sLog->outError(ERROR_INST_DATA);

        DrainLifeTimer = 3000 + rand()%4000;
        DrainManaTimer = DrainLifeTimer + 5000;
        FelExplosionTimer = 2100;
        DrainCrystalTimer = 10000 + rand()%5000;
        DrainCrystalTimer = 20000 + rand()%5000;
        EmpowerTimer = 10000;

        IsDraining = false;
        DrainingCrystal = false;
        CrystalGUID = 0;
    }
Example #19
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;

        if (!DrainingCrystal)
        {
            uint32 maxPowerMana = me->GetMaxPower(POWER_MANA);
            if (maxPowerMana && ((me->GetPower(POWER_MANA)*100 / maxPowerMana) < 10))
            {
                if (DrainLifeTimer <= diff)
                {
                    DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DRAIN_LIFE);
                    DrainLifeTimer = 10000;
                } else DrainLifeTimer -= diff;

                // Heroic only
                if (Heroic)
                {
                    if (DrainManaTimer <= diff)
                    {
                        DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_DRAIN_MANA);
                        DrainManaTimer = 10000;
                    } else DrainManaTimer -= diff;
                }
            }

            if (FelExplosionTimer <= diff)
            {
                if (!me->IsNonMeleeSpellCasted(false))
                {
                    DoCast(me, SPELL_FEL_EXPLOSION);
                    FelExplosionTimer = 2000;
                }
            } else FelExplosionTimer -= diff;

            // If below 10% mana, start recharging
            maxPowerMana = me->GetMaxPower(POWER_MANA);
            if (maxPowerMana && ((me->GetPower(POWER_MANA)*100 / maxPowerMana) < 10))
            {
                if (DrainCrystalTimer <= diff)
                {
                    SelectNearestCrystal();
                    if (Heroic)
                        DrainCrystalTimer = 10000 + rand()%5000;
                    else
                        DrainCrystalTimer = 20000 + rand()%5000;
                } else DrainCrystalTimer -= diff;
            }
        } else
        {
            if (IsDraining)
            {
                if (EmpowerTimer <= diff)
                {
                    IsDraining = false;
                    DrainingCrystal = false;

                    DoScriptText(SAY_EMPOWERED, me);

                    Unit* CrystalChosen = Unit::GetUnit(*me, CrystalGUID);
                    if (CrystalChosen && CrystalChosen->isAlive())
                        // Use Deal Damage to kill it, not setDeathState.
                        CrystalChosen->Kill(CrystalChosen);

                    CrystalGUID = 0;

                    me->GetMotionMaster()->Clear();
                    me->GetMotionMaster()->MoveChase(me->getVictim());
                } else EmpowerTimer -= diff;
            }
        }

        DoMeleeAttackIfReady();                             // No need to check if we are draining crystal here, as the spell has a stun.
    }