//Spintwin, Thok and Float
addHook("JumpSpinSpecial", function(p)
	if p.mo.skin != "taz" then return end
	if (p.pflags & PF_SPINDOWN) then return end
	if p.mo.state == S_SPINTWIN 
	and p.floated != true 
	and p.wallbounces == 0
	and p.mo.momz >= -5*FRACUNIT 
	and p.mo.momz <= 5*FRACUNIT 
	and not (p.mo.eflags & MFE_GOOWATER)then
		S_StartSound(p.mo, sfx_tzft)
		P_SpawnGhostMobj(p.mo)
		p.mo.state = S_TAZFLOAT
		p.weapondelay = TICRATE/4*3
		p.floated = true
		p.zok = true
		p.wallbounce = false
		P_SpawnMobj(p.mo.x, p.mo.y, p.mo.z, MT_OTRAIL)
	elseif p.mo.state == S_PLAY_TWINSPIN
	and p.zok != true then
		P_SpawnGhostMobj(p.mo)
		S_StartSound(p.mo, sfx_tzok)
		p.mo.state = S_TAZTHOK
		p.normalspeed = FRACUNIT*36
		p.zok = true
		if p.powers[pw_super]
		or (p.tashnado != true 
		and p.wallbounces == 0) then
			P_InstaThrust(p.mo, p.mo.angle, 40*FRACUNIT)
			p.tashnado = true
		else
			P_InstaThrust(p.mo, p.mo.angle, 30*FRACUNIT)
		end
	else
		p.mo.state = S_SPINTWIN
		S_StartSound(p.mo, sfx_tzpn)
		if p.mo.eflags & MFE_GOOWATER then
			P_SetObjectMomZ(p.mo, p.mo.momz-FRACUNIT*2)
		end
	return true
	end
end)

//Float alternate input
addHook("AbilitySpecial", function(p)
	if p.mo.skin != "taz" then return end 
	if (p.pflags & PF_JUMPDOWN) then return end
	if p.mo.state == S_SPINTWIN 
	and p.floated != true 
	and p.mo.momz >= -5*FRACUNIT 
	and p.mo.momz <= 5*FRACUNIT 
	and not (p.mo.eflags & MFE_GOOWATER) then
		P_SpawnGhostMobj(p.mo)
		p.mo.state = S_TAZFLOAT
		S_StartSound(p.mo, sfx_tzft)
		p.weapondelay = TICRATE/4*3
		p.floated = true
		p.zok = true
		p.wallbounce = false
		P_SpawnMobj(p.mo.x, p.mo.y, p.mo.z, MT_OTRAIL)
	return true
	elseif p.mo.eflags & MFE_GOOWATER then
		P_SetObjectMomZ(p.mo, p.mo.momz+FRACUNIT)
	end
end)

//Wallbounce Wallslide Walljump
addHook("MobjMoveBlocked", function(mo,t,l)
    local player = mo.player
	if player and player.valid and player.mo.skin == "taz" then
		if not (player.mo.eflags & MFE_UNDERWATER) then
//Wall Crash
			if player.tazlide != 0 
			and player.speed > FRACUNIT*20 then
				player.tashnado = false
				player.tazwanted = false
				player.tazlide = 0
				player.height = FRACUNIT*48
				player.mo.momx = -player.mo.momx/7
				player.mo.momy = -player.mo.momy/7
				player.tazquished = true
				player.crashed = true
				player.pflags = $|PF_FULLSTASIS
				player.mo.state = S_TAZCRASHED
				S_StartSound(player.mo, sfx_tbnk)
				S_StartSound(player.mo, sfx_tsqsh)
				P_StartQuake(FRACUNIT*20, TICRATE/4)
			end
//Thok barrier check
			if l and l.valid then
				if (l.frontsector) and (l.frontsector.ceilingheight == l.frontsector.floorheight) and (mo.z > l.frontsector.ceilingheight) then return end
				if (l.backsector) and (l.backsector.ceilingheight == l.backsector.floorheight) and (mo.z > l.backsector.ceilingheight) then return end
			end
//Wall Bounce
			if (player.mo.state == S_SPINTWIN
			or (player.mo.state == S_TAZFLOAT
			and (player.pflags & PF_JUMPDOWN or player.pflags & PF_SPINDOWN)))
			and player.speed > FRACUNIT*9
			and player.wallbounce != true
			and player.wallbounces != 5
			and l and l.valid then
				player.laztwall = l
				player.pflags = $&~PF_STARTJUMP
				player.normalspeed = FRACUNIT*36
				player.wallmomx = player.mo.momx
				player.wallmomy = player.mo.momy
				player.wallbounce = true
				player.wallbounces = $+1
				player.zok = false
				if not (player.mo.flags2 & MF2_OBJECTFLIP)
				and not (player.mo.eflags & MFE_VERTICALFLIP)then
					P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_OTRAIL)
					player.mo.state = S_TRIPLETSPIN
					if player.mo.momz >= -2*FRACUNIT then
						P_SetObjectMomZ(player.mo, FRACUNIT*12, false)
					else
						P_SetObjectMomZ(player.mo, FRACUNIT*5, false)
					end
				elseif player.mo.flags2 & MF2_OBJECTFLIP
				or player.mo.eflags & MFE_VERTICALFLIP then 
					if player.mo.momz <= FRACUNIT*2 then
						P_SetObjectMomZ(player.mo, FRACUNIT*12, false)
					else
						P_SetObjectMomZ(player.mo, FRACUNIT*5, false)
					end
				end
			else
				player.wallbounce = false
			end
