FS2_Open
Open source remastering of the Freespace 2 engine
playerstarteditor.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 #include "stdafx.h"
13 #include "FRED.h"
14 #include "FREDDoc.h"
15 #include "PlayerStartEditor.h"
16 #include "mission/missionparse.h"
17 #include "object/object.h"
18 #include "Management.h"
19 #include "weapon/weapon.h"
20 
21 #ifdef _DEBUG
22 #undef THIS_FILE
23 static char THIS_FILE[] = __FILE__;
24 #endif
25 
27 // player_start_editor dialog
28 
29 player_start_editor::player_start_editor(CWnd* pParent) : CDialog(player_start_editor::IDD, pParent)
30 {
31  //{{AFX_DATA_INIT(player_start_editor)
32  m_delay = 0;
33  m_weapon_pool = 0;
34  m_ship_pool = 0;
35  //}}AFX_DATA_INIT
36 
37  selected_team = 0;
38  autobalance = false;
39  previous_team = -1;
40  dlg_inited = 0;
41 }
42 
43 void player_start_editor::DoDataExchange(CDataExchange* pDX)
44 {
45  CDialog::DoDataExchange(pDX);
46  //{{AFX_DATA_MAP(player_start_editor)
47  DDX_Control(pDX, IDC_POOL_SPIN, m_pool_spin);
48  DDX_Control(pDX, IDC_DELAY_SPIN, m_delay_spin);
49  DDX_Control(pDX, IDC_SPIN1, m_spin1);
50  DDX_Control(pDX, IDC_SHIP_LIST, m_ship_list);
51  DDX_Control(pDX, IDC_WEAPON_LIST, m_weapon_list);
56  DDX_Control(pDX, IDC_WINGS_SHP_COUNT, m_ships_used_in_wings);
57  DDX_Control(pDX, IDC_WINGS_WPN_COUNT, m_weapons_used_in_wings);
58  DDX_Text(pDX, IDC_DELAY, m_delay);
59  DDX_Text(pDX, IDC_SHIP_POOL, m_ship_pool);
60  DDX_Text(pDX, IDC_WEAPON_POOL, m_weapon_pool);
61  //}}AFX_DATA_MAP
62 }
63 
64 BEGIN_MESSAGE_MAP(player_start_editor, CDialog)
65  //{{AFX_MSG_MAP(player_start_editor)
66  ON_WM_INITMENU()
67  ON_LBN_SELCHANGE(IDC_SHIP_LIST, OnSelchangeShipList)
68  ON_CLBN_CHKCHANGE(IDC_SHIP_LIST, OnSelchangeShipList)
69  ON_LBN_SELCHANGE(IDC_WEAPON_LIST, OnSelchangeWeaponList)
70  ON_CLBN_CHKCHANGE(IDC_SHIP_LIST, OnSelchangeWeaponList)
71  ON_EN_UPDATE(IDC_SHIP_POOL, OnUpdateShipPool)
72  ON_EN_UPDATE(IDC_WEAPON_POOL, OnUpdateWeaponPool)
73  ON_LBN_SELCHANGE(IDC_SHIP_VARIABLES_LIST, OnSelchangeShipVariablesList)
74  ON_LBN_SELCHANGE(IDC_WEAPON_VARIABLES_LIST, OnSelchangeWeaponVariablesList)
75  ON_CBN_SELCHANGE(IDC_SHIP_VARIABLES_COMBO, OnSelchangeShipVariablesCombo)
76  ON_WM_CLOSE()
77  ON_CBN_SELCHANGE(IDC_WEAPON_VARIABLES_COMBO, OnSelchangeWeaponVariablesCombo)
78  //}}AFX_MSG_MAP
79 END_MESSAGE_MAP()
80 
82 // player_start_editor message handlers
83 
84 
85 BOOL player_start_editor::OnInitDialog()
86 {
87  int i, j;
88  int idx;
89 
90  // initialize ship pool data
91  memset(static_ship_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_SHIP_CLASSES);
92  memset(dynamic_ship_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_SEXP_VARIABLES);
93  memset(static_ship_variable_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_SHIP_CLASSES);
94  memset(dynamic_ship_variable_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_SEXP_VARIABLES);
95  for(i=0; i<MAX_TVT_TEAMS; i++){
96  for(idx=0; idx<Team_data[i].num_ship_choices; idx++)
97  {
98  // do we have a variable for this entry? if we don't....
99  if (!strlen(Team_data[i].ship_list_variables[idx]))
100  {
101  // This pool is set to hold the number of ships available at an index corresponding to the Ship_info array.
102  static_ship_pool[i][Team_data[i].ship_list[idx]] = Team_data[i].ship_count[idx];
103  // This pool is set to hold whether a ship at a Ship_info index has been set by a variable (and the
104  // variables index in Sexp_variables) if it has).
105  if (strlen(Team_data[i].ship_count_variables[idx])) {
106  static_ship_variable_pool[i][Team_data[i].ship_list[idx]] = get_index_sexp_variable_name(Team_data[i].ship_count_variables[idx]);
107  }
108  else {
109  static_ship_variable_pool[i][Team_data[i].ship_list[idx]] = -1;
110  }
111  }
112  // if we do....
113  else
114  {
115  // This pool is set to hold the number of ships available at an index corresponding to the Sexp_variables array
116  dynamic_ship_pool[i][get_index_sexp_variable_name(Team_data[i].ship_list_variables[idx])] = Team_data[i].ship_count[idx];
117  // This pool is set to hold whether a ship at a Ship_info index has been set by a variable (and the
118  // variables index in Sexp_variables) if it has).
119  if (strlen(Team_data[i].ship_count_variables[idx])) {
120  dynamic_ship_variable_pool[i][get_index_sexp_variable_name(Team_data[i].ship_list_variables[idx])] = get_index_sexp_variable_name(Team_data[i].ship_count_variables[idx]);
121  }
122  else {
123  dynamic_ship_variable_pool[i][get_index_sexp_variable_name(Team_data[i].ship_list_variables[idx])] = -1;
124  }
125  }
126  }
127  }
128 
129 
130  // initialize weapon pool data
131  memset(static_weapon_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_WEAPON_TYPES);
132  memset(dynamic_weapon_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_SEXP_VARIABLES);
133  memset(static_weapon_variable_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_WEAPON_TYPES);
134  memset(dynamic_weapon_variable_pool, -1, sizeof(int) * MAX_TVT_TEAMS * MAX_SEXP_VARIABLES);
135  for(i=0; i<MAX_TVT_TEAMS; i++){
136  for(idx=0; idx<Team_data[i].num_weapon_choices; idx++)
137  {
138  // do we have a variable for this entry?
139  if (!strlen(Team_data[i].weaponry_pool_variable[idx]))
140  {
141  static_weapon_pool[i][Team_data[i].weaponry_pool[idx]] = Team_data[i].weaponry_count[idx];
142  if (strlen(Team_data[i].weaponry_amount_variable[idx])) {
143  static_weapon_variable_pool[i][Team_data[i].weaponry_pool[idx]] = get_index_sexp_variable_name(Team_data[i].weaponry_amount_variable[idx]);
144  }
145  else {
146  static_weapon_variable_pool[i][Team_data[i].weaponry_pool[idx]] = -1;
147  }
148  }
149  // if we do....
150  else
151  {
152  dynamic_weapon_pool[i][get_index_sexp_variable_name(Team_data[i].weaponry_pool_variable[idx])] = Team_data[i].weaponry_count[idx];
153  if (strlen(Team_data[i].weaponry_amount_variable[idx])) {
154  dynamic_weapon_variable_pool[i][get_index_sexp_variable_name(Team_data[i].weaponry_pool_variable[idx])] = get_index_sexp_variable_name(Team_data[i].weaponry_amount_variable[idx]);
155  }
156  else {
157  dynamic_weapon_variable_pool[i][get_index_sexp_variable_name(Team_data[i].weaponry_pool_variable[idx])] = -1;
158  }
159  }
160  }
161  }
162 
163  // initialise the ship and weapon usage list
164  memset(ship_usage, 0, sizeof(int) * MAX_TVT_TEAMS * MAX_SHIP_CLASSES);
165  memset(weapon_usage, 0, sizeof(int) * MAX_TVT_TEAMS * MAX_WEAPON_TYPES);
166 
167 
169  for (i=0; i<MAX_TVT_TEAMS; i++) {
170  for (j=0; j<MAX_TVT_WINGS_PER_TEAM; j++) {
171  generate_ship_usage_list(ship_usage[i], TVT_wings[(i*MAX_TVT_WINGS_PER_TEAM) + j]);
172  generate_weaponry_usage_list(weapon_usage[i], TVT_wings[(i*MAX_TVT_WINGS_PER_TEAM) + j]);
173  }
174  }
175  }
176  else {
177  for (i=0; i<MAX_STARTING_WINGS; i++) {
178  generate_ship_usage_list(ship_usage[0], Starting_wings[i]);
179  generate_weaponry_usage_list(weapon_usage[0], Starting_wings[i]);
180  }
181  }
182 
183  // entry delay time
184  m_delay = f2i(Entry_delay_time);
185 
186  // misc window crap
187  CDialog::OnInitDialog();
189  m_spin1.SetRange(0, 99);
190  m_pool_spin.SetRange(0, 9999);
191  m_delay_spin.SetRange(0, 30);
192 
193  // regenerate all the controls
194  reset_controls();
195 
196  dlg_inited = 1;
197 
198  return TRUE;
199 }
200 
201 // regenerate all controls
202 void player_start_editor::reset_controls()
203 {
204  int i;
205  int ct;
206  char buff[TOKEN_LENGTH + TOKEN_LENGTH + 2]; // VariableName[VariableValue]
207 
208  if (autobalance && (previous_team != -1) && (previous_team != selected_team)) {
209  // copy across all the ship stuff
210  for (i=0; i<MAX_SHIP_CLASSES; i++) {
211  static_ship_pool[selected_team][i] = static_ship_pool[previous_team][i];
212  static_ship_variable_pool[selected_team][i] = static_ship_variable_pool[previous_team][i];
213  }
214 
215  // copy across weapon stuff
216  for (i=0; i<MAX_WEAPON_TYPES; i++) {
217  static_weapon_pool[selected_team][i] = static_weapon_pool[previous_team][i];
218  static_weapon_variable_pool[selected_team][i] = static_weapon_variable_pool[previous_team][i];
219  }
220 
221  // copy across variable stuff
222  for (i=0; i<MAX_SEXP_VARIABLES; i++) {
223  dynamic_ship_pool[selected_team][i] = dynamic_ship_pool[previous_team][i];
224  dynamic_ship_variable_pool[selected_team][i] = dynamic_ship_variable_pool[previous_team][i];
225  dynamic_weapon_pool[selected_team][i] = dynamic_weapon_pool[previous_team][i];
226  dynamic_weapon_variable_pool[selected_team][i] = dynamic_weapon_variable_pool[previous_team][i];
227  }
228  }
229 
230  m_ship_variable_list.ResetContent();
231  m_ship_quantity_variable.ResetContent();
232 
233  m_weapon_variable_list.ResetContent();
234  m_weapon_quantity_variable.ResetContent();
235 
236  // Add the default entry to both variable quantity ComboBoxes
237  m_ship_quantity_variable.AddString("Don't Use Variables");
238  m_weapon_quantity_variable.AddString("Don't Use Variables");
239 
240  int current_entry = 0;
241  int num_sexp_variables = sexp_variable_count();
242  for (i=0; i < num_sexp_variables; i++)
243  {
245  {
246  sprintf(buff, "%s [%s]", Sexp_variables[i].variable_name, Sexp_variables[i].text);
247  m_ship_variable_list.AddString(buff);
248  m_weapon_variable_list.AddString(buff);
249 
250  // Now we set the checkbox for ships
251  if((dynamic_ship_pool[selected_team][i] > 0) ||
252  (dynamic_ship_variable_pool[selected_team][i] != -1))
253  {
254  m_ship_variable_list.SetCheck(current_entry, TRUE);
255  }
256  else
257  {
258  m_ship_variable_list.SetCheck(current_entry, FALSE);
259  }
260 
261  // and now for weapons
262  if((dynamic_weapon_pool[selected_team][i] > 0) ||
263  (dynamic_weapon_variable_pool[selected_team][i] != -1))
264  {
265  m_weapon_variable_list.SetCheck(current_entry, TRUE);
266  }
267  else
268  {
269  m_weapon_variable_list.SetCheck(current_entry, FALSE);
270  }
271 
272  current_entry++;
273  }
274 
275  // Since we're looping through Sexp_variables amyway we might as well fill the number variable combo boxes
277  {
278  m_ship_quantity_variable.AddString(Sexp_variables[i].variable_name);
279  m_weapon_quantity_variable.AddString(Sexp_variables[i].variable_name);
280  }
281  }
282 
283  // create a checklistbox for each "player" ship type
284  m_ship_list.ResetContent();
285  ct = 0;
286  for (auto it = Ship_info.cbegin(); it != Ship_info.cend(); ++it) {
287  if (it->flags & SIF_PLAYER_SHIP) {
288  i = std::distance(Ship_info.cbegin(), it);
289  m_ship_list.AddString(it->name);
290 
291  // if the ship currently has pool entries or was set by a variable, check it
292  if((static_ship_pool[selected_team][i] > 0) || (static_ship_variable_pool[selected_team][i] != -1)) {
293  m_ship_list.SetCheck(ct, TRUE);
294  } else {
295  m_ship_list.SetCheck(ct, FALSE);
296  }
297 
298  // next
299  ct++;
300  }
301  }
302 
303  // create a checklistbox for each weapon ship type
304  m_weapon_list.ResetContent();
305  ct = 0;
306  for (i=0; i<Num_weapon_types; i++) {
307  if (Weapon_info[i].wi_flags & WIF_PLAYER_ALLOWED) {
308  m_weapon_list.AddString(Weapon_info[i].name);
309 
310  // if the ship currently has pool entries or was set by a variable, check it
311  if((static_weapon_pool[selected_team][i] > 0) || (static_weapon_variable_pool[selected_team][i] != -1)){
312  m_weapon_list.SetCheck(ct, TRUE);
313  } else {
314  m_weapon_list.SetCheck(ct, FALSE);
315  }
316 
317  ct++;
318  } else if (static_weapon_pool[selected_team][i] > 0 || (static_weapon_variable_pool[selected_team][i] != -1)) {
319  // not sure if this should be a verbal warning or not, so I'm adding both and making it verbal for now
320  Warning(LOCATION, "Weapon '%s' in weapon pool isn't allowed on player loadout! Resetting count to 0...\n", Weapon_info[i].name);
321  static_weapon_pool[selected_team][i] = 0;
322  static_weapon_variable_pool[selected_team][i] = -1;
323  }
324  }
325 
326  // be sure that nothing is selected
327  m_ship_list.SetCurSel(-1);
328  m_ship_variable_list.SetCurSel(-1);
329  m_ship_quantity_variable.SetCurSel(-1);
330  m_weapon_list.SetCurSel(-1);
331  m_weapon_variable_list.SetCurSel(-1);
332  m_weapon_quantity_variable.SetCurSel(-1);
333 
334  UpdateData(FALSE);
335 }
336 
338 {
339  int i;
340  CMenu *m;
341 
342  // disable any items we should disable
343  m = pMenu->GetSubMenu(0);
344 
345  // uncheck all menu items
346  for (i = 0; i < Num_teams; i++ ){
347  m->CheckMenuItem(i, MF_BYPOSITION | MF_UNCHECKED);
348  }
349 
350  for ( i = Num_teams; i < MAX_TVT_TEAMS; i++ ){
351  m->EnableMenuItem(i, MF_BYPOSITION | MF_GRAYED);
352  }
353 
354  // put a check next to the currently selected item
355  m->CheckMenuItem(selected_team, MF_BYPOSITION | MF_CHECKED);
356 
357 
358  m = pMenu->GetSubMenu(1);
359  if (Num_teams > 1) {
360  m->CheckMenuItem(ID_AUTOBALANCE, autobalance ? MF_CHECKED : MF_UNCHECKED);
361  }
362  else {
363  m->EnableMenuItem(ID_AUTOBALANCE, MF_GRAYED);
364  }
365 
366  CDialog::OnInitMenu(pMenu);
367 }
368 
369 // switch between active teams
371 {
372  int id;
373 
374  // select a team
375  id = LOWORD(wParam);
376  switch(id){
377  case ID_TEAM_1:
378  previous_team = selected_team;
379  selected_team = 0;
380  reset_controls();
381  break;
382 
383  case ID_TEAM_2:
384  previous_team = selected_team;
385  selected_team = 1;
386  reset_controls();
387  break;
388 
389  case ID_AUTOBALANCE:
390  autobalance = !autobalance;
391  break;
392  }
393 
394  // low level stuff
395  return CDialog::OnCommand(wParam, lParam);
396 }
397 
398 // ship list changed
400 {
401  int selected;
402  int si_index;
403  char ship_name[255] = "";
404  char ship_usage_buff[10];
405 
406  // If the ship list is selected the variable ship list should be deselected
407  m_ship_variable_list.SetCurSel(-1);
408 
409  // determine if we've selected something
410  selected = m_ship_list.GetCurSel();
411  if (selected != -1) {
412  // lookup the ship
413  m_ship_list.GetText(selected, ship_name);
414  si_index = ship_info_lookup(ship_name);
415 
416  // if we have a valid ship type
417  if(si_index >= 0){
418  // if this item is checked
419  if(m_ship_list.GetCheck(selected)) {
420  if (static_ship_variable_pool[selected_team][si_index] == -1) {
421  if (static_ship_pool[selected_team][si_index] <= 0){
422  static_ship_pool[selected_team][si_index] = 5;
423  }
424  m_ship_pool = static_ship_pool[selected_team][si_index];
425  // Set the ship variable ComboBox to reflect that we are not using variables for this ship
426  m_ship_quantity_variable.SetCurSel(0);
427  }
428  // If the number of ships was set by a variable
429  else {
430  Assert (Sexp_variables[static_ship_variable_pool[selected_team][si_index]].type & SEXP_VARIABLE_NUMBER);
431 
432  m_ship_pool = atoi(Sexp_variables[static_ship_variable_pool[selected_team][si_index]].text);
433  int selected_variable = sexp_variable_typed_count(static_ship_variable_pool[selected_team][si_index], SEXP_VARIABLE_NUMBER);
434  m_ship_quantity_variable.SetCurSel(selected_variable + 1);
435  }
436  }
437  // otherwise zero the count
438  else {
439  static_ship_pool[selected_team][si_index] = 0;
440  static_ship_variable_pool[selected_team][si_index] = -1;
441  m_ship_pool = 0;
442  m_ship_quantity_variable.SetCurSel(0);
443  }
444 
445  // set the number used in wings
446  sprintf(ship_usage_buff, "%d", ship_usage[selected_team][si_index]);
447  m_ships_used_in_wings.SetWindowText(ship_usage_buff);
448 
449  } else {
450  Int3();
451  }
452  }
453 
454  // update stuff
455  UpdateData(FALSE);
456 }
457 
458 // ship variable list changed
460 {
461  int selection;
462 
463  // If the variable list is selected the ship list should be deselected
464  m_ship_list.SetCurSel(-1);
465 
466  //Have we selected something?
467  selection = m_ship_variable_list.GetCurSel();
468  if (selection != -1) {
469  int sexp_index = get_nth_variable_index(selection+1, SEXP_VARIABLE_STRING);
470 
471  if (sexp_index > -1) {
472  Assert(selection == sexp_variable_typed_count(sexp_index, SEXP_VARIABLE_STRING));
473 
474  // Is this item checked?
475  if (m_ship_variable_list.GetCheck(selection)) {
476  if (dynamic_ship_variable_pool[selected_team][sexp_index] == -1) {
477  if (dynamic_ship_pool[selected_team][sexp_index] <= 0) {
478  dynamic_ship_pool[selected_team][sexp_index] = 5;
479  }
480  m_ship_pool = dynamic_ship_pool[selected_team][sexp_index];
481  m_ship_quantity_variable.SetCurSel(0);
482  }
483  else {
484  Assert (Sexp_variables[dynamic_ship_variable_pool[selected_team][sexp_index]].type & SEXP_VARIABLE_NUMBER);
485  m_ship_pool = atoi(Sexp_variables[dynamic_ship_variable_pool[selected_team][sexp_index]].text);
486  int selected_variable = sexp_variable_typed_count(dynamic_ship_variable_pool[selected_team][sexp_index], SEXP_VARIABLE_NUMBER);
487  m_ship_quantity_variable.SetCurSel(selected_variable + 1);
488  }
489  }
490  // We've unselected the tickbox, reset everything
491  else {
492  dynamic_ship_pool[selected_team][sexp_index] = -1;
493  dynamic_ship_variable_pool[selected_team][sexp_index] = -1;
494  m_ship_pool = 0;
495  m_ship_quantity_variable.SetCurSel(0);
496  }
497 
498  // It might be nice to have FRED work out if any ships of the class represented by the variable are in the wings
499  // but for now just set it to zero
500  m_ships_used_in_wings.SetWindowText("0");
501  }
502  else {
503  Int3();
504  }
505 
506  }
507 
508  // update stuff
509  UpdateData(FALSE);
510 }
511 
513 {
514  // Get the new selection
515  char variable_name[TOKEN_LENGTH];
516  bool update_static_pool = false;
517  bool update_dynamic_pool = false;
518 
519  m_ship_quantity_variable.GetLBText(m_ship_quantity_variable.GetCurSel(), variable_name);
520  int sexp_index = get_index_sexp_variable_name(variable_name);
521 
522  Assert ((sexp_index > -1) || (!strcmp("Don't Use Variables", variable_name)));
523 
524  // See if the ship_list was selected
525  int ship_index = GetSelectedShipListIndex();
526  if (ship_index >= 0) {
527  static_ship_variable_pool[selected_team][ship_index] = sexp_index;
528  update_static_pool = true;
529  }
530 
531  // Maybe it's the ship_variables_list that is actually selected
532  int ship_variable_index = GetSelectedShipVariableListIndex();
533  if (ship_variable_index >= 0 ) {
534  dynamic_ship_variable_pool[selected_team][ship_variable_index] = sexp_index;
535  update_dynamic_pool = true;
536  }
537 
538  // Somethings gone wrong if they're both marked as true
539  Assert (! (update_static_pool && update_dynamic_pool));
540 
541  // Update the ship_pool
542  if (update_static_pool || update_dynamic_pool) {
543  int new_quantity = 5;
544  if (sexp_index > -1) {
545  Assert (Sexp_variables[sexp_index].type & SEXP_VARIABLE_NUMBER);
546  new_quantity = atoi(Sexp_variables[sexp_index].text);
547  }
548 
549  if (update_static_pool) {
550  static_ship_pool[selected_team][ship_index] = new_quantity;
551  }
552  else {
553  dynamic_ship_pool[selected_team][ship_variable_index] = new_quantity;
554  }
555 
556  m_ship_pool = new_quantity;
557  }
558 
559  // update stuff
560  UpdateData(FALSE);
561 }
562 
563 // weapon list changed
565 {
566  int selected;
567  int wi_index;
568  char weapon_name[255] = "";
569  char weapon_usage_buff[10];
570 
571  // If the weapon list is selected the variable weapon list shouldn't be
572  m_weapon_variable_list.SetCurSel(-1);
573 
574  // determine if we've selected something
575  selected = m_weapon_list.GetCurSel();
576  if (selected != -1) {
577  // lookup the weapon
578  m_weapon_list.GetText(selected, weapon_name);
579  wi_index = weapon_info_lookup(weapon_name);
580 
581  // if we have a valid ship type
582  if(wi_index >= 0){
583  // if this item is checked
584  if(m_weapon_list.GetCheck(selected)) {
585  if (static_weapon_variable_pool[selected_team][wi_index] == -1) {
586  if (static_weapon_pool[selected_team][wi_index] <= 0){
587  static_weapon_pool[selected_team][wi_index] = 100;
588  }
589  m_weapon_pool = static_weapon_pool[selected_team][wi_index];
590  // Set the combo reflect that we are not using variables for this weapon
591  m_weapon_quantity_variable.SetCurSel(0);
592  }
593  // If the number of ships was set by a variable
594  else {
595  Assert (Sexp_variables[static_weapon_variable_pool[selected_team][wi_index]].type & SEXP_VARIABLE_NUMBER);
596 
597  m_weapon_pool = atoi(Sexp_variables[static_weapon_variable_pool[selected_team][wi_index]].text);
598  int selected_variable = sexp_variable_typed_count(static_weapon_variable_pool[selected_team][wi_index], SEXP_VARIABLE_NUMBER);
599  m_weapon_quantity_variable.SetCurSel(selected_variable + 1);
600  }
601  }
602  // otherwise zero the count
603  else {
604  static_weapon_pool[selected_team][wi_index] = 0;
605  static_weapon_variable_pool[selected_team][wi_index] = -1;
606  m_weapon_pool = 0;
607  m_weapon_quantity_variable.SetCurSel(0);
608  }
609 
610  // set the number used in wings
611  sprintf(weapon_usage_buff, "%d", weapon_usage[selected_team][wi_index]);
612  m_weapons_used_in_wings.SetWindowText(weapon_usage_buff);
613 
614  } else {
615  Int3();
616  }
617  }
618 
619  // update stuff
620  UpdateData(FALSE);
621 }
622 
624 {
625  int selection;
626 
627  // deselect the other list
628  m_weapon_list.SetCurSel(-1);
629 
630  //Have we selected something?
631  selection = m_weapon_variable_list.GetCurSel();
632  if (selection != -1) {
633  int sexp_index = get_nth_variable_index(selection+1, SEXP_VARIABLE_STRING);
634 
635  if (sexp_index > -1) {
636  Assert(selection == sexp_variable_typed_count(sexp_index, SEXP_VARIABLE_STRING));
637 
638  // Is this item checked?
639  if (m_weapon_variable_list.GetCheck(selection)) {
640  if (dynamic_weapon_variable_pool[selected_team][sexp_index] == -1) {
641  if (dynamic_weapon_pool[selected_team][sexp_index] <= 0) {
642  dynamic_weapon_pool[selected_team][sexp_index] = 5;
643  }
644  m_weapon_pool = dynamic_weapon_pool[selected_team][sexp_index];
645  m_weapon_quantity_variable.SetCurSel(0);
646  }
647  else {
648  Assert (Sexp_variables[dynamic_weapon_variable_pool[selected_team][sexp_index]].type & SEXP_VARIABLE_NUMBER);
649  m_weapon_pool = atoi(Sexp_variables[dynamic_weapon_variable_pool[selected_team][sexp_index]].text);
650  int selected_variable = sexp_variable_typed_count(dynamic_weapon_variable_pool[selected_team][sexp_index], SEXP_VARIABLE_NUMBER);
651  m_weapon_quantity_variable.SetCurSel(selected_variable + 1);
652  }
653  }
654  // We've unselected the tickbox, reset everything
655  else {
656  dynamic_weapon_pool[selected_team][sexp_index] = -1;
657  dynamic_weapon_variable_pool[selected_team][sexp_index] = -1;
658  m_weapon_pool = 0;
659  m_weapon_quantity_variable.SetCurSel(0);
660  }
661 
662  // It might be nice to have FRED work out if any weapons of this type are in the wings
663  // but for now just set it to zero
664  m_weapons_used_in_wings.SetWindowText("0");
665  }
666  else {
667  Int3();
668  }
669  }
670 
671  // update stuff
672  UpdateData(FALSE);
673 }
674 
676 {
677  // Get the new selection
678  char variable_name[TOKEN_LENGTH];
679  bool update_static_pool = false;
680  bool update_dynamic_pool = false;
681 
682  m_weapon_quantity_variable.GetLBText(m_weapon_quantity_variable.GetCurSel(), variable_name);
683  int sexp_index = get_index_sexp_variable_name(variable_name);
684 
685  Assert ((sexp_index > -1) || (!strcmp("Don't Use Variables", variable_name)));
686 
687  // See if the weapon_list was selected
688  int weapon_index = GetSelectedWeaponListIndex();
689  if (weapon_index >= 0) {
690  static_weapon_variable_pool[selected_team][weapon_index] = sexp_index;
691  update_static_pool = true;
692  }
693 
694  // Maybe it's the weapon_variables_list that is actually selected
695  int weapon_variable_index = GetSelectedWeaponVariableListIndex();
696  if (weapon_variable_index >= 0 ) {
697  dynamic_weapon_variable_pool[selected_team][weapon_variable_index] = sexp_index;
698  update_dynamic_pool = true;
699  }
700 
701  // Somethings gone wrong if they're both marked as true
702  Assert (! (update_static_pool && update_dynamic_pool));
703 
704  // Update the weapon_pool
705  if (update_static_pool || update_dynamic_pool) {
706  int new_quantity = 100;
707  if (sexp_index > -1) {
708  Assert (Sexp_variables[sexp_index].type & SEXP_VARIABLE_NUMBER);
709  new_quantity = atoi(Sexp_variables[sexp_index].text);
710  }
711 
712  if (update_static_pool) {
713  static_weapon_pool[selected_team][weapon_index] = new_quantity;
714  }
715  else {
716  dynamic_weapon_pool[selected_team][weapon_variable_index] = new_quantity;
717  }
718 
719  m_weapon_pool = new_quantity;
720  }
721 
722  // update stuff
723  UpdateData(FALSE);
724 }
725 
726 // cancel
728 {
730  CDialog::OnCancel();
731 }
732 
733 // ok
735 {
736  int i, idx;
737  int num_choices;
738 
739  int num_sexp_variables = sexp_variable_count();
740 
741  // store player entry time delay
743 
744  // store ship pools
745  for(i=0; i<MAX_TVT_TEAMS; i++) {
746  num_choices = 0;
747  // First look through the variables list and write out anything there
748  for (idx=0; idx < num_sexp_variables; idx++) {
749  // As soon as we come across a sexp_variable we are using
750  if (dynamic_ship_pool[i][idx] != -1) {
751  Assert (Sexp_variables[idx].type & SEXP_VARIABLE_STRING);
752  int ship_class = ship_info_lookup(Sexp_variables[idx].text);
753 
754  // If the variable doesn't actually contain a valid ship class name. Warn the user and skip to the next one
755  if (ship_class < 0) {
756  char buffer[256];
757  sprintf(buffer,
758  "Sexp Variable %s holds the value %s. This is not a valid ship class. Skipping this entry",
759  Sexp_variables[idx].variable_name,
760  Sexp_variables[idx].text
761  );
762  MessageBox(buffer);
763  continue;
764  }
765 
766  /* Can we can prevent the user from having to enter all his variables again just cause he can't spull gud?
767  // If the variable doesn't actually contain a valid ship class name. Warn the user
768  if (ship_class < 0)
769  {
770  char buffer[256];
771  sprintf(buffer,
772  "Sexp Variable %s holds the value %s. This is not a valid ship class. You should change this!",
773  Sexp_variables[idx].variable_name,
774  Sexp_variables[idx].text
775  );
776  MessageBox(buffer);
777  ship_class = ship_info_lookup(default_player_ship);
778  if (ship_class < 0 ) {
779  sprintf(buffer, "No default ship is set either. Skipping variable %s!", Sexp_variables[idx].variable_name);
780  }
781  }*/
782 
783 
784  // Copy the variable to Team_data
785  if (idx != -1) {
786  Assert (idx < MAX_SEXP_VARIABLES);
787  strcpy_s(Team_data[i].ship_list_variables[num_choices], Sexp_variables[idx].variable_name);
788  }
789  else {
790  strcpy_s(Team_data[i].ship_list_variables[num_choices], "");
791  }
792  Team_data[i].ship_list[num_choices] = -1;
793 
794  // Now we need to set the number of this type available
795  if (dynamic_ship_variable_pool[i][idx] == -1) {
796  Team_data[i].ship_count[num_choices] = dynamic_ship_pool[i][idx];
797  strcpy_s(Team_data[i].ship_count_variables[num_choices], "");
798  }
799  else {
800  Assert (Sexp_variables[dynamic_ship_variable_pool[i][idx]].type & SEXP_VARIABLE_NUMBER);
801 
802  strcpy_s(Team_data[i].ship_count_variables[num_choices], Sexp_variables[dynamic_ship_variable_pool[i][idx]].variable_name);
803  Team_data[i].ship_count[num_choices] = atoi(Sexp_variables[dynamic_ship_variable_pool[i][idx]].text);
804  }
805 
806  num_choices++;
807  }
808  }
809 
810  // Now we deal with the loadout ships that are statically assigned by class
811 
812  for (idx = 0; idx < static_cast<int>(Ship_info.size()); idx++) {
813  // if we have ships here
814  if(static_ship_pool[i][idx] > 0 || static_ship_variable_pool[i][idx] > -1) {
815  Team_data[i].ship_list[num_choices] = idx;
816  strcpy_s(Team_data[i].ship_list_variables[num_choices], "");
817 
818  // Now set the number of this class available
819  if (static_ship_variable_pool[i][idx] == -1) {
820  Team_data[i].ship_count[num_choices] = static_ship_pool[i][idx];
821  strcpy_s(Team_data[i].ship_count_variables[num_choices], "");
822  }
823  else {
824  Assert (Sexp_variables[static_ship_variable_pool[i][idx]].type & SEXP_VARIABLE_NUMBER);
825 
826  strcpy_s(Team_data[i].ship_count_variables[num_choices], Sexp_variables[static_ship_variable_pool[i][idx]].variable_name);
827  Team_data[i].ship_count[num_choices] = atoi(Sexp_variables[static_ship_variable_pool[i][idx]].text);
828  }
829 
830  num_choices++;
831  }
832  }
833  Team_data[i].num_ship_choices = num_choices;
834  }
835 
836  // store weapon pools
837  for(i=0; i<MAX_TVT_TEAMS; i++){
838  num_choices = 0;
839 
840  // First look through the variables list and write out anything there
841  for (idx=0; idx < num_sexp_variables; idx++) {
842  // As soon as we come across a sexp_variable we are using
843  if (dynamic_weapon_pool[i][idx] != -1) {
844  Assert (Sexp_variables[idx].type & SEXP_VARIABLE_STRING);
845  int weapon_class = weapon_info_lookup(Sexp_variables[idx].text);
846 
847  // If the variable doesn't actually contain a valid ship class name. Warn the user and skip to the next one
848  if (weapon_class < 0)
849  {
850  char buffer[256];
851  sprintf(buffer,
852  "Sexp Variable %s holds the value %s. This is not a valid weapon class. Skipping this entry",
853  Sexp_variables[idx].variable_name,
854  Sexp_variables[idx].text
855  );
856  MessageBox(buffer);
857  continue;
858  }
859 
860  // Copy the variable to Team_data
861  strcpy_s(Team_data[i].weaponry_pool_variable[num_choices], Sexp_variables[idx].variable_name);
862  Team_data[i].weaponry_pool[num_choices] = -1;
863 
864  // Now we need to set the number of this class available
865  if (dynamic_weapon_variable_pool[i][idx] == -1)
866  {
867  Team_data[i].weaponry_count[num_choices] = dynamic_weapon_pool[i][idx];
868  strcpy_s(Team_data[i].weaponry_amount_variable[num_choices], "");
869  }
870  else
871  {
872  Assert (Sexp_variables[dynamic_weapon_variable_pool[i][idx]].type & SEXP_VARIABLE_NUMBER);
873 
874  strcpy_s(Team_data[i].weaponry_amount_variable[num_choices], Sexp_variables[dynamic_weapon_variable_pool[i][idx]].variable_name);
875  Team_data[i].weaponry_count[num_choices] = atoi(Sexp_variables[dynamic_weapon_variable_pool[i][idx]].text);
876  }
877 
878  num_choices++;
879  }
880  }
881 
882  // Now we deal with the loadout weapons that are statically assigned by class
883 
884  for(idx=0; idx<Num_weapon_types; idx++)
885  {
886  // if we have weapons here
887  if(static_weapon_pool[i][idx] > 0 || static_weapon_variable_pool[i][idx] > -1)
888  {
889  Team_data[i].weaponry_pool[num_choices] = idx;
890  strcpy_s(Team_data[i].weaponry_pool_variable[num_choices], "");
891 
892  // Now set the number of this class available
893  if (static_weapon_variable_pool[i][idx] == -1)
894  {
895  Team_data[i].weaponry_count[num_choices] = static_weapon_pool[i][idx];
896  strcpy_s(Team_data[i].weaponry_amount_variable[num_choices], "");
897  }
898  else
899  {
900  Assert (Sexp_variables[static_weapon_variable_pool[i][idx]].type & SEXP_VARIABLE_NUMBER);
901 
902  strcpy_s(Team_data[i].weaponry_amount_variable[num_choices], Sexp_variables[static_weapon_variable_pool[i][idx]].variable_name);
903  Team_data[i].weaponry_count[num_choices] = atoi(Sexp_variables[static_weapon_variable_pool[i][idx]].text);
904  }
905 
906  num_choices++;
907  }
908  }
909  Team_data[i].num_weapon_choices = num_choices;
910  }
911 
913  CDialog::OnOK();
914 }
915 
916 // Returns the ship_info index of the selected and checked ship_list item or -1 if nothing is checked or
917 // the ship is invalid
918 int player_start_editor::GetSelectedShipListIndex()
919 {
920  char name[255] = "";
921  int selected = m_ship_list.GetCurSel();
922  if((selected != -1) && m_ship_list.GetCheck(selected))
923  {
924  // lookup the ship
925  m_ship_list.GetText(m_ship_list.GetCurSel(), name);
926  int ship_index = ship_info_lookup(name);
927  return ship_index;
928  }
929  return -1;
930 }
931 
932 // Returns the weapon_info index of the selected and checked ship_list item or -1 if nothing is checked or
933 // the weapon is invalid
934 int player_start_editor::GetSelectedWeaponListIndex()
935 {
936  char name[255] = "";
937  int selected = m_weapon_list.GetCurSel();
938  if((selected != -1) && m_weapon_list.GetCheck(selected))
939  {
940  // lookup the weapon
941  m_weapon_list.GetText(m_weapon_list.GetCurSel(), name);
942  int weapon_index = weapon_info_lookup(name);
943  return weapon_index;
944  }
945  return -1;
946 }
947 
948 // Returns the Sexp_variables index of the selected and checked ship_variables_list item or -1 if nothing is checked
949 // or the ship is invalid
950 int player_start_editor::GetSelectedShipVariableListIndex()
951 {
952  // Try the ship_variables_list
953  int selected = m_ship_variable_list.GetCurSel();
954  if((selected != -1) && m_ship_variable_list.GetCheck(selected))
955  {
956  //lookup the variable
957  return get_nth_variable_index(selected+1, SEXP_VARIABLE_STRING);
958  }
959  return -1;
960 }
961 
962 // Returns the Sexp_variables index of the selected and checked weapon_variables_list item or -1 if nothing is checked
963 // or the weapon is invalid
964 int player_start_editor::GetSelectedWeaponVariableListIndex()
965 {
966  // Try the ship_variables_list
967  int selected = m_weapon_variable_list.GetCurSel();
968  if((selected != -1) && m_weapon_variable_list.GetCheck(selected))
969  {
970  return get_nth_variable_index(selected+1, SEXP_VARIABLE_STRING);
971  }
972  return -1;
973 }
974 
975 // Updates the Sexp_variable in a variable combobox to the value supplied
976 void player_start_editor::UpdateQuantityVariable(CComboBox *variable_list, int pool_value)
977 {
978  char variable_name[TOKEN_LENGTH];
979  variable_list->GetLBText(variable_list->GetCurSel(), variable_name);
980  int variable_index = get_index_sexp_variable_name(variable_name);
981  if (variable_index > -1)
982  {
983  char variable_value[TOKEN_LENGTH];
984  sprintf(variable_value, "%d", pool_value);
985  Assert (Sexp_variables[variable_index].type & SEXP_VARIABLE_NUMBER);
986  sexp_fred_modify_variable(variable_value, variable_name, variable_index, SEXP_VARIABLE_NUMBER);
987  }
988 }
989 
990 // ship pool count change
992 {
993  int si_index;
994  if (!dlg_inited){
995  return;
996  }
997 
998  UpdateData(TRUE);
999 
1000  si_index = GetSelectedShipListIndex();
1001  // Update the pool if we have a valid ship type
1002  if(si_index >= 0)
1003  {
1004  static_ship_pool[selected_team][si_index] = m_ship_pool;
1005  // If this value came from a variable we should update its value
1006  UpdateQuantityVariable(&m_ship_quantity_variable, m_ship_pool);
1007  return ;
1008  }
1009 
1010  // Maybe it's the ship_variables_list that is actually selected
1011  int sexp_index = GetSelectedShipVariableListIndex();
1012  // if we have a valid sexp_variable
1013  if(sexp_index >= 0)
1014  {
1015  dynamic_ship_pool[selected_team][sexp_index] = m_ship_pool;
1016  UpdateQuantityVariable(&m_ship_quantity_variable, m_ship_pool);
1017  }
1018 }
1019 
1020 // weapon pool count change
1022 {
1023  int wi_index;
1024 
1025  if (!dlg_inited){
1026  return;
1027  }
1028 
1029  UpdateData(TRUE);
1030 
1031  wi_index = GetSelectedWeaponListIndex();
1032  // Update the pool if we have a valid weapon type
1033  if(wi_index >= 0)
1034  {
1035  static_weapon_pool[selected_team][wi_index] = m_weapon_pool;
1036  // If this value came from a variable we should update its value
1037  UpdateQuantityVariable(&m_weapon_quantity_variable, m_weapon_pool);
1038  return ;
1039  }
1040 
1041  // Maybe it's the ship_variables_list that is actually selected
1042  int sexp_index = GetSelectedWeaponVariableListIndex();
1043  // if we have a valid sexp_variable
1044  if(sexp_index >= 0)
1045  {
1046  dynamic_weapon_pool[selected_team][sexp_index] = m_weapon_pool;
1047  UpdateQuantityVariable(&m_weapon_quantity_variable, m_weapon_pool);
1048  }
1049 }
void record_window_data(window_data *wndd, CWnd *wnd)
Definition: fred.cpp:670
int ship_info_lookup(const char *token)
Definition: ship.cpp:12772
int i
Definition: multi_pxo.cpp:466
CFREDApp theApp
Definition: fred.cpp:115
CCheckListBox m_ship_list
void generate_weaponry_usage_list(int *arr, int wing)
#define IDC_WINGS_WPN_COUNT
Definition: resource.h:758
#define ID_AUTOBALANCE
Definition: resource.h:1462
#define SIF_PLAYER_SHIP
Definition: ship.h:875
int game_type
Definition: missionparse.h:138
weapon_info Weapon_info[MAX_WEAPON_TYPES]
Definition: weapons.cpp:79
afx_msg void OnInitMenu(CMenu *pMenu)
CSpinButtonCtrl m_pool_spin
#define IDC_WEAPON_VARIABLES_COMBO
Definition: resource.h:540
int sexp_variable_typed_count(int sexp_variables_index, int variable_type)
Definition: sexp.cpp:29522
int weapon_info_lookup(const char *name=NULL)
Definition: weapons.cpp:467
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
Assert(pm!=NULL)
int init_window(window_data *wndd, CWnd *wnd, int adjust=0, int pre=0)
Definition: fred.cpp:639
afx_msg void OnSelchangeWeaponList()
#define TRUE
Definition: pstypes.h:399
void sexp_fred_modify_variable(const char *text, const char *var_name, int index, int type)
Definition: sexp.cpp:29289
UINT WPARAM wParam
Definition: msacm.h:1064
#define ID_TEAM_1
Definition: resource.h:1428
#define IDC_WINGS_SHP_COUNT
Definition: resource.h:756
sexp_variable Sexp_variables[MAX_SEXP_VARIABLES]
Definition: sexp.cpp:846
UINT WPARAM LPARAM lParam
Definition: msacm.h:1064
afx_msg void OnSelchangeShipList()
#define Int3()
Definition: pstypes.h:292
int get_index_sexp_variable_name(const char *text)
Definition: sexp.cpp:29324
player_start_editor(CWnd *pParent=NULL)
long LPARAM
Definition: config.h:101
GLenum type
Definition: Gl.h:1492
#define IDC_WEAPON_VARIABLES_LIST
Definition: resource.h:768
int ship_count[MAX_SHIP_CLASSES]
Definition: missionparse.h:535
fix Entry_delay_time
#define IDC_SPIN1
Definition: resource.h:404
#define IDC_SHIP_VARIABLES_LIST
Definition: resource.h:553
#define f2i(a)
Definition: fix.h:22
#define MAX_SHIP_CLASSES
Definition: globals.h:48
#define MAX_STARTING_WINGS
Definition: globals.h:54
#define MAX_WEAPON_TYPES
Definition: globals.h:73
int num_weapon_choices
Definition: missionparse.h:539
afx_msg void OnUpdateWeaponPool()
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
CComboBox m_ship_quantity_variable
int weaponry_pool[MAX_WEAPON_TYPES]
Definition: missionparse.h:540
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam)
#define IDC_SHIP_VARIABLES_COMBO
Definition: resource.h:533
GLuint buffer
Definition: Glext.h:5492
int Num_teams
#define ID_TEAM_2
Definition: resource.h:1429
#define IDC_WEAPON_POOL
Definition: resource.h:906
GLenum GLuint id
Definition: Glext.h:5156
#define IDC_SHIP_POOL
Definition: resource.h:715
CCheckListBox m_ship_variable_list
CCheckListBox m_weapon_list
int idx
Definition: multiui.cpp:761
#define IDC_DELAY
Definition: resource.h:870
afx_msg void OnSelchangeShipVariablesCombo()
int sexp_variable_count()
Definition: sexp.cpp:29490
afx_msg void OnSelchangeWeaponVariablesList()
int TVT_wings[MAX_TVT_WINGS]
Definition: ship.cpp:136
int Num_weapon_types
Definition: weapons.cpp:105
int Starting_wings[MAX_STARTING_WINGS]
Definition: ship.cpp:132
#define IDC_SHIP_LIST
Definition: resource.h:548
GLuint const GLchar * name
Definition: Glext.h:5608
int weaponry_count[MAX_WEAPON_TYPES]
Definition: missionparse.h:541
virtual void DoDataExchange(CDataExchange *pDX)
int BOOL
Definition: config.h:80
#define TOKEN_LENGTH
Definition: globals.h:41
#define WIF_PLAYER_ALLOWED
Definition: weapon.h:68
afx_msg void OnSelchangeShipVariablesList()
CSpinButtonCtrl m_delay_spin
SCP_vector< ship_info > Ship_info
Definition: ship.cpp:164
#define LOCATION
Definition: pstypes.h:245
int MessageBox(HWND h, const char *s1, const char *s2, int i)
CCheckListBox m_weapon_variable_list
const GLfloat * m
Definition: Glext.h:10319
#define MAX_TVT_WINGS_PER_TEAM
Definition: globals.h:58
#define MAX_TVT_TEAMS
Definition: globals.h:57
afx_msg void OnSelchangeWeaponVariablesCombo()
#define i2f(a)
Definition: fix.h:23
team_data Team_data[MAX_TVT_TEAMS]
#define SEXP_VARIABLE_NUMBER
Definition: sexp.h:873
CComboBox m_weapon_quantity_variable
int get_nth_variable_index(int nth, int variable_type)
Definition: sexp.cpp:29471
void generate_ship_usage_list(int *arr, int wing)
mission The_mission
afx_msg void OnUpdateShipPool()
#define IDC_WEAPON_LIST
Definition: resource.h:761
#define FALSE
Definition: pstypes.h:400
#define IDC_POOL_SPIN
Definition: resource.h:904
#define IDC_DELAY_SPIN
Definition: resource.h:871
CSpinButtonCtrl m_spin1
int num_ship_choices
Definition: missionparse.h:531
window_data Player_wnd_data
Definition: fred.cpp:67
#define SEXP_VARIABLE_STRING
Definition: sexp.h:874
#define MAX_SEXP_VARIABLES
Definition: sexp.h:23
int ship_list[MAX_SHIP_CLASSES]
Definition: missionparse.h:533
#define strcpy_s(...)
Definition: safe_strings.h:67
#define MISSION_TYPE_MULTI_TEAMS
Definition: missionparse.h:65