
require "scripts/camera.rb"
require "scripts/player.rb"

def preload
	return nil if ($preloaded);
	$preloaded=true;
	preloadCharsetImage("player.pcx","chrs/player.cha",true,35,5,2,32,32,4,8,24,24,0,1,nil);
	preloadCharsetImage("font.pcx","chrs/font.cha",true,256-32,20,2,16,16,0,0,16,16,0,1,nil);
	preloadCharsetImage("font2.pcx","chrs/font2.cha",true,256-32,20,2,16,16,0,0,16,16,0,1,nil);
	preloadCharsetImage("fontbig.pcx","chrs/fontbig.cha",true,256-32,20,1,17,17,0,0,15,16,0,1,nil);
	preloadCharsetImage("flag.pcx","chrs/flag.cha",true,1,1,0,64,64,0,0,64,64,0,1,nil);
	preloadCharsetImage("goomba.pcx","chrs/goomba.cha",true,90,10,2,32,40,4,12,24,28,0,1,nil);
	preloadCharsetImage("claw.pcx","chrs/claw.cha",true,1,1,0,64,320,8,8,48,80,0,1,nil);
	preloadCharsetImage("stony.pcx","chrs/stony.cha",true,40,10,2,32,40,4,12,24,28,0,1,nil);
	preloadCharsetImage("tiles_big.pcx","chrs/tiles_big.cha",true,36*8,12,0,48,48,8,8,32,32,0,1,[[24,6,75],[24+36*1,6,100],[24+36*2,6,125],[24+36*3,6,300],[24+36*4,6,75],[24+36*5,6,30],[24+36*6,6,100],[24+36*7,6,300]]);

	preloadCharsetImage("tclaw.pcx","chrs/tclaw.cha",true,5,1,0,240,48,192,0,48,48,0,1,nil);
	preloadCharsetImage("princess.pcx","chrs/princess.cha",true,15,5,0,64,96,0,32,32,64,0,1,nil);
	preloadCharsetImage("eyepop.pcx","chrs/eyepop.cha",true,4,4,0,8,8,0,0,8,8,0,1,nil);
	preloadCharsetVsp("eversion.vsp","chrs/tiles.cha",true);
	$font=loadCharset("font2.cha");
	$font_white=loadCharset("font.cha");
	
#	$img_status=loadImage("status.pcx");
	$img_title=loadImage("title.pcx",0x400040,true);	
	$img_title2=loadImage("title2.pcx",0x400040,true);	
	
	$img_bg=[[loadImage("bg11.pcx",0x400040,true),loadImage("bg12.pcx",0x400040,true),240,0,0.5,0.25],
			[loadImage("bg21.pcx",0x400040,true),loadImage("bg22.pcx",0x400040,true),240,0,0.5,0.25],
			[loadImage("bg31.pcx",0x400040,true),loadImage("bg32.pcx",0x400040,true),240,0,0.5,0.25],
			[loadImage("bg41.pcx",0x400040,true),loadImage("bg42.pcx",0x400040,true),240,240,0,0],
			[loadImage("bg51.pcx",0x400040,true),loadImage("bg52.pcx",0x400040,true),240,0,0.5,0.25],
			[loadImage("bg61.pcx",0x400040,true),loadImage("bg62.pcx",0x400040,true),240,0,0.5,0.25],
			[loadImage("bg71.pcx",0x400040,true),loadImage("bg72.pcx",0x400040,true),240,0,0.5,0.25],
			[loadImage("bg81.pcx",0x400040,true),loadImage("bg82.pcx",0x400040,true),0,0,0.25,0.5]
			]
	
	$img_eye=loadImage("eye.pcx",0x400040,true);	
	$img_eye2=loadImage("eye2.pcx",0x400040,true);	
end

def stringify(k)
return ((k/180000+100).to_i.to_s)[1..2]+":"+(((k%180000)/3000+100).to_i.to_s)[1..2]+":"+(((k%3000)/50+100).to_i.to_s)[1..2]+"."+(((k%50)*2+100).to_i.to_s)[1..2];
end

class MainState < State
	def startup()
		setTitle("Eversion Steam by Guilherme S. Tows");
		preload();
		$timeattack=false;
		enterState(GameState); 
	end
	def daemon()
		exit();
	end
end

	def loadNewMap(x)
		$darkness=0;
	
		$darkness=($midpoint?$midpoint_d:0);
		if (x) then
		$gemarray[0][0]=x if ($gemarray[0][0]<x);
		Marshal.dump($gemarray, File.new("save.sav","w")).close();
		$darkness=($midpoint?$midpoint_d:$startdark[$mapno]);
		end
		
		$gems=0;
		$mute=false;
		$map.destroy() if ($map)
		
		$playerx=5;
		$playery=12.25;
		
		$vertical=false;
		$ywins=nil;
		$ywine=nil;
		
		$map = loadMap("area"+x.to_s+".map","tiles_big.cha",EvMap) if (x);	
		$map = loadMap($mapname,"tiles_big.cha",EvMap) if (!x);	
		$map.renderstring="2E";

		$cameray=0;
		if ($midpoint) then
		$player = $map.spawnEntity(Player,"player.cha",$midpoint_x,$midpoint_y+0.25,0,0);
		$map.counter=$midpoint_t;
		$cameray=($midpoint_y/20).to_i*20;		
		else
		$player = $map.spawnEntity(Player,"player.cha",$playerx,$playery,0,0);
		end
		
		$limitx=0;
		
		$camera = $player;
		$xwins=0;
		$ywins=0 if ($ywins == nil); 
		$xwine=$map.w*32;
		$ywine=$height if ($ywine == nil);
		$volume=[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0];		
		$success=false;
		$oldv=-1;
		$flash=0;
		$ready=0;
		$ready=75 if ($staato);
		stopMusic();
		for i in 1..8
			resetMusic(i);
		end
		$restart=0;
		$event=random(256);
	end


def writeTextOutline(x,y,text,align)
	writeText($font,x-1,y,text,align);
	writeText($font,x+1,y,text,align);
	writeText($font,x,y-1,text,align);
	writeText($font,x,y+1,text,align);
	writeText($font_white,x,y,text,align);
end



