//freeslots, get your freeslots here!
	freeslot("sfx_rev1", "sfx_rev2", "sfx_rev3", "sfx_rev4", "sfx_rev5", "sfx_rev6", "sfx_rev7")
//fix amy's hammer jump disallowing her display angle changing
//make eggman always use his running frames
sfxinfo[sfx_rev1].caption = "Spincharge 2"
sfxinfo[sfx_rev2].caption = "Spincharge 3"
sfxinfo[sfx_rev3].caption = "Spincharge 4"
sfxinfo[sfx_rev4].caption = "Spincharge 5"
sfxinfo[sfx_rev5].caption = "Spincharge 6"
sfxinfo[sfx_rev6].caption = "Spincharge 7"
sfxinfo[sfx_rev7].caption = "Spincharge Max"


local function classic_SpindashAssist(player,arg)
	if player.mo and player.mo.valid
		local arg1 = player.SpindashAssist and "on" or "off" //thank you goldentails for making this work.
		if arg == nil
			CONS_Printf(player, "\"spindashassist\" is \""+arg1+"\" default is \"on\"")
		elseif (arg == "1" or arg == "on")
			player.SpindashAssist = true
		elseif (arg == "0" or arg == "off")
			player.SpindashAssist = false
		else
			CONS_Printf(player, "\""+arg+"\" is not a possible value for \"spindashassist\"")
		end	
	else
		CONS_Printf(player, "You must be in a level to use this.")
	end
end

COM_AddCommand("SpindashAssist",classic_SpindashAssist)

