if srb2p return end

addHook("AbilitySpecial", function(player)
    if player.mo and player.mo.skin == "silverp" 
	and player.pflags & PF_JUMPED 
	and not(player.pflags & PF_THOKKED)
	and not(player.mo.state == S_PLAY_ROLL) 
		player.mo.flaretimer = 20
		S_StartSound(player.mo, sfx_thok)
	end
end)

local function DashModeSpeed(mo, trailmo, freq)
    if not mo.prevz or not mo.prevleveltime or (mo.prevleveltime ~= leveltime - 1) then
       mo.prevz = mo.z
    end
    local rmomz = mo.z - mo.prevz
    mo.prevz = mo.z
    mo.prevleveltime = leveltime
    local mospeed = R_PointToDist2(0, 0, R_PointToDist2(0, 0, mo.momx, mo.momy), rmomz)
    local dist = (mospeed/freq)
    for i = dist, 1, -1 do
        local spawnedmo = P_SpawnMobjFromMobj(mo, (mo.momx/dist)*i, (mo.momy/dist)*i, (rmomz/dist)*i, trailmo)
        spawnedmo.color = SKINCOLOR_ORANGE
        spawnedmo.blendmode = AST_ADD
		spawnedmo.frame = FF_TRANS50
    end
end

addHook("ThinkFrame", do
	for player in players.iterate
		if player.mo and player.mo.skin == "silverp"
			if not (player.mo.flaretimer)
				player.mo.flaretimer = 0
			end
			if player.mo.flaretimer > 0
				player.mo.flaretimer = $1 - 1
			end
			if player.mo.flaretimer > 1
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				player.mo.state = S_PLAY_GLIDE
				local firefloat = P_SpawnMobj(player.mo.x+P_RandomRange(-10,10)*FRACUNIT,player.mo.y+P_RandomRange(-10,10)*FRACUNIT,player.mo.z+player.mo.height-15*FRACUNIT+P_RandomRange(-10,10)*FRACUNIT, MT_SPINDUST)
				firefloat.state = S_SPINFIRE1
				firefloat.fuse = 7
				firefloat.scale = player.mo.scale/2
				player.pflags = $1|PF_THOKKED
				player.pflags = $1 & ~PF_SPINNING
				player.mo.floatspindash = 0
				local trail = P_SpawnGhostMobj(player.mo)
				for i = 0,9
					trail.fuse = 9
					trail.color = SKINCOLOR_SALMON
					trail.colorized = true
					trail.blendmode = AST_ADD
					trail.scale = FRACUNIT - (i * FRACUNIT/240)
					trail.destscale = 0
				end
				if (player.cmd.buttons & BT_JUMP)
					player.mo.momz = 0
				else 
					player.mo.flaretimer = 1
				end
			end
			if player.mo.flaretimer == 1
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				player.mo.state = S_PLAY_JUMP
				S_StartSound(player.mo, sfx_s23c)
				if (player.cmd.buttons & BT_JUMP)
					if player.powers[pw_super]
						P_SetObjectMomZ(player.mo, 29*FRACUNIT, false)
						P_SpawnParaloop(player.mo.x,player.mo.y,player.mo.z,player.mo.scale*52,22,MT_SPINFIRE,ANGLE_90,nil,true)
					elseif (player.mo.eflags & MFE_UNDERWATER)
						P_SetObjectMomZ(player.mo, 8*FRACUNIT, false)
						P_SpawnParaloop(player.mo.x,player.mo.y,player.mo.z,player.mo.scale*52,22,MT_MEDIUMBUBBLE,ANGLE_90,nil,true)
					else
						P_SetObjectMomZ(player.mo, 19*FRACUNIT, false)
						P_SpawnParaloop(player.mo.x,player.mo.y,player.mo.z,player.mo.scale*52,22,MT_SPINFIRE,ANGLE_90,nil,true)
					end
				end
				if not (player.cmd.buttons & BT_JUMP)
					if player.powers[pw_super]
						P_SetObjectMomZ(player.mo, 29*FRACUNIT/2, false)
						P_SpawnParaloop(player.mo.x,player.mo.y,player.mo.z,player.mo.scale*52,22,MT_SPINFIRE,ANGLE_90,nil,true)
					elseif (player.mo.eflags & MFE_UNDERWATER)
						P_SetObjectMomZ(player.mo, 8*FRACUNIT/2, false)
						P_SpawnParaloop(player.mo.x,player.mo.y,player.mo.z,player.mo.scale*52,22,MT_MEDIUMBUBBLE,ANGLE_90,nil,true)
					else
						P_SetObjectMomZ(player.mo, 19*FRACUNIT/2, false)
						P_SpawnParaloop(player.mo.x,player.mo.y,player.mo.z,player.mo.scale*52,22,MT_SPINFIRE,ANGLE_90,nil,true)
					end
				end
			end
			if not (player.mo.punchtimer)
				player.mo.punchtimer = 0
			end
			if player.mo.punchtimer > 0
				player.mo.punchtimer = $1 - 1
			end
			if player.mo.punchtimer > 1
			and (P_IsObjectOnGround(player.mo))
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				player.drawangle = player.mo.angle
				local ghost = P_SpawnGhostMobj(player.mo)
				ghost.color = player.mo.color
				ghost.fuse = 4
				ghost.colorized = true
				player.charflags = $|SF_CANBUSTWALLS
				player.mo.state = S_PLAY_RUN
				P_SpawnSkidDust(player, 18*FRACUNIT, sfx_none)
				player.mo.momx = 0
				P_InstaThrust(player.mo, player.mo.angle, player.speed+2)
			end
			if player.mo.punchtimer == 1
			and player.playerstate == PST_LIVE
				player.charflags = $ & ~SF_CANBUSTWALLS
			end
			if not (player.mo.floatspindash)
				player.mo.floatspindash = 0
			end
			if player.mo.floatspindash > 0
				player.mo.floatspindash = $1 - 1
			end
			if player.mo.floatspindash > 1
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				A_Thrust(player.mo, 0, 1)
				player.mo.momz = 0
				player.mo.momy = 0
				player.mo.momx = 0
				player.mo.flaretimer = 0
			end
			if player.mo.floatspindash > 1
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				player.mo.state = S_PLAY_SPINDASH
			end
			if player.mo.floatspindash > 10
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				if (leveltime % 8 == 0)
					S_StartSound(player.mo, sfx_spin)
				end
			end
			if player.mo.floatspindash == 1
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				player.mo.state = S_PLAY_JUMP
				player.pflags = $1 & ~PF_JUMPED
				S_StartSound(player.mo, sfx_zoom)
				P_InstaThrust(player.mo, player.mo.angle, 50*FRACUNIT)
				if (player.mo.eflags & MFE_UNDERWATER)
					P_SetObjectMomZ(player.mo, 8*FRACUNIT, false)
				else
					P_SetObjectMomZ(player.mo, 19*FRACUNIT, false)
				end
			end
			if (player.mo.state == S_PLAY_RUN or player.mo.state == S_PLAY_DASH)
			and player.speed > 14*player.mo.scale
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				local firefloat = P_SpawnMobj(player.mo.x+P_RandomRange(-10,10)*FRACUNIT,player.mo.y+P_RandomRange(-10,10)*FRACUNIT,player.mo.z+player.mo.height-15*FRACUNIT+P_RandomRange(-10,10)*FRACUNIT, MT_SPINDUST)
				firefloat.state = S_SPINFIRE1
				firefloat.fuse = 7
				firefloat.scale = player.mo.scale/2
			end
			if not player.powers[pw_extralife]
			and not (player.exiting)
				if player.powers[pw_super] then
					S_ChangeMusic("silverb",true,player)
				end	
			else
				P_RestoreMusic(player)
			end
			if player.powers[pw_super]
			and player.rings == 1
				P_KillMobj(player.mo)
			end
			if player.playerstate == PST_DEAD then
				player.mo.flags = $ & ~MF_NOCLIP
				player.mo.flags = $ & ~MF_NOCLIPHEIGHT
			end
			if (player.cmd.buttons & BT_CUSTOM1) 
			and not player.weapondelay 
			and P_IsObjectOnGround(player.mo) 
			and not (player.pflags & PF_SLIDING) 
			and not (player.pflags & PF_FINISHED)
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				player.mo.punchtimer = 8
				player.weapondelay = 15
				player.mo.state = S_PLAY_RUN
				S_StartSound(player.mo, sfx_ssbst)
			end
			if (player.cmd.buttons & BT_CUSTOM2) 
			and not player.weapondelay 
			and (player.mo.state == S_PLAY_JUMP)
			and not (player.prevuse)
			and not (player.prevclimbing)
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				player.mo.floatspindash = 89
				player.weapondelay = 6*TICRATE
				player.mo.state = S_PLAY_GLIDE
			end
			if (player.cmd.buttons & BT_CUSTOM3) 
			and not player.weapondelay
			and not (player.pflags & PF_FINISHED)
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				S_StartSound(player.mo, sfx_ssarm)
				P_SPMAngle(player.mo, MT_SILVERSONICARM, player.drawangle, 0)
				player.weapondelay = 15
				player.mo.state = S_PLAY_SILVERSONIC_ARM
				player.pflags = $1 & ~PF_SPINNING
				player.pflags = $1 & ~PF_JUMPED
				player.pflags = $1 & ~PF_THOKKED
				player.pflags = $1 & ~PF_SPINDOWN
				player.pflags = $1 & ~PF_STARTDASH
			end
			if not player.dashmode
				player.pflags = $1 & ~PF_DRILLING
			end
			if player.dashmode > 3*TICRATE
			and not (player.mo.state == S_PLAY_SPINDASH)
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				player.pflags = $|PF_DRILLING
				if (leveltime % 59 == 0)
					S_StartSound(player.mo, sfx_s3ka1)
				end
			end
			if player.dashmode > 3*TICRATE
			and not (player.mo.state == S_PLAY_SPINDASH)
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				local boost = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_THOK)
				boost.color = SKINCOLOR_ORANGE
				boost.colorized = true
				boost.sprite = SPR_FIRS
				boost.frame = S|FF_TRANS70
				boost.angle = player.mo.angle
				boost.fuse = 2
				boost.blendmode = AST_ADD
				boost.scalespeed = FRACUNIT/35
			end
			if player.dashmode > 3*TICRATE
			and not (player.mo.state == S_PLAY_SPINDASH)
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				local aura = P_SpawnMobjFromMobj(player.mo, 0, 0, 0, MT_THOK)
				for i = 0,9
					aura.target = player.mo
					aura.scale = FRACUNIT - (i * FRACUNIT/370)
					aura.sprite = SPR_ARMA
					aura.color = SKINCOLOR_RED
					aura.colorized = true
					aura.fuse = 9
					aura.blendmode = AST_ADD
					aura.destscale = 0
					aura.scalespeed = FRACUNIT/15
				end
			end
			if player.dashmode > 3*TICRATE
			and not (player.mo.state == S_PLAY_SPINDASH)
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				A_BossScream(player.mo, 0, MT_WATERZAP)
			end
			if (player.pflags & PF_SPINNING)
			and P_IsObjectOnGround(player.mo) 
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				DashModeSpeed(player.mo, MT_THOK, 4*FRACUNIT)
			end
			if player.dashmode > 3*TICRATE
			and not (player.mo.state == S_PLAY_SPINDASH)
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				if (leveltime % 3) == 1
					local thok = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_THOK)
					thok.state = S_FACESTABBERSPEAR
					thok.angle = player.drawangle+ANGLE_90
					thok.scale = player.mo.scale/2+FRACUNIT/4
					thok.fuse = 8
					thok.color = SKINCOLOR_ORANGE
					thok.colorized = true
					thok.blendmode = AST_ADD
				end
			end
			if player.playerstate == PST_DEAD
			and player.deadtimer == 48
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				player.mo.flags2 = $1|MF2_DONTDRAW
				player.mo.momx = 0
				player.mo.momy = 0
				player.mo.momz = 0
				player.mo.flags = $ & ~MF_NOCLIP
				player.mo.flags = $ & ~MF_NOCLIPHEIGHT
				player.mo.state = S_NULL
				P_SpawnParaloop(player.mo.x, player.mo.y, player.mo.z, 64*FRACUNIT, 32,	MT_NIGHTSPARKLE, ANGLE_90, S_NIGHTSPARKLE1, true)
				P_SpawnParaloop(player.mo.x, player.mo.y, player.mo.z, 64*FRACUNIT, 32, MT_NIGHTSPARKLE, 0, S_NIGHTSPARKLE1, true)
				P_SpawnParaloop(player.mo.x, player.mo.y, player.mo.z, 64*FRACUNIT, 32, MT_NIGHTSPARKLE, ANGLE_45, S_NIGHTSPARKLE1, true)
			end
			if player.powers[pw_super]
				if (leveltime % 8 == 0)
					local supersilverparticles = P_SpawnMobj(player.mo.x-P_RandomRange(-51, 51)*player.mo.scale, player.mo.y+P_RandomRange(-51, 51)*player.mo.scale, player.mo.z+10*player.mo.scale, MT_THOK)
					supersilverparticles.eflags = player.mo.eflags
					supersilverparticles.blendmode = AST_ADD
					P_SetObjectMomZ(supersilverparticles, 4*FRACUNIT)
					supersilverparticles.state = S_WATERZAP
					supersilverparticles.scale = player.mo.scale/3
					supersilverparticles.fuse = 10				
					supersilverparticles.scalespeed = $/3
					supersilverparticles.destscale = $*99
					local supersilverparticles2 = P_SpawnMobj(player.mo.x-P_RandomRange(-51, 51)*player.mo.scale, player.mo.y+P_RandomRange(-51, 51)*player.mo.scale, player.mo.z+10*player.mo.scale, MT_PARTICLE)
					supersilverparticles2.eflags = player.mo.eflags
					supersilverparticles2.blendmode = AST_ADD
					P_SetObjectMomZ(supersilverparticles2, 4*FRACUNIT)
					supersilverparticles2.scale = player.mo.scale/3
					supersilverparticles2.fuse = 10				
					supersilverparticles2.scalespeed = $/3
					supersilverparticles2.destscale = $*99
				end
			end
			if player.pflags & PF_SPINNING
			and not (player.pflags & PF_STARTDASH)
			and P_IsObjectOnGround(player.mo) then
				if player.cmd.forwardmove ~= 0
				or player.cmd.sidemove ~= 0
				or player.camangle == nil
				or player.mo.eflags & MFE_SPRUNG then
					player.camangle = player.cmd.angleturn<<16 + R_PointToAngle2(0, 0, player.cmd.forwardmove*FRACUNIT, -player.cmd.sidemove<<16)
				end
				player.movespd = R_PointToDist2(player.mo.x, player.mo.y, player.mo.x + player.mo.momx, player.mo.y + player.mo.momy)
				P_InstaThrust(player.mo,R_PointToAngle2(player.mo.x - player.mo.momx,player.mo.y - player.mo.momy,player.mo.x + P_ReturnThrustX(player.mo,player.camangle,player.movespd),player.mo.y + P_ReturnThrustY(player.mo,player.camangle,player.movespd)),player.movespd)
			else
				player.camangle = nil
			end
		end
	end
