// used when Archaedas dies.  All active minions must be despawned.
            void DeActivateMinions()
            {
                // first despawn any aggroed wall minions
                for (std::vector<uint64>::const_iterator i = vArchaedasWallMinions.begin(); i != vArchaedasWallMinions.end(); ++i)
                {
                    Creature* pTarget = instance->GetCreature(*i);
                    if (!pTarget || pTarget->isDead() || pTarget->getFaction() != 14)
                        continue;
                    pTarget->setDeathState(JUST_DIED);
                    pTarget->RemoveCorpse();
                }

                // Vault Walkers
                for (std::vector<uint64>::const_iterator i = vVaultWalker.begin(); i != vVaultWalker.end(); ++i)
                {
                    Creature* pTarget = instance->GetCreature(*i);
                    if (!pTarget || pTarget->isDead() || pTarget->getFaction() != 14)
                        continue;
                    pTarget->setDeathState(JUST_DIED);
                    pTarget->RemoveCorpse();
                }

                // Earthen Guardians
                for (std::vector<uint64>::const_iterator i = vEarthenGuardian.begin(); i != vEarthenGuardian.end(); ++i)
                {
                    Creature* pTarget = instance->GetCreature(*i);
                    if (!pTarget || pTarget->isDead() || pTarget->getFaction() != 14)
                        continue;
                    pTarget->setDeathState(JUST_DIED);
                    pTarget->RemoveCorpse();
                }
            }
void instance_dire_maul::ProcessForceFieldOpening()
{
    // 'Open' the force field
    DoUseDoorOrButton(GO_FORCEFIELD);

    // Let the summoners attack Immol'Thar
    Creature* pImmolThar = GetSingleCreatureFromStorage(NPC_IMMOLTHAR);
    if (!pImmolThar || pImmolThar->isDead())
        return;

    bool bHasYelled = false;
    for (GuidList::const_iterator itr = m_luiHighborneSummonerGUIDs.begin(); itr != m_luiHighborneSummonerGUIDs.end(); ++itr)
    {
        Creature* pSummoner = instance->GetCreature(*itr);

        if (!bHasYelled && pSummoner)
        {
            DoScriptText(SAY_KILL_IMMOLTHAR, pSummoner);
            bHasYelled = true;
        }

        if (!pSummoner || pSummoner->isDead())
            continue;

        pSummoner->AI()->AttackStart(pImmolThar);
    }
    m_luiHighborneSummonerGUIDs.clear();
}
Example #3
0
        void UpdateAI(uint32 diff) override
        {
            if (CheckTimer <= diff)
            {
                if (AzgalorGUID)
                {
                    Creature* boss = ObjectAccessor::GetCreature(*me, AzgalorGUID);
                    if (!boss || (boss && boss->isDead()))
                    {
                        me->setDeathState(JUST_DIED);
                        me->RemoveCorpse();
                        return;
                    }
                }
                CheckTimer = 5000;
            } else CheckTimer -= diff;

            //Return since we have no target
            if (!UpdateVictim())
                return;

            if (WarstompTimer <= diff)
            {
                DoCast(me, SPELL_WARSTOMP);
                WarstompTimer = 10000 + rand32() % 5000;
            } else WarstompTimer -= diff;

            if (CrippleTimer <= diff)
            {
                DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_CRIPPLE);
                CrippleTimer = 25000 + rand32() % 5000;
            } else CrippleTimer -= diff;

            DoMeleeAttackIfReady();
        }
    void MoveInLineOfSight(Unit* /*who*/)
    {
        if (!GridSearcherSucceeded)
        {
            FindChannelers();

            if (!Channelers.empty())
            {
                for (std::list<uint64>::iterator itr = Channelers.begin(); itr != Channelers.end(); ++itr)
                {
                    Creature* Channeler = (Unit::GetCreature(*me, *itr));
                    if (Channeler)
                    {
                        if (Channeler->isDead())
                        {
                            Channeler->RemoveCorpse();
                            Channeler->Respawn();
                            Channeler->InterruptNonMeleeSpells(true);
                            Channeler->RemoveAurasDueToSpell(SPELL_SHADE_SOUL_CHANNEL);
                        }

                        if (Channeler->isAlive())
                        {
                            Channeler->CastSpell(me, SPELL_SHADE_SOUL_CHANNEL, true);
                            Channeler->CastSpell(me, SPELL_SHADE_SOUL_CHANNEL_2, true);
                            Channeler->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                            GridSearcherSucceeded = true;
                        }
                    }
                }
            } else error_log("BSCR ERROR: No Channelers are stored in the list. This encounter will not work properly");
        }
    }
        Creature* RespawnNearbyBugsAndGetOne()
        {
            CellCoord p(Oregon::ComputeCellCoord(me->GetPositionX(), me->GetPositionY()));
            Cell cell(p);
            cell.SetNoCreate();

            std::list<Creature*> unitList;

            AnyBugCheck u_check(me, 150);
            Oregon::CreatureListSearcher<AnyBugCheck> searcher(me, unitList, u_check);
            TypeContainerVisitor<Oregon::CreatureListSearcher<AnyBugCheck>, GridTypeMapContainer >  grid_creature_searcher(searcher);
            cell.Visit(p, grid_creature_searcher, *(me->GetMap()), *me, me->GetGridActivationRange());

            Creature* nearb = NULL;

            for (std::list<Creature*>::iterator iter = unitList.begin(); iter != unitList.end(); ++iter)
            {
                Creature* c = (Creature*)(*iter);
                if (c && c->isDead())
                {
                    c->Respawn();
                    c->SetFaction(7);
                    c->RemoveAllAuras();
                }
                if (c->IsWithinDistInMap(me, ABUSE_BUG_RANGE))
                {
                    if (!nearb || (rand() % 4) == 0)
                        nearb = c;
                }
            }
            return nearb;
        }
Example #6
0
        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

            if (Check_Timer <= diff)
            {
                Creature *Shaffar = me->FindNearestCreature(NPC_SHAFFAR, 100);
                if (!Shaffar || Shaffar->isDead() || !Shaffar->isInCombat())
                {
                    KillSelf();
                    return;
                }
                Check_Timer = 1000;
            } else Check_Timer -= diff;

            if (ArcaneBolt_Timer <= diff)
            {
                DoCast(me->getVictim(), SPELL_ARCANE_BOLT);
                ArcaneBolt_Timer = 2000 + rand()%2500;
            } else ArcaneBolt_Timer -= diff;

            if (Apprentice_Timer <= diff)
            {
                if (me->IsNonMeleeSpellCasted(false))
                    me->InterruptNonMeleeSpells(true);

                DoCast(me, SPELL_ETHEREAL_APPRENTICE, true);
                me->ForcedDespawn();
                return;
            } else Apprentice_Timer -= diff;
        }
