summaryrefslogtreecommitdiff
path: root/data/artery/global/sh_chopwood.txt
blob: 46e2c0787a1d2af9b33f3c8a9b5be411783baaa4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
--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 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")
	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