class GameState < State
	def startup()
		$score=0;
		$pause=false;
		
		$width=640;
		$height=480;
		
		$menu=0;
		$option=0;
		
		begin
		f=File.new("save.sav","r");
		rescue Exception
		f=File.new("empty.sav","r");
		#$gemarray=nil;
		end
		$gemarray=Marshal.restore(f) if(f!=nil);
		f.close() if(f!=nil);
		
		
		$gemarray=[[1,0,[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]]] if ($gemarray==nil);
		$gemarray[0][2]=[0,0,0,0,0,0,0,0] if ($gemarray[0][2]==nil||$gemarray[0][2]==0);
		$gemarray[0][3]=[0,0,0,0,0,0,0,0] if ($gemarray[0][3]==nil||$gemarray[0][3]==0);
		$gemarray[0][4]=[0,0,0,0,0,0,0,0] if ($gemarray[0][4]==nil||$gemarray[0][4]==0);
		log($gemarray[0].to_s);
		
		
		$mapgems=[0,0,0,0,0,0,0,0];
		
		$totalgems=0;
		$maxtotalgems=0;
		for i in 1..7
			if ($gemarray[i]!=nil) then
			log($gemarray[i].length)
			$gemarray[i].each {|k| $totalgems+=1 if (k==0); $mapgems[i]+=1 if (k==0);}
			$maxtotalgems+=$gemarray[i].length();
			end
		end
		steamAddAchievement("GEMS_240") if ($totalgems==$maxtotalgems)
		
		$startdark=[nil,0,0,1,0,4,5,6,7];
		
		$bgcolor=[[0,128,255],[51,204,204],[102,153,153],[102,153,102],[184,149,46],[160,80,40],[133,33,33],[133,33,133],[0,0,0]];
		$darkness=0;
		$glimmer=0;
		$maxgems=0;
		
		loadMusic("song1.mp3",1);
		loadMusic("song1_master.ogg",2);
		loadMusic("song2_master.ogg",3);
		loadMusic("song3_master.ogg",4);
		loadMusic("song4.mp3",5);
		loadMusic("song1b.ogg",6);
		loadMusic("song7.mp3",7);
		loadMusic("song8.ogg",8);
		
		$mapno=1 if (!$timeattack);
		
		
		$staato=false;
		$midpoint=false;
		
		loadNewMap($mapno);
		$ready=200 if ($titled==nil);
		$titled=true;
		playMusic("title.mp3",0) if ($ready!=200)
		

		$mapno=0 if ($gemarray[0][1]>0 && !$timeattack);
		log("there I am");
	end
	
	def loadEndMap(fake, what)
		$gemarray[0][1]=1 if (!fake && !what);

		steamAddAchievement("ENDING_1") if (fake && !what)
		steamAddAchievement("ENDING_2") if (!fake && !what)
		steamAddAchievement("ENDING_3") if (what)


		Marshal.dump($gemarray, File.new("save.sav","w")).close();
		
		$mapno=nil;
		$gems=0;
		$darkness=0;
		$mute=false;
		$vertical=false;
		$ywins=nil;
		$ywine=nil;
	
		$map.destroy() if ($map)
		$map = loadMap("areaend.map","tiles_big.cha",EvMap);	
		$map.renderstring="2E";

		$player = $map.spawnEntity(PlayerImmobile,"player.cha",5,12.25,0,0);
		
		
		$princess = $map.spawnEntity(WhatPrincess,"princess.cha",14,11,0,0) if (what);
		
		$princess = $map.spawnEntity(Princess,"princess.cha",14,11,0,0) if (fake && !what);
		$princess = $map.spawnEntity(TruePrincess,"princess.cha",14,11,0,0) if (!fake && !what);
		$camera = $player;
		$xwins=0;
		$ywins=0;
		$xwine=$width;
		$ywine=$height;
		$volume=[0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0];		
		$success=false;
		$oldv=-1;
		$flash=0;
		$ready=0;
		stopMusic();
		for i in 1..8
			resetMusic(i);
		end
		$restart=0;
		$event=random(256);
	end	
	def keydown(k)
		enterState(StateKeySetup) if (!$staato && k==284)
		enterState(StateOptions) if (!$staato && k==283)
		$pause =false if (!$staato || $restart>0 || $ready>0 || $success)
	end
	
	def daemon()
			if ($restart>0) then
				$restart-=1;
				loadNewMap($mapno) if ($restart==0);
			end
			
			if ($ready>0) then
				$ready-=1;
				playMusic("title.mp3",0) if ($ready==0 && !$staato) 
				return;
			end

				if (getButtonOnce(6)>0) then
					$pause=!$pause
					$pause =false if (!$staato || $restart>0 || $ready>0 || $success)
				end
			
			if (!$staato) then
			
			
				if ((getButtonOnce(8)>0 || getButtonOnce(3)>0)) then
					$option+=1;
					$option+=1 if ($menu==0 && $option==1 && $gemarray[0][1]==0)
					$option=0 if ($menu==0 && $option>4)
					$option=0 if ($menu==1 && $option>$gemarray[0][0]-1)
				end
			
				if ((getButtonOnce(7)>0 || getButtonOnce(2)>0)) then
					$option-=1;
					$option-=1 if ($menu==0 && $option==1 && $gemarray[0][1]==0)
					$option=4 if ($menu==0 && $option<0)
					$option=$gemarray[0][0]-1 if ($menu==1 && $option<0)
				end
			
				if (getButton(4)>0) then
					setButton(4,0)
					
					if ($menu==1) then
					$mapno=$option+1;
					$staato=true;
					stopMusic();
					loadNewMap($mapno) 
					elsif ($option==0) then
					$menu=1
					elsif ($option==1) then
					enterState(StateTimeAttack) 
					elsif ($option==2) then
					enterState(StateOptions) 
					elsif ($option==3) then
					steamOpenAchievements();
					elsif ($option==4) then
					exit();
					end
				end
			return;
			end
	
			return if ($pause)
			
			$map.runDaemon();
			
			if (getButton(4)>0 && $success) then
				setButton(4,0);
				stopMusic();
				if $timeattack then leaveState(); return; end
				$midpoint=false;
				$mapno+=1;
				if ($mapno==8 && $fakeend) then
					loadEndMap(true, $darkness==3);
				elsif ($mapno==9)
					loadEndMap(false, $darkness==3);
				else
					loadNewMap($mapno);
				end
				return;
			end
			
			if (getButton(4)>0 && $glimmer!=0) then
			setButton(4,0);
			$darkness+=($glimmer<=>0);
			steamAddAchievement("EVERSION_LAYER_"+$darkness.to_s) if ($darkness>0)
			$flash=255;
			$map.readjust();
			end;
			$flash-=5 if ($flash>0);
			v=($glimmer+$darkness);
			if ($oldv!=v) then
			$oldvolume=$volume+[];
			for i in 0..7
				$volume[i]=0;
			end
			if (!$mute)
			case v
				when 0.0..1.0
				$volume[0]=1.0-v;
				$volume[1]=v;
				when 1.0..2.0
				$volume[1]=2.0-v;
				$volume[2]=v-1.0;
				when 2.0..3.0
				$volume[2]=3.0-v;
				$volume[3]=v-2.0;
				when 3.0..4.0
				$volume[3]=4.0-v;
				$volume[4]=v-3.0;
				when 4.0..5.0
				$volume[4]=5.0-v;
				$volume[5]=v-4.0;
				when 5.0..6.0
				$volume[5]=6.0-v;
				$volume[6]=v-5.0;
				when 6.0..7.0
				$volume[6]=7.0-v;
				$volume[7]=v-6.0;
			end
			end
			log (v.to_s+"="+$oldvolume.join(",")+"-"+$volume.join(","));
			for i in 0..7
				continueMusic(i+1) if ($oldvolume[i]==0.0 && $volume[i]>0.0);
				pauseMusic(i+1) if ($oldvolume[i]>0.0 && $volume[i]==0.0);
				setMusicVolume(i+1,$volume[i]);
			end
			end
			$oldv=v;
	end
	def render()
	
		if ($ready>0) then
			strokeColor(0,0,0);
			drawFilledRectangle(0,0,$width,$height);
			if (!$staato) then
				y=120;
				writeText($font_white,$width/2,y,"Welcome to my mod ",1);
				writeText($font_white,$width/2,y+20,"This is not a valid copy",1);
				writeText($font_white,$width/2,y+40,"If you want to play eversion",1);
				writeText($font_white,$width/2,y+80,"purchase it by steam",1);
				writeText($font_white,$width/2,y+140,"",1);
				writeText($font_white,$width/2,y+160,"",1);
				writeText($font_white,$width/2,y+220,"Thank you for zaraustra ",1);
				writeText($font_white,$width/2,y+240,"for making eversion!",1);
				writeText($font_white,$width/2,y+280,"VISIT HIM AT HTTP://ZARAT.US/",1);
				return true;
			
			else
			
			
			
			if ($darkness>=5 && ($event/16)<($darkness*2-5) && (!$timeattack))
				case ($event%8)
					when 0 then
						writeText($font_white,$width/2,232,"I SEE YOU",1);
					when 1 then
						writeText($font_white,$width/2,232,"BEHIND YOU",1);
					when 2 then
						writeText($font_white,$width/2,232,"READY!",1);
						writeText($font_white,$width/2,248,"TO DIE",1) if ($ready<25);
					when 3 then
						writeText($font_white,$width/2,232,"STOP",1);
					when 4 then
						writeText($font_white,$width/2,232,"GAME OVER",1);
					when 5 then
						writeText($font_white,$width/2,232,"MOTHER",1);
					when 6 then
						writeText($font_white,$width/2,232,"GIVE UP",1);
					when 7 then
				end
				if ($gemarray[0][3][$event%8]==0) then
				$gemarray[0][3][$event%8]=1;
				steamAddAchievement("MESSAGE_8") if ($gemarray[0][3][0..7]==[1,1,1,1,1,1,1,1])
				end
			else
				if ($timeattack)
				case ($event%8)
					when 0 then
						writeText($font_white,$width/2,232,"GO!",1);
					when 1 then
						writeText($font_white,$width/2,232,"ON YOUR MARKS",1);
					when 2 then
						writeText($font_white,$width/2,232,"READY!",1);
						writeText($font_white,$width/2,248,"TO RACE",1) if ($ready<25);
					when 3 then
						writeText($font_white,$width/2,232,"GEMS ADD TIME",1);
					when 4 then
						writeText($font_white,$width/2,232,"HURRY UP",1);
					when 5 then
						writeText($font_white,$width/2,232,"TOO SLOW",1);
					when 6 then
						writeText($font_white,$width/2,232,"GAME ON",1);
					when 7 then
						writeText($font_white,$width/2,232,"FORWARD",1);
				end
				else
					writeText($font_white,$width/2,232,"READY!",1);
				end
			end
			return;
			end
		end
	
		strokeColor($bgcolor[$darkness][0],$bgcolor[$darkness][1],$bgcolor[$darkness][2]);
		strokeColor($bgcolor[$darkness][0]*(1-$glimmer)+$bgcolor[$darkness+1][0]*($glimmer),
					$bgcolor[$darkness][1]*(1-$glimmer)+$bgcolor[$darkness+1][1]*($glimmer),
					$bgcolor[$darkness][2]*(1-$glimmer)+$bgcolor[$darkness+1][2]*($glimmer)) if ($glimmer>0);
		strokeColor($bgcolor[$darkness][0]*(1+$glimmer)+$bgcolor[$darkness-1][0]*(-$glimmer),
					$bgcolor[$darkness][1]*(1+$glimmer)+$bgcolor[$darkness-1][1]*(-$glimmer),
					$bgcolor[$darkness][2]*(1+$glimmer)+$bgcolor[$darkness-1][2]*(-$glimmer)) if ($glimmer<0);
		drawFilledRectangle(0,0,$width,$height);
		$img_eye.blit(0,0) if ($evilbg==1); 
		$img_eye2.blit(0,0) if ($evilbg==2); 
		
		
		
		if (!$success) then
		x=$camera.pixelx-316;
		y=$camera.pixely-118;
		
		x=($map.fnar.pixelx + x) / 2 if ($map.fnar); #  && x<$map.fnar.pixelx
		x=$map.fnar.pixelx if ($map.fnar) && x<$map.fnar.pixelx

		y=$cameray*32;
		y=$player.y*32-240 if ($vertical && !$success && !$player.dead)

		x=0 if (x<0);
		x=$xwine-$width if (x>$xwine-$width);
		
		y=$ywins if ($ywins && y<$ywins);
		y=$ywine-$height if ($vertical && $ywine && y>$ywine-$height)
		
		$cameray = y/32  if( !$success && $vertical && !$player.dead );
		
		
		@camx=x;
		@camy=y;
		end
		
		$img_bg[$darkness][0].blit((6400-@camx*$img_bg[$darkness][4])%640,     $img_bg[$darkness][2]);
		$img_bg[$darkness][0].blit((6400-@camx*$img_bg[$darkness][4])%640-640, $img_bg[$darkness][2]);
		$img_bg[$darkness][1].blit((6400-@camx*$img_bg[$darkness][5])%640,     $img_bg[$darkness][3]);
		$img_bg[$darkness][1].blit((6400-@camx*$img_bg[$darkness][5])%640-640, $img_bg[$darkness][3]);
		
		$map.draw(@camx.to_i,@camy.to_i);

		if (!$staato) then
			$img_title.blit(0,0) if ($gemarray[0][1]!=1); 
			$img_title2.blit(0,0) if ($gemarray[0][1]==1); 

			f=$font;			
			f=$font_white if ($gemarray[0][1]==1); 
			
			d=0
			d=8 if ($gemarray[0][1]==1); 


			for i in 0..7
				writeTextOutline(640-128+i*16,0,["E","V","E","R","S","I","O","N"][i],1) if ($gemarray[0][4][i]==1);
			end
			
			writeText(f,$width/2,160,"BY GUILHERME S. TOWS",1);
			
			writeText(f,$width/2,176,"MUSIC BY MATTHEW STEELE",1);
			writeText(f,$width/2,192,"AND MIROSLAV MALESEVIC",1);

			
			
			case ($menu)
				when 0 then
						writeTextOutline($width/2,256-24,"> PLAY GAME <",1) if ($option==0)
						writeTextOutline($width/2,256-24,"  PLAY GAME  ",1) if ($option!=0)
				
					if ($gemarray[0][1]==0) then
						writeTextOutline($width/2,256-24+24,($totalgems+1000).to_s[1..3]+"/"+($maxtotalgems+1000).to_s[1..3]+" GEMS",1) if ($totalgems>0);
					else
						writeTextOutline($width/2,256-24+24,"> TIME ATTACK <",1) if ($option==1)
						writeTextOutline($width/2,256-24+24,"  TIME ATTACK  ",1) if ($option!=1)
					
					end

						writeTextOutline($width/2,256-24+48,"> OPTIONS <",1) if ($option==2)
						writeTextOutline($width/2,256-24+48,"  OPTIONS  ",1) if ($option!=2)

						writeTextOutline($width/2,256-24+72,"> ACHIEVEMENTS <",1) if ($option==3)
						writeTextOutline($width/2,256-24+72,"  ACHIEVEMENTS  ",1) if ($option!=3)

						writeTextOutline($width/2,256-24+96,"> QUIT GAME <",1) if ($option==4)
						writeTextOutline($width/2,256-24+96,"  QUIT GAME  ",1) if ($option!=4)

				when 1 then
					for i in 0..$gemarray[0][0]-1
						s=($mapgems[i+1]+100).to_s[1..2]+"/"+($gemarray[i+1].length+100).to_s[1..2] if (i!=7)
						s="     " if (i==7)
						writeTextOutline($width/2,288-64+i*16,"> WORLD "+(i+1).to_s+" "+s+" <",1) if ($option==i)
						writeTextOutline($width/2,288-64+i*16,"  WORLD "+(i+1).to_s+" "+s+"  ",1) if ($option!=i)
						
					end
				
			end
			
			writeText(f,$width/2,400-32+d,"PRESS EVERT BUTTON TO CHOOSE",1);
			writeTextOutline($width/2,400+d,"F2 - OPTIONS, F3 - KEY CONFIG",1);
			writeText(f,$width/2,440,"V1.STEAM @ 2010 GUILHERME S. TOWS",1);
			writeTextOutline($width/2,458,"HTTP://ZARAT.US",1);
			return;
		end;

		if ($mapno!=8 && $mapno!=nil && !$timeattack) then
		writeText($font,8,8,"SCORE "+($score+1000000).to_s[1..6],0) if ($darkness<5);
		writeText($font,8,8,"SCORE "+(random(900000)+100000).to_s,0) if ($darkness==5);
		writeText($font,320-56,8,"GEMS",0) if ($darkness<6);
		writeText($font,320-56,8,"????",0) if ($darkness==6);
		writeText($font,320+24,8,($gems+100).to_s[1..2]+"/"+($maxgems+100).to_s[1..2],0);
		writeText($font,632,8,"WORLD "+($mapno.to_s)+"-"+($darkness+1).to_s,2) if ($darkness<7);
		end

		writeText(($darkness>=6)?$font_white:$font,320,4,"TIME "+stringify($map.counter),1) if (!$success && $timeattack)
		

		#$img_title.blit(0,0)
		if ($flash>0) then
			strokeColorAlpha(255,255,255,$flash);
			strokeColorAlpha(255,255-($darkness-2)*51,255-($darkness-2)*51,$flash) if ($darkness>2);
			drawFilledRectangle(0,0,$width,$height);			
		end

		writeText($font,320,232,"PAUSE!",1) if ($pause);

	end
	def abort()
		Marshal.dump($gemarray, File.new("save.sav","w")).close() if ($gemarray);
		
		stopMusic() if ($timeattack)
		leaveState();
		enterState(GameState) if (($staato && !$timeattack) || $menu==1); 
	end
	def quit()
		Marshal.dump($gemarray, File.new("save.sav","w")).close() if ($gemarray);
	end
