//Terra the Pangolin by jayflamestar
//Code by RubyTheMii

//No, this code is NOT reusable. Cry about it.

//custom sound stuff
freeslot("sfx_sling")
freeslot("sfx_hydsh")

sfxinfo[sfx_sling].caption = "Super Sling"
sfxinfo[sfx_hydsh].caption = "Hyper Dash"

//Custom color
freeslot("SKINCOLOR_LOAMY", "SKINCOLOR_PHOLIDOTA")
skincolors[SKINCOLOR_LOAMY] = {
	name = "Loamy",
	ramp = {234,234,234,235,235,236,237,237,238,239,239,27,28,28,29,30},
	invcolor = SKINCOLOR_TAN,
	invshade = 0, 
	chatcolor = V_BROWNMAP,
	accessible = true
}

//XMomentum color
skincolors[SKINCOLOR_PHOLIDOTA] = {
	name = "Pholidota",
	ramp = {67,67,67,68,68,69,233,235,236,237,237,238,239,239,28,29},
	invcolor = SKINCOLOR_COBALT,
	invshade = 0,
	chatcolor = V_BROWNMAP,
	accessible = true
}

//Now for some lazily reused code from Extra Life v2.
//Speaking of, go download Extra Life. Shameless plug, I know.
local function XMomCheck(player)
	if not player.mo and player.mo.valid then return end
	if player.isxmomentum == nil
	or player.xmomtoggledoff == true
		player.terraxm = false
	elseif player.isxmomentum == true
	or player.xmomtoggledoff == false
		player.terraxm = true
	end
end
addHook("PlayerThink", XMomCheck)

local function XMomColor(player)
	if netgame then return end //it would piss people off to have to stick to one color lol
   
	if player.mo.skin ~= "terra" then return end
   
	if player.powers[pw_super] then return end
   
	if player.mo and player.mo.valid
	and player.terraxm == true
		player.skincolor = SKINCOLOR_PHOLIDOTA
		player.mo.color = SKINCOLOR_PHOLIDOTA
	elseif player.terraxm == false
		player.skincolor = SKINCOLOR_LOAMY
		player.mo.color = SKINCOLOR_LOAMY
	end
end
addHook("PlayerThink", XMomColor)

//This concludes the boring part of the script. NOW FOR THE ABILITIIIIIEEEESSSSS!!!!!! ~RubyTheMii

//Check stuff for the abilities.
addHook("PlayerThink", function(player)
	if player.mo.skin ~= "terra" then return end
	if player.uptime == nil
	or P_IsObjectOnGround(player.mo)
	or player.mo.eflags & MFE_JUSTHITFLOOR
		player.uptime = 0
	end
	if player.upped == nil
	or P_IsObjectOnGround(player.mo)
	or player.mo.eflags & MFE_JUSTHITFLOOR
		player.upped = false
		player.charflags = $1|SF_NOSHIELDABILITY
	end
   
	if player.fwrdtime == nil
	or P_IsObjectOnGround(player.mo)
	or player.mo.eflags & MFE_JUSTHITFLOOR
		player.fwrdtime = 0
	end
   
	if player.forwarded == nil
	or P_IsObjectOnGround(player.mo)
	or player.mo.eflags & MFE_JUSTHITFLOOR
		player.forwarded = false
		player.charflags = $1|SF_NOSHIELDABILITY
	end
end)

//Jump ability - the Super Sling - a straight dash up.
//But first, a quick check as to not immediately enable the jump ability.
addHook("AbilitySpecial", function(player)
	if player.mo.skin == "terra" and player.charability == CA_NONE
	and player.playerstate == PST_LIVE
		if not (player.pflags & PF_THOKKED)
			player.pflags = $1|PF_THOKKED
		end
	end
end)

