diff options
Diffstat (limited to 'data/artery/global/sh_minerock.txt')
| -rw-r--r-- | data/artery/global/sh_minerock.txt | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/data/artery/global/sh_minerock.txt b/data/artery/global/sh_minerock.txt new file mode 100644 index 0000000..0e6bcaf --- /dev/null +++ b/data/artery/global/sh_minerock.txt @@ -0,0 +1,371 @@ +if not nrequire then return end +local meta = FindMetaTable("Player") +local rockdata = { + {nil,0}, + {"Stone" , 15}, + {"Copper" , 30}, + {"Tin" , 60}, + {"Iron" , 120}, + {"Coal" , 180}, +} + +local skil = nrequire("sh_skillcommon.lua") +skil.RegisterSkill({"Forageing","Mineing"}) + +local function printpuzzle(puzzle) + Msg("========================") + for y = 0, puzzle.height-1 do + for x = 0, puzzle.width-1 do + Msg(puzzle.tiles[x][y]) + end + Msg("\n") + end +end + +local function findmatchesfortile(puzzle,x,y) + printpuzzle(puzzle) + local matches = {} + local pt = puzzle.tiles + local t = pt[x][y] + --Find horizontal matches + local matcheshoizontal = 1 + local cursor = x + 1 + local pot = {{x,y}} + while cursor < puzzle.width and pt[cursor][y] == t do + matcheshoizontal = matcheshoizontal + 1 + pot[#pot + 1] = {cursor,y} + cursor = cursor + 1 + end + cursor = x - 1 + while cursor >= 0 and pt[cursor][y] == t do + matcheshoizontal = matcheshoizontal + 1 + pot[#pot + 1] = {cursor,y} + cursor = cursor - 1 + end + if matcheshoizontal > 2 then + for k,v in ipairs(pot) do + matches[#matches+1] = v + end + end + + --Find verticle matches + local matchesverticle = 1 + cursor = y + 1 + pot = {{x,y}} + while cursor < puzzle.height and pt[x][cursor] == t do + matchesverticle = matchesverticle + 1 + pot[#pot + 1] = {x,cursor} + cursor = cursor + 1 + end + cursor = y - 1 + while cursor >= 0 and pt[x][cursor] == t do + matchesverticle = matchesverticle + 1 + pot[#pot + 1] = {x,cursor} + cursor = cursor - 1 + end + if matchesverticle > 2 then + for k,v in ipairs(pot) do + matches[#matches+1] = v + end + end + return matches +end + +local function canswitch(puzzle,x1,y1,x2,y2) + if x1 == x2 and (y1 + 1 == y2 or y1 - 1 == y2) or + y1 == y2 and (x1 + 1 == x2 or x1 - 1 == x2) then + local v1 = puzzle.tiles[x1][y1] + local v2 = puzzle.tiles[x2][y2] + local tcpy = table.Copy(puzzle) + tcpy.tiles[x2][y2] = v1 + tcpy.tiles[x1][y1] = v2 + printpuzzle(tcpy) + local m1 = findmatchesfortile(tcpy,x1,y1) + local m2 = findmatchesfortile(tcpy,x2,y2) + return #m1 > 0 or #m2 > 0 + end + return false +end + +local oremap = { + [0] = "materials/svg/faithtoken/originals/svg/000000/transparent/ore.svg", + "materials/svg/lorc/originals/svg/000000/transparent/rock.svg", + "materials/svg/lorc/originals/svg/000000/transparent/stone-block.svg", + "materials/svg/faithtoken/originals/svg/000000/transparent/minerals.svg", + "materials/svg/delapouite/originals/svg/000000/transparent/stone-pile.svg", + "materials/svg/lorc/originals/svg/000000/transparent/fossil.svg" + +} + +if SERVER then + local itm = nrequire("item.lua") + + for k,v in pairs(oremap) do + resource.AddSingleFile(v) + end + + util.AddNetworkString("artery_mine_rock_start") + util.AddNetworkString("artery_mine_rock_new") + util.AddNetworkString("artery_mine_rock_quit") + util.AddNetworkString("artery_mine_rock_action") + util.AddNetworkString("artery_mine_rocks_update") + + local function genpuzzle(width,height,variety) + local puzzle = {} + puzzle.width = width + puzzle.height = height + puzzle.variety = variety + puzzle.tiles = {} + + for i = 0,puzzle.width do + puzzle.tiles[i] = {} + for j = 0,puzzle.height do + puzzle.tiles[i][j] = math.random(0,puzzle.variety) + end + end + + return puzzle + end + + local function del_and_replace(puzzle,matches) + local tp = puzzle.tiles + local function dropcolumn(x,y,spaces) + print("dropping ", x,y) + for ty = y, 0, -1 do + tp[x][ty] = tp[x][ty - spaces] or math.random(0,puzzle.variety) + end + end + for k,v in pairs(matches) do + dropcolumn(v[1],v[2],1) + end + end + + + + local function findmatchesfor(puzzle) + local duped = {} + for i = 0, puzzle.width-1 do + duped [i] = {} + end + for y = 0,puzzle.height-1 do + for x = 0, puzzle.width-1 do + local matches = findmatchesfortile(puzzle,x,y) + for k,v in pairs(matches) do + duped[v[1]][v[2]] = true + end + end + end + local m = {} + for y = 0,puzzle.height-1 do + for x = 0, puzzle.width-1 do + if duped[x][y] then + m[#m+1] = {x,y} + end + end + end + return m + end + + local puzzles = {} + local scores = {} + function meta:MineRock() + local p = genpuzzle(5,5,4) + local m = findmatchesfor(p) + while #m > 0 do + del_and_replace(p,m) + m = findmatchesfor(p) + end + puzzles[self] = p + scores[self] = 0 + self:StartAnimation("stranded_mine_rocks") + net.Start("artery_mine_rock_start") + net.WriteTable(p) + net.Send(self) + end + + local function kick_cheating_player(who) + error(who:Nick() .. " was cheating!") + end + + net.Receive("artery_mine_rock_action",function(ln,ply) + local p = puzzles[ply] + local x1 = net.ReadUInt(8) + local y1 = net.ReadUInt(8) + local x2 = net.ReadUInt(8) + local y2 = net.ReadUInt(8) + if not canswitch(p,x1,y1,x2,y2) then + kick_cheating_player(ply) + end + local v1,v2 = p.tiles[x1][y1],p.tiles[x2][y2] + p.tiles[x2][y2] = v1 + p.tiles[x1][y1] = v2 + local m = findmatchesfor(p) + while #m > 0 do + scores[ply] = scores[ply] + #m + del_and_replace(p,m) + m = findmatchesfor(p) + end + printpuzzle(p) + net.Start("artery_mine_rocks_update") + net.WriteTable(p) + net.WriteDouble(scores[ply]) + net.Send(ply) + ply:StartAnimation("stranded_mine_rock") + end) + + net.Receive("artery_mine_rock_quit",function(ln,ply) + local s = scores[ply] + local cursor = 1 + while cursor <= #rockdata and s >= rockdata[cursor][2] do + cursor = cursor + 1 + end + local n = rockdata[cursor-1][1] + if n == nil then return end + local togive = itm.GetItemByName(n) + ply:GiveItem(togive) + ply:AddSkill("Mineing",s) + ply:StopAnimation("stranded_mine_rock") + end) +else + local svg = nrequire("cl_svg.lua") + + local mine = {} + local tbl + local puzzleview + local rocks = {} + + local oremats = {} + for k,v in pairs(oremap) do + oremats[k] = svg.MaterialFromSVG(v,nil,"rgb(0,0,0);") + end + local oremats_selected = {} + for k,v in pairs(oremap) do + oremats_selected[k] = svg.MaterialFromSVG(v,"rgb(100,100,200);","rgb(255,255,255);") + end + net.Receive("artery_mine_rock_start",function() + tbl = net.ReadTable() + puzzleview = vgui.Create( "DFrame" ) + puzzleview:SetSize( ScrW()*0.5, ScrH()*0.5 ) + puzzleview:Center() + puzzleview:SetTitle( "Mine Rocks..." ) + puzzleview:SetDraggable( true ) + puzzleview:MakePopup() + puzzleview.OnClose = function(self) + net.Start("artery_mine_rock_quit") + net.SendToServer() + end + + local puzzlepane = vgui.Create( "DPanel", puzzleview ) + puzzlepane:Dock(FILL) + + local help = vgui.Create("DLabel",puzzlepane) + help:SetText("Click two cells to switch them.\nCreate runs of 3 or more to clear them from the board\nNew numbers come in from the top\nQuit at any time to receive the resource you have worked towards.") + help:SetDark(true) + help:SizeToContents() + help:Dock(RIGHT) + + local rocklayout = vgui.Create("DPanel",puzzlepane) + rocklayout:Dock(BOTTOM) + + local rockprogress = vgui.Create( "DProgress",rocklayout ) + rockprogress:Dock(FILL) + + local rocknameleft = vgui.Create("DLabel",rocklayout) + rocknameleft:Dock(LEFT) + rocknameleft:SetDark(true) + rocknameleft:SetText("") + + local rocknameright = vgui.Create("DLabel",rocklayout) + rocknameright:Dock(RIGHT) + rocknameright:SetDark(true) + rocknameright:SetText(rockdata[2][1]) + + rocks = {rockprogress,rocknameleft,rocknameright} + + local puzzlegrid = vgui.Create( "DGrid", puzzlepane ) + puzzlegrid:SetCols(tbl.width) + puzzlegrid:Dock(TOP) + local selected + for y = 0,tbl.height-1 do + for x = 0,tbl.width-1 do + local tile = vgui.Create("DImageButton") + mine[x] = mine[x] or {} + mine[x][y] = tile + local tmat = oremats[tbl.tiles[x][y]] + if tmat.material then + tile:SetMaterial(tmat.material) + end + tile:SetStretchToFit( true ) + tile.position = {x,y} + tile:SetWidth(32) + tile:SetHeight(32) + tile:SetIsToggle(true) + tile.OnToggled = function(self,state) + if state then + self:SetMaterial(oremats_selected[tbl.tiles[x][y]].material) + else + self:SetMaterial(oremats[tbl.tiles[x][y]].material) + end + end + tile.DoClick = function(self) + if selected == nil then + selected = self + self:SetToggle(true) + self:OnToggled(true) + elseif selected ~= self then + --Check if we can switch + local sp = selected.position + local tp = self.position + if canswitch(tbl,sp[1],sp[2],tp[1],tp[2]) then + net.Start("artery_mine_rock_action") + net.WriteUInt(sp[1],8) + net.WriteUInt(sp[2],8) + net.WriteUInt(tp[1],8) + net.WriteUInt(tp[2],8) + net.SendToServer() + local v1,v2 = selected:GetText(),self:GetText() + selected:SetText(v2) + self:SetText(v1) + selected:SetToggle(false) + selected:OnToggled(false) + selected = nil + end + else + selected:SetToggle(false) + selected:OnToggled(false) + selected = nil + end + end + puzzlegrid:AddItem(tile) + end + end + + end) + + net.Receive("artery_mine_rocks_update",function() + tbl = net.ReadTable() + local score = net.ReadDouble() + puzzleview:SetTitle("Mine Rocks... (" .. score .. ")") + printpuzzle(tbl) + for y = 0, tbl.height-1 do + for x = 0, tbl.width-1 do + mine[x][y]:SetMaterial(oremats[(tbl.tiles[x][y])].material) + end + end + if score > rockdata[#rockdata][2] then + puzzleview:Close() + return + end + for k,v in ipairs(rockdata) do + if score >= v[2] then + local l = v[2] + local n = rockdata[k+1][2] + local frac = (score-l) / (n - l) + rocks[1]:SetFraction(frac) + rocks[2]:SetText(v[1] or "") + rocks[3]:SetText(rockdata[k+1][1]) + end + end + end) + +end |