//Main Configuration for everyone
addHook("ThinkFrame", do
    for player in players.iterate
		if player.mo and player.mo.valid
	
	
	//setting up variables
			local testing = false
		//setting up prevz
			if player.mo.prevz == nil
				player.mo.prevz = 0
			end
		
			if player.mo.prevmomx == nil
				player.mo.prevmomx = 0
			end
		
			if player.mo.prevmomy == nil
				player.mo.prevmomy = 0
			end
		//setting up a prevnormspd because I can't think of another way to incriment the speed
			if player.prevnormspd == nil
				player.prevnormspd = 0
			end
		
		//setting up player.isclassic to boost compatibility with other wads
			if player.isclassic == nil
				player.isclassic = true
			end
		
		//setting up the player.hasmomentum and classic animations for greater compatibility
			if player.hasmomentum == nil
				player.hasmomentum = true
			elseif not (player.isclassic)
				player.hasmomentum = false
			end
		
	//Classic animations: This was split into its own seperate things but this disables all of them
			if player.classicanimations == nil
				player.classicanimations = false
			elseif not (player.isclassic)
				player.classicanimations = false
			end
	
		//specialspindash: If set to true, the player will no longer use the new spindash animations
			if player.specialspindash == nil
				player.specialspindash = false
			elseif not (player.classicanimations)
				player.specialspindash = true
			end
			
		//nowalkspring: disables the walking animation and gives back the old falling frames, good for if your character needs to be in falling frames to avoid conflict.
			if player.nowalkspring == nil
				player.nowalkspring = true
			elseif not (player.classicanimations)
				player.nowalkspring = true
			end
			
		//nocharge: disables the new spindash behavior, for if you have a character like silver that needs to do his own thing while still using PF_STARTDASH
			if player.nocharge == nil
				player.nocharge = false
			elseif not (player.isclassic)
				player.nocharge = true
			end
		//nospinfix: this disables the new spin-when-you-hit-the-ground fix, in case you need to stop the player from spinning when landing.
			if player.nospinfix == nil
				player.nospinfix = false 
			end //This is the only one to not get turned off by "not player.classic"
			
		//SpindashAssist: enables and disables the spindash assistance feature. defaults to on
			if player.SpindashAssist == nil
				player.SpindashAssist = true
			end
	
		
		//setting up the check for our real speed
			player.rspeed = R_PointToDist2(0, 0, player.rmomx, player.rmomy)
			//print(player.rspeed/FRACUNIT, "speed", "", "")
	
		//setting up a check for conveyor speed
			player.conveyorspeed = R_PointToDist2(0, 0, player.cmomx, player.cmomy)
			//print(player.conveyorspeed/FRACUNIT, "CSPEED","","")
		
		//setting up stats for everyone to have
			if (player.mo.skin == "sonic")
			and player.charability == CA_THOK
				player.charability = CA_NONE
			end
			if not (player.mo.skin == "nasya")
				player.topspeed = 36*FRACUNIT
				player.maxspeed = 120*FRACUNIT //Because we can't just have Sonic zooming at an out-of-control speed	
				player.accelstart = 96
				player.acceleration = 40
				if (player.powers[pw_super])
					player.thrustfactor = 7
				elseif (player.powers[pw_sneakers])
					player.thrustfactor = 6
				else
					player.thrustfactor = 5
				end
				
				if player.spinitem == MT_THOK //unless you have a unique spintrail, you don't really need one
					player.spinitem = 0
				end
				
				if player.revitem == MT_THOK //same with rev item, which may or may not be used for certain characters in unique ways
					player.revitem = 0
				end
			end
		
			/*		~TO DO~
			//Make an options screen to make certain aspects of this WAD togglable, akin to the level select in the Sonic 1/2 mobile ports.
			//Add abilities from other classic games for Sonic such as the Insta-Shield, My version of the Drop Dash script, the Super PeelOut (needs running animations) and possibly with Saph's permission, normal shields replaced with elemental shields.
			//Add support for Axis2D.
			//Possibly add in the air drag mechanic.
			//Possibly nerf slope acceleration in later versions when slopes become more widely used (I.E. closer to 2.2's release).
			*/
			if not (player.mo.skin == "peach") //If you're not the exception, you're the rule
			and not (player.mo.skin == "robo-hood")
			and not (player.mo.skin == "toad")
			and not (player.mo.skin == "samus")
			and not (player.mo.skin == "marisa")
			and not (player.mo.skin == "alice")
			and not (player.mo.skin == "sonicrefancy")
			and not (player.mo.skin == "modernsonic")
			and not (player.mo.skin == "sonicre")
			and not (player.mo.skin == "tailsre")
			and not (player.mo.skin == "knuxre")
			and not (player.mo.skin == "kirby")
			and not (player.mo.skin == "brakeggman")
			and not (player.mo.skin == "tailsguy")
			and not (player.mo.skin == "flicky")
			and not (player.mo.skin == "earless") //our "earless" leader
			and not (player.mo.skin == "handdrawn")//here's old sonic, you're living in the past if you really need a thok
			and not (player.mo.skin == "ssntails") //for if you want to play as crappy tails for some reason, i thought the buffs i gave were pretty good
			and not (player.mo.skin == "uglyknux") //if you want to play with that classic knuckles experience.
			and not (player.isclassic == false)
		
		//Here's our base values for everyone, hopefully this is closer to Sonic 2/3's stats
		//KNOWN BUG: Running down ramp sectors will cause them to act like slopes
		//KNOWN BUG: Running on ice when changing sectors will sometimes cause the player to accelerate into infinity.
		//This also happens when running down slopes in Axis2D, I'll have to look at Axis2D's source code to figure out why this happens.
			//Breaking the vanilla speed cap
				if testing == true
					print((player.normalspeed)/FRACUNIT, "","","")
				end
				if player.rspeed > player.topspeed //If the player is running faster than they can normally
				and player.rspeed < player.maxspeed
				and (player.hasmomentum)
				and not (player.isclassic == false)
				and not (player.mo.skin == "dirk" and player.cmd.buttons & BT_USE)
				and not (player.mo.skin == "silver") //moved cuz i don't want to manually write out new stats for silver
				and not (player.mo.skin == "fang") //can we start a fang gang? i kinda wanna start a fang gang
					if not (player.powers[pw_sneakers])
					and not (player.powers[pw_super])
						if player.rspeed > player.normalspeed //If the player is going faster than their normalspeed
						and player.rspeed >= (player.normalspeed - player.rspeed)/13
						and P_IsObjectOnGround(player.mo) //and the player is on the ground
							if (player.normalspeed - player.rspeed)/13 <= 0
								player.normalspeed = player.rspeed + 3*FRACUNIT
							else
								player.normalspeed = $1 + (player.normalspeed - player.rspeed)/9
							end
						elseif player.rspeed < (player.normalspeed) - 6*FRACUNIT
							player.normalspeed = $1 - 2*FRACUNIT
						end
					elseif player.rspeed > player.topspeed*2
						if player.rspeed > player.normalspeed*2 //If the player is going faster than what their normalspeed would be
						and player.rspeed >= (player.normalspeed*2) - (3*FRACUNIT)
						and P_IsObjectOnGround(player.mo) //and the player is on the ground
							player.normalspeed = $1 + ((player.rspeed - player.topspeed)) + (4*FRACUNIT)
						elseif player.rspeed < (player.normalspeed*2) - 6*FRACUNIT
							player.normalspeed = $1 - 2*FRACUNIT
						end
					end
				elseif not (player.dashmode)
					player.normalspeed = player.topspeed
				end
			//Adding slope acceleration to play better with the new speed cap
				if player.mo.prevz*P_MobjFlip(player.mo) > player.mo.z*P_MobjFlip(player.mo) //if the player is going downhill
				and P_IsObjectOnGround(player.mo) //And the player is on the ground (kinda important)
				and player.rspeed < player.maxspeed //Don't accelerate if we're over max speed, this keeps control managable
				and (player.hasmomentum) //gives us support for other characters to utilize this
				and not (player.isclassic == false) //isclassic enables and disables the entire system
					if not (player.pflags & PF_SPINNING)
					and not (player.mo.state == S_PLAY_ROLL)
					and not (player.mo.skin == "silver")
						if player.dashmode >= 3*TICRATE
							player.normalspeed = $ + 2*FRACUNIT
						end
						player.normalspeed = player.prevnormspd + (((player.mo.prevz*P_MobjFlip(player.mo) - player.mo.z*P_MobjFlip(player.mo))*2)/(player.normalspeed/FRACUNIT)) //MOAR SPED
					else
						P_Thrust(player.mo, R_PointToAngle2(0, 0, player.rmomx, player.rmomy), player.rspeed/175)
					end
				end
			
				if (player.pflags & PF_SPINNING)
				and (player.mo.state == S_PLAY_ROLL)
				and P_IsObjectOnGround(player.mo)
					if player.pflags & PF_ANALOGMODE
					and not (player.pflags & PF_STARTDASH)
					and not (player.mo.tracer and player.mo.tracer.type == MT_TUBEWAYPOINT)
					and (player.rmomx != 0 or player.rmomy != 0)
						player.mo.angle = R_PointToAngle2(0, 0, player.rmomx, player.rmomy)
					end
				end
			
				player.mo.prevz = player.mo.z
				player.prevnormspd = player.normalspeed
				player.mo.prevmomx = player.mo.momx
				player.mo.prevmomy = player.mo.momy
			
			//Buffing glide acceleration
				if player.charability == CA_GLIDEANDCLIMB
					if not P_IsObjectOnGround(player.mo)
					and player.pflags & PF_THOKKED
						if player.rspeed <= player.maxspeed/2
							player.actionspd = $+((player.glidetime^2)/20)
						end
					else
						player.actionspd = skins[player.mo.skin].actionspd
					end
				end
			end
		end
	end
end)

