Commits

luastoned committed b6f169c

Mari0 1.5

Comments (0)

Files changed (19)

 	end
 	
 	if a == "goomba" or a == "bulletbill" then
+		b:stomp()
 		addpoints(200, self.x, self.y)
 		playsound(stompsound)
 		self.falling = true
 end
 
 function box:portaled()
-	print("!")
 	self.portaledframe = true
 end
 	--MAIN
 	guielements["autoscrollcheckbox"] = guielement:new("checkbox", 291, 65, toggleautoscroll, autoscroll)
 	guielements["backgrounddropdown"] = guielement:new("dropdown", 17, 85, 6, changebackground, background, "blue", "black", "water")
-	guielements["musicdropdown"] = guielement:new("dropdown", 17, 110, 11, changemusic, musici, "none", "overworld", "underground", "castle", "underwater", "star")
+	guielements["musicdropdown"] = guielement:new("dropdown", 17, 110, 11, changemusic, musici, "none", "overworld", "underground", "castle", "underwater", "star", "custom")
 	guielements["spritesetdropdown"] = guielement:new("dropdown", 17, 135, 11, changespriteset, spriteset, "overworld", "underground", "castle", "underwater")
 	guielements["timelimitdecrease"] = guielement:new("button", 17, 160, "{", decreasetimelimit, 0)
 	guielements["timelimitincrease"] = guielement:new("button", 31 + string.len(mariotimelimit)*8, 160, "}", increasetimelimit, 0)
-	guielements["mapwidthdecrease"] = guielement:new("button", 268, 163, "{", nil, 0)
-	guielements["mapwidthincrease"] = guielement:new("button", 264, 163, "}", nil, 0)
-	guielements["mapwidthapply"] = guielement:new("button", 320, 163, "apply", applymapwidth, 0)
+	guielements["mapwidthdecrease"] = guielement:new("button", 268, 178, "{", nil, 0)
+	guielements["mapwidthincrease"] = guielement:new("button", 264, 178, "}", nil, 0)
+	guielements["mapwidthapply"] = guielement:new("button", 320, 178, "apply", applymapwidth, 0)
 	guielements["savebutton"] = guielement:new("button", 10, 200, "save", savelevel, 2)
 	guielements["menubutton"] = guielement:new("button", 54, 200, "return to menu", menu_load, 2)
 	guielements["testbutton"] = guielement:new("button", 178, 200, "test level", test_level, 2)
 	guielements["warpzonecheckbox"] = guielement:new("checkbox", 200, 95, togglewarpzone, haswarpzone)
 	guielements["underwatercheckbox"] = guielement:new("checkbox", 200, 110, toggleunderwater, underwater)
 	guielements["bonusstagecheckbox"] = guielement:new("checkbox", 200, 125, togglebonusstage, bonusstage)
-	guielements["portalbackgroundcheckbox"] = guielement:new("checkbox", 200, 140, toggleportalbackground, portalbackground)
+	guielements["custombackgroundcheckbox"] = guielement:new("checkbox", 200, 140, togglecustombackground, custombackground)
+	
+	guielements["scrollfactorscrollbar"] = guielement:new("scrollbar", 298, 154, 100, 35, 11, reversescrollfactor(), "hor")
 	
 	--TILES
 	guielements["tilesall"] = guielement:new("button", 70, 20, "all", tilesall, 2)
 	guielements["tilescustom"] = guielement:new("button", 193, 20, "custom", tilescustom, 2)
 	guielements["tilesentities"] = guielement:new("button", 268, 20, "entities", tilesentities, 2)
 	
-	guielements["tilesscrollbar"] = guielement:new("scrollbar", 381, 37, 167, 15, 40)
+	guielements["tilesscrollbar"] = guielement:new("scrollbar", 381, 37, 167, 15, 40, 0, "ver")
 	
 	--TOOLS
 	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)
 				end
 			end
 		end
+		updatescrollfactor()
 	elseif editorstate == "tiles" then
 		tilesoffset = guielements["tilesscrollbar"].value * tilescrollbarheight * scale
 	end
 			love.graphics.setColor(255, 255, 255)
 			properprint("minimap", 3*scale, 21*scale)
 			love.graphics.rectangle("fill", minimapx*scale, minimapy*scale, 394*scale, 34*scale)
-			if portalbackground then
-				love.graphics.setColor(240, 240, 240)
-			else
-				love.graphics.setColor(unpack(backgroundcolor[background]))
-			end
+			love.graphics.setColor(unpack(backgroundcolor[background]))
 			love.graphics.rectangle("fill", (minimapx+2)*scale, (minimapy+2)*scale, 390*scale, 30*scale)
 			
 			local lmap = map
 				guielements["mapwidthdecrease"]:draw()
 				guielements["mapwidthincrease"]:draw()
 				guielements["mapwidthapply"]:draw()
-				properprint("current mapwidth: " .. mapwidth, 160*scale, 155*scale)
-				properprint("new mapwidth:  " .. targetmapwidth, 160*scale, 165*scale)
+				properprint("current mapwidth: " .. mapwidth, 160*scale, 170*scale)
+				properprint("new mapwidth:  " .. targetmapwidth, 160*scale, 180*scale)
 				guielements["savebutton"]:draw()
 				guielements["menubutton"]:draw()
 				guielements["testbutton"]:draw()
 				guielements["warpzonecheckbox"]:draw()
 				guielements["underwatercheckbox"]:draw()
 				guielements["bonusstagecheckbox"]:draw()
-				guielements["portalbackgroundcheckbox"]:draw()
+				guielements["custombackgroundcheckbox"]:draw()
 				
+				if custombackground then
+					love.graphics.setColor(255, 255, 255, 255)
+				else
+					love.graphics.setColor(150, 150, 150, 255)
+				end
+				properprint("scrollfactor", 199*scale, 156*scale)
+				
+				guielements["scrollfactorscrollbar"]:draw()
+				if custombackground then
+					love.graphics.setColor(255, 255, 255, 255)
+				else
+					love.graphics.setColor(150, 150, 150, 255)
+				end
+				properprint(formatscrollnumber(scrollfactor), (guielements["scrollfactorscrollbar"].x+1+guielements["scrollfactorscrollbar"].xrange*guielements["scrollfactorscrollbar"].value)*scale, 156*scale)
+				
+				love.graphics.setColor(255, 255, 255, 255)
+					
 				properprint("intermission", 210*scale, 81*scale)
 				properprint("has warpzone", 210*scale, 96*scale)
 				properprint("underwater", 210*scale, 111*scale)
 				properprint("bonusstage", 210*scale, 126*scale)