addHook("PlayerThink", function(player)
	if player.mo.skin ~= "terra" then return end
   
	if player.forwarded == true
	or P_PlayerInPain(player)
	or player.mo.eflags & MFE_SPRUNG
	or (All7Emeralds(emeralds) and player.rings > 49 and not player.powers[pw_super])
	or (player.mo.state == (S_PLAY_SUPER_TRANS1 or S_PLAY_SUPER_TRANS2 or S_PLAY_SUPER_TRANS3 or S_PLAY_SUPER_TRANS4 or S_PLAY_SUPER_TRANS5 or S_PLAY_SUPER_TRANS6)) then return end
   
	//Let's get to business.
	if player.pflags & PF_THOKKED
	and player.pflags & PF_JUMPED
	and player.upped == false
	and player.cmd.buttons & BT_JUMP //jump key obv
	and not (player.uptime > 0)
		player.upped = true
		player.pflags = $1|PF_NOJUMPDAMAGE
	end
	if player.upped == true
	and player.playerstate == PST_LIVE
		if not (player.uptime == 17)
			player.uptime = $ + 1
			local forwarded_boost2 = P_SpawnGhostMobj(player.mo)
			forwarded_boost2.color = player.mo.color
			forwarded_boost2.colorized = true
			forwarded_boost2.fuse = 4
			forwarded_boost2.frame = ($1 & ~FF_TRANSMASK)|FF_TRANS40
			forwarded_boost2.eflags = player.mo.eflags & MFE_VERTICALFLIP
			player.mo.state = S_PLAY_SPRING
			if player.powers[pw_super]
				if (player.mo.eflags & MFE_UNDERWATER)
					P_SetObjectMomZ(player.mo, 8*FRACUNIT, false)
				else
					P_SetObjectMomZ(player.mo, 16*FRACUNIT, false)
				end
				if player.uptime == 1
					if (player.mo.eflags & MFE_UNDERWATER)
						P_InstaThrust(player.mo, player.mo.angle, player.speed*0/1)
					else
						P_InstaThrust(player.mo, player.mo.angle, player.speed*1/3)
					end
				end
			else
				if (player.mo.eflags & MFE_UNDERWATER)
					P_SetObjectMomZ(player.mo, 6*FRACUNIT, false)
				else
					P_SetObjectMomZ(player.mo, 12*FRACUNIT, false)
				end
				P_InstaThrust(player.mo, player.mo.angle, 0)
			end
		else
			player.upped = false
		end
	end
	//Sound cue plus visual effect.
	if player.upped == true
	and (player.uptime == 1)
		S_StartSound(player.mo, sfx_sling)
		A_OldRingExplode(player.mo, MT_SPINDUST)
	end
end)

//Super Sling recurl.
addHook("JumpSpecial", function(player)
	if (player.pflags & PF_JUMPED) and not (player.pflags & PF_JUMPDOWN) and (player.upped == true) and player.mo.skin == "terra"
		if not (player.mo.state == S_PLAY_JUMP)
			player.mo.state = S_PLAY_JUMP
			player.upped = false
			P_SpawnThokMobj(player)
			S_StartSound(player.mo, sfx_s3ka2)
		end
	end
end)


