-
Notifications
You must be signed in to change notification settings - Fork 0
/
rules.lua
350 lines (302 loc) · 8.41 KB
/
rules.lua
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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
local field = require "field"
local movement = require "movement"
local preview = require "preview"
local particle = require "particle"
local rules = {}
local offense = 1
local team_info = {}
local qb = 0
local down = 0
local scrimmage = 0
local goal = 0
local lineup_h = {0, 0}
local lineup_buffer = 1
local intercept = false
local pos_select = true
local char_team = 1
local down_suffix = {"st", "nd", "rd", "th"}
local yard_scale = 0
local replay_active = false
rules.load = function(menu_client_list, menu_client_info, menu_team_info, menu_settings, game_replay_active)
if network_state == "client" then
network.client_callback("score", function(data)
team_info[data.team].score = data.score
end, {"team", "score"})
network.client_callback("qb", function(data)
qb = data
end)
network.client_callback("scrimmage", function(data)
scrimmage = data
end)
end
replay_active = game_replay_active
local field_w, field_h = field.get_dimensions()
for team = 1, 2 do
lineup_h[team] = math.ceil((menu_settings.knights*menu_team_info[team].size+4)/2)
if lineup_h[team] < 3 then
lineup_h[team] = 3
elseif lineup_h[team] > field_h then
lineup_h[team] = field_h
end
end
pos_select = true
offense = 1
rules.set_scrimmage(math.floor(field.get_dimensions()/2)-1)
rules.set_goal()
yard_scale = 120/field_w
down = 1
team_info = menu_team_info
team_info[1].score = 0
team_info[2].score = 0
qb = 0
intercept = false
rules.set_lineup(1)
rules.set_lineup(2)
field.set_color(team_info[1].color, team_info[2].color)
end
rules.update = function(dt)
if not replay_active and pos_select then
local x = team_info[char_team].lineup[1].x+scrimmage
local y = team_info[char_team].lineup[1].y
preview.set_border(x, y, lineup_h[char_team]/2, rules.valid_pos, char_team)
if char_team == offense then
preview.add_icon("preview", 1, x, y, "green")
end
end
end
rules.draw = function()
local field_w, field_h = field.get_dimensions()
art.rectangle(scrimmage+1-3/tile_size, 0, 6/tile_size, field_h, colors.yellow[1], colors.yellow[2], colors.yellow[3])
if goal then
art.rectangle(goal+1-3/tile_size, 0, 6/tile_size, field_h, colors.green[1], colors.green[2], colors.green[3])
end
end
rules.set_team = function(team)
char_team = team
end
rules.get_offense = function()
return offense
end
rules.get_qb = function()
return qb
end
rules.get_score = function(team)
return team_info[team].score
end
rules.get_info = function()
return team_info
end
rules.get_color = function(team)
return team_info[team].color
end
rules.catch = function(knight)
if knight.team ~= offense then
rules.turnover()
intercept = true
else
return true
end
return false
end
rules.incomplete = function()
rules.end_down()
end
rules.tackle = function(x)
rules.set_scrimmage(x)
rules.end_down()
end
rules.touchdown = function()
rules.reset()
rules.end_down()
end
rules.set_scrimmage = function(x)
scrimmage = x
local scrim_min, scrim_max = rules.get_endzones()
if scrimmage > scrim_max then
scrimmage = scrim_max
elseif scrimmage < scrim_min then
scrimmage = scrim_min
end
network.server_send("scrimmage", scrimmage)
end
rules.set_goal = function()
goal = scrimmage + math.floor(field.get_dimensions()/12) * (offense-1.5)*-2
local scrim_min, scrim_max = rules.get_endzones()
if goal > scrim_max or scrimmage < scrim_min then
goal = false
end
end
rules.end_down = function()
if intercept then -- if ball was just intercepted, set down to 1
down = 1
intercept = false
rules.set_goal()
else
down = down + 1
if (offense == 1 and goal < scrimmage) or (offense == 2 and goal > scrimmage) then
rules.set_goal()
down = 1
end
if down > 4 then
rules.turnover()
down = 1
rules.set_goal()
end
end
qb = 0
for team = 1, 2 do -- reset lineup positioning
for i, v in ipairs(team_info[team].lineup) do
v.taken = false
end
end
end
rules.reset = function()
rules.turnover()
local field_w = field.get_dimensions()
rules.set_scrimmage(math.floor(field_w/12*6)-1)
rules.set_goal()
end
rules.turnover = function()
if offense == 1 then
offense = 2
else
offense = 1
end
qb = 0
particle.clear() -- new set of particles for every drive
end
rules.get_endzones = function()
local field_w = field.get_dimensions()
return math.floor(field_w/12)-1, math.floor(field_w/12*11)-1
end
rules.check_td = function(knight, step)
local min, max = rules.get_endzones()
local x= knight.tile_x
if movement.can_move(knight, step) then
x = knight.path[step].x
end
if (knight.team == 1 and x > max) or (knight.team == 2 and x <= min) then
if network_state == "server" then -- server has final say on touchdowns
team_info[knight.team].score = team_info[knight.team].score + 7
network.server_send("score", {knight.team, team_info[knight.team].score})
end
return true
end
return false
end
rules.start_select = function()
pos_select = true
end
rules.finish_select = function()
pos_select = false
end
rules.get_play_string = function()
local yards = math.ceil(math.abs(goal-scrimmage)*yard_scale)
if yards > 0 then
return tostring(down)..down_suffix[down].." and "..tostring(yards)
elseif goal then
return tostring(down)..down_suffix[down].." and Inches"
else
return tostring(down)..down_suffix[down].." and Goal"
end
end
rules.get_name = function(team)
return team_info[team].name
end
rules.valid_pos = function(x1, y1, x2, y2, team)
for i, v in ipairs(team_info[team].lineup) do
if team ~= offense or i > 1 then
if v.x == x2-scrimmage and v.y == y2 then
return true
end
end
end
return false
end
rules.set_position = function(knight_id, knight, tile_x, tile_y)
for i, v in ipairs(team_info[knight.team].lineup) do
if v.x == tile_x-scrimmage and v.y == tile_y and not v.taken then
rules.remove_host(knight_id, knight)
rules.set_tile(knight_id, knight, i, v)
return true
end
end
return false
end
rules.preview_position = function(knight_id, knight, tile_x, tile_y)
for i, v in ipairs(team_info[knight.team].lineup) do
if v.x == tile_x-scrimmage and v.y == tile_y and not v.taken then
preview.add_icon("preview", 3, tile_x, tile_y, "green")
return
end
end
preview.add_icon("preview", 3, tile_x, tile_y, "red")
end
rules.remove_host = function(knight_id, knight)
for i, v in ipairs(team_info[knight.team].lineup) do
if v.host == knight_id then
v.taken = false
v.host = false
break
end
end
end
rules.set_tile = function(knight_id, knight, tile_num, tile)
tile.taken = true
tile.host = knight_id
local tile_x = tile.x+scrimmage
local tile_y = tile.y
if network_state == "server" then
knight.tile_x = tile_x
knight.tile_y = tile_y
network.server_send("knight_tile", {knight_id, tile_x, tile_y})
end
knight.x = tile_x
knight.y = tile_y
if tile_num == 1 and knight.team == offense then -- if knight is standing in qb position, make them qb
qb = knight_id
network.server_send("qb", qb)
end
end
rules.give_position = function(knight_id, knight)
for i, v in ipairs(team_info[knight.team].lineup) do
if not v.taken then
rules.set_tile(knight_id, knight, i, v)
break
end
end
end
rules.ensure_qb = function(knights)
if not team_info[offense].lineup[1].taken then
for i, v in ipairs(team_info[offense].lineup) do
if v.taken then
rules.set_tile(v.host, knights[v.host], 1, team_info[offense].lineup[1])
break
end
end
end
end
rules.set_lineup = function(team)
local lineup = {}
local sign = (team-1.5)*2
local field_w, field_h = field.get_dimensions()
local y = math.floor(field_h/2)
local x = lineup_buffer+team-1 -- team 2 has an extra offset of one to account for the scrimmage marker being inbetween tiles but saved as one
lineup[1] = {x = (x+1)*sign, y = y}
lineup[2] = {x = x*sign, y = y}
for i = 1, math.floor(lineup_h[team]/2) do
lineup[#lineup+1] = {x = (x+1)*sign, y = y+i}
lineup[#lineup+1] = {x = (x+1)*sign, y = y-i}
lineup[#lineup+1] = {x = x*sign, y = y+i}
lineup[#lineup+1] = {x = x*sign, y = y-i}
end
team_info[team].lineup = lineup
end
rules.get_scrimmage = function()
return scrimmage
end
rules.max_players = function()
local field_w, field_h = field.get_dimensions()
return 2*field_h
end
return rules