View difference between Paste ID: WBG8q8Bv and nnRGZiZA
SHOW: | | - or go back to the newest paste.
1
local scr_x, scr_y = term.getSize()
2
palateFile = fs.combine(shell.dir(),"palate")
3-
levelFile = nil
3+
levelFile = "level"
4
5
guy = {
6
	x = 2,						--Your X position on the MAP, not the screen.
7
	y = 5,						--Same, but with Y.
8
	speedY = 0,					--I want to represent gravity fairly accurately.
9
	char = "O",					--The character that represents you.
10
	mode = "",					--Determines whether you are walking, jumping, whatever.
11
	grounded = false,			--Whether or not you are on solid ground, and can jump.
12
	bgcol = colors.red,			--Background color.
13
	txtcol = colors.yellow,		--Text color.
14
	name = "Mario",				--Thine name! I just added this in case I want to use it.
15
}
16
17
local tArg = {...}
18
if tArg[1] then
19
	levelFile = fs.combine(shell.dir(),tArg[1])
20
end
21
if tArg[2] then
22
	palateFile = fs.combine(shell.dir(),tArg[2])
23
end
24
25
scrollX = 0
26
scrollY = 0
27
28
function CTB(_color) --Color To Blit
29
	local blitcolors = {
30
		[colors.white] = "0",
31
		[colors.orange] = "1",
32
		[colors.magenta] = "2",
33
		[colors.lightBlue] = "3",
34
		[colors.yellow] = "4",
35
		[colors.lime] = "5",
36
		[colors.pink] = "6",
37
		[colors.gray] = "7",
38
		[colors.lightGray] = "8",
39
		[colors.cyan] = "9",
40
		[colors.purple] = "a",
41
		[colors.blue] = "b",
42
		[colors.brown] = "c",
43
		[colors.green] = "d",
44
		[colors.red] = "e",
45
		[colors.black] = "f",
46
	}
47
	return blitcolors[_color]
48
end
49
50
if fs.exists(palateFile) then
51
	dofile(palateFile)
52
end
53
54
if not palate then
55
	palate = {						--I say palate because it can (as should be expected to) be changed per game.
56
		[1] = {						--Blocks will be stored as IDs, not by name.
57
			desc = "air",			--Brief description of what it is supposed to represent.
58
			char = " ",				--Character used to represent it.
59
			txtcol = colors.black,	--TEXT color. Uses colors API, not blit.
60
			bgcol = colors.black,	--BACKGROUND color. Again, colors API.
61
			solid = false,			--Whether or not you can go through it.
62
			isLiquid = false,		--Whether it is a liquid or not.
63
			touchDamage = 0,		--Damage done by TOUCHING IT. Meaning, being inside it OR a space next to it.
64
			insideDamage = 0,		--Damage done by BEING IN THE SAME SPACE AS IT. Not being next to it.
65
			gravity = 1,			--Gravity (let's just say in G's) when INSIDE the block.
66
		},							--Oh BTW, [1] will always be air. That's constant. Also, it's not really a block, but an empty space.
67
		[2] = {
68
			desc = "sto	ne",
69
			char = "L",	
70
			txtcol = colors.lightGray,
71
			bgcol = colors.gray,
72
			solid = true,
73
			isLiquid = false,	
74
			touchDamage = 0,
75
			insideDamage = 0,
76
			gravity = 1,
77
		},
78
		[3] = {
79
			desc = "woodplank",
80
			char = "=",
81
			txtcol = colors.orange,
82
			bgcol = colors.brown,
83
			solid = true,
84
			isLiquid = false,
85
			touchDamage = 0,
86
			insideDamage = 0,
87
			gravity = 1,
88
		},
89
		[4] = {
90
			desc = "water",
91
			char = "/",
92
			txtcol = colors.lightBlue,
93
			bgcol = colors.cyan,
94
			solid = false,
95
			isLiquid = true,
96
			touchDamage = 0,
97
			insideDamage = 0,
98
			gravity = 0.4,
99
		},
100
		[5] = {
101
			desc = "lava",
102
			char = "#",
103
			txtcol = colors.red,
104
			bgcol = colors.orange,
105
			solid = false,
106
			isLiquid = true,
107
			touchDamage = 0,
108
			insideDamage = 2,
109
			gravity = 1.2,
110
		},
111
		[6] = {
112
			desc = "cactus",
113
			char = "#",
114
			txtcol = colors.gray,
115
			bgcol = colors.green,
116
			solid = true,
117
			isLiquid = false,
118
			touchDamage = 1,
119
			insideDamage = 0,
120
			gravity = 1,
121
		},
122
	}
