-- BOSS PLUS VERSION 1
-- Source Values for your bosses
local bossplus_currenthealth = 0
local bossplus_currentwaterlevel = 0
local bossplus_mode = false
local boss5players = {}

-- Functions for helping
local function bossplus_changeringslinger(object,currentammo,targetammo,newammo,currenttime,targettime)
	if currentammo == targetammo and currenttime >= targettime then
		object.boss5timetochange = -TICRATE*6
		object.boss5slingtype = newammo
		object.boss5firerate = -TICRATE*6
		S_StartSound(nil,sfx_cdfm15)
	end
end
local function bossplus_fireringslinger(object,currentammo,targetammo,currenttime,targettime,type)
	if currentammo == targetammo and currenttime >= targettime and object.health > 0 then
		object.boss5firerate = 0
		boss5players = {}
		for player in players.iterate() do
			if player.playerstate == PST_LIVE and player.lives > 0 and player.spectator == false then
				table.insert(boss5players,player.mo)
			end
		end
		if #boss5players > 0 then
			local bossplus_shot = P_SpawnMissile(object,boss5players[P_RandomRange(1,#boss5players)],type)
			if bossplus_shot ~= nil then
				bossplus_shot.target = object
				bossplus_shot.colorized = true
				if ultimatemode == true then
					bossplus_shot.color = SKINCOLOR_YELLOW
					bossplus_shot.fuse = TICRATE*7
				else
					bossplus_shot.color = SKINCOLOR_BLACK
					bossplus_shot.fuse = TICRATE*3
				end
				if bossplus_shot.type == MT_THROWNBOUNCE and ultimatemode == false then
					bossplus_shot.momx = $1/2
					bossplus_shot.momy = $1/2
					bossplus_shot.momz = $1/2
				end
			end
		end
	end
end

-- Tics globaly to change metal sonics color
local bossplus_supermetalsoniccolor = SKINCOLOR_SUPERGOLD1
local bossplus_supermetalsonictic = 0
addHook("ThinkFrame", function()
	if bossplus_supermetalsonictic < 26 then
		bossplus_supermetalsonictic = $1 + 1
	else
		bossplus_supermetalsonictic = -2
	end
	if bossplus_supermetalsonictic == 26 then
		bossplus_supermetalsoniccolor = SKINCOLOR_SUPERGOLD1
	elseif bossplus_supermetalsonictic == 3 or bossplus_supermetalsonictic == 23 then
		bossplus_supermetalsoniccolor = SKINCOLOR_SUPERGOLD2
	elseif bossplus_supermetalsonictic == 6 or bossplus_supermetalsonictic == 20 then
		bossplus_supermetalsoniccolor = SKINCOLOR_SUPERGOLD3
	elseif bossplus_supermetalsonictic == 9 or bossplus_supermetalsonictic == 17 then
		bossplus_supermetalsoniccolor = SKINCOLOR_SUPERGOLD4
	elseif bossplus_supermetalsonictic == 13 then
		bossplus_supermetalsoniccolor = SKINCOLOR_SUPERGOLD5
	end
end)

-- Players get all 7 Chaos Emeralds
local function bossplus_getallemeralds()
	for player in players.iterate
		if player.playerstate == PST_LIVE and player.lives > 0 and player.spectator == false and All7Emeralds(emeralds) == false then
			P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_EMERALD1)
			P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_EMERALD2)
			P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_EMERALD3)
			P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_EMERALD4)
			P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_EMERALD5)
			P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_EMERALD6)
			P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_EMERALD7)
		end
	end
end
-- Give Ring Overtime
local function bossplus_givesrings()
	for player in players.iterate
		if player.powers[pw_super] <= 0 and player.playerstate == PST_LIVE and player.lives > 0 and player.spectator == false then
			P_GivePlayerRings(player,10)
			S_StartSound(nil,sfx_s3k33,player)
		end
	end
end

