//TY Alfredo!
//TY Dirk!

//Fireball sounds
sfxinfo[freeslot("sfx_mrfire")].caption = "Flame"
sfxinfo[freeslot("sfx_mriceb")].caption = "Iceball"
sfxinfo[freeslot("sfx_mricbr")].caption = "Shattering"
sfxinfo[freeslot("sfx_mrfrze")].caption = "Freezing"
sfxinfo[freeslot("sfx_mrslip")].caption = "Sliding"
sfxinfo[freeslot("sfx_mrshtr")].caption = "Shattering"

//
//

rawset(_G, "MARIO_DESPAWNTIME", TICRATE*16) // How long the powerup lasts for

//
//The Lua for Mario's Powerup Abilities
//

states[freeslot("S_MARIO_FIREEXPLODE")] = {SPR_BOM2, FF_FULLBRIGHT|FF_ANIMATE, 7, nil, 6, 1, S_NULL}
mobjinfo[freeslot("MT_KAMEK_FIREBALL")] = {
	spawnstate = S_SMALLFIREBAR1,
	spawnhealth = 1000,
	reactiontime = 8,
	//deathsound = sfx_mario1,
	deathstate = S_MARIO_FIREEXPLODE,
	speed = 24*FRACUNIT,
	radius = 24*FRACUNIT,
	height = 48*FRACUNIT,
	mass = DMG_FIRE,
	damage = 1,
	flags = MF_MISSILE|MF_NOCLIP|MF_GRENADEBOUNCE|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_PUSHABLE,
}

local MAXGRAVITY = 32
local GRAVITYFACTOR = MAXGRAVITY/3

rawset(_G, "MARIO_FIRECOLOR", SKINCOLOR_FLAME)
rawset(_G, "MARIO_ICEFIRECOLOR", SKINCOLOR_ICY)
rawset(_G, "MARIO_MAGICFIRECOLOR", SKINCOLOR_MAGENTA)
rawset(_G, "MARIO_YELLOWFIRECOLOR", SKINCOLOR_YELLOW)
rawset(_G, "MARIO_BLUEFIRECOLOR", SKINCOLOR_CERULEAN)
rawset(_G, "MARIO_GREENFIRECOLOR", SKINCOLOR_EMERALD)

//Set up the fireball type (I edited this a bit)
local function MarioFireballSpawn(mobj, after)
	mobj.hit_sound = sfx_mario2
	if (globalweather == 2 or globallevelskynum == 55)
		mobj.color = MARIO_ICEFIRECOLOR
		mobj.colorized = true
		mobj.hit_sound = sfx_mrfrze
		mobj.name = "iceball"
	elseif (globalweather == 3
	or globalweather == 4
	or globallevelskynum == 8
	or globallevelskynum == 132)
		mobj.color = MARIO_BLUEFIRECOLOR
		mobj.colorized = true
		mobj.name = "bluefireball"
	elseif (globalweather == 1
	or globalweather == 5
	or globalweather == 6
	or globallevelskynum == 64
	or globallevelskynum == 103)
		mobj.color = MARIO_YELLOWFIRECOLOR
		mobj.colorized = true
		mobj.name = "yellowfireball"
	elseif globallevelskynum == 1
	or globallevelskynum == 13
	or globallevelskynum == 14
	or globallevelskynum == 31
	or globallevelskynum == 159
		mobj.color = MARIO_FIRECOLOR
		mobj.name = "fireball"
	elseif globallevelskynum == 33
	or globallevelskynum == 34
	or globallevelskynum == 172
	or globallevelskynum == 1025
	or globallevelskynum == 1028
		mobj.color = MARIO_GREENFIRECOLOR
		mobj.colorized = true
		mobj.name = "greenfireball"
	else
		mobj.color = MARIO_MAGICFIRECOLOR
		mobj.colorized = true
		mobj.name = "magicfireball"
	end
	
	mobj.cantouchteam = false
	mobj.blockable = 1
	mobj.block_stun = 6
	mobj.block_sound = sfx_mario1
	mobj.block_hthrust = 7
	mobj.block_vthrust = 5
	mobj.spawnfire = true
	
	mobj.info.raisestate = 0
end
addHook("MobjSpawn", MarioFireballSpawn, MT_KAMEK_FIREBALL)

