-- Ember's Stuff --

-- VARIABLES
local autoaim = nil
local chargetimer = 0
local chargedstinger = nil
local aura = nil

-- VARIABLE RESET
addHook("PlayerSpawn", function(player)
	if player.mo and player.mo.skin == "ember"
		chargetimer = 0
		player.mo.drippedout = 0
	end
end)

-- FLIGHT
addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "ember"
		if not player.exiting and player.mo.drippedout != 1
			if not (P_PlayerInPain(player) or (player.playerstate == PST_DEAD))
				if ((player.powers[pw_carry] == CR_NONE) and not (player.pflags & PF_SPINNING))
					if (player.cmd.buttons & BT_JUMP)
						if player.mo.waterlogged == 1 and not player.powers[pw_super]
							if (player.mo.eflags & MFE_VERTICALFLIP)
								player.mo.momz = -2*FRACUNIT
							else
								player.mo.momz = 2*FRACUNIT
							end
						else
							player.pflags = $|PF_CANCARRY
							if (player.mo.eflags & MFE_VERTICALFLIP)
								player.mo.momz = -5*FRACUNIT
							else
								player.mo.momz = 5*FRACUNIT
							end
						end
						S_StartSound(player.mo, sfx_buzz4)
						player.panim = PA_JUMP
					end
					if not (player.cmd.buttons & BT_JUMP)
						player.jumptapready = true
						player.jumptapping = false
					elseif player.jumptapready
						player.jumptapping = true
						player.jumptapready = false
					else
						player.jumptapping = false
					end
					if player.jumptapping
						player.mo.state = S_STARTFLIGHT
						player.panim = PA_JUMP
					end
				end
			end
		end
	end
end)

-- FLAME STINGER
addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "ember"
		if not player.exiting and player.mo.drippedout != 1
			if not (P_PlayerInPain(player) or (player.playerstate == PST_DEAD))
				if ((player.powers[pw_carry] == CR_NONE) and not (player.pflags == PF_SPINNING))
					if (player.cmd.buttons & BT_USE)
						player.spintapping = true
						player.spintapready = false
					elseif player.spintapping
						player.spintapready = true
						player.spintapping = false
					else
						player.spintapready = false
					end
					if player.mo.state == S_PLAY_WALK or player.mo.state == S_PLAY_RUN or player.pflags & PF_JUMPED or player.mo.state == S_PLAY_STND or player.mo.state == S_PLAY_WAIT or player.mo.state == S_PLAY_FIRE or player.mo.state == S_PLAY_FIRE_FINISH and player.mo.state != S_FLYSHOOT and player.mo.state != S_FLYSHOOT_FIN
						if player.spintapping
							if player.powers[pw_super]
								chargetimer = 51
							end
							if not player.weapondelay and not (player.mo.state == S_PLAY_SPRING)
								chargetimer = $+1
							end
						end
					end
					if player.mo.state == S_PLAY_SPRING
						player.spintapready = false
						player.spintapping = false
						chargetimer = 0
					end
					if player.mo.state != S_PLAY_FIRE and player.mo.state != S_PLAY_FIRE_FINISH and player.mo.state != S_FLYSHOOT and player.mo.state != S_FLYSHOOT_FIN
						autoaim = P_LookForEnemies(player, false, true)
					end
					if (autoaim 
					and autoaim.valid 
					and autoaim.health)
						player.stingerangle = R_PointToAngle2(player.mo.x, player.mo.y, autoaim.x, autoaim.y)
						if player.mo.state == S_PLAY_WALK 
						or player.mo.state == S_PLAY_RUN 
						or (player.pflags & PF_JUMPED) 
						or player.mo.state == S_PLAY_STND 
						or player.mo.state == S_PLAY_WAIT
							P_SpawnLockOn(player, autoaim, S_LOCKON1)
						end
					end
					if player.mo.state == S_PLAY_WALK or player.mo.state == S_PLAY_RUN or player.pflags & PF_JUMPED or player.mo.state == S_PLAY_STND or player.mo.state == S_PLAY_WAIT or player.mo.state == S_PLAY_FIRE or player.mo.state == S_PLAY_FIRE_FINISH and player.mo.state != S_FLYSHOOT and player.mo.state != S_FLYSHOOT_FIN
						if player.spintapready and not player.weapondelay
							if autoaim and autoaim.valid
								if player.mo.waterlogged != 1
									if chargetimer >= 50
										chargedstinger = P_SpawnMissile(player.mo, autoaim, MT_CHARGEDFS)
										S_StartSound(player.mo, sfx_s3ka0)
									else
										P_SpawnMissile(player.mo, autoaim, MT_FLAMESTINGER)
										S_StartSound(player.mo, sfx_fire)
										player.charflags = $ & ~SF_SUPER 
									end
									chargetimer = 0
								else
									if chargetimer >= 50
										chargedstinger = P_SpawnMissile(player.mo, autoaim, MT_WATERCFS)
										S_StartSound(player.mo, sfx_s3ka0)
									else
										P_SpawnMissile(player.mo, autoaim, MT_WATERFS)
										S_StartSound(player.mo, sfx_s3k47)
										player.charflags = $ & ~SF_SUPER
									end
									S_StartSound(player.mo, sfx_s3k47)
									chargetimer = 0
								end
								if player.powers[pw_super]
									player.weapondelay = TICRATE*1/2
								else
									player.weapondelay = TICRATE*1
								end
							else
								if player.mo.waterlogged != 1
									if chargetimer >= 50
										chargedstinger = P_SPMAngle(player.mo, MT_CHARGEDFS, player.mo.angle)
										S_StartSound(player.mo, sfx_s3ka0)
									else
										P_SPMAngle(player.mo, MT_FLAMESTINGER, player.mo.angle)
										S_StartSound(player.mo, sfx_fire)
									end
									chargetimer = 0
								else
									if chargetimer >= 50
										chargedstinger = P_SPMAngle(player.mo, MT_WATERCFS, player.mo.angle)
										S_StartSound(player.mo, sfx_s3ka0)
									else
										P_SPMAngle(player.mo, MT_WATERFS, player.mo.angle)
										S_StartSound(player.mo, sfx_s3k47)
									end
									chargetimer = 0
								end
								if player.powers[pw_super]
									player.weapondelay = TICRATE*1/2
								else
									player.weapondelay = TICRATE*1
								end
							end
							if P_IsObjectOnGround(player.mo)
								if player.mo.state != S_PLAY_FIRE and player.mo.state != S_PLAY_FIRE_FINISH
									player.mo.state = S_PLAY_FIRE
									if autoaim
										player.drawangle = player.stingerangle
									end
								end
							else
								if player.mo.state != S_FLYSHOOT and player.mo.state != S_FLYSHOOT_FIN
									player.mo.state = S_FLYSHOOT
									if autoaim
										player.drawangle = player.stingerangle
									end
								end
							end
						end
					end
				else
					chargetimer = 0
				end
			else
				chargetimer = 0
			end
		end
	end
