--When spawning, reset stuff!
addHook("PlayerSpawn", function(p)
	if p.mo and p.mo.health and p.mo.valid and p.mo.skin == "surge" and p.stt
		p.stt.eleccharging = 0
		p.stt.fullcharge = false
		p.stt.killaura = true
		p.stt.homer = false
		p.stt.cancelhomer = 0
	end
end)

local function ElectricShield(player)
	local pshield = (player.powers[pw_shield] & SH_NOSTACK)
	return pshield == SH_THUNDERCOIN or pshield == SH_ATTRACT
end

--Get into the main thinker!

addHook("PlayerThink",  function(p)
	if not (p.realmo and p.realmo.valid)
	return
	end 
	
	if not p.stt
		p.stt = {
		eleccharging = 0, //max 105
		fullcharge = false,
		homer = false,
		cancelhomer = 0,
		voltjump = 0,
		voltdash = 0,
		supercharge = 0,
		voltframe = A,
		trailframe = A,
		newcharge = false,
		egirl = false,
		killaura = false
		}
	end
	
local yu = p.stt --Yep, this is Yuji Uekawa too.
local s = p.realmo
	
	--For our sparky thinkers
	if (yu.voltframe > 45)
		yu.voltframe = A
	else
		yu.voltframe = $+1
	end
	if (yu.trailframe > 45)
		yu.trailframe = A
	else
		yu.trailframe = $+1
	end
	if yu.ringattract --Lovingly stolen/referenced from Modern Spork. He's fiiiine with it!
		for i = table.maxn(yu.ringattract),1,-1
			local ring = yu.ringattract[i]
				if not (ring.valid and ring.health)
					table.remove(yu.ringattract,i)
					continue
				end
				if not ring.ringchasetimer
					P_RemoveMobj(ring)
					table.remove(yu.ringattract,i)
					continue
				end
				if FixedHypot(s.z-ring.z,FixedHypot(s.x-ring.x, s.y-ring.y)) <= 256*s.scale
					ring.flags = $ & ~MF_NOCLIP
				else
					ring.flags = $|MF_NOCLIP
				end
				ring.ringchasetimer = $-1
				A_HomingChase(ring, min((6*TICRATE-ring.ringchasetimer)*8, max(48, FixedHypot(FixedHypot(s.momx, s.momy), s.momz)/FRACUNIT+100))*ring.scale)
		end
	end		
	
	if s.skin == "surge" and s.health
		if (s.eflags & MFE_SPRUNG) --Reset ASAP!
			yu.homingspeed = nil
			yu.homingangle = nil
			yu.voltjump = 0
			yu.voltdash = 0		
		end
		local waterfactor = FRACUNIT
		if (s.eflags & MFE_UNDERWATER)
			waterfactor = $*3/5
			if not SurgeWaterProofing(p) and not (p.powers[pw_super] and p.hyper)
				yu.fullcharge = false
				yu.killaura = true
			end	
		end
		
		if ElectricShield(p) and not p.powers[pw_super]
			if not yu.egirl
			yu.egirl = true -- We are now an electric girl.
				if not yu.fullcharge		
				SurgeMaxAura(p, s, yu)
				yu.fullcharge = true
				SurgeAuraSpawn(p, s, yu, A, E) 
				end
			end
			if not yu.voltjump and (yu.supercharge < 120) --THIS 190 must match the one below!
				if not yu.fullcharge
					yu.supercharge = $+1		
				end 											--LIGHTDASHER!! HEEEEY!
			elseif (yu.supercharge >= 120) and not yu.fullcharge --This 190 and the one above us! Lower it decrease the time it takes for Super Surge to get charge! 
				yu.eleccharging = 0
				yu.supercharge = 0
				yu.fullcharge = true
				if (p.pflags & PF_JUMPED) and (p.pflags & PF_THOKKED)
				p.pflags = $ & ~PF_THOKKED --So you can voltjump again.
				end
			end			
		else
			yu.egirl = false
		end
		
		if s.state == S_PLAY_SPINDASH
			yu.eleccharging = $ + 1
			if yu.eleccharging > 10		
				local ghs = P_SpawnMobjFromMobj(s, P_RandomRange(yu.eleccharging+40,-yu.eleccharging-40)*s.scale, P_RandomRange(yu.eleccharging+40,-yu.eleccharging-40)*s.scale, 0, MT_STTAUTOVOLT)
				ghs.sttspeed = 1
				ghs.tics = 4
				ghs.frame = P|FF_FULLBRIGHT
					if yu.eleccharging < 50
					ghs.flags2 = MF2_SHADOW
					ghs.scale = s.scale/2
					end
					P_RadiusAttack(s, s, (yu.eleccharging*FRACUNIT))
				SurgeQuake(p,(yu.eleccharging/10)*FRACUNIT, 1)
			end
		else
			yu.eleccharging = 0
			if p.homing --Stop homing when too slow.
			yu.homingspeed = p.speed
			yu.homingangle = s.angle
				if (p.speed < 5*s.scale)
				and (s.momz > -5*s.scale) and (s.momz < 5*s.scale)
					if p.homing > 80
					p.homing = $-15
					else
						SurgeQuake(p,30*FRACUNIT, 5)
						if p.powers[pw_nocontrol] < 8
						p.powers[pw_nocontrol] = 8
						end
					P_InstaThrust(s, s.angle, -15*FRACUNIT)
					p.pflags = $ & ~PF_SPINNING
					P_SetObjectMomZ(s, 6*FRACUNIT, false)
					p.pflags = $ & ~PF_SPINNING
					S_StartSound(s, sfx_bedeen)
					S_StartSound(s, sfx_dmpain)
					s.state = S_PLAY_PAIN
					p.pflags = $ & ~PF_THOKKED & ~PF_JUMPED & ~PF_SPINNING
					p.homing = 0
					end
				end
			end			
		end  
		if (yu.eleccharging > 105)
			if ((s.eflags & MFE_UNDERWATER) and not SurgeWaterProofing(p)) or (p.cmd.buttons & BT_CUSTOM1)
				yu.eleccharging = 51 --Nope.
			elseif yu.fullcharge
				yu.eleccharging = 105
			else
				SurgeMaxAura(p, s, yu)
				yu.fullcharge = true
				SurgeAuraSpawn(p, s, yu, A, E) 
				s.state = S_PLAY_SPRING
				S_StartSound(s, sfx_susfx4)
				for d = 0,3
					local ghs = P_SpawnGhostMobj(s)
					ghs.colorized = true 
					ghs.color = SKINCOLOR_CYAN+d
					ghs.rollangle = -ANG20+(ANG10*d)
					ghs.destscale = $*99
					ghs.fuse = 20
					ghs.tics = 40
					ghs.flags2 = $|MF2_SHADOW
					ghs.blendmode = AST_ADD
				end
			p.pflags = $ & ~PF_STARTDASH
			s.state = S_PLAY_STND
			end
		end
		if p.powers[pw_super] --This is a Saiyan that has ascended past the Super Saiyan!
			if not yu.voltjump and (yu.supercharge < 60) --THIS 50 must match the one below!
			and not ((s.eflags & MFE_UNDERWATER) and not p.hyper)
				if not yu.fullcharge
					yu.supercharge = $+1
					if p.hyper and p.hyper.capable
					yu.supercharge = 99
					end
				end 											--LIGHTDASHER!! HEEEEY!
			elseif (yu.supercharge >= 60) and not yu.fullcharge --This 50 and the one above us! Lower it decrease the time it takes for Super Surge to get charge! 
			and not ((s.eflags & MFE_UNDERWATER) and not p.hyper)
				yu.eleccharging = 0
				yu.supercharge = 0
				yu.fullcharge = true
				if (p.pflags & PF_JUMPED) and (p.pflags & PF_THOKKED)
				p.pflags = $ & ~PF_THOKKED --So you can voltjump again.
				end
			end
			if p.name == "Sol" or p.name == "Solbliminal" or p.name == "Mania"
			or p.name == "sol" or p.name == "solbliminal" or p.name == "mania"
				if s.color == SKINCOLOR_SUPERSKY1
				s.color = SKINCOLOR_SUPER_SURGE_1
				elseif s.color == SKINCOLOR_SUPERSKY2
				s.color = SKINCOLOR_SUPER_SURGE_2
				elseif s.color == SKINCOLOR_SUPERSKY3
				s.color = SKINCOLOR_SUPER_SURGE_3
				elseif s.color == SKINCOLOR_SUPERSKY4
				s.color = SKINCOLOR_SUPER_SURGE_4
				else
				s.color = SKINCOLOR_SUPER_SURGE_5
				end
			end
		end	
		if yu.curltime
		and not P_IsObjectOnGround(s)
		and not P_PlayerInPain(p)
			if not (yu.voltjump > 20)
				s.state = S_PLAY_ROLL
				p.pflags = $& ~PF_NOJUMPDAMAGE
				yu.controltime = 2
			end
			yu.curltime = false
		end	
		if not yu.homer --DOH!
			yu.cancelhomer = 0
		end
		if yu.cancelhomer == 105
			yu.homer = false
		end
		if (s.state == S_PLAY_SUPER_TRANS1)
			if s.tics == 7 --Why all of this? Look, ask Lightdasher, idfk. Surge is SSJ2.
			S_StartSound(nil, sfx_susfxe)
			yu.eleccharging = 0
			yu.supercharge = 0
			yu.fullcharge = true			
				if p.powers[pw_nocontrol] < 12
				p.powers[pw_nocontrol] = 12
				end
				SurgeQuake(p,70*FRACUNIT, 34)
				P_RadiusAttack(s, s, 400*FRACUNIT)
				for d = 1,3
					local ghs = P_SpawnMobjFromMobj(s, 0, 0, -s.height/3, MT_STTAUTOVOLT)
					ghs.sttspeed = 3+d
					ghs.sttfade = true
					ghs.tics = 58-(d*4)
					ghs.blendmode = AST_ADD
					ghs.frame = Z+19|FF_FULLBRIGHT|(TR_TRANS60+(d*FRACUNIT))
					ghs.scale = ($*(d*3))/4
					ghs.scalespeed = ($*d)/3
					ghs.destscale = $*99
					P_SetObjectMomZ(ghs, -18000*d, true)
					p.pflags = $ & ~PF_SPINNING
				end
				
				local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_STTAUTOVOLT) 
				ghs.sprite = SPR_STAU
				ghs.frame = Z+9|FF_FULLBRIGHT|TR_TRANS30
				ghs.scale = s.scale*2
				ghs.scalespeed = $*3
				ghs.destscale = $*99
				ghs.sttspeed = 3
				ghs.tics = 11
				ghs.blendmode = AST_ADD
				
				local ghs = P_SpawnMobjFromMobj(s, 0, 0, -s.height*2, MT_STTAUTOVOLT) 
				ghs.sprite = SPR_STAU
				ghs.frame = Z+9|FF_FULLBRIGHT|TR_TRANS40
				ghs.mirrored = true
				ghs.scalespeed = $*2
				ghs.destscale = $*99
				ghs.sttspeed = 6
				ghs.tics = 22
				P_SetObjectMomZ(ghs, 10*FRACUNIT)
				p.pflags = $ & ~PF_SPINNING
				ghs.blendmode = AST_ADD				
			
				for d = 0,15
					local ghs = P_SpawnMobjFromMobj(s, 0, 0, -s.height, MT_STTAUTOVOLT)
					ghs.sttspeed = 4
					ghs.tics = 16
					ghs.frame = P|FF_FULLBRIGHT|TR_TRANS20
					ghs.blendmode = AST_ADD
					P_InstaThrust(ghs, s.angle+((ANGLE_45/2)*d), 12*FRACUNIT) 
					p.pflags = $ & ~PF_SPINNING
					P_SetObjectMomZ(ghs, 6*FRACUNIT)
					p.pflags = $ & ~PF_SPINNING
				end
			end
		end
		if yu.killaura
			yu.killaura = false
		end

	--Full power! Now with benefits!
		if yu.fullcharge
		
			p.amstt = true
			yu.supercharge = 0
			--Stat boosts
			p.charflags = $|SF_RUNONWATER
			p.normalspeed = 43*FRACUNIT
			p.jumpfactor = 12*FRACUNIT/10
			SurgeAuraSpawn(p, s, yu, A, E)
			
			if not yu.newcharge
				local ghs = P_SpawnGhostMobj(s)
				ghs.scalespeed = $*3
				ghs.blendmode = AST_ADD
				ghs.destscale = $*99
				if not (p.cmd.buttons & BT_CUSTOM1)
				S_StartSound(s, sfx_cdfm55)
				end				
			yu.newcharge = true
			end
		
			if ((p.speed > 38*s.scale) or ((p.speed > 28*s.scale) and (p.pflags & PF_SPINNING))) and not yu.voltdash
				if ((p.pflags & PF_JUMPED) or (p.pflags & PF_SPINNING) or (p.panim == PA_RUN))
				SurgeVoltSpawn(p, s, yu, H, G, nil, true)
				end
			end
			
			yu.ringrange = P_SpawnMobjFromMobj(s, 0, 0, -s.height*3, MT_STTRINGRANGE)
			yu.ringrange.target = s
			yu.ringrange.tics = 2
			yu.ringrange.fuse = 2
			
			if p.skidtime and (p.skidtime < 25) --Skidding effects when charged
				if p.skidtime == 13 or p.skidtime == 1
				S_StartSound(s, sfx_susfxa)
				end
				local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_STTAUTOVOLT) 
				ghs.sprite = SPR_STAU					
				ghs.scale = FixedDiv(FixedMul($, 25), 25-p.skidtime)
				
					if (leveltime % 2 == 0)
					ghs.scale = s.scale/2
					ghs.mirrored = true
					else
					ghs.flags2 = $|MF2_SHADOW
					end
					
				ghs.frame = (Z+13)|FF_FULLBRIGHT
				ghs.sttspeed = 1
				ghs.tics = 8			
			end
			
		else 
		--Not fully charged then?
			p.amstt = false
			p.charflags = $ & ~SF_RUNONWATER
			S_StopSoundByID(s, sfx_susfx2)
			S_StopSoundByID(s, sfx_susfxd)
			yu.newcharge = false
			p.normalspeed = 36*FRACUNIT
			p.jumpfactor = 1*FRACUNIT
			
		end
		if p.powers[pw_carry] or P_IsObjectOnGround(s)
			yu.curltime = false
			yu.voltdash = 0
			yu.voltjump = 0
		end
		--Methods to lose your aura.
		if (p.cmd.buttons & BT_CUSTOM1) or P_PlayerInPain(p) or p.gotflag 
			if yu.fullcharge and not p.powers[pw_super]
				S_StartSound(s, sfx_susfx5)
				
				local ghs = P_SpawnGhostMobj(s) --Turn it off, boys!
				ghs.scalespeed = $*3
				ghs.blendmode = AST_ADD
				ghs.destscale = $*99

				local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_STTAUTOVOLT)
				ghs.sttspeed = 3
				ghs.tics = 12
				ghs.frame = L|FF_FULLBRIGHT
				
			end
			yu.fullcharge = false
			yu.killaura = true
			if P_PlayerInPain(p)
			yu.curltime = false
			end
		end
	else
		p.amstt = false
	end	
