void
RandomMovementGenerator<Creature>::Initialize(Creature &creature)
{
//	sLog.outDebug(" $$ RandomMovementGenerator::Initialize");
	uint16 x, y;

	creature.GetRespawnCoord(x, y);

	i_nextMove = 1;
	i_waypoints[0][0] = x;
	i_waypoints[0][1] = y;

	for(uint8 idx=1; idx < MAX_RAND_WAYPOINTS+1; ++idx)
	{
		i_waypoints[idx][0] = x + (urand(100, 150) * (urand(0,1) * -1));
		i_waypoints[idx][1] = y + (urand(100, 150) * (urand(0,1) * -1));
		//i_waypoints[idx][0] = x + ((rand() % 3) - 150);
		//i_waypoints[idx][1] = y + ((rand() % 3) - 150);
	}
	i_nextMoveTime.Reset(urand(5000, 6000-1));
	creature.StopMoving();
}
void instance_blackfathom_deeps::DoSpawnMobs(uint8 uiWaveIndex)
{
    Creature* pKelris = GetSingleCreatureFromStorage(NPC_KELRIS);
    if (!pKelris)
        return;

    float fX_resp, fY_resp, fZ_resp;

    pKelris->GetRespawnCoord(fX_resp, fY_resp, fZ_resp);

    for (uint8 i = 0; i < countof(aWaveSummonInformation); ++i)
    {
        if (aWaveSummonInformation[i].m_uiWaveIndex != uiWaveIndex)
            continue;

        // Summon mobs at positions
        for (uint8 j = 0; j < MAX_COUNT_POS; ++j)
        {
            for (uint8 k = 0; k < aWaveSummonInformation[i].m_aCountAndPos[j].m_uiCount; ++k)
            {
                uint8 uiPos = aWaveSummonInformation[i].m_aCountAndPos[j].m_uiSummonPosition;
                float fPosX = aSpawnLocations[uiPos].m_fX;
                float fPosY = aSpawnLocations[uiPos].m_fY;
                float fPosZ = aSpawnLocations[uiPos].m_fZ;
                float fPosO = aSpawnLocations[uiPos].m_fO;

                // Adapt fPosY slightly in case of higher summon-counts
                if (aWaveSummonInformation[i].m_aCountAndPos[j].m_uiCount > 1)
                    fPosY = fPosY - INTERACTION_DISTANCE / 2 + k * INTERACTION_DISTANCE / aWaveSummonInformation[i].m_aCountAndPos[j].m_uiCount;

                if (Creature* pSummoned = pKelris->SummonCreature(aWaveSummonInformation[i].m_uiNpcEntry, fPosX, fPosY, fPosZ, fPosO, TEMPSUMMON_DEAD_DESPAWN, 0))
                {
                    pSummoned->GetMotionMaster()->MovePoint(0, fX_resp, fY_resp, fZ_resp);
                    m_lWaveMobsGuids[uiWaveIndex].push_back(pSummoned->GetGUIDLow());
                }
            }
        }
    }
}
void ObjectGridRespawnMover::Visit(CreatureMapType &m) {
	// creature in unloading grid can have respawn point in another grid
	// if it will be unloaded then it will not respawn in original grid until unload/load original grid
	// move to respawn point to prevent this case. For player view in respawn grid this will be normal respawn.
	for (CreatureMapType::iterator iter = m.begin(); iter != m.end();) {
		Creature * c = iter->getSource();
		++iter;

		ASSERT(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets");

		Cell const& cur_cell = c->GetCurrentCell();

		float resp_x, resp_y, resp_z;
		c->GetRespawnCoord(resp_x, resp_y, resp_z);
		CellPair resp_val = Trinity::ComputeCellPair(resp_x, resp_y);
		Cell resp_cell(resp_val);

		if (cur_cell.DiffGrid(resp_cell)) {
			c->GetMap()->CreatureRespawnRelocation(c);
			// false result ignored: will be unload with other creatures at grid
		}
	}
}
void HomeMovementGenerator<Creature>::_setTargetLocation(Creature& owner)
{
    if (owner.hasUnitState(UNIT_STAT_NOT_MOVE))
        return;

    Movement::MoveSplineInit<Unit*> init(owner);
    float x, y, z, o;

    // at apply we can select more nice return points base at current movegen
    if (owner.GetMotionMaster()->empty() || !owner.GetMotionMaster()->CurrentMovementGenerator()->GetResetPosition(owner, x, y, z, o))
        owner.GetRespawnCoord(x, y, z, &o);

    init.SetFacing(o);
    init.MoveTo(x, y, z, true);
    init.SetSmooth(); // fix broken fly movement for old creatures
    //init.SetWalk(false);
    // hack for old creatures with bugged fly animation
    bool bSetWalk = (owner.GetTypeId() == TYPEID_UNIT && owner.IsLevitating() && owner.GetFloatValue(UNIT_FIELD_HOVERHEIGHT) == 0.0f);
    init.SetWalk(bSetWalk);
    init.Launch();

    m_arrived = false;
    owner.clearUnitState(UNIT_STAT_ALL_DYN_STATES);
}
Example #5
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();
    bool is_water_ok = creature.canSwim();
    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 
    Trinity::NormalizeMapCoord(nx);
    Trinity::NormalizeMapCoord(ny);

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

    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(MOVEMENTFLAG_FLYING2);
    }
    //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(MOVEMENTFLAG_WALK_MODE);
    }
}
void instance_draktharon_keep::DoSortNovosDummies()
{
    // Sorting once is good enough
    if (m_lNovosDummyGuids.empty())
        return;

    Creature* pNovos = GetSingleCreatureFromStorage(NPC_NOVOS);
    if (!pNovos)
        return;

    // First sort the Dummies to the Crystals
    for (uint8 i = 0; i < MAX_CRYSTALS; ++i)
    {
        GameObject* pCrystal = instance->GetGameObject(m_aNovosCrystalInfo[i].m_crystalGuid);
        if (!pCrystal)
            continue;

        for (GuidList::iterator itr = m_lNovosDummyGuids.begin(); itr != m_lNovosDummyGuids.end();)
        {
            Creature* pDummy = instance->GetCreature(*itr);
            if (!pDummy)
            {
                m_lNovosDummyGuids.erase(itr++);
                continue;
            }

            // Check if dummy fits to crystal
            if (pCrystal->IsWithinDistInMap(pDummy, INTERACTION_DISTANCE, false))
            {
                m_aNovosCrystalInfo[i].m_channelGuid = pDummy->GetObjectGuid();
                m_lNovosDummyGuids.erase(itr);
                break;
            }

            ++itr;
        }
    }

    // Find the crystal channel target (above Novos)
    float fNovosX, fNovosY, fNovosZ;
    pNovos->GetRespawnCoord(fNovosX, fNovosY, fNovosZ);
    for (GuidList::iterator itr = m_lNovosDummyGuids.begin(); itr != m_lNovosDummyGuids.end();)
    {
        Creature* pDummy = instance->GetCreature(*itr);
        if (!pDummy)
        {
            m_lNovosDummyGuids.erase(itr++);
            continue;
        }

        // As the wanted dummy is exactly above Novos, check small range, and only 2d
        if (pDummy->IsWithinDist2d(fNovosX, fNovosY, 5.0f))
        {
            m_novosChannelGuid = pDummy->GetObjectGuid();
            m_lNovosDummyGuids.erase(itr);
            break;
        }

        ++itr;
    }

    // Summon positions (at end of stairs)
    for (GuidList::iterator itr = m_lNovosDummyGuids.begin(); itr != m_lNovosDummyGuids.end();)
    {
        Creature* pDummy = instance->GetCreature(*itr);
        if (!pDummy)
        {
            m_lNovosDummyGuids.erase(itr++);
            continue;
        }

        // The wanted dummies are quite above Novos
        if (pDummy->GetPositionZ() > fNovosZ + 20.0f)
        {
            m_vSummonDummyGuids.push_back(pDummy->GetObjectGuid());
            m_lNovosDummyGuids.erase(itr++);
        }
        else
            ++itr;
    }

    // Clear remaining (unused) dummies
    m_lNovosDummyGuids.clear();
}
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);
    }
}
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);
    }
}
Example #9
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 #10
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);
}