end)

-- CHARGED F.S. THINKER
addHook("MobjThinker", function(chargedstinger)
	for player in players.iterate do
		local p = player.mo
		if chargedstinger and chargedstinger.valid
			for x = chargedstinger.x, chargedstinger.x + chargedstinger.radius, chargedstinger.radius
				for y = chargedstinger.y, chargedstinger.y + chargedstinger.radius, chargedstinger.radius
					local ss = R_PointInSubsector(x,y)
					for fof in ss.sector.ffloors()
						if (fof.flags & FF_BUSTUP) and (fof.flags & FF_EXISTS)
							EV_CrumbleChain(ss.sector, fof)
						end
					end
				end
			end
			local fx = chargedstinger.x
			local fy = chargedstinger.y
			local fr = 60*FRACUNIT
			searchBlockmap("objects", function(chargedstinger, found)
				if found.flags & MF_SHOOTABLE
				and found.z - found.scale <= chargedstinger.z + chargedstinger.height
				and found.z + found.height + found.scale >= chargedstinger.z
					P_DamageMobj(found, chargedstinger, p, 2)
				end
			end, chargedstinger, fx-fr, fx+fr, fy-fr, fy+fr)
		end
	end
end, MT_CHARGEDFS)

-- CHARGED F.S. (WATER) THINKER
addHook("MobjThinker", function(chargedstinger)
	for player in players.iterate do
		local p = player.mo
		if chargedstinger and chargedstinger.valid
			for x = chargedstinger.x, chargedstinger.x + chargedstinger.radius, chargedstinger.radius
				for y = chargedstinger.y, chargedstinger.y + chargedstinger.radius, chargedstinger.radius
					local ss = R_PointInSubsector(x,y)
					for fof in ss.sector.ffloors()
						if (fof.flags & FF_BUSTUP) and (fof.flags & FF_EXISTS)
							EV_CrumbleChain(ss.sector, fof)
						end
					end
				end
			end
			local fx = chargedstinger.x
			local fy = chargedstinger.y
			local fr = 60*FRACUNIT
			searchBlockmap("objects", function(chargedstinger, found)
				if found.flags & MF_SHOOTABLE
				and found.z - found.scale <= chargedstinger.z + chargedstinger.height
				and found.z + found.height + found.scale >= chargedstinger.z
					P_DamageMobj(found, chargedstinger, p, 2)
				end
			end, chargedstinger, fx-fr, fx+fr, fy-fr, fy+fr)
		end
	end
end, MT_WATERCFS)

-- CHARGE EFFECTS
addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "ember"
		if chargetimer == 10
			S_StartSound(player.mo, sfx_s3kcal)
		end
		if chargetimer == 0 or chargetimer >= 50
			S_StopSoundByID(player.mo, sfx_s3kcal) 
		end
		if chargetimer == 50
			S_StartSound(player.mo, sfx_kc48)
			P_Earthquake(player.mo, player.mo, 50*FRACUNIT)
		end
	end
end)

