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 
14 #include "RTS.h"
15 
16 #include "Globals.h"
17 #include "Group.h"
18 #include "RTSInlines.h"
19 #include "PreBattle.h"
20 
21 namespace RTS {
22 
SideInfo(int ix,int iy,int iMySide,int flags)23 SideInfo::SideInfo(int ix, int iy, int iMySide, int flags):
24 DragWindow(ix, iy, none_constant, flags), mySide(iMySide) {
25 	borderColor = sides[mySide].color;
26 }
27 
MouseD(Uint8 button,Uint16 x,Uint16 y)28 bool SideInfo::MouseD(Uint8 button, Uint16 x, Uint16 y) {
29 	bool ret = DragWindow::MouseD(button, x, y);
30 
31 	if (ret == true && button == SDL_BUTTON_RIGHT)
32 		myWindows.push_back(GenWindow(x, y, RTS_InfoChoicePU, myID, 0, 0));
33 
34 	return ret;
35 }
36 
WinMessage(WindowChoice theMessage,int paremOne,int paremTwo,int targetID,int sourceID)37 void SideInfo::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
38 	GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);
39 	if (targetID == all_constant || targetID == myID) {
40 		switch (theMessage) {
41 		case RTS_SideStats:
42 		case RTS_SideVars:
43 		case RTS_SideSaveGroups:
44 		case RTS_SideAIDebug:
45 			myWindows.push_back(GenWindow(rect.x, rect.y, theMessage, mySide, 0, 0));
46 			closed = true;
47 			break;
48 		}
49 	}
50 }
51 
SideStatsInfo(int ix,int iy,int iMySide)52 SideStatsInfo::SideStatsInfo(int ix, int iy, int iMySide):
53 SideInfo(ix, iy, iMySide, 0) {
54 	rect.w = 210;
55 	rect.h = 130;
56 
57 	InitRects();
58 }
59 
DrawSelf()60 void SideStatsInfo::DrawSelf() {
61 	theText.clear();
62 
63 	AddSideTitle(mySide);
64 
65 	char output[32];
66 	WindowText outputStr = "Commander: " + sides[mySide].commander;
67 	theText.push_back(outputStr);
68 
69 	int numberLeft = sides[mySide].GetTotalCapShips();
70 	if (numberLeft)
71 		sprintf(output, "Capital ships left: %d", numberLeft);
72 	else
73 		sprintf(output, "Capital ships left: none");
74 	theText.push_back(WindowText(output));
75 
76 	numberLeft = sides[mySide].GetTotalUnits();
77 	if (numberLeft)
78 		sprintf(output, "Units left: %d", numberLeft);
79 	else
80 		sprintf(output, "Units left: none");
81 	theText.push_back(WindowText(output));
82 
83 	if (numberLeft)
84 		sprintf(output, "Total health left: %d", sides[mySide].GetTotalHealth());
85 	else
86 		sprintf(output, "Total health left: 0");
87 	theText.push_back(WindowText(output));
88 
89 	DragWindow::DrawSelf();
90 }
91 
92 ////
93 
GroupInfo(int ix,int iy,int iMySide,int iMyGroup,int flags)94 GroupInfo::GroupInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
95 DragWindow(ix, iy, none_constant, flags), mySide(iMySide), myGroup(iMyGroup) {
96 	borderColor = sides[mySide].color;
97 }
98 
MouseD(Uint8 button,Uint16 x,Uint16 y)99 bool GroupInfo::MouseD(Uint8 button, Uint16 x, Uint16 y) {
100 	bool ret = DragWindow::MouseD(button, x, y);
101 
102 	if (ret == true && button == SDL_BUTTON_RIGHT)
103 		myWindows.push_back(GenWindow(x, y, RTS_InfoChoicePU, myID, 1, 0));
104 
105 	return ret;
106 }
107 
WinMessage(WindowChoice theMessage,int paremOne,int paremTwo,int targetID,int sourceID)108 void GroupInfo::WinMessage(WindowChoice theMessage, int paremOne, int paremTwo, int targetID, int sourceID) {
109 	GenWindow_Base::WinMessage(theMessage, paremOne, paremTwo, targetID, sourceID);
110 
111 	if (targetID == all_constant || targetID == myID) {
112 		switch (theMessage) {
113 		case RTS_GroupStats:
114 		case RTS_GroupShieldsInfo:
115 		case RTS_GroupStatusReport:
116 		case RTS_GroupAIReport:
117 		case RTS_GroupVars:
118 		case RTS_GroupSaveGroups:
119 		case RTS_GroupTimers:
120 			myWindows.push_back(GenWindow(rect.x, rect.y, theMessage, mySide, myGroup, 0));
121 			closed = true;
122 			break;
123 		}
124 	}
125 }
126 
GroupStatsInfo(int ix,int iy,int iMySide,int iMyGroup,int flags)127 GroupStatsInfo::GroupStatsInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
128 GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
129 	rect.w = 310;
130 	rect.h = 200;
131 
132 	InitRects();
133 }
134 
DrawSelf()135 void GroupStatsInfo::DrawSelf() {
136 	theText.clear();
137 
138 	char output[48];
139 
140 	AddGroupTitle(mySide, myGroup);
141 
142 	theText.push_back(WindowText(sides[mySide].groups[myGroup].GetUnitName()));
143 
144 	int numberLeft = sides[mySide].groups[myGroup].GetUnitsLeft();
145 	string asterisks;
146 	if (numberLeft)
147 		asterisks.insert(asterisks.end(), numberLeft, '*');
148 	else
149 		asterisks = "Destroyed";
150 
151 	int health = sides[mySide].groups[myGroup].GetHealth();
152 	if (health > 0) {
153 		sprintf(output, "Total health: %d", health);
154 		theText.push_back(WindowText(output));
155 	}
156 
157 	string outputStr = "Engine: " + sides[mySide].groups[myGroup].GetEngineName();
158 	theText.push_back(WindowText(outputStr));
159 
160 	outputStr = "Shield: " + sides[mySide].groups[myGroup].GetShieldName();
161 	theText.push_back(WindowText(outputStr));
162 
163 	outputStr = "Armour: " + sides[mySide].groups[myGroup].GetArmourName();
164 	theText.push_back(WindowText(outputStr));
165 
166 	if (sides[mySide].groups[myGroup].GetType() != UT_SmShUnit) {
167 		sprintf(output, "Small weapon: %s * %d", weaponLookup[sides[mySide].groups[myGroup].GetSmallType()].name.c_str(), sides[mySide].groups[myGroup].GetSmallNumber());
168 		theText.push_back(WindowText(output));
169 	} else {
170 		outputStr = "Small weapon: " + weaponLookup[sides[mySide].groups[myGroup].GetSmallType()].name;
171 		theText.push_back(WindowText(outputStr));
172 	}
173 
174 	if (sides[mySide].groups[myGroup].GetType() == UT_SmShUnit) {
175 		sprintf(output, "Big weapon: %s * %d", weaponLookup[sides[mySide].groups[myGroup].GetBigType()].name.c_str(), sides[mySide].groups[myGroup].GetBigAmmo());
176 		theText.push_back(WindowText(output));
177 	} else {
178 		outputStr = "Big weapon: " + weaponLookup[sides[mySide].groups[myGroup].GetBigType()].name;
179 		theText.push_back(WindowText(outputStr));
180 	}
181 
182 	DragWindow::DrawSelf();
183 }
184 
GroupShieldsInfo(int ix,int iy,int iMySide,int iMyGroup,int flags)185 GroupShieldsInfo::GroupShieldsInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
186 GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
187 	rect.w = 250;
188 	rect.h = 150;
189 
190 	InitRects();
191 }
192 
DrawSelf()193 void GroupShieldsInfo::DrawSelf() {
194 	theText.clear();
195 
196 	char output[48];
197 
198 	AddGroupTitle(mySide, myGroup);
199 
200 	theText.push_back(WindowText("Shields (recharge) - Armour"));
201 
202 	int shieldC, shieldM, shieldR, armourC, armourM;
203 
204 	for (int i = 0; i != sides[mySide].groups[myGroup].GetUnitsLeft(); ++i) {
205 		sides[mySide].groups[myGroup].GetShAndAr(shieldC, shieldM, shieldR, armourC, armourM, i);
206 		sprintf(output, "Unit %d: %d/%d (%d) - %d/%d", i+1, shieldC, shieldM, shieldR, armourC, armourM);
207 		theText.push_back(WindowText(output));
208 
209 	}
210 
211 	DragWindow::DrawSelf();
212 }
213 
GroupStatusReport(int ix,int iy,int iMySide,int iMyGroup,int flags)214 GroupStatusReport::GroupStatusReport(int ix, int iy, int iMySide, int iMyGroup, int flags):
215 GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
216 	rect.w = 300;
217 	rect.h = 220;
218 
219 	InitRects();
220 }
221 
DrawSelf()222 void GroupStatusReport::DrawSelf() {
223 	theText.clear();
224 	const AICommands* pCommands = sides[mySide].groups[myGroup].GetTheCommands();
225 	char output[32];
226 
227 	AddGroupTitle(mySide, myGroup);
228 
229 	CoordsInt center = sides[mySide].groups[myGroup].GetCenter();
230 	sprintf(output, "Position: %d, %d", center.x, center.y);
231 	theText.push_back(WindowText(output));
232 
233 	CoordsFloat speeds = sides[mySide].groups[myGroup].GetSpeeds();
234 
235 	sprintf(output, "Speed x: %.2f", speeds.x);
236 	theText.push_back(WindowText(output));
237 
238 	sprintf(output, "Speed y: %.2f", speeds.y);
239 	theText.push_back(WindowText(output));
240 
241 	theText.push_back(WindowText(""));
242 
243 	theText.push_back(WindowText(MoveComToString(*pCommands)));
244 
245 	if (pCommands->moveCommand != MC_NoMove) {
246 		sprintf(output, "Distance: %d", pCommands->moveTargetDist);
247 		theText.push_back(WindowText(output));
248 	} else
249 		theText.push_back(WindowText("Distance: N/A"));
250 
251 	theText.push_back(WindowText(""));
252 
253 	theText.push_back(WindowText(FireComToString(*pCommands)));
254 
255 	if (pCommands->bFire) {
256 		sprintf(output, "Distance: %d", pCommands->fireTargetDist);
257 		theText.push_back(WindowText(output));
258 	} else
259 		theText.push_back(WindowText("Distance: N/A"));
260 
261 	DragWindow::DrawSelf();
262 }
263 
GroupAIReport(int ix,int iy,int iMySide,int iMyGroup,int flags)264 GroupAIReport::GroupAIReport(int ix, int iy, int iMySide, int iMyGroup, int flags):
265 GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
266 	rect.w = 300;
267 	rect.h = 270;
268 
269 	//it works without this but relying on uninitialised memory to be different to memset to 0 memory is rather dodge, so we have it
270 	const AICommands* pCommands = sides[mySide].groups[myGroup].GetTheCommands();
271 	string tempStr = MoveComToString(*pCommands) + '\n' + FireComToString(*pCommands);
272 	reports.push_back(tempStr);
273 	oldCommands = *pCommands;
274 
275 	InitRects();
276 }
277 
DrawSelf()278 void GroupAIReport::DrawSelf() {
279 	const AICommands* pCommands = sides[mySide].groups[myGroup].GetTheCommands();
280 
281 	theText.clear();
282 	AddGroupTitle(mySide, myGroup);
283 
284 	//remove blank line
285 	theText.erase(theText.end() - 1);
286 
287 	string tempStr = "AI script: " + sides[mySide].groups[myGroup].GetAIFilename();
288 	theText.push_back(WindowText(tempStr));
289 	theText.push_back(WindowText(""));
290 
291 	if (
292 	pCommands->bFire != oldCommands.bFire ||
293 	pCommands->fireTarget != oldCommands.fireTarget ||
294 	pCommands->moveCommand != oldCommands.moveCommand ||
295 	pCommands->bInverse != oldCommands.bInverse ||
296 	pCommands->moveTarget != oldCommands.moveTarget) {
297 		tempStr = MoveComToString(*pCommands) + '\n' + FireComToString(*pCommands);
298 		reports.push_back(tempStr);
299 		oldCommands = *pCommands;
300 
301 		if (reports.size() > maxMessageVectorSize)
302 			reports.erase(reports.begin());
303 	}
304 
305 	for (list<string>::const_iterator iter = reports.begin(); iter != reports.end(); ++iter) {
306 		theText.push_back(WindowText(*iter));
307 		//each string has a newline
308 		theText.push_back(WindowText(""));
309 	}
310 
311 	DragWindow::DrawSelf();
312 }
313 
InfoChoicePU(int ix,int iy,int iInfoWinID,int groupOptions)314 InfoChoicePU::InfoChoicePU(int ix, int iy, int iInfoWinID, int groupOptions):
315 PopupMenu(ix, iy, iInfoWinID, 0), createNew(false) {
316 	MenuItem tempItem;
317 	if (groupOptions)
318 		AddGroupOptions(tempItem);
319 	else
320 		AddSideOptions(tempItem);
321 	InitRects();
322 }
323 
InfoChoicePU(int ix,int iy,int iMySide,int iMyGroup,int groupOptions,int iParentID)324 InfoChoicePU::InfoChoicePU(int ix, int iy, int iMySide, int iMyGroup, int groupOptions, int iParentID):
325 PopupMenu(ix, iy, iParentID, 0), mySide(iMySide), myGroup(iMyGroup), createNew(true) {
326 	MenuItem tempItem;
327 
328 	if (groupOptions) {
329 		tempItem.desc = "Side info:";
330 		tempItem.choice = WC_Nothing;
331 		AddItem(tempItem);
332 		AddBlankItem();
333 	}
334 
335 	AddSideOptions(tempItem);
336 
337 	if (groupOptions) {
338 		AddBlankItem();
339 		tempItem.desc = "Group info:";
340 		tempItem.choice = WC_Nothing;
341 		AddItem(tempItem);
342 		AddBlankItem();
343 		AddGroupOptions(tempItem);
344 
345 		AddBlankItem();
346 		tempItem.desc = "Cycle group information (F4)";
347 		tempItem.choice = RTS_CycleGroupInfo;
348 		AddItem(tempItem);
349 	}
350 
351 	InitRects();
352 }
353 
AddSideOptions(MenuItem & tempItem)354 void InfoChoicePU::AddSideOptions(MenuItem& tempItem) {
355 	tempItem.desc = "Stats";
356 	tempItem.choice = RTS_SideStats;
357 	AddItem(tempItem);
358 
359 	tempItem.desc = "Global script variables";
360 	tempItem.choice = RTS_SideVars;
361 	AddItem(tempItem);
362 
363 	tempItem.desc = "Global script saved groups";
364 	tempItem.choice = RTS_SideSaveGroups;
365 	AddItem(tempItem);
366 
367 	tempItem.desc = "AI error messages";
368 	tempItem.choice = RTS_SideAIDebug;
369 	AddItem(tempItem);
370 }
371 
AddGroupOptions(MenuItem & tempItem)372 void InfoChoicePU::AddGroupOptions(MenuItem& tempItem) {
373 	tempItem.desc = "Stats";
374 	tempItem.choice = RTS_GroupStats;
375 	AddItem(tempItem);
376 
377 	tempItem.desc = "Shields/Armour";
378 	tempItem.choice = RTS_GroupShieldsInfo;
379 	AddItem(tempItem);
380 
381 	tempItem.desc = "Status report";
382 	tempItem.choice = RTS_GroupStatusReport;
383 	AddItem(tempItem);
384 
385 	tempItem.desc = "AI Report";
386 	tempItem.choice = RTS_GroupAIReport;
387 	AddItem(tempItem);
388 
389 	tempItem.desc = "Group script variables";
390 	tempItem.choice = RTS_GroupVars;
391 	AddItem(tempItem);
392 
393 	tempItem.desc = "Group script saved groups";
394 	tempItem.choice = RTS_GroupSaveGroups;
395 	AddItem(tempItem);
396 
397 	tempItem.desc = "Group script timers";
398 	tempItem.choice = RTS_GroupTimers;
399 	AddItem(tempItem);
400 }
401 
SwitchOnChoice(Uint16 x,Uint16 y)402 bool InfoChoicePU::SwitchOnChoice(Uint16 x, Uint16 y) {
403 	if (currentSelection.choiceType == MCT_LeftCursor) {
404 		if (currentSelection.choice == RTS_CycleGroupInfo)
405 			CycleGroupInfoType();
406 		else if (createNew) {
407 			if (currentSelection.choice == RTS_GroupStats
408 				|| currentSelection.choice == RTS_GroupStats
409 				|| currentSelection.choice == RTS_GroupShieldsInfo
410 				|| currentSelection.choice == RTS_GroupStatusReport
411 				|| currentSelection.choice == RTS_GroupAIReport
412 				|| currentSelection.choice == RTS_GroupVars
413 				|| currentSelection.choice == RTS_GroupSaveGroups
414 				|| currentSelection.choice == RTS_GroupTimers)
415 				SelectGroup(mySide, myGroup, currentSelection.choice);
416 			else
417 				myWindows.push_back(GenWindow(rect.x, rect.y, currentSelection.choice, mySide, 0, 0));
418 			MessageWindows(WC_YouClose, 0, 0, parentID, myID);
419 			closed = true;
420 		} else {
421 			MessageWindows(currentSelection.choice, 0, 0, parentID, myID);
422 			closed = true;
423 		}
424 	}
425 
426 	return false;
427 }
428 
BasePU(int ix,int iy)429 BasePU::BasePU(int ix, int iy):
430 PopupMenu(ix, iy, none_constant, 0) {
431 	MenuItem tempItem;
432 
433 	tempItem.flags = MFLAG_CRECT;
434 	for (int i = 0; i != sides.size(); ++i) {
435 		tempItem.desc = sides[i].name;
436 		tempItem.choice = WC_SidePU;
437 		tempItem.parem = i;
438 		AddItem(tempItem);
439 	}
440 
441 	tempItem.flags = 0;
442 
443 	AddBlankItem();
444 
445 	tempItem.desc = "Game Info";
446 	tempItem.choice = RTS_GameInfo;
447 	AddItem(tempItem);
448 
449 	tempItem.desc = "Options";
450 	tempItem.choice = RTS_OptPU;
451 	AddItem(tempItem);
452 
453 	if (gsTo == GST_PreBattle) {
454 		AddBlankItem();
455 
456 		if (PreBattle::pbState == PBS_PreBattle) {
457 			tempItem.desc = "Start battle";
458 			tempItem.choice = PB_IntoBattle;
459 			AddItem(tempItem);
460 		} else {
461 			tempItem.desc = "Save and exit";
462 			tempItem.choice = PB_SaveAndExit;
463 			AddItem(tempItem);
464 		}
465 	}
466 
467 	InitRects();
468 }
469 
SwitchOnChoice(Uint16 x,Uint16 y)470 bool BasePU::SwitchOnChoice(Uint16 x, Uint16 y) {
471 	if (currentSelection.choiceType == MCT_LeftCursor) {
472 		switch (currentSelection.choice) {
473 		case WC_SidePU:
474 			myWindows.push_back(GenWindow(WC_SidePU, currentSelection.parem, 0, RTS_GroupStats));
475 			closed = true;
476 			break;
477 
478 		case RTS_OptPU:
479 			myWindows.push_back(GenWindow(rect.x, rect.y, RTS_OptPU, 0, 0, 0));
480 			closed = true;
481 			break;
482 
483 		case RTS_GameInfo:
484 			myWindows.push_back(GenWindow(0, 0, RTS_GameInfo, 0, 0, WFLAG_TILED));
485 			closed = true;
486 			break;
487 
488 		case PB_IntoBattle:
489 			gsTo = GST_Battle;
490 			closed = true;
491 			break;
492 
493 		case PB_SaveAndExit:
494 			gsTo = GST_ForceSelect;
495 			closed = true;
496 			break;
497 		}
498 	}
499 
500 	if (currentSelection.choiceType == MCT_RightCursor && currentSelection.choice == WC_SidePU)
501 		myWindows.push_back(GenWindow(x, y, RTS_InfoChoicePU, currentSelection.parem, 0, 0, myID, 0));
502 
503 	return false;
504 }
505 
OptPU(int ix,int iy)506 OptPU::OptPU(int ix, int iy):
507 StandardOptions(ix, iy, none_constant, 0) {
508 	Update();
509 }
510 
Update()511 void OptPU::Update() {
512 	ClearItems();
513 
514 	MenuItem tempItem;
515 
516 	tempItem.desc = "Game speed";
517 	tempItem.choice = RTS_SetGameSpeed;
518 	AddItem(tempItem);
519 
520 	tempItem.desc = "Scroll speed";
521 	tempItem.choice = RTS_SetScrollSpeed;
522 	AddItem(tempItem);
523 
524 	AddBlankItem();
525 
526 	tempItem.desc = "Toggle group numbers";
527 	tempItem.choice = RTS_GroupNums;
528 	AddItem(tempItem);
529 
530 	tempItem.desc = "Toggle group boundaries";
531 	tempItem.choice = RTS_GroupRects;
532 	AddItem(tempItem);
533 
534 	AddBlankItem();
535 
536 	PushBackSharedItems();
537 
538 	AddBlankItem();
539 
540 	tempItem.desc = "Restart battle";
541 	tempItem.choice = RTS_RestartQ;
542 	AddItem(tempItem);
543 
544 	tempItem.desc = "Return to main menu";
545 	tempItem.choice = WC_Quit;
546 	AddItem(tempItem);
547 
548 	InitRects();
549 }
550 
RestartQ()551 RestartQ::RestartQ():
552 Menu_Base(0, 0, none_constant, 0) {
553 	MenuItem tempItem;
554 	tempItem.rect.h = lineGap << 1;
555 
556 	tempItem.desc = "Are you sure you want to restart the battle?";
557 	tempItem.choice = WC_Nothing;
558 	AddItem(tempItem);
559 
560 	tempItem.rect.h = lineGap;
561 
562 	tempItem.desc = "Yes";
563 	tempItem.choice = WC_Yes;
564 	AddItem(tempItem);
565 
566 	tempItem.desc = "No";
567 	tempItem.choice = WC_No;
568 	AddItem(tempItem);
569 
570 	InitRects();
571 
572 	CentreWindow();
573 }
574 
SwitchOnChoice(Uint16 x,Uint16 y)575 bool RestartQ::SwitchOnChoice(Uint16 x, Uint16 y) {
576 	if (currentSelection.choiceType == MCT_LeftCursor) {
577 		switch(currentSelection.choice) {
578 		case WC_Yes:
579 			gsTo = GST_PreBattle;
580 			closed = true;
581 			break;
582 
583 		case WC_No:
584 			closed = true;
585 			break;
586 		}
587 	}
588 
589 	return false;
590 }
591 
GameInfo(int ix,int iy,int flags)592 GameInfo::GameInfo(int ix, int iy, int flags):
593 DragWindow(ix, iy, none_constant, flags) {
594 	rect.w = 250;
595 	rect.h = 150;
596 
597 	InitRects();
598 }
599 
DrawSelf()600 void GameInfo::DrawSelf() {
601 	theText.clear();
602 
603 	theText.push_back(WindowText("Game Info:", 1));
604 	theText.push_back(WindowText(""));
605 
606 	char output[50];
607 	sprintf(output, "Elapsed frames: %d", frameCounter);
608 	theText.push_back(WindowText(output));
609 
610 	DragWindow::DrawSelf();
611 }
612 
SideVarsInfo(int ix,int iy,int iMySide)613 SideVarsInfo::SideVarsInfo(int ix, int iy, int iMySide):
614 SideInfo(ix, iy, iMySide, 0) {
615 	rect.w = 200;
616 	rect.h = 230;
617 	InitRects();
618 }
619 
DrawSelf()620 void SideVarsInfo::DrawSelf() {
621 	theText.clear();
622 	AddSideTitle(mySide);
623 	char output[32];
624 	for (int i = 0; i != nAIVars; ++i) {
625 		sprintf(output, "$global%d:    %d", i, sides[mySide].scriptVars[i]);
626 		theText.push_back(WindowText(output));
627 	}
628 
629 	DragWindow::DrawSelf();
630 }
631 
SideAIErrors(int ix,int iy,int iMySide)632 SideAIErrors::SideAIErrors(int ix, int iy, int iMySide):
633 SideInfo(ix, iy, iMySide, 0) {
634 	rect.w = 600;
635 	rect.h = 270;
636 	InitRects();
637 }
638 
DrawSelf()639 void SideAIErrors::DrawSelf() {
640 	theText.clear();
641 	AddSideTitle(mySide);
642 
643 	for (list<string>::const_iterator iter = sides[mySide].aiErrorReports.begin(); iter != sides[mySide].aiErrorReports.end(); ++iter) {
644 		theText.push_back(WindowText(*iter));
645 		//each string has a newline
646 		theText.push_back(WindowText(""));
647 	}
648 
649 	DragWindow::DrawSelf();
650 }
651 
GroupVarsInfo(int ix,int iy,int iMySide,int iMyGroup,int flags)652 GroupVarsInfo::GroupVarsInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
653 GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
654 	rect.w = 200;
655 	rect.h = 230;
656 
657 	InitRects();
658 }
659 
DrawSelf()660 void GroupVarsInfo::DrawSelf() {
661 	theText.clear();
662 	AddGroupTitle(mySide, myGroup);
663 	char output[32];
664 	for (int i = 0; i != nAIVars; ++i) {
665 		sprintf(output, "$%d:    %d", i, sides[mySide].groups[myGroup].GetScriptVar(i));
666 		theText.push_back(WindowText(output));
667 	}
668 
669 	DragWindow::DrawSelf();
670 }
671 
SideSaveGroupsInfo(int ix,int iy,int iMySide)672 SideSaveGroupsInfo::SideSaveGroupsInfo(int ix, int iy, int iMySide):
673 SideInfo(ix, iy, iMySide, 0) {
674 	rect.w = 200;
675 	rect.h = 230;
676 
677 	InitRects();
678 }
679 
DrawSelf()680 void SideSaveGroupsInfo::DrawSelf() {
681 	theText.clear();
682 	AddSideTitle(mySide);
683 	char output[32];
684 	for (int i = 0; i != nAIVars; ++i) {
685 		CoordsInt saveGroup = sides[mySide].saveGroups[i];
686 		sprintf(output, "$globalg%d:    %d-%d", i, saveGroup.x + 1, saveGroup.y + 1);
687 		theText.push_back(WindowText(output));
688 	}
689 
690 	DragWindow::DrawSelf();
691 }
692 
GroupSaveGroupsInfo(int ix,int iy,int iMySide,int iMyGroup,int flags)693 GroupSaveGroupsInfo::GroupSaveGroupsInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
694 GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
695 	rect.w = 200;
696 	rect.h = 230;
697 
698 	InitRects();
699 }
700 
DrawSelf()701 void GroupSaveGroupsInfo::DrawSelf() {
702 	theText.clear();
703 	AddGroupTitle(mySide, myGroup);
704 	char output[32];
705 	for (int i = 0; i != nAIVars; ++i) {
706 		CoordsInt saveGroup = sides[mySide].groups[myGroup].GetSaveGroup(i);
707 		sprintf(output, "$g%d:    %d-%d", i, saveGroup.x + 1, saveGroup.y + 1);
708 		theText.push_back(WindowText(output));
709 	}
710 
711 	DragWindow::DrawSelf();
712 }
713 
GroupTimersInfo(int ix,int iy,int iMySide,int iMyGroup,int flags)714 GroupTimersInfo::GroupTimersInfo(int ix, int iy, int iMySide, int iMyGroup, int flags):
715 GroupInfo(ix, iy, iMySide, iMyGroup, flags) {
716 	rect.w = 200;
717 	rect.h = 230;
718 
719 	InitRects();
720 }
721 
DrawSelf()722 void GroupTimersInfo::DrawSelf() {
723 	theText.clear();
724 	AddGroupTitle(mySide, myGroup);
725 	char output[32];
726 	for (int i = 0; i != nAIVars; ++i) {
727 		sprintf(output, "$timer%d:    %d", i, sides[mySide].groups[myGroup].GetScriptTimer(i));
728 		theText.push_back(WindowText(output));
729 	}
730 
731 	DragWindow::DrawSelf();
732 }
733 
GameSpeedSlider(int ix,int iy,int flags)734 GameSpeedSlider::GameSpeedSlider(int ix, int iy, int flags):
735 SliderWithUnits(ix, iy, maxWorldUpdateInterval - worldUpdateInterval, 0, maxWorldUpdateInterval, "Game speed", "", none_constant, flags) {}
736 
MouseM(Uint8 state,Uint16 x,Uint16 y)737 bool GameSpeedSlider::MouseM(Uint8 state, Uint16 x, Uint16 y) {
738 	bool ret = Slider::MouseM(state, x, y);
739 
740 	if (bSliderDrag)
741 		SetWorldUpdateInterval(maxWorldUpdateInterval - sliderVar);
742 
743 	return ret;
744 }
745 
DrawSelf()746 void GameSpeedSlider::DrawSelf() {
747 	sliderVar = maxWorldUpdateInterval - worldUpdateInterval;
748 	if (paused || worldUpdateInterval == standardInterval) {
749 		Slider::DrawSelf();
750 		int x = rect.x + smallBorderSize;
751 		int y = rect.y + smallBorderSize;
752 		char output[48];
753 		if (paused)
754 			sprintf(output, "%s: Paused", varName.c_str());
755 		else
756 			sprintf(output, "%s: %d - Normal", varName.c_str(), *varPointer);
757 		normalFonts.BlitString(x, y, 0, output);
758 	} else
759 		SliderWithUnits::DrawSelf();
760 }
761 
ScrollSpeedSlider(int ix,int iy,int flags)762 ScrollSpeedSlider::ScrollSpeedSlider(int ix, int iy, int flags):
763 SliderWithUnits(ix, iy, maxScrollInterval - scrollInterval, 0, maxScrollInterval, "Scroll speed", "", none_constant, flags) {}
764 
MouseM(Uint8 state,Uint16 x,Uint16 y)765 bool ScrollSpeedSlider::MouseM(Uint8 state, Uint16 x, Uint16 y) {
766 	bool ret = Slider::MouseM(state, x, y);
767 
768 	scrollInterval = maxScrollInterval - sliderVar;
769 
770 	if (scrollInterval > standardInterval - 10 && scrollInterval < standardInterval + 10) {
771 		scrollInterval = standardInterval;
772 		sliderVar = maxScrollInterval - scrollInterval;
773 	}
774 
775 	return ret;
776 }
777 
778 } //end namespace
779 
780