freeslot("SPR2_RSAA", "sfx_rsaaa2", "sfx_rsaaa1", "SPR2_MEME", "S_PLAY_SCREAM1", "S_PLAY_SCREAM2", "S_PLAY_SCREAM3", "S_PLAY_SCREAM4", "S_PLAY_SCREAM5", "MT_WEREHOGRETICLE", "sfx_homing", "sfx_whurt1", "sfx_whurt2", "sfx_whurt3", "sfx_whurt4", "S_PLAY_SPIN", "MT_WEREHOGFIST", "SPR2_CLAW", "S_PLAY_WERECLAW", "sfx_attk1", "sfx_attk2", "sfx_attk3", "sfx_attk4", "sfx_attk5", "sfx_grapp", "S_PLAY_TWIRL", "SPR2_DBJP", "S_PLAY_GRAB", "SPR2_PNCH", "S_WEREHOGARM", "MT_WEREHOGARM", "S_PLAY_SHIT", "SPR2_SHIT")
states[S_PLAY_TWIRL] = {SPR_PLAY, SPR2_DBJP|FF_ANIMATE, 8, nil, 7, 1, S_PLAY_JUMP}
states[S_PLAY_WERECLAW] = {SPR_PLAY, SPR2_CLAW|FF_ANIMATE, 12, nil, 5, 2, S_PLAY_FALL}
states[S_PLAY_SPIN] = {SPR_PLAY, SPR2_SPIN|FF_ANIMATE, 8, nil, 3, 2, S_PLAY_WALK}
states[S_PLAY_GRAB] = {SPR_PLAY, SPR2_PNCH, 1, nil, 0, 0, S_PLAY_GRAB}
states[S_PLAY_SCREAM1] = {SPR_PLAY, SPR2_RSAA, -1, nil, 0, 0, S_PLAY_SCREAM2}
states[S_PLAY_SCREAM2] = {SPR_PLAY, SPR2_MEME, 1, nil, 0, 0, S_PLAY_SCREAM3}
states[S_PLAY_SCREAM3] = {SPR_PLAY, SPR2_MEME, 1, nil, 0, 0, S_PLAY_SCREAM4}
states[S_PLAY_SCREAM4] = {SPR_PLAY, SPR2_MEME, 1, nil, 0, 0, S_PLAY_SCREAM5}
states[S_PLAY_SCREAM5] = {SPR_PLAY, SPR2_MEME, 1, nil, 0, 0, S_PLAY_SCREAM2}

sfxinfo[sfx_rsaaa1].caption = "Screaming"
sfxinfo[sfx_rsaaa2].caption = "Screaming"
sfxinfo[sfx_attk1].caption = "Werehog grunt"
sfxinfo[sfx_attk2].caption = "Werehog grunt"
sfxinfo[sfx_attk3].caption = "Werehog grunt"
sfxinfo[sfx_attk4].caption = "Werehog grunt"
sfxinfo[sfx_attk5].caption = "Werehog grunt"
sfxinfo[sfx_whurt1].caption = "Werehog pain"
sfxinfo[sfx_whurt2].caption = "Werehog pain"
sfxinfo[sfx_whurt3].caption = "Werehog pain"
sfxinfo[sfx_whurt4].caption = "Werehog pain"
sfxinfo[sfx_homing].caption = "Lock-On"
sfxinfo[sfx_grapp].caption = "Werehog Vibe"

