--=============================MISCMATCH======================================
--MISC hooks related to the player are here. Usually Match and damage hooks.
--Also put Battlemod functions here since I don't want to clutter LUA_FUNCTIONS with that incompatible stuff.
--=============================================================================

//Spawn Silver Rings and other drops on hit!
local function pkufling(z, s)
	z.target = s
	z.fuse = 415
	z.flags2 = $|MF2_DONTRESPAWN
	z.flags = $|MF_BOUNCE & ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT)
		
	if (z.type == MT_SMSSILVERRING)
		z.color = SKINCOLOR_BONE
		z.scale = z.target.scale*2
		z.fuse = 280
	end
	z.angle = (P_RandomRange(1, 359))*ANG1
	P_InstaThrust(z, z.angle, 4*z.target.scale)
	P_SetObjectMomZ(z, 4*FRACUNIT)
end

//Recoil off enemies from tricks if you hit them! This needs to go BEFORE the transformation damage hook.
addHook("MobjDamage", function(s, i, so)
	if not s.player return end --
	local p = s.player
	
	if p.hypermysticsonic --What damage?
		if s.skin == "sms"
			return true --
		end
	end
	--Don't get killed by what you're holding
	if p.smspickup and p.smspickup.valid and (i == p.smspickup or so == p.smspickup)
		return true --
	end
	if p.footsweepanim and s.battlemodsms
		if i and i.player and (i.player.pflags & (PF_SPINNING|PF_JUMPED))
			p.footsweep01 = 0
			p.footsweep02 = 0
			p.footsweep03 = 0
			p.footsweepanim = false
			p.sweepanimrecovery = 0
			p.smsdivetimer = 0
			p.smsdivefloat = 0
			p.smsatomicdivefail = 0
			s.state = S_PLAY_ROLL
			p.pflags = $|PF_SPINNING
			return true --
		end
	end
	if so and so.player and so.skin == "sms"
		if (gametype == GT_COOP or (G_GametypeHasTeams() and so.player.ctfteam == p.ctfteam) )
			if i and (i.type == MT_SMSFIREBLAST)	
				P_GivePlayerRings(p, 1)
				if p.boostmeter ~= nil
					p.boostmeter = $+18
				end
				if i.valid and i.health
					P_SpawnMobj(i.x, i.y, i.z, MT_SPARK)
					i.gzmd = P_SpawnGhostMobj(i)
					i.gzmd.destscale = i.gzmd.scalespeed+1
					P_HomingAttack(i.gzmd, s)
					S_StartSound(s, sfx_itemup)
					S_StartSound(s, sfx_s1c0)
					i.state = S_NULL
				end
			end
			return true --
		elseif so.battlemodsms and i and (i.type == MT_SMSFIREBLAST) and not (i.mysticflame and i.fuse and (i.fuse < 297))
			if p.powers[pw_nocontrol] //You CAN hurt already stunned players
			
			else
				p.panim = PA_FALL
				s.state = S_PLAY_FALL
				p.pflags = $&~(PF_GLIDING|PF_JUMPED|PF_BOUNCING|PF_THOKKED|PF_SPINNING) s.sms_spintrickspeed = 30
				p.powers[pw_nocontrol] = (i.mysticflame) and 56 or 45
				p.powers[pw_flashing] = 2
				S_StartSound(s, sfx_kc4d)
				s.flags2 = $|MF2_DONTDRAW
				s.recoilangle = i.angle
				s.recoilthrust = 48*FRACUNIT //Regular flames only stun players for balance reasons
				if i and i.valid and i.health
					P_ExplodeMissile(i)
				end
				return true --
			end
		end
	end

	if s.skin != "sms" return end --Be SMS from here on out.
	
	//If you've got a good dive going, don't let enemies stop your fun.
	if (p.smsdivetimer and (p.smsdivetimer > 9))
		if i and (i.flags & (MF_ENEMY|MF_BOSS))
			return true --
		end
	end
	--Crash with superarmor off some things that WOULD've hurt you!
	if (p.footsweepanim or ((s.state == S_SMS_AIRBOOST) and p.sms_didairboost > 1))
		if i 
			if SMS_ArmoredCrash(s, p, i) return true end --
		elseif SMS_ArmoredCrash(s, p, so)
			return true --
		end
	elseif i
		if (p.sms_boostlevel > 64 and p.speed > 44*s.scale)
		or (s.state == S_SMS_AIRBOOST)
		or ((p.cmd.buttons & BT_CUSTOM1 or p.sms_autoboosthold) and p.speed > 88*s.scale and p.panim == PA_RUN)	
			--Negate damage once if you hit stuff with an airboost.	
			--Fling with momentum off stuff you're crashing into!
			if (i.flags & MF_PAIN)
			or (i.flags & (MF_ENEMY|MF_BOSS))
			or (i.type == MT_DETON)
		
				if (so and so.player) --None of this from player-owned objects.
				or p.rings <= 0 and not p.powers[pw_shield] --You're about to die entirely at this rate.
					return
				end
				A_SMSquake(s, 65*FRACUNIT, 4, 1500)
				s.momx = $*2/3
				s.momy = $*2/3
				if (s.momz*P_MobjFlip(s) < 6*s.scale)
					P_SetObjectMomZ(s, 6*FRACUNIT)
				else
					P_SetObjectMomZ(s, 2*FRACUNIT, true)
				end
				if (i.type == MT_DETON)
					P_DamageMobj(i)	
				end
				if p.powers[pw_shield] --Recreate SRB2's damage behaviour ,but keep your speed.
					P_RemoveShield(p)
					S_StartSound(s, sfx_shldls)
				else
					P_PlayRinglossSound(s)
					if p.sms_transformstate == 1
						p.sms_transformstate = 2
						P_PlayerRingBurst(p, -1) 
						P_GivePlayerRings(p, p.rings/-2)
					else	
						P_PlayerRingBurst(p, -1)
						P_GivePlayerRings(p, p.rings*-1)
						if p.sms_transformstate == 2 or  p.sms_transformstate == 3
							s.state = S_PLAY_PAIN 
							p.panim = PA_PAIN
							A_SMSTOSONIC(s, true)
						end
					end
				end		
				s.SMS_CrashRoll = {timer = 27, extratime = false}			
				SMS_RagDoll(s)
				p.powers[pw_flashing] = max($,105)
				return true --
			end
		end
	end
/*	if (p.hometrickanim or  p.sms_stompanim)
	and not p.powers[pw_invulnerability]
		if (s.skin == "sms")
			if i and (i.flags & (MF_ENEMY|MF_BOSS))
				if p.hometrickanim
					s.state = S_PLAY_ROLL
				end
				p.pflags = $|PF_JUMPED
				p.hometrickanim = false
				return true	 --		
			end
		end
  	end */
 
  	if p.powers[pw_shield] //Don't drop stuff or detransform if you're shielded
		return
	end
	
//Drop weapons for players when hit!
	
	if G_RingSlingerGametype() and not s.battlemodsms
		local ghs
		if s.sms_ringweapons --We copied p.ringweapons earlier. Should we drop any?
			if (s.sms_ringweapons & RW_SCATTER)
				ghs = P_SpawnMobjFromMobj(s, 0,0, 33*s.scale, MT_SCATTERPICKUP)
				pkufling(ghs, s)
			end
			if (s.sms_ringweapons & RW_EXPLODE)
				ghs = P_SpawnMobjFromMobj(s, 0,0, 33*s.scale, MT_EXPLODEPICKUP)
				ghs.target = s
				pkufling(ghs, s)
			end
			if (s.sms_ringweapons & RW_GRENADE)
				ghs = P_SpawnMobjFromMobj(s, 0,0, 33*s.scale, MT_GRENADEPICKUP)
				pkufling(ghs, s)
			end
			if (s.sms_ringweapons & RW_AUTO)
				ghs = P_SpawnMobjFromMobj(s, 0,0, 33*s.scale, MT_AUTOPICKUP)
				pkufling(ghs, s)
			end
			if (s.sms_ringweapons & RW_RAIL)
				ghs = P_SpawnMobjFromMobj(s, 0,0, 33*s.scale, MT_RAILPICKUP)
				pkufling(ghs, s)
			end
			s.sms_ringweapons = 0
		end
		if s.sms_infinityring --Augh, you special little shit.
			ghs = P_SpawnMobjFromMobj(s, 0,0, 35*s.scale, MT_INFINITYRING)
			pkufling(ghs, s)
			s.sms_infinityring= nil
		end
		if (p.rings > 78) --Drop excess rings in the form of silver rings.
			ghs = P_SpawnMobjFromMobj(s, 0,0, 54*s.scale, MT_SMSSILVERRING)
			pkufling(ghs, s)
			if (p.rings > 158)
				ghs = P_SpawnMobjFromMobj(s, 0,0, 58*s.scale, MT_SMSSILVERRING)
				pkufling(ghs, s)
				if (p.rings > 238)
					ghs = P_SpawnMobjFromMobj(s, 0,0, 62*s.scale, MT_SMSSILVERRING)
					pkufling(ghs, s)
				end				
			end			
		end
	end
	
	//SMS can take 2 hits when manually transformed before detransforming, not counting shields.
	//The first hit he has an extra 50% defense, only losing half of his rings.
	//pw_bouncering, pw_railring, pw_automaticring, pw_explosionring, pw_scatterring, and pw_grenadering 
	
	if p.sms_transformstate
	   if (p.sms_transformstate == 1)
	   and i
	   and not ( (i.flags & MF_PAIN|MF_ENEMY|MF_BOSS) and ((p.sms_boostlevel > 64) or s.airboostimmune) )
		 
			if (p.rings > 49)
			
				P_DoPlayerPain(p)
				P_PlayerRingBurst(p, -1)
				P_PlayRinglossSound(s)
				p.sms_transformstate = 2
				P_GivePlayerRings(p, p.rings/-2)
				HMS_AuraStorm(s, nil, SKINCOLOR_RED)
				SMS_LightClash(s, SKINCOLOR_RED, s)	
				return true --
				
			elseif (p.rings == 1)
			
				S_StartSound(s, sfx_shldls)
				P_DoPlayerPain(p)
				P_PlayerRingBurst(p, 0)
				p.sms_transformstate = 2	
				HMS_AuraStorm(s, nil, SKINCOLOR_RED)
				SMS_LightClash(s, SKINCOLOR_RED, s)	
				return true --
				
			elseif (p.rings == 0) //Block a death blow!
				P_DoPlayerPain(p)
			--	S_StartSound(s, sfx_shldls)
			
				local ghs = P_SpawnGhostMobj(s)
				ghs.destscale = $*99
				ghs.blendmode = AST_ADD
				ghs.colorized = true
				ghs.fuse = 13 ghs.tics = 99
				
				P_FlashPal(p, PAL_MIXUP, 4)
			--	S_StartSound(target, sfx_s3k4e)
					if p.presmsskin
						R_SetPlayerSkin(p, p.presmsskin)
						s.skin = p.presmsskin					
					else
						R_SetPlayerSkin(p, "sonic")
						s.skin = "sonic"
					end
					if not s.battlemodsms
						P_NukeEnemies(s, s, 350*s.scale)
					else --Give score bonus and send SMS flying
						s.lastbmrings = p.rings
						if s.supersmsrecoil and i
							P_SetObjectMomZ(s, 10*FRACUNIT)				
							s.supersmsrecoil2ang = R_PointToAngle2(s.x, s.y, i.x, i.y)
							P_InstaThrust(s, s.supersmsrecoil2ang, -65*s.scale)
							s.supersmsrecoil2 = 17
							if so and so.player
								P_FlashPal(so.player, PAL_MIXUP, 4)
							end
						end
						if so and so.player and (so.skin != "sms")
							if s.supersmsrecoil
								so.player.score = $+50 //Slight score boost for hitting SMS!
								CONS_Printf(so.player, "\x82"+"Gained 50 score bonus for taking down SMS hard!")
							else
								so.player.score = $+25 //Slight score boost for hitting SMS!
								CONS_Printf(so.player, "\x82"+"Gained 25 score bonus for taking down SMS!")
							end
						end
					end
					if not (p.powers[pw_shield] & SH_FIREFLOWER)
					and not ((mariomode) and p.powers[pw_invulnerability])
						s.color = p.sms_originalcolor
					else
						s.color = SKINCOLOR_WHITE
					end
					p.skincolor = p.sms_originalcolor
					p.sms_transformstate = 0
					SMS_LightFlash(s, SKINCOLOR_RED)	
					SMS_LightningTrail(s, s)
					HMS_GigaJetBolt(s)
					SMS_AngledLightning(s, SKINCOLOR_RED, 23, 3-SMS_Graphix(s))
					P_PlayRinglossSound(s)
					S_StartSound(s, sfx_smscrt)
					S_StartSoundAtVolume(s, sfx_nerf, 120)
					S_StartSound(s, sfx_smscr2)		
					return true --
			else
				P_DoPlayerPain(p)
				P_PlayerRingBurst(p, p.rings/2)
				P_PlayRinglossSound(s)
				p.sms_transformstate = 2
				P_GivePlayerRings(p, p.rings/-2)
				return true --
			end
			
		elseif (p.sms_transformstate == 2) or (p.sms_transformstate == 3)
		
				local ghs = P_SpawnGhostMobj(s)
				ghs.destscale = $*99
				ghs.blendmode = AST_ADD
				ghs.colorized = true
				ghs.fuse = 13 ghs.tics = 99
				P_FlashPal(p, PAL_MIXUP, 4)
			--	S_StartSound(s, sfx_s3k4e)
				if p.presmsskin
					R_SetPlayerSkin(p, p.presmsskin)
					s.skin = p.presmsskin					
				else
					R_SetPlayerSkin(p, "sonic")
					s.skin = "sonic"
				end
				if not s.battlemodsms
					P_NukeEnemies(s, s, 350*s.scale)
				else --Give score bonus and send SMS flying
					s.lastbmrings = p.rings
					if s.supersmsrecoil and i
						P_SetObjectMomZ(s, 10*FRACUNIT)				
						s.supersmsrecoil2ang = R_PointToAngle2(s.x, s.y, i.x, i.y)
						P_InstaThrust(s, s.supersmsrecoil2ang, -65*s.scale)
						s.supersmsrecoil2 = 17
						S_StartSound(s, sfx_smscrt)
						S_StartSoundAtVolume(s, sfx_nerf, 110)
						S_StartSound(s, sfx_smscr2)
						if so and so.player
							P_FlashPal(so.player, PAL_MIXUP, 4)
						end
					end
					if so and so.player and (so.skin != "sms")
						if s.supersmsrecoil
							so.player.score = $+50 //Slight score boost for hitting SMS!
							CONS_Printf(so.player, "\x82"+"Gained 50 score bonus for taking down SMS hard!")
						else
							so.player.score = $+25 //Slight score boost for hitting SMS!
							CONS_Printf(so.player, "\x82"+"Gained 25 score bonus for taking down SMS!")
						end
					end
				end
				if not (p.powers[pw_shield] & SH_FIREFLOWER)
				and not ((mariomode) and p.powers[pw_invulnerability])
					s.color = p.sms_originalcolor
				else
					s.color = SKINCOLOR_WHITE
				end
				p.skincolor = p.sms_originalcolor
				p.sms_transformstate = 0
				S_StartSoundAtVolume(s, sfx_nerf, 77)
				S_StartSound(s, sfx_smscrt)
				SMS_LightFlash(s, SKINCOLOR_WHITE)
				SMS_AngledLightning(s, SKINCOLOR_SUPERSKY2, 23, 3-SMS_Graphix(s))
				SMS_LightningTrail(s, s)
				return --
		end	
	end
end, MT_PLAYER)

