//Sorry in advance for bad code - I'm an idiot, and still relatively new to this.
freeslot("S_BAIG_SHOT",
"S_BAIG_SHOT_JUMP",
"S_BAIG_SHOT_SPRING",
"S_BAIG_JUMPSHOT",
"S_BAIG_SKICK",
"S_BAIG_STOMP",
"S_BAIG_SPED",
"S_BAIG_DFTR",
"S_BAIG_DFTL",
"S_BAIG_JPKU",
"S_BAIG_SHIT",
"S_BAIG_TAUNT1",
"S_BAIG_TAUNT2",
"S_BAIG_DAB",
"S_BAIG_MAZINTRANSFORM",      //Shhhhhh you don't see anything just keep scrolling
"S_BAIGLAZER",
"S_BAIGJUMPLAZER",
"S_BAIGCHARGELAZER",
"S_BAIGLAZEREND",
"S_BAIGGROUNDSPARK",
"S_BOST",
"S_LZHP",
"S_STHP",
"S_OORB",
"SPR_HUDE",
"SPR_HUDC",
"SPR_HUDR",
"SPR_HUDS",
"SPR_DASH",
"SPR_LAZF",
"SPR_LAZJ",
"SPR_GSPK",
"SPR_CHRG",
"SPR_BOST",
"SPR_LZHP",
"SPR_STHP",
"SPR_OORB",
"SPR_TOST",
"SPR_TSTY",
"SPR2_BANG",
"SPR2_STMP",
"SPR2_SPED",
"SPR2_DFTR",
"SPR2_DFTL",
"SPR2_JPKU",
"SPR2_FKIK",	//pssssst: If you want to have your character dancing with Milne, make an 8-frame animation with sprites named "FKIK"
"SPR2_SHIT",	//This one's for that "fallen down" frame when you fail an XMomentum trick
"SPR2_SIIT",    //Taunts, yeeeeeeeeeeee
"SPR2_LUGI",
"SPR2_DAAB",
"SPR2_ATRK",	//For the ChrispyChars tricks - these don't need specific names, I just prefer these
"SPR2_BTRK",
"SPR2_CTRK",
"SPR2_MAZN",    //Seriously - for anyone diving into the code here, don't tell anyone else about Mazin Backwards Aigis! I want it to be a surprise find - for at least a week.
"SPR2_IDLE",	//SRB2 Persona stuff
"SPR2_OUCH",
"SPR2_GARD",
"SPR2_KICK",
"MT_BOST",
"MT_LZHP",
"MT_STHP",
"MT_OORB",
"MT_BAIGLAZER",
"MT_BAIGJUMPLAZER",
"MT_BAIGCHARGELAZER")

//Shooting states
states[S_BAIG_SHOT] = {
	sprite = SPR_PLAY,
	tics = 10,
	nextstate = S_PLAY_WALK,
	frame = FF_ANIMATE|SPR2_FIRE,
	var1 = 5,
	var2 = 2
}

states[S_BAIG_SHOT_JUMP] = {
	sprite = SPR_PLAY,
	tics = 10,
	nextstate = S_PLAY_FALL,
	frame = FF_ANIMATE|SPR2_FIRE,
	var1 = 5,
	var2 = 2
}

states[S_BAIG_SHOT_SPRING] = {
	sprite = SPR_PLAY,
	tics = 10,
	nextstate = S_PLAY_FALL,
	frame = FF_ANIMATE|SPR2_FIRE,
	var1 = 5,
	var2 = 2
}

//Jumpshooting State
states[S_BAIG_JUMPSHOT] = {
	sprite = SPR_PLAY,
	tics = 10,
	nextstate = S_PLAY_FALL,
	frame = SPR2_BANG
}

//Spinkick state
states[S_BAIG_SKICK] = {
	sprite = SPR_PLAY,
	tics = -1,
	nextstate = S_BAIG_STOMP,
	frame = FF_ANIMATE|SPR2_KICK,
	var1 = 7,
	var2 = 1
}

//Stomping state
states[S_BAIG_STOMP] = {
	sprite = SPR_PLAY,
	tics = -1,
	nextstate = S_PLAY_FALL,
	frame = SPR2_STMP
}

//SpeedCharge state
states[S_BAIG_SPED] = {
	sprite = SPR_PLAY,
	tics = -1,
	nextstate = S_PLAY_RUN,
	frame = SPR2_SPED
}

//DriftDash states
states[S_BAIG_DFTR] = {
	sprite = SPR_PLAY,
	tics = -1,
	nextstate = S_PLAY_RUN,
	frame = FF_ANIMATE|SPR2_DFTR,
	var1 = 3,
	var2 = 2
}

states[S_BAIG_DFTL] = {
	sprite = SPR_PLAY,
	tics = -1,
	nextstate = S_PLAY_RUN,
	frame = FF_ANIMATE|SPR2_DFTL,
	var1 = 3,
	var2 = 2
}

//Jetpack Up State
states[S_BAIG_JPKU] = {
	sprite = SPR_PLAY,
	tics = -1,
	nextstate = S_PLAY_WALK,
	frame = FF_ANIMATE|SPR2_JPKU,
	var1 = 3,
	var2 = 2
}

//Taunt States, pfffft
states[S_BAIG_SHIT] = {
	sprite = SPR_PLAY,
	tics = -1,
	nextstate = S_PLAY_WALK,
	frame = SPR2_SHIT
}

states[S_BAIG_TAUNT1] = {
	sprite = SPR_PLAY,
	tics = -1,
	nextstate = S_PLAY_WALK,
	frame = SPR2_SIIT
}

states[S_BAIG_TAUNT2] = {
	sprite = SPR_PLAY,
	tics = 36,
	nextstate = S_PLAY_STND,
	frame = FF_ANIMATE|SPR2_LUGI,
	var1 = 17,
	var2 = 2
}

states[S_BAIG_DAB] = {
	sprite = SPR_PLAY,
	tics = -1,
	nextstate = S_PLAY_WALK,
	frame = SPR2_DAAB
}

//Lazer Object States
states[S_BAIGLAZER] = {
	sprite = SPR_LAZF,
	tics = -1,
	nextstate = S_BAIGLAZEREND,
	frame = FF_FULLBRIGHT|FF_ANIMATE|A,
	var1 = 6,
	var2 = 2
}

states[S_BAIGJUMPLAZER] = {
	sprite = SPR_LAZJ,
	tics = -1,
	nextstate = S_BAIGLAZEREND,
	frame = FF_FULLBRIGHT|FF_ANIMATE|A,
	var1 = 6,
	var2 = 2
}

states[S_BAIGCHARGELAZER] = {
	sprite = SPR_CHRG,
	tics = 175,
	nextstate = S_NULL,
	frame = FF_FULLBRIGHT|FF_ANIMATE|A,
	var1 = 6,
	var2 = 2
}

states[S_BAIGLAZEREND] = {
	sprite = SPR_GSPK,
	tics = 2,
	nextstate = S_NULL,
	frame = FF_FULLBRIGHT|FF_ANIMATE|A,
	var1 = 1,
	var2 = 2
}

states[S_BAIGGROUNDSPARK] = {
	sprite = SPR_GSPK,
	tics = 2,
	nextstate = S_NULL,
	frame = FF_FULLBRIGHT|FF_ANIMATE|A,
	var1 = 1,
	var2 = 2
}

//Lazer Object Codes
mobjinfo[MT_BAIGLAZER].spawnstate = S_BAIGLAZER
mobjinfo[MT_BAIGLAZER].deathstate = S_NULL
mobjinfo[MT_BAIGLAZER].deathsound = sfx_turhit
mobjinfo[MT_BAIGLAZER].speed = 100*FRACUNIT
mobjinfo[MT_BAIGLAZER].radius = 30*FRACUNIT
mobjinfo[MT_BAIGLAZER].height = 30*FRACUNIT
mobjinfo[MT_BAIGLAZER].damage = 1
mobjinfo[MT_BAIGLAZER].flags = MF_NOGRAVITY | MF_MISSILE | MF_NOCLIPHEIGHT

mobjinfo[MT_BAIGCHARGELAZER].spawnstate = S_BAIGCHARGELAZER
mobjinfo[MT_BAIGCHARGELAZER].deathstate = S_NULL
mobjinfo[MT_BAIGCHARGELAZER].speed = 100*FRACUNIT
mobjinfo[MT_BAIGCHARGELAZER].radius = 50*FRACUNIT
mobjinfo[MT_BAIGCHARGELAZER].height = 50*FRACUNIT
mobjinfo[MT_BAIGCHARGELAZER].damage = 2
mobjinfo[MT_BAIGCHARGELAZER].health = 10
mobjinfo[MT_BAIGCHARGELAZER].flags = MF_NOGRAVITY | MF_MISSILE | MF_NOCLIPHEIGHT

mobjinfo[MT_BAIGJUMPLAZER].spawnstate = S_BAIGJUMPLAZER
mobjinfo[MT_BAIGJUMPLAZER].deathstate = S_BAIGGROUNDSPARK
mobjinfo[MT_BAIGJUMPLAZER].radius = 40*FRACUNIT
mobjinfo[MT_BAIGJUMPLAZER].height = 40*FRACUNIT
mobjinfo[MT_BAIGJUMPLAZER].damage = 1
mobjinfo[MT_BAIGJUMPLAZER].flags = MF_NOGRAVITY

//Flashing Orb particle Code and state
states[S_OORB] = {
	sprite = SPR_OORB,
	tics = 6,
	nextstate = S_NULL,
	frame = FF_FULLBRIGHT|FF_ANIMATE|A,
	var1 = 1,
	var2 = 1
}