//Modified from ModernSonic by MotdSpork for Werehug's attack sounds
rawset(_G, "WereSound", function(player, soundtype)
  if player.werehugsoundtime > 0 -- don't play a sound if the timer is active
    return
  end
  
  local soundlist = WERE_SOUNDS[soundtype] -- get the list of sounds for the sound type
  local sound = soundlist[P_RandomKey(#soundlist) + 1] -- choose a sound from the list
  if sound == sfx_null -- don't play a sound if silence is picked
    return
  end
  S_StartSound(player.mo, sound)
  player.werehugsoundtime = soundtype -- initiate the timer
end)

local TYPE_ATTK = 4
local TYPE_HURT = 50

rawset(_G, "WERE_SOUNDS", {
  [TYPE_ATTK] = {sfx_attk1, sfx_attk2, sfx_attk3, sfx_attk4, sfx_attk5},
  [TYPE_HURT] = {sfx_whurt1, sfx_whurt2, sfx_whurt3, sfx_whurt4},
})

function A_ReticleThinker (actor, var1, var2)
	//Use a variable to determine if the actor has a tracer
	actor.hastracer = false
	if (actor.tracer)
	and (actor.tracer.valid) then
		actor.hastracer = true
	end
	//If the actor has a target...
	if (actor.target)
	and (actor.target.valid) then
		//Turn visible
		actor.flags2 = $1 & ~MF2_DONTDRAW
		//Follow it
		P_TeleportMove(actor, actor.target.x, actor.target.y, actor.target.z)
		actor.momx = 0
		actor.momy = 0
		actor.momz = 0
		//Copy its attributes
		//actor.scale = actor.target.scale
		if actor.target.eflags & MFE_VERTICALFLIP then
			actor.flags2 = $1|MF2_OBJECTFLIP // flip gravity!
		end
		//If tracer present, point towards it
		if actor.hastracer == true then
			local an = R_PointToAngle2(actor.x, actor.y, actor.tracer.x, actor.tracer.y)
			actor.angle = an
			P_TeleportMove(actor, actor.x + 1*cos(an), actor.y + 1*sin(an), actor.z)
		end
	else
		//If no target, turn invisible
		actor.flags2 = $1|MF2_DONTDRAW
		//Follow tracer and copy its attributes if there is one
		if actor.hastracer == true then
			P_TeleportMove(actor, actor.tracer.x, actor.tracer.y, actor.tracer.z)
			actor.momx = 0
			actor.momy = 0
			actor.momz = 0
			actor.scale = actor.tracer.scale
			if actor.tracer.eflags & MFE_VERTICALFLIP then
				actor.flags2 = $1|MF2_OBJECTFLIP // flip gravity!
			end
		end
	end
end

if srb2p return end

local function P_PlayerColorSpawn (player)
	if player.powers[pw_super] != 0 then
		return SKINCOLOR_YELLOW
	else
		return player.mo.color
	end
end

addHook("MapLoad", do
	for player in players.iterate
		player.werehogbattlemusic = 0
	end
end)

addHook("MapChange", do
	for player in players.iterate
		player.werehogbattlemusic = 0
	end
end)
local JAZZFILE = "client/whjazzmusic.dat"
local RUNFILE = "client/whrunbutton.dat"
local CHIPFILE = "client/chip.dat"
local configplayer = nil

local function valid(mo)
	return mo and mo.valid
end

addHook("ThinkFrame", do
	if valid(consoleplayer)
	and not valid(configplayer)
		configplayer = consoleplayer
		local file = io.openlocal(JAZZFILE)
		if file
			local num = file:read("*a")
			COM_BufInsertText(consoleplayer, "jazzband "..num)
			file:close()
		else
			COM_BufInsertText(consoleplayer, "jazzband 1")
		end
		local file = io.openlocal(CHIPFILE)
		if file
			local num = file:read("*a")
			COM_BufInsertText(consoleplayer, "chip "..num)
			file:close()
		else
			COM_BufInsertText(consoleplayer, "chip 1")
		end
		local file = io.openlocal(RUNFILE)
		if file
			local num = file:read("*a")
			COM_BufInsertText(consoleplayer, "runbutton "..num)
			file:close()
		else
			COM_BufInsertText(consoleplayer, "runbutton 1")
		end
	end
	for player in players.iterate
		if player.mo and player.mo.skin == "werehog"
			//Variables and Misc stuff
			if player.werehogspin == nil
				player.werehogspin = 0
			end
			if player.werehogspintimer == nil
				player.werehogspintimer = 0
			end
			if not (player.customhoming)
				player.customhoming = 0
			end
			if not (player.werehugsoundtime)
				player.werehugsoundtime = 0
			end
			if player.werehugsoundtime > 0
				player.werehugsoundtime = $1-1
			end
			if player.runbuttondisable == 1
				player.acceleration = 40
			else
				player.acceleration = 60
			end
			if not (player.werehogbattlemusic)
				player.werehogbattlemusic = 0
			else
				if player.werehogbattlemusic > 0
					player.werehogbattlemusic = $-1
				end
			end
			if player.screamtimer == nil
				player.screamtimer = 0
			end
			if player.powers[pw_shield]
			and not (player.powers[pw_shield] == SH_ARMAGEDDON)
				player.pflags = $1|PF_USEDOWN
			end
			if not (player.twirling)
				player.twirling = false
			end
			if player.mo.state ~= S_PLAY_WERECLAW
			and player.twirling == false
			and player.panim ~= PA_ABILITY2
				player.charability2 = CA2_NONE
			end
			if not (player.cmd.buttons & BT_USE)
				player.usedown = false
				player.twirldown = false
			end
			if player.customhoming > 0
			or player.twirling == true
			or player.mo.state == S_PLAY_WERECLAW
			or player.mo.state == S_PLAY_ROLL
				player.pflags = $1 & ~PF_NOJUMPDAMAGE
			else
				player.pflags = $1|PF_NOJUMPDAMAGE
			end
			if P_IsObjectOnGround(player.mo)
				if player.cmd.buttons & BT_USE
					player.usedown = true
				end
				if player.fist and player.fist.valid
					player.fist.target = player.fist.source 
				end
			end
			//Hurt Sound
			if not (player.werehurt)
				player.werehurt = 0
			end
			if P_PlayerInPain(player)
				if player.werehurt == 0
					player.werehurt = 1
					if not (player.mo.eflags & MFE_UNDERWATER)
						WereSound(player, TYPE_HURT)
					end
				end
			else
				player.werehurt = 0
			end
			//Music!
			if player.playerstate == PST_LIVE
			and not (player.powers[pw_extralife])
			and player.powers[pw_sneakers] < 20*TICRATE
			and player.powers[pw_invulnerability] < 20*TICRATE
			and not (player.exiting)
			and player.battlemusic == 1
				if player.werehogbattlemusic > 2
					S_ChangeMusic("WERE", true, player)
				elseif player.werehogbattlemusic >= 1
					P_RestoreMusic(player)
				end
			end
			if player.playerstate == PST_DEAD
				player.werehogbattlemusic = 0
				player.twirling = false
			end
			if player.powers[pw_sneakers] == 20*TICRATE
			or player.powers[pw_invulnerability] == 20*TICRATE
				player.werehogbattlemusic = 2
			end
			//Breaking walls...Amy style
			if player.mo.state == S_PLAY_WERECLAW
				player.charability2 = CA2_MELEE
				player.panim = PA_ABILITY2
			end
			//WereClaw
			if player.cmd.buttons & BT_USE
			and player.usedown == false
			and not (P_PlayerInPain(player))
			and player.fist == nil
			and not (P_IsObjectOnGround(player.mo))
			and not (player.panim == PA_ABILITY2)
			and not (player.powers[pw_carry])
			and player.mo.state ~= S_PLAY_WERECLAW
			and player.playerstate == PST_LIVE
			and not (player.isxmomentum and (player.mo.state == S_PLAY_TRICKUP or player.mo.state == S_PLAY_TRICKDOWN or player.trickboostcount and player.trickboostcount > 0))
				player.usedown = true
				if player.mo.state ~= S_PLAY_WERECLAW
					if not (player.mo.eflags & MFE_UNDERWATER)
						WereSound(player, TYPE_ATTK)
					end
					player.mo.state = S_PLAY_WERECLAW
					S_StartSound(player.mo, sfx_s3k42)
				end
			end
			/////////////GRAPPPPPLE PUNCH/////////////////////
			//Homing Hand!
			if player.fist
			and player.fist.valid
			and player.fist.target
			and player.fist.target == player.werehogrettarget
			and player.fist.target.health > 0
			and player.fisthoming > 0
			and not (P_PlayerInPain(player))
			and not (player.fist.target.flags2 & MF2_FRET)
			and player.playerstate == PST_LIVE
			and player.fist.target ~= player.fist.source
			and not (player.powers[pw_carry])
				player.fisthoming = $1-1
				if (player.mo.eflags & MFE_VERTICALFLIP and not (player.mo.flags2 & MF2_OBJECTFLIP))
				or (player.mo.flags2 & MF2_OBJECTFLIP and not (player.mo.eflags & MFE_VERTICALFLIP))
				or (player.mo.flags2 & MF2_OBJECTFLIP and player.mo.eflags & MFE_VERTICALFLIP)
					player.fist.flags2 = $1|MF2_OBJECTFLIP
					player.fist.eflags = $1|MFE_VERTICALFLIP
				end
				
				searchBlockmap("objects", function(refmobj, foundmobj)
					if foundmobj and foundmobj.valid and foundmobj.type == MT_METALSONIC_BATTLE
					and foundmobj.health and foundmobj.state == S_METALSONIC_FLOAT
						//That's right, we're doing this the hard way.
						foundmobj.movedir = ANGLE_11hh - FixedAngle(FixedMul(AngleFixed(ANGLE_11hh),
						FixedDiv((foundmobj.info.spawnhealth - foundmobj.health)<<FRACBITS, (foundmobj.info.spawnhealth-1)<<FRACBITS)))
						if (P_RandomChance(FRACUNIT/2)) then foundmobj.movedir = InvAngle(foundmobj.movedir) end
						foundmobj.threshold = 6 + (FixedMul(24<<FRACBITS, FixedDiv((foundmobj.info.spawnhealth - foundmobj.health)<<FRACBITS, (foundmobj.info.spawnhealth-1)<<FRACBITS))>>FRACBITS)
						if (foundmobj.info.activesound) then S_StartSound(foundmobj, foundmobj.info.activesound) end
						if (foundmobj.info.painchance) then foundmobj.state = foundmobj.info.painchance end
						foundmobj.flags2 = $ & ~MF2_INVERTAIMABLE
					end
				end, player.fist)
				if player.fistfoundtarget == true
					P_TeleportMove(player.fist, player.werehogrettarget.x, player.werehogrettarget.y, player.werehogrettarget.z)
				else
					local zdist = (P_MobjFlip(player.mo) == 1) and (player.werehogrettarget.z + player.werehogrettarget.height) - (player.fist.z + player.fist.height) or (player.werehogrettarget.z - player.fist.z)
					local dist = P_AproxDistance(P_AproxDistance(player.werehogrettarget.x - player.fist.x, player.werehogrettarget.y - player.fist.y), zdist)
					player.fist.momx = FixedMul(FixedDiv(player.werehogrettarget.x-player.fist.x, dist), 50*FRACUNIT)
					player.fist.momy = FixedMul(FixedDiv(player.werehogrettarget.y-player.fist.y, dist), 50*FRACUNIT)
					player.fist.momz = FixedMul(FixedDiv(zdist, dist), 50*FRACUNIT)
					player.fist.angle = R_PointToAngle2(player.fist.x, player.fist.y, player.werehogrettarget.x, player.werehogrettarget.y)
				end
				local dist = R_PointToDist2(0, 0, R_PointToDist2(0, 0, player.mo.x - player.fist.x, player.mo.y - player.fist.y), player.mo.z-player.fist.z)
				local x = FixedDiv(player.fist.x - player.mo.x, dist)
				local y = FixedDiv(player.fist.y - player.mo.y, dist)
				if (player.mo.eflags & MFE_VERTICALFLIP and not (player.mo.flags2 & MF2_OBJECTFLIP))
				or (player.mo.flags2 & MF2_OBJECTFLIP and not (player.mo.eflags & MFE_VERTICALFLIP))
				or (player.mo.flags2 & MF2_OBJECTFLIP and player.mo.eflags & MFE_VERTICALFLIP)
					player.z = -FixedDiv(player.fist.z - player.mo.z, dist) 
				else
					player.z = FixedDiv(player.fist.z - player.mo.z-player.mo.height, dist) 
				end
				for i = 15, dist/FRACUNIT
					local arm = P_SpawnMobjFromMobj(player.mo, x*i, y*i, player.z*i, MT_WEREHOGARM)
					arm.color = player.mo.color
					arm.z = $ + arm.height/4
					arm.scale = player.mo.scale*3/4 + i * FixedDiv(FRACUNIT,dist)
				end
				player.mo.momy = $1*5/8
				player.mo.momx = $1*5/8
				player.mo.momz = $1*5/8
				player.drawangle = R_PointToAngle2(player.mo.x, player.mo.y, player.werehogrettarget.x, player.werehogrettarget.y)
			else
				if player.fist 
				and player.fist.valid
					P_RemoveMobj(player.fist)
				end
				player.fist = nil
				player.fisthoming = 0
			end
			if player.mo.state == S_PLAY_GRAB
			and player.fist == nil
				player.mo.state = S_PLAY_FALL
			end
			if player.fist
			and player.fist.target == player.fist.source
			and player.playerstate == PST_LIVE
				if player.fist 
				and player.fist.valid
					P_RemoveMobj(player.fist)
				end
				player.fist = nil
			end
			//Custom homing attack code
			if player.customhoming > 0
			and not (P_PlayerInPain(player))
			and player.playerstate == PST_LIVE
			and not (player.powers[pw_carry])
				player.customhoming = $1 - 1
				if player.werehogrettarget and player.werehogrettarget.health
					player.mo.state = S_PLAY_GRAB
					player.pflags = $1|PF_JUMPED
					local zdist = (P_MobjFlip(player.mo) == 1) and (player.werehogrettarget.z + player.werehogrettarget.height) - (player.mo.z + player.mo.height) or (player.werehogrettarget.z - player.mo.z)
					local dist = P_AproxDistance(P_AproxDistance(player.werehogrettarget.x - player.mo.x, player.werehogrettarget.y - player.mo.y), zdist)
					player.mo.momx = FixedMul(FixedDiv(player.werehogrettarget.x-player.mo.x, dist), 60*FRACUNIT)
					player.mo.momy = FixedMul(FixedDiv(player.werehogrettarget.y-player.mo.y, dist), 60*FRACUNIT)
					player.mo.momz = FixedMul(FixedDiv(zdist, dist), 60*FRACUNIT)
					player.mo.angle = R_PointToAngle2(player.mo.x, player.mo.y, player.werehogrettarget.x, player.werehogrettarget.y)
					player.drawangle = player.mo.angle
				end
				if player.werehogrettarget == nil
				or (player.werehogrettarget and not player.werehogrettarget.health)
				or (player.werehogrettarget and player.werehogrettarget.flags2 & MF2_FRET)
				or (player.werehogrettarget and player.werehogrettarget.flung == true)
				or (player.werehogrettarget and not (player.werehogrettarget.flags & MF_SPRING) and not (player.werehogrettarget.flags & MF_SHOOTABLE) and not (player.werehogrettarget.type == MT_METALSONIC_BATTLE))
				or (player.powers[pw_carry])
				or (player.werehogrettarget and player.werehogrettarget.state == S_METALSONIC_VECTOR)
					if player.cmd.buttons & BT_JUMP
						player.mo.momx = $1*5/7
						player.mo.momy = $1*5/7
						if player.mo.eflags & MFE_UNDERWATER
							P_SetObjectMomZ(player.mo, FixedMul(6*FRACUNIT, player.mo.scale))
						else
							P_SetObjectMomZ(player.mo, FixedMul(12*FRACUNIT, player.mo.scale))
						end
					else
						P_InstaThrust(player.mo, player.mo.angle, 0)
						if player.mo.eflags & MFE_UNDERWATER
							P_SetObjectMomZ(player.mo, FixedMul(5*FRACUNIT, player.mo.scale))
						else
							P_SetObjectMomZ(player.mo, FixedMul(10*FRACUNIT, player.mo.scale))
						end
					end
					player.fistfoundtarget = false
					
					player.mo.state = S_PLAY_ROLL
					player.pflags = $1 & ~PF_THOKKED
					player.customhoming = 0
					player.fisthoming = 0
					if player.fist 
					and player.fist.valid
						P_RemoveMobj(player.fist)
					end
					player.fist = nil
				end
				if P_PlayerInPain(player)
					player.fistfoundtarget = false
					player.customhoming = 0
					player.fisthoming = 0
					if player.fist 
					and player.fist.valid
						P_RemoveMobj(player.fist)
					end
					player.fist = nil
				end
			else
				player.customhoming = 0
			end
			/////////////////Run button and Twirl attack////////////////
			if player.cmd.buttons & BT_CUSTOM1
			and player.playerstate == PST_LIVE
			and not (player.powers[pw_carry])
			and player.twirling == false
			or player.runbuttondisable == 1
				player.normalspeed = 36*FRACUNIT
				player.hasnomomentum = false
			else
				if player.normalspeed  == 36*FRACUNIT or player.hasnomomentum == false
					player.normalspeed = 20*FRACUNIT
					player.hasnomomentum = true
				end
			end
			if player.cmd.buttons & BT_USE
			and player.playerstate == PST_LIVE
			and not (player.powers[pw_carry])
			and player.panim ~= PA_ABILITY2
			and not (P_PlayerInPain(player))
			and not (player.pflags & PF_STASIS)
			and not (player.powers[pw_nocontrol])
			and player.mo.state ~= S_PLAY_HUG
			and not (player.exiting)
			and player.mo.state ~= S_PLAY_FALL
				if P_IsObjectOnGround(player.mo)
				and player.twirling == false
				and not (P_PlayerInPain(player))
				and player.twirldown == false
					player.twirling = true
					if player.speed > FixedMul(20*FRACUNIT, player.mo.scale)
						player.mo.momx = $1*5/7
						player.mo.momy = $1*5/7
					end
				end
				if not (P_IsObjectOnGround(player.mo))
				and not (P_PlayerInPain(player))
					player.twirldown = true
				end
			else
				if player.twirling == true
				and player.playerstate == PST_LIVE
				and not (P_PlayerInPain(player))
					player.twirling = false
					player.pflags = $1 & ~PF_JUMPED
					if not (player.powers[pw_carry])
						if P_IsObjectOnGround(player.mo)
							player.mo.state = S_PLAY_WALK
						else
							player.mo.state = S_PLAY_FALL
						end
					end
				end
				if player.normalspeed == 15*FRACUNIT
				or player.normalspeed == 30*FRACUNIT
					player.normalspeed = 20*FRACUNIT
				end
			end
			if player.twirling == true
			and player.playerstate == PST_LIVE
			and not (P_PlayerInPain(player))
			and not (player.pflags & PF_SLIDING)
			and player.mo.state ~= S_PLAY_FALL
				player.charability = CA_GLIDEANDCLIMB
				player.jumpfactor = FRACUNIT*3/4
				if player.mo.state ~= S_PLAY_SPIN
					player.mo.state = S_PLAY_SPIN
				end
				player.pflags = $|PF_THOKKED
				if not (S_SoundPlaying(player.mo, sfx_s3k42))
					S_StartSound(player.mo, sfx_s3k42)
				end
				if player.powers[pw_sneakers]
					player.normalspeed = 30*FRACUNIT
				else
					player.normalspeed = 15*FRACUNIT
				end
				player.mo.friction = FRACUNIT+35
				player.charflags = $1|SF_NOSKID
			else
				player.jumpfactor = skins[player.mo.skin].jumpfactor
				player.charability = CA_NONE
				player.charflags = $ & ~SF_NOSKID
			end
			if player.mo.state == S_PLAY_SPIN
				player.panim = PA_DASH
			end
			if (P_PlayerInPain(player))
			or (player.pflags & PF_SLIDING)
				player.twirling = false
			end
			//So you can grapple after springing
			if not (P_IsObjectOnGround(player.mo))
			and not (player.powers[pw_carry])
			and not (player.pflags & PF_JUMPED)
			and player.playerstate == PST_LIVE
			and not (P_PlayerInPain(player)) 
			and not (player.isxmomentum and (player.mo.state == S_PLAY_SPRING or player.mo.state == S_PLAY_FALL))
				player.pflags = $|PF_JUMPED
			end
			//AAAAAAAAAAAAAAAA
			if (player.cmd.buttons & BT_TOSSFLAG)
            and not P_PlayerInPain(player)
			and player.cmd.buttons & BT_CUSTOM2
	        and player.playerstate == PST_LIVE
			and P_IsObjectOnGround(player.mo)
			and not (player.mo.eflags & MFE_UNDERWATER)
			and player.speed == 0
			and not (player.powers[pw_super])
			and player.screamtimer == 0
			and not (player.powers[pw_nocontrol])
			and not (player.pflags & PF_STASIS)
				player.mo.state = S_PLAY_SCREAM1
            else
				//player.screamtimer = 0
			end
			if player.mo.state >= S_PLAY_SCREAM1 and player.mo.state <= S_PLAY_SCREAM5
				player.screamtimer = $+1
				player.panim = PA_IDLE
				player.drawangle = player.mo.angle + ANGLE_180
			end
			if player.screamtimer >= 30
			and player.cmd.buttons & BT_CUSTOM2
			and (player.cmd.buttons & BT_TOSSFLAG)
				if player.mo.state == S_PLAY_SCREAM1
					player.mo.state = S_PLAY_SCREAM2
					S_StartSound(player.mo, sfx_rsaaa1)
				end
				if player.screamtimer == 51
					S_StartSound(player.mo, sfx_rsaaa2)
				end
				if player.screamtimer > 61
					player.screamtimer = 50
				end
			end
			if P_PlayerInPain(player)
			or player.powers[pw_carry]
			or player.playerstate == PST_DEAD
			or not (player.cmd.buttons & BT_TOSSFLAG)
			or not (player.cmd.buttons & BT_CUSTOM2)
			or player.speed > 0
			or player.powers[pw_nocontrol]
			or (player.pflags & PF_STASIS)
				if player.screamtimer > 0
					player.screamtimer = 0
					player.mo.state = S_PLAY_STND
					S_StopSound(player.mo)
				end
			end
			//LOCKON
			if not (player.powers[pw_carry] == CR_NIGHTSMODE)
			and not (player.gotflag)
				if not (player.pflags & PF_JUMPED)
					player.werehogrettarget = 0
					if (player.werehogret) and (player.werehogret.valid) then
						P_RemoveMobj(player.werehogret)
						player.werehogret = 0
					end
				end	
				if not (player.exiting)
					if player.pflags & PF_JUMPED
						if player.werehogret == nil
						or player.werehogret == 0
							player.werehogrettarget = P_LookForEnemies(player, true, true)
						end
					end
					//too far from the target
					local targdist = FixedMul(700*FRACUNIT, player.mo.scale)
					if (player.werehogret) and (player.werehogret.valid)
					and player.customhoming == 0
					and player.fisthoming == 0
						if (P_AproxDistance(P_AproxDistance(player.mo.x-player.werehogrettarget.x, player.mo.y-player.werehogrettarget.y),
						player.mo.z-player.werehogrettarget.z) > targdist) then
							P_RemoveMobj(player.werehogret)
							player.werehogret = 0
							player.werehogrettarget = 0
						end
					end
					//not facing the target
					if (player.werehogret) and (player.werehogret.valid)
					and player.customhoming == 0
					and player.fisthoming == 0
						local angdiff = R_PointToAngle2(player.mo.x, player.mo.y, player.werehogrettarget.x, player.werehogrettarget.y) - player.mo.angle
						if ((angdiff > ANG30) or (angdiff < -ANG30))
						and player.customhoming == 0
							P_RemoveMobj(player.werehogret)
							player.werehogret = 0
							player.werehogrettarget = 0
						end
					end
					//If orb target no longer exists, set the variable to nil
					if (player.werehogrettarget)
						if not (player.werehogrettarget.valid) then
						
							if (player.werehogret) and (player.werehogret.valid) then
								P_RemoveMobj(player.werehogret)
								player.werehogret = 0
								player.werehogrettarget = 0
							end
						end
					end
					//If orb target no longer has health, set the variable to nil
					if (player.werehogrettarget) and (player.werehogrettarget.valid) then
						if (player.werehogrettarget.health < 1) then
							player.werehogrettarget = 0
							if (player.werehogret) and (player.werehogret.valid) then
								P_RemoveMobj(player.werehogret)
								player.werehogret = 0
							end
						end
					end
					//Stuff to do if there is currently a valid target
					if (player.werehogrettarget) and (player.werehogrettarget.valid) then
						//Add a target reticule if there is none
						local targdist = FixedMul(700*FRACUNIT, player.mo.scale)
						if not (player.werehogret) 
						and (player.werehogrettarget and player.werehogrettarget.valid)
						and player.werehogrettarget.type ~= MT_RING
						and player.werehogrettarget.type ~= MT_SIGN 
						and player.werehogrettarget.type ~= MT_TNTBARREL
						and player.werehogrettarget.type ~= MT_BIGMINE
						and player.werehogrettarget.type ~= MT_EGGSHIELD
						//and (player.werehogrettarget.flags & MF_SHOOTABLE)
						and not (player.werehogrettarget.flags2 & MF2_FRET)
						and P_CheckSight(player.mo, player.werehogrettarget)
						and (P_AproxDistance(P_AproxDistance(player.mo.x-player.werehogrettarget.x, player.mo.y-player.werehogrettarget.y),
						player.mo.z-player.werehogrettarget.z) < targdist) then
							S_StartSound(player.mo, sfx_homing, player)
							player.werehogret = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_WEREHOGRETICLE)
							player.werehogret.tracer = player.mo
							player.werehogret.target = player.werehogrettarget
							player.werehogret.scale = player.werehogrettarget.scale*3/2
						end
					end
					if (player.werehogret) 
					and player.werehogret.valid
					and player.werehogrettarget
					and player.werehogrettarget.valid
					and player.customhoming == 0
					and player.fisthoming == 0
						if player.werehogrettarget ~= P_LookForEnemies(player, true, true)
							player.werehogrettarget = 0
							P_RemoveMobj(player.werehogret)
							player.werehogret = 0
						end
					end
					if player.werehogret and player.werehogret.valid
					and player.werehogrettarget and player.werehogrettarget.valid
						if player.werehogret.scale ~= player.werehogrettarget.scale/3*2
							player.werehogret.destscale = player.werehogrettarget.scale/3*2
						end
					end
				elseif player.werehogret and player.werehogret.valid
					player.werehogrettarget = 0
					P_RemoveMobj(player.werehogret)
					player.werehogret = 0
				end
				player.dontdisplaymarker = true
			else
				if player.werehogret and player.werehogret.valid
					player.werehogrettarget = 0
					P_RemoveMobj(player.werehogret)
					player.werehogret = 0
				end
				player.dontdisplaymarker = false
			end
		end
	end
end)

addHook("MobjThinker", function(marker)
  if not marker.valid then return end
  if displayplayer and displayplayer.dontdisplaymarker == true
  or secondarydisplayplayer and secondarydisplayplayer.dontdisplaymarker == true
    marker.flags2 = $ | MF2_DONTDRAW
    return true
  end
end, MT_LOCKON)

addHook("MobjThinker", function(marker)
  if not marker.valid then return end
  if marker ~= displayplayer.werehogret
    marker.flags2 = $ | MF2_DONTDRAW
    return true
  end
end, MT_WEREHOGRETICLE)

//DoubleJump and Grapple
addHook("AbilitySpecial", function(player)
	if player.mo.skin == "werehog"
		if not (P_PlayerInPain(player))
		and player.fist == nil
		and not (P_IsObjectOnGround(player.mo))
		and not (player.panim == PA_ABILITY2)
		and not (player.powers[pw_carry])
		and player.mo.state ~= S_PLAY_WERECLAW
		and player.playerstate == PST_LIVE
		and player.twirling == false
			player.charability = CA_NONE
			player.usedown = true
			if player.werehogrettarget and player.werehogrettarget.health
			and player.werehogret and player.werehogret.valid
			and not (player.werehogrettarget.flags2 & MF2_FRET)
			and player.werehogrettarget.type ~= MT_BIGMINE
			and player.werehogrettarget.type ~= MT_EGGSHIELD
			and player.werehogrettarget.type ~= MT_TNTBARREL
			and (player.werehogrettarget.flags & MF_SHOOTABLE or player.werehogrettarget.flags & MF_SPRING or player.werehogrettarget.type == MT_METALSONIC_BATTLE)
			and not (player.werehogrettarget and player.werehogrettarget.state == S_METALSONIC_VECTOR)
				player.fist = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z+ player.mo.height/2, MT_WEREHOGFIST)
				player.fist.target = player.werehogrettarget
				player.fist.source = player.mo
				player.fist.scale = player.mo.scale*2
				player.fist.flags = $ & ~(MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY)
				player.fist.color = player.mo.color
				player.fisthoming = 3*TICRATE
				player.mo.state = S_PLAY_GRAB
				S_StartSound(player.mo, sfx_grapp)
				if not (player.mo.eflags & MFE_UNDERWATER)
					WereSound(player, TYPE_ATTK)
				end
			elseif not (player.pflags & PF_THOKKED)
				player.pflags = $1 & ~PF_JUMPED
				P_DoJump(player, true)
				player.pflags = $1 & ~PF_SPINNING
				player.pflags = $1|PF_THOKKED
				player.mo.state = S_PLAY_TWIRL
				for i = 1, 16 //spawn some dust yee
					local dust = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z + (player.mo.eflags & MFE_VERTICALFLIP and 4*player.mo.scale or 0), player.mo.eflags & (MFE_UNDERWATER | MFE_TOUCHWATER) and MT_MEDIUMBUBBLE or MT_PARTICLE)
					dust.fuse = TICRATE/4
					dust.scale = player.mo.scale
					dust.destscale = player.mo.scale/8
					dust.eflags = player.mo.eflags & MFE_VERTICALFLIP
					P_InstaThrust(dust, i*ANGLE_22h, 6*player.mo.scale)
					dust.momz = -2*P_MobjFlip(player.mo)*player.mo.scale
					dust.frame = $1|TR_TRANS60
				end
			end
		end
	end