//SMS doesn't get hurt while dodging/ringbursting, unless it's a lava, acid, or electricity sector.
//Like a true cliche Matrix dodge, though, he can stylefully ignore lasers!
//This also merges every other ShouldDamage hook.
addHook("ShouldDamage", function(s, i, so)
	if not s.player return end --
	local p = s.player
	
	if p.hypermysticsonic and s.skin == "sms" --Undefeatable!
		return false --
	elseif p.smspickup and (p.smspickup == so) --Don't hit by your own item pickup!
		return false --
	end
	
	//Don't give rings in these cases.
		if (i and i.valid)	
			if G_GametypeHasTeams() and not (i.type == MT_SMSFIREBLAST)
				if so and so.player and (so.player.ctfteam == p.ctfteam)
					if ((i.type == MT_HMSFIREBLAST) or (i.type == MT_HMS_NAPALM_FLAMES))
						return false --
					end
					if (s.skin == "sms") and (i.flags & MF_MISSILE) and not (i.type == MT_REDRING)
						return false -- //Only allow red-rings so people can't feed you with autorings for an easy HMS transformation
					end
					if (so.skin == "sms") and not (i.type == MT_SMSFIREBLAST) //Fireblast ring-sharing only!
						return false --
					end
				end
			end	
			
			if s.ibethrownbysmshelp
				return false --	
			//Kids, don't kill friends and family with black holes
			elseif (i.type == MT_HMSBLACKHOLE)
				if (gametype == GT_COOP)
				or (i.target and i.target.player and (i.target.player.ctfteam == p.ctfteam))
					return false --
				end

		//Even though the walljump technically becomes a missile, it should NEVER hurt players.

			elseif (i.type == MT_SMSWALLJUMP)
					return false --
			elseif i.fusrodah //Ignore hits from enemies currently flying towards their death
				if (i.flags & MF_PAIN|MF_ENEMY|MF_BOSS)
					return false --
				end
			end
		end
		if (s.skin != "sms") or p.powers[pw_invulnerability] or (p.pflags & PF_GODMODE)	
			return -- Need to be SMS from now on, and have a source or inflictor.
		end
		
		--Invincibility?
		if (p.sms_dodging > 2)
		or p.sms_ringburstfly
		or p.sms_comethaymaker
		or p.mslightspeedattack
		or p.lightspeedchain
		or ((s.state >=  S_SMS_LIGHTDASH) and (s.state <= S_SMSCOMETHAYMAKER2))
			if s.battlemodsms --Don't get interrupted by people's jumps here.
				return false --
			end
			if not ( P_PlayerTouchingSectorSpecial(p, 1, 4) --You're not standing in death?
			or P_PlayerTouchingSectorSpecial(p, 1, 3)
			or P_PlayerTouchingSectorSpecial(p, 1, 2) )
				
			and not SMSSHIELD(p) == SH_ELEMENTAL --Or you are standing in death, but you have shield.
			and not (so and so.player and so.player.hypermysticsonic) --Unbypassable damage.
				return false --Dodge!
			end
		end
		
		local RAGDOLL = 0
		
		if so and (so.type == MT_TNTBARREL)
		or i and (i.type == MT_TNTBARREL)
			if p.homing or s.SMS_HomingBolt or p.footsweepanim
			or (so and so.YOUKICKEDME and so.YOUKICKEDME == s)
			or (i and i.YOUKICKEDME and i.YOUKICKEDME == s)
				return false --Ignore barrels when kicked/homed into.
			else
				RAGDOLL = 2
			end
		end

		if not (i and i.valid)
		or p.powers[pw_flashing]
			if RAGDOLL != 0 SMS_RagDoll(s, RAGDOLL) end		
			return --
		end --Need inflictor at all points now.
			
		if p.lightspeedchain --You're invincible to conventional attacks during a lightspeed attack!
			return false --			
		elseif p.footsweepanim			
			if (i.flags & (MF_ENEMY|MF_BOSS)) --Don't get hurt by (most) enemies you're footsweeping!
			and not ((i.type == MT_GSNAPPER) or (i.type == MT_CRUSHCLAW) and p.footsweep01) 	
				return false
			end	
		end
end, MT_PLAYER)