end

class StateTimeAttack < State
	def startup()
		@maps = Dir.entries("./time_attack");
		@maps=@maps.select {|a| (a[-4..-1]==".map")} 
		@maps=@maps.sort
		@mapselected=0;
		@choice=0;
		@leaderboards=steamInitializeLeaderboards();
		steamGetLeaderboardFile("time_attack/"+@maps[@mapselected], @choice);
		stopMusic();
		@doot=false;
	end
	def keydown(k)
	end
	def abort()
		$timeattack=false;
		$staato=false;
		playMusic("title.mp3",0);
	
		leaveState();
	end
	def daemon()
		a=false;
		if ( ( getButtonOnce(2)>0)) then @mapselected-=1 ; a=true; end
		if ( ( getButtonOnce(3)>0)) then @mapselected+=1 ; a=true; end
		if (getButtonOnce(8)>0 ) then @choice=(@choice+1)%3 ; a=true; end
		if (getButtonOnce(7)>0 ) then @choice=(@choice+2)%3 ; a=true; end
		@mapselected+=@maps.length if (@mapselected<0)
		@mapselected-=@maps.length if (@mapselected>=@maps.length);
		a=true if (@doot);
		@doot=false;

		steamGetLeaderboardFile("time_attack/"+@maps[@mapselected], @choice) if (a)


		if (getButton(4)>0) then
			setButton(4,0);
			$mapname="time_attack/"+@maps[@mapselected];
			$mapno=nil
			$midpoint=false;
			$timeattack=true;
			enterState(GameState);
			$staato=true;
			stopMusic();
			$ready=75;
			$timeattack=true;
			@doot=true;	
		end
	end

	def render()
		strokeColor(0,0,0);
		drawFilledRectangle(0,0,640,480);
		f=$font_white;
		writeText(f,320,16,"TIME ATTACK",1);
		writeText(f,320,80-32,"PRESS ESC TO LEAVE",1);
		writeText(f,320,96-32,"LEFT AND RIGHT TO CHOOSE A LEVEL",1);
		writeText(f,320,112-32,"UP AND DOWN TO CHANGE SCOREBOARDS",1);
		writeText(f,320,128-32,"PRESS EVERT TO START",1);
		
		writeText(f,320,160-32,"< "+@maps[@mapselected][0..-5]+" >",1);
		
		writeText(f,320,192-32,["YOUR POSITION","YOUR FRIENDS","TOP PLAYERS"][@choice],1);
		
		if (!@leaderboards["count"] && !@leaderboards["failure"]) then
		writeText(f,320,224-32,"LOADING...",1) 
		else
		writeText(f,320,224-32,"CONNECTION ERROR",1) if (@leaderboards["failure"])
		writeText(f,320,224-32,"SCOREBOARD IS EMPTY",1) if (@leaderboards["count"]==0 && @choice!=0)
		writeText(f,320,224-32,"YOU HAVE NO SCORE YET",1) if (@leaderboards["count"]==0 && @choice==0)
		
		y=224-32
		for i in 0..@leaderboards["count"]-1
			writeText(f,64,y,@leaderboards[i][0].to_s,2);
			writeText(f,64+16,y,@leaderboards[i][1].to_s,0);
			writeText(f,640-16,y,stringify(@leaderboards[i][2]/20),2);
			y+=16;
		end
		end
		
		
	end
end

