// Final Demo Ring Boxes - Ported by MIDIMan
// Use with LUA_FBOX

/*
The silver ring monitor (referred to as the "Grey Ring Box" in the source code) 
was introduced in the Christmas demos, and remained in the game all the way up 
until 2.0.

The CTF ring monitors were introduced in 2.0.
*/

freeslot(
	"SPR_FBXR",
	"MT_FDBOX_RING",
	"MT_FDBOX_RING_ICON",
	"MT_FDBOX_SRING",
	"MT_FDBOX_SRING_ICON",
	"MT_FDBOX_REDRING",
	"MT_FDBOX_BLUERING",
	"S_FDBOX_RING_IDLE",
	"S_FDBOX_RING_ICON1",
	"S_FDBOX_RING_ICON2",
	"S_FDBOX_SRING_IDLE",
	"S_FDBOX_SRING_ICON1",
	"S_FDBOX_SRING_ICON2",
	"S_FDBOX_REDRING_IDLE1",
	"S_FDBOX_REDRING_IDLE2",
	"S_FDBOX_BLUERING_IDLE1",
	"S_FDBOX_BLUERING_IDLE2"
)

// Hack to allow players to achieve a "Perfect" bonus with these monitors
local function P_AddToNumMapRings(mobj, numrings)
	if not (mobj and mobj.valid and numrings) then return end
	
	/*
	if numrings >= 10
		for i = 1, numrings/10, 1
			local ringbox = P_SpawnMobj(mobj.x, mobj.y, mobj.z, MT_RING_BOX)
			P_RemoveMobj(ringbox)
		end
		
		numrings = $%10
	end
	*/
	//print("FDBOXRINGS: " + numrings)
	for i = 1, numrings, 1 do
		local ring = P_SpawnMobj(mobj.x, mobj.y, mobj.z, MT_RING)
		P_RemoveMobj(ring)
	end
end

// Final Demo Ring Box

addHook("MobjFuse", function(mobj)
	if not (mobj and mobj.valid) then return end
	
	P_FDMonitorFuseThink(mobj)
	return true
end, MT_FDBOX_RING)

addHook("MapThingSpawn", function(mobj, mthing)
	if not (mobj and mobj.valid
	and mthing and mthing.valid) then
		return
	end
	
	P_FDMonitorTypeSpawn(mobj, mthing)
	
	if mobj and mobj.valid then
		if ultimatemode and not G_IsSpecialStage(gamemap) then
			P_RemoveMobj(mobj)
			return
		end
	
		P_AddToNumMapRings(mobj, 10)
	end
end, MT_FDBOX_RING)

mobjinfo[MT_FDBOX_RING] = {
	//$Name Final Demo Super Ring (10 Rings)
	//$Sprite FBXRA0
	//$Category Monitors
	//$Flags4Text Random (Strong)
	//$Flags8Text Random (Weak) / Random (Pre-2.0)
	//$ParameterText Behavior
	doomednum = 462,
	spawnstate = S_FDBOX_RING_IDLE,
	spawnhealth = 1,
	painstate = S_FDBOX_RING_IDLE,
	deathstate = S_FDBOX_EXPLOSION1,
	deathsound = sfx_pop,
	speed = 1,
	radius = 16*FRACUNIT,
	height = 32*FRACUNIT,
	damage = MT_FDBOX_RING_ICON,
	flags = MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE
}

states[S_FDBOX_RING_IDLE] =	{SPR_FBXR,	A,	2,	nil,	0,	0,	S_FDBOX_FLICKER}

mobjinfo[MT_FDBOX_RING_ICON] = {
	doomednum = -1,
	spawnstate = S_FDBOX_RING_ICON1,
	spawnhealth = 1,
	seesound = sfx_itemup,
	reactiontime = 10,
	speed = 4*FRACUNIT,	// Originally 2*FRACUNIT; Changed to match pre-2.1's speed
	radius = 8*FRACUNIT,
	height = 14*FRACUNIT,
	damage = 62*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON
}

states[S_FDBOX_RING_ICON1] =	{SPR_FBXR,	B,	18,	nil,		0,	0,	S_FDBOX_RING_ICON2}
states[S_FDBOX_RING_ICON2] =	{SPR_FBXR,	B,	18,	A_RingBox,	0,	0,	S_NULL}

// Final Demo Silver Ring Box

