Example #1
0
bool ProcessEventId_event_go_focusing_iris(uint32 /*uiEventId*/, Object* pSource, Object* /*pTarget*/, bool /*bIsStart*/)
{
    if (instance_eye_of_eternity* pInstance = (instance_eye_of_eternity*)((Creature*)pSource)->GetInstanceData())
    {
        if (pSource->GetTypeId() != TYPEID_PLAYER)
            return false;

        if (pInstance->GetData(TYPE_MALYGOS) == IN_PROGRESS || pInstance->GetData(TYPE_MALYGOS) == DONE)
            return false;

        Creature* pMalygos = pInstance->GetSingleCreatureFromStorage(NPC_MALYGOS);
        Creature* pTrigger = pInstance->GetSingleCreatureFromStorage(NPC_LARGE_TRIGGER);
        if (!pMalygos || !pTrigger)
            return false;

        // Enter combat area - Move to ground point first, then start chasing target
        float fX, fY, fZ;
        pTrigger->GetNearPoint(pTrigger, fX, fY, fZ, 0, 30.0f, pTrigger->GetAngle(pMalygos));
        pMalygos->GetMotionMaster()->MovePoint(POINT_ID_COMBAT, fX, fY, fZ);
        pMalygos->AI()->AttackStart((Player*)pSource);

        return true;
    }
    return false;
}
Example #2
0
	static bool HandleNpcAddFormationCommand(ChatHandler* handler,
			const char* args) {
		if (!*args)
			return false;

		uint32 leaderGUID = (uint32) atoi((char*) args);
		Creature *pCreature = handler->getSelectedCreature();

		if (!pCreature || !pCreature->GetDBTableGUIDLow()) {
			handler->SendSysMessage(LANG_SELECT_CREATURE);
			handler->SetSentErrorMessage(true);
			return false;
		}

		uint32 lowguid = pCreature->GetDBTableGUIDLow();
		if (pCreature->GetFormation()) {
			handler->PSendSysMessage(
					"Selected creature is already member of group %u",
					pCreature->GetFormation()->GetId());
			return false;
		}

		if (!lowguid)
			return false;

		Player *chr = handler->GetSession()->GetPlayer();
		FormationInfo *group_member;

		group_member = new FormationInfo;
		group_member->follow_angle = (pCreature->GetAngle(chr)
				- chr->GetOrientation()) * 180 / M_PI;
		group_member->follow_dist = sqrtf(
				pow(chr->GetPositionX() - pCreature->GetPositionX(), int(2))
						+ pow(chr->GetPositionY() - pCreature->GetPositionY(),
								int(2)));
		group_member->leaderGUID = leaderGUID;
		group_member->groupAI = 0;

		CreatureGroupMap[lowguid] = group_member;
		pCreature->SearchFormation();

		WorldDatabase.PExecute(
				"INSERT INTO creature_formations (leaderGUID, memberGUID, dist, angle, groupAI) VALUES ('%u','%u','%f', '%f', '%u')",
				leaderGUID, lowguid, group_member->follow_dist,
				group_member->follow_angle, group_member->groupAI);

		handler->PSendSysMessage(
				"Creature %u added to formation with leader %u", lowguid,
				leaderGUID);

		return true;
	}
Example #3
0
		void DoAction(const int32 actionId) {
			switch (actionId) {
			case ACTION_OUTRO: {
				Position pos;
				if (Creature* pIck = GetIck()) {
					// TODO: tele on Ick then run some distance.
					pIck->GetNearPosition(pos, 5.0f, 3.14f);
					me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(),
							pos.GetPositionZ(), 0.0f);
				}
				me->SetVisible(true);

				Creature* pJainaOrSylvanas = me->GetCreature(*me,
						pInstance->GetData64(DATA_JAINA_SYLVANAS_1));
				if (pJainaOrSylvanas) {
					Position pos;
					me->GetNearPosition(pos, 5.0f, 0);
					pJainaOrSylvanas->NearTeleportTo(
							pos.GetPositionX(),
							pos.GetPositionY(),
							pos.GetPositionZ(),
							pos.GetAngle(me->GetPositionX(),
									me->GetPositionY()));
				} else {
					if (pInstance->GetData(DATA_TEAM_IN_INSTANCE)
							== TEAM_ALLIANCE)
						pJainaOrSylvanas = me->SummonCreature(
								NPC_SYLVANAS_PART1, *me,
								TEMPSUMMON_MANUAL_DESPAWN);
					else
						pJainaOrSylvanas = me->SummonCreature(NPC_JAINA_PART1,
								*me, TEMPSUMMON_MANUAL_DESPAWN);
				}

				if (pJainaOrSylvanas) {
					pJainaOrSylvanas->SetOrientation(
							pJainaOrSylvanas->GetAngle(me->GetPositionX(),
									me->GetPositionY()));
					me->SetOrientation(
							me->GetAngle(pJainaOrSylvanas->GetPositionX(),
									pJainaOrSylvanas->GetPositionY()));
					uiNpcOutroDialog = pJainaOrSylvanas->GetGUID();
				}

				phase = PHASE_OUTRO;
				events.Reset();
				events.ScheduleEvent(EVENT_OUTRO_1, 1000);
				break;
			}
			}
		}
Example #4
0
    static bool HandleNpcAddFormationCommand(ChatHandler* handler, const char* args)
    {
        if (!*args)
            return false;

        uint32 leaderGUID = (uint32) atoi((char*)args);
        Creature* creature = handler->getSelectedCreature();

        if (!creature || !creature->GetDBTableGUIDLow())
        {
            handler->SendSysMessage(LANG_SELECT_CREATURE);
            handler->SetSentErrorMessage(true);
            return false;
        }

        uint32 lowguid = creature->GetDBTableGUIDLow();
        if (creature->GetFormation())
        {
            handler->PSendSysMessage("Selected creature is already member of group %u", creature->GetFormation()->GetId());
            return false;
        }

        if (!lowguid)
            return false;

        Player* chr = handler->GetSession()->GetPlayer();
        FormationInfo* group_member;

        group_member                 = new FormationInfo;
        group_member->follow_angle   = (creature->GetAngle(chr) - chr->GetOrientation()) * 180 / M_PI;
        group_member->follow_dist    = sqrtf(pow(chr->GetPositionX() - creature->GetPositionX(), int(2))+pow(chr->GetPositionY() - creature->GetPositionY(), int(2)));
        group_member->leaderGUID     = leaderGUID;
        group_member->groupAI        = 0;

        CreatureGroupMap[lowguid] = group_member;
        creature->SearchFormation();

        PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE_FORMATION);

        stmt->setUInt32(0, leaderGUID);
        stmt->setUInt32(1, lowguid);
        stmt->setFloat(2, group_member->follow_dist);
        stmt->setFloat(3, group_member->follow_angle);
        stmt->setUInt32(4, uint32(group_member->groupAI));

        WorldDatabase.Execute(stmt);

        handler->PSendSysMessage("Creature %u added to formation with leader %u", lowguid, leaderGUID);

        return true;
    }
bool ChargeMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
    i_nextMoveTime.Update(diff);

    if(i_nextMoveTime.Passed())
    {
        i_nextMoveTime.Reset(m_pointTime);
        float angle = creature.GetAngle(m_path[curPoint].x,m_path[curPoint].y);
        creature.GetMap()->CreatureRelocation(&creature, m_path[curPoint].x, m_path[curPoint].y, m_path[curPoint].z, angle);

        if(curPoint >= m_end)
        {
            creature.clearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
            return false;
        }
        ++curPoint;
    }
    return true;
}
            void FilterTargets(std::list<WorldObject*>& targets)
            {
                Creature* varos = GetCaster()->ToCreature();
                if (!varos)
                    return;

                if (varos->GetEntry() != NPC_VAROS)
                    return;

                float orientation = ENSURE_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation();

                for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)
                {
                    float angle = varos->GetAngle((*itr)->GetPositionX(), (*itr)->GetPositionY());
                    float diff = std::fabs(orientation - angle);

                    if (diff > 1.0f)
                        itr = targets.erase(itr);
                    else
                        ++itr;
                }
            }