mobjinfo[MT_OORB].spawnstate = S_OORB
mobjinfo[MT_OORB].deathstate = S_NULL
mobjinfo[MT_OORB].radius = 5*FRACUNIT
mobjinfo[MT_OORB].height = 5*FRACUNIT
mobjinfo[MT_OORB].flags = MF_NOGRAVITY | MF_NOCLIP

//Glowing Hoop Codes and states
states[S_LZHP] = {
	sprite = SPR_LZHP,
	tics = 8,
	nextstate = S_NULL,
	frame = FF_FULLBRIGHT|FF_ANIMATE|A,
	var1 = 3,
	var2 = 2
}

states[S_STHP] = {
	sprite = SPR_STHP,
	tics = 4,
	nextstate = S_NULL,
	frame = FF_FULLBRIGHT|FF_ANIMATE|A,
	var1 = 3,
	var2 = 1
}

mobjinfo[MT_LZHP].spawnstate = S_LZHP
mobjinfo[MT_LZHP].deathstate = S_NULL
mobjinfo[MT_LZHP].radius = 5*FRACUNIT
mobjinfo[MT_LZHP].height = 5*FRACUNIT
mobjinfo[MT_LZHP].flags = MF_NOGRAVITY | MF_NOCLIP

mobjinfo[MT_STHP].spawnstate = S_STHP
mobjinfo[MT_STHP].deathstate = S_NULL
mobjinfo[MT_STHP].radius = 5*FRACUNIT
mobjinfo[MT_STHP].height = 5*FRACUNIT
mobjinfo[MT_STHP].flags = MF_NOGRAVITY | MF_NOCLIP




//Code for T116Chars Boostmode - Might make more special later! Feel free to copy and edit for custom dashmode shenanigans.

//Object state and info for the blue dash particles - replace with whatever sprites you'd like, but don't forget to freeslot them above!
//While doing so, replace every instance of "BOST" in your code and sprite names with a different name, or sprite conflicts will occur -
//namely, Backwards Aigis will use whatever graphic you added in instead of her dashlines, or your character will use the dashlines instead of your graphic.

states[S_BOST] = {
	sprite = SPR_BOST,
	tics = 4,
	nextstate = S_NULL,
	frame = FF_FULLBRIGHT|FF_ANIMATE|FF_PAPERSPRITE|A,
	var1 = 3,
	var2 = 2
}

mobjinfo[MT_BOST].spawnstate = S_BOST
mobjinfo[MT_BOST].deathstate = S_NULL
mobjinfo[MT_BOST].radius = 20*FRACUNIT
mobjinfo[MT_BOST].height = 5*FRACUNIT
mobjinfo[MT_BOST].flags = MF_NOGRAVITY | MF_NOCLIP


//The code itself
local function boostmode()
    for player in players.iterate
        if player.mo.skin == "backwards_aigis" then
		
		S_StopSoundByID(player.mo, 703)
		S_StopSoundByID(player.mo, 727) //Sounds 703 and 727 are the "power up" and "power down" sounds that occur
		//when entering or exiting vanilla dashmode.
		//This stops it from playing, as setting player.dashmode to 3*TICRATE 
		//under certain conditions while testing used to cause the latter to play on every frame -
		//namely, not setting dashmode to true in S_SKIN. I thought it wouldn't be necessary, and
		//I had hoped to keep this version of boost mode as seperate as possible from the vanilla one
		//to prevent any random conflicts.
		//That said, since vanilla dashmode is very hardcoded, the sounds might still pop up
		//from time to time. If you see this and know of an alternate fix, please let me know.
		//The reason why you have to set player.dashmode to 3*TICRATE is explained below.
		
		player.bostspawn = $ or 0 //counter for spawning the blue dash particles
		if player.bostspawn > 2 then
			player.bostspawn = 0
		end
		
		player.boostmode = $ or 0 //starts a counter for boost mode
			if player.speed > player.runspeed //if moving fast enough or spindashing, the counter increases. Remove "player.panim == PA_ABILITY2" if your character can't spindash, unless you want things like melee attacks to speed you up.      Actually... Hmm.
			or player.panim == PA_ABILITY2 
			or player.mo.state == S_BAIG_SPED then
				player.boostmode = $ + 1
			elseif player.panim == PA_SPRING and not (player.pflags & PF_JUMPED) //if launching off a spring/similar objects or rolling, the counter stays put. This lets you preserve speed!
			or player.panim == PA_FALL and not (player.pflags & PF_JUMPED)
			or player.panim == PA_ROLL
			or player.mo.state == S_BAIG_SHOT //also preserves boostmode counter if in shooting states
			or player.mo.state == S_BAIG_SHOT_JUMP //you can check for states instead of animations if you'd like
			or player.mo.state == S_BAIG_SHOT_SPRING then
				player.boostmode = $
			else //if not doing any of those things, the counter decreases.
				player.boostmode = $ - 1
			end
			
			if player.boostmode < 0 then //prevents the counter from going under 0.
				player.boostmode = 0
			end
			
			if leveltime == 0*TICRATE then //stops boostmode from being preserved bewteen levels
				player.boostmode = 0
			end
			
			
            if player.boostmode >= 70 then// once the counter reaches 70 (about two in-game seconds), boost mode activates!
				if player.boostghost and player.boostghost.valid then // Prevents the first ghost from showing, preventing weird visuals. Thanks to L_CloneFighter-v2.pk3 on Discord for helping with this.
					player.boostghost.flags2 = $ & ~MF2_DONTDRAW
				end
			    player.boostghost = P_SpawnGhostMobj(player.mo) //spawns afterimages
                player.boostghost.fuse = 3 //amount of afterimages
				player.boostghost.flags2 = $|MF2_DONTDRAW // Part of preventing the first ghost from showing
				player.bostspawn = $ + 1
				if player.bostspawn == 1 then
					local bostlocal = P_SpawnMobjFromMobj(player.mo, P_RandomRange(-64, 64)*FRACUNIT, P_RandomRange(-64, 64)*FRACUNIT, P_RandomRange(5, 56)*FRACUNIT, MT_BOST) //spawns blue dash particles randomly around the player
					if bostlocal and bostlocal.valid then
						bostlocal.angle = player.mo.angle
					end
				end
				
				if not player.isxmomentum then //prevents normalspeed from changing while xmomentum is loaded, since normalspeed is what's used for xmomentum to work.
					player.normalspeed = 48*FRACUNIT //increases player's top speed
				end
				
				if player.speed > player.runspeed
				and player.panim ~= PA_PAIN
				and not (player.pflags & PF_FULLSTASIS)then
					player.dashmode = 3*TICRATE //This allows the custom boost mode to function with momentum mods - those usually only recognize vanilla dashmode, and this is a way around that.
				end
		    elseif player.boostmode >= 50 then
				if player.boostghost and player.boostghost.valid then
					player.boostghost.flags2 = $ & ~MF2_DONTDRAW
				end
			    player.boostghost = P_SpawnGhostMobj(player.mo) //Spawns 2 afterimages before it activates, as a warning before it does
				player.boostghost.fuse = 2
				player.boostghost.flags2 = $|MF2_DONTDRAW
				if not player.isxmomentum then
					player.normalspeed = 36*FRACUNIT
				end
				player.bostspawn = $
				player.dashmode = 0*TICRATE
			else
				if not player.isxmomentum then
					player.normalspeed = 36*FRACUNIT
				end
				player.bostspawn = $
				player.dashmode = 0*TICRATE
            end
			
			if player.boostmode > 106 then //prevents the counter from increasing infinitely, but with about an extra second of leeway while not moving to keep the speed up.
				player.boostmode = 105
			end
			
			//This bit controls the sound that plays when entering boost mode.
			//It prevents it from playing when exiting boost mode.
			//Thanks to amperbee on Discord for helping - I had coded my own way around this,
			//but it was dumb and confusing.
			local boostmode = player.boostmode
			local boostmodeprev = player.boostmodeprev or 0
			
			if player.boostmode == 70
			and boostmode > boostmodeprev then
				S_StartSound(player.mo, 469)
			end
			
			player.boostmodeprev = boostmode
			
		//Gonna archive the way I did it here, if you want to see that for some reason
			
		//  //A check to make sure the sound below only plays when entering boost mode, and not exiting it.
		//  if player.boostmode == 69 then
		//  	player.boostmodesoundcheck = true
		//  end
			
		//  //plays a sound upon entering boost mode. This isn't part of the code above because that would cause the sound to play on every frame
		//  if player.boostmode == 70 
		//  and player.boostmodesoundcheck == true then
		//  	S_StartSound(player.mo, 469)
		//  end
		//  //when the variable is false, the sound doesn't trigger.
		//  if player.boostmode == 71 then
		//  	player.boostmodesoundcheck = false
		//  end
			
        end
    end
end

addHook("ThinkFrame", boostmode)



//Lazer Code Section



