--BattleMod support! Chaos Mode is also supported, but doesn't require a dedicated Lua file.

if srb2p return end
local loadonce

addHook("ThinkFrame", function()
	if not CBW_Battle --Save on resources if Battlemod isn't added.
	or loadonce
		return
	end
	local B = CBW_Battle
	loadonce = true
	
	--SA Sonic has a growing arsenal of special moves that unlock with every 20 ring increment, just like SA2's multiplayer mode.
	--In Battlemod you cannot use the lightspeed attack at all until you have 40+ rings.
	local SASonicSpecial = function(s, doaction)
		local p = s.player
		local yu = p.yusonictable	
		
		if yu.lsacharged and (p.rings >= 40)
			p.actiontext = "Lightspeed Attack" --Fast and outprioritizes everything. Can only be stopped with a guard/airdodge.
			p.action2text = "Attack nearby players" --You must manually charge your LSA before you can use it!
			p.actionrings = 40 --If it finds no target, it refunds 20 rings.
		elseif (p.rings >= 60 and P_IsObjectOnGround(s))
			p.actiontext = "Time Stop" --A massive AoE spell stopping players in place for 6 seconds! Cancels if you get hurt.
			p.action2text = "Large AoE" -- Mash to escape the timestop much quicker!
			p.actionrings = 60 --The move cancels if it can't find a target.
		else
			p.actiontext = "Sonic Wind" --Spawns a tornado on the furthest away enemy. Can be guarded or outran.
			p.action2text = "Attack furthest player" --Rolling makes you invincible to this move.
			p.actionrings = 20 --The move cancels if it can't find a target.
		end
		
		
		if not P_IsObjectOnGround(s) and p.canguard --SA-Sonic cannot airdodge, true to his "strongest on the ground" gameplay staple.
			p.canguard = 0
		end
		
		--Checks before we can use a special.
		if not CBW_Battle.CanDoAction(p)
		or s --Disable it all for now. Undo in v2.
		or P_PlayerInPain(p)
		or p.powers[pw_nocontrol]
		or p.powers[pw_carry]
		or yu.lsaattack or yu.tauntstate
		or p.homing or yu.bouncestate == 1
			return
		end
		
		//Ignore rest of the code if....
		if doaction != 1
			return
		end		
		B.PayRings(p)
		local didmove = false
		
		//Activate Lightspeed Attack!		
		if (yu.lsacharged and (p.rings >= 40))
			p.cmd.buttons = $ & ~BT_USE
			p.powers[pw_nocontrol] = 3
			yu.lsabattle = 178 --Special property that targets players as enemies and turns LSA electric gold.
			if (p == displayplayer)
				P_FlashPal(p, PAL_RECYCLE, 3)
				P_StartQuake(42*FRACUNIT, 5)
			end		
			
		//Activate Time Stop!!	
		elseif (p.rings >= 60 and P_IsObjectOnGround(s))		
			p.actionstate = 3
			didmove = true		
			
		//Activate Sonic Wind!!
		elseif (p.rings >= 20)	
			S_StartSound(s, sfx_s3k70)		
			p.actionstate = 3
			p.powers[pw_nocontrol] = 18
			s.state = S_PLAY_FLY
			p.actionstate = 2 --Sonic Wind action state. Runs from this hook.
			didmove = true
		end
		
		if didmove
			local ghs = P_SpawnGhostMobj(s)
			ghs.color = SKINCOLOR_SUPERSKY5
			ghs.destscale = $*99
			ghs.fuse = 11
			ghs.tics = 15
			ghs.colorized = true
			s.momx = 0 s.momy = 0 s.momz = 0
			p.pflags = $ & ~PF_JUMPED & ~PF_STARTDASH & ~PF_SPINNING & ~PF_THOKKED
		end
	end


	//Defense and attack values. Outside of the downwards bounce or LSA, SA-Sonic is pretty lightweight
	local SASonicPriority = function(p)
	local s = p.mo
	local yu = p.yusonictable	
		--Note to self on what all these numbers actually do...	
		--B.SetPriority = function(p,atk,def,sfunc,satk,sdef,txt)	
		
		--Kicking names and taking ass.
		if yu.lsaattack or yu.lightdashing or yu.lsahoming
			B.SetPriority(p,99,99,nil,99,99,"SA Light Speed")
		
		--Attacks will "bounce" right off you! Only on the downwards trajectory, though!
		elseif (yu.bouncestate == 1) 
			B.SetPriority(p,2,3,nil,2,2,"SA Bounce Attack")

		elseif p.homing --Homing attacks come with a bit of extra physical defense.
			B.SetPriority(p,1,2,nil,1,1,"SA Homing Attack")
		
		--Use a powerful spindash for an offensive edge. Defensively you're not gaining anything.
		elseif ((p.speed > 66*s.scale) and ((p.pflags & PF_SPINNING) and not ((p.pflags & PF_STARTDASH) or yu.startdash)))
			B.SetPriority(p,2,1,nil,1,1,"SA Speed Spin")

		--You have zero defense when charging a spindash or uncurling, be careful!
		elseif (p.pflags & PF_STARTDASH) or yu.startdash or yu.uncurlanim
		
			B.SetPriority(p,0,0,nil,0,0,"SA Spin Rev")
		
		--Standard jump priority.
		elseif (p.pflags&PF_JUMPED) or yu.homingtrick or ((p.pflags & PF_SPINNING) and not ((p.pflags & PF_STARTDASH) or yu.startdash))
		
			B.SetPriority(p,1,1,nil,1,1,"SA roll")
	
		end
	end


	//Stylish guard parry! Easy to counter with!
	local SASonicParry = function(s, i, so, dmg, dmgtype)
	local p = s.player
	local yu = p.yusonictable
		if leveltime % 3 == 0
			YuVoice(p, s, yu, sfx_yuvoci, true)
		end
		local ghs = P_SpawnGhostMobj(s)
		ghs.color = SKINCOLOR_SUPERSKY5
		ghs.colorized = true
		ghs.fuse = 12 ghs.tics = 22
		ghs.destscale = $*99
		ghs = P_SpawnGhostMobj(s)
		ghs.frame = 2|FF_FULLBRIGHT ghs.color = SKINCOLOR_WHITE
		ghs.fuse = 12 ghs.tics = 22
		ghs.destscale = $*99 ghs.scalespeed = $*2		
		if p == displayplayer
			P_StartQuake(62*FRACUNIT, 7)
		end
		for n = 0, 16
			local dust = P_SpawnMobj(s.x,s.y,s.z,MT_DUST)
			if dust and dust.valid then
				P_InstaThrust(dust,s.angle+ANGLE_22h*n,s.scale*36)
			end
		end
		p.canguard = 1
		p.guardtics = 0
		p.guard = 0
		--Lazy copy-paste. Trick off the enemy and taunt.
		s.z = $+((5*s.scale)*P_MobjFlip(s))	
		s.state = S_PLAY_ROLL
		p.pflags = $|PF_JUMPED & ~PF_THOKKED & ~PF_NOJUMPDAMAGE
		yu.airborne = 0
		yu.homingtrick = 10
		yu.chosentrick = 200
		yu.lasttrick = 2									
		yu.airborne = 30
		yu.sa2jumpdone = true
		yu.airstart = 10
		P_SetObjectMomZ(s, 9*FRACUNIT, false)	
		--Extra gfx.
		for d = 0,6,2
			local boom = P_SpawnMobjFromMobj(s, 0, 0,0, MT_YUINSTASHIELD)
			boom.scale = $+(50000*d)
			boom.scalespeed = $*7+d
			boom.destscale = s.scale*99
			boom.colorized = true
			boom.renderflags = $|RF_FULLBRIGHT|RF_NOCOLORMAPS
			boom.blendmode = AST_ADD
			boom.color = SKINCOLOR_AETHER+d
		end
		S_StartSound(so, sfx_bedeen)
		for d = 0,7
			local debris = P_SpawnMobj(s.x+(P_RandomRange(-50,50)*s.scale), s.y+(P_RandomRange(-50,50)*s.scale), s.z+(P_RandomRange(5,80)*s.scale), MT_BOSSJUNK)
			if debris and debris.valid
				debris.flags = $|MF_BOUNCE|MF_GRENADEBOUNCE|MF_NOCLIPTHING
				debris.state = S_IVSP
				P_InstaThrust(debris, so.angle+(P_RandomRange(-30,30)*ANG1), (P_RandomRange(10,25)*s.scale)+p.speed)
				P_SetObjectMomZ(debris, P_RandomRange(2,11)*s.scale, false)		
			end
		end
		if i and i.valid
			P_RadiusAttack(s, s, 60*FRACUNIT)
			P_InstaThrust(s, R_PointToAngle2(s.x, s.y, i.x, i.y), -21*FRACUNIT)
			P_SpawnMobj(i.x, i.y, i.z, MT_EXPLODE)			
		else
			P_SpawnMobj(s.x, s.y, s.z, MT_EXPLODE)
		end
	end


	//BattleMod's version of an S_SKIN, basically.
	B.SkinVars["adventuresonic"] = {
		weight = 91, --Fairly lightweight, easy to shove around.
		shields = 1, --Glass cannon.
		flags = SKINVARS_GUARD|SKINVARS_NOSPINSHIELD, --No shield abilities. Can guard but not air dodge.
		guard_frame = 12, --We have ALOT of super transformation frames. Bless Metalwario.
		func_guard_trigger = SASonicParry, --Parrying but le cool.
		special = SASonicSpecial, --We're imitating SA2B's multiplayer!
		func_priority = SASonicPriority --Defense and Attack values.
	}

	print("\x82\Adventure Sonic\x80 WIP battlemod support added.\x83 Expect balancing and specials in\x82 v2!")
end)