1--       _________ __                 __
2--      /   _____//  |_____________ _/  |______     ____  __ __  ______
3--      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
4--      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ \
5--     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
6--             \/                  \/          \//_____/            \/
7--  ______________________                           ______________________
8--                        T H E   W A R   B E G I N S
9--         Stratagus - A free fantasy real time strategy game engine
10--
11--      guichan.lua - Define the main guichan menu.
12--
13--      (c) Copyright 2006-2016 by Jimmy Salmon, Pali Rohár and cybermind
14--
15--      This program is free software; you can redistribute it and/or modify
16--      it under the terms of the GNU General Public License as published by
17--      the Free Software Foundation; either version 2 of the License, or
18--      (at your option) any later version.
19--
20--      This program is distributed in the hope that it will be useful,
21--      but WITHOUT ANY WARRANTY; without even the implied warranty of
22--      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23--      GNU General Public License for more details.
24--
25--      You should have received a copy of the GNU General Public License
26--      along with this program; if not, write to the Free Software
27--      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28--
29
30SetDefaultRaceView()
31SetGrabMouse(wc2.preferences.GrabMouse)
32
33-- Global useful objects for menus  ----------
34dark = Color(38, 38, 78)
35clear = Color(200, 200, 120)
36black = Color(0, 0, 0)
37
38bckground = CGraphic:New("ui/Menu_background_with_title.png")
39bckground:Load()
40bckground:Resize(Video.Width, Video.Height)
41backgroundWidget = ImageWidget(bckground)
42
43g_hbln = CGraphic:New("ui/human/widgets/button-large-normal.png")
44g_hbln:Load()
45g_hblp = CGraphic:New("ui/human/widgets/button-large-pressed.png")
46g_hblp:Load()
47g_hblg = CGraphic:New("ui/human/widgets/button-large-grayed.png")
48g_hblg:Load()
49
50g_hbsn = CGraphic:New("ui/human/widgets/button-small-normal.png")
51g_hbsn:Load()
52g_hbsp = CGraphic:New("ui/human/widgets/button-small-pressed.png")
53g_hbsp:Load()
54g_hbsg = CGraphic:New("ui/human/widgets/button-small-grayed.png")
55g_hbsg:Load()
56
57g_obln = CGraphic:New("ui/orc/widgets/button-large-normal.png")
58g_obln:Load()
59g_oblp = CGraphic:New("ui/orc/widgets/button-large-pressed.png")
60g_oblp:Load()
61g_oblg = CGraphic:New("ui/orc/widgets/button-large-grayed.png")
62g_oblg:Load()
63
64g_obsn = CGraphic:New("ui/orc/widgets/button-small-normal.png")
65g_obsn:Load()
66g_obsp = CGraphic:New("ui/orc/widgets/button-small-pressed.png")
67g_obsp:Load()
68g_obsg = CGraphic:New("ui/orc/widgets/button-small-grayed.png")
69g_obsg:Load()
70
71g_hcheckbox_off = CGraphic:New("ui/human/widgets/checkbox-normal-unselected.png")
72g_hcheckbox_off:Load()
73g_hcheckbox_off2 = CGraphic:New("ui/human/widgets/checkbox-pressed-unselected.png")
74g_hcheckbox_off2:Load()
75g_hcheckbox_on = CGraphic:New("ui/human/widgets/checkbox-normal-selected.png")
76g_hcheckbox_on:Load()
77g_hcheckbox_on2 = CGraphic:New("ui/human/widgets/checkbox-pressed-selected.png")
78g_hcheckbox_on2:Load()
79
80g_ocheckbox_off = CGraphic:New("ui/orc/widgets/checkbox-normal-unselected.png")
81g_ocheckbox_off:Load()
82g_ocheckbox_off2 = CGraphic:New("ui/orc/widgets/checkbox-pressed-unselected.png")
83g_ocheckbox_off2:Load()
84g_ocheckbox_on = CGraphic:New("ui/orc/widgets/checkbox-normal-selected.png")
85g_ocheckbox_on:Load()
86g_ocheckbox_on2 = CGraphic:New("ui/orc/widgets/checkbox-pressed-selected.png")
87g_ocheckbox_on2:Load()
88
89g_oradio_off = CGraphic:New("ui/orc/widgets/radio-normal-unselected.png")
90g_oradio_off:Load()
91g_oradio_off2 = CGraphic:New("ui/orc/widgets/radio-pressed-unselected.png")
92g_oradio_off2:Load()
93g_oradio_on = CGraphic:New("ui/orc/widgets/radio-normal-selected.png")
94g_oradio_on:Load()
95g_oradio_on2 = CGraphic:New("ui/orc/widgets/radio-pressed-selected.png")
96g_oradio_on2:Load()
97
98g_hradio_off = CGraphic:New("ui/human/widgets/radio-normal-unselected.png")
99g_hradio_off:Load()
100g_hradio_off2 = CGraphic:New("ui/human/widgets/radio-pressed-unselected.png")
101g_hradio_off2:Load()
102g_hradio_on = CGraphic:New("ui/human/widgets/radio-normal-selected.png")
103g_hradio_on:Load()
104g_hradio_on2 = CGraphic:New("ui/human/widgets/radio-pressed-selected.png")
105g_hradio_on2:Load()
106
107-- original continue button for the campaign, chapter and victory/defeat screens
108g_continue_n = CGraphic:New("ui/human/widgets/button-grayscale-normal.png")
109g_continue_n:Load()
110g_continue_p = CGraphic:New("ui/human/widgets/button-grayscale-pressed.png")
111g_continue_p:Load()
112
113-- right slider arrows for human
114g_hrslider_n = CGraphic:New("ui/human/widgets/right-arrow-normal.png")
115g_hrslider_n:Load()
116g_hrslider_p = CGraphic:New("ui/human/widgets/right-arrow-pressed.png")
117g_hrslider_p:Load()
118g_hrslider_d = CGraphic:New("ui/human/widgets/right-arrow-grayed.png")
119g_hrslider_d:Load()
120
121-- left slider arrows for human
122g_hlslider_n = CGraphic:New("ui/human/widgets/left-arrow-normal.png")
123g_hlslider_n:Load()
124g_hlslider_p = CGraphic:New("ui/human/widgets/left-arrow-pressed.png")
125g_hlslider_p:Load()
126g_hlslider_d = CGraphic:New("ui/human/widgets/left-arrow-grayed.png")
127g_hlslider_d:Load()
128
129-- up slider arrows for human
130g_huslider_n = CGraphic:New("ui/human/widgets/up-arrow-normal.png")
131g_huslider_n:Load()
132g_huslider_p = CGraphic:New("ui/human/widgets/up-arrow-pressed.png")
133g_huslider_p:Load()
134g_huslider_d = CGraphic:New("ui/human/widgets/up-arrow-grayed.png")
135g_huslider_d:Load()
136
137-- down slider arrows for human
138g_hdslider_n = CGraphic:New("ui/human/widgets/down-arrow-normal.png")
139g_hdslider_n:Load()
140g_hdslider_p = CGraphic:New("ui/human/widgets/down-arrow-pressed.png")
141g_hdslider_p:Load()
142g_hdslider_d = CGraphic:New("ui/human/widgets/down-arrow-grayed.png")
143g_hdslider_d:Load()
144
145-- right slider arrows for orc
146g_orslider_n = CGraphic:New("ui/orc/widgets/right-arrow-normal.png")
147g_orslider_n:Load()
148g_orslider_p = CGraphic:New("ui/orc/widgets/right-arrow-pressed.png")
149g_orslider_p:Load()
150g_orslider_d = CGraphic:New("ui/orc/widgets/right-arrow-grayed.png")
151g_orslider_d:Load()
152
153-- left slider arrows for orc
154g_olslider_n = CGraphic:New("ui/orc/widgets/left-arrow-normal.png")
155g_olslider_n:Load()
156g_olslider_p = CGraphic:New("ui/orc/widgets/left-arrow-pressed.png")
157g_olslider_p:Load()
158g_olslider_d = CGraphic:New("ui/orc/widgets/left-arrow-grayed.png")
159g_olslider_d:Load()
160
161-- up slider arrows for orc
162g_ouslider_n = CGraphic:New("ui/orc/widgets/up-arrow-normal.png")
163g_ouslider_n:Load()
164g_ouslider_p = CGraphic:New("ui/orc/widgets/up-arrow-pressed.png")
165g_ouslider_p:Load()
166g_ouslider_d = CGraphic:New("ui/orc/widgets/up-arrow-grayed.png")
167g_ouslider_d:Load()
168
169-- down slider arrows for orc
170g_odslider_n = CGraphic:New("ui/orc/widgets/down-arrow-normal.png")
171g_odslider_n:Load()
172g_odslider_p = CGraphic:New("ui/orc/widgets/down-arrow-pressed.png")
173g_odslider_p:Load()
174g_odslider_d = CGraphic:New("ui/orc/widgets/down-arrow-grayed.png")
175g_odslider_d:Load()
176
177-- slider marker - so we know the value of the option we're trying to change
178g_hmarker = CGraphic:New("ui/human/widgets/slider-knob.png")
179g_hmarker:Load()
180
181-- slider background image
182g_hslider = CGraphic:New("ui/human/widgets/hslider-bar-normal.png")
183g_hslider:Load()
184g_hslider_d = CGraphic:New("ui/human/widgets/hslider-bar-grayed.png")
185g_hslider_d:Load()
186
187-- vertical slider background image
188g_hvslider = CGraphic:New("ui/human/widgets/vslider-bar-normal.png")
189g_hvslider:Load()
190g_hvslider_d = CGraphic:New("ui/human/widgets/vslider-bar-grayed.png")
191g_hvslider_d:Load()
192
193-- same, but for orc this time.
194g_omarker = CGraphic:New("ui/orc/widgets/slider-knob.png")
195g_omarker:Load()
196
197-- slider image for the orcs
198g_oslider = CGraphic:New("ui/orc/widgets/hslider-bar-normal.png")
199g_oslider:Load()
200g_oslider_d = CGraphic:New("ui/orc/widgets/hslider-bar-grayed.png")
201g_oslider_d:Load()
202
203-- vertical slider image for the orcs
204g_ovslider = CGraphic:New("ui/orc/widgets/vslider-bar-normal.png")
205g_ovslider:Load()
206g_ovslider_d = CGraphic:New("ui/orc/widgets/vslider-bar-grayed.png")
207g_ovslider_d:Load()
208
209-- human list box item bar
210g_hibar = CGraphic:New("ui/human/widgets/pulldown-bar-normal.png")
211g_hibar:Load()
212
213-- orc list box item bar
214g_oibar = CGraphic:New("ui/orc/widgets/pulldown-bar-normal.png")
215g_oibar:Load()
216
217local hpanels = {
218  "ui/human/panel_1.png",
219  "ui/human/panel_2.png",
220  "ui/human/panel_3.png",
221  "ui/human/panel_4.png",
222  "ui/human/panel_5.png"
223}
224
225local opanels = {
226  "ui/orc/panel_1.png",
227  "ui/orc/panel_2.png",
228  "ui/orc/panel_3.png",
229  "ui/orc/panel_4.png",
230  "ui/orc/panel_5.png"
231}
232
233local wc1_hpanels = {
234  "ui/human_war1/panel_1.png",
235  "ui/human_war1/panel_2.png",
236  "ui/human_war1/panel_3.png",
237  "ui/human_war1/panel_4.png",
238  "ui/human_war1/panel_5.png"
239}
240
241local wc1_opanels = {
242  "ui/orc_war1/panel_1.png",
243  "ui/orc_war1/panel_2.png",
244  "ui/orc_war1/panel_3.png",
245  "ui/orc_war1/panel_4.png",
246  "ui/orc_war1/panel_5.png"
247}
248
249function panel(n)
250  if (currentExp == "wc1") then
251    if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
252      return wc1_hpanels[n]
253    else
254      return wc1_opanels[n]
255    end
256  else
257    if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
258      return hpanels[n]
259    else
260      return opanels[n]
261    end
262  end
263end
264
265
266
267function AddMenuHelpers(menu)
268  function menu:addCentered(widget, x, y)
269    self:add(widget, x - widget:getWidth() / 2, y)
270  end
271
272  function menu:addLabel(text, x, y, font, center)
273    local label = Label(text)
274    if (font == nil) then font = Fonts["large"] end
275    label:setFont(font)
276    label:adjustSize()
277    if (center == nil or center == true) then -- center text by default
278      x = x - label:getWidth() / 2
279    end
280    self:add(label, x, y)
281
282    return label
283  end
284
285function menu:addMultiLineLabel(text, x, y, font, center, line_width)
286	local label = MultiLineLabel(text)
287	if (font == nil) then font = Fonts["large"] end
288	label:setFont(font)
289	label:setVerticalAlignment(MultiLineLabel.TOP)
290	if (center == nil or center == false) then -- center text by default
291		label:setAlignment(MultiLineLabel.LEFT)
292	elseif (center == true) then
293		label:setAlignment(MultiLineLabel.CENTER)
294	else
295		label:setAlignment(MultiLineLabel.RIGHT)
296	end
297	label:setLineWidth(line_width)
298	label:setWidth(line_width)
299	label:setHeight(240)
300	label:adjustSize()
301	self:add(label, x, y)
302	return label
303end
304
305  function menu:writeText(text, x, y, font)
306	if (font == nil) then font = Fonts["game"] end
307    return self:addLabel(text, x, y, font, false)
308  end
309
310  function menu:writeLargeText(text, x, y)
311    return self:addLabel(text, x, y, Fonts["large"], false)
312  end
313
314  function menu:addButton(caption, hotkey, x, y, callback, size)
315    local b = ButtonWidget(caption)
316	b:setHotKey(hotkey)
317    b:setActionCallback(callback)
318    if (size == nil) then size = {200, 24} end
319    b:setSize(size[1], size[2])
320    b:setBackgroundColor(dark)
321    b:setBaseColor(dark)
322    self:add(b, x, y)
323	b:setBorderSize(0)
324    return b
325  end
326
327function menu:addImageButton(caption, hotkey, x, y, callback)
328	local b = ImageButton(caption)
329	if (hotkey ~= "") then
330		b:setHotKey(hotkey)
331	end
332        b:setMouseCallback(
333           function(evtname)
334              if evtname == "mousePress" then
335                 PlaySound("click")
336              end
337        end)
338	b:setActionCallback(
339           function()
340              PlaySound("click")
341              callback()
342        end)
343	self:add(b, x, y)
344	b:setBorderSize(0) -- Andrettin: make buttons not have the borders they previously had
345	return b
346end
347
348  function menu:addFullButton(caption, hotkey, x, y, callback)
349    local b = self:addImageButton(caption, hotkey, x, y, callback)
350    if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
351	  b:setNormalImage(g_hbln)
352      b:setPressedImage(g_hblp)
353      b:setDisabledImage(g_hblg)
354    else
355      b:setNormalImage(g_obln)
356      b:setPressedImage(g_oblp)
357      b:setDisabledImage(g_oblg)
358    end
359    b:setSize(224, 28)
360	b:setBorderSize(0)
361    return b
362  end
363
364  function menu:addContinueButton(caption, hotkey, x, y, callback)
365    local b = self:addImageButton(caption, hotkey, x, y, callback)
366    b:setNormalImage(g_continue_n)
367    b:setPressedImage(g_continue_p)
368    b:setSize(106, 28)
369	b:setBorderSize(0)
370    return b
371  end
372
373  function menu:addMenuButton(caption, hotkey, x, y, callback)
374	local b = self:addImageButton(caption, hotkey, x, y, callback)
375	b:setBaseColor(Color(0,0,0,0))
376	b:setForegroundColor(Color(0,0,0,0))
377	b:setBackgroundColor(Color(0,0,0,0))
378	local g_bln
379	local g_blp
380	local g_blg
381	g_bln = CGraphic:New("graphics/ui/kindland.png")
382	g_blp = CGraphic:New("graphics/ui/kindland.png")
383	g_blg = CGraphic:New("graphics/ui/kindland.png") -- greyed
384	g_bln:Load()
385	g_blp:Load()
386	g_blg:Load()
387	b:setNormalImage(g_bln)
388	b:setPressedImage(g_blp)
389	b:setDisabledImage(g_blg)
390	b:setSize(132, 50)
391	if (string.len(caption) > 24) then
392		b:setFont(Fonts["game"])
393	end
394	return b
395  end
396
397  function menu:addHalfButton(caption, hotkey, x, y, callback)
398    local b = self:addImageButton(caption, hotkey, x, y, callback)
399	if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
400      b:setNormalImage(g_hbsn)
401      b:setPressedImage(g_hbsp)
402      b:setDisabledImage(g_hbsg)
403	else
404      b:setNormalImage(g_obsn)
405      b:setPressedImage(g_obsp)
406      b:setDisabledImage(g_obsg)
407    end
408    b:setSize(106, 28)
409	b:setBorderSize(0)
410    return b
411  end
412
413  function menu:addImageLeftSliderButton(caption, hotkey, x, y, callback)
414    local b = self:addImageButton(caption, hotkey, x, y, callback)
415    if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
416	  b:setNormalImage(g_hlslider_n)
417	  b:setPressedImage(g_hlslider_p)
418	  b:setDisabledImage(g_hlslider_d)
419	else
420	  b:setNormalImage(g_olslider_n)
421	  b:setPressedImage(g_olslider_p)
422	  b:setDisabledImage(g_olslider_d)
423    end
424	b:setSize(20, 19)
425	b:setBorderSize(0)
426    return b
427  end
428
429  function menu:addImageSlider(min, max, w, h, x, y, mi, bi, callback)
430    local b = ImageSlider(min, max)
431	-- New Slider Functions
432    if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
433		b:setMarkerImage(g_hmarker)
434		b:setBackgroundImage(g_hslider)
435		b:setDisabledBackgroundImage(g_hslider_d)
436    else
437		b:setMarkerImage(g_omarker)
438		b:setBackgroundImage(g_oslider)
439		b:setDisabledBackgroundImage(g_oslider_d)
440    end
441    b:setSize(w, h)
442    b:setActionCallback(function(s) callback(b, s) end)
443    self:add(b, x, y)
444	b:setBorderSize(0)
445    return b
446  end
447
448  function menu:addImageRightSliderButton(caption, hotkey, x, y, callback)
449    local b = self:addImageButton(caption, hotkey, x, y, callback)
450    if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
451	  b:setNormalImage(g_hrslider_n)
452	  b:setPressedImage(g_hrslider_p)
453	  b:setDisabledImage(g_hrslider_d)
454	else
455	  b:setNormalImage(g_orslider_n)
456	  b:setPressedImage(g_orslider_p)
457	  b:setDisabledImage(g_orslider_d)
458    end
459    b:setSize(20, 19)
460	b:setBorderSize(0)
461    return b
462  end
463
464  function menu:addListBox(x, y, w, h, list)
465    local bq = ListBoxWidget(w, h)
466    bq:setList(list)
467    bq:setBaseColor(black)
468    bq:setForegroundColor(clear)
469    bq:setBackgroundColor(dark)
470    bq:setFont(Fonts["game"])
471    self:add(bq, x, y)
472    bq.itemslist = list
473    return bq
474  end
475
476  function menu:addImageListBox(x, y, w, h, list)
477    local bq = ImageListBoxWidget(w, h)
478    bq:setList(list)
479    bq:setBaseColor(black)
480    bq:setForegroundColor(clear)
481    bq:setBackgroundColor(dark)
482    bq:setFont(Fonts["game"])
483	if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
484		bq:setItemImage(g_hibar)
485		bq:setUpButtonImage(g_huslider_n)
486		bq:setDownButtonImage(g_hdslider_n)
487		bq:setLeftButtonImage(g_hlslider_n)
488		bq:setRightButtonImage(g_hrslider_n)
489		bq:setUpPressedButtonImage(g_huslider_p)
490		bq:setDownPressedButtonImage(g_hdslider_p)
491		bq:setLeftPressedButtonImage(g_hlslider_p)
492		bq:setRightPressedButtonImage(g_hrslider_p)
493		bq:setMarkerImage(g_hmarker)
494		bq:setHBarImage(g_hslider)
495		bq:setVBarImage(g_hvslider)
496	else
497		bq:setItemImage(g_oibar)
498		bq:setUpButtonImage(g_ouslider_n)
499		bq:setDownButtonImage(g_odslider_n)
500		bq:setLeftButtonImage(g_olslider_n)
501		bq:setRightButtonImage(g_orslider_n)
502		bq:setUpPressedButtonImage(g_ouslider_p)
503		bq:setDownPressedButtonImage(g_odslider_p)
504		bq:setLeftPressedButtonImage(g_olslider_p)
505		bq:setRightPressedButtonImage(g_orslider_p)
506		bq:setMarkerImage(g_omarker)
507		bq:setHBarImage(g_oslider)
508		bq:setVBarImage(g_ovslider)
509	end
510    self:add(bq, x, y)
511    bq.itemslist = list
512    return bq
513  end
514
515  function menu:addBrowser(path, filter, x, y, w, h, default, relative)
516    -- Create a list of all dirs and files in a directory
517    local function listfiles(path)
518      local dirlist = {}
519      local i
520      local f
521      local u = 1
522
523      local dirs = ListDirsInDirectory(path, relative)
524      for i,f in ipairs(dirs) do
525        dirlist[u] = f .. "/"
526        u = u + 1
527      end
528
529      local fileslist = ListFilesInDirectory(path, relative)
530      for i,f in ipairs(fileslist) do
531        if (string.find(f, filter)) then
532          dirlist[u] = f
533          u = u + 1
534        end
535      end
536
537      return dirlist
538    end
539
540    local bq = self:addImageListBox(x, y, w, h, {})
541
542    if (string.sub(path, string.len(path)) ~= "/") then
543      path = path .. "/"
544    end
545    bq.origpath = path
546    bq.actioncb = nil
547
548    -- The directory changed, update the list
549    local function updatelist()
550      bq.itemslist = listfiles(bq.path)
551      if (bq.path ~= bq.origpath) then
552        table.insert(bq.itemslist, 1, "../")
553      end
554      bq:setList(bq.itemslist)
555    end
556
557    -- Change to the default directory and select the default file
558    if (default == nil) then
559      bq.path = path
560      updatelist()
561    else
562      local i
563      if string.match(default, "/") then
564         for i=string.len(default)-1,1,-1 do
565            if (string.sub(default, i, i) == "/") then
566               bq.path = string.sub(default, 1, i)
567               updatelist()
568
569               local f = string.sub(default, i + 1)
570               for i=1,table.getn(bq.itemslist) do
571                  if (bq.itemslist[i] == f) then
572                     bq:setSelected(i - 1)
573                  end
574               end
575               break
576            end
577         end
578      else
579         bq.path = path
580         updatelist()
581         for i=1,table.getn(bq.itemslist) do
582            if (bq.itemslist[i] == default) then
583               bq:setSelected(i - 1)
584               break
585            end
586         end
587      end
588    end
589
590    function bq:exists(name)
591     for i,v in ipairs(self.itemslist) do
592       if(v == name) then
593         return true
594       end
595     end
596     return false
597    end
598
599
600    function bq:getSelectedItem()
601      if (self:getSelected() < 0) then
602        return self.itemslist[1]
603      end
604      return self.itemslist[self:getSelected() + 1]
605    end
606
607    -- If a directory was clicked change dirs
608    -- Otherwise call the user's callback
609    local function cb(s)
610      local f = bq:getSelectedItem()
611      if (f == "../") then
612        local i
613        for i=string.len(bq.path)-1,1,-1 do
614          if (string.sub(bq.path, i, i) == "/") then
615            bq.path = string.sub(bq.path, 1, i)
616            updatelist()
617            break
618          end
619        end
620      elseif (string.sub(f, string.len(f)) == '/') then
621        bq.path = bq.path .. f
622        updatelist()
623      else
624        if (bq.actioncb ~= nil) then
625          bq:actioncb(s)
626        end
627      end
628    end
629    bq:setActionCallback(cb)
630
631    function bq:setDoubleClickAction(cb)
632       bq:setMouseCallback(function(evt, btn, cnt)
633             if cnt == 2 and btn == 1 and evt == "mouseClick" then
634                cb()
635             end
636       end)
637       bq:setKeyCallback(function(evt, btn, cnt)
638             if cnt == 2 and btn == 1 and evt == "mouseClick" then
639                cb()
640             end
641       end)
642    end
643
644    bq.oldSetActionCallback = bq.setActionCallback
645    function bq:setActionCallback(cb)
646      bq.actioncb = cb
647    end
648
649    return bq
650  end
651
652  function menu:addCheckBox(caption, x, y, callback) --my new function
653	local b = ImageCheckBox(caption)
654    b:setBaseColor(clear)
655    b:setForegroundColor(clear)
656    b:setBackgroundColor(dark)
657	if (callback ~= nil) then b:setActionCallback(function(s) callback(b, s) end) end
658    b:setFont(Fonts["game"])
659    self:add(b, x, y)
660    return b
661  end
662
663  function menu:addImageCheckBox(caption, x, y, offi, offi2, oni, oni2, callback) --my new function
664	local b = ImageCheckBox(caption)
665    b:setBaseColor(clear)
666    b:setForegroundColor(clear)
667    b:setBackgroundColor(dark)
668	-- new functions to display checkbox graphics
669	if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
670        b:setUncheckedNormalImage(g_hcheckbox_off)
671		b:setUncheckedPressedImage(g_hcheckbox_off2)
672		b:setCheckedNormalImage(g_hcheckbox_on)
673		b:setCheckedPressedImage(g_hcheckbox_on2)
674    else
675		b:setUncheckedNormalImage(g_ocheckbox_off)
676		b:setUncheckedPressedImage(g_ocheckbox_off2)
677		b:setCheckedNormalImage(g_ocheckbox_on)
678		b:setCheckedPressedImage(g_ocheckbox_on2)
679    end
680	if (callback ~= nil) then b:setActionCallback(function(s) callback(b, s) end) end
681    b:setFont(Fonts["game"])
682    self:add(b, x, y)
683    return b
684  end
685
686 function menu:addRadioButton(caption, group, x, y, callback)
687    local b = RadioButton(caption, group)
688    b:setBaseColor(dark)
689    b:setForegroundColor(clear)
690    b:setBackgroundColor(dark)
691    b:setActionCallback(callback)
692    self:add(b, x, y)
693    return b
694  end
695
696 function menu:addImageRadioButton(caption, group, x, y, offi, offi2, oni, oni2, callback)
697    local b = ImageRadioButton(caption, group)
698    b:setBaseColor(dark)
699    b:setForegroundColor(clear)
700    b:setBackgroundColor(dark)
701	if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
702		b:setUncheckedNormalImage(g_hradio_off)
703		b:setUncheckedPressedImage(g_hradio_off2)
704		b:setCheckedNormalImage(g_hradio_on)
705		b:setCheckedPressedImage(g_hradio_on2)
706    else
707		b:setUncheckedNormalImage(g_oradio_off)
708		b:setUncheckedPressedImage(g_oradio_off2)
709		b:setCheckedNormalImage(g_oradio_on)
710		b:setCheckedPressedImage(g_oradio_on2)
711    end
712	b:setFont(Fonts["game"])
713    b:setActionCallback(callback)
714    self:add(b, x, y)
715    return b
716  end
717
718  function menu:addDropDown(list, x, y, callback)
719    local dd = ImageDropDownWidget()
720    dd:setFont(Fonts["game"])
721	if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
722		dd:setItemImage(g_hibar)
723		dd:setDownNormalImage(g_hdslider_n)
724		dd:setDownPressedImage(g_hdslider_p)
725	else
726		dd:setItemImage(g_oibar)
727		dd:setDownNormalImage(g_odslider_n)
728		dd:setDownPressedImage(g_odslider_p)
729	end
730    dd:setList(list)
731    dd:setActionCallback(function(s) callback(dd, s) end)
732
733
734    self:add(dd, x, y)
735    return dd
736  end
737
738  function menu:addTextInputField(text, x, y, w)
739    local b = ImageTextField(text)
740	if (GetPlayerData(GetThisPlayer(), "RaceName") == "human") then
741		b:setItemImage(g_hibar)
742	else
743		b:setItemImage(g_oibar)
744	end
745    b:setActionCallback(function() end) --FIXME: remove this?
746    b:setFont(Fonts["game"])
747    b:setBaseColor(clear)
748    b:setForegroundColor(clear)
749    b:setBackgroundColor(dark)
750    if (w == nil) then w = 100 end
751    b:setSize(w, 18)
752    self:add(b, x, y)
753    return b
754  end
755end
756
757function WarMenu(title, background, resize)
758  local menu
759  local exitButton
760  local bg
761  local bgg
762
763  menu = MenuScreen()
764
765  function menu:resize(w, h)
766     menu:setSize(w, h)
767     menu:setPosition(
768        (Video.Width - menu:getWidth()) / 2,
769        (Video.Height - menu:getHeight()) / 2
770     )
771  end
772
773  if background == nil then
774    bg = backgroundWidget
775  else
776    bgg = CGraphic:ForceNew(background)
777    bgg:Load()
778    if (resize == nil or resize == true) then
779       bgg:Resize(Video.Width, Video.Height)
780    elseif type(resize) == "table" then
781      bgg:Resize(resize[1], resize[2])
782      menu:resize(resize[1], resize[2])
783    end
784    bg = ImageWidget(bgg)
785  end
786  menu:add(bg, 0, 0)
787
788  AddMenuHelpers(menu)
789
790  if title then
791    menu:addLabel(title, Video.Width / 2, Video.Height / 20, Fonts["large"])
792  end
793
794  return menu
795end
796
797function WarMenuWithLayout(background, box)
798  box:calculateMinExtent()
799  local menu = WarMenu(title, background, {box.width, box.height})
800  menu:setSize(box.width, box.height)
801  menu:setPosition((Video.Width - menu:getWidth()) / 2, (Video.Height - menu:getHeight()) / 2)
802  menu:setDrawMenusUnder(true)
803  box:addWidgetTo(menu)
804  return menu
805end
806
807-- Default configurations -------
808Widget:setGlobalFont(Fonts["large"])
809
810
811DefaultObjectives = {_("-Destroy the enemy")}
812Objectives = DefaultObjectives
813
814
815-- Define the different menus ----------
816
817function InitGameSettings()
818	local resources = { "gold", "wood", "oil" }
819	for i=0, PlayerMax-1 do
820		for j = 1,table.getn(resources) do
821			SetSpeedResourcesHarvest(i, resources[j], 100)
822			SetSpeedResourcesReturn(i, resources[j], 100)
823		end
824		SetSpeedBuild(i, 100)
825		SetSpeedTrain(i, 100)
826		SetSpeedUpgrade(i, 100)
827		SetSpeedResearch(i, 100)
828	end
829	GameSettings.NetGameType = 1
830	for i=0, PlayerMax-1 do
831		GameSettings.Presets[i].PlayerColor = i
832		GameSettings.Presets[i].AIScript = _("Map Default")
833		GameSettings.Presets[i].Race = -1
834		GameSettings.Presets[i].Team = -1
835		GameSettings.Presets[i].Type = -1
836	end
837	GameSettings.Difficulty = -1
838	GameSettings.Resources = -1
839	GameSettings.NumUnits = -1
840	GameSettings.Opponents = -1
841	GameSettings.Terrain = -1
842	GameSettings.GameType = -1
843	GameSettings.NoFogOfWar = false
844	GameSettings.RevealMap = 0
845	GameSettings.Tileset = nil
846	IsSkirmishClassic = false
847  Load("scripts/fov.lua") -- Reload Default FOV settings because some maps|tilesets could change it
848  SetFogOfWarType(wc2.preferences.FogOfWarType) -- Reload default FOG type because changing fov type may cause to change it too
849end
850InitGameSettings()
851
852function RunMap(map, objective, fow, revealmap, results)
853  if objective == nil then
854    Objectives = DefaultObjectives
855  else
856    Objectives = objective
857  end
858  local loop = true
859  while (loop) do
860    InitGameVariables()
861    if fow ~= nil then
862      SetFogOfWar(fow)
863    end
864    if revealmap ~= nil then
865        local revealTypes = {"hidden", "known", "explored"}
866        RevealMap(revealTypes[revealmap + 1])
867    else
868      if GameSettings.RevealMap >= 2 then
869        if fow == nil and not IsNetworkGame() then
870          SetFogOfWar(false)
871        end
872        RevealMap("explored")
873      elseif GameSettings.RevealMap == 1 then
874        RevealMap("known")
875      elseif GameSettings.RevealMap == 0 and fow == nil and not IsNetworkGame() then
876        SetFogOfWar(wc2.preferences.FogOfWar)
877      end
878    end
879    StartMap(map)
880    if GameResult ~= GameRestart then
881      loop = false
882    else
883		StartCustomGame_Lua()
884	end
885  end
886  if (results ~= false) then
887	RunResultsMenu(s)
888  end
889  InitGameSettings()
890  SetDefaultRaceView()
891end
892
893function RunDemo()
894  Objectives = DefaultObjectives
895  local mapname = "maps/demo/demo0" .. math.random(1, 4) .. ".smp"
896  InitGameVariables()
897  SetFogOfWar(false)
898  RevealMap("explored")
899  OldShowTips = wc2.preferences.ShowTips
900  wc2.preferences.ShowTips = false
901  OldSinglePlayerTriggers = SinglePlayerTriggers
902  function SinglePlayerTriggers()
903    AddTrigger(
904     function() return GameCycle > 1000 end,
905     function() return ActionDraw() end)
906  end
907  Load(mapname)
908  GameSettings.Presets[0].Team = 1
909  GameSettings.Presets[1].Team = 2
910  GameSettings.Presets[2].Type = 3
911  GameSettings.Presets[2].Race = 2
912  StartMap(mapname)
913  wc2.preferences.ShowTips = OldShowTips
914  SinglePlayerTriggers = OldSinglePlayerTriggers
915  InitGameSettings()
916  SetDefaultRaceView()
917end
918
919function SetDefaultPlayerNames()
920-- Add player names according to player color
921	for i=0,7 do
922		if (GetPlayerData(i, "RaceName") == "human") then
923			if (i == 0) then
924				SetPlayerData(i, "Name", _("Nation of Stromgarde"))
925			elseif (i == 1) then
926				SetPlayerData(i, "Name", _("Nation of Azeroth"))
927			elseif (i == 2) then
928				SetPlayerData(i, "Name", _("Nation of Kul Tiras"))
929			elseif (i == 3) then
930				SetPlayerData(i, "Name", _("Nation of Dalaran"))
931			elseif (i == 4) then
932				SetPlayerData(i, "Name", _("Nation of Alterac"))
933			elseif (i == 5) then
934				SetPlayerData(i, "Name", _("Nation of Gilneas"))
935			elseif (i == 6) then
936				SetPlayerData(i, "Name", _("Nation of Lordaeron"))
937			elseif (i == 7) then
938				SetPlayerData(i, "Name", _("Alliance Traitors"))
939			end
940		elseif  (GetPlayerData(i, "RaceName") == "orc") then
941			if (i == 0) then
942				SetPlayerData(i, "Name", _("Blackrock Clan"))
943			elseif (i == 1) then
944				SetPlayerData(i, "Name", _("Stormreaver Clan"))
945			elseif (i == 2) then
946				SetPlayerData(i, "Name", _("Bleeding Hollow Clan"))
947			elseif (i == 3) then
948				SetPlayerData(i, "Name", _("Twilight's Hammer Clan"))
949			elseif (i == 4) then
950				SetPlayerData(i, "Name", _("Burning Blade Clan"))
951			elseif (i == 5) then
952				SetPlayerData(i, "Name", _("Black Tooth Grin Clan"))
953			elseif (i == 6) then
954				SetPlayerData(i, "Name", _("Dragonmaw Clan"))
955			elseif (i == 7) then
956				SetPlayerData(i, "Name", _("Laughing Skull Clan"))
957			end
958		end
959	end
960end
961
962mapname = "maps/skirmish/singleplayer/(2)blick-nach-oben.smp.gz"
963local buttonStatut = 0 -- 0:not initialised, 1: Ok, 2: Cancel
964mapinfo = {
965  playertypes = {nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
966  playerais = {nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
967  playerrace = {nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil},
968  description = "",
969  nplayers = 1,
970  w = 32,
971  h = 32,
972  id = 0
973}
974
975function GetMapInfo(mapname)
976  local OldDefinePlayerTypes = DefinePlayerTypes
977  local OldPresentMap = PresentMap
978  local OldSetAiType = SetAiType
979  local OldSetStartView = SetStartView
980  local OldSetPlayerData = SetPlayerData
981  local OldLoadTileModels = LoadTileModels
982  local OldSetTile = SetTile
983  local OldCreateUnit = CreateUnit
984  local OldSetResourcesHeld = SetResourcesHeld
985
986  mapinfo.playerais = {nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil}
987  mapinfo.playerrace = {nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil}
988  function DefinePlayerTypes(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)
989    mapinfo.playertypes[1] = p1
990    mapinfo.playertypes[2] = p2
991    mapinfo.playertypes[3] = p3
992    mapinfo.playertypes[4] = p4
993    mapinfo.playertypes[5] = p5
994    mapinfo.playertypes[6] = p6
995    mapinfo.playertypes[7] = p7
996    mapinfo.playertypes[8] = p8
997    mapinfo.playertypes[9] = p9
998    mapinfo.playertypes[10] = p10
999    mapinfo.playertypes[11] = p11
1000    mapinfo.playertypes[12] = p12
1001    mapinfo.playertypes[13] = p13
1002    mapinfo.playertypes[14] = p14
1003    mapinfo.playertypes[15] = p15
1004    mapinfo.nplayers = 0
1005    for i=0,15 do
1006      local t = mapinfo.playertypes[i]
1007	  if (t~= nil) then
1008		  if (t == "person" or t == "computer") then
1009			mapinfo.nplayers = mapinfo.nplayers + 1
1010		  end
1011	  end
1012    end
1013  end
1014
1015  function PresentMap(description, nplayers, w, h, id)
1016    mapinfo.description = description
1017    -- nplayers includes rescue-passive and rescue-active
1018    -- calculate the real nplayers in DefinePlayerTypes
1019    --mapinfo.nplayers = nplayers
1020    mapinfo.w = w
1021    mapinfo.h = h
1022    mapinfo.id = id
1023  end
1024
1025  Load(mapname)
1026
1027  DefinePlayerTypes = OldDefinePlayerTypes
1028  PresentMap = OldPresentMap
1029end
1030
1031function RunSelectScenarioMenu()
1032  buttonStatut = 0
1033  local menu = WarMenu(nil, panel(5), false)
1034  menu:setSize(352, 352)
1035  menu:setPosition((Video.Width - 352) / 2, (Video.Height - 352) / 2)
1036  menu:setDrawMenusUnder(true)
1037
1038  menu:addLabel(_("Select scenario"), 176, 8)
1039
1040  local browser = menu:addBrowser("maps/", "^.*%.smp%.?g?z?$",
1041    24, 140, 300, 108, mapname)
1042
1043  local l = menu:addLabel(browser:getSelectedItem(), 24, 260, Fonts["game"], false)
1044
1045  local function cb(s)
1046    l:setCaption(browser:getSelectedItem())
1047    l:adjustSize()
1048  end
1049  browser:setActionCallback(cb)
1050
1051  local okFunc = function()
1052     local cap = l:getCaption()
1053
1054     if (browser:getSelected() < 0) then
1055        return
1056     end
1057     buttonStatut = 1
1058     mapname = browser.path .. cap
1059     menu:stop()
1060  end
1061
1062  browser:setDoubleClickAction(okFunc)
1063
1064  menu:addHalfButton("~!OK", "o", 48, 318, okFunc)
1065  menu:addHalfButton(_("Cancel (~<Esc~>)"), "escape", 198, 318,
1066    function() buttonStatut = 2; menu:stop() end)
1067
1068  menu:run()
1069end
1070
1071function RunSinglePlayerTypeMenu()
1072
1073  wargus.playlist = { "music/Orc Briefing" .. wargus.music_extension }
1074  SetDefaultRaceView()
1075
1076  if not (IsMusicPlaying()) then
1077    PlayMusic("music/Orc Briefing" .. wargus.music_extension)
1078  end
1079
1080  local menu = WarMenu()
1081  local offx = (Video.Width - 640) / 2
1082  local offy = (Video.Height - 480) / 2
1083
1084  menu:addLabel(wargus.Name .. " V" .. wargus.Version .. ", " .. wargus.Copyright, offx + 320, (Video.Height - 90) + 18*4, Fonts["small"])
1085  menu:addLabel(_("~<Single Player~>"), offx + 320, offy + 212 - 25)
1086  local buttonNewMap =
1087  menu:addFullButton(_("~!Standard Game"), "s", offx + 208, offy + 104 + 36*3,
1088    function() RunSinglePlayerGameModeMenu(); menu:stop(1) end)
1089  menu:addFullButton(_("~!Campaign Game"), "c", offx + 208, offy + 104 + 36*4,
1090    function() RunModCampaignGameMenu(); menu:stop(1) end)
1091  menu:addFullButton(_("~!Load Game"), "l", offx + 208, offy + 104 + 36*5,
1092    function() RunLoadGameMenu(); menu:stop(1) end)
1093  menu:addFullButton(_("Previous Menu (~<Esc~>)"), "escape", offx + 208, offy + 104 + 36*6,
1094    function() menu:stop() end)
1095  return menu:run()
1096end
1097
1098function RunSinglePlayerGameModeMenu()
1099
1100  buttonStatut = 0
1101  local menu = WarMenu(nil, panel(5), false)
1102  menu:setSize(352, 352)
1103  menu:setPosition((Video.Width - 352) / 2, (Video.Height - 352) / 2)
1104  menu:setDrawMenusUnder(true)
1105
1106  menu:addLabel(_("Standard Game"), 176, 8)
1107
1108  local browser = menu:addBrowser("scripts/lists/maps/", "", 24, (24+8+8), (300+5), (318-24-8-8-24), "Skirmish Modern", true)
1109
1110  local okFunc = function()
1111     if (browser:getSelected() < 0) then
1112        return
1113     end
1114     Load(browser.path .. browser:getSelectedItem())
1115     menu:stop()
1116  end
1117
1118  browser:setDoubleClickAction(okFunc)
1119
1120  menu:addHalfButton("~!OK", "o", 48, 318, okFunc)
1121  menu:addHalfButton(_("~!Cancel"), "c", 198, 318,
1122    function() buttonStatut = 2; menu:stop(1); RunSinglePlayerTypeMenu() end)
1123
1124  menu:run()
1125
1126end
1127
1128function RunSinglePlayerGameMenu()
1129  local menu = WarMenu()
1130  local offx = (Video.Width - 640) / 2
1131  local offy = (Video.Height - 480) / 2
1132  local d
1133  local race
1134  local resources
1135  local opponents
1136  local numunits
1137  local gametype
1138  local mapl
1139  local descriptionl
1140  local tilesetdd
1141
1142  -- Setup variables
1143  local nameslist = {"1:","2:","3:","4:","5:","6:","7:","8:","9:","10:","11:","12:","13:","14:","15:"}
1144  local colorlist = {_("~red~Red"),_("~blue~Blue"),_("~green~Green"),_("~violet~Violet"),_("~orange~Orange"),_("~black~Black"),
1145	_("~white~White"),_("~yellow~Yellow")}
1146  local sidelist = {_("Map Default"), _("Human"),_("Orc"),_("Random")}
1147  local teamlist = {"-","1","2","3","4"}
1148  local playerlist = {_("Player"),_("Computer"),_("Rescue-passive"),_("Rescue-active"),_("None")}
1149  local reveal_list = {_("Hidden"),_("Known"),_("Revealed")}
1150  local game_types = {_("Use map settings"), _("Melee"), _("Free for all"), _("Top vs bottom"), _("Left vs right"), _("Man vs Machine")}
1151  local tileset_names = {_("Map Default"), _("Summer"), _("Swamp"), _("Wasteland"), _("Winter")}
1152  local numunit_types = {_("Map Default"), _("One Peasant Only")}
1153  local difficulty_types = {_("Easy"), _("Normal"), _("Hard"),_("Nightmare"),_("Hell")}
1154  local resource_types = {_("Map Default"), _("Low"), _("Medium"), _("High"),_("Quick Start")}
1155  local nms = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
1156  local pcolor = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
1157  local ptype = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
1158  local paitype = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
1159  local pside = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
1160  local teams = {nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil}
1161  local rescount = nil
1162  local game_type = nil
1163  local difficulty = nil
1164  local max_score = nil
1165  local reveal_type = nil
1166
1167  -- Logo
1168  menu:addLabel(_("~<Single Player Game Setup~>"), offx + 640/2 + 12, offy + 35)
1169  -- Copyright information.
1170  menu:addLabel(wargus.Name .. " V" .. wargus.Version .. ", " .. wargus.Copyright, offx + 320, (Video.Height - 90) + 18*4, Fonts["small"])
1171
1172  -- Error handling function
1173  function ErrorMessage(errmsg)
1174	  local menu = WarMenu(nil, panel(4), false)
1175	  menu:setSize(288, 128)
1176	  menu:setPosition((Video.Width - 288) / 2, (Video.Height - 128) / 2)
1177	  menu:setDrawMenusUnder(true)
1178
1179	  menu:addLabel(_("Error:"), 144, 11)
1180
1181	  local l = MultiLineLabel(errmsg)
1182	  l:setFont(Fonts["large"])
1183	  l:setAlignment(MultiLineLabel.CENTER)
1184	  l:setVerticalAlignment(MultiLineLabel.CENTER)
1185	  l:setLineWidth(270)
1186	  l:setWidth(270)
1187	  l:setHeight(41)
1188	  l:setBackgroundColor(dark)
1189	  menu:add(l, 9, 38)
1190
1191	  menu:addHalfButton("~!OK", "o", 92, 80, function() menu:stop() end)
1192
1193	  menu:run()
1194  end
1195
1196  -- Check for correct data before start
1197  function CheckCorrect()
1198	local firstTeam=0
1199	local firstTeam2=0
1200	--Team Check
1201	for i=0,15 do
1202		if teams[i+1]~=nil then
1203			if teams[i+1]:isVisible() and teams[i+1]:getSelected()~=0 then
1204				firstTeam = teams[i+1]:getSelected()
1205				break
1206			elseif teams[i+1]:getSelected()==0 then
1207				firstTeam = -1
1208				firstTeam2 = i
1209				break
1210			end
1211		end
1212	end
1213	if firstTeam > -1 then
1214		for j=firstTeam2+1,15 do
1215			if teams[j+1]~=nil then
1216				if teams[j+1]:isVisible() and teams[j+1]:getSelected()~=firstTeam then
1217					break
1218				elseif j==15 then
1219					return 1 -- only 1 team
1220				end
1221			end
1222		end
1223	end
1224	--PlayerCheck
1225	local personcount = 0
1226	local compcount = 0
1227	for i=0,15 do
1228		if ptype[i+1]~=nil then
1229			if ptype[i+1]:isVisible() and ptype[i+1]:getSelected()==0 then
1230				personcount = personcount + 1
1231			elseif ptype[i+1]:isVisible() and ptype[i+1]:getSelected()==1 then
1232				compcount = compcount + 1
1233			end
1234		end
1235	end
1236	if compcount == 0 and personcount == 0 then
1237		return 2 -- no players or computers
1238	elseif compcount>0 and personcount == 0 then
1239		return 3 -- only computers and no player
1240	elseif compcount+personcount < 2 then
1241		return 4 -- only one player
1242	end
1243	--Success
1244	return 0
1245  end
1246
1247  if mapname == nil then
1248	mapname = "maps/skirmish/singleplayer/(2)blick-nach-oben.sms.gz"
1249  end
1250
1251  menu:addLabel(_("Scenario:"), offx + 16, offy + 360, Fonts["game"], false)
1252  mapl = menu:addLabel(string.sub(mapname, 6), offx + 16, offy + 360 + 24, Fonts["game"], false)
1253  descriptionl = menu:addLabel("descriptionl", offx + 16 + 70, offy + 360, Fonts["game"], false)
1254
1255
1256  menu:addFullButton(_("S~!elect Scenario"), "e", offx + 640 - 224 - 16, offy + 360 + 36*0,
1257    function()
1258      local oldmapname = mapname
1259      RunSelectScenarioMenu()
1260      if (mapname ~= oldmapname) then
1261        GetMapInfo(mapname)
1262        MapChanged()
1263      end
1264    end)
1265  menu:addFullButton(_("~!Start Game"), "s", offx + 640 - 224 - 16, offy + 360 + 36*1,
1266    function()
1267      local tilesetFilename = {nil, "summer.lua", "swamp.lua", "wasteland.lua", "winter.lua"}
1268	  InitGameSettings()
1269		local errorlevel = CheckCorrect()
1270		if errorlevel==1 then
1271			ErrorMessage(_("Need more than 1 team"))
1272		elseif errorlevel==2 then
1273			ErrorMessage(_("No players selected"))
1274		elseif errorlevel==3 then
1275			ErrorMessage(_("Need at least 1 person player"))
1276		elseif errorlevel==4 then
1277			ErrorMessage(_("Need at least 2 players"))
1278		else
1279			local wefoundperson = false
1280			for i=0,14 do
1281				if pside[i+1]==nil then
1282					GameSettings.Presets[i].Race = 0
1283				elseif (pside[i+1]:getSelected() == 3) then
1284					GameSettings.Presets[i].Race = math.random(1, 2)
1285				else
1286					GameSettings.Presets[i].Race = pside[i+1]:getSelected()
1287				end
1288				if teams[i+1]==nil then
1289					GameSettings.Presets[i].Team = -1
1290				else
1291					GameSettings.Presets[i].Team = teams[i+1]:getSelected()
1292				end
1293				if ptype[i+1]==nil then
1294					GameSettings.Presets[i].Type = -1
1295				elseif ptype[i+1]:getSelected()==0 then
1296					if wefoundperson == false then
1297						wefoundperson = true
1298						GameSettings.Presets[i].Type = PlayerPerson
1299					else
1300						GameSettings.Presets[i].Type = PlayerComputer
1301					end
1302				elseif ptype[i+1]:getSelected()==1 then
1303					GameSettings.Presets[i].Type = PlayerComputer
1304				elseif ptype[i+1]:getSelected()==2 then
1305					GameSettings.Presets[i].Type = PlayerRescuePassive
1306				elseif ptype[i+1]:getSelected()==3 then
1307					GameSettings.Presets[i].Type = PlayerRescueActive
1308				elseif ptype[i+1]:getSelected()==4 then
1309					GameSettings.Presets[i].Type = -1
1310				end
1311				if pcolor[i+1]==nil then
1312					GameSettings.Presets[i].PlayerColor = i
1313				else
1314					GameSettings.Presets[i].PlayerColor = pcolor[i+1]:getSelected()
1315				end
1316				if paitype[i+1] ~= nil and paitype[i+1]:getSelected() > 0 then
1317					GameSettings.Presets[i].AIScript = AIStrategyTypes[paitype[i+1]:getSelected() + 1]
1318				end
1319			end
1320			GameSettings.Difficulty = difficulty:getSelected() + 1
1321			GameSettings.GameType = game_type:getSelected() - 1
1322			GameSettings.Resources = rescount:getSelected()
1323			GameSettings.RevealMap = reveal_type:getSelected()
1324			GameSettings.NumUnits = numunits:getSelected()
1325			GameSettings.Tileset = tilesetFilename[tilesetdd:getSelected() + 1]
1326			GameSettings.NetGameType = 1
1327			Load(mapname)
1328			RunMap(mapname)
1329			menu:stop()
1330		end
1331    end)
1332
1333  -- Player redrawing function
1334  function PlayersRedraw()
1335	local offset=0
1336	  for i=0,15 do
1337		if nms[i+1]~=nil then
1338			nms[i+1]:setVisible(false)
1339		end
1340		if ptype[i+1]~=nil then
1341			ptype[i+1]:setVisible(false)
1342		end
1343		if pside[i+1]~=nil then
1344			pside[i+1]:setVisible(false)
1345		end
1346		if pcolor[i+1]~=nil then
1347			pcolor[i+1]:setVisible(false)
1348		end
1349		if teams[i+1]~=nil then
1350			teams[i+1]:setVisible(false)
1351		end
1352		if paitype[i+1]~=nil then
1353			paitype[i+1]:setVisible(false)
1354		end
1355	  end
1356	  for i=0,15 do
1357	    if mapinfo.playertypes[i+1] ~= "nobody" and mapinfo.playertypes[i+1] ~= nil then
1358		  nms[i+1] = menu:addLabel(nameslist[i+1], offx + 2 , offy + 80+offset+15,Fonts["game"], false)
1359		  offset=offset+25
1360	    end
1361	  end
1362	  offset=0
1363	  menu:addLabel(_("~<Color:~>"), offx+25, offy +10+60,Fonts["game"], false)
1364	  for i=0,15 do
1365	    if mapinfo.playertypes[i+1] ~= "nobody" and mapinfo.playertypes[i+1] ~= nil then
1366		  pcolor[i+1] = menu:addDropDown(colorlist, offx + 20, offy + 10 + 80+ offset, function(dd) end)
1367		  if (i > 7) then
1368		    pcolor[i+1]:setSelected(i-8)
1369		  else
1370		    pcolor[i+1]:setSelected(i)
1371		  end
1372		  pcolor[i+1]:setSize(60, 20)
1373		  pcolor[i+1]:setActionCallback(
1374		  function()
1375		  	sk_pcolor[i+1] = pcolor[i+1]:getSelected()
1376		  end)
1377		  if sk_pcolor[i+1]~=-1 then
1378			pcolor[i+1]:setSelected(sk_pcolor[i+1])
1379		  end
1380		  offset=offset+25
1381	    end
1382	  end
1383	  offset=0
1384	  menu:addLabel(_("~<Type:~>"), offx+100, offy +10+60,Fonts["game"], false)
1385	  for i=0,15 do
1386		if mapinfo.playertypes[i+1] ~= "nobody" and mapinfo.playertypes[i+1] ~= nil  then
1387			ptype[i+1] = menu:addDropDown(playerlist, offx + 85, offy + 10 + 80+ offset, function(dd) end)
1388			if mapinfo.playertypes[i+1] == "computer" then
1389				ptype[i+1]:setSelected(1)
1390			elseif mapinfo.playertypes[i+1] == "rescue-passive" then
1391				ptype[i+1]:setSelected(2)
1392			elseif mapinfo.playertypes[i+1] == "rescue-active" then
1393				ptype[i+1]:setSelected(3)
1394			end
1395			ptype[i+1]:setSize(80, 20)
1396			ptype[i+1]:setActionCallback(
1397			function()
1398				sk_ptype[i+1] = ptype[i+1]:getSelected()
1399			end)
1400			if sk_ptype[i+1]~=-1 then
1401				ptype[i+1]:setSelected(sk_ptype[i+1])
1402			end
1403			offset=offset+25
1404		end
1405	  end
1406	  offset=0
1407	  menu:addLabel(_("~<Race:~>"), offx+170, offy +10+60,Fonts["game"], false)
1408	  for i=0,15 do
1409		if mapinfo.playertypes[i+1] ~= "nobody" and mapinfo.playertypes[i+1] ~= nil  then
1410		pside[i+1] = menu:addDropDown(sidelist, offx + 170, offy + 10 + 80+ offset, function(dd) end)
1411		if mapinfo.playerrace[i+1] == "human" then
1412			pside[i+1]:setSelected(1)
1413		elseif mapinfo.playerrace[i+1] == "orc" then
1414			pside[i+1]:setSelected(2)
1415		end
1416		pside[i+1]:setSize(70, 20)
1417		pside[i+1]:setActionCallback(
1418		function()
1419			sk_pside[i+1] = pside[i+1]:getSelected()
1420		end)
1421		if sk_pside[i+1]~=-1 then
1422			pside[i+1]:setSelected(sk_pside[i+1])
1423		end
1424		offset=offset+25
1425		end
1426	  end
1427	  offset=0
1428	  menu:addLabel(_("~<Teams:~>"), offx+238, offy +10+60,Fonts["game"], false)
1429	  for i=0,15 do
1430		if mapinfo.playertypes[i+1] ~= "nobody" and mapinfo.playertypes[i+1] ~= nil  then
1431		teams[i+1] = menu:addDropDown(teamlist, offx + 245, offy + 10 + 80 +offset, function(dd) end)
1432		teams[i+1]:setSize(40, 20)
1433		teams[i+1]:setActionCallback(
1434		function()
1435			sk_teams[i+1] = teams[i+1]:getSelected()
1436		end)
1437		if sk_teams[i+1]~=-1 then
1438			teams[i+1]:setSelected(sk_teams[i+1])
1439		end
1440		offset=offset+25
1441		end
1442	  end
1443	  offset=0
1444	  menu:addLabel(_("~<AI Script:~>"), offx+320, offy +10+60,Fonts["game"], false)
1445	  for i=0,15 do
1446		if mapinfo.playertypes[i+1] ~= "nobody" and mapinfo.playertypes[i+1] ~= nil  then
1447		paitype[i+1] = menu:addDropDown(AIStrategyTypes, offx + 290, offy + 10 + 80 +offset, function(dd) end)
1448		for cc = 1, table.getn(AIStrategyTypes) do
1449			if mapinfo.playerais[i+1] == AIStrategyTypes[cc] then
1450
1451				paitype[i+1]:setSelected(cc-1)
1452				break
1453			end
1454		end
1455		paitype[i+1]:setSize(130, 20)
1456		paitype[i+1]:setActionCallback(
1457		function()
1458			sk_paitype[i+1] = paitype[i+1]:getSelected()
1459		end)
1460		if sk_paitype[i+1]~=-1 then
1461			paitype[i+1]:setSelected(sk_paitype[i+1])
1462		end
1463		offset=offset+25
1464		end
1465	  end
1466
1467	  for i=0,15 do
1468		if mapinfo.playertypes[i+1] == "nobody" or mapinfo.playertypes[i+1] == nil then
1469			if nms[i+1] ~= nil then
1470				nms[i+1]:setVisible(false)
1471			end
1472			if pcolor[i+1] ~= nil then
1473				pcolor[i+1]:setVisible(false)
1474			end
1475			if ptype[i+1] ~= nil then
1476				ptype[i+1]:setVisible(false)
1477				ptype[i+1]:setSelected(2)
1478			end
1479			if pside[i+1] ~= nil then
1480				pside[i+1]:setVisible(false)
1481			end
1482			if teams[i+1] ~= nil then
1483				teams[i+1]:setVisible(false)
1484			end
1485			if paitype[i+1] ~= nil then
1486				paitype[i+1]:setVisible(false)
1487			end
1488		end
1489	  end
1490  end
1491
1492  menu:addFullButton(_("~!Cancel Game"), "c", offx + 640 - 224 - 16, offy + 360 + 36*2, function()  menu:stop(1); RunSinglePlayerTypeMenu() end)
1493
1494  menu:addLabel(_("~<Terrain:~>"), offx + 450, offy + 74, Fonts["game"], false)
1495  reveal_type = menu:addDropDown(reveal_list, offx + 450, offy + 90,
1496    function(dd) end)
1497  reveal_type:setSize(170, 20)
1498  reveal_type:setActionCallback(
1499	function()
1500		sk_reveal_type = reveal_type:getSelected()
1501	end)
1502	if sk_reveal_type~=-1 then
1503		reveal_type:setSelected(sk_reveal_type)
1504	end
1505
1506  menu:addLabel(_("~<Game Type:~>"), offx + 450, offy + 114, Fonts["game"], false)
1507  game_type = menu:addDropDown(game_types, offx + 450, offy + 130,
1508   function(dd) TimerRedraw() end)
1509  game_type:setSize(170, 20)
1510  game_type:setActionCallback(
1511	function()
1512		sk_game_type = game_type:getSelected()
1513	end)
1514	if sk_game_type~=-1 then
1515		game_type:setSelected(sk_game_type)
1516	end
1517
1518  menu:addLabel(_("~<Resources:~>"), offx + 450, offy + 154, Fonts["game"], false)
1519  rescount = menu:addDropDown(resource_types, offx + 450, offy + 170,
1520    function(dd) end)
1521  rescount:setSize(170, 20)
1522  rescount:setActionCallback(
1523	function()
1524		sk_rescount = rescount:getSelected()
1525	end)
1526	if sk_rescount~=-1 then
1527		rescount:setSelected(sk_rescount)
1528	end
1529
1530  menu:addLabel(_("~<AI Difficulty:~>"), offx + 450, offy + 194, Fonts["game"], false)
1531  difficulty = menu:addDropDown(difficulty_types, offx + 450, offy + 210,
1532    function(dd) end)
1533  difficulty:setSize(170, 20)
1534  difficulty:setSelected(2)
1535  difficulty:setActionCallback(
1536	function()
1537		sk_difficulty = difficulty:getSelected()
1538	end)
1539	if sk_difficulty~=-1 then
1540		difficulty:setSelected(sk_difficulty)
1541	end
1542
1543  menu:addLabel(_("~<Tileset:~>"), offx + 450, offy + 234, Fonts["game"], false)
1544  tilesetdd = menu:addDropDown(tileset_names, offx + 450, offy + 250,
1545    function(dd) end)
1546  tilesetdd:setSize(170, 20)
1547  tilesetdd:setActionCallback(
1548	function()
1549		sk_tileset = tilesetdd:getSelected()
1550	end)
1551	if sk_tileset~=-1 then
1552		tilesetdd:setSelected(sk_tileset)
1553	end
1554  menu:addLabel(_("~<Units:~>"), offx + 450, offy + 274, Fonts["game"], false)
1555  numunits = menu:addDropDown(numunit_types, offx + 450, offy + 290,
1556    function(dd) end)
1557  numunits:setSize(170, 20)
1558  numunits:setActionCallback(
1559	function()
1560		sk_numunits = numunits:getSelected()
1561	end)
1562	if sk_numunits~=-1 then
1563		numunits:setSelected(sk_numunits)
1564	end
1565
1566  function MapChanged()
1567    mapl:setCaption(string.sub(mapname, 6))
1568    mapl:adjustSize()
1569
1570    descriptionl:setCaption(mapinfo.description ..
1571      " (" .. mapinfo.w .. " x " .. mapinfo.h .. ")")
1572    descriptionl:adjustSize()
1573
1574    PlayersRedraw()
1575  end
1576
1577  GetMapInfo(mapname)
1578  MapChanged()
1579
1580  menu:run()
1581end
1582
1583function BuildProgramStartMenu()
1584  wargus.playlist = { "music/Orc Briefing" .. wargus.music_extension }
1585  SetDefaultRaceView()
1586
1587  if not (IsMusicPlaying()) then
1588    PlayMusic("music/Orc Briefing" .. wargus.music_extension)
1589  end
1590
1591  local menu = WarMenu()
1592  local offx = (Video.Width - 640) / 2
1593  local offy = (Video.Height - 480) / 2
1594
1595  --menu:addLabel(wargus.Name .. " V" .. wargus.Version .. "  " .. wargus.Homepage, offx + 320, offy + 390 + 18*0)
1596  --menu:addLabel("Stratagus V" .. GetStratagusVersion() .. "  " .. GetStratagusHomepage(), offx + 320, offy + 390 + 18*1)
1597  --menu:addLabel(wargus.Copyright, offx + 320, offy + 390 + 18*4)
1598
1599  menu:addLabel(wargus.Name .. _(" V") .. wargus.Version .. ", " .. wargus.Copyright, offx + 320, (Video.Height - 90) + 18*4, Fonts["small"])
1600
1601  menu:addFullButton(_("~!Single Player Game"), "s", offx + 208, offy + 104 + 36*0,
1602    function() RunSinglePlayerTypeMenu(); menu:stop(1) end)
1603  menu:addFullButton(_("~!Multi Player Game"), "m", offx + 208, offy + 104 + 36*1,
1604                     function() RunMultiPlayerGameMenu(); menu:stop(1) end)
1605  menu:addFullButton(_("~!Replay Game"), "r", offx + 208, offy + 104 + 36*2,
1606    function() RunReplayGameMenu(); menu:stop(1) end)
1607  menu:addFullButton(_("~!Options"), "o", offx + 208, offy + 104 + 36*3,
1608    function() RunOptionsSubMenu(); menu:stop(1) end)
1609  menu:addFullButton(_("~!Load Mod"), "l", offx + 208, offy + 104 + 36*4,
1610    function() RunLoadModMenu(); menu:stop(1) end)
1611  menu:addFullButton(_("Map ~!Editor"), "e", offx + 208, offy + 104 + 36*5,
1612    function() RunEditorMenu(); menu:stop(1) end)
1613  menu:addFullButton(_("S~!how Credits"), "h", offx + 208, offy + 104 + 36*6, RunShowCreditsMenu)
1614
1615  menu:addFullButton(_("E~!xit Program"), "x", offx + 208, offy + 104 + 36*7,
1616    function() menu:stop() end)
1617
1618  local time = 0
1619  function checkRunDemo()
1620    time = time +1
1621    if (time > 2000) then
1622      time = 0
1623      RunDemo()
1624      wargus.playlist = { "music/Orc Briefing" .. wargus.music_extension }
1625      PlayMusic("music/Orc Briefing" .. wargus.music_extension)
1626    end
1627  end
1628  local listener = LuaActionListener(function(s) checkRunDemo() end)
1629  menu:addLogicCallback(listener)
1630
1631  return menu:run()
1632end
1633
1634LoadGameFile = nil
1635
1636function RunProgramStartMenu()
1637  local continue = 1
1638
1639  while continue == 1 do
1640    if (LoadGameFile ~= nil) then
1641      LoadGame(LoadGameFile)
1642    else
1643      continue = BuildProgramStartMenu(menu)
1644    end
1645  end
1646end
1647
1648function RunLoadModMenu()
1649  buttonStatut = 0
1650  local menu = WarMenu(nil, panel(5), false)
1651  menu:setSize(352, 352)
1652  menu:setPosition((Video.Width - 352) / 2, (Video.Height - 352) / 2)
1653  menu:setDrawMenusUnder(true)
1654
1655  menu:addLabel(_("Load Mod"), 176, 8)
1656
1657  local browser = menu:addBrowser("scripts/lists/mods/", "", 24, (24+8+8), (300+5), (318-24-8-8-24), "", true)
1658
1659  local okFunc = function()
1660     if (browser:getSelected() < 0) then
1661        return
1662     end
1663     Load(browser.path .. browser:getSelectedItem())
1664     menu:stop()
1665  end
1666
1667  browser:setDoubleClickAction(okFunc)
1668
1669  menu:addHalfButton("~!OK", "o", 48, 318, okFunc)
1670  menu:addHalfButton(_("Cancel (~<Esc~>)"), "escape", 198, 318,
1671    function() buttonStatut = 2; menu:stop() end)
1672
1673  menu:run()
1674end
1675
1676function RunModCampaignGameMenu()
1677  local menu = WarMenu()
1678  local offx = (Video.Width - 640) / 2
1679  local offy = (Video.Height - 480) / 2
1680
1681  local path = "scripts/lists/campaigns/"
1682  local campaignList = ListFilesInDirectory(path, true)
1683  local lastCampaign = 0
1684  local currentPrefix = nil
1685  local usedAccellerators = {}
1686
1687  for i,f in ipairs(campaignList) do
1688     local prefix = string.match(f, "^([%w%s]+%w)")
1689     local btn = string.match(f, "%(([%w%s]+%w)%)$")
1690     if btn and prefix then
1691        if prefix ~= currentPrefix then
1692           currentPrefix = prefix
1693           local label = menu:addLabel(currentPrefix, Video.Width / 2, offy + 104 + 36*lastCampaign)
1694           label:setAlignment(MultiLineLabel.CENTER)
1695           lastCampaign = lastCampaign + 0.5
1696        end
1697     else
1698        btn = f
1699     end
1700     local accell = ""
1701     for idx=1,#btn do
1702        local used = false
1703        accell = string.lower(string.sub(btn, idx, idx))
1704        for _,usedAccel in ipairs(usedAccellerators) do
1705           if usedAccel == accell then
1706              used = true
1707              break
1708           end
1709        end
1710        if not used then
1711           table.insert(usedAccellerators, accell)
1712           btn = string.sub(btn, 1, idx - 1) .. "~!" .. string.sub(btn, idx)
1713           break
1714        else
1715           accell = ""
1716        end
1717     end
1718     menu:addFullButton(btn, accell, offx + 208, offy + 104 + 36*lastCampaign, function()
1719                           Load(path .. f)
1720                           menu:stop()
1721     end)
1722     lastCampaign = lastCampaign + 1
1723  end
1724
1725  menu:addFullButton(_("Previous Menu (~<Esc~>)"), "escape", offx + 208, offy + 104 + 36*(lastCampaign + 2),
1726    function() menu:stop() end)
1727
1728  menu:run()
1729end
1730
1731Load("scripts/menus/campaign.lua")
1732Load("scripts/menus/load.lua")
1733Load("scripts/menus/save.lua")
1734Load("scripts/menus/replay.lua")
1735Load("scripts/menus/options.lua")
1736Load("scripts/menus/editor.lua")
1737Load("scripts/menus/credits.lua")
1738Load("scripts/menus/game.lua")
1739Load("scripts/menus/help.lua")
1740Load("scripts/menus/objectives.lua")
1741Load("scripts/menus/endscenario.lua")
1742Load("scripts/menus/diplomacy.lua")
1743Load("scripts/menus/results.lua")
1744Load("scripts/menus/network.lua")
1745
1746Load("scripts/lib/layouts.lua")
1747
1748function GameStarting()
1749  if (wc2.preferences.ShowTips and not IsReplayGame() and not IsNetworkGame()) then
1750    SetGamePaused(true)
1751    RunTipsMenu()
1752  end
1753  if GameSettings.NetGameType == 1 then
1754		if GameSettings.GameType==0 or GameSettings.GameType==1 then
1755			for plrs=0,14 do
1756				for plrs2=0,14 do
1757					if plrs==plrs2 then
1758					else
1759						if GameSettings.Presets[plrs].Team == -1 then
1760						elseif GameSettings.Presets[plrs].Team == 0 then
1761							if GameSettings.Presets[plrs].Type == PlayerComputer and GameSettings.Presets[plrs2].Type == PlayerComputer then
1762								SetDiplomacy(plrs, "allied" , plrs2)
1763								SetSharedVision(plrs, true, plrs2)
1764							else
1765								SetDiplomacy(plrs, "enemy" , plrs2)
1766								SetSharedVision(plrs, false, plrs2)
1767							end
1768						else
1769							if GameSettings.Presets[plrs].Team == GameSettings.Presets[plrs2].Team then
1770								SetDiplomacy(plrs, "allied" , plrs2)
1771								SetSharedVision(plrs, true, plrs2)
1772							else
1773								SetDiplomacy(plrs, "enemy" , plrs2)
1774								SetSharedVision(plrs, false, plrs2)
1775							end
1776						end
1777					end
1778				end
1779			end
1780		end
1781	end
1782end
1783
1784if (CustomStartup) then
1785   CustomStartup()
1786   return
1787end
1788
1789if SetShader then
1790   SetShader(wc2.preferences.VideoShader)
1791end
1792
1793if (Editor.Running == EditorCommandLine) then
1794  if (CliMapName and CliMapName ~= "") then
1795    StartEditor(CliMapName)
1796  else
1797    RunEditorMenu()
1798  end
1799else
1800  if (CliMapName and CliMapName ~= "") then
1801    RunMap(CliMapName)
1802  else
1803    RunProgramStartMenu()
1804  end
1805end
1806