freeslot(
"SPR_ASST",
"S_ASSTMP1",
"S_ASSTMP2",
"S_ASSTMP3",
"S_ASSTMP4",
"S_ASJDSH",
"MT_ASJDSH"
)
//Stomp overlay
states[S_ASSTMP1] = {
	sprite = SPR_ASST,
	frame = A|FF_FULLBRIGHT,
	tics = 1,
	var1 = 0,
	var2 = 0,
	nextstate = S_ASSTMP2
}

states[S_ASSTMP2] = {
	sprite = SPR_ASST,
	frame = B|FF_FULLBRIGHT,
	tics = 1,
	var1 = 0,
	var2 = 0,
	nextstate = S_ASSTMP3
}

states[S_ASSTMP3] = {
	sprite = SPR_ASST,
	frame = C|FF_FULLBRIGHT,
	tics = 1,
	var1 = 0,
	var2 = 0,
	nextstate = S_ASSTMP4
}

states[S_ASSTMP4] = {
	sprite = SPR_ASST,
	frame = D|FF_FULLBRIGHT,
	tics = 1,
	var1 = 0,
	var2 = 0,
	nextstate = S_ASSTMP1
}

mobjinfo[MT_ASJDSH] = {
	doomednum = -1,
	spawnstate =  S_ASJDSH,
	flags = MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY
}
states[S_ASJDSH] = {
	sprite = SPR_JDSH,
	frame = A|FF_ANIMATE|FF_FULLBRIGHT,
	tics = 10,
	var1 = 9,
	var2 = 1,
	nextstate = S_DEATHSTATE
}
addHook("PlayerThink", function(player)
    if player.mo.skin ~= "nknuckles" then
        return
    end

    if (player.cmd.buttons & BT_CUSTOM2) and P_IsObjectOnGround(player.mo) and player.speed == 0 then
        player.height = 30*FRACUNIT
        player.mo.state = S_PLAY_GLIDE_LANDING
        player.pflags = $1|PF_FULLSTASIS
    else
        player.height = 48*FRACUNIT
    end
end)
addHook("PlayerThink", function(player)
//print(player.dashmode)
	if player.mo and player.mo.valid and (player.mo.skin == "nknuckles")
		if player.dashpreserve == nil
				player.dashpreserve = 0
			end
		if player.dashmode > 3*TICRATE //If you have dash mode, preserve it in the air.
			player.dashpreserve = true
		end
		if not P_IsObjectOnGround(player.mo) //If in the air, keep dash mode set so it doesn't count down.
			if player.dashpreserve == true
				player.dashmode = max(player.dashmode, 3*36)
			end
		end
		if not P_IsObjectOnGround(player.mo) //Build dash mode in the air the same way you would on the ground. Based on source code.
		and (player.dashmode >= 3*TICRATE)
		and player.speed > 28*FRACUNIT
			if (player.normalspeed < skins[player.mo.skin].normalspeed*2) // If the player normalspeed is not currently at normalspeed*2 in dash mode, add speed each tic.
				player.normalspeed = $ + FRACUNIT/5
			end
			if (player.jumpfactor < FixedMul(skins[player.mo.skin].jumpfactor, 5*FRACUNIT/4)) // Boost jump height.
				player.jumpfactor = $ + FRACUNIT/300
			end
		end
		if (player.dashmode) //If you have dash mode :v
            if not (player.mo.health) //If any of these conditionals are met, don't preserve dash mode.
            or (P_PlayerInPain(player))
            or (player.gotflag)
            or (player.exiting)
            or (player.pflags & (PF_STASIS|PF_JUMPSTASIS))
            or (player.powers[pw_carry])
            or (player.powers[pw_super] == 1)
			or (player.mo.chargefalling == true)
                player.dashpreserve = false
			end
		end
		if P_IsObjectOnGround(player.mo) //If on the ground and dash mode isn't active, don't preserve what doesn't exist.
            if player.dashmode <= 3*TICRATE
                player.dashpreserve = false
            end
        end
	end
end)


//KNOCKLOS
addHook("SpinSpecial", function(player)
		if player.mo.skin == "nknuckles"
		if (player.mo.state == S_PLAY_SWIM)
		player.pflags = $1 & ~PF_JUMPED
		S_StartSound(player.mo, sfx_none)
		player.mo.momz = 5*FRACUNIT
		player.mo.height = 5*FRACUNIT
		player.mo.state = S_PLAY_SWIM
		player.pflags = $1|PF_JUMPED
		end
	end
end)