-				properprint("portal background", 210*scale, 141*scale)
+				properprint("custom background", 210*scale, 141*scale)
 			end
 		elseif editorstate == "maps" then
 			for i = 1, 8 do
 	guielements["warpzonecheckbox"].active = true
 	guielements["underwatercheckbox"].active = true
 	guielements["bonusstagecheckbox"].active = true
-	guielements["portalbackgroundcheckbox"].active = true
+	guielements["custombackgroundcheckbox"].active = true
+	guielements["scrollfactorscrollbar"].active = true
 end
 
 function tilestab()
 		currenttile = map[cox][coy][1]
 		
 	elseif button == "wu" then
-		if currenttile > 1 then
-			currenttile = currenttile - 1
+		if editormenuopen then
+		else
+			if currenttile > 1 then
+				currenttile = currenttile - 1
+			end
 		end
 		
 	elseif button == "wd" then
-		if editentities then
-			if currenttile < #entitylist then
-				currenttile = currenttile + 1
-			end
+		if editormenuopen then
 		else
-			if currenttile < smbtilecount+portaltilecount+customtilecount then
-				currenttile = currenttile + 1
+			if editentities then
+				if currenttile < #entitylist then
+					currenttile = currenttile + 1
+				end
+			else
+				if currenttile < smbtilecount+portaltilecount+customtilecount then
+					currenttile = currenttile + 1
+				end
 			end
 		end
 		
 	guielements["bonusstagecheckbox"].var = bonusstage
 end
 
-function toggleportalbackground(var)
+function togglecustombackground(var)
 	if var ~= nil then
-		portalbackground = var
+		custombackground = var
 	else
-		portalbackground = not portalbackground
+		custombackground = not custombackground
 	end
-	guielements["portalbackgroundcheckbox"].var = portalbackground
+	
+	if custombackground then
+		loadcustombackground()
+	end
+	
+	guielements["custombackgroundcheckbox"].var = custombackground
 end
 
 function changebackground(var)
 end
 
 function changemusic(var)
-	if musici ~= 1 then
+	if musici == 7 and custommusic then
+		music:stop(custommusic)
+	elseif musici ~= 1 then
 		music:stopIndex(musici-1)
 	end
 	musici = var
-	if musici ~= 1 then
+	if musici == 7 and custommusic then
+		music:play(custommusic)
+	elseif musici ~= 1 then
 		music:playIndex(musici-1)
 	end
 	guielements["musicdropdown"].var = var
 		mariolivecount = mariolivecount + 1
 	end
 	guielements["livesincrease"].x = 212 + string.len(mariolivecount)*8
+end
+
+function updatescrollfactor()
+	scrollfactor = round((guielements["scrollfactorscrollbar"].value*3)^2, 2)
+end
+
+function reversescrollfactor()
+	return math.sqrt(scrollfactor)/3
+end
+
+function formatscrollnumber(i)
+	if string.len(i) == 1 then
+		return i .. ".00"
+	elseif string.len(i) == 3 then
+		return i .. "0"
+	else
+		return i
+	end
 end
 	self:hitstuff(a, b)
 end
 
+function fireball:passivecollide(a, b)
+	self:ceilcollide(a, b)
+	return false
+end
+
 function fireball:hitstuff(a, b)
 	if a == "tile" or a == "bulletbill" or a == "portalwall" or a == "spring" then
 		self:explode()
 	self.width = 12/16
 	self.height = 12/16
 	self.static = true
-	self.active = false
+	self.active = true
 	self.category = 6
 	self.mask = {true}
 	self.destroy = false
 	if self.uptimer < mushroomtime then
 		self.uptimer = self.uptimer + dt
 		self.y = self.y - dt*(1/mushroomtime)
+	end
+	
+	if self.uptimer > mushroomtime then
+		self.y = self.starty-27/16
+		self.active = true
+		self.drawable = true
+	end
+	
+	--animate
+	self.timer = self.timer + dt
+	while self.timer > staranimationdelay do
+		self.quadi = self.quadi + 1
+		if self.quadi == 5 then
+			self.quadi = 1
+		end
+		self.quad = flowerquad[self.quadi]
+		self.timer = self.timer - staranimationdelay
+	end
+	
+	if self.destroy then
+		return true
 	else
-		if self.static == true then
-			self.y = self.starty-27/16
-			self.active = true
-			self.drawable = true
-		end
-		
-		--animate
-		self.timer = self.timer + dt
-		while self.timer > staranimationdelay do
-			self.quadi = self.quadi + 1
-			if self.quadi == 5 then
-				self.quadi = 1
-			end
-			self.quad = flowerquad[self.quadi]
-			self.timer = self.timer - staranimationdelay
-		end
-		
-		if self.destroy then
-			return true
-		else
-			return false
-		end
+		return false
 	end
 end
 
 function flower:draw()
-	if self.uptimer < mushroomtime then
+	if self.uptimer < mushroomtime and not self.destroy then
 		--Draw it coming out of the block.
 		love.graphics.drawq(self.graphic, self.quad, math.floor(((self.x-xscroll)*16+self.offsetX)*scale), math.floor((self.y*16-self.offsetY)*scale), 0, scale, scale, self.quadcenterX, self.quadcenterY)
 	end
 		spritebatchX[i] = 0
 	end
 	
+	custommusic = false
+	if love.filesystem.exists("mappacks/" .. mappack .. "/music.ogg") then
+		custommusic = "mappacks/" .. mappack .. "/music.ogg"
+		music:load(custommusic)
+	elseif love.filesystem.exists("mappacks/" .. mappack .. "/music.mp3") then
+		custommusic = "mappacks/" .. mappack .. "/music.mp3"
+		music:load(custommusic)
+	end
+	
 	--FINALLY LOAD THE DAMN LEVEL
 	levelscreen_load("initial")
 end
 		generatespritebatch()
 	end
 	
+	--coinblocktimer things
+	for i, v in pairs(coinblocktimers) do
+		if v[3] > 0 then
+			v[3] = v[3] - dt
+		end
+	end
+	
 	--blockdebris
 	local delete = {}
 	
 					end
 				end
 				