//Code for her neutral special
local function shoot()
    for player in players.iterate
	    player.baigisshootcounter = $ or 0 //starts a counter to prevent shooting on every frame - maybe I'll give her a "machine gun mode" someday.
        if player.mo.skin == "backwards_aigis" then
			
			if player.mo.state == S_PLAY_DEAD then //stops her from shooting when dead, for obvious reasons
				return
			end
			
			if G_IsSpecialStage(gamemap) then //Prevents shots from occuring in special stages
				return
			end
			
            if (player.cmd.buttons & BT_CUSTOM1) and player.baigisshootcounter > 10 then //when the counter reaches 10, she can shoot
			    if (player.pflags & PF_JUMPED) //makes sure she doesn't spin without damaging, or vise versa
				or (player.pflags & PF_SPINNING)
				or (player.pflags & PF_STARTDASH) then
					player.mo.state = S_BAIG_SHOT_JUMP //the states from way earlier
				elseif player.panim == PA_SPRING
				or player.panim == PA_FALL then
					player.mo.state = S_BAIG_SHOT_SPRING
				else
					player.mo.state = S_BAIG_SHOT
				end
				S_StartSoundAtVolume(player.mo, 141, 100)
				P_SpawnPlayerMissile(player.mo, MT_BAIGLAZER)
				player.baigisshootcounter = 0 //resets the counter
			end
			player.baigisshootcounter = $ + 1 //actually makes the counter increment upwards
        end
    end
end

//Function for command that switches homing lazers on or off
local function HomingLazerSwitch(player, arg)
	if player.mo and player.mo.valid then
		if player.mo.skin == "backwards_aigis" then //Checks if you're playing as her
			if arg then //Arg is short for argument, aka what a player types in the console after the command
				arg = arg:lower() //lower() switches the argument to all lowercase - it's easier to manage
				if arg == "off"
				or arg == "no"
				or arg == "disable"
				or arg == "disabled"
				or arg == "0"
				or arg == "false"
					player.hominglazers = "Off" //Turns them off
					CONS_Printf(player, "Lazers will not lock onto enemies and monitors.") //Prints this message, only for the player who activate the command
				elseif arg == "on"
				or arg == "yes"
				or arg == "enable"
				or arg == "enabled"
				or arg == "1"
				or arg == "true" then
					player.hominglazers = "On" //Turns them on
					CONS_Printf(player, "Lazers will now lock onto enemies and monitors.")
				else
					CONS_Printf(player, "Invalid Input. Options are on and off.")
				end
			else
				CONS_Printf(player, "Toggles homing lazers. Will not affect charge shots. Current option is: " + player.hominglazers) //Printed when no argument is present
			end
		else
			CONS_Printf(player, "You're not playing as Backwards Aigis. Swap skins first!") //Printed for obvious reasons
		end
	else
		CONS_Printf(player, "This can only be done in a level.") //Same as above
	end
end

//Registers the command under the name specified
COM_AddCommand("hominglazers", function(player, arg)
	HomingLazerSwitch(player, arg)
end)


//Code for homing lazers - I'm an idiot for not doing this earlier...
addHook("MobjThinker", function(mo, player)
	if mo.target.player.hominglazers == "On" then
		mo.tracer = P_LookForEnemies(mo.target.player, false, true)
		A_HomingChase(mo, 75*FRACUNIT, 1)
	else
		return
	end
end, MT_BAIGLAZER)


addHook("ThinkFrame", shoot)

//Code for her charge shot
local function chargeshot()
	for player in players.iterate
		player.baigischargeshotcounter = $ or 0
		if player.mo.skin == "backwards_aigis" then
		
			if player.mo.state == S_PLAY_DEAD then
				return
			end
			
			if G_IsSpecialStage(gamemap) then //Prevents shots from occuring in special stages
				return
			end
			
			if player.powers[pw_super] ~= 0 then //superform-only rapid charge shot code - nearly identical to the regular shot code
				if (player.cmd.buttons & BT_CUSTOM2) and player.baigischargeshotcounter > 10 then
					if (player.pflags & PF_JUMPED)
					or (player.pflags & PF_SPINNING)
					or (player.pflags & PF_STARTDASH) then
						player.mo.state = S_BAIG_SHOT_JUMP
					elseif player.panim == PA_SPRING
					or player.panim == PA_FALL then
						player.mo.state = S_BAIG_SHOT_SPRING
					else
						player.mo.state = S_BAIG_SHOT
					end
					S_StartSoundAtVolume(player.mo, 93, 150)
					P_SpawnPlayerMissile(player.mo, MT_BAIGCHARGELAZER)
					player.baigischargeshotcounter = 0
				end
				player.baigischargeshotcounter = $ + 1
			else                                            //Actual charge shot code
				if (player.cmd.buttons & BT_CUSTOM2) then //counter that goes up when custom 2 is held, and goes down when it isn't
					if not S_SoundPlaying(player.mo, 647) 
					and player.chargeshotready == false then
						S_StartSoundAtVolume(player.mo, 647, 150)
					end
					player.baigischargeshotcounter = $ + 1
				else
					S_StopSoundByID(player.mo, 647)
					player.baigischargeshotcounter = $ - 1
				end
				
				if player.baigischargeshotcounter < 0 then //prevents the counter from decreasing or increasing infinitely
					player.baigischargeshotcounter = 0
				elseif player.baigischargeshotcounter > 50 then
					player.baigischargeshotcounter = 50
				end
				
				if player.baigischargeshotcounter > 30 then //variable for when the charge is ready, easier to code with
					S_StopSoundByID(player.mo, 647)
					player.chargeshotready = true
				else
					player.chargeshotready = false
				end
				
				if player.chargeshotready
				and not (player.cmd.buttons & BT_CUSTOM2) then //makes her shoot on release of custom2 instead of rapid firing
					if (player.pflags & PF_JUMPED) //again, makes sure she doesn't spin without damaging, or vise versa
					or (player.pflags & PF_SPINNING)
					or (player.pflags & PF_STARTDASH) then
						player.mo.state = S_BAIG_SHOT_JUMP
					elseif player.panim == PA_SPRING
					or player.panim == PA_FALL then
						player.mo.state = S_BAIG_SHOT_SPRING
					else
						player.mo.state = S_BAIG_SHOT
					end
					S_StartSoundAtVolume(player.mo, 93, 150)
					P_SpawnPlayerMissile(player.mo, MT_BAIGCHARGELAZER)
					player.baigischargeshotcounter = 0 //resets the timer completely upon shooting
				end
			end
		end
	end
end

addHook("ThinkFrame", chargeshot)

addHook("MobjLineCollide", function(mo) //Prevents charge shots from disappearing immediately if shot next to a wall
	if mo and mo.valid then
		return false
	end
end, MT_BAIGCHARGELAZER)

//Adds cool hoops around the lazer shots - helps with seeing where they are (also an excuse to make their hitboxes bigger)
addHook("MobjThinker", function(mo)
	if not mo.hoopspawn then
		mo.hoopspawn = 0
	end
	
	if mo.hoopspawn > 8 then
		mo.hoopspawn = 0
	end
	
	mo.hoopspawn = $ + 1
	if mo.hoopspawn == 1 then
		mo.hooplocal = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_LZHP) //spawns speed hoops
		mo.hooplocal.color = SKINCOLOR_CYAN
		if mo.hooplocal and mo.hooplocal.valid then
			mo.hooplocal.angle = mo.angle
			mo.hooplocal.scale = FRACUNIT/4
		end
	end
end, MT_BAIGLAZER)

addHook("MobjThinker", function(mo)
	if not mo.hoopspawn then
		mo.hoopspawn = 0
	end
	
	if mo.hoopspawn > 8 then
		mo.hoopspawn = 0
	end
	
	mo.hoopspawn = $ + 1
	if mo.hoopspawn == 1 then
		mo.hooplocal = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_LZHP) //spawns speed hoops
		mo.hooplocal.color = SKINCOLOR_CYAN
		if mo.hooplocal and mo.hooplocal.valid then
			mo.hooplocal.angle = mo.angle
			mo.hooplocal.scale = FRACUNIT/2
		end
	end
end, MT_BAIGCHARGELAZER)


//function that checks if a wall is bustable, then crumbles it, by Tatsuru
local function CheckAndCrumble(mo, sec)
  for fof in sec.ffloors()
    if not (fof.flags & FF_EXISTS) then continue end
    if not (fof.flags & FF_BUSTUP) then continue end
    
    if mo.z + mo.height < fof.bottomheight then continue end 
    if mo.z > fof.topheight then continue end

    EV_CrumbleChain(fof)
  end
end

//Calls the crumble function for the chargeshot
addHook("MobjThinker", function(mo)
  CheckAndCrumble(mo, mo.subsector.sector)
end, MT_BAIGCHARGELAZER)

//Collision code to let everything activate properly
addHook("MobjLineCollide", function(mo, line)
  for _, sec in ipairs({line.frontsector, line.backsector})
    CheckAndCrumble(mo, sec)
  end
end, MT_BAIGCHARGELAZER)


//Code that lets chargeshots break spikes
addHook("MobjMoveCollide", function(mo, spike)
	if not spike and not spike.valid then
		return
	end
	
	if (mo.z < spike.z - 40*FRACUNIT) or (mo.z >= spike.z + 40*FRACUNIT) then
		return
	end
	
	if spike.type == MT_SPIKE
	or spike.type == MT_SALOONDOOR //WIP behaviour to also break through ACZ's saloon doors - for now, they sort of just disappear :P
	or spike.type == MT_SALOONDOORCENTER then
		P_KillMobj(spike)
	else
		return
	end
	
	P_KillMobj(spike)
end, MT_BAIGCHARGELAZER)

