ldd-CC/tron

883 lines
20 KiB
Plaintext
Raw Normal View History

2018-11-14 21:26:04 +00:00
--[[
TRON Light Cycle Game
programmed by LDDestroier
wget https://raw.githubusercontent.com/LDDestroier/CC/master/tron
--]]
2018-11-14 17:01:01 +00:00
local port = 701
2018-11-13 20:02:55 +00:00
local scr_x, scr_y = term.getSize()
2018-11-14 17:01:01 +00:00
local modem = peripheral.find("modem")
if (not modem) and ccemux then
ccemux.attach("top", "wireless_modem")
modem = peripheral.find("modem")
end
2018-11-14 04:01:14 +00:00
2018-11-14 17:01:01 +00:00
if modem then
modem.open(port)
else
error("You should attach a modem.")
2018-11-14 17:01:01 +00:00
end
2018-11-13 20:02:55 +00:00
local gamename = ""
local isHost
2018-11-14 22:27:21 +00:00
local squareGrid = true
local waitingForGame = true
2018-11-14 21:37:31 +00:00
local deepCopy
deepCopy = function(tbl, ...)
local output = {}
for k,v in pairs(tbl) do
if type(v) == "table" then
output[k] = deepCopy(v)
else
output[k] = v
end
end
for i = 1, #arg do
output[#output+1] = arg[i]
end
return output
end
2018-11-14 22:27:21 +00:00
local initGrid = {
x1 = -100,
y1 = -100,
x2 = 100,
y2 = 100,
2018-11-13 20:06:05 +00:00
border = "#",
2018-11-13 20:02:55 +00:00
voidcol = "f",
forecol = "8",
backcol = "7",
edgecol = "0"
}
2018-11-14 22:27:21 +00:00
grid = deepCopy(initGrid)
2018-11-13 20:02:55 +00:00
local you = 1
local nou = 2
local keysDown = {}
local netKeysDown = {}
2018-11-14 21:09:32 +00:00
-- the scrolling of the screen
2018-11-13 20:02:55 +00:00
local scrollX = 0
local scrollY = 0
2018-11-14 21:09:32 +00:00
-- used when panning with WASD
2018-11-14 01:09:15 +00:00
local scrollAdjX = 0
local scrollAdjY = 0
local lockInput = false
2018-11-15 05:50:18 +00:00
local gameDelayInit = 0.1 -- lower value = faster game. I'd reccommend 0.1 for SMP play.
2018-11-14 01:09:15 +00:00
local player
local resetPlayers = function()
player = {
[1] = {
2018-11-14 01:34:28 +00:00
x = -2,
2018-11-14 01:09:15 +00:00
y = -5,
direction = -1,
char = "@",
color = {
colors.blue,
colors.blue,
colors.blue,
colors.cyan,
colors.cyan,
colors.lightBlue,
colors.lightBlue,
colors.cyan,
colors.cyan
},
dead = false,
putTrail = true
},
[2] = {
2018-11-14 01:34:28 +00:00
x = 2,
2018-11-14 01:09:15 +00:00
y = -5,
direction = -1,
char = "@",
color = {
colors.red,
colors.red,
colors.red,
colors.orange,
colors.orange,
colors.yellow,
colors.yellow,
colors.orange,
colors.orange
},
dead = false,
putTrail = true
}
}
end
2018-11-14 01:09:15 +00:00
resetPlayers()
local images = {
logo = {
{
" •ƒƒƒƒƒƒƒƒƒ•—ƒƒƒƒƒƒƒ‹‹ ‡‡ƒƒƒ‹‹ Ÿ‹ •ƒƒ•",
" •ƒƒƒ”€—ƒƒƒ•‚ƒƒƒƒƒ‹€€€Š —€Ÿƒƒƒ€” •‚‚ •€€•",
" •€• ‚‚ƒƒ•€€—€€€”€€••€€‹‹ •€€•",
" •€• —ƒ”‹“ƒƒ‹€€€•€€•€€€•€€••€•ˆƒ€€•",
" •€• •€• ‚‹€€‹€Š€‹‡€Ÿ…•€• ‚‚€•",
" •€• •€• ‹€‚‹ ‹‹€€€Ÿ‡‡ •€• ‹‹•",
"   Š ‚‹‡  ‚…",
},
{
" f7777777777777777777f f77777f 7f f777",
" f99979999979999999999f 799999799 77f7 f997",
" 799 79999f997ffff9977997f f997",
" 799 7797777fffff997ffff9977997797997",
" 799 799 799977f7797fff7997799 79797",
" 799 799 7797f 797999997 799 797",
" 777 777 7777 7777777 777 77",
},
{
" 7999999999f9999999997 7999997 97 799f",
" 7777997777f77777779997 997777997 997f 799f",
" 997 f7777799ffff799f99997 799f",
" 997 997f9997fff799ffff799f997ff7999f",
" 997 997 f7999fff999777997f997 f799f",
" 997 997 f9997 f7999977f 997 f7f",
" fff fff ffff fffffff fff ff",
}
},
win = {
{
2018-11-15 00:51:52 +00:00
"€•€€€€€€€••€€€€€€€€Š€€€€•€€€•",
"€•€€€€€€€•‚€€•€ƒ€€€‚€€•€€€•",
"€•€€‡€€€•€€€€•€€€€•‹€‹€•€€€•",
"€•ŸŸ€‹€€•€€€€•€€€€•€‚‚…€€€•",
"€‚€‡€‚‚€•Ÿ€€•€€€•€€€‹€€€",
"€Ÿ€€€€‹€••€€€€€€€€•€€€€•€€€•",
},
{
2018-11-15 00:51:52 +00:00
"55ffffff55f555555f5ffffff5f55",
"55ffffff5555f55f5f55f5fff5f55",
"55fff5ff55fff55fff5555fff5f55",
"55ff55ff55fff55fff55f5fff5f55",
"5f55f5ff55f5f55fff55fff555ff5",
"555ffff555f555555f55fffff5f55",
},
{
2018-11-15 00:51:52 +00:00
"5fffffff5f5555555f55ffff55f5f",
"5fffffff5ffff5ffff555fff55f5f",
"5fff5fff5ffff5ffff5ff55f55f5f",
"5f55f55f5ffff5ffff5fff5555f5f",
"555fff555f5ff5ff5f5fffff55f5f",
"5fffffff5f5555555f5fffff55f5f",
}
},
lose = {
{
2018-11-15 00:51:52 +00:00
"€•€€€€€€Ÿ€€€‚€€€€€€‚€€€€€€€€",
"€•€€€€€€€Ÿ€‚€€€—€€€‚ƒ€€•€€€‚ƒ",
"€•€€€€€€€•€€€•€€€€ƒƒƒƒ‹€€‚ƒƒƒ”€",
"€•€€€€€€€•€€€•€€‚ƒƒƒƒ€€€—ƒƒƒ€",
"€•€€€€€€€‚€Ÿ€€€€€…€€€•€€€Ÿ",
"€€€€€€€€‚€€€Ÿ€€€€€€Ÿ€€€€€€€€",
},
{
2018-11-15 00:51:52 +00:00
"eeffffffffeeefeffeeeeeffeeeeeee",
"eeffffffeeefefefeefffeefeefffee",
"eeffffffeeffffefeeffffffeffffef",
"eeffffffeeffffefeeeeefefeeeeeef",
"eeffffffefefffeffeffffefeefffff",
"eeeeeeefefeeeeeffeeeeeefeeeeeee",
},
{
2018-11-15 00:51:52 +00:00
"efffffffeeeeeeffeeeeeeefeeeeeee",
"efffffffeffffeefefffffffeffffff",
"efffffffeffffeefeeeeeeefeeeeeff",
"efffffffeffffeeffffffeefeffffff",
"efffffffeeffeeefeffffeefeffffee",
"eeeeeeeffeeeefffeeeeeeffeeeeeee",
}
},
tie = {
{
2018-11-15 00:51:52 +00:00
"€€€€€€€••€€€€€€€€€€€€€€€",
"€€€€•€€€‚€•€€€ƒ€€•€€€€ƒ",
"€€€€•€€€€€€•€€€€€€‚ƒƒƒ”€",
"€€€€•€€€€€€•€€€€€€—ƒƒƒ€",
"€€€€•€€€Ÿ€•€€€€€•€€€€",
"€€€€•€€€•€€€€€€€€€€€€€€€",
},
{
2018-11-15 00:51:52 +00:00
"77888800f0000000f0888877",
"fff88fff00ff0ff0f08ffff7",
"fff88fffffff0ffff0ffff7f",
"fff88fffffff0ffff088887f",
"fff88ffff0ff0ffff08fffff",
"fff88ffff0000000f0888877",
},
{
2018-11-15 00:51:52 +00:00
"7788880f00000000f0888877",
"fff8fffffff00ffff0ffffff",
"fff8fffffff00ffff08888ff",
"fff8fffffff00ffff0ffffff",
"fff8ffff0ff00ff0f0fffff7",
"fff8ffff00000000f0888877",
},
}
}
for k,v in pairs(images) do
v.x = #v[1][1]
v.y = #v[1]
2018-11-15 16:56:27 +00:00
for i = 2, #v do
for line = 1, #v[i] do
images[k][i][line] = v[i][line]:gsub("f", " ")
end
end
end
local drawImage = function(im, x, y)
local cx, cy = term.getCursorPos()
for iy = 1, #im[1] do
2018-11-15 16:56:27 +00:00
for ix = 1, #im[1][iy] do
term.setCursorPos(x+(ix-1),y+(iy-1))
if not (im[2][iy]:sub(ix,ix) == " " and im[3][iy]:sub(ix,ix) == " ") then
term.blit(im[1][iy]:sub(ix,ix), im[2][iy]:sub(ix,ix), im[3][iy]:sub(ix,ix))
end
end
end
term.setCursorPos(cx,cy)
end
local deadGuys = {}
2018-11-14 01:09:15 +00:00
local trail = {}
local putTrail = function(p)
trail[p.y] = trail[p.y] or {}
trail[p.y][p.x] = {
player = p,
age = 0
}
end
local getTrail = function(x, y)
if trail[y] then
if trail[y][x] then
if doAge then
trail[y][x].age = trail[y][x].age + 1
end
return trail[y][x].player.char, trail[y][x].player.color, trail[y][x].age
end
end
return false
end
local ageTrails = function()
for y,l in pairs(trail) do
for x,v in pairs(l) do
trail[y][x].age = trail[y][x].age + 1
end
end
end
local toblit = {
[0] = " ",
[colors.white] = "0",
[colors.orange] = "1",
[colors.magenta] = "2",
[colors.lightBlue] = "3",
[colors.yellow] = "4",
[colors.lime] = "5",
[colors.pink] = "6",
[colors.gray] = "7",
[colors.lightGray] = "8",
[colors.cyan] = "9",
[colors.purple] = "a",
[colors.blue] = "b",
[colors.brown] = "c",
[colors.green] = "d",
[colors.red] = "e",
[colors.black] = "f"
2018-11-13 20:02:55 +00:00
}
2018-11-13 21:35:25 +00:00
local control = {
up = keys.up,
down = keys.down,
left = keys.left,
right = keys.right,
lookUp = keys.w,
lookDown = keys.s,
lookLeft = keys.a,
lookRight = keys.d,
release = keys.space
}
-- keeps track of where you are
local gamemode = ""
2018-11-13 20:39:29 +00:00
2018-11-14 22:27:21 +00:00
local gridFore, gridBack
if squareGrid then
gridFore = {
"+-------",
"| ",
"| ",
"| ",
"| "
}
gridBack = {
"+------------",
"| ",
"| ",
"| ",
"| ",
"| ",
"| ",
"| "
}
else
gridFore = {
" / ",
" / ",
" / ",
" / ",
"/__________"
}
gridBack = {
" / ",
" / ",
" / ",
" / ",
" / ",
" / ",
" / ",
"/_______________"
}
end
2018-11-13 20:17:08 +00:00
2018-11-14 01:09:15 +00:00
local dirArrow = {
[-1] = "^",
[0] = ">",
[1] = "V",
[2] = "<"
}
local doesIntersectBorder = function(x, y)
return x == grid.x1 or x == grid.x2 or y == grid.y1 or y == grid.y2
end
2018-11-15 17:17:45 +00:00
--draws grid and background at scroll 'x' and 'y', along with trails and players
local drawGrid = function(x, y, onlyDrawGrid)
2018-11-13 20:11:07 +00:00
x, y = math.floor(x + 0.5), math.floor(y + 0.5)
2018-11-13 20:02:55 +00:00
local bg = {{},{},{}}
local foreX, foreY
local backX, backY
local adjX, adjY
2018-11-14 01:09:15 +00:00
local trailChar, trailColor, trailAge, isPlayer
2018-11-13 20:02:55 +00:00
for sy = 1, scr_y do
bg[1][sy] = ""
bg[2][sy] = ""
bg[3][sy] = ""
for sx = 1, scr_x do
2018-11-14 01:09:15 +00:00
adjX = (sx + x)
adjY = (sy + y)
foreX = 1 + (sx + x) % #gridFore[1]
foreY = 1 + (sy + y) % #gridFore
2018-11-14 01:40:32 +00:00
backX = 1 + math.floor(sx + (x / 2)) % #gridBack[1]
backY = 1 + math.floor(sy + (y / 2)) % #gridBack
2018-11-14 01:09:15 +00:00
trailChar, trailColor, trailAge = getTrail(adjX, adjY)
isPlayer = false
2018-11-15 17:17:45 +00:00
if not onlyDrawGrid then
for i = 1, #player do
if player[i].x == adjX and player[i].y == adjY then
isPlayer = i
break
end
2018-11-14 01:09:15 +00:00
end
end
if isPlayer and not (doesIntersectBorder(adjX, adjY)) then
bg[1][sy] = bg[1][sy] .. dirArrow[player[isPlayer].direction]
bg[2][sy] = bg[2][sy] .. toblit[player[isPlayer].color[1]]
2018-11-13 20:39:29 +00:00
bg[3][sy] = bg[3][sy] .. grid.voidcol
2018-11-13 20:02:55 +00:00
else
2018-11-15 17:17:45 +00:00
if (not onlyDrawGrid) and trailChar and trailColor then
2018-11-14 01:09:15 +00:00
trailColor = trailColor[1 + ((trailAge - 1) % #trailColor)]
bg[1][sy] = bg[1][sy] .. trailChar
bg[2][sy] = bg[2][sy] .. toblit[trailColor]
2018-11-13 20:02:55 +00:00
bg[3][sy] = bg[3][sy] .. grid.voidcol
else
2018-11-15 17:17:45 +00:00
if (not onlyDrawGrid) and (adjX < grid.x1 or adjX > grid.x2 or adjY < grid.y1 or adjY > grid.y2) then
2018-11-14 01:09:15 +00:00
bg[1][sy] = bg[1][sy] .. " "
bg[2][sy] = bg[2][sy] .. grid.voidcol
bg[3][sy] = bg[3][sy] .. grid.voidcol
2018-11-15 17:17:45 +00:00
elseif (not onlyDrawGrid) and doesIntersectBorder(adjX, adjY) then
2018-11-14 01:09:15 +00:00
bg[1][sy] = bg[1][sy] .. grid.border
bg[2][sy] = bg[2][sy] .. grid.voidcol
bg[3][sy] = bg[3][sy] .. grid.edgecol
else
if gridFore[foreY]:sub(foreX,foreX) ~= " " then
bg[1][sy] = bg[1][sy] .. gridFore[foreY]:sub(foreX,foreX)
bg[2][sy] = bg[2][sy] .. grid.forecol
bg[3][sy] = bg[3][sy] .. grid.voidcol
elseif gridBack[backY]:sub(backX,backX) ~= " " then
bg[1][sy] = bg[1][sy] .. gridBack[backY]:sub(backX,backX)
bg[2][sy] = bg[2][sy] .. grid.backcol
bg[3][sy] = bg[3][sy] .. grid.voidcol
else
bg[1][sy] = bg[1][sy] .. " "
bg[2][sy] = bg[2][sy] .. grid.voidcol
bg[3][sy] = bg[3][sy] .. grid.voidcol
end
end
2018-11-13 20:02:55 +00:00
end
end
end
end
for sy = 1, scr_y do
term.setCursorPos(1,sy)
term.blit(bg[1][sy], bg[2][sy], bg[3][sy])
end
end
2018-11-14 01:09:15 +00:00
local render = function()
local p = player[you]
drawGrid(scrollX + scrollAdjX, scrollY + scrollAdjY)
term.setCursorPos(1,1)
term.setTextColor(player[you].color[1])
term.write("P" .. you)
end
local pleaseWait = function()
local periods = 1
local maxPeriods = 5
term.setBackgroundColor(colors.black)
term.setTextColor(colors.gray)
term.clear()
local tID = os.startTimer(0.2)
local evt
local txt = "Waiting for game"
while true do
term.setCursorPos(math.floor(scr_x / 2 - (#txt + maxPeriods) / 2), scr_y - 2)
term.write(txt .. ("."):rep(periods))
evt = {os.pullEvent()}
if evt[1] == "timer" and evt[2] == tID then
tID = os.startTimer(0.5)
periods = (periods % maxPeriods) + 1
term.clearLine()
elseif evt[1] == "new_game" then
return evt[2]
end
end
2018-11-14 01:09:15 +00:00
end
2018-11-15 00:28:01 +00:00
local startCountdown = function()
local cName = "PLAYER " .. you
local col = colors.white
for k,v in pairs(colors) do
if player[you].color[1] == v then
cName = k:upper()
col = v
break
end
end
local cMessage = "You are "
2018-11-15 00:38:57 +00:00
scrollX = player[you].x - math.floor(scr_x / 2)
scrollY = player[you].y - math.floor(scr_y / 2)
2018-11-15 00:30:05 +00:00
for i = 3, 1, -1 do
2018-11-15 00:28:01 +00:00
render()
2018-11-15 00:39:40 +00:00
term.setCursorPos(math.floor(scr_x / 2 - (#cMessage + #cName) / 2), math.floor(scr_y / 2) + 2)
2018-11-15 00:28:01 +00:00
term.setTextColor(colors.white)
term.write(cMessage)
term.setTextColor(col)
term.write(cName)
term.setTextColor(colors.white)
2018-11-15 00:39:40 +00:00
term.setCursorPos(math.floor(scr_x / 2 - 2), math.floor(scr_y / 2) + 4)
2018-11-15 00:28:01 +00:00
term.write(i .. "...")
sleep(1)
end
end
2018-11-15 17:17:45 +00:00
local makeMenu = function(x, y, options, doAnimate)
2018-11-13 21:35:25 +00:00
local cpos = 1
local cursor = "> "
2018-11-15 17:17:45 +00:00
local gsX, gsY = 0, 0
local step = 0
local lastPos = cpos
if not doAnimate then
drawImage(images.logo, math.ceil(scr_x / 2 - images.logo.x / 2), 2)
end
2018-11-15 05:38:39 +00:00
local rend = function()
2018-11-15 17:17:45 +00:00
if doAnimate then
drawImage(images.logo, math.ceil(scr_x / 2 - images.logo.x / 2), 2)
end
2018-11-13 21:35:25 +00:00
for i = 1, #options do
if i == cpos then
2018-11-15 17:17:45 +00:00
term.setCursorPos(x, y + (i - 1))
2018-11-13 21:35:25 +00:00
term.setTextColor(colors.white)
term.write(cursor .. options[i])
else
2018-11-15 17:17:45 +00:00
if i == lastPos then
term.setCursorPos(x, y + (i - 1))
term.write((" "):rep(#cursor))
lastPos = nil
else
term.setCursorPos(x + #cursor, y + (i - 1))
end
2018-11-13 21:35:25 +00:00
term.setTextColor(colors.gray)
2018-11-15 17:17:45 +00:00
term.write(options[i])
2018-11-13 21:35:25 +00:00
end
end
end
2018-11-15 17:17:45 +00:00
local gstID, evt = math.random(1,65535)
if doAnimate then
os.queueEvent("timer", gstID)
end
2018-11-14 01:09:15 +00:00
while true do
2018-11-15 05:38:39 +00:00
rend()
2018-11-14 01:09:15 +00:00
evt = {os.pullEvent()}
if evt[1] == "key" then
if evt[2] == keys.up then
2018-11-15 17:17:45 +00:00
lastPos = cpos
2018-11-14 22:27:21 +00:00
cpos = (cpos - 2) % #options + 1
2018-11-14 01:09:15 +00:00
elseif evt[2] == keys.down then
2018-11-15 17:17:45 +00:00
lastPos = cpos
2018-11-14 21:42:14 +00:00
cpos = (cpos % #options) + 1
2018-11-15 17:17:45 +00:00
elseif evt[2] == keys.home then
lastPos = cpos
cpos = 1
elseif evt[2] == keys["end"] then
lastPos = cpos
cpos = #options
2018-11-14 01:09:15 +00:00
elseif evt[2] == keys.enter then
return cpos
end
2018-11-15 17:17:45 +00:00
elseif evt[1] == "timer" and evt[2] == gstID then
gstID = os.startTimer(0.05)
drawGrid(gsX, gsY, true)
step = step + 1
if math.ceil(step / 100) % 2 == 1 then
gsX = gsX + 1
else
gsY = gsY - 1
end
2018-11-14 01:09:15 +00:00
end
end
2018-11-13 21:35:25 +00:00
end
local titleScreen = function()
term.clear()
2018-11-14 01:09:15 +00:00
local choice = makeMenu(2, scr_y - 4, {
"Start Game",
2018-11-14 21:26:04 +00:00
"How to Play",
2018-11-14 01:09:15 +00:00
"Grid Demo",
"Exit"
2018-11-15 17:17:45 +00:00
}, true)
2018-11-14 01:09:15 +00:00
if choice == 1 then
return "start"
elseif choice == 2 then
2018-11-14 21:26:04 +00:00
return "help"
2018-11-14 01:09:15 +00:00
elseif choice == 3 then
2018-11-14 21:26:04 +00:00
return "demo"
elseif choice == 4 then
2018-11-14 01:09:15 +00:00
return "exit"
end
2018-11-13 21:35:25 +00:00
end
2018-11-14 01:09:15 +00:00
local cleanExit = function()
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1,1)
2018-11-14 21:31:24 +00:00
print("Thanks for playing!")
2018-11-14 01:09:15 +00:00
end
2018-11-13 21:35:25 +00:00
2018-11-13 20:39:29 +00:00
local getInput = function()
local evt
2018-11-13 20:39:29 +00:00
while true do
evt = {os.pullEvent()}
2018-11-14 01:09:15 +00:00
if lockInput then
keysDown = {}
else
if evt[1] == "key" then
keysDown[evt[2]] = true
elseif evt[1] == "key_up" then
keysDown[evt[2]] = false
end
2018-11-13 20:39:29 +00:00
end
end
end
2018-11-14 01:09:15 +00:00
2018-11-14 21:31:24 +00:00
local scrollToPosition = function(x, y)
2018-11-14 01:09:15 +00:00
for i = 1, 16 do
scrollX = (scrollX + x - (scr_x/2)) / 2
scrollY = (scrollY + y - (scr_y/2)) / 2
render()
2018-11-14 21:37:31 +00:00
sleep(0.05)
2018-11-14 01:09:15 +00:00
end
end
2018-11-13 20:39:29 +00:00
local gridDemo = function()
2018-11-14 01:40:32 +00:00
keysDown = {}
2018-11-13 20:39:29 +00:00
while true do
if keysDown[keys.left] then
2018-11-14 01:09:15 +00:00
scrollX = scrollX - 1
2018-11-13 20:39:29 +00:00
end
if keysDown[keys.right] then
2018-11-14 01:09:15 +00:00
scrollX = scrollX + 1
2018-11-13 20:39:29 +00:00
end
if keysDown[keys.up] then
2018-11-14 01:09:15 +00:00
scrollY = scrollY - 1
2018-11-13 20:39:29 +00:00
end
if keysDown[keys.down] then
2018-11-14 01:09:15 +00:00
scrollY = scrollY + 1
2018-11-13 20:39:29 +00:00
end
2018-11-14 01:34:28 +00:00
if keysDown[keys.q] then
return "end"
end
2018-11-13 20:39:29 +00:00
drawGrid(scrollX, scrollY)
2018-11-14 01:09:15 +00:00
ageTrails()
2018-11-14 21:31:24 +00:00
sleep(gameDelay)
2018-11-13 20:39:29 +00:00
end
2018-11-13 20:02:55 +00:00
end
2018-11-14 01:09:15 +00:00
2018-11-15 05:21:43 +00:00
local sendInfo = function(gameID)
modem.transmit(port, port, {
player = player,
gameID = gameID,
keysDown = keysDown,
trail = isHost and trail or nil,
2018-11-14 21:31:24 +00:00
deadGuys = isHost and deadGuys or {},
})
end
2018-11-14 21:09:32 +00:00
local waitForKey = function(time)
sleep(time or 0.1)
2018-11-14 21:26:59 +00:00
os.pullEvent("key")
2018-11-14 21:09:32 +00:00
end
local deadAnimation = function(doSend)
for k,v in pairs(deadGuys) do
player[k].char = "X"
lockInput = true
end
if doSend then
2018-11-15 05:21:43 +00:00
sendInfo(gamename)
2018-11-14 01:09:15 +00:00
end
2018-11-14 01:34:28 +00:00
if deadGuys[you] or deadGuys[nou] then
term.setTextColor(colors.white)
if deadGuys[you] and deadGuys[nou] then
scrollToPosition(player[nou].x, player[nou].y)
scrollToPosition(player[you].x, player[you].y)
2018-11-15 00:48:05 +00:00
drawImage(images.tie, math.ceil(scr_x / 2 - images.tie.x / 2), math.floor(scr_y / 2 - images.tie.y / 2))
2018-11-14 21:09:32 +00:00
waitForKey(1)
2018-11-14 01:34:28 +00:00
return "end"
else
if deadGuys[you] then
scrollX, scrollY = player[nou].x - scr_x / 2, player[nou].y - scr_y / 2
scrollToPosition(player[you].x, player[you].y)
2018-11-15 00:48:05 +00:00
drawImage(images.lose, math.ceil(scr_x / 2 - images.lose.x / 2), math.floor(scr_y / 2 - images.lose.y / 2))
2018-11-14 21:09:32 +00:00
waitForKey(1)
2018-11-14 01:34:28 +00:00
return "end"
elseif deadGuys[nou] then
scrollToPosition(player[nou].x, player[nou].y)
2018-11-15 00:48:05 +00:00
drawImage(images.win, math.ceil(scr_x / 2 - images.win.x / 2), math.floor(scr_y / 2 - images.win.y / 2))
2018-11-14 21:09:32 +00:00
waitForKey(1)
2018-11-14 01:34:28 +00:00
return "end"
end
end
end
end
local moveTick = function(doSend)
local p
for i = 1, #player do
p = player[i]
if not p.dead then
2018-11-15 06:28:54 +00:00
if isHost then
p.x = p.x + math.floor(math.cos(math.rad(p.direction * 90)))
p.y = p.y + math.floor(math.sin(math.rad(p.direction * 90)))
if doesIntersectBorder(p.x, p.y) or getTrail(p.x, p.y) then
p.dead = true
deadGuys[i] = true
elseif p.putTrail then
putTrail(p)
end
2018-11-15 06:28:54 +00:00
end
for a = 1, #player do
if (a ~= i) and (player[a].x == p.x and player[a].y == p.y) then
p.dead = true
deadGuys[i] = true
if (p.direction + 2) % 4 == player[a].direction % 4 then
player[a].dead = true
deadGuys[a] = true
end
break
end
end
end
end
2018-11-14 01:09:15 +00:00
ageTrails()
return deadAnimation(doSend)
end
2018-11-15 05:29:31 +00:00
local setDirection = function(keylist, p, checkDir)
2018-11-15 05:21:43 +00:00
p.putTrail = not keylist[control.release]
2018-11-15 05:29:31 +00:00
if keylist[control.left] and (checkDir or p.direction) ~= 0 then
2018-11-15 05:21:43 +00:00
p.direction = 2
2018-11-15 05:29:31 +00:00
elseif keylist[control.right] and (checkDir or p.direction) ~= 2 then
2018-11-15 05:21:43 +00:00
p.direction = 0
2018-11-15 05:32:51 +00:00
elseif keylist[control.up] and (checkDir or p.direction) ~= 1 then
2018-11-15 05:21:43 +00:00
p.direction = -1
2018-11-15 05:29:31 +00:00
elseif keylist[control.down] and (checkDir or p.direction) ~= -1 then
2018-11-15 05:21:43 +00:00
p.direction = 1
end
2018-11-14 01:09:15 +00:00
end
local game = function()
2018-11-14 17:01:01 +00:00
local outcome
local p, np
2018-11-14 01:09:15 +00:00
while true do
p = player[you]
np = player[nou]
if isHost then
2018-11-15 05:21:43 +00:00
setDirection(keysDown, p)
setDirection(netKeysDown, np)
2018-11-15 05:30:02 +00:00
else
2018-11-15 05:37:02 +00:00
setDirection(keysDown, p)
2018-11-14 01:09:15 +00:00
end
if keysDown[control.lookLeft] then
scrollAdjX = scrollAdjX - 2
end
if keysDown[control.lookRight] then
scrollAdjX = scrollAdjX + 2
end
if keysDown[control.lookUp] then
scrollAdjY = scrollAdjY - 1.5
end
if keysDown[control.lookDown] then
scrollAdjY = scrollAdjY + 1.5
end
2018-11-14 01:09:15 +00:00
scrollAdjX = scrollAdjX * 0.8
scrollAdjY = scrollAdjY * 0.8
if isHost then
outcome = moveTick(true)
else
outcome = deadAnimation(true)
end
2018-11-14 01:09:15 +00:00
if outcome == "end" then
return
else
scrollX = p.x - math.floor(scr_x / 2)
scrollY = p.y - math.floor(scr_y / 2)
render()
2018-11-14 21:31:24 +00:00
sleep(gameDelay)
2018-11-14 01:09:15 +00:00
end
end
end
local decision
2018-11-14 04:01:14 +00:00
local networking = function()
local evt, side, channel, repchannel, msg, distance
while true do
evt, side, channel, repchannel, msg, distance = os.pullEvent("modem_message")
if channel == port and repchannel == port and type(msg) == "table" then
if type(msg.player) == "table" and type(msg.gameID) == "string" then
if waitingForGame and (type(msg.new) == "number") then
if msg.new < os.time() then
gamename = msg.gameID
isHost = false
2018-11-14 21:37:31 +00:00
gameDelay = tonumber(msg.gameDelay) or 0.05
2018-11-14 22:27:21 +00:00
grid = msg.grid or deepCopy(initGrid)
else
you, nou = nou, you
isHost = true
end
you, nou = nou, you
modem.transmit(port, port, {
player = player,
gameID = gamename,
2018-11-14 22:27:21 +00:00
new = isHost and (-math.huge) or (math.huge),
grid = initGrid
})
waitingForGame = false
netKeysDown = {}
os.queueEvent("new_game", gameID)
2018-11-14 22:27:21 +00:00
elseif msg.gameID == gamename then
if not isHost then
player = msg.player
trail = msg.trail
deadGuys = msg.deadGuys
elseif type(msg.keysDown) == "table" then
netKeysDown = msg.keysDown
end
end
end
end
end
end
2018-11-15 05:38:39 +00:00
local helpScreen = function()
2018-11-14 21:26:04 +00:00
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1,2)
print([[
Move with arrow keys.
Pan the camera with WASD.
Hold SPACE to create gaps.
That's basically it.
Press any key to go back.
]])
waitForKey(0.25)
end
2018-11-14 01:09:15 +00:00
while true do
decision = titleScreen()
lockInput = false
if decision == "start" then
trail = {}
deadGuys = {}
2018-11-14 21:37:31 +00:00
gameDelay = gameDelayInit
2018-11-14 22:27:21 +00:00
grid = deepCopy(initGrid)
2018-11-14 01:09:15 +00:00
resetPlayers()
you, nou = 1, 2
gamename = ""
for i = 1, 32 do
gamename = gamename .. string.char(math.random(1,126))
end
waitingForGame = true
modem.transmit(port, port, {
player = player,
gameID = gamename,
2018-11-14 21:39:44 +00:00
new = os.time(),
gameDelay = gameDelayInit,
2018-11-14 22:27:21 +00:00
grid = initGrid
})
parallel.waitForAny(pleaseWait, networking)
2018-11-15 00:38:57 +00:00
sleep(0.1)
2018-11-15 00:28:01 +00:00
startCountdown()
parallel.waitForAny(getInput, game, networking)
2018-11-14 21:26:04 +00:00
elseif decision == "help" then
helpScreen()
2018-11-14 01:09:15 +00:00
elseif decision == "demo" then
parallel.waitForAny(getInput, gridDemo)
elseif decision == "exit" then
return cleanExit()
end
2018-11-14 21:09:32 +00:00
end