--Score overhaul
local enemycount = 0
local enemydestroyed = 0
local ringcount = 0
local ringcollect = 0

--Constants for emblems

local WOODS_EMBLEM = 10
local WOODS_TIME_EMBLEM = 11
local WOODS_SCORE_EMBLEM = 12
local BEACH_EMBLEM = 13
local BEACH_TIME_EMBLEM = 14
local BEACH_SCORE_EMBLEM = 15
local MAX_RINGS_EMBLEM = 18
local ALL_ENEMIES_EMBLEM = 19

--resetting the ring and enemy counters here is a very band-aid fix but at least it works.
--(Remember to never spawn any rings while in mid-level)
local function doRingValue(val)
	ringcollect = 0
	enemydestroyed = 0
	return val
end

--Award points for vanilla rings and monitors, invincibility doubles points

addHook("MobjDeath", function(mobj, inflictor, player)
	if not mapheaderinfo[gamemap].scorehaullua then return end
	if player == nil then return end
	if player.player == nil then return end
	local scorebonustoadd = 0
	if mobj.type == MT_RING
		scorebonustoadd = 10
	elseif mobj.type == MT_RING_BOX
		scorebonustoadd = 100
	elseif mobj.type >= MT_PITY_BOX
	and mobj.type <= MT_1UP_BOX
	or mobj.type >= MT_FLAMEAURA_BOX
	and mobj.type <= MT_THUNDERCOIN_BOX
	or mobj.type == MT_SOUTHDIST_RINGBOX20
		scorebonustoadd = 200
	elseif mobj.type == MT_YELLOW_LUM
		scorebonustoadd = 100
	elseif mobj.type == MT_SOUTHDIST_RINGBOX5
		scorebonustoadd = 50
	elseif mobj.type == MT_EMERHUNT
		scorebonustoadd = 1000
	end
	if player.player.powers[pw_invulnerability] > 0
		scorebonustoadd = $ * 2
	end
	P_AddPlayerScore(player.player, scorebonustoadd)
end)

--Award time bonus and emblems

addHook("PlayerThink", function(player)
	if not mapheaderinfo[gamemap].scorehaullua then return end
	
	local ZeroError = 0
	if not(mapheaderinfo[gamemap].sherror == nil)
		ZeroError = mapheaderinfo[gamemap].sherror
	end
	
	if (player.drawtimebonus == nil)
		player.drawtimebonus = player.timebonus
	end
	if (player.pflags & PF_FINISHED != 0 or player.exiting > 0)
		for thing in mapthings.iterate
			if modifiedgame then return end
			if thing.type == mobjinfo[MT_EMBLEM].doomednum
				if thing.angle == WOODS_EMBLEM
				and player.mo.x/FRACUNIT < 10000
				and multiplayer == false
					P_TeleportMove(thing.mobj, player.mo.x, player.mo.y, player.mo.z)
				end
				if thing.angle == WOODS_TIME_EMBLEM
				and player.mo.x/FRACUNIT < 10000
				and leveltime <= tonumber(mapheaderinfo[gamemap].woodstime)*TICRATE
				and multiplayer == false
					P_TeleportMove(thing.mobj, player.mo.x, player.mo.y, player.mo.z)
				end
				if thing.angle == WOODS_SCORE_EMBLEM
				and player.mo.x/FRACUNIT < 10000
				and player.score <= ZeroError
				and modeattacking == true
					P_TeleportMove(thing.mobj, player.mo.x, player.mo.y, player.mo.z)
				end
				if thing.angle == BEACH_EMBLEM
				and player.mo.x/FRACUNIT > 20000
				and multiplayer == false
					P_TeleportMove(thing.mobj, player.mo.x, player.mo.y, player.mo.z)
				end
				if thing.angle == BEACH_TIME_EMBLEM
				and player.mo.x/FRACUNIT > 20000
				and leveltime <= tonumber(mapheaderinfo[gamemap].beachtime)*TICRATE
				and multiplayer == false
					P_TeleportMove(thing.mobj, player.mo.x, player.mo.y, player.mo.z)
				end
				if thing.angle == BEACH_SCORE_EMBLEM
				and player.mo.x/FRACUNIT > 20000
				and player.score <= ZeroError
				and modeattacking == true
					P_TeleportMove(thing.mobj, player.mo.x, player.mo.y, player.mo.z)
				end
			end
		end
		
		player.score = $ + player.timebonus
		player.timebonus = 0
	else
		player.timebonus = min(max((mapheaderinfo[gamemap].shtimebase +(60*mapheaderinfo[gamemap].shtimepenalty))-player.realtime/TICRATE*mapheaderinfo[gamemap].shtimepenalty,0), mapheaderinfo[gamemap].shtimebase)
		player.drawtimebonus = player.timebonus
		player.basescore = player.score
	end
	if P_IsObjectOnGround(player.mo)
		player.scoreadd = 0
	end
	
	if modifiedgame then return end
	
	for thing in mapthings.iterate
		if thing.type == mobjinfo[MT_EMBLEM].doomednum
			if thing.angle == MAX_RINGS_EMBLEM
				if ringcollect >= ringcount
					if multiplayer == false
						if ringcount > 0
							P_TeleportMove(thing.mobj, player.mo.x, player.mo.y, player.mo.z)
						end
					end
				end
			end
			if thing.angle == ALL_ENEMIES_EMBLEM
			and enemydestroyed >= enemycount
			and multiplayer == false
			and enemycount > 0
				P_TeleportMove(thing.mobj, player.mo.x, player.mo.y, player.mo.z)
			end
		end
	end
end)

