--Wood chopping minigame if not nrequire then return end local meta = FindMetaTable("Player") local itm = nrequire("item.lua") local skil = nrequire("sh_skillcommon.lua") skil.RegisterSkill({"Forageing","Woodcutting"}) local matmap = { [0] = "materials/svg/delapouite/originals/svg/000000/transparent/log.svg", "materials/svg/lorc/originals/svg/000000/transparent/root-tip.svg", "materials/svg/lorc/originals/svg/000000/transparent/oak.svg", "materials/svg/lorc/originals/svg/000000/transparent/pine-tree.svg", "materials/svg/lorc/originals/svg/000000/transparent/dead-wood.svg", } local function isoutside(puzzle,width,height,position) --rewrite this at some point print("Checking ",width,height,position) PrintTable(puzzle) return position < width or position > ((height-1) * width) or --If we are top or bottom position % width == 0 or (position + 1) % width == 0 or --If we are on either side puzzle[position + width] == nil or puzzle[position - width] == nil or puzzle[position + 1] == nil or puzzle[position - 1] == nil end if SERVER then util.AddNetworkString("artery_chop_wood_start") util.AddNetworkString("artery_chop_wood_quit") util.AddNetworkString("artery_chop_wood_action") for k,v in pairs(matmap) do resource.AddSingleFile(v) end function puzzlefactory(width,height,veriety) local puzzle = {} local height,width = 4,4 local avaliable = {} for i = 0,width-1 do table.insert(avaliable,i) --first row table.insert(avaliable,(height-1) * width + i) --last row end for i = 1,height-2 do table.insert(avaliable,width * i) --first column end for i = 2,height-1 do table.insert(avaliable,(width * i) - 1 ) --last column end table.RemoveByValue(avaliable,-1) for i = 0,((width*height)/2)-1 do local pairtype = math.random(0,veriety-1) --Randomly add tiles to the board, marking new places as avaliable as we go local rs1 = table.remove(avaliable,math.random(1,#avaliable)) local rs2 = table.remove(avaliable,math.random(1,#avaliable)) puzzle[rs1] = pairtype puzzle[rs2] = pairtype local pot = { --Potential new avaliable spots to put things rs1+width, rs1-width, rs2+width, rs2-width, } --Add things left and right, but not if they jump left-to-right on the board if rs1 % width ~= 0 then pot[#pot+1] = rs1-1 end if rs1+1 % width ~= 0 then pot[#pot+1] = rs1+1 end if rs2 % width ~= 0 then pot[#pot+1] = rs2-1 end if rs2+1 % width ~= 0 then pot[#pot+1] = rs2+1 end --Remove up-down things that go off the board local npot = {} for k,v in ipairs(pot) do if puzzle[v] == nil and v >= 0 and v < height*width then npot[#npot+1] = v end end pot = npot for k,v in ipairs(pot) do local alreadyin = false for i,j in ipairs(avaliable) do if j == v then alreadyin = true break end end if not alreadyin then avaliable[#avaliable+1] = v end end end return puzzle end local playerpuzzles = {} local playerpuzzledims = {} function meta:ChopWood() print("Chopwood called") playerpuzzles[self] = puzzlefactory(4,4,5) playerpuzzledims[self] = {4,4} net.Start("artery_chop_wood_start") net.WriteTable(playerpuzzles[self]) net.WriteUInt(4,8) net.WriteUInt(4,8) net.Send(self) end local function kickcheater(who) print("I think",who,"was cheating!!!") end net.Receive("artery_chop_wood_action",function(ln,ply) local pos1 = net.ReadUInt(8) local pos2 = net.ReadUInt(8) local pz = playerpuzzles[ply] local dim = playerpuzzledims[ply] if isoutside(pz,dim[1],dim[2],pos1) and isoutside(pz,dim[1],dim[2],pos2) then pz[pos1] = nil pz[pos2] = nil else error("Player cheated!") kickcheater(ply) end ply:SetLuaAnimation("stranded_chop_wood") end) net.Receive("artery_chop_wood_quit",function(ln,ply) local pz = playerpuzzles[ply] if #pz == 0 then print("Player completed puzzle!") local item = itm.GetItemByName("Wood") ply:GiveItem(item) ply:AddSkill("Woodcutting",1) else print("Player did not complete puzzle!") end ply:StopLuaAnimation("stranded_chop_wood") end) else --client local svg = nrequire("cl_svg.lua") local matmap = { [0] = "materials/svg/delapouite/originals/svg/000000/transparent/log.svg", "materials/svg/lorc/originals/svg/000000/transparent/root-tip.svg", "materials/svg/lorc/originals/svg/000000/transparent/oak.svg", "materials/svg/lorc/originals/svg/000000/transparent/pine-tree.svg", "materials/svg/lorc/originals/svg/000000/transparent/dead-wood.svg", } local matico = {} for k,v in pairs(matmap) do matico[k] = svg.MaterialFromSVG(v,nil,"rgb(0,0,0);") end local matico_selected = {} for k,v in pairs(matmap) do matico_selected[k] = svg.MaterialFromSVG(v,"rgb(100,100,200);","rgb(255,255,255);") end net.Receive("artery_chop_wood_start",function() local puzzle = net.ReadTable() local width = net.ReadUInt(8) local height = net.ReadUInt(8) local puzzleview = vgui.Create( "DFrame" ) puzzleview:SetSize( ScrW()*0.5, ScrH()*0.5 ) puzzleview:Center() puzzleview:SetTitle( "Chop wood..." ) puzzleview:SetDraggable( true ) puzzleview:MakePopup() local puzzlepane = vgui.Create( "DPanel", puzzleview ) puzzlepane:Dock(FILL) local puzzlehelp = vgui.Create( "DLabel",puzzlepane) puzzlehelp:SetText("To chop wood, match the cells in pairs.\nYou complete the puzzle when all the cells are gone.\nYou may only match cells that are not surrounded\nby other cells.") puzzlehelp:SizeToContents() puzzlehelp:SetDark(true) puzzlehelp:Dock(RIGHT) local puzzlegrid = vgui.Create( "DGrid", puzzlepane ) puzzlegrid:SetCols(width) puzzlegrid:Dock(FILL) local numleft = width*height local selected for i = 0, width*height - 1 do local tile = vgui.Create("DImageButton") --tile:SetText(puzzle[i]) local tmat = matico[puzzle[i]] if tmat.material then tile:SetMaterial(tmat.material) end tile.position = i tile.number = puzzle[i] --tile:SizeToContents() tile:SetWidth(32) tile:SetHeight(32) tile:SetStretchToFit( true ) tile:SetIsToggle(true) tile.DoClick = function(self) local tp = self.position if not isoutside(puzzle,width,height,tp) then print("Could not press this button!") return end if selected == nil then selected = self self:SetToggle(true) self:SetMaterial(matico_selected[self.number].material) elseif self == selected then print("Selected is self!") self:SetToggle(false) self:SetMaterial(matico[self.number].material) selected = nil else if selected.number == self.number then net.Start("artery_chop_wood_action") net.WriteUInt(self.position,8) net.WriteUInt(selected.position,8) net.SendToServer() puzzle[self.position] = nil puzzle[selected.position] = nil --puzzlegrid:RemoveItem(self) --puzzlegrid:RemoveItem(selected) self:Remove() selected:Remove() selected = nil numleft = numleft - 2 if numleft == 0 then timer.Simple(0.5,function() print("Puzzle is empty! sending quit!") net.Start("artery_chop_wood_quit") net.SendToServer() end) puzzleview:Remove() else print("Puzzle is") PrintTable(puzzle) end end end end puzzlegrid:AddItem(tile) end puzzlegrid:Center() puzzlegrid:InvalidateLayout(true) function puzzlegrid:PerformLayout(w,h)--Don't re-layout ourselves. end end) end