freeslot("MT_STOMPER", "S_STOMPER", "SPR_STMP")
mobjinfo[MT_STOMPER] = {
	spawnstate = S_STOMPER,
	flags = MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY|MF_NOBLOCKMAP,
	dispoffset = 1,
	radius = FU,
	height = FU
}
states[S_STOMPER] = {
	sprite = SPR_STMP,
	frame = FF_FULLBRIGHT|FF_ADD|FF_ANIMATE,
	var1 = 3,
	var2 = 1,
	tics = -1
}
local stmpbtn = {
    [0] = BT_SPIN,
    [1] = BT_CUSTOM1,
    [2] = BT_CUSTOM2,
    [3] = BT_CUSTOM3
}
addHook("PlayerThink", function(p)
	if not _G["stomp_enabled"] or p.menu_open or not (p.mo and p.mo.valid) then return end
	if p.stomp_cooldown == nil then p.stomp_cooldown = 0 end
	if p.stompbutton == nil then p.stompbutton = 1 end
	if p.stomp_cooldown > 0 then
		p.stomp_cooldown = $ - 1
	end
	local stomp = stmpbtn[p.stompbutton]
	if (p.cmd.buttons & stomp)
	and not (p.lastbuttons & stomp)
	and not P_IsObjectOnGround(p.mo)
	and not p.exiting
	and not p.stompin 
	and not (p.mo.eflags & MFE_SPRUNG)
	and not p.powers[pw_carry]
	and not P_IsObjectInGoop(p.mo)
	and not (P_PlayerInPain(p) or p.playerstate == PST_DEAD)
		p.mo.state = S_PLAY_FALL
		p.pflags = $|PF_JUMPED|PF_STASIS
		S_StartSound(p.mo, sfx_stm)	
		p.stompin = true
		p.stompeffect = false
		P_InstaThrust(p.mo, 0,0)
		P_SetObjectMomZ(p.mo, -25*FRACUNIT, false)
		p.powers[pw_strong] = STR_ANIM|STR_FLOOR|STR_SPRING
	end
end)


addHook("PlayerThink", function(player)
	if not (player.mo and player.mo.valid) or player.stompin ~= true then return end
	local vfxColor = player.chosenbvfxcolor or player.mo.color
	player.mo.state = S_PLAY_FALL
	player.pflags = $|PF_STASIS
	P_InstaThrust(player.mo, 0, 0)
	StompVfx(player)
	if FixedHypot(player.mo.momx, player.mo.momy) > 0 then
		player.mo.momx = $ - ($/40)
		player.mo.momy = $ - ($/40)
	else
		player.mo.momx = 0
		player.mo.momy = 0
	end
	if player.mo.momz <= -25*FRACUNIT then P_SetObjectMomZ(player.mo, -FRACUNIT, true)
	else P_SetObjectMomZ(player.mo, -25*FRACUNIT, false)
	end
end)





addHook("PostThinkFrame", function()
    for player in players.iterate do
	if not (player and player.valid) then continue end
	if player.stompin == true then
	if player.stompeffect == false then
		local stompeffect = P_SpawnMobjFromMobj(player.mo, 0,0,0, MT_STOMPER)
		stompeffect.colorized = true
		stompeffect.color = player.chosenbvfxcolor or player.mo.color
		stompeffect.blendmode = AST_ADD
		stompeffect.frame = $|FF_FULLBRIGHT|FF_TRANS40
		stompeffect.scale = FRACUNIT*6/7
		stompeffect.target = player.mo
		stompeffect.tics = -1
		stompeffect.momz = player.mo.momz
		stompeffect.momx = player.mo.momx
		stompeffect.momy = player.mo.momy
		player.stompeffect = true
		P_MoveOrigin(stompeffect, player.mo.x, player.mo.y, player.mo.z)
end
end
end
end)