-				
 				--check if maze was solved!
 				for i = 1, players do
 					if objects["player"][i].mazevar == mazegates[mazei] then
-						mazesolved[mazei] = true
+						local actualmaze = 0
+						for j = 1, #mazestarts do
+							if objects["player"][i].x > mazestarts[j] then
+								actualmaze = j
+							end
+						end
+						mazesolved[actualmaze] = true
 						for j = 1, players do
 							objects["player"][j].mazevar = 0
 						end
 			end
 		end
 		
-		--portal background
-		if portalbackground then
-			for x = 1, xtodraw do
-				love.graphics.draw(portalbackgroundimg, math.floor((x-1)*16*scale) - math.floor(math.mod(xscroll, 1)*16*scale), -8*scale, 0, scale, scale)
+		--custom background
+		if custombackground then
+			for i = #custombackgroundimg, 1, -1  do
+				local xscroll = xscroll / (i * scrollfactor + 1)
+				if reversescrollfactor() == 1 then
+					xscroll = 0
+				end
+				for y = 1, math.ceil(15/custombackgroundheight[i]) do
+					for x = 1, math.ceil(width/custombackgroundwidth[i])+1 do
+						love.graphics.draw(custombackgroundimg[i], math.floor(((x-1)*custombackgroundwidth[i])*16*scale) - math.floor(math.mod(xscroll, custombackgroundwidth[i])*16*scale), (y-1)*custombackgroundheight[i]*16*scale, 0, scale, scale)
+					end
+				end
 			end
 		end
 		
 		end
 		
 		--castleflag
-		if levelfinished and levelfinishtype == "flag" and not portalbackground then
+		if levelfinished and levelfinishtype == "flag" and not custombackground then
 			love.graphics.draw(castleflagimg, math.floor((flagx+6-xscroll)*16*scale), 106*scale+castleflagy*16*scale, 0, scale, scale)
 		end
 		
 	sunrot = 0
 	gelcannontimer = 0
 	pausemenuselected = 1
+	coinblocktimers = {}
 	
 	portaldelay = {}
 	for i = 1, players do
 	haswarpzone = false
 	underwater = false
 	bonusstage = false
-	portalbackground = false
+	custombackground = false
 	mariotimelimit = 400
 	spriteset = 1
 	--LOAD THE MAP
 	--set startx to checkpoint
 	if checkpointx and checkcheckpoint then
 		startx = checkpointx
-		print_r(checkpointpoints)
 		starty = checkpointpoints[checkpointx] or 13
 		
 		--clear enemies from spawning near
 		end
 	end
 	
+	scrollfactor = 0
+	
 	--MORE STUFF
 	for i = 2, #s2 do
 		s3 = s2[i]:split("=")
 			musici = tonumber(s3[2])
 		elseif s3[1] == "bonusstage" then
 			bonusstage = true
-		elseif s3[1] == "portalbackground" then
-			portalbackground = true
+		elseif s3[1] == "custombackground" or s3[1] == "portalbackground" then
+			custombackground = true
 		elseif s3[1] == "timelimit" then
 			mariotimelimit = tonumber(s3[2])
+		elseif s3[1] == "scrollfactor" then
+			scrollfactor = tonumber(s3[2])
 		end
 	end
 	
+	if custombackground then
+		loadcustombackground()
+	end
+	
 	return true
 end
 
 			editormode = true
 			startlevel(marioworld .. "-" .. mariolevel)
 			return
-		elseif not editormode and not levelfinished and not everyonedead then
+		elseif not editormode and not everyonedead then
 			pausemenuopen = true
 			love.audio.pause()
 			playsound(pausesound)
 	if underwater then
 		s = s .. ";underwater"
 	end
-	if portalbackground then
-		s = s .. ";portalbackground"
+	if custombackground then
+		s = s .. ";custombackground"
 	end
 	s = s .. ";timelimit=" .. mariotimelimit
+	s = s .. ";scrollfactor=" .. scrollfactor
 	
 	--tileset
 	
 	end
 	
 	for i = 1, players do
-		if not noupdate and objects["player"][i].controlsenabled and not objects["player"][i].vine and mouseowner ~= i then
+		if not noupdate and objects["player"][i].controlsenabled and not objects["player"][i].vine then
 			local s1 = controls[i]["jump"]
 			local s2 = controls[i]["run"]
 			local s3 = controls[i]["reload"]
 end
 
 function playmusic()
-	if musici ~= 1 then
+	if musici == 7 and custommusic then
+		music:play(custommusic)
+	elseif musici ~= 1 then
 		if mariotime < 100 and mariotime > 0 then
 			music:playIndex(musici-1, true)
 		else
 		love.graphics.draw(geldispenserimg, math.floor((self.cox-xscroll-1)*16*scale), (self.coy-1.5)*16*scale, 0, scale, scale, 0, 0)
 	elseif self.dir == "right" then
 		love.graphics.draw(geldispenserimg, math.floor((self.cox-xscroll-1)*16*scale), (self.coy+.5)*16*scale, math.pi*1.5, scale, scale, 0, 0)
+	elseif self.dir == "left" then
+		love.graphics.draw(geldispenserimg, math.floor((self.cox-xscroll+1)*16*scale), (self.coy-1.5)*16*scale, math.pi*0.5, scale, scale, 0, 0)
 	end
 end

graphics/SMB/portalbackground.png

Old
Old image
New
New image
 		self.type = arg[1]
 		self.x = arg[2]
 		self.y = arg[3]
-		self.yrange = arg[4]
+		self.range = arg[4]
 		self.width = arg[5]
 		self.height = arg[6]
 		self.value = arg[7] or 0
+		self.dir = arg[8] or "ver"
 		
-		self.yrange = self.yrange - self.height
+		if self.dir == "ver" then
+			self.yrange = self.range - self.height
+		else
+			self.xrange = self.range - self.width
+		end	
 		
 		self.backgroundcolor = {127, 127, 127}
 		self.bordercolorhigh = {255, 255, 255}
 	if self.active then
 		if self.type == "scrollbar" then
 			if self.dragging then
