freeslot(
"S_PLAY_LDSH", "S_PLAY_LDSH2", "sfx_djmpdv", "sfx_stmpdv", "sfx_ftheat", "sfx_kart", "sfx_kartgo")

states[S_PLAY_LDSH] = {SPR_PLAY, SPR2_FRUN|FF_ANIMATE|FF_SPR2MIDSTART, 1, A_HomingChase, 50*FRACUNIT, 0, S_PLAY_LDSH2}
states[S_PLAY_LDSH2] = {SPR_PLAY, SPR2_FRUN|FF_ANIMATE|FF_SPR2MIDSTART, 2, A_GhostMe, 0, 0, S_PLAY_FALL}

COM_AddCommand("supercar", function(player)
	if player.supercar == false
		player.supercar = true
		CONS_Printf(player, "Greeneyes will now drive a car. Air dash has been nerfed")
	elseif player.supercar == true
		player.supercar = false
		CONS_Printf(player, "Greeneyes will no longer drive a car. Air dash has been restored")
	end
end, 0)

addHook("ThinkFrame", do
	for player in players.iterate
		
		if player.lightdash == nil
			player.lightdash = 0
		end
		if player.tossflagdown == nil
			player.tossflagdown = 1
		end
		if player.prevrings == nil
			player.prevrings = 1
		end
		if player.prevscore == nil
			player.prevscore = 1
		end
		if player.notboostmeter == nil
			player.notboostmeter = 1
		end
		if player.heatready == nil
			player.heatready = 1
		end
		if player.notboostmeter > 40
			player.notboostmeter = 40
		end
		if player.feelingheat == nil
			player.feelingheat = 0
		end
		if player.heatadvance == nil
			player.heatadvance = 0
		end
		if player.supercar == nil
			player.supercar = false
		end
		if player.drivingsupercar == nil
			player.drivingsupercar = 0
		end

		if player.mo and player.mo.skin == "greeneyesonic"
		and player.powers[pw_carry] != CR_NIGHTSMODE
		and (player.playerstate == PST_LIVE)
		//Momentum Homing	
			if player.mo.state == S_PLAY_SPRING
			and (player.pflags & PF_JUMPED)
			and (player.pflags & PF_JUMPDOWN)
			and not (player.mo.eflags & MFE_SPRUNG)
				P_Thrust(player.mo, player.mo.angle, player.speed)
				P_SetObjectMomZ(player.mo, 10*FRACUNIT, false)
				player.mo.state = S_PLAY_JUMP
			elseif player.mo.state == S_PLAY_SPRING
			and (player.pflags & PF_JUMPED)
			and not (player.pflags & PF_JUMPDOWN)
			end
			
			if (player.pflags & PF_THOKKED)
			and player.mo.state == S_PLAY_JUMP
				player.mo.state = S_PLAY_ROLL
			end
		//Heat mode stuff	
			if player.feelingheat == 1
				P_SpawnGhostMobj(player.mo)
				player.normalspeed = 60*FRACUNIT
				player.actionspd = 150*FRACUNIT
				player.acceleration = 55
				player.accelstart = 125
				player.heatadvance = $1+1
				if player.heatadvance >= 7
				and player.notboostmeter >= 0
					player.notboostmeter = $1 - 1
					player.heatadvance = 0
				end
			end
			
			if player.feelingheat == 0
				if player.normalspeed == 60*FRACUNIT then player.normalspeed = 36*FRACUNIT end
				if player.actionspd == 150*FRACUNIT then player.actionspd = 75*FRACUNIT end
				if player.acceleration == 55 then player.acceleration = 40 end
				if player.accelstart == 125 then player.accelstart = 96 end
			end
			
			if player.notboostmeter == 0
				player.feelingheat = 0
			end
		//SuperCar	
			if (player.supercar == true)
				player.charflags = $ | SF_DASHMODE
				if player.carexplodetimer == nil
					player.carexplodetimer = 0
				end
				if player.dashmode > 3*TICRATE
					
					if player.drivingsupercar == 0
						S_StartSound(player.mo, sfx_kartgo)
					end
					player.drivingsupercar = 1
					player.charflags = $ | SF_MACHINE
					player.mo.state = S_PLAY_DASH
					if P_IsObjectOnGround(player.mo)
						P_SpawnSkidDust(player, player.mo.radius)
						S_StartSound(player.mo, sfx_kart)
					end
					
					player.nomoredashmodeflash = P_SpawnGhostMobj(player.mo)
					player.nomoredashmodeflash.fuse = 1
					player.nomoredashmodeflash.frame = player.mo.frame
				end
				
				if player.dashmode < 3*TICRATE
				and player.drivingsupercar == 1
					player.carexplosion = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_THOK)
					player.carexplosion.fuse = 35
					player.carexplosion.state = S_INVISIBLE
					player.carexplodetimer = 35
					player.charflags = $ & ~SF_MACHINE
					player.drivingsupercar = 0
				end
				if player.carexplodetimer > 0
				and player.carexplosion.valid
					player.carexplodetimer = $ - 1
					A_BossScream(player.carexplosion, 2, MT_SONIC3KBOSSEXPLODE)
					S_StartSound(player.carexplosion, sfx_s244)
				end
			elseif (player.supercar == false)
				player.charflags = $ & ~SF_DASHMODE
			end
		
			if player.powers[pw_super]
				player.notboostmeter = 40
			end
		//Double jump
			if (player.cmd.buttons & BT_CUSTOM1)
			and (player.pflags & PF_JUMPED)
			and not player.powers[pw_carry]
			and not (player.pflags & PF_STASIS)
			and not (player.pflags & PF_JUMPSTASIS)
			and not (player.pflags & PF_STARTJUMP)
			and not (player.mo.tracer and player.mo.tracer.type == MT_TUBEWAYPOINT)
			and not P_IsObjectOnGround(player.mo)
			and not (player.pflags & PF_THOKKED)
			and not  player.lightdash
				P_SetObjectMomZ(player.mo, FRACUNIT*10, false)
				player.pflags = $1|PF_THOKKED
				S_StartSound(player.mo, sfx_djmpdv)
				P_SpawnGhostMobj(player.mo)
				if player.feelingheat == 1
					P_SetObjectMomZ(player.mo, FRACUNIT*20, false)
				end
			end
			if (player.wasjuststomping == nil) then
				player.wasjuststomping = false
			end
			
			if player.prevrings < player.rings
				player.notboostmeter = $1 + (player.rings - player.prevrings)
			end
			if player.prevscore < player.score
				player.notboostmeter = $1 + (player.score - player.prevscore)/100
			end
			
			if player.notboostmeter == 40
			and player.heatready == 0
				S_StartSound(player.mo, sfx_ftheat)
				player.heatready = 1
			elseif player.notboostmeter == 40
			and player.heatready == 1
			end
			
			if player.notboostmeter < 40
				player.heatready = 0
			end
			
			if player.exiting
				player.feelingheat = 0
			end
			
			if (player.cmd.buttons & BT_CUSTOM3)
			and player.feelingheat != 1
			and player.notboostmeter == 40
			and not player.powers[pw_carry]
			and not player.powers[pw_carry]
			and not (player.pflags & PF_STASIS)
			and not (player.pflags & PF_JUMPSTASIS)
			and not (player.pflags & PF_FINISHED)
			and not (player.mo.tracer and player.mo.tracer.type == MT_TUBEWAYPOINT)
				player.feelingheat = 1
				S_StartSound(player.mo, sfx_thok)
			end
		//Speed Stomp
			if (player.cmd.buttons & BT_CUSTOM2)
			and not player.powers[pw_carry]
			and not (player.pflags & PF_STASIS)
			and not (player.pflags & PF_JUMPSTASIS)
			and not (player.pflags & PF_STARTJUMP)
			and not (player.mo.eflags & MFE_GOOWATER)
			and not (player.mo.tracer and player.mo.tracer.type == MT_TUBEWAYPOINT)
			and not P_IsObjectOnGround(player.mo)
			and not (player.mo.state == player.mo.info.painstate)
				P_SetObjectMomZ(player.mo, FRACUNIT*-12, true)
				player.pflags = $1|PF_JUMPED
				P_SpawnGhostMobj(player.mo)
				if (player.wasjuststomping == false) then
					S_StartSound(player.mo, sfx_stmpdv)
				end
				player.wasjuststomping = true
			else 
				player.wasjuststomping = false
			end
		//Uncurl
			if not player.powers[pw_carry]
			and (player.cmd.buttons & BT_USE)
			and (player.pflags & PF_USEDOWN)
			and not (player.mo.state == S_PLAY_PAIN)
			and not (player.mo.tracer and player.mo.tracer.type == MT_TUBEWAYPOINT)
			and not (player.pflags & PF_STASIS)
			and (player.pflags & PF_SPINNING)
			and not (player.pflags & PF_STARTDASH)
			and player.spinningtime > 1
			and (P_IsObjectOnGround(player.mo)) then
				player.mo.state = S_PLAY_MELEE
				player.pflags = $1 & ~PF_SPINNING
			end
			
			if player.mo.state == S_PLAY_MELEE
				player.mo.tics = 1
			end
			if player.mo.state == S_PLAY_MELEE_FINISH
				player.mo.state = S_PLAY_WALK
			end
			
			if (player.pflags & PF_SPINNING) and not (player.pflags & PF_USEDOWN) then
				player.spinningtime = $+1
			else
				player.spinningtime = 0
			end
		//Lightspeed Dash
			if (((player.cmd.buttons & BT_TOSSFLAG) and not player.tossflagdown) or player.lightdash > 0)
			and not player.powers[pw_carry]
			and not (player.pflags & PF_STASIS)
			and not (player.pflags & PF_JUMPSTASIS)
			and not (player.pflags & PF_SPINNING)
			and not (player.powers[pw_shield] == SH_ATTRACT)
			and not (player.mo.state == player.mo.info.painstate)
				A_FindTarget (player.mo, MT_RING, 0)
				if player.mo.target
				and player.mo.target.type == MT_RING
					A_CheckTrueRange (player.mo, 160, S_PLAY_LDSH)
				end
				
				if player.mo.state >= S_PLAY_LDSH and player.mo.state <= S_PLAY_LDSH2
					//player.mo.angle = R_PointToAngle2(player.mo.x, player.mo.y, player.mo.target.x, player.mo.target.y)
					player.drawangle = R_PointToAngle2(player.mo.x, player.mo.y, player.mo.target.x, player.mo.target.y)
					player.lightdash = 5
				end
			else
				player.lightdash = 0
			end
		end
		
		if (player.cmd.buttons & BT_TOSSFLAG)
		or (P_IsObjectOnGround(player.mo) and (player.cmd.buttons & BT_CUSTOM1))
			player.tossflagdown = true
		else
			player.tossflagdown = false
		end
		
		if (player.lightdash > 0)
			player.lightdash = $1 - 1
		end
		
		if player.mo.state == S_PLAY_LDSH
		or player.mo.state == S_PLAY_LDSH2
		and not (player.pflags & PF_JUMPED)
			player.pflags = $ | PF_JUMPED
		end
		
		player.prevrings = player.rings
		player.prevscore = player.score
	end
