summaryrefslogtreecommitdiffhomepage
path: root/Stars45/FltDlg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Stars45/FltDlg.cpp')
-rw-r--r--Stars45/FltDlg.cpp2194
1 files changed, 1109 insertions, 1085 deletions
diff --git a/Stars45/FltDlg.cpp b/Stars45/FltDlg.cpp
index c9ac443..c432b82 100644
--- a/Stars45/FltDlg.cpp
+++ b/Stars45/FltDlg.cpp
@@ -1,1085 +1,1109 @@
-/* Project Starshatter 4.5
- Destroyer Studios LLC
- Copyright (C) 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Stars.exe
- FILE: FltDlg.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
-*/
-
-#include "MemDebug.h"
-#include "FltDlg.h"
-#include "GameScreen.h"
-#include "Sim.h"
-#include "Ship.h"
-#include "ShipDesign.h"
-#include "Hangar.h"
-#include "FlightDeck.h"
-#include "Element.h"
-#include "CombatGroup.h"
-#include "Mission.h"
-#include "RadioMessage.h"
-#include "RadioTraffic.h"
-#include "Instruction.h"
-#include "FlightPlanner.h"
-#include "NetUtil.h"
-
-#include "Game.h"
-#include "Button.h"
-#include "ListBox.h"
-#include "ComboBox.h"
-#include "FormatUtil.h"
-
-// +--------------------------------------------------------------------+
-// DECLARE MAPPING FUNCTIONS:
-DEF_MAP_CLIENT(FltDlg, OnFilter);
-DEF_MAP_CLIENT(FltDlg, OnPackage);
-DEF_MAP_CLIENT(FltDlg, OnAlert);
-DEF_MAP_CLIENT(FltDlg, OnLaunch);
-DEF_MAP_CLIENT(FltDlg, OnStandDown);
-DEF_MAP_CLIENT(FltDlg, OnRecall);
-DEF_MAP_CLIENT(FltDlg, OnClose);
-DEF_MAP_CLIENT(FltDlg, OnMissionType);
-
-// +--------------------------------------------------------------------+
-
-static const ShipDesign* design = 0;
-
-// +--------------------------------------------------------------------+
-
-FltDlg::FltDlg(Screen* s, FormDef& def, GameScreen* mgr)
-: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr),
-ship(0), filter_list(0), hangar_list(0),
-package_btn(0), alert_btn(0), launch_btn(0), stand_btn(0), recall_btn(0),
-mission_type(-1), flight_planner(0), patrol_pattern(0)
-{
- Init(def);
-}
-
-FltDlg::~FltDlg()
-{
- delete flight_planner;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::RegisterControls()
-{
- filter_list = (ComboBox*) FindControl(101);
- hangar_list = (ListBox*) FindControl(102);
- package_btn = (Button*) FindControl(110);
- alert_btn = (Button*) FindControl(111);
- launch_btn = (Button*) FindControl(112);
- stand_btn = (Button*) FindControl(113);
- recall_btn = (Button*) FindControl(114);
- close_btn = (Button*) FindControl(1);
-
- if (filter_list)
- REGISTER_CLIENT(EID_SELECT, filter_list, FltDlg, OnFilter);
-
- if (package_btn)
- REGISTER_CLIENT(EID_CLICK, package_btn, FltDlg, OnPackage);
-
- if (alert_btn)
- REGISTER_CLIENT(EID_CLICK, alert_btn, FltDlg, OnAlert);
-
- if (launch_btn)
- REGISTER_CLIENT(EID_CLICK, launch_btn, FltDlg, OnLaunch);
-
- if (stand_btn)
- REGISTER_CLIENT(EID_CLICK, stand_btn, FltDlg, OnStandDown);
-
- if (recall_btn)
- REGISTER_CLIENT(EID_CLICK, recall_btn, FltDlg, OnRecall);
-
- if (close_btn)
- REGISTER_CLIENT(EID_CLICK, close_btn, FltDlg, OnClose);
-
- for (int i = 0; i < 6; i++) {
- mission_btn[i] = (Button*) FindControl(210 + i);
- if (mission_btn[i])
- REGISTER_CLIENT(EID_CLICK, mission_btn[i], FltDlg, OnMissionType);
- }
-
- objective_list = (ListBox*) FindControl(221);
- loadout_list = (ListBox*) FindControl(222);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::SetShip(Ship* s)
-{
- if (ship != s) {
- ship = s;
-
- delete flight_planner;
- flight_planner = 0;
-
- if (filter_list) {
- filter_list->ClearItems();
-
- if (ship) {
- int nsquadrons = 0;
- int nslots = 0;
- Hangar* hangar = ship->GetHangar();
-
- if (hangar) {
- nsquadrons = hangar->NumSquadrons();
-
- for (int i = 0; i < nsquadrons; i++) {
- char filter[64];
- sprintf_s(filter, "%s %s",
- hangar->SquadronDesign(i)->abrv,
- hangar->SquadronName(i).data());
-
- filter_list->AddItem(filter);
- }
-
- filter_list->AddItem(Game::GetText("FltDlg.PENDING"));
- filter_list->AddItem(Game::GetText("FltDlg.ACTIVE"));
- }
-
- flight_planner = new(__FILE__,__LINE__) FlightPlanner(ship);
- }
-
- OnFilter(0);
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::ExecFrame()
-{
- if (!ship || !ship->GetHangar()) {
- manager->HideFltDlg();
- }
- else {
- UpdateSelection();
- UpdateObjective();
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::UpdateSelection()
-{
- if (!filter_list || !hangar_list || !ship) return;
-
- design = 0;
-
- bool package = false;
- bool alert = false;
- bool launch = false;
- bool stand = false;
- bool recall = false;
-
- Hangar* hangar = ship->GetHangar();
- int seln = filter_list->GetSelectedIndex();
- char txt[32];
- int item;
-
- // selected squadron:
- if (seln < hangar->NumSquadrons()) {
- int nslots = hangar->SquadronSize(seln);
-
- for (item = 0; item < hangar_list->NumItems(); item++) {
- int i = hangar_list->GetItemData(item);
- const HangarSlot* s = hangar->GetSlot(seln, i);
-
- if (hangar->GetState(s) == Hangar::UNAVAIL)
- hangar_list->SetItemColor(item, Color::DarkGray);
- else if (hangar->GetState(s) == Hangar::MAINT)
- hangar_list->SetItemColor(item, Color::Gray);
- else
- hangar_list->SetItemColor(item, Color::White);
-
- if (hangar->GetState(s) > Hangar::STORAGE) {
- if (hangar->GetShip(s))
- hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name());
- else if (hangar->GetPackageElement(s))
- hangar_list->SetItemText(item, 1, hangar->GetPackageElement(s)->Name());
- else
- hangar_list->SetItemText(item, 1, hangar->SquadronName(seln));
-
- if (hangar->GetPackageElement(s))
- hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
- else
- hangar_list->SetItemText(item, 3, "--");
-
- }
- else {
- hangar_list->SetItemText(item, 1, "--");
- hangar_list->SetItemText(item, 3, "--");
- }
-
- hangar_list->SetItemText(item, 2, hangar->StatusName(s));
-
- if (hangar->GetState(s) >= Hangar::ACTIVE) {
- FormatTime(txt, hangar->GetShip(s)->MissionClock() / 1000);
- hangar_list->SetItemText(item, 4, txt);
- }
-
- else if (hangar->GetState(s) == Hangar::MAINT ||
- hangar->GetState(s) > Hangar::STORAGE) {
- FormatTime(txt, hangar->TimeRemaining(s));
- hangar_list->SetItemText(item, 4, txt);
- }
-
- else {
- hangar_list->SetItemText(item, 4, "");
- }
-
- if (hangar_list->IsSelected(item)) {
- if (!design) design = hangar->GetDesign(s);
-
- switch (hangar->GetState(s)) {
- case Hangar::STORAGE: alert = true; break;
- case Hangar::ALERT: launch = true;
- stand = true; break;
- case Hangar::QUEUED: stand = true; break;
- case Hangar::ACTIVE: recall = true; break;
- }
- }
- }
- }
-
- // selected pending filter:
- else if (seln == hangar->NumSquadrons()) {
- for (item = 0; item < hangar_list->NumItems(); item++) {
- int f = hangar_list->GetItemData(item, 1);
- int i = hangar_list->GetItemData(item, 2);
-
- int squadron = -1;
- int slot = -1;
- const HangarSlot* s = 0;
-
- FlightDeck* deck = ship->GetFlightDeck(f);
-
- if (deck->IsLaunchDeck()) {
- int state = deck->State(i);
- int seq = deck->Sequence(i);
- double time = deck->TimeRemaining(i);
- Ship* deckship = deck->GetShip(i);
-
- if (deckship) {
- hangar_list->SetItemText(item, 1, deckship->Name());
-
- for (int a = 0; !s && a < hangar->NumSquadrons(); a++) {
- for (int b = 0; !s && b < hangar->SquadronSize(a); b++) {
- const HangarSlot* test = hangar->GetSlot(a,b);
- if (hangar->GetShip(test) == deckship) {
- s = test;
- squadron = a;
- slot = b;
- }
- }
- }
-
- if (s) {
- hangar_list->SetItemText(item, 2, hangar->StatusName(s));
- if (hangar->GetPackageElement(s))
- hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
- }
- }
- else {
- hangar_list->SetItemText(item, 1, "--");
- hangar_list->SetItemText(item, 2, Game::GetText("FltDlg.Open"));
- }
-
- FormatTime(txt, time);
- hangar_list->SetItemText(item, 4, txt);
- hangar_list->SetItemData(item, 3, squadron);
- hangar_list->SetItemData(item, 4, slot);
-
- if (hangar_list->IsSelected(item) && s) {
- if (!design) design = hangar->GetDesign(s);
-
- switch (hangar->GetState(s)) {
- case Hangar::ALERT: launch = true;
- stand = true; break;
- case Hangar::QUEUED: stand = true; break;
- }
- }
- }
- }
- }
-
- // selected active filter:
- else if (seln == hangar->NumSquadrons()+1) {
- int last_index = -1;
-
- for (item = 0; item < hangar_list->NumItems(); item++) {
- int squadron = hangar_list->GetItemData(item, 1);
- int slot = hangar_list->GetItemData(item, 2);
-
- int nslots = hangar->SquadronSize(squadron);
-
- if (slot >= 0 && slot < nslots) {
- const HangarSlot* s = hangar->GetSlot(squadron, slot);
-
- if (hangar->GetState(s) > Hangar::STORAGE) {
- if (hangar->GetShip(s))
- hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name());
- else if (hangar->GetPackageElement(s))
- hangar_list->SetItemText(item, 1, hangar->GetPackageElement(s)->Name());
- else
- hangar_list->SetItemText(item, 1, hangar->SquadronName(squadron));
-
- if (hangar->GetPackageElement(s))
- hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
- else
- hangar_list->SetItemText(item, 3, "--");
-
- hangar_list->SetItemText(item, 2, hangar->StatusName(s));
-
- FormatTime(txt, hangar->GetShip(s)->MissionClock() / 1000);
- hangar_list->SetItemText(item, 4, txt);
-
- if (last_index < (int) hangar_list->GetItemData(item))
- last_index = (int) hangar_list->GetItemData(item);
- }
- else {
- hangar_list->RemoveItem(item);
- item--;
- }
- }
- else {
- hangar_list->RemoveItem(item);
- item--;
- }
- }
-
- for (int i = 0; i < hangar->NumSquadrons(); i++) {
- int nslots = hangar->SquadronSize(i);
-
- for (int j = 0; j < nslots; j++) {
- const HangarSlot* s = hangar->GetSlot(i, j);
-
- if (hangar->GetState(s) >= Hangar::ACTIVE) {
- bool found = false;
-
- for (int n = 0; !found && n < hangar_list->NumItems(); n++) {
- if (hangar_list->GetItemData(n, 1) == (DWORD) i &&
- hangar_list->GetItemData(n, 2) == (DWORD) j)
- found = true;
- }
-
- if (!found) {
- last_index++;
-
- char txt[32];
- sprintf_s(txt, "%2d ", last_index+1);
- hangar_list->AddItemWithData(txt, last_index); // use data for sort
-
- if (hangar->GetShip(s))
- hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name());
-
- hangar_list->SetItemText(item, 2, hangar->StatusName(s));
-
- if (hangar->GetPackageElement(s))
- hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
-
- FormatTime(txt, hangar->GetShip(s)->MissionClock() / 1000);
- hangar_list->SetItemText(item, 4, txt);
-
- hangar_list->SetItemData(item, 1, i);
- hangar_list->SetItemData(item, 2, j);
-
- item++;
- }
- }
- }
- }
-
- if (hangar_list->GetSelCount() > 0)
- recall = true;
- }
-
- if (package_btn) {
- bool pkg_ok = alert && mission_type > -1;
-
- if (pkg_ok && mission_type > 0) {
- pkg_ok = objective_list &&
- objective_list->GetSelCount() > 0;
-
- if (pkg_ok) {
- int obj_index = objective_list->GetSelection();
- DWORD obj_data = objective_list->GetItemData(obj_index, 2);
-
- if (obj_data > 1e9)
- pkg_ok = false;
- }
- }
-
- package_btn->SetEnabled(pkg_ok);
- }
-
- if (alert_btn) {
- alert_btn->SetEnabled(alert);
-
- for (int i = 0; i < 6; i++)
- if (mission_btn[i])
- mission_btn[i]->SetEnabled(alert);
- }
-
- if (launch_btn)
- launch_btn->SetEnabled(launch);
-
- if (stand_btn)
- stand_btn->SetEnabled(stand);
-
- if (recall_btn)
- recall_btn->SetEnabled(recall);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::UpdateObjective()
-{
- if (!objective_list || mission_type < 0 || !ship) return;
-
- Sim* sim = Sim::GetSim();
- char txt[32];
-
- for (int item = 0; item < objective_list->NumItems(); item++) {
- const char* obj_name = objective_list->GetItemText(item);
-
- Element* elem = sim->FindElement(obj_name);
-
- // if element has expired, remove it from the objective list
- if (!elem || !elem->IsActive() || elem->IsFinished()) {
- objective_list->RemoveItem(item);
- item--;
- }
-
- // otherwise, the element is still active, so update range/region
- else {
- Ship* s = elem->GetShip(1);
- double r = 0;
- bool con = false;
-
- if (s) {
- Point s_loc = s->Location() + s->GetRegion()->Location();
- Point h_loc = ship->Location() + ship->GetRegion()->Location();
-
- r = (s_loc - h_loc).length();
-
- con = ship->FindContact(s) != 0;
-
- if (con) {
- FormatNumber(txt, r);
- }
- else {
- strcpy_s(txt, Game::GetText("FltDlg.Unknown").data());
- r = 2e9;
- }
- }
-
- objective_list->SetItemText(item, 1, s->GetRegion()->Name());
-
- objective_list->SetItemText(item, 2, txt);
- objective_list->SetItemData(item, 2, (DWORD) r);
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::Show()
-{
- if (shown) return;
-
- FormWindow::Show();
- UpdateSelection();
- UpdateObjective();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::Hide()
-{
- FormWindow::Hide();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::OnFilter(AWEvent* event)
-{
- if (!filter_list || !hangar_list) return;
-
- int seln = filter_list->GetSelectedIndex();
-
- hangar_list->ClearItems();
-
- if (!ship) return;
-
- Hangar* hangar = ship->GetHangar();
-
- // selected squadron:
- if (seln < hangar->NumSquadrons()) {
- int nslots = hangar->SquadronSize(seln);
-
- for (int i = 0; i < nslots; i++) {
- char txt[32];
- sprintf_s(txt, " %2d ", i+1);
-
- const HangarSlot* s = hangar->GetSlot(seln, i);
- hangar_list->AddItemWithData(txt, i);
-
- hangar_list->SetItemText(i, 1, "--");
- hangar_list->SetItemText(i, 2, hangar->StatusName(s));
-
- FormatTime(txt, hangar->TimeRemaining(s));
- hangar_list->SetItemText(i, 4, txt);
- }
- }
-
- // selected pending filter:
- else if (seln == hangar->NumSquadrons()) {
- int item = 0;
-
- for (int f = 0; f < ship->NumFlightDecks(); f++) {
- FlightDeck* deck = ship->GetFlightDeck(f);
-
- if (deck->IsLaunchDeck()) {
- for (int i = 0; i < deck->NumSlots(); i++) {
- int state = deck->State(i);
- int seq = deck->Sequence(i);
- double time = deck->TimeRemaining(i);
- Ship* deckship = deck->GetShip(i);
-
- int squadron = -1;
- int slot = -1;
-
- char txt[32];
- sprintf_s(txt, "%d-%d ", f+1, i+1);
-
- hangar_list->AddItemWithData(txt, item); // use data for sort
-
- if (deckship) {
- hangar_list->SetItemText(item, 1, deckship->Name());
-
- const HangarSlot* s = 0;
-
- for (int a = 0; !s && a < hangar->NumSquadrons(); a++) {
- for (int b = 0; !s && b < hangar->SquadronSize(a); b++) {
- const HangarSlot* test = hangar->GetSlot(a, b);
- if (hangar->GetShip(test) == deckship) {
- s = test;
- squadron = a;
- slot = b;
- }
- }
- }
-
- if (s) {
- hangar_list->SetItemText(item, 2, hangar->StatusName(s));
- if (hangar->GetPackageElement(s))
- hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
- }
- }
- else {
- hangar_list->SetItemText(item, 1, "--");
- hangar_list->SetItemText(item, 2, Game::GetText("FltDlg.Open"));
- }
-
-
- FormatTime(txt, time);
- hangar_list->SetItemText(item, 4, txt);
-
- hangar_list->SetItemData(item, 1, f);
- hangar_list->SetItemData(item, 2, i);
- hangar_list->SetItemData(item, 3, squadron);
- hangar_list->SetItemData(item, 4, slot);
-
- item++;
- }
- }
- }
- }
-
- // selected active filter:
- else if (seln == hangar->NumSquadrons()+1) {
- int item = 0;
-
- for (int i = 0; i < hangar->NumSquadrons(); i++) {
- int nslots = hangar->SquadronSize(i);
-
- for (int j = 0; j < nslots; j++) {
- const HangarSlot* s = hangar->GetSlot(i,j);
-
- if (hangar->GetState(s) >= Hangar::ACTIVE) {
- char txt[32];
- sprintf_s(txt, " %2d ", item+1);
-
- hangar_list->AddItemWithData(txt, item); // use data for sort
-
- if (hangar->GetShip(s))
- hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name());
-
- hangar_list->SetItemText(item, 2, hangar->StatusName(s));
-
- if (hangar->GetPackageElement(s))
- hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
-
- FormatTime(txt, hangar->TimeRemaining(s));
- hangar_list->SetItemText(item, 4, txt);
-
- hangar_list->SetItemData(item, 1, i);
- hangar_list->SetItemData(item, 2, j);
-
- item++;
- }
- }
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::OnPackage(AWEvent* event)
-{
- if (!filter_list || !hangar_list || !ship) return;
-
- int code = Mission::PATROL;
-
- switch (mission_type) {
- case 0: code = Mission::PATROL; break;
- case 1: code = Mission::INTERCEPT; break;
- case 2: code = Mission::ASSAULT; break;
- case 3: code = Mission::STRIKE; break;
- case 4: code = Mission::ESCORT; break;
- case 5: code = Mission::INTEL; break;
- }
-
- int squad = filter_list->GetSelectedIndex();
- Hangar* hangar = ship->GetHangar();
- Sim* sim = Sim::GetSim();
- const char* call = sim->FindAvailCallsign(ship->GetIFF());
- Element* elem = sim->CreateElement(call, ship->GetIFF(), code);
- Element* tgt = 0;
- FlightDeck* deck = 0;
- int queue = 1000;
- int* load = 0;
-
- elem->SetSquadron(hangar->SquadronName(squad));
- elem->SetCarrier(ship);
-
- if (objective_list) {
- int index = objective_list->GetListIndex();
- Text target = objective_list->GetItemText(index);
-
- Instruction* objective = new(__FILE__,__LINE__) Instruction(code, target.data());
- elem->AddObjective(objective);
-
- tgt = sim->FindElement(target.data());
- }
-
- if (loadout_list && design) {
- int index = loadout_list->GetListIndex();
- Text loadname = loadout_list->GetItemText(index);
-
- ListIter<ShipLoad> sl = (List<ShipLoad>&) design->loadouts;
- while (++sl && !load) {
- if (sl->name == loadname) {
- load = sl->load;
- elem->SetLoadout(load);
- }
- }
- }
-
- for (int i = 0; i < ship->NumFlightDecks(); i++) {
- FlightDeck* d = ship->GetFlightDeck(i);
-
- if (d && d->IsLaunchDeck()) {
- int dq = hangar->PreflightQueue(d);
-
- if (dq < queue) {
- queue = dq;
- deck = d;
- }
- }
- }
-
- int npackage = 0;
- int slots[4];
-
- for (int i = 0; i < 4; i++)
- slots[i] = -1;
-
- for (int i = 0; i < hangar_list->NumItems(); i++) {
- if (hangar_list->IsSelected(i)) {
- int nslot = hangar_list->GetItemData(i);
- hangar->GotoAlert(squad, nslot, deck, elem, load, true);
- slots[npackage] = nslot;
- hangar_list->SetSelected(i, false);
- npackage++;
-
- if (npackage >= 4)
- break;
- }
- }
-
- NetUtil::SendElemCreate(elem, squad, slots, false);
-
- if (flight_planner) {
- switch (mission_type) {
- case 0:
- default:
- flight_planner->CreatePatrolRoute(elem, patrol_pattern++);
- break;
-
- case 1:
- case 2:
- case 3:
- if (tgt)
- flight_planner->CreateStrikeRoute(elem, tgt);
- else
- flight_planner->CreatePatrolRoute(elem, patrol_pattern++);
- break;
-
- case 4:
- if (tgt)
- flight_planner->CreateEscortRoute(elem, tgt);
- else
- flight_planner->CreatePatrolRoute(elem, patrol_pattern++);
- break;
- }
-
- if (patrol_pattern < 0 || patrol_pattern > 3)
- patrol_pattern = 0;
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::OnAlert(AWEvent* event)
-{
- if (!filter_list || !hangar_list || !ship) return;
-
- int squad = filter_list->GetSelectedIndex();
- Hangar* hangar = ship->GetHangar();
- Sim* sim = Sim::GetSim();
- const char* call = sim->FindAvailCallsign(ship->GetIFF());
- Element* elem = sim->CreateElement(call, ship->GetIFF());
- FlightDeck* deck = 0;
- int queue = 1000;
- const int* load = 0;
-
- elem->SetSquadron(hangar->SquadronName(squad));
- elem->SetCarrier(ship);
-
- for (int i = 0; i < ship->NumFlightDecks(); i++) {
- FlightDeck* d = ship->GetFlightDeck(i);
-
- if (d && d->IsLaunchDeck()) {
- int dq = hangar->PreflightQueue(d);
-
- if (dq < queue) {
- queue = dq;
- deck = d;
- }
- }
- }
-
- int nalert = 0;
- int slots[4];
-
- for (int i = 0; i < 4; i++)
- slots[i] = -1;
-
- for (int i = 0; i < hangar_list->NumItems(); i++) {
- if (hangar_list->IsSelected(i)) {
- int nslot = hangar_list->GetItemData(i);
- slots[nalert] = nslot;
-
- if (!load) {
- const HangarSlot* hangar_slot = hangar->GetSlot(squad, nslot);
- if (hangar_slot) {
- load = hangar->GetLoadout(hangar_slot);
- elem->SetLoadout((int*) load);
- }
- }
-
- hangar->GotoAlert(squad, nslot, deck, elem);
- hangar_list->SetSelected(i, false);
- nalert++;
-
- if (nalert >= 4)
- break;
- }
- }
-
- NetUtil::SendElemCreate(elem, squad, slots, true);
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::OnLaunch(AWEvent* event)
-{
- if (!filter_list || !hangar_list || !ship) return;
-
- int squad = filter_list->GetSelectedIndex();
-
- Hangar* hangar = ship->GetHangar();
-
- // selected squadron:
- if (squad < hangar->NumSquadrons()) {
- for (int i = 0; i < hangar_list->NumItems(); i++) {
- if (hangar_list->IsSelected(i)) {
- int nslot = hangar_list->GetItemData(i);
- hangar->Launch(squad, nslot);
- NetUtil::SendShipLaunch(ship, squad, nslot);
- }
- }
- }
-
- // selected pending filter:
- else if (squad == hangar->NumSquadrons()) {
- for (int item = 0; item < hangar_list->NumItems(); item++) {
- if (hangar_list->IsSelected(item)) {
- int squadron = hangar_list->GetItemData(item, 3);
- int slot = hangar_list->GetItemData(item, 4);
-
- if (squadron >= 0 && slot >= 0) {
- hangar->Launch(squadron, slot);
- NetUtil::SendShipLaunch(ship, squadron, slot);
- }
- }
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::OnStandDown(AWEvent* event)
-{
- if (!filter_list || !hangar_list || !ship) return;
-
- int seln = filter_list->GetSelectedIndex();
-
- Hangar* hangar = ship->GetHangar();
-
- // selected squadron:
- if (seln < hangar->NumSquadrons()) {
- for (int i = 0; i < hangar_list->NumItems(); i++) {
- if (hangar_list->IsSelected(i)) {
- int nslot = hangar_list->GetItemData(i);
- hangar->StandDown(seln, nslot);
- }
- }
- }
-
- // selected pending filter:
- else if (seln == hangar->NumSquadrons()) {
- for (int item = 0; item < hangar_list->NumItems(); item++) {
- if (hangar_list->IsSelected(item)) {
- int squadron = hangar_list->GetItemData(item, 3);
- int slot = hangar_list->GetItemData(item, 4);
-
- if (squadron >= 0 && slot >= 0)
- hangar->StandDown(squadron, slot);
- }
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::OnRecall(AWEvent* event)
-{
- if (!filter_list || !hangar_list || !ship) return;
-
- int seln = filter_list->GetSelectedIndex();
-
- Hangar* hangar = ship->GetHangar();
-
- // selected squadron: or selected active filter:
- if (seln < hangar->NumSquadrons() || seln == hangar->NumSquadrons()+1) {
- for (int i = 0; i < hangar_list->NumItems(); i++) {
- if (hangar_list->IsSelected(i)) {
- int nsquad = seln;
- int nslot = hangar_list->GetItemData(i);
-
- if (seln > hangar->NumSquadrons()) {
- nsquad = hangar_list->GetItemData(i, 1);
- nslot = hangar_list->GetItemData(i, 2);
- }
-
- const HangarSlot* slot = hangar->GetSlot(nsquad, nslot);
- Ship* recall = hangar->GetShip(slot);
-
- if (recall) {
- RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage(recall, ship, RadioMessage::RTB);
- RadioTraffic::Transmit(msg);
- }
- }
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::OnMissionType(AWEvent* event)
-{
- mission_type = -1;
-
- for (int i = 0; i < 6; i++) {
- if (mission_btn[i]) {
- if (mission_btn[i] == event->window) {
- mission_btn[i]->SetButtonState(1);
- mission_type = i;
- }
- else {
- mission_btn[i]->SetButtonState(0);
- }
- }
- }
-
- if (objective_list && mission_type > -1) {
- objective_list->ClearItems();
-
- char txt[32];
- Sim* sim = Sim::GetSim();
- ListIter<Element> iter = sim->GetElements();
-
- while (++iter) {
- Element* elem = iter.value();
-
- if (!elem->IsActive() || elem->IsFinished() || elem->IsSquadron())
- continue;
-
- CombatGroup* group = elem->GetCombatGroup();
- int iff = elem->GetIFF();
- Ship* s = elem->GetShip(1);
- double r = 0;
- bool con = false;
-
- if (iff != ship->GetIFF()) {
- if (elem->IntelLevel() < Intel::LOCATED)
- continue;
-
- if (group && group->IntelLevel() < Intel::LOCATED)
- continue;
- }
-
- if (s) {
- Point s_loc = s->Location() + s->GetRegion()->Location();
- Point h_loc = ship->Location() + ship->GetRegion()->Location();
-
- r = (s_loc - h_loc).length();
-
- con = ship->FindContact(s) != 0;
-
- if (con) {
- FormatNumber(txt, r);
- }
- else {
- strcpy_s(txt, Game::GetText("FltDlg.Unknown").data());
- r = 2e9;
- }
- }
-
- switch (mission_type) {
- case 1: // INTERCEPT
- if (iff && iff != ship->GetIFF() && s && s->IsDropship()) {
- int item = objective_list->AddItem(elem->Name()) - 1;
- objective_list->SetItemText(item, 1, s->GetRegion()->Name());
-
- objective_list->SetItemText(item, 2, txt);
- objective_list->SetItemData(item, 2, (DWORD) r);
- }
- break;
-
- case 2: // ASSAULT
- if (iff && iff != ship->GetIFF() && s && (s->IsStarship() || s->IsStatic())) {
- int item = objective_list->AddItem(elem->Name()) - 1;
- objective_list->SetItemText(item, 1, s->GetRegion()->Name());
-
- objective_list->SetItemText(item, 2, txt);
- objective_list->SetItemData(item, 2, (DWORD) r);
- }
- break;
-
- case 3: // STRIKE
- if (iff && iff != ship->GetIFF() && s && s->IsGroundUnit()) {
- int item = objective_list->AddItem(elem->Name()) - 1;
- objective_list->SetItemText(item, 1, s->GetRegion()->Name());
-
- objective_list->SetItemText(item, 2, txt);
- objective_list->SetItemData(item, 2, (DWORD) r);
- }
- break;
-
- case 4: // ESCORT
- if ((iff == 0 || iff == ship->GetIFF()) && (!s || !s->IsStatic())) {
- int item = objective_list->AddItem(elem->Name()) - 1;
-
- if (s) {
- objective_list->SetItemText(item, 1, s->GetRegion()->Name());
- objective_list->SetItemText(item, 2, txt);
- objective_list->SetItemData(item, 2, (DWORD) r);
- }
-
- else {
- objective_list->SetItemText(item, 1, "0");
- objective_list->SetItemData(item, 1, 0);
- }
- }
- break;
-
- case 5: // SCOUT?
- break;
-
- default: break;
- }
- }
- }
-
- if (loadout_list && mission_type > -1) {
- loadout_list->ClearItems();
-
- if (design) {
- ListIter<ShipLoad> sl = (List<ShipLoad>&) design->loadouts;
- while (++sl) {
- int item = loadout_list->AddItem(sl->name) - 1;
-
- char weight[32];
- sprintf_s(weight, "%d kg", (int) ((design->mass + sl->mass) * 1000));
- loadout_list->SetItemText(item, 1, weight);
- loadout_list->SetItemData(item, 1, (DWORD) (sl->mass * 1000));
- }
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-FltDlg::OnClose(AWEvent* event)
-{
- if (manager)
- manager->CloseTopmost();
-}
-
-
-
+/* Starshatter OpenSource Distribution
+ Copyright (c) 1997-2004, Destroyer Studios LLC.
+ All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name "Destroyer Studios" nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ SUBSYSTEM: Stars.exe
+ FILE: FltDlg.cpp
+ AUTHOR: John DiCamillo
+
+
+ OVERVIEW
+ ========
+*/
+
+#include "MemDebug.h"
+#include "FltDlg.h"
+#include "GameScreen.h"
+#include "Sim.h"
+#include "Ship.h"
+#include "ShipDesign.h"
+#include "Hangar.h"
+#include "FlightDeck.h"
+#include "Element.h"
+#include "CombatGroup.h"
+#include "Mission.h"
+#include "RadioMessage.h"
+#include "RadioTraffic.h"
+#include "Instruction.h"
+#include "FlightPlanner.h"
+#include "NetUtil.h"
+
+#include "Game.h"
+#include "Button.h"
+#include "ListBox.h"
+#include "ComboBox.h"
+#include "FormatUtil.h"
+
+// +--------------------------------------------------------------------+
+// DECLARE MAPPING FUNCTIONS:
+DEF_MAP_CLIENT(FltDlg, OnFilter);
+DEF_MAP_CLIENT(FltDlg, OnPackage);
+DEF_MAP_CLIENT(FltDlg, OnAlert);
+DEF_MAP_CLIENT(FltDlg, OnLaunch);
+DEF_MAP_CLIENT(FltDlg, OnStandDown);
+DEF_MAP_CLIENT(FltDlg, OnRecall);
+DEF_MAP_CLIENT(FltDlg, OnClose);
+DEF_MAP_CLIENT(FltDlg, OnMissionType);
+
+// +--------------------------------------------------------------------+
+
+static const ShipDesign* design = 0;
+
+// +--------------------------------------------------------------------+
+
+FltDlg::FltDlg(Screen* s, FormDef& def, GameScreen* mgr)
+: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr),
+ship(0), filter_list(0), hangar_list(0),
+package_btn(0), alert_btn(0), launch_btn(0), stand_btn(0), recall_btn(0),
+mission_type(-1), flight_planner(0), patrol_pattern(0)
+{
+ Init(def);
+}
+
+FltDlg::~FltDlg()
+{
+ delete flight_planner;
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::RegisterControls()
+{
+ filter_list = (ComboBox*) FindControl(101);
+ hangar_list = (ListBox*) FindControl(102);
+ package_btn = (Button*) FindControl(110);
+ alert_btn = (Button*) FindControl(111);
+ launch_btn = (Button*) FindControl(112);
+ stand_btn = (Button*) FindControl(113);
+ recall_btn = (Button*) FindControl(114);
+ close_btn = (Button*) FindControl(1);
+
+ if (filter_list)
+ REGISTER_CLIENT(EID_SELECT, filter_list, FltDlg, OnFilter);
+
+ if (package_btn)
+ REGISTER_CLIENT(EID_CLICK, package_btn, FltDlg, OnPackage);
+
+ if (alert_btn)
+ REGISTER_CLIENT(EID_CLICK, alert_btn, FltDlg, OnAlert);
+
+ if (launch_btn)
+ REGISTER_CLIENT(EID_CLICK, launch_btn, FltDlg, OnLaunch);
+
+ if (stand_btn)
+ REGISTER_CLIENT(EID_CLICK, stand_btn, FltDlg, OnStandDown);
+
+ if (recall_btn)
+ REGISTER_CLIENT(EID_CLICK, recall_btn, FltDlg, OnRecall);
+
+ if (close_btn)
+ REGISTER_CLIENT(EID_CLICK, close_btn, FltDlg, OnClose);
+
+ for (int i = 0; i < 6; i++) {
+ mission_btn[i] = (Button*) FindControl(210 + i);
+ if (mission_btn[i])
+ REGISTER_CLIENT(EID_CLICK, mission_btn[i], FltDlg, OnMissionType);
+ }
+
+ objective_list = (ListBox*) FindControl(221);
+ loadout_list = (ListBox*) FindControl(222);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::SetShip(Ship* s)
+{
+ if (ship != s) {
+ ship = s;
+
+ delete flight_planner;
+ flight_planner = 0;
+
+ if (filter_list) {
+ filter_list->ClearItems();
+
+ if (ship) {
+ int nsquadrons = 0;
+ int nslots = 0;
+ Hangar* hangar = ship->GetHangar();
+
+ if (hangar) {
+ nsquadrons = hangar->NumSquadrons();
+
+ for (int i = 0; i < nsquadrons; i++) {
+ char filter[64];
+ sprintf_s(filter, "%s %s",
+ hangar->SquadronDesign(i)->abrv,
+ hangar->SquadronName(i).data());
+
+ filter_list->AddItem(filter);
+ }
+
+ filter_list->AddItem(Game::GetText("FltDlg.PENDING"));
+ filter_list->AddItem(Game::GetText("FltDlg.ACTIVE"));
+ }
+
+ flight_planner = new(__FILE__,__LINE__) FlightPlanner(ship);
+ }
+
+ OnFilter(0);
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::ExecFrame()
+{
+ if (!ship || !ship->GetHangar()) {
+ manager->HideFltDlg();
+ }
+ else {
+ UpdateSelection();
+ UpdateObjective();
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::UpdateSelection()
+{
+ if (!filter_list || !hangar_list || !ship) return;
+
+ design = 0;
+
+ bool package = false;
+ bool alert = false;
+ bool launch = false;
+ bool stand = false;
+ bool recall = false;
+
+ Hangar* hangar = ship->GetHangar();
+ int seln = filter_list->GetSelectedIndex();
+ char txt[32];
+ int item;
+
+ // selected squadron:
+ if (seln < hangar->NumSquadrons()) {
+ int nslots = hangar->SquadronSize(seln);
+
+ for (item = 0; item < hangar_list->NumItems(); item++) {
+ int i = hangar_list->GetItemData(item);
+ const HangarSlot* s = hangar->GetSlot(seln, i);
+
+ if (hangar->GetState(s) == Hangar::UNAVAIL)
+ hangar_list->SetItemColor(item, Color::DarkGray);
+ else if (hangar->GetState(s) == Hangar::MAINT)
+ hangar_list->SetItemColor(item, Color::Gray);
+ else
+ hangar_list->SetItemColor(item, Color::White);
+
+ if (hangar->GetState(s) > Hangar::STORAGE) {
+ if (hangar->GetShip(s))
+ hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name());
+ else if (hangar->GetPackageElement(s))
+ hangar_list->SetItemText(item, 1, hangar->GetPackageElement(s)->Name());
+ else
+ hangar_list->SetItemText(item, 1, hangar->SquadronName(seln));
+
+ if (hangar->GetPackageElement(s))
+ hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
+ else
+ hangar_list->SetItemText(item, 3, "--");
+
+ }
+ else {
+ hangar_list->SetItemText(item, 1, "--");
+ hangar_list->SetItemText(item, 3, "--");
+ }
+
+ hangar_list->SetItemText(item, 2, hangar->StatusName(s));
+
+ if (hangar->GetState(s) >= Hangar::ACTIVE) {
+ FormatTime(txt, hangar->GetShip(s)->MissionClock() / 1000);
+ hangar_list->SetItemText(item, 4, txt);
+ }
+
+ else if (hangar->GetState(s) == Hangar::MAINT ||
+ hangar->GetState(s) > Hangar::STORAGE) {
+ FormatTime(txt, hangar->TimeRemaining(s));
+ hangar_list->SetItemText(item, 4, txt);
+ }
+
+ else {
+ hangar_list->SetItemText(item, 4, "");
+ }
+
+ if (hangar_list->IsSelected(item)) {
+ if (!design) design = hangar->GetDesign(s);
+
+ switch (hangar->GetState(s)) {
+ case Hangar::STORAGE: alert = true; break;
+ case Hangar::ALERT: launch = true;
+ stand = true; break;
+ case Hangar::QUEUED: stand = true; break;
+ case Hangar::ACTIVE: recall = true; break;
+ }
+ }
+ }
+ }
+
+ // selected pending filter:
+ else if (seln == hangar->NumSquadrons()) {
+ for (item = 0; item < hangar_list->NumItems(); item++) {
+ int f = hangar_list->GetItemData(item, 1);
+ int i = hangar_list->GetItemData(item, 2);
+
+ int squadron = -1;
+ int slot = -1;
+ const HangarSlot* s = 0;
+
+ FlightDeck* deck = ship->GetFlightDeck(f);
+
+ if (deck->IsLaunchDeck()) {
+ int state = deck->State(i);
+ int seq = deck->Sequence(i);
+ double time = deck->TimeRemaining(i);
+ Ship* deckship = deck->GetShip(i);
+
+ if (deckship) {
+ hangar_list->SetItemText(item, 1, deckship->Name());
+
+ for (int a = 0; !s && a < hangar->NumSquadrons(); a++) {
+ for (int b = 0; !s && b < hangar->SquadronSize(a); b++) {
+ const HangarSlot* test = hangar->GetSlot(a,b);
+ if (hangar->GetShip(test) == deckship) {
+ s = test;
+ squadron = a;
+ slot = b;
+ }
+ }
+ }
+
+ if (s) {
+ hangar_list->SetItemText(item, 2, hangar->StatusName(s));
+ if (hangar->GetPackageElement(s))
+ hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
+ }
+ }
+ else {
+ hangar_list->SetItemText(item, 1, "--");
+ hangar_list->SetItemText(item, 2, Game::GetText("FltDlg.Open"));
+ }
+
+ FormatTime(txt, time);
+ hangar_list->SetItemText(item, 4, txt);
+ hangar_list->SetItemData(item, 3, squadron);
+ hangar_list->SetItemData(item, 4, slot);
+
+ if (hangar_list->IsSelected(item) && s) {
+ if (!design) design = hangar->GetDesign(s);
+
+ switch (hangar->GetState(s)) {
+ case Hangar::ALERT: launch = true;
+ stand = true; break;
+ case Hangar::QUEUED: stand = true; break;
+ }
+ }
+ }
+ }
+ }
+
+ // selected active filter:
+ else if (seln == hangar->NumSquadrons()+1) {
+ int last_index = -1;
+
+ for (item = 0; item < hangar_list->NumItems(); item++) {
+ int squadron = hangar_list->GetItemData(item, 1);
+ int slot = hangar_list->GetItemData(item, 2);
+
+ int nslots = hangar->SquadronSize(squadron);
+
+ if (slot >= 0 && slot < nslots) {
+ const HangarSlot* s = hangar->GetSlot(squadron, slot);
+
+ if (hangar->GetState(s) > Hangar::STORAGE) {
+ if (hangar->GetShip(s))
+ hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name());
+ else if (hangar->GetPackageElement(s))
+ hangar_list->SetItemText(item, 1, hangar->GetPackageElement(s)->Name());
+ else
+ hangar_list->SetItemText(item, 1, hangar->SquadronName(squadron));
+
+ if (hangar->GetPackageElement(s))
+ hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
+ else
+ hangar_list->SetItemText(item, 3, "--");
+
+ hangar_list->SetItemText(item, 2, hangar->StatusName(s));
+
+ FormatTime(txt, hangar->GetShip(s)->MissionClock() / 1000);
+ hangar_list->SetItemText(item, 4, txt);
+
+ if (last_index < (int) hangar_list->GetItemData(item))
+ last_index = (int) hangar_list->GetItemData(item);
+ }
+ else {
+ hangar_list->RemoveItem(item);
+ item--;
+ }
+ }
+ else {
+ hangar_list->RemoveItem(item);
+ item--;
+ }
+ }
+
+ for (int i = 0; i < hangar->NumSquadrons(); i++) {
+ int nslots = hangar->SquadronSize(i);
+
+ for (int j = 0; j < nslots; j++) {
+ const HangarSlot* s = hangar->GetSlot(i, j);
+
+ if (hangar->GetState(s) >= Hangar::ACTIVE) {
+ bool found = false;
+
+ for (int n = 0; !found && n < hangar_list->NumItems(); n++) {
+ if (hangar_list->GetItemData(n, 1) == (DWORD) i &&
+ hangar_list->GetItemData(n, 2) == (DWORD) j)
+ found = true;
+ }
+
+ if (!found) {
+ last_index++;
+
+ char txt[32];
+ sprintf_s(txt, "%2d ", last_index+1);
+ hangar_list->AddItemWithData(txt, last_index); // use data for sort
+
+ if (hangar->GetShip(s))
+ hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name());
+
+ hangar_list->SetItemText(item, 2, hangar->StatusName(s));
+
+ if (hangar->GetPackageElement(s))
+ hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
+
+ FormatTime(txt, hangar->GetShip(s)->MissionClock() / 1000);
+ hangar_list->SetItemText(item, 4, txt);
+
+ hangar_list->SetItemData(item, 1, i);
+ hangar_list->SetItemData(item, 2, j);
+
+ item++;
+ }
+ }
+ }
+ }
+
+ if (hangar_list->GetSelCount() > 0)
+ recall = true;
+ }
+
+ if (package_btn) {
+ bool pkg_ok = alert && mission_type > -1;
+
+ if (pkg_ok && mission_type > 0) {
+ pkg_ok = objective_list &&
+ objective_list->GetSelCount() > 0;
+
+ if (pkg_ok) {
+ int obj_index = objective_list->GetSelection();
+ DWORD obj_data = objective_list->GetItemData(obj_index, 2);
+
+ if (obj_data > 1e9)
+ pkg_ok = false;
+ }
+ }
+
+ package_btn->SetEnabled(pkg_ok);
+ }
+
+ if (alert_btn) {
+ alert_btn->SetEnabled(alert);
+
+ for (int i = 0; i < 6; i++)
+ if (mission_btn[i])
+ mission_btn[i]->SetEnabled(alert);
+ }
+
+ if (launch_btn)
+ launch_btn->SetEnabled(launch);
+
+ if (stand_btn)
+ stand_btn->SetEnabled(stand);
+
+ if (recall_btn)
+ recall_btn->SetEnabled(recall);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::UpdateObjective()
+{
+ if (!objective_list || mission_type < 0 || !ship) return;
+
+ Sim* sim = Sim::GetSim();
+ char txt[32];
+
+ for (int item = 0; item < objective_list->NumItems(); item++) {
+ const char* obj_name = objective_list->GetItemText(item);
+
+ Element* elem = sim->FindElement(obj_name);
+
+ // if element has expired, remove it from the objective list
+ if (!elem || !elem->IsActive() || elem->IsFinished()) {
+ objective_list->RemoveItem(item);
+ item--;
+ }
+
+ // otherwise, the element is still active, so update range/region
+ else {
+ Ship* s = elem->GetShip(1);
+ double r = 0;
+ bool con = false;
+
+ if (s) {
+ Point s_loc = s->Location() + s->GetRegion()->Location();
+ Point h_loc = ship->Location() + ship->GetRegion()->Location();
+
+ r = (s_loc - h_loc).length();
+
+ con = ship->FindContact(s) != 0;
+
+ if (con) {
+ FormatNumber(txt, r);
+ }
+ else {
+ strcpy_s(txt, Game::GetText("FltDlg.Unknown").data());
+ r = 2e9;
+ }
+ }
+
+ objective_list->SetItemText(item, 1, s->GetRegion()->Name());
+
+ objective_list->SetItemText(item, 2, txt);
+ objective_list->SetItemData(item, 2, (DWORD) r);
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::Show()
+{
+ if (shown) return;
+
+ FormWindow::Show();
+ UpdateSelection();
+ UpdateObjective();
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::Hide()
+{
+ FormWindow::Hide();
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::OnFilter(AWEvent* event)
+{
+ if (!filter_list || !hangar_list) return;
+
+ int seln = filter_list->GetSelectedIndex();
+
+ hangar_list->ClearItems();
+
+ if (!ship) return;
+
+ Hangar* hangar = ship->GetHangar();
+
+ // selected squadron:
+ if (seln < hangar->NumSquadrons()) {
+ int nslots = hangar->SquadronSize(seln);
+
+ for (int i = 0; i < nslots; i++) {
+ char txt[32];
+ sprintf_s(txt, " %2d ", i+1);
+
+ const HangarSlot* s = hangar->GetSlot(seln, i);
+ hangar_list->AddItemWithData(txt, i);
+
+ hangar_list->SetItemText(i, 1, "--");
+ hangar_list->SetItemText(i, 2, hangar->StatusName(s));
+
+ FormatTime(txt, hangar->TimeRemaining(s));
+ hangar_list->SetItemText(i, 4, txt);
+ }
+ }
+
+ // selected pending filter:
+ else if (seln == hangar->NumSquadrons()) {
+ int item = 0;
+
+ for (int f = 0; f < ship->NumFlightDecks(); f++) {
+ FlightDeck* deck = ship->GetFlightDeck(f);
+
+ if (deck->IsLaunchDeck()) {
+ for (int i = 0; i < deck->NumSlots(); i++) {
+ int state = deck->State(i);
+ int seq = deck->Sequence(i);
+ double time = deck->TimeRemaining(i);
+ Ship* deckship = deck->GetShip(i);
+
+ int squadron = -1;
+ int slot = -1;
+
+ char txt[32];
+ sprintf_s(txt, "%d-%d ", f+1, i+1);
+
+ hangar_list->AddItemWithData(txt, item); // use data for sort
+
+ if (deckship) {
+ hangar_list->SetItemText(item, 1, deckship->Name());
+
+ const HangarSlot* s = 0;
+
+ for (int a = 0; !s && a < hangar->NumSquadrons(); a++) {
+ for (int b = 0; !s && b < hangar->SquadronSize(a); b++) {
+ const HangarSlot* test = hangar->GetSlot(a, b);
+ if (hangar->GetShip(test) == deckship) {
+ s = test;
+ squadron = a;
+ slot = b;
+ }
+ }
+ }
+
+ if (s) {
+ hangar_list->SetItemText(item, 2, hangar->StatusName(s));
+ if (hangar->GetPackageElement(s))
+ hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
+ }
+ }
+ else {
+ hangar_list->SetItemText(item, 1, "--");
+ hangar_list->SetItemText(item, 2, Game::GetText("FltDlg.Open"));
+ }
+
+
+ FormatTime(txt, time);
+ hangar_list->SetItemText(item, 4, txt);
+
+ hangar_list->SetItemData(item, 1, f);
+ hangar_list->SetItemData(item, 2, i);
+ hangar_list->SetItemData(item, 3, squadron);
+ hangar_list->SetItemData(item, 4, slot);
+
+ item++;
+ }
+ }
+ }
+ }
+
+ // selected active filter:
+ else if (seln == hangar->NumSquadrons()+1) {
+ int item = 0;
+
+ for (int i = 0; i < hangar->NumSquadrons(); i++) {
+ int nslots = hangar->SquadronSize(i);
+
+ for (int j = 0; j < nslots; j++) {
+ const HangarSlot* s = hangar->GetSlot(i,j);
+
+ if (hangar->GetState(s) >= Hangar::ACTIVE) {
+ char txt[32];
+ sprintf_s(txt, " %2d ", item+1);
+
+ hangar_list->AddItemWithData(txt, item); // use data for sort
+
+ if (hangar->GetShip(s))
+ hangar_list->SetItemText(item, 1, hangar->GetShip(s)->Name());
+
+ hangar_list->SetItemText(item, 2, hangar->StatusName(s));
+
+ if (hangar->GetPackageElement(s))
+ hangar_list->SetItemText(item, 3, Mission::RoleName(hangar->GetPackageElement(s)->Type()));
+
+ FormatTime(txt, hangar->TimeRemaining(s));
+ hangar_list->SetItemText(item, 4, txt);
+
+ hangar_list->SetItemData(item, 1, i);
+ hangar_list->SetItemData(item, 2, j);
+
+ item++;
+ }
+ }
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::OnPackage(AWEvent* event)
+{
+ if (!filter_list || !hangar_list || !ship) return;
+
+ int code = Mission::PATROL;
+
+ switch (mission_type) {
+ case 0: code = Mission::PATROL; break;
+ case 1: code = Mission::INTERCEPT; break;
+ case 2: code = Mission::ASSAULT; break;
+ case 3: code = Mission::STRIKE; break;
+ case 4: code = Mission::ESCORT; break;
+ case 5: code = Mission::INTEL; break;
+ }
+
+ int squad = filter_list->GetSelectedIndex();
+ Hangar* hangar = ship->GetHangar();
+ Sim* sim = Sim::GetSim();
+ const char* call = sim->FindAvailCallsign(ship->GetIFF());
+ Element* elem = sim->CreateElement(call, ship->GetIFF(), code);
+ Element* tgt = 0;
+ FlightDeck* deck = 0;
+ int queue = 1000;
+ int* load = 0;
+
+ elem->SetSquadron(hangar->SquadronName(squad));
+ elem->SetCarrier(ship);
+
+ if (objective_list) {
+ int index = objective_list->GetListIndex();
+ Text target = objective_list->GetItemText(index);
+
+ Instruction* objective = new(__FILE__,__LINE__) Instruction(code, target.data());
+ elem->AddObjective(objective);
+
+ tgt = sim->FindElement(target.data());
+ }
+
+ if (loadout_list && design) {
+ int index = loadout_list->GetListIndex();
+ Text loadname = loadout_list->GetItemText(index);
+
+ ListIter<ShipLoad> sl = (List<ShipLoad>&) design->loadouts;
+ while (++sl && !load) {
+ if (sl->name == loadname) {
+ load = sl->load;
+ elem->SetLoadout(load);
+ }
+ }
+ }
+
+ for (int i = 0; i < ship->NumFlightDecks(); i++) {
+ FlightDeck* d = ship->GetFlightDeck(i);
+
+ if (d && d->IsLaunchDeck()) {
+ int dq = hangar->PreflightQueue(d);
+
+ if (dq < queue) {
+ queue = dq;
+ deck = d;
+ }
+ }
+ }
+
+ int npackage = 0;
+ int slots[4];
+
+ for (int i = 0; i < 4; i++)
+ slots[i] = -1;
+
+ for (int i = 0; i < hangar_list->NumItems(); i++) {
+ if (hangar_list->IsSelected(i)) {
+ int nslot = hangar_list->GetItemData(i);
+ hangar->GotoAlert(squad, nslot, deck, elem, load, true);
+ slots[npackage] = nslot;
+ hangar_list->SetSelected(i, false);
+ npackage++;
+
+ if (npackage >= 4)
+ break;
+ }
+ }
+
+ NetUtil::SendElemCreate(elem, squad, slots, false);
+
+ if (flight_planner) {
+ switch (mission_type) {
+ case 0:
+ default:
+ flight_planner->CreatePatrolRoute(elem, patrol_pattern++);
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ if (tgt)
+ flight_planner->CreateStrikeRoute(elem, tgt);
+ else
+ flight_planner->CreatePatrolRoute(elem, patrol_pattern++);
+ break;
+
+ case 4:
+ if (tgt)
+ flight_planner->CreateEscortRoute(elem, tgt);
+ else
+ flight_planner->CreatePatrolRoute(elem, patrol_pattern++);
+ break;
+ }
+
+ if (patrol_pattern < 0 || patrol_pattern > 3)
+ patrol_pattern = 0;
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::OnAlert(AWEvent* event)
+{
+ if (!filter_list || !hangar_list || !ship) return;
+
+ int squad = filter_list->GetSelectedIndex();
+ Hangar* hangar = ship->GetHangar();
+ Sim* sim = Sim::GetSim();
+ const char* call = sim->FindAvailCallsign(ship->GetIFF());
+ Element* elem = sim->CreateElement(call, ship->GetIFF());
+ FlightDeck* deck = 0;
+ int queue = 1000;
+ const int* load = 0;
+
+ elem->SetSquadron(hangar->SquadronName(squad));
+ elem->SetCarrier(ship);
+
+ for (int i = 0; i < ship->NumFlightDecks(); i++) {
+ FlightDeck* d = ship->GetFlightDeck(i);
+
+ if (d && d->IsLaunchDeck()) {
+ int dq = hangar->PreflightQueue(d);
+
+ if (dq < queue) {
+ queue = dq;
+ deck = d;
+ }
+ }
+ }
+
+ int nalert = 0;
+ int slots[4];
+
+ for (int i = 0; i < 4; i++)
+ slots[i] = -1;
+
+ for (int i = 0; i < hangar_list->NumItems(); i++) {
+ if (hangar_list->IsSelected(i)) {
+ int nslot = hangar_list->GetItemData(i);
+ slots[nalert] = nslot;
+
+ if (!load) {
+ const HangarSlot* hangar_slot = hangar->GetSlot(squad, nslot);
+ if (hangar_slot) {
+ load = hangar->GetLoadout(hangar_slot);
+ elem->SetLoadout((int*) load);
+ }
+ }
+
+ hangar->GotoAlert(squad, nslot, deck, elem);
+ hangar_list->SetSelected(i, false);
+ nalert++;
+
+ if (nalert >= 4)
+ break;
+ }
+ }
+
+ NetUtil::SendElemCreate(elem, squad, slots, true);
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::OnLaunch(AWEvent* event)
+{
+ if (!filter_list || !hangar_list || !ship) return;
+
+ int squad = filter_list->GetSelectedIndex();
+
+ Hangar* hangar = ship->GetHangar();
+
+ // selected squadron:
+ if (squad < hangar->NumSquadrons()) {
+ for (int i = 0; i < hangar_list->NumItems(); i++) {
+ if (hangar_list->IsSelected(i)) {
+ int nslot = hangar_list->GetItemData(i);
+ hangar->Launch(squad, nslot);
+ NetUtil::SendShipLaunch(ship, squad, nslot);
+ }
+ }
+ }
+
+ // selected pending filter:
+ else if (squad == hangar->NumSquadrons()) {
+ for (int item = 0; item < hangar_list->NumItems(); item++) {
+ if (hangar_list->IsSelected(item)) {
+ int squadron = hangar_list->GetItemData(item, 3);
+ int slot = hangar_list->GetItemData(item, 4);
+
+ if (squadron >= 0 && slot >= 0) {
+ hangar->Launch(squadron, slot);
+ NetUtil::SendShipLaunch(ship, squadron, slot);
+ }
+ }
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::OnStandDown(AWEvent* event)
+{
+ if (!filter_list || !hangar_list || !ship) return;
+
+ int seln = filter_list->GetSelectedIndex();
+
+ Hangar* hangar = ship->GetHangar();
+
+ // selected squadron:
+ if (seln < hangar->NumSquadrons()) {
+ for (int i = 0; i < hangar_list->NumItems(); i++) {
+ if (hangar_list->IsSelected(i)) {
+ int nslot = hangar_list->GetItemData(i);
+ hangar->StandDown(seln, nslot);
+ }
+ }
+ }
+
+ // selected pending filter:
+ else if (seln == hangar->NumSquadrons()) {
+ for (int item = 0; item < hangar_list->NumItems(); item++) {
+ if (hangar_list->IsSelected(item)) {
+ int squadron = hangar_list->GetItemData(item, 3);
+ int slot = hangar_list->GetItemData(item, 4);
+
+ if (squadron >= 0 && slot >= 0)
+ hangar->StandDown(squadron, slot);
+ }
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::OnRecall(AWEvent* event)
+{
+ if (!filter_list || !hangar_list || !ship) return;
+
+ int seln = filter_list->GetSelectedIndex();
+
+ Hangar* hangar = ship->GetHangar();
+
+ // selected squadron: or selected active filter:
+ if (seln < hangar->NumSquadrons() || seln == hangar->NumSquadrons()+1) {
+ for (int i = 0; i < hangar_list->NumItems(); i++) {
+ if (hangar_list->IsSelected(i)) {
+ int nsquad = seln;
+ int nslot = hangar_list->GetItemData(i);
+
+ if (seln > hangar->NumSquadrons()) {
+ nsquad = hangar_list->GetItemData(i, 1);
+ nslot = hangar_list->GetItemData(i, 2);
+ }
+
+ const HangarSlot* slot = hangar->GetSlot(nsquad, nslot);
+ Ship* recall = hangar->GetShip(slot);
+
+ if (recall) {
+ RadioMessage* msg = new(__FILE__,__LINE__) RadioMessage(recall, ship, RadioMessage::RTB);
+ RadioTraffic::Transmit(msg);
+ }
+ }
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::OnMissionType(AWEvent* event)
+{
+ mission_type = -1;
+
+ for (int i = 0; i < 6; i++) {
+ if (mission_btn[i]) {
+ if (mission_btn[i] == event->window) {
+ mission_btn[i]->SetButtonState(1);
+ mission_type = i;
+ }
+ else {
+ mission_btn[i]->SetButtonState(0);
+ }
+ }
+ }
+
+ if (objective_list && mission_type > -1) {
+ objective_list->ClearItems();
+
+ char txt[32];
+ Sim* sim = Sim::GetSim();
+ ListIter<Element> iter = sim->GetElements();
+
+ while (++iter) {
+ Element* elem = iter.value();
+
+ if (!elem->IsActive() || elem->IsFinished() || elem->IsSquadron())
+ continue;
+
+ CombatGroup* group = elem->GetCombatGroup();
+ int iff = elem->GetIFF();
+ Ship* s = elem->GetShip(1);
+ double r = 0;
+ bool con = false;
+
+ if (iff != ship->GetIFF()) {
+ if (elem->IntelLevel() < Intel::LOCATED)
+ continue;
+
+ if (group && group->IntelLevel() < Intel::LOCATED)
+ continue;
+ }
+
+ if (s) {
+ Point s_loc = s->Location() + s->GetRegion()->Location();
+ Point h_loc = ship->Location() + ship->GetRegion()->Location();
+
+ r = (s_loc - h_loc).length();
+
+ con = ship->FindContact(s) != 0;
+
+ if (con) {
+ FormatNumber(txt, r);
+ }
+ else {
+ strcpy_s(txt, Game::GetText("FltDlg.Unknown").data());
+ r = 2e9;
+ }
+ }
+
+ switch (mission_type) {
+ case 1: // INTERCEPT
+ if (iff && iff != ship->GetIFF() && s && s->IsDropship()) {
+ int item = objective_list->AddItem(elem->Name()) - 1;
+ objective_list->SetItemText(item, 1, s->GetRegion()->Name());
+
+ objective_list->SetItemText(item, 2, txt);
+ objective_list->SetItemData(item, 2, (DWORD) r);
+ }
+ break;
+
+ case 2: // ASSAULT
+ if (iff && iff != ship->GetIFF() && s && (s->IsStarship() || s->IsStatic())) {
+ int item = objective_list->AddItem(elem->Name()) - 1;
+ objective_list->SetItemText(item, 1, s->GetRegion()->Name());
+
+ objective_list->SetItemText(item, 2, txt);
+ objective_list->SetItemData(item, 2, (DWORD) r);
+ }
+ break;
+
+ case 3: // STRIKE
+ if (iff && iff != ship->GetIFF() && s && s->IsGroundUnit()) {
+ int item = objective_list->AddItem(elem->Name()) - 1;
+ objective_list->SetItemText(item, 1, s->GetRegion()->Name());
+
+ objective_list->SetItemText(item, 2, txt);
+ objective_list->SetItemData(item, 2, (DWORD) r);
+ }
+ break;
+
+ case 4: // ESCORT
+ if ((iff == 0 || iff == ship->GetIFF()) && (!s || !s->IsStatic())) {
+ int item = objective_list->AddItem(elem->Name()) - 1;
+
+ if (s) {
+ objective_list->SetItemText(item, 1, s->GetRegion()->Name());
+ objective_list->SetItemText(item, 2, txt);
+ objective_list->SetItemData(item, 2, (DWORD) r);
+ }
+
+ else {
+ objective_list->SetItemText(item, 1, "0");
+ objective_list->SetItemData(item, 1, 0);
+ }
+ }
+ break;
+
+ case 5: // SCOUT?
+ break;
+
+ default: break;
+ }
+ }
+ }
+
+ if (loadout_list && mission_type > -1) {
+ loadout_list->ClearItems();
+
+ if (design) {
+ ListIter<ShipLoad> sl = (List<ShipLoad>&) design->loadouts;
+ while (++sl) {
+ int item = loadout_list->AddItem(sl->name) - 1;
+
+ char weight[32];
+ sprintf_s(weight, "%d kg", (int) ((design->mass + sl->mass) * 1000));
+ loadout_list->SetItemText(item, 1, weight);
+ loadout_list->SetItemData(item, 1, (DWORD) (sl->mass * 1000));
+ }
+ }
+ }
+}
+
+// +--------------------------------------------------------------------+
+
+void
+FltDlg::OnClose(AWEvent* event)
+{
+ if (manager)
+ manager->CloseTopmost();
+}
+
+
+