-- MT_EGGMOBILE
addHook("BossThinker", function(mobj)
	-- Rotate Left
	if mobj.sprite == SPR_EGGM and mobj.frame >= 5 and mobj.frame <= 7 then
		mobj.angle = $1 + ANG30
	end
	-- Rotate Right
	if mobj.sprite == SPR_EGGM and mobj.frame >= 13 and mobj.frame <= 15 then
		mobj.angle = $1 - ANG30
	end
	-- Drop Bombs on Low Health
	if mobj.health <= 3 then
		if mobj.sprite == SPR_EGGM then
			if mobj.boss1dropbomb == nil then
				mobj.boss1dropbomb = 0
			end
			if mobj.boss1dropbomb == 1 and mobj.tics == 4 then
				mobj.boss1dropbomb = 0
			end
			if mobj.frame == 7 or mobj.frame == 15 then
				if mobj.boss1dropbomb == 0 then
					mobj.boss1dropbomb = 1
					local boss1bomb = P_SpawnMobjFromMobj(mobj,0,0,-FRACUNIT*8,MT_CYBRAKDEMON_NAPALM_BOMB_LARGE)
					boss1bomb.colorized = true
					boss1bomb.color = SKINCOLOR_RED
					boss1bomb.target = mobj
					boss1bomb.momx = FRACUNIT*(P_RandomRange(-4,4)*4)
					boss1bomb.momy = FRACUNIT*(P_RandomRange(-4,4)*4)
					boss1bomb.momz = -FRACUNIT*8
				end
			end
		end
	end
end, MT_EGGMOBILE)


-- MT_EGGMOBILE2
addHook("BossThinker",function(mobj)
	-- Eggman uses a SHOCKWAVE Attack on Low Health
	if mobj.health <= 3 and mobj.health > 0 then
		if mobj.boss2electrictime == nil then
			mobj.boss2electrictime = 0
		end
		mobj.boss2electrictime = $1+1
		-- Freeze Midair Overtime
		if mobj.boss2electrictime >= TICRATE then
			mobj.momx = 0
			mobj.momy = 0
			mobj.momz = 0
		end
		-- Shockwave Attack
		if mobj.boss2electrictime == TICRATE+5 or mobj.boss2electrictime == TICRATE+10 then
			for player in players.iterate() do
				if P_RandomChance(FRACUNIT/4) == true or netgame == false then
					local boss2shockwave = P_SpawnMissile(mobj,player.mo,MT_SHOCKWAVE)
					if ultimatemode == false then
						boss2shockwave.momx = $1/2
						boss2shockwave.momy = $1/2
						boss2shockwave.momz = $1/2
					end
					boss2shockwave.colorized = true
					boss2shockwave.color = SKINCOLOR_SUPERSKY3
					boss2shockwave.target = mobj
				end
			end
		end
		-- Return to Normal
		if mobj.boss2electrictime >= TICRATE*2 then
			mobj.boss2electrictime = -TICRATE*2
			mobj.momz = -FRACUNIT*8
		end
	end
end,MT_EGGMOBILE2)
-- 25% Chance to drop a Big Green GOOP or a Red GOOP
addHook("MobjSpawn",function(mobj)
	if bossplus_mode == true then
		if P_RandomChance(FRACUNIT/4) == true and bossplus_currenthealth > 3 then
			mobj.scale = FRACUNIT*2
			mobj.colorized = true
			mobj.color = SKINCOLOR_EMERALD
			mobj.goopspecial = 1
		elseif P_RandomChance(FRACUNIT/4) == true or bossplus_currenthealth <= 3 then
			mobj.colorized = true
			mobj.color = SKINCOLOR_RED
			mobj.goopspecial = 2
			S_StartSound(mobj,sfx_s3ka4)
		else
			mobj.goopspecial = 0
		end
	end
end,MT_GOOP)
-- Goop Special
addHook("MobjThinker",function(mobj)
	if bossplus_mode == true then
		-- Big Green Goop
		if mobj.goopspecial == 1 then
			mobj.scale = $1+(FRACUNIT/100)
		end
		-- Red Goop
		if mobj.goopspecial == 2 then
			if mobj.fuse == TICRATE/2 and bossplus_currenthealth > 0 then
				mobj.color = SKINCOLOR_SUPERSILVER1
				S_StartSound(mobj,sfx_s3k86)
			end
			if mobj.fuse == 1 and bossplus_currenthealth > 0 then
				local boss2explode = P_SpawnMobjFromMobj(mobj,0,0,0,MT_FBOMB)
				boss2explode.target = mobj.target
				boss2explode.health = 0
			end
		end
	end
end,MT_GOOP)