void ChargeMovementGenerator<Creature>::Initialize(Creature &creature)
{
    if (!creature.isAlive())
        return;

    creature.addUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);

    if (m_start == m_end)
    {
        float dist = creature.GetDistance(m_path[m_end].x, m_path[m_end].y, m_path[m_end].z);
        float angle = creature.GetAngle(m_path[m_end].x, m_path[m_end].y);
        bool outdoor = creature.GetTerrain()->IsOutdoors(m_path[m_end].x, m_path[m_end].y, m_path[m_end].z);
        Coords pos = creature.GetPosition();
        float itr = 1;
        if(m_pointTime > 1000)
        {
            while(float(m_pointTime)/(float(dist+itr)/itr) <= 1000 && itr < dist)
                itr+=0.3f;
        }
        else itr = dist;

        for(float i = 1; i < dist; i+=itr)
        {
            m_path.resize(m_path.size()+1);
            m_path.set(m_end+1, m_path[m_end]);

            pos.x += cos(angle)*itr;
            pos.y += sin(angle)*itr;
            creature.UpdateGroundPositionZ(pos.x, pos.y, pos.z, outdoor ? 10.0f : 3.0f);
            m_path.set(m_end, pos);
            ++m_end;
        }
        m_pointTime = float(m_pointTime)/float((m_end - m_start) + 1);
        i_nextMoveTime.Reset(m_pointTime);
    }
}
Example #8
0
        // Emote Ardonis and Pathaleon
        void Turn_to_Pathaleons_Image()
        {
            Creature* ardonis = Unit::GetCreature(*me, ardonisGUID);
            Creature* pathaleon = Unit::GetCreature(*me, pathaleonGUID);
            Player* player = Unit::GetPlayer(*me, PlayerGUID);

            if (!ardonis || !pathaleon || !player)
                return;

            //Calculate the angle to Pathaleon
            angle_dawnforge = me->GetAngle(pathaleon->GetPositionX(), pathaleon->GetPositionY());
            angle_ardonis = ardonis->GetAngle(pathaleon->GetPositionX(), pathaleon->GetPositionY());

            //Turn Dawnforge and update
            me->SetOrientation(angle_dawnforge);
            me->SendUpdateToPlayer(player);
            //Turn Ardonis and update
            ardonis->SetOrientation(angle_ardonis);
            ardonis->SendUpdateToPlayer(player);

            //Set them to kneel
            me->SetStandState(UNIT_STAND_STATE_KNEEL);
            ardonis->SetStandState(UNIT_STAND_STATE_KNEEL);
        }
Example #9
0
    void Transform()
    {
        if (m_creature->GetMap()->GetPlayer(m_playerGuid))
        {
            Creature* pDemon = m_creature->SummonCreature(NPC_SIMONE_THE_SEDUCTRESS,
                m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetAngle(m_creature), TEMPSPAWN_DEAD_DESPAWN, 0);
            Creature* pPrecious = GetClosestCreatureWithEntry(m_creature, NPC_PRECIOUS, 100.0f);

            if (pDemon)
            {
                if (npc_simone_seductressAI * pSimone = dynamic_cast<npc_simone_seductressAI*> (pDemon->AI()))
                    pSimone->m_simoneGuid = m_creature->GetObjectGuid();

                m_creature->SetVisibility(VISIBILITY_OFF);
                m_creature->ForcedDespawn();
            }

            if (pDemon && pPrecious)
            {
                Creature* pPreciousDevourer = m_creature->SummonCreature(NPC_PRECIOUS_THE_DEVOURER,
                    pPrecious->GetPositionX(), pPrecious->GetPositionY(), pPrecious->GetPositionZ(), pPrecious->GetAngle(pPrecious), TEMPSPAWN_DEAD_DESPAWN, 0, true);

                if (pPreciousDevourer)
                {
                    if (npc_simone_seductressAI * pSimone = dynamic_cast<npc_simone_seductressAI*> (pDemon->AI()))
                        pSimone->m_preciousGuid = pPreciousDevourer->GetObjectGuid();

                    if (npc_precious_the_devourerAI * pDevourer = dynamic_cast<npc_precious_the_devourerAI*> (pPreciousDevourer->AI()))
                        pDevourer->m_simoneGuid = pDemon->GetObjectGuid();
                }

                pPrecious->SetVisibility(VISIBILITY_OFF);
                pPrecious->ForcedDespawn();
            }
        }
    }