//KNICKLIS
addHook("JumpSpecial", function(player)
		if player.mo.skin == "nknuckles"
		if (player.mo.state == S_PLAY_GLIDE)
		and player.powers[pw_super]
		player.pflags = $1 & ~PF_JUMPED
		S_StartSound(player.mo, sfx_none)
		player.mo.momz = 1*FRACUNIT
		player.mo.height = 1*FRACUNIT
		player.mo.state = S_PLAY_GLIDE
		player.pflags = $1|PF_JUMPED
		end
	end
end)
/*
//advance climb sound script made by neo trashed
addHook("PlayerThink", function(player)
	if player.mo.skin == "nknuckles"	
		if not P_IsObjectOnGround(player.mo)
		local advanceswim = false
			if (player.mo.state == S_PLAY_CLIMB)
				if (player.mo.frame == A or player.mo.frame == C)
					if not advanceswim
					and not player.powers[pw_extralife]
					and not S_SoundPlaying(player.mo, sfx_advcli)
					S_StartSound(player.mo, sfx_advcli)
					end
				end
			end
		end
	end
end)
*/
//megamix knux mega punch script made by neo
	addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "nknuckles"
	and player.rings >= 0 
	and P_IsObjectOnGround(player.mo)
	and not player.powers[pw_super]
	and not (player.pflags & PF_THOKKED)
	and (player.cmd.buttons & BT_CUSTOM1)
	player.mo.momz = 5*FRACUNIT
	player.mo.height = 60*FRACUNIT
	P_InstaThrust(player.mo, player.mo.angle, 21*FRACUNIT)
	P_Thrust(player.mo, player.mo.angle, 20*FRACUNIT)
	player.mo.state = S_PLAY_ROLL
	player.pflags = $|PF_THOKKED
	S_StartSound(player.mo, sfx_zoom)
	P_GivePlayerRings(player, -0)
	end
end)
	addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "nknuckles"
	and player.rings >= 0 
	and player.powers[pw_super]
	and P_IsObjectOnGround(player.mo)
	and not (player.pflags & PF_THOKKED)
	and (player.cmd.buttons & BT_CUSTOM1)
	player.mo.momz = 5*FRACUNIT
	player.mo.height = 60*FRACUNIT
	P_InstaThrust(player.mo, player.mo.angle, 50*FRACUNIT)
	P_Thrust(player.mo, player.mo.angle, 51*FRACUNIT) --eheehheheh
	player.mo.state = S_PLAY_ROLL
	player.pflags = $|PF_THOKKED
	S_StartSound(player.mo, sfx_zoom)
	P_GivePlayerRings(player, -0)
	end
end)
addHook("PlayerCanDamage", function(p, mo)
	if p.mo.state == S_PLAY_ROLL
		return true
	end
end)
addHook("PlayerCanDamage", function(p, mo)
	if p.mo.state == S_ROCK_BLAST
		return true
	end
end)
addHook("PlayerCanDamage", function(p, mo)
	if p.mo.state == S_AIR_DRILL
		return true
	end
end)
freeslot("S_ROCK_BLAST","S_SPRING_LANDING","S_BOMB_THROW","S_AIR_DRILL")
states[S_ROCK_BLAST] = {SPR_PLAY, SPR2_MLEE|FF_ANIMATE, 17, nil, 2, 1, S_PLAY_MELEE}
states[S_SPRING_LANDING] = {SPR_PLAY, SPR2_ROLL|FF_ANIMATE, 17, nil, 20, 1, S_PLAY_FALL}
states[S_AIR_DRILL] = {SPR_PLAY, SPR2_FIRE|FF_ANIMATE, 19, nil, 2, 1, S_PLAY_SPRING}
//rock blast
addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "nknuckles"
		if(player.mo.state == S_PLAY_JUMP)
		and(player.cmd.buttons & BT_SPIN)
		and(player.playerstate == PST_LIVE)
		and not (player.pflags & PF_STASIS)
		and not (player.pflags & PF_FULLSTASIS)
		and not (player.pflags & PF_THOKKED)
        and(P_IsObjectOnGround(player.mo) == false)
           P_SpawnThokMobj(player)
		   player.mo.state = S_ROCK_BLAST
		   player.bonuce = true
		   player.bonucea = true
		   player.mo.momz = -23*FRACUNIT
		   S_StartSound(player.mo, sfx_airdsh, player)
		end
		
		if(player.bonuce)
        and(P_IsObjectOnGround(player.mo) == true) 
		and not player.powers[pw_justsprung]
		local dust = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z + (player.mo.eflags & MFE_VERTICALFLIP and 4*player.mo.scale or 0), player.mo.eflags & (MFE_UNDERWATER | MFE_TOUCHWATER) and MT_MEDIUMBUBBLE or MT_PARTICLE)
	    dust.fuse = TICRATE/2
		dust.scale = player.mo.scale*2
		dust.destscale = player.mo.scale/8
		P_InstaThrust(dust, i*ANG10+ANG1, 4*player.mo.scale)
		dust.frame = $1|TR_TRANS60
		P_StartQuake(10*FRACUNIT, 11)
		   player.mo.state = S_PLAY_ROLL
		   player.bonuce = false
		   player.mo.momz = 10*FRACUNIT
		   player.mo.state = S_SPRING_LANDING
		   S_StartSound(player.mo, sfx_bounc2, player)
		   P_SpawnSkidDust(player, 10*FRACUNIT, sfx_none)
		   //and player.powers[pw_super] and P_NukeEnemies(player.mo, player.mo, 200*FRACUNIT)
		   P_SpawnGhostMobj(player.mo)
		end
	end