--Pick up Silver Ring dropped by SMS in match?
local function SMS_SRCollide(s, v)
	if v and v.player and s.health
		if not P_CanPickupItem(v.player, s)
			return false --
		end
	end
end
addHook("MobjCollide", SMS_SRCollide, MT_SMSSILVERRING)
addHook("MobjMoveCollide", SMS_SRCollide, MT_SMSSILVERRING)

addHook("TouchSpecial", function(r, s)
	if s and s.player and r.health
		if not (r.z > s.z+s.height)
		and not (s.z > r.z+r.height)
			if P_CanPickupItem(s.player, r)
				S_StartSound(s, sfx_itemup)
				P_GivePlayerRings(s.player, 10)
				r.destscale = r.scale*4
				P_KillMobj(r, s, s)
			end
		end
	end
	return true --
end, MT_SMSSILVERRING)

addHook("MobjThinker", function(s)
	if not s.valid return end
	if not (s.target and s.target.player) --FIND one.
		A_FindTarget(s, MT_PLAYER, 0)
	end
	if (s.state == S_SMSTSPARK1)
	s.blendmode = AST_ADD
		if (s.target and s.target.player and s.target.player.elauracolors and s.target.skin == "sms")
		local p = s.target.player
			if (p.elauracolors < 100)
				s.color = SKINCOLOR_YELLOW 
			elseif (p.elauracolors >= 100 and p.elauracolors < 120)
				s.color = SKINCOLOR_PERIDOT //Greenish yellow
			elseif (p.elauracolors >= 120 and p.elauracolors < 140)
				s.color = SKINCOLOR_GREEN  
			elseif (p.elauracolors >= 140 and p.elauracolors < 160)
				s.color = SKINCOLOR_EMERALD //Neon G
			elseif (p.elauracolors >= 160 and p.elauracolors < 180)
				s.color = SKINCOLOR_PERIDOT//Greenish yellow
			elseif (p.elauracolors >= 180 and p.elauracolors < 200)
				s.color = SKINCOLOR_YELLOW 
			elseif (p.elauracolors >= 200 and p.elauracolors < 220)
				s.color = SKINCOLOR_GOLD //Gold
			elseif (p.elauracolors >= 220 and p.elauracolors < 240)
				s.color = SKINCOLOR_ORANGE //Orange
			elseif (p.elauracolors >= 240 and p.elauracolors < 260)
				s.color = SKINCOLOR_RED //Red
			else //if (p.elauracolors >= 260 and p.elauracolors < 281)
				s.color = SKINCOLOR_RUST //Pink
			end
		elseif not s.coverride
			s.color = SKINCOLOR_YELLOW
		end
	end
end, MT_SMSTSPARK)

