2
-- / __ )____ _____ | | / /___ ___________
3
-- / __ / __ \/ ___/ | | /| / / __ `/ ___/ ___/
4
-- / /_/ / /_/ (__ ) | |/ |/ / /_/ / / (__ )
5
-- /_____/\____/____/ |__/|__/\__,_/_/ /____/
7
-- A futuristic real-time strategy game.
8
-- This file is part of Bos Wars.
10
-- game.lua - In-game menus.
12
-- (c) Copyright 2006 by Jimmy Salmon and Francois Beerten
14
-- This program is free software; you can redistribute it and/or modify
15
-- it under the terms of the GNU General Public License as published by
16
-- the Free Software Foundation; only version 2 of the License.
18
-- This program is distributed in the hope that it will be useful,
19
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
20
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
-- GNU General Public License for more details.
23
-- You should have received a copy of the GNU General Public License
24
-- along with this program; if not, write to the Free Software
25
-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
29
function BosGameMenu()
30
local menu = MenuScreen()
31
menu:setSize(256, 288)
32
menu:setPosition((Video.Width - menu:getWidth()) / 2,
33
(Video.Height - menu:getHeight()) / 2)
36
menu:setBaseColor(dark)
40
-- FIXME: not a good solution
41
-- default size is 200,24 but we want 224,28 so we override these functions
42
menu.addButtonOrig = menu.addButton
43
function menu:addButton(caption, x, y, callback, size)
44
return self:addButtonOrig(caption, x, y, callback, {224, 28})
46
function menu:addSmallButton(caption, x, y, callback)
47
return self:addButtonOrig(caption, x, y, callback, {100, 24})
54
function RunGameMenu(s)
55
local menu = BosGameMenu()
57
menu:addLabel(_("Game Menu"), 128, 11)
58
local b = menu:addButton(_("Save (~<F11~>)"), 16, 40,
59
function() RunSaveMenu() end)
60
if (IsReplayGame() or IsNetworkGame()) then
63
menu:addButton(_("Options (~<F5~>)"), 16, 40 + (36 * 1),
64
function() RunGameOptionsMenu() end)
65
menu:addButton(_("Help (~<F1~>)"), 16, 40 + (36 * 2),
66
function() RunHelpMenu() end)
67
menu:addButton(_("~!Objectives"), 16, 40 + (36 * 3),
68
function() RunObjectivesMenu() end)
69
menu:addButton(_("~!End Game"), 16, 40 + (36 * 4),
70
function() RunEndGameMenu() end)
71
menu:addButton(_("Return to Game (~<Esc~>)"), 16, 248,
72
function() menu:stop() end)
77
function RunSaveMenu()
78
local menu = BosGameMenu()
80
menu:addLabel(_("Save Game"), 128, 11)
82
local t = menu:addTextInputField("game.sav", 16, 40, 224)
84
local lister = CreateFilteringLister(".sav.gz$", ListFilesInDirectory)
85
local browser = menu:addBrowser("~save", lister, 16, 70, 224, 166)
87
t:setText(browser:getSelectedItem())
89
browser:setActionCallback(cb)
91
menu:addSmallButton(_("~!Save"), 16, 248,
92
-- FIXME: use a confirm menu if the file exists already
94
local name = t:getText()
96
if (string.find(name, ".gz$") ~= nil) then
97
name = string.sub(name, 1, string.len(name) - 3)
100
if (string.find(name, ".sav$") == nil) then
101
name = name .. ".sav"
103
-- replace invalid chars with underscore
104
local t = {"\\", "/", ":", "*", "?", "\"", "<", ">", "|"}
105
table.foreachi(t, function(k,v) name = string.gsub(name, v, "_") end)
108
UI.StatusLine:Set("Saved game to: " .. name)
112
menu:addSmallButton(_("Cancel (~<Esc~>)"), 16 + 12 + 106, 248,
113
function() menu:stop() end)
118
function RunGameSoundOptionsMenu()
119
local menu = BosGameMenu()
121
menu:addLabel(_("Sound Options"), 128, 11)
122
AddSoundOptions(menu, 0, 0, 128 - 224/2, 280)
127
function RunGameOptionsMenu()
128
local menu = BosGameMenu()
130
menu:addLabel(_("Game Options"), 128, 11)
131
menu:addButton(_("Sound (~<F7~>)"), 16, 40 + (36 * 0),
132
function() RunGameSoundOptionsMenu() end)
133
menu:addButton(_("Game (~<F9~>)"), 16, 40 + (36 * 1),
134
function() RunPreferencesMenu() end)
135
menu:addButton(_("~!Diplomacy"), 16, 40 + (36 * 2),
136
function() RunDiplomacyMenu() end)
137
menu:addButton(_("Previous (~<Esc~>)"), 128 - (224 / 2), 248,
138
function() menu:stop() end)
143
function RunPreferencesMenu()
144
local menu = BosGameMenu()
146
menu:addLabel(_("Game Options"), 128, 11)
149
fog = menu:addCheckBox(_("Fog of War Enabled"), 16, 36 * 1,
150
function() SetFogOfWar(fog:isMarked()) end)
151
fog:setMarked(GetFogOfWar())
152
if (IsReplayGame() or IsNetworkGame()) then
153
fog:setEnabled(false)
157
ckey = menu:addCheckBox(_("Show command key"), 16, 36 * 2,
158
function() UI.ButtonPanel.ShowCommandKey = ckey:isMarked() end)
159
ckey:setMarked(UI.ButtonPanel.ShowCommandKey)
161
local l = Label(_("Game Speed"))
162
l:setFont(Fonts["game"])
164
menu:add(l, 16, 36 * 3)
167
gamespeed = menu:addSlider(15, 75, 198, 18, 32, 36 * 3.5,
168
function() SetGameSpeed(gamespeed:getValue()) end)
169
gamespeed:setValue(GetGameSpeed())
172
l:setFont(Fonts["small"])
174
menu:add(l, 32, (36 * 4) + 6)
176
l:setFont(Fonts["small"])
178
menu:add(l, 230 - l:getWidth(), (36 * 4) + 6)
180
menu:addSmallButton(_("~!OK"), 128 - (106 / 2), 245,
182
preferences.FogOfWar = GetFogOfWar()
183
preferences.ShowCommandKey = UI.ButtonPanel.ShowCommandKey
184
preferences.GameSpeed = GetGameSpeed()
192
function RunDiplomacyMenu()
193
local menu = BosGameMenu()
194
menu:setSize(384, 384)
195
menu:setPosition((Video.Width - menu:getWidth()) / 2,
196
(Video.Height - menu:getHeight()) / 2)
198
menu:addLabel(_("Diplomacy"), 192, 11)
200
menu:addLabel(_("Allied"), 136, 30, Fonts["game"])
201
menu:addLabel(_("Enemy"), 208, 30, Fonts["game"])
202
menu:addLabel(_("Shared Vision"), 310, 30, Fonts["game"])
206
local sharedvision = {}
210
if (Players[i].Type ~= PlayerNobody and ThisPlayer.Index ~= i) then
213
local l = Label(Players[i].Name)
214
l:setFont(Fonts["game"])
216
menu:add(l, 16, (21 * j) + 27)
220
local sharedvisioncb = {}
222
alliedcb = menu:addCheckBox("", 126, (21 * j) + 24,
224
if (alliedcb:isMarked() and enemycb:isMarked()) then
225
enemycb:setMarked(false)
228
alliedcb:setMarked(ThisPlayer:IsAllied(Players[i]))
232
enemycb = menu:addCheckBox("", 198, (21 * j) + 24,
234
if (alliedcb:isMarked() and enemycb:isMarked()) then
235
alliedcb:setMarked(false)
238
enemycb:setMarked(ThisPlayer:IsEnemy(Players[i]))
241
sharedvisioncb = menu:addCheckBox("", 300, (21 * j) + 24,
243
sharedvisioncb:setMarked(ThisPlayer:IsSharedVision(Players[i]))
244
sharedvision[j] = sharedvisioncb
246
if (IsReplayGame() or ThisPlayer:IsTeamed(Players[i])) then
247
alliedcb:setEnabled(false)
248
enemycb:setEnabled(false)
249
sharedvisioncb:setEnabled(false)
254
menu:addSmallButton(_("~!OK"), 75, 384 - 40,
256
for j=1,table.getn(allied) do
257
local i = allied[j].index
260
if (allied[j]:isMarked() and enemy[j]:isMarked() == false) then
261
if (ThisPlayer:IsAllied(Players[i]) == false or
262
ThisPlayer:IsEnemy(Players[i])) then
263
SetDiplomacy(ThisPlayer.Index, "allied", i)
268
if (allied[j]:isMarked() == false and enemy[j]:isMarked()) then
269
if (ThisPlayer:IsAllied(Players[i]) or
270
ThisPlayer:IsEnemy(Players[i]) == false) then
271
SetDiplomacy(ThisPlayer.Index, "enemy", i)
276
if (allied[j]:isMarked() == false and enemy[j]:isMarked() == false) then
277
if (ThisPlayer:IsAllied(Players[i]) or
278
ThisPlayer:IsEnemy(Players[i])) then
279
SetDiplomacy(ThisPlayer.Index, "neutral", i)
284
if (allied[j]:isMarked() and enemy[j]:isMarked()) then
285
if (ThisPlayer:IsAllied(Players[i]) == false or
286
ThisPlayer:IsEnemy(Players[i]) == false) then
287
SetDiplomacy(ThisPlayer.Index, "crazy", i)
292
if (sharedvision[j]:isMarked()) then
293
if (ThisPlayer:IsSharedVision(Players[i]) == false) then
294
SetSharedVision(ThisPlayer.Index, true, i)
297
if (ThisPlayer:IsSharedVision(Players[i])) then
298
SetSharedVision(ThisPlayer.Index, false, i)
304
menu:addSmallButton(_("Cancel (~<Esc~>)"), 195, 384 - 40, function() menu:stop() end)
310
function RunRestartConfirmMenu()
312
_("Are you sure you want to restart the game?"),
313
_("~!Restart Game"), GameRestart)
316
function RunQuitToMenuConfirmMenu()
318
_("Are you sure you want to quit to the main menu?"),
319
_("~!Quit to Menu"), GameQuitToMenu)
322
function RunEndGameMenu()
323
local menu = BosGameMenu()
325
menu:addLabel(_("End Game"), 128, 11)
326
local b = menu:addButton(_("~!Restart Game"), 16, 40 + (36 * 0),
327
RunRestartConfirmMenu)
328
if (IsNetworkGame()) then
331
menu:addButton(_("~!Surrender"), 16, 40 + (36 * 1),
332
function() RunConfirmTypeMenu(
333
_("Are you sure you want to surrender to your enemies?"),
334
_("~!Surrender"), GameDefeat) end)
335
menu:addButton(_("~!Quit to Menu"), 16, 40 + (36 * 2),
336
RunQuitToMenuConfirmMenu)
337
menu:addButton(_("E~!xit Bos Wars"), 16, 40 + (36 * 3),
339
menu:addButton(_("Previous (~<Esc~>)"), 16, 248,
340
function() menu:stop() end)
345
function RunConfirmTypeMenu(boxtext, buttontext, stopgametype)
346
local menu = BosGameMenu()
349
height = height + menu:addMultiLineLabel(boxtext, 128, 11):getHeight()
350
menu:addButton(buttontext, 16, height + 29,
351
function() StopGame(stopgametype); menu:stopAll() end)
352
menu:addButton(_("Cancel (~<Esc~>)"), 16, 248,
353
function() menu:stop() end)
357
function RunExitConfirmMenu()
358
local menu = BosGameMenu()
361
height = height + menu:addMultiLineLabel(
362
_("Are you sure you want to exit Bos Wars?"), 128, 11):getHeight()
363
menu:addButton(_("E~!xit Program"), 16, height + 29,
364
function() Exit(0) end)
365
menu:addButton(_("Cancel (~<Esc~>)"), 16, 248,
366
function() menu:stop() end)
371
function RunHelpMenu()
372
local menu = BosGameMenu()
374
menu:addLabel(_("Help Menu"), 128, 11)
375
menu:addButton(_("Keystroke ~!Help"), 16, 40 + (36 * 0),
376
function() RunKeystrokeHelpMenu() end)
377
menu:addButton(_("Bos Wars ~!Tips"), 16, 40 + (36 * 1),
378
function() RunTipsMenu() end)
379
menu:addButton(_("Previous (~<Esc~>)"), 128 - (224 / 2), 248,
380
function() menu:stop() end)
385
function InitKeystrokes(keystrokes)
386
table.insert(keystrokes, {_("Alt-F"), _("- toggle full screen")})
387
table.insert(keystrokes, {_("Alt-G"), _("- toggle grab mouse")})
388
table.insert(keystrokes, {_("Ctrl-S"), _("- mute sound")})
389
table.insert(keystrokes, {_("Ctrl-M"), _("- mute music")})
390
table.insert(keystrokes, {_("+"), _("- increase game speed")})
391
table.insert(keystrokes, {_("-"), _("- decrease game speed")})
392
table.insert(keystrokes, {_("Ctrl-P"), _("- pause game")})
393
table.insert(keystrokes, {_("PAUSE"), _("- pause game")})
394
table.insert(keystrokes, {_("PRINT"), _("- make screen shot")})
395
table.insert(keystrokes, {_("Alt-H"), _("- help menu")})
396
table.insert(keystrokes, {_("Alt-R"), _("- restart game")})
397
table.insert(keystrokes, {_("Alt-Q"), _("- quit to main menu")})
398
table.insert(keystrokes, {_("Alt-X"), _("- quit game")})
399
table.insert(keystrokes, {_("Alt-B"), _("- toggle expand map")})
400
table.insert(keystrokes, {_("Alt-M"), _("- game menu")})
401
table.insert(keystrokes, {_("ENTER"), _("- write a message")})
402
table.insert(keystrokes, {_("SPACE"), _("- goto last event")})
403
table.insert(keystrokes, {_("TAB"), _("- hide/unhide terrain")})
404
table.insert(keystrokes, {_("Ctrl-T"), _("- track unit")})
405
table.insert(keystrokes, {_("Alt-I"), _("- find idle peon")})
406
table.insert(keystrokes, {_("Alt-C"), _("- center on selected unit")})
407
table.insert(keystrokes, {_("Alt-V"), _("- next view port")})
408
table.insert(keystrokes, {_("Ctrl-V"), _("- previous view port")})
409
table.insert(keystrokes, {_("^"), _("- select nothing")})
410
table.insert(keystrokes, {_("#"), _("- select group")})
411
table.insert(keystrokes, {_("##"), _("- center on group")})
412
table.insert(keystrokes, {_("Ctrl-#"), _("- define group")})
413
table.insert(keystrokes, {_("Shift-#"), _("- add to group")})
414
table.insert(keystrokes, {_("Alt-#"), _("- add to alternate group")})
415
table.insert(keystrokes, {_("F2-F4"), _("- recall map position")})
416
table.insert(keystrokes, {_("Shift F2-F4"), _("- save map position")})
417
table.insert(keystrokes, {_("F5"), _("- game options")})
418
table.insert(keystrokes, {_("F7"), _("- sound options")})
419
table.insert(keystrokes, {_("F8"), _("- speed options")})
420
table.insert(keystrokes, {_("F9"), _("- preferences")})
421
table.insert(keystrokes, {_("F10"), _("- game menu")})
422
table.insert(keystrokes, {_("F11"), _("- save game")})
423
table.insert(keystrokes, {_("F12"), _("- load game")})
426
function RunKeystrokeHelpMenu()
427
local keystrokes = {}
428
InitKeystrokes(keystrokes)
430
local menu = BosGameMenu()
431
menu:setSize(352, 352)
432
menu:setPosition((Video.Width - menu:getWidth()) / 2,
433
(Video.Height - menu:getHeight()) / 2)
435
local c = Container()
438
for i=1,table.getn(keystrokes) do
439
local l = Label(keystrokes[i][1])
440
l:setFont(Fonts["game"])
442
c:add(l, 0, 20 * (i - 1))
443
local l = Label(keystrokes[i][2])
444
l:setFont(Fonts["game"])
446
c:add(l, 80, 20 * (i - 1))
449
local s = ScrollArea()
450
c:setSize(320 - s:getScrollbarWidth(), 20 * table.getn(keystrokes))
452
s:setBackgroundColor(dark)
453
s:setForegroundColor(clear)
458
menu:addLabel(_("Keystroke Help Menu"), 352 / 2, 11)
459
menu:addButton(_("Previous (~<Esc~>)"), (352 / 2) - (224 / 2), 352 - 40,
460
function() menu:stop() end)
465
function InitTips(tips)
466
table.insert(tips, _("You can select all of your currently visible units of the same type by holding down the CTRL key and selecting a unit or by \"double clicking\" on a unit."))
467
table.insert(tips, _("The more engineers you have collecting resources, the faster your economy will grow."))
469
table.insert(tips, _("Use your engineers to repair damaged buildings."))
470
table.insert(tips, _("Explore your surroundings early in the game."))
473
table.insert(tips, _("Keep all engineers working. Use ALT-I to find idle engineers."))
474
table.insert(tips, _("You can make units automatically perform special actions by selecting a unit, holding down CTRL and clicking on the icon. CTRL click again to turn off."))
477
table.insert(tips, _("You can give an unit an order which is executed after it finishes the current work, if you hold the SHIFT key."))
478
table.insert(tips, _("You can give way points, if you press the SHIFT key, while you click right for the move command."))
479
table.insert(tips, _("You can order an engineer to build one building after the other, if you hold the SHIFT key, while you place the building."))
480
table.insert(tips, _("You can build many of the same building, if you hold the ALT and SHIFT keys while you place the buildings."))
482
table.insert(tips, _("Use CTRL-V or ALT-V to cycle through the viewport configuration, you can than monitor your base and lead an attack."))
484
table.insert(tips, _("Know a useful tip? Then add it here!"))
487
function RunTipsMenu()
491
local menu = BosGameMenu()
492
menu:setSize(384, 256)
493
menu:setPosition((Video.Width - menu:getWidth()) / 2,
494
(Video.Height - menu:getHeight()) / 2)
496
menu:addLabel(_("Bos Wars Tips"), 192, 11)
498
local l = MultiLineLabel()
499
l:setFont(Fonts["game"])
504
preferences.TipNumber = preferences.TipNumber - 1
505
if (preferences.TipNumber < 1) then
506
preferences.TipNumber = table.getn(tips)
511
preferences.TipNumber = preferences.TipNumber + 1
512
if (preferences.TipNumber > table.getn(tips)) then
513
preferences.TipNumber = 1
517
function l:updateCaption()
518
self:setCaption(tips[preferences.TipNumber])
520
if (preferences.TipNumber == 0) then
527
showtips = menu:addCheckBox(_("Show tips at startup"), 14, 256 - 75,
529
preferences.ShowTips = showtips:isMarked()
532
showtips:setMarked(preferences.ShowTips)
533
menu:addSmallButton(_("~!OK"), 14, 256 - 40,
534
function() l:nextTip(); menu:stop() end)
535
menu:addSmallButton(_("~!Previous Tip"), 14 + 106 + 11, 256 - 40,
536
function() l:prevTip(); l:updateCaption() end)
537
menu:addSmallButton(_("~!Next Tip"), 14 + 106 + 11 + 106 + 11, 256 - 40,
538
function() l:nextTip(); l:updateCaption() end)
543
function RunObjectivesMenu()
544
local menu = BosGameMenu()
545
menu:setSize(384, 256)
546
menu:setPosition((Video.Width - menu:getWidth()) / 2,
547
(Video.Height - menu:getHeight()) / 2)
549
menu:addLabel(_("Objectives"), 192, 11)
551
local l = MultiLineLabel()
552
l:setFont(Fonts["game"])
557
local objs = GetObjectives()
559
for i,f in ipairs(objs) do
560
objText = objText .. f .. "\n"
562
l:setCaption(objText)
564
menu:addButton(_("~!OK"), 80, 256 - 40,
565
function() menu:stop() end)