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; }
CAirBaseHandler::LandingPad* CAirBaseHandler::FindAirBase(CUnit* unit, float minPower, bool wantFreePad) { float minDist = std::numeric_limits<float>::max(); AirBaseLstIt foundBaseIt = bases[unit->allyteam].end(); for (AirBaseLstIt bi = bases[unit->allyteam].begin(); bi != bases[unit->allyteam].end(); ++bi) { AirBase* base = *bi; CUnit* baseUnit = base->unit; if (unit == baseUnit) { // do not pick ourselves as a landing pad continue; } if (baseUnit->beingBuilt || baseUnit->IsStunned()) { continue; } if (baseUnit->pos.SqDistance(unit->pos) >= minDist || baseUnit->unitDef->buildSpeed < minPower) { continue; } if (wantFreePad && base->freePads.empty()) { continue; } minDist = baseUnit->pos.SqDistance(unit->pos); foundBaseIt = bi; } if (foundBaseIt != bases[unit->allyteam].end()) { AirBase* foundBase = *foundBaseIt; if (wantFreePad) { LandingPad* foundPad = foundBase->freePads.front(); foundBase->freePads.pop_front(); return foundPad; } else { if (!foundBase->pads.empty()) return foundBase->pads.front(); } } return NULL; }