addHook("MobjFuse", function(mobj)
	if not (mobj and mobj.valid) then return end
	
	P_FDMonitorFuseThink(mobj)
	return true
end, MT_FDBOX_SRING)

addHook("MapThingSpawn", function(mobj, mthing)
	if not (mobj and mobj.valid
	and mthing and mthing.valid) then
		return
	end
	
	P_FDMonitorTypeSpawn(mobj, mthing)
	
	if mobj and mobj.valid then
		if ultimatemode and not G_IsSpecialStage(gamemap) then
			P_RemoveMobj(mobj)
			return
		end
	
		P_AddToNumMapRings(mobj, 25)
	end
end, MT_FDBOX_SRING)

mobjinfo[MT_FDBOX_SRING] = {
	//$Name Final Demo Silver Ring (25 Rings)
	//$Sprite FBXRC0
	//$Category Monitors
	//$Flags4Text Random (Strong)
	//$Flags8Text Random (Weak) / Random (Pre-2.0)
	//$ParameterText Behavior
	doomednum = 463,
	spawnstate = S_FDBOX_SRING_IDLE,
	spawnhealth = 1,
	painstate = S_FDBOX_SRING_IDLE,
	deathstate = S_FDBOX_EXPLOSION1,
	deathsound = sfx_pop,
	speed = 1,
	radius = 16*FRACUNIT,
	height = 32*FRACUNIT,
	damage = MT_FDBOX_SRING_ICON,
	flags = MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE
}

states[S_FDBOX_SRING_IDLE] =	{SPR_FBXR,	C,	2,	nil,	0,	0,	S_FDBOX_FLICKER}

mobjinfo[MT_FDBOX_SRING_ICON] = {
	doomednum = -1,
	spawnstate = S_FDBOX_SRING_ICON1,
	spawnhealth = 1,
	seesound = sfx_itemup,
	reactiontime = 25,
	speed = 4*FRACUNIT,	// Originally 2*FRACUNIT; Changed to match pre-2.1's speed
	radius = 8*FRACUNIT,
	height = 14*FRACUNIT,
	damage = 62*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY|MF_NOGRAVITY|MF_BOXICON
}

states[S_FDBOX_SRING_ICON1] =	{SPR_FBXR,	D,	18,	nil,		0,	0,	S_FDBOX_SRING_ICON2}
states[S_FDBOX_SRING_ICON2] =	{SPR_FBXR,	D,	18,	A_RingBox,	0,	0,	S_NULL}

// CTF Monitor Exclusive Functions/Hooks

local function CTFRingSpawn(mobj, mthing)
	if not (mobj and mobj.valid
	and mthing and mthing.valid) then
		return
	end
	
	if (gametype ~= GT_CTF) then
		mobj.type = MT_FDBOX_RING
		
		mobj.radius = FixedMul(mobj.scale, mobj.info.radius)
		mobj.height = FixedMul(mobj.scale, mobj.info.height)
		mobj.flags = mobj.info.flags
		
		mobj.health = mobj.info.spawnhealth
		
		mobj.reactiontime = mobj.info.reactiontime
		
		mobj.state = mobj.info.spawnstate
	end
end

// This is needed so the player can't go through the top or bottom of the red and blue ring monitors
addHook("PlayerCanDamage", function(player, mobj)
	if not (player and player.valid
	and mobj and mobj.valid) then
		return
	end
	
	if (mobj.type == MT_FDBOX_REDRING and player.ctfteam ~= 1) 
	or (mobj.type == MT_FDBOX_BLUERING and player.ctfteam ~= 2) then
		return false
	end
end)

// Final Demo Red Ring Monitor

/*
addHook("MobjSpawn", function(mobj, mthing)
	if (gametype == GT_CTF)
		P_AddToNumMapRings(mobj, 10)
	end
end, MT_FDBOX_REDRING)
*/

addHook("MobjFuse", function(mobj)
	if not (mobj and mobj.valid) then return end
	
	P_FDMonitorFuseThink(mobj)
	return true
end, MT_FDBOX_REDRING)

addHook("MapThingSpawn", function(mobj, mthing)
	if not (mobj and mobj.valid
	and mthing and mthing.valid) then
		return
	end
	
	P_FDMonitorTypeSpawn(mobj, mthing)
	
	if mobj and mobj.valid then
		if (mobj.type == MT_FDBOX_REDRING) then
			if ultimatemode and not G_IsSpecialStage(gamemap) then
				P_RemoveMobj(mobj)
				return
			end
			
			P_AddToNumMapRings(mobj, 10)
			CTFRingSpawn(mobj, mthing)
		end
	end
end, MT_FDBOX_REDRING)