-				local y = (love.mouse.getY()-self.draggingy) - self.y*scale
-				local actualyrange = self.yrange*scale
-				
-				self.value = y / actualyrange
-				self.value = math.min(math.max(self.value, 0), 1) --clamp
+				if self.dir == "ver" then
+					local y = (love.mouse.getY()-self.draggingy) - self.y*scale
+					local actualyrange = self.yrange*scale
+					
+					self.value = y / actualyrange
+					self.value = math.min(math.max(self.value, 0), 1) --clamp
+				else
+					local x = (love.mouse.getX()-self.draggingx) - self.x*scale
+					local actualxrange = self.xrange*scale
+					
+					self.value = x / actualxrange
+					self.value = math.min(math.max(self.value, 0), 1) --clamp
+				end
 			end
 		elseif self.type == "input" then
 			self.timer = self.timer + dt
 		properprint(self.text, (self.x+1+self.space)*scale, (self.y+2+self.space)*scale)
 		
 	elseif self.type == "scrollbar" then
-		local high = self:inhighlight(love.mouse.getPosition())
+		if self.dir == "ver" then
+			local high = self:inhighlight(love.mouse.getPosition())
+			
+			love.graphics.setColor(self.backgroundcolor)
+			love.graphics.rectangle("fill", self.x*scale, self.y*scale, self.width*scale, (self.yrange+self.height)*scale)
 		
-		love.graphics.setColor(self.backgroundcolor)
-		love.graphics.rectangle("fill", self.x*scale, self.y*scale, self.width*scale, (self.yrange+self.height)*scale)
-	
-		love.graphics.setColor(self.bordercolor)
-		if self.dragging or high then
-			love.graphics.setColor(self.bordercolorhigh)
+			love.graphics.setColor(self.bordercolor)
+			if self.dragging or high then
+				love.graphics.setColor(self.bordercolorhigh)
+			end
+			
+			love.graphics.rectangle("fill", self.x*scale, (self.y+self.yrange*self.value)*scale, (self.width)*scale, (self.height)*scale)
+			
+			love.graphics.setColor(self.fillcolor)
+			love.graphics.rectangle("fill", (self.x+1)*scale, (self.y+1+self.yrange*self.value)*scale, (self.width-2)*scale, (self.height-2)*scale)
+		else
+			local high = self:inhighlight(love.mouse.getPosition())
+			
+			love.graphics.setColor(self.backgroundcolor)
+			love.graphics.rectangle("fill", self.x*scale, self.y*scale, (self.xrange+self.width)*scale, self.height*scale)
+		
+			love.graphics.setColor(self.bordercolor)
+			if self.dragging or high then
+				love.graphics.setColor(self.bordercolorhigh)
+			end
+			
+			love.graphics.rectangle("fill", (self.x+self.xrange*self.value)*scale, self.y*scale, (self.width)*scale, (self.height)*scale)
+			
+			love.graphics.setColor(self.fillcolor)
+			love.graphics.rectangle("fill", (self.x+1+self.xrange*self.value)*scale, (self.y+1)*scale, (self.width-2)*scale, (self.height-2)*scale)
 		end
-		
-		love.graphics.rectangle("fill", self.x*scale, (self.y+self.yrange*self.value)*scale, (self.width)*scale, (self.height)*scale)
-		
-		love.graphics.setColor(self.fillcolor)
-		love.graphics.rectangle("fill", (self.x+1)*scale, (self.y+1+self.yrange*self.value)*scale, (self.width-2)*scale, (self.height-2)*scale)
-		
 	elseif self.type == "input" then
 		local high = self:inhighlight(love.mouse.getPosition())
 	
 				self.func(unpack(self.arguments))
 			end
 		elseif self.type == "scrollbar" then
-			if self:inhighlight(x, y) then
-				self.dragging = true
-				self.draggingy = y-(self.y+self.yrange*self.value)*scale
+			if self.dir == "ver" then
+				if self:inhighlight(x, y) then
+					self.dragging = true
+					self.draggingy = y-(self.y+self.yrange*self.value)*scale
+				end
+			else
+				if self:inhighlight(x, y) then
+					self.dragging = true
+					self.draggingx = x-(self.x+self.xrange*self.value)*scale
+				end
 			end
 			if button == "wd" then
 				self.value = math.min(1, self.value+0.2)
 			return true
 		end
 	elseif self.type == "scrollbar" then
-		if x >= self.x*scale and x < (self.x+self.width)*scale and y >= (self.y+self.yrange*self.value)*scale and y < (self.height+self.y+self.yrange*self.value)*scale then
-			return true
+		if self.dir == "ver" then
+			if x >= self.x*scale and x < (self.x+self.width)*scale and y >= (self.y+self.yrange*self.value)*scale and y < (self.height+self.y+self.yrange*self.value)*scale then
+				return true
+			end
+		else
+			if x >= (self.x+self.xrange*self.value)*scale and x < (self.x+self.width+self.xrange*self.value)*scale and y >= self.y*scale and y < (self.height+self.y)*scale then
+				return true
+			end
 		end
 	elseif self.type == "input" then
 		if x >= self.x*scale and x < (self.x+3+self.width*8+2)*scale and y >= self.y*scale and y < (self.y+1+self.height*10+2)*scale then
 	self:shotted()
 end
 
+function hammerbro:portaled()
+	self.jumping = false
+	self.mask[2] = false
+end
 
 -------------------------------
 hammer = class:new()
 		
 		if introprogress > 0.5 and playedwilhelm == nil then
 			playsound(stabsound)
+			
 			playedwilhelm = true
 		end
 		
 				end
 			end
 		elseif self.dir == "hor" then
-			if v.speedy >= 0 then
+			if v.speedy <= 0 then
 				if #checkrect(v.x, self.y - v.height, v.width, v.height, {"exclude", v}, true) > 0 then
 					v.y = self.y + self.height
 				else
 ]]
 
 function love.load()
-	marioversion = 1004
-	versionstring = "version 1.4"
+	marioversion = 1005
+	versionstring = "version 1.5"
 	shaderlist = love.filesystem.enumerate( "shaders/" )
 	
 	local rem
 	currentshaderi1 = 1
 	currentshaderi2 = 1
 	
+	hatcount = #love.filesystem.enumerate("graphics/SMB/hats")
+	
 	loadconfig()
 	saveconfig()
 	width = 25
 	changescale(scale, fullscreen)
 	love.graphics.setCaption( "Mari0" )
 	
-	--version check
+	--version check by checking for a const that was added in 0.8.0
 	if love._version_major == nil then error("You have an outdated version of Love! Get 0.8.0 or higher and retry.") end
 	
 	iconimg = love.graphics.newImage("graphics/icon.gif")
 	require "koopa"
 	require "cheepcheep"
 	require "mushroom"
