void SummonCreature()
 {
     uint32 random = rand()%2;
     float X = SpawnLocations[random].x;
     float Y = SpawnLocations[random].y;
     // max of 6 sorcerers can be summoned
     if ((rand()%3 == 0) && (DeathCount > 0) && (SorcererCount < 7))
     {
         Creature* Sorcerer = me->SummonCreature(CREATURE_SORCERER, X, Y, Z_SPAWN, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
         if (Sorcerer)
         {
             CAST_AI(mob_ashtongue_sorcerer::mob_ashtongue_sorcererAI, Sorcerer->AI())->ShadeGUID = me->GetGUID();
             Sorcerer->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
             Sorcerer->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
             Sorcerer->SetTarget(me->GetGUID());
             Sorcerers.push_back(Sorcerer->GetGUID());
             --DeathCount;
             ++SorcererCount;
         }
     }
     else
     {
         for (uint8 i = 0; i < 3; ++i)
         {
             Creature* Spawn = me->SummonCreature(spawnEntries[i], X, Y, Z_SPAWN, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000);
             if (Spawn)
             {
                 Spawn->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
                 Spawn->GetMotionMaster()->MovePoint(0, AGGRO_X, AGGRO_Y, AGGRO_Z);
                 Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                 Spawn->AI()->AttackStart(target);
             }
         }
     }
 }
void HomeMovementGenerator<Creature>::Initialize(Creature & owner) {
	float x, y, z;
	owner.GetHomePosition(x, y, z, ori);
	owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
	owner.AddUnitState(UNIT_STAT_EVADE);
	_setTargetLocation(owner);
}
Example #3
0
void CreatureGroup::LeaderMoveTo(float x, float y, float z)
{
    if (!m_leader)
        return;

    float pathangle    = atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);

    for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
    {
        Creature* member = itr->first;
        if (member == m_leader || !member->isAlive() || member->getVictim())
            continue;

        float angle = itr->second->follow_angle;
        float dist = itr->second->follow_dist;

        float dx = x + cos(angle + pathangle) * dist;
        float dy = y + sin(angle + pathangle) * dist;
        float dz = z;

        Trinity::NormalizeMapCoord(dx);
        Trinity::NormalizeMapCoord(dy);

        member->UpdateGroundPositionZ(dx, dy, dz);

        if (member->IsWithinDist(m_leader, dist + MAX_DESYNC))
            member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
        else
            member->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);

        member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
        member->SetHomePosition(dx, dy, dz, pathangle);
    }
}
Example #4
0
void hyjalAI::SummonCreature(uint32 entry, float Base[4][3])
{
    uint32 random = rand()%4;
    float SpawnLoc[3];
    float AttackLoc[3];

    for(uint8 i = 0; i < 3; ++i)
    {
        SpawnLoc[i] = Base[random][i];
        AttackLoc[i] = AttackArea[Faction][i];
    }
    Creature* pCreature = m_creature->SummonCreature(entry, SpawnLoc[0], SpawnLoc[1], SpawnLoc[2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
    if(pCreature)
    {
        EnemyCount++; // Increment Enemy Count to be used in World States

        pCreature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
        pCreature->GetMotionMaster()->MovePoint(0, AttackLoc[0],AttackLoc[1],AttackLoc[2]);
        pCreature->AddThreat(m_creature, 1.0f);
        DoZoneInCombat(pCreature);

        // Check if creature is a boss.
        if(pCreature->GetCreatureInfo()->rank == 3)
        {
            if(!FirstBossDead)
                BossGUID[0] = pCreature->GetGUID();
            else BossGUID[1] = pCreature->GetGUID();
            CheckBossTimer = 5000;
        }
    }
}
Example #5
0
		void UpdateAI(const uint32 diff) {
			if (!UpdateVictim())
				return;

			if (ShadowboltTimer <= diff) {
				Unit *pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);
				if (pTarget && pTarget->isAlive()
						&& pTarget->GetTypeId() == TYPEID_PLAYER)
					me->CastSpell(
							pTarget,
							DUNGEON_MODE(SPELL_SHADOWBOLT,
									SPELL_SHADOWBOLT_HEROIC), true);
				ShadowboltTimer = 10000;
			} else
				ShadowboltTimer -= diff;

			if (!Skeletons) {
				if ((SummonSkeletonsTimer <= diff)) {
					Creature* Skeleton;
					DoScriptText(SAY_SKELETONS, me);
					for (uint8 i = 0; i < 5; ++i) {
						Skeleton = me->SummonCreature(CREATURE_SKELETON,
								SkeletonSpawnPoint[i][0],
								SkeletonSpawnPoint[i][1], SKELETONSPAWN_Z, 0,
								TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
						if (Skeleton) {
							Skeleton->RemoveUnitMovementFlag(
									MOVEMENTFLAG_WALKING);
							Skeleton->GetMotionMaster()->MovePoint(0,
									me->GetPositionX(), me->GetPositionY(),
									me->GetPositionZ());
							Skeleton->AddThreat(me->getVictim(), 0.0f);
							DoZoneInCombat(Skeleton);
						}
					}
					Skeletons = true;
				} else
					SummonSkeletonsTimer -= diff;
			}

			if (FrostTombTimer <= diff) {
				if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
					if (pTarget->isAlive()) {
						//DoCast(pTarget, SPELL_FROST_TOMB_SUMMON, true);
						if (Creature *pChains = me->SummonCreature(CREATURE_FROSTTOMB, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 20000)) {
							CAST_AI(mob_frost_tomb::mob_frost_tombAI, pChains->AI())->SetPrisoner(
									pTarget);
							pChains->CastSpell(pTarget, SPELL_FROST_TOMB, true);

							DoScriptText(SAY_FROST_TOMB, me);
						}
					}
				FrostTombTimer = 15000;
			} else
				FrostTombTimer -= diff;

			DoMeleeAttackIfReady();
		}
void WaypointMovementGenerator<Creature>::InitTraveller(Creature &unit, const WaypointData &node)
{
    node.run ? unit.RemoveUnitMovementFlag(MOVEFLAG_WALK_MODE):
        unit.AddUnitMovementFlag(MOVEFLAG_WALK_MODE);

    unit.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
    unit.SetUInt32Value(UNIT_FIELD_BYTES_1, 0);

    unit.addUnitState(UNIT_STAT_ROAMING);
}
    void SummonCreature()
    {
        uint32 random = rand()%2;
        float X = SpawnLocations[random].x;
        float Y = SpawnLocations[random].y;
        // max of 6 sorcerers can be summoned
        if ((rand()%3 == 0) && (DeathCount > 0) && (SorcererCount < 7))
        {
            Creature* Sorcerer = me->SummonCreature(CREATURE_SORCERER, X, Y, Z_SPAWN, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
            if (Sorcerer)
            {
                CAST_AI(mob_ashtongue_sorcererAI, Sorcerer->AI())->ShadeGUID = me->GetGUID();
                Sorcerer->RemoveUnitMovementFlag(MOVEFLAG_WALK_MODE);
                Sorcerer->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
                Sorcerer->SetUInt64Value(UNIT_FIELD_TARGET, me->GetGUID());
                Sorcerers.push_back(Sorcerer->GetGUID());
                --DeathCount;
                ++SorcererCount;
            }
        }
        //else
        //{
        for (uint8 pos = 0; pos < 2; ++pos)
        {
            X = SpawnLocations[pos].x;
            Y = SpawnLocations[pos].y;

            for (uint8 i = 0; i < 3; ++i)
            {
                Creature* Spawn = me->SummonCreature(spawnEntries[i], X, Y, Z_SPAWN, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                if (Spawn)
                {
                    Spawn->RemoveUnitMovementFlag(MOVEFLAG_WALK_MODE);
                    Spawn->GetMotionMaster()->MovePoint(0, AGGRO_X, AGGRO_Y, AGGRO_Z);
                    Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
                    Spawn->AI()->AttackStart(pTarget);
                    DoZoneInCombat(Spawn);
                }
            }
        }
        //}
    }
void WaypointMovementGenerator<Creature>::InitTraveller(Creature &unit, const WaypointData &node)
{
    node.run ? unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING):
        unit.AddUnitMovementFlag(MOVEMENTFLAG_WALKING);

    unit.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
    unit.SetUInt32Value(UNIT_FIELD_BYTES_1, 0);

    // TODO: make this part of waypoint node, so that creature can walk when desired?
    if (unit.canFly())
        unit.SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02);

    unit.AddUnitState(UNIT_STAT_ROAMING);
}
Example #9
0
bool
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 diff)
{
    if (creature.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
    {
        i_nextMoveTime.Update(i_nextMoveTime.GetExpiry());    // Expire the timer
        creature.ClearUnitState(UNIT_STAT_ROAMING);
        return true;
    }

    i_nextMoveTime.Update(diff);

    if (i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
        creature.ClearUnitState(UNIT_STAT_ROAMING | UNIT_STAT_MOVE);

    if (!i_destinationHolder.HasArrived() && creature.IsStopped())
        creature.AddUnitState(UNIT_STAT_ROAMING);

    CreatureTraveller traveller(creature);

    if (i_destinationHolder.UpdateTraveller(traveller, diff, true))
    {
        if (i_nextMoveTime.Passed())
        {
            if (irand(0, RUNNING_CHANCE_RANDOMMV) > 0)
                creature.AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
            _setRandomLocation(creature);
        }
        else if (creature.isPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(), PET_FOLLOW_DIST+2.5f))
        {
           creature.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
           _setRandomLocation(creature);
        }
    }
    return true;
}
void
HomeMovementGenerator<Creature>::Initialize(Creature & owner)
{
    owner.RemoveUnitMovementFlag(MOVEFLAG_WALK_MODE);
    _setTargetLocation(owner);
}
        void UpdateAI(const uint32 diff)
        {
            if (!me->isInCombat())
                return;

            if (IsBanished)
            {
                // Akama is set in the threatlist so when we reset, we make sure that he is not included in our check
                if (me->getThreatManager().getThreatList().size() < 2)
                {
                    EnterEvadeMode();
                    return;
                }

                if (DefenderTimer <= diff)
                {
                    uint32 ran = rand()%2;
                    Creature* Defender = me->SummonCreature(CREATURE_DEFENDER, SpawnLocations[ran].x, SpawnLocations[ran].y, Z_SPAWN, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 25000);
                    if (Defender)
                    {
                        Defender->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
                        bool move = true;
                        if (AkamaGUID)
                        {
                            if (Creature* Akama = Unit::GetCreature(*me, AkamaGUID))
                            {
                                float x, y, z;
                                Akama->GetPosition(x, y, z);
                                // They move towards AKama
                                Defender->GetMotionMaster()->MovePoint(0, x, y, z);
                                Defender->AI()->AttackStart(Akama);
                            } else move = false;
                        } else move = false;
                        if (!move)
                            Defender->GetMotionMaster()->MovePoint(0, AKAMA_X, AKAMA_Y, AKAMA_Z);
                    }
                    DefenderTimer = 15000;
                } else DefenderTimer -= diff;

                if (SummonTimer <= diff)
                {
                    SummonCreature();
                    SummonTimer = 35000;
                } else SummonTimer -= diff;

                if (DeathCount >= 6)
                {
                    if (AkamaGUID)
                    {
                        Creature* Akama = Unit::GetCreature((*me), AkamaGUID);
                        if (Akama && Akama->isAlive())
                        {
                            IsBanished = false;
                            me->GetMotionMaster()->Clear(false);
                            me->GetMotionMaster()->MoveChase(Akama);
                            Akama->GetMotionMaster()->Clear();
                            // Shade should move to Akama, not the other way around
                            Akama->GetMotionMaster()->MoveIdle();
                            me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                            // Crazy amount of threat
                            me->AddThreat(Akama, 10000000.0f);
                            Akama->AddThreat(me, 10000000.0f);
                            me->Attack(Akama, true);
                            Akama->Attack(me, true);
                        }
                    }
                }
            }
            else                                                // No longer banished, let's fight Akama now
            {
                if (ReduceHealthTimer <= diff)
                {
                    if (AkamaGUID)
                    {
                        Creature* Akama = Unit::GetCreature((*me), AkamaGUID);
                        if (Akama && Akama->isAlive())
                        {
                            //10 % less health every few seconds.
                            me->DealDamage(Akama, Akama->GetMaxHealth()/10, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                            ReduceHealthTimer = 12000;
                        }
                    }
                } else ReduceHealthTimer -= diff;

                if (HasKilledAkama)
                {
                    if (!HasKilledAkamaAndReseting)//do not let players kill Shade if Akama is dead and Shade is waiting for ResetTimer!! event would bug
                    {
                        HasKilledAkamaAndReseting = true;
                        me->RemoveAllAuras();
                        me->DeleteThreatList();
                        me->CombatStop();
                        //me->SetFullHealth();
                        me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                        me->GetMotionMaster()->MoveTargetedHome();
                    }
                    if (ResetTimer <= diff)
                    {
                        EnterEvadeMode();// Reset a little while after killing Akama, evade and respawn Akama
                        return;
                    } else ResetTimer -= diff;
                }

                DoMeleeAttackIfReady();
            }
        }
void HomeMovementGenerator<Creature>::Initialize(Creature & owner)
{
    owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
    owner.AddUnitState(UNIT_STATE_EVADE);
    _setTargetLocation(owner);
}
Example #13
0
void CreatureGroup::LeaderMoveTo(float x, float y, float z, bool run)
{
    //! To do: This should probably get its own movement generator or use WaypointMovementGenerator.
    //! If the leader's path is known, member's path can be plotted as well using formation offsets.
    if (!m_leader)
        return;

	uint8 groupAI = sFormationMgr->CreatureGroupMap[m_leader->GetDBTableGUIDLow()]->groupAI;
	if (groupAI == 5)
		return;

	float pathDist = m_leader->GetExactDist(x, y, z);
    float pathAngle = m_leader->GetAngle(x, y);

    for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
    {
        Creature* member = itr->first;
        if (member == m_leader || !member->IsAlive() || member->GetVictim())
            continue;

		// Xinef: If member is stunned / rooted etc don't allow to move him
		if (member->HasUnitState(UNIT_STATE_NOT_MOVE))
			continue;

		// Xinef: this should be automatized, if turn angle is greater than PI/2 (90°) we should swap formation angle
        if (M_PI - fabs(fabs(m_leader->GetOrientation() - pathAngle) - M_PI) > M_PI*0.50f)
        {
			// pussywizard: in both cases should be 2*M_PI - follow_angle
			// pussywizard: also, GetCurrentWaypointID() returns 0..n-1, while point_1 must be > 0, so +1
			// pussywizard: db table waypoint_data shouldn't have point id 0 and shouldn't have any gaps for this to work!
            // if (m_leader->GetCurrentWaypointID()+1 == itr->second->point_1 || m_leader->GetCurrentWaypointID()+1 == itr->second->point_2)
			itr->second->follow_angle = Position::NormalizeOrientation(itr->second->follow_angle + M_PI); //(2 * M_PI) - itr->second->follow_angle;
        }

        float followAngle = itr->second->follow_angle;
        float followDist = itr->second->follow_dist;

        float dx = x + cos(followAngle + pathAngle) * followDist;
        float dy = y + sin(followAngle + pathAngle) * followDist;
        float dz = z;

        Trinity::NormalizeMapCoord(dx);
        Trinity::NormalizeMapCoord(dy);

        member->UpdateGroundPositionZ(dx, dy, dz);

        member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
		// pussywizard: setting the same movementflags is not enough, spline decides whether leader walks/runs, so spline param is now passed as "run" parameter to this function
        if (run && member->IsWalking())
            member->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
        else if (!run && !member->IsWalking())
            member->AddUnitMovementFlag(MOVEMENTFLAG_WALKING);

		// xinef: if we move members to position without taking care of sizes, we should compare distance without sizes
		// xinef: change members speed basing on distance - if too far speed up, if too close slow down
		UnitMoveType mtype = Movement::SelectSpeedType(member->GetUnitMovementFlags());
		member->SetSpeedRate(mtype, m_leader->GetSpeedRate(mtype) * member->GetExactDist(dx, dy, dz) / pathDist);

        member->GetMotionMaster()->MovePoint(0, dx, dy, dz);
        member->SetHomePosition(dx, dy, dz, pathAngle);
    }
}
Example #14
0
void hyjalAI::SummonCreature(uint32 entry, float Base[4][3])
{
    uint32 random = rand()%4;
    float SpawnLoc[3];

    for (uint8 i = 0; i < 3; ++i)
    {
        SpawnLoc[i] = Base[random][i];
    }
    Creature* creature = NULL;
    switch (entry)
    {
    case 17906:    //GARGOYLE

        if (!FirstBossDead && (WaveCount == 1 || WaveCount == 3))
        {   //summon at tower
            creature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_NEAR_TOWER][0]+irand(-20, 20), SpawnPointSpecial[SPAWN_NEAR_TOWER][1]+irand(-20, 20), SpawnPointSpecial[SPAWN_NEAR_TOWER][2]+irand(-10, 10), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
            if (creature)
                CAST_AI(hyjal_trashAI, creature->AI())->useFlyPath = true;
        }
        else
        {   //summon at gate
            creature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_GARG_GATE][0]+irand(-10, 10), SpawnPointSpecial[SPAWN_GARG_GATE][1]+irand(-10, 10), SpawnPointSpecial[SPAWN_GARG_GATE][2]+irand(-10, 10), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
        }
        break;
    case 17907:    //FROST_WYRM,
        if (FirstBossDead && WaveCount == 1) //summon at gate
            creature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_WYRM_GATE][0], SpawnPointSpecial[SPAWN_WYRM_GATE][1], SpawnPointSpecial[SPAWN_WYRM_GATE][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
        else
        {
            creature = me->SummonCreature(entry, SpawnPointSpecial[SPAWN_NEAR_TOWER][0], SpawnPointSpecial[SPAWN_NEAR_TOWER][1], SpawnPointSpecial[SPAWN_NEAR_TOWER][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
            if (creature)
                CAST_AI(hyjal_trashAI, creature->AI())->useFlyPath = true;
        }
        break;
    case 17908:    //GIANT_INFERNAL
        ++InfernalCount;
        if (InfernalCount > 7)
            InfernalCount = 0;
        creature = me->SummonCreature(entry, InfernalPos[InfernalCount][0], InfernalPos[InfernalCount][1], InfernalPos[InfernalCount][2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
        break;
    default:
        creature = me->SummonCreature(entry, SpawnLoc[0], SpawnLoc[1], SpawnLoc[2], 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
        break;
    }

    if (creature)
    {
        // Increment Enemy Count to be used in World States and instance script
        ++EnemyCount;

        creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
        creature->setActive(true);
        switch (entry)
        {
        case NECROMANCER:
        case ABOMINATION:
        case GHOUL:
        case BANSHEE:
        case CRYPT_FIEND:
        case GARGOYLE:
        case FROST_WYRM:
        case GIANT_INFERNAL:
        case FEL_STALKER:
        case RAGE_WINTERCHILL:
        case ANETHERON:
        case KAZROGAL:
        case AZGALOR:
            CAST_AI(hyjal_trashAI, creature->AI())->IsEvent = true;
            break;
        }
        if (instance)
        {
            if (instance->GetData(DATA_RAIDDAMAGE) < MINRAIDDAMAGE)
                creature->SetDisableReputationGain(true);//no repu for solo farming
        }
        // Check if Creature is a boss.
        if (creature->isWorldBoss())
        {
            if (!FirstBossDead)  BossGUID[0] = creature->GetGUID();
            else                BossGUID[1] = creature->GetGUID();
            CheckTimer = 5000;
        }
    }
}