freeslot(
	"SPR2_HAMR",
	"MT_HAMMERSHIELD",
	"S_HAMMERSHIELD1",
	"S_HAMMERSHIELD2",
	"S_PLAY_HAMMERSHIELD",
	"S_PLAY_HAMMERSHIELD_LAND",
	"SKINCOLOR_CLASSICPASSION",
	"SKINCOLOR_SUPER_CPASSION1",
	"SKINCOLOR_SUPER_CPASSION2",
	"SKINCOLOR_SUPER_CPASSION3",
	"SKINCOLOR_SUPER_CPASSION4",
	"SKINCOLOR_SUPER_CPASSION5"
	//"sfx_hmrlnd"
)

mobjinfo[MT_HAMMERSHIELD] = {
	doomednum = -1,
	spawnhealth = 1,
	spawnstate = S_HAMMERSHIELD1,
	deathstate = S_HAMMERSHIELD1,
	xdeathstate = S_HAMMERSHIELD1,
	radius = 42*FRACUNIT,
	height = 60*FRACUNIT,
	flags = MF_NOGRAVITY|MF_MISSILE
}

mobjinfo[MT_HAMMERSHIELD].name = "hammer shield"

states[S_HAMMERSHIELD1] = {SPR_NULL, 0, 1, A_CapeChase, 0, 0, S_HAMMERSHIELD2}
states[S_HAMMERSHIELD2] = {SPR_NULL, 0, 1, A_CapeChase, 0, 0, S_HAMMERSHIELD1}

states[S_PLAY_HAMMERSHIELD] = {SPR_PLAY, SPR2_HAMR, 1, nil, 0, 0, S_PLAY_HAMMERSHIELD}
states[S_PLAY_HAMMERSHIELD_LAND] = {SPR_PLAY, SPR2_MLEE, 2, nil, 0, 0, S_PLAY_HAMMERSHIELD_LAND}

spr2defaults[SPR2_HAMR] = SPR2_TWIN

skincolors[SKINCOLOR_CLASSICPASSION] = {
	name = "Classic_Passion",
	ramp = {0,252,176,176,177,178,178,179,202,203,204,204,205,206,207,186},
	invcolor = SKINCOLOR_PASTEL,
	invshade = 5,
	chatcolor = V_MAGENTAMAP,
	accessible = true
}

skincolors[SKINCOLOR_SUPER_CPASSION1] = {
	name = "Super Classic_Passion 1",
	ramp = {0,0,0,0,0,0,0,0,0,0,252,252,176,176,177,177},
	accessible = false
}

skincolors[SKINCOLOR_SUPER_CPASSION2] = {
	name = "Super Classic_Passion 2",
	ramp = {0,0,0,252,252,252,176,176,176,177,177,177,178,178,179,179},
	accessible = false
}

skincolors[SKINCOLOR_SUPER_CPASSION3] = {
	name = "Super Classic_Passion 3",
	ramp = {0,0,252,252,176,176,177,177,178,178,179,179,202,202,203,203},
	accessible = false
}

skincolors[SKINCOLOR_SUPER_CPASSION4] = {
	name = "Super Classic_Passion 4",
	ramp = {0,252,176,176,177,177,178,178,179,179,202,202,203,203,204,204},
	accessible = false
}

skincolors[SKINCOLOR_SUPER_CPASSION5] = {
	name = "Super Classic_Passion 5",
	ramp = {252,176,177,177,178,178,179,179,202,202,203,203,204,204,205,205},
	accessible = false
}

addHook("AbilitySpecial", function(player) //Hammer Shield
    if player.mo and player.mo.skin == "amy"
	and (player.playerstate == PST_LIVE)
	and not (player.pflags & PF_THOKKED)
		player.mo.state = S_PLAY_HAMMERSHIELD
		player.pflags = $1|PF_THOKKED
		player.pflags = $ & ~PF_SPINNING
		player.mo.hammershield = 1
		S_StartSound(player.mo, sfx_s3k42)
		//S_StartSound(player.mo, sfx_s25a)
		local hammer = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_HAMMERSHIELD)
		hammer.target = player.mo
		return true
    end 
end)

addHook("SpinSpecial", function(player) //Manual Hammer Rush
    if player.mo and player.mo.skin == "amy"
	and (P_IsObjectOnGround(player.mo))
	and (player.speed > 5)
	and (player.playerstate == PST_LIVE)
	and not (player.pflags & PF_THOKKED)
	and not (player.amydelay)
	and not (player.mo.hammerswingtimer)
		player.mo.state = S_PLAY_HAMMERSHIELD_LAND
		player.mo.hammerswingtimer = TICRATE + TICRATE/2
		player.amydelay = TICRATE*3
		S_StartSound(player.mo, sfx_s1ab)
		return false
    end 
end)