Example #10
0
void
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
{
    float X, Y, Z, z, nx, ny, nz, ori, dist;

    creature.GetHomePosition(X, Y, Z, ori);

    z = creature.GetPositionZ();
    Map const* map = creature.GetBaseMap();

    // For 2D/3D system selection
    //bool is_land_ok  = creature.canWalk();
    //bool is_water_ok = creature.canSwim();
    bool is_air_ok   = creature.canFly();

    for (uint32 i = 0; ; ++i)
    {
        const float angle = (float)rand_norm()*static_cast<float>(M_PI*2);
        const float range = (float)rand_norm()*wander_distance;
        const float distanceX = range * cos(angle);
        const float distanceY = range * sin(angle);

        nx = X + distanceX;
        ny = Y + distanceY;

        // prevent invalid coordinates generation
        Trillium::NormalizeMapCoord(nx);
        Trillium::NormalizeMapCoord(ny);

        dist = (nx - X)*(nx - X) + (ny - Y)*(ny - Y);

        if (i == 5)
        {
            nz = Z;
            break;
        }

        if (is_air_ok) // 3D system above ground and above water (flying mode)
        {
            const float distanceZ = (float)(rand_norm()) * sqrtf(dist)/2; // Limit height change
            nz = Z + distanceZ;
            float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height.
            float wz = map->GetWaterLevel(nx, ny);
            if (tz >= nz || wz >= nz)
                continue; // Problem here, we must fly above the ground and water, not under. Let's try on next tick
        }
        //else if (is_water_ok) // 3D system under water and above ground (swimming mode)
        else // 2D only
        {
            dist = dist >= 100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)

            // The fastest way to get an accurate result 90% of the time.
            // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
            nz = map->GetHeight(nx, ny, Z+dist-2.0f, false); // Map check
            if (fabs(nz-Z)>dist)
            {
                nz = map->GetHeight(nx, ny, Z-2.0f, true); // Vmap Horizontal or above
                if (fabs(nz-Z)>dist)
                {
                    nz = map->GetHeight(nx, ny, Z+dist-2.0f, true); // Vmap Higher
                    if (fabs(nz-Z)>dist)
                        continue; // let's forget this bad coords where a z cannot be find and retry at next tick
                }
            }
        }
        break;
    }

    Traveller<Creature> traveller(creature);
    creature.SetOrientation(creature.GetAngle(nx, ny));
    i_destinationHolder.SetDestination(traveller, nx, ny, nz);
    creature.AddUnitState(UNIT_STAT_ROAMING);
    if (is_air_ok)
    {
        i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
    }
    //else if (is_water_ok) // Swimming mode to be done with more than this check
    else
    {
        i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(), 5000+i_destinationHolder.GetTotalTravelTime()));
        creature.AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
    }

    //Call for creature group update
    if (creature.GetFormation() && creature.GetFormation()->getLeader() == &creature)
    {
        creature.GetFormation()->LeaderMoveTo(nx, ny, nz);
    }
}
void
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
{
    float respX, respY, respZ, respO, currZ, destX, destY, destZ, wander_distance, travelDistZ;

    creature.GetRespawnCoord(respX, respY, respZ, &respO, &wander_distance);

    currZ = creature.GetPositionZ();
    TerrainInfo const* map = creature.GetTerrain();

    // For 2D/3D system selection
    //bool is_land_ok  = creature.CanWalk();                // not used?
    //bool is_water_ok = creature.CanSwim();                // not used?
    bool is_air_ok = creature.CanFly();

    const float angle = rand_norm_f() * (M_PI_F*2.0f);
    const float range = rand_norm_f() * wander_distance;
    const float distanceX = range * cos(angle);
    const float distanceY = range * sin(angle);

    destX = respX + distanceX;
    destY = respY + distanceY;

    // prevent invalid coordinates generation
    MaNGOS::NormalizeMapCoord(destX);
    MaNGOS::NormalizeMapCoord(destY);

    travelDistZ = distanceX*distanceX + distanceY*distanceY;

    if (is_air_ok)                                          // 3D system above ground and above water (flying mode)
    {
        // Limit height change
        const float distanceZ = rand_norm_f() * sqrtf(travelDistZ)/2.0f;
        destZ = respZ + distanceZ;
        float levelZ = map->GetWaterOrGroundLevel(destX, destY, destZ-2.0f);

        // Problem here, we must fly above the ground and water, not under. Let's try on next tick
        if (levelZ >= destZ)
            return;
    }
    //else if (is_water_ok)                                 // 3D system under water and above ground (swimming mode)
    else                                                    // 2D only
    {
        destZ = respZ;
        if(!map->IsNextZcoordOK(destX, destY, destZ, travelDistZ))
            return;                                         // let's forget this bad coords where a z cannot be find and retry at next tick
        creature.UpdateGroundPositionZ(destX, destY, destZ, travelDistZ);
    }

    Traveller<Creature> traveller(creature);

    creature.SetOrientation(creature.GetAngle(destX, destY));
    i_destinationHolder.SetDestination(traveller, destX, destY, destZ);
    creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

    if (is_air_ok)
    {
        i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
        creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7);
    }
    //else if (is_water_ok)                                 // Swimming mode to be done with more than this check
    else
    {
        i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(), 10000+i_destinationHolder.GetTotalTravelTime()));
        creature.AddSplineFlag(SPLINEFLAG_WALKMODE);
    }
}
Example #12
0
void
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
{
    float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist;

    creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance);

    z = creature.GetPositionZ();
    uint32 mapid=creature.GetMapId();
    Map const* map = MapManager::Instance().GetBaseMap(mapid);

    // For 2D/3D system selection
    //bool is_land_ok  = creature.canWalk();                // not used?
    //bool is_water_ok = creature.canSwim();                // not used?
    bool is_air_ok   = creature.canFly();

    const float angle = rand_norm()*(M_PI*2);
    const float range = rand_norm()*wander_distance;
    const float distanceX = range * cos(angle);
    const float distanceY = range * sin(angle);

    nx = X + distanceX;
    ny = Y + distanceY;

    // prevent invalid coordinates generation
    MaNGOS::NormalizeMapCoord(nx);
    MaNGOS::NormalizeMapCoord(ny);

    dist = distanceX*distanceX + distanceY*distanceY;

    if (is_air_ok) // 3D system above ground and above water (flying mode)
    {
        const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change
        nz = Z + distanceZ;
        float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height.
        float wz = map->GetWaterLevel(nx, ny);
        if (tz >= nz || wz >= nz)
            return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick
    }
    //else if (is_water_ok) // 3D system under water and above ground (swimming mode)
    else // 2D only
    {
        dist = dist>=100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
        // The fastest way to get an accurate result 90% of the time.
        // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
        nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check
        if (fabs(nz-Z)>dist)
        {
            nz = map->GetHeight(nx,ny,Z-2.0f,true); // Vmap Horizontal or above
            if (fabs(nz-Z)>dist)
            {
                nz = map->GetHeight(nx,ny,Z+dist-2.0f,true); // Vmap Higher
                if (fabs(nz-Z)>dist)
                    return; // let's forget this bad coords where a z cannot be find and retry at next tick
            }
        }
    }

    Traveller<Creature> traveller(creature);
    creature.SetOrientation(creature.GetAngle(nx,ny));
    i_destinationHolder.SetDestination(traveller, nx, ny, nz);
    creature.addUnitState(UNIT_STAT_ROAMING);
    if (is_air_ok)
    {
        i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
        creature.AddUnitMovementFlag(MONSTER_MOVE_FLY);
    }
    //else if (is_water_ok) // Swimming mode to be done with more than this check
    else
    {
        i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime()));
        creature.SetUnitMovementFlags(MONSTER_MOVE_WALK);
    }
}
void
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
{
    float respX, respY, respZ, respO, currZ, destX, destY, destZ, wander_distance, travelDistZ;

    creature.GetRespawnCoord(respX, respY, respZ, &respO, &wander_distance);

    currZ = creature.GetPositionZ();
    TerrainInfo const* map = creature.GetTerrain();

    // For 2D/3D system selection
    //bool is_land_ok  = creature.CanWalk();                // not used?
    //bool is_water_ok = creature.CanSwim();                // not used?
    bool is_air_ok = creature.CanFly();

    const float angle = rand_norm_f() * (M_PI_F*2.0f);
    const float range = rand_norm_f() * wander_distance;
    const float distanceX = range * cos(angle);
    const float distanceY = range * sin(angle);

    destX = respX + distanceX;
    destY = respY + distanceY;

    // prevent invalid coordinates generation
    MaNGOS::NormalizeMapCoord(destX);
    MaNGOS::NormalizeMapCoord(destY);

    travelDistZ = distanceX*distanceX + distanceY*distanceY;

    if (is_air_ok)                                          // 3D system above ground and above water (flying mode)
    {
        // Limit height change
        const float distanceZ = rand_norm_f() * sqrtf(travelDistZ)/2.0f;
        destZ = respZ + distanceZ;
        float levelZ = map->GetWaterOrGroundLevel(destX, destY, destZ-2.0f);

        // Problem here, we must fly above the ground and water, not under. Let's try on next tick
        if (levelZ >= destZ)
            return;
    }
    //else if (is_water_ok)                                 // 3D system under water and above ground (swimming mode)
    else                                                    // 2D only
    {
        // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
        travelDistZ = travelDistZ >= 100.0f ? 10.0f : sqrtf(travelDistZ);

        // The fastest way to get an accurate result 90% of the time.
        // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
        destZ = map->GetHeight(destX, destY, respZ+travelDistZ-2.0f, false);

        if (fabs(destZ - respZ) > travelDistZ)              // Map check
        {
            // Vmap Horizontal or above
            destZ = map->GetHeight(destX, destY, respZ - 2.0f, true);

            if (fabs(destZ - respZ) > travelDistZ)
            {
                // Vmap Higher
                destZ = map->GetHeight(destX, destY, respZ+travelDistZ-2.0f, true);

                // let's forget this bad coords where a z cannot be find and retry at next tick
                if (fabs(destZ - respZ) > travelDistZ)
                    return;
            }
        }
    }

    Traveller<Creature> traveller(creature);

    creature.SetOrientation(creature.GetAngle(destX, destY));
    i_destinationHolder.SetDestination(traveller, destX, destY, destZ);
    creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

    if (is_air_ok)
    {
        i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
        creature.AddSplineFlag(SPLINEFLAG_FLYING);
    }
    //else if (is_water_ok)                                 // Swimming mode to be done with more than this check
    else
    {
        i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime() + urand(500, 10000));
        creature.AddSplineFlag(SPLINEFLAG_WALKMODE);
    }
}
bool EffectAuraDummy_npc_captured_beryl_sorcerer(const Aura* pAura, bool bApply)
{
    if (pAura->GetId() == SPELL_ARCANE_CHAINS_CHANNEL)
    {
        if (pAura->GetEffIndex() != EFFECT_INDEX_0 || !bApply)
            return false;

        Creature* pCreature = (Creature*)pAura->GetTarget();
        Unit* pCaster = pAura->GetCaster();
        if (!pCreature || !pCaster || pCaster->GetTypeId() != TYPEID_PLAYER || pCreature->GetEntry() != NPC_CAPTURED_BERYL_SORCERER)
            return false;

        // follow the caster
        ((Player*)pCaster)->KilledMonsterCredit(NPC_CAPTURED_BERYL_SORCERER);
        pCreature->GetMotionMaster()->MoveFollow(pCaster, pCreature->GetDistance(pCaster), M_PI_F - pCreature->GetAngle(pCaster));
        return true;
    }

    return false;
}
Example #15
0
void
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
{
    float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist;

    creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance);

    z = creature.GetPositionZ();
    Map const* map = creature.GetBaseMap();

    // For 2D/3D system selection
    //bool is_land_ok  = creature.canWalk();                // not used?
    //bool is_water_ok = creature.canSwim();                // not used?
    bool is_air_ok   = creature.canFly();

    const float angle = rand_norm_f()*(M_PI_F*2.0f);
    const float range = rand_norm_f()*wander_distance;
    const float distanceX = range * cos(angle);
    const float distanceY = range * sin(angle);

    nx = X + distanceX;
    ny = Y + distanceY;

    // prevent invalid coordinates generation
    MaNGOS::NormalizeMapCoord(nx);
    MaNGOS::NormalizeMapCoord(ny);

    dist = distanceX*distanceX + distanceY*distanceY;

    if (is_air_ok)                                          // 3D system above ground and above water (flying mode)
    {
        // Limit height change
        const float distanceZ = rand_norm_f() * sqrtf(dist)/2.0f;
        nz = Z + distanceZ;
        float tz = map->GetHeight(nx, ny, nz-2.0f, false);  // Map check only, vmap needed here but need to alter vmaps checks for height.
        float wz = map->GetWaterLevel(nx, ny);

        // Problem here, we must fly above the ground and water, not under. Let's try on next tick
        if (tz >= nz || wz >= nz)
            return;
    }
    //else if (is_water_ok)                                 // 3D system under water and above ground (swimming mode)
    else                                                    // 2D only
    {
        nz = Z;
        if (!map->IsNextZcoordOK(nx, ny, nz, dist))
            return;                                         // let's forget this bad coords where a z cannot be find and retry at next tick
        creature.UpdateGroundPositionZ(nx, ny, nz, dist);
    }

    Traveller<Creature> traveller(creature);

    creature.SetOrientation(creature.GetAngle(nx, ny));
    i_destinationHolder.SetDestination(traveller, nx, ny, nz);
    creature.addUnitState(UNIT_STAT_ROAMING_MOVE);

    if (is_air_ok && !(creature.canWalk() && creature.IsAtGroundLevel(nx, ny, nz)))
    {
        i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
        creature.AddSplineFlag(SPLINEFLAG_UNKNOWN7);
    }
    //else if (is_water_ok)                                 // Swimming mode to be done with more than this check
    else
    {
        i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(), 10000+i_destinationHolder.GetTotalTravelTime()));
        creature.AddSplineFlag(SPLINEFLAG_WALKMODE);
    }
}
Example #16
0
void
RandomCircleMovementGenerator<Creature>::fillSplineWayPoints(Creature &creature)
{
    m_splineMap.clear();
    float spawnX, spawnY, spawnZ, spawnO, spawnDist, x, y, z;
    creature.GetRespawnCoord(spawnX, spawnY, spawnZ, &spawnO, &spawnDist);
    creature.GetPosition(x,y,z);
    //Add first waypoint
   /* SplineWayPointInfo *firstwp = new SplineWayPointInfo();
    firstwp->x = x;
    firstwp->y = y;
    firstwp->z = z;
    m_splineMap.insert(std::make_pair<uint32, SplineWayPointInfo*>(0, firstwp)); */

    //calculate other ones
    float m_fDistance = creature.GetDistance2d(spawnX, spawnY);
    float m_fLenght = 2*M_PI_F*m_fDistance;

    float m_fAngle = (M_PI_F - ((2*M_PI_F) / m_fLenght)) / 2;

    if (m_bClockWise)
        m_fAngle += ((2*M_PI_F) / m_fLenght) + creature.GetAngle(spawnX, spawnY);
    else
        m_fAngle = creature.GetAngle(spawnX, spawnY) - m_fAngle - ((2*M_PI_F) / m_fLenght);
    //because it cant be lower than 0 or bigger than 2*PI
    m_fAngle = (m_fAngle >= 0) ? m_fAngle : 2 * M_PI_F + m_fAngle;
    m_fAngle = (m_fAngle <= 2*M_PI_F) ? m_fAngle : m_fAngle - 2 * M_PI_F;
    float creature_speed = creature.GetSpeed(MOVE_FLIGHT) / 2;

    float lastx = x;
    float lasty = y;
    for(uint32 wpId = 0; wpId < 30; ++wpId)
    {
        bool canIncerase = true;
        bool canDecerase = true;
        if (m_fDistance > spawnDist)
            canIncerase = false;
        if (m_fDistance < 1)
            canDecerase = false;
        uint8 tmp = urand(0,2); // 0 nothing, 1 incerase, 2 decerase
        if (tmp == 1 && canIncerase)
            m_fDistance += 0.5f;
        else if (tmp == 2 && canDecerase)
            m_fDistance -= 0.5f;

        m_fLenght = 2*M_PI_F*m_fDistance;
        float m_fRotateAngle = ((2*M_PI_F) / m_fLenght); // Moving by half of speed every 500ms
        if (m_bClockWise)
            m_fAngle -= m_fRotateAngle;
        else
            m_fAngle += m_fRotateAngle;
        //because it cant be lower than 0 or bigger than 2*PI
        m_fAngle = (m_fAngle >= 0) ? m_fAngle : 2 * M_PI_F + m_fAngle;
        m_fAngle = (m_fAngle <= 2*M_PI_F) ? m_fAngle : m_fAngle - 2 * M_PI_F;
        lastx += cos(m_fAngle)*creature_speed;
        lasty += sin(m_fAngle)*creature_speed;
        MaNGOS::NormalizeMapCoord(lastx);
        MaNGOS::NormalizeMapCoord(lasty);
        Position *wp = new Position();
        wp->x = lastx;
        wp->y = lasty;
        wp->z = z;
        wp->o = m_fAngle;
        m_splineMap.insert(std::make_pair<uint32, Position*>(wpId, wp));
    }
    i_nextMoveTime.Reset(500);
}