-- CHARGE AURA
addHook("MobjThinker", function(aura)
	for player in players.iterate do
		local p = player.mo
		if aura and aura.valid
			if chargetimer == 10
				aura.state = S_CHARGEAURA1
			end
			if p.state == S_PLAY_SUPER_TRANS1
				aura.state = S_CHARGEAURA3
			end
			if (chargetimer == 0
			or chargetimer > 50)
			and not player.powers[pw_super]
				aura.state = S_INVISIBLE
			end
		end
	end
end, MT_CHARGEAURA)

-- WATER WEAKNESS
addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "ember"
		if player.mo.eflags & MFE_UNDERWATER
			player.mo.waterlogged = 1
		else
			player.mo.waterlogged = 0
		end
	end
end)

-- SUPER TRANSFORMATION
local function EmberSuperTrans(player)
    if ((player.mo.state == S_PLAY_SUPER_TRANS1) 
	or (player.mo.state == S_PLAY_SUPER_TRANS2) 
	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))
        return true
    else
        return false
    end
end

local function EmberSuperCheck(player)
    if not P_IsObjectOnGround(player.mo) and player.rings >= 50 and All7Emeralds(emeralds) and not player.powers[pw_super] and (player.playerstate == PST_LIVE)
    and (skins[player.mo.skin].flags & SF_SUPER)
    and not (player.cmd.buttons & BT_USE)
    and not (player.pflags & PF_THOKKED) and not (mapheaderinfo[gamemap].typeoflevel & TOL_NIGHTS) and not (player.pflags & PF_SHIELDABILITY) and (player.pflags & PF_JUMPED) and not EmberSuperTrans(player)
    and not EmberSuperTrans(player)
    and ((player.powers[pw_shield] == 0) or (player.powers[pw_shield] > 0))
    then
        return true
    else
        return false
    end
end

local function EmberSuper(player)
    player.pflags = $ & ~PF_JUMPED
    player.charflags = $1 | SF_SUPER
	P_DoSuperTransformation(player, false)
end

addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "ember"
		if not G_EnoughPlayersFinished()
			if not player.powers[pw_super]
				player.charflags = $ & ~SF_SUPER
			end
			if (player.cmd.buttons & BT_CUSTOM1) and EmberSuperCheck(player)
				EmberSuper(player)
			end
			if P_PlayerTouchingSectorSpecial(player, 4, 6) and All7Emeralds(emeralds) and not player.powers[pw_super] then
				player.rings = 50
				EmberSuper(player)
			end
			if player.powers[pw_super]
				S_StartSound(player.mo, sfx_burnin)
			else
				S_StopSoundByID(player.mo, sfx_burnin)
			end
        end
	end
end)

addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "ember"
		if (All7Emeralds(emeralds)) and not player.beenotified
			player.beenotified = true
			S_StartSound(player.mo, sfx_s3k68)
		end
	end
end)

hud.add(function(v, player)
	if player.mo == nil or player.mo.skin ~= "ember"
		return
	end
	local emerdudes2 = v.cachePatch('EHUDA0')
	if (All7Emeralds(emeralds))
		if (leveltime > 0) and (leveltime < 150)
			v.draw(70, 60, emerdudes2, V_PERPLAYER)
			v.drawString(5, 150, "Ember can now transform into Blazing Ember", V_PERPLAYER)
			v.drawString(50, 160, "by pressing Custom 1 while flying!", V_PERPLAYER)
		end
	end
end)

-- FIRE IMMUNITY
addHook("ShouldDamage", function(mo, inf, src, dmg, dmgt)
	if (mo and (mo.skin == "ember") and mo.player)
		if ((inf and inf.valid) or (src and src.valid))
			if dmgt == DMG_FIRE
				return false
			end
		end
	end
end, MT_PLAYER)

-- EMBER DRIP
addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "ember"
		if not player.exiting
			if not (P_PlayerInPain(player) or (player.playerstate == PST_DEAD))
				if ((player.powers[pw_carry] == CR_NONE) and not (player.pflags & PF_SPINNING))
					if not (player.cmd.buttons & BT_CUSTOM1)
						player.cust1tapready = true
						player.cust1tapping = false
					elseif player.cust1tapready
						player.cust1tapping = true
						player.cust1tapready = false
					else
						player.cust1tapping = false
					end
					if player.cust1tapping 
					and not player.weapondelay 
					and P_IsObjectOnGround(player.mo)
						if player.mo.drippedout != 1
							player.mo.drippedout = 1
							player.mo.state = S_EMBER_DRIP
							player.weapondelay = TICRATE*1
							P_PlayJingleMusic(player, "EMDRIP", nil, true, JT_OTHER)
						elseif player.mo.drippedout == 1
							player.mo.drippedout = 0
							player.mo.state = S_PLAY_STND
							player.weapondelay = TICRATE*1
							P_RestoreMusic(player)
						end
					end
					if player.mo.state == S_EMBER_DRIP
						player.pflags = $|PF_FULLSTASIS|PF_GODMODE
					else
						player.pflags = $ & ~PF_GODMODE
					end
				end
			end
		end
	end
end)