//animation behaviors. all animation related tweaks go here
addHook("ThinkFrame", do
	for player in players.iterate
		if player.mo and player.mo.valid
			if player.mo.sprung == nil
			or (player.mo.eflags & MFE_JUSTHITFLOOR)
				player.mo.sprung = false
			end
			if (player.mo.eflags & MFE_SPRUNG)
				player.mo.sprung = true
			end
			
			
		//spring falling animation handler
			if (player.mo and player.mo.valid)
			and not (player.mo.skin == "handdrawn")//here's old sonic, you're living in the past if you really need a thok
			and not (player.mo.skin == "ssntails") //for if you want to play as crappy tails for some reason, i thought the buffs i gave were pretty good
			and not (player.mo.skin == "uglyknux") //if you want to play with that classic knuckles experience.
				if (player.mo.state == S_PLAY_FALL)
				and not (player.pflags & PF_JUMPED)
				and not (player.pflags & PF_THOKKED)
				and not player.boostmode
				and not (player.mo.skin == "pointy")
				and not (player.mo.skin == "dirk" and player.mo.standonice)
				and not (player.mo.skin == "blaze" and player.airboosted)
				and not (player.mo.skin == "fang") //fang gang rise up!
				and not (player.mo.skin == "modernsonic")
				and not (player.mo.skin == "msonic")
				and (player.classicanimations)
				and not (player.isclassic == false)
				and not (player.nowalkspring)
				and player.mo.sprung == true
					if player.rspeed < player.runspeed
						player.mo.state = S_PLAY_WALK
					else
						player.mo.state = S_PLAY_RUN
					end
				end
			end
			
		//eggman running animation handler
		//eggman's always outrun sonic on foot in the past he should be just fine without a jetpack
			if not (player.mo and player.mo.valid)
			or player.mo.skin ~= "eggman"
				return
			else
				if player.speed >= player.runspeed
				and player.mo.state == S_PLAY_RUN
					player.panim = $ & PA_WALK
				end
			end
		end
	end
end)


 //non-classic spindash behavior and other spin-related things
