aboutsummaryrefslogtreecommitdiff
path: root/src/menu/lobby.moon
blob: c20face1e8af68d2993ee935ccb417bebba7cda3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
ui = require("ui")
world = require("world")
log = require("log")
util = require("util")
task = require("task")
net = require("net")
game = require("menu.game")

menu = {}
net.register_message("RespondLevel",{
	name: "string" -- name of the level e.g. "levels.lobby"
	data: "table" -- sequence to initalize the level
})
net.register_message("StartGame",{})
start_game = nil
lobby_url = nil
menu.initialize = () ->
	log.info("Initializing lobby", {"ui"})
	game_data = am.load_state("gameplay")
	now = am.eval_js("Date.now()")
	--if game_data and (not world.hub) and (now - game_data.start > game_data.time * 1000)
		--error("Looks like we have a game in progress:" .. tostring(game_data))
		--menu.destroy!
		--game.create!
		--return
	log.info("Got game data", {"ui","net"})
	ready = false
	if world.network_mode == "host"
		start_game = ui.button(-150,400-128,300,128,"Start!")
		start_game.on = (e) =>
			log.info("Starting game!",{"net","server"})
			world.level_sync.name = "levels.game"
			for _, ent in pairs(world.level.entities)
				ent\destroy!
			-- Actually send the message to start the game
			log.info("Connected peers were:" .. tostring(world.hub.clients), {"net","server"})
			world.hub\broadcast("StartGame",{})
			log.info("Finished creating game, level_sync.name is" .. world.level_sync.name,{"net","server"})
	else 
		start_game = ui.text(0, 400-64,300,128,"Waiting...")
	code = nil
	if world.network_mode == "host"
		-- For host, use the hub's peer ID (not the local client's peer ID)
		code = util.peer_to_code(world.hub.peer.id)
	elseif world.network_mode == "client"
		params = am.eval_js("window.CLIPBOARD.get_params()")
		code = params.i
	else
		error("world.network must be initialized before creating lobby menu")
	world.network\listen("StartGame","Lobby start game",() ->
		log.info("Starting game!",{"net","client"})
		for _, ent in pairs(world.level.entities)
			ent\destroy!
		menu.destroy!
		game.create!
		log.info("Finished creating game", {"net","client"})
	)
	world.level_sync.data[1] = code
	path = am.eval_js("window.CLIPBOARD.get_path()")
	url = string.format("%s?i=%s", path, code)
	--url_display = string.format("%s\n?i=%s",path,code)
	url_display = "Copy URL"
	lobby_url = ui.button(-180,-400+64,360,84,url_display)
	lobby_url.on = () =>
		log.info("Clicked button, copying text",{"ui"})
		transform = am.translate(0,-400+128)
		copied_text = am.text("Coppied!", vec4(1,1,1,1))
		transform\append(copied_text)
		copied_text\action(coroutine.create(() ->
			i = 1
			while i > 0
				i = i - (2/255)
				copied_text.color = vec4(1,1,1,i)
				transform.y += i * 3
				coroutine.yield!
			lobby_url.node\remove(transform)
		))
		lobby_url.node\append(transform)
		-- This HAS to be the last action in this function, or else
		-- javascript thinks this is happening outside of a user interaction.
		am.eval_js("navigator.clipboard.writeText('" .. url .. "');")
	log.info("Created lobby buttons", {"ui"})
	level_loader = coroutine.create(() ->
		while not world.network.connected
			log.info("Waiting for network to load level...",{"net","client"})
			coroutine.yield!
		--level = world.network\sync("RequestLevel",{},"RespondLevel")
		--log.info("Got information back from sync" .. tostring(level), {"net","client"})
		--world.level_sync.name = level.name
		--world.level_sync.data = level.data
		--log.info("Loading " .. level.name .. " with data " .. tostring(level.data), {"net","client","level"})
		--level_mod = assert(require(level.name))
		--assert(level_mod.create, "Level " .. level.name .. " had no .create()")
		--level_mod.create(unpack(level.data))
	)
	task.add(level_loader)

menu.destroy = () ->
	ui.delete(lobby_url)
	if start_game
		ui.delete(start_game)

menu