addHook("MobjThinker", function(s)
	if s.valid
	and (s.state == S_SMSTSPARK1) and not s.coverride
		s.color = SKINCOLOR_YELLOW
	end
end, MT_NIGHTSPARKLE)


//SMS' various unique hurt messages!
--2020: A local function here would've done wonders here. Oh well. Live and learn!

--Are you dead? Kill Message.
local function SMS_hmdead(s)
	if not s.health and not s.player.powers[pw_shield]
		return true --
	end
end
addHook("HurtMsg", function(p, i, so)
	if (gametype == GT_COOP) or not (p.mo and p.mo.valid)
		return --
	end
	if not (so and so.skin == "sms" or i and i.skin == "sms") --We need either an SMS inflictor or source.
		return --
	end	
	if not i return end
	
	local s = p.mo	
	if (p and s.battlemodsms) 
	or (so and so.battlemodsms) --Don't bother for battlemod.
		return
	end
	
	if i.player
	local IP = i.player	
		if IP.footsweepanim
			if SMS_hmdead(s)
				print(IP.ctfnamecolor+" roundhoused "+p.ctfnamecolor+" with a footsweep attack!")
                return true
			else
				print(IP.ctfnamecolor+" spinkicked "+p.ctfnamecolor+".")
				return true
            end

		elseif IP.sms_ringburstfly
			if SMS_hmdead(s)
               print(IP.ctfnamecolor+" skewered "+p.ctfnamecolor+" to death with the ringburst!")
               return true
			else
				print(IP.ctfnamecolor+" pierced "+p.ctfnamecolor+" with the flight of ringburst!")
				return true
            end

		elseif ((i.state == S_HMSCOMETHAYMAKER2) or (i.state == S_SMSCOMETHAYMAKER2) or (i.state == S_SMSCOMETHAYMAKER1) or (i.state == S_HMSCOMETHAYMAKER1))
			if not s.health
				print(IP.ctfnamecolor+" smashed "+p.ctfnamecolor+" out of the stadium! Homerun!")
                return true
			else
				print(IP.ctfnamecolor+" sent "+p.ctfnamecolor+" flying with a Comet Haymaker!")
				return true
            end

		else
			if SMS_hmdead(s)
				print(IP.ctfnamecolor+" killed "+p.ctfnamecolor+"!")
                return true
			else
                print(IP.ctfnamecolor+" hit "+p.ctfnamecolor+".")
				return true
			end
		end
	elseif i.type == MT_SMMK
		if not SMS_hmdead(s)
			if i.smssmmk
				print(p.ctfnamecolor+" got killed by "+i.target.player.ctfnamecolor+"'s stomp shockwave!")
                return true
			else
				print(i.target.player.ctfnamecolor+" roundhoused "+p.ctfnamecolor+" with a footsweep attack!")
                return true
			end

		else
			if i.smssmmk
				print(i.target.player.ctfnamecolor+" stomp shockwave hit "+p.ctfnamecolor+"!")
				return true
			else
				print(i.target.player.ctfnamecolor+" spinkicked "+p.ctfnamecolor+".")
				return true
			end
        end

	elseif i.type == MT_SMSSPINFIRE
		if SMS_hmdead(s)
            print(p.ctfnamecolor+" died to "+i.target.player.ctfnamecolor+"'s dashing flames!")
            return true
		else

			print(i.target.player.ctfnamecolor+" left "+p.ctfnamecolor+" in the fiery dust!")
			return true
        end
	elseif i.type == MT_SMSDIVEBOMB
		if SMS_hmdead(s)
            print(i.target.player.ctfnamecolor+" killed "+p.ctfnamecolor+" with an explosive divebomb!")
            return true
		else
			print(i.target.player.ctfnamecolor+"'s explosive divebomb wounded "+p.ctfnamecolor+".")
			return true
        end
	elseif i.type == MT_SMSPOWERBOMB
		if SMS_hmdead(s)
             print(p.ctfnamecolor+" was vaporized by "+i.target.player.ctfnamecolor+"'s powerbomb.")
             return true
		else
			print(i.target.player.ctfnamecolor+" powerbombed "+p.ctfnamecolor+"!")
			return true
        end
	elseif i.type == MT_HMSPOWERBOMB	
		if SMS_hmdead(s)
			print(i.target.player.ctfnamecolor+" completely obliterated "+p.ctfnamecolor+"!")
			return true
		else
			print(i.target.player.ctfnamecolor+" nuked "+p.ctfnamecolor+" with an enormous explosion!")
			return true
        end
	elseif i.type == MT_CMPHRADIUS
		if not s.health
            print(i.target.player.ctfnamecolor+" smashed "+p.ctfnamecolor+" out of the stadium! Homerun!")
            return true
		else
			print(i.target.player.ctfnamecolor+" sent "+p.ctfnamecolor+" flying with a Comet Haymaker!")
			return true
        end
	elseif i.type == MT_HMSFIREBLAST
		if SMS_hmdead(s)
			print("Ding!"+p.ctfnamecolor+" was cooked alive by "+i.target.player.ctfnamecolor+"'s flames! Enjoy while it's hot!")
			return true
		else
			print(p.ctfnamecolor+" was torched by "+i.target.player.ctfnamecolor+".")
			return true
        end
	elseif ((i.type == MT_HMSFLAMEREST) or (i.type == MT_HMS_NAPALM_FLAMES))
		if SMS_hmdead(s)
             print(i.target.player.ctfnamecolor+" 's inferno consumed "+p.ctfnamecolor+"'s life!")
             return true
		else
			print(i.target.player.ctfnamecolor+" caught "+p.ctfnamecolor+" in the inferno!")
			return true
        end
	elseif i.type == MT_HMSNOVABLAST or (i.type == MT_HMSNOVABLASTHB)
		if SMS_hmdead(s)
			print(i.target.player.ctfnamecolor+" annihilated "+p.ctfnamecolor+" with the Nova Blast!")
			return true

		else
			print(i.target.player.ctfnamecolor+" blew "+p.ctfnamecolor+" away with the Nova Blast!")
			return true
        end
	elseif i.type == MT_HMSLIPILLAR
		if SMS_hmdead(s)
			print("RIP: "+p.ctfnamecolor+". You will be missed. But not by "+i.target.player.ctfnamecolor+", who clearly hates you.")
			return true
		else
			print(p.ctfnamecolor+" was blown away by "+i.target.player.ctfnamecolor+"'s lightshow!")
			return true
		end
	end
/*	--If we got this far, do the usual thing.
	if so and so.player and (so.skin == "sms")
		if SMS_hmdead(s)
			print(so.player.ctfnamecolor+" killed "+p.ctfnamecolor+"!")
            return true
		else
            print(so.player.ctfnamecolor+" hit "+p.ctfnamecolor+".")
		    return true
		end
	end */
end)