Example #7
0
        void UpdateAI(const uint32 diff)
        {
            if (CheckTimer <= diff)
            {
                if (AnetheronGUID)
                {
                    Creature* boss = Unit::GetCreature((*me), AnetheronGUID);
                    if (!boss || (boss && boss->isDead()))
                    {
                        me->setDeathState(JUST_DIED);
                        me->RemoveCorpse();
                        return;
                    }
                }
                CheckTimer = 5000;
            } else CheckTimer -= diff;

            //Return since we have no target
            if (!UpdateVictim())
                return;

            if (ImmolationTimer <= diff)
            {
                DoCast(me, SPELL_IMMOLATION);
                ImmolationTimer = 5000;
            } else ImmolationTimer -= diff;

            DoMeleeAttackIfReady();
        }
Example #8
0
        void MoveInLineOfSight(Unit* /*who*/)
        {
            if (!GridSearcherSucceeded)
            {
                FindChannelers();

                if (!Channelers.empty())
                {
                    for (std::list<uint64>::const_iterator itr = Channelers.begin(); itr != Channelers.end(); ++itr)
                    {
                        Creature* Channeler = (Unit::GetCreature(*me, *itr));
                        if (Channeler)
                        {
                            if (Channeler->isDead())
                            {
                                Channeler->RemoveCorpse();
                                Channeler->Respawn();
                            }

                            Channeler->CastSpell(me, SPELL_SHADE_SOUL_CHANNEL, true);
                            Channeler->CastSpell(me, SPELL_SHADE_SOUL_CHANNEL_2, true);
                            Channeler->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                            GridSearcherSucceeded = true;
                        }
                    }
                }
                else
                    TC_LOG_ERROR(LOG_FILTER_TSCR, "SD2 ERROR: No Channelers are stored in the list. This encounter will not work properly");
            }
        }
void instance_dire_maul::SortPylonGuards()
{
    if (!m_lGeneratorGuardGUIDs.empty())
    {
        for (uint8 i = 0; i < MAX_GENERATORS; ++i)
        {
            GameObject* pGenerator = instance->GetGameObject(m_aCrystalGeneratorGuid[i]);
            // Skip non-existing or finished generators
            if (!pGenerator || GetData(TYPE_PYLON_1 + i) == DONE)
                continue;

            // Sort all remaining (alive) NPCs to unfinished generators
            for (GuidList::iterator itr = m_lGeneratorGuardGUIDs.begin(); itr != m_lGeneratorGuardGUIDs.end();)
            {
                Creature* pGuard = instance->GetCreature(*itr);
                if (!pGuard || pGuard->isDead())    // Remove invalid guids and dead guards
                {
                    m_lGeneratorGuardGUIDs.erase(itr++);
                    continue;
                }

                if (pGuard->IsWithinDist2d(pGenerator->GetPositionX(), pGenerator->GetPositionY(), 20.0f))
                {
                    m_sSortedGeneratorGuards[i].insert(pGuard->GetGUIDLow());
                    m_lGeneratorGuardGUIDs.erase(itr++);
                }
                else
                    ++itr;
            }
        }
    }
}
    Creature* RespawnNearbyBugsAndGetOne()
    {
        std::list<Creature*> lUnitList;
        me->GetCreatureListWithEntryInGrid(lUnitList, 15316, 150.0f);
        me->GetCreatureListWithEntryInGrid(lUnitList, 15317, 150.0f);

        if (lUnitList.empty())
            return NULL;

        Creature* nearb = NULL;

        for (std::list<Creature*>::const_iterator iter = lUnitList.begin(); iter != lUnitList.end(); ++iter)
        {
            Creature* c = *iter;
            if (c)
            {
                if (c->isDead())
                {
                    c->Respawn();
                    c->setFaction(7);
                    c->RemoveAllAuras();
                }
                if (c->IsWithinDistInMap(me, ABUSE_BUG_RANGE))
                {
                    if (!nearb || (rand()%4) == 0)
                        nearb = c;
                }
            }
        }
        return nearb;
    }
void WaypointMovementGenerator<Creature>::StartMove(Creature& creature)
{
    if (!i_path || i_path->empty())
        return;

    if (Stopped(creature))
        return;

    if (!creature.isAlive() || creature.hasUnitState(UNIT_STAT_NOT_MOVE))
        return;

    WaypointPath::const_iterator currPoint = i_path->find(i_currentNode);
    MANGOS_ASSERT(currPoint != i_path->end());

    if (WaypointBehavior* behavior = currPoint->second.behavior)
    {
        if (behavior->model2 != 0)
            creature.SetDisplayId(behavior->model2);
        creature.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
    }

    if (m_isArrivalDone)
    {
        bool reachedLast = false;
        ++currPoint;
        if (currPoint == i_path->end())
        {
            reachedLast = true;
            currPoint = i_path->begin();
        }

        // Inform AI
        if (creature.AI() && m_PathOrigin == PATH_FROM_EXTERNAL &&  m_pathId > 0)
        {
            if (!reachedLast)
                creature.AI()->MovementInform(EXTERNAL_WAYPOINT_MOVE_START + m_pathId, currPoint->first);
            else
                creature.AI()->MovementInform(EXTERNAL_WAYPOINT_FINISHED_LAST + m_pathId, currPoint->first);

            if (creature.isDead() || !creature.IsInWorld()) // Might have happened with above calls
                return;
        }

        i_currentNode = currPoint->first;
    }

    m_isArrivalDone = false;

    creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

    WaypointNode const& nextNode = currPoint->second;;
    Movement::MoveSplineInit init(creature);
    init.MoveTo(nextNode.x, nextNode.y, nextNode.z, true);

    if (nextNode.orientation != 100 && nextNode.delay != 0)
        init.SetFacing(nextNode.orientation);
    creature.SetWalk(!creature.hasUnitState(UNIT_STAT_RUNNING_STATE) && !creature.IsLevitating(), false);
    init.Launch();
}
Example #12
0
            void UpdateAI(uint32 const diff)
            {
                if (!UpdateVictim())
                    return;

                if (me->GetDistance(me->GetHomePosition()) > 60.0f)
                {
                    // Not blizzlike, hack to avoid an exploit
                    EnterEvadeMode();
                    return;
                }

                if (me->HasAura(SPELL_RIFT_SHIELD))
                {
                    if (uiChaoticRiftGUID)
                    {
                        Creature* Rift = ObjectAccessor::GetCreature(*me, uiChaoticRiftGUID);
                        if (Rift && Rift->isDead())
                        {
                            me->RemoveAurasDueToSpell(SPELL_RIFT_SHIELD);
                            uiChaoticRiftGUID = 0;
                        }
                        return;
                    }
                }
                else
                    uiChaoticRiftGUID = 0;

                if ((Phase == 0) && HealthBelowPct(50))
                {
                    Phase = 1;
                    DoScriptText(SAY_SHIELD, me);
                    DoCast(me, SPELL_RIFT_SHIELD);
                    if (Creature* Rift = me->SummonCreature(MOB_CHAOTIC_RIFT, RiftLocation[urand(0, 5)], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000))
                    {
                        //DoCast(Rift, SPELL_CHARGE_RIFT);
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                            Rift->AI()->AttackStart(target);
                        uiChaoticRiftGUID = Rift->GetGUID();
                        DoScriptText(SAY_RIFT , me);
                    }
                }

                if (uiSparkTimer <= diff)
                {
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                        DoCast(target, SPELL_SPARK);
                    uiSparkTimer = 5000;
                }
                else
                    uiSparkTimer -= diff;

                DoMeleeAttackIfReady();
            }