--Draw score bonus

hud.add(function(v,player)
	if not mapheaderinfo[gamemap].scorehaullua then return end
	if (player.pflags & PF_FINISHED == 0 and player.exiting <= 0) then return end
	v.draw(215,50,v.cachePatch("YB_SCORE"),V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_PERPLAYER)
	v.drawNum(200,70,player.basescore,V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_PERPLAYER)
	v.draw(215,90,v.cachePatch("YB_TIME"),V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_PERPLAYER)
	v.drawNum(200,110,player.drawtimebonus,V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_PERPLAYER)
	v.draw(235,130,v.cachePatch("YB_TOTAL"),V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_PERPLAYER)
	v.drawNum(200,150,player.score,V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_PERPLAYER)
end)

--Draw enemy and ring count

hud.add(function(v,player)
	if not mapheaderinfo[gamemap].scorehaullua then return end
	v.draw(166,180,v.cachePatch("STTRINGS"),V_SNAPTOLEFT|V_SNAPTOTOP|V_PERPLAYER)
	v.drawNum(250,180,ringcollect,V_SNAPTOLEFT|V_SNAPTOTOP|V_PERPLAYER)
	v.drawNum(300,180,ringcount,V_SNAPTOLEFT|V_SNAPTOTOP|V_PERPLAYER)
	v.draw(166,160,v.cachePatch("SH_ROBOT"),V_SNAPTOLEFT|V_SNAPTOTOP|V_PERPLAYER)
	v.drawNum(250,160,enemydestroyed,V_SNAPTOLEFT|V_SNAPTOTOP|V_PERPLAYER)
	v.drawNum(300,160,enemycount,V_SNAPTOLEFT|V_SNAPTOTOP|V_PERPLAYER)
end,"scores")

--Enemy scores, each enemy in combo adds 200 bonus points

addHook("MobjDeath", function(mobj, inflictor, player)
	if not mapheaderinfo[gamemap].scorehaullua then return end
	
	local scorebonustoadd = mobj.info.mass
	
	if mobj.ringvalue > 0
		ringcollect = $ + mobj.ringvalue
	end
	
	if mobj.type == MT_YELLOWSHELL
		P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_YELLOWSPRING)
		scorebonustoadd = 200
	elseif mobj.type == MT_SPRINGSHELL
		scorebonustoadd = 150
	elseif mobj.type == MT_BIGMINE
		scorebonustoadd = 300
	end
	
	if (mobj.flags & MF_ENEMY)
		enemydestroyed = $ + 1
		if player != nil and player.player != nil
			if player.player.powers[pw_invulnerability] > 0
				scorebonustoadd = $ * 2
			end
			P_AddPlayerScore(player.player, player.player.scoreadd * 200 + scorebonustoadd)
			player.player.scoreadd = $ + 1
		else
			for player in players.iterate
				P_AddPlayerScore(player, scorebonustoadd)
			end
		end
		mobj.state = mobj.info.deathstate
		return true
	end
	return false
end)

--count the rings and enemies in the level

addHook("MapLoad", function(mapnum)
	if not mapheaderinfo[gamemap].scorehaullua then return end
	ringcount = 0
	enemycount = 0
	ringcollect = 0
	enemydestroyed = 0
	for thing in mapthings.iterate
		if thing.mobj != nil
			if thing.mobj.ringvalue >= 0
				ringcount = $ + thing.mobj.ringvalue
			end
			if (thing.mobj.flags & MF_ENEMY)
				enemycount = $ + 1
			end
		end
	end
end)

--make collected emblems invisible

addHook("MobjThinker", function(mobj)
	if not mapheaderinfo[gamemap].scorehaullua then return end
	if (mobj.frame & FF_TRANS50 and mobj.angle > 9)
		mobj.state = S_INVISIBLE
	end
end, MT_EMBLEM)

--ring values for the counter

addHook("MobjSpawn", function(mobj)
	if not mapheaderinfo[gamemap].scorehaullua then return end
	if mobj.type == MT_RING
		mobj.ringvalue = doRingValue(1)
	elseif mobj.type == MT_SOUTHDIST_RINGBOX5
		mobj.ringvalue = doRingValue(5)
	elseif mobj.type == MT_RING_BOX
		mobj.ringvalue = doRingValue(10)
	elseif mobj.type == MT_SOUTHDIST_RINGBOX20
		mobj.ringvalue = doRingValue(20)
	else
		mobj.ringvalue = 0
	end
end)