//Spin ability - the Hyper Dash - a straight dash forward.
addHook("PlayerThink", function(player)
	if player.mo.skin ~= "terra" then return end
   
	if player.upped == true
	or P_PlayerInPain(player)
	or (All7Emeralds(emeralds) and player.rings > 49 and not player.powers[pw_super])
	or (player.mo.state == (S_PLAY_SUPER_TRANS1 or S_PLAY_SUPER_TRANS2 or S_PLAY_SUPER_TRANS3 or S_PLAY_SUPER_TRANS4 or S_PLAY_SUPER_TRANS5 or S_PLAY_SUPER_TRANS6)) then return end
   
   //Back to business
	if player.pflags & PF_JUMPED
	and player.forwarded == false
	and player.cmd.buttons & BT_SPIN //spin key
	and not (player.fwrdtime > 0)
		player.forwarded = true
	end
	if player.forwarded == true
	and player.playerstate == PST_LIVE
		if not (player.fwrdtime == 28)
			player.fwrdtime = $ + 1
			player.mo.state = S_THEH
			player.mo.momz = 0
			local forwarded_boost2 = P_SpawnGhostMobj(player.mo)
			forwarded_boost2.color = player.mo.color
			forwarded_boost2.colorized = true
			forwarded_boost2.fuse = 4
			forwarded_boost2.frame = ($1 & ~FF_TRANSMASK)|FF_TRANS40
			forwarded_boost2.eflags = player.mo.eflags & MFE_VERTICALFLIP
			player.charflags = $|SF_CANBUSTWALLS
			//Accounting for Speed Shoes and XMomentum.
			if player.powers[pw_sneakers] and (player.terraxm == false)
				if (player.mo.eflags & MFE_UNDERWATER)
					P_InstaThrust(player.mo, player.drawangle, 30*FRACUNIT)
				else
					P_InstaThrust(player.mo, player.drawangle, 60*FRACUNIT)
				end
			elseif player.powers[pw_super]
				if (player.mo.eflags & MFE_UNDERWATER)
					P_InstaThrust(player.mo, player.drawangle, 40*FRACUNIT)
				else
					P_InstaThrust(player.mo, player.drawangle, 80*FRACUNIT)
				end
			else
				if (player.mo.eflags & MFE_UNDERWATER)
					P_InstaThrust(player.mo, player.drawangle, 20*FRACUNIT)
				else
					P_InstaThrust(player.mo, player.drawangle, 40*FRACUNIT)
				end
			end
		elseif (player.fwrdtime == 28)
			player.charflags = $ & ~SF_CANBUSTWALLS
			player.mo.state = S_PLAY_FALL
			player.forwarded = false
			player.pflags = $1|PF_NOJUMPDAMAGE
		end
	end
	//Sound cue and visual effect, again
	if player.forwarded == true
	and (player.fwrdtime == 1)
	and player.playerstate == PST_LIVE
		S_StartSound(player.mo, sfx_hydsh)
		//A_OldRingExplode(player.mo, MT_SPINDUST)
		local thokforwarded_boost = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_THOK)
		thokforwarded_boost.state = S_FACESTABBERSPEAR
		thokforwarded_boost.angle = player.drawangle+ANGLE_90
		thokforwarded_boost.scale = player.mo.scale/2+FRACUNIT/4
		thokforwarded_boost.fuse = 8
		thokforwarded_boost.color = SKINCOLOR_WHITE
		thokforwarded_boost.colorized = true
		thokforwarded_boost.blendmode = AST_ADD
	end
	//Spring thing.
	if player.mo.state == S_THEH
	and player.mo.eflags & MFE_SPRUNG
		player.forwarded = false
		player.mo.state = S_PLAY_SPRING
	end
	//Finally fixing the HDOG bug.
	//What does HDOG stand for? Figure it out.
	if player.mo.state == S_THEH
	and (player.mo.eflags & MFE_JUSTHITFLOOR)
		player.forwarded = false
	end
	if player.powers[pw_justsprung]
	or (player.mo.eflags & MFE_SPRUNG)
		player.forwarded = false
		player.fwrdtime = 0
	end
	if player.mo.state == S_THEH
	and player.pflags & PF_USEDOWN
	and (player.mo.eflags & MFE_JUSTHITFLOOR or P_IsObjectOnGround(player.mo))
		player.charflags = $ & ~SF_CANBUSTWALLS
		player.fowarded = false
		player.mo.state = S_PLAY_ROLL
		player.pflags = $ & ~PF_JUMPED
	end
end)