end)

//Spring collision
addHook("MobjMoveCollide", function(mobj, spring)
	if (spring.flags & MF_SPRING)
		if (mobj.z <= spring.z + spring.height)
		and (spring.z <= mobj.z + mobj.height)
		and (mobj.skin == "werehog")
			mobj.player.customhoming = 0
			mobj.player.fisthoming = 0
			mobj.player.fistfoundtarget = false
		end
	end
	if (spring.type == MT_SPRINGSHELL and spring.health > 0) then
		local tmz = (spring.eflags & MFE_VERTICALFLIP and -((mobj.z + mobj.height) or 1) or mobj.z)
		local tmznext = (spring.eflags & MFE_VERTICALFLIP and -mobj.momz or mobj.momz) + tmz
		local thzh = (spring.eflags & MFE_VERTICALFLIP and -(spring.z or 1) or spring.z + spring.height)
		local sprarea = FixedMul(8*FRACUNIT, spring.scale) * P_MobjFlip(spring)
		if (((tmznext <= thzh) and (tmz > thzh)) or ((tmznext > thzh - sprarea) and (tmznext < thzh)))
		and (mobj.skin == "werehog")
			mobj.player.customhoming = 0
			mobj.player.fisthoming = 0
			mobj.player.fistfoundtarget = false
		end
	end
end, MT_PLAYER)

//Doesnt allow enemies to hurt you while doing the "WereSpin" or the "WereClaw"
addHook("ShouldDamage", function(target, inflictor, source, damage)
	if target and target.valid
		if target.skin == "werehog" 
			if target.player.twirling == true
			or target.state == S_PLAY_WERECLAW
				if (inflictor and inflictor.valid )
					if (inflictor.flags & MF_ENEMY or inflictor.flags & MF_BOSS)
						return false
					end
				end
			end
		end
	end
end, MT_PLAYER)

//Do Damage to enemies while doing the "WereSpin" or homing attack
addHook("PlayerCanDamage", function(player)
	if player.mo and player.mo.valid and player.mo.skin == "werehog"
	and (player.customhoming or player.twirling == true)
		return true
	end
end, MT_PLAYER)

//Small chance at starting the battle music when damaging an enemy
addHook("MobjDamage", function(enemy, werehog, werehog)
	if (werehog and werehog.valid and werehog.skin == "werehog")
	and werehog.player.battlemusic == 1
		if (enemy and enemy.valid and enemy.flags & (MF_ENEMY|MF_SHOOTABLE))
		and not (enemy.player)
		and not (enemy.flags & MF_BOSS)
			if werehog.player.werehogbattlemusic < TICRATE
				local music = P_RandomRange(0, 40)
				if music == 20
					werehog.player.werehogbattlemusic = 11*TICRATE
				end
			else
				werehog.player.werehogbattlemusic = 11*TICRATE
			end
		end
		return false
	end
end)

//Break spikes with WereSpin
addHook("MobjCollide", function(spike, werehog)
	if not (werehog.player and werehog.skin == "werehog")
	return nil 
	end
	if werehog.player.twirling == false
	return nil
	end
	if (werehog.z > spike.z+spike.height)
	or (spike.z > werehog.z+werehog.height)
		return nil 
	else
		spike.health = 0
		S_StartSound(werehog, spike.info.deathsound)
		P_KillMobj(spike, werehog, werehog)
	return false 
	end
end, MT_SPIKE)

//Start custom homing if the hand collides with something you can homein on
addHook("MobjMoveCollide", function(fist, mobj)
	if fist.valid
		if (mobj.valid and mobj.health)
		and mobj == fist.source.player.werehogrettarget
			if( fist.z > mobj.z+mobj.height) or (mobj.z > fist.z+fist.height)
				return nil
			end
			if not (mobj.flags2 & MF2_FRET)
			or mobj.flags & MF_SHOOTABLE
			or mobj.flags & MF_SPRING
				
				if fist.source.player.customhoming == 0
					fist.source.player.customhoming = 3*TICRATE
				end
				fist.source.player.fistfoundtarget = true
				return false 
			end
		end
	end
end, MT_WEREHOGFIST)

local function RunButton(player, arg)
	if player.mo and player.mo.valid
		if arg
			arg = arg:lower()
			if arg == "0"
			or arg == "false"
			or arg == "no"
			or arg == "off"
			or arg == "disable"
				player.runbuttondisable = 1
				CONS_Printf(player, "Run button is disabled.")
				if io and player == consoleplayer--this calls to save the data
					local file = io.openlocal(RUNFILE, "w+")
					file:write(player.runbuttondisable)
					file:close()
				end
			elseif arg == "true"
			or arg == "yes"
			or arg == "1"
			or arg == "on"
			or arg == "enable"
				player.runbuttondisable = 0
				CONS_Printf(player, "Run button is enabled.")
				if io and player == consoleplayer--this calls to save the data
					local file = io.openlocal(RUNFILE, "w+")
					file:write(player.runbuttondisable)
					file:close()
				end
			end
		else
			if player.runbuttondisable == 1
				CONS_Printf(player, "Enables/Disables the run button. Currently Disabled")
			else
				CONS_Printf(player, "Enables/Disables the run button. Currently Enabled")
			end
		end
	else
		CONS_Printf(player, "You must be in a level to use this")
	end