class StateOptions < State
	def startup()
		$option=0;
		@deletesavedata=0;
	end
	def keydown(k)
		if (k==13) then
		
			configWrite("video","fullscreen",1-configRead("video","fullscreen")) if ($option==0);
			configWrite("video","glrenderer",1-configRead("video","glrenderer")) if ($option==1);
			videoReset() if ($option==0 || $option==1);
			enterState(StateJoystickSetup) if ($option==2);
			enterState(StateKeySetup) if ($option==3);
		end
	end
	def daemon()
		if (getButtonOnce(8)>0 ) then $option=($option+1)%5; end
		if (getButtonOnce(7)>0 ) then $option=($option+4)%5; end
		@deletesavedata==0 if (@deletesavedata<3 && $option!=4)

		if (getButtonOnce(4)>0) then
		
			configWrite("video","fullscreen",1-configRead("video","fullscreen")) if ($option==0);
			configWrite("video","glrenderer",1-configRead("video","glrenderer")) if ($option==1);
			videoReset() if ($option==0 || $option==1);
			enterState(StateJoystickSetup) if ($option==2);
			enterState(StateKeySetup) if ($option==3);
			if ($option==4) then
				@deletesavedata+=1 if (@deletesavedata<3)
				if (@deletesavedata==3) then
		f=File.new("empty.sav","r");
		$gemarray=Marshal.restore(f) if(f!=nil);
		f.close() if(f!=nil);
		$gemarray[0][2]=[0,0,0,0,0,0,0,0] if ($gemarray[0][2]==nil||$gemarray[0][2]==0);
		$gemarray[0][3]=[0,0,0,0,0,0,0,0] if ($gemarray[0][3]==nil||$gemarray[0][3]==0);
		$gemarray[0][4]=[0,0,0,0,0,0,0,0] if ($gemarray[0][4]==nil||$gemarray[0][4]==0);
					Marshal.dump($gemarray, File.new("save.sav","w")).close();
					
					
		$mapgems=[0,0,0,0,0,0,0,0];
		
		$totalgems=0;
					
				end
			end
			
		end
	end

	def render()
		strokeColor(0,0,0);
		drawFilledRectangle(0,0,640,480);
		f=$font_white;
		writeText(f,320,64,"OPTIONS",1);
		writeText(f,320,80,"PRESS ESC TO LEAVE AND SAVE",1);
		writeText(f,320,112,"ARROWS CHOOSE AN OPTION",1);
		writeText(f,320,128,"ENTER TO CHANGE",1);

		k=configRead("video","fullscreen");

		a="  "; b="  ";	if ($option==0) then a="> "; b=" <"; end
		writeText(f,320,200,a+"FULLSCREEN "+["OFF","ON"][k]+b,1);
		writeText(f,320,200+16,"(CAN TOGGLE WITH ALT+ENTER)",1);

		k=configRead("video","glrenderer");

		a="  "; b="  ";	if ($option==1) then a="> "; b=" <"; end
		writeText(f,320,200+48,a+"OPENGL RENDERER "+["OFF","ON"][k]+b,1);
		writeText(f,320,200+64,"(TURN OFF TO FIX LAG)",1);
		writeText(f,320,200+80,"(STEAM OVERLAY REQUIRES THIS)",1);

		a="  "; b="  ";	if ($option==2) then a="> "; b=" <"; end
		writeText(f,320,200+112,a+"CALIBRATE JOYSTICK"+b,1);

		a="  "; b="  ";	if ($option==3) then a="> "; b=" <"; end
		writeText(f,320,200+144,a+"CONFIGURE BUTTONS"+b,1);

		a="  "; b="  ";	if ($option==4) then a="> "; b=" <"; end
		text=["DELETE SAVE DATA","REALLY DELETE SAVE DATA","DELETE ALL GEMS AND LEVELS","SAVE DATA DELETED"][@deletesavedata];
		writeText(f,320,200+176,a+text+b,1);

	end
	def abort()
		$option=2;
		configSave();
		leaveState();
	end

end

class StateJoystickSetup < State
	def startup()
		@option=0;
	end
	def keydown(k)
		if (k==276 && @option==1) then
		centerdistance=configRead("joystick","centerdistance");		
		if (centerdistance<=4000) then
			centerdistance=centerdistance-1000;
		else
			centerdistance=(centerdistance/1.5).to_i;
			centerdistance=4000 if (centerdistance<5000);
		end
		configWrite("joystick","centerdistance",centerdistance);		
		inputReset();
		
		end

		if (k==275 && @option==1) then
		centerdistance=configRead("joystick","centerdistance");		
		if (centerdistance<4000) then
			centerdistance=centerdistance+1000;
		else
			centerdistance=(centerdistance*1.5).to_i if (centerdistance<32000);
		end
		configWrite("joystick","centerdistance",centerdistance);		
		inputReset();
		
		end

		
		if (k==13  && @option==0 ) then
			configWrite("joystick","centerx",joystickAxisValue(0));
			configWrite("joystick","centery",joystickAxisValue(1));
			inputReset();
		end
	end
	def daemon()

		if (getButtonOnce(8)>0 ) then $option=($option+1)%2; end
		if (getButtonOnce(7)>0 ) then $option=($option+1)%2; end


		if (getButtonOnce(3)>0 && @option==1) then
		centerdistance=configRead("joystick","centerdistance");		
		if (centerdistance<=4000) then
			centerdistance=centerdistance-1000;
		else
			centerdistance=(centerdistance/1.5).to_i;
			centerdistance=4000 if (centerdistance<5000);
		end
		configWrite("joystick","centerdistance",centerdistance);		
		inputReset();
		
		end

		if (getButtonOnce(2)>0 && @option==1) then
		centerdistance=configRead("joystick","centerdistance");		
		if (centerdistance<4000) then
			centerdistance=centerdistance+1000;
		else
			centerdistance=(centerdistance*1.5).to_i if (centerdistance<32000);
		end
		configWrite("joystick","centerdistance",centerdistance);		
		inputReset();
		
		end


		if ( getButtonOnce(4)>0 && @option==0 ) then
			configWrite("joystick","centerx",joystickAxisValue(0));
			configWrite("joystick","centery",joystickAxisValue(1));
			inputReset();
		end
	end
	def render()
		strokeColor(0,0,0);
		drawFilledRectangle(0,0,640,480);
		f=$font_white;
		writeText(f,320,32,"JOYSTICK CONFIGURATION",1);


		centerdistance=configRead("joystick","centerdistance");		

		a="  "; b="  ";	if (@option==0) then a="> "; b=" <"; end
		writeText(f,320,64,a+"RECENTER JOYSTICK"+b,1);
		
		a="  "; b="  ";	if (@option==1) then a="> "; b=" <"; end
		writeText(f,320,96,a+"CENTER AREA SIZE "+(centerdistance/1000).to_i.to_s+"000"+b,1);

		
		
		strokeColor(255,0,0);
		drawLine(320,300,320+(joystickAxisValue(0)-joystickAxisCenter(0))/100,300+(joystickAxisValue(1)-joystickAxisCenter(1))/100);
		strokeColor(0,0,255);
		drawFilledEllipse(320,300,6,6);
		strokeColor(255,0,0);
		drawEllipse(320,300,centerdistance/100,centerdistance/100);


		drawFilledEllipse(320+(joystickAxisValue(0)-joystickAxisCenter(0))/100,300+(joystickAxisValue(1)-joystickAxisCenter(1))/100,6,6);

		writeText(f,320,432,"TEST YOUR JOYSTICK",1);
		writeText(f,320,448," UP",0)	if (getButton(7)>0) ;
		writeText(f,320,448," DOWN",0)	if (getButton(8)>0) ;
		writeText(f,320,448,"LEFT ",2)	if (getButton(2)>0) ;
		writeText(f,320,448,"RIGHT ",2)	if (getButton(3)>0) ;
		writeText(f,320+8,464,joystickAxisValue(0).to_s+",",2);
		writeText(f,320-8,464,","+joystickAxisValue(1).to_s,0);
		
	end
	def abort()
		leaveState();
	end
end

class StateKeySetup < State
	KEY_LIST = ["---","","","","","","","","BS","Tab","","","Clear","Enter","","","","","","Pause","","","","","","","","Esc","","","","","Space","!","\"","#","$","","&","'","(",")","*","+",",","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@","","","","","","","","","","","","","","","","","","","","","","","","","","","[","\\","]","^","_","`","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","","","","","Delete","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Pad0","Pad1","Pad2","Pad3","Pad4","Pad5","Pad6","Pad7","Pad8","Pad9","Pad.","Pad/","Pad*","Pad-","Pad+","PadEnt","Pad=","Up","Down","Right","Left","Insert","Home","End","PgUp","PgDn","F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12","F13","F14","F15","","","","NumL","CapsL","ScrL","RShift","LShift","RCtrl","LCtrl","RAlt","LAlt","RMeta","LMeta","LSuper","RSuper","Mode","","Help","Print","SysRq","Break","Menu","Power","Euro"];
	KEY = [2, 3, 7, 8, 0, 4, 6];
	KEY_NAME = ["left","right","up","down","jump","evert","pause"];
	def startup()
		@x=0;
		@y=0;
		@setkey=false;
	end
	def keydown(k)
		log(k);
		if (@setkey && k!=27) then
			setButtonKey(KEY[@y],@x,k)
			@setkey=false
			return true;
		end
		@x=(@x+1)%3 if (k==276)
		@x=(@x+2)%3 if (k==275)
		@y=(@y+1)%KEY.length if (k==274)
		@y=(@y+(KEY.length-1))%KEY.length if (k==273)
		@setkey=true if (k==13)
	end
	def abort()
		if (@setkey) then
			setButtonKey(KEY[@y],@x,0);
			@setkey=false;
			return true;
		end
		leaveState();
	end
	def joyname(n)
		m=n>>2;
		return "JAxis"+m.to_s+"-" if (n%4==1)
		return "JAxis"+m.to_s+"+" if (n%4==2)
		return "JButton"+m.to_s if (n%4==3)
	end
	def daemon()
	end
	def render()
		strokeColor(0,0,0);
		drawFilledRectangle(0,0,640,480);
		f=$font_white;
		writeText(f,320,64,"KEY CONFIGURATION",1);
		writeText(f,320,80,"PRESS ESC TO LEAVE",1);
		writeText(f,320,112,"ARROWS CHOOSE A KEY",1);
		writeText(f,320,128,"ENTER TO CHANGE",1);
		
		y=176
		for i in 0..KEY.length-1

			writeText(f,40, y+i*32,KEY_NAME[i],0);
			writeText(f,160,y+i*32,KEY_LIST[getButtonKey(KEY[i],0)],0) if (getButtonKey(KEY[i],0)>=0);
			writeText(f,320,y+i*32,KEY_LIST[getButtonKey(KEY[i],1)],0) if (getButtonKey(KEY[i],1)>=0);
			writeText(f,480,y+i*32,KEY_LIST[getButtonKey(KEY[i],2)],0) if (getButtonKey(KEY[i],2)>=0);

			writeText(f,160,y+i*32,joyname(-getButtonKey(KEY[i],0)),0) if (getButtonKey(KEY[i],0)<0);
			writeText(f,320,y+i*32,joyname(-getButtonKey(KEY[i],1)),0) if (getButtonKey(KEY[i],1)<0);
			writeText(f,480,y+i*32,joyname(-getButtonKey(KEY[i],2)),0) if (getButtonKey(KEY[i],2)<0);
		end
		writeText(f,160-32+@x*160,y+@y*32,">",0);
		
		writeText(f,320,432,"PRESS THE NEW KEY",1) if (@setkey)
		writeText(f,320,448,"OR ESC TO CLEAR",1) if (@setkey)
	end
