Esempio n. 1
0
WayPoint ResetCurrentWP (TaskForce tf)
{
    WayPoint	w;
    GridIndex	x,y,ux,uy;

    w = tf->GetCurrentUnitWP();
    while (w && w->GetWPDepartureTime() < Camp_GetCurrentTime())
    {
        if (w->GetWPFlags())				// Make sure we actually get here, it's important
        {
            w->GetWPLocation(&x,&y);
            tf->GetLocation(&ux,&uy);
            if (DistSqu(x,y,ux,uy) > 2.0F)
                return w;
            if (DoWPAction(tf,w))
                return tf->GetCurrentUnitWP();
        }
        w = w->GetNextWP();
        tf->SetCurrentUnitWP(w);
    }
    return w;
}
Esempio n. 2
0
int TaskForceClass::MoveUnit (CampaignTime time)
{
    GridIndex x = 0, y = 0;
    GridIndex nx = 0, ny = 0;
    GridIndex ox = 0, oy = 0;
    WayPoint w = NULL, ow = NULL;
    Objective o = NULL;
    int	moving = 1;
    CampaignHeading	h = 0;

    // RV - Biker
    // Naval units now have three modes:
    // (a) Sit still in harbor
    // (b) Do a 20 km track (repeating waypoints)
    // (c) Followy WPs

    GetLocation(&x,&y);

    w = ResetCurrentWP(this);

    FindNearestUnit(x, y, NULL);

    // Check for mode a
    o = FindNearestObjective(x, y, NULL, 1);

    // RV - Biker - If we are in port and have no WPs do nothing
    if (o && o->GetType() == TYPE_PORT && !w) {
        return TRUE;
    }

    // If not in port and no WPs... create a repeating path 20 km north and back
    if (!w)	{
        DisposeWayPoints();

        w = AddUnitWP(x, y, 0, 60,	TheCampaign.CurrentTime + (rand()%15), 0, 0);
        w->SetWPFlags(WPF_REPEAT);

        // This should prevent naval units to run into ground
        if (GetCover(x, y+20) == Water) {
            w = AddUnitWP(x, y+20, 0, 60, TheCampaign.CurrentTime + (15+(rand()%15))*CampaignMinutes, 0, 0);
        }
        else {
            w = AddUnitWP(x, y, 0, 60, TheCampaign.CurrentTime + 15*CampaignMinutes, 0, 0);
        }
        w->SetWPFlags(WPF_REPEAT);

        w = AddUnitWP(x, y, 0, 60, TheCampaign.CurrentTime + (30+(rand()%15))*CampaignMinutes, 0xffffffff, 0);
        w->SetWPFlags(WPF_REPEAT);

        SetCurrentWaypoint (1);
        w = GetCurrentUnitWP();
    }

    w->GetWPLocation(&nx, &ny);

    // RV - Biker - Wait for departure
    if (Camp_GetCurrentTime() < w->GetWPDepartureTime()) {
        SetUnitLastMove(Camp_GetCurrentTime());
        return 0;
    }

    // Move, if we're not at destination
    if (x!=nx || y!=ny)
    {
        if (w)
            ow = w->GetPrevWP();
        if (ow)
            ow->GetWPLocation(&ox, &oy);
        else
            GetLocation(&ox, &oy);

        while (moving) {
            h = DirectionTo(ox, oy, nx, ny, x, y);
            if (h > 7) {
                moving = 0;
                h = Here;
            }
            // This is kinda hacky - basically, limit change in direction to 45 deg per move
            if (h > last_direction) {
                if (h - last_direction < 5)
                    h = (last_direction+1) & 0x07;
                else
                    h = (last_direction+7) & 0x07;
            }

            else if (h < last_direction) {
                if (last_direction - h < 5)
                    h = (last_direction+7) & 0x07;
                else
                    h = (last_direction+1) & 0x07;
            }

            //this moves the unit
            if (ChangeUnitLocation(h) > 0) {
                last_direction = h;
            }
            else {
                moving = 0;
            }

            // Now do combat
            if (GetCombatTime() > CombatTime()) {
                DoCombat();
            }
        }
    }
    return 0;
}
Esempio n. 3
0
int TaskForceClass::GetVehicleDeagData (SimInitDataClass *simdata, int remote)
{
    static CampEntity		ent;
    static int				round;
    int						dist, i, ptIndexAt;

    // Reinitialize static vars upon query of first vehicle
    if (simdata->vehicleInUnit < 0)
    {
        simdata->vehicleInUnit = 0;
        ent = NULL;

        if (!remote)
        {
            // Used only in port
            round = 0;
            simdata->ptIndex = GetDeaggregationPoint(0, &ent);
            if (simdata->ptIndex) {
                // Yuck!  The first call returns only the list index, NOT a real point index.
                // To ensure we have at least one set of points we have to actually query for them
                // then reset again...
                simdata->ptIndex = GetDeaggregationPoint(0, &ent);
                if (simdata->ptIndex)
                    simdata->ptIndex = GetDeaggregationPoint(0, &ent);
                ent = NULL;
                GetDeaggregationPoint(0, &ent);
            }

            // Used only at sea
            WayPoint			w;
            w = GetCurrentUnitWP();
            if (w)
            {
                // Find heading to next waypoint
                GridIndex	ux,uy,wx,wy;
                GetLocation(&ux,&uy);
                w->GetWPLocation(&wx,&wy);
                simdata->heading = AngleTo(ux,uy,wx,wy);
            }
        }
    }
    else
    {
        simdata->vehicleInUnit++;
    }

    if (!remote)
    {
        if (simdata->ptIndex) {
            // In port
            float	dx, dy;

            // Find the center point and direction point for this ship
            simdata->ptIndex = GetDeaggregationPoint(simdata->campSlot, &ent);
            ptIndexAt        = GetDeaggregationPoint(simdata->campSlot, &ent);

            if (!ptIndexAt)
            {
                ShiAssert( !simdata->ptIndex );	// We should always have an even number of points

                // Reuse the old points, but with an offset
                ent = NULL;
                GetDeaggregationPoint(simdata->campSlot, &ent);		// Reset
                simdata->ptIndex = GetDeaggregationPoint(simdata->campSlot, &ent);
                ptIndexAt        = GetDeaggregationPoint(simdata->campSlot, &ent);
                round++;
            }
            ShiAssert( ptIndexAt );		// We must have at least two points (center and toward)
            TranslatePointData(ent, simdata->ptIndex, &simdata->x, &simdata->y);

            // Face toward the "at" point
            dx = PtDataTable[ptIndexAt].yOffset - PtDataTable[simdata->ptIndex].yOffset; // KCK NOTE: axis' are reversed
            dy = PtDataTable[ptIndexAt].xOffset - PtDataTable[simdata->ptIndex].xOffset; // KCK NOTE: axis' are reversed
            simdata->heading = (float)atan2(dx,dy);

            // If we reused a point, shift our center point along the at vector
            simdata->x += dx * round;
            simdata->y += dy * round;
        } else {
            // At sea
            dist = (simdata->vehicleInUnit - 1) >> 2;
            switch ( (simdata->vehicleInUnit - 1) & 0x3 )
            {
            case 0:
                simdata->x = XPos() - 1500.0f - 1500.0f * dist;
                simdata->y = YPos() - 1500.0f - 1500.0f * dist;
                break;
            case 1:
                simdata->x = XPos() + 1500.0f + 1500.0f * dist;
                simdata->y = YPos() - 1500.0f - 1500.0f * dist;
                break;
            case 2:
                simdata->x = XPos() + 1500.0f + 1500.0f * dist;
                simdata->y = YPos() + 1500.0f + 1500.0f * dist;
                break;
            case 3:
            default:
                simdata->x = XPos() - 1500.0f - 1500.0f * dist;
                simdata->y = YPos() + 1500.0f + 1500.0f * dist;
                break;
            }
        }
    }

    // We're always at sea level
    simdata->z = 0.0f;

    // Determine skill (Sim only uses it for anti-air stuff right now, so bow to expedience
    simdata->skill = ((TeamInfo[GetOwner()]->airDefenseExperience - 60) / 10) + rand()%3 - 1;
    //	simdata->skill = ((TeamInfo[GetOwner()]->navalExperience - 60) / 10) + rand()%3 - 1;

    // Clamp it to legal sim side values
    if (simdata->skill > 4)
        simdata->skill = 4;
    if (simdata->skill < 0)
        simdata->skill = 0;

    // Weapon loadout
    for (i=0; i<HARDPOINT_MAX; i++)
    {
        simdata->weapon[i] = GetUnitWeaponId(i,simdata->campSlot);
        if (simdata->weapon[i])
            simdata->weapons[i] = GetUnitWeaponCount(i,simdata->campSlot);
        else
            simdata->weapons[i] = 0;
    }

    simdata->playerSlot = NO_PILOT;
    simdata->waypointList = CloneWPToList(GetFirstUnitWP(),NULL);

    return  MOTION_GND_AI;
}