end)

addHook("SpinSpecial", function(player)
	if (player.mo.skin == "silverp")
	and player.playerstate == PST_LIVE
	and player.playerstate == PST_LIVE
		and not P_PlayerInPain(player)
		if (player.pflags & PF_STARTDASH)
			if player.dashmode > 3*TICRATE
				if (leveltime % 70 == 10)
					S_StartSound(player.mo, sfx_s3k5a)
				end
			end
		end
	end
end)

addHook("MobjThinker", function(mobj)
	local player = mobj.player
	if (player.mo and player.mo.skin == "silverp")
	and player.playerstate == PST_LIVE
	and not P_PlayerInPain(player)
		if (player.pflags & PF_JUMPED)
		and not (player.pflags & PF_THOKKED)
		and (player.cmd.buttons & BT_USE)
		and not (player.prevuse)
		and not (player.mo.state == S_PLAY_ROLL or player.mo.state == S_PLAY_SPINDASH)
		and not (player.prevclimbing)
			player.powers[pw_nocontrol] = 1
			player.pflags = $1|PF_THOKKED
			player.bellybounce = true
			player.mo.state = S_PLAY_ROLL	// Temp
			S_StartSound(player.mo, sfx_s3k51)
		end
		if (player.bellybounce)
		and (P_IsObjectOnGround(player.mo))
			player.pflags = $1 & ~PF_THOKKED
			player.pflags = $1|PF_JUMPED
			player.bellybounce = false
			player.mo.state = S_PLAY_ROLL
			S_StartSound(player.mo, sfx_s3k77)
			if (player.mo.eflags & MFE_UNDERWATER)
				player.mo.momz = FixedMul(player.mo.momz, FixedDiv(117*FRACUNIT, 200*FRACUNIT))
				P_SetObjectMomZ(player.mo, 6*FRACUNIT, false)
			else
				P_SetObjectMomZ(player.mo, 12*FRACUNIT, false)
			end
		end
		if (player.bellybounce)
			DashModeSpeed(player.mo, MT_THOK, 4*FRACUNIT)
			P_SetObjectMomZ(player.mo, -44*FRACUNIT, false)
		end
		if (player.bellybounce)
			if (player.mo.eflags & MFE_GOOWATER)
				player.bellybounce = false
			end
		end
		if (player.bellybounce)
			if not(player.pflags & PF_JUMPED)
				player.bellybounce = false
			end
		end
		player.prevuse = player.cmd.buttons & BT_USE
		player.prevclimbing = player.climbing
	end
end, MT_PLAYER)

