// content by Luigifan

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

--actions
freeslot(
"S_PLAY_VIXENVORTEX",
"S_PLAY_ENERGY",
"S_PLAY_HOLYBOLT",
"S_PLAY_HOLYBOLTCHARGING"
)

--objects
freeslot("MT_HOLYBOLT")

freeslot("SPR_HBLT")

freeslot(
"S_HOLYBOLT_SPAWNSTATE",
"S_HOLYBOLT_MISSILESTATE",
"S_HOLYBOLT_DEATHSTATE"
)

--sound effects
freeslot(
"sfx_hblt",
"sfx_hchrg",
"sfx_bhblt",
"sfx_vbhblt",
"sfx_ebhblt"
)

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

//Vixen Vortex (double jump)
addHook("AbilitySpecial", function(player)
	for player in players.iterate do
		if player.mo.skin ~= "annie_belnades" then
			continue
		end
		
		if not (player.pflags & PF_THOKKED) --if Vixen Vortex hasn't been used in the current jump
		and (player.pflags & PF_JUMPED) then --if the player is jumping
			//if --set baseline and weakened jump heights based on whether or not Annie is carrying a heavy character
				P_SetObjectMomZ(player.mo, 20*FRACUNIT, false) --high double jump
/*					mobj = player.mo
					momz = 40*FRACUNIT --The planned height is 130 fracunits. Setting momz to 130*FRACUNIT took the Belnades to the ceiling of GFZ1.
					relative? = false*/
//			else --weakened jump height
//				P_SetObjectMomZ(player.mo, 16*FRACUNIT, false)
//			end
			player.pflags = $1|PF_THOKKED
			player.mo.vixenvortexed = 1
		end
	end
end)

addHook("PlayerThink", function(player)
	if player.mo and player.mo.valid then
	
		if player.mo.skin ~= "annie_belnades" then
			return
		end
		
		if player.mo.vixenvortexed == nil then
			player.mo.vixenvortexed = 0
		end
		
		if player.mo.momz <= 0 --This should be "when player.momz <= 0", but Lua doesn't allow that...
		and (player.pflags & PF_THOKKED)
		and player.mo.vixenvortexed == 1 then --if PF_THOKKED was specifically turned on by Vixen Vortex
			player.pflags = $1|PF_NOJUMPDAMAGE
			player.pflags = $&~PF_SPINNING --Player can't damage enemies by colliding with them after Vixen Vortex until they touch the ground or otherwise stop descending.
			player.panim = PA_FALL
		end
	
		if not (player.pflags & PF_JUMPED) then --if the player is on the ground
			player.mo.vixenvortexed = 0
			player.pflags = $&~PF_NOJUMPDAMAGE
		end
	end
end)

--code ripped from Hinote that I don't think is working as intended
/*function A_ResetJumpFlags(actor, var1, var2)
	if actor.player and not P_IsObjectOnGround(actor)
		actor.player.pflags = $1|PF_JUMPED|PF_THOKKED
	end
end*/

//Energy meter (limitation on Holy Bolt and unique abilities)
addHook("PlayerThink", function(player)
	if player.mo and player.mo.valid then
	
		if player.mo.skin ~= "annie_belnades" then
			return --only the Belnades Sisters get this energy meter mechanic
		end
	
		player.mo.energy = max(min($,100*FRACUNIT),0) --defines player.mo.energy as a value that has a lower limit of 0 and an upper limit of 100
/*			if not (leveltime%(TICRATE*5)) then
				print("current energy = ", player.mo.energy>>FRACBITS) --will return a number between 0-100, including 0 and 100
			end*/
		if player.mo.energy == nil then
			player.mo.energy = 100*FRACUNIT --Sets the energy meter to 100 upon player.mo.energy being initially defined at game start
		end
		
		if not (leveltime%TICRATE) then --refill energy over time
			if player.firenormaldown < 2 then --default refill rate when Holy Bolt isn't charging
				if player.custom1down == 0 --energy does not refill while healing
				and player.custom3down == 0 --energy does not refill while reviving
				and player.mo.deathdefiance == 0 then --energy briefly stops refilling after a Hard to Kill passive saves Annie's life
					if player.panim == (PA_IDLE or PA_EDGE or PA_RIDE) then
						player.mo.energy = $ + 2*FRACUNIT --energy refills faster when the player isn't moving
					else
						player.mo.energy = $ + 1*FRACUNIT
					end
				end
			else --slower refill rate when Holy Bolt is charging
				if player.custom1down == 0 --energy does not refill while healing
				and player.custom3down == 0 --energy does not refill while reviving
				and player.mo.deathdefiance == 0 then --energy briefly stops refilling after a Hard to Kill passive saves Annie's life
					if player.panim == (PA_IDLE or PA_EDGE or PA_RIDE) then
						player.mo.energy = $ + 16*FRACUNIT/10 --energy refills faster when the player isn't moving
					else
						player.mo.energy = $ + 8*FRACUNIT/10
					end
				end
			end
		end
	end
end)

addHook("TouchSpecial", function(special, toucher) --code should run when the player collects a Ring
	if special and special.valid then
		if toucher.player and toucher.player.valid then
			if toucher.player.mo.skin ~= "annie_belnades" then
				return
			end
		end
      
		toucher.player.mo.energy = $ + 5*FRACUNIT --energy increases by 5 when a Ring is collected
	end
end, MT_RING)

addHook("MobjDeath", function(target, inflictor, source, damagetype) --code should run when the player breaks a Super Ring Monitor
	if target and target.valid then
		if source.player and source.player.valid then
			if source.player.mo.skin ~= "annie_belnades" then
				return
			end
		end
		
		source.player.mo.energy = $ + 50*FRACUNIT --energy increases by 50 when a Super Ring Monitor is broken
	end
end, MT_RING_BOX)

addHook("PlayerSpawn", function(player) --Fills the energy meter to maximum when the player starts a level or dies and respawns
	if player.mo and player.mo.valid then
	
		if player.mo.skin ~= "annie_belnades" then
			return
		else
			player.mo.energy = 100*FRACUNIT
		end
	end
end)

--Devmode-exclusive console command to set energy to any valid value

//Holy Bolt (chargeable projectile)
mobjinfo[MT_HOLYBOLT] = {
	spawnstate = S_HOLYBOLT_SPAWNSTATE,
	missilestate = S_HOLYBOLT_MISSILESTATE,
	deathstate = S_HOLYBOLT_DEATHSTATE,
	damage = 0, //((1*FRACUNIT/6) * (player.mo.holyboltcharge + 1))
	speed = 75*FRACUNIT,
	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...
	spawnhealth = 1,
	fuse = 8*TICRATE,
	flags = MF_NOGRAVITY|MF_MISSILE
}
states[S_HOLYBOLT_SPAWNSTATE] = {
	sprite = SPR_HBLTA,
	frame = FF_FULLBRIGHT|FF_TRANS60|FF_PAPERSPRITE|A,
	tics = 2,
	nextstate = S_HOLYBOLT_MISSILESTATE
}
states[S_HOLYBOLT_MISSILESTATE] = {
	sprite = SPR_HBLTA,
	frame = FF_FULLBRIGHT|FF_TRANS30|FF_PAPERSPRITE|A,
	tics = -1,
	nextstate = S_HOLYBOLT_DEATHSTATE
}
states[S_HOLYBOLT_DEATHSTATE] = {
	sprite = SPR_HBLTA,
	frame = FF_FULLBRIGHT|FF_TRANS80|FF_PAPERSPRITE|A,
	tics = 1,
	nextstate = S_NULL
}
sfxinfo[sfx_hblt] = {
	singular = true,
	caption = "Holy energy shot",
	priority = 6,
	flags = SF_X2AWAYSOUND
}
sfxinfo[sfx_hchrg] = {
	singular = false,
	caption = "Holy energy accumulation",
	priority = 5,
	flags = SF_NOMULTIPLESOUND
}
sfxinfo[sfx_bhblt] = {
	singular = true,
	caption = "Holy energy shot",
	priority = 9,
	flags = SF_X4AWAYSOUND
}
sfxinfo[sfx_vbhblt] = {
	singular = true,
	caption = "Intense holy energy shot",
	priority = 10,
	flags = SF_X8AWAYSOUND
}
sfxinfo[sfx_ebhblt] = {
	singular = true,
	caption = "Intense holy energy shot",
	priority = 12,
	flags = SF_X2AWAYSOUND|SF_X8AWAYSOUND
}