addHook("MobjThinker", function(mobj)
	local player = mobj.player
	
	if (player.mo.skin ~= "amy") return end
	
	if not (player.amydelay)
		player.amydelay = 0
	end
	
	if (player.amydelay > 0)
		player.amydelay = $ - 1
	end
	
	if (player.mo.state == S_PLAY_HAMMERSHIELD or player.mo.state == S_PLAY_HAMMERSHIELD_LAND)
		if (player.mo.state == S_PLAY_HAMMERSHIELD)
			player.panim = PA_ABILITY
		end
		if (player.mo.state == S_PLAY_HAMMERSHIELD_LAND)
			if (player.mo.hammerswingtimer <= 0)
				player.mo.state = S_PLAY_WALK
			end
			if not (P_IsObjectOnGround(player.mo))
				player.mo.state = S_PLAY_HAMMERSHIELD
				player.mo.hammerswingtimer = 0
			end
		end
		if SUBVERSION > 8
			player.charflags = $1|SF_CANBUSTWALLS
		else
			player.charability = CA_GLIDEANDCLIMB
		end
		player.charability2 = CA2_NONE
		local sectorthing = P_PlayerTouchingSectorSpecial(player, 0, 0)
		if sectorthing.valid then
			for fof in sectorthing.ffloors()
				if fof.valid and (fof.flags & FF_BUSTUP) and (fof.flags & FF_EXISTS)
				and not (tracer and tracer.type == MT_TUBEWAYPOINT)
				and not player.powers[pw_carry]
				and (abs(fof.topheight - player.mo.z) <= 30*player.mo.scale) then
					EV_CrumbleChain(player.sectorthing, fof)
				end
			end
		end
	else
		if SUBVERSION > 8
		    player.charflags = $ & ~SF_CANBUSTWALLS
		else
			player.charability = CA_TWINSPIN
		end
		if (player.speed > 5)
			player.charability2 = CA2_NONE
		else
			player.charability2 = CA2_SPINDASH
		end
	end
	
	if (player.mo.state == S_PLAY_HAMMERSHIELD_LAND)
		player.charflags = $1|SF_NOSKID
	else
		player.charflags = $ & ~SF_NOSKID
	end
	
	if not (player.mo.hammerswingtimer)
		player.mo.hammerswingtimer = 0
	end
	
	if (player.mo.hammerswingtimer > 0)
		player.mo.hammerswingtimer = $ - 1
		if (player.mo.state ~= S_PLAY_HAMMERSHIELD_LAND)
			player.mo.hammerswingtimer = 0
		end
	end
	
	if not (player.mo.hammerbounces)
		player.mo.hammerbounces = 0
	end
	
	if (player.mo.hammerbounces ~= 0) and (P_IsObjectOnGround(player.mo))
		player.mo.hammerbounces = 0
	end
	
	if (player.mo.hammershield == 1)
		if (P_IsObjectOnGround(player.mo))
		or (player.mo.eflags & MFE_JUSTHITFLOOR)
			if not (P_CheckDeathPitCollide(player.mo))
				player.mo.hammershield = 0
				if (player.pflags & PF_JUMPDOWN)
					player.mo.state = S_PLAY_HAMMERSHIELD_LAND
					player.mo.hammerswingtimer = TICRATE + TICRATE/2
					S_StartSound(player.mo, sfx_s3k8b)
					//S_StartSound(player.mo, sfx_hmrlnd)
					local speed
					if (player.powers[pw_sneakers] or player.powers[pw_super])
						speed = skins.amy.normalspeed*2
					else
						speed = skins.amy.normalspeed
					end
					if (player.speed < speed)
						P_InstaThrust(player.mo, player.drawangle, speed)
					else
						P_InstaThrust(player.mo, player.drawangle, player.speed)
					end
					local i = 0
		    		local throwang = -(2*ANG30)
		    		local xo = P_ReturnThrustX(player.mo, player.mo.angle, 16*player.mo.scale)
		    		local yo = P_ReturnThrustY(player.mo, player.mo.angle, 16*player.mo.scale)
		    		local zo = 6*player.mo.scale
		    		local mu = FixedMul(6*FRACUNIT, player.mo.scale)
		    		local mu2 = FixedHypot(player.mo.momx, player.mo.momy)
		    		local missile = nil
		    		if (mu2 < mu)
		    			mu2 = mu
		    	    end
		    		local ev = (50*FRACUNIT - (mu/25))/50
                
		    		while (i < 5)
		        		missile = P_SpawnMobjFromMobj(player.mo, xo, yo, zo, MT_LHRT)
		        		missile.target = player.mo
		        	    missile.angle = throwang + player.mo.angle
		        		P_Thrust(missile, player.drawangle + ANGLE_90,
		        		P_ReturnThrustY(missile, throwang, mu))
		        	    P_Thrust(missile, player.drawangle, mu2)
		        		P_SetObjectMomZ(missile, (4 + ((i&1)<<1))*FRACUNIT, true)
		        		missile.momz = $ + player.mo.pmomz
		        		missile.fuse = TICRATE/2
		        		missile.extravalue2 = ev

		        		i = $+1
		        		throwang = $+ANG30
					end
				end
			end
		end
		if (player.powers[pw_carry] == CR_NIGHTSMODE)
		or (player.powers[pw_carry] == CR_NIGHTSFALL)
		or (player.powers[pw_carry] == CR_ROPEHANG)
		or (player.powers[pw_carry] == CR_MACESPIN)
		or (player.powers[pw_carry] == CR_ZOOMTUBE)
		or (player.powers[pw_carry] == CR_MINECART)
		or (player.powers[pw_carry] == CR_ROLLOUT)
		or (player.powers[pw_carry] == CR_GENERIC)
		or (player.powers[pw_carry] == CR_PLAYER)
		or (player.powers[pw_justsprung])
		or P_PlayerInPain(player)
		or P_CheckDeathPitCollide(player.mo)
			player.mo.hammershield = 0
		end
	end
end, MT_PLAYER)

