Created
October 20, 2020 07:49
-
-
Save x4fx77x4f/4cb61ea0d46067d93238448ec2b381c9 to your computer and use it in GitHub Desktop.
Minesweeper in StarfallEx. State is not kept in sync across clients.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--@name Minesweeper | |
--@author x4fx77x4f | |
--@client | |
local hook_add = hook.add | |
local hook_remove = hook.remove | |
local IN_KEY_USE = IN_KEY.USE | |
local IN_KEY_ATTACK = IN_KEY.ATTACK | |
local IN_KEY_ATTACK2 = IN_KEY.ATTACK2 | |
local material_create = material.create | |
local math_floor = math.floor | |
local math_random = math.random | |
local render_createRenderTarget = render.createRenderTarget | |
local render_drawRect = render.drawRect | |
local render_drawTexturedRectUV = render.drawTexturedRectUV | |
local render_cursorPos = render.cursorPos | |
local render_selectRenderTarget = render.selectRenderTarget | |
local render_setFilterMag = render.setFilterMag | |
local render_setRenderTargetTexture = render.setRenderTargetTexture | |
local render_setMaterial = render.setMaterial | |
local timer_systime = timer.systime | |
local tostring = tostring | |
local unpack = unpack | |
local texture = material_create("UnlitGeneric") | |
texture:setTextureURL("$basetexture", "https://i.imgur.com/O0vf4Fa.png", function() | |
local atlas = { | |
[0] = {0.046875, 0, 0.0625, 0.015625}, | |
[1] = {0, 0.015625, 0.015625, 0.03125}, | |
[2] = {0.015625, 0.015625, 0.03125, 0.03125}, | |
[3] = {0.03125, 0.015625, 0.046875, 0.03125}, | |
[4] = {0.046875, 0.015625, 0.0625, 0.03125}, | |
[5] = {0, 0.03125, 0.015625, 0.046875}, | |
[6] = {0.015625, 0.03125, 0.03125, 0.046875}, | |
[7] = {0.03125, 0.03125, 0.046875, 0.046875}, | |
[8] = {0.046875, 0.03125, 0.0625, 0.046875} | |
} | |
local w = 16 | |
local h = 16 | |
local mn = 40 | |
local field1 = {} | |
local field2 = {} | |
local function init() | |
for y=1, h do | |
local row1 = {} | |
local row2 = {} | |
for x=1, w do | |
row1[x] = 0 | |
row2[x] = 1 | |
end | |
field1[y] = row1 | |
field2[y] = row2 | |
end | |
for m=1, mn do | |
local mx, my | |
repeat | |
mx, my = math_random(1, w), math_random(1, h) | |
until field1[my][mx] >= 0 | |
if my > 1 then | |
local row1 = field1[my-1] | |
if mx > 1 then | |
row1[mx-1] = row1[mx-1]+1 | |
end | |
row1[mx] = row1[mx]+1 | |
if mx < w then | |
row1[mx+1] = row1[mx+1]+1 | |
end | |
end | |
local row2 = field1[my] | |
if mx > 1 then | |
row2[mx-1] = row2[mx-1]+1 | |
end | |
row2[mx] = -mn | |
if mx < w then | |
row2[mx+1] = row2[mx+1]+1 | |
end | |
if my < h then | |
local row3 = field1[my+1] | |
if mx > 1 then | |
row3[mx-1] = row3[mx-1]+1 | |
end | |
row3[mx] = row3[mx]+1 | |
if mx < w then | |
row3[mx+1] = row3[mx+1]+1 | |
end | |
end | |
end | |
end | |
init() | |
local mw = 512/w | |
local mh = 512/h | |
local mw2 = mw/2 | |
local mh2 = mh/2 | |
local cx, cy | |
local updatePending = true | |
render_createRenderTarget("main") | |
hook_add("render", "", function() | |
cx, cy = render_cursorPos() | |
render_setFilterMag(1) | |
if updatePending then | |
render_selectRenderTarget("main") | |
render_setMaterial(texture) | |
for y=1, h do | |
local row1 = field1[y] | |
local row2 = field2[y] | |
for x=1, w do | |
local mx = x*mw-mw | |
local my = y*mh-mh | |
local state = row2[x] | |
if state == 0 then | |
if row1[x] < 0 then | |
render_drawTexturedRectUV(mx, my, mw, mh, 0.03125, 0, 0.046875, 0.015625) | |
else | |
render_drawTexturedRectUV(mx, my, mw, mh, unpack(atlas[row1[x]])) | |
end | |
elseif state == 1 then | |
render_drawTexturedRectUV(mx, my, mw, mh, 0, 0, 0.015625, 0.015625) | |
else | |
render_drawTexturedRectUV(mx, my, mw, mh, 0.015625, 0, 0.03125, 0.015625) | |
end | |
end | |
end | |
updatePending = false | |
render_selectRenderTarget() | |
end | |
render_setRenderTargetTexture("main") | |
render_drawTexturedRectUV(0, 0, 512, 512, 0, 0, 0.5, 0.5) | |
end) | |
local seen = {} | |
for y=1, h do | |
seen[y] = {} | |
end | |
local function traverse(x, y) | |
if x < 1 or y < 1 or x > w or y > h or seen[y][x] then | |
return | |
end | |
seen[y][x] = true | |
field2[y][x] = 0 | |
if field1[y][x] == 0 then | |
traverse(x, y-1) | |
traverse(x+1, y-1) | |
traverse(x+1, y) | |
traverse(x+1, y+1) | |
traverse(x, y+1) | |
traverse(x-1, y+1) | |
traverse(x-1, y) | |
traverse(x-1, y-1) | |
end | |
end | |
local lost = false | |
local lastTime = 0 | |
hook_add("keyPress", "", function(ply, key) | |
if not cx then | |
return | |
end | |
local now = timer_systime() | |
if now-lastTime < 0.1 then | |
return | |
end | |
lastTime = now | |
local mode | |
if key == IN_KEY_ATTACK or key == IN_KEY_USE then | |
mode = 0 | |
if lost then | |
init() | |
lost = false | |
updatePending = true | |
return | |
end | |
elseif key == IN_KEY_ATTACK2 then | |
mode = 2 | |
else | |
return | |
end | |
updatePending = true | |
local x, y = math_floor(cx/512*w)+1, math_floor(cy/512*h)+1 | |
if mode == 2 then | |
local row = field2[y] | |
if row[x] == 1 then | |
row[x] = 2 | |
elseif row[x] == 2 then | |
row[x] = 1 | |
end | |
elseif field2[y][x] ~= 2 then | |
local m = field1[y][x] | |
if m < 0 then | |
for y=1, h do | |
local row = field2[y] | |
for x=1, w do | |
row[x] = 0 | |
end | |
end | |
lost = true | |
elseif m == 0 then | |
for y=1, h do | |
seen[y] = {} | |
end | |
traverse(x, y) | |
else | |
field2[y][x] = mode | |
end | |
end | |
end) | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment