1
2--  Menu for new map to edit
3local function RunEditorNewMapMenu()
4  local menu = WarMenu()
5  local offx = (Video.Width - 640) / 2
6  local offy = (Video.Height - 480) / 2
7  local tilesets = { "summer", "swamp", "wasteland", "winter"}
8  local tilesets1 = {_("Summer"), _("Swamp"), _("Wasteland"), _("Winter")}
9  local mapSizes = {"32", "64", "96", "128", "160", "192", "224", "256"}
10  local tilesetLabel = _("TileSet : ")
11  local sizeLabel = _("Size :")
12
13  menu:addLabel(_("Map description :"), offx + 208, offy + 104 + 32 * 0, Fonts["game"], false)
14  local mapDescription = menu:addTextInputField("", offx + 208, offy + 104 + 32 * 1, 200)
15  menu:addLabel(tilesetLabel, offx + 208, offy + 104 + 32 * 2, Fonts["game"], false)
16  local dropDownTileset = menu:addDropDown(tilesets1, offx + 208 + CFont:Get("game"):Width(tilesetLabel) + 10, offy + 104 + 32 * 2, function() end)
17
18  menu:addLabel(sizeLabel, offx + 208, offy + 104 + 32 * 3, Fonts["game"], false)
19  local mapSizex = menu:addDropDown(mapSizes, offx + 208 + CFont:Get("game"):Width(sizeLabel) + 10, offy + 104 + 32 * 3, function() end)
20  mapSizex:setWidth(50)
21  mapSizex:setSelected(3)
22  menu:addLabel("x", offx + 208 + CFont:Get("game"):Width(sizeLabel) + 70, offy + 104 + 32 * 3, Fonts["game"], false)
23  local mapSizey = menu:addDropDown(mapSizes, offx + 208 + CFont:Get("game"):Width(sizeLabel) + 90, offy + 104 + 32 * 3, function() end)
24  mapSizey:setWidth(50)
25  mapSizey:setSelected(3)
26
27  menu:addFullButton(_("~!New map"), "n", offx + 208, offy + 104 + 36 * 5,
28    function()
29      -- TODO : check value
30      Map.Info.Description = mapDescription:getText()
31      Map.Info.MapWidth = mapSizes[1 + mapSizex:getSelected()]
32      Map.Info.MapHeight = mapSizes[1 + mapSizey:getSelected()]
33      Map.Info.Preamble = ""
34      Map.Info.Postamble = ""
35      LoadTileModels("scripts/tilesets/" .. tilesets[1 + dropDownTileset:getSelected()] .. ".lua")
36      menu:stop()
37      StartEditor(nil)
38      RunEditorMenu()
39    end)
40  menu:addFullButton(_("Cancel (~<Esc~>)"), "escape", offx + 208, offy + 104 + 36 * 6, function() menu:stop(1); RunEditorMenu() end)
41  return menu:run()
42end
43
44-- Menu for loading map to edit
45local function RunEditorLoadMapMenu()
46  local menu = WarMenu()
47  local offx = (Video.Width - 640) / 2
48  local offy = (Video.Height - 480) / 2
49  local labelMapName
50  local labelDescription
51  local labelNbPlayer
52  local labelMapSize
53
54  -- update label content
55  local function MapChanged()
56    labelMapName:setCaption(_("File : ") .. string.sub(mapname, 6))
57    labelMapName:adjustSize()
58
59    labelNbPlayer:setCaption(_("Players : ") .. mapinfo.nplayers)
60    labelNbPlayer:adjustSize()
61
62    labelDescription:setCaption(_("Scenario : ") .. mapinfo.description)
63    labelDescription:adjustSize()
64
65    labelMapSize:setCaption(_("Size : ") .. mapinfo.w .. " x " .. mapinfo.h)
66    labelMapSize:adjustSize()
67  end
68
69  labelMapName = menu:addLabel("", offx + 208, offy + 104 + 36 * 0, Fonts["game"], false)
70  labelDescription = menu:addLabel("", offx + 208, offy + 104 + 32 * 1, Fonts["game"], false)
71  labelNbPlayer = menu:addLabel("", offx + 208, offy + 104 + 32 * 2, Fonts["game"], false)
72  labelMapSize = menu:addLabel("", offx + 208, offy + 104 + 32 * 3, Fonts["game"], false)
73
74  menu:addFullButton(_("~!Select map"), "s", offx + 208, offy + 104 + 36 * 4,
75    function()
76      local oldmapname = mapname
77      RunSelectScenarioMenu()
78      if (mapname ~= oldmapname) then
79        GetMapInfo(mapname)
80        MapChanged()
81      end
82    end)
83
84  menu:addFullButton(_("~!Edit map"), "e", offx + 208, offy + 104 + 36 * 5, function() menu:stop(); StartEditor(mapname); RunEditorMenu() end)
85  menu:addFullButton(_("Cancel (~<Esc~>)"), "escape", offx + 208, offy + 104 + 36 * 6, function() menu:stop(1); RunEditorMenu() end)
86
87  GetMapInfo(mapname)
88  MapChanged()
89  return menu:run()
90end
91
92-- root of the editor menu
93function RunEditorMenu()
94  wargus.playlist = { "music/Orc Briefing" .. wargus.music_extension }
95  SetDefaultRaceView()
96
97  if not (IsMusicPlaying()) then
98    PlayMusic("music/Orc Briefing" .. wargus.music_extension)
99  end
100
101  local menu = WarMenu()
102  local offx = (Video.Width - 640) / 2
103  local offy = (Video.Height - 480) / 2
104
105  menu:addLabel(wargus.Name .. " V" .. wargus.Version .. ", " .. wargus.Copyright, offx + 320, (Video.Height - 90) + 18*4, Fonts["small"]) -- Copyright information.
106
107  menu:addLabel(_("~<Map Editor~>"), offx + 320, offy + 212 - 25)
108  local buttonNewMap =
109  menu:addFullButton(_("~!New map"), "n", offx + 208, offy + 104 + 36*3, function() RunEditorNewMapMenu(); menu:stop() end)
110  menu:addFullButton(_("~!Load map"), "l", offx + 208, offy + 104 + 36*4, function() RunEditorLoadMapMenu(); menu:stop() end)
111  menu:addFullButton(_("Cancel (~<Esc~>)"), "escape", offx + 208, offy + 104 + 36*5, function() menu:stop() end)
112  return menu:run()
113end
114
115function RunEditorSaveMap(browser, name, menu)
116  local saved = EditorSaveMap(browser.path .. name)
117  if (saved == -1) then
118    local confirm = WarGameMenu(panel(3))
119    confirm:resize(300,120)
120    confirm:addLabel(_("Cannot save map to file:"), 300 / 2, 11)
121    confirm:addLabel(browser.path .. name, 300 / 2, 31)
122    confirm:addHalfButton("~!OK", "o", 1 * (300 / 3), 120 - 16 - 27, function() confirm:stop() end)
123    confirm:run(false)
124  else
125    UI.StatusLine:Set(_("Saved map to: ") .. browser.path .. name)
126    menu:stop()
127  end
128end
129
130--
131--  Save map from the editor
132--
133editorMapName = "game.smp"
134function RunEditorSaveMenu()
135  local menu = WarGameMenu(panel(3))
136
137  menu:resize(384, 256)
138
139  menu:addLabel(_("Save Game"), 384 / 2, 11)
140
141  local t = menu:addTextInputField(editorMapName,
142    (384 - 300 - 18) / 2, 11 + 36, 318)
143
144  local browser = menu:addBrowser("maps", ".smp.gz$",
145    (384 - 300 - 18) / 2, 11 + 36 + 22, 318, 126)
146  local function cb(s)
147    t:setText(browser:getSelectedItem())
148  end
149  browser:setActionCallback(cb)
150
151  menu:addHalfButton(_("Cancel (~<Esc~>)"), "escape", 384 - ((384 - 300 - 18) / 2) - 106, 256 - 16 - 27, function() menu:stop() end)
152  menu:addHalfButton(_("~!Save"), "s", (384 - 300 - 18) / 2, 256 - 16 - 27,
153    function()
154      local name = t:getText()
155      -- check for an empty string
156      if (string.len(name) == 0) then
157        return
158      end
159      -- strip .gz
160      if (string.find(name, ".gz$") ~= nil) then
161        name = string.sub(name, 1, string.len(name) - 3)
162      end
163      -- append .smp
164      if (string.find(name, ".smp$") == nil) then
165        name = name .. ".smp"
166      end
167      -- replace invalid chars with underscore
168      local t = {"\\", "/", ":", "*", "?", "\"", "<", ">", "|"}
169      table.foreachi(t, function(k,v) name = string.gsub(name, v, "_") end)
170
171      if (browser:exists(name .. ".gz")) then
172        local confirm = WarGameMenu(panel(3))
173        confirm:resize(300,120)
174        confirm:addLabel(name, 300 / 2, 11)
175        confirm:addLabel(_("File exists, are you sure ?"), 300 / 2, 31)
176        confirm:addHalfButton("~!Yes", "y", 1 * (300 / 3) - 90, 120 - 16 - 27,
177          function()
178            confirm:stop()
179            RunEditorSaveMap(browser, name, menu)
180            editorMapName = name
181          end)
182        confirm:addHalfButton("~!No", "n", 3 * (300 / 3) - 116, 120 - 16 - 27, function() confirm:stop() end)
183        confirm:run(false)
184      else
185        RunEditorSaveMap(browser, name, menu)
186        editorMapName = name
187      end
188    end)
189
190  menu:run(false)
191end
192
193function RunEditorResizeMap(browser, name, menu, w, h, x, y)
194  local saved = EditorResizeMap(browser.path .. name, w, h, x, y)
195  if (saved == -1) then
196    local confirm = WarGameMenu(panel(3))
197    confirm:resize(300,120)
198    confirm:addLabel(_("Cannot save map to file:"), 300 / 2, 11)
199    confirm:addLabel(browser.path .. name, 300 / 2, 31)
200    confirm:addHalfButton("~!OK", "o", 1 * (300 / 3), 120 - 16 - 27, function() confirm:stop() end)
201    confirm:run(false)
202  else
203    UI.StatusLine:Set(_("Saved map to: ") .. browser.path .. name)
204    menu:stop()
205  end
206end
207
208--
209--  Save map from the editor
210--
211function RunEditorEnlargeMenu()
212  local menu = WarGameMenu(panel(3))
213
214  menu:resize(384, 256)
215
216  menu:addLabel(_("Save Resized Map"), 384 / 2, 11)
217
218  menu:addLabel("Resize:", (384 - 300 - 18) / 2 - 106, 36)
219  local sz = menu:addTextInputField("128x128+0+0", (384 - 300 - 18) / 2, 36)
220
221  local t = menu:addTextInputField("game.smp",
222    (384 - 300 - 18) / 2, 14 + 36, 318)
223
224  local browser = menu:addBrowser("maps", ".smp.gz$",
225    (384 - 300 - 18) / 2, 14 + 36 + 22, 318, 123)
226  local function cb(s)
227    t:setText(browser:getSelectedItem())
228  end
229  browser:setActionCallback(cb)
230
231  menu:addHalfButton(_("Cancel (~<Esc~>)"), "escape", 384 - ((384 - 300 - 18) / 2) - 106, 256 - 16 - 27, function() menu:stop() end)
232  menu:addHalfButton(_("~!Save"), "s", (384 - 300 - 18) / 2, 256 - 16 - 27,
233    function()
234      local name = t:getText()
235      -- check for an empty string
236      if (string.len(name) == 0) then
237        return
238      end
239      -- strip .gz
240      if (string.find(name, ".gz$") ~= nil) then
241        name = string.sub(name, 1, string.len(name) - 3)
242      end
243      -- append .smp
244      if (string.find(name, ".smp$") == nil) then
245        name = name .. ".smp"
246      end
247      -- replace invalid chars with underscore
248      local t = {"\\", "/", ":", "*", "?", "\"", "<", ">", "|"}
249      table.foreachi(t, function(k,v) name = string.gsub(name, v, "_") end)
250
251      local newWidth = 0
252      local newHeight = 0
253      local xOffset = 0
254      local yOffset = 0
255      for w, h, x, y in string.gmatch(sz:getText(), "(%d+)x(%d+)+(%d+)+(%d+)") do
256         newWidth = tonumber(w)
257         newHeight = tonumber(h)
258         xOffset = tonumber(x)
259         yOffset = tonumber(y)
260      end
261
262      if (browser:exists(name .. ".gz")) then
263        local confirm = WarGameMenu(panel(3))
264        confirm:resize(300,120)
265        confirm:addLabel(name, 300 / 2, 11)
266        confirm:addLabel(_("File exists, are you sure ?"), 300 / 2, 31)
267        confirm:addHalfButton("~!Yes", "y", 1 * (300 / 3) - 90, 120 - 16 - 27,
268          function()
269            confirm:stop()
270            RunEditorResizeMap(browser, name, menu, newWidth, newHeight, xOffset, yOffset)
271          end)
272        confirm:addHalfButton("~!No", "n", 3 * (300 / 3) - 116, 120 - 16 - 27, function() confirm:stop() end)
273        confirm:run(false)
274      else
275        RunEditorResizeMap(browser, name, menu, newWidth, newHeight, xOffset, yOffset)
276      end
277    end)
278
279  menu:run(false)
280end
281
282--
283--  Load a other map to edit.
284--
285function RunEditorLoadMenu()
286-- TODO : fill this function correctly
287--[[
288--  RunSelectScenarioMenu()
289--  if (buttonStatut == 1) then
290--    EditorLoadMap(mapname)
291--    StartEditor(mapname)
292--  end
293--]]
294end
295
296--
297--  Change player properties from the editor
298--
299function RunEditorPlayerProperties()
300-- TODO : manage edition.
301  local sizeX = 500
302  local sizeY = 480
303  local menu = WarGameMenu(panel(5), 500, 480)
304
305  menu:resize(sizeX, sizeY)
306  menu:addLabel(_("Players properties"), sizeX / 2, 11)
307
308  local offxPlayer = 15
309  local offxType = 70
310  local offxRace = 170
311  local offxAI = 285
312  local offxGold = 375
313  local offxLumber = 425
314  local offxOil = 470
315
316  local types = {"neutral", "nobody", "computer", "person", "rescue-passive", "rescue-active"}
317  local types1 = {_("Neutral"), _("Nobody"), _("Computer"), _("Person"), _("Rescue-passive"), _("Rescue-active")}
318  local racenames = {"human", "orc"}
319  local racenames1 = {_("Human"),_("Orc")}
320  local aiList = AIStrategyTypes
321  table.remove(aiList, 1)
322
323  menu:addLabel("#", 15, 36)
324  menu:addLabel(_("Type"), offxType, 36)
325  menu:addLabel(_("Race"), offxRace, 36)
326  menu:addLabel(_("AI"), offxAI, 36)
327  menu:addLabel(_("Gold"), offxGold, 36)
328  menu:addLabel(_("Lumber"), offxLumber, 36)
329  menu:addLabel(_("Oil"), offxOil, 36)
330
331  local playersProp = {nil, nil, nil, nil, nil,
332                       nil, nil, nil, nil, nil,
333                       nil, nil, nil, nil, nil}
334  for i = 0, 14 do
335    local playerLine = {
336      type = nil,
337      race = nil,
338      ai = nil,
339      gold = nil,
340      lumber = nil,
341      oil = nil
342    }
343    local offy_i = 36 + 25 * (i + 1)
344    local index = i -- use for local function
345
346    local function updateProp(ind)
347      local b = (playersProp[1 + ind].type:getSelected() ~= 1) -- != nobody
348      playersProp[1 + ind].race:setVisible(b)
349      playersProp[1 + ind].ai:setVisible(b)
350      playersProp[1 + ind].gold:setVisible(b)
351      playersProp[1 + ind].lumber:setVisible(b)
352      playersProp[1 + ind].oil:setVisible(b)
353    end
354
355    playersProp[1 + i] = playerLine
356
357    menu:addLabel("p" .. (i + 1), offxPlayer, offy_i)
358
359    playersProp[1 + i].type = menu:addDropDown(types1, offxType - 40, offy_i, function() updateProp(index) end)
360    playersProp[1 + i].type:setSelected(Map.Info.PlayerType[i] - 2)
361    playersProp[1 + i].type:setWidth(115)
362
363    playersProp[1 + i].race = menu:addDropDown(racenames1, offxRace - 20, offy_i, function() end)
364    playersProp[1 + i].race:setSelected(Players[i].Race)
365    playersProp[1 + i].race:setWidth(65)
366
367    playersProp[1 + i].ai = menu:addDropDown(aiList, offxAI - 65, offy_i, function() end)
368    for j = 1,table.getn(aiList) do
369      if (aiList[j] == Players[i].AiName) then playersProp[1 + i].ai:setSelected(j - 1) end
370    end
371    playersProp[1 + i].ai:setWidth(130)
372
373    playersProp[1 + i].gold = menu:addTextInputField(Players[i].Resources[1], offxGold - 20, offy_i, 40)
374    playersProp[1 + i].lumber = menu:addTextInputField(Players[i].Resources[2], offxLumber - 20, offy_i, 40)
375    playersProp[1 + i].oil = menu:addTextInputField(Players[i].Resources[3], offxOil - 20, offy_i, 40)
376    updateProp(i)
377  end
378
379  menu:addHalfButton("~!Ok", "o", 1 * (sizeX / 4) - 106 - 10, sizeY - 16 - 27,
380    function()
381      for i = 0, 14 do
382        Map.Info.PlayerType[i] = playersProp[1 + i].type:getSelected() + 2
383        Players[i].Race = playersProp[1 + i].race:getSelected()
384        Players[i].AiName = aiList[1 + playersProp[1 + i].ai:getSelected()]
385        Players[i].Resources[1] = playersProp[1 + i].gold:getText()
386        Players[i].Resources[2] = playersProp[1 + i].lumber:getText()
387        Players[i].Resources[3] = playersProp[1 + i].oil:getText()
388      end
389      menu:stop()
390    end)
391
392  menu:addHalfButton(_("Cancel (~<Esc~>)"), "escape", 3 * (sizeX / 4) - 106 - 10, sizeY - 16 - 27,
393    function() menu:stop() end)
394
395  menu:run(false)
396end
397
398--
399--  Change player properties from the editor
400--
401function RunEditorMapProperties()
402-- TODO : manage edition of all properties.
403  local menu = WarGameMenu(panel(3))
404
405  local sizeX = 384
406  local sizeY = 256
407
408  menu:resize(sizeX, sizeY)
409  menu:addLabel(_("Map properties"), sizeX / 2, 11)
410
411  menu:addLabel(_("Map descritption : "), 45, 11 + 36, nil, false)
412  local desc = menu:addTextInputField(Map.Info.Description, 15, 36 * 2, 350)
413
414  menu:addLabel(_("Size    : ") .. Map.Info.MapWidth .. " x " .. Map.Info.MapHeight, 45, 36 * 3, nil, false)
415--  menu:addLabel("Size : ", 15, 36 * 3, nil, false)
416--  local sizeX = menu:addTextInputField(Map.Info.MapWidth, 75, 36 * 3, 50)
417--  menu:addLabel(" x ", 130, 36 * 3, nil, false)
418--  local sizeY = menu:addTextInputField(Map.Info.MapHeight, 160, 36 * 3, 50)
419
420  menu:addLabel(_("Tileset : "), 45, 36 * 4, nil, false)
421
422  local list = { _("Summer"), _("Swamp"), _("Wasteland"), _("Winter")}
423  local dropDownTileset = menu:addDropDown(list, 145, 36 * 4, function() end)
424  for i = 0,3 do
425    if (list[1 + i] == Map.Tileset.Name) then dropDownTileset:setSelected(i)
426    end
427  end
428  dropDownTileset:setEnabled(false) -- TODO : manage this properties
429
430  menu:addHalfButton("~!Ok", "o", 1 * (sizeX / 3) - 106 - 10, sizeY - 16 - 27,
431    function()
432      Map.Info.Description = desc:getText()
433      -- TODO : Add others properties
434      menu:stop()
435    end
436    )
437
438  menu:addHalfButton(_("Cancel (~<Esc~>)"), "escape", 3 * (sizeX / 3) - 106 - 10, sizeY - 16 - 27,
439    function() menu:stop() end)
440
441  menu:run(false)
442end
443
444function EditScript(filename)
445   local contents
446   local preamble = filename:sub(-#"preamble") == "preamble"
447   if preamble then
448      contents = Map.Info.Preamble
449   else
450      contents = Map.Info.Postamble
451   end
452   if contents == "" then
453      if CanAccessFile(filename) then
454         contents = GetFileContent(filename)
455      else
456         if preamble then
457            contents = [[
458-- Stratagus preamble script.
459-- Use this script to set up anything that needs to run before the map is loaded.
460-- Commonly, this would be things like patching functions that place units, define
461-- players etc to modify the behaviour of these functions.
462
463if Editor.Running == EditorNotRunning then
464  -- Add code here
465end
466]]
467         else
468            contents = [[
469-- Stratagus postamble script.
470-- Use this script to set up anything after the map is loaded. Commonly this would
471-- be adding triggers or customizing players, their alliances or similar things.
472
473if Editor.Running == EditorNotRunning then
474  -- Add code here
475end
476]]
477         end
478      end
479   end
480   local menu = WarMenu()
481   local menubox = VBox({
482         HBox({
483               LFiller(),
484               LLabel(filename),
485               LFiller(),
486         }):withPadding(5),
487         LTextBox(contents):expanding():id("textbox"),
488         HBox({
489               LFiller(),
490               LHalfButton(_("Accept"), nil, function()
491                              if preamble then
492                                 Map.Info.Preamble = menu.textbox:getText()
493                              else
494                                 Map.Info.Postamble = menu.textbox:getText()
495                              end
496               end),
497               LHalfButton(_("Close"), nil, function() menu:stop() end),
498         }):withPadding(5)
499   }):withPadding(10)
500   menubox:addWidgetTo(menu, true)
501   menu:run()
502end
503
504--
505--  Main menu in editor.
506--
507function RunInEditorMenu()
508   local menu
509
510   local function EditPreamble()
511      EditScript(mapname .. ".preamble")
512   end
513
514   local function EditPostamble()
515      EditScript(mapname .. ".postamble")
516   end
517
518   menu = WarMenuWithLayout(
519      panel(1),
520      VBox({
521            HBox({
522                  LFiller(),
523                  LLabel(_("Editor Menu")),
524                  LFiller(),
525            }):withPadding(5),
526            LFiller(),
527            HBox({
528                  LHalfButton(_("Help (~<F1~>)"), "f1", RunEditorHelpMenu),
529                  LFiller(),
530                  LHalfButton(_("Save (~<F11~>)"), "f11", RunEditorSaveMenu),
531            }),
532            LButton(_("Map Properties (~<F5~>)"), "f5", RunEditorMapProperties),
533            LButton(_("Player Properties (~<F6~>)"), "f6", RunEditorPlayerProperties),
534            LButton(_("~!Resize Map"), "r", RunEditorEnlargeMenu),
535            HBox({
536                  LHalfButton(_("Pr~!eamble"), "e", EditPreamble),
537                  LFiller():expanding(),
538                  LHalfButton(_("~!Postamble"), "p", EditPostamble)
539            }),
540            LLabel(""),
541            LButton(_("E~!xit to Menu"), "x", function() Editor.Running = EditorNotRunning; menu:stopAll(); end),
542            LButton(_("Return to Editor (~<Esc~>)"), "escape", function() menu:stop() end),
543      }):withPadding({10, 8})
544   )
545   menu:run(false)
546end
547
548--
549--  Function to edit unit properties in Editor
550--
551function EditUnitProperties()
552
553  if (GetUnitUnderCursor() == nil) then
554    return;
555  end
556  local menu = WarGameMenu(panel(1))
557  local sizeX = 256
558  local sizeY = 200 -- 288
559
560  menu:resize(sizeX, sizeY)
561  menu:addLabel(_("Unit properties"), sizeX / 2, 11)
562
563  if (GetUnitUnderCursor().Type.GivesResource == 0) then
564    menu:addLabel(_("Artificial Intelligence"), sizeX / 2, 11 + 36)
565    local activeCheckBox = menu:addImageCheckBox("Active", 15, 11 + 72, offi, offi2, oni, oni2)
566    activeCheckBox:setMarked(GetUnitUnderCursor().Active)
567
568    menu:addHalfButton("~!Ok", "o", 24, sizeY - 40,
569      function() GetUnitUnderCursor().Active = activeCheckBox:isMarked();  menu:stop() end)
570  else
571    local resourceName = {_("gold"), _("wood"), _("oil")}
572    local resource = GetUnitUnderCursor().Type.GivesResource - 1
573    menu:addLabel(_("Amount of ") .. resourceName[1 + resource] .. " :", 24, 11 + 36, nil, false)
574	local resourceValue = menu:addTextInputField(GetUnitUnderCursor().ResourcesHeld, sizeX / 2 - 30, 11 + 36 * 2, 60)
575
576    menu:addHalfButton("~!Ok", "o", 24, sizeY - 40,
577      function() GetUnitUnderCursor().ResourcesHeld = resourceValue:getText();  menu:stop() end)
578  end
579  menu:addHalfButton(_("Cancel (~<Esc~>)"), "escape", 134, sizeY - 40,
580    function() menu:stop() end)
581  menu:run(false)
582end
583