menu.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. local love = require("compat")
  2. local menu = {
  3. ip = ""
  4. }
  5. local scr, listScr
  6. Images = require "images"
  7. local playernameInput, addressInput
  8. local ERROR_MSG = nil
  9. local ERROR_TIMER = 0
  10. function menu:init()
  11. scr = ui:newScreen( "menu" )
  12. scr:addPanel( "centerPanel",
  13. 50,
  14. love.graphics.getHeight()/2-200,
  15. 300, 350 )
  16. local y = 0
  17. scr:addHeader( "centerPanel", "welcome", 0, y, "Welcome!" )
  18. y = y + 30
  19. scr:addText( "centerPanel", "welcometxt", 10, y, nil, 7, "Start a server or join someone else's server. Press 'H' for help.")
  20. y = y + 40
  21. playernameInput = scr:addInput( "centerPanel", "name", 10, y, nil, 20, "p", menu.playername )
  22. playernameInput:setContent( PLAYERNAME )
  23. y = y + 40
  24. --scr:addText( "centerPanel", "h1", 10, y, nil, 7, "{h}Server:")
  25. scr:addHeader( "centerPanel", "h1", 0, y, "Server:" )
  26. y = y + 20
  27. scr:addFunction( "centerPanel", "serverOnline", 10, y, "Start Server (Online)", "s", function() menu.startServer("online") end )
  28. y = y + 20
  29. scr:addFunction( "centerPanel", "serverLAN", 10, y, "Start Server (LAN)", "a", function() menu.startServer("lan") end )
  30. y = y + 40
  31. --scr:addText( "centerPanel", "h2", 10, y, nil, 7, "{h}Client:")
  32. scr:addHeader( "centerPanel", "h2", 0, y, "Client:" )
  33. y = y + 20
  34. --addressInput = scr:addInput( "centerPanel", "ip", 10, y, nil, 20, "i", menu.ipEntered )
  35. --addressInput:setContent( ADDRESS )
  36. --y = y + 20
  37. scr:addFunction( "centerPanel", "connect", 10, y, "Connect", "c", menu.showServerList )
  38. y = y + 40
  39. scr:addFunction( "centerPanel", "options", 10, y, "Options", "o", menu.toggleOptions )
  40. y = y + 20
  41. scr:addFunction( "centerPanel", "help", 10, y, "Help", "h", menu.toggleHelp )
  42. y = y + 20
  43. scr:addFunction( "centerPanel", "close", 10, y, "Quit", "q", love.event.quit )
  44. listScr = ui:newScreen( "Serverlist" )
  45. listScr:addPanel( "headerPanel",
  46. 60, 60,
  47. love.graphics.getWidth()-120, 50 )
  48. listScr:addHeader( "headerPanel", "h", 20, 10, "Servers:" )
  49. listScr:addFunction( "headerPanel", "return", love.graphics.getWidth() - 260, 10, "Return", "q", menu.show )
  50. listScr:addFunction( "headerPanel", "refresh", love.graphics.getWidth() - 360, 10, "Refresh", "r", menu.showServerList )
  51. end
  52. function menu.playername( name )
  53. name = name:gsub( "|", "" )
  54. name = name:gsub( " ", "" )
  55. if #name > 0 then
  56. PLAYERNAME = name
  57. config.setValue( "PLAYERNAME", PLAYERNAME )
  58. end
  59. if playernameInput then
  60. playernameInput:setContent( PLAYERNAME )
  61. end
  62. end
  63. function menu:show()
  64. STATE = "Menu"
  65. ui:setActiveScreen( scr )
  66. menu.ip = ADDRESS
  67. if addressInput then
  68. addressInput:setContent( ADDRESS )
  69. end
  70. chat:reset()
  71. stats:clear()
  72. map:reset()
  73. menu:closeConnectPanel()
  74. network.advertise:stop()
  75. ERROR_TIMER = 0
  76. end
  77. function menu.showServerList()
  78. if serverList ~= nil then
  79. listScr:removeList( serverList.name )
  80. end
  81. network.advertise.callbacks.newEntryOnline = newServerListEntryRemote
  82. network.advertise.callbacks.newEntryLAN = newServerListEntryLocal
  83. network.advertise.callbacks.requestWarnings = function( msg )
  84. menu:newWarning( "Could not load online list:\n" .. msg ) end
  85. local list = {}
  86. serverList = listScr:newList( 60, 120, love.graphics.getWidth() - 132, list, 15 )
  87. --network:requestServerList( GAME_ID, MAIN_SERVER_URL )
  88. --network:requestServerListLAN( GAME_ID )
  89. network.advertise:setURL( MAIN_SERVER_URL )
  90. network.advertise:setID( GAME_ID )
  91. network.advertise:request( "both" )
  92. ui:setActiveScreen( listScr )
  93. end
  94. function newServerListEntryRemote( entry )
  95. if serverList then
  96. -- Event to be called when clicking the button:
  97. local event = function()
  98. menu.connect( entry.address, entry.port)
  99. end
  100. local servername, otherinfo = entry.info:match("Name:(.-),(.*)")
  101. otherinfo = otherinfo:gsub(",","\t")
  102. otherinfo = otherinfo:gsub(":",": ")
  103. local item = {
  104. --txt = "(Online) " .. entry.address .. "\t" .. entry.info:gsub(",","\t"):gsub(":", ": "),
  105. txt = "(Online) " .. servername .. "\t" .. otherinfo,
  106. event = event
  107. }
  108. serverList:addListItem( item )
  109. end
  110. end
  111. function newServerListEntryLocal( entry )
  112. if serverList then
  113. -- Event to be called when clicking the button:
  114. local event = function()
  115. menu.connect( entry.address, entry.port)
  116. end
  117. local servername, otherinfo = entry.info:match("Name:(.-),(.*)")
  118. otherinfo = otherinfo:gsub(",","\t")
  119. local item = {
  120. txt = "(LAN) " .. entry.address .. "\t" .. entry.info:gsub(",","\t"):gsub(":", ": "),
  121. event = event
  122. }
  123. serverList:addListItem( item )
  124. end
  125. end
  126. function menu:closeConnectPanel()
  127. scr:removePanel( "connectPanel" )
  128. end
  129. function menu:update( dt )
  130. if ERROR_TIMER > 0 then
  131. ERROR_TIMER = ERROR_TIMER - dt
  132. end
  133. end
  134. function menu:draw()
  135. x, y, tbl = love.window.getMode()
  136. love.graphics.setColor( 255,255,255,255 )
  137. love.graphics.draw(images["Logo.png"], x/2, 50, 0, 1, 1, 0, 0, 0, 0)
  138. --love.graphics.draw(images["Logo.png"], 0, 0, 0, 1, 1, 0, 0, 0, 0)
  139. if ERROR_TIMER > 0 then
  140. love.graphics.setColor( 0, 0, 0, 200 )
  141. love.graphics.rectangle( "fill", 60, love.graphics.getHeight() - 70,
  142. love.graphics.getWidth() - 120, 60 )
  143. love.graphics.setColor( 255,128,0, 200 )
  144. love.graphics.printf( ERROR_MSG, 60, love.graphics.getHeight() - 60,
  145. love.graphics.getWidth() - 120, "center" )
  146. end
  147. end
  148. function menu:keypressed( key )
  149. end
  150. function menu:mousepressed( button, x, y )
  151. end
  152. function menu.startServer( lan )
  153. if lan == "lan" then
  154. LAN_ONLY = true
  155. else
  156. LAN_ONLY = false
  157. end
  158. local err
  159. server, err = network:startServer( MAX_PLAYERS, PORT )
  160. if server then
  161. -- set client callbacks:
  162. setServerCallbacks( server )
  163. updateAdvertisementInfo()
  164. network.advertise:setURL( MAIN_SERVER_URL )
  165. network.advertise:setID( GAME_ID )
  166. if LAN_ONLY then
  167. network.advertise:start( server, "lan" )
  168. else
  169. network.advertise:start( server, "both" )
  170. end
  171. else
  172. menu:errorMsg( "Error:", err )
  173. end
  174. -- Also start a client!
  175. if server then
  176. menu.ipEntered( 'localhost' )
  177. menu.connect()
  178. end
  179. end
  180. function menu.ipEntered( ip )
  181. menu.ip = ip
  182. end
  183. function menu.connect( ip, port )
  184. local y = 0
  185. scr:addPanel( "connectPanel",
  186. love.graphics.getWidth()/2 - 175,
  187. love.graphics.getHeight()-100,
  188. 350, 50 )
  189. scr:addHeader( "connectPanel", "hConnect", 0, 0, "Connecting" )
  190. scr:addText( "connectPanel", "connectTxt", 10, 15, nil, 7, "Connecting to: '" ..
  191. (ip or menu.ip) .. "'...")
  192. local err
  193. client, err = network:startClient( ip or menu.ip, PLAYERNAME, port or PORT, VERSION )
  194. if client then
  195. -- set client callbacks:
  196. setClientCallbacks( client )
  197. if not server then -- only save address if this is not a server (in this case ADDRESS would be localhost)
  198. config.setValue( "ADDRESS", menu.ip )
  199. end
  200. --ui:setActiveScreen( nil )
  201. else
  202. print("Could not conect:", client )
  203. local commands = {}
  204. commands[1] = { txt = "Ok", key = "y" }
  205. listScr:newMsgBox( "Error:", "Could not connect:" .. (err or ""), nil, nil, nil, commands)
  206. menu:closeConnectPanel()
  207. end
  208. end
  209. function menu:authorized( auth, reason )
  210. if not auth then
  211. self:errorMsg( "Could not connect: ", reason )
  212. menu:closeConnectPanel()
  213. end
  214. end
  215. function menu:errorMsg( header, msg )
  216. local commands = {}
  217. commands[1] = { txt = "Ok", key = "y" }
  218. scr:newMsgBox( header, msg, nil, nil, nil, commands)
  219. end
  220. function menu:toggleHelp()
  221. if scr:panelByName( "optionsPanel" ) ~= nil then
  222. scr:removePanel( "optionsPanel" )
  223. end
  224. if scr:panelByName( "helpPanel" ) ~= nil then
  225. scr:removePanel( "helpPanel" )
  226. else
  227. local width = 600
  228. local x = math.min( 450, love.graphics.getWidth() - width - 50 )
  229. local y = 0
  230. scr:addPanel( "helpPanel",
  231. x,
  232. love.graphics.getHeight()/2-150,
  233. width, 320 )
  234. scr:addHeader( "helpPanel", "h1", 0, y, "Help:" )
  235. y = y + 30
  236. --scr:addText( "helpPanel", "helpText1", 10, y, nil, 7, "Press {f}'p'{p}")
  237. scr:addText( "helpPanel", "helpText", 10, y, nil, 7, "To change a server's setting go to:{g}\n " .. love.filesystem.getSaveDirectory() .. "/config.txt{p}\n\nPress {f}'p'{p} to change your playername.\n{f}'s'{p} starts a server.\nUse {f}'c'{p} to see a server list.\nIf the server is not in your LAN, but on the web, then the server must probably port-forward port " .. PORT .. " on his/her router.\n\nTo play your own maps, put them into the following folder:\n{g} " ..love.filesystem.getSaveDirectory() .. "/maps/" )
  238. end
  239. end
  240. function menu:toggleOptions()
  241. if scr:panelByName( "helpPanel" ) ~= nil then
  242. scr:removePanel( "helpPanel" )
  243. end
  244. if scr:panelByName( "optionsPanel" ) ~= nil then
  245. scr:removePanel( "optionsPanel" )
  246. else
  247. local width = 300
  248. local x = math.min( 450, love.graphics.getWidth() - width - 50 )
  249. local y = 0
  250. scr:addPanel( "optionsPanel",
  251. x,
  252. love.graphics.getHeight()/2-150,
  253. width, 320 )
  254. scr:addHeader( "optionsPanel", "h1", 0, y, "Options:" )
  255. y = y + 30
  256. scr:addHeader( "optionsPanel", "h2", 0, y, "Width and Height:" )
  257. y = y + 20
  258. local input
  259. local w, h, flags = love.window.getMode()
  260. input = scr:addInput( "optionsPanel", "width", 10, y, nil, 20, "1", menu.widthEntered )
  261. input:setContent( tostring(w) )
  262. y = y + 20
  263. input = scr:addInput( "optionsPanel", "height", 10, y, nil, 20, "2", menu.heightEntered )
  264. input:setContent( tostring(h) )
  265. y = y + 40
  266. if flags.fullscreen then
  267. scr:addFunction( "optionsPanel", "fullscreen", 10, y, "Fullscreen (on)", "f", menu.fullscreen )
  268. else
  269. scr:addFunction( "optionsPanel", "fullscreen", 10, y, "Fullscreen (off)", "f", menu.fullscreen )
  270. end
  271. end
  272. end
  273. function menu.widthEntered( txt )
  274. local num = tonumber(txt)
  275. if num then
  276. ok = pcall( love.window.setMode, num, HEIGHT, {fullscreen = FULLSCREEN} )
  277. if ok then
  278. WIDTH = num
  279. config.setValue( "WIDTH", num )
  280. love.load()
  281. menu:toggleOptions()
  282. end
  283. end
  284. end
  285. function menu.heightEntered( txt )
  286. local num = tonumber(txt)
  287. if num then
  288. ok = pcall( love.window.setMode, WIDTH, num, {fullscreen = FULLSCREEN} )
  289. if ok then
  290. HEIGHT = num
  291. config.setValue( "HEIGHT", num )
  292. love.load()
  293. menu:toggleOptions()
  294. end
  295. end
  296. end
  297. function menu.fullscreen()
  298. local w, h, flags = love.window.getMode()
  299. local fscr = not flags.fullscreen
  300. ok = pcall( love.window.setMode, WIDTH, HEIGHT, {fullscreen = fscr} )
  301. if ok then
  302. config.setValue( "FULLSCREEN", fscr )
  303. FULLSCREEN = fscr
  304. _G.love.load()
  305. menu:toggleOptions()
  306. end
  307. end
  308. function menu:newWarning( msg )
  309. ERROR_MSG = msg
  310. ERROR_TIMER = 10
  311. end
  312. return menu