addHook("PlayerThink", function(player)
	if player.mo and player.mo.valid then
	
		if player.mo.skin ~= "annie_belnades" then
			return
		end
		
/*		if player.firenormaldown == nil then
			player.firenormaldown = 0
		end
		
		if player.cmd.buttons & BT_FIRENORMAL > 0 then
			player.firenormaldown = $1 + 1
		else
			player.firenormaldown = 0
		end*/
		
		if player.mo.holyboltcooldown > 0 then
			if (leveltime%TICRATE) then
				player.mo.holyboltcooldown = $ - 1
			end
		end
		
		if player.firenormaldown == 1 --if FireNormal has been tapped
		and player.mo.holyboltcooldown == 0 --a cooldown is required to avoid making this a machine gun and/or draining the entire energy meter in seconds flat
		and player.mo.energy >= 1*FRACUNIT then --Holy Bolt costs 1 energy (plus 1 per 3 seconds of charging)
			player.mo.energy = $ - 1*FRACUNIT --energy cost
			local bolt = P_SpawnPlayerMissile(player.mo, MT_HOLYBOLT, 0) --Fire Holy Bolt and assign ownership of it to the player
//			print(bolt.valid) --Did the bolt actually fire?
			S_StartSoundAtVolume(player.mo, sfx_hblt, 50, nil)
			bolt.holyboltcharge = player.mo.holyboltcharge --transfer charge to Holy Bolt
			player.mo.holyboltcooldown = 1*TICRATE --1-second cooldown
			player.mo.holyboltcharge = 0 --cleanup of errant charge
		end
		
		if player.firenormaldown > 1 then --if FireNormal is being held
			if not (leveltime%TICRATE) then
				player.mo.holyboltcharge = $ + 1 --Charge up Holy Bolt
				S_StartSoundAtVolume(player.mo, sfx_hchrg, 40, nil)
			end
		end
		
		if player.mo.holyboltcharge > 300 then
			player.mo.holyboltcharge = 300 --I didn't want to have a hard cap, but if holyboltcharge rises any higher than this, it can't be fired at all
		end
		
		if player.firenormaldown == 0 --If FireNormal isn't being held
		and player.mo.holyboltcooldown == 0
		and player.mo.holyboltcharge ~= 0 then --and the player has charged Holy Bolt
			S_StopSoundByID(player.mo, sfx_hchrg)
			if player.mo.energy >= (1*FRACUNIT + (player.mo.holyboltcharge*FRACUNIT/3)) then --if the player has enough energy
				player.mo.energy = $ - (1*FRACUNIT + (player.mo.holyboltcharge*FRACUNIT/3)) --energy cost
				local bolt = P_SpawnPlayerMissile(player.mo, MT_HOLYBOLT, 0) --Fire Holy Bolt and assign ownership of it to the player
//				print(bolt.valid) --Did the bolt actually fire?
				if player.mo.holyboltcharge == 1 then --scaling Holy Bolt volume with charge
					S_StartSoundAtVolume(player.mo, sfx_hblt, 55, nil)
				end
				if player.mo.holyboltcharge == 2 then
					S_StartSoundAtVolume(player.mo, sfx_hblt, 60, nil)
				end
				if player.mo.holyboltcharge == 3 then
					S_StartSoundAtVolume(player.mo, sfx_hblt, 65, nil)
				end
				if player.mo.holyboltcharge == 4 then
					S_StartSoundAtVolume(player.mo, sfx_hblt, 70, nil)
				end
				if player.mo.holyboltcharge == 5 then
					S_StartSoundAtVolume(player.mo, sfx_hblt, 75, nil)
				end
				if player.mo.holyboltcharge == 6 then
					S_StartSoundAtVolume(player.mo, sfx_bhblt, 80, nil)
				end
				if player.mo.holyboltcharge == 7 then
					S_StartSoundAtVolume(player.mo, sfx_bhblt, 85, nil)
				end
				if player.mo.holyboltcharge == 8 then
					S_StartSoundAtVolume(player.mo, sfx_bhblt, 90, nil)
				end
				if player.mo.holyboltcharge == 9 then
					S_StartSoundAtVolume(player.mo, sfx_bhblt, 95, nil)
				end
				if player.mo.holyboltcharge == 10 then
					S_StartSoundAtVolume(player.mo, sfx_bhblt, 100, nil)
				end
				if player.mo.holyboltcharge == 11 then
					S_StartSoundAtVolume(player.mo, sfx_bhblt, 105, nil)
				end
				if player.mo.holyboltcharge == 12 then
					S_StartSoundAtVolume(player.mo, sfx_vbhblt, 110, nil)
				end
				if player.mo.holyboltcharge == 13 then
					S_StartSoundAtVolume(player.mo, sfx_vbhblt, 115, nil)
				end
				if player.mo.holyboltcharge == 14 then
					S_StartSoundAtVolume(player.mo, sfx_vbhblt, 120, nil)
				end
				if player.mo.holyboltcharge == 15 then
					S_StartSoundAtVolume(player.mo, sfx_vbhblt, 125, nil)
				end
				if player.mo.holyboltcharge == 16 then
					S_StartSoundAtVolume(player.mo, sfx_vbhblt, 130, nil)
				end
				if player.mo.holyboltcharge == 17 then
					S_StartSoundAtVolume(player.mo, sfx_vbhblt, 135, nil)
				end
				if player.mo.holyboltcharge == 18 then
					S_StartSoundAtVolume(player.mo, sfx_ebhblt, 140, nil)
				end
				if player.mo.holyboltcharge == 19 then
					S_StartSoundAtVolume(player.mo, sfx_ebhblt, 145, nil)
				end
				if player.mo.holyboltcharge == 20 then
					S_StartSoundAtVolume(player.mo, sfx_ebhblt, 150, nil)
				end
				if player.mo.holyboltcharge == 21 then
					S_StartSoundAtVolume(player.mo, sfx_ebhblt, 155, nil)
				end
				if player.mo.holyboltcharge == 22 then
					S_StartSoundAtVolume(player.mo, sfx_ebhblt, 160, nil)
				end
				if player.mo.holyboltcharge == 23 then
					S_StartSoundAtVolume(player.mo, sfx_ebhblt, 165, nil)
				end
				if player.mo.holyboltcharge >= 24 then
					S_StartSoundAtVolume(player.mo, sfx_ebhblt, 170, nil)
				end
				bolt.holyboltcharge = player.mo.holyboltcharge --transfer charge to Holy Bolt
				player.mo.holyboltcooldown = 1*TICRATE --1-second cooldown
				player.mo.holyboltcharge = 0 --reset Holy Bolt charge
			else
				player.mo.holyboltcharge = 0 --Can't fire without enough energy, but the charge still has to reset so that it doesn't accumulate to the point where firing is impossible
			end
		end
	end
end)