+	require "hatconfigs"
+	require "bighatconfigs"
 	require "flower"
 	require "star"
 	require "oneup"
 	require "bulletbill"
 	require "hammerbro"
 	require "fireball"
-	require "hatconfigs"
-	require "bighatconfigs"
 	require "gui"
 	require "blockdebris"
 	require "firework"
 	if getupdate() then
 		updatenotification = true
 	end
+	http.TIMEOUT = 4
 	
 	graphicspack = "SMB" --SMB, ALLSTARS
 	playertypei = 1
 	
 	gradientimg = love.graphics.newImage("graphics/gradient.png");gradientimg:setFilter("linear", "linear")
 	
-	portalbackgroundimg = love.graphics.newImage("graphics/" .. graphicspack .. "/portalbackground.png")
-	
 	--optionsmenu
 	skinpuppet = {}
 	secondskinpuppet = {}
 end
 
 function love.update(dt)
-	music:update()
-	
+	if music then
+		music:update()
+	end
 	dt = math.min(0.01666667, dt)
 	
 	--speed
 			end
 			s3 = s2[3]:split(",")
 			for i = 1, #s3 do
-				mariohats[tonumber(s2[2])][i] = tonumber(s3[i])
+				local hatno = tonumber(s3[i])
+				if hatno > hatcount then
+					hatno = hatcount
+				end
+				mariohats[tonumber(s2[2])][i] = hatno
 			end
 			
+			
 		elseif s2[1] == "scale" then
 			scale = tonumber(s2[2])
 			
 				if tonumber(s3[i]) == 1 then
 					reachedworlds[s2[2]][i] = true
 				end
-			end	
+			end
 		end
 	end
 	
 end
 
 function getupdate()
-	local onlinedata = http.request("http://server.stabyourself.net/mari0/?mode=mappacks")
+	local onlinedata, code = http.request("http://server.stabyourself.net/mari0/?mode=mappacks")
 	
-	if not onlinedata then
-		print("server down!")
+	if code ~= 200 then
+		return false
+	elseif not onlinedata then
 		return false
 	end
 	
 			love.graphics.drawq(fontimage, fontquads[char], x+((i-1)*8)*scale, y, 0, scale, scale)
 		end
 	end
+end
+
+function loadcustombackground()
+	local i = 1
+	custombackgroundimg = {}
+	custombackgroundwidth = {}
+	custombackgroundheight = {}
+	--try to load map specific background first
+	local levelstring = marioworld .. "-" .. mariolevel
+	if mariosublevel ~= 0 then
+		levelstring = levelstring .. "_" .. mariosublevel
+	end
+	
+	while love.filesystem.exists("mappacks/" .. mappack .. "/" .. levelstring .. "background" .. i .. ".png") do
+		custombackgroundimg[i] = love.graphics.newImage("mappacks/" .. mappack .. "/" .. levelstring .. "background" .. i .. ".png")
+		custombackgroundwidth[i] = custombackgroundimg[i]:getWidth()/16
+		custombackgroundheight[i] = custombackgroundimg[i]:getHeight()/16
+		i = i +1
+	end
+	
+	if #custombackgroundimg == 0 then
+		while love.filesystem.exists("mappacks/" .. mappack .. "/background" .. i .. ".png") do
+			custombackgroundimg[i] = love.graphics.newImage("mappacks/" .. mappack .. "/background" .. i .. ".png")
+			custombackgroundwidth[i] = custombackgroundimg[i]:getWidth()/16
+			custombackgroundheight[i] = custombackgroundimg[i]:getHeight()/16
+			i = i +1
+		end
+	end
+	
+	if #custombackgroundimg == 0 then
+		custombackgroundimg[i] = love.graphics.newImage("graphics/SMB/portalbackground.png")
+		custombackgroundwidth[i] = custombackgroundimg[i]:getWidth()/16
+		custombackgroundheight[i] = custombackgroundimg[i]:getHeight()/16
+	end
 end
 				end
 			end
 			
-			if not starstill then
+			if not starstill and not levelfinished then
 				playmusic()
 				music:stop("starmusic")
 			end
 	end
 	
 	--coins
-	local x = math.floor(self.x+self.width/2)+1
-	local y = math.floor(self.y+self.height)+1
-	if inmap(x, y) and tilequads[map[x][y][1]].coin then
-		collectcoin(x, y)
-	end
-	local y = math.floor(self.y+self.height/2)+1
-	if inmap(x, y) and tilequads[map[x][y][1]].coin then
-		collectcoin(x, y)
-	end
-	if self.size > 1 then
-		if inmap(x, y-1) and tilequads[map[x][y-1][1]].coin then
-			collectcoin(x, y-1)
+	if not editormode then
+		local x = math.floor(self.x+self.width/2)+1
+		local y = math.floor(self.y+self.height)+1
+		if inmap(x, y) and tilequads[map[x][y][1]].coin then
+			collectcoin(x, y)
+		end
+		local y = math.floor(self.y+self.height/2)+1
+		if inmap(x, y) and tilequads[map[x][y][1]].coin then
+			collectcoin(x, y)
+		end
+		if self.size > 1 then
+			if inmap(x, y-1) and tilequads[map[x][y-1][1]].coin then
+				collectcoin(x, y-1)
+			end
 		end
 	end
 	
 					self.speedx = uwmaxairwalkspeed
 				end
 			end
-		else --ON GROUND
+		elseif self.ducking == false then --ON GROUND
 			if self.speedx < uwmaxwalkspeed then
 				if self.speedx < 0 then
 					if self.speedx < -uwmaxrunspeed then
 					self.speedx = -uwmaxairwalkspeed
 				end
 			end
-		else --ON GROUND
+		elseif self.ducking == false then --ON GROUND
 			if self.speedx > -uwmaxwalkspeed then
 				if self.speedx > 0 then
 					if self.speedx > uwmaxrunspeed then
 				self:setquad()
 			end
 		else
+			if self.ducking then
+				self:duck(false)
+			end
 			playsound(swimsound)
 			
 			self.speedy = -uwjumpforce - (math.abs(self.speedx) / maxrunspeed)*uwjumpforceadd
 				playsound(oneupsound)
 			end
 			addpoints(200)