Example #13
0
 void EnterCombat(Unit * who)
 {
     // Send Shaffar to fight
     Creature* Shaffar = me->FindNearestCreature(NPC_SHAFFAR, 100);
     if (!Shaffar || Shaffar->isDead())
     {
         KillSelf();
         return;
     }
     if (!Shaffar->isInCombat())
         Shaffar->AI()->AttackStart(who);
 }
 void SummonChannelers()
 {
     for (uint8 i = 0; i < 5; ++i)
     {
         Creature* channeler = ObjectAccessor::GetCreature(*me, Channelers[i]);
         if (!channeler || channeler->isDead())
             channeler = me->SummonCreature(ENTRY_CHANNELER, ShadowmoonChannelers[i][0], ShadowmoonChannelers[i][1], ShadowmoonChannelers[i][2], ShadowmoonChannelers[i][3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
         if (channeler)
             Channelers[i] = channeler->GetGUID();
         else
             Channelers[i].Clear();
     }
 }
 void JustDied(Unit* /*who*/)
 {
     for (int ni=0; ni<3; ++ni)
     {
         Creature* sent = Unit::GetCreature(*me, NearbyGUID[ni]);
         if (!sent)
             continue;
         if (sent->isDead())
             continue;
         sent->ModifyHealth(int32(sent->CountPctFromMaxHealth(50)));
         CAST_AI(aqsentinelAI, sent->AI())->GainSentinelAbility(ability);
     }
 }
Example #16
0
            void RespawnMinions()
            {
                // first respawn any aggroed wall minions
                for (std::vector<uint64>::const_iterator i = vArchaedasWallMinions.begin(); i != vArchaedasWallMinions.end(); ++i)
                {
                    Creature* pTarget = instance->GetCreature(*i);
                    if (pTarget && pTarget->isDead())
                    {
                        pTarget->Respawn();
                        pTarget->GetMotionMaster()->MoveTargetedHome();
                        SetFrozenState(pTarget);
                    }
                }

                // Vault Walkers
                for (std::vector<uint64>::const_iterator i = vVaultWalker.begin(); i != vVaultWalker.end(); ++i)
                {
                    Creature* pTarget = instance->GetCreature(*i);
                    if (pTarget && pTarget->isDead())
                    {
                        pTarget->Respawn();
                        pTarget->GetMotionMaster()->MoveTargetedHome();
                        SetFrozenState(pTarget);
                    }
                }

                // Earthen Guardians
                for (std::vector<uint64>::const_iterator i = vEarthenGuardian.begin(); i != vEarthenGuardian.end(); ++i)
                {
                    Creature* pTarget = instance->GetCreature(*i);
                    if (pTarget && pTarget->isDead())
                    {
                        pTarget->Respawn();
                        pTarget->GetMotionMaster()->MoveTargetedHome();
                        SetFrozenState(pTarget);
                    }
                }
            }
        void UpdateAI(uint32 const diff)
        {
            if (!VorpilGUID)
            {
                me->Kill(me);
                return;
            }

            if (move <= diff)
            {
                Creature* Vorpil = Unit::GetCreature(*me, VorpilGUID);
                if (!Vorpil)
                {
                    VorpilGUID = 0;
                    return;
                }

                if (sacrificed)
                {
                    if (Vorpil->isAlive())
                    {
                        me->AddAura(DUNGEON_MODE(SPELL_EMPOWERING_SHADOWS, H_SPELL_EMPOWERING_SHADOWS), Vorpil);
                        Vorpil->ModifyHealth(int32(Vorpil->CountPctFromMaxHealth(4)));
                    }
                    DoCast(me, SPELL_SHADOW_NOVA, true);
                    me->Kill(me);
                    return;
                }

                me->GetMotionMaster()->MoveFollow(Vorpil, 0, 0);

                if (me->IsWithinDist(Vorpil, 3))
                {
                    DoCast(me, SPELL_SACRIFICE, false);
                    sacrificed = true;
                    move = 500;
                    return;
                }

                if (!Vorpil->isInCombat() || Vorpil->isDead())
                {
                    me->Kill(me);
                    return;
                }
                move = 1000;
            }
            else
                move -= diff;
        }
Example #18
0
		void UpdateAI(uint32 diff)
		{	
			if (pTarget == NULL || !isAtAnEgg || me->HasUnitState(UNIT_STATE_CASTING))
				return;

			events.Update(diff);

			while (uint32 eventId = events.ExecuteEvent())
			{
				switch (eventId)
				{
				case EVENT_CAST_SHIELD_OF_NIGHTMARE_DELAY:
					DoCast(me, SPELL_SHIELD_OF_NIGHTMARE, true);
					break;

				default:
					break;
				}
			}

			if(isCastingUmbraMending)
			{	// If the Egg is Death and Umbra Mending was casted go to the next Egg

				pTarget = GetNextEgg();

				if(pTarget != NULL) // Solves Crashes if the Faceless killed all eggs
					me->GetMotionMaster()->MovePoint(POINT_FACELESS_IS_AT_AN_EGG,pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ());

				isAtAnEgg = false;
				isCastingUmbraMending = false;

				return;
			}

			if(pTarget->isDead())
			{
				if(Unit* pErudax = me->FindNearestCreature(BOSS_ERUDAX,1000.0f, true))
					DoCast(pErudax, SPELL_UMBRAL_MENDING,false);

				isCastingUmbraMending = true;

				return;
			}

			pTarget->AI()->DoZoneInCombat();

			DoCast(pTarget,SPELL_TWILIGHT_CORRUPTION_DOT,true);
			DoCast(pTarget,SPELL_TWILIGHT_CORRUPTION_VISUAL,true);
		}
Example #19
0
 void JustDied(Unit* /*killer*/)
 {
     if(pInstance && pInstance->GetData(DATA_SINDRAGOSA_EVENT) != DONE)
     {
         Creature* dragon = Unit::GetCreature(*me, pInstance->GetData64(DATA_RIMEFANG));
         if(dragon && dragon->isDead())
         {
             Creature* DragonBoss = me->SummonCreature(CREATURE_SINDRAGOSA, SpawnLoc[1], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,30000);
             /*if(DragonBoss)
             {
                 DragonBoss->GetMotionMaster()->MovePoint(0, SpawnLoc[1]);
             }*/
         }
     }
 }
            void SummonChannelers()
            {
                for (uint8 i = 0; i < 5; ++i)
                {
                    Creature* channeler = ObjectAccessor::GetCreature(*me, channelers[i]);
                    if (channeler && channeler->isDead())
                    {
                        channeler->DespawnOrUnsummon(1);
                        channeler = NULL;
                    }
                    if (!channeler)
                        channeler = me->SummonCreature(NPC_CHANNELER, ShadowmoonChannelers[i][0], ShadowmoonChannelers[i][1], ShadowmoonChannelers[i][2], ShadowmoonChannelers[i][3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);

                    channelers[i] = channeler ? channeler->GetGUID() : 0;
                }
            }
    void Update(uint32 diff)
    {
        if (!check && !RitualistGUIDList.empty())
        {
            for (std::list<uint64>::iterator iter = RitualistGUIDList.begin(); iter != RitualistGUIDList.end(); ++iter)
            {
                Creature* ritualist = instance->GetCreature(*iter);
                if (ritualist && ritualist->isDead())
                    --RitualistCount;
            }

            if (!RitualistCount)
                Encounter[1] = DONE;

            check = true;
        }
    }
            void ResetBossEncounter(uint8 bossId)
            {
                if (bossId < DATA_CYANIGOSA || bossId > DATA_ZURAMAT)
                    return;

                Creature* boss = GetCreature(bossId);
                if (!boss)
                    return;

                switch (bossId)
                {
                    case DATA_CYANIGOSA:
                        boss->DespawnOrUnsummon();
                        break;
                    case DATA_EREKEM:
                        for (uint32 i = DATA_EREKEM_GUARD_1; i <= DATA_EREKEM_GUARD_2; ++i)
                        {
                            if (Creature* guard = instance->GetCreature(GetGuidData(i)))
                            {
                                if (guard->isDead())
                                    guard->Respawn();

                                if (GetBossState(bossId) == DONE)
                                    UpdateKilledBoss(guard);

                                guard->GetMotionMaster()->MoveTargetedHome();
                                guard->SetImmuneToAll(true);
                            }
                        }
                        /* fallthrough */
                    default:
                        if (boss->isDead())
                        {
                            // respawn and update to a placeholder npc to avoid be looted again
                            boss->Respawn();
                            UpdateKilledBoss(boss);
                        }

                        boss->GetMotionMaster()->MoveTargetedHome();
                        boss->SetImmuneToAll(true);
                        break;
                }
            }
Example #23
0
        void EnterCombat(Unit* /*who*/)
        {
            if(pInstance && pInstance->GetData(DATA_SINDRAGOSA_EVENT) == NOT_STARTED)
            {
                pInstance->SetData(DATA_SINDRAGOSA_EVENT, IN_PROGRESS);
            }

            Creature* dragon = me->GetCreature(*me, pInstance->GetData64(DATA_RIMEFANG));
            if (dragon)
            {
                if(dragon->isDead())
                {
                    dragon->Respawn();
                }
                else
                {
                    dragon->SetInCombatWithZone();
                }
            }
        }
Example #24
0
        void EnterCombat(Unit* /*who*/)
        {
            if(pInstance && pInstance->GetData(DATA_SINDRAGOSA_EVENT) == NOT_STARTED)
            {
                pInstance->SetData(DATA_SINDRAGOSA_EVENT, IN_PROGRESS);
            }

            Creature* dragon = Unit::GetCreature(*me, pInstance->GetData64(DATA_SPINESTALKER));
            if (dragon)
            {
                if(dragon->isDead())
                {
                    dragon->Respawn();
                }
                else
                {
                    DoCast(me, SPELL_FROST_AURA_ADD);
                    dragon->SetInCombatWithZone();
                }
            }
        }
Example #25
0
    void UpdateAI(const uint32 diff)
    {
        if (!VorpilGUID)
        {
            m_creature->Kill(m_creature);
            return;
        }
        if (move <= diff)
        {
            Creature *Vorpil = Unit::GetCreature(*m_creature, VorpilGUID);
            if (!Vorpil)
            {
                VorpilGUID = 0;
                return;
            }

            if (sacrificed)
            {
                m_creature->AddAura(DUNGEON_MODE(SPELL_EMPOWERING_SHADOWS, H_SPELL_EMPOWERING_SHADOWS), Vorpil);
                Vorpil->SetHealth(Vorpil->GetHealth() + Vorpil->GetMaxHealth()/25);
                DoCast(m_creature, SPELL_SHADOW_NOVA, true);
                m_creature->Kill(m_creature);
                return;
            }
            m_creature->GetMotionMaster()->MoveFollow(Vorpil,0,0);
            if (m_creature->IsWithinDist(Vorpil, 3))
            {
                DoCast(m_creature, SPELL_SACRIFICE, false);
                sacrificed = true;
                move = 500;
                return;
            }
            if (!Vorpil->isInCombat() || Vorpil->isDead())
            {
                m_creature->Kill(m_creature);
                return;
            }
            move = 1000;
        } else move -= diff;
    }
Example #26
0
//////////////////////////////////////////////////////////////////////////////
// 뱀파이어 타일 핸들러
//////////////////////////////////////////////////////////////////////////////
void BloodyBreaker::execute(Vampire* pVampire, ZoneCoord_t X, ZoneCoord_t Y, VampireSkillSlot* pVampireSkillSlot, CEffectID_t CEffectID)
	throw(Error)
{
	__BEGIN_TRY

	//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << "begin " << endl;
	SkillType_t SkillType = getSkillType();

	// Knowledge of Blood 가 있다면 hit bonus 10
	int HitBonus = 0;
	if (pVampire->hasRankBonus(RankBonus::RANK_BONUS_KNOWLEDGE_OF_BLOOD ) )
	{
		RankBonus* pRankBonus = pVampire->getRankBonus(RankBonus::RANK_BONUS_KNOWLEDGE_OF_BLOOD);
		Assert(pRankBonus != NULL);

		HitBonus = pRankBonus->getPoint();
	}

	try 
	{
		SkillInput input(pVampire);
		SkillOutput output;
		computeOutput(input, output);

		Dir_t	Dir		= getDirectionToPosition(pVampire->getX(), pVampire->getY(), X, Y);

		// 강제로 knockback시킬 확률
//		bool bForceKnockback = rand()%100 < output.ToHit;

		Player* pPlayer = pVampire->getPlayer();
		Zone* pZone = pVampire->getZone();
		Assert(pPlayer != NULL);
		Assert(pZone != NULL);

		VSRect rect(1, 1, pZone->getWidth()-2, pZone->getHeight()-2);
		if (!rect.ptInRect(X, Y ))
		{
			executeSkillFailException(pVampire, SkillType);
			return;
		}


		GCSkillToTileOK1 _GCSkillToTileOK1;
		GCSkillToTileOK2 _GCSkillToTileOK2;
//		GCSkillToTileOK3 _GCSkillToTileOK3;
//		GCSkillToTileOK4 _GCSkillToTileOK4;
		GCSkillToTileOK5 _GCSkillToTileOK5;
//		GCSkillToTileOK6 _GCSkillToTileOK6;

		SkillInfo*  pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType);

		int  RequiredMP  = decreaseConsumeMP(pVampire, pSkillInfo);
		bool bManaCheck  = hasEnoughMana(pVampire, RequiredMP);
		bool bTimeCheck  = verifyRunTime(pVampireSkillSlot);
		bool bRangeCheck = verifyDistance(pVampire, X, Y, pSkillInfo->getRange());

		if (bManaCheck && bTimeCheck && bRangeCheck )
		{
			// 마나를 떨어뜨린다.
			decreaseMana(pVampire, RequiredMP, _GCSkillToTileOK1);

			// 좌표와 방향을 구한다.
			ZoneCoord_t myX          = pVampire->getX();
			ZoneCoord_t myY          = pVampire->getY();
			Dir_t       dir          = calcDirection(myX, myY, X, Y);

			list<Creature*> cList;

			// knockback 때문에 recursive 하게 데미지를 먹는 경우가 있다.
			// 그래서 제일 먼쪽에 있는 마스크부터 체크한다.
			for (int i = 21; i >= 0; i-- )
			{
				int tileX   = myX + m_pBloodyBreakerMask[Dir][i].x;
				int tileY   = myY + m_pBloodyBreakerMask[Dir][i].y;

				// 현재 타일이 존 내부이고, 안전지대가 아니라면 맞을 가능성이 있다.
				if (rect.ptInRect(tileX, tileY))
				{
					// 타일을 받아온다.
					Tile& tile = pZone->getTile(tileX, tileY);

					list<Creature*> targetList;
					if (tile.hasCreature(Creature::MOVE_MODE_WALKING))
					{
						Creature* pCreature = tile.getCreature(Creature::MOVE_MODE_WALKING);
						targetList.push_back(pCreature);
					}
					if (tile.hasCreature(Creature::MOVE_MODE_FLYING))
					{
						Creature* pCreature = tile.getCreature(Creature::MOVE_MODE_FLYING);
						targetList.push_back(pCreature);
					}
					if (tile.hasCreature(Creature::MOVE_MODE_BURROWING))
					{
						Creature* pCreature = tile.getCreature(Creature::MOVE_MODE_BURROWING);
						targetList.push_back(pCreature);
					}

					list<Creature*>::iterator itr = targetList.begin();
					for(; itr != targetList.end(); itr++)
					{
						Creature* pTargetCreature = (*itr);
						Assert(pTargetCreature != NULL);

						if (!canAttack(pVampire, pTargetCreature )
							|| pTargetCreature->isFlag(Effect::EFFECT_CLASS_COMA) )
						{
							continue;
						}

						if (pTargetCreature != pVampire)
						{
							bool bPK             = verifyPK(pVampire, pTargetCreature);
							bool bRaceCheck      = pTargetCreature->isSlayer() || pTargetCreature->isMonster() || pTargetCreature->isOusters();
							bool bZoneLevelCheck = checkZoneLevelToHitTarget(pTargetCreature);
							bool bHitRoll        = false;//HitRoll::isSuccessMagic(pVampire, pSkillInfo, pVampireSkillSlot, HitBonus);

							int EnemyLevel = 0;

							if (pTargetCreature->isSlayer() )
							{
								Slayer* pSlayer = dynamic_cast<Slayer*>(pTargetCreature);
								EnemyLevel = pSlayer->getHighestSkillDomainLevel();
							}
							else if (pTargetCreature->isOusters() )
							{
								Ousters* pOusters = dynamic_cast<Ousters*>(pTargetCreature);
								EnemyLevel = pOusters->getLevel();
							}
							else if (pTargetCreature->isMonster() )
							{
								Monster* pMonster = dynamic_cast<Monster*>(pTargetCreature);
								EnemyLevel = pMonster->getLevel();
							}

							// min : 20, max : 100
							int hitRatio = max(20, 50 + pVampire->getLevel() - EnemyLevel + HitBonus);
							bHitRoll = (rand()%100) < hitRatio;

							if (bPK && bRaceCheck && bZoneLevelCheck && bHitRoll)
							{
								Damage_t Damage = 0;
								bool bForceKnockback = rand() & 1;

								Damage += computeMagicDamage(pTargetCreature, output.Damage, SkillType, true, pVampire);

								ObjectID_t targetObjectID = pTargetCreature->getObjectID();
								cList.push_back(pTargetCreature);

								_GCSkillToTileOK1.addCListElement(targetObjectID);
								_GCSkillToTileOK2.addCListElement(targetObjectID);
								_GCSkillToTileOK5.addCListElement(targetObjectID);

								// 일단 맞는 놈이 받을 패킷은 널 상태로 한 채로, 데미지를 준다.
								setDamage(pTargetCreature, Damage, pVampire, SkillType, NULL, &_GCSkillToTileOK1);
								computeAlignmentChange(pTargetCreature, Damage, pVampire, NULL, &_GCSkillToTileOK1);

								increaseAlignment(pVampire, pTargetCreature, _GCSkillToTileOK1);

								// 크리티컬 히트라면 상대방을 뒤로 물러나게 한다.
								if (bForceKnockback)
								{
									knockbackCreature(pZone, pTargetCreature, pVampire->getX(), pVampire->getY());
								}

								if (pTargetCreature->isDead())
								{
									int exp = computeCreatureExp(pTargetCreature, KILL_EXP);
									shareVampExp(pVampire, exp, _GCSkillToTileOK1);
								}
							}
						}
					}
				}
			}


			// 공격자의 아이템 내구성을 떨어뜨린다.
			decreaseDurability(pVampire, NULL, pSkillInfo, &_GCSkillToTileOK1, NULL);

			_GCSkillToTileOK1.setSkillType(SkillType);
			_GCSkillToTileOK1.setCEffectID(0);
			_GCSkillToTileOK1.setX(X);
			_GCSkillToTileOK1.setY(Y);
			_GCSkillToTileOK1.setRange(dir);
			_GCSkillToTileOK1.setDuration(0);

			_GCSkillToTileOK2.setObjectID(pVampire->getObjectID());
			_GCSkillToTileOK2.setSkillType(SkillType);
			_GCSkillToTileOK2.setX(X);
			_GCSkillToTileOK2.setY(Y);
			_GCSkillToTileOK2.setRange(dir);
			_GCSkillToTileOK2.setDuration(0);

			_GCSkillToTileOK5.setObjectID(pVampire->getObjectID());
			_GCSkillToTileOK5.setSkillType(SkillType);
			_GCSkillToTileOK5.setX(X);
			_GCSkillToTileOK5.setY(Y);
			_GCSkillToTileOK5.setRange(dir);
			_GCSkillToTileOK5.setDuration(0);

			pPlayer->sendPacket(&_GCSkillToTileOK1);

			// 이 기술에 의해 영향을 받는 놈들에게 패킷을 보내줘야 한다.
			for (list<Creature*>::const_iterator itr = cList.begin(); itr != cList.end(); itr++)
			{
				Creature * pTargetCreature = *itr;
				Assert(pTargetCreature != NULL);

				if (pTargetCreature->isPC())
				{
					_GCSkillToTileOK2.clearList();

					// HP의 변경사항을 패킷에다 기록한다.
					HP_t targetHP = 0;
					if (pTargetCreature->isSlayer())
					{
						targetHP = (dynamic_cast<Slayer*>(pTargetCreature))->getHP(ATTR_CURRENT);
					}
					else if (pTargetCreature->isVampire())
					{
						targetHP = (dynamic_cast<Vampire*>(pTargetCreature))->getHP(ATTR_CURRENT);
					}
					else if (pTargetCreature->isOusters())
					{
						targetHP = (dynamic_cast<Ousters*>(pTargetCreature))->getHP(ATTR_CURRENT);
					}

					_GCSkillToTileOK2.addShortData(MODIFY_CURRENT_HP, targetHP);

					// 아이템의 내구력을 떨어뜨린다.
					decreaseDurability(NULL, pTargetCreature, pSkillInfo, NULL, &_GCSkillToTileOK2);

					// 패킷을 보내준다.
					pTargetCreature->getPlayer()->sendPacket(&_GCSkillToTileOK2);
				}
				else if (pTargetCreature->isMonster())
				{
					// 당근 적으로 인식한다.
					Monster* pMonster = dynamic_cast<Monster*>(pTargetCreature);
					pMonster->addEnemy(pVampire);
				}
			}

			cList.push_back(pVampire);

			pZone->broadcastPacket(myX, myY, &_GCSkillToTileOK5 , cList);

			// set Next Run Time
			pVampireSkillSlot->setRunTime(output.Delay);
		}
		else 
		{
			executeSkillFailNormal(pVampire, SkillType, NULL);
		}
	}
	catch (Throwable & t) 
	{
		executeSkillFailException(pVampire, SkillType);
	}

//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " end " << endl;

	__END_CATCH
}
Example #27
0
void instance_zulfarrak::Update(uint32 uiDiff)
{
    // Pyramide Trash
    if (GetData(TYPE_PYRAMIDE) == IN_PROGRESS || GetData(TYPE_PYRAMIDE) == SPECIAL)
    {
		if (GetData(TYPE_PYRAMIDE) == IN_PROGRESS && m_uiPyramideTrash.size() <= 15 && m_uiPyramideTrashTemp.empty())
			SetData(TYPE_PYRAMIDE, SPECIAL);	//Make Bly's crew walk downstairs

        if (m_uiCheckPyramideTrash_Timer <= uiDiff && m_uiWave < 6)
        {
            debug_log("SD0: Instance Zul'Farrak: Pyramide event: Sending 2 trolls up stairs.");

			for (uint32 i = 0; i < 5; i++) {
            if (!m_uiPyramideNPCs[i].empty())
			{
                for(GUIDList::iterator itr = m_uiPyramideNPCs[i].begin(); itr != m_uiPyramideNPCs[i].end(); ++itr)
				{
                    if (Creature* pTroll = instance->GetCreature(*itr))
					{
                        if (!pTroll->isDead() || pTroll->isAlive())
                        {
                            if (++m_uiTrollsMovedCount > spawnNumber[m_uiWave][i])
                            {
                                m_uiTrollsMovedCount = 0;
                                break;
                            }

                            // Move troll up Stairs
                            if (!pTroll->getVictim())
                            {
                                pTroll->GetMotionMaster()->Clear();
                                pTroll->GetMotionMaster()->MovePoint(1, 1886.31f, 1269.72f, 42.f);
								CreatureCreatePos pos(pTroll->GetMap(), 1886.31f, 1269.72f, 42.f, 0.0f);
								pTroll->SetSummonPoint(pos);
                            }

							m_uiPyramideTrashTemp.push_back(pTroll->GetObjectGuid());
                            itr = m_uiPyramideNPCs[i].erase(itr);
                        }
					}
				}
			}
			}
			m_uiWave++;
			m_uiCheckPyramideTrash_Timer = 40000;
		}
        else m_uiCheckPyramideTrash_Timer -= uiDiff;
	}

    // Nekrum death state checker
    if (GetData(TYPE_PYRAMIDE) != DONE)
	{
	    Creature* pNekrum = GetSingleCreatureFromStorage(NPC_NEKRUM_GUTCHEWER);
        if (pNekrum && pNekrum->isDead())
        {
            SetData(TYPE_PYRAMIDE, DONE);
            m_uiPyramideTrash.clear();
        }
	}

    // Bomb explodation
    if (m_uiBombExplodationExpire_Timer)
    {
        if (m_uiBombExplodationExpire_Timer <= uiDiff)
        {
            // Bomb explodation
            GameObject* DoorExplosive = GetSingleGameObjectFromStorage(GO_DOOR_EXPLOSIVE);
			if (DoorExplosive && DoorExplosive->GetGoState() != GO_STATE_ACTIVE_ALTERNATIVE)
				DoorExplosive->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
            // Door opened by exploding bomb
            GameObject* EndDoor = GetSingleGameObjectFromStorage(GO_END_DOOR);
			if (EndDoor && EndDoor->GetGoState() != GO_STATE_ACTIVE_ALTERNATIVE)
				EndDoor->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
        }
        else
			m_uiBombExplodationExpire_Timer -= uiDiff;
    }

    // Bly's crew use Heartstone after defeating trolls
    //if (m_uiBlysBandHeartstone_Timer)
    //    if ( (GetData(TYPE_PYRAMIDE) == DONE) && (m_uiBlysBandHeartstone_Timer <= uiDiff) )
    //    {
    //        Creature* pBly = GetSingleCreatureFromStorage(NPC_SERGEANT_BLY);
    //        if (pBly && pBly->isAlive() && !pBly->getVictim())
    //            pBly->CastSpell(pBly, SPELL_BLYS_BANDS_ESCAPE, false);
    //        Creature* pRaven = GetSingleCreatureFromStorage(NPC_RAVEN);
    //        if (pRaven && pRaven->isAlive() && !pRaven->getVictim())
    //            pRaven->CastSpell(pRaven, SPELL_BLYS_BANDS_ESCAPE, false);
    //        Creature* pOro = GetSingleCreatureFromStorage(NPC_ORO_EYEGOUGE);
    //        if (pOro && pOro->isAlive() && !pOro->getVictim())
    //            pOro->CastSpell(pOro, SPELL_BLYS_BANDS_ESCAPE, false);
    //        Creature* pMurta = GetSingleCreatureFromStorage(NPC_MURTA_GRIMGUT);
    //        if (pMurta && pMurta->isAlive() && !pMurta->getVictim())
    //            pMurta->CastSpell(pMurta, SPELL_BLYS_BANDS_ESCAPE, false);
    //
    //        m_uiBlysBandHeartstone_Timer = 0;
    //    }
    //    else m_uiBlysBandHeartstone_Timer -= uiDiff;
}
        void StartBossEncounter(uint8 uiBoss, bool bForceRespawn = true)
        {
            Creature* boss = nullptr;

            switch (uiBoss)
            {
                case BOSS_MORAGG:
                    HandleGameObject(GetObjectGuid(DATA_MORAGG_CELL), bForceRespawn);
                    boss = GetCreature(DATA_MORAGG);
                    if (boss)
                        boss->GetMotionMaster()->MovePoint(0, BossStartMove1);
                    break;
                case BOSS_EREKEM:
                    HandleGameObject(GetObjectGuid(DATA_EREKEM_CELL), bForceRespawn);
                    HandleGameObject(GetObjectGuid(DATA_EREKEM_LEFT_GUARD_CELL), bForceRespawn);
                    HandleGameObject(GetObjectGuid(DATA_EREKEM_RIGHT_GUARD_CELL), bForceRespawn);

                    boss = GetCreature(DATA_EREKEM);
                    if (boss)
                        boss->GetMotionMaster()->MovePoint(0, BossStartMove2);

                    if (Creature* pGuard1 = instance->GetCreature(uiErekemGuard[0]))
                    {
                        if (bForceRespawn)
                            pGuard1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
                        else
                            pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
                        pGuard1->GetMotionMaster()->MovePoint(0, BossStartMove21);
                    }

                    if (Creature* pGuard2 = instance->GetCreature(uiErekemGuard[1]))
                    {
                        if (bForceRespawn)
                            pGuard2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
                        else
                            pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
                        pGuard2->GetMotionMaster()->MovePoint(0, BossStartMove22);
                    }
                    break;
                case BOSS_ICHORON:
                    HandleGameObject(GetObjectGuid(DATA_ICHORON_CELL), bForceRespawn);
                    boss = GetCreature(DATA_ICHORON);
                    if (boss)
                        boss->GetMotionMaster()->MovePoint(0, BossStartMove3);
                    break;
                case BOSS_LAVANTHOR:
                    HandleGameObject(GetObjectGuid(DATA_LAVANTHOR_CELL), bForceRespawn);
                    boss = GetCreature(DATA_LAVANTHOR);
                    if (boss)
                        boss->GetMotionMaster()->MovePoint(0, BossStartMove4);
                    break;
                case BOSS_XEVOZZ:
                    HandleGameObject(GetObjectGuid(DATA_XEVOZZ_CELL), bForceRespawn);
                    boss = GetCreature(DATA_XEVOZZ);
                    if (boss)
                        boss->GetMotionMaster()->MovePoint(0, BossStartMove5);
                    break;
                case BOSS_ZURAMAT:
                    HandleGameObject(GetObjectGuid(DATA_ZURAMAT_CELL), bForceRespawn);
                    boss = GetCreature(DATA_ZURAMAT);
                    if (boss)
                        boss->GetMotionMaster()->MovePoint(0, BossStartMove6);
                    break;
            }

            // generic boss state changes
            if (boss)
            {
                boss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
                boss->SetReactState(REACT_AGGRESSIVE);

                if (!bForceRespawn)
                {
                    if (boss->isDead())
                    {
                        // respawn but avoid to be looted again
                        boss->Respawn();
                        boss->RemoveLootMode(1);
                    }
                    boss->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
                    uiWaveCount = 0;
                }
            }
        }
Example #29
0
    void StartBossEncounter(uint8 uiBoss, bool bForceRespawn = true)
    {
        Creature* pBoss = NULL;

        switch(uiBoss)
        {
            case BOSS_MORAGG:
                HandleGameObject(uiMoraggCell,bForceRespawn);
                pBoss = instance->GetCreature(uiMoragg);
                if (pBoss)
                    pBoss->GetMotionMaster()->MovePoint(0, BossStartMove1);
                break;
            case BOSS_EREKEM:
                HandleGameObject(uiErekemCell, bForceRespawn);
                HandleGameObject(uiErekemRightGuardCell, bForceRespawn);
                HandleGameObject(uiErekemLeftGuardCell, bForceRespawn);

                pBoss = instance->GetCreature(uiErekem);

                if (pBoss)
                    pBoss->GetMotionMaster()->MovePoint(0, BossStartMove2);

                if (Creature* pGuard1 = instance->GetCreature(uiErekemGuard[0]))
                {
                    if (bForceRespawn)
                        pGuard1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
                    else
                        pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
                    pGuard1->GetMotionMaster()->MovePoint(0, BossStartMove21);
                }

                if (Creature* pGuard2 = instance->GetCreature(uiErekemGuard[1]))
                {
                    if (bForceRespawn)
                        pGuard2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
                    else
                        pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
                    pGuard2->GetMotionMaster()->MovePoint(0, BossStartMove22);
                }
                break;
            case BOSS_ICHORON:
                HandleGameObject(uiIchoronCell,bForceRespawn);
                pBoss = instance->GetCreature(uiIchoron);
                if (pBoss)
                    pBoss->GetMotionMaster()->MovePoint(0, BossStartMove3);
                break;
            case BOSS_LAVANTHOR:
                HandleGameObject(uiLavanthorCell,bForceRespawn);
                pBoss = instance->GetCreature(uiLavanthor);
                if (pBoss)
                    pBoss->GetMotionMaster()->MovePoint(0, BossStartMove4);
                break;
            case BOSS_XEVOZZ:
                HandleGameObject(uiXevozzCell,bForceRespawn);
                pBoss = instance->GetCreature(uiXevozz);
                if (pBoss)
                    pBoss->GetMotionMaster()->MovePoint(0, BossStartMove5);
                break;
            case BOSS_ZURAMAT:
                HandleGameObject(uiZuramatCell,bForceRespawn);
                pBoss = instance->GetCreature(uiZuramat);
                if (pBoss)
                    pBoss->GetMotionMaster()->MovePoint(0, BossStartMove6);
                break;
        }

        // generic boss state changes
        if (pBoss)
        {
            pBoss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
            pBoss->SetReactState(REACT_AGGRESSIVE);

            if (!bForceRespawn)
            {
                if (pBoss->isDead())
                {
                    // respawn but avoid to be looted again
                    pBoss->Respawn();
                    pBoss->RemoveLootMode(1);
                }
                pBoss->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE|UNIT_FLAG_NON_ATTACKABLE);
                uiWaveCount = 0;
            }
        }
    }
Example #30
0
//////////////////////////////////////////////////////////////////////////////
// 아우스터즈 오브젝트 핸들러
//////////////////////////////////////////////////////////////////////////////
void ChargingAttack::execute(Ousters * pOusters, ObjectID_t TargetObjectID, OustersSkillSlot * pOustersSkillSlot, CEffectID_t CEffectID)
	throw(Error)
{
	__BEGIN_TRY

	//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " Begin" << endl;

	Assert(pOusters != NULL);
	Assert(pOustersSkillSlot != NULL);

	try 
	{
		Player* pPlayer = pOusters->getPlayer();
		Zone* pZone = pOusters->getZone();
		Assert(pPlayer != NULL);
		Assert(pZone != NULL);

		Creature* pTargetCreature = pZone->getCreature(TargetObjectID);
		//Assert(pTargetCreature != NULL);

		// NoSuch제거. by sigi. 2002.5.2
		// NPC는 공격할 수가 없다.
		if (pTargetCreature==NULL
			|| pTargetCreature->isNPC())
		{
			executeSkillFailException(pOusters, getSkillType());
			//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl;
			return;
		}

		// 무장하고 있는 무기가 널이거나, 검이 아니라면 기술을 사용할 수 없다.
		Item* pItem = pOusters->getWearItem(Ousters::WEAR_RIGHTHAND);
		if (pItem == NULL)
		{
			executeSkillFailException(pOusters, getSkillType());
			//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl;
			return;
		}

		GCSkillToObjectOK1 _GCSkillToObjectOK1;
		GCSkillToObjectOK2 _GCSkillToObjectOK2;

		SkillType_t       SkillType  = pOustersSkillSlot->getSkillType();
		SkillInfo*        pSkillInfo = g_pSkillInfoManager->getSkillInfo(SkillType);
		SkillLevel_t      SkillLevel = pOustersSkillSlot->getExpLevel();

		SkillInput input(pOusters, pOustersSkillSlot);
		SkillOutput output;
		computeOutput(input, output);

		int  RequiredMP  = (int)pSkillInfo->getConsumeMP();
		bool bManaCheck  = hasEnoughMana(pOusters, RequiredMP);
		bool bTimeCheck  = verifyRunTime(pOustersSkillSlot);
		bool bRangeCheck = verifyDistance(pOusters, pTargetCreature, output.Range);
		bool bHitRoll    = HitRoll::isSuccess(pOusters, pTargetCreature, SkillLevel/2);
		bool bCanHit     = canHit(pOusters, pTargetCreature, SkillType) && canAttack(pOusters, pTargetCreature);
		bool bPK         = verifyPK(pOusters, pTargetCreature);
		bool bEffected	 = pOusters->hasRelicItem() 
							|| pOusters->isFlag(Effect::EFFECT_CLASS_HAS_FLAG)
							|| pOusters->isFlag(Effect::EFFECT_CLASS_HAS_SWEEPER);

		if (bManaCheck && bTimeCheck && bRangeCheck && bHitRoll && bCanHit && bPK && !bEffected )
		{
			// 빠르게 PC를 움직여준다.
			if (pZone->moveFastPC(pOusters, pOusters->getX(), pOusters->getY(), pTargetCreature->getX(), pTargetCreature->getY(), getSkillType())) 
			{
				decreaseMana(pOusters, RequiredMP, _GCSkillToObjectOK1);

				bool bCriticalHit = false;

				// 데미지를 준다.
				Damage_t Damage = computeDamage(pOusters, pTargetCreature, 0, bCriticalHit) + output.Damage;
				setDamage(pTargetCreature, Damage, pOusters, SkillType, &_GCSkillToObjectOK2, &_GCSkillToObjectOK1);
				computeAlignmentChange(pTargetCreature, Damage, pOusters, &_GCSkillToObjectOK2, &_GCSkillToObjectOK1);
				decreaseDurability(pOusters, pTargetCreature, pSkillInfo, &_GCSkillToObjectOK1, &_GCSkillToObjectOK2);

				// 크리티컬 히트라면 상대방을 뒤로 물러나게 한다.
				if (bCriticalHit)
				{
					knockbackCreature(pZone, pTargetCreature, pOusters->getX(), pOusters->getY());
				}

				if (pTargetCreature->isDead())
				{
					int exp = computeCreatureExp(pTargetCreature, 100, pOusters);
					shareOustersExp(pOusters, exp, _GCSkillToObjectOK1);
				}

				// 패킷을 준비하고 보낸다.
				_GCSkillToObjectOK1.setSkillType(SkillType);
				_GCSkillToObjectOK1.setCEffectID(CEffectID);
				_GCSkillToObjectOK1.setTargetObjectID(TargetObjectID);
				_GCSkillToObjectOK1.setDuration(0);

				pPlayer->sendPacket(&_GCSkillToObjectOK1);
				_GCSkillToObjectOK2.setObjectID(pOusters->getObjectID());
				_GCSkillToObjectOK2.setSkillType(SkillType);
				_GCSkillToObjectOK2.setDuration(0);

				if (pTargetCreature->isPC()) 
				{
					Player* pTargetPlayer = pTargetCreature->getPlayer();
					Assert(pTargetPlayer != NULL);
					pTargetPlayer->sendPacket(&_GCSkillToObjectOK2);
				} 
				else 
				{
					Monster * pMonster = dynamic_cast<Monster*>(pTargetCreature);
					pMonster->addEnemy(pOusters);
				}

				pOustersSkillSlot->setRunTime(output.Delay);

			} 
			else 
			{
				executeSkillFailNormal(pOusters, getSkillType(), pTargetCreature);
			}
		} 
		else 
		{
			executeSkillFailNormal(pOusters, getSkillType(), pTargetCreature);
		}
	} 
	catch (Throwable & t) 
	{
		executeSkillFailException(pOusters, getSkillType());
	}

	//cout << "TID[" << Thread::self() << "]" << getSkillHandlerName() << " End" << endl;

	__END_CATCH
}