// content by Luigifan

//----------- ability definition -----------

--actions
freeslot(
"S_PLAY_CASSANDRA_COPYBOLT",
"S_PLAY_CASSANDRA_MIMICRY"
)

--objects
freeslot("MT_CASSANDRA_COPYBOLT")

freeslot("SPR_CBLT")

freeslot(
"S_CASSANDRA_COPYBOLT_SPAWNSTATE",
"S_CASSANDRA_COPYBOLT_MISSILESTATE",
"S_CASSANDRA_COPYBOLT_DEATHSTATE"
)

--sound effects

freeslot("sfx_cblt")

//Cassandra's passive, Quick Recovery, doesn't need special code of its own. It's already accounted for in the code of her energy meter.

// main thinker
addHook("ThinkFrame", function()
	for player in players.iterate do
		if player.mo.skin ~= "cassandra_b" then
			continue
		end
	end
end)

//Copy Bolt (Code to copy the abilities of nearby characters and enemies and gain their abilities until the power is discarded)
mobjinfo[MT_CASSANDRA_COPYBOLT] = {
	spawnstate = S_CASSANDRA_COPYBOLT_SPAWNSTATE,
	missilestate = S_CASSANDRA_COPYBOLT_MISSILESTATE,
	deathstate = S_CASSANDRA_COPYBOLT_DEATHSTATE,
	damage = 0, //1*FRACUNIT/2
	height = 10*FRACUNIT,
	radius = 40*FRACUNIT, //It really should be 40 fracunits long and 10 fracunits wide, but there are no separate "length" and "width" parameters...
	speed = 75*FRACUNIT,
	spawnhealth = 1,
	fuse = 8*TICRATE,
	flags = MF_NOGRAVITY|MF_MISSILE
}
states[S_CASSANDRA_COPYBOLT_SPAWNSTATE] = {
	sprite = SPR_CBLTA,
	frame = FF_FULLBRIGHT|FF_TRANS60|FF_PAPERSPRITE|A,
	tics = 2,
	nextstate = S_CASSANDRA_COPYBOLT_MISSILESTATE
}
states[S_CASSANDRA_COPYBOLT_MISSILESTATE] = {
	sprite = SPR_CBLTA,
	frame = FF_FULLBRIGHT|FF_TRANS30|FF_PAPERSPRITE|A,
	tics = -1,
	nextstate = S_CASSANDRA_COPYBOLT_DEATHSTATE
}
states[S_CASSANDRA_COPYBOLT_DEATHSTATE] = {
	sprite = SPR_CBLTA,
	frame = FF_FULLBRIGHT|FF_TRANS80|FF_PAPERSPRITE|A,
	tics = 1,
	nextstate = S_NULL
}
sfxinfo[sfx_cblt] = {
	singular = true,
	caption = "Copy bolt",
	priority = 8,
	flags = SF_X2AWAYSOUND
}

addHook("PlayerThink", function(player)
	if player.mo and player.mo.valid then
	
		if player.mo.skin ~= "cassandra_b" then
			return
		end
		
/*		if player.custom1down == nil then
			player.custom1down = 0
		end
		
		if player.cmd.buttons & BT_CUSTOM1 > 0 then
			player.custom1down = $1 + 1
		else
			player.custom1down = 0
		end*/
		
		if player.mo.copyboltcooldown == nil then
			player.mo.copyboltcooldown = 0
		end
		
		if player.mo.copyboltcooldown > 0 then
			if (leveltime%TICRATE) then
				player.mo.copyboltcooldown = $ - 1
			end
		end
		
		if player.mo.copy == nil then
			player.mo.copy = 0
		end
		
		if player.custom1down == 1
		and player.mo.copy == 0 //Can't use Copy Bolt if Cassandra already has a copied power
		and player.mo.mimicry == 0 //Can't use Copy Bolt if Cassandra is mimicking someone
		and player.mo.copyboltcooldown == 0 --Copy Bolt is NOT a machine gun
		and player.mo.energy >= 2*FRACUNIT then
			player.mo.energy = $ - 2*FRACUNIT
			local cbolt = P_SpawnPlayerMissile(player.mo, MT_CASSANDRA_COPYBOLT, 0)
			S_StartSoundAtVolume(player.mo, sfx_cblt, 60, nil)
			player.mo.copyboltcooldown = 1*TICRATE
		end
		
		if player.mo.copy ~= 0
		and player.tossflagdown == 1 then
			player.mo.copy = 0 --Discard copied power
		end
	end
end)