//Code that lets chargeshots deal two damage - except for certain instances where you aren't dead center on your shots for some reason
//Stupid bees and their stupid bee spawners
addHook("MobjMoveCollide", function(mo, mohit)
	if (mo.z < mohit.z - 40*FRACUNIT) or (mo.z >= mohit.z + 40*FRACUNIT) then
		return
	end
	
	if mohit and mohit.valid then
		if mohit.flags & MF_ENEMY
		or mohit.flags & MF_SHOOTABLE
		or mohit.flags & MF_BOSS then
			P_DamageMobj(mohit, mo, mo.target, 2)
		end
	end
end, MT_BAIGCHARGELAZER)

//Code for Jumpshooting
local function jumpshot()
	for player in players.iterate
		if player.mo.skin == "backwards_aigis" then
			
			if player.mo.state == S_PLAY_DEAD then
				return
			end
			
			if not player.powers[pw_super] then
				if not (player.cmd.buttons & BT_JUMP) then //variables are being set to make sure this all works properly
					player.jumpshotready = true
					player.jumpshooting = false
				elseif not (player.pflags & PF_JUMPED) then //if she hasn't jumped, the jumpshot won't go off - prevents it from breaking things on springs, like ChrispyChars Tricks
					player.jumpshotready = true
					player.jumpshooting = false
				elseif player.jumpshotready then //actually causes the shot
					player.jumpshooting = true
					player.jumpshotready = false
				else
					player.jumpshooting = false
				end
				
				if player.jumpshooting then //the shot itself
					player.mo.state = S_BAIG_JUMPSHOT
					if (player.mo.eflags & MFE_VERTICALFLIP) then
						S_StartSoundAtVolume(player.mo, 141, 100)
						local mylocal = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z + 20*FRACUNIT, MT_BAIGJUMPLAZER)
						mylocal.target = player.mo
					else
						S_StartSoundAtVolume(player.mo, 141, 100)
						local mylocal = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_BAIGJUMPLAZER)
						mylocal.target = player.mo
					end
				end
			end
		end
	end
end

addHook("ThinkFrame", jumpshot)

//Codes for lazer afterimages
addHook("MobjThinker", function(mo)
	local lazerghost = P_SpawnGhostMobj(mo)
    lazerghost.fuse = 10
end, MT_BAIGLAZER)

addHook("MobjThinker", function(mo)
	local chargelazerghost = P_SpawnGhostMobj(mo)
    chargelazerghost.fuse = 10
end, MT_BAIGCHARGELAZER)


//Code for vertical lazers, thank you so much Marcos
addHook("MobjThinker", function(mo)
	if mo and mo.valid then
	
		if (mo.eflags & MFE_VERTICALFLIP) then //checks if she's upside down, and pushes the lazer upwards or downwards respectively
			mo.z = $ + 70*FRACUNIT
		else
			mo.z = $ - 70*FRACUNIT
		end
		
		if mo.target and mo.target.valid then
			if (mo.target.eflags & MFE_VERTICALFLIP) and not (mo.eflags & MFE_VERTICALFLIP) then //sets the verticalflip flag based on Backwards Aigis' current state, so the code above triggers properly
				mo.eflags = $ | MFE_VERTICALFLIP
			elseif not (mo.target.eflags & MFE_VERTICALFLIP) and (mo.eflags & MFE_VERTICALFLIP) then
				mo.eflags = $ & ~MFE_VERTICALFLIP
			end
		end
		
		if (mo.state ~= S_BAIGGROUNDSPARK) and P_IsObjectOnGround(mo) then //calls the groundspark state. Causes lag in netgames, so it's been disabled for now (the state only lasts for 2 tics)
			mo.state = S_BAIGGROUNDSPARK
		end
	end
end, MT_BAIGJUMPLAZER)

//JumpLazer collision code, again thank you Marcos
addHook("MobjMoveCollide", function(mo, mohit)
	if mo and mo.valid then
		if (mo.z < mohit.z) or (mo.z >= mohit.z + 10*FRACUNIT) then //I know what this does now - it's a height check.
			return
		end
	end
	
	if mohit and mohit.valid then
		if mohit.flags & MF_ENEMY //if the lazer or groundspark hits something, it damages it and disappears
		or mohit.flags & MF_MONITOR
		or mohit.flags & MF_SHOOTABLE
		or mohit.flags & MF_BOSS then
			P_DamageMobj(mohit, mo, mo.target, 1)
			P_RemoveMobj(mo)
		else
			return
		end
	end
end, MT_BAIGJUMPLAZER)



//Other Abilities


//SpinKick and Stomp Ability
local function spinstomp()
	for player in players.iterate
		if player.mo.skin == "backwards_aigis" then
		
			if not (player.cmd.buttons & BT_USE) then //I misunderstood what this really does for the longest time -
				player.spintapready = true			  //checking for "player.spintapping" using this code from the wiki tutorial
				player.spintapping = false			  //instead of just checking for the spin button lets you stop things from happening
			elseif player.spintapready then			  //if spin is constantly held, instead requiring a re-press of the button.
				player.spintapping = true
				player.spintapready = false
			else
				player.spintapping = false
			end
			
			
			if player.mo.state == S_PLAY_DEAD then //again, pretty sure a robot out of battery can't stomp or spinkick
				return
			end
		
			if player.mo.state == S_PLAY_SUPER_TRANS1 //lets you transform with the animation instead of just spinkicking
			or player.mo.state == S_PLAY_SUPER_TRANS2 //though... that gives me an idea for a custom transform animation.
			or player.mo.state == S_PLAY_SUPER_TRANS3
			or player.mo.state == S_PLAY_SUPER_TRANS4
			or player.mo.state == S_PLAY_SUPER_TRANS5
			or player.mo.state == S_PLAY_SUPER_TRANS6 then
				return
			end
			
			//This bit's mostly from SSNMighty since he's reusable and I can't think of a better way to code it
			if (player.stomped == true) then
				for x=player.mo.x,player.mo.x+player.mo.radius,player.mo.radius
					for y=player.mo.y,player.mo.y+player.mo.radius,player.mo.radius
						local ss = R_PointInSubsector(x,y)
						for fof in ss.sector.ffloors()
							if (fof.flags & FF_BUSTUP) and (fof.flags & FF_EXISTS) then
								if (player.mo.z+player.mo.momz==fof.topheight or player.mo.z+player.mo.height+player.mo.momz==fof.bottomheight or (player.mo.eflags & MFE_VERTICALFLIP and (player.mo.z+player.mo.momz==fof.bottomheight or player.mo.z-player.mo.height-player.mo.momz==fof.topheight))) then
									EV_CrumbleChain(ss.sector, fof)
									player.stomping = true
									player.mo.momz = -40*FRACUNIT*P_MobjFlip(player.mo)
									player.mo.state = S_BAIG_STOMP
									player.spinpressed = true
								end
							end
						end
					end
				end
			end
		
			if not player.kickcounter then //initial value for a counter
				player.kickcounter = 0
			end
			
			if player.spinpressed then //increases the counter when spin's pressed
				player.kickcounter = $ + 1
			end
			
			
			//if not player.powers[pw_super] then //prevents certain shields from overriding or messing with spinkicks and stomps.
			//	if (player.powers[pw_shield] & SH_WHIRLWIND)
			//	or (player.powers[pw_shield] & SH_ELEMENTAL)
			//	or (player.powers[pw_shield] & SH_FORCE) then
			//		player.charflags = $|SF_NOSHIELDABILITY
			//	elseif (player.powers[pw_shield] & SH_ATTRACT) then
			//		//not actually sure what I'll do for this one tbh, but for now:
			//		player.charflags = $|SF_NOSHIELDABILITY
			//	else
			//		player.charflags = $ & ~SF_NOSHIELDABILITY
			//	end
			//end
			//Was planning on disabling certain shield abilities, but for now I'll just turn them all off
			
			if player.spintapping //If spin is pressed after a jump, she'll kick out and spin, gaining some height!
			and ((player.pflags & PF_JUMPED) or ((not P_IsObjectOnGround(player.mo)) and player.powers[pw_super])) then //If spin is pressed after a jump, she'll kick out and spin, gaining some height!
				player.spinpressed = true //a seperate variable for checking if spin's been pressed (stays true for more than one frame)
				if (player.mo.eflags & MFE_UNDERWATER) then
					P_SetObjectMomZ(player.mo, 5*FRACUNIT, false) //Doesn't send as high underwater
				else
					P_SetObjectMomZ(player.mo, 10*FRACUNIT, false)
				end
				player.mo.state = S_BAIG_SKICK
				if player.kickcounter > 1 then
					player.kicked = true //variable to check if she's already spinkicked
				end
			end
		
			if player.mo.state == S_BAIG_SKICK then //cool blue afterimage effect :D
				if player.spinghost and player.spinghost.valid then // Prevents the first ghost from showing, preventing weird visuals. Thanks to L_CloneFighter-v2.pk3 on Discord for helping with this.
					player.spinghost.flags2 = $ & ~MF2_DONTDRAW
				end
				player.spinghost = P_SpawnGhostMobj(player.mo)
				player.spinghost.fuse = 5
				player.spinghost.color = SKINCOLOR_CYAN
				player.spinghost.colorized = true
				player.spinghost.flags2 = $|MF2_DONTDRAW
			end
		
			if not (player.cmd.buttons & BT_USE) then //variables are being set to make sure this all works properly
				player.stompready = true
				player.stomping = false
			elseif not ((player.pflags & PF_JUMPED) or ((not P_IsObjectOnGround(player.mo)) and player.powers[pw_super])) then //if she hasn't jumped and spinkicked, the stomp won't happen
				player.stompready = true
				player.stomping = false
			elseif player.stompready and player.kicked == true then //actually causes the stomp
				player.stomping = true
				player.stompready = false
			end

			if P_IsObjectOnGround(player.mo) then //resetting variables to prevent jank
				player.spinpressed = false
				player.kickcounter = 0
				player.stompcounter = 0
				player.kicked = false
				player.stomped = false
			end

			if player.spintapping 
			and player.kicked == true
			and player.mo.state ~= S_BAIG_STOMP then
				player.spinpressed = true
				player.mo.state = S_BAIG_STOMP //If you press spin again after already spinkicking, she'll launch towards the ground!
				player.stomped = true
				if P_IsObjectOnGround(player.mo) then //Helps the stomp break through the ground
					player.mo.state = S_BAIG_STOMP
				end
			end
			
			if player.mo.state ~= S_BAIG_STOMP then
				player.stompcounter = 0
			end
			
			if not player.stomphoopspawn then
				player.stomphoopspawn = 0
			end
			
			if player.stomphoopspawn > 4 then
				player.stomphoopspawn = 0
			end
			
			if player.mo.state == S_BAIG_STOMP then
				if player.stompghost and player.stompghost.valid then // Prevents the first ghost from showing, preventing weird visuals. Thanks to L_CloneFighter-v2.pk3 on Discord for helping with this.
					player.stompghost.flags2 = $ & ~MF2_DONTDRAW
				end
				player.stompghost = P_SpawnGhostMobj(player.mo) //spawns afterimages
                player.stompghost.fuse = 5 //amount of afterimages
				player.stompghost.color = SKINCOLOR_CYAN
				player.stompghost.colorized = true
				player.stompghost.flags2 = $|MF2_DONTDRAW
				player.stomphoopspawn = $ + 1 // Cool hoops following her down - this is the counter
				if player.stomphoopspawn == 1 then //whenever this counter == 1, a hoop spawns
					player.stomphooplocal = P_SpawnMobjFromMobj(player.mo, 0, 0, 0, MT_STHP) //spawns speed hoops
					player.stomphooplocal.color = SKINCOLOR_CYAN
					if player.stomphooplocal and player.stomphooplocal.valid then
						player.stomphooplocal.angle = player.mo.angle
						player.stomphooplocal.scale = FRACUNIT/2
					end
				end
				player.stompcounter = $ + 1 //A counter, used below!
				player.mo.momz = -40*(player.mo.scale)*P_MobjFlip(player.mo) - (player.stompcounter)*(player.mo.scale)*P_MobjFlip(player.mo)
				//Sends her down!
				//*(player.mo.scale) can be used to scale movement with the player, in the case they've shrunk or grown.
				//*P_MobjFlip checks if you're upside-down or not, returning -1 if you are, letting me add or take away momentum.
				//At the end of this line, -(player.stompcounter) lets her actually accelerate downwards instead of keeping a steady speed, unlike most other stomp moves.
				if (player.mo.eflags & MFE_GOOWATER) then //stops a stomp if it's done in THZ goop - she'd get stuck until shooting a lazer.
					player.stomping = false
					if player.mo.state ~= S_PLAY_ROLL then
						player.mo.state = S_PLAY_ROLL
					end
				end
			end
				
			local state = player.mo.state //An easy way to check for the state you were in previously.
			local prevstate = player.prevstate or 0 // Note that the "player.prevstate = state" down there is needed for this to work, too.
													//Make sure it's after all the other code, though.
			if prevstate == S_BAIG_STOMP then //Boosts spring power if hit while stomping!
				if (player.powers[pw_justsprung]) then
					player.mo.momx = $ * 125/100
					player.mo.momy = $ * 125/100
					player.mo.momz = $ * 125/100
					S_StartSound(player.mo, sfx_sprong)
				end
			end
			
			if prevstate ~= S_BAIG_SKICK
			and player.mo.state == S_BAIG_SKICK then //plays a sound when she spinkicks
				S_StartSoundAtVolume(player.mo, 18, 150)
			elseif prevstate ~= S_BAIG_STOMP
			and player.mo.state == S_BAIG_STOMP then //plays a sound when she stomps
				S_StartSound(player.mo, 20) 
				S_StartSound(player.mo, 577)
			end
			
			player.prevstate = state
			//That was a lot		
		end
	end
