Example #1
0
bool AAirMoveType::HaveLandedOnPad(const float3& padPos) {
	const AircraftState landingState = GetLandingState();
	const float landingPadHeight = CGround::GetHeightAboveWater(padPos.x, padPos.z);

	reservedLandingPos = padPos;
	wantedHeight = padPos.y - landingPadHeight;

	const float3 padVector = (padPos - owner->pos).SafeNormalize2D();
	const float curOwnerAltitude = (owner->pos.y - landingPadHeight);
	const float minOwnerAltitude = (wantedHeight + 1.0f);

	if (aircraftState != landingState)
		SetState(landingState);
	if (aircraftState == AIRCRAFT_LANDED)
		return true;

	if (curOwnerAltitude <= minOwnerAltitude) {
		// deal with overshooting aircraft: "tractor" them in
		// once they descend down to the landing pad altitude
		// this is a no-op for HAMT planes which do not apply
		// speed updates at this point
		owner->SetVelocityAndSpeed((owner->speed + (padVector * accRate)) * XZVector);
	}

	if (Square(owner->rightdir.y) < 0.01f && owner->frontdir.dot(padVector) > 0.01f) {
		owner->frontdir = padVector;
		owner->rightdir = owner->frontdir.cross(UpVector);
		owner->updir    = owner->rightdir.cross(owner->frontdir);

		owner->SetHeadingFromDirection();
	}

	if (curOwnerAltitude > minOwnerAltitude)
		return false;

	return ((owner->pos.SqDistance2D(padPos) <= 1.0f || owner->unitDef->IsHoveringAirUnit()));
}
Example #2
0
bool AAirMoveType::MoveToRepairPad() {
	CUnit* airBase = reservedPad->GetUnit();

	if (airBase->beingBuilt || airBase->stunned) {
		// pad became inoperable after being reserved
		DependentDied(airBase);
		return false;
	} else {
		const float3& relPadPos = airBase->script->GetPiecePos(reservedPad->GetPiece());
		const float3 absPadPos = airBase->pos +
			(airBase->frontdir * relPadPos.z) +
			(airBase->updir    * relPadPos.y) +
			(airBase->rightdir * relPadPos.x);

		if (padStatus == 0) {
			// approaching pad
			if (aircraftState != AIRCRAFT_FLYING && aircraftState != AIRCRAFT_TAKEOFF) {
				SetState(AIRCRAFT_FLYING);
			}

			goalPos = absPadPos;

			if (absPadPos.SqDistance2D(owner->pos) < (400.0f * 400.0f)) {
				padStatus = 1;
			}
		} else if (padStatus == 1) {
			// landing on pad
			const AircraftState landingState = GetLandingState();
			if (aircraftState != landingState)
				SetState(landingState);

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

			if ((owner->pos.SqDistance(absPadPos) < SQUARE_SIZE * SQUARE_SIZE) || aircraftState == AIRCRAFT_LANDED) {
				padStatus = 2;
			}
		} else {
			// taking off from pad
			if (aircraftState != AIRCRAFT_LANDED) {
				SetState(AIRCRAFT_LANDED);
			}

			owner->pos = absPadPos;

			owner->UpdateMidPos();
			owner->AddBuildPower(airBase->unitDef->buildSpeed / GAME_SPEED, airBase);

			owner->currentFuel += (owner->unitDef->maxFuel / (GAME_SPEED * owner->unitDef->refuelTime));
			owner->currentFuel = std::min(owner->unitDef->maxFuel, owner->currentFuel);

			if (owner->health >= owner->maxHealth - 1.0f && owner->currentFuel >= owner->unitDef->maxFuel) {
				// repaired and filled up, leave the pad
				UnreservePad(reservedPad);
			}
		}
	}

	return true;
}