/* Starshatter: The Open Source Project Copyright (c) 2021-2024, Starshatter: The Open Source Project Contributors Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors Copyright (c) 1997-2006, Destroyer Studios LLC. AUTHOR: John DiCamillo OVERVIEW ======== CampaignPlanAssignment creates combat assignments for assets within each combat zone as the third step in force tasking. */ #include "CampaignPlanAssignment.h" #include "Campaign.h" #include "Combatant.h" #include "CombatAssignment.h" #include "CombatGroup.h" #include "CombatUnit.h" #include "CombatZone.h" #include "Mission.h" // +--------------------------------------------------------------------+ void CampaignPlanAssignment::ExecFrame() { if (campaign && campaign->IsActive()) { // once every few minutes is plenty: if (Campaign::Stardate() - exec_time < 300) return; ListIter iter = campaign->GetCombatants(); while (++iter) { ProcessCombatant(iter.value()); } exec_time = Campaign::Stardate(); } } // +--------------------------------------------------------------------+ void CampaignPlanAssignment::ProcessCombatant(Combatant* c) { CombatGroup* force = c->GetForce(); if (force) { force->CalcValue(); force->ClearAssignments(); } ListIter zone = campaign->GetZones(); while (++zone) { ProcessZone(c, zone.value()); } } // +--------------------------------------------------------------------+ void CampaignPlanAssignment::BuildZoneList(CombatGroup* g, CombatZone* zone, List& groups) { if (!g) return; if (g->GetAssignedZone() == zone) groups.append(g); ListIter iter = g->GetComponents(); while (++iter) BuildZoneList(iter.value(), zone, groups); } // +--------------------------------------------------------------------+ void CampaignPlanAssignment::BuildAssetList(const int* pref, List& groups, List& assets) { if (!pref) return; while (*pref) { ListIter g = groups; while (++g) { if (g->Type() == *pref && g->CountUnits() > 0) assets.append(g.value()); } pref++; } } // +--------------------------------------------------------------------+ void CampaignPlanAssignment::ProcessZone(Combatant* c, CombatZone* zone) { List groups; BuildZoneList(c->GetForce(), zone, groups); ZoneForce* force = zone->FindForce(c->GetIFF()); // defensive assignments: ListIter def = force->GetDefendList(); while (++def) { List assets; BuildAssetList(CombatGroup::PreferredDefender(def->Type()), groups, assets); ListIter g = assets; while (++g) { CombatAssignment* a = new CombatAssignment(Mission::DEFEND, def.value(), g.value()); if (a) g->GetAssignments().append(a); } } // offensive assignments: ListIter tgt = force->GetTargetList(); while (++tgt) { CombatGroup* target = tgt.value(); List assets; BuildAssetList(CombatGroup::PreferredAttacker(tgt->Type()), groups, assets); ListIter g = assets; while (++g) { CombatGroup* asset = g.value(); int mtype = Mission::ASSAULT; if (target->IsStrikeTarget()) mtype = Mission::STRIKE; else if (target->IsFighterGroup()) mtype = Mission::SWEEP; else if (target->Type() == CombatGroup::LCA_SQUADRON) mtype = Mission::INTERCEPT; CombatAssignment* a = new CombatAssignment(mtype, target, asset); if (a) g->GetAssignments().append(a); } } }