end

class StageEnd < Entity
	def startup()
		$totalgems=0;
		$maxtotalgems=0;
		@time=self.map.counter;
		for i in 1..8
			log($gemarray[i].to_s)
			if ($gemarray[i]!=nil) then
			$gemarray[i].each {|k| $totalgems+=1 if (k==0); }
			$maxtotalgems+=$gemarray[i].length();
			end
		end
		steamAddAchievement("GEMS_240") if ($totalgems==$maxtotalgems && !$timeattack)
		steamSetLeaderboardFileScore($mapname, @time*20) if ($timeattack)
#		$gemarray[0][2][$mapno-1]=@time if ($gemarray[0][2][$mapno-1]==0 || $gemarray[0][2][$mapno-1]>@time);
		self.everywhere=1;
	end
	def daemon()
		stopMusic() if (self.counter==350);
	end
	def render(x,y)
		writeText($font,320,128,"WORLD CLEAR",1)
		writeText($font,320,240,"GEMS "+($gems+100).to_s[1..2]+"/"+($maxgems+100).to_s[1..2],1) if (self.counter>50)
		writeText($font,320,288,"TOTAL GEMS "+($totalgems+1000).to_s[1..3]+"/"+($maxtotalgems+1000).to_s[1..3],1) if (self.counter>100 && !$timeattack)
		writeText($font,320,328,"TIME "+stringify(@time),1) if (self.counter>150 && $timeattack)
		writeText($font,320,368,"PRESS EVERT BUTTON",1) if (self.counter>200)
		return true;
	end
end

#				0 1 2 3 4 5 6 7
# clouds        - # # - - - - - 
# bushes		# # - - - - - -
# bricks		# # # X X - - -
# item bricks	! ! ! ! # # # #
# flowers       - - - - - ! ! !

class EvMap < Map
	attr_accessor :fnar
	def startup()
		@fnar=false;
		$maxgems=0;
		y=0; x=0; t=0;
		$evilbg=0;
		
		gv=0;
		
		$gemref=Hash.new;
		$randomeversions=false;
		$goombarevive=false;
		
		for y in 0..self.h
		for x in 0..self.w
			t=self.getTile(0,x,y);
			case t
			when 4 then
				if ($mapno) then
				$gemarray.push(Array.new) while ($gemarray[$mapno]==nil);
				$gemarray[$mapno].push(1) while ($gemarray[$mapno][gv]==nil);
				if ($gemarray[$mapno][gv]==0) then
					self.setTile(0,x,y,3);
					$gems+=1;
				end
				end
				$gemref[(y-1)*self.w+x]=gv;
				gv+=1;
				$maxgems+=1;
			when 6 then
				if ($mapno) then
				$gemarray.push(Array.new) while ($gemarray[$mapno]==nil);
				$gemarray[$mapno].push(1) while ($gemarray[$mapno][gv]==nil);
				if ($gemarray[$mapno][gv]==0) then
					self.setTile(0,x,y,0);
					$gems+=1;
				end
				end
				$gemref[y*self.w+x]=gv;
				gv+=1;
				$maxgems+=1;
			when 16 then
				$cloud=self.spawnEntity(DoomCloud,"tiles_big.cha",-20,0,0,0);
			when 17 then
				self.spawnEntity(DislocatePoint,"",x,y,0,0);
			when 18 then
				self.spawnEntity(WrapPoint,"",x,y,0,0);
			when 19 then
				self.spawnEntity(MidPoint,"",x,y,0,0);
			when 21 then
				self.spawnEntity(Goomba,"goomba.cha",x,y,0,0);
			when 22 then
				self.setTile(0,x,y,4);
				self.setZone(x,y,22);
			when 23 then
				self.spawnEntity(Claw,"claw.cha",x,y,0,0);
			when 25 then
				self.spawnEntity(Stony,"stony.cha",x,y,0,0);
			when 26 then
				self.spawnEntity(WhatClaw,"claw.cha",x,y,0,0);
			when 29 then
				self.spawnEntity(FakeFlag,"flag.cha",x,y-1,0,0);
			when 31 then
				e=self.spawnEntity(GemWarp,"tiles_big.cha",x,y,0,0);
				e.warp=6;
				log("warp "+e.warp.to_s);
			when 32..38 then
				e=self.spawnEntity(Warp,"tiles_big.cha",x,y,0,0);
				e.warp=t-32;
				log("warp "+e.warp.to_s);
			when 39 then
				self.spawnEntity(Flag,"flag.cha",x,y-1,0,0);
			when 30 then
				self.spawnEntity(SecretItem,"tiles_big.cha",x,y,0,0);
			when 200..207 then
				$darkness=t-200 if (!$midpoint);
			when 208 then
				$randomeversions=true;
			when 209 then
				$goombarevive=true;
			when 221 then
				if ($ywins) then $ywine=y*32; else $ywins=y*32; end
			when 222 then
				$vertical=true;
			when 225..232 then
				$darkness=t-225 if (!$midpoint);			
			when 253 then
					self.setZone(x,y,20);
			when 254 then
					self.setZone(x,y,24);
			when 255 then
				$playerx=x if (!$midpoint);
				$playery=y if (!$midpoint);
			end
		end
		end
		
		#$gemarray[$mapno] = $gemarray[$mapno][0..$maxgems-1] if ($mapno && $gemarray[$mapno].length>$maxgems)
		@tilemap=[0,12,13,14,15,16,2,24,0,4,5,6,3,0,0,0,0,0,0,0];
		readjust();
	end
	def readjust()
		y=0; x=0; t=0;
		for y in 0..self.h
		for x in 0..self.w
			t=self.getTile(0,x,y);
			z=self.getZone(x,y);
			case t
			when 1..18 then
				self.setTile(1,x,y,@tilemap[t]+($darkness*36));
				self.setObs(x,y,0);
				self.setZone(x,y,0) if (self.getZone(x,y)<20);
				case t
				when 1..5 then
					self.setObs(x,y,20);
					self.setTile(1,x,y,32+( ( (x * (x * x * 15731 + 789221) + 1376312589) >> 8 ) & 3)+($darkness*36)) if (t==1);
					self.setTile(1,x,y,20+( ( (x * (x * x * 15731 + 789221) + 1376312589) >> 8 ) + ( (y * (y * y * 15731 + 789221) + 1376312589) >> 8 ) & 3)+($darkness*36)) if (t==4 && ($darkness>=4));
					self.setTile(1,x,y, 8+( ( (x * (x * x * 15731 + 789221) + 1376312589) >> 8 ) + ( (y * (y * y * 15731 + 789221) + 1376312589) >> 8 ) & 3)+($darkness*36)) if (t==3 && ($darkness>=4));
					self.setZone(x,y,2) if (t==4);
					self.setZone(x,y,3) if (t==5);
				when 6 then
					self.setZone(x,y,1);
				when 9 then # tree
					self.setObs(x,y,20) if ($darkness<=1)
				when 10 then
					self.setZone(x,y,10);
				when 11 then # cloud
					self.setTile(1,x,y,19+($darkness*36)) if (self.getTile(0,x-1,y)==11);
					self.setTile(1,x,y,17+($darkness*36)) if (self.getTile(0,x+1,y)==11);
					self.setTile(1,x,y,18+($darkness*36)) if (self.getTile(0,x+1,y)==11 && self.getTile(0,x-1,y)==11);
					self.setTile(1,x,y,0) if ($darkness>3)
					self.setObs(x,y,20) if ($darkness>=1 && $darkness<=2)
				when 12 then # tree
					self.setObs(x,y,20) if ($darkness<=3)
				end
			end
			self.setZone(x,y,22) if (z==22);
		end
		end
	end
	def daemon()
		if($randomeversions && self.counter%200==0) then
			$darkness=($darkness+random(7)+1)%8;
				$flash=255;
				$map.readjust();
		end
	end
	def event(e,x,y,z)
		return false if (e!=$player);
		case z
			when 1 then
			 playSFX(1) if ($darkness<6); 
			 playSFX(2) if ($darkness>=6); 
			self.setTile(0,x,y,0);
			self.setTile(1,x,y,0);
			self.setZone(x,y,0);

			self.counter-=25 if ($gemarray[0][1]>0);
			self.counter=0 if (self.counter<0);

			$gemarray[$mapno][$gemref[y*$map.w+x]]=0 if ($mapno);
			$gems+=1;
			$score+=50+50*$darkness;
			when 10 then
				$player.hurt() if ($darkness>=5);
			when 20 then
			if (@fnar==false) then		
				$darkness=3;
				steamAddAchievement("EVERSION_LAYER_"+$darkness.to_s);
				$flash=255;
				$map.readjust();
				@fnar=self.spawnEntity(DeathCloud,"tiles_big.cha",$player.x-10,0,1.0/16,0);
				playSFX(4);
			end
			when 24 then
			if (@fnar==false) then		
				$darkness=6;
				steamAddAchievement("EVERSION_LAYER_"+$darkness.to_s);
				$flash=255;
				$map.readjust();
				@fnar=self.spawnEntity(BloodCloud,"tiles_big.cha",$player.x-10,0,1.0/16,0);
				playSFX(4);
			end			
		end
	end
	def step(e,x,y,z)
		return false if (e!=$player);
		case z
			when 3 then
			if ($darkness>=5) then
				playSFX(9);
				self.spawnEntity(BumpedBrick,"tiles_big.cha",x,y,0,-3.0/16).frame=self.getTile(1,x,y);			
				self.setTile(0,x,y,0);
				self.setTile(1,x,y,0);
				self.setZone(x,y,0);
			end
		end
	end
	def bump(e,x,y,z)
		return false if (e!=$player);
		case z
			when 2 then
			if ($darkness<4) then
				playSFX(9);
			self.spawnEntity(BumpedBlock,"tiles_big.cha",x,y,0,-3.0/16).frame=self.getTile(1,x,y)-1;
			self.setTile(0,x,y-1,6);
			self.setTile(1,x,y-1,$darkness*36+2);
			self.setZone(x,y-1,1);
			self.setTile(0,x,y,3);
			self.setZone(x,y,0);
			else
			self.spawnEntity(BumpedBlock,"tiles_big.cha",x,y,0,-3.0/16).frame=self.getTile(1,x,y);			
			end
			self.setTile(1,x,y,0);
			when 3 then
			if ($darkness>=3) then
				playSFX(9);
				self.spawnEntity(BumpedBrick,"tiles_big.cha",x,y,0,-3.0/16).frame=self.getTile(1,x,y);			
				self.setTile(0,x,y,0);
				self.setZone(x,y,0);
				$player.ys=0;
			else
				playSFX(9);
				self.spawnEntity(BumpedBlock,"tiles_big.cha",x,y,0,-3.0/16).frame=self.getTile(1,x,y);			
			end
			self.setTile(1,x,y,0);
			when 22 then
				$darkness=4;
				$flash=255;
				playSFX(4);
				self.setZone(x,y,0);
				self.spawnEntity(EyePop,"eyepop.cha",x+0.125,y+0.25,-0.125,-0.25);
				self.spawnEntity(EyePop,"eyepop.cha",x+0.625,y+0.25,+0.125,-0.25);
				
				$map.readjust();
			
		end
	end	
