Example #1
0
/// Returns true if indicated position is a suitable landing spot
bool CTAAirMoveType::CanLandAt(const float3& pos) const
{
    if (dontLand) {
        return false;
    }
    if (!autoLand) {
        return false;
    }
    if (!pos.IsInBounds()) {
        return false;
    }

    if ((ground->GetApproximateHeight(pos.x, pos.z) < 0.0f) && !(owner->unitDef->floater || owner->unitDef->canSubmerge)) {
        return false;
    }

    const int2 mp = owner->GetMapPos(pos);

    for (int z = mp.y; z < mp.y + owner->zsize; z++) {
        for (int x = mp.x; x < mp.x + owner->xsize; x++) {
            const CObject* o = groundBlockingObjectMap->GroundBlockedUnsafe(z * gs->mapx + x);
            if (o && o != owner) {
                return false;
            }
        }
    }

    return true;
}
Example #2
0
/// Returns true if indicated position is a suitable landing spot
bool CHoverAirMoveType::CanLandAt(const float3& pos) const
{
	if (forceHeading)
		return true;
	if (!CanLand(false))
		return false;
	if (!pos.IsInBounds())
		return false;

	const UnitDef* ud = owner->unitDef;
	const float gah = CGround::GetApproximateHeight(pos.x, pos.z);

	if ((gah < 0.0f) && !(ud->floatOnWater || ud->canSubmerge)) {
		return false;
	}

	const int2 mp = owner->GetMapPos(pos);

	for (int z = mp.y; z < mp.y + owner->zsize; z++) {
		for (int x = mp.x; x < mp.x + owner->xsize; x++) {
			if (groundBlockingObjectMap->GroundBlocked(x, z, owner)) {
				return false;
			}
		}
	}

	return true;
}
//Returns true if indicated position is a suitable landing spot
bool CTAAirMoveType::CanLandAt(float3 pos)
{
	if (dontLand)
		return false;

	if (!autoLand)
		return false;

	if (!pos.IsInBounds())
		return false;

	float h = ground->GetApproximateHeight(pos.x, pos.z);
	if ((h < 0) && !(owner -> unitDef -> floater || owner -> unitDef -> canSubmerge))
		return false;

	float3 tpos = owner->pos;
	owner->pos = pos;
	int2 mp = owner->GetMapPos();
	owner->pos = tpos;

	for (int z = mp.y; z < mp.y + owner->ysize; z++) {
		for (int x = mp.x; x < mp.x + owner->xsize; x++) {
			CObject* o = groundBlockingObjectMap->GroundBlockedUnsafe(z * gs->mapx + x);
			if (o && o != owner) {
				return false;
			}
		}
	}
	return true;
}
Example #4
0
void CDefenseMatrix::MaskBadBuildSpot(float3 pos) {
	if (pos.IsInBounds()) {
		const int f3multiplier = 8 * THREATRES;
		const int x = (int) (pos.x / f3multiplier);
		const int y = (int) (pos.z / f3multiplier);

		BuildMaskArray[y * ai->pather->PathMapXSize + x] = 1;
	}
}
Example #5
0
bool CTAAirMoveType::Update()
{
    float3& pos = owner->pos;
    float3& speed = owner->speed;

    // This is only set to false after the plane has finished constructing
    if (useHeading) {
        useHeading = false;
        SetState(AIRCRAFT_TAKEOFF);
    }

    if (owner->stunned || owner->beingBuilt) {
        wantedSpeed = ZeroVector;
        wantToStop = true;
    }

    // Allow us to stop if wanted
    if (wantToStop) {
        ExecuteStop();
    }

    const float3 lastSpeed = speed;

    if (owner->fpsControlPlayer != NULL) {
        SetState(AIRCRAFT_FLYING);

        const FPSUnitController& con = owner->fpsControlPlayer->fpsController;

        const float3 forward = con.viewDir;
        const float3 right = forward.cross(UpVector);
        const float3 nextPos = pos + speed;

        float3 flatForward = forward;
        flatForward.y = 0.0f;
        flatForward.Normalize();

        wantedSpeed = ZeroVector;

        if (con.forward) wantedSpeed += flatForward;
        if (con.back   ) wantedSpeed -= flatForward;
        if (con.right  ) wantedSpeed += right;
        if (con.left   ) wantedSpeed -= right;

        wantedSpeed.Normalize();
        wantedSpeed *= maxSpeed;

        if (!nextPos.IsInBounds()) {
            speed = ZeroVector;
        }

        UpdateAirPhysics();
        wantedHeading = GetHeadingFromVector(flatForward.x, flatForward.z);
    } else {

        if (reservedPad) {
            CUnit* unit = reservedPad->GetUnit();
            const float3 relPos = unit->script->GetPiecePos(reservedPad->GetPiece());
            const float3 pos = unit->pos + unit->frontdir * relPos.z
                               + unit->updir * relPos.y + unit->rightdir * relPos.x;

            if (padStatus == 0) {
                if (aircraftState != AIRCRAFT_FLYING && aircraftState != AIRCRAFT_TAKEOFF)
                    SetState(AIRCRAFT_FLYING);

                goalPos = pos;

                if (pos.SqDistance2D(owner->pos) < 400*400) {
                    padStatus = 1;
                }
            } else if (padStatus == 1) {
                if (aircraftState != AIRCRAFT_FLYING) {
                    SetState(AIRCRAFT_FLYING);
                }
                flyState = FLY_LANDING;

                goalPos = pos;
                reservedLandingPos = pos;
                wantedHeight = pos.y - ground->GetHeightAboveWater(pos.x, pos.z);

                if (owner->pos.SqDistance(pos) < 9 || aircraftState == AIRCRAFT_LANDED) {
                    padStatus = 2;
                }
            } else {
                if (aircraftState != AIRCRAFT_LANDED)
                    SetState(AIRCRAFT_LANDED);

                owner->pos = pos;
                owner->AddBuildPower(unit->unitDef->buildSpeed / 30, unit);
                owner->currentFuel = std::min(owner->unitDef->maxFuel,
                                              owner->currentFuel + (owner->unitDef->maxFuel
                                                      / (GAME_SPEED * owner->unitDef->refuelTime)));

                if (owner->health >= owner->maxHealth - 1
                        && owner->currentFuel >= owner->unitDef->maxFuel) {
                    airBaseHandler->LeaveLandingPad(reservedPad);
                    reservedPad = NULL;
                    padStatus = 0;
                    goalPos = oldGoalPos;
                    SetState(AIRCRAFT_TAKEOFF);
                }
            }
        }

        // Main state handling
        switch (aircraftState) {
        case AIRCRAFT_LANDED:
            UpdateLanded();
            break;
        case AIRCRAFT_TAKEOFF:
            UpdateTakeoff();
            break;
        case AIRCRAFT_FLYING:
            UpdateFlying();
            break;
        case AIRCRAFT_LANDING:
            UpdateLanding();
            break;
        case AIRCRAFT_HOVERING:
            UpdateHovering();
            break;
        case AIRCRAFT_CRASHING:
            break;
        }
    }


    // Banking requires deltaSpeed.y = 0
    deltaSpeed = speed - lastSpeed;
    deltaSpeed.y = 0.0f;

    // Turn and bank and move; update dirs
    UpdateHeading();
    UpdateBanking(aircraftState == AIRCRAFT_HOVERING);

    owner->UpdateMidPos();
    return (HandleCollisions());
}
Example #6
0
bool CHoverAirMoveType::Update()
{
	const float3 lastPos = owner->pos;
	const float4 lastSpd = owner->speed;

	AAirMoveType::Update();

	if ((owner->IsStunned() && !owner->IsCrashing()) || owner->beingBuilt) {
		wantedSpeed = ZeroVector;

		UpdateAirPhysics();
		return (HandleCollisions(collide && !owner->beingBuilt && (padStatus == PAD_STATUS_FLYING) && (aircraftState != AIRCRAFT_TAKEOFF)));
	}

	// allow us to stop if wanted (changes aircraft state)
	if (wantToStop)
		ExecuteStop();

	if (aircraftState != AIRCRAFT_CRASHING) {
		if (owner->UnderFirstPersonControl()) {
			SetState(AIRCRAFT_FLYING);

			const FPSUnitController& con = owner->fpsControlPlayer->fpsController;

			const float3 forward = con.viewDir;
			const float3 right = forward.cross(UpVector);
			const float3 nextPos = lastPos + owner->speed;

			float3 flatForward = forward;
			flatForward.Normalize2D();

			wantedSpeed = ZeroVector;

			if (con.forward) wantedSpeed += flatForward;
			if (con.back   ) wantedSpeed -= flatForward;
			if (con.right  ) wantedSpeed += right;
			if (con.left   ) wantedSpeed -= right;

			wantedSpeed.Normalize();
			wantedSpeed *= maxSpeed;

			if (!nextPos.IsInBounds()) {
				owner->SetVelocityAndSpeed(ZeroVector);
			}

			UpdateAirPhysics();
			wantedHeading = GetHeadingFromVector(flatForward.x, flatForward.z);
		}

		if (reservedPad != NULL) {
			MoveToRepairPad();

			if (padStatus >= PAD_STATUS_LANDING) {
				flyState = FLY_LANDING;
			}
		}
	}

	switch (aircraftState) {
		case AIRCRAFT_LANDED:
			UpdateLanded();
			break;
		case AIRCRAFT_TAKEOFF:
			UpdateTakeoff();
			break;
		case AIRCRAFT_FLYING:
			UpdateFlying();
			break;
		case AIRCRAFT_LANDING:
			UpdateLanding();
			break;
		case AIRCRAFT_HOVERING:
			UpdateHovering();
			break;
		case AIRCRAFT_CRASHING: {
			UpdateAirPhysics();

			if ((CGround::GetHeightAboveWater(owner->pos.x, owner->pos.z) + 5.0f + owner->radius) > owner->pos.y) {
				owner->ClearPhysicalStateBit(CSolidObject::PSTATE_BIT_CRASHING);
				owner->KillUnit(NULL, true, false);
			} else {
				#define SPIN_DIR(o) ((o->id & 1) * 2 - 1)
				wantedHeading = GetHeadingFromVector(owner->rightdir.x * SPIN_DIR(owner), owner->rightdir.z * SPIN_DIR(owner));
				wantedHeight = 0.0f;
				#undef SPIN_DIR
			}

			new CSmokeProjectile(owner, owner->midPos, gs->randVector() * 0.08f, 100 + gs->randFloat() * 50, 5, 0.2f, 0.4f);
		} break;
	}

	if (lastSpd == ZeroVector && owner->speed != ZeroVector) { owner->script->StartMoving(false); }
	if (lastSpd != ZeroVector && owner->speed == ZeroVector) { owner->script->StopMoving(); }

	// Banking requires deltaSpeed.y = 0
	deltaSpeed = owner->speed - lastSpd;
	deltaSpeed.y = 0.0f;

	// Turn and bank and move; update dirs
	UpdateHeading();
	UpdateBanking(aircraftState == AIRCRAFT_HOVERING);

	return (HandleCollisions(collide && !owner->beingBuilt && (padStatus == PAD_STATUS_FLYING) && (aircraftState != AIRCRAFT_TAKEOFF)));
}
Example #7
0
bool CHoverAirMoveType::Update()
{
	float3& pos = owner->pos;
	float3& speed = owner->speed;

	AAirMoveType::Update();

	if (owner->stunned || owner->beingBuilt) {
		wantedSpeed = ZeroVector;
		wantToStop = true;
	}

	// Allow us to stop if wanted
	if (wantToStop) {
		ExecuteStop();
	}

	const float3 lastSpeed = speed;

	if (owner->fpsControlPlayer != NULL) {
		SetState(AIRCRAFT_FLYING);

		const FPSUnitController& con = owner->fpsControlPlayer->fpsController;

		const float3 forward = con.viewDir;
		const float3 right = forward.cross(UpVector);
		const float3 nextPos = pos + speed;

		float3 flatForward = forward;
		flatForward.y = 0.0f;
		flatForward.Normalize();

		wantedSpeed = ZeroVector;

		if (con.forward) wantedSpeed += flatForward;
		if (con.back   ) wantedSpeed -= flatForward;
		if (con.right  ) wantedSpeed += right;
		if (con.left   ) wantedSpeed -= right;

		wantedSpeed.Normalize();
		wantedSpeed *= maxSpeed;

		if (!nextPos.IsInBounds()) {
			speed = ZeroVector;
		}

		UpdateAirPhysics();
		wantedHeading = GetHeadingFromVector(flatForward.x, flatForward.z);
	} else {
		if (reservedPad != NULL) {
			MoveToRepairPad();

			if (padStatus >= 1) {
				flyState = FLY_LANDING;
			}
		}

		// Main state handling
		switch (aircraftState) {
			case AIRCRAFT_LANDED:
				UpdateLanded();
				break;
			case AIRCRAFT_TAKEOFF:
				UpdateTakeoff();
				break;
			case AIRCRAFT_FLYING:
				UpdateFlying();
				break;
			case AIRCRAFT_LANDING:
				UpdateLanding();
				break;
			case AIRCRAFT_HOVERING:
				UpdateHovering();
				break;
			case AIRCRAFT_CRASHING:
				break;
		}
	}


	// Banking requires deltaSpeed.y = 0
	deltaSpeed = speed - lastSpeed;
	deltaSpeed.y = 0.0f;

	// Turn and bank and move; update dirs
	UpdateHeading();
	UpdateBanking(aircraftState == AIRCRAFT_HOVERING);

	return (HandleCollisions());
}
Example #8
0
void CFactory::SendToEmptySpot(CUnit* unit)
{
	const float searchRadius = radius * 4.0f + unit->radius * 4.0f;
	const int numSteps = 36;

	const float3 exitPos = pos + frontdir*(radius + unit->radius);
	float3 foundPos = pos + frontdir * searchRadius;
	const float3 tempPos = foundPos;

	for (int x = 0; x < numSteps; ++x) {
		const float a = searchRadius * math::cos(x * PI / (numSteps * 0.5f));
		const float b = searchRadius * math::sin(x * PI / (numSteps * 0.5f));

		float3 testPos = pos + frontdir * a + rightdir * b;

		if (!testPos.IsInBounds())
			continue;
		// don't pick spots behind the factory (because
		// units will want to path through it when open
		// which slows down production)
		if ((testPos - pos).dot(frontdir) < 0.0f)
			continue;

		testPos.y = CGround::GetHeightAboveWater(testPos.x, testPos.z);

		if (quadField->GetSolidsExact(testPos, unit->radius * 1.5f, 0xFFFFFFFF, CSolidObject::CSTATE_BIT_SOLIDOBJECTS).empty()) {
			foundPos = testPos; break;
		}
	}

	if (foundPos == tempPos) {
		// no empty spot found, pick one randomly so units do not pile up even more
		// also make sure not to loop forever if we happen to be facing a map border
		foundPos.y = 0.0f;

		do {
			const float x = ((gs->randInt() * 1.0f) / RANDINT_MAX) * numSteps;
			const float a = searchRadius * math::cos(x * PI / (numSteps * 0.5f));
			const float b = searchRadius * math::sin(x * PI / (numSteps * 0.5f));

			foundPos.x = pos.x + frontdir.x * a + rightdir.x * b;
			foundPos.z = pos.z + frontdir.z * a + rightdir.z * b;
			foundPos.y += 1.0f;
		} while ((!foundPos.IsInBounds() || (foundPos - pos).dot(frontdir) < 0.0f) && (foundPos.y < 100.0f));

		foundPos.y = CGround::GetHeightAboveWater(foundPos.x, foundPos.z);
	}

	// first queue a temporary waypoint outside the factory
	// (otherwise units will try to turn before exiting when
	// foundPos lies behind exit and cause jams / get stuck)
	// we assume this temporary point is not itself blocked
	//
	// NOTE:
	//   MobileCAI::AutoGenerateTarget inserts a _third_
	//   command when |foundPos - tempPos| >= 100 elmos,
	//   because MobileCAI::FinishCommand only updates
	//   lastUserGoal for non-internal orders --> the
	//   final order given here should not be internal
	//   (and should also be more than CMD_CANCEL_DIST
	//   elmos distant from foundPos)
	//
	if (!unit->unitDef->canfly && exitPos.IsInBounds()) {
		Command c0(CMD_MOVE, SHIFT_KEY, exitPos);
		unit->commandAI->GiveCommand(c0);
	}
	Command c1(CMD_MOVE, SHIFT_KEY, foundPos);
	unit->commandAI->GiveCommand(c1);
}