void CampaignPlanStrategic::ExecFrame() { if (campaign && campaign->IsActive()) { if (Campaign::Stardate() - exec_time < 300) return; ListIter<CombatZone> zone = campaign->GetZones(); while (++zone) zone->Clear(); ListIter<Combatant> iter = campaign->GetCombatants(); while (++iter) { Combatant* c = iter.value(); CombatGroup* force = c->GetForce(); force->CalcValue(); PlaceGroup(force); ScoreCombatant(c); ScoreNeeds(c); force->ClearUnlockedZones(); AssignZones(c); ResolveZoneMovement(force); } exec_time = Campaign::Stardate(); } }
bool CombatAction::IsAvailable() const { CombatAction* pThis = (CombatAction*) this; if (rval < 0) { pThis->rval = (int) Random(0, 100); if (rval > probability) pThis->status = SKIPPED; } if (status != PENDING) return false; if (min_rank > 0 || max_rank < 100) { Player* player = Player::GetCurrentPlayer(); if (player->Rank() < min_rank || player->Rank() > max_rank) return false; } Campaign* campaign = Campaign::GetCampaign(); if (campaign) { if (campaign->GetTime() < start_after) { return false; } if (campaign->GetTime() > start_before) { pThis->status = FAILED; // too late! return false; } // check requirements against actions in current campaign: ListIter<CombatActionReq> iter = pThis->requirements; while (++iter) { CombatActionReq* r = iter.value(); bool ok = false; if (r->action > 0) { ListIter<CombatAction> action = campaign->GetActions(); while (++action) { CombatAction* a = action.value(); if (a->Identity() == r->action) { if (r->not) { if (a->Status() == r->stat) return false; } else { if (a->Status() != r->stat) return false; } } } } // group-based requirement else if (r->group_type > 0) { if (r->c1) { CombatGroup* group = r->c1->FindGroup(r->group_type, r->group_id); if (group) { int test = 0; int comp = 0; if (r->intel) { test = group->IntelLevel(); comp = r->intel; } else { test = group->CalcValue(); comp = r->score; } switch (r->comp) { case CombatActionReq::LT: ok = (test < comp); break; case CombatActionReq::LE: ok = (test <= comp); break; case CombatActionReq::GT: ok = (test > comp); break; case CombatActionReq::GE: ok = (test >= comp); break; case CombatActionReq::EQ: ok = (test == comp); break; } } if (!ok) return false; } } // score-based requirement else { int test = 0; if (r->comp <= CombatActionReq::EQ) { // absolute if (r->c1) { int test = r->c1->Score(); switch (r->comp) { case CombatActionReq::LT: ok = (test < r->score); break; case CombatActionReq::LE: ok = (test <= r->score); break; case CombatActionReq::GT: ok = (test > r->score); break; case CombatActionReq::GE: ok = (test >= r->score); break; case CombatActionReq::EQ: ok = (test == r->score); break; } } } else { // relative if (r->c1 && r->c2) { int test = r->c1->Score() - r->c2->Score(); switch (r->comp) { case CombatActionReq::RLT: ok = (test < r->score); break; case CombatActionReq::RLE: ok = (test <= r->score); break; case CombatActionReq::RGT: ok = (test > r->score); break; case CombatActionReq::RGE: ok = (test >= r->score); break; case CombatActionReq::REQ: ok = (test == r->score); break; } } } if (!ok) return false; } if (delay > 0) { pThis->start_after = (int) campaign->GetTime() + delay; pThis->delay = 0; return IsAvailable(); } } } return true; }
CampaignMissionRequest* CampaignPlanMission::PlanRandomFighterMission() { CampaignMissionRequest* request = 0; int type = fighter_mission_types[fighter_mission_index++]; int ownside = player_group->GetIFF(); CombatGroup* primary = player_group; CombatGroup* obj = 0; if (fighter_mission_index > 15) fighter_mission_index = 0; if (type == Mission::ESCORT_FREIGHT) { CombatGroup* freight = campaign->FindGroup(ownside, CombatGroup::FREIGHT); if (!freight || freight->CalcValue() < 1) type = Mission::PATROL; else obj = freight; } else if (type == Mission::ESCORT_SHUTTLE) { CombatGroup* shuttle = campaign->FindGroup(ownside, CombatGroup::LCA_SQUADRON); if (!shuttle || shuttle->CalcValue() < 1) type = Mission::PATROL; else obj = shuttle; } else if (primary->Type() == CombatGroup::WING) { if (RandomChance()) primary = primary->FindGroup(CombatGroup::INTERCEPT_SQUADRON); else primary = primary->FindGroup(CombatGroup::FIGHTER_SQUADRON); } if (type >= Mission::AIR_PATROL && type <= Mission::AIR_INTERCEPT) { CombatZone* zone = 0; bool airborne = false; if (primary) zone = primary->GetAssignedZone(); if (zone && zone->GetRegions().size() > 1) { Text air_region = *zone->GetRegions().at(1); StarSystem* system = campaign->GetSystem(zone->System()); if (system) { OrbitalRegion* rgn = system->FindRegion(air_region); if (rgn && rgn->Type() == Orbital::TERRAIN) airborne = true; } } if (!airborne) { if (type == Mission::AIR_INTERCEPT) type = Mission::INTERCEPT; else if (type == Mission::AIR_SWEEP) type = Mission::SWEEP; else type = Mission::PATROL; } } request = new(__FILE__,__LINE__) CampaignMissionRequest(campaign, type, start, primary); if (request) request->SetObjective(obj); return request; }