end)

addHook("MapLoad", do
	for player in players.iterate
		if player.mo and player.mo.skin == "greeneyesonic"
			player.lightdash = 0
			player.tossflagdown = 0
			player.prevrings = 0
			player.notboostmeter = 0
			player.heatready = 0
			player.feelingheat = 0
			player.heatadvance = 0
			player.drivingsupercar = 0
		end
	end
end)

addHook("PlayerSpawn", function(player)
	if not netgame return end
	if player.mo and player.mo.skin == "greeneyesonic"
		player.lightdash = 0
		player.tossflagdown = 0
		player.prevrings = 0
		player.notboostmeter = 0
		player.heatready = 0
		player.feelingheat = 0
		player.heatadvance = 0
		player.drivingsupercar = 0
	end
end)

//quickstep from Modern Abilities for 2.1, by MotdSpork
freeslot("sfx_sonicd")
addHook("ThinkFrame", do
	for player in players.iterate
		if player.mo
			if player.pflags & PF_JUMPED
				player.pflags = $1 & ~PF_SPINNING
			end
			if not (player.mo.sidestepping)
				player.mo.sidestepping = 0
			end
			if not (player.mo.sidetimer)
				player.mo.sidetimer = 0
			end
			if not (player.mo.sidestep)
				player.mo.sidestep = 0
			end
			if not (player.mo.prevspeed)
				player.mo.prevspeed = 0
			end
			if player.mo.sidestepping == 0
				player.prevspeed = player.speed
			end
			if (player.mo and player.mo.skin == "greeneyesonic")				
				if P_IsObjectOnGround(player.mo)
				and player.mo and player.mo.valid //and player.health
				//and player.cmd.sidemove < 0
				and player.mo.sidestepping == 0
				and player.cmd.buttons & BT_ATTACK
					if not (player.mo.eflags & MFE_UNDERWATER)
						P_InstaThrust(player.mo, player.mo.angle + ANGLE_90, (FixedMul(64*FRACUNIT, player.mo.scale)+5*FRACUNIT)+cos(player.aiming))
					else
						P_InstaThrust(player.mo, player.mo.angle + ANGLE_90, (FixedMul(28*FRACUNIT, player.mo.scale)+5*FRACUNIT)+cos(player.aiming))
					end
					S_StartSound(player.mo, sfx_sonicd)
					player.mo.sidestepping = 1
					player.mo.sidetimer = 2
					player.mo.sidestep = 1
				else
					if P_IsObjectOnGround(player.mo)
					and player.mo and player.mo.valid //and player.health
					//and player.cmd.sidemove > 0
					and player.mo.sidestepping == 0
					and player.cmd.buttons & BT_FIRENORMAL
						if not (player.mo.eflags & MFE_UNDERWATER)
							P_InstaThrust(player.mo, player.mo.angle - ANGLE_90, (FixedMul(64*FRACUNIT, player.mo.scale)+5*FRACUNIT)+cos(player.aiming))
						else
							P_InstaThrust(player.mo, player.mo.angle - ANGLE_90,  (FixedMul(28*FRACUNIT, player.mo.scale)+5*FRACUNIT)+cos(player.aiming))
						end
						S_StartSound(player.mo, sfx_sonicd)
						player.mo.sidestepping = 1
						player.mo.sidetimer = 2
						player.mo.sidestep = 1
					end
					if not (player.cmd.buttons & BT_ATTACK)
					and not (player.cmd.buttons & BT_FIRENORMAL)
					and player.mo.sidestepping == 1
						player.mo.sidestepping = 0
					end
					if player.mo.sidestep == 1
					and player.mo.sidetimer == 0
						player.mo.sidestep = 0
						P_InstaThrust(player.mo, player.mo.angle - ANGLE_90, (FixedMul(0*FRACUNIT, player.mo.scale)+0*FRACUNIT)+cos(player.aiming))
						P_InstaThrust(player.mo, player.mo.angle + ANGLE_90, (FixedMul(0*FRACUNIT, player.mo.scale)+0*FRACUNIT)+cos(player.aiming))
						P_InstaThrust(player.mo, player.mo.angle, player.prevspeed)
						if player.prevspeed <= 1*FRACUNIT
							player.mo.state = S_PLAY_STND
						end
					end	
				end
				if player.mo.sidetimer > 0
					P_SpawnGhostMobj(player.mo)
					player.mo.sidetimer = $1 - 1
				end
			end
		end
	end
end)

//Music
addHook("MusicChange", function(oldname, newname)
	if consoleplayer
		local character = skins[consoleplayer.skin].name
		if character == "greeneyesonic"
			if newname == "_super"
				return "GSUPER"
			elseif newname == "_inv"
				return "GINV"
			elseif newname == "_shoes"
				return "GSHOES"
			end
		end
	end
end)