addHook("ThinkFrame", do
	for player in players.iterate
		if player.mo and player.mo.valid
		//Spindash prevention code, moved up here because I didn't want to have to rewrite the entire spindash code to accomodate it
			if ((leveltime < 4*TICRATE) and (gametype == GT_RACE or gametype == GT_COMPETITION) and P_IsObjectOnGround(player.mo)) //also because someone had the bright idea to make it so none of the buttons register durring the race countdown
				player.charability2 = CA2_NONE
				if player.weapondelay ~= nil
					player.weapondelay = 1
				end
			elseif (leveltime == (4*TICRATE)+1)
				player.charability2 = skins[player.mo.skin].ability2
				if player.weapondelay ~= nil
					player.weapondelay = 0
				end
			end
			
			if (player.mo.skin == "amy") //here we go again...
				if not (player.cmd.buttons & BT_CUSTOM1)
					player.mindash = 2*FRACUNIT
					player.maxdash = 6*FRACUNIT
				elseif player.mo.state == S_PLAY_RUN
				and (player.cmd.buttons & BT_CUSTOM1)
					if not (player.powers[pw_super])
						if player.rspeed <= 65*FRACUNIT
							player.mindash = (player.rspeed/4)+(player.rspeed/4)
						else
							player.mindash = ((player.rspeed/4)+(player.rspeed/4) + ((65*FRACUNIT) - (player.rspeed)))
						end
					else
						if player.rspeed <= 130*FRACUNIT
							player.mindash = (player.rspeed/4)+(player.rspeed/4)
						else
							player.mindash = ((player.rspeed/4)+(player.rspeed/4) + ((130*FRACUNIT) - (player.rspeed)))
						end
					end
					player.maxdash = 0
				end
			end
		//These checks do two things: 1. Re-enable player control when spinning in the air,
		//& 2. Keep the player from skimming on water when rolling.	
			if player.pflags & PF_SPINNING
			and not P_IsObjectOnGround(player.mo)
				if player.pflags & PF_JUMPED
					player.pflags = $1 & ~PF_SPINNING
				else
					player.pflags = $1 & ~PF_SPINNING
					player.pflags = $1 | PF_JUMPED
					player.pflags = $1 | PF_THOKKED
				end
			end
		end
	end
end)


//Fixing Spin-pressed-when-landing behavior
//KNOWN BUG: Spin SFX will play when the player lands even if they're in their standing animation
addHook("ThinkFrame", do
	for player in players.iterate
		if player.mo
		and player.charability2 == CA2_SPINDASH
		and not (player.mo.skin == "silver")
		and not (player.mo.skin == "amy")
		and not (player.mo.skin == "handdrawn") //You want your vanilla sonic back? have him
		and not (player.mo.skin == "ssntails") //for if you want to play as crappy tails for some reason, i thought the buffs i gave were pretty good
		and not (player.mo.skin == "uglyknux") //if you want to play with that classic knuckles experience.
		and not (player.mo.skin == "dirk") //Thank goodness I don't need *THAT* anymore
		and (player.cmd.buttons & BT_USE)
		and (player.mo.eflags & MFE_JUSTHITFLOOR)
		and player.mo.state != S_PLAY_DEAD
		and not (player.nospinfix)
		and not P_CheckDeathPitCollide(player.mo)
		and not player.mo.sprung
			player.pflags = $1 | PF_SPINNING
			player.mo.state = S_PLAY_ROLL
			if (player.rspeed > (5*player.mo.scale))
				S_StartSound(player.mo, sfx_spin)
			end
		end
	end
end)