end

addHook("ThinkFrame", spinstomp)
				
//SpeedCharge ability
local function speedcharge()
	for player in players.iterate
		if player.mo.skin == "backwards_aigis" then
			
			if srb2p then return end //Disabled in SRB2Persona - I figured it'd be annoying since a menu's mapped to spin there
			
			if player.mo.state == S_PLAY_DEAD then //again, probably need batteries if you wanna speed up
				return
			end
			
			if G_EnoughPlayersFinished() then //if she's finished a level, then she can't speedcharge.
				return
			end
			
			if (player.pflags & PF_SLIDING) then //prevents activation on slides
				return
			end
			
			if not player.speedboosting then //checks if it has a value yet
				player.speedboosting = false
			end
			
			if not player.speedchargecounter then //same as above
				player.speedchargecounter = 0
			end
			
			if not player.speedboostcounter then //guess what this is for
				player.speedboostcounter = 0
				
			end
			
			if player.speedchargecounter > 75 then //prevents infinite increasing
				player.speedchargecounter = 75
			end
			
			if player.speedchargecounter >= 75 then //Orbs spawn around her when she's reached maximum charge
				local orblocal = P_SpawnMobjFromMobj(player.mo, P_RandomRange(-64, 64)*FRACUNIT, P_RandomRange(-64, 64)*FRACUNIT, P_RandomRange(5, 56)*FRACUNIT, MT_OORB)
				orblocal.color = SKINCOLOR_CYAN
				orblocal.scale = player.mo.scale
			end
			
			if player.speedboostcounter > 36 then //prevents infinite increasing, but also stops the boost state (after about one in-game second)
				player.speedboostcounter = 36
				player.speedboosting = false
				player.speedchargecounter = 0
			end
			
			if player.spintapping then //lets me use player.spintapping to prevent jank (usually out of a stomp), while also letting her charge for more than a single frame
				player.spinboostusage = true
			elseif not P_IsObjectOnGround(player.mo) then
				player.spinboostusage = false
			end
			
			if player.speed <= 10*FRACUNIT //if moving slowly enough on the ground, holding spin charges a peelout-esque move that'll see her charge backwards!
			and P_IsObjectOnGround(player.mo)
			and (player.cmd.buttons & BT_USE)
			and player.spinboostusage then
				player.speedchargecounter = $ + 2 //counter for how long she's been charging
				player.mo.state = S_BAIG_SPED
				player.mo.momx = 0 //halt
				player.mo.momy = 0 //stop
				player.speedboosting = false //if she was already in a boosting state, it stops - prevents her from being blue while charging
				player.speedboostcounter = 0 //resets the counter that checks how long she was in the boosting state
				if player.speedchargecounter < 75 //plays a sound until max charge
				and not S_SoundPlaying(player.mo, 539) then
					S_StartSound(player.mo, 539)
				end
			elseif player.mo.state == S_BAIG_SPED
			and not (player.cmd.buttons & BT_USE) then //upon release of spin, she shoots off!
				player.speedboosting = true
				P_InstaThrust(player.mo, player.mo.angle, (player.speedchargecounter)*(player.mo.scale))
				S_StartSound(player.mo, 20)
				S_StartSound(player.mo, 577)
				if player.speed > player.runspeed then
					player.mo.state = S_PLAY_RUN
				else
					player.mo.state = S_PLAY_WALK
				end
			end
			
			if player.mo.state == S_BAIG_SPED then //gives her the cool boost particles while charging
				local bostspedlocal = P_SpawnMobjFromMobj(player.mo, P_RandomRange(-64, 64)*FRACUNIT, P_RandomRange(-64, 64)*FRACUNIT, P_RandomRange(5, 56)*FRACUNIT, MT_BOST) //spawns blue dash particles randomly around the player
				if bostspedlocal and bostspedlocal.valid then
					bostspedlocal.angle = player.mo.angle
				end
			end
			
			if player.mo.state ~= S_BAIG_SPED //stops the charging sound from playing when you aren't charging or have already maxed the counter
			or player.speedchargecounter > 74 then
				S_StopSoundByID(player.mo, 539)
			end
				
			if player.speedboosting then
				player.speedboostcounter = $ + 1 //how long you've been boosting
				if player.speedboostcounter < 35 then //only activates while boosting
					if player.speedchargecounter > 36 then //only changes her speed if it's charged enough to be faster than normal
						player.normalspeed = (player.speedchargecounter)*FRACUNIT
					end
					if player.speedghost and player.speedghost.valid then // Prevents the first ghost from showing, preventing weird visuals. Thanks to L_CloneFighter-v2.pk3 on Discord for helping with this.
						player.speedghost.flags2 = $ & ~MF2_DONTDRAW
					end
					player.speedghost = P_SpawnGhostMobj(player.mo)
					player.speedghost.fuse = 3
					player.speedghost.color = SKINCOLOR_CYAN
					player.speedghost.colorized = true
					player.speedghost.flags2 = $|MF2_DONTDRAW
				end
			
			end
		end
	end
end

addHook("ThinkFrame", speedcharge)


