1 /*
2 Copyright (C) 2004 by James Gregory
3 Part of the GalaxyHack project
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY.
9
10 See the COPYING file for more details.
11 */
12
13 #include "ForceSelect.h"
14
15 #include "Globals.h"
16 #include "RTSInlines.h"
17 #include "PreBattle.h"
18
19 #include <boost/filesystem/operations.hpp>
20 #include <boost/filesystem/exception.hpp>
21
22 namespace ForceSelect {
23
LoadSideDW()24 LoadSideDW::LoadSideDW():
25 LargeBlankDW("Edit a fleet or create a new one. Right click to copy or delete.") {}
26
~LoadSideDW()27 LoadSideDW::~LoadSideDW() {
28 if (!sides.size())
29 gsTo = GST_MainMenu;
30 }
31
LoadSideSM(int iParentID)32 LoadSideSM::LoadSideSM(int iParentID):
33 FileListMenu(iParentID) {
34 ExpensiveUpdate();
35 }
36
ExpensiveUpdate()37 void LoadSideSM::ExpensiveUpdate() {
38 ClearItems();
39
40 MenuItem tempItem;
41 tempItem.desc = "New";
42 tempItem.choice = FS_NewSide;
43 AddItem(tempItem);
44
45 AddBlankItem();
46 AddFleets(FS_LoadSide);
47
48 InitBorder();
49 }
50
SwitchOnChoice(Uint16 x,Uint16 y)51 bool LoadSideSM::SwitchOnChoice(Uint16 x, Uint16 y) {
52 if (currentSelection.choiceType == MCT_LeftCursor) {
53 switch (currentSelection.choice) {
54 case FS_NewSide:
55 myWindows.push_back(GenWindow(0, 0, FS_NewSideName, 0, 0, 0));
56 break;
57
58 case FS_LoadSide:
59 ForceSelect::LoadSide(currentSelection.desc, false);
60 closed = true;
61 break;
62 }
63 } else if (currentSelection.choiceType == MCT_RightCursor) {
64 switch (currentSelection.choice) {
65 case FS_NewSide:
66 break;
67
68 case FS_LoadSide:
69 myWindows.push_back(GenWindow(x, y, FS_LoadSidePU, currentSelection.desc, myID, 0));
70 break;
71 }
72 }
73
74 return false;
75 }
76
LoadSidePU(int ix,int iy,const string & iSideName,int iParentID)77 LoadSidePU::LoadSidePU(int ix, int iy, const string& iSideName, int iParentID):
78 PopupMenu(ix, iy, iParentID, 0), sideName(iSideName) {
79 MenuItem tempItem;
80
81 tempItem.desc = "Copy fleet: " + sideName;
82 tempItem.choice = FS_CopyFleet;
83 AddItem(tempItem);
84
85 tempItem.desc = "Delete fleet: " + sideName;
86 tempItem.choice = FS_DeleteFleet;
87 AddItem(tempItem);
88
89 InitRects();
90 }
91
SwitchOnChoice(Uint16 x,Uint16 y)92 bool LoadSidePU::SwitchOnChoice(Uint16 x, Uint16 y) {
93 if (currentSelection.choiceType == MCT_LeftCursor) {
94 switch(currentSelection.choice) {
95 case FS_CopyFleet:
96 myWindows.push_back(GenWindow(0, 0, FS_CopyFleet, sideName, parentID, 0));
97 closed = true;
98 break;
99
100 case FS_DeleteFleet:
101 myWindows.push_back(GenWindow(0, 0, FS_DeleteFleet, sideName, parentID, 0));
102 closed = true;
103 break;
104 }
105 }
106
107 return false;
108 }
109
NewSideName()110 NewSideName::NewSideName():
111 StringInputBox(maxNameLength, none_constant, 0) {
112 title = "What do you wish to call your new side?";
113
114 rect.w = 400;
115 rect.h = 100;
116
117 CentreWindow();
118
119 InitRects();
120 }
121
Keyboard(SDL_keysym & keysym)122 bool NewSideName::Keyboard(SDL_keysym& keysym) {
123 bool ret = StringInputBox::Keyboard(keysym);
124
125 if (userHitEnter) {
126 if (CheckNameValid(theInput, true)) {
127 MessageWindows(WC_YouClose, 0, 0, all_constant, myID);
128 ForceSelect::LoadSide(theInput, true);
129 }
130 }
131
132 return ret;
133 }
134
ChangeCommanderName()135 ChangeCommanderName::ChangeCommanderName():
136 StringInputBox(maxNameLength, none_constant, 0) {
137 title = "What is your name, commander?";
138
139 rect.w = 400;
140 rect.h = 100;
141
142 CentreWindow();
143
144 InitRects();
145 }
146
Keyboard(SDL_keysym & keysym)147 bool ChangeCommanderName::Keyboard(SDL_keysym& keysym) {
148 bool ret = StringInputBox::Keyboard(keysym);
149
150 if (userHitEnter) {
151 if (CheckNameValid(theInput, true)) {
152 sides[0].commander = theInput;
153 globalSettings.commander = theInput;
154 }
155 }
156
157 return ret;
158 }
159
BasePU(int ix,int iy)160 BasePU::BasePU(int ix, int iy):
161 PopupMenu(ix, iy, none_constant, 0) {
162 MenuItem tempItem;
163
164 tempItem.desc = "Edit group";
165 tempItem.choice = WC_SidePU;
166 AddItem(tempItem);
167
168 tempItem.desc = "Add new group(s)";
169 tempItem.choice = FS_AddGroups;
170 AddItem(tempItem);
171
172 tempItem.desc = "Delete group";
173 tempItem.choice = FS_DeleteGroup;
174 AddItem(tempItem);
175
176 tempItem.desc = "Starting positions";
177 tempItem.choice = FS_StartingPositions;
178 AddItem(tempItem);
179
180 AddBlankItem();
181
182 tempItem.desc = "Options";
183 tempItem.choice = Opt_StandardOptions;
184 AddItem(tempItem);
185
186 tempItem.desc = "Save and exit";
187 tempItem.choice = WC_Quit;
188 AddItem(tempItem);
189
190 tempItem.desc = "Exit without saving";
191 tempItem.choice = FS_ExitNoSave;
192 AddItem(tempItem);
193
194 InitRects();
195 }
196
SwitchOnChoice(Uint16 x,Uint16 y)197 bool BasePU::SwitchOnChoice(Uint16 x, Uint16 y) {
198 if (currentSelection.choiceType == MCT_LeftCursor) {
199 switch(currentSelection.choice) {
200 case WC_SidePU:
201 myWindows.push_back(GenWindow(WC_SidePU, 0, 0, FS_EditGroup));
202 closed = true;
203 break;
204
205 case FS_AddGroups:
206 if (sides[0].groups.size() < maxGroups) {
207 myWindows.push_back(GenWindow(0, 0, WC_LargeBlankDW, "What sort of unit will this group consist of?\nRight click to copy or delete.", 0, 0));
208 myWindows.push_back(GenWindow(100, 100 + (lineGap << 1), FS_AddGroupMenu, windowIDs, 0, 0));
209 } else
210 CreateInfoString("\n\n You cannot have more than 60 groups on a side");
211 closed = true;
212 break;
213
214 case FS_DeleteGroup:
215 myWindows.push_back(GenWindow(WC_SidePU, 0, 0, FS_DeleteGroup));
216 closed = true;
217 break;
218
219 case FS_StartingPositions:
220 PreBattle::pbState = PBS_Position;
221 gsTo = GST_PreBattle;
222 break;
223
224 case Opt_StandardOptions:
225 myWindows.push_back(GenWindow(rect.x, rect.y, Opt_StandardOptions, 0, 0, 0));
226 closed = true;
227 break;
228
229 case WC_Quit:
230 TrySaveAndExit();
231 break;
232
233 case FS_ExitNoSave:
234 myWindows.push_back(GenWindow(0, 0, FS_ExitNoSaveQ, 0, 0, 0));
235 closed = true;
236 break;
237 }
238 }
239
240 return false;
241 }
242
SideOptions(int ix,int iy,int flags)243 SideOptions::SideOptions(int ix, int iy, int flags):
244 DragWindow(0, 0, none_constant, flags) {
245 rect.w = 200;
246 rect.h = 150;
247
248 rect.x = globalSettings.screenWidth - rect.w - 10;
249 rect.y = 10;
250
251 InitBorder();
252 }
253
MouseD(Uint8 button,Uint16 x,Uint16 y)254 bool SideOptions::MouseD(Uint8 button, Uint16 x, Uint16 y) {
255 bool ret = GenWindow_Base::MouseD(button, x, y);
256
257 if (ret == true && button == SDL_BUTTON_RIGHT)
258 myWindows.push_back(GenWindow(x, y, FS_SideOptionsPU, 0, 0, 0));
259
260 return ret;
261 }
262
DrawSelf()263 void SideOptions::DrawSelf() {
264 DragWindow::DrawSelf();
265
266 int x = rect.x + smallBorderSize;
267 int y = rect.y + smallBorderSize;
268
269 char output[60];
270
271 boldFonts.BlitString(x, y, 0, sides[0].name);
272 y += lineGap << 1;
273
274 string outputStr = "Commander: " + sides[0].commander;
275 normalFonts.BlitString(x, y, 0, outputStr);
276 y += lineGap << 1;
277
278 sprintf(output, "Points value: %d", sides[0].GetPointsValue());
279 normalFonts.BlitString(x, y, 0, output);
280 }
281
SideOptionsPU(int ix,int iy)282 SideOptionsPU::SideOptionsPU(int ix, int iy):
283 PopupMenu(ix, iy, none_constant, 0) {
284 MenuItem tempItem;
285
286 tempItem.desc = "Commander name";
287 tempItem.choice = FS_Commander;
288 AddItem(tempItem);
289
290 tempItem.desc = "Change saved groups";
291 tempItem.choice = FS_ChooseGSaveGroup;
292 AddItem(tempItem);
293
294 InitRects();
295 }
296
SwitchOnChoice(Uint16 x,Uint16 y)297 bool SideOptionsPU::SwitchOnChoice(Uint16 x, Uint16 y) {
298 if (currentSelection.choiceType == MCT_LeftCursor) {
299 switch(currentSelection.choice) {
300 case FS_Commander:
301 myWindows.push_back(GenWindow(0, 0, FS_Commander, 0, 0, 0));
302 closed = true;
303 break;
304
305 case FS_ChooseGSaveGroup:
306 myWindows.push_back(GenWindow(0, 0, FS_WhichSaveGroup, 0, 1, 0));
307 closed = true;
308 break;
309 }
310 }
311
312 return false;
313 }
314
EditGroup(int ix,int iy,int iMyGroup,int flags)315 EditGroup::EditGroup(int ix, int iy, int iMyGroup, int flags):
316 DragWindow(ix, iy, none_constant, flags), myGroup(iMyGroup) {
317 rect.w = 350;
318 rect.h = 170;
319
320 InitRects();
321 }
322
MouseD(Uint8 button,Uint16 x,Uint16 y)323 bool EditGroup::MouseD(Uint8 button, Uint16 x, Uint16 y) {
324 bool ret = DragWindow::MouseD(button, x, y);
325
326 if (ret == true && button == SDL_BUTTON_RIGHT)
327 myWindows.push_back(GenWindow(x, y, FS_EditGroupPU, myGroup, 0, 0));
328
329 return ret;
330 }
331
DrawSelf()332 void EditGroup::DrawSelf() {
333 DragWindow::DrawSelf();
334
335 int x = rect.x + smallBorderSize;
336 int y = rect.y + smallBorderSize;
337
338 char output[50];
339 sprintf(output, "Group %d:", myGroup+1);
340 boldFonts.BlitString(x, y, 0, output);
341
342 y += lineGap;
343
344 string outputStr = "Unit name: " + sides[0].groups[myGroup].GetUnitName();
345 normalFonts.BlitString(x, y, 0, outputStr);
346
347 y += lineGap;
348
349 outputStr = "Unit type: " + GetFullTypeName(0, myGroup);
350 normalFonts.BlitString(x, y, 0, outputStr);
351
352 y += lineGap;
353
354 sprintf(output, "Number: %d", sides[0].groups[myGroup].GetUnitsLeft());
355 normalFonts.BlitString(x, y, 0, output);
356
357 y += lineGap;
358
359 sprintf(output, "Points value: %d", sides[0].groups[myGroup].GetPointsValue());
360 normalFonts.BlitString(x, y, 0, output);
361 y += lineGap << 1;
362
363 int groupNumber = sides[0].groups[myGroup].GetParentCaSh();
364 if (groupNumber != -1)
365 sprintf(output, "Parent capital ship: Group %d", groupNumber + 1);
366 else
367 sprintf(output, "Parent capital ship: None");
368 normalFonts.BlitString(x, y, 0, output);
369
370 y += lineGap;
371
372 sprintf(output, "AI script: %s", sides[0].groups[myGroup].GetAIFilename().c_str());
373 normalFonts.BlitString(x, y, 0, output);
374
375 y += lineGap;
376
377 if (sides[0].groups[myGroup].GetType() == UT_CaShUnit) {
378 sprintf(output, "Capacity: %d / %d", sides[0].groups[myGroup].GetHowFull(), sides[0].groups[myGroup].GetCapacity());
379 normalFonts.BlitString(x, y, 0, output);
380 }
381 }
382
WinMessage(WindowChoice theMessage,int paremOne,int paremTwo,int targetID,int sourceID)383 void EditGroup::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
384 GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);
385
386 if (targetID == all_constant || targetID == myID) {
387 switch (theMessage) {
388 //our group has been deleted
389 case FS_GroupNumChange:
390 GroupNumChange(paremOne, paremTwo, myGroup);
391 break;
392 }
393 }
394 }
395
AddGroupMenu(int iParentID)396 AddGroupMenu::AddGroupMenu(int iParentID):
397 FileListMenu(iParentID) {
398 ExpensiveUpdate();
399 }
400
ExpensiveUpdate()401 void AddGroupMenu::ExpensiveUpdate() {
402 ClearItems();
403
404 MenuItem tempItem;
405
406 tempItem.desc = "New capital ship";
407 tempItem.choice = FS_NewCaSh;
408 AddItem(tempItem);
409
410 tempItem.desc = "New frigate";
411 tempItem.choice = FS_NewFr;
412 AddItem(tempItem);
413
414 tempItem.desc = "New small ship";
415 tempItem.choice = FS_NewSmSh;
416 AddItem(tempItem);
417
418 AddBlankItem();
419
420 AddFleetFiles(0, ".dat", FS_AddGroups);
421
422 InitBorder();
423 }
424
425
SwitchOnChoice(Uint16 x,Uint16 y)426 bool AddGroupMenu::SwitchOnChoice(Uint16 x, Uint16 y) {
427 if (currentSelection.choiceType == MCT_LeftCursor) {
428 switch(currentSelection.choice) {
429 case FS_NewCaSh:
430 myWindows.push_back(GenWindow(FS_NewUnitName, UT_CaShUnit, myID));
431 break;
432
433 case FS_NewFr:
434 myWindows.push_back(GenWindow(FS_NewUnitName, UT_FrUnit, myID));
435 break;
436
437 case FS_NewSmSh:
438 myWindows.push_back(GenWindow(FS_NewUnitName, UT_SmShUnit, myID));
439 break;
440
441 case FS_AddGroups:
442 UnitType iType = RTSUnit::WhatUTIsThis(0, currentSelection.desc);
443 CreateNewGroupWins(currentSelection.desc, iType, 0);
444 closed = true;
445 break;
446 }
447 }
448 else if (currentSelection.choiceType == MCT_RightCursor) {
449 switch(currentSelection.choice) {
450 case FS_AddGroups:
451 myWindows.push_back(GenWindow(x, y, FS_AddGroupPU, currentSelection.desc, myID, 0));
452 break;
453 }
454 }
455
456 return false;
457 }
458
NewGroupParentPU(const string & iName,UnitType iType,int iNumber)459 NewGroupParentPU::NewGroupParentPU(const string& iName, UnitType iType, int iNumber):
460 SidePU(0, 0, FS_ChangeParentCap), name(iName), myType(iType), number(iNumber) {}
461
SwitchOnChoice(Uint16 x,Uint16 y)462 bool NewGroupParentPU::SwitchOnChoice(Uint16 x, Uint16 y) {
463 if (currentSelection.choiceType == MCT_LeftCursor) {
464 switch (currentSelection.choice) {
465 case FS_ChangeParentCap:
466 if (sides[mySide].groups[currentSelection.parem].GetType() == UT_CaShUnit) {
467 if (sides[mySide].groups[currentSelection.parem].GetHowFull() + number <= sides[0].groups[currentSelection.parem].GetCapacity())
468 AddGroups(name, myType, number, CST_None, currentSelection.parem);
469
470 else {
471 char output[80];
472 sprintf(output, "Cannot fit another %d groups in capital ship %d", number, currentSelection.parem + 1);
473 CreateInfoString(output);
474 }
475 }
476 break;
477 }
478 }
479
480 return false;
481 }
482
AddGroupPU(int ix,int iy,const string & iUnitName,int iParentID)483 AddGroupPU::AddGroupPU(int ix, int iy, const string& iUnitName, int iParentID):
484 PopupMenu(ix, iy, iParentID, 0), unitName(iUnitName) {
485 MenuItem tempItem;
486
487 tempItem.desc = "Copy unit: " + unitName;
488 tempItem.choice = FS_CopyUnit;
489 AddItem(tempItem);
490
491 tempItem.desc = "Delete unit: " + unitName;
492 tempItem.choice = FS_DeleteUnit;
493 AddItem(tempItem);
494
495 InitRects();
496 }
497
SwitchOnChoice(Uint16 x,Uint16 y)498 bool AddGroupPU::SwitchOnChoice(Uint16 x, Uint16 y) {
499 if (currentSelection.choiceType == MCT_LeftCursor) {
500 switch(currentSelection.choice) {
501 case FS_CopyUnit:
502 myWindows.push_back(GenWindow(WC_CopyBox, unitName, GetFleetDir(0), parentID));
503 closed = true;
504 break;
505
506 case FS_DeleteUnit:
507 myWindows.push_back(GenWindow(WC_DeleteBox, unitName, GetFleetDir(0), parentID));
508 closed = true;
509 break;
510 }
511 }
512
513 return false;
514 }
515
NewUnitName(UnitType iUnitType,int iParentID)516 NewUnitName::NewUnitName(UnitType iUnitType, int iParentID):
517 StringInputBox(maxNameLength, iParentID, 0), unitType(iUnitType) {
518 title = "What do you wish to call the new unit type?";
519
520 rect.w = 400;
521 rect.h = 100;
522
523 CentreWindow();
524
525 InitRects();
526 }
527
Keyboard(SDL_keysym & keysym)528 bool NewUnitName::Keyboard(SDL_keysym& keysym) {
529 bool ret = StringInputBox::Keyboard(keysym);
530
531 if (userHitEnter) {
532 if (CheckNameValid(theInput, true)) {
533 if (theInput == sides[0].name)
534 CreateInfoString("A unit cannot have the same name as your side");
535 else {
536 CreateNewGroupWins(theInput, unitType, 1);
537 MessageWindows(WC_YouClose, 0, 0, parentID, myID);
538 }
539 }
540 }
541
542 return ret;
543 }
544
EditGroupPU(int ix,int iy,int iMyGroup)545 EditGroupPU::EditGroupPU(int ix, int iy, int iMyGroup):
546 PopupMenu(ix, iy, none_constant, 0), myGroup(iMyGroup) {
547 MenuItem tempItem;
548
549 tempItem.desc = "Edit unit";
550 tempItem.choice = FS_EditUnit;
551 AddItem(tempItem);
552
553 tempItem.desc = "AI script";
554 tempItem.choice = FS_ChangeAIScript;
555 AddItem(tempItem);
556
557 tempItem.desc = "Change saved groups";
558 tempItem.choice = FS_ChooseSaveGroup;
559 AddItem(tempItem);
560
561 InitRects();
562 }
563
SwitchOnChoice(Uint16 x,Uint16 y)564 bool EditGroupPU::SwitchOnChoice(Uint16 x, Uint16 y) {
565 if (currentSelection.choiceType == MCT_LeftCursor) {
566 switch (currentSelection.choice) {
567 case FS_EditUnit: {
568 string unitName = sides[0].groups[myGroup].GetUnitName();
569 myWindows.push_back(GenWindow(rect.x, rect.y, FS_EditUnit, myGroup, 0, 0));
570 closed = true;
571 }
572 break;
573
574 case FS_ChangeAIScript:
575 myWindows.push_back(GenWindow(0, 0, WC_LargeBlankDW, "Choose an AI script", 0, 0));
576 myWindows.push_back(GenWindow(100, 100 + (lineGap << 1), FS_AIScriptMenu, myGroup, windowIDs, 0));
577 closed = true;
578 break;
579
580 case FS_ChooseSaveGroup:
581 myWindows.push_back(GenWindow(0, 0, FS_WhichSaveGroup, myGroup, 0, 0));
582 closed = true;
583 break;
584 }
585 }
586
587 return false;
588 }
589
SetAIScriptMenu(int iMyGroup,int iParentID)590 SetAIScriptMenu::SetAIScriptMenu(int iMyGroup, int iParentID):
591 FileListMenu(iParentID), myGroup(iMyGroup) {
592 MenuItem tempItem;
593
594 tempItem.desc = "None";
595 tempItem.choice = FS_ChangeAIScript;
596 AddItem(tempItem);
597
598 AddBlankItem();
599
600 AddFleetFiles(0, ".ai", FS_ChangeAIScript);
601
602 InitBorder();
603 }
604
SwitchOnChoice(Uint16 x,Uint16 y)605 bool SetAIScriptMenu::SwitchOnChoice(Uint16 x, Uint16 y) {
606 if (currentSelection.choiceType == MCT_LeftCursor) {
607 switch(currentSelection.choice) {
608 case FS_ChangeAIScript:
609 if (currentSelection.desc == "None")
610 currentSelection.desc = "";
611 if (sides[0].aiScripts.find(currentSelection.desc) == sides[0].aiScripts.end()) {
612 try {
613 sides[0].CreateAIScriptVec(currentSelection.desc);
614 sides[0].MakeFunctionLookupTable(currentSelection.desc);
615 } catch (runtime_error e) {
616 //FIXME we should probably delete the half-loaded script
617 ReportOnMinorError(e.what());
618 closed = true;
619 break;
620 }
621 }
622
623 if (WhichGSharesName(myGroup) != -1)
624 myWindows.push_back(GenWindow(0, 0, FS_ChangeAIScriptPU, currentSelection.desc, myGroup, 0));
625 else
626 sides[0].groups[myGroup].ChangeAIScript(currentSelection.desc);
627 closed = true;
628 break;
629 }
630 }
631
632 return false;
633 }
634
WinMessage(WindowChoice theMessage,int paremOne,int paremTwo,int targetID,int sourceID)635 void SetAIScriptMenu::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
636 GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);
637
638 if (targetID == all_constant || targetID == myID) {
639 switch (theMessage) {
640 //our group has been deleted
641 case FS_GroupNumChange:
642 GroupNumChange(paremOne, paremTwo, myGroup);
643 break;
644 }
645 }
646 }
647
SetAIScriptPU(const string & iNewScript,int iMyGroup,int iParentID)648 SetAIScriptPU::SetAIScriptPU(const string& iNewScript, int iMyGroup, int iParentID):
649 Menu_Base(0, 0, iParentID, 0), newScript(iNewScript), myGroup(iMyGroup) {
650 MenuItem tempItem;
651
652 tempItem.desc = "Change AI script for just this group or all groups with this unit type?";
653 tempItem.choice = WC_Nothing;
654 AddItem(tempItem);
655
656 tempItem.desc = "Just this one";
657 tempItem.choice = WC_Yes;
658 AddItem(tempItem);
659
660 tempItem.desc = "All";
661 tempItem.choice = WC_No;
662 AddItem(tempItem);
663
664 InitRects();
665
666 CentreWindow();
667 }
668
SwitchOnChoice(Uint16 x,Uint16 y)669 bool SetAIScriptPU::SwitchOnChoice(Uint16 x, Uint16 y) {
670 if (currentSelection.choiceType == MCT_LeftCursor) {
671 switch(currentSelection.choice) {
672 case WC_Yes:
673 sides[0].groups[myGroup].ChangeAIScript(newScript);
674 closed = true;
675 break;
676
677 case WC_No:
678 ChangeUnitAI(sides[0].groups[myGroup].GetUnitName(), newScript);
679 closed = true;
680 break;
681 }
682 }
683
684 return false;
685 }
686
WinMessage(WindowChoice theMessage,int paremOne,int paremTwo,int targetID,int sourceID)687 void SetAIScriptPU::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
688 GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);
689
690 if (targetID == all_constant || targetID == myID) {
691 switch (theMessage) {
692 //our group has been deleted
693 case FS_GroupNumChange:
694 GroupNumChange(paremOne, paremTwo, myGroup);
695 break;
696 }
697 }
698 }
699
EditUnit(int ix,int iy,int iMyGroup)700 EditUnit::EditUnit(int ix, int iy, int iMyGroup):
701 DragWindow(ix, iy, none_constant, 0), myGroup(iMyGroup), myType(sides[0].groups[iMyGroup].GetType()) {
702 switch (myType) {
703 case UT_SmShUnit:
704 case UT_FrUnit:
705 rect.w = 400;
706 rect.h = FrHeight + 400;
707 break;
708
709 case UT_CaShUnit:
710 rect.w = HCSWidth + (bigBorderSize << 1);
711 rect.h = HCSHeight + 400;
712 break;
713 }
714
715 CentreWindow();
716
717 InitRects();
718 }
719
MouseD(Uint8 button,Uint16 x,Uint16 y)720 bool EditUnit::MouseD(Uint8 button, Uint16 x, Uint16 y) {
721 bool ret = DragWindow::MouseD(button, x, y);
722
723 if (ret == true && button == SDL_BUTTON_RIGHT)
724 myWindows.push_back(GenWindow(x, y, FS_EditUnitPU, myGroup, 0, 0));
725
726 return ret;
727 }
728
DrawSelf()729 void EditUnit::DrawSelf() {
730 DragWindow::DrawSelf();
731
732 int x = rect.x + bigBorderSize;
733 int y = rect.y + smallBorderSize;
734
735 char output[50];
736
737 boldFonts.BlitString(x, y, 0, sides[0].groups[myGroup].GetUnitName());
738
739 y += lineGap;
740
741 int picAllowance;
742
743 switch(myType) {
744 case UT_CaShUnit:
745 picAllowance = HCSHeight;
746 break;
747
748 case UT_FrUnit:
749 case UT_SmShUnit:
750 picAllowance = FrHeight;
751 break;
752 }
753
754 sides[0].groups[myGroup].DrawUnitPic(x + bigBorderSize, y);
755
756 y += picAllowance + lineGap;
757
758 string outputStr = "Unit type: " + GetFullTypeName(0, myGroup);
759
760 normalFonts.BlitString(x, y, 0, outputStr);
761
762 y += lineGap << 1;
763
764 outputStr = sides[0].groups[myGroup].GetShieldName();
765 outputStr = "Shield: " + outputStr;
766 normalFonts.BlitString(x, y, 0, outputStr);
767
768 y += lineGap << 1;
769
770 outputStr = sides[0].groups[myGroup].GetArmourName();
771 outputStr = "Armour: " + outputStr;
772 normalFonts.BlitString(x, y, 0, outputStr);
773
774 y += lineGap << 1;
775
776 outputStr = sides[0].groups[myGroup].GetEngineName();
777 outputStr = "Engine: " + outputStr;
778 normalFonts.BlitString(x, y, 0, outputStr);
779
780 y += lineGap << 1;
781
782 outputStr = weaponLookup[sides[0].groups[myGroup].GetSmallType()].name;
783 outputStr = "Small weapons: " + outputStr;
784
785 if (myType != UT_SmShUnit) {
786 sprintf(output, " * %d", sides[0].groups[myGroup].GetSmallNumber());
787 outputStr+= output;
788 }
789
790 normalFonts.BlitString(x, y, 0, outputStr);
791
792 y += lineGap << 1;
793
794 outputStr = weaponLookup[sides[0].groups[myGroup].GetBigType()].name;
795 outputStr = "Big weapons: " + outputStr;
796 if (weaponLookup[sides[0].groups[myGroup].GetBigType()].category == WCAT_Torpedo)
797 outputStr += " (25% speed penalty)";
798 normalFonts.BlitString(x, y, 0, outputStr);
799 y += lineGap << 1;
800
801 if (myType == UT_CaShUnit) {
802 sprintf(output, "Capacity: %d", sides[0].groups[myGroup].GetCapacity());
803 normalFonts.BlitString(x, y, 0, output);
804 y += lineGap << 1;
805 }
806
807 if (sides[0].groups[myGroup].GetUnitMaxPoints() != infinite_constant)
808 sprintf(output, "Points value: %d / %d", sides[0].groups[myGroup].GetUnitPointsValue(), sides[0].groups[myGroup].GetUnitMaxPoints());
809 else
810 sprintf(output, "Points value: %d / infinite", sides[0].groups[myGroup].GetUnitPointsValue());
811 normalFonts.BlitString(x, y, 0, output);
812 }
813
WinMessage(WindowChoice theMessage,int paremOne,int paremTwo,int targetID,int sourceID)814 void EditUnit::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
815 GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);
816
817 if (targetID == all_constant || targetID == myID) {
818 switch (theMessage) {
819 //our group has been deleted
820 case FS_GroupNumChange:
821 if(!UnitNameSharedQ(myGroup, paremOne, paremTwo))
822 closed = true;
823 break;
824 }
825 }
826 }
827
EditUnitPU(int ix,int iy,int iMyGroup)828 EditUnitPU::EditUnitPU(int ix, int iy, int iMyGroup):
829 PopupMenu(ix, iy, none_constant, 0), myGroup(iMyGroup) {
830 MenuItem tempItem;
831
832 tempItem.desc = "Change picture";
833 tempItem.choice = FS_Picture;
834 AddItem(tempItem);
835
836 tempItem.desc = "Small weapons";
837 tempItem.choice = FS_SmallWeapons;
838 AddItem(tempItem);
839
840 if (sides[0].groups[myGroup].GetType() != UT_CaShUnit) {
841 tempItem.desc = "Big weapons";
842 tempItem.choice = FS_BigWeapons;
843 AddItem(tempItem);
844
845 tempItem.desc = "Engine";
846
847 tempItem.choice = FS_Engine;
848 AddItem(tempItem);
849
850 tempItem.desc = "Armour";
851 tempItem.choice = FS_Armour;
852 AddItem(tempItem);
853
854 tempItem.desc = "Shield";
855 tempItem.choice = FS_Shield;
856 AddItem(tempItem);
857 }
858 else {
859 tempItem.desc = "Size";
860 tempItem.choice = FS_CSType;
861 AddItem(tempItem);
862 }
863
864 InitRects();
865 }
866
867
SwitchOnChoice(Uint16 x,Uint16 y)868 bool EditUnitPU::SwitchOnChoice(Uint16 x, Uint16 y) {
869 if (currentSelection.choiceType == MCT_LeftCursor) {
870 switch(currentSelection.choice) {
871 case FS_Picture:
872 myWindows.push_back(GenWindow(0, 0, WC_LargeBlankDW, "Choose a picture", 0, 0));
873 myWindows.push_back(GenWindow(100, 100 + (lineGap << 1), FS_PictureMenu, myGroup, windowIDs, 0));
874 closed = true;
875 break;
876
877 case FS_SmallWeapons:
878 myWindows.push_back(GenWindow(200, 200, FS_WeaponsDW, myGroup, 0, 0));
879 myWindows.push_back(GenWindow(200, 200, FS_SmallWeaponsMenu, myGroup, windowIDs, 0));
880 closed = true;
881 break;
882
883 case FS_BigWeapons:
884 myWindows.push_back(GenWindow(200, 200, FS_WeaponsDW, myGroup, 1, 0));
885 myWindows.push_back(GenWindow(200, 200, FS_BigWeaponsMenu, myGroup, windowIDs, 0));
886 closed = true;
887 break;
888
889 case FS_Engine:
890 myWindows.push_back(GenWindow(200, 200, FS_EquipmentDW, myGroup, FS_Engine, 0));
891 myWindows.push_back(GenWindow(200, 200, FS_EngineMenu, myGroup, windowIDs, 0));
892 closed = true;
893 break;
894
895 case FS_Armour:
896 myWindows.push_back(GenWindow(200, 200, FS_EquipmentDW, myGroup, FS_Armour, 0));
897 myWindows.push_back(GenWindow(200, 200, FS_ArmourMenu, myGroup, windowIDs, 0));
898 closed = true;
899 break;
900
901 case FS_Shield:
902 myWindows.push_back(GenWindow(200, 200, FS_EquipmentDW, myGroup, FS_Shield, 0));
903 myWindows.push_back(GenWindow(200, 200, FS_ShieldMenu, myGroup, windowIDs, 0));
904 closed = true;
905 break;
906
907 case FS_CSType:
908 myWindows.push_back(GenWindow(200, 200, FS_CSType, myGroup, 0, 0));
909 closed = true;
910 break;
911 }
912 }
913
914 return false;
915 }
916
917 ///
918
SetUnitPicMenu(int iMyGroup,int iParentID)919 SetUnitPicMenu::SetUnitPicMenu(int iMyGroup, int iParentID):
920 FileListMenu(iParentID), myGroup(iMyGroup) {
921 MenuItem tempItem;
922
923 try {
924 UnitType uType = sides[0].groups[myGroup].GetType();
925 string dir = MakePicDirString(0, RTSUnit_Base::UTypeToPicDir(uType), false);
926 if (DoesFileExist(dir))
927 AddDirectory(dir, ".png", FS_Picture);
928 dir = MakePicDirString(0, RTSUnit_Base::UTypeToPicDir(uType), true);
929 AddDirectory(dir, ".png", FS_Picture);
930 } catch (boost::filesystem::filesystem_error e) {
931 string errorStr = "\n";
932 errorStr += e.what();
933 CreateInfoString(errorStr);
934 }
935
936 InitBorder();
937 }
938
SwitchOnChoice(Uint16 x,Uint16 y)939 bool SetUnitPicMenu::SwitchOnChoice(Uint16 x, Uint16 y) {
940 if (currentSelection.choiceType == MCT_LeftCursor)
941 closed = true;
942
943 return false;
944 }
945
MouseM(Uint8 state,Uint16 x,Uint16 y)946 bool SetUnitPicMenu::MouseM(Uint8 state, Uint16 x, Uint16 y) {
947 bool ret = Menu_Base::MouseM(state, x, y);
948
949 if (currentSelection.choiceType == MCT_Highlight) {
950 switch (currentSelection.choice) {
951 case FS_Picture:
952 string newPic = RTSUnit_Base::UTypeToPicDir(sides[0].groups[myGroup].GetType()) + currentSelection.desc + ".png";
953 string oldPic = sides[0].groups[myGroup].GetRealPictureName();
954
955 if (oldPic != newPic)
956 ChangeUnitPic(sides[0].groups[myGroup].GetUnitName(), newPic);
957 break;
958 }
959 }
960
961 return ret;
962 }
963
WinMessage(WindowChoice theMessage,int paremOne,int paremTwo,int targetID,int sourceID)964 void SetUnitPicMenu::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
965 GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);
966
967 if (targetID == all_constant || targetID == myID) {
968 switch (theMessage) {
969 //our group has been deleted
970 case FS_GroupNumChange:
971 if(!UnitNameSharedQ(myGroup, paremOne, paremTwo))
972 closed = true;
973 break;
974 }
975 }
976 }
977
978 ////
979
WeapEquipMenu_Base(int ix,int iy,int iMyGroup,int iParentID)980 WeapEquipMenu_Base::WeapEquipMenu_Base(int ix, int iy, int iMyGroup, int iParentID):
981 Menu_Base(ix, iy, iParentID, 0), myGroup(iMyGroup) {}
982
~WeapEquipMenu_Base()983 WeapEquipMenu_Base::~WeapEquipMenu_Base() {
984 MessageWindows(WC_YouClose, 0, 0, parentID, myID);
985 }
986
WinMessage(WindowChoice theMessage,int paremOne,int paremTwo,int targetID,int sourceID)987 void WeapEquipMenu_Base::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
988 GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);
989
990 if (targetID == all_constant || targetID == myID) {
991 switch (theMessage) {
992 //our group has been deleted
993 case FS_GroupNumChange:
994 if(!UnitNameSharedQ(myGroup, paremOne, paremTwo))
995 closed = true;
996 break;
997 }
998 }
999 }
1000
InitEquipMenu(WindowChoice first,WindowChoice last)1001 void WeapEquipMenu_Base::InitEquipMenu(WindowChoice first, WindowChoice last) {
1002 MenuItem tempItem;
1003
1004 for (WindowChoice i = first; i != last + 1; i = static_cast<WindowChoice>(i + 1)) {
1005 tempItem.desc = WCToETLookup[i];
1006 tempItem.choice = equipLookup[tempItem.desc].FSEC;
1007 AddItem(tempItem);
1008 }
1009
1010 InitRects();
1011 }
1012
SharedSwitchOnChoice(void (* ChangeUnitFunction)(const string &,const string &))1013 bool WeapEquipMenu_Base::SharedSwitchOnChoice(void (*ChangeUnitFunction)(const string&, const string&)) {
1014 if (currentSelection.choiceType == MCT_LeftCursor) {
1015 try {
1016 ChangeUnitFunction(sides[0].groups[myGroup].GetUnitName(), currentSelection.desc);
1017 } catch (MinorError e) {
1018 CreateInfoString(e.what());
1019 }
1020 closed = true;
1021 }
1022
1023 return false;
1024 }
1025
MouseM(Uint8 state,Uint16 x,Uint16 y)1026 bool WeapEquipMenu_Base::MouseM(Uint8 state, Uint16 x, Uint16 y) {
1027 bool ret = Menu_Base::MouseM(state, x, y);
1028
1029 if (currentSelection.choiceType == MCT_Highlight)
1030 MessageWindows(currentSelection.choice, 0, 0, parentID, myID);
1031
1032 return ret;
1033 }
1034
WeaponsDW(int ix,int iy,int iMyGroup,int bBig)1035 WeaponsDW::WeaponsDW(int ix, int iy, int iMyGroup, int bBig):
1036 DragWindow(ix, iy, none_constant, 0) {
1037 rect.w = 450;
1038 rect.h = 200;
1039
1040 if (bBig)
1041 weaponChoice = sides[0].groups[iMyGroup].GetBigType();
1042 else
1043 weaponChoice = sides[0].groups[iMyGroup].GetSmallType();
1044
1045 InitRects();
1046 }
1047
DrawSelf()1048 void WeaponsDW::DrawSelf() {
1049 DragWindow::DrawSelf();
1050
1051 int x = rect.x + 190;
1052 int y = rect.y;
1053
1054 char output[50];
1055
1056 sprintf(output, "Name: %s", (weaponLookup[weaponChoice].name).c_str());
1057 boldFonts.BlitString(x, y, 0, output);
1058
1059 y += lineGap;
1060
1061 sprintf(output, "Power: %d", weaponLookup[weaponChoice].power);
1062 normalFonts.BlitString(x, y, 0, output);
1063
1064 y += lineGap;
1065
1066 sprintf(output, "Range: %d", weaponLookup[weaponChoice].range);
1067 normalFonts.BlitString(x, y, 0, output);
1068
1069 y += lineGap;
1070
1071 sprintf(output, "Base accuracy: %d %%", weaponLookup[weaponChoice].accuracy);
1072 normalFonts.BlitString(x, y, 0, output);
1073
1074 y += lineGap;
1075
1076 sprintf(output, "Reload: %d ms", weaponLookup[weaponChoice].reload);
1077 normalFonts.BlitString(x, y, 0, output);
1078
1079 y += lineGap;
1080
1081 int startAmmo = weaponLookup[weaponChoice].startAmmo;
1082
1083 if (startAmmo != 100)
1084 sprintf(output, "Ammo: %d", weaponLookup[weaponChoice].startAmmo);
1085 else
1086 sprintf(output, "Ammo: Infinite");
1087
1088 normalFonts.BlitString(x, y, 0, output);
1089
1090 y += lineGap << 1;
1091
1092 sprintf(output, "Points: %d", weaponLookup[weaponChoice].points);
1093 normalFonts.BlitString(x, y, 0, output);
1094 }
1095
WinMessage(WindowChoice theMessage,int paremOne,int paremTwo,int targetID,int sourceID)1096 void WeaponsDW::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
1097 //group deletion should be handled by child menu
1098
1099 GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);
1100
1101 if (targetID == all_constant || targetID == myID) {
1102 if (theMessage >= FS_WT_None - 1 && theMessage <= FS_WT_Torpedo3)
1103 weaponChoice = WCToWTLookup[theMessage];
1104 }
1105 }
1106
1107
SmallWeaponsMenu(int ix,int iy,int iMyGroup,int iParentID)1108 SmallWeaponsMenu::SmallWeaponsMenu(int ix, int iy, int iMyGroup, int iParentID):
1109 WeapEquipMenu_Base(ix, iy, iMyGroup, iParentID) {
1110 MenuItem tempItem;
1111
1112 tempItem.desc = weaponLookup[WT_None].name;
1113 tempItem.choice = FS_WT_None;
1114 AddItem(tempItem);
1115
1116 for (WeaponType i = WT_Twin1; i != WT_Twin3 + 1; i = static_cast<WeaponType>(i + 1)) {
1117 tempItem.desc = weaponLookup[i].name;
1118 tempItem.choice = weaponLookup[i].FSWC;
1119 AddItem(tempItem);
1120 }
1121
1122 if (sides[0].groups[myGroup].GetType() != UT_SmShUnit) {
1123 AddBlankItem();
1124
1125 for (WeaponType i = WT_BSSmall1; i != WT_BSSmall3 + 1; i = static_cast<WeaponType>(i + 1)) {
1126 tempItem.desc = weaponLookup[i].name;
1127 tempItem.choice = weaponLookup[i].FSWC;
1128 AddItem(tempItem);
1129 }
1130 }
1131
1132 InitRects();
1133 }
1134
SwitchOnChoice(Uint16 x,Uint16 y)1135 bool SmallWeaponsMenu::SwitchOnChoice(Uint16 x, Uint16 y) {
1136 return SharedSwitchOnChoice(ChangeUnitSmallWeapons);
1137 }
1138
BigWeaponsMenu(int ix,int iy,int iMyGroup,int iParentID)1139 BigWeaponsMenu::BigWeaponsMenu(int ix, int iy, int iMyGroup, int iParentID):
1140 WeapEquipMenu_Base(ix, iy, iMyGroup, iParentID) {
1141 MenuItem tempItem;
1142
1143 tempItem.desc = weaponLookup[WT_None].name;
1144 tempItem.choice = weaponLookup[WT_None].FSWC;
1145 AddItem(tempItem);
1146
1147 WeaponType first;
1148 WeaponType last;
1149
1150 if (sides[0].groups[myGroup].GetType() == UT_SmShUnit) {
1151 first = WT_Missile1;
1152 last = WT_Torpedo3;
1153 } else {
1154 first = WT_BSLarge1;
1155 last = WT_BSLarge3;
1156 }
1157
1158 for (WeaponType i = first; i != last + 1; i = static_cast<WeaponType>(i + 1)) {
1159 tempItem.desc = weaponLookup[i].name;
1160 tempItem.choice = weaponLookup[i].FSWC;
1161 AddItem(tempItem);
1162 }
1163
1164 InitRects();
1165 }
1166
SwitchOnChoice(Uint16 x,Uint16 y)1167 bool BigWeaponsMenu::SwitchOnChoice(Uint16 x, Uint16 y) {
1168 return SharedSwitchOnChoice(ChangeUnitBigWeapons);
1169 }
1170
1171 ///
1172
EquipmentDW(int ix,int iy,int iMyGroup,int equipType)1173 EquipmentDW::EquipmentDW(int ix, int iy, int iMyGroup, int equipType):
1174 DragWindow(ix, iy, none_constant, 0) {
1175 rect.w = 450;
1176 rect.h = 200;
1177
1178 switch (static_cast<WindowChoice>(equipType)) {
1179 case FS_Engine:
1180 equipChoice = sides[0].groups[iMyGroup].GetEngineName();
1181 break;
1182 case FS_Armour:
1183 equipChoice = sides[0].groups[iMyGroup].GetArmourName();
1184 break;
1185 case FS_Shield:
1186 equipChoice = sides[0].groups[iMyGroup].GetShieldName();
1187 break;
1188 }
1189
1190 InitRects();
1191 }
1192
DrawSelf()1193 void EquipmentDW::DrawSelf() {
1194 DragWindow::DrawSelf();
1195
1196 int x = rect.x + 190;
1197 int y = rect.y;
1198
1199 char output[50];
1200
1201 string outputStr = "Name: " + equipChoice;
1202 boldFonts.BlitString(x, y, 0, outputStr);
1203
1204 y += lineGap;
1205
1206 sprintf(output, "Max: %d", equipLookup[equipChoice].max);
1207 normalFonts.BlitString(x, y, 0, output);
1208
1209 y += lineGap;
1210
1211 if (equipLookup[equipChoice].category == EQCAT_SSShield || equipLookup[equipChoice].category == EQCAT_FrShield) {
1212 sprintf(output, "Recharge interval: %d ms", equipLookup[equipChoice].recharge);
1213 normalFonts.BlitString(x, y, 0, output);
1214
1215 y += lineGap;
1216 }
1217
1218 y += lineGap;
1219
1220 sprintf(output, "Points: %d", equipLookup[equipChoice].points);
1221 normalFonts.BlitString(x, y, 0, output);
1222 }
1223
WinMessage(WindowChoice theMessage,int paremOne,int paremTwo,int targetID,int sourceID)1224 void EquipmentDW::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
1225 //group deletion should be handled by child menu
1226
1227 GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);
1228
1229 if (targetID == all_constant || targetID == myID) {
1230 if (theMessage >= FS_ET_None - 1 && theMessage <= FS_ET_FrShield3)
1231 equipChoice = WCToETLookup[theMessage];
1232 }
1233 }
1234
EngineMenu(int ix,int iy,int iMyGroup,int iParentID)1235 EngineMenu::EngineMenu(int ix, int iy, int iMyGroup, int iParentID):
1236 WeapEquipMenu_Base(ix, iy, iMyGroup, iParentID) {
1237 if (sides[0].groups[myGroup].GetType() == UT_SmShUnit)
1238 InitEquipMenu(FS_ET_SSEngine1, FS_ET_SSEngine3);
1239 else
1240 InitEquipMenu(FS_ET_FrEngine1, FS_ET_FrEngine3);
1241 }
1242
SwitchOnChoice(Uint16 x,Uint16 y)1243 bool EngineMenu::SwitchOnChoice(Uint16 x, Uint16 y) {
1244 return SharedSwitchOnChoice(ChangeUnitEngine);
1245 }
1246
ArmourMenu(int ix,int iy,int iMyGroup,int iParentID)1247 ArmourMenu::ArmourMenu(int ix, int iy, int iMyGroup, int iParentID):
1248 WeapEquipMenu_Base(ix, iy, iMyGroup, iParentID) {
1249 if (sides[0].groups[myGroup].GetType() == UT_SmShUnit)
1250 InitEquipMenu(FS_ET_SSArmour1, FS_ET_SSArmour3);
1251 else
1252 InitEquipMenu(FS_ET_FrArmour1, FS_ET_FrArmour3);
1253 }
1254
SwitchOnChoice(Uint16 x,Uint16 y)1255 bool ArmourMenu::SwitchOnChoice(Uint16 x, Uint16 y) {
1256 return SharedSwitchOnChoice(ChangeUnitArmour);
1257 }
1258
ShieldMenu(int ix,int iy,int iMyGroup,int iParentID)1259 ShieldMenu::ShieldMenu(int ix, int iy, int iMyGroup, int iParentID):
1260 WeapEquipMenu_Base(ix, iy, iMyGroup, iParentID) {
1261 MenuItem tempItem;
1262
1263 tempItem.desc = weaponLookup[WT_None].name;
1264 tempItem.choice = weaponLookup[WT_None].FSWC;
1265 AddItem(tempItem);
1266
1267 if (sides[0].groups[myGroup].GetType() == UT_SmShUnit)
1268 InitEquipMenu(FS_ET_SSShield1, FS_ET_SSShield3);
1269 else
1270 InitEquipMenu(FS_ET_FrShield1, FS_ET_FrShield3);
1271 }
1272
SwitchOnChoice(Uint16 x,Uint16 y)1273 bool ShieldMenu::SwitchOnChoice(Uint16 x, Uint16 y) {
1274 return SharedSwitchOnChoice(ChangeUnitShield);
1275 }
1276
1277
1278 ////
1279
CSTypeMenu(int ix,int iy,int iMyGroup)1280 CSTypeMenu::CSTypeMenu(int ix, int iy, int iMyGroup):
1281 Menu_Base(ix, iy, none_constant, 0), myGroup(iMyGroup) {
1282 MenuItem tempItem;
1283 tempItem.rect.h = lineGap << 1;
1284
1285 tempItem.desc = "New capital ship type?";
1286 tempItem.choice = WC_Nothing;
1287 AddItem(tempItem);
1288
1289 tempItem.rect.h = lineGap;
1290
1291 tempItem.desc = "Heavy";
1292 tempItem.choice = FS_HCS;
1293 AddItem(tempItem);
1294
1295 tempItem.desc = "Medium";
1296 tempItem.choice = FS_MCS;
1297 AddItem(tempItem);
1298
1299 tempItem.desc = "Light";
1300 tempItem.choice = FS_LCS;
1301 AddItem(tempItem);
1302
1303 InitRects();
1304 }
1305
SwitchOnChoice(Uint16 x,Uint16 y)1306 bool CSTypeMenu::SwitchOnChoice(Uint16 x, Uint16 y) {
1307 if (currentSelection.choiceType == MCT_LeftCursor) {
1308 switch (currentSelection.choice) {
1309 case FS_HCS:
1310 ChangeUnitCSType(sides[0].groups[myGroup].GetUnitName(), CST_Heavy);
1311 closed = true;
1312 break;
1313 case FS_MCS:
1314 ChangeUnitCSType(sides[0].groups[myGroup].GetUnitName(), CST_Medium);
1315 closed = true;
1316 break;
1317 case FS_LCS:
1318 ChangeUnitCSType(sides[0].groups[myGroup].GetUnitName(), CST_Light);
1319 closed = true;
1320 break;
1321 }
1322
1323 //check that no capital ships are now overly full
1324 for (int i = 0; i != sides[0].groups.size(); ++i) {
1325 if (sides[0].groups[i].GetType() == UT_CaShUnit && sides[0].groups[i].GetHowFull() > sides[0].groups[i].GetCapacity()) {
1326 char output[80];
1327 sprintf(output, "Capital ship %d now contains too many small ship groups", i + 1);
1328 CreateInfoString(output);
1329 }
1330 }
1331 }
1332
1333 //don't let other windows get input until we have got a response
1334 return true;
1335 }
1336
ForceExitQ(const string & error)1337 ForceExitQ::ForceExitQ(const string& error):
1338 Menu_Base(0, 0, none_constant, 0) {
1339 MenuItem tempItem;
1340 tempItem.rect.h = lineGap * 5;
1341
1342 tempItem.desc = "Error saving side:\n" + error + "\n\n" +
1343 "Force exit without save?" + '\n';
1344 tempItem.choice = WC_Nothing;
1345 AddItem(tempItem);
1346
1347 tempItem.rect.h = lineGap;
1348
1349 tempItem.desc = "Yes";
1350 tempItem.choice = WC_Yes;
1351 AddItem(tempItem);
1352
1353 tempItem.desc = "No";
1354 tempItem.choice = WC_No;
1355 AddItem(tempItem);
1356
1357 InitRects();
1358 CentreWindow();
1359 }
1360
1361
SwitchOnChoice(Uint16 x,Uint16 y)1362 bool ForceExitQ::SwitchOnChoice(Uint16 x, Uint16 y) {
1363 if (currentSelection.choiceType == MCT_LeftCursor) {
1364 switch(currentSelection.choice) {
1365 case WC_Yes:
1366 gsTo = GST_MainMenu;
1367 break;
1368
1369 case WC_No:
1370 closed = true;
1371 break;
1372 }
1373 }
1374
1375 return false;
1376 }
1377
ExitNoSaveQ()1378 ExitNoSaveQ::ExitNoSaveQ():
1379 Menu_Base(0, 0, none_constant, 0) {
1380 MenuItem tempItem;
1381 tempItem.rect.h = lineGap * 2;
1382
1383 tempItem.desc = "Exit without saving changes?\n";
1384 tempItem.choice = WC_Nothing;
1385 AddItem(tempItem);
1386
1387 tempItem.rect.h = lineGap;
1388
1389 tempItem.desc = "Yes";
1390 tempItem.choice = WC_Yes;
1391 AddItem(tempItem);
1392
1393 tempItem.desc = "No";
1394 tempItem.choice = WC_No;
1395 AddItem(tempItem);
1396
1397 InitRects();
1398 CentreWindow();
1399 }
1400
1401
SwitchOnChoice(Uint16 x,Uint16 y)1402 bool ExitNoSaveQ::SwitchOnChoice(Uint16 x, Uint16 y) {
1403 if (currentSelection.choiceType == MCT_LeftCursor) {
1404 switch(currentSelection.choice) {
1405 case WC_Yes:
1406 gsTo = GST_MainMenu;
1407 break;
1408
1409 case WC_No:
1410 closed = true;
1411 break;
1412 }
1413 }
1414
1415 return false;
1416 }
1417
NewGroupChoicesOK(int ix,int iy,const string & iName,UnitType iMyType,int iIDOne,int iIDTwo,int iParentID)1418 NewGroupChoicesOK::NewGroupChoicesOK(int ix, int iy, const string& iName, UnitType iMyType, int iIDOne, int iIDTwo, int iParentID):
1419 Menu_Base(ix, iy, iParentID, 0), name(iName), myType(iMyType), sliderOneID(iIDOne), sliderTwoID(iIDTwo) {
1420 MenuItem tempItem;
1421 tempItem.desc = "OK";
1422 tempItem.choice = WC_Yes;
1423 AddItem(tempItem);
1424
1425 InitRects();
1426 }
1427
SwitchOnChoice(Uint16 x,Uint16 y)1428 bool NewGroupChoicesOK::SwitchOnChoice(Uint16 x, Uint16 y) {
1429 if (currentSelection.choiceType == MCT_LeftCursor) {
1430 switch (currentSelection.choice) {
1431 case WC_Yes: {
1432 int number;
1433
1434 if (sliderOneID != none_constant) {
1435 Slider* sliderOne = dynamic_cast<Slider*>(LocateWindow(sliderOneID));
1436 number = sliderOne->GetSliderVar();
1437 } else
1438 number = 1;
1439
1440 switch (myType) {
1441 case UT_CaShUnit: {
1442 int sliderTwoVar = 0;
1443
1444 if (sliderTwoID != none_constant) {
1445 Slider* sliderTwo = dynamic_cast<Slider*>(LocateWindow(sliderTwoID));
1446 sliderTwoVar = sliderTwo->GetSliderVar();
1447 }
1448
1449 CapShipType csType = static_cast<CapShipType>(sliderTwoVar);
1450 AddGroups(name, myType, number, csType, -1);
1451 }
1452 break;
1453 case UT_FrUnit:
1454 AddGroups(name, myType, number, CST_None, -1);
1455 break;
1456 case UT_SmShUnit:
1457 myWindows.push_back(GenWindow(0, 0, FS_NewGroupParentPU, name, myType, number, 0, 0));
1458 break;
1459 }
1460
1461 MessageWindows(WC_YouClose, 0, 0, parentID, myID);
1462 closed = true;
1463 }
1464 break;
1465 }
1466 }
1467
1468 return false;
1469 }
1470
CapShipTypeSlider(int ix,int iy,int iParentID,int flags)1471 CapShipTypeSlider::CapShipTypeSlider(int ix, int iy, int iParentID, int flags):
1472 Slider(ix, iy, static_cast<int>(CST_Medium), static_cast<int>(CST_Light), static_cast<int>(CST_Heavy), iParentID, flags) {}
1473
DrawSelf()1474 void CapShipTypeSlider::DrawSelf() {
1475 Slider::DrawSelf();
1476
1477 CapShipType currentType = static_cast<CapShipType>(sliderVar);
1478 string typeStr = csTypeToString[currentType];
1479 typeStr = typeStr.substr(0, typeStr.find(' '));
1480
1481 //in text
1482 int x = rect.x + smallBorderSize;
1483 int y = rect.y + smallBorderSize;
1484 string output = "Capital ship type: " + typeStr;
1485 normalFonts.BlitString(x, y, 0, output);
1486 }
1487
WhichSaveGroup(int iMyGroup,bool globalVar)1488 WhichSaveGroup::WhichSaveGroup(int iMyGroup, bool globalVar):
1489 PopupMenu(0, 0, none_constant, 0), myGroup(iMyGroup) {
1490 MenuItem tempItem;
1491
1492 for (int i = 0; i != nAIVars; ++i) {
1493 char whichStr[60];
1494
1495 if (globalVar) {
1496 sprintf(whichStr, "$globalg%d: myside-%d", i, sides[0].saveGroups[i].y + 1);
1497 tempItem.choice = FS_ChooseGSaveGroup;
1498 } else {
1499 sprintf(whichStr, "$g%d: myside-%d", i, sides[0].groups[myGroup].GetSaveGroup(i).y + 1);
1500 tempItem.choice = FS_ChooseSaveGroup;
1501 }
1502
1503 tempItem.desc = whichStr;
1504 tempItem.parem = i;
1505 AddItem(tempItem);
1506 }
1507
1508 InitRects();
1509 CentreWindow();
1510 }
1511
SwitchOnChoice(Uint16 x,Uint16 y)1512 bool WhichSaveGroup::SwitchOnChoice(Uint16 x, Uint16 y) {
1513 if (currentSelection.choiceType == MCT_LeftCursor) {
1514 myWindows.push_back(GenWindow(WC_SidePU, 0, myGroup, currentSelection.choice, currentSelection.parem));
1515 closed = true;
1516 }
1517
1518 return false;
1519 }
1520
DeleteFleet(const string & iSideName,int iParentID)1521 DeleteFleet::DeleteFleet(const string& iSideName, int iParentID):
1522 Menu_Base(0, 0, iParentID, 0), sideName(iSideName) {
1523 MenuItem tempItem;
1524
1525 tempItem.desc = "Are you sure you wish to delete this fleet?";
1526 tempItem.choice = WC_Nothing;
1527 AddItem(tempItem);
1528
1529 tempItem.desc = "Yes";
1530 tempItem.choice = WC_Yes;
1531 AddItem(tempItem);
1532
1533 tempItem.desc = "No";
1534 tempItem.choice = WC_No;
1535 AddItem(tempItem);
1536
1537 InitRects();
1538 CentreWindow();
1539 }
1540
SwitchOnChoice(Uint16 x,Uint16 y)1541 bool DeleteFleet::SwitchOnChoice(Uint16 x, Uint16 y) {
1542 if (currentSelection.choiceType == MCT_LeftCursor) {
1543 switch (currentSelection.choice) {
1544 case WC_Yes:
1545 RemoveDirectory(globalSettings.bdp + "fleets/" + sideName);
1546 MessageWindows(WC_ExpensiveUpdate, 0, 0, parentID, myID);
1547 closed = true;
1548 break;
1549
1550 case WC_No:
1551 closed = true;
1552 break;
1553 }
1554 }
1555
1556 return false;
1557 }
1558
CopyFleet(const string & iSideName,int iParentID)1559 CopyFleet::CopyFleet(const string& iSideName, int iParentID):
1560 StringInputBox(maxNameLength, iParentID, 0), sideName(iSideName) {
1561 title = "What would you like to call the copy?";
1562 rect.x = 200;
1563 rect.y = 200;
1564 rect.w = 400;
1565 rect.h = 100;
1566
1567 InitRects();
1568 }
1569
Keyboard(SDL_keysym & keysym)1570 bool CopyFleet::Keyboard(SDL_keysym& keysym) {
1571 StringInputBox::Keyboard(keysym);
1572
1573 namespace fs = boost::filesystem;
1574
1575 if (userHitEnter) {
1576 if (CheckNameValid(theInput, true)) {
1577 try {
1578 fs::path sourcePath(globalSettings.bdp + "fleets/" + sideName);
1579 fs::path destPath(globalSettings.bdp + "fleets/" + theInput);
1580 fs::create_directory(destPath);
1581 DoCopy(sourcePath, destPath);
1582 MessageWindows(WC_ExpensiveUpdate, 0, 0, parentID, myID);
1583 } catch (fs::filesystem_error e) {
1584 string errorStr = "\n";
1585 errorStr += e.what();
1586 CreateInfoString(errorStr);
1587 }
1588 }
1589 }
1590
1591 return true;
1592 }
1593
DoCopy(boost::filesystem::path sourcePath,boost::filesystem::path destPath)1594 void CopyFleet::DoCopy(boost::filesystem::path sourcePath, boost::filesystem::path destPath) {
1595 namespace fs = boost::filesystem;
1596 fs::directory_iterator directoryEnd; // default construction yields past-the-end
1597 for (fs::directory_iterator iter(sourcePath); iter != directoryEnd; ++iter) {
1598 if (is_directory(*iter)) {
1599 fs::create_directory(destPath.string() + "/" + iter->path().filename().string());
1600 DoCopy(sourcePath.string() + "/" + iter->path().filename().string(), destPath.string() + "/" + iter->path().filename().string());
1601 continue;
1602 }
1603 string destFile;
1604 if (iter->path().filename() == sideName + ".dat")
1605 destFile = theInput + ".dat";
1606 else
1607 destFile = iter->path().filename().string();
1608
1609 fs::copy_file(*iter, destPath.string() + "/" + destFile);
1610 }
1611 }
1612
1613 } //end namespace
1614