-- MT_EGGMOBILE3
addHook("BossThinker",function(mobj)
	if mobj.boss3waterheight == nil then
		mobj.boss3waterheight = 0
	end
	if leveltime == 1 then
		for line in lines.iterate do
			if line.special >= 120 and line.special <= 123 then
				bossplus_currentwaterlevel = line.frontsector.ceilingheight
			end
		end
	end
	-- Raise the water level after 1 Second and lowers after defeat
	if leveltime >= TICRATE then
		for line in lines.iterate do
			if line.special >= 120 and line.special <= 123 then
				line.frontsector.ceilingheight = bossplus_currentwaterlevel+(mobj.boss3waterheight*FRACUNIT)
			end
		end
		if mobj.health > 0 and mobj.boss3waterheight < 256 then
			mobj.boss3waterheight = $1+8
		elseif mobj.health == 0 and mobj.boss3waterheight > -32 then
			mobj.boss3waterheight = $1-16
		end
	end
end,MT_EGGMOBILE3)
-- If your boss get damaged, the bubbles spawn
addHook("MobjDamage",function(target,inflictor,source,damage,damagetype)
	P_SpawnMobjFromMobj(target,0,0,-FRACUNIT*8,MT_EXTRALARGEBUBBLE)
end,MT_EGGMOBILE3)

-- MT_EGGMOBILE4
addHook("BossThinker",function(mobj)
	-- CHANGE BOSS HP FROM 8 TO 12
	if mobj.refillhealth == nil then
		mobj.refillhealth = 0
	end
	if mobj.health <= 4 and mobj.refillhealth < 2 then
		mobj.health = 5
		mobj.refillhealth = $1+1
	elseif mobj.health <= 1 and mobj.refillhealth < 4 then
		mobj.health = 2
		mobj.refillhealth = $1+1
	end
end,MT_EGGMOBILE4)
-- Mace can transform into fireballs
addHook("MobjThinker",function(mobj)
	mobj.sprite = SPR_BFBR
	mobj.frame = FF_FULLBRIGHT|A
	-- Make the fireballs taller so they can't jump over as sonic, metal sonic, and amy
	if mobj.fireobject == nil and bossplus_currenthealth > 3 and leveltime > 0 then
		mobj.fireobject = P_SpawnMobjFromMobj(mobj,0,0,FRACUNIT*64,MT_FLAME)
	end
	if mobj.fireobject ~= nil and bossplus_currenthealth > 3 then
		P_TeleportMove(mobj.fireobject,mobj.x,mobj.y,mobj.z+(FRACUNIT*64))
		mobj.fireobject.scale = (FRACUNIT*3)+(FRACUNIT/2)
	end
	if mobj.fireobject ~= nil and bossplus_currenthealth <= 3 then
		P_RemoveMobj(mobj.fireobject)
		mobj.fireobject = nil
	end
end,MT_EGGMOBILE4_MACE)

-- MT_FANG
addHook("BossThinker", function(mobj)
	-- Become Dark Fang
	mobj.colorized = true
	mobj.color = SKINCOLOR_BLACK
	-- Fang can THROW RINGs from ringslinger modes
	if mobj.boss5slingtype == nil then
		mobj.boss5slingtype = 0
	end
	if mobj.boss5firerate == nil then
		mobj.boss5firerate = 0
	end
	if mobj.boss5timetochange == nil then
		mobj.boss5timetochange = 0
	end
	if leveltime >= TICRATE*6 and mobj.health > 0 then
		mobj.boss5firerate = $1+1
		mobj.boss5timetochange = $1+1
	end
	if leveltime == TICRATE*5 or mobj.boss5timetochange == -TICRATE then
		S_StartSound(nil,sfx_wepchg)
	end
	bossplus_changeringslinger(mobj,mobj.boss5slingtype,0,1,mobj.boss5timetochange,TICRATE*7)
	bossplus_fireringslinger(mobj,mobj.boss5slingtype,0,mobj.boss5firerate,TICRATE/2,MT_REDRING)
	bossplus_changeringslinger(mobj,mobj.boss5slingtype,1,2,mobj.boss5timetochange,TICRATE*5)
	bossplus_fireringslinger(mobj,mobj.boss5slingtype,1,mobj.boss5firerate,TICRATE-5,MT_THROWNBOUNCE)
	bossplus_changeringslinger(mobj,mobj.boss5slingtype,2,0,mobj.boss5timetochange,TICRATE*3)
	bossplus_fireringslinger(mobj,mobj.boss5slingtype,2,mobj.boss5firerate,6,MT_THROWNAUTOMATIC)
end,MT_FANG)