end

COM_AddCommand("runbutton", function(player, arg)
	RunButton(player, arg)
end)

COM_AddCommand("runbutton2", RunButton, COM_SPLITSCREEN)

local function JazzBand(player, arg)
	if player.mo and player.mo.valid
		if arg
			arg = arg:lower()
			if arg == "0"
			or arg == "false"
			or arg == "no"
			or arg == "off"
			or arg == "disable"
				player.battlemusic = 0
				CONS_Printf(player, "Battle music has been disabled.")
				if io and player == consoleplayer--this calls to save the data
					local file = io.openlocal(JAZZFILE, "w+")
					file:write(player.battlemusic)
					file:close()
				end
			elseif arg == "true"
			or arg == "yes"
			or arg == "1"
			or arg == "on"
			or arg == "enable"
				player.battlemusic = 1
				CONS_Printf(player, "Battle music has been enabled.")
				if io and player == consoleplayer--this calls to save the data
					local file = io.openlocal(JAZZFILE, "w+")
					file:write(player.battlemusic)
					file:close()
				end
			end
		else
			if player.battlemusic == 0
				CONS_Printf(player, "Enables/Disables the Battle music. Currently Disabled")
			else
				CONS_Printf(player, "Enables/Disables the Battle music. Currently Enabled")
			end
		end
	else
		CONS_Printf(player, "You must be in a level to use this")
	end
