freeslot("S_PLAY_MPEEL1", "S_PLAY_MPEEL2", "S_PLAY_MPEEL3", "S_PLAY_MPEEL4", "S_PLAY_PEEL1", "S_PLAY_PEEL2", "S_PLAY_PEEL3", "S_PLAY_PEEL4", "S_PLAY_PWALK1", "S_PLAY_PWALK2", "S_PLAY_PWALK3", "S_PLAY_PWALK4", "S_PLAY_PWALK5", "S_PLAY_PWALK6", "S_PLAY_PWALK7", "S_PLAY_PWALK8", "S_PLAY_PWALK9", "S_PLAY_PWALK10", "S_PLAY_PWALK11", "S_PLAY_PWALK12", "S_PLAY_PWALK13", "S_PLAY_PWALK14", "S_PLAY_PWALK15", "S_PLAY_PWALK16", "S_PLAY_SPEEL1", "S_PLAY_SPEEL2")
states[S_PLAY_PWALK1] = {SPR_PLAY, SPR2_WALK1, 4, nil, 0, 0, S_PLAY_PWALK2}
states[S_PLAY_PWALK2] = {SPR_PLAY, SPR2_WALK2, 4, nil, 0, 0, S_PLAY_PWALK3}
states[S_PLAY_PWALK3] = {SPR_PLAY, SPR2_WALK3, 4, nil, 0, 0, S_PLAY_PWALK4}
states[S_PLAY_PWALK4] = {SPR_PLAY, SPR2_WALK4, 3, nil, 0, 0, S_PLAY_PWALK5}
states[S_PLAY_PWALK5] = {SPR_PLAY, SPR2_WALK5, 3, nil, 0, 0, S_PLAY_PWALK6}
states[S_PLAY_PWALK6] = {SPR_PLAY, SPR2_WALK6, 3, nil, 0, 0, S_PLAY_PWALK7}
states[S_PLAY_PWALK7] = {SPR_PLAY, SPR2_WALK7, 2, nil, 0, 0, S_PLAY_PWALK8}
states[S_PLAY_PWALK8] = {SPR_PLAY, SPR2_WALK8, 2, nil, 0, 0, S_PLAY_PWALK9}
states[S_PLAY_PWALK9] = {SPR_PLAY, SPR2_WALK1, 2, nil, 0, 0, S_PLAY_PWALK10}
states[S_PLAY_PWALK10] = {SPR_PLAY, SPR2_WALK2, 1, nil, 0, 0, S_PLAY_PWALK11}
states[S_PLAY_PWALK11] = {SPR_PLAY, SPR2_WALK3, 1, nil, 0, 0, S_PLAY_PWALK12}
states[S_PLAY_PWALK12] = {SPR_PLAY, SPR2_WALK4, 1, nil, 0, 0, S_PLAY_PWALK13}
states[S_PLAY_PWALK13] = {SPR_PLAY, SPR2_WALK5, 1, nil, 0, 0, S_PLAY_PWALK14}
states[S_PLAY_PWALK14] = {SPR_PLAY, SPR2_WALK6, 1, nil, 0, 0, S_PLAY_PWALK15}
states[S_PLAY_PWALK15] = {SPR_PLAY, SPR2_WALK7, 1, nil, 0, 0, S_PLAY_PWALK16}
states[S_PLAY_PWALK16] = {SPR_PLAY, SPR2_WALK8, 1, nil, 0, 0, S_PLAY_PEEL1}
states[S_PLAY_PEEL1] = {SPR_PLAY, SPR2_RUN_1, 1, nil, 0, 0, S_PLAY_PEEL2}
states[S_PLAY_PEEL2] = {SPR_PLAY, SPR2_RUN_2, 1, nil, 0, 0, S_PLAY_PEEL3}
states[S_PLAY_PEEL3] = {SPR_PLAY, SPR2_RUN_3, 1, nil, 0, 0, S_PLAY_PEEL4}
states[S_PLAY_PEEL4] = {SPR_PLAY, SPR2_RUN_4, 1, nil, 0, 0, S_PLAY_PEEL1}
states[S_PLAY_SPEEL1] = {SPR_PLAY, SPR2_RUN_1, 1, nil, 0, 0, S_PLAY_SPEEL2}
states[S_PLAY_SPEEL2] = {SPR_PLAY, SPR2_RUN_2, 1, nil, 0, 0, S_PLAY_SPEEL1}
states[S_PLAY_MPEEL1] = {SPR_PLAY, SPR2_DASH1, 1, nil, 0, 0, S_PLAY_MPEEL2}
states[S_PLAY_MPEEL2] = {SPR_PLAY, SPR2_DASH2, 1, nil, 0, 0, S_PLAY_MPEEL3}
states[S_PLAY_MPEEL3] = {SPR_PLAY, SPR2_DASH3, 1, nil, 0, 0, S_PLAY_MPEEL4}
states[S_PLAY_MPEEL4] = {SPR_PLAY, SPR2_DASH4, 1, nil, 0, 0, S_PLAY_MPEEL1}

