FS2_Open
Open source remastering of the Freespace 2 engine
AltShipClassDlg.cpp
Go to the documentation of this file.
1 /*
2  * Created by Hassan "Karajorma" Kazmi for the FreeSpace2 Source Code Project.
3  * You may not sell or otherwise commercially exploit the source or things you
4  * create based on the source.
5  */
6 
7 // AltShipClassDlg.cpp : implementation file
8 //
9 
10 #include "stdafx.h"
11 #include "fred.h"
12 #include "AltShipClassDlg.h"
13 #include "globalincs/linklist.h"
14 #include "ship/ship.h"
15 
16 #ifdef _DEBUG
17 #undef THIS_FILE
18 static char THIS_FILE[] = __FILE__;
19 #endif
20 
22 // AltShipClassDlg dialog
23 
24 
25 AltShipClassDlg::AltShipClassDlg(CWnd* pParent /*=NULL*/)
26  : CDialog(AltShipClassDlg::IDD, pParent)
27 {
28  //{{AFX_DATA_INIT(AltShipClassDlg)
30  m_selected_class = -1;
31  //}}AFX_DATA_INIT
32 
33  multi_edit = false;
34  player_ships_only = true;
35  num_string_variables = 0;
36 
37  memset(string_variable_indices, -1, sizeof (int)*MAX_SEXP_VARIABLES);
38  memset(ship_class_indices, -1, sizeof (int)*MAX_SHIP_CLASSES);
39 }
40 
41 
42 void AltShipClassDlg::DoDataExchange(CDataExchange* pDX)
43 {
44  CDialog::DoDataExchange(pDX);
45  //{{AFX_DATA_MAP(AltShipClassDlg)
46  DDX_Control(pDX, IDC_DEFAULT_TO_CLASS, m_default_to_class);
47  DDX_Control(pDX, IDC_ALT_CLASS_LIST, m_alt_class_list);
51  DDX_CBIndex(pDX, IDC_SET_FROM_SHIP_CLASS, m_selected_class);
52  //}}AFX_DATA_MAP
53 }
54 
55 
56 BEGIN_MESSAGE_MAP(AltShipClassDlg, CDialog)
57  //{{AFX_MSG_MAP(AltShipClassDlg)
58  ON_BN_CLICKED(IDC_ALT_CLASS_ADD, OnAltClassAdd)
59  ON_BN_CLICKED(IDC_ALT_CLASS_INSERT, OnAltClassInsert)
60  ON_BN_CLICKED(IDC_ALT_CLASS_DELETE, OnAltClassDelete)
61  ON_BN_CLICKED(IDC_ALT_CLASS_UP, OnMoveUp)
62  ON_BN_CLICKED(IDC_ALT_CLASS_DOWN, OnMoveDown)
63  ON_CBN_SELENDOK(IDC_SET_FROM_SHIP_CLASS, OnSelendokSetFromShipClass)
64  ON_CBN_SELENDOK(IDC_SET_FROM_VARIABLES, OnSelendokSetFromVariables)
65  ON_LBN_SELCHANGE(IDC_ALT_CLASS_LIST, OnSelchangeAltClassList)
66  ON_BN_CLICKED(IDC_DEFAULT_TO_CLASS, OnDefaultToClass)
67  //}}AFX_MSG_MAP
68 END_MESSAGE_MAP()
69 
71 // AltShipClassDlg message handlers
72 
73 
74 BOOL AltShipClassDlg::OnInitDialog()
75 {
76  int i, count;
77  char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
78 
79  CDialog::OnInitDialog();
80 
81  // have we got multiple selected ships?
82  num_selected_ships = 0;
83  object *objp;
84 
85  objp = GET_FIRST(&obj_used_list);
86  while (objp != END_OF_LIST(&obj_used_list)) {
87  if ((objp->type == OBJ_START) || (objp->type == OBJ_SHIP)) {
88  if (objp->flags & OF_MARKED) {
89  m_selected_ships[num_selected_ships++] = objp->instance;
90  }
91  }
92  objp = GET_NEXT(objp);
93  }
94 
95  Assert (num_selected_ships > 0);
97 
98  if (num_selected_ships > 1)
99  {
100  multi_edit = true;
101  }
102 
103  // Fill the variable combo box
104  m_set_from_variables.ResetContent();
105  m_set_from_variables.AddString("Set From Ship Class");
106  for (i=0; i < MAX_SEXP_VARIABLES; i++)
107  {
109  {
110  sprintf(buff, "%s[%s]", Sexp_variables[i].variable_name, Sexp_variables[i].text);
111  m_set_from_variables.AddString(buff);
112  string_variable_indices[num_string_variables++] = i;
113  }
114  }
115  m_set_from_variables.SetCurSel(0);
116  if (!num_string_variables) {
117  m_set_from_variables.EnableWindow(FALSE);
118  }
119 
120  // Fill the ship classes combo box
121  m_set_from_ship_class.ResetContent();
122  // Add the default entry if we need one followed by all the ship classes
123  if (num_string_variables) {
124  m_set_from_ship_class.AddString("Set From Variable");
125  }
126  count = 0;
127  for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it)
128  {
129  if (player_ships_only && !(it->flags & SIF_PLAYER_SHIP)) {
130  continue;
131  }
132 
133  ship_class_indices[count++] = std::distance(Ship_info.cbegin(), it);
134  m_set_from_ship_class.AddString(it->name);
135  }
136  m_set_from_ship_class.SetCurSel(num_string_variables?1:0); // Set to the first ship class
137 
138  // Set up the actual list of alt classes
139  alt_class_pool.clear();
141  alt_class_list_rebuild();
142 
143  return TRUE; // return TRUE unless you set the focus to a control
144  // EXCEPTION: OCX Property Pages should return FALSE
145 }
146 
147 
148 void AltShipClassDlg::alt_class_list_rebuild()
149 {
150  int i, j;
151  char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
152 
153  j = m_alt_class_list.GetCount();
154  for ( i=0; i < j ; i++) {
155  m_alt_class_list.DeleteString(0);
156  }
157 
158  for (i = 0; i < (int)alt_class_pool.size() ; i++) {
159  // Default classes should be at the end of the list
160  if(alt_class_pool[i].default_to_this_class && (i < (int)alt_class_pool.size() - 1) ) {
161  // Int3();
162  // TO DO : we should fix this.
163  }
164 
165  if (alt_class_pool[i].variable_index != -1) {
166  Assert (alt_class_pool[i].variable_index > -1 && alt_class_pool[i].variable_index < MAX_SEXP_VARIABLES);
167  Assert (Sexp_variables[alt_class_pool[i].variable_index].type & SEXP_VARIABLE_STRING);
168 
169  sprintf(buff, "%s[%s]", Sexp_variables[alt_class_pool[i].variable_index].variable_name, Sexp_variables[alt_class_pool[i].variable_index].text);
170 
171  // add it to the list
172  m_alt_class_list.AddString(buff);
173  }
174  else {
175  if (alt_class_pool[i].ship_class >= 0 && alt_class_pool[i].ship_class < MAX_SHIP_CLASSES) {
176  m_alt_class_list.AddString(Ship_info[alt_class_pool[i].ship_class].name);
177  }
178  else {
179  m_alt_class_list.AddString("Invalid Ship Class");
180  Int3();
181  }
182  }
183  }
184 }
185 
187 {
188  // TODO: Add extra cleanup here
189 
190  CDialog::OnCancel();
191 }
192 
194 {
195  // TODO: Add extra validation here
196 
197  for (int i=0; i < num_selected_ships; i++) {
198  Ships[m_selected_ships[i]].s_alt_classes = alt_class_pool;
199  }
200 
201  CDialog::OnOK();
202 }
203 
205 {
206  alt_class new_list_item;
207 
208  alt_class_update_entry(new_list_item);
209 
210  alt_class_pool.push_back(new_list_item);
211  alt_class_list_rebuild();
212 }
213 
215 {
216  int index;
217  alt_class new_list_item;
218  alt_class_update_entry(new_list_item);
219 
220  index = m_alt_class_list.GetCurSel();
221 
222  // If nothing is selected just add it
223  if ( index == -1) {
224  alt_class_pool.push_back(new_list_item);
225  }
226  // Stick it in front of the current selection
227  else {
228  alt_class_pool.insert(alt_class_pool.begin() + index, new_list_item );
229  }
230 
231  alt_class_list_rebuild();
232 
233  // If we inserted the user will probably want to edit the selection
234  if (index > -1) {
235  m_alt_class_list.SetCurSel(index);
236  }
237 }
238 
239 // Updates the currently selected list entry
240 void AltShipClassDlg::alt_class_update_entry(alt_class &list_item)
241 {
242  int index;
243 
244  // Add a string variable to the list
245  if (num_string_variables && m_set_from_variables.GetCurSel() > 0) {
246  index = string_variable_indices[m_set_from_variables.GetCurSel() -1];
247 
248  Assert (index >= 0);
249  list_item.variable_index = index;
250  list_item.ship_class = ship_info_lookup(Sexp_variables[index].text);
251  }
252  // Add a ship class to the list
253  else {
254  index = m_set_from_ship_class.GetCurSel();
255 
256  // Correct the index if the first entry isn't actually a ship class
257  if (num_string_variables) {
258  Assert (index > 0);
259  index--;
260  }
261 
262  list_item.variable_index = -1;
263  list_item.ship_class = ship_class_indices[index];
264  }
265 
266  // check the default tickbox
267  list_item.default_to_this_class = m_default_to_class.GetCheck() ? true:false;
268 }
269 
271 {
272  int index = m_alt_class_list.GetCurSel();
273 
274  // Nothing selected
275  if (index == -1) {
276  return;
277  }
278 
279  Assert (index < (int) alt_class_pool.size());
280  alt_class_pool.erase(alt_class_pool.begin()+index);
281  alt_class_list_rebuild();
282 }
283 
285 {
286  int index = m_alt_class_list.GetCurSel();
287 
288  // Nothing selected or already at the top
289  if (index < 1) {
290  return;
291  }
292 
293  std::swap(alt_class_pool[index], alt_class_pool[index-1]);
294  alt_class_list_rebuild();
295  m_alt_class_list.SetCurSel(index-1);
296 }
297 
299 {
300  int index = m_alt_class_list.GetCurSel();
301  int inext = index + 1;
302 
303  // Nothing selected or already at the bottom
304  if (index == -1 || (index >= m_alt_class_list.GetCount() - 1) ) {
305  return;
306  }
307 
308  std::swap(alt_class_pool[index], alt_class_pool[inext]);
309  alt_class_list_rebuild();
310  m_alt_class_list.SetCurSel(index);
311 }
312 
314 {
315  int current_selection;
316 
317  if (m_set_from_ship_class.GetCurSel() == 0 && num_string_variables) {
318  m_set_from_variables.SetCurSel(1);
319  }
320  else {
321  m_set_from_variables.SetCurSel(0);
322  }
323 
324  // if a list entry is selected we should update it
325  current_selection = m_alt_class_list.GetCurSel();
326  if (current_selection >= 0) {
327  alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
328  alt_class_list_rebuild();
329  }
330 }
331 
333 {
334  int current_selection;
335 
336  if (m_set_from_variables.GetCurSel() == 0) {
337  m_set_from_ship_class.SetCurSel(num_string_variables ? 1 : 0);
338  }
339  else {
340  m_set_from_ship_class.SetCurSel(0);
341  }
342 
343  // if a list entry is selected we should update it
344  current_selection = m_alt_class_list.GetCurSel();
345  if (current_selection >= 0) {
346  alt_class_update_entry(alt_class_pool[m_alt_class_list.GetCurSel()]);
347  alt_class_list_rebuild();
348  }
349 }
350 
352 {
353  int i;
354  int variable_selection = 0;
355  int ship_selection = 0;
356  int index = m_alt_class_list.GetCurSel();
357 
358  // Selected nothing
359  if (index == -1) {
360  return;
361  }
362 
363  // If we have a variable selected
364  if (alt_class_pool[index].variable_index != -1) {
365  for (i=0; i < MAX_SEXP_VARIABLES; i++)
366  {
367  if (string_variable_indices[i] == alt_class_pool[index].variable_index) {
368  variable_selection = i+1;
369  break;
370  }
371  }
372  }
373  // Ship selected
374  else {
375  for (i=0; i < MAX_SHIP_CLASSES; i++) {
376  if (ship_class_indices[i] == alt_class_pool[index].ship_class) {
377  ship_selection = i;
378  break;
379  }
380  }
381 
382  // if we have string variables in the mission the first entry on the list won't be a ship
383  if (num_string_variables) {
384  ship_selection++;
385  }
386  }
387 
388  m_set_from_variables.SetCurSel(variable_selection);
389  m_set_from_ship_class.SetCurSel(ship_selection);
390  m_default_to_class.SetCheck(alt_class_pool[index].default_to_this_class ? 1:0);
391 }
392 
394 {
395  int index = m_alt_class_list.GetCurSel();
396 
397  // Nothing selected
398  if (index == -1) {
399  return;
400  }
401 
402  alt_class_pool[index].default_to_this_class = m_default_to_class.GetCheck() ? true:false;
403 }
404 
405 
406 
int ship_info_lookup(const char *token)
Definition: ship.cpp:12772
int i
Definition: multi_pxo.cpp:466
#define SIF_PLAYER_SHIP
Definition: ship.h:875
#define IDC_ALT_CLASS_LIST
Definition: resource.h:599
GLuint index
Definition: Glext.h:5608
#define IDC_ALT_CLASS_INSERT
Definition: resource.h:1142
Assert(pm!=NULL)
afx_msg void OnSelchangeAltClassList()
#define TRUE
Definition: pstypes.h:399
object obj_used_list
Definition: object.cpp:53
sexp_variable Sexp_variables[MAX_SEXP_VARIABLES]
Definition: sexp.cpp:846
bool default_to_this_class
Definition: missionparse.h:335
object * objp
Definition: lua.cpp:3105
#define Int3()
Definition: pstypes.h:292
afx_msg void OnDefaultToClass()
GLenum type
Definition: Gl.h:1492
afx_msg void OnAltClassInsert()
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
int instance
Definition: object.h:150
#define OBJ_START
Definition: object.h:35
SCP_vector< alt_class > s_alt_classes
Definition: ship.h:791
virtual void OnOK()
#define IDC_SET_FROM_VARIABLES
Definition: resource.h:645
#define MAX_SHIP_CLASSES
Definition: globals.h:48
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
CButton m_default_to_class
int variable_index
Definition: missionparse.h:334
CListBox m_alt_class_list
CComboBox m_set_from_variables
object Objects[MAX_OBJECTS]
Definition: object.cpp:62
#define IDC_ALT_CLASS_UP
Definition: resource.h:1140
#define OF_MARKED
Definition: object.h:125
afx_msg void OnAltClassDelete()
#define OBJ_SHIP
Definition: object.h:32
GLbitfield flags
Definition: Glext.h:6722
#define IDC_ALT_CLASS_ADD
Definition: resource.h:567
GLuint const GLchar * name
Definition: Glext.h:5608
int BOOL
Definition: config.h:80
#define TOKEN_LENGTH
Definition: globals.h:41
ship Ships[MAX_SHIPS]
Definition: ship.cpp:122
#define IDC_DEFAULT_TO_CLASS
Definition: resource.h:1139
CComboBox m_set_from_ship_class
afx_msg void OnMoveDown()
afx_msg void OnSelendokSetFromVariables()
#define IDC_ALT_CLASS_DOWN
Definition: resource.h:1141
virtual void DoDataExchange(CDataExchange *pDX)
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
afx_msg void OnMoveUp()
afx_msg void OnSelendokSetFromShipClass()
GLint GLsizei count
Definition: Gl.h:1491
int cur_object_index
Definition: management.cpp:79
int ship_class
Definition: missionparse.h:333
#define IDC_ALT_CLASS_DELETE
Definition: resource.h:572
uint flags
Definition: object.h:151
char type
Definition: object.h:146
#define FALSE
Definition: pstypes.h:400
afx_msg void OnAltClassAdd()
#define IDC_SET_FROM_SHIP_CLASS
Definition: resource.h:592
#define SEXP_VARIABLE_STRING
Definition: sexp.h:874
#define MAX_SEXP_VARIABLES
Definition: sexp.h:23
virtual void OnCancel()
AltShipClassDlg(CWnd *pParent=NULL)