--Credits:

--Sapheros 
--Jimita
--Nev3r
--Prisima
--Antimodern


addHook("MobjThinker", function(frostburn)	
	if frostburn.state == S_FROSTBURN_ICE1
		if (frostburn.target and frostburn.target.valid)
		and R_PointToDist2(frostburn.x, frostburn.y, frostburn.target.x, frostburn.target.y) > RING_DIST
			A_HomingChase(frostburn, 10*FRACUNIT, 0)
		else
			A_ForceStop(frostburn)
		end
		if frostburn.tics %10 == 0
			A_BossFireShot(frostburn, MT_FROSTBURN_PUFF, 2)
			A_BossFireShot(frostburn, MT_FROSTBURN_PUFF, 3)
		elseif frostburn.tics %5 == 0
			A_BossFireShot(frostburn, MT_FROSTBURN_PUFF, 4)
			A_BossFireShot(frostburn, MT_FROSTBURN_PUFF, 5)
		end
		if frostburn.target.frostburnt
			frostburn.state = S_FROSTBURN_ICE2
			S_StartSound(frostburn, sfx_bewar4)
		end
	end
	if frostburn.state == S_FROSTBURN_FIRE1
		if (frostburn.target and frostburn.target.valid)
		and R_PointToDist2(frostburn.x, frostburn.y, frostburn.target.x, frostburn.target.y) > RING_DIST
			A_HomingChase(frostburn, 10*FRACUNIT, 0)
		else
			A_ForceStop(frostburn)
		end
		
		if frostburn.tics%4 == 0
			for i=2,5
				A_BossFireShot(frostburn, MT_CYBRAKDEMON_FLAMESHOT, i)
			end
		end
	end
	local s,it,ft = "S_FROSTBURN_","ICETHROW","FIRETHROW"
	if (frostburn.state >= _G[s..it.."1"] and frostburn.state <= _G[s..it.."3"])
	or (frostburn.state >= _G[s..ft.."1"] and frostburn.state <= _G[s..ft.."3"])
		A_HomingChase(frostburn, 5*FRACUNIT, 0)
	end
	if frostburn.state == S_FROSTBURN_PANIC1
		if frostburn.tics == 5
			A_ZThrust(frostburn, 5, 1)
		end
	end
	if frostburn.state == S_FROSTBURN_PANIC2
		frostburn.angle = frostburn.angle+ANGLE_22h
		local iceballs = P_SpawnMobj(frostburn.x, frostburn.y, frostburn.z-(frostburn.height/3), MT_FROSTBURN_ICEBALL)
		P_Thrust(iceballs, frostburn.angle, 10*FRACUNIT)
	end
	if frostburn.state == S_FROSTBURN_PANIC4
		if frostburn.target.frostburnt
			A_FireShot(frostburn, MT_CYBRAKDEMON_FLAMESHOT, -30)
		elseif (frostburn.tics < 35)
		and not (frostburn.target.frostburn)
			frostburn.state = S_FROSTBURN_PANIC_ESCAPE
		else
			frostburn.state = S_FROSTBURN_PANIC_MISS
		end
	end
	if frostburn.state == S_FROSTBURN_PANIC_MISS
		P_SetObjectMomZ(frostburn, -2*FRACUNIT, false)
	end
end, MT_FROSTBURN)

local function FrostburnDebris(mo)
	for i=1,10 do
		local debris = P_SpawnMobj(mo.x, mo.y, mo.z, MT_FROSTDEBRIS)
		P_Thrust(debris, (ANG30+(ANG2*3))*i, P_RandomRange(5, 10)*FRACUNIT)
		debris.momz = P_RandomRange(5, 15)*FRACUNIT
		debris.fuse = TICRATE
		debris.scale = 2*FRACUNIT
	end
end

local function BreakIce(mo)
	if (mo.frostblock and mo.frostblock.valid)
		P_KillMobj(mo.frostblock)
		for i = 1,4
			P_KillMobj(mo.frostblocksides[i])
		end
		mo.frostblock = nil
		mo.frostblocksides = nil
	end
	FrostburnDebris(mo)
	mo.frostburnt = false
	S_StartSound(mo, sfx_s3k9b)
	for mobj in mobjs.iterate()
		if mobj.type == MT_TAILSOVERLAY
			if mobj.tracer == mo
				mobj.flags2 = $ & ~MF2_DONTDRAW
			end
		end
	end	
	if mo.health
		mo.flags = $ & ~MF_NOCLIP
		mo.flags = $ & ~MF_NOCLIPHEIGHT
		//mo.flags = $ | MF_SOLID
		mo.player.pflags = $1 & ~PF_FORCESTRAFE
		mo.player.pflags = $1 & ~PF_STASIS
		mo.tics = 1
		P_DoPlayerPain(mo.player)
	end
	for p in players.iterate
		if mo == p.mo
			p.mo.colorized = false
			p.mo.color = p.skincolor
		end
	end
end