addHook("MobjThinker", function(hammer)
	if (hammer.target and hammer.target.valid)
		if (hammer.target.state ~= S_PLAY_HAMMERSHIELD)
			P_RemoveMobj(hammer)
		end
	end
end, MT_HAMMERSHIELD)

addHook("MobjCollide", function(hammer, missile)
	if (missile.z > hammer.z+hammer.height) or (hammer.z > missile.z+missile.height) return end
	if (hammer.state ~= S_PLAY_HAMMERSHIELD) return end
	if (missile.target ~= hammer)
		if (missile and missile.valid)
			if (missile.flags & MF_MISSILE)
				missile.momx = -missile.momx
				missile.momy = -missile.momy
				missile.momz = -missile.momz
				missile.target = hammer
				S_StartSound(hammer, sfx_tink)
			end
		end
	end
end, MT_PLAYER)

addHook("MobjCollide", function(hammer, missile)
	if (missile.z > hammer.z+hammer.height) or (hammer.z > missile.z+missile.height) return end
	if (missile.target ~= hammer.target)
		if (missile and missile.valid)
			if (missile.flags & MF_MISSILE)
				missile.momx = -missile.momx
				missile.momy = -missile.momy
				missile.momz = -missile.momz
				missile.target = hammer.target
				S_StartSound(hammer.target, sfx_tink)
			end
		end
	end
end, MT_HAMMERSHIELD)

