Files
Goober5000andClaude Opus 4.7 30d81a83fb store campaign allowed-class lists in sets
Convert the allowed-ships and allowed-weapons lists to sets, rather than naive vectors that stored a true/false for every class.  Since these are ordered sets, iteration occurs in the same sequence as iteration of `Ship_info` or `Weapon_info`.  Associated data structures such as `Granted_ships` and `Granted_weapons` are converted as well.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-08-04 22:14:58 -04:00

169 lines
4.9 KiB
C++

/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
// InitialShips.cpp : implementation file
//
#include "stdafx.h"
#include "FRED.h"
#include "InitialShips.h"
#include "CampaignTreeView.h"
#include "CampaignEditorDlg.h"
#include "weapon/weapon.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define IDCAT(x,y) x ## y
/////////////////////////////////////////////////////////////////////////////
// InitialShips dialog
InitialShips::InitialShips(CWnd* pParent /*=NULL*/)
: CDialog(InitialShips::IDD, pParent)
{
//{{AFX_DATA_INIT(InitialShips)
//}}AFX_DATA_INIT
}
void InitialShips::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(InitialShips)
DDX_Control(pDX, IDC_INITIAL_LIST, m_initial_list);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(InitialShips, CDialog)
//{{AFX_MSG_MAP(InitialShips)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// InitialShips message handlers
BOOL InitialShips::OnInitDialog()
{
CDialog::OnInitDialog();
// fix overlapping checkboxes issue
// https://stackoverflow.com/questions/57951333/cchecklistbox-items-get-overlapped-on-selection-if-app-build-using-visual-studi
m_initial_list.SetFont(GetFont());
m_list_count = 0;
// change the window text, get the index into the array, and check the box for either the ships
// or weapons
if ( m_initial_items == INITIAL_SHIPS ) {
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it) {
if (it->flags[Ship::Info_Flags::Player_ship]) {
int i = static_cast<int>(std::distance(Ship_info.cbegin(), it));
m_initial_list.AddString(it->name);
if (Campaign.ships_allowed.contains(i)) {
m_initial_list.SetCheck(m_list_count, 1);
}
else if ((strlen(Campaign.filename) == 0) && strstr(it->name, "Myrmidon")) { //-V805
m_initial_list.SetCheck(m_list_count, 1);
}
else {
m_initial_list.SetCheck(m_list_count, 0);
}
m_initial_list.SetItemData(m_list_count, i);
m_list_count++;
}
}
// set the titale of the window
SetWindowText("Initial Ships Allowed");
} else if ( m_initial_items == INITIAL_WEAPONS ) {
// get the list of initial weapons available by looking at all possible player ships, getting
// the weapon information for those ships, then putting those weapons onto the list
SCP_vector<int> allowed_weapons(weapon_info_size(), 0);
for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it) {
if (it->flags[Ship::Info_Flags::Player_ship]) {
for (int i = 0; i < weapon_info_size(); ++i) {
if (it->allowed_weapons[i])
allowed_weapons[i] = 1;
}
}
}
// now add the weapons to the list
for (int i = 0; i < weapon_info_size(); ++i) {
if ( allowed_weapons[i] ) {
m_initial_list.AddString( Weapon_info[i].name );
int add_weapon = 0;
if ( Campaign.weapons_allowed.contains(i) ) {
add_weapon = 1;
} else if ( strlen(Campaign.filename) == 0 ) { //-V805
if ( strstr(Weapon_info[i].name, "Subach")) {
add_weapon = 1;
} else if ( strstr(Weapon_info[i].name, "Akheton")) {
add_weapon = 1;
} else if ( strstr(Weapon_info[i].name, "Rockeye")) {
add_weapon = 1;
} else if ( strstr(Weapon_info[i].name, "Tempest")) {
add_weapon = 1;
}
}
if (add_weapon) {
m_initial_list.SetCheck( m_list_count, 1 );
} else {
m_initial_list.SetCheck( m_list_count, 0 );
}
m_initial_list.SetItemData(m_list_count, i );
m_list_count++;
}
}
SetWindowText("Initial Weapons Allowed");
} else
Int3();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void InitialShips::OnOK()
{
int i;
// zero out whichever set we are setting
if ( m_initial_items == INITIAL_SHIPS ) {
Campaign.ships_allowed.clear();
} else if ( m_initial_items == INITIAL_WEAPONS ) {
Campaign.weapons_allowed.clear();
}
for ( i = 0; i < m_list_count; i++ ) {
if ( m_initial_list.GetCheck(i) ) {
// this item is checked. Get the index into either the ship info array or the weapons
// array
int index = static_cast<int>(m_initial_list.GetItemData(i));
if ( m_initial_items == INITIAL_SHIPS ) {
Campaign.ships_allowed.insert(index);
} else if ( m_initial_items == INITIAL_WEAPONS ) {
Campaign.weapons_allowed.insert(index);
} else
Int3();
}
}
CDialog::OnOK();
}