123
	local file = fs.open(palateFile,"w")
124
	file.write("palate = "..textutils.serialise(palate))
125
	file.close()
126
end
127
selectedItem = 1
128
local level
129
if levelFile then
130
	local file = fs.open(levelFile,"r")
131
	level = textutils.unserialize(file.readAll())
132
	file.close()
133
else
134
	level = {{}}
135
end
136
137
function inflateLevel(_level)
138
	local output = _level
139
	local maxLong = 0
140
	local maxHigh = #level
141
	for a = 1, #_level do
142
		for b = 1, #_level[a] do
143
			if #_level[a][b] > maxLong then
144
				maxLong = #_level[a]
145
			end
146
		end
147
	end
148
	for a = 1, maxHigh do
149
		if not _level[a] then
150-
				lobster = palate[level[x+scrollX][(scr_y-y)+scrollY+1]] --Well it wasn't a rock
150+
			output[a] = {}
151-
				if lobster and y ~= scr_y then
151+
152
		for b = 1, maxLong do
153
			if not _level[a][b] then
154
				output[a][b] = 1
155
			end
156
		end
157
	end
158
	return output
159
end
160
161
level = inflateLevel(level)
162
163
local function clearDot(x,y,col)
164
	local pX,pY = term.getCursorPos()
165
	term.setCursorPos(x,y)
166
	if col then
167
		term.blit(" ",CTB(col),CTB(col))
168
	else
169-
function drawDock(_palate,selected)
169+
170
	end
171-
	term.setBackgroundColor(colors.white)
171+
172
end
173
174-
	local dockpos = {}
174+
175-
	for a = 1, #_palate do
175+
176-
		term.setCursorPos(a,scr_y)
176+
177-
		table.insert(dockpos,{x=a,desc=_palate[a].desc})
177+
178-
		term.blit(_palate[a].char,CTB(_palate[a].txtcol),CTB(_palate[a].bgcol))
