1function editor_load()
2
3	tilecount1 = 168
4	tilecount2 = 74
5
6	minimapscroll = 0
7	minimapx = 3
8	minimapy = 30
9
10	currenttile = 1
11
12	minimapscrollspeed = 30
13	minimapdragging = false
14
15	allowdrag = true
16
17	guielements["tabmain"] = guielement:new("button", 1, 1, "main", maintab, 3)
18	guielements["tabmain"].fillcolor = {63, 63, 63}
19	guielements["tabtiles"] = guielement:new("button", 43, 1, "tiles", tilestab, 3)
20	guielements["tabtiles"].fillcolor = {63, 63, 63}
21	guielements["tabtools"] = guielement:new("button", 93, 1, "tools", toolstab, 3)
22	guielements["tabtools"].fillcolor = {63, 63, 63}
23	guielements["tabmaps"] = guielement:new("button", 143, 1, "maps", mapstab, 3)
24	guielements["tabmaps"].fillcolor = {63, 63, 63}
25
26	--MAIN
27	guielements["autoscrollcheckbox"] = guielement:new("checkbox", 291, 65, toggleautoscroll, autoscroll)
28	guielements["backgrounddropdown"] = guielement:new("dropdown", 17, 85, 6, changebackground, background, "blue", "black", "water")
29	guielements["musicdropdown"] = guielement:new("dropdown", 17, 110, 11, changemusic, musici, "none", "overworld", "underground", "castle", "underwater", "star", "custom")
30	guielements["spritesetdropdown"] = guielement:new("dropdown", 17, 135, 11, changespriteset, spriteset, "overworld", "underground", "castle", "underwater")
31	guielements["timelimitdecrease"] = guielement:new("button", 17, 160, "{", decreasetimelimit, 0)
32	guielements["timelimitincrease"] = guielement:new("button", 31 + string.len(mariotimelimit)*8, 160, "}", increasetimelimit, 0)
33	guielements["mapwidthdecrease"] = guielement:new("button", 268, 178, "{", nil, 0)
34	guielements["mapwidthincrease"] = guielement:new("button", 264, 178, "}", nil, 0)
35	guielements["mapwidthapply"] = guielement:new("button", 320, 178, "apply", applymapwidth, 0)
36	guielements["savebutton"] = guielement:new("button", 10, 200, "save", savelevel, 2)
37	guielements["menubutton"] = guielement:new("button", 54, 200, "return to menu", menu_load, 2)
38	guielements["testbutton"] = guielement:new("button", 178, 200, "test level", test_level, 2)
39	guielements["savebutton"].bordercolor = {255, 0, 0}
40	guielements["savebutton"].bordercolorhigh = {255, 127, 127}
41
42	guielements["intermissioncheckbox"] = guielement:new("checkbox", 200, 80, toggleintermission, intermission)
43	guielements["warpzonecheckbox"] = guielement:new("checkbox", 200, 95, togglewarpzone, haswarpzone)
44	guielements["underwatercheckbox"] = guielement:new("checkbox", 200, 110, toggleunderwater, underwater)
45	guielements["bonusstagecheckbox"] = guielement:new("checkbox", 200, 125, togglebonusstage, bonusstage)
46	guielements["custombackgroundcheckbox"] = guielement:new("checkbox", 200, 140, togglecustombackground, custombackground)
47
48	guielements["scrollfactorscrollbar"] = guielement:new("scrollbar", 298, 154, 100, 35, 11, reversescrollfactor(), "hor")
49
50	--TILES
51	guielements["tilesall"] = guielement:new("button", 70, 20, "all", tilesall, 2)
52	guielements["tilessmb"] = guielement:new("button", 103, 20, "smb", tilessmb, 2)
53	guielements["tilesportal"] = guielement:new("button", 136, 20, "portal", tilesportal, 2)
54	guielements["tilescustom"] = guielement:new("button", 193, 20, "custom", tilescustom, 2)
55	guielements["tilesentities"] = guielement:new("button", 268, 20, "entities", tilesentities, 2)
56
57	guielements["tilesscrollbar"] = guielement:new("scrollbar", 381, 37, 167, 15, 40, 0, "ver")
58
59	--TOOLS
60	guielements["linkbutton"] = guielement:new("button", 5, 22, "link tool|to link testing equipment, drag a line from the|red devices to a yellow activator to turn them|green and connected. insert zelda joke here.", linkbutton, 2, false, 4, 383)
61	guielements["linkbutton"].bordercolor = {0, 255, 0}
62	guielements["linkbutton"].bordercolorhigh = {220, 255, 220}
63	guielements["portalbutton"] = guielement:new("button", 5, 71, "portal gun|for testing purposes, use this to shoot portals!", portalbutton, 2, false, 2, 383)
64	guielements["portalbutton"].bordercolor = {0, 0, 255}
65	guielements["portalbutton"].bordercolorhigh = {127, 127, 255}
66
67	guielements["livesdecrease"] = guielement:new("button", 198, 104, "{", livesdecrease, 0)
68	guielements["livesincrease"] = guielement:new("button", 194, 104, "}", livesincrease, 0)
69
70	--MAPS
71	guielements["savebutton2"] = guielement:new("button", 10, 140, "save", savelevel, 2)
72	guielements["savebutton2"].bordercolor = {255, 0, 0}
73	guielements["savebutton2"].bordercolorhigh = {255, 127, 127}
74
75	--get current description and shit
76	local mappackname = ""
77	local mappackauthor = ""
78	local mappackdescription = ""
79	if love.filesystem.exists("mappacks/" .. mappack .. "/settings.txt") then
80		local data = love.filesystem.read("mappacks/" .. mappack .. "/settings.txt")
81		local split1 = data:split("\n")
82		for i = 1, #split1 do
83			local split2 = split1[i]:split("=")
84			if split2[1] == "name" then
85				mappackname = split2[2]:lower()
86			elseif split2[1] == "author" then
87				mappackauthor = split2[2]:lower()
88			elseif split2[1] == "description" then
89				mappackdescription = split2[2]:lower()
90			end
91		end
92	end
93
94	guielements["edittitle"] = guielement:new("input", 5, 115, 17, nil, mappackname, 17)
95	guielements["editauthor"] = guielement:new("input", 5, 140, 13, nil, mappackauthor, 13)
96	guielements["editdescription"] = guielement:new("input", 5, 165, 17, nil, mappackdescription, 51, 3)
97	guielements["savesettings"] = guielement:new("button", 5, 203, "save settings", savesettings, 2)
98	guielements["savesettings"].bordercolor = {255, 0, 0}
99	guielements["savesettings"].bordercolorhigh = {255, 127, 127}
100
101	tilesall()
102	if editorloadopen then
103		editoropen()
104		editorloadopen = false
105	else
106		editorclose()
107		editorstate = "main"
108		editentities = false
109	end
110end
111
112function editor_update(dt)
113	----------
114	--EDITOR--
115	----------
116	if editormenuopen == false then
117		--key scroll
118		if love.keyboard.isDown("left") then
119			autoscroll = false
120			guielements["autoscrollcheckbox"].var = autoscroll
121			splitxscroll[1] = splitxscroll[1] - 30*gdt
122			if splitxscroll[1] < 0 then
123				splitxscroll[1] = 0
124			end
125			generatespritebatch()
126		elseif love.keyboard.isDown("right") then
127			autoscroll = false
128			guielements["autoscrollcheckbox"].var = autoscroll
129			splitxscroll[1] = splitxscroll[1] + 30*gdt
130			if splitxscroll[1] > mapwidth-width then
131				splitxscroll[1] = mapwidth-width
132			end
133			generatespritebatch()
134		end
135
136		if editorstate == "linktool" or editorstate == "portalgun" then
137			return
138		end
139
140		if love.mouse.isDown("l") and allowdrag then
141			local x, y = love.mouse.getPosition()
142			placetile(x, y)
143		end
144	elseif editorstate == "main" then
145		if love.mouse.isDown("l") then
146			local mousex, mousey = love.mouse.getPosition()
147			if mousey >= minimapy*scale and mousey < (minimapy+34)*scale then
148				if mousex >= minimapx*scale and mousex < (minimapx+394)*scale then
149					if mousex < (minimapx+width)*scale then
150						if minimapscroll > 0 then
151							minimapscroll = minimapscroll - minimapscrollspeed*dt
152							if minimapscroll < 0 then
153								minimapscroll = 0
154							end
155						end
156					elseif mousex >= (minimapx+394-width)*scale then
157						if minimapscroll < mapwidth-width-170 then
158							minimapscroll = minimapscroll + minimapscrollspeed*dt
159							if minimapscroll > mapwidth-width-170 then
160								minimapscroll = mapwidth-width-170
161							end
162						end
163					end
164
165					splitxscroll[1] = (mousex/scale-3-width) / 2 + minimapscroll
166
167					if splitxscroll[1] < minimapscroll then
168						splitxscroll[1] = minimapscroll
169					end
170					if splitxscroll[1] > 170 + minimapscroll then
171						splitxscroll[1] = 170 + minimapscroll
172					end
173					if splitxscroll[1] > mapwidth-width then
174						splitxscroll[1] = mapwidth-width
175					end
176
177					--SPRITEBATCH UPDATE
178					if math.floor(splitxscroll[1]) ~= spritebatchX[1] then
179						generatespritebatch()
180						spritebatchX[1] = math.floor(splitxscroll[1])
181					end
182				end
183			end
184
185			--mapwidth repeat
186			if guirepeattimer > 0 then
187				guirepeattimer = guirepeattimer - dt
188			else
189				if guielements["mapwidthincrease"]:inhighlight(mousex, mousey) then
190					targetmapwidth = targetmapwidth+1
191					guirepeattimer = guirepeatdelay
192					guielements["mapwidthincrease"].x = 282 + string.len(targetmapwidth)*8
193				elseif guielements["mapwidthdecrease"]:inhighlight(mousex, mousey) then
194					targetmapwidth = targetmapwidth-1
195					guirepeattimer = guirepeatdelay
196					guielements["mapwidthincrease"].x = 282 + string.len(targetmapwidth)*8
197				end
198			end
199		end
200		updatescrollfactor()
201	elseif editorstate == "tiles" then
202		tilesoffset = guielements["tilesscrollbar"].value * tilescrollbarheight * scale
203	end
204end
205
206function editor_draw()
207	love.graphics.setColor(255, 255, 255)
208
209	local mousex, mousey = love.mouse.getPosition()
210
211	--EDITOR
212	if editormenuopen == false then
213		if rightclickmenuopen then
214			rightclickmenu:draw()
215		elseif editorstate ~= "linktool" and editorstate ~= "portalgun" then
216			local x, y = getMouseTile(love.mouse.getX(), love.mouse.getY()-8*scale)
217
218			if inmap(x, y+1) then
219				love.graphics.setColor(255, 255, 255, 200)
220				if editentities == false then
221					love.graphics.drawq(tilequads[currenttile].image, tilequads[currenttile].quad, math.floor((x-splitxscroll[1]-1)*16*scale), ((y-1)*16+8)*scale, 0, scale, scale)
222				else
223					love.graphics.drawq(entityquads[currenttile].image, entityquads[currenttile].quad, math.floor((x-splitxscroll[1]-1)*16*scale), ((y-1)*16+8)*scale, 0, scale, scale)
224				end
225			end
226		end
227
228		if editorstate == "linktool" and editorstate ~= "portalgun" then
229			if linktoolX and love.mouse.isDown("l") then
230				love.graphics.line(math.floor((linktoolX-xscroll-.5)*16*scale), math.floor((linktoolY-1)*16*scale), mousex, mousey)
231			end
232
233			local cox, coy = getMouseTile(mousex, mousey+8*scale)
234
235			local table1 = {}
236			for i, v in pairs(outputsi) do
237				table.insert(table1, v)
238			end
239			for i, v in pairs(inputsi) do
240				table.insert(table1, v)
241			end
242
243			for x = math.floor(splitxscroll[1]), math.floor(splitxscroll[1])+width+1 do
244				for y = 1, 15 do
245					for i, v in pairs(table1) do
246						if inmap(x, y) and #map[x][y] > 1 and map[x][y][2] == v then
247							local r = map[x][y]
248							local drawline = false
249
250							if tablecontains(r, "link") and cox == x and coy == y and not love.mouse.isDown("l") then
251								love.graphics.setColor(0, 255, 0, 255)
252								drawline = true
253							elseif tablecontains(r, "link") then
254								love.graphics.setColor(150, 255, 150, 100)
255								drawline = true
256							elseif tablecontains(outputsi, map[x][y][2]) and cox == x and coy == y and linktoolX and love.mouse.isDown("l") then
257								love.graphics.setColor(255, 255, 0, 255)
258							elseif tablecontains(outputsi, map[x][y][2]) then
259								love.graphics.setColor(255, 255, 150, 150)
260							elseif cox == x and coy == y and not love.mouse.isDown("l") then
261								love.graphics.setColor(255, 0, 0, 255)
262							else
263								love.graphics.setColor(255, 150, 150, 150)
264							end
265							love.graphics.rectangle("fill", math.floor((x-splitxscroll[1]-1)*16*scale), ((y-1)*16-8)*scale, 16*scale, 16*scale)
266
267							if drawline then
268								local x2, y2
269								for i = 3, #map[x][y] do
270									if map[x][y][i] == "link" then
271										x2, y2 = tonumber(map[x][y][i+1]), tonumber(map[x][y][i+2])
272										break
273									end
274								end
275								love.graphics.line((x-xscroll-.5)*16*scale, (y-1)*16*scale, (x2-xscroll-.5)*16*scale, (y2-1)*16*scale)
276							end
277						end
278					end
279				end
280			end
281		end
282	else
283		if editorstate == "maps" then
284			love.graphics.setColor(0, 0, 0, 100)
285		else
286			love.graphics.setColor(0, 0, 0, 230)
287		end
288
289		if minimapdragging == false then
290			love.graphics.rectangle("fill", 1*scale, 18*scale, 398*scale, 205*scale)
291		else
292			love.graphics.rectangle("fill", 1*scale, 18*scale, 398*scale, 57*scale)
293		end
294
295		guielements["tabmain"]:draw()
296		guielements["tabtiles"]:draw()
297		guielements["tabtools"]:draw()
298		guielements["tabmaps"]:draw()
299
300		if editorstate == "tiles" then
301			--TILES
302			love.graphics.setColor(255, 255, 255)
303
304			properprint("tilelist", 3*scale, 24*scale)
305			guielements["tilesall"]:draw()
306			guielements["tilessmb"]:draw()
307			guielements["tilesportal"]:draw()
308			guielements["tilescustom"]:draw()
309			guielements["tilesentities"]:draw()
310
311			drawrectangle(4, 37, 375, 167)
312
313			love.graphics.setScissor(5*scale, 38*scale, 373*scale, 165*scale)
314
315			if editentities == false then
316				for i = 1, tilelistcount+1 do
317					love.graphics.drawq(tilequads[i+tileliststart-1].image, tilequads[i+tileliststart-1].quad, math.mod((i-1), 22)*17*scale+5*scale, math.floor((i-1)/22)*17*scale+38*scale-tilesoffset, 0, scale, scale)
318				end
319			else
320				for i = 1, entitiescount do
321					love.graphics.drawq(entityquads[i].image, entityquads[i].quad, math.mod((i-1), 22)*17*scale+5*scale, math.floor((i-1)/22)*17*scale+38*scale-tilesoffset, 0, scale, scale)
322				end
323			end
324
325			local tile = gettilelistpos(love.mouse.getX(), love.mouse.getY())
326			if editentities == false then
327				if tile and tile <= tilelistcount+1 then
328					love.graphics.setColor(255, 255, 255, 127)
329					love.graphics.rectangle("fill", (5+math.mod((tile-1), 22)*17)*scale, (38+math.floor((tile-1)/22)*17)*scale-tilesoffset, 16*scale, 16*scale)
330				end
331			else
332				if tile and tile <= entitiescount then
333					love.graphics.setColor(255, 255, 255, 127)
334					love.graphics.rectangle("fill", (5+math.mod((tile-1), 22)*17)*scale, (38+math.floor((tile-1)/22)*17)*scale-tilesoffset, 16*scale, 16*scale)
335				end
336			end
337
338			love.graphics.setScissor()
339
340			guielements["tilesscrollbar"]:draw()
341
342			if editentities and entitydescriptions[tile] then
343				local newstring = entitydescriptions[tile]
344				if string.len(newstring) > 49 then
345					newstring = string.sub(newstring, 1, 49) .. "|" .. string.sub(newstring, 50, 98)
346				end
347				properprint(newstring, 3*scale, 205*scale)
348			else
349				if tile and tilequads[tile+tileliststart-1] then
350					if tilequads[tile+tileliststart-1].collision then
351						properprint("collision: true", 3*scale, 205*scale)
352					else
353						properprint("collision: false", 3*scale, 205*scale)
354					end
355
356					if tilequads[tile+tileliststart-1].collision and tilequads[tile+tileliststart-1].portalable then
357						properprint("portalable: true", 3*scale, 215*scale)
358					else
359						properprint("portalable: false", 3*scale, 215*scale)
360					end
361				end
362			end
363
364			love.graphics.setColor(255, 255, 255)
365		elseif editorstate == "main" then
366			--MINIMAP
367			love.graphics.setColor(255, 255, 255)
368			properprint("minimap", 3*scale, 21*scale)
369			love.graphics.rectangle("fill", minimapx*scale, minimapy*scale, 394*scale, 34*scale)
370			love.graphics.setColor(unpack(backgroundcolor[background]))
371			love.graphics.rectangle("fill", (minimapx+2)*scale, (minimapy+2)*scale, 390*scale, 30*scale)
372
373			local lmap = map
374
375			love.graphics.setScissor((minimapx+2)*scale, (minimapy+2)*scale, 390*scale, 30*scale)
376
377			for x = 1, mapwidth do
378				for y = 1, 15 do
379					if x-minimapscroll > 0 and x-minimapscroll < 196 then
380						local id = lmap[x][y][1]
381						if id ~= nil and id ~= 0 and tilequads[id].invisible == false then
382							if rgblist[id] then
383								love.graphics.setColor(unpack(rgblist[id]))
384								love.graphics.rectangle("fill", (minimapx+x*2-minimapscroll*2)*scale, (minimapy+y*2)*scale, 2*scale, 2*scale)
385							end
386						end
387					end
388				end
389			end
390
391			love.graphics.setScissor()
392
393			love.graphics.setColor(255, 0, 0)
394			drawrectangle(splitxscroll[1]*2+minimapx-minimapscroll*2, minimapy, (width+2)*2, 34)
395			drawrectangle(splitxscroll[1]*2+minimapx-minimapscroll*2+1, minimapy+1, (width+1)*2, 32)
396			guielements["autoscrollcheckbox"]:draw()
397			properprint("follow mario", 301*scale, 66*scale)
398
399			if minimapdragging == false then
400				guielements["mapwidthdecrease"]:draw()
401				guielements["mapwidthincrease"]:draw()
402				guielements["mapwidthapply"]:draw()
403				properprint("current mapwidth: " .. mapwidth, 160*scale, 170*scale)
404				properprint("new mapwidth:  " .. targetmapwidth, 160*scale, 180*scale)
405				guielements["savebutton"]:draw()
406				guielements["menubutton"]:draw()
407				guielements["testbutton"]:draw()
408				guielements["timelimitdecrease"]:draw()
409				properprint(mariotimelimit, 29*scale, 162*scale)
410				guielements["timelimitincrease"]:draw()
411				properprint("timelimit", 8*scale, 151*scale)
412				guielements["spritesetdropdown"]:draw()
413				properprint("spriteset", 8*scale, 126*scale)
414				guielements["musicdropdown"]:draw()
415				properprint("music", 8*scale, 101*scale)
416				guielements["backgrounddropdown"]:draw()
417				properprint("background color", 8*scale, 76*scale)
418
419				guielements["intermissioncheckbox"]:draw()
420				guielements["warpzonecheckbox"]:draw()
421				guielements["underwatercheckbox"]:draw()
422				guielements["bonusstagecheckbox"]:draw()
423				guielements["custombackgroundcheckbox"]:draw()
424
425				if custombackground then
426					love.graphics.setColor(255, 255, 255, 255)
427				else
428					love.graphics.setColor(150, 150, 150, 255)
429				end
430				properprint("scrollfactor", 199*scale, 156*scale)
431
432				guielements["scrollfactorscrollbar"]:draw()
433				if custombackground then
434					love.graphics.setColor(255, 255, 255, 255)
435				else
436					love.graphics.setColor(150, 150, 150, 255)
437				end
438				properprint(formatscrollnumber(scrollfactor), (guielements["scrollfactorscrollbar"].x+1+guielements["scrollfactorscrollbar"].xrange*guielements["scrollfactorscrollbar"].value)*scale, 156*scale)
439
440				love.graphics.setColor(255, 255, 255, 255)
441
442				properprint("intermission", 210*scale, 81*scale)
443				properprint("has warpzone", 210*scale, 96*scale)
444				properprint("underwater", 210*scale, 111*scale)
445				properprint("bonusstage", 210*scale, 126*scale)
446				properprint("custom background", 210*scale, 141*scale)
447			end
448		elseif editorstate == "maps" then
449			for i = 1, 8 do
450				properprint("w" .. i, ((i-1)*49 + 19)*scale, 23*scale)
451				for j = 1, 4 do
452					for k = 0, 5 do
453						guielements[i .. "-" .. j .. "_" .. k]:draw()
454					end
455				end
456			end
457			properprint("do not forget to save your current map before|changing!", 5*scale, 120*scale)
458			guielements["savebutton2"]:draw()
459		elseif editorstate == "tools" then
460			guielements["linkbutton"]:draw()
461			guielements["portalbutton"]:draw()
462
463			properprint("mappack title:", 5*scale, 106*scale)
464			properprint("author:", 5*scale, 131*scale)
465			properprint("description:", 5*scale, 156*scale)
466			guielements["edittitle"]:draw()
467			guielements["editauthor"]:draw()
468			guielements["editdescription"]:draw()
469			guielements["savesettings"]:draw()
470
471			properprint("lives:", 150*scale, 106*scale)
472			guielements["livesincrease"]:draw()
473			if mariolivecount == false then
474				properprint("inf", 210*scale, 106*scale)
475			else
476				properprint(mariolivecount, 210*scale, 106*scale)
477			end
478
479			guielements["livesdecrease"]:draw()
480		end
481	end
482end
483
484function maintab()
485	editorstate = "main"
486	for i, v in pairs(guielements) do
487		v.active = false
488	end
489
490	guielements["tabmain"].fillcolor = {0, 0, 0}
491	guielements["tabtiles"].fillcolor = {63, 63, 63}
492	guielements["tabtools"].fillcolor = {63, 63, 63}
493	guielements["tabmaps"].fillcolor = {63, 63, 63}
494	guielements["tabmain"].active = true
495	guielements["tabtiles"].active = true
496	guielements["tabtools"].active = true
497	guielements["tabmaps"].active = true
498
499	guielements["autoscrollcheckbox"].active = true
500	guielements["backgrounddropdown"].active = true
501	guielements["musicdropdown"].active = true
502	guielements["spritesetdropdown"].active = true
503	guielements["timelimitdecrease"].active = true
504	guielements["timelimitincrease"].active = true
505	guielements["mapwidthdecrease"].active = true
506	guielements["mapwidthincrease"].active = true
507	guielements["mapwidthapply"].active = true
508	guielements["savebutton"].active = true
509	guielements["menubutton"].active = true
510	guielements["testbutton"].active = true
511	guielements["intermissioncheckbox"].active = true
512	guielements["warpzonecheckbox"].active = true
513	guielements["underwatercheckbox"].active = true
514	guielements["bonusstagecheckbox"].active = true
515	guielements["custombackgroundcheckbox"].active = true
516	guielements["scrollfactorscrollbar"].active = true
517end
518
519function tilestab()
520	editorstate = "tiles"
521	for i, v in pairs(guielements) do
522		v.active = false
523	end
524
525	guielements["tabmain"].fillcolor = {63, 63, 63}
526	guielements["tabtiles"].fillcolor = {0, 0, 0}
527	guielements["tabtools"].fillcolor = {63, 63, 63}
528	guielements["tabmaps"].fillcolor = {63, 63, 63}
529	guielements["tabmain"].active = true
530	guielements["tabtiles"].active = true
531	guielements["tabtools"].active = true
532	guielements["tabmaps"].active = true
533
534	guielements["tilesscrollbar"].active = true
535
536	guielements["tilesall"].active = true
537	guielements["tilessmb"].active = true
538	guielements["tilesportal"].active = true
539	guielements["tilescustom"].active = true
540	guielements["tilesentities"].active = true
541
542end
543
544function toolstab()
545	editorstate = "tools"
546	for i, v in pairs(guielements) do
547		v.active = false
548	end
549
550	guielements["tabmain"].fillcolor = {63, 63, 63}
551	guielements["tabtiles"].fillcolor = {63, 63, 63}
552	guielements["tabtools"].fillcolor = {0, 0, 0}
553	guielements["tabmaps"].fillcolor = {63, 63, 63}
554	guielements["tabmain"].active = true
555	guielements["tabtiles"].active = true
556	guielements["tabtools"].active = true
557	guielements["tabmaps"].active = true
558
559	guielements["linkbutton"].active = true
560	guielements["portalbutton"].active = true
561	guielements["edittitle"].active = true
562	guielements["editauthor"].active = true
563	guielements["editdescription"].active = true
564	guielements["savesettings"].active = true
565
566	guielements["livesdecrease"].active = true
567	guielements["livesincrease"].active = true
568end
569
570function mapstab()
571	editorstate = "maps"
572	for i, v in pairs(guielements) do
573		v.active = false
574	end
575
576	guielements["tabmain"].fillcolor = {63, 63, 63}
577	guielements["tabtiles"].fillcolor = {63, 63, 63}
578	guielements["tabtools"].fillcolor = {63, 63, 63}
579	guielements["tabmaps"].fillcolor = {0, 0, 0}
580	guielements["tabmain"].active = true
581	guielements["tabtiles"].active = true
582	guielements["tabtools"].active = true
583	guielements["tabmaps"].active = true
584	guielements["savebutton2"].active = true
585
586	for i = 1, 8 do --world
587		for j = 1, 4 do --level
588			for k = 0, 5 do --sublevel
589				guielements[i .. "-" .. j .. "_" .. k].active = true
590			end
591		end
592	end
593end
594
595function tilesall()
596	guielements["tilesall"].textcolor = {255, 255, 255}
597	guielements["tilessmb"].textcolor = {127, 127, 127}
598	guielements["tilesportal"].textcolor = {127, 127, 127}
599	guielements["tilescustom"].textcolor = {127, 127, 127}
600	guielements["tilesentities"].textcolor = {127, 127, 127}
601
602	tileliststart = 1
603	tilelistcount = smbtilecount + portaltilecount + customtilecount -1
604
605	tilescrollbarheight = math.max(0, math.ceil((smbtilecount + portaltilecount + customtilecount)/22)*17 - 1 - (17*9) - 12)
606	editentities = false
607end
608
609function tilessmb()
610	guielements["tilesall"].textcolor = {127, 127, 127}
611	guielements["tilessmb"].textcolor = {255, 255, 255}
612	guielements["tilesportal"].textcolor = {127, 127, 127}
613	guielements["tilescustom"].textcolor = {127, 127, 127}
614	guielements["tilesentities"].textcolor = {127, 127, 127}
615
616	tileliststart = 1
617	tilelistcount = smbtilecount-1
618
619	tilescrollbarheight = math.max(0, math.ceil((smbtilecount)/22)*17 - 1 - (17*9) - 12)
620	editentities = false
621end
622
623function tilesportal()
624	guielements["tilesall"].textcolor = {127, 127, 127}
625	guielements["tilessmb"].textcolor = {127, 127, 127}
626	guielements["tilesportal"].textcolor = {255, 255, 255}
627	guielements["tilescustom"].textcolor = {127, 127, 127}
628	guielements["tilesentities"].textcolor = {127, 127, 127}
629
630	tileliststart = smbtilecount + 1
631	tilelistcount = portaltilecount - 1
632
633	tilescrollbarheight = math.max(0, math.ceil((portaltilecount)/22)*17 - 1 - (17*9) - 12)
634	editentities = false
635end
636
637function tilescustom()
638	guielements["tilesall"].textcolor = {127, 127, 127}
639	guielements["tilessmb"].textcolor = {127, 127, 127}
640	guielements["tilesportal"].textcolor = {127, 127, 127}
641	guielements["tilescustom"].textcolor = {255, 255, 255}
642	guielements["tilesentities"].textcolor = {127, 127, 127}
643
644	tileliststart = smbtilecount + portaltilecount + 1
645	tilelistcount = customtilecount - 1
646
647	tilescrollbarheight = math.max(0, math.ceil((customtilecount)/22)*17 - 1 - (17*9) - 12)
648	editentities = false
649end
650
651function tilesentities()
652	guielements["tilesall"].textcolor = {127, 127, 127}
653	guielements["tilessmb"].textcolor = {127, 127, 127}
654	guielements["tilesportal"].textcolor = {127, 127, 127}
655	guielements["tilescustom"].textcolor = {127, 127, 127}
656	guielements["tilesentities"].textcolor = {255, 255, 255}
657
658	tilescrollbarheight = math.max(0, math.ceil((entitiescount)/22)*17 - 1 - (17*9) - 12)
659	editentities = true
660
661	if currenttile > entitiescount then
662		currenttile = 1
663	end
664end
665
666function placetile(x, y)
667	local cox, coy = getMouseTile(x, y+8*scale)
668	if inmap(cox, coy) == false then
669		return
670	end
671
672	if editentities == false then
673		if tilequads[currenttile].collision == true and tilequads[map[cox][coy][1]].collision == false then
674			objects["tile"][cox .. "-" .. coy] = tile:new(cox-1, coy-1, 1, 1, true)
675		elseif tilequads[currenttile].collision == false and tilequads[map[cox][coy][1]].collision == true then
676			objects["tile"][cox .. "-" .. coy] = nil
677		end
678		if map[cox][coy][1] ~= currenttile then
679			map[cox][coy][1] = currenttile
680			map[cox][coy]["gels"] = {}
681			generatespritebatch()
682		end
683
684		if currenttile == 136 then
685			currenttile = 137
686			placetile(x+16*scale, y)
687
688			currenttile = 138
689			placetile(x, y+16*scale)
690
691			currenttile = 139
692			placetile(x+16*scale, y+16*scale)
693
694			currenttile = 136
695		end
696
697	else
698		local t = map[cox][coy]
699		if entityquads[currenttile].t == "remove" then --removing tile
700			for i = 2, #map[cox][coy] do
701				map[cox][coy][i] = nil
702			end
703		else
704			map[cox][coy][2] = currenttile
705			--check if tile has settable option, if so default to this.
706			if rightclickvalues[entitylist[currenttile]] then
707				map[cox][coy][3] = rightclickvalues[entitylist[currenttile]][2]
708				for i = 4, #map[cox][coy] do
709					map[cox][coy][i] = nil
710				end
711			else
712				for i = 3, #map[cox][coy] do
713					map[cox][coy][i] = nil
714				end
715			end
716		end
717	end
718end
719
720function editorclose()
721	editormenuopen = false
722	for i, v in pairs(guielements) do
723		v.active = false
724	end
725end
726
727function editoropen()
728	for i = 1, players do
729		objects["player"][i]:removeportals()
730	end
731	if editorstate == "linktool" or editorstate == "portalgun" then
732		editorstate = "tools"
733	end
734	rightclickmenuopen = false
735	editormenuopen = true
736	targetmapwidth = mapwidth
737	guielements["mapwidthincrease"].x = 282 + string.len(targetmapwidth)*8
738	if mariolivecount == false then
739		guielements["livesincrease"].x = 212 + 24
740	else
741		guielements["livesincrease"].x = 212 + string.len(mariolivecount)*8
742	end
743	guirepeattimer = 0
744	getmaps()
745
746	if editorstate == "main" then
747		maintab()
748	elseif editorstate == "tiles" then
749		tilestab()
750	elseif editorstate == "tools" then
751		toolstab()
752	elseif editorstate == "maps" then
753		mapstab()
754	end
755end
756
757function mapnumberclick(i, j, k)
758	if editormode then
759		marioworld = i
760		mariolevel = j
761		checkpointx = nil
762		editorloadopen = true
763		if k ~= 0 then
764			startlevel(k)
765		else
766			startlevel(i .. "-" .. j)
767		end
768	end
769end
770
771function getmaps()
772	existingmaps = {}
773	for i = 1, 8 do --world
774		existingmaps[i] = {}
775		for j = 1, 4 do --level
776			existingmaps[i][j] = {}
777			for k = 0, 5 do --sublevel
778				if k == 0 then
779					guielements[i .. "-" .. j .. "_" .. k] = guielement:new("button", (i-1)*49 + (j-1)*11 + 6, 35, j, mapnumberclick, 0, {i, j, k})
780				else
781					guielements[i .. "-" .. j .. "_" .. k] = guielement:new("button", (i-1)*49 + (j-1)*11 + 6, k*11+40, k, mapnumberclick, 0, {i, j, k})
782				end
783
784				local s = i .. "-" .. j
785				if k ~= 0 then
786					s = s .. "_" .. k
787				end
788				s = s .. ".txt"
789				if love.filesystem.exists("mappacks/" .. mappack .. "/" .. s) then
790					existingmaps[i][j][k] = true
791					guielements[i .. "-" .. j .. "_" .. k].fillcolor = {0, 150, 0}
792				else
793					guielements[i .. "-" .. j .. "_" .. k].fillcolor = {150, 0, 0}
794				end
795
796				if i == marioworld and j == mariolevel and k == mariosublevel then
797					if existingmaps[i][j][k] == true  then
798						guielements[i .. "-" .. j .. "_" .. k].textcolor = {0, 150, 0}
799					else
800						guielements[i .. "-" .. j .. "_" .. k].textcolor = {150, 0, 0}
801					end
802
803					guielements[i .. "-" .. j .. "_" .. k].bordercolor = {255, 255, 255}
804					guielements[i .. "-" .. j .. "_" .. k].bordercolorhigh = {255, 255, 255}
805					guielements[i .. "-" .. j .. "_" .. k].fillcolor = {255, 255, 255}
806				end
807			end
808		end
809	end
810end
811
812function editor_mousepressed(x, y, button)
813	if rightclickmenuopen then
814		rightclickmenu:click(x, y, button)
815		rightclickmenuopen = false
816		allowdrag = false
817		return
818	end
819
820	if button == "l" then
821		if editormenuopen == false then
822			if editorstate == "linktool" then
823				local tileX, tileY = getMouseTile(x, y+8*scale)
824				local r = map[tileX][tileY]
825				if #r > 1 then
826					local tile = r[2]
827					--LIST OF NUMBERS THAT ARE ACCEPT AS OUTPUT (doors, lights)
828					if tablecontains( inputsi, r[2] ) then
829						linktoolX, linktoolY = tileX, tileY
830					end
831				end
832			elseif editorstate ~= "portalgun" then
833				placetile(x, y)
834			end
835		else
836			if editorstate == "tiles" then
837				local tile = gettilelistpos(x, y)
838				if editentities == false then
839					if tile and tile <= tilelistcount+1 then
840						currenttile = tile + tileliststart-1
841						editorclose()
842						allowdrag = false
843					end
844				else
845					if tile and tile <= entitiescount then
846						currenttile = tile
847						editorclose()
848						allowdrag = false
849					end
850				end
851			elseif editorstate == "main" then
852				if y >= minimapy*scale and y < (minimapy+34)*scale then
853					if x >= minimapx*scale and x < (minimapx+394)*scale then
854						minimapdragging = true
855						toggleautoscroll(false)
856					end
857				end
858			end
859		end
860	elseif button == "m" then
861		local cox, coy = getMouseTile(x, y+8*scale)
862		if inmap(cox, coy) == false then
863			return
864		end
865		editentities = false
866		tilesall()
867		currenttile = map[cox][coy][1]
868
869	elseif button == "wu" then
870		if editormenuopen then
871		else
872			if currenttile > 1 then
873				currenttile = currenttile - 1
874			end
875		end
876
877	elseif button == "wd" then
878		if editormenuopen then
879		else
880			if editentities then
881				if currenttile < #entitylist then
882					currenttile = currenttile + 1
883				end
884			else
885				if currenttile < smbtilecount+portaltilecount+customtilecount then
886					currenttile = currenttile + 1
887				end
888			end
889		end
890
891	elseif button == "r" then
892		if editormenuopen == false then
893			local tileX, tileY = getMouseTile(x, y+8*scale)
894			if inmap(tileX, tileY) == false then
895				return
896			end
897
898			local r = map[tileX][tileY]
899			if #r > 1 then
900				local tile = r[2]
901				--LIST OF TILES THAT DO SHIT
902				if rightclickvalues[entitylist[r[2]]] then
903					rightclickmenuX = x
904					rightclickmenuY = y
905					rightclickmenucox = tileX
906					rightclickmenucoy = tileY
907					rightclickmenuopen = true
908					rightclickmenutile = entitylist[r[2]]
909
910					--create button
911					--get width and start
912					local width = 0
913					local start
914					for i = 1, #rightclickvalues[rightclickmenutile] do
915						if string.len(rightclickvalues[rightclickmenutile][i]) > width then
916							width = string.len(rightclickvalues[rightclickmenutile][i])
917						end
918
919						if rightclickvalues[rightclickmenutile][i] == r[3] then
920							start = rightclickvalues[rightclickmenutile][i]
921						end
922					end
923
924					rightclickmenu = guielement:new("rightclick", x/scale, y/scale, width, rightclickmenuclick, start, unpack(rightclickvalues[rightclickmenutile]))
925				end
926			else
927				if editorstate ~= "portalgun" then
928					local cox, coy = getMouseTile(x, y+8*scale)
929
930					if objects["player"][1] then
931						objects["player"][1].x = cox-1+2/16
932						objects["player"][1].y = coy-objects["player"][1].height
933					end
934				end
935			end
936		else
937			if editorstate == "main" then
938				if y >= (minimapy+2)*scale and y < (minimapy+32)*scale then
939					if x >= (minimapx+2)*scale and x < (minimapx+392)*scale then
940						local x = math.floor((x-minimapx*scale+math.floor(minimapscroll*scale*2))/scale/2)
941						local y = math.floor((y-minimapy*scale)/scale/2)
942
943						if objects["player"][1] then
944							objects["player"][1].x = x-1+2/16
945							objects["player"][1].y = y-1+2/16
946						end
947					end
948				end
949			end
950		end
951	end
952end
953
954function rightclickmenuclick(i)
955	if i > 1 then
956		map[rightclickmenucox][rightclickmenucoy][3] = rightclickvalues[rightclickmenutile][i]
957	end
958end
959
960function editor_mousereleased(x, y, button)
961	if button == "l" then
962		guirepeattimer = 0
963		minimapdragging = false
964		if editorstate == "linktool" then
965			if linktoolX then
966				local startx, starty = linktoolX, linktoolY
967				local endx, endy = getMouseTile(x, y+8*scale)
968
969				if startx ~= endx or starty ~= endy then
970					local r = map[endx][endy]
971
972					--LIST OF NUMBERS THAT ARE ACCEPTED AS INPUTS (buttons, laserdetectors)
973					if #r > 1 and tablecontains( outputsi, r[2] ) then
974						r = map[startx][starty]
975
976						local i = 1
977						while r[i] ~= "link" and i <= #r do
978							i = i + 1
979						end
980
981						map[startx][starty][i] = "link"
982						map[startx][starty][i+1] = endx
983						map[startx][starty][i+2] = endy
984					end
985
986					linktoolX, linktoolY = nil, nil
987
988					--Update links
989					for i, v in pairs(objects) do
990						for j, w in pairs(v) do
991							if w.outtable then
992								w.outtable = {}
993							end
994						end
995					end
996
997					for i, v in pairs(objects) do
998						for j, w in pairs(v) do
999							if w.link then
1000								w:link()
1001							end
1002						end
1003					end
1004				end
1005			end
1006		else
1007			allowdrag = true
1008		end
1009	end
1010end
1011
1012function editor_keypressed(key)
1013	if key == "escape" then
1014		if editormenuopen then
1015			editorclose()
1016		else
1017			editoropen()
1018		end
1019	end
1020end
1021
1022function toggleautoscroll(var)
1023	if var ~= nil then
1024		autoscroll = var
1025	else
1026		autoscroll = not autoscroll
1027	end
1028	guielements["autoscrollcheckbox"].var = autoscroll
1029end
1030
1031function toggleintermission(var)
1032	if var ~= nil then
1033		intermission = var
1034	else
1035		intermission = not intermission
1036	end
1037	guielements["intermissioncheckbox"].var = intermission
1038end
1039
1040function togglewarpzone(var)
1041	if var ~= nil then
1042		haswarpzone = var
1043	else
1044		haswarpzone = not haswarpzone
1045	end
1046	guielements["warpzonecheckbox"].var = haswarpzone
1047end
1048
1049function toggleunderwater(var)
1050	if var ~= nil then
1051		underwater = var
1052	else
1053		underwater = not underwater
1054	end
1055	guielements["underwatercheckbox"].var = underwater
1056end
1057
1058function togglebonusstage(var)
1059	if var ~= nil then
1060		bonusstage = var
1061	else
1062		bonusstage = not bonusstage
1063	end
1064	guielements["bonusstagecheckbox"].var = bonusstage
1065end
1066
1067function togglecustombackground(var)
1068	if var ~= nil then
1069		custombackground = var
1070	else
1071		custombackground = not custombackground
1072	end
1073
1074	if custombackground then
1075		loadcustombackground()
1076	end
1077
1078	guielements["custombackgroundcheckbox"].var = custombackground
1079end
1080
1081function changebackground(var)
1082	background = var
1083	guielements["backgrounddropdown"].var = var
1084	love.graphics.setBackgroundColor(backgroundcolor[var])
1085end
1086
1087function changemusic(var)
1088	if musici == 7 and custommusic then
1089		music:stop(custommusic)
1090	elseif musici ~= 1 then
1091		music:stopIndex(musici-1)
1092	end
1093	musici = var
1094	if musici == 7 and custommusic then
1095		music:play(custommusic)
1096	elseif musici ~= 1 then
1097		music:playIndex(musici-1)
1098	end
1099	guielements["musicdropdown"].var = var
1100end
1101
1102function changespriteset(var)
1103	spriteset = var
1104	guielements["spritesetdropdown"].var = var
1105end
1106
1107function decreasetimelimit()
1108	mariotimelimit = mariotimelimit - 10
1109	if mariotimelimit < 0 then
1110		mariotimelimit = 0
1111	end
1112	mariotime = mariotimelimit
1113	guielements["timelimitincrease"].x = 31 + string.len(mariotimelimit)*8
1114end
1115
1116function increasetimelimit()
1117	mariotimelimit = mariotimelimit + 10
1118	mariotime = mariotimelimit
1119	guielements["timelimitincrease"].x = 31 + string.len(mariotimelimit)*8
1120end
1121
1122function applymapwidth()
1123	changemapwidth(targetmapwidth)
1124end
1125
1126function linkbutton()
1127	editorstate = "linktool"
1128	editorclose()
1129end
1130
1131function test_level()
1132	savelevel()
1133	editorclose()
1134	editormode = false
1135	testlevel = true
1136	testlevelworld = marioworld
1137	testlevellevel = mariolevel
1138	autoscroll = true
1139	checkpointx = false
1140	if mariosublevel ~= 0 then
1141		startlevel(marioworld .. "-" .. mariolevel .. "_" .. mariosublevel)
1142	else
1143		startlevel(marioworld .. "-" .. mariolevel)
1144	end
1145end
1146
1147function portalbutton()
1148	editorstate = "portalgun"
1149	editorclose()
1150end
1151
1152function gettilelistpos(x, y)
1153	if x >= 5*scale and y >= 38*scale and x < 378*scale and y < 203*scale then
1154		x = (x - 5*scale)/scale
1155		y = y + tilesoffset
1156		y = (y - 38*scale)/scale
1157
1158
1159		out = math.floor(x/17)+1
1160		out = out + math.floor(y/17)*22
1161
1162		return out
1163	end
1164
1165	return false
1166end
1167
1168function savesettings()
1169	local s = ""
1170	s = s .. "name=" .. guielements["edittitle"].value .. "\n"
1171	s = s .. "author=" .. guielements["editauthor"].value .. "\n"
1172	s = s .. "description=" .. guielements["editdescription"].value .. "\n"
1173	if mariolivecount == false then
1174		s = s .. "lives=0\n"
1175	else
1176		s = s .. "lives=" .. mariolivecount .. "\n"
1177	end
1178
1179	love.filesystem.mkdir( "mappacks" )
1180	love.filesystem.mkdir( "mappacks/" .. mappack )
1181
1182	love.filesystem.write("mappacks/" .. mappack .. "/settings.txt", s)
1183end
1184
1185function livesdecrease()
1186	if mariolivecount == false then
1187		return
1188	end
1189
1190	mariolivecount = mariolivecount - 1
1191	if mariolivecount == 0 then
1192		mariolivecount = false
1193		guielements["livesincrease"].x = 212 + 24
1194	else
1195		guielements["livesincrease"].x = 212 + string.len(mariolivecount)*8
1196	end
1197end
1198
1199function livesincrease()
1200	if mariolivecount == false then
1201		mariolivecount = 1
1202	else
1203		mariolivecount = mariolivecount + 1
1204	end
1205	guielements["livesincrease"].x = 212 + string.len(mariolivecount)*8
1206end
1207
1208function updatescrollfactor()
1209	scrollfactor = round((guielements["scrollfactorscrollbar"].value*3)^2, 2)
1210end
1211
1212function reversescrollfactor()
1213	return math.sqrt(scrollfactor)/3
1214end
1215
1216function formatscrollnumber(i)
1217	if string.len(i) == 1 then
1218		return i .. ".00"
1219	elseif string.len(i) == 3 then
1220		return i .. "0"
1221	else
1222		return i
1223	end
1224end