end

class EyePop < Entity
	def startup()
		self.pause=5;
	end
	def daemon()
		self.ys+=0.01;
		self.frame=(self.counter/4)%4;
		self.destroy() if (self.y>20);
	end
end

class BumpedBlock < Entity
	def startup
#		self.ys=-3.0/16;
	end
	def daemon()
		self.ys+=1.0/16;
		if (self.ys>=3.0/16) 
			self.map.setTile(1,self.x0.to_i,self.y0.to_i,(self.frame%36)+$darkness*36);
			self.destroy();
		end
	end
end

class BumpedBrick < Entity
	def startup
#		self.ys=-3.0/16;
	end
	def daemon()
		self.ys+=1.0/16;
		self.alpha-=50;
		if (self.ys>=3.0/16) 
			self.map.setObs(self.x0.to_i,self.y0.to_i,0);
			self.destroy();
		end
	end
end

class Flag < Entity
	def startup()
		$fakeend=false
	end
	def daemon()
#		self.alpha=($darkness==0)?255:0;
	end
	def collision(e)
		if (e=$player && !$success) then
			$success=true
			self.map.spawnEntity(StageEnd,"tiles_big.cha",self.x0,self.y0,0,0)	
			stopMusic();
			playMusic("goal.mp3",0);
		end
	end
end

class FakeFlag < Entity
	def startup()
		$fakeend=false
	end
	def daemon()
		if ($darkness==7) then
		$xwine=$map.w*32;
		else
		$xwine=self.x*32+96;
		end
		self.alpha=($darkness<7)?255:0;
	end
	def collision(e)
		if (e=$player && !$success && $darkness<7) then
			$success=true
			$fakeend=true if (!$timeattack)
			self.map.spawnEntity(StageEnd,"tiles_big.cha",self.x0,self.y0,0,0)	
			stopMusic();
			playMusic("goal.mp3",0);
		end
	end
end

class PlayerImmobile<Entity
end

class Princess < Entity
	def startup()
	$mute=true;
	$cameray=0;
	end
	def daemon
		self.xs=0;
		case (self.counter)
			when 1 then
				playMusic("title.mp3",0);
			when 100..200 then
				self.xs=-0.01;
				self.frame=(self.counter/10)%2;
			when 300..400 then
				self.xs=-0.01;
				self.frame=(self.counter/10)%2;
			when 600..700 then
				stopMusic();
				if (self.counter%10==0) then
				$darkness=7; $map.readjust();
				end;
				if (self.counter%10==5) then
				$darkness=0; $map.readjust();
				end;
			when 701 then
				$mute=false;
				$oldv=nil;
				$darkness=7; $map.readjust();
			when 800..850 then
				self.frame=((self.counter/5)%2)*3;			
			when 851 then
				self.frame=3;
			when 1000..1100 then
				self.xs=-0.01;
				self.frame=(self.counter/10)%2+2;
			when 1200..1300 then
				self.xs=-0.01;
				self.frame=(self.counter/10)%2+2;
			when 1400..1449 then
				self.frame=((self.counter%100)/10)+5;
			when 1500..1900 then
				self.xs=-0.01;
				self.frame=(self.counter/10)%2+10;
				if (self.counter>1700 && self.counter<1750) then
				  $evilbg=(self.counter/5)%2;
				elsif (self.counter>=1750)
				  $evilbg=1;
				end
			when 1901 then
				playSFX(3);
			when 2000 then
				exit();

		end
	end
	def render(x,y)
		if (self.counter>1900) then
			strokeColor(0,0,0);
			drawFilledRectangle(0,0,640,480);
			writeText($font_white,320,232,"GAME OVER",1);
			else
			return false;
		end
	end
end

class TruePrincess < Entity
	def startup()
	$mute=true;
	$cameray=0;
	end
	def daemon
		self.xs=0;
		$player.xs=0;
		case (self.counter)
			when 1 then
				playMusic("title.mp3",0);
			when 100..200 then
				self.xs=-0.005;
				self.frame=(self.counter/10)%2;
			when 300..400 then
				self.xs=-0.005;
				self.frame=(self.counter/10)%2;
			when 600..700 then
				stopMusic();
				if (self.counter%10==0) then
				$darkness=7; $map.readjust();
				end;
				if (self.counter%10==5) then
				$darkness=0; $map.readjust();
				end;
			when 701 then
				$mute=false;
				$oldv=nil;
				$darkness=7; $map.readjust();
			when 800..850 then
				self.frame=((self.counter/5)%2)*3;			
			when 851 then
				self.frame=3;
			when 900..950 then
				$player.frame=((self.counter/5)%2)*25;			
			when 951 then
				$player.frame=25;
			when 961 then
				$player.frame=26;
			when 971 then
				$player.frame=27;
			when 1000..1049 then
				self.frame=((self.counter%100)/10)+5;
			when 1100..1200 then
				self.xs=-0.005;
				$player.xs=0.01;
				self.frame=(self.counter/10)%2+10;
				$player.frame=(self.counter/10)%2+30;
			when 1300..1400 then
				self.xs=-0.005;
				self.frame=(self.counter/10)%2+10;
				$player.xs=0.01;
				$player.frame=(self.counter/10)%2+30;
			when 1500..1900 then
				self.xs=-0.005;
				self.frame=(self.counter/10)%2+10;
				$player.xs=0.005;
				$player.frame=(self.counter/10)%2+30;
				if (self.counter>1700 && self.counter<1750) then
				  $evilbg=((self.counter/5)%2)*2;
				elsif (self.counter>=1750)
				  $evilbg=2;
				end
			when 1901 then
				playSFX(3);
			when 2000 then
				exit();

		end
	end
	def render(x,y)
		if (self.counter>1900) then
			strokeColor(0,0,0);
			drawFilledRectangle(0,0,640,480);
			writeText($font_white,320,232,"THE END",1)
			else
			return false;
		end
	end
end

class WhatPrincess < Entity
	def startup()
	$mute=true;
	$cameray=0;
	end
	def daemon
		self.xs=0;
		case (self.counter)
			when 1 then
				playMusic("title.mp3",0);
			when 100..200 then
				self.xs=-0.01;
				self.frame=(self.counter/10)%2;
			when 300..400 then
				self.xs=-0.01;
				self.frame=(self.counter/10)%2;
			when 600..700 then
				stopMusic();
				if (self.counter%10==0) then
				$darkness=3; $map.readjust();
				end;
				if (self.counter%10==5) then
				$darkness=0; $map.readjust();
				end;
			when 701 then
				$mute=false;
				$oldv=nil;
				$darkness=3; $map.readjust();
			when 800..850 then
				self.frame=((self.counter/5)%2)*12;			
			when 851 then
				self.frame=12;
			when 900..950 then
				$player.frame=((self.counter/5)%2)*32;			
			when 951 then
				$player.frame=32;
		end
	end
	def render(x,y)
		return false;
	end
end


