aboutsummaryrefslogtreecommitdiffstats
path: root/Gamestates/Multiplayer/InGame.lua
blob: f94be12cb50f009f71d2d0334c0c41d5f062057a (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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
--[[
	Gamestates/Multiplayer/InGame.lua
	Multiplayer mode
	by piernov
]]--
local GUI = { InGame = require("GUI/InGame")}
local Game = require("Gamestates/Game")
local Protocol = require("Gamestates/Multiplayer/Protocol")

local InGame = {}

function InGame:enter(Local) -- Initialize or reset variables when entering game
	Previous = "Gamestates/Multiplayer/Local"
	InGame.Keypressed = {{}} -- 2D array for storage of button pressed
	InGame.Hints = {} -- Hints displayed for local player
	InGame.opponentHints = {} -- Hints displayed for remote player
	InGame.state = "playing" -- Default to "playing" but it doesn't mean anything
	InGame.localLife = {} 
	InGame.remoteLife = {}

	InGame.host = Local.host
	InGame.client = Local.client

	InGame.opponentAnswer = Game.genAnswer() -- Generate answer for the opponent

	for o = 0, 9	do
	table.insert(InGame.remoteLife, { Type = "line", LineWidth = 0.015, Position = { x1 = 0.135, y1 = 0.61+0.02*o, x2 = 0.185, y2 = 0.61+0.02*o}, Colors = {171, 0, 0, 255} }) -- Display life bar content
	end

	for o = 0, 9	do
	table.insert(InGame.localLife, { Type = "line", LineWidth = 0.022, Position = { x1 = 0.535+0.0275*o, y1 = 0.66, x2 = 0.535+0.0275*o, y2 = 0.71}, Colors = {171, 0, 0, 255} }) -- Display life bar content
	end

	InGame:resize() -- Call the function filling the canvas

	InGame.Musiclowlife = love.audio.newSource("Resources/BlueMind midlife.ogg")
	InGame.Music = love.audio.newSource("Resources/BlueMind.ogg")
	InGame.Music:setLooping(true)
	InGame.Music:play()
end

function InGame:resize() -- Called in :enter() and when the window is resized
	InGame.Display = love.graphics.newCanvas(Screen.width, Screen.height) -- Create the canvas containing base interface to avoid drawing it entirely each frame
	love.graphics.setCanvas(InGame.Display)
		love.graphics.setFont(Fonts[3]) -- Use font with size 3% by default
		InGame.Display:clear()
		for id, polygon in ipairs(GUI.InGame.Polygons) do
			GUI.InGame.drawPolygon(polygon)
		end
	love.graphics.setCanvas()
end

function InGame:init(host, client)
	Game.init()
	GUI.InGame.loadInterface()
	GUI.InGame.loadMultiplayerInterface()
end

function InGame:draw()
	love.graphics.setColor(255, 255, 255, 255)
	love.graphics.setBlendMode('premultiplied')
	love.graphics.draw(InGame.Display)
	love.graphics.setBlendMode('alpha')

	for num, line in ipairs(InGame.Hints) do
		for k, poly in ipairs(line) do
			GUI.InGame.drawPolygon(poly)
		end
	end

	for line, keys in ipairs(InGame.Keypressed) do
		for id, num in ipairs(keys) do
			GUI.InGame.drawPolygon({ Type = "rectangle", DrawMode = "fill", Position = { x = 0.50+(id-1)*0.075, y = 0.15+(line-1)*0.075-0.025}, Dimension = {width = 0.04, height = 0.04}, Colors = GUI.InGame.Colors[num] })
		end
	end

	for num, poly in ipairs(InGame.localLife) do
		GUI.InGame.drawPolygon(poly)
	end

	for num, poly in ipairs(InGame.remoteLife) do
		GUI.InGame.drawPolygon(poly)
	end

	for id, num in ipairs(InGame.opponentAnswer) do
		GUI.InGame.drawPolygon({ Type = "rectangle", DrawMode = "fill", Position = { x = 0.08+(id-1)*0.075+0.005, y = 0.12+0.005}, Dimension = {width = 0.035, height = 0.04}, Colors = GUI.InGame.Colors[num] }) -- Top left boxes content displaying opponent answer
	end

-- Display popup for win/loose and found answer
	if InGame.state == "found" then
		GUI.InGame.displayPopup("Found !")
	elseif InGame.state == "not-found" then
		GUI.InGame.displayPopup("Not found...")
	elseif InGame.state == "win" then
		GUI.InGame.displayPopup("You win !")
	elseif InGame.state == "loose" then
		GUI.InGame.displayPopup("You loose...")
	end
-- End

	GUI.InGame.drawPolygon({ Type = "print", Text = InGame.client.name, Position = { x = 0.15, y = 0.06}, Colors = {0, 0, 171, 255} }) -- Display remote player's name
	GUI.InGame.drawPolygon({ Type = "print", Text = Config.player_name.text, Position = { x = 0.60, y = 0.06}, Colors = {0, 0, 171, 255} }) -- Display local player's name
end

function InGame:update(dt)
	local event = InGame.host:service()

	while event ~= nil do -- Handle network events
		Protocol.parseGlobalEvents(event)

		if event.type == "receive" then
			command, args = event.data:match("(.*): (.*)") -- Split received message : "<COMMAND>: <ARGS>"
			if command == "ANSWER" then
				local hints = table.concat(Game.checkKeys({args:match("(%d)(%d)(%d)(%d)")}, InGame.opponentAnswer)) -- Process received answers
				if hints == "1111" then -- Only well-placed hints = answer found
					event.peer:send("FOUND: TRUE", 0, "reliable")
					table.remove(InGame.localLife, 1) -- Loss of 1 life point
					if #InGame.localLife < 1 then -- Empty life
						InGame.state = "loose"
					else
						if #InGame.localLife == 2 then
							InGame.Music:stop()
							InGame.Musiclowlife:setLooping(true)
							InGame.Musiclowlife:play()
						end
						InGame.opponentAnswer = Game.genAnswer() -- Generate a new answer
						InGame.opponentHints = {}
					end
				else
					event.peer:send("HINTS: " .. hints, 0, "reliable")
				end
			elseif command == "FOUND" and args == "TRUE" then
				table.remove(InGame.remoteLife, 1) -- Opponent loose 1 life point
				if #InGame.remoteLife < 1 then -- Opponent's life is empty, we won
					InGame.state = "win"
				else
					InGame.Keypressed = {{}}
					InGame.Hints = {}
					InGame.state = "found"
				end
			elseif command == "FOUND" and args == "FALSE" then
				table.remove(InGame.remoteLife, 1) -- Opponent loose 1 life point
				InGame.opponentAnswer = Game.genAnswer() -- Generate a new answer
				InGame.opponentHints = {}
			elseif command == "HINTS" then
				table.insert(InGame.Hints, Game.addHints(args, #InGame.Keypressed))
				InGame.Keypressed[#InGame.Keypressed+1] = {}
				InGame.state = "playing"
				if #InGame.Keypressed > 7 then
					table.remove(InGame.localLife, 1) -- Loss of 1 life point
					InGame.Keypressed = {{}}
					InGame.Hints = {}
					InGame.state = "not-found"
					event.peer:send("FOUND: FALSE", 0, "reliable")
				end
			end
		end
		event = InGame.host:service() -- Process next event
	end
end

function InGame:mousepressed(x, y, b) -- Handle mouse
	if InGame.state == "found" or InGame.state == "not-found" then -- Click anywhere to hide the "found" popup message
		InGame.state = "playing"
	end

	x = x/Screen.width -- relative coordinates
	y = y/Screen.height
	if 0.875 < y and y < 0.915 and InGame.state ~= "validating" then -- lower part of the screen, and don't do anything if we're waiting for hints from peer
		if x > 0.45 then
			for i = 0,5 do
				if 0.50+i*0.075 < x and x < 0.50+i*0.075+0.04 then
					if #InGame.Keypressed > 7 or #InGame.Keypressed[#InGame.Keypressed] >= 4  then -- Line already full
						return
					else
						for k,v in pairs(InGame.Keypressed[#InGame.Keypressed]) do
							if v == i+1 then
								return -- Disallow multiple identical colors in same line
							end
						end

						table.insert(InGame.Keypressed[#InGame.Keypressed], i+1) -- Click detected on a color-button
					end
				end
			end
		elseif 0.25 < x and x < 0.375 and #InGame.Keypressed <= 7 and #InGame.Keypressed[#InGame.Keypressed] == 4 then -- Clik on Ok button
			local peer = InGame.host:get_peer(InGame.client.index)
			InGame.state = "validating"
			peer:send("ANSWER: " .. table.concat(InGame.Keypressed[#InGame.Keypressed]), 0, "reliable")
		elseif #InGame.Keypressed <= 7 and 0.075 < x and x < 0.200 and #InGame.Keypressed[#InGame.Keypressed] > 0 then -- Click on reset button
			InGame.Keypressed[#InGame.Keypressed] = {}
		end
	end
end

function InGame:leave()
	InGame.Music:stop()
	InGame.Musiclowlife:stop()
end

return InGame