end)

--Surge's double jump and super jump!

addHook("AbilitySpecial", function(p, mobj)
local s = p.mo
local yu = p.stt
	if (p.mo.skin == "surge")
	and p.playerstate == PST_LIVE
	and not (yu.voltjump > 20)
		if not (p.pflags & PF_THOKKED)
		and not P_PlayerInPain(p)
		local waterfactor = FRACUNIT
			if s.eflags&MFE_UNDERWATER
			waterfactor = $*3/5
			end  
			if p.stt.fullcharge
				P_SetObjectMomZ(s, 72*waterfactor)
				p.pflags = $ & ~PF_SPINNING
				if p.hyper and p.hyper.capable and p.powers[pw_super]
					P_NukeEnemies(s, s, 700*FRACUNIT)
				else
				P_RadiusAttack(s, s, 350*FRACUNIT)
				end
				p.stt.fullcharge = false
				p.stt.killaura = true
				S_StartSound(s, sfx_kc5b)
				S_StartSound(s, sfx_kc4d)
				S_StartSound(s, sfx_susfx7)
				yu.voltjump = 25
				s.state = S_PLAY_SPRING
				SurgeQuake(p,40*FRACUNIT, 5)

				--Big AoE explosion!

				local ghs = P_SpawnMobjFromMobj(s, 0, 0, 16*s.scale, MT_STTAUTOVOLT) 
				ghs.sprite = SPR_STAU
				ghs.frame = Z+9|FF_FULLBRIGHT
				ghs.scale = s.scale*2
				ghs.scalespeed = $*2
				ghs.destscale = $*99
				ghs.sttspeed = 3
				ghs.tics = 11
				ghs.blendmode = AST_ADD
			
				for d = 0,7
					local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_STTAUTOVOLT)
					ghs.sttspeed = 2
					ghs.tics = 8
					ghs.scale = s.scale
					ghs.frame = P|FF_FULLBRIGHT
					P_InstaThrust(ghs, s.angle+(ANGLE_45*d), 35*FRACUNIT) 
					p.pflags = $ & ~PF_SPINNING
				end
				
			else --Small jump, then!

				for d = 0,7
				local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_STTAUTOVOLT)
				ghs.sttspeed = 2
				ghs.tics = 8
				ghs.scale = s.scale/2
				ghs.frame = P|FF_FULLBRIGHT
				P_InstaThrust(ghs, s.angle+(ANGLE_45*d), 20*FRACUNIT) 
				p.pflags = $ & ~PF_SPINNING
				end
				
				s.state = S_PLAY_ROLL
					if (p.pflags & PF_THOKKED) or yu.voltdash --This is seriously busted, let's nerf it a tiiiny bit.
					P_SetObjectMomZ(s, 9*waterfactor)
					p.pflags = $ & ~PF_SPINNING
					else
					P_SetObjectMomZ(s, 11*waterfactor)
					p.pflags = $ & ~PF_SPINNING
					end
			end
			yu.doublejumpy = 8			
			p.pflags = $|PF_THOKKED|PF_JUMPED & ~PF_NOJUMPDAMAGE
			S_StartSound(s,sfx_s3k45)
		end
		return true
	end  