//Wall Slide by KirbTheKorb, from: Extra spicy momentum! (modified a bit) TY Kirb!
			if (player.pflags & PF_SPINNING
			or player.tazwanted == true)
			and player.mo.state != S_TAZFLOAT
			and player.mo.state != S_SPINTWIN
			and player.mo.state != S_TAZTHOK
			and player.mo.state != S_TRIPLETSPIN
			and player.mo.state != S_PLAY_TWINSPIN 
			and player.tazlide == 0
			and l and l.valid then
				if player.tazwall != true then
					player.weapondelay = TICRATE/4*3
				end
				if player.weapondelay 
				and player.speed >= 10 then
					player.tazwall = true
					player.charability = CA_TWINSPIN
					if (player.mo.momz < 1
					and not (player.mo.flags2 & MF2_OBJECTFLIP)
					and not (player.mo.eflags & MFE_VERTICALFLIP))
					or (player.mo.momz > -1
					and (player.mo.flags2 & MF2_OBJECTFLIP
					or player.mo.eflags & MFE_VERTICALFLIP)) then
						if P_IsObjectOnGround(player.mo) then
							if player.speed >= 17 then
								if player.pflags & PF_SPINNING then
									P_SetObjectMomZ(player.mo, player.speed/5, true)
								else
									P_SetObjectMomZ(player.mo, player.speed/4, true)
								end
							end
						else
							if player.pflags & PF_SPINNING then
								P_SetObjectMomZ(player.mo, player.speed/5, true)
							else
								P_SetObjectMomZ(player.mo, player.speed/4, true)
							end
						end
					end
				end
			end
//Wall Jump
			if player.cmd.buttons & BT_JUMP
			and player.tazwall == true 
			and l and l.valid then
				player.pflags = $&~PF_JUMPED
				player.jumpfactor = 11*FRACUNIT/10
				P_DoJump(player)
				P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_OTRAIL)
				player.tazwall = false
				local fart = (P_RandomRange(1, 3))
				if fart == 1 then
					S_StartSound(player.mo, sfx_fart)
				elseif fart == 2 then
					S_StartSound(player.mo, sfx_fart2)	
				end
			end
		end
	end
end,MT_PLAYER)
addHook("MobjMoveCollide", function(m,t)
	if m.valid and m.player.mo.skin == "taz" then
//Wall Crash
		if m.z - m.scale <= t.z + t.height
		and m.z + m.height + m.scale >= t.z then
			if t and t.valid and t.flags & MF_MONITOR 
			and t.target 
			and t.info.deathstate == S_BOX_POP1 then
			return false
			end
			if t and t.valid and t.flags & MF_MONITOR 
			and m.player.tazlide != 0 
			and not t.target 
			and t.info.deathstate  == S_BOX_POP1 then
			t.target = m.player.mo
			t.state = t.info.deathstate
			return false
			end
		end
	end
end,MT_PLAYER)