addHook("MobjMoveCollide", function(bolt, thing) --tmthing == bolt
	if not (bolt.z >= (thing.z - bolt.height) and bolt.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, bolt, bolt.target, ((bolt.holyboltcharge/3) + 1)) --Holy Bolt damages/triggers the object --bolt.target == player according to P_SpawnPlayerMissile
		P_KillMobj(bolt, nil, nil) --Holy Bolt stops moving
	end
	
	if (thing.flags & MF_MONITOR) then
		P_DamageMobj(thing, bolt, bolt.target, 1) --Holy Bolt breaks the monitor and grants its effects to the player
		P_KillMobj(bolt, nil, nil) --Holy Bolt stops moving
	end
	
	if thing.type == MT_PLAYER then
		if G_CoopGametype() == true
		or (G_GametypeHasTeams == true and thing.player.ctfteam == bolt.target.ctfteam) then
			return --don't harm friendly players
		else
			P_DamageMobj(thing, bolt, bolt.target, ((bolt.holyboltcharge/3) + 1)) --damage opposing players in competitive modes
			P_KillMobj(bolt, 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
		if bolt.holyboltcharge >= 3 then
			P_DamageMobj(thing, bolt, bolt.target, (bolt.holyboltcharge/3)) --+1 real damage for every 3 seconds of charge
			if thing.health >= 1 then
				print("Target hit! "..thing.type.."'s current health: "..thing.health.." full HP, "..thing.holyboltblock.." sub-HP.") --check to make sure that Holy Bolt actually connected, particularly in the absence of pain state
			end
		end
		if bolt.holyboltcharge == 0 then
			if thing.holyboltblock == nil then
				thing.holyboltblock = 5 --establish the sub-health meter used to govern Holy Bolt damage
				print("Target hit! "..thing.type.."'s current health: "..thing.health.." full HP, "..thing.holyboltblock.." sub-HP.") --check to make sure that Holy Bolt actually connected, particularly in the absence of pain state
				if thing.healthonhit == thing.health then --if Holy Bolt wasn't charged enough to lower the target's actual health and induce a pain state or death
					thing.flags = $&~MF_SHOOTABLE --temporarily remove MF_SHOOTABLE to prevent consecutive hits
					thing.holyboltrecovery = (1*TICRATE)+1 --set timer before returning MF_SHOOTABLE
				end
			else
				thing.holyboltblock = $ - 1 --uncharged Holy Bolt deals 1/6 damage
				print("Target hit! "..thing.type.."'s current health: "..thing.health.." full HP, "..thing.holyboltblock.." sub-HP.") --check to make sure that Holy Bolt actually connected, particularly in the absence of pain state
				if thing.healthonhit == thing.health and thing.holyboltblock > 0 then --if Holy 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)+1 --set timer before returning MF_SHOOTABLE
				end
			end
		end
		if (bolt.holyboltcharge%3) == 1 then --if Holy Bolt has been charged for 1, 4, 7, etc. seconds
			if thing.holyboltblock == nil then
				thing.holyboltblock = 4 --establish the sub-health meter used to govern Holy Bolt damage
				print("Target hit! "..thing.type.."'s current health: "..thing.health.." full HP, "..thing.holyboltblock.." sub-HP.") --check to make sure that Holy Bolt actually connected, particularly in the absence of pain state
				if thing.healthonhit == thing.health then --if Holy Bolt wasn't charged enough to lower the target's actual health and induce a pain state or death
					thing.flags = $&~MF_SHOOTABLE --temporarily remove MF_SHOOTABLE to prevent consecutive hits
					thing.holyboltrecovery = (1*TICRATE)+1 --set timer before returning MF_SHOOTABLE
				end
			else
				thing.holyboltblock = $ - 2 --1 second of charging = 1/3 damage
				print("Target hit! "..thing.type.."'s current health: "..thing.health.." full HP, "..thing.holyboltblock.." sub-HP.") --check to make sure that Holy Bolt actually connected, particularly in the absence of pain state
				if thing.healthonhit == thing.health and thing.holyboltblock > 0 then --if Holy 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)+1 --set timer before returning MF_SHOOTABLE
				end
			end
		end
		if (bolt.holyboltcharge%3) == 2 then --if Holy Bolt has been charged for 2, 5, 8, etc. seconds
			if thing.holyboltblock == nil then
				thing.holyboltblock = 2 --establish the sub-health meter used to govern Holy Bolt damage
				print("Target hit! "..thing.type.."'s current health: "..thing.health.." full HP, "..thing.holyboltblock.." sub-HP.") --check to make sure that Holy Bolt actually connected, particularly in the absence of pain state
				if thing.healthonhit == thing.health then --if Holy Bolt wasn't charged enough to lower the target's actual health and induce a pain state or death
					thing.flags = $&~MF_SHOOTABLE --temporarily remove MF_SHOOTABLE to prevent consecutive hits
					thing.holyboltrecovery = (1*TICRATE)+1 --set timer before returning MF_SHOOTABLE
				end
			else
				thing.holyboltblock = $ - 4 --2 seconds of charging = 2/3 damage
				print("Target hit! "..thing.type.."'s current health: "..thing.health.." full HP, "..thing.holyboltblock.." sub-HP.") --check to make sure that Holy Bolt actually connected, particularly in the absence of pain state
				if thing.healthonhit == thing.health and thing.holyboltblock > 0 then --if Holy 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)+1 --set timer before returning MF_SHOOTABLE
				end
			end
		end
		if thing.holyboltblock <= 0 then
			P_DamageMobj(thing, bolt, bolt.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 Holy Bolt actually connected, particularly in the absence of pain state
			end
		end
		P_KillMobj(bolt, nil, nil)
	end
	
	if thing.type == MT_BOMBSPHERE then
		P_KillMobj(thing, bolt, bolt.tracer) --Allow Holy Bolt to disarm Bomb Spheres
		P_KillMobj(bolt, nil, nil)
	end
end, MT_HOLYBOLT)