--Battlemod thinker aider for all skin.
rawset(_G, "SMS_BattleModThinker", function(s, p)
			--	if s.skin == "sms"
					if not s.supersmsrecoil
						if ((p.powers[pw_nocontrol] > 5) and (s.recoilthrust and (s.recoilthrust > 10*FRACUNIT)) )
						s.supersmsrecoil = true
						P_SetObjectMomZ(s, -6*FRACUNIT, true)
						A_SMSquake(s, 60*FRACUNIT, 5, 1500)
						S_StartSound(s, sfx_smscrt)
						p.powers[pw_nocontrol] = $*2
						s.recoilthrust = $*5/4
						P_SpawnGhostMobj(s)
						P_SpawnMobjFromMobj(s, 0, 0, 0, MT_BURSTWAVE)
						A_SMSSTOMPSMOKE(s, 30, MT_HMSLIGHTNING2, 0, 20*FRACUNIT, FRACUNIT/2, SKINCOLOR_LAVENDER)
							if not P_IsObjectOnGround(s)
							s.supersmsrecoillanding = true
							end
						end
					elseif s.supersmsrecoil
						if s.supersmsrecoillanding
						S_StartSound(s, sfx_smscrt)
						if not p.smsgraphix
						local ghs = P_SpawnMobj(s.x, s.y, s.z-20*FRACUNIT, MT_HMSWAVEAURA)
						ghs.dustwave = 1
						ghs.sprite = SPR_SMMK
						ghs.frame = 3
						ghs.target = s
						ghs.fuse = 15
						ghs.scale = s.scale
						ghs.destscale = $*2
						end
						A_SMSSTOMPSMOKE(s, 60, MT_SPINDUST, nil, nil, 2*FRACUNIT)
						A_SMSSTOMPQUAKE(s, 45, 14, FRACUNIT, 0, 0, 0, 0, SKINCOLOR_SUPERGOLD3)
						A_SMSSTOMPQUAKE(s, 80, 18, 2*FRACUNIT, 0, ANG20, 0, 0, SKINCOLOR_SUPERSILVER4)
						s.supersmsrecoillanding = false
						end
						if (p.powers[pw_nocontrol] <= 1)
						s.supersmsrecoil = false					
						else
							if P_IsObjectOnGround(s) and CBW_Battle and CBW_Battle.DoDebris
							s.sprite = SPR_SMSO
							s.frame = Q|FF_FULLBRIGHT
							s.ghs = P_SpawnGhostMobj(s)
							s.ghs.tics = 3
							CBW_Battle.DoDebris(s,P_RandomChance(FRACUNIT/2),P_RandomRange(5,20))
							end
							if P_RandomRange(0,1)
							S_StartSound(s, sfx_cdfm42)
							end
						A_SMSquake(s, P_RandomRange(30,60)*FRACUNIT, 2, 1200)
						end					
					end
					if (p.rings > 299)
					p.sms_flamedelay = 10
						if (p.cmd.buttons & (BT_ATTACK|BT_FIRENORMAL))
						and not (p.hypermysticsonic or p.sms_ringburstfly or p.sms_stompanim or p.exiting or p.homing)
						and not p.powers[pw_nocontrol]
			  			and not p.exiting and not P_PlayerInPain(p) and not (p.charmed and p.charmedtime)
						and not p.powers[pw_carry]
						and not (p.pflags & (PF_GAMETYPEOVER|PF_STASIS))
							if P_IsObjectOnGround(s)
							P_SetObjectMomZ(s, 50*FRACUNIT, false)
							end
							p.sms_flamedelay = 15
							A_TOGOEVENFURTHERBEYOND(s) //Become Hyper Mystic Sonic!
						end		
					end
		--		end
		
			/*	if p.captureamount --Mild capture speed nerf incase SMS becomes OP here.
					if (leveltime % 5 == 0) 
					and s.lastcaptureamountsms and (s.lastcaptureamountsms < p.captureamount)
					p.captureamount = $-1 //Slightly slower capture speed for SMS.
					end			
				s.lastcaptureamountsms = p.captureamount
				end */
				
				if p.smsnobmgame == 2
					if not p.sms_transformstate
					p.presmsskin = "sonic"
					s.playerhomecharge = false
					A_SMSTOSONIC(s, nil, true, true)
					p.smssonicbattle = true
					S_StartSound(s, sfx_appear, p)
					P_FlashPal(p, PAL_MIXUP, 3)		
					CONS_Printf(p, "\x82"+"Sonic's special Battle ability is now the Super Mystic transformation!")
						if s.skin != "sms" and p.sms_originalcolor
							s.ssittcpls = p.sms_originalcolor
							s.ssittcpls2 = 2
						end
						return
					else
						if p.powers[pw_shield] //No extra hits while in battle mode!
							if not SMSSHIELD(p, SH_PINK, SH_PITY)
							and not s.hmsshieldconsumecd
								P_GivePlayerRings(p, 5) //But feel free to gain some extra rings!
								s.hmsshieldconsume = 18
								s.hmsshieldconsumecd = 105
							end
							P_RemoveShield(p)
							p.powers[pw_shield] = 0
						end
						if (p.sms_transformstate < 2)
							p.sms_transformstate = 2 //Only 1 hitpoint in battle mode!
						end
					end
					
				elseif p.smsnobmgame == 1
			  		p.presmsskin = "sonic"
				 	A_SMSTOSONIC(s, nil, true, true)
				 	 p.smssonicbattle = false	
		 		 	S_StartSound(s, sfx_lose)
				 	CONS_Printf(p, "\x85"+"SMS is not allowed in Battlemode matches right now!")	 
				 	return 
	--		  	elseif not p.smsnobmgame
					--?
			   	end
end)

