summaryrefslogtreecommitdiff
path: root/data/artery/global/sh_minerock.txt
diff options
context:
space:
mode:
Diffstat (limited to 'data/artery/global/sh_minerock.txt')
-rw-r--r--data/artery/global/sh_minerock.txt371
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