local SKIN = "ultclsonic" -- Here you can change the character's skin name.
local ACTIVATIONTHOK = false -- Activates thok if equal to true.
local ACTIVATIONMOMENTUM = false -- Activates momentum if equal to true.
local SONICDASHMODE = false -- Activates dash mode if equal to true, but disables the ability to charge super peel-out.
local BUTTONPEELOUT = BT_CUSTOM1 -- Super peel-out charging button.
local DASHDELAYFRAMES = 4 -- DASH status delay.
local DASHTRUE = false
local PLUSSPEED = 0

// Charging and smoke super peel-out.
addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == SKIN and P_IsObjectOnGround(player.mo) and not (player.powers[pw_nocontrol] or player.playerstate == PST_DEAD or (player.sonicdashmode == true or SONICDASHMODE == true) 
	or player.exiting or player.mo.state == S_PLAY_PAIN or player.mo.state == S_PLAY_DEAD or player.mo.state == S_PLAY_SUPER_TRANS1 or player.mo.state == S_PLAY_SPRING)
		if not (player.pflags & PF_SPINNING) and player.cmd.buttons & BUTTONPEELOUT
			if player.mo.peelsound == 0 and player.speed == 0
				S_StartSound(player.mo, sfx_cdfm11)
				player.mo.peelsound = 1
			end
		if player.mo.peelsound == 1		
			if player.mo.peelouttimer < 70 
				player.mo.peelouttimer = $1 + 1
			end 
			if player.mo.peeloutspeed < 60
				if not player.powers[pw_super]
					player.mo.peeloutspeed = $1 + 2
				else
					player.mo.peeloutspeed = $1 + 3
				end
			end
	player.pflags = $1|PF_STASIS
	// player.mo.momx = 0
	// player.mo.momy = 0
			if player.drawangle ~= player.mo.angle
				local diff = 0
				local factor = 0
				diff = player.mo.angle - player.drawangle
				factor = 8
				if diff > ANGLE_180
					diff = InvAngle(InvAngle(diff)/(factor or 1))
				else
					diff = $ / (factor or 1)
				end
				player.drawangle = $ + diff
			end
			if not (player.mo.eflags & MFE_GOOWATER) then
				for i=(leveltime%7)/2,(leveltime%7) do
				local particle = P_SpawnMobj(player.mo.x, player.mo.y,
				player.mo.z + ((player.mo.eflags & MFE_VERTICALFLIP)/MFE_VERTICALFLIP * (player.mo.height - mobjinfo[MT_SPINDUST].height)), MT_SPINDUST)
					if (player.powers[pw_shield] == SH_ELEMENTAL and not (player.mo.eflags & MFE_TOUCHWATER or player.mo.eflags & MFE_UNDERWATER)) then
						particle.state = S_SPINDUST_FIRE1
						particle.bubble = false
					elseif (player.mo.eflags & MFE_TOUCHWATER or player.mo.eflags & MFE_UNDERWATER) then
						particle.state = S_SPINDUST_BUBBLE1
						particle.bubble = true
					else
						particle.state = S_SPINDUST1
						particle.bubble = false
					end
				particle.target = player.mo
		   		particle.eflags = $1 | (player.mo.eflags & MFE_VERTICALFLIP)
		    	particle.scale = player.mo.scale*2/3
		    	P_SetObjectMomZ(particle, player.mo.peelouttimer*FRACUNIT/50+P_RandomByte()<<10, false)
		    	P_InstaThrust(particle, player.mo.angle+(P_RandomRange(-ANG30/FRACUNIT, ANG30/FRACUNIT)*FRACUNIT), FixedMul(-player.mo.peelouttimer*FRACUNIT/12-1*FRACUNIT-P_RandomByte()<<11, player.mo.scale))
		   		P_TryMove(particle, particle.x+particle.momx, particle.y+particle.momy, true)
			end
		end
	end	
   elseif player.mo.peelsound == 1 
			player.pflags = $1|PF_STASIS
   end
			if not (player.cmd.buttons & BUTTONPEELOUT) and player.mo.peelsound == 1
				if ((player.mo.peelouttimer >= 1) and (player.mo.peelouttimer <= 17) and not (player.powers[pw_super]))
				or ((player.mo.peelouttimer >= 1) and (player.mo.peelouttimer <= 11) and (player.powers[pw_super]))
					player.normalspeed = 36*FRACUNIT
					player.mo.state = 14
					player.mo.peelouttimer = 0
					player.mo.peeloutspeed = 0
					player.mo.peelsound = 0
					player.mo.state = S_PLAY_STND
				end
		    end
			if not player.powers[pw_super] and player.mo.peelsound == 1
				if player.mo.peelouttimer >= 1
				and player.mo.peelouttimer <= 17
					if not (player.mo.state >= S_PLAY_PWALK1)
					and (player.mo.state <= S_PLAY_PWALK16)
						player.mo.state = S_PLAY_PWALK1
					end
				end
				if player.mo.peelouttimer >= 18
				and player.mo.peelouttimer <= 29
					if not ((player.mo.state >= S_PLAY_PEEL1) and (player.mo.state <= S_PLAY_PEEL4))
					or ((player.mo.state >= S_PLAY_PWALK1) and (player.mo.state <= S_PLAY_PWALK16))
						player.mo.state = S_PLAY_PEEL1
					end
				end
				if player.mo.peelouttimer >= 30 and not (player.mo.eflags & MFE_UNDERWATER)
					if not ((player.mo.state >= S_PLAY_MPEEL1) and (player.mo.state <= S_PLAY_MPEEL4))
					or ((player.mo.state >= S_PLAY_PEEL1) and (player.mo.state <= S_PLAY_PEEL4))
					or ((player.mo.state >= S_PLAY_PWALK1) and (player.mo.state <= S_PLAY_PWALK16))
						player.mo.state = S_PLAY_MPEEL1
					end
				end
			elseif player.powers[pw_super] and player.mo.peelsound == 1
				if player.mo.peelouttimer >= 1 and player.mo.peelouttimer <= 11
					if not (player.mo.state >= S_PLAY_PWALK8)
					and (player.mo.state <= S_PLAY_PWALK16)
						player.mo.state = S_PLAY_PWALK8
					end
				end
				if player.mo.peelouttimer >= 12 and player.mo.peelouttimer <= 19
					if not (player.mo.state >= S_PLAY_SPEEL1)
					and (player.mo.state <= S_PLAY_SPEEL2)
						player.mo.state = S_PLAY_SPEEL1
					end
				end
				if player.mo.peelouttimer >= 20 and not (player.mo.eflags & MFE_UNDERWATER)
					if not ((player.mo.state >= S_PLAY_MPEEL1) and (player.mo.state <= S_PLAY_MPEEL4))
					or ((player.mo.state >= S_PLAY_SPEEL1) and (player.mo.state <= S_PLAY_SPEEL2))
					or ((player.mo.state >= S_PLAY_PWALK8) and (player.mo.state <= S_PLAY_PWALK16))
						player.mo.state = S_PLAY_MPEEL1
					end
				end
			end
	end