end)
//air drill player.bonuce = false
addHook("PlayerThink", function(player)
    if player.mo and player.mo.skin == "nknuckles"
		local mo = player.mo
		if player.knuxjustuseduppercut == nil
			player.knuxjustuseduppercut = false
		end
		if (P_IsObjectOnGround(mo)) or player.climbing or mo.eflags&MFE_SPRUNG
			player.knuxjustuseduppercut = false
		end
		if (player.cmd.buttons & BT_CUSTOM1)
			if not player.isholding 
			and not P_IsObjectOnGround(player.mo)
			and not (player.pflags & PF_THOKKED)
			and not player.climbing
			and player.knuxjustuseduppercut == false
			player.mo.momz = 19*FRACUNIT
			player.knuxjustuseduppercut = true
			P_Thrust(player.mo, player.mo.angle, 3*FRACUNIT)
			player.mo.state = S_AIR_DRILL
			S_StartSound(player.mo, sfx_kc3c, player)
			player.pflags = $|PF_THOKKED
			end
			player.isholding = true
		else
			player.isholding = false
		end
	end
end)
addHook("MobjMoveCollide", function(knux, spring)
	if not (knux.player and knux.skin == "nknuckles") or not (spring.flags & MF_SPRING)
		return nil
	elseif ((knux.player.bounce)) and (knux.player.powers[pw_justsprung])
		S_StartSound(knux, sfx_sprong)
		knux.state = S_PLAY_SPRING
		knux.player.bounce = 0
		knux.player.mo.momz = $ * 120/100
		knux.player.powers[pw_justsprung] = 0
		return false
	end
end, MT_PLAYER)
//Crumble FOF by Frostii
local function CheckAndCrumble2(mo, sec)
  for fof in sec.ffloors()
    if not (fof.flags & FF_EXISTS) continue end -- Does it exist?
    if not (fof.flags & FF_BUSTUP) continue end -- Is it bustable?
    
    if mo.z + mo.momz + mo.height < fof.bottomheight continue end -- Are we too low?
    if mo.z + mo.momz > fof.topheight continue end -- Are we too high?

    -- Check for whatever else you may want to    

    EV_CrumbleChain(fof) -- Crumble
  end
end

addHook("PlayerThink", function(p)
  if not p.mo return end
  if not p.bonuce then return end
	CheckAndCrumble2(p.mo, p.mo.subsector.sector)
end)

addHook("MobjLineCollide", function(mo, line)
  if not mo.player return end
  if not mo.player.bonuce then return end
  for _, sec in ipairs({line.frontsector, line.backsector})
    CheckAndCrumble2(mo, sec)
  end
end, MT_PLAYER)
//crouch ability
addHook("PlayerThink", function(p) --main hook
	local pmo = p.mo //local variable for simplicity
	if pmo.skin == "nknuckles"
		if not ((pmo and pmo.valid) or (p.exiting)) //our player check
			return
		end
		if pmo.usetics != nil and (p.cmd.buttons & BT_CUSTOM2) //lets set up the counter for how many tics our button is pressed
			pmo.usetics = $ + 1 //if held, the counter goes up by 1.
		else
			pmo.usetics = 0 //other wise set to 0.
		end
		local crouchheight = 30*FRACUNIT -- set the height for the crouch, though you can also use p.spinheight
		if P_IsObjectOnGround(pmo) and not (p.pflags&PF_SPINNING) -- is the player grounded?
			if (pmo.usetics ~= 0)
			 --and (p.speed <= p.runspeed/4) //the player is pressing the specified button (our case, SPIN) and, if added back in (remove the /* */), slower than a specified speed.
				pmo.state = S_PLAY_GLIDE_LANDING -- set our animation, add sprites with the sprite subset of LAND with your character's sprites for a custom sprite.
				p.pflags = $|PF_STASIS --make sure the player can't move
				p.height = crouchheight --change the height
			else --we can use the delay from the alredy made code for the glide landing animation to a different one to our advantage!
				if (pmo.state == S_PLAY_GLIDE_LANDING) 
					p.height = 48*FRACUNIT --set our height back to normal
					if  p.pflags&PF_STASIS
						p.pflags = $ & ~PF_STASIS --allow movement
					end
				end
			end	
			if ((pmo.state == S_PLAY_GLIDE_LANDING) and (pmo.usetics)) and (p.speed >= p.runspeed/3) --dust effects
				P_SpawnSkidDust(p, 15*FRACUNIT, sfx_s3k7e) --dust bs
			end
		end
	end
end)