-			--7 coins; 7 sins. COINCIDENCE? I THINK NOT.
-			if tonumber(r[3]) == 1 then
-				if tilequads[r[1]].invisible then
-					if spriteset == 1 then
-						map[x][y][1] = 113
-					elseif spriteset == 2 then
-						map[x][y][1] = 118
-					else
-						map[x][y][1] = 112
-					end
+			
+			local exists = false
+			for i = 1, #coinblocktimers do
+				if x == coinblocktimers[i][1] and y == coinblocktimers[i][2] then
+					exists = i
+				end
+			end
+			
+			if not exists then
+				table.insert(coinblocktimers, {x, y, coinblocktime})
+			elseif coinblocktimers[exists][3] <= 0 then
+				if spriteset == 1 then
+					map[x][y][1] = 113
+				elseif spriteset == 2 then
+					map[x][y][1] = 114
 				else
-					if spriteset == 1 then
-						map[x][y][1] = 113
-					elseif spriteset == 2 then
-						map[x][y][1] = 114
-					else
-						map[x][y][1] = 117
-					end
+					map[x][y][1] = 117
 				end
-			else
-				map[x][y][3] = r[3]-1
 			end
 		end
 		
 			self:shrink()
 			return
 		end
-	else
+	elseif how ~= "time" then
 		if bonusstage then
 			levelscreen_load("sublevel", 0)
 			return
 end
 
 function mario:star()
+	addpoints(1000)
 	self.startimer = 0
 	self.colors = starcolors[1]
 	self.starred = true
 end
 
 function mario:fire()
-	if not noupdate and self.controlsenabled and self.size == 3 then
+	if not noupdate and self.controlsenabled and self.size == 3 and self.ducking == false then
 		if self.fireballcount < maxfireballs then
 			local dir = "right"
 			if self.pointingangle > 0 then
 		end
 	end
 	
+	self.colors = mariocolors[self.playernumber]
 	self.speedy = 0
 	self.speedx = 0
 	self.dead = false
 		continueavailable = true
 	end
 	
+	mariolevel = 1
+	marioworld = 1
+	mariosublevel = 0
+	
 	--load 1-1 as background
 	loadbackground("1-1.txt")
 	
 	if mappackscroll then
 		--smooth the scroll
 		if mappackscrollsmooth > mappackscroll then
-			mappackscrollsmooth = mappackscrollsmooth - scrollsmoothrate*dt
+			mappackscrollsmooth = mappackscrollsmooth - (mappackscrollsmooth-mappackscroll)*dt*5-0.1*dt
 			if mappackscrollsmooth < mappackscroll then
 				mappackscrollsmooth = mappackscroll
 			end
 		elseif mappackscrollsmooth < mappackscroll then
-			mappackscrollsmooth = mappackscrollsmooth + scrollsmoothrate*dt
+			mappackscrollsmooth = mappackscrollsmooth - (mappackscrollsmooth-mappackscroll)*dt*5+0.1*dt
 			if mappackscrollsmooth > mappackscroll then
 				mappackscrollsmooth = mappackscroll
 			end
 	if onlinemappackscroll then
 		--smooth the scroll
 		if onlinemappackscrollsmooth > onlinemappackscroll then
-			onlinemappackscrollsmooth = onlinemappackscrollsmooth - scrollsmoothrate*dt
+			onlinemappackscrollsmooth = onlinemappackscrollsmooth - (onlinemappackscrollsmooth-onlinemappackscroll)*dt*5-0.1*dt
 			if onlinemappackscrollsmooth < onlinemappackscroll then
 				onlinemappackscrollsmooth = onlinemappackscroll
 			end
 		elseif onlinemappackscrollsmooth < onlinemappackscroll then
-			onlinemappackscrollsmooth = onlinemappackscrollsmooth + scrollsmoothrate*dt
+			onlinemappackscrollsmooth = onlinemappackscrollsmooth - (onlinemappackscrollsmooth-onlinemappackscroll)*dt*5+0.1*dt
 			if onlinemappackscrollsmooth > onlinemappackscroll then
 				onlinemappackscrollsmooth = onlinemappackscroll
 			end
 	
 	if mappackhorscroll then
 		if mappackhorscrollsmooth > mappackhorscroll then
-			mappackhorscrollsmooth = mappackhorscrollsmooth - scrollsmoothrate*dt
+			mappackhorscrollsmooth = mappackhorscrollsmooth - (mappackhorscrollsmooth-mappackhorscroll)*dt*5-0.03*dt
 			if mappackhorscrollsmooth < mappackhorscroll then
 				mappackhorscrollsmooth = mappackhorscroll
 			end
 		elseif mappackhorscrollsmooth < mappackhorscroll then
-			mappackhorscrollsmooth = mappackhorscrollsmooth + scrollsmoothrate*dt
+			mappackhorscrollsmooth = mappackhorscrollsmooth - (mappackhorscrollsmooth-mappackhorscroll)*dt*5+0.03*dt
 			if mappackhorscrollsmooth > mappackhorscroll then
 				mappackhorscrollsmooth = mappackhorscroll
 			end
 			xtodraw = width
 		end
 	end
-	
-	--portal background
-	if portalbackground then
-		for x = 1, xtodraw do
-			love.graphics.draw(portalbackgroundimg, (x-1)*16*scale, -8*scale, 0, scale, scale)
+		
+	--custom background
+	if custombackground then
+		for i = #custombackgroundimg, 1, -1 do
+			for y = 1, math.ceil(15/custombackgroundheight[i]) do
+				for x = 1, math.ceil(width/custombackgroundwidth[i])+1 do
+					love.graphics.draw(custombackgroundimg[i], math.floor(((x-1)*custombackgroundwidth[i])*16*scale), (y-1)*custombackgroundheight[i]*16*scale, 0, scale, scale)
+				end
+			end
 		end
 	end
 	
 		end
 		
 		local start = 9
-		if portalbackground then
+		if custombackground then
 			start = 1
 		end
 		
 			love.graphics.setColor(255, 255, 255, 255)
 			properprint("a little patience..|downloading " .. currentdownload .. " of " .. downloadcount, 50*scale, 30*scale)
 		else
-			love.graphics.translate(- mappackhorscrollsmooth*scale*mappackhorscrollrange, 0)
+			love.graphics.translate(-round(mappackhorscrollsmooth*scale*mappackhorscrollrange), 0)
 			
 			if mappackhorscrollsmooth < 1 then
 				--draw each butten (even if all you do, is press ONE. BUTTEN.)
 				--scrollbar offset
