//Sonic Lost World Bounce Attack. made by me, MotdSpork. Boing!

addHook("MobjThinker", function(sonic)

	local InWater = ((sonic.player.mo.eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) != 0);
	
	if (sonic and sonic.skin == "ratatin") //if you're ratatin..
	and sonic.player.playerstate == PST_LIVE //you alive bruh?
	and not (sonic.player.powers[pw_super]) //super sonic has float instead
		if sonic.player.bounceattack == nil //if the variable doesnt exist
			sonic.player.bounceattack = 0 //create variable
		end
		if sonic.player.bouncenumber == nil //if the variable doesnt exist
			sonic.player.bouncenumber = 0 //create variable
			sonic.player.justchangedbouncenumber = 0 //create variable
		end
		if P_IsObjectOnGround(sonic) //are you on the ground?
		and sonic.player.bounceattack == 0 //the player isnt bouncing
			sonic.player.bouncenumber = 0 //set it to zero!
		end
		if sonic.player.usedown == nil //if the variable doesnt exist
		or not (sonic.player.cmd.buttons & BT_USE) //not pressing the spin button?
			sonic.player.usedown = 0 //create variable
			sonic.player.justchangedbouncenumber = 0 //create variable
		end
		if P_IsObjectOnGround(sonic) //Is the player on the ground?
		and (sonic.player.cmd.buttons & BT_USE) //Is the player holding the spin button?
			sonic.player.usedown = 1 //Set it to one!
		end
		if sonic.player.pflags & PF_JUMPED //if the player has jumped
		and not (sonic.player.pflags & PF_THOKKED) //and the player hasnt used their mid-air ability
		and not (P_IsObjectOnGround(sonic)) //and you arent on the ground.
		and sonic.player.cmd.buttons & BT_USE //pressing custom2?
		and sonic.player.bounceattack == 0 //checking if the custom variable it set to 0
		and sonic.player.usedown == 0 //make sure you arent holding the spin button.
		and not (sonic.player.exiting) //not...exiting the level?
		and sonic.health //you're alive?
		and not (P_PlayerInPain(sonic.player)) //not hurt are you?
			sonic.player.bounceattack = 1 //set it to one!
			P_SetObjectMomZ(sonic, -35*FRACUNIT) //make the player "shoot" downward
			//P_SetObjectMomZ(sonic, FixedMul(-35*FRACUNIT, sonic.scale)) //make the player shoot downwards 
			sonic.player.pflags = $1|PF_THOKKED //force the player into a "thokked" state
		end
			
		if (sonic.eflags & MFE_JUSTHITFLOOR) //you're on the ground.
		and not (sonic.player.pflags & PF_SPINNING) //you arent spinning....somehow
		and not (sonic.player.pflags & PF_STARTDASH) //you arent doing a spindash
		and not (sonic.tracer and sonic.tracer.type == MT_TUBEWAYPOINT) //not in a...zoomtube?
		and sonic.player.bounceattack == 1 //our custom variable is one right...?
		and sonic.health //is the player alive..?
		and not (P_PlayerInPain(sonic.player)) //not hurt are you?
			if sonic.player.bouncenumber == 0 //if he hasnt bounced yet
			and sonic.player.justchangedbouncenumber == 0 //if he hasnt left the ground yet
				sonic.player.justchangedbouncenumber = 1 //now he has!
				sonic.player.bouncenumber = 1 //Set this to one!
				sonic.player.pflags = $1|PF_JUMPED //forcing the player into a jumping state.
				if (InWater == true)
					P_SetObjectMomZ(sonic, 10*FRACUNIT)
					sonic.state = S_PLAY_ROLL //force the player into a spinning state.
				else
					P_SetObjectMomZ(sonic, 15*FRACUNIT)			
				if not (sonic.player.panim == PA_ROLL) //checking if the players animation is it's spinning anim.
					sonic.state = S_PLAY_ROLL //force the player into a spinning state.
					end
				end
			end
			if sonic.player.bouncenumber == 1 //if it's currently on his first bounce
			and sonic.player.justchangedbouncenumber == 0 //if he hasnt left the ground yet
			and not (P_PlayerInPain(sonic.player)) //not hurt are you?
				sonic.player.justchangedbouncenumber = 1 //now he has!
				sonic.player.bouncenumber = 2 //set this to two!
				sonic.player.pflags = $1|PF_JUMPED //forcing the player into a jumping state.
				if (InWater == true)
					P_SetObjectMomZ(sonic, 11*FRACUNIT)
					sonic.state = S_PLAY_ROLL //force the player into a spinning state.					
				else
					P_SetObjectMomZ(sonic, 16*FRACUNIT)
				if not (sonic.player.panim == PA_ROLL) //checking if the players animation is it's spinning anim.
					sonic.state = S_PLAY_ROLL //force the player into a spinning state.
					end
				end
			end
			if sonic.player.bouncenumber == 2 //if it's currently on his second bounce
			and sonic.player.justchangedbouncenumber == 0 //if he hasnt left the ground yet
			and not (P_PlayerInPain(sonic.player)) //not hurt are you?
				
				sonic.player.justchangedbouncenumber = 1 //now he has!
				sonic.player.bouncenumber = 0 //set it back to zero
				sonic.state = S_PLAY_SPRING //change to spring frame, like is SLW!
				if (InWater == true)
					P_SetObjectMomZ(sonic, 13*FRACUNIT)
				else
					P_SetObjectMomZ(sonic, 18*FRACUNIT)
				sonic.player.pflags = $1 & ~PF_JUMPED // No longer jumping. Don't land on an enemy!
				end
			end
			sonic.player.bounceattack = 0 //set it back to zero.
			sonic.player.usedown = 1 //set it to one.
			sonic.player.pflags = $1 & ~PF_THOKKED //uncheck the thokked flag, allowing you to bounce again.
			S_StartSound(sonic, sfx_s3k44) //play a sound c:			
			
		end
		//some quick checks
		
		if sonic.player.bounceattack == 1 //checking our variable.
		and sonic.health //and you're alive
		and not (P_PlayerInPain(sonic.player)) //not hurt are you?
			P_SpawnThokMobj(sonic.player) //spawn the players thok object
			if not (sonic.player.panim == PA_ROLL) //checking if the players animation is it's spinning anim.
				sonic.state = S_PLAY_ROLL //force the player into a spinning state.
			end
			if (sonic.momz > (9000*P_MobjFlip(sonic))) // the player is going up...?  
				P_SetObjectMomZ(sonic, FixedMul(-35*FRACUNIT, sonic.scale)) //not anymore >.>
			end
		else 
			sonic.player.bounceattack = 0 //set it to 0
		end
		if sonic.player.bounceattack == 1 //checking if hes bouncing
			sonic.player.pflags = $1 & ~PF_SPINNING // you're no longer "spinning" if you were before
		end
		if not (sonic.player.pflags & PF_JUMPED) // if you are not actuallly jumping
			sonic.player.bounceattack = 0 //set this back to zero to be safe
		end
		
		if sonic.eflags & MFE_GOOWATER //is the player in THZ goop?
		or sonic.player.powers[pw_carry] //is the player being carried?
		//or sonic.player.pflags & PF_ROPEHANG //is the player on a ACZ ropehang?
			sonic.player.bounceattack = 0 //set to zero!
		end
		if not (sonic.player.pflags & PF_JUMPED) //if the player hasnt jumped
			sonic.player.bounceattack = 0 //set this to zero
		end
	end
end, MT_PLAYER)