addHook("MobjMoveBlocked", function(mo)
	if (mo and mo.player and mo.valid and mo.skin == "silverp")
	and mo.player.playerstate == PST_LIVE
	and not mo.player.exiting
	and G_PlatformGametype()
	and not (mo.player.pflags & PF_SPINNING)
    	if not (mo.flags2 & MF2_TWOD)
			P_BounceMove(mo)
			P_InstaThrust(mo, R_PointToAngle2(0, 0, mo.momx, mo.momy), 24*FRACUNIT)
			S_StartSound(mo, sfx_rebund)
			mo.punchtimer = 0
		end
	end
end, MT_PLAYER)

local function SuperKill(touchedmobj, mobj)
	local player = mobj.player
	if not player return end
	if mobj.z + mobj.height < touchedmobj.z return end
	if mobj.z > touchedmobj.z return end
	if (player.mo.skin == "silverp")
	and (touchedmobj.flags & (MF_ENEMY|MF_MONITOR))
	and player.powers[pw_super]
		S_StartSound(player.mo, sfx_s3k49, player)
		P_KillMobj(touchedmobj, mobj, mobj)
		return true
	end
end

addHook("MobjCollide", SuperKill)

local function PunchKillSound(touchedmobj, mobj)
	local player = mobj.player
	if not player return end
	if mobj.z + mobj.height < touchedmobj.z return end
	if mobj.z > touchedmobj.z return end
	if (player.mo.skin == "silverp")
	and (touchedmobj.flags & (MF_ENEMY|MF_BOSS))
	and (player.mo.state == S_PLAY_ROLL)
		S_StartSound(player.mo, sfx_s3k49, player)
		P_DamageMobj(touchedmobj, mobj, mobj)
		return true
	elseif (player.mo.skin == "silverp")
	and (touchedmobj.flags & (MF_MONITOR))
	and (player.mo.state == S_PLAY_ROLL)
		P_KillMobj(touchedmobj, mobj, mobj)
		S_StartSound(player.mo, sfx_s3k49, player)
		return true
	end
end

addHook("MobjCollide", PunchKillSound)