//Classic spindash behavior
addHook("ThinkFrame", do
	for player in players.iterate
		if player.mo and player.mo.valid
		and not (player.nocharge)
		and not (player.mo.skin == "handdrawn")//here's old sonic, you're living in the past if you really need a thok
		and not (player.mo.skin == "ssntails") //for if you want to play as crappy tails for some reason, i thought the buffs i gave were pretty good
		and not (player.mo.skin == "uglyknux") //if you want to play with that classic knuckles experience.
		and not (player.mo.skin == "samus")
		and not (player.mo.skin == "silver")
		and not (player.mo.skin == "metal_sonic")
		and not (player.mo.skin == "samus")
		and not (player.mo.skin == "handdrawn")//here's old sonic, you're living in the past if you really need a thok
		and not (player.mo.skin == "ssntails") //for if you want to play as crappy tails for some reason, i thought the buffs i gave were pretty good
		and not (player.mo.skin == "uglyknux") //if you want to play with that classic knuckles experience.
		and (player.isclassic)
		and not (player.mo.state == S_PLAY_DEAD)
		and player.charability2 == CA2_SPINDASH		
		
		//setting up the variable to check for how many charges the current spindash has
			if player.spincharges == nil
				player.spincharges = 0
			end
		//this one checks how long the spindash has been held for
			if player.dashtime == nil
			or not (player.pflags & PF_STARTDASH)
				player.dashtime = 15
			end
		//and this one checks how many automatic charges we've added, as we can only have 4
			if player.dashcounter == nil
			or not (player.pflags & PF_STARTDASH)
				player.dashcounter = 0
			end
		//checks if player was holding jump last frame
			if player.jumpwasdown == nil
				player.jumpwasdown = 0
			end
			
		//makes our life easier
			if player.pflags & PF_STARTDASH
				player.dashspeed = player.maxdash
				player.mindash = player.maxdash - (21*player.dashspeed)
			end
	
			if player.dashcounter >= 3
				player.dashcounter = 3
			end
			if player.dashtime <= 0
				player.dashtime = 15
			end
			if testing == true then print(player.dashcounter, player.dashtime, player.dashspeed/FRACUNIT, player.spincharges) end
			//You gotta be spindashing, man!
			if (player.pflags & PF_STARTDASH)
				player.dashtime = $ - 1
				player.jumpfactor = 0
				if player.spincharges == 0
					player.mindash = 23*FRACUNIT
					player.maxdash = 25*FRACUNIT
					player.mindash = player.maxdash - (21*player.dashspeed)
				else
					player.maxdash = (25*FRACUNIT) + (player.spincharges*(5*FRACUNIT))
				end
				if player.cmd.buttons & BT_JUMP
				and not (player.jumpwasdown)
					if player.spincharges < 7
						player.spincharges = $ + 1
					else
						player.spincharges = 7
					end
				S_StartSound(player.mo, sfx_rev2 - 2 + player.spincharges) //thank you lach for shortening this down for me
				end
				if player.dashtime == 0
				and player.dashcounter < 3
				and player.SpindashAssist == true
				and player.spincharges < 7
					player.spincharges = $ + 1
					player.dashcounter = $ + 1
					player.dashtime = 15
					S_StartSound(player.mo, sfx_rev1 - 1 + player.spincharges) //thank you lach for shortening this down for me
				end
			else
				player.jumpfactor = skins[player.mo.skin].jumpfactor
				player.spincharges = 0
			end
		end
		
	//Our "was jump pressed last frame?" check ends here
		player.jumpwasdown = (player.cmd.buttons & BT_JUMP)
		
	end
end)



// Everybody's Super Sonic, even outside of match
addHook("ThinkFrame", do
	for player in players.iterate
		if player.mo and player.mo.valid
			if not (player.charflags & SF_SUPER)
			and not (player.isclassic == false)
			and not (player.mo.skin == "tsonic") //Toei breaks counter: 6
				player.charflags = $1|SF_SUPER
			end
		end
	end
end)