//DriftDash ability
local function driftdash()
	for player in players.iterate
		if player.mo.skin == "backwards_aigis" then
			
			if srb2p then return end //Disabled in SRB2Persona - I figured it'd be annoying since a menu's mapped to spin there
			
			if player.mo.state == S_PLAY_DEAD then //no drifting if you're dead
				return
			end
			
			if G_EnoughPlayersFinished() then //if she's finished a level, then she can't drift.
				return
			end
			
			if (player.pflags & PF_SLIDING) then //prevents activation on slides
				return
			end
		
			if not player.driftcounter then //you already know what this does if you're down here
				player.driftcounter = 0
			end
			
			if player.driftcounter > 90 then //counter cap
				player.driftcounter = 90
			end
			
			if player.speed > 10*FRACUNIT //if moving fast enough and moving to the side (not with the camera, the "strafe buttons"), you'll drift!
			and P_IsObjectOnGround(player.mo) //comes with unique physics!
			and (player.cmd.buttons & BT_USE)
			and player.spinboostusage then
				if player.cmd.sidemove > 0 then //checks for the left and right buttons, and changes her state depending on right and left
					if player.mo.state ~= S_BAIG_DFTR then
						player.mo.state = S_BAIG_DFTR
					end
				elseif player.cmd.sidemove < 0 then
					if player.mo.state ~= S_BAIG_DFTL then
						player.mo.state = S_BAIG_DFTL
					end
				end
			elseif (player.mo.state == S_BAIG_DFTR or player.mo.state == S_BAIG_DFTL)
			and not (player.cmd.buttons & BT_USE) then //after a drift, you'll get a small boost!
				if player.speed > 50*FRACUNIT then //decreases the speed boost if moving fast enough - makes sure she can't as easily spam to really fast speeds with momentum active
					P_InstaThrust(player.mo, player.drawangle, player.speed + 1*player.mo.scale)
				else
					P_InstaThrust(player.mo, player.drawangle, player.speed + 10*player.mo.scale)
				end
				S_StartSound(player.mo, 20)
				if player.speed > player.runspeed then
					player.mo.state = S_PLAY_RUN
				else
					player.mo.state = S_PLAY_WALK
				end
			end
			
			if player.mo.state == S_BAIG_DFTR then
				player.driftcounter = $ + 1
				if player.cmd.sidemove > 0 then //Rotates her more or less depending on which direction she's facing,
					player.drawangle = player.drawangle - (ANGLE_45)/10 //and which direction you're holding
				elseif player.cmd.sidemove < 0 then
					player.drawangle = player.drawangle - (ANGLE_45)/45
				else
					player.drawangle = player.drawangle - (ANGLE_45)/30
				end
				P_Thrust(player.mo, player.drawangle - ANGLE_90, 1*FRACUNIT) //Constantly thrusts her sideways
			elseif player.mo.state == S_BAIG_DFTL then
				player.driftcounter = $ + 1
				if player.cmd.sidemove < 0 then
					player.drawangle = player.drawangle + (ANGLE_45)/10
				elseif player.cmd.sidemove > 0 then
					player.drawangle = player.drawangle + (ANGLE_45)/45
				else
					player.drawangle = player.drawangle + (ANGLE_45)/30
				end
				P_Thrust(player.mo, player.drawangle + ANGLE_90, 1*FRACUNIT)
			else
				player.driftcounter = 0
			end
			
			if player.mo.state == S_BAIG_DFTR
			or player.mo.state == S_BAIG_DFTL then
				player.pflags = $|PF_STASIS //While she's drifting, other directional controls are disabled to prevent jank
				player.mo.friction = 1*FRACUNIT //Removes her friction to keep her from just stopping immediately - cool bonus is that you get momentum on slopes while drifting
				P_SpawnSkidDust(player, 20, 534) //spawns dust behind her (also plays a sound, which is really neat!)
				if player.driftghost and player.driftghost.valid then // Prevents the first ghost from showing, preventing weird visuals. Thanks to L_CloneFighter-v2.pk3 on Discord for helping with this.
					player.driftghost.flags2 = $ & ~MF2_DONTDRAW
				end
				player.driftghost = P_SpawnGhostMobj(player.mo)
				player.driftghost.fuse = 3
				player.driftghost.color = SKINCOLOR_YELLOW
				player.driftghost.colorized = true
				player.driftghost.flags2 = $|MF2_DONTDRAW
			else
				player.mo.friction = (29*FRACUNIT/32) //returns her friction back to normal once the drift is finished
			end
		end
	end
end

addHook("ThinkFrame", driftdash)
			

//Lets states deal damage
addHook("PlayerCanDamage", function(player, mohit)
	if player.mo.skin == "backwards_aigis" then
		if player.mo.state == S_BAIG_STOMP //if stomping
		or player.mo.state == S_BAIG_SKICK //spinkicking
		or player.mo.state == S_BAIG_SPED  //charging a boost
		or player.mo.state == S_BAIG_DFTR  //drifting right...
		or player.mo.state == S_BAIG_DFTL  //...or left
		or player.speedboosting then	   //or while boosting
			if mohit.flags & MF_ENEMY	   //if in contact with a badnik
			or mohit.flags & MF_MONITOR	   //a monitor
			or mohit.flags & MF_SHOOTABLE  //anything shootable
			or mohit.flags & MF_BOSS then  //or a boss
				return true				   //damage it
			end
		end
	end
end)


//Other misc. code, such as HUD, super, and addon support





//Code for superabilities - superfly (rip infinite jump - you will be missed)
local function superabilities()
    for player in players.iterate
        if player.mo.skin == "backwards_aigis" then
            if player.powers[pw_super] ~= 0 then
				if (player.cmd.buttons & BT_JUMP) then //If jump is held, she'll use the jetpack on her back to fly!
					if player.mo.state ~= S_BAIG_JPKU then
						player.mo.state = S_BAIG_JPKU
					end
					P_SpawnSkidDust(player, 20*FRACUNIT)
					if not S_SoundPlaying(player.mo, 549) then
						S_StartSound(player.mo, 549)
					end
					if (player.mo.eflags & MFE_VERTICALFLIP) then //checks if she's upside down, and pushes her up or down
						if P_GetMobjGravity(player.mo) >= 2 then //Checks if she's moved down, since acceleration towards gravity doubles if you do so. Again, thank you Clone Fighter
							player.mo.momz = $ - 2*player.mo.scale
						else
							player.mo.momz = $ - 1*player.mo.scale
						end
					else
						if P_GetMobjGravity(player.mo) <= 2 then //I'm not using P_MobjFlip here so she can have normal gravity instead of double
							player.mo.momz = $ + 2*player.mo.scale
						else
							player.mo.momz = $ + 1*player.mo.scale
						end
					end
				end
				
				if not (player.cmd.buttons & BT_JUMP) then
					if player.mo.state == S_BAIG_JPKU then
						player.mo.state = S_PLAY_WALK
					end
					S_StopSoundByID(player.mo, 549)
				end
			else
				S_StopSoundByID(player.mo, 549)
				player.charability = CA_DOUBLEJUMP //makes sure her double jump is restored, even if spin was held while detransforming. Playing as her with a thok was interesting, though.
				//This was used back when she had Super Sonic's float. Keeping it here for memories.
			end
		end
	end
end

addHook("ThinkFrame", superabilities)

addHook("JumpSpecial", function(player) //Prevents regular jumps if you're super. Might change this behaviour later.
	if player.mo.skin == "backwards_aigis" then
		if (not player.powers[pw_super])
		or player.mo.state == S_PLAY_ROLL 
		or player.mo.state == S_PLAY_RIDE then
			return false
		else
			return true
		end
	end
end)


//Taunts, hahaha
local function chrispysearch(mo, otherplayer) //function for searchBlockmap that looks for the ChrispyCharacters
	if otherplayer and otherplayer.valid then //Go play Pointy Sonic and Fluffy Tails
		if otherplayer.skin == "pointy"
		or otherplayer.skin == "fluffy" then
			return true
		else
			return nil
		end
	end
end

local function taunts()
	for player in players.iterate
		if player.mo.skin == "backwards_aigis" then
			//P_LookForPlayers(player.mo, 50*FRACUNIT, true) //was going to use this, but it just returns the player searching
			//Quick funny note here - don't use P_LookForPlayers while in a special stage! Your character will detach from the path and fly into the background!
			player.tauntroll = P_RandomRange(1, 3)
			
			if not (player.cmd.buttons & BT_TOSSFLAG) then //spintapping check from earlier, but for tossflag
				player.tossflagtapready = true
				player.tossflagtapping = false
			elseif player.tossflagtapready then
				player.tossflagtapping = true
				player.tossflagtapready = false
			else
				player.tossflagtapping = false
			end
			
			if player.tossflagtapping
			and P_IsObjectOnGround(player.mo) then
				player.playersearch = searchBlockmap("objects", chrispysearch, player.mo, player.mo.x - 20, player.mo.x + 20, player.mo.y - 20, player.mo.y + 20) //Searches around Baigis for Pointy and Fluffy
				if player.playersearch == false then //If it finds them...
					if player.mo.state ~= S_BAIG_DAB then //She'll dab!
						player.mo.state = S_BAIG_DAB	  //You can blame Mylo for this if you hate it lololololol
					end
				else	//If it doesn't find them, she'll pick from this list of taunts that may or may not get bigger as time passes
					if player.tauntroll == 1 then
						if player.mo.state ~= S_BAIG_TAUNT1 then
							player.mo.state = S_BAIG_TAUNT1
						end
					elseif player.tauntroll == 2
						if player.mo.state ~= S_BAIG_TAUNT2 then
							player.mo.state = S_BAIG_TAUNT2
						end
					elseif player.tauntroll == 3
						if player.mo.state ~= S_BAIG_SHIT then
							player.mo.state = S_BAIG_SHIT
						end
					end
				end
			end
		end
	end
end