end)

// Super peel-out jerk.
addHook("ThinkFrame", do
	for player in players.iterate
			if player.mo and player.mo.skin == SKIN
			//CONS_Printf(player, player.mo.peelouttimer)
				if player.mo.state == S_PLAY_STND
					player.normalspeed = 36*FRACUNIT
				end
				if player.mo.peelouttimer == nil
					player.mo.peelouttimer = 0
				end
				if player.mo.peelout == nil
					player.mo.peelout = 0
				end
				if player.mo.peeloutrun == nil
					player.mo.peeloutrun = 0
				end
				if player.mo.peelsound == nil
					player.mo.peelsound = 0
				end
				if player.mo.peelsound2 == nil
					player.mo.peelsound2 = 0
				end
				if player.pflags & PF_SPINNING
					player.mo.peelouttimer = 0
				end
				if player.mo.peeloutspeed == nil
					player.mo.peeloutspeed = 0
				end
				if (P_PlayerInPain(player)) or (player.playerstate == PST_DEAD) or player.powers[pw_nocontrol] or player.exiting
					player.normalspeed = 36*FRACUNIT
					player.mo.peelouttimer = 0
					player.mo.peelout = 0
					player.mo.peeloutrun = 0
					player.mo.peelsound = 0
					player.mo.peeloutsound = 0
					player.mo.peeloutspeed = 0
					elseif not P_IsObjectOnGround(player.mo)
					player.mo.peelouttimer = 0
					player.mo.peelsound = 0
					player.mo.peeloutsound = 0
				end
				if (player.mo.peelsound == 1 or player.mo.peelout > 0)
					player.mo.peeloutspeed = player.mo.peeloutspeed
				else
					player.mo.peeloutspeed = 0
				end
	if not (player.cmd.buttons & BUTTONPEELOUT) and P_IsObjectOnGround(player.mo)
				if ((player.mo.peelouttimer >= 30) and not (player.powers[pw_super])) 
				or ((player.mo.peelouttimer >= 20) and (player.powers[pw_super]))
					if player.mo.peelsound == 1
						S_StartSound(player.mo, sfx_cdfm01)
						player.mo.state = S_PLAY_RUN
						player.mo.peelsound = 0
						player.mo.peelout = 2	
					end
					P_InstaThrust(player.mo, player.mo.angle, FixedMul(player.mo.peeloutspeed*FRACUNIT, player.mo.scale))
					player.mo.peelouttimer = 0
					player.drawangle = player.mo.angle
					player.speed = player.mo.peeloutspeed*FRACUNIT
				elseif ((player.mo.peelouttimer >= 18) and (player.mo.peelouttimer <= 29) and not (player.powers[pw_super]))
				or ((player.mo.peelouttimer >= 12) and (player.mo.peelouttimer <= 19) and (player.powers[pw_super])) 
					if player.mo.peelsound == 1
						S_StartSound(player.mo, sfx_cdfm01)
						player.mo.state = S_PLAY_RUN
						player.mo.peelsound = 0
						player.mo.peelout = 1
					end
					P_InstaThrust(player.mo, player.mo.angle, FixedMul(player.mo.peeloutspeed*FRACUNIT, player.mo.scale))
					player.mo.peelouttimer = 0
					player.drawangle = player.mo.angle
					player.speed = player.mo.peeloutspeed*FRACUNIT
				end
	end
			if not (player.activationmomentum == true or ACTIVATIONMOMENTUM == true)
				if player.speed >= 1*FRACUNIT and player.mo.peelout == 2 
					player.mo.peeloutrun = 2
					player.normalspeed = player.mo.peeloutspeed*FRACUNIT
				elseif player.speed >= 1*FRACUNIT and player.mo.peelout == 1 
					player.mo.peeloutrun = 1
					player.normalspeed = player.mo.peeloutspeed*FRACUNIT
				end
				if (player.mo.peeloutrun > 0) and (player.powers[pw_sneakers]) and not (player.powers[pw_super])
					player.normalspeed = 36*FRACUNIT
				end
			end
			if not (player.activationmomentum == true or ACTIVATIONMOMENTUM == true) 
			and (player.speed <= 24*FRACUNIT and player.mo.peeloutrun == 1) or (player.speed <= 44*FRACUNIT and player.mo.peeloutrun == 2)
				player.mo.peelout = 0
				player.mo.peeloutrun = 0
				player.mo.peeloutspeed = 0
				player.normalspeed = 36*FRACUNIT
			elseif (player.activationmomentum == true or ACTIVATIONMOMENTUM == true)
			and (player.mo.peelout == 1 and player.speed <= 24*FRACUNIT) or (player.mo.peelout == 2 and player.speed <= 44*FRACUNIT)
				player.mo.peeloutspeed = 0 
				player.mo.peelout = 0
			end
			if player.pflags & PF_JUMPED
				if ((player.mo.state >= S_PLAY_PWALK1) and (player.mo.state <= S_PLAY_PWALK16))
				or ((player.mo.state >= S_PLAY_PEEL1) and (player.mo.state <= S_PLAY_PEEL4))
				or ((player.mo.state >= S_PLAY_SPEEL1) and (player.mo.state <= S_PLAY_SPEEL2))
				or ((player.mo.state >= S_PLAY_MPEEL1) and (player.mo.state <= S_PLAY_MPEEL4))
					player.mo.state = S_PLAY_JUMP
				end
				if player.normalspeed == 0*FRACUNIT
					player.normalspeed = 36*FRACUNIT
				end
				player.mo.peelouttimer = 0
				player.mo.peelsound = 0
				player.mo.peelsound2 = 0
			end
		end
	end
end)