end)

--Surge's thok, super thok and homing attack!

addHook("JumpSpinSpecial", function(p, mobj)
local s = p.mo
local yu = p.stt
   if(p.mo.skin == "surge")
   and p.playerstate == PST_LIVE 
   and not (p.pflags&PF_SPINDOWN)
   and not P_PlayerInPain(p)
   and not (yu.voltjump > 20)
		if p.stt.fullcharge --VOLT DASH!!
		
			if (p.speed < 66*s.scale)
				P_InstaThrust(s, s.angle, 67*FRACUNIT)
			else
				P_InstaThrust(s, s.angle, p.speed+(2*FRACUNIT)) --Always speed up at least a little!
			end
			
		p.pflags = $ & ~PF_SPINNING
		
			if p.powers[pw_super] and p.hyper and p.hyper.capable 
			P_NukeEnemies(p.mo, p.mo, 500*FRACUNIT)
			P_InstaThrust(s, s.angle, 90*FRACUNIT)
			p.pflags = $ & ~PF_SPINNING
			end
		P_SetObjectMomZ(s, FRACUNIT)
		p.pflags = $ & ~PF_SPINNING
		p.stt.fullcharge = false  
		p.stt.killaura = true
		S_StartSound(s,sfx_s3k45)
		S_StartSound(s, sfx_susfx7)
			S_StartSound(s, sfx_kc3c)
			S_StartSound(s, sfx_kc4d)
			yu.voltdash = 25
			SurgeQuake(p,50*FRACUNIT, 4)
			if s.state != S_PLAY_ROLL
				s.state = S_PLAY_ROLL
			end			
			
			
		else --Regular homing attack!
		
		local homing = P_LookForEnemies(p)
		if homing and homing.valid
			s.tracer = homing
			p.homing = 105
			yu.nohb = 2
			S_StartSound(s,sfx_susfx4)
			p.stt.homer = true
			p.pflags = $& ~PF_THOKKED
			p.pflags = $& ~PF_NOJUMPDAMAGE
			p.pflags = $ & ~PF_SPINNING
			p.mo.state = S_PLAY_ROLL
			
		else --Nothing found!
			s.momx = FixedDiv(FixedMul($, 50), 57)
			s.momy = FixedDiv(FixedMul($, 50), 57) --Speed penalty for spamming.
			S_StartSound(s,sfx_s3ka6)
			s.flags2 = $|MF2_DONTDRAW
				local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_STTAUTOVOLT)
				ghs.sttspeed = 1
				ghs.tics = 4
				ghs.scale = s.scale/3
				ghs.frame = L|FF_FULLBRIGHT
				if s.state != S_PLAY_ROLL
				s.state = S_PLAY_ROLL
				end
			p.stt.homer = false
		end				
		end
	yu.doublejumpy = 6		
   end	
end)

COM_AddCommand("surgequakes", function(p)
	if (p.valid and p.stt)
		if p.stt.noquakes
		p.stt.noquakes = false
		CONS_Printf(p, "\x8d"+"QUAKES from Surge turned\x83 on!")
		else
		p.stt.noquakes = true
		CONS_Printf(p, "\x8d"+"QUAKES from Surge turned\x85 off!")
		end
	end
end)


// Abilites table for Kirby to eat
if not(kirbyabilitytable)
	rawset(_G, "kirbyabilitytable", {})
end
// 5 = Spark!
kirbyabilitytable["surge"] = 5