class Warp < Entity
	attr_accessor :warp
	def startup()
		@poof=0
		@poofed=false
	end
	def daemon()
		@poof-=1 if (@poof>0)
		return if (@warp<$darkness-1 || @warp>$darkness) 
		if ($player.x>self.x-2 && $player.x<self.x+4 && $player.y>self.y-2 && $player.y<self.y+4) then
			$glimmer=0.5-Math.sqrt(($player.x-self.x-1)*($player.x-self.x-1)+($player.y-self.y-1)*($player.y-self.y-1))/4
			$glimmer=0 if ($glimmer<0)
			$glimmer=-$glimmer if @warp<$darkness		
		end
		@poof=20-$darkness*4 if (@poofed==false && getButton(4)>0 && !@dead)
		@poofed=(getButton(4)>0)
	end
	def render(x, y)
		return true if ($darkness>=4)
		return true if ($darkness==2 && (self.map.counter%3)==0)
		return true if ($darkness==3 && (self.map.counter%3)<=1)
		strokeColorAlpha(0,0,0,128);
		drawEllipse(x+32,y+32,(100-@poof*5)/2,(100-@poof*5)/2) if (@poof>0)
		drawEllipse(x+32,y+32,(100-@poof*5)/2-1,(100-@poof*5)/2-1) if (@poof>0)
		drawEllipse(x+32,y+32,(100-@poof*5)/2-2,(100-@poof*5)/2-2) if (@poof>0)
		return true;
	end
end

class GemWarp < Entity
	attr_accessor :warp
	def startup()
	end
	def daemon()
		return if (@warp<$darkness-1 || @warp>$darkness || $totalgems<$maxtotalgems) 
		if ($player.x>self.x-2 && $player.x<self.x+4 && $player.y>self.y-2 && $player.y<self.y+4) then
			$glimmer=0.5-Math.sqrt(($player.x-self.x-1)*($player.x-self.x-1)+($player.y-self.y-1)*($player.y-self.y-1))/4
			$glimmer=0 if ($glimmer<0)
			$glimmer=-$glimmer if @warp<$darkness		
		end
	end
	def render(x, y)
		writeText($font_white,x+16,y,($totalgems+1000).to_s[1..3]+"/"+($maxtotalgems+1000).to_s[1..3],1) if ($darkness>=6);
		return true;
	end
end

class Goomba < Entity
	attr_accessor :wait
	def startup()
		self.y=self.y0+(2/16.0);
		self.xs=-1/16.0;
		@fl=0; @fr=4; @ft=5; @fn=4;
		@dead=false;
		@resting=0;
		@wait=0;
	end
	def daemon()
		if (@wait>0) then
			self.pause=10;
			self.x-=self.xs;
			return;
		end
		if (@resting>0) then
			@resting-=1 if ($darkness==7);
			 if (@resting <50) then
			self.alpha=255*((@resting/5)%2);
			else self.alpha=0;
			end
			self.alpha=255 if (@resting==0);
			self.xs=-1/16.0 if (@resting==0);
			self.frame=$darkness*10;
		end
	
		if (@dead) then
			self.ys+=1/16.0 if (self.ys<4/16.0);
			if (self.y>$cameray+20) then
				self.destroy if (!$goombarevive)
				if ($goombarevive) then
				self.x=self.x0;
				self.y=self.y0+(2/16.0);
				self.ys=0;
				self.xs=0;
				self.alpha=0;
				@resting=250;
				@dead=false;
				self.frame=$darkness*10;
				end
			end
			return	
		end
		case $darkness
			when 0..1 then
				self.xs=(self.xs<=>0)/16.0;
			when 2 then
				self.xs=(self.xs<=>0)/24.0;
			when 3 then
				self.x-=self.xs;
			when 4..7 then
				self.xs=(self.xs<=>0)*(($darkness-3)/32.0);
			
		end
		if    (self.xs>0 && (self.isObstructed(1,self.xs,0,-2) || !self.isObstructed(1,self.xs,0.25,0))) 
		self.xs=-self.xs; 
		elsif (self.xs<0 && (self.isObstructed(3,self.xs,0,-2) || !self.isObstructed(3,self.xs,0.25,0)))
		self.xs=-self.xs;
		end
		self.ys=self.isObstructed(2,1.0/16,self.ys,-2)?0:(2.0/16.0);
		self.frame = (self.xs>0?@fr:@fl)+((self.counter/@ft)%@fn)+($darkness*10);
	end
	def collision(e)
		return if (@resting>0 || @wait>0);
		return if (@dead);
		if (e==$player) then
			if ((e.ys>0 || e.geddon>0) && e.y<self.y) then
				e.geddon=4;
				if ($darkness>4) then
					playSFX(8);
					if ($darkness==7) then
						for i in 1..4
							self.map.spawnEntity(BlackSplosion,"",x+0.5,y+0.5,(random(100)-50)*0.01,(random(100)-50)*0.01).parent=self;
						end
						@wait=4;
						self.frame=(self.xs>0?1:0)+8+($darkness*10);
					else					
						for i in 1..8
							self.map.spawnEntity(BloodSplosion,"",x+0.5,y+0.5,(random(100)-50)*0.01,(random(100)-50)*0.01);
						end
						if ($goombarevive) then
							self.x=self.x0;
							self.y=self.y0+(2/16.0);
							self.ys=0;
							self.xs=0;
							@resting=250;
						else
							self.destroy();
						end
					end
				else
					log("goombadead");
					playSFX(7);
					@dead=true;
					self.frame=(self.xs>0?9:8)+$darkness*10;
					self.xs=0;
				end
				$score+=100+100*$darkness;
				e.ys=-7.5/16.0;
				return;
			else
				$player.die();
			end
		end
	end
end

class Stony < Goomba
	def daemon()
		if    (self.xs>0 && (self.isObstructed(1,self.xs,0,-2) || !self.isObstructed(1,self.xs,0.25,0))) 
		self.xs=-self.xs; 
		elsif (self.xs<0 && (self.isObstructed(3,self.xs,0,-2) || !self.isObstructed(3,self.xs,0.25,0)))
		self.xs=-self.xs;
		end
		self.ys=self.isObstructed(2,1.0/16,self.ys,-2)?0:(2.0/16.0);
		self.x-=self.xs if ($darkness<6)
		if ($darkness>4) then
		self.frame = (self.xs>0?@fr:@fl)+((self.counter/@ft)%@fn)+(($darkness-4)*10);
		else
		self.frame=0;
		end
	end
	def collision(e)
		return if ($darkness<6);

		if (e==$player) then
			if ((e.ys>0 || e.geddon>0) && e.y<self.y) then
				e.geddon=4;
				e.ys=-7.5/16.0;
				playSFX(7);
				self.pause=20;
			else
				$player.die();
			end
		end

	end
end

class DeathCloud < Entity
	def startup()
#		self.ys=+1.0/16;
		@spatters=0
	end
	def daemon()
		self.x+=($player.x-self.x-15)/32.0 if ($player.x>self.x+15);
		if ($darkness!=3) then
			$map.fnar=nil;
			self.destroy();
		end;
		$player.die() if ($player.x<self.x);
		self.y=$cameray;
		if (@spatters<150) then
			@spatters+=1
			self.map.spawnEntity(DarkWallSpatter,"tiles_big.cha",self.x+random(96)/16.0,self.y+random(15*16)/16.0,0,0).parent=self;
		end
#		if (self.counter>50 && @spatters<100) then
#			@spatters+=1
#			self.map.spawnEntity(DarkWallSpatter,"tiles_big.cha",self.x+random(96)/16.0,self.y+random(15*16)/16.0,0,0).parent=self
#		end
#		if (self.counter>100 && @spatters<150) then
#			@spatters+=1
#			self.map.spawnEntity(DarkWallSpatter,"tiles_big.cha",self.x+random(96)/16.0,self.y+random(15*16)/16.0,0,0).parent=self
#		end
	end
end

class DoomCloud < Entity
	def startup()
		@spatters=0
		if ($midpoint) then
			self.x=$midpoint_x.to_i-11;
			self.y=($midpoint_y/20).to_i*20;
		end
	end
	def daemon()
		self.x=0 if ($darkness==3 && self.y==80)
		
		if (self.x==0 and $darkness!=3) then
			self.x=30-11 if ($player.x>30-11);
			self.x=$midpoint_x.to_i-11 if ($player.x>$midpoint_x-11);
		end
		
		$player.die() if ($player.x<self.x);
		self.y=$cameray;
		if (@spatters<150) then
			@spatters+=1
			self.map.spawnEntity(DoomWallSpatter,"tiles_big.cha",self.x-2+random(64)/16.0,self.y+random(15*16)/16.0,0,0).parent=self;
		end
	end
	def render(x,y)
		return true if (x<0);
		strokeColor(0,0,0);
		drawFilledRectangle(0,0,x,480);
		return true;
	end
end


class BloodCloud < Entity
	def startup()
#		self.ys=+0.75/16;
		@spatters=0
	end
	def daemon()
		self.x+=($player.x-self.x-15)/60.0 if ($player.x>self.x+15);
		if ($darkness!=6) then
			$map.fnar=nil;
			self.destroy();
		end;
		
		$player.die() if ($player.x<self.x);
		self.y=$cameray;
		
#		self.map.spawnEntity(RedWallSpatter,"tiles_big.cha",self.x+random(96)/16.0,self.y+random(15*16)/16.0,0,0);
#		self.map.spawnEntity(RedWallSpatter,"tiles_big.cha",self.x+random(96)/16.0,self.y+random(15*16)/16.0,0,0) if (self.counter>50);
#		self.map.spawnEntity(RedWallSpatter,"tiles_big.cha",self.x+random(96)/16.0,self.y+random(15*16)/16.0,0,0) if (self.counter>100);

		if (@spatters<150) then
			@spatters+=1
			self.map.spawnEntity(RedWallSpatter,"tiles_big.cha",self.x+random(96)/16.0,self.y+random(15*16)/16.0,0,0).parent=self;
		end