-				love.graphics.translate(0, -mappackscrollsmooth*60*scale)
+				love.graphics.translate(0, -round(mappackscrollsmooth*60*scale))
 				
 				love.graphics.setScissor(240*scale, 16*scale, 200*scale, 200*scale)
 				love.graphics.setColor(0, 0, 0, 200)
 					end
 				end
 			
-				love.graphics.translate(0, mappackscrollsmooth*60*scale)
+				love.graphics.translate(0, round(mappackscrollsmooth*60*scale))
 			
 				local i = mappackscrollsmooth / (#mappacklist-3.233)
 			
 			
 			end
 			
-			love.graphics.translate(- (- mappackhorscrollsmooth*scale*mappackhorscrollrange), 0)
+			love.graphics.translate(round(mappackhorscrollsmooth*scale*mappackhorscrollrange), 0)
 			----------
 			--ONLINE--
 			----------
 			
-			love.graphics.translate(mappackhorscrollrange*scale - mappackhorscrollsmooth*scale*mappackhorscrollrange, 0)
+			love.graphics.translate(round(mappackhorscrollrange*scale - mappackhorscrollsmooth*scale*mappackhorscrollrange), 0)
 			
 			if mappackhorscrollsmooth > 0 then
 				if #onlinemappacklist == 0 then
-					properprint(" no dlc yet, sorry..| come back later for| more mari0 content!||  you can also send|us your own mappacks!", 40*scale, 80*scale)
+					properprint("something went wrong||      sorry d:||maybe your internet|does not work right?", 40*scale, 80*scale)
 				end
 				
 				love.graphics.setScissor()
 				love.graphics.setScissor(21*scale, 16*scale, 218*scale, 200*scale)
 				
 				--scrollbar offset
-				love.graphics.translate(0, -onlinemappackscrollsmooth*60*scale)
+				love.graphics.translate(0, -round(onlinemappackscrollsmooth*60*scale))
 				for i = 1, #onlinemappacklist do
 					--back
 					love.graphics.draw(mappackback, 25*scale, (20+(i-1)*60)*scale, 0, scale, scale)
 					end
 				end
 			
-				love.graphics.translate(0, onlinemappackscrollsmooth*60*scale)
+				love.graphics.translate(0, round(onlinemappackscrollsmooth*60*scale))
 			
 				local i = onlinemappackscrollsmooth / (#onlinemappacklist-3.233)
 			
 				love.graphics.draw(mappackscrollbar, 227*scale, (20+i*160)*scale, 0, scale, scale)
 			end
 			
-			love.graphics.translate(- (mappackhorscrollrange*scale - mappackhorscrollsmooth*scale*mappackhorscrollrange), 0)
+			love.graphics.translate(- round(mappackhorscrollrange*scale - mappackhorscrollsmooth*scale*mappackhorscrollrange), 0)
 		end
 		
 		love.graphics.setScissor()
 			
 			love.graphics.setColor(255, 255, 255, alpha)
 			
-			properprint("portal 1 color:", 31*scale, 150*scale)
+			properprint("coop portal 1 color:", 31*scale, 150*scale)
 			
 			love.graphics.draw(huebarimg, 32*scale, 170*scale, 0, scale, scale)
 			
 			
 			love.graphics.setColor(255, 255, 255, alpha)
 			
-			properprint("portal 2 color:", 31*scale, 180*scale)
+			properprint("coop portal 2 color:", 31*scale, 180*scale)
 			
 			love.graphics.draw(huebarimg, 32*scale, 200*scale, 0, scale, scale)
 			
 		end
 		startx = 3
 		starty = 13
-		portalbackground = false
+		custombackground = false
 		backgroundi = 1
 		love.graphics.setBackgroundColor(backgroundcolor[backgroundi])
 	else
 		end
 		
 		--get background color
-		portalbackground = false
+		custombackground = false
 		
 		for i = 2, #s2 do
 			s3 = s2[i]:split("=")
 				love.graphics.setBackgroundColor(backgroundcolor[backgroundi])
 			elseif s3[1] == "spriteset" then
 				spriteset = tonumber(s3[2])
-			elseif s3[1] == "portalbackground" then
-				portalbackground = true
+			elseif s3[1] == "custombackground" or s3[1] == "portalbackground" then
+				custombackground = true
 			end
 		end
+		
+		if custombackground then
+			loadcustombackground()
+		end
 	end
 end
 
 end
 
 function downloadmappacks()	
-	local onlinedata = http.request("http://server.stabyourself.net/mari0/?mode=mappacks")
+	local onlinedata, code = http.request("http://server.stabyourself.net/mari0/?mode=mappacks")
 	
-	if not onlinedata then
-		print("server down!")
-		return
+	if code ~= 200 then
+		return false
+	elseif not onlinedata then
+		return false
 	end
 	
 	local maplist = {}
 	local versionlist = {}
+	local latestversion = marioversion
 	
 	local split1 = onlinedata:split("<")
 	for i = 2, #split1 do
 	
 	if latestversion > marioversion then
 		outdated = true
-		return
+		return false
 	end
 	
 	--download all mappacks
 			end
 			
 			love.filesystem.mkdir("mappacks/" .. maplist[i])
-			local onlinedata = http.request("http://server.stabyourself.net/mari0/?mode=getmap&get=" .. maplist[i])
+			local onlinedata, code = http.request("http://server.stabyourself.net/mari0/?mode=getmap&get=" .. maplist[i])
+			
+			if code ~= 200 then
+				return false
+			end
+			
 			local split1 = onlinedata:split("<")
 			for j = 2, #split1 do
 				local split2 = split1[j]:split(">")
 			love.filesystem.write( "mappacks/" .. maplist[i] .. "/version.txt", versionlist[i])
 		end
 	end
+	
+	return true
 end
 
 function menu_keypressed(key, unicode)
 end
 
 function downloadfile(url, target)
-	local data = http.request(url)
-	love.filesystem.write(target, data)
+	local data, code = http.request(url)
+	
+	if code ~= 200 then
+		return false
+	end
+	
+	if data then
+		love.filesystem.write(target, data)
+		return true
+	else
+		return false
+	end
 end
 
 function reset_mappacks()
 	self.width = 12/16
 	self.height = 12/16
 	self.static = true
-	self.active = false
+	self.active = true
 	self.category = 6
 	self.mask = {	true,
 					false, false, true, true, true,
 			self.active = true
 			self.drawable = true
 		end
-		
-		if self.destroy then
-			return true
-		else
-			return false
-		end
+	end
+	
+	if self.destroy then
+		return true
+	else
+		return false
 	end
 end
 
 function mushroom:draw()
-	if self.uptimer < mushroomtime then
+	if self.uptimer < mushroomtime and not self.destroy then
 		--Draw it coming out of the block.
 		love.graphics.drawq(entitiesimg, entityquads[2].quad, math.floor(((self.x-xscroll)*16+self.offsetX)*scale), math.floor((self.y*16-self.offsetY)*scale), 0, scale, scale, self.quadcenterX, self.quadcenterY)
 	end
 music = {
 	thread = love.thread.newThread("musicthread", "musicloader_thread.lua"),
-	toload = {
-		"overworld",
-		"overworld-fast",
-		"underground",
-		"underground-fast",
-		"castle",
-		"castle-fast",
-		"underwater",
-		"underwater-fast",
-		"starmusic",
-		"starmusic-fast",
-		"princessmusic",
-	},
+	toload = {},
 	loaded = {},
 	list = {},
 	list_fast = {},
 
 music.stringlist = table.concat(music.toload, ";")
 
-for i,v in ipairs(music.toload) do
-	music.loaded[v] = false
-	if v:match("fast") then
-		table.insert(music.list_fast, v)
-	elseif not v:match("princessmusic") then
-		table.insert(music.list, v)
+function music:init()
+	self.thread:start()
+end
+
+function music:load(musicfile) -- can take a single file string or an array of file strings
+	if type(musicfile) == "table" then
+		for i,v in ipairs(musicfile) do
+			self:preload(v)
+		end
+	else
+		self:preload(musicfile)
+	end
+	self.stringlist = table.concat(self.toload, ";")
+	self.thread:set("musiclist", self.stringlist)
+end
+
+function music:preload(musicfile)
+	if self.loaded[musicfile] == nil then
+		self.loaded[musicfile] = false
+		table.insert(self.toload, musicfile)
 	end
 end
 
 end
 
 
-music.thread:start()
-music.thread:set("musiclist", music.stringlist)
+music:load{
+	"overworld",
+	"overworld-fast",
+	"underground",
+	"underground-fast",
+	"castle",
+	"castle-fast",
+	"underwater",
+	"underwater-fast",
+	"starmusic",
+	"starmusic-fast",
+	"princessmusic",
+}
 
+-- the original/default music needs to be put in the correct lists
+for i,v in ipairs(music.toload) do
+	if v:match("fast") then
+		table.insert(music.list_fast, v)
+	elseif not v:match("princessmusic") then
+		table.insert(music.list, v)
+	end
+end
+
+music:init()
+

musicloader_thread.lua

 local musiclist = {}
 local musictoload = {} -- waiting to be loaded into memory
 
-local musiclist_str = this:demand("musiclist")
+local function getmusiclist()
+	-- the music string should have names separated by the ";" character
+	-- music will be loaded in in the same order as they appear in the string
+	local musicliststr = this:get("musiclist")
+	if musicliststr then
+		for musicname in musicliststr:gmatch("[^;]+") do
+			if not musiclist[musicname] then
+				musiclist[musicname] = true
+				table.insert(musictoload, musicname)
+			end
+		end
+	end
+end
 
--- the music string should have names separated by the ";" character
--- music will be loaded in in the same order as they appear in the string
-for musicname in musiclist_str:gmatch("[^;]+") do
-	table.insert(musiclist, musicname)
-	table.insert(musictoload, musicname)
+local function getfilename(name)
+	local filename = name:match("%.[mo][pg][3g]$") and name or musicpath:format(name) -- mp3 or ogg
+	if love.filesystem.exists(filename) and love.filesystem.isFile(filename) then
+		return filename
+	else
+		print(string.format("thread can't load \"%s\": not a file!", filename))
+	end
+end
+
+local function loadmusic()
+	if #musictoload > 0 then
+		local name = table.remove(musictoload, 1)
+		local filename = getfilename(name)
+		if filename then
+			local source = love.audio.newSource(love.sound.newDecoder(filename, 512 * 1024), "static")
+			--print("thread loaded music", name)
+			this:set(name, source)
+		end
+	end
 end
 
 while true do
-	if #musictoload > 0 then
-		local name = table.remove(musictoload, 1)
-		local filename = musicpath:format(name)
-		local source = love.audio.newSource(love.sound.newDecoder(filename, 512 * 1024), "static")
-		-- print("thread loaded music", name)
-		this:set(name, source)
-	else
-		-- if we loaded all music then we need to make sure to only finish if the main thread has received it
-		local keep_waiting = false
-		for i,v in ipairs(musiclist) do
-			if this:peek(v) then
-				keep_waiting = true
-			end
-		end
-		if not keep_waiting then
-			break
-		end
-	end
+	getmusiclist()
+	loadmusic()
 end
 	self.width = 12/16
 	self.height = 12/16
 	self.static = true
-	self.active = false
+	self.active = true
 	self.category = 6
 	self.mask = {	true,
 					false, false, true, true, true,
 		self.uptimer = self.uptimer + dt
 		self.y = self.y - dt*(1/mushroomtime)
 		self.speedx = mushroomspeed
-		
 	else
 		if self.static == true then
 			self.static = false
 			self.drawable = true
 			self.speedy = -starjumpforce/2
 		end
-		
-		--animate
-		self.timer = self.timer + dt
-		while self.timer > staranimationdelay do
-			self.quadi = self.quadi + 1
-			if self.quadi == 5 then
-				self.quadi = 1
-			end
-			self.quad = starquad[self.quadi]
-			self.timer = self.timer - staranimationdelay
+	end
+	
+	--animate
+	self.timer = self.timer + dt
+	while self.timer > staranimationdelay do
+		self.quadi = self.quadi + 1
+		if self.quadi == 5 then
+			self.quadi = 1
 		end
-		
-		if self.destroy then
-			return true
-		else
-			return false
-		end
+		self.quad = starquad[self.quadi]
+		self.timer = self.timer - staranimationdelay
+	end
+	
+	if self.destroy then
+		return true
+	else
+		return false
 	end
 end
 
 guirepeatdelay = 0.07
 mappackhorscrollrange = 220
 
-maximumbulletbills = 5
+maximumbulletbills = 5
+coinblocktime = 4