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)
//s3 bomb throw troll jump
addHook("ThinkFrame", do
	for player in players.iterate
		if player.mo and player.mo.skin == "nknuckles" //If you're Fang
			if not player.exiting //If you're leaving a level, you won't need them, right?
			and player.rings >= 5 -- get 100 rings
			and (player.mo.state == S_PLAY_GLIDE)
				and not (player.pflags & PF_THOKKED)
				and not P_IsObjectOnGround(player.mo)
					if not (P_PlayerInPain(player) or (player.playerstate == PST_DEAD)) //Hurt/dead weasels can't throw bombs
					if ((player.cmd.buttons & BT_CUSTOM1) and not (player.weapondelay)) //If you press Toss Flag...
						S_StartSound(player.mo, sfx_s3k51) //...Play the bomb throwing sound...
						P_SetObjectMomZ(player.mo, 6*FRACUNIT)
						P_InstaThrust(player.mo, player.mo.angle, 3*FRACUNIT)
						P_GivePlayerRings(player, -5) -- and buy
						player.mo.state = S_BOMB_THROW
						player.pflags = $|PF_THOKKED 
						local bomb = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z + player.mo.height, MT_FBOMB) //...And spawn the bomb itself
						bomb.target = player.mo //The bomb can't hurt its user
						if (player.mo.state == S_PLAY_GLIDE) //If you're jumping/springing/bouncing...
							bomb.momz = (player.mo.momz)+(5*FRACUNIT) //...The bomb gets some height boost
						else //But if you're falling...
							bomb.momz = 10*FRACUNIT //...The bomb just flies at this fixed height
						end
						P_InstaThrust(bomb, player.mo.angle, ((player.speed)+(7*FRACUNIT))) //The bomb describes an arc while flying, affected by your current speed
						if (player.powers[pw_super]) //If you're Super Fang...
							player.weapondelay = TICRATE*1 //...You can throw bombs 3X faster
							P_GivePlayerRings(player, -0)
						else //But if that's not the case...
							player.weapondelay = TICRATE*5 //...You have to wait three seconds between bombs
						end
					end
				end
			end
		end
	end
end)
//all of knux.