-- MT_METALSONIC_RACE
addHook("MobjThinker", function(mobj)
	-- Enable Super Sparkle Mode
	if mobj.msonicsparkletime == nil then
		mobj.msonicsparkletime = 0
	end
	-- Always a Super Form
	if mobj.colorized == true then
		mobj.color = SKINCOLOR_GOLD
	else
		mobj.color = bossplus_supermetalsoniccolor
		mobj.msonicsparkletime = $1 + 1
	end
	-- Super Sparkle Mode
	if mobj.msonicsparkletime >= 3 then
		mobj.msonicsparkletime = 0
		local boss7sparkle = P_SpawnMobjFromMobj(mobj,FRACUNIT*P_RandomRange(-16,16),FRACUNIT*P_RandomRange(-16,16),FRACUNIT*P_RandomRange(0,32),MT_BOXSPARKLE)
		boss7sparkle.colorized = true
		boss7sparkle.color = SKINCOLOR_GOLD
	end
	-- Can Drop Eggman Box Overtime
	if leveltime >= TICRATE*4 then
		if mobj.eggboxdroptime == nil then
			mobj.eggboxdroptime = 0
		end
		mobj.eggboxdroptime = $1 + 1
		if mobj.eggboxdroptime >= TICRATE*2
			mobj.eggboxdroptime = 0
			P_SpawnMobjFromMobj(mobj,0,0,0,MT_EGGMAN_BOX)
			S_StartSound(mobj,sfx_s3k7b)
		end
	end
end, MT_METALSONIC_RACE)

-- MT_METALSONIC_BATTLE
addHook("BossThinker", function(mobj)
	-- Enable Super Sparkle Mode
	if mobj.msonicsparkletime == nil then
		mobj.msonicsparkletime = 0
	end
	-- Always a Super Form
	if mobj.colorized == true then
		mobj.color = SKINCOLOR_GOLD
	else
		mobj.color = bossplus_supermetalsoniccolor
		mobj.msonicsparkletime = $1 + 1
	end
	-- Super Sparkle Mode
	if mobj.msonicsparkletime >= 3 then
		mobj.msonicsparkletime = 0
		local boss7sparkle = P_SpawnMobjFromMobj(mobj,FRACUNIT*P_RandomRange(-16,16),FRACUNIT*P_RandomRange(-16,16),FRACUNIT*P_RandomRange(0,32),MT_BOXSPARKLE)
		boss7sparkle.colorized = true
		boss7sparkle.color = SKINCOLOR_GOLD
	end
	-- Endless Shooting Energy Balls At Target with S_METALSONIC_SHOOT
	if mobj.state == S_METALSONIC_SHOOT or mobj.state == S_METALSONIC_DASH then
		for player in players.iterate() do
			if P_RandomChance(FRACUNIT/10) == true then
				local boss7energyball = P_SpawnMissile(mobj,player.mo,MT_ENERGYBALL)
				boss7energyball.scale = FRACUNIT/3
				boss7energyball.momx = $1/3
				boss7energyball.momy = $1/3
				boss7energyball.momz = $1/3
				boss7energyball.colorized = true
				boss7energyball.color = SKINCOLOR_SUPERRED3
				boss7energyball.target = mobj
				boss7energyball.fuse = TICRATE*3
			end
		end
	end
end, MT_METALSONIC_BATTLE)
-- Gives Chaos Emaralds on defeated
addHook("BossDeath",function()
	if All7Emeralds(emeralds) == true then
		print("Super Metal Sonic has been defeated.  But you already have all 7 Emeralds")
	else
		print("Super Metal Sonic has been defeated.  You got all 7 Emeralds")
	end
	bossplus_getallemeralds()
end,MT_METALSONIC_BATTLE)

-- MT_CYBRAKDEMON
addHook("BossThinker",function(mobj)
	-- Give Chaos Emaralds at the start
	if leveltime == 1 then
		bossplus_getallemeralds()
	end
	-- Give 10 Rings to all Players Every 10 Seconds
	if mobj.health > 0 then
		if mobj.getringovertime == nil then
			mobj.getringovertime = 0
		end
		mobj.getringovertime = $1+1
		if mobj.getringovertime >= TICRATE*10 then
			bossplus_givesrings()
			mobj.getringovertime = 0
		end
	end
	-- Become More Powerful
	mobj.colorized = true
	mobj.color = SKINCOLOR_CYAN
	mobj.scale = FRACUNIT*2
	if mobj.refillhealth == nil then
		mobj.refillhealth = 0
	end
	if mobj.health <= 1 and mobj.refillhealth < 8 then
		mobj.health = 2
		mobj.refillhealth = $1+1
	end
end,MT_CYBRAKDEMON)

-- When the map loads, Disable bossplus_mode
addHook("MapLoad",function()
	bossplus_mode = false
end)

-- ALL BOSSES
addHook("BossThinker", function(mobj)
	bossplus_currenthealth = mobj.health
	bossplus_mode = true
end)