addHook("MobjMoveCollide", function(cbolt, thing) --tmthing == cbolt
	if not (cbolt.z >= (thing.z - cbolt.height) and cbolt.z <= (thing.z + thing.height)) then --height check
		return false
	end
	
	if (thing.flags & MF_SHOOTABLE)
	and not ((thing.flags & MF_MONITOR) or thing.type == MT_PLAYER or (thing.flags & MF_ENEMY) or (thing.flags & MF_BOSS)) then --if the shot object can be interacted with by projectiles, but is not a monitor, player, enemy, or boss
		P_DamageMobj(thing, cbolt, cbolt.target, 1) --Copy Bolt damages/triggers the object --cbolt.target == player according to P_SpawnPlayerMissile
		P_KillMobj(cbolt, nil, nil) --Copy Bolt stops moving
	end
	
	if (thing.flags & MF_MONITOR) then
		P_DamageMobj(thing, cbolt, cbolt.target, 1) --Copy Bolt breaks the monitor and grants its effects to the player
		P_KillMobj(cbolt, nil, nil) --Copy Bolt stops moving
	end
	
	if thing.type == MT_PLAYER
	and thing ~= cbolt.target then --don't copy Cassandra herself!
		if (G_CoopGametype() == true
		or (G_GametypeHasTeams == true and thing.player.ctfteam == cbolt.target.ctfteam)) then
			cbolt.target.copy = thing.player.mo.skin --copy the hit player's skin to use their abilities
			print("You copied "..cbolt.target.copy.."!") --Let's make sure Cassandra actually copied something
			cbolt.target.pflags = $&~PF_THOKKED --Cassandra can chain multiple characters' air actions
			cbolt.target.vixenvortexed = 0
			P_KillMobj(cbolt, nil, nil) --stop Copy Bolt to avoid copying multiple skins in succession
			return --don't harm friendly players
		else
			cbolt.target.copy = thing.player.mo.skin --copy the hit player's skin to use their abilities (BEFORE doing damage and potentially killing them, which would make them null)
			print("You copied "..cbolt.target.copy.."!") --Let's make sure Cassandra actually copied something
			cbolt.target.pflags = $&~PF_THOKKED --Cassandra can chain multiple characters' air actions
			cbolt.target.vixenvortexed = 0
			P_DamageMobj(thing, cbolt, cbolt.target, 1) --damage opposing players in competitive modes
			P_KillMobj(cbolt, nil, nil)
		end
	end
	
	if (thing.flags & MF_ENEMY) or (thing.flags & MF_BOSS) then
		//local healthonhit = thing.health --record how much HP the target had when it was hit before doing any damage
		cbolt.target.copy = thing.type --copy the ID of the hit enemy to obtain their ability (BEFORE doing damage and potentially killing them, which would make them null)
		print("You copied "..cbolt.target.copy.."!") --Let's make sure Cassandra actually copied something
//		cbolt.target.pflags = $&~PF_THOKKED --Cassandra can chain multiple characters' air actions
		if thing.holyboltblock == nil then
			thing.holyboltblock = 3 --establish the sub-health meter used to govern Holy Bolt & Copy Bolt damage
			print("Target hit! "..thing.type.."'s current health: "..thing.health.." full HP, "..thing.holyboltblock.." sub-HP.") --check to make sure that Copy Bolt actually connected, particularly in the absence of pain state
			if thing.healthonhit == thing.health then --double-checking that initial Copy Bolt didn't somehow induce a pain state or kill the target (despite it not being chargeable like Holy Bolt and thus never having a damage value of 1 or higher)
				thing.flags = $&~MF_SHOOTABLE --temporarily remove MF_SHOOTABLE to prevent consecutive hits
				thing.holyboltrecovery = 1*TICRATE --set timer before returning MF_SHOOTABLE
			end
		else
			thing.holyboltblock = $ - 3 --Copy Bolt always deals 1/2 damage
			print("Target hit! "..thing.type.."'s current health: "..thing.health.." full HP, "..thing.holyboltblock.." sub-HP.") --check to make sure that Copy Bolt actually connected, particularly in the absence of pain state
			if thing.healthonhit == thing.health and thing.holyboltblock > 0 then --if Copy Bolt removed no "real" HP and thus didn't induce a pain state or kill the target
				thing.flags = $&~MF_SHOOTABLE --temporarily remove MF_SHOOTABLE to prevent consecutive hits
				thing.holyboltrecovery = 1*TICRATE --set timer before returning MF_SHOOTABLE
			end
		end
		if thing.holyboltblock <= 0 then
			P_DamageMobj(thing, cbolt, cbolt.target, 1) --if a total of 6 sub-damage has been dealt, the target takes 1 real damage
			if thing.health >= 1 then
				thing.holyboltblock = $ + 6 --if the target isn't dead, add 6 sub-health (prior sub-damage can carry over)
				print("Target hit! "..thing.type.."'s current health: "..thing.health.." full HP, "..thing.holyboltblock.." sub-HP.") --check to make sure that Copy Bolt actually connected, particularly in the absence of pain state
			end
		end
		P_KillMobj(cbolt, nil, nil)
	end
	
	if thing.type == MT_TURRET then --Copy Bolt can't hurt turrets, but can still copy them
		cbolt.target.copy = MT_TURRET
		print("You copied "..cbolt.target.copy.."!") --Let's make sure Cassandra actually copied something
		P_KillMobj(cbolt, nil, nil)
		return true
	end
	
	if thing.type == MT_METALSONIC_RACE then
		cbolt.target.copy = "metalsonic"
		print("You copied "..cbolt.target.copy.."!") --Let's make sure Cassandra actually copied something
		cbolt.target.pflags = $&~PF_THOKKED --Cassandra can chain multiple characters' air actions
		cbolt.target.vixenvortexed = 0
		P_KillMobj(cbolt, nil, nil)
	end
	
	if thing.type == MT_BOMBSPHERE then
		P_KillMobj(thing, cbolt, cbolt.tracer) --Allow Copy Bolt to disarm Bomb Spheres
		if P_RandomChance(5*FRACUNIT/100) == true then
			cbolt.target.copy = MT_DETON --Have Copy Bolt grant Cassandra the Deton power (self-destruction) on roughly 1 out of 20 Bomb Sphere eliminations
			print("You copied "..cbolt.target.copy.."!") --Let's make sure Cassandra actually copied something
		end
		P_KillMobj(cbolt, nil, nil)
	end
end, MT_CASSANDRA_COPYBOLT)

//Mimicry (Code to replace Cassandra's abilities with another skin until the mimicry is discarded or her energy runs out)
addHook("PlayerThink", function(player)
	if player.mo and player.mo.valid then
	
		if player.mo.skin ~= "cassandra_b" then
			return
		end
		
/*		if player.custom2down == nil then
			player.custom2down = 0
		end
		
		if player.cmd.buttons & BT_CUSTOM2 > 0 then
			player.custom2down = $1 + 1
		else
			player.custom2down = 0
		end*/
		
		if player.mo.mimicry == nil then
			player.mo.mimicry = 0
		end
		
		if player.custom2down == 1
		and player.mo.copy == 0 //Can't use mimicry with a copied power
		and player.mo.mimicry == 0 //Cassandra can't mimic two or more people at once
		and player.mo.energy >= 4*FRACUNIT then
			//open mimicry menu
			player.mo.energy = $ - 4*FRACUNIT
			player.pflags = $&~PF_THOKKED //Cassandra is allowed to chain multiple characters' air actions together
			player.mo.vixenvortexed = 0
		end
	end
end)

--Mimicry menu