From d17521c8b9085a91d08fecfd0b51bbbf7b1dccac Mon Sep 17 00:00:00 2001 From: "milo24x7@gmail.com" Date: Sun, 7 Jul 2013 22:08:49 +0000 Subject: Updated open source license declaration and fixed some formatting issues. --- Stars45/CmdForceDlg.cpp | 1459 ++++++++++++++++++++++++----------------------- 1 file changed, 741 insertions(+), 718 deletions(-) (limited to 'Stars45/CmdForceDlg.cpp') diff --git a/Stars45/CmdForceDlg.cpp b/Stars45/CmdForceDlg.cpp index 8f3bca4..c73fe82 100644 --- a/Stars45/CmdForceDlg.cpp +++ b/Stars45/CmdForceDlg.cpp @@ -1,718 +1,741 @@ -/* Project Starshatter 4.5 - Destroyer Studios LLC - Copyright © 1997-2004. All Rights Reserved. - - SUBSYSTEM: Stars.exe - FILE: CmdForceDlg.cpp - AUTHOR: John DiCamillo - - - OVERVIEW - ======== - Operational Command Dialog (Order of Battle Tab) -*/ - -#include "MemDebug.h" -#include "CmdForceDlg.h" -#include "CmdMsgDlg.h" -#include "CmpnScreen.h" -#include "Starshatter.h" -#include "Campaign.h" -#include "Combatant.h" -#include "CombatAssignment.h" -#include "CombatGroup.h" -#include "CombatUnit.h" -#include "CombatZone.h" -#include "Ship.h" -#include "ShipDesign.h" -#include "Player.h" -#include "Weapon.h" - -#include "Game.h" -#include "DataLoader.h" -#include "Button.h" -#include "ComboBox.h" -#include "ListBox.h" -#include "Slider.h" -#include "Video.h" -#include "Keyboard.h" -#include "Mouse.h" -#include "ParseUtil.h" -#include "FormatUtil.h" - -// +--------------------------------------------------------------------+ -// DECLARE MAPPING FUNCTIONS: - -DEF_MAP_CLIENT(CmdForceDlg, OnMode); -DEF_MAP_CLIENT(CmdForceDlg, OnSave); -DEF_MAP_CLIENT(CmdForceDlg, OnExit); -DEF_MAP_CLIENT(CmdForceDlg, OnForces); -DEF_MAP_CLIENT(CmdForceDlg, OnCombat); -DEF_MAP_CLIENT(CmdForceDlg, OnTransfer); - -// +--------------------------------------------------------------------+ - -CmdForceDlg::CmdForceDlg(Screen* s, FormDef& def, CmpnScreen* mgr) -: FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), -CmdDlg(mgr), -cmb_forces(0), lst_combat(0), lst_desc(0), -stars(0), campaign(0), current_group(0), current_unit(0), -btn_transfer(0) -{ - stars = Starshatter::GetInstance(); - campaign = Campaign::GetCampaign(); - - Init(def); -} - -CmdForceDlg::~CmdForceDlg() -{ -} - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::RegisterControls() -{ - cmb_forces = (ComboBox*) FindControl(400); - lst_combat = (ListBox*) FindControl(401); - lst_desc = (ListBox*) FindControl(402); - btn_transfer = (Button*) FindControl(403); - - RegisterCmdControls(this); - - if (btn_save) - REGISTER_CLIENT(EID_CLICK, btn_save, CmdForceDlg, OnSave); - - if (btn_exit) - REGISTER_CLIENT(EID_CLICK, btn_exit, CmdForceDlg, OnExit); - - for (int i = 0; i < 5; i++) { - if (btn_mode[i]) - REGISTER_CLIENT(EID_CLICK, btn_mode[i], CmdForceDlg, OnMode); - } - - if (cmb_forces) - REGISTER_CLIENT(EID_SELECT, cmb_forces, CmdForceDlg, OnForces); - - if (lst_combat) { - lst_combat->AddColumn("datatype", 0); - REGISTER_CLIENT(EID_SELECT, lst_combat, CmdForceDlg, OnCombat); - } - - if (btn_transfer) { - btn_transfer->SetEnabled(false); - REGISTER_CLIENT(EID_CLICK, btn_transfer, CmdForceDlg, OnTransfer); - } -} - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::ExecFrame() -{ - CmdDlg::ExecFrame(); -} - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::Show() -{ - mode = MODE_FORCES; - - FormWindow::Show(); - ShowCmdDlg(); - - cmb_forces->ClearItems(); - - campaign = Campaign::GetCampaign(); - - if (campaign) { - List& combatants = campaign->GetCombatants(); - - if (combatants.size() > 0) { - for (int i = 0; i < combatants.size(); i++) { - if (IsVisible(combatants[i])) { - cmb_forces->AddItem(combatants[i]->Name()); - } - } - - cmb_forces->SetSelection(0); - Combatant* c = combatants[0]; - ShowCombatant(c); - } - } -} - -// +--------------------------------------------------------------------+ - -bool -CmdForceDlg::IsVisible(Combatant* c) -{ - int nvis = 0; - - if (c) { - CombatGroup* force = c->GetForce(); - - if (force) { - List& groups = force->GetComponents(); - for (int i = 0; i < groups.size(); i++) { - CombatGroup* g = groups[i]; - - if (g->Type() < CombatGroup::CIVILIAN && - g->CountUnits() > 0 && - g->IntelLevel() >= Intel::KNOWN) - - nvis++; - } - } - } - - return nvis > 0; -} - -// +--------------------------------------------------------------------+ - -static char pipe_stack[32]; -static bool blank_line = false; - -void -CmdForceDlg::ShowCombatant(Combatant* c) -{ - if (!lst_combat || !c) return; - - lst_combat->ClearItems(); - ZeroMemory(pipe_stack, 32); - - CombatGroup* force = c->GetForce(); - - if (force) { - List& groups = force->GetComponents(); - for (int i = 0; i < groups.size(); i++) { - CombatGroup* g = groups[i]; - if (g->Type() < CombatGroup::CIVILIAN && g->CountUnits() > 0) - AddCombatGroup(g); - } - } - - current_group = 0; - current_unit = 0; - - if (lst_desc) lst_desc->ClearItems(); - if (btn_transfer) btn_transfer->SetEnabled(false); -} - -void -CmdForceDlg::AddCombatGroup(CombatGroup* grp, bool last_child) -{ - if (!lst_combat || !grp || grp->IntelLevel() < Intel::KNOWN) return; - - char prefix[4]; - - if (!grp->GetParent() || grp->GetParent()->Type() == CombatGroup::FORCE) { - if (!grp->IsExpanded()) { - prefix[0] = Font::PIPE_PLUS; - prefix[1] = 0; - } - else { - prefix[0] = Font::PIPE_MINUS; - prefix[1] = 0; - } - } - else { - prefix[0] = last_child ? Font::PIPE_LL : Font::PIPE_LT; - prefix[1] = Font::PIPE_HORZ; - prefix[2] = 0; - prefix[3] = 0; - - if (grp->GetLiveComponents().size() > 0 || grp->GetUnits().size() > 0) { - if (grp->IsExpanded()) - prefix[1] = Font::PIPE_MINUS; - else - prefix[1] = Font::PIPE_PLUS; - } - } - - int index = lst_combat->AddItemWithData( - Text(pipe_stack) + - Text(prefix) + - grp->GetDescription(), - (DWORD) grp); - lst_combat->SetItemData(index-1, 1, 0); - blank_line = false; - - int stacklen = strlen(pipe_stack); - - if (!grp->GetParent() || grp->GetParent()->Type() == CombatGroup::FORCE) - ; // no stack after first entry - else if (prefix[0] == Font::PIPE_LT) - pipe_stack[stacklen++] = Font::PIPE_VERT; - else - pipe_stack[stacklen++] = Font::PIPE_NBSP; - pipe_stack[stacklen] = 0; - - if (grp->IsExpanded() && grp->GetUnits().size() > 0) { - prefix[0] = (grp->GetLiveComponents().size() > 0) ? Font::PIPE_VERT : Font::PIPE_NBSP; - prefix[1] = Font::PIPE_NBSP; - prefix[2] = 0; - prefix[3] = 0; - - ListIter unit_iter = grp->GetUnits(); - while (++unit_iter) { - CombatUnit* unit = unit_iter.value(); - char info[512]; - int damage = (int) (100 * unit->GetSustainedDamage() / unit->GetDesign()->integrity); - - if (damage < 1 || unit->DeadCount() >= unit->Count()) { - sprintf_s(info, "%s%s%s", pipe_stack, prefix, unit->GetDescription()); - } else { - sprintf_s(info, "%s%s%s %d%% damage", pipe_stack, prefix, unit->GetDescription(), damage); - } - - int index = lst_combat->AddItemWithData(info, (DWORD) unit); - - lst_combat->SetItemData(index-1, 1, 1); - lst_combat->SetItemColor(index-1, lst_combat->GetForeColor() * 0.65); - } - - // blank line after last unit in group: - lst_combat->AddItem(Text(pipe_stack) + Text(prefix)); - blank_line = true; - } - - if (grp->IsExpanded() && grp->GetLiveComponents().size() > 0) { - List& groups = grp->GetLiveComponents(); - for (int i = 0; i < groups.size(); i++) { - AddCombatGroup(groups[i], i == groups.size()-1); - } - - // blank line after last group in group: - if (!blank_line) { - lst_combat->AddItem(pipe_stack); - blank_line = true; - } - } - - if (stacklen > 1) - pipe_stack[stacklen-1] = 0; - else - pipe_stack[0] = 0; -} - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::OnForces(AWEvent* event) -{ - Text name = cmb_forces->GetSelectedItem(); - - campaign = Campaign::GetCampaign(); - - if (campaign) { - ListIter iter = campaign->GetCombatants(); - - while (++iter) { - Combatant* c = iter.value(); - - if (name == c->Name()) { - ShowCombatant(c); - break; - } - } - } -} - -// +--------------------------------------------------------------------+ - -struct WepGroup { - Text name; - int count; - - WepGroup() : count(0) { } -}; - -WepGroup* FindWepGroup(WepGroup* weapons, const char* name) -{ - WepGroup* group = 0; - WepGroup* iter = weapons; - int w = 0; - int first = -1; - - while (!group && w < 8) { - if (first < 0 && iter->name.length() == 0) - first = w; - - if (!_stricmp(iter->name, name)) - group = iter; - - iter++; - w++; - } - - if (!group && first >= 0) { - group = weapons + first; - group->name = name; - } - - return group; -} - -void -CmdForceDlg::OnCombat(AWEvent* event) -{ - static int old_index = -1; - - int top_index = 0; - bool expand = false; - DWORD data = 0; - DWORD type = 0; - - current_group = 0; - current_unit = 0; - - if (lst_combat) { - top_index = lst_combat->GetTopIndex(); - - int index = lst_combat->GetListIndex(); - data = lst_combat->GetItemData(index); - type = lst_combat->GetItemData(index, 1); - Text item = lst_combat->GetItemText(index); - int nplus = item.indexOf(Font::PIPE_PLUS); - int xplus = -1; - int dx = 10000; - - if (nplus < 0) - nplus = item.indexOf(Font::PIPE_MINUS); - - if (nplus >= 0 && nplus < 64) { - char pipe[64]; - strncpy(pipe, item.data(), nplus+1); - pipe[nplus+1] = 0; - - Rect rect(0, 0, 1000, 20); - lst_combat->DrawText(pipe, 0, rect, DT_LEFT|DT_SINGLELINE|DT_VCENTER|DT_CALCRECT); - - xplus = rect.w; - } - - if (xplus > 0) { - dx = Mouse::X() - (lst_combat->GetRect().x + xplus - 16); - } - - // look for click on plus/minus in pipe - if (dx >= 0 && dx < 16) { - if (data && type == 0) { - CombatGroup* grp = (CombatGroup*) data; - grp->SetExpanded(!grp->IsExpanded()); - expand = true; - - current_group = grp; - current_unit = 0; - } - } - - old_index = index; - } - - if (campaign && data) { - if (!expand) { - lst_desc->ClearItems(); - - // combat group - if (type == 0) { - CombatGroup* grp = (CombatGroup*) data; - - current_group = grp; - current_unit = 0; - - // if has units, show location and assignment - if (grp->GetUnits().size() > 0) { - char txt[64]; - int n; - - n = lst_desc->AddItem("Group:") - 1; - lst_desc->SetItemText(n, 1, grp->GetDescription()); - n = lst_desc->AddItem("Sector:") - 1; - lst_desc->SetItemText(n, 1, grp->GetRegion()); - - lst_desc->AddItem(" "); - n = lst_desc->AddItem("Sorties:") - 1; - - if (grp->Sorties() >= 0) - sprintf_s(txt, "%d", grp->Sorties()); - else - strcpy_s(txt, "Unavail"); - - lst_desc->SetItemText(n, 1, txt); - - n = lst_desc->AddItem("Kills:") - 1; - - if (grp->Kills() >= 0) - sprintf_s(txt, "%d", grp->Kills()); - else - strcpy_s(txt, "Unavail"); - - lst_desc->SetItemText(n, 1, txt); - - n = lst_desc->AddItem("Eff Rating:") - 1; - - if (grp->Points() >= 0) { - if (grp->Sorties() > 0) - sprintf_s(txt, "%.1f", (double) grp->Points() / grp->Sorties()); - else - sprintf_s(txt, "%.1f", (double) grp->Points()); - } else { - strcpy_s(txt, "Unavail"); - } - - lst_desc->SetItemText(n, 1, txt); - } - - // else (if high-level) show components - else { - int n; - - n = lst_desc->AddItem("Group:") - 1; - lst_desc->SetItemText(n, 1, grp->GetDescription()); - - ListIter c = grp->GetLiveComponents(); - while (++c) { - n = lst_desc->AddItem("-") - 1; - lst_desc->SetItemText(n, 1, c->GetDescription()); - } - } - } - // combat unit - else { - CombatUnit* unit = (CombatUnit*) data; - current_group = unit->GetCombatGroup(); - current_unit = unit; - - int n; - char txt[64]; - - n = lst_desc->AddItem("Unit:") - 1; - lst_desc->SetItemText(n, 1, unit->GetDescription()); - n = lst_desc->AddItem("Sector:") - 1; - lst_desc->SetItemText(n, 1, unit->GetRegion()); - - const ShipDesign* design = unit->GetDesign(); - if (design) { - lst_desc->AddItem(" "); - n = lst_desc->AddItem("Type:") - 1; - lst_desc->SetItemText(n, 1, Ship::ClassName(design->type)); - n = lst_desc->AddItem("Class:") - 1; - lst_desc->SetItemText(n, 1, design->DisplayName()); - - if (design->type < Ship::STATION) - FormatNumber(txt, design->radius/2); - else - FormatNumber(txt, design->radius*2); - - strcat_s(txt, " m"); - - n = lst_desc->AddItem("Length:") - 1; - lst_desc->SetItemText(n, 1, txt); - - FormatNumber(txt, design->mass); - strcat_s(txt, " T"); - - n = lst_desc->AddItem("Mass:") - 1; - lst_desc->SetItemText(n, 1, txt); - - FormatNumber(txt, design->integrity); - n = lst_desc->AddItem("Hull:") - 1; - lst_desc->SetItemText(n, 1, txt); - - if (design->weapons.size()) { - lst_desc->AddItem(" "); - n = lst_desc->AddItem("Weapons:") - 1; - - WepGroup groups[8]; - for (int w = 0; w < design->weapons.size(); w++) { - Weapon* gun = design->weapons[w]; - WepGroup* group = FindWepGroup(groups, gun->Group()); - - if (group) - group->count++; - } - - for (int g = 0; g < 8; g++) { - WepGroup* group = &groups[g]; - if (group && group->count) { - sprintf_s(txt, "%s (%d)", group->name.data(), group->count); - if (g > 0) n = lst_desc->AddItem(" ") - 1; - lst_desc->SetItemText(n, 1, txt); - } - } - } - } - } - } - - else { - List& combatants = campaign->GetCombatants(); - Combatant* c = combatants[0]; - - if (cmb_forces) { - Text name = cmb_forces->GetSelectedItem(); - - for (int i = 0; i < combatants.size(); i++) { - c = combatants[i]; - - if (name == c->Name()) { - break; - } - } - } - - if (c) { - ShowCombatant(c); - - lst_combat->ScrollTo(top_index); - lst_combat->SetSelected(old_index); - } - } - } - - if (btn_transfer && campaign && current_group) - btn_transfer->SetEnabled( campaign->IsActive() && - CanTransfer(current_group) ); -} - -// +--------------------------------------------------------------------+ - -bool -CmdForceDlg::CanTransfer(CombatGroup* grp) -{ - if (!grp || !campaign) - return false; - - if (grp->Type() < CombatGroup::WING) - return false; - - if (grp->Type() > CombatGroup::CARRIER_GROUP) - return false; - - if (grp->Type() == CombatGroup::FLEET || - grp->Type() == CombatGroup::LCA_SQUADRON) - return false; - - CombatGroup* player_group = campaign->GetPlayerGroup(); - if (player_group->GetIFF() != grp->GetIFF()) - return false; - - return true; -} - - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::OnSave(AWEvent* event) -{ - CmdDlg::OnSave(event); -} - -void -CmdForceDlg::OnExit(AWEvent* event) -{ - CmdDlg::OnExit(event); -} - -void -CmdForceDlg::OnMode(AWEvent* event) -{ - CmdDlg::OnMode(event); -} - - -// +--------------------------------------------------------------------+ - -void -CmdForceDlg::OnTransfer(AWEvent* event) -{ - if (campaign && current_group) { - - // check player rank/responsibility: - Player* player = Player::GetCurrentPlayer(); - int cmd_class = Ship::FIGHTER; - - switch (current_group->Type()) { - case CombatGroup::WING: - case CombatGroup::INTERCEPT_SQUADRON: - case CombatGroup::FIGHTER_SQUADRON: - cmd_class = Ship::FIGHTER; - break; - - case CombatGroup::ATTACK_SQUADRON: - cmd_class = Ship::ATTACK; - break; - - case CombatGroup::LCA_SQUADRON: - cmd_class = Ship::LCA; - break; - - case CombatGroup::DESTROYER_SQUADRON: - cmd_class = Ship::DESTROYER; - break; - - case CombatGroup::BATTLE_GROUP: - cmd_class = Ship::CRUISER; - break; - - case CombatGroup::CARRIER_GROUP: - case CombatGroup::FLEET: - cmd_class = Ship::CARRIER; - break; - } - - char transfer_info[512]; - - if (player->CanCommand(cmd_class)) { - if (current_unit) { - campaign->SetPlayerUnit(current_unit); - - sprintf_s(transfer_info, "Your transfer request has been approved, %s %s. You are now assigned to the %s. Good luck.\n\nFleet Admiral A. Evars FORCOM\nCommanding", - Player::RankName(player->Rank()), - player->Name().data(), - current_unit->GetDescription()); - } - else { - campaign->SetPlayerGroup(current_group); - - sprintf_s(transfer_info, "Your transfer request has been approved, %s %s. You are now assigned to the %s. Good luck.\n\nFleet Admiral A. Evars FORCOM\nCommanding", - Player::RankName(player->Rank()), - player->Name().data(), - current_group->GetDescription()); - } - - Button::PlaySound(Button::SND_ACCEPT); - - CmdMsgDlg* msgdlg = manager->GetCmdMsgDlg(); - msgdlg->Title()->SetText("Transfer Approved"); - msgdlg->Message()->SetText(transfer_info); - msgdlg->Message()->SetTextAlign(DT_LEFT); - - manager->ShowCmdMsgDlg(); - } - - else { - Button::PlaySound(Button::SND_REJECT); - - sprintf_s(transfer_info, "Your transfer request has been denied, %s %s. The %s requires a command rank of %s. Please return to your unit and your duties.\n\nFleet Admiral A. Evars FORCOM\nCommanding", - Player::RankName(player->Rank()), - player->Name().data(), - current_group->GetDescription(), - Player::RankName(Player::CommandRankRequired(cmd_class))); - - CmdMsgDlg* msgdlg = manager->GetCmdMsgDlg(); - msgdlg->Title()->SetText("Transfer Denied"); - msgdlg->Message()->SetText(transfer_info); - msgdlg->Message()->SetTextAlign(DT_LEFT); - - manager->ShowCmdMsgDlg(); - } - } -} +/* 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: CmdForceDlg.cpp + AUTHOR: John DiCamillo + + + OVERVIEW + ======== + Operational Command Dialog (Order of Battle Tab) +*/ + +#include "MemDebug.h" +#include "CmdForceDlg.h" +#include "CmdMsgDlg.h" +#include "CmpnScreen.h" +#include "Starshatter.h" +#include "Campaign.h" +#include "Combatant.h" +#include "CombatAssignment.h" +#include "CombatGroup.h" +#include "CombatUnit.h" +#include "CombatZone.h" +#include "Ship.h" +#include "ShipDesign.h" +#include "Player.h" +#include "Weapon.h" + +#include "Game.h" +#include "DataLoader.h" +#include "Button.h" +#include "ComboBox.h" +#include "ListBox.h" +#include "Slider.h" +#include "Video.h" +#include "Keyboard.h" +#include "Mouse.h" +#include "ParseUtil.h" +#include "FormatUtil.h" + +// +--------------------------------------------------------------------+ +// DECLARE MAPPING FUNCTIONS: + +DEF_MAP_CLIENT(CmdForceDlg, OnMode); +DEF_MAP_CLIENT(CmdForceDlg, OnSave); +DEF_MAP_CLIENT(CmdForceDlg, OnExit); +DEF_MAP_CLIENT(CmdForceDlg, OnForces); +DEF_MAP_CLIENT(CmdForceDlg, OnCombat); +DEF_MAP_CLIENT(CmdForceDlg, OnTransfer); + +// +--------------------------------------------------------------------+ + +CmdForceDlg::CmdForceDlg(Screen* s, FormDef& def, CmpnScreen* mgr) + : FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr), CmdDlg(mgr), + cmb_forces(0), lst_combat(0), lst_desc(0), + stars(0), campaign(0), current_group(0), current_unit(0), + btn_transfer(0) +{ + stars = Starshatter::GetInstance(); + campaign = Campaign::GetCampaign(); + + Init(def); +} + +CmdForceDlg::~CmdForceDlg() +{ +} + +// +--------------------------------------------------------------------+ + +void +CmdForceDlg::RegisterControls() +{ + cmb_forces = (ComboBox*) FindControl(400); + lst_combat = (ListBox*) FindControl(401); + lst_desc = (ListBox*) FindControl(402); + btn_transfer = (Button*) FindControl(403); + + RegisterCmdControls(this); + + if (btn_save) + REGISTER_CLIENT(EID_CLICK, btn_save, CmdForceDlg, OnSave); + + if (btn_exit) + REGISTER_CLIENT(EID_CLICK, btn_exit, CmdForceDlg, OnExit); + + for (int i = 0; i < 5; i++) { + if (btn_mode[i]) + REGISTER_CLIENT(EID_CLICK, btn_mode[i], CmdForceDlg, OnMode); + } + + if (cmb_forces) + REGISTER_CLIENT(EID_SELECT, cmb_forces, CmdForceDlg, OnForces); + + if (lst_combat) { + lst_combat->AddColumn("datatype", 0); + REGISTER_CLIENT(EID_SELECT, lst_combat, CmdForceDlg, OnCombat); + } + + if (btn_transfer) { + btn_transfer->SetEnabled(false); + REGISTER_CLIENT(EID_CLICK, btn_transfer, CmdForceDlg, OnTransfer); + } +} + +// +--------------------------------------------------------------------+ + +void +CmdForceDlg::ExecFrame() +{ + CmdDlg::ExecFrame(); +} + +// +--------------------------------------------------------------------+ + +void +CmdForceDlg::Show() +{ + mode = MODE_FORCES; + + FormWindow::Show(); + ShowCmdDlg(); + + cmb_forces->ClearItems(); + + campaign = Campaign::GetCampaign(); + + if (campaign) { + List& combatants = campaign->GetCombatants(); + + if (combatants.size() > 0) { + for (int i = 0; i < combatants.size(); i++) { + if (IsVisible(combatants[i])) { + cmb_forces->AddItem(combatants[i]->Name()); + } + } + + cmb_forces->SetSelection(0); + Combatant* c = combatants[0]; + ShowCombatant(c); + } + } +} + +// +--------------------------------------------------------------------+ + +bool +CmdForceDlg::IsVisible(Combatant* c) +{ + int nvis = 0; + + if (c) { + CombatGroup* force = c->GetForce(); + + if (force) { + List& groups = force->GetComponents(); + for (int i = 0; i < groups.size(); i++) { + CombatGroup* g = groups[i]; + + if (g->Type() < CombatGroup::CIVILIAN && + g->CountUnits() > 0 && + g->IntelLevel() >= Intel::KNOWN) + + nvis++; + } + } + } + + return nvis > 0; +} + +// +--------------------------------------------------------------------+ + +static char pipe_stack[32]; +static bool blank_line = false; + +void +CmdForceDlg::ShowCombatant(Combatant* c) +{ + if (!lst_combat || !c) return; + + lst_combat->ClearItems(); + ZeroMemory(pipe_stack, 32); + + CombatGroup* force = c->GetForce(); + + if (force) { + List& groups = force->GetComponents(); + for (int i = 0; i < groups.size(); i++) { + CombatGroup* g = groups[i]; + if (g->Type() < CombatGroup::CIVILIAN && g->CountUnits() > 0) + AddCombatGroup(g); + } + } + + current_group = 0; + current_unit = 0; + + if (lst_desc) lst_desc->ClearItems(); + if (btn_transfer) btn_transfer->SetEnabled(false); +} + +void +CmdForceDlg::AddCombatGroup(CombatGroup* grp, bool last_child) +{ + if (!lst_combat || !grp || grp->IntelLevel() < Intel::KNOWN) return; + + char prefix[4]; + + if (!grp->GetParent() || grp->GetParent()->Type() == CombatGroup::FORCE) { + if (!grp->IsExpanded()) { + prefix[0] = Font::PIPE_PLUS; + prefix[1] = 0; + } + else { + prefix[0] = Font::PIPE_MINUS; + prefix[1] = 0; + } + } + else { + prefix[0] = last_child ? Font::PIPE_LL : Font::PIPE_LT; + prefix[1] = Font::PIPE_HORZ; + prefix[2] = 0; + prefix[3] = 0; + + if (grp->GetLiveComponents().size() > 0 || grp->GetUnits().size() > 0) { + if (grp->IsExpanded()) + prefix[1] = Font::PIPE_MINUS; + else + prefix[1] = Font::PIPE_PLUS; + } + } + + int index = lst_combat->AddItemWithData( + Text(pipe_stack) + + Text(prefix) + + grp->GetDescription(), + (DWORD) grp); + lst_combat->SetItemData(index-1, 1, 0); + blank_line = false; + + int stacklen = strlen(pipe_stack); + + if (!grp->GetParent() || grp->GetParent()->Type() == CombatGroup::FORCE) + ; // no stack after first entry + else if (prefix[0] == Font::PIPE_LT) + pipe_stack[stacklen++] = Font::PIPE_VERT; + else + pipe_stack[stacklen++] = Font::PIPE_NBSP; + pipe_stack[stacklen] = 0; + + if (grp->IsExpanded() && grp->GetUnits().size() > 0) { + prefix[0] = (grp->GetLiveComponents().size() > 0) ? Font::PIPE_VERT : Font::PIPE_NBSP; + prefix[1] = Font::PIPE_NBSP; + prefix[2] = 0; + prefix[3] = 0; + + ListIter unit_iter = grp->GetUnits(); + while (++unit_iter) { + CombatUnit* unit = unit_iter.value(); + char info[512]; + int damage = (int) (100 * unit->GetSustainedDamage() / unit->GetDesign()->integrity); + + if (damage < 1 || unit->DeadCount() >= unit->Count()) { + sprintf_s(info, "%s%s%s", pipe_stack, prefix, unit->GetDescription()); + } else { + sprintf_s(info, "%s%s%s %d%% damage", pipe_stack, prefix, unit->GetDescription(), damage); + } + + int index = lst_combat->AddItemWithData(info, (DWORD) unit); + + lst_combat->SetItemData(index-1, 1, 1); + lst_combat->SetItemColor(index-1, lst_combat->GetForeColor() * 0.65); + } + + // blank line after last unit in group: + lst_combat->AddItem(Text(pipe_stack) + Text(prefix)); + blank_line = true; + } + + if (grp->IsExpanded() && grp->GetLiveComponents().size() > 0) { + List& groups = grp->GetLiveComponents(); + for (int i = 0; i < groups.size(); i++) { + AddCombatGroup(groups[i], i == groups.size()-1); + } + + // blank line after last group in group: + if (!blank_line) { + lst_combat->AddItem(pipe_stack); + blank_line = true; + } + } + + if (stacklen > 1) + pipe_stack[stacklen-1] = 0; + else + pipe_stack[0] = 0; +} + +// +--------------------------------------------------------------------+ + +void +CmdForceDlg::OnForces(AWEvent* event) +{ + Text name = cmb_forces->GetSelectedItem(); + + campaign = Campaign::GetCampaign(); + + if (campaign) { + ListIter iter = campaign->GetCombatants(); + + while (++iter) { + Combatant* c = iter.value(); + + if (name == c->Name()) { + ShowCombatant(c); + break; + } + } + } +} + +// +--------------------------------------------------------------------+ + +struct WepGroup { + Text name; + int count; + + WepGroup() : count(0) { } +}; + +WepGroup* FindWepGroup(WepGroup* weapons, const char* name) +{ + WepGroup* group = 0; + WepGroup* iter = weapons; + int w = 0; + int first = -1; + + while (!group && w < 8) { + if (first < 0 && iter->name.length() == 0) + first = w; + + if (!_stricmp(iter->name, name)) + group = iter; + + iter++; + w++; + } + + if (!group && first >= 0) { + group = weapons + first; + group->name = name; + } + + return group; +} + +void +CmdForceDlg::OnCombat(AWEvent* event) +{ + static int old_index = -1; + + int top_index = 0; + bool expand = false; + DWORD data = 0; + DWORD type = 0; + + current_group = 0; + current_unit = 0; + + if (lst_combat) { + top_index = lst_combat->GetTopIndex(); + + int index = lst_combat->GetListIndex(); + data = lst_combat->GetItemData(index); + type = lst_combat->GetItemData(index, 1); + Text item = lst_combat->GetItemText(index); + int nplus = item.indexOf(Font::PIPE_PLUS); + int xplus = -1; + int dx = 10000; + + if (nplus < 0) + nplus = item.indexOf(Font::PIPE_MINUS); + + if (nplus >= 0 && nplus < 64) { + char pipe[64]; + strncpy(pipe, item.data(), nplus+1); + pipe[nplus+1] = 0; + + Rect rect(0, 0, 1000, 20); + lst_combat->DrawText(pipe, 0, rect, DT_LEFT|DT_SINGLELINE|DT_VCENTER|DT_CALCRECT); + + xplus = rect.w; + } + + if (xplus > 0) { + dx = Mouse::X() - (lst_combat->GetRect().x + xplus - 16); + } + + // look for click on plus/minus in pipe + if (dx >= 0 && dx < 16) { + if (data && type == 0) { + CombatGroup* grp = (CombatGroup*) data; + grp->SetExpanded(!grp->IsExpanded()); + expand = true; + + current_group = grp; + current_unit = 0; + } + } + + old_index = index; + } + + if (campaign && data) { + if (!expand) { + lst_desc->ClearItems(); + + // combat group + if (type == 0) { + CombatGroup* grp = (CombatGroup*) data; + + current_group = grp; + current_unit = 0; + + // if has units, show location and assignment + if (grp->GetUnits().size() > 0) { + char txt[64]; + int n; + + n = lst_desc->AddItem("Group:") - 1; + lst_desc->SetItemText(n, 1, grp->GetDescription()); + n = lst_desc->AddItem("Sector:") - 1; + lst_desc->SetItemText(n, 1, grp->GetRegion()); + + lst_desc->AddItem(" "); + n = lst_desc->AddItem("Sorties:") - 1; + + if (grp->Sorties() >= 0) + sprintf_s(txt, "%d", grp->Sorties()); + else + strcpy_s(txt, "Unavail"); + + lst_desc->SetItemText(n, 1, txt); + + n = lst_desc->AddItem("Kills:") - 1; + + if (grp->Kills() >= 0) + sprintf_s(txt, "%d", grp->Kills()); + else + strcpy_s(txt, "Unavail"); + + lst_desc->SetItemText(n, 1, txt); + + n = lst_desc->AddItem("Eff Rating:") - 1; + + if (grp->Points() >= 0) { + if (grp->Sorties() > 0) + sprintf_s(txt, "%.1f", (double) grp->Points() / grp->Sorties()); + else + sprintf_s(txt, "%.1f", (double) grp->Points()); + } else { + strcpy_s(txt, "Unavail"); + } + + lst_desc->SetItemText(n, 1, txt); + } + + // else (if high-level) show components + else { + int n; + + n = lst_desc->AddItem("Group:") - 1; + lst_desc->SetItemText(n, 1, grp->GetDescription()); + + ListIter c = grp->GetLiveComponents(); + while (++c) { + n = lst_desc->AddItem("-") - 1; + lst_desc->SetItemText(n, 1, c->GetDescription()); + } + } + } + // combat unit + else { + CombatUnit* unit = (CombatUnit*) data; + current_group = unit->GetCombatGroup(); + current_unit = unit; + + int n; + char txt[64]; + + n = lst_desc->AddItem("Unit:") - 1; + lst_desc->SetItemText(n, 1, unit->GetDescription()); + n = lst_desc->AddItem("Sector:") - 1; + lst_desc->SetItemText(n, 1, unit->GetRegion()); + + const ShipDesign* design = unit->GetDesign(); + if (design) { + lst_desc->AddItem(" "); + n = lst_desc->AddItem("Type:") - 1; + lst_desc->SetItemText(n, 1, Ship::ClassName(design->type)); + n = lst_desc->AddItem("Class:") - 1; + lst_desc->SetItemText(n, 1, design->DisplayName()); + + if (design->type < Ship::STATION) + FormatNumber(txt, design->radius/2); + else + FormatNumber(txt, design->radius*2); + + strcat_s(txt, " m"); + + n = lst_desc->AddItem("Length:") - 1; + lst_desc->SetItemText(n, 1, txt); + + FormatNumber(txt, design->mass); + strcat_s(txt, " T"); + + n = lst_desc->AddItem("Mass:") - 1; + lst_desc->SetItemText(n, 1, txt); + + FormatNumber(txt, design->integrity); + n = lst_desc->AddItem("Hull:") - 1; + lst_desc->SetItemText(n, 1, txt); + + if (design->weapons.size()) { + lst_desc->AddItem(" "); + n = lst_desc->AddItem("Weapons:") - 1; + + WepGroup groups[8]; + for (int w = 0; w < design->weapons.size(); w++) { + Weapon* gun = design->weapons[w]; + WepGroup* group = FindWepGroup(groups, gun->Group()); + + if (group) + group->count++; + } + + for (int g = 0; g < 8; g++) { + WepGroup* group = &groups[g]; + if (group && group->count) { + sprintf_s(txt, "%s (%d)", group->name.data(), group->count); + if (g > 0) n = lst_desc->AddItem(" ") - 1; + lst_desc->SetItemText(n, 1, txt); + } + } + } + } + } + } + + else { + List& combatants = campaign->GetCombatants(); + Combatant* c = combatants[0]; + + if (cmb_forces) { + Text name = cmb_forces->GetSelectedItem(); + + for (int i = 0; i < combatants.size(); i++) { + c = combatants[i]; + + if (name == c->Name()) { + break; + } + } + } + + if (c) { + ShowCombatant(c); + + lst_combat->ScrollTo(top_index); + lst_combat->SetSelected(old_index); + } + } + } + + if (btn_transfer && campaign && current_group) + btn_transfer->SetEnabled( campaign->IsActive() && + CanTransfer(current_group) ); +} + +// +--------------------------------------------------------------------+ + +bool +CmdForceDlg::CanTransfer(CombatGroup* grp) +{ + if (!grp || !campaign) + return false; + + if (grp->Type() < CombatGroup::WING) + return false; + + if (grp->Type() > CombatGroup::CARRIER_GROUP) + return false; + + if (grp->Type() == CombatGroup::FLEET || + grp->Type() == CombatGroup::LCA_SQUADRON) + return false; + + CombatGroup* player_group = campaign->GetPlayerGroup(); + if (player_group->GetIFF() != grp->GetIFF()) + return false; + + return true; +} + + +// +--------------------------------------------------------------------+ + +void +CmdForceDlg::OnSave(AWEvent* event) +{ + CmdDlg::OnSave(event); +} + +void +CmdForceDlg::OnExit(AWEvent* event) +{ + CmdDlg::OnExit(event); +} + +void +CmdForceDlg::OnMode(AWEvent* event) +{ + CmdDlg::OnMode(event); +} + + +// +--------------------------------------------------------------------+ + +void +CmdForceDlg::OnTransfer(AWEvent* event) +{ + if (campaign && current_group) { + + // check player rank/responsibility: + Player* player = Player::GetCurrentPlayer(); + int cmd_class = Ship::FIGHTER; + + switch (current_group->Type()) { + case CombatGroup::WING: + case CombatGroup::INTERCEPT_SQUADRON: + case CombatGroup::FIGHTER_SQUADRON: + cmd_class = Ship::FIGHTER; + break; + + case CombatGroup::ATTACK_SQUADRON: + cmd_class = Ship::ATTACK; + break; + + case CombatGroup::LCA_SQUADRON: + cmd_class = Ship::LCA; + break; + + case CombatGroup::DESTROYER_SQUADRON: + cmd_class = Ship::DESTROYER; + break; + + case CombatGroup::BATTLE_GROUP: + cmd_class = Ship::CRUISER; + break; + + case CombatGroup::CARRIER_GROUP: + case CombatGroup::FLEET: + cmd_class = Ship::CARRIER; + break; + } + + char transfer_info[512]; + + if (player->CanCommand(cmd_class)) { + if (current_unit) { + campaign->SetPlayerUnit(current_unit); + + sprintf_s(transfer_info, "Your transfer request has been approved, %s %s. You are now assigned to the %s. Good luck.\n\nFleet Admiral A. Evars FORCOM\nCommanding", + Player::RankName(player->Rank()), + player->Name().data(), + current_unit->GetDescription()); + } + else { + campaign->SetPlayerGroup(current_group); + + sprintf_s(transfer_info, "Your transfer request has been approved, %s %s. You are now assigned to the %s. Good luck.\n\nFleet Admiral A. Evars FORCOM\nCommanding", + Player::RankName(player->Rank()), + player->Name().data(), + current_group->GetDescription()); + } + + Button::PlaySound(Button::SND_ACCEPT); + + CmdMsgDlg* msgdlg = manager->GetCmdMsgDlg(); + msgdlg->Title()->SetText("Transfer Approved"); + msgdlg->Message()->SetText(transfer_info); + msgdlg->Message()->SetTextAlign(DT_LEFT); + + manager->ShowCmdMsgDlg(); + } + + else { + Button::PlaySound(Button::SND_REJECT); + + sprintf_s(transfer_info, "Your transfer request has been denied, %s %s. The %s requires a command rank of %s. Please return to your unit and your duties.\n\nFleet Admiral A. Evars FORCOM\nCommanding", + Player::RankName(player->Rank()), + player->Name().data(), + current_group->GetDescription(), + Player::RankName(Player::CommandRankRequired(cmd_class))); + + CmdMsgDlg* msgdlg = manager->GetCmdMsgDlg(); + msgdlg->Title()->SetText("Transfer Denied"); + msgdlg->Message()->SetText(transfer_info); + msgdlg->Message()->SetTextAlign(DT_LEFT); + + manager->ShowCmdMsgDlg(); + } + } +} -- cgit v1.1