addHook("MobjThinker", function(mobj)
	if mobj and mobj.valid then
	
		if (mobj.flags & MF_ENEMY) or (mobj.flags & MF_BOSS) then
			if mobj.holyboltrecovery == nil then
				mobj.holyboltrecovery = 0 --set up the Holy Bolt recovery timer
			end
			
			if mobj.healthonhit == nil
			or mobj.health == mobj.spawnhealth then --just in case the following MobjSpawn hook doesn't work
				mobj.healthonhit = mobj.health --setting up the healthonhit variable
			end
			
			if mobj.holyboltrecovery > 0 then
				if (leveltime%TICRATE) then
					mobj.holyboltrecovery = $ - 1 --countdown
				end
			end
			
			if mobj.healthsynchronize == nil then
				mobj.healthsynchronize = 0
			end
			
			//if mobj.holyboltrecovery == 1 then --if holyboltrecovery has run down (but is not yet inactive)
			if mobj.holyboltrecovery > 0 and mobj.holyboltrecovery <5 then --let's make sure this can run properly regardless of whether or not loading multiple Belnades Sisters makes this hook run multiple times per tic
				if not (mobj.flags & MF_SHOOTABLE) then --let's make sure Holy Bolt actually took the MF_SHOOTABLE flag
					mobj.flags = $1|MF_SHOOTABLE --make the target susceptible to damage again
				end
			end
			
			if mobj.healthonhit ~= mobj.health then --if a mobj's health changes due to damage or healing
				//mobj.healthsynchronize = 3 --setting up a delay before changing the value of healthonhit so that hooks that compare healthonhit to health can function
				mobj.healthsynchronize = 24 --setting healthsynchronize to the smallest value that's divisible by 1, 2, 3, or 4
			end
			
			if mobj.healthsynchronize > 0 then
				if (leveltime%TICRATE) then
					mobj.healthsynchronize = $ - 1
				end
			end
			
			if mobj.healthsynchronize == 1 --setting healthonhit to health after comparison hooks have run
			or mobj.healthsynchronize == 2
			or mobj.healthsynchronize == 3
			or mobj.healthsynchronize == 4 then
				mobj.healthonhit = mobj.health
			end
		end
	end
end, MT_NULL) --run this hook for all enemies

addHook("MobjSpawn", function(mobj)
	if (mobj.flags & MF_ENEMY) or (mobj.flags & MF_BOSS) then
		mobj.healthonhit = mobj.health
	end
end, MT_NULL) --run this hook for all enemies