--Battlemod script. I've ended support after battlemod version 6, so it may not even work anymore.
rawset(_G, "SMS_BattleMod", function(s, p)

		local mo = s --Failsafe. Because most modders use "mo" instead of "s", I suppose.
		
		--Instant Transformation for battle.
		if (s.skin == "sonic")
		and (p.cmd.buttons & (BT_ATTACK|BT_FIRENORMAL))
		and (p.rings > 29) 
		and not P_PlayerInPain(p)
		and not (p.charmed and p.charmedtime)		
		and not p.powers[pw_nocontrol]
		and not p.exiting
		and s.health
		
			p.sms_originalcolor = p.skincolor //Remember the player's original color.
			P_FlashPal(p, PAL_MIXUP, 7)
				
			if p.powers[pw_super]
				p.powers[pw_super] = 0
				P_RestoreMusic(p)
			end
				
			p.presmsskin = 0
			s.skin = "sms"	
			R_SetPlayerSkin(p, "sms") //For the life icon.
				
			if not (p.powers[pw_shield] & SH_FIREFLOWER)
			and not ((mariomode) and p.powers[pw_invulnerability])
				s.color = 0
			end
			
			if not p.smscoatc5 or not p.shinyglosscoat
				p.skincolor = SKINCOLOR_MYSTICAL4
			end
			
			s.SMS_locked = true
			S_StartSound(s, sfx_s3k9f)
			p.sms_transformstate = 2
			s.state = S_PLAY_SPRING
			p.pflags = $ & ~PF_JUMPED
			p.sms_hugeflametoss = 0
			p.powers[pw_flashing] = 85 //Some invincibility upon transforming.
			s.flags2 = $|MF2_DONTDRAW
			p.sms_flamedelay = 10
			p.powers[pw_nocontrol] = 2
			P_GivePlayerRings(p, -30)
				
			for d = 0,15
				P_SpawnParaloop(s.x, s.y, s.z+FixedMul(20*FRACUNIT, s.scale), 10*FRACUNIT, 16, MT_NIGHTSPARKLE, d*ANGLE_22h, S_SMSTSPARK1, false)
			end
			
			if G_GametypeHasTeams()
				if p.ctfteam == 1
					p.sms_originalcolor = SKINCOLOR_RED
					s.color = SKINCOLOR_RED
					p.skincolor = SKINCOLOR_RED
				elseif p.ctfteam == 2
					p.sms_originalcolor = SKINCOLOR_BLUE
					s.color = SKINCOLOR_BLUE
					p.skincolor = SKINCOLOR_BLUE						
				end				
			end
		end

		
		--Don't display shield gauge, SMS can't use them anyway.
	--	CBW_Battle.Action.SMSTransform = function(s, doaction)	
			p.action2text = nil
				
				if s.skin == "sms"
				
			   		if p.hypermysticsonic
					 	p.actiontext = nil --As far as you can go!
			 	 	 	p.actionrings = nil
			   		else
			  	 		p.actiontext = "Hyper Mystic Sonic" --Because a good time is waiting!
			 	 	 	p.actionrings = 300
					end
					return true --
					
			  	elseif p.smssonicbattle
				
			  		p.actiontext = "Super Mystic Sonic" --You can become SMS with 30+ rings!
			  		p.actionrings = 30
					if s.skin == "sonic" --You're weaker than usual when untransformed, slow down the speed thok.
						p.actionspd = 37*FRACUNIT 
					end
					return true --
					
			  	elseif P_IsObjectOnGround(s) --Go back to default abilities, SMSbattle is turned off.				
			  		p.actiontext = "Super Jump"
			  		p.actionrings = 10				
			  	else			
			  		p.actiontext = "Ground Pound"
			  		p.actionrings = 10				
			  	end
				
				--If we got this far, return to Sonic's vanilla Battlemod ability behaviour!
			  	doaction = CBW_Battle.CheckRings(p,$)
	
			  	local water = CBW_Battle.WaterFactor(s)
			  	local thrust = 18*FRACUNIT
			  	local jumpflags = (p.pflags|PF_JUMPED|PF_THOKKED) & ~(PF_STARTJUMP|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SPINNING)
				
			  	if p.actionstate == 0
			  		if doaction == 1 then
			  			CBW_Battle.PayRings(p)
			  			if P_IsObjectOnGround(s) then
			  				p.actionstate = 2 
			  				thrust = 18*FRACUNIT/water
			  				P_SetObjectMomZ(s,thrust,true) 
			  				S_StartSound(s,sfx_s3k3c)
			  				S_StartSound(s,sfx_kc5b)
			  				p.pflags = jumpflags
			  				s.state = S_PLAY_ROLL
			  				p.secondjump = 0
			  			else
			  				thrust = 24*FRACUNIT/water
			  				p.actionstate = 1 
			  				P_SetObjectMomZ(s,-thrust,false) 
			  				S_StartSound(s,sfx_zoom)
			  				s.state = S_PLAY_ROLL
			  				p.pflags = jumpflags
			  				p.secondjump = 0
			  			end
			  		end
					
			  	elseif p.actionstate == 1 
				
			  		p.actioncooldown = TICRATE/2
			  		if s.momz*P_MobjFlip(s) > 0
			  			p.actionstate = 0
			  			s.state = S_PLAY_SPRING
			  			p.pflags = $ & ~PF_JUMPED
			  		else
			  			if P_IsObjectOnGround(s) then
			  				thrust = 10*FRACUNIT/water
			  				P_SetObjectMomZ(s,thrust,true) 
			  				S_StartSound(s,sfx_s3k5f)
			  				p.state = S_PLAY_SPRING
			  				P_InstaThrust(s,R_PointToAngle2(0,0,s.momx,s.momy),FixedHypot(s.momx,s.momy)/4)
			  				for n = 0, 23
			  					local p = P_SPMAngle(s,MT_GROUNDPOUND,s.angle+n*ANG15,0)
			  					if p and p.valid then
			  						p.momz = s.scale*P_MobjFlip(s)*2/water
			  						p.fuse = TICRATE/3
					  			end
					  		end
					  	end
				  	end
					
			  	elseif p.actionstate == 2
				
			  		if (s.momz*P_MobjFlip(s) < 0)
			  			s.state = S_PLAY_FALL
			  			p.pflags = $ & ~PF_JUMPED
			  			p.actionstate = 0
			  		end
			  		if P_IsObjectOnGround(s)
			  			p.actionstate = 0
			  		end
			  	end
				
			  	if p.actionstate and (p.pflags & PF_JUMPED)
				  	P_SpawnThokMobj(p)
			  	end
			
				if CBW_Battle.ActionChar
					CBW_Battle.ActionChar["sonic"] = CBW_Battle.Action.SMSTransform
					CBW_Battle.ActionChar["sms"] = CBW_Battle.Action.SMSTransform	
				elseif CBW_Battle.SkinVars
					CBW_Battle.SkinVars["sonic"] = {
					special = CBW_Battle.Action.SMSTransform,
					}
				end
end)