#		if (self.counter>50 && @spatters<60) then
#			@spatters+=1
#			self.map.spawnEntity(RedWallSpatter,"tiles_big.cha",self.x+random(96)/16.0,self.y+random(15*16)/16.0,0,0).parent=self 
#		end
		
		self.map.spawnEntity(SideClaw,"tclaw.cha",self.x-2,self.y+random(11)+0.25,0.02,0).behind(self) if (self.x>30 && self.counter%200==0);
	end
end

class BloodSplosion < Entity
	def daemon()
		self.destroy() if ($darkness<5);
		self.ys+=0.01;
		self.destroy() if (self.y>$cameray+20 || self.map.getObs(self.x.to_i, self.y.to_i)>0)
		self.map.spawnEntity(BloodSpatter,"tiles_big.cha",x,y,0,0);
	end
end

class BloodSpatter < Entity
	def daemon()
		self.destroy() if (self.counter>30)
	end
	def render(x, y)
		self.destroy() if ($darkness<5);
		strokeColor(255,0,0);
		drawFilledEllipse(x,y,(30-self.counter),(30-self.counter));
	end
end


class BlackSplosion < Entity
	attr_accessor :parent
	def daemon()
		if ($darkness<7) then
			@parent.wait-=1;
			self.destroy();
		end
		self.ys+=0.01 if (self.y<self.y0)
		self.ys-=0.01 if (self.y>self.y0)
		self.xs+=0.01 if (self.x<self.x0)
		self.xs-=0.01 if (self.x>self.x0)
		if (self.counter>50)  then
		self.x=self.x*(1-self.counter*0.0002)+self.x0*(self.counter*0.0002);
		self.y=self.y*(1-self.counter*0.0002)+self.y0*(self.counter*0.0002);
		end
		
		if ((self.x-self.x0)>-0.5 && (self.x-self.x0)<0.5 && (self.y-self.y0)>-0.5 && (self.y-self.y0)<0.5 && self.counter>50) then
			@parent.wait-=1;
			self.destroy();
		end
		self.map.spawnEntity(BlackSpatter,"tiles_big.cha",x,y,0,0);
	end
end

class BlackSpatter < Entity
	def daemon()
		self.destroy() if (self.counter>30)
	end
	def render(x, y)
		if ($darkness<7) then
			self.destroy();
		end
		strokeColor(0,0,0);
		drawFilledEllipse(x,y,(30-self.counter)/2,(30-self.counter)/2);
	end
end



class DarkWallSpatter < Entity
	attr_accessor :parent
	def daemon()
#		self.destroy() if (self.counter>100)
		self.destroy() if ($darkness!=3);
		if (self.counter>100) then
			self.x=@parent.x+random(96)/16.0;
			self.y=@parent.y+random(15*16)/16.0;
			self.counter=0;
		end
	end
	def render(x, y)
		strokeColor(0,0,0);
		drawFilledEllipse(x,y,Math.sin((self.counter/100.0)*3.1415)*40,Math.sin((self.counter/100.0)*3.1415)*40);
	end
end

class DoomWallSpatter < Entity
	attr_accessor :parent
	def daemon()
#		self.destroy() if (self.counter>100)
		if (self.counter>100) then
			self.x=@parent.x-2+random(64)/16.0;
			self.y=@parent.y+random(15*16)/16.0;
			self.counter=0;
		end
	end
	def render(x, y)
		strokeColor(0,0,0);
		drawFilledEllipse(x,y,Math.sin((self.counter/100.0)*3.1415)*40,Math.sin((self.counter/100.0)*3.1415)*40);
	end
end


class RedWallSpatter < Entity
	attr_accessor :parent
	def startup()
		@color=192+random(64);
	end
	def daemon()
#		self.destroy() if (self.counter>100)
		self.destroy() if ($darkness!=6);
		if (self.counter>100) then
			@color=192+random(64);
			self.x=@parent.x+random(96)/16.0;
			self.y=@parent.y+random(15*16)/16.0;
			self.counter=0;
		end
	end
	def render(x, y)
		strokeColor(@color,0,0);
		drawFilledEllipse(x,y,Math.sin((self.counter/100.0)*3.1415)*40,Math.sin((self.counter/100.0)*3.1415)*40);
	end
end

class SideClaw < Entity
	def startup()
		self.xs=4.0/16;
		self.everywhere=1;
	end
	def daemon()
		self.frame=(self.counter/3)%4;
		self.destroy() if ($darkness!=6);
		self.destroy() if (self.x>$player.x+20);
	end
	def collision(e)
		e.die() if (e==$player);
	end
end

class Claw < Entity
	def startup()
		self.y=self.y0+2.75;
		self.x=self.x0+0.25;
	end
	def daemon()
		return if ((self.y/20).to_i*20 != $cameray);
	
		 if ($player.x+$player.w>self.x-1.5 && $player.x<self.x+3) then
		 	playSFX(3) if ($darkness>=4 && self.y==self.y0+2.75);
		 	self.ys=-1;
		 else
		 	self.ys=0.5;
		 end
		 #self.ys=self.y-(self.y0-7.75) if (self.ys<self.y-(self.y0-7.75));
		 if ($darkness<4) then
			self.y=self.y0+2.75;
		 	self.ys=0;
		 end
		if (self.y+self.ys<=self.y0-7.5) then
			self.y=self.y0-7.75;
			self.ys=0 if (self.ys<0);
		end
		if (self.y+self.ys>=self.y0+2.75) then
			self.y=self.y0+2.75;
			self.ys=0 if (self.ys>0);
		end
	end
	def collision(e)
		e.die() if (e==$player) # && $player.x+$player.w>self.x+(2/16.0) && $player.x<self.x+self.w-(2/16.0)&&$player.y+$player.h>self.y+(2/16.0));
	end
end

class WhatClaw < Entity
	def startup()
		self.y=self.y0+2.75;
		self.x=self.x0+0.25;
	end
	def daemon()
		return if ((self.y/20).to_i*20 != $cameray) ;

		 if ($player.x+$player.w>self.x-1.5 && $player.x<self.x+3) then
		 	playSFX(3) if (self.y==self.y0+2.75);
		 	self.ys=-1;
		 else
		 	self.ys=0.5;
		 end
		 #self.ys=self.y-(self.y0-7.75) if (self.ys<self.y-(self.y0-7.75));
		if (self.y<=self.y0-7.5) then
			self.y=self.y0-7.75;
			self.ys=0 if (self.ys<0);
		end
		if (self.y>=self.y0+2.75) then
			self.y=self.y0+2.75;
			self.ys=0 if (self.ys>0);
		end
	end
	def collision(e)
		e.die() if (e==$player) # && $player.x+$player.w>self.x+(2/16.0) && $player.x<self.x+self.w-(2/16.0)&&$player.y+$player.h>self.y+(2/16.0));
	end
end

class DislocatePoint < Entity
	def daemon()
		if ($player.x.to_i==self.x.to_i && self.x.to_i>$limitx) then
			$player.y=$player.y-($player.y/20).to_i*20+(7-$darkness)*20;
			y=$cameray;
			$cameray=(7-$darkness)*20;
			
			$limitx=self.x.to_i+1;

			$midpoint=true;
			$midpoint_x=$player.x.to_i;
			$midpoint_y=$player.y.to_i;
			$midpoint_d=$darkness;
			$midpoint_t=self.map.counter;
			
			$cloud.x=$player.x.to_i-11;
			$cloud.y=$cameray;
		end
	end
end

class WrapPoint < Entity
	def daemon()
		if ($player.x>self.x && $darkness>0) then
			$player.x=$player.x+30-self.x;
			$player.y=$player.y-($player.y/20).to_i*20+(7-$darkness)*20;
			$cameray=(7-$darkness)*20;
			

			$midpoint=true;
			$limitx=0;
			$midpoint_x=$player.x.to_i;
			$midpoint_y=$player.y.to_i;
			$midpoint_d=$darkness;
			$midpoint_t=self.map.counter;

			$cloud.x=$player.x.to_i-11;
			$cloud.y=$cameray;
		end
	end
end

class MidPoint < Entity
	def daemon()
		if ($player.x.to_i==self.x.to_i) then
		$midpoint=true;
		$midpoint_x=self.x.to_i;
		$midpoint_y=self.y.to_i;
		$midpoint_d=$darkness;
		$midpoint_t=self.map.counter;
		end
	end
end

class SecretItem < Entity
	def startup()
		self.destroy() if (!$mapno || $gemarray[0][4][$mapno-1]==1);
		@visible=0;
	end
	def daemon()
		@visible+=1 if (@visible>0 && @visible<100);
		@visible=100 if (@visible>100);
	end
	
	def collision(e)
		@visible+=1 if (@visible==0)
		if (@visible>=100) then
		
		self.destroy();
		$flash=255;
		playSFX(8);
		$gemarray[0][4][$mapno-1]=1;
		
		steamAddAchievement("SECRET_8") if ($gemarray[0][4]==[1,1,1,1,1,1,1,1]);
		end;
	end

	def render(x, y)
		return true if (@visible==0);
		@visible=100 if (@visible>100);
		f=$font_white;
		f=$font if (self.map.counter%2>0)
		k=(100-@visible)*2;
		if (k>0) then
		x+=random(k)-k/2;
		y+=random(k)-k/2;
		end
		writeText(f,x+16,y+8,["","E","V","E","R","S","I","O","N"][$mapno],1);
		return true;
	end
end