rawset(_G, "StompVfx", function(player)
    if not (player and player.valid and player.mo and player.mo.valid) then return end
    local vfxColor = player.chosenbvfxcolor or player.mo.color
local stmpe = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z-player.mo.height , MT_THOK)
    if stmpe and stmpe.valid then
        stmpe.colorized = true
        stmpe.blendmode = AST_ADD
        stmpe.sprite = SPR_VAST
        stmpe.frame = (leveltime*2 % 4) | FF_TRANS60 | FF_FULLBRIGHT
        stmpe.tics = 5
        stmpe.tracer = player.mo
        stmpe.destscale = FRACUNIT/3
        stmpe.scale = FRACUNIT*3
        stmpe.color = vfxColor
    end   
	local trail = P_SpawnGhostMobj(player.mo)
    if trail and trail.valid then
        trail.tics = 9
        trail.blendmode = AST_ADD
        trail.frame = $|FF_FULLBRIGHT
        P_MoveOrigin(trail, player.mo.x, player.mo.y, player.mo.z)
        trail.color = vfxColor
    end   
	local adventurerip2 = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_THOK)
    if adventurerip2 and adventurerip2.valid then
        adventurerip2.colorized = true
        adventurerip2.blendmode = AST_ADD
        adventurerip2.sprite = SPR_TMPE
        adventurerip2.frame = (leveltime*2 % 4) | FF_TRANS60 | FF_FULLBRIGHT
        adventurerip2.tics = 5
        adventurerip2.tracer = player.mo
        adventurerip2.destscale = FRACUNIT/3
        adventurerip2.scale = FRACUNIT
        adventurerip2.rollangle = player.mo.rollangle + FixedMul(player.mo.momz, sin(player.mo.angle - (player.mo.momx + player.mo.momy)))
        adventurerip2.angle = player.drawangle
        adventurerip2.color = vfxColor
    end
    local sparkle = P_SpawnMobj(player.mo.x+P_RandomRange(-20, 20)*player.mo.scale, player.mo.y+P_RandomRange(-30, 30)*player.mo.scale, player.mo.z+P_RandomRange(-30, 0)*player.mo.scale+player.mo.height, MT_WATERZAP)
    if sparkle and sparkle.valid then
        sparkle.flags2 = $|MF2_OBJECTFLIP
        sparkle.colorized = true
        sparkle.state = S_BOOST_SPARK
        sparkle.scale = FRACUNIT/3
        sparkle.destscale = -2
        sparkle.blendmode = AST_ADD
        sparkle.tics = 20
        sparkle.color = vfxColor
    end
end)

addHook("MobjThinker", function(mo)
	if mo and mo.valid then
		local pmo = mo.target
		if pmo and pmo.valid then
			P_MoveOrigin(mo, pmo.x, pmo.y, pmo.z)
			if P_IsObjectOnGround(pmo)  or pmo.state ~= S_PLAY_FALL or P_IsObjectInGoop(pmo) then P_KillMobj(mo) end
		else P_KillMobj(mo) end
	end
end, MT_STOMPER)


addHook("PlayerThink", function(player)
	if player.mo and player.mo.valid and player.stompin and (player.mo.eflags & MFE_JUSTHITFLOOR) then
		S_StartSound(player.mo, sfx_lan)
		player.stomp_cooldown = 12
		local dashpart1 = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z - player.mo.height, MT_BOOSTVFX) 
		dashpart1.tics = 10
		dashpart1.blendmode = AST_ADD
		dashpart1.momx = 0
		dashpart1.momy = 0
		dashpart1.colorized = true
		dashpart1.destscale = FRACUNIT*7
		dashpart1.scale = FRACUNIT*7/2
		dashpart1.scalespeed = FRACUNIT/3
		dashpart1.momz = 0
		dashpart1.frame = $|FF_FLOORSPRITE
		dashpart1.color = player.chosenbvfxcolor or player.mo.color
		P_Telekinesis(player, 25*FRACUNIT, 175*FRACUNIT)
		player.stompin = false
		player.stompeffect = false
		player.pflags = $ & ~PF_SPINNING
		player.mo.state = S_PLAY_STND
	end
end)

local function SpringRollCollide(mo, inf)
	if not (mo and mo.valid) or not (inf and inf.valid) then return end
	if not mo.player then return end
	if mo.momz >= 0 then return end
	local playerisstomping = (mo.state == S_PLAY_FALL) or (mo.player.stompin == true)
	if not playerisstomping then return end
	local isSpring = ((inf.flags & MF_SPRING) ~= 0) 
	if not isSpring then return end
	local is_above = (mo.z + (mo.height / 4) >= inf.z)
	local within_height_reach = (mo.z <= inf.z + inf.height + (12 * FRACUNIT)) 
	if is_above and within_height_reach then
		local dist2D = P_AproxDistance(mo.x - inf.x, mo.y - inf.y)
		if dist2D <= (inf.radius * 2) then
			mo.player.stompin = false
			mo.player.stompeffect = false
			mo.player.springed = true
			mo.momx = 0
			mo.momy = 0
		end
	end
end

addHook("MobjMoveCollide", SpringRollCollide, MT_PLAYER)



addHook("PlayerThink", function(p)
	if p.powers[pw_justsprung] or (p.mo and p.mo.valid and (p.mo.eflags & MFE_SPRUNG)) then p.springed = true end
	if P_IsObjectOnGround(p.mo) and p.springed then p.springed = false end
	if p.mo and p.mo.valid and p.mo.state == S_PLAY_FALL and P_IsObjectInGoop(p.mo) then
		p.stompin = false
		p.stompeffect = false
	end
	if p.mo and p.mo.valid and p.stompin and P_IsObjectOnGround(p.mo) and p.springed then
		p.stompin = false
	end
end)
addHook("PlayerThink", function(p)
	if p.mo and p.mo.valid and p.stompin == true then
		if P_IsObjectOnGround(p.mo) and p.springed then p.stompin = false end
	end
end)



addHook("PlayerThink", function(p)
if p.powers[pw_carry] == 3888 then
p.stompin = false
end
end)



addHook("PlayerThink", function(p)
if p.mo.momz >= 1 then
p.stompin = false
end
end)