local function HammerShieldDamage(hammer, mobj)
	if hammer.target.state ~= S_PLAY_HAMMERSHIELD return end
	if not (hammer.z-FixedMul(24*FRACUNIT, hammer.scale) > mobj.z+mobj.height) and not(mobj.z-FixedMul(24*FRACUNIT, hammer.scale) > hammer.z+hammer.height)
		if (mobj.valid and mobj.health and mobj ~= hammer.target and (mobj.flags & (MF_ENEMY|MF_BOSS|MF_MONITOR|MF_SHOOTABLE)))
			if not (CBW_Battle and mobj.player)
				if not (mobj.flags2 & MF2_FRET)
					if ((hammer.target.momz < 0) and not (hammer.target.eflags & MFE_VERTICALFLIP))
						if (hammer.target.hammerbounces < 1) and (hammer.target.player.pflags & PF_JUMPDOWN)
							S_StartSound(hammer.target, sfx_s3kae)
							P_SetObjectMomZ(hammer.target, -hammer.target.momz + 12*FRACUNIT)
							hammer.target.hammerbounces = $ + 1
						else
							P_SetObjectMomZ(hammer.target, -hammer.target.momz)
						end
					elseif ((hammer.target.momz > 0) and (hammer.target.eflags & MFE_VERTICALFLIP))
						if (hammer.target.hammerbounces < 1) and (hammer.player.pflags & PF_JUMPDOWN)
							S_StartSound(hammer.target, sfx_s3kae)
							P_SetObjectMomZ(hammer.target, hammer.target.momz - 12*FRACUNIT)
							hammer.target.hammerbounces = $ + 1
						else
							P_SetObjectMomZ(hammer.target, hammer.target.momz)
						end
					end
				end
				if (mobj.info.spawnhealth > 1)
					if not (mobj.flags2 & MF2_FRET)
						P_InstaThrust(hammer.target, hammer.target.player.drawangle, -hammer.target.player.speed)
					end
				end
			end
			if not (mobj.flags & MF_MONITOR)
				if (mobj.player and CBW_Battle) return end
				P_DamageMobj(mobj, hammer, hammer.target)
			else
				P_KillMobj(mobj, hammer, hammer.target)
			end
			if not (mobj.player)
				local type = MT_LHRT
				local actionspd
				local movang, ang, fa
				local v, h
				local i = 0

				actionspd = FixedMul(6*FRACUNIT, hammer.target.scale)

				fa = R_PointToAngle2(0, 0, hammer.target.momz, FixedHypot(hammer.target.momx, hammer.target.momy))
				movang = R_PointToAngle2(0, 0, hammer.target.momx, hammer.target.momy)
				ang = 0

				v = FixedMul(actionspd, sin(fa))
				h = actionspd - FixedMul(actionspd, cos(fa))

				while (i < 8)
					local side = actionspd - FixedMul(h, abs(sin(ang)))
					local xo = P_ReturnThrustX(nil, ang + movang, side)
					local yo = P_ReturnThrustY(nil, ang + movang, side)
					local zo = -FixedMul(sin(ang), v)
					local missile = P_SpawnMobj(hammer.target.x, hammer.target.y, hammer.target.height/2 + hammer.target.z, type)
					missile.target = hammer.target
					missile.destscale = $ * 2/3
					missile.scale = missile.destscale
					missile.angle = ang + movang
					missile.fuse = TICRATE/2
					missile.extravalue2 = (99*FRACUNIT)/100
					missile.momx = xo
					missile.momy = yo
					missile.momz = zo

					ang = $ + ANGLE_45
					i = $+1
				end
			end
		end
	else
		return nil
	end
end

addHook("MobjMoveCollide", HammerShieldDamage, MT_HAMMERSHIELD)
addHook("MobjCollide", HammerShieldDamage, MT_HAMMERSHIELD)

local function HammerShieldSwingDamage(hammer, mobj)
	if hammer.state ~= S_PLAY_HAMMERSHIELD and hammer.state ~= S_PLAY_HAMMERSHIELD_LAND return end
	if not (hammer.z-FixedMul(24*FRACUNIT, hammer.scale) > mobj.z+mobj.height) and not(mobj.z-FixedMul(24*FRACUNIT, hammer.scale) > hammer.z+hammer.height)
		if (mobj.valid and mobj.health and mobj ~= hammer and (mobj.flags & (MF_ENEMY|MF_BOSS|MF_MONITOR|MF_SHOOTABLE)))
			if (hammer.state == S_PLAY_HAMMERSHIELD)
				if not (CBW_Battle and mobj.player)
					if not (mobj.flags2 & MF2_FRET)
						if ((hammer.momz < 0) and not (hammer.eflags & MFE_VERTICALFLIP))
							if (hammer.hammerbounces < 1) and (hammer.player.pflags & PF_JUMPDOWN)
								S_StartSound(hammer, sfx_s3kae)
								P_SetObjectMomZ(hammer, -hammer.momz + 12*FRACUNIT)
								hammer.hammerbounces = $ + 1
							else
								P_SetObjectMomZ(hammer, -hammer.momz)
							end
						elseif ((hammer.momz > 0) and (hammer.eflags & MFE_VERTICALFLIP))
							if (hammer.hammerbounces < 1) and (hammer.player.pflags & PF_JUMPDOWN)
								S_StartSound(hammer, sfx_s3kae)
								P_SetObjectMomZ(hammer, hammer.momz - 12*FRACUNIT)
								hammer.hammerbounces = $ + 1
							else
								P_SetObjectMomZ(hammer, hammer.momz)
							end
						end
					end
					if (mobj.info.spawnhealth > 1)
						if not (mobj.flags2 & MF2_FRET)
							local angle = R_PointToDist2(hammer.x,hammer.y,mobj.x,mobj.y)
							P_InstaThrust(hammer, angle, -hammer.player.speed)
						end
					end
				end
			end
			if not (mobj.flags & MF_MONITOR)
				if (mobj.player and CBW_Battle and hammer.state == S_PLAY_HAMMERSHIELD) return end
				P_DamageMobj(mobj, hammer, hammer)
			else
				P_KillMobj(mobj, hammer, hammer)
			end
			if not (mobj.player)
				local type = MT_LHRT
				local actionspd
				local movang, ang, fa
				local v, h
				local i = 0

				actionspd = FixedMul(6*FRACUNIT, hammer.scale)

				fa = R_PointToAngle2(0, 0, hammer.momz, FixedHypot(hammer.momx, hammer.momy))
				movang = R_PointToAngle2(0, 0, hammer.momx, hammer.momy)
				ang = 0

				v = FixedMul(actionspd, sin(fa))
				h = actionspd - FixedMul(actionspd, cos(fa))

				while (i < 8)
					local side = actionspd - FixedMul(h, abs(sin(ang)))
					local xo = P_ReturnThrustX(nil, ang + movang, side)
					local yo = P_ReturnThrustY(nil, ang + movang, side)
					local zo = -FixedMul(sin(ang), v)
					local missile = P_SpawnMobj(hammer.x, hammer.y, hammer.height/2 + hammer.z, type)
					missile.target = hammer
					missile.destscale = $ * 2/3
					missile.scale = missile.destscale
					missile.angle = ang + movang
					missile.fuse = TICRATE/2
					missile.extravalue2 = (99*FRACUNIT)/100
					missile.momx = xo
					missile.momy = yo
					missile.momz = zo

					ang = $ + ANGLE_45
					i = $+1
				end
			end
		end
	else
		return nil
	end