addHook("ThinkFrame", do
	for player in players.iterate
		if (player.mo and player.mo.valid and player.mo.skin == "terra")
		and player.playerstate == PST_LIVE
			player.charflags = $ & ~SF_NOSHIELDABILITY
			player.pflags = $ & ~PF_NOJUMPDAMAGE
			if player.mo.state == S_THEH
				local forwarded_boost = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_THOK)
				forwarded_boost.color = player.mo.color
				forwarded_boost.colorized = true
				forwarded_boost.blendmode = AST_ADD
				forwarded_boost.sprite = SPR_FIRS
				forwarded_boost.frame = S|FF_TRANS50
				forwarded_boost.angle = player.mo.angle
				forwarded_boost.fuse = 1
			end
			if player.mo.sprite == SPR2_SHIT
				local fire = 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)
				fire.state = S_SPINFIRE1
				fire.fuse = 7
				fire.scale = player.mo.scale/2
			end
			if (player.pflags & PF_JUMPED)
				player.pflags = $1 & ~PF_SPINNING
			end
			if not (player.mo.terrakick)
				player.mo.terrakick = 0
			end
			if player.mo.terrakick > 0
				player.mo.terrakick = $1 - 1
			end
			if player.mo.terrakick > 1
			and player.playerstate == PST_LIVE
			and not P_PlayerInPain(player)
				player.mo.momz = 0
				player.mo.momx = FixedMul($, FRACUNIT*97/100)
				player.mo.momy = FixedMul($, FRACUNIT*97/100)
				player.powers[pw_nocontrol] = 2
			end
			if player.mo.state == S_TERRA_DAMAGE1
			or player.mo.state == S_TERRA_DAMAGE2
			or player.mo.state == S_TERRA_DAMAGE3
			or player.mo.state == S_TERRA_DAMAGE4
				local terrakick = P_SpawnGhostMobj(player.mo)
				for i = 0,9
					terrakick.fuse = 13
					terrakick.scale = (FRACUNIT * 8/10) - (i * FRACUNIT/320)
					terrakick.destscale = 0
					terrakick.blendmode = AST_ADD
					terrakick.color = player.mo.color
					terrakick.colorized = true
				end
			end
			if P_IsObjectOnGround(player.mo)
				player.mo.terrakick = 0
			end
			if player.mo.terrakick == 1
				player.mo.state = S_PLAY_FALL
			end
		end
	end
end)

addHook("ShieldSpecial", function(player)
	if (player.mo and player.valid and player.mo.skin == "terra")
		return true
	end
end)

addHook("PlayerSpawn", function(player)
	if (player.mo and player.valid and player.mo.skin == "terra")
		player.charflags = $ & ~SF_CANBUSTWALLS
	end
end)

//Hyper Dash recurl.
addHook("JumpSpinSpecial", function(player)
	if not (player.pflags & PF_USEDOWN) and (player.forwarded == true) and player.mo.skin == "terra"
	and player.playerstate == PST_LIVE
		if not (player.mo.state == S_PLAY_JUMP)
			player.charflags = $ & ~SF_NOSHIELDABILITY
			player.mo.state = S_PLAY_JUMP
			player.forwarded = false
			P_SpawnThokMobj(player)
			S_StartSound(player.mo, sfx_s3ka2)
		end
	end
end)

//Rebound Dash. Literally.
addHook("MobjMoveBlocked", function(mo)
	local play = mo.player
	if play.mo.skin ~= "terra" or play.speed < 10*mo.scale then return end
	if play.mo.state == S_THEH
	and play.playerstate == PST_LIVE
		P_SpawnMobjFromMobj(play.mo, 0, 0, play.height/2, MT_SUPERSPARK)
		S_StartSound(play.mo, sfx_s3k5d)
		P_StartQuake(11*FRACUNIT, TICRATE/4)
		play.forwarded = false
		play.mo.state = S_PLAY_JUMP
		P_BounceMove(mo)
		mo.momx = $/2
		mo.momy = $/2
	end
end, MT_PLAYER)

//Enemy rebound.
addHook("MobjDamage", function(mo, player)
	for player in players.iterate
		if player.mo.state == S_THEH
		and ((mo.flags & MF_ENEMY) or (mo.flags & MF_BOSS))
		and player.playerstate == PST_LIVE then
			P_SpawnMobjFromMobj(player.mo, 0, 0, player.height/2, MT_SUPERSPARK)
			S_StartSound(player.mo, sfx_s3k5d)
			P_StartQuake(11*FRACUNIT, TICRATE/4)
			player.forwarded = false
			player.mo.state = S_PLAY_JUMP
			P_InstaThrust(player.mo, player.drawangle, (-player.speed)/2)
		end
	end
end)