// Prevents a player on the blue team from destroying a red ring monitor
addHook("ShouldDamage", function(target, inflictor, source, damage, damagetype)
	if not (source and source.valid
	and source.player and source.player.valid) then
		return
	end
	
	if source.player.ctfteam ~= 1 then
		return false
	end
end, MT_FDBOX_REDRING)

mobjinfo[MT_FDBOX_REDRING] = {
	//$Name 2.0 CTF Team Ring Monitor (Red)
	//$Sprite FBXRE0
	//$Category Monitors
	//$Flags4Text Random (Strong)
	//$Flags8Text Random (Weak)
	doomednum = 464,
	spawnstate = S_FDBOX_REDRING_IDLE1,
	spawnhealth = 1,
	painstate = S_FDBOX_REDRING_IDLE1,
	deathstate = S_FDBOX_EXPLOSION1,
	deathsound = sfx_pop,
	speed = 1,
	radius = 16*FRACUNIT,
	height = 32*FRACUNIT,
	damage = MT_FDBOX_RING_ICON,
	flags = MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE
}

states[S_FDBOX_REDRING_IDLE1] =	{SPR_FBXR,	E,	2,	nil,	0,	0,	S_FDBOX_REDRING_IDLE2}
states[S_FDBOX_REDRING_IDLE2] =	{SPR_FBXR,	F,	1,	nil,	0,	0,	S_FDBOX_REDRING_IDLE1}

// Final Demo Blue Ring Monitor

/*
addHook("MobjSpawn", function(mobj, mthing)
	if (gametype == GT_CTF)
		P_AddToNumMapRings(mobj, 10)
	end
end, MT_FDBOX_BLUERING)
*/

addHook("MobjFuse", function(mobj)
	if not (mobj and mobj.valid) then return end
	
	P_FDMonitorFuseThink(mobj)
	return true
end, MT_FDBOX_BLUERING)

addHook("MapThingSpawn", function(mobj, mthing)
	if not (mobj and mobj.valid
	and mthing and mthing.valid) then
		return
	end
	
	P_FDMonitorTypeSpawn(mobj, mthing)
	
	if mobj and mobj.valid then
		if (mobj.type == MT_FDBOX_BLUERING) then
			if ultimatemode and not G_IsSpecialStage(gamemap) then
				P_RemoveMobj(mobj)
				return
			end
			
			P_AddToNumMapRings(mobj, 10)
			CTFRingSpawn(mobj, mthing)
		end
	end
end, MT_FDBOX_BLUERING)

// Prevents a player on the red team from destroying a blue ring monitor
addHook("ShouldDamage", function(target, inflictor, source, damage, damagetype)
	if not (source and source.valid
	and source.player and source.player.valid) then
		return
	end
	
	if source.player.ctfteam ~= 2 then
		return false
	end
end, MT_FDBOX_BLUERING)

mobjinfo[MT_FDBOX_BLUERING] = {
	//$Name 2.0 CTF Team Ring Monitor (Blue)
	//$Sprite FBXRG0
	//$Category Monitors
	//$Flags4Text Random (Strong)
	//$Flags8Text Random (Weak)
	doomednum = 465,
	spawnstate = S_FDBOX_BLUERING_IDLE1,
	spawnhealth = 1,
	painstate = S_FDBOX_BLUERING_IDLE1,
	deathstate = S_FDBOX_EXPLOSION1,
	deathsound = sfx_pop,
	speed = 1,
	radius = 16*FRACUNIT,
	height = 32*FRACUNIT,
	damage = MT_FDBOX_RING_ICON,
	flags = MF_SOLID|MF_SHOOTABLE|MF_MONITOR|MF_GRENADEBOUNCE
}

states[S_FDBOX_BLUERING_IDLE1] =	{SPR_FBXR,	G,	2,	nil,	0,	0,	S_FDBOX_BLUERING_IDLE2}
states[S_FDBOX_BLUERING_IDLE2] =	{SPR_FBXR,	H,	1,	nil,	0,	0,	S_FDBOX_BLUERING_IDLE1}