end

COM_AddCommand("jazzband", function(player, arg)
	JazzBand(player, arg)
end)

local function Chip(player, arg)
	if player.mo and player.mo.valid
		if arg
			arg = arg:lower()
			if arg == "0"
			or arg == "false"
			or arg == "no"
			or arg == "off"
			or arg == "disable"
				player.chipactive = 0
				if io and player == consoleplayer--this calls to save the data
					local file = io.openlocal(CHIPFILE, "w+")
					file:write(player.chipactive)
					file:close()
				end
				CONS_Printf(player, "Chip is disabled.")
			elseif arg == "true"
			or arg == "yes"
			or arg == "1"
			or arg == "on"
			or arg == "enable"
				player.chipactive = 1
				if io and player == consoleplayer--this calls to save the data
					local file = io.openlocal(CHIPFILE, "w+")
					file:write(player.chipactive)
					file:close()
				end
				CONS_Printf(player, "Chip is enabled.")
			end
		else
			if player.chipactive == 0
				CONS_Printf(player, "Enables/Disables Chip following you. Currently Disabled")
			else
				CONS_Printf(player, "Enables/Disables Chip following you. Currently Enabled")
			end
		end
	else
		CONS_Printf(player, "You must be in a level to use this")
	end
end

COM_AddCommand("chip", function(player, arg)
	Chip(player, arg)
end)

COM_AddCommand("chip2", Chip, COM_SPLITSCREEN)