addHook("ThinkFrame", taunts)
			


//Code for her HUD
hud.add(function(v, player)
	if srb2p then //Checking if SRB2Persona is loaded, then disabling the HUD if true.
		return 
	end
	
	if G_IsSpecialStage(gamemap) then //Checking if she's in a special stage, then disabling the HUD if true.
		return
	end
	
	if player.mo == nil or player.mo.skin ~= "backwards_aigis" then //prevents her hud from showing up on everyone's screen if even one person is playing as her
		return
	end
	
	local cmap = v.getColormap(player.mo.skin, player.mo.color) //Copy this too if your boost mode bar has parts that change with skincolor
		
		
	local hudempty = v.cachePatch('HUDEA0')			//caching the graphics made for her charge hud
	local hudchargeone = v.cachePatch('HUDCA0')		//Thank you so much Pizza ^-^
	local hudchargetwo = v.cachePatch('HUDCB0')
	local hudready = v.cachePatch('HUDRA0')
	local hudsupercharge = v.cachePatch('HUDSA0')
		
	//v.drawString(210, 5, "CHARGE:")
	//I used to have the word "charge" next to the bar, but it ain't necessary anymore
			
	if player.powers[pw_super] then
		v.draw(240, 10, hudsupercharge, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT, cmap)
	else
		if player.baigischargeshotcounter > 0
		and player.baigischargeshotcounter < 16 then
			v.draw(240, 10, hudchargeone, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT, cmap)
		elseif player.baigischargeshotcounter > 15
		and player.baigischargeshotcounter < 31 then
			v.draw(240, 10, hudchargetwo, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT, cmap)
		elseif player.baigischargeshotcounter > 30 then
			v.draw(240, 10, hudready, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT, cmap)
		else
			v.draw(240, 10, hudempty, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT, cmap)
		end
	end
		
			
	//116Chars Boost Mode hud stuff - don't forget the cmap
	local dashzero = v.cachePatch('DASHA0')
	local dashone = v.cachePatch('DASHB0')
	local dashtwo = v.cachePatch('DASHC0')
	local dashthree = v.cachePatch('DASHD0')
	local dashfour = v.cachePatch('DASHE0')
	local dashfive = v.cachePatch('DASHF0')
	local dashfull = v.cachePatch('DASHG0')
	
	if player.boostmode >= 0
	and player.boostmode < (18 + (1/2)) then
		v.draw(170, 145, dashzero, V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, cmap)
	elseif player.boostmode > (17 + (1/2))
	and player.boostmode < 36 then
		v.draw(170, 145, dashone, V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, cmap)
	elseif player.boostmode > 35
	and player.boostmode < (53 + (1/2)) then
		v.draw(170, 145, dashtwo, V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, cmap)
	elseif player.boostmode > (52 + (1/2))
	and player.boostmode < 71 then
		v.draw(170, 145, dashthree, V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, cmap)
	elseif player.boostmode > 70
	and player.boostmode < (88 + (1/2)) then
		v.draw(170, 145, dashfour, V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, cmap)
	elseif player.boostmode > (87 + (1/2))
	and player.boostmode < 101 then
		v.draw(170, 145, dashfive, V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, cmap)
	elseif player.boostmode > 100 then
		v.draw(170, 145, dashfull, V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, cmap)
	end
	
	//v.drawPaddedNum(304, 168, player.boostmode, 3, V_YELLOWMAP)
	//Might eventually do this with the numbers accurately lining up with player.boostmode, but I need to learn how to make a "font drawer"
	
end)


//shh, secrets!

states[S_BAIG_MAZINTRANSFORM] = {
	sprite = SPR_PLAY,
	tics = 36,
	nextstate = S_PLAY_FALL,
	frame = FF_ANIMATE|SPR2_MAZN,
	var1 = 3,
	var2 = 3
}

local function rarities()
	for player in players.iterate
		if player.mo.skin == "backwards_aigis" then
			
			if G_IsSpecialStage(gamemap) then
				return
			end
//			
//			if not player.beegroll then
//				player.beegroll = 0
//			end
//			
//			if not player.powers[pw_invulnerability] then
//				player.beegroll = P_RandomRange(1, 100)
//				player.mo.destscale = FRACUNIT
//			elseif player.powers[pw_invulnerability]
//			and not player.powers[pw_super] then
//				if player.beegroll >= 10 then
//					player.mo.destscale = 2*FRACUNIT
//				end
//			end
//			--Had an idea where she had a 1 in 10 chance of gaining Kart's grow powerup when grabbing an invincibility box
//			--Maybe later

//Mazin Backwards Aigis Form
//Fun is Infinite

			if player.mo.state == S_PLAY_DEAD //unfortunately, there's no such thing as an infinite battery
			or G_EnoughPlayersFinished() then //I probably should still give you the option to turn the form off once a level has passed
				player.canmazin = false
			end

			if not player.mazin then
				player.mazin = false
			end
			
			if not player.mazincolorcounter then
				player.mazincolorcounter = 1
			end
			
			if player.mazincolorcounter > 20 then
				player.mazincolorcounter = 1
			end
			
			if player.canmazin == false then
				player.mazin = false
			end
			
			if All7Emeralds(emeralds) then
				player.canmazin = true
			else
				player.canmazin = false
			end
			
			if player.mazin == false then
				player.mazintransformcounter = 0
			end
			
			if player.mazintransformcounter < 36 then
				player.mazintransforming = true
			else
				player.mazintransforming = false
			end
			
			if player.mazintransformcounter > 36 then
				player.mazintransformcounter = 36
				S_StopSoundByID(player.mo, 550)
			end
			
			if player.mazintransformcounter == 34 then
				player.mazintransformsoundcheck = true
			end
				
			if player.mazintransformcounter == 35 
			and player.mazintransformsoundcheck == true then
				S_StartSound(player.mo, 466)
				local transformhoop = P_SpawnMobjFromMobj(player.mo, 0, 0, 0, MT_STHP)
				transformhoop.color = player.mo.color
			end
			if player.mazintransformcounter == 36 then
				player.mazintransformsoundcheck = false
			end
			
			if player.mazin then
				player.mazintransformcounter = $ + 1
				if player.mazintransforming then
					if not S_SoundPlaying(player.mo, 550) then
						S_StartSound(player.mo, 550)
					end
					P_InstaThrust(player.mo, player.mo.angle, 0*FRACUNIT)
					P_SetObjectMomZ(player.mo, 1*FRACUNIT)
					if player.mo.state ~= S_BAIG_MAZINTRANSFORM then
						player.mo.state = S_BAIG_MAZINTRANSFORM
					end
				end
				player.charflags = $ & ~SF_SUPER
				if player.mo.state == S_PLAY_FALL then
					player.mo.state = S_PLAY_ROLL
				end
				local orblocal = P_SpawnMobjFromMobj(player.mo, P_RandomRange(-64, 64)*FRACUNIT, P_RandomRange(-64, 64)*FRACUNIT, P_RandomRange(5, 56)*FRACUNIT, MT_OORB)
				orblocal.color = player.mo.color
				orblocal.scale = player.mo.scale
				player.mazincolorcounter = $ + 1
				if player.mazincolorcounter == 2 then
					player.mo.color = SKINCOLOR_SUPERPURPLE1
				elseif player.mazincolorcounter == 4 then
					player.mo.color = SKINCOLOR_SUPERPURPLE2
				elseif player.mazincolorcounter == 6 then
					player.mo.color = SKINCOLOR_SUPERPURPLE3
				elseif player.mazincolorcounter == 8 then
					player.mo.color = SKINCOLOR_SUPERPURPLE4
				elseif player.mazincolorcounter == 10 then
					player.mo.color = SKINCOLOR_SUPERPURPLE5
				elseif player.mazincolorcounter == 12 then
					player.mo.color = SKINCOLOR_SUPERPURPLE4
				elseif player.mazincolorcounter == 16 then
					player.mo.color = SKINCOLOR_SUPERPURPLE3
				elseif player.mazincolorcounter == 18 then
					player.mo.color = SKINCOLOR_SUPERPURPLE2
				elseif player.mazincolorcounter == 20 then
					player.mo.color = SKINCOLOR_SUPERPURPLE1
				end
				if (player.pflags & PF_JUMPED)
					player.pflags = $ & ~PF_THOKKED
				end
				
				if player.dashmode >= 3*TICRATE then //thanks to Frostiikin and SMS Alfredo - this stops the orange flash during boostmode
					if (((leveltime-3)/2) & 1) then
						player.mo.colorized = true
					else
						player.mo.colorized = false
					end
				else
					if player.mo.colorized == true
						player.mo.colorized = false
					end
				end
			else
				if player.mo.color == SKINCOLOR_SUPERPURPLE1
				or player.mo.color == SKINCOLOR_SUPERPURPLE2
				or player.mo.color == SKINCOLOR_SUPERPURPLE3
				or player.mo.color == SKINCOLOR_SUPERPURPLE4
				or player.mo.color == SKINCOLOR_SUPERPURPLE5 then
					player.mo.color = player.skincolor
				end
				player.charflags = $|SF_SUPER
			end
			
			
		else
			player.canmazin = false
		end
	end
end
addHook("ThinkFrame", rarities)

addHook("PlayerSpawn", function(player)
	if player.mo.skin == "backwards_aigis" then
		player.canmazin = false
	end
end)