// Dash state appearances.
addHook("ThinkFrame", do
    for player in players.iterate
        if (player.mo and player.mo.skin == SKIN) and not ((player.sonicdashmode == true or SONICDASHMODE == true) or (player.pflags & PF_SPINNING))
            if player.mo.state == S_PLAY_RUN and ((player.speed >= 44*FRACUNIT and not player.powers[pw_super]) or (player.speed >= 84*FRACUNIT and player.powers[pw_super])) and not (player.mo.eflags & MFE_UNDERWATER)
				    if (player.mo.peelout == 2 or player.powers[pw_sneakers] or DASHTRUE == true)
				        player.mo.state = S_PLAY_DASH
					end
					if not player.dashDelay
                        player.dashDelay = DASHDELAYFRAMES
                    else
						if P_IsObjectOnGround(player.mo)
                       		player.dashDelay = player.dashDelay - 1
                        	if player.dashDelay <= 0
                           		DASHTRUE = true
                            	player.dashDelay = nil
							end
						end	
					end
            elseif player.mo.state == S_PLAY_DASH and ((player.speed >= 0) and (player.speed <= 44*FRACUNIT and not player.powers[pw_super]) or (player.speed <= 84*FRACUNIT and player.powers[pw_super]))
					player.mo.state = S_PLAY_RUN
			end
			if (player.mo.eflags & MFE_UNDERWATER) or ((player.speed >= 0) and (player.speed <= 59*FRACUNIT) and not (player.powers[pw_super])) or ((player.speed >= 0) and (player.speed <= 99*FRACUNIT) and (player.powers[pw_super]))
				DASHTRUE = false
				player.dashDelay = nil
			end
		end
	end
end) 


// Peel-out disappears when you complete a level.
addHook("PlayerThink", function(player)
	if player.exiting and (player.mo and player.mo.skin == SKIN) 
		if not player.speed and P_IsObjectOnGround(player.mo) and (player.mo.peelouttimer == 0 or player.mo.peelout == 0 or player.mo.peeloutrun == 0 
		or player.mo.peelsound == 0 or player.mo.peeloutsound == 0)
			player.mo.state = S_PLAY_STND
		end
	return
	end
end)