local function FrozenPlayer(p)
	if p and p.mo and p.valid
		local i = p.mo.frostblock
		p.mo.sprite2 = SPR2_DEAD
		p.mo.frame = A
		//p.mo.momx,p.mo.momy,p.mo.momz = 0,0,0
		p.mo.momz = 0
		p.mo.tracer = i
		p.pflags = $1|PF_FORCESTRAFE|PF_STASIS
		p.mo.flags = $1|MF_NOCLIP|MF_NOCLIPHEIGHT	// don't move the camera
		p.mo.breaktimer = $ and $ or 0
		--P_SetOrigin(i, p.mo.x, p.mo.y, p.mo.lastz)
		//P_SetOrigin(p.mo, i.x, i.y, i.z+(12*FRACUNIT))
		A_CapeChase(p.mo, 12*FRACUNIT+1)
		//print(p.mo.z/FRACUNIT+" player.mo.z", p.mo.momz/FRACUNIT+" player.mo.momz", i.z/FRACUNIT+" ice.z", i.momz/FRACUNIT+" ice.momz")
		i.momx,i.momy = p.mo.momx,p.mo.momy	
		for j = 1,4
			p.mo.frostblocksides[j].frame = _G[string.char(string.byte("A")+i.icehits)]
			p.mo.frostblocksides[j].state = _G["S_FROSTBURNT"..(i.icehits+1)]
			P_SetOrigin(p.mo.frostblocksides[j], p.mo.frostblocksides[j].x, p.mo.frostblocksides[j].y, i.z)
		end
		if p.mo.breaktimer > 0
			p.mo.breaktimer = $-1
		end
		if (p.jumpbtn == 1) and (p.mo.breaktimer == 0)
			p.mo.breaktimer = 13
			if i.icehits < 5
				i.icehits = $+1
				S_StartSound(p.mo, sfx_s3k80)
			end
			if i.icehits == 5 then // break! -mpc
				BreakIce(p.mo)
				return
			end
		end
		for mobj in mobjs.iterate()
			if mobj.type == MT_TAILSOVERLAY
				if mobj.tracer == p.mo
					mobj.flags2 = $1|MF2_DONTDRAW
				end
			end
		end	
		p.mo.colorized = true
		p.mo.color = SKINCOLOR_ICY
	end
end


local function FreezePlayer(p)
	if p and p.mo and p.mo.valid
		p.mo.frostburnt = true		// Variable to check if player is frozen
		p.mo.lastz = p.mo.z		// to align the player -mpc
		p.pflags = $&~(PF_JUMPED|PF_SPINNING|PF_THOKKED)
		//p.mo.flags = $&~MF_SOLID
		local ice = p.mo.frostblock
		local icesides = p.mo.frostblocksides
		if not ice then
			ice = P_SpawnMobj(p.mo.x, p.mo.y, p.mo.z, MT_FROSTBURNT)	
			//Ice cube sides
			icesides = {}
			local pos = {}
			for i = 1,4
				pos[i] = {}
				pos[i].x = p.mo.x
				pos[i].y = p.mo.y
			end
			pos[1].x = $+35*FRACUNIT
			pos[3].x = $-35*FRACUNIT
			pos[2].y = $+35*FRACUNIT
			pos[4].y = $-35*FRACUNIT
			for i = 1,4
				icesides[i] = P_SpawnMobj(pos[i].x, pos[i].y, p.mo.z, MT_ICEBLOCKSIDE)
				icesides[i].angle = FixedAngle(90*FRACUNIT*i)	
			end
			p.mo.frostblock = ice
			p.mo.frostblocksides = icesides
			ice.frozenplayer = p
			ice.friction = FRACUNIT
		end
		ice.icehits = 0	// How many hits the ice has
	end
end

// thinkframe is cooler because it happens after mobjthinker -mpc
addHook("ThinkFrame", do
	for p in players.iterate do
		if p.mo and p.mo.valid 
			if (p.cmd.buttons & BT_JUMP)
				p.jumpbtn = $ and $+1 or 1
			else
				p.jumpbtn = 0
			end
			if p.mo.frostburnt then
				if p.mo.health
					FrozenPlayer(p)
				end
				if P_PlayerInPain(p)
				or p.deadtimer
				or p.exiting then
					BreakIce(p.mo)
				end
			end
		end
	end
end, MT_PLAYER)

addHook("TouchSpecial", function(mo, tmo)
	if mo and mo.valid and tmo and tmo.valid
		if tmo.player
			if not (tmo.frostburnt)
				//S_StartSound(mo, sfx_spkdth)
				tmo.momx,tmo.momy,tmo.momz = 0,0,0
				FreezePlayer(tmo.player)
				return true
			else
				return false
			end
		/*elseif (tmo.type == MT_FROSTBURNT)
			print("ydoobah doobah yae")
			return true*/
		end
	end
end, MT_FROSTBURN_ICE)

addHook("ShouldDamage", function(target, inflictor, source, damage)
	if not inflictor then return end
	if inflictor.type == MT_FROSTBURN_ICE
		return false
	elseif inflictor.type == MT_FROSTBURN_PUFF
		return false
	end
end, MT_PLAYER)

addHook("ShouldDamage", function(target, inflictor, source, damage)
	if not inflictor then return end
	if not source then return end
	if source.type == MT_FROSTBURN
	and not inflictor.type == MT_FROSTBURN_PUFF
		return true
	else
		return false
	end
end, MT_FROSTBURNT)

addHook("MobjDamage", function(target, inflictor)
	if (target.frozenplayer) then
		BreakIce(target)		// oh shoot	-mpc
	end
end, MT_FROSTBURNT)

/*addHook("MobjSpawn", function(mo)
	if not mo.initfuse
		mo.fuse = TICRATE
		mo.initfuse = 1
	end
end, MT_FROSTDEBRIS)*/

// puff spawns ice on death
addHook("MobjDeath", function(mo)
	P_SpawnMobj(mo.x, mo.y, mo.z, MT_FROSTBURN_ICE)
end, MT_FROSTBURN_PUFF)
// no idea if this is needed -mpc
addHook("MobjRemoved", function(mo)
	P_SpawnMobj(mo.x, mo.y, mo.z, MT_FROSTBURN_ICE)
end, MT_FROSTBURN_PUFF)