if GS_RAILS_SKINS==nil rawset(_G,"GS_RAILS_SKINS",{}) end --Always make sure this is set.

local RAIL = GS_RAILS if RAIL and RAIL.blockload return end --Don't include this part in your own file
if GS_RAILS_SKINS["amy"] return end --Already have a table.

--Vanilla Amy is a great grinder for starters. Good stats all around, but a lower maxspeed most newbies will probably never reach.
GS_RAILS_SKINS["amy"] = {} 
local SKIN = GS_RAILS_SKINS["amy"]

SKIN["S_SKIN"] = {
SIDEHOP = 29,
SIDEHOPARC = 20,
SIDEHOPTIME = 13,
SIDEFLIP = SPR2_MLEL, --Hammerspin sidehop, with an actual AoE radius!

MUSTBALANCE = true, --Must balance! 
CROUCH = true, 
HEROESTWIST = 21, --And has a great Twist Drive to negate slopes with.
MAXSPEED = 165, --A bit slower than the rest.

NOSIDEHOPGFX = 1,
}

local function AMYHEARTIMPACT(p, s, GS)
	local ANG,ghs = p.drawangle
	for i = 1,8
		for d = 1,2
			ghs = P_SpawnMobjFromMobj(s, FixedMul(48*s.scale/d, cos(ANG)), FixedMul(48*s.scale/d, sin(ANG)), 1, 
			(d==2) and MT_EXPLODE or MT_LHRT)
			if (d==1)
				if ghs and ghs.valid
					if GS and GS.railspeed P_Thrust(ghs, p.drawangle, abs(GS.railspeed)) end
					ghs.momx,ghs.momy = $+s.momx,$+s.momy
					P_Thrust(ghs, ANG, 64*s.scale)
					ghs.momz = 8*s.scale*P_MobjFlip(s)
					ghs.scale = s.scale/2
					ghs.scalespeed = FRACUNIT/31
					ghs.destscale = s.scale*2
					ghs.target,ghs.tracer = s,s
					ghs.fuse = 18
					ghs.renderflags = $|RF_SEMIBRIGHT
				end
				if i==8 ANG = ANGLE_22h end
			end
		end ANG = $+ANGLE_45
	end
end

SKIN["CustomSideHop"] = function(p, s, GS,rail, SIDEJUMP)
	if GS_RAILS.GrindState(s, "hang") return "hangflip" end
	S_StopSoundByID(s, sfx_gsral9)
	S_StartSound(s, sfx_s3k8b) --Play hammer sound instead of rail hop.
	AMYHEARTIMPACT(p, s, GS)
	P_RadiusAttack(s, s, 200<<16) --Minor AoE damage!
end

--You're hitting the rail with your hammer! ...but why?
SKIN["PreAttach"] = function(p, s, GS, mainrail, seg)
	if (p.panim==PA_ABILITY) and (p.pflags & PF_THOKKED) and (p.pflags & PF_NOJUMPDAMAGE) and (p.pflags & PF_JUMPED)
		if mainrail and (mainrail.GSinvisiblerail or (mainrail.flags2 & MF2_DONTDRAW) or mainrail.sprite==SPR_NULL)
			return --It's weird doing this off invisible rails.
		end
		local TMOMZ = (s.momz*2/3)*P_MobjFlip(s)
		local SEG = seg or mainrail
		if (abs(TMOMZ) < 10*s.scale)
			s.momz = 10*s.scale*P_MobjFlip(s)
		else
			s.momz = abs(TMOMZ)*P_MobjFlip(s)
		end
		if mainrail and mainrail.GSrailZDelta and (abs(mainrail.GSrailZDelta) > ANG1) --A little slopethrust too, why not.
			local ZDELTA = mainrail.GSrailZDelta
			local THRUST = (ZDELTA/(ANG1/4))*s.scale 
			if (abs(TMOMZ) < 24*s.scale)
				THRUST = (abs(TMOMZ) < 10*s.scale) and $/2 or (abs(TMOMZ) < 16*s.scale) and $*2/3 or $*3/4
			end
			P_Thrust(s, GS_RAILS.ANG(mainrail), -THRUST)
		end
		
		local TOANG = R_PointToAngle2(s.x, s.y, SEG.x, SEG.y)
		local DIST = max(8*s.scale, min(24*s.scale, p.speed/3))
		s.momx,s.momy = $*3/4,$*3/4
		P_Thrust(s, TOANG, -DIST)
		S_StartSound(s, sfx_s3k8b)
		p.pflags = $|PF_JUMPDOWN & ~PF_THOKKED
		GS.cannotgrind = max($, 9)

		local TYPE = GS_RAILS_TYPES[RAIL.LearnRailType(mainrail or seg)] if not (TYPE) TYPE = GS_RAILS_TYPES[0] end
		if not (TYPE.landSFX==sfx_none) 
			local LANDSFX = sfx_gsral5 if (TYPE.landSFX!=nil) LANDSFX = TYPE.landSFX end
			if not (TYPE.spawnleaves) and not (TYPE.nosparks)
				S_StopSoundByID(s, sfx_gsralg)
				S_StartSoundAtVolume(s, sfx_gsralg, 130) 
			else
				S_StopSoundByID(s, LANDSFX)
				S_StartSoundAtVolume(s, LANDSFX, 104)
			end
		end
		
		AMYHEARTIMPACT(p, s, GS)
		for i = 1,5 P_SpawnSkidDust(p, 62<<16) end
		
		return true --
	end
end

--Regain ability to use hammer after flinging.
SKIN["PostFling"] = function(p,s,GS,rail, METHOD, SLOPEFLING)
	if METHOD!="sidehop" and METHOD!="jump"
		p.pflags = $|PF_JUMPDOWN|PF_NOJUMPDAMAGE|PF_JUMPED & ~PF_THOKKED
	end
end

--Unique hangjump hop
SKIN["PlayerThink"] = function(p, s, GS)
	if GS.hanghop and GS.railswitching
		if (p.pflags & (PF_JUMPED|PF_NOJUMPDAMAGE)) and not GS.grinding and not P_IsObjectOnGround(s)
		and not (p.pflags & (PF_THOKKED|PF_SLIDING|PF_SPINNING|PF_STARTDASH)) and not p.powers[pw_carry]
			if (p.speed > 5*s.scale) and GS.railswitchANG!=nil 
				local _,P = GS_RAILS.AngleDifference(GS.railswitchANG,R_PointToAngle2(s.x,s.y, s.x+s.momx,s.y+s.momy),2,ANG60,2)
				GS.forcesprite = SPR2_SPNG
				GS.forceangle = GS.railswitchANG - (GS.railswitching*ANG1*43*P)
				
				local DIST = (48-(GS.hanghop*2))*s.scale
				local ghs = P_SpawnMobjFromMobj(s, 
				((GS.hanghop%2) and -s.momx or 0)+FixedMul(DIST, cos(GS.forceangle+ANGLE_90)), 
				((GS.hanghop%2) and -s.momy or 0)+FixedMul(DIST, sin(GS.forceangle+ANGLE_90)), (48*s.scale)-DIST, MT_LHRT)
				if ghs and ghs.valid
					ghs.target,ghs.tracer = s,s
					ghs.scale = s.scale*2/3
					ghs.destscale = 1
					ghs.fuse = 30
					ghs.renderflags = $|RF_SEMIBRIGHT
				end				
			end
		end		
	end
end