end

addHook("MobjMoveCollide", HammerShieldSwingDamage, MT_PLAYER)
addHook("MobjCollide", HammerShieldSwingDamage, MT_PLAYER)

addHook("MobjCollide", function(spike, amy)
	if not (amy.player and amy.skin == "amy")
		return nil
	end
	if (amy.z > spike.z+spike.height+10*FRACUNIT)
	or (spike.z > amy.z+amy.height)
		return nil 
	elseif (amy.player.mo.state == S_PLAY_HAMMERSHIELD_LAND)
		spike.health = 0
		S_StartSound(spike, spike.info.deathsound)
		P_KillMobj(spike, amy, amy)
		return false
	end
end, MT_SPIKE)

addHook("MobjMoveCollide", function(amy, spring)
	if not (amy.player and amy.skin == "amy")
		return nil
	end
	if not (spring.flags & MF_SPRING) return end
	if (amy.z > spring.z+spring.height+10*FRACUNIT)
	or (spring.z > amy.z+amy.height)
		return nil
	elseif (amy.player.mo.state == S_PLAY_HAMMERSHIELD_LAND)
		S_StartSound(amy, sfx_sprong)
		P_DoSpring(spring, amy)
		if (spring.type ~= MT_YELLOWHORIZ and spring.type ~= MT_REDHORIZ and spring.type ~= MT_BLUEHORIZ)
			amy.player.mo.momz = $ * 5/4
			amy.state = S_PLAY_SPRING
		else
			amy.player.mo.momx = $ * 5/4
			amy.player.mo.momy = $ * 5/4
			amy.player.mo.state = S_PLAY_ROLL
			amy.player.pflags = $1|PF_SPINNING
		end
		local type = MT_LHRT
		local actionspd
		local movang, ang, fa
		local v, h
		local i = 0

		actionspd = FixedMul(6*FRACUNIT, amy.scale)

		fa = R_PointToAngle2(0, 0, amy.momz, FixedHypot(amy.momx, amy.momy))
		movang = R_PointToAngle2(0, 0, amy.momx, amy.momy)
		ang = 0

		v = FixedMul(actionspd, sin(fa))
		h = actionspd - FixedMul(actionspd, cos(fa))

		while (i < 8)
			local side = actionspd - FixedMul(h, abs(sin(ang)))
			local xo = P_ReturnThrustX(nil, ang + movang, side)
			local yo = P_ReturnThrustY(nil, ang + movang, side)
			local zo = -FixedMul(sin(ang), v)
			local missile = P_SpawnMobj(amy.x, amy.y, amy.height/2 + amy.z, type)
			missile.target = amy
			missile.destscale = $ * 2/3
			missile.scale = missile.destscale
			missile.angle = ang + movang
			missile.fuse = TICRATE/2
			missile.extravalue2 = (99*FRACUNIT)/100
			missile.momx = xo
			missile.momy = yo
			missile.momz = zo

			ang = $ + ANGLE_45
			i = $+1
		end
	end
end, MT_PLAYER)