178+
179-
		term.setCursorPos(scr_x-#_palate[selected].desc,scr_y)
179+
180-
		term.setTextColor(colors.black)
180+
181-
		term.setBackgroundColor(colors.white)
181+
182-
		term.write(_palate[selected].desc)
182+
183
end
184-
	return dockpos
184+
185
function renderLevel(_level,_scrollX,_scrollY)
186
	if guy.x > math.floor(scr_x/2) then
187-
function handleKey(e)
187+
		scrollX = guy.x - math.floor(scr_x/2)
188-
	local _,key = table.unpack(e)
188+
		term.clear()
189-
	oldScrollX, oldScrollY = scrollX, scrollY
189+
190-
	if key == keys.left and scrollX > 0 then
190+
		clearDot(guy.x,guy.y,palate[level[guy.y][guy.x]].bgcol)
191-
		scrollX = scrollX - 1
191+
192-
	elseif key == keys.right then
192+
193-
		scrollX = scrollX + 1
193+
194-
	elseif key == keys.down and scrollY > 0 then
194+
195-
		scrollY = scrollY - 1
195+
				lobster = palate[level[(scr_y-y)+scrollY+1][x+scrollX]] --Well it wasn't a rock
196-
	elseif key == keys.up then
196+
				if lobster then
197-
		scrollY = scrollY + 1
197+
198-
	elseif key == keys.q then
198+
199-
		handleQuit()
199+
200
			end
201-
	if oldScrollX ~= scrollX or oldScrollY ~= scrollY then
201+
202-
		palateclear()
202+
203-
		drawDock(palate,selectedItem)
203+
	term.setCursorPos(guy.x-scrollX,(scr_y-guy.y)+scrollY)
204
	term.blit(guy.char,CTB(guy.txtcol),CTB(guy.bgcol))
205
end
206
207
function handleQuit()
208-
function handleMouseClick(e)
208+
209-
	local _,button,x,y = table.unpack(e)
209+
210-
	local dockpos = drawDock(palate,selectedItem)
210+
211-
	if y == scr_y then	--handle dock clicking
211+
212-
		for a = 1, #dockpos do
212+
213-
			if dockpos[a].x == x then
213+
214-
				selectedItem = a
214+
215-
				dockpos = drawDock(palate,selectedItem)
215+
216-
				break
216+
function handleGuyPhysics(mode)
217
	local gravity
218
	if level[guy.y] then
219-
	else	--handle drawing things
219+
		if level[guy.y][guy.x] then
220-
		if not level[x+scrollX] then level[x+scrollX] = {} end
220+
			gravity = palate[level[guy.y][guy.x]].gravity
221-
		if selectedItem == 1 then --air
221+
222-
			level[x+scrollX][(scr_y-y)+scrollY+1] = nil
222+
			gravity = palate[1].gravity
223-
			clearDot(x,y,palate[1].bgcol)
223+
224
	else
225-
			level[x+scrollX][(scr_y-y)+scrollY+1] = selectedItem
225+
		gravity = palate[1].gravity
226
	end
227
	guy.speedY = guy.speedY - gravity
228
	if level[guy.x] then
229
		if level[guy.x][guy.y-gravity] then
230
			if palate[level[guy.y-gravity][guy.x]].solid then
231
				guy.grounded = true
232
				guy.speedY = 0
233-
	drawDock(palate,selectedItem)
233+
			else
234
				guy.grounded = false
235
				guy.y = guy.y + guy.speedY
236-
		evt = {os.pullEvent()}
236+
237-
		if evt[1] == "mouse_click" or evt[1] == "mouse_drag" then
237+
238-
			handleMouseClick(evt)
238+
			guy.grounded = false
239-
		elseif evt[1] == "key" then
239+
			guy.y = guy.y + guy.speedY
240-
			handleKey(evt)
240+
241
	end
242
	if mode == "jump" then
243
		if guy.grounded then
244
			guy.speedY = 5*gravity
245-
doit()
245+
246
	end
247
	if mode == "walkRight" then
248
		if level[guy.x+1] then
249
			if level[guy.y][guy.x+1] then
250
				if not level[guy.y][guy.x+1].solid then
251
					guy.x = guy.x + 1
252
				end
253
			else
254
				guy.x = guy.x + 1
255
			end
256
		else
257
			guy.x = guy.x + 1
258
		end
259
	end
260
	if mode == "walkLeft" then
261
		if level[guy.y] then
262
			if level[guy.y][guy.x-1] then
263
				if not level[guy.y][guy.x-1].solid then
264
					guy.x = guy.x - 1
265
				end
266
			else
267
				guy.x = guy.x - 1
268
			end
269
		else
270
			guy.x = guy.x - 1
271
		end
272
	end
273
end
274
275
function handleKeyMovement()
276
	keysPressed = {
277
		["right"] = false,
278
		["left"] = false,
279
		["space"] = false,
280
	}
281
	while true do
282
		local evt = {os.pullEvent()}
283
		if evt[1] == "key" then
284
			if evt[2] == keys.right then
285
				keysPressed["right"] = true
286
			elseif evt[2] == keys.left then
287
				keysPressed["left"] = true
288
			elseif evt[2] == keys.space then
289
				keysPressed["space"] = true
290
			end
291
		elseif evt[1] == "key_up" then
292
			if evt[2] == keys.right then
293
				keysPressed["right"] = false
294
			elseif evt[2] == keys.left then
295
				keysPressed["left"] = false
296
			elseif evt[2] == keys.space then
297
				keysPressed["space"] = false
298
			end
299
		end
300
	end
301
end
302
303
function doit()
304
	palateclear()
305
	renderLevel(level,scrollX,scrollY)
306
	while true do
307
		sleep(0.05)
308
		if keysPressed["space"] and guy.grounded then
309
			handleGuyPhysics("jump")
310
		end
311
		if keysPressed["right"] then
312
			handleGuyPhysics("walkRight")
313
		elseif keysPressed["left"] then
314
			handleGuyPhysics("walkLeft")
315
		else
316
			handleGuyPhysics()
317
		end
318
		renderLevel(level,scrollX,scrollY)
319
	end
320
end
321
322
parallel.waitForAny(doit,handleKeyMovement)