//Fireball Thinker
local function MarioFireballThinker(mobj)
	local mobjgravity = -gravity * P_MobjFlip(mobj)
	if mobj.target and mobj.target.valid then mobjgravity = FixedMul($, mobj.target.scale) end
	if mobj.color == MARIO_BALLFIRECOLOR then mobjgravity = $/2 end
	local dumbgravity = mobjgravity * MAXGRAVITY
	
	//Fake MobjSpawn hook for after the object has been spawned
	if not mobj.threshold
		if mobj.target and mobj.target.valid
			P_TryMove(mobj, mobj.x + mobj.target.momx,
			mobj.y + mobj.target.momy, true)
			if P_MobjFlip(mobj.target) == -1 and P_MobjFlip(mobj) != -1
				mobj.flags2 = $ | MF2_OBJECTFLIP
				mobjgravity = -$
				dumbgravity = -$
			end
		end
		
		mobj.scalespeed = mobj.scale/6
		P_SetScale(mobj, mobj.scale/2)
		
		mobj.momz = mobjgravity * MAXGRAVITY
		mobj.z = $ + mobj.height/2*P_MobjFlip(mobj)
		
		//Fun little hack for water splashing
		mobj.flags = $ &~ MF_PUSHABLE
		if not mobj.fuse then mobj.fuse = TICRATE*8 end
		
		if mobj.color != MARIO_BALLFIRECOLOR
			mobj.renderflags = $ | RF_FULLBRIGHT | RF_NOCOLORMAPS
			mobj.blendmode = AST_ADD
		end
		
		//Different properties
		if mobj.color == MARIO_BALLFIRECOLOR //Super ball
			mobj.flags = $ | MF_BOUNCE
			mobj.destscale = $*3/2
		end
		
		mobj.flags = $ &~ MF_NOCLIP
		mobj.threshold = 1
	end
		
	//You're dead! Don't go any further
	if not mobj.health or not (mobj.flags & MF_MISSILE)
		mobj.momx = 0
		mobj.momy = 0
		mobj.momz = 0
		
		mobj.destscale = mobj.scale
		mobj.spritexscale = FRACUNIT*3/2
		mobj.spriteyscale = FRACUNIT*3/2
		
		//First time stuff
		if mobj.threshold != 69 then mobj.threshold = 69 else return end
		
		if mobj.color == MARIO_ICEFIRECOLOR
			S_StartSound(mobj, sfx_mricbr)
		else
			S_StartSound(mobj, sfx_mrfire)
		end
		
		return
	end
	
	//Horizontal Movement
	mobj.friction = FRACUNIT
	if mobj.target and mobj.target.valid
		local angle = mobj.angle
		if mobj.color == MARIO_BALLFIRECOLOR and mobj.momx and mobj.momy
			angle = R_PointToAngle2(0,0, mobj.momx, mobj.momy)
			mobj.angle = angle - ANGLE_180
		end
		
		P_InstaThrust(mobj, angle, FixedMul(mobj.info.speed, mobj.target.scale))
	end
	
	//Vertical Movement
	//Floor bounce
	if P_IsObjectOnGround(mobj)
	or (mobj.eflags & MFE_JUSTHITFLOOR and mobj.eflags & MFE_ONGROUND)
		mobj.momz = -dumbgravity
		
	//Gravity
	elseif mobj.color != MARIO_BALLFIRECOLOR
		dumbgravity = abs($)
		mobj.momz = min(max($ + mobjgravity * GRAVITYFACTOR, -dumbgravity), dumbgravity)
		
	//Super ball hit ceiling or floor
	elseif mobj.z + mobj.height >= mobj.ceilingz
		mobj.momz = dumbgravity
	elseif mobj.z <= mobj.floorz
		mobj.momz = -dumbgravity
	end
	
	//Ghost trail
	if mobj.threshold <= 1
		mobj.threshold = 2
	else
		local ghost = P_SpawnGhostMobj(mobj)
		ghost.blendmode = mobj.blendmode
		ghost.scalespeed = ghost.scale/12
		ghost.renderflags = mobj.renderflags
		ghost.destscale = 1
	end
end
addHook("MobjThinker", MarioFireballThinker, MT_KAMEK_FIREBALL)

//No monitors!
addHook("ShouldDamage", function(monitor, mobj)
	if monitor and monitor.valid and monitor.flags & MF_MONITOR
	and mobj and mobj.valid and mobj.type == MT_KAMEK_FIREBALL
	and globalweather == 2
		return false
	end
end)

//Collect coins
addHook("MobjMoveCollide", function(mo, mobj)
	if mo.color == MARIO_BALLFIRECOLOR and mo.flags & MF_MISSILE
	and mo.target and mo.target.valid and mo.target.player
	and mobj.health and mobj.flags & (MF_SPECIAL|MF_SPRING)
	and not (mobj.mariomonitorcoin and mobj.fuse > MARIO_DESPAWNTIME - TICRATE)
	and (mobj.type == MT_COIN or mobj.type == MT_FLINGCOIN
	or mobj.type == MT_RING or mobj.type == MT_FLINGRING)
	and mobj.z - mobj.scale <= mo.z + mo.height
	and mobj.z + mobj.height + mobj.scale >= mo.z
		if mobj.info.deathsound == sfx_rnglft
		or mobj.info.deathsound == sfx_rngrgh
			mobj.info.deathsound = sfx_itemup
		end
		if mo.target.player == displayplayer or mo.target.player == secondarydisplayplayer
			S_StartSound(mo.target, mobj.info.deathsound)
		else
			S_StartSound(mobj, mobj.info.deathsound)
		end
		A_ForceStop(mobj)
		P_KillMobj(mobj)
		P_GivePlayerRings(mo.target.player, 1)
	end
end, MT_KAMEK_FIREBALL)

//Replace SRB2's original fireballs
mobjinfo[MT_FIREBALL].flags = $ | MF_NOCLIP
addHook("MobjSpawn", function(mobj)
	mobj.type = MT_KAMEK_FIREBALL
	mobj.state = mobj.info.spawnstate
	mobj.flags = mobj.info.flags
	mobj.scale = $
	
	mobj.info.raisestate = 0
	mobj.threshold = 0
	MarioFireballSpawn(mobj)
end, MT_FIREBALL)