AAirMoveType::~AAirMoveType() { // NOTE: // this calls Takeoff and (indirectly) SetState, // so neither of these must be pure virtuals (!) UnreservePad(reservedPad); }
bool AAirMoveType::MoveToRepairPad() { CUnit* airBase = reservedPad->GetUnit(); if (airBase->beingBuilt || airBase->IsStunned()) { // pad became inoperable after being reserved DependentDied(airBase); return false; } else { const float3& relPadPos = airBase->script->GetPiecePos(reservedPad->GetPiece()); const float3 absPadPos = airBase->GetObjectSpacePos(relPadPos); switch (padStatus) { case PAD_STATUS_FLYING: { // flying toward pad if (aircraftState != AIRCRAFT_FLYING && aircraftState != AIRCRAFT_TAKEOFF) { SetState(AIRCRAFT_FLYING); } if (CanLandOnPad(goalPos = absPadPos)) { padStatus = PAD_STATUS_LANDING; } } break; case PAD_STATUS_LANDING: { // landing on pad if (HaveLandedOnPad(goalPos = absPadPos)) { padStatus = PAD_STATUS_ARRIVED; } } break; case PAD_STATUS_ARRIVED: { if (aircraftState != AIRCRAFT_LANDED) { SetState(AIRCRAFT_LANDED); } owner->SetVelocityAndSpeed(ZeroVector); owner->Move(absPadPos, false); owner->UpdateMidAndAimPos(); // needed here? owner->AddBuildPower(airBase, airBase->unitDef->buildSpeed / GAME_SPEED); 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); } } break; } } return true; }
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; }