local function MazinSwitch(player, arg)
	if player.mo and player.mo.valid then
		if player.mo.skin == "backwards_aigis" then
			if player.canmazin then
				CONS_Printf(player, "Fun is Infinite!")
				player.mazin = true
			else
				CONS_Printf(player, "Try again with all the emeralds, then the fun can truly begin!")
			end
		else
			CONS_Printf(player, "You're not playing as Backwards Aigis. Swap skins first!")
		end
	else
		CONS_Printf(player, "This can only be done in a level.")
	end
end

COM_AddCommand("mazin", function(player, arg)
	MazinSwitch(player, arg)
end)

addHook("PlayerCanDamage", function(player, mohit)
	if player.mo.skin == "backwards_aigis" then
		if player.mazin then
			return true
		end
	end
end)

//custom tunes and such

local function customtunes()
	for player in players.iterate
		if player.mo.skin == "backwards_aigis" then
			if player.isxmomentum then //prevents these during xmomentum since it has its own supermusic that would cause lag if this tried to run too
				return
			end
			
			if player.powers[pw_invulnerability]
			and not player.powers[pw_super]
			and not player.mazin then
				COM_BufInsertText(player, "tunes _minv") //this inserts a tunes command into the console to change music - done to assist the TPS server in managing crashes
			elseif player.powers[pw_super] then
				COM_BufInsertText(player, "tunes redial")
			elseif player.mazin then
				COM_BufInsertText(player, "tunes mazin")
			else
				if S_MusicName() == "redial" //Checks the current track's name, then sets it to whatever the default music is
				or S_MusicName() == "_minv" //Prevents "tunes -default" being entered every frame, which caused things like the CEZ bridge music to not play
				or S_MusicName() == "mazin" then
					COM_BufInsertText(player, "tunes -default")
				end
			end
		end
	end
end

addHook("ThinkFrame", customtunes)

//ChrispyChars Tricks - refer to its .pk3 for easy instructions to make these yourself, but feel free to use these as an example too.
if not CC_TrickSkins
	rawset(_G, "CC_TrickSkins", {})
end

CC_TrickSkins["backwards_aigis"] = {
	{
		sprite2 = SPR2_SPNG,
		rotation = 1,
		tics = 0
	},
	{
		sprite2 = SPR2_FIRE,
		rotation = -1,
		tics = 0
	},
	{
		sprite2 = SPR2_ATRK,
		rotation = 0,
		tics = 0,
		frame = A
	},
	{
		sprite2 = SPR2_BTRK,
		rotation = -1,
		tics = 0,
		frame = A
	},
	{
		sprite2 = SPR2_CTRK,
		rotation = 0,
		tics = 0,
		frame = A
	}
}

//Kirby ability
if not(kirbyabilitytable)
    rawset(_G, "kirbyabilitytable", {})
end

kirbyabilitytable["backwards_aigis"] = 16
kirbyabilitytable[MT_BAIGLAZER] = 16
kirbyabilitytable[MT_BAIGCHARGELAZER] = 16
kirbyabilitytable[MT_BAIGJUMPLAZER] = 16



//SRB2Persona support - again, I took way too long to do this. Thanks to SnakeErik for helping with it.
if not srb2p then return end //Makes sure none of this activates when not in SRB2Persona

charStats["backwards_aigis"] = {

	name = "Backwards Aigis",
	basehp = 40,
	basesp = 50,
	persona = "toaster",
	melee_natk = "spinkick",
	atk = 20,
	acc = 97,
	crit = 5,
	anim_stand =       {SPR_PLAY, A, 8, "SPR2_IDLE"},
	anim_stand_hurt =  {SPR_PLAY, A, 1, "SPR2_OUCH"},
	anim_stand_bored = {SPR_PLAY, A, 8, "SPR2_IDLE"},
	anim_guard =       {SPR_PLAY, A, 1, "SPR2_GARD"},
	anim_move =        {SPR_PLAY, A, B, 2, "SPR2_WALK"},
	anim_run =         {SPR_PLAY, A, B, 2, "SPR2_RUN_"},   
    anim_atk =         {SPR_PLAY, A, B, C, D, E, F, G, H, 1, "SPR2_KICK"},         
    anim_aoa_end =     {SPR_PLAY, H, G, F, E, D, C, B, A, 2, "SPR2_ROLL"},        
    anim_hurt =        {SPR_PLAY, A, 35, "SPR2_PAIN"},                
    anim_getdown =     {SPR_PLAY, A, 1, "SPR2_CNT1"},                  
    anim_downloop =    {SPR_PLAY, A, 1, "SPR2_CNT1"},                  
    anim_getup =       {SPR_PLAY, A, B, C, D, E, F, G, H, 1, "SPR2_ROLL"},         
    anim_death =       {SPR_PLAY, A, 30, "SPR2_DEAD"},                 
    anim_revive =      {SPR_PLAY, A, 1, "SPR2_FALL"},
	anim_special1 =    {SPR_PLAY, A, B, C, D, E, F, 2, "SPR2_FIRE"},
	vfx_summon = {},
	
	icon = "ICO_BAIG",
	hudbust = "H_BAIGBAR",
	hudaoa = "H_BAIGAOA",
	aoa_quote = "You won't escape!",
	hudcutin = "BAIGA_A",
	tip = "True to her Karting roots, she's quick, but light on the attacks. She's more accurate than others though, and can shoot enemies down with her electric lazer shots.",
	}

attackDefs["spinkick"] = {
	name = "Spin Kick",
	type = ATK_STRIKE,
	power = 80,
	accuracy = 95,
	costtype = CST_HP,
	cost = 5,
	critical = 10,
	physical = true,
	desc = "Spinning kick that damages \none enemy.",
	target = TGT_ENEMY,
	anim = function(mo, targets, hittargets, timer)
		
		local target = hittargets[1]
		
		if timer == 1 then
			local ang = R_PointToAngle2(mo.x, mo.y, target.x, target.y)
			mo.angle = ang
			S_StartSound(mo, 469)
			ANIM_set(mo, mo.anim_atk, true)
			local g = P_SpawnGhostMobj(mo)
			P_InstaThrust(mo, mo.angle, FRACUNIT*75)
		elseif timer == 12 then
			createSplat(mo)
			createSplat(mo)
			localquake(mo.battlen, FRACUNIT*10, 10)
			S_StartSound(mo, 98)
			damageObject(target)
			P_InstaThrust(mo, mo.angle, -45*FRACUNIT)
		elseif timer == 35 then
			return true
		end
		
		if timer >= 2
		and 11 >= timer then
			local bostlocal = P_SpawnMobjFromMobj(mo, P_RandomRange(-64, 64)*FRACUNIT, P_RandomRange(-64, 64)*FRACUNIT, P_RandomRange(5, 56)*FRACUNIT, MT_BOST) //spawns blue dash particles randomly around the player
			if bostlocal and bostlocal.valid then
				bostlocal.angle = player.mo.angle
			end
		end
		
	end,
}
	
personaList["toaster"] = {
	
	name = "Toaster Aigis",
	anim_idle = {TOST, A},
	anim_atk =  {TSTY, A},
	strength = 9,
	magic = 7,
	endurance = 5,
	luck = 5,
	agility = 9,
	weak = ATK_ICE,
	resist = ATK_CURSE,
	block = ATK_PSY,
	skills = {
		{"lazer", 1}, {"chargeshot", 1},
	},
}

attackDefs["lazer"] = {
	name = "Lazer",
	type = ATK_ELEC,
	power = 80,
	accuracy = 95,
	costtype = CST_SP,
	cost = 5,
	critical = 10,
	desc = "Single shot that damages \none enemy.",
	target = TGT_ENEMY,
	anim = function(mo, targets, hittargets, timer)
		local target = hittargets[1]
		if timer == 10 then
			local ang = R_PointToAngle2(mo.x, mo.y, target.x, target.y)
			mo.angle = ang
			ANIM_set(mo, anim_special1)
			S_StartSoundAtVolume(mo, 141, 100)
			local shot = P_SpawnMobj(mo.x, mo.y, mo.z, MT_BAIGLAZER)
			if shot and shot.valid then
				shot.angle = mo.angle
			end
			P_InstaThrust(shot, shot.angle, 75*FRACUNIT)
		elseif timer == 18 then
			S_StartSound(shot, 143)
			createSplat(mo)
			createSplat(mo)
			localquake(mo.battlen, FRACUNIT*10, 10)
			damageObject(target)
		elseif timer == 40 then
			return true
		end
	end,
}

attackDefs["chargeshot"] = {
	name = "Charge Shot",
	type = ATK_ELEC,
	power = 100,
	accuracy = 95,
	costtype = CST_SP,
	cost = 10,
	critical = 10,
	desc = "Charged shot that damages \none enemy.",
	target = TGT_ENEMY,
	anim = function(mo, targets, hittargets, timer)
		local target = hittargets[1]
		if timer == 10 then
			local ang = R_PointToAngle2(mo.x, mo.y, target.x, target.y)
			mo.angle = ang
			ANIM_set(mo, anim_special1)
			S_StartSoundAtVolume(mo, 93, 150)
			local shot = P_SpawnMobj(mo.x, mo.y, mo.z, MT_BAIGCHARGELAZER)
			if shot and shot.valid then
				shot.angle = mo.angle
			end
			P_InstaThrust(shot, shot.angle, 75*FRACUNIT)
		elseif timer == 18 then
			S_StartSound(shot, 143)
			createSplat(mo)
			createSplat(mo)
			localquake(mo.battlen, FRACUNIT*10, 10)
			damageObject(target)
		elseif timer == 40 then
			return true
		end
	end,
}

	
	

//If you see this, I hope you're having a nice day! :D