freeslot("MT_TARGETDUMMY")

local buttontotext = {
[BT_CUSTOM1] = "Custom 1",
[BT_CUSTOM2] = "Custom 2",
[BT_CUSTOM3] = "Custom 3",
[BT_TOSSFLAG] = "Toss Flag",
[BT_ATTACK] = "Fire / Toss Ring",
[BT_FIRENORMAL] = "Fire Normal",
[0] = "None"
}

COM_AddCommand("spd_shieldbutton", function(player, arg) //A very shitty command, but it works!
	if player and player.valid
		if not arg
			CONS_Printf(player, "Change your shield button! \nButtons: C1, C2, C3, TF, Fire, Fire Normal")
			if player.shieldbutton and buttontotext[player.shieldbutton]
				CONS_Printf(player, "Current button: "..buttontotext[player.shieldbutton])
			else
				CONS_Printf(player, "Current button: \x85No button")
				CONS_Printf(player, "\x82(Always no button when first time using command)")
			end	
		else
			local var = string.lower(arg)
			if var == "custom1"
			or var == "c1"
				player.shieldbutton = BT_CUSTOM1
			end
			if var == "custom2"
			or var == "c2"
				player.shieldbutton = BT_CUSTOM2
			end
			if var == "custom3"
			or var == "c3"
				player.shieldbutton = BT_CUSTOM3
			end
			if var == "tossflag"
			or var == "tf"
				player.shieldbutton = BT_TOSSFLAG
			end
			if var == "fire"
			or var == "toss ring"
				player.shieldbutton = BT_ATTACK
			end
			if var == "fire normal"
			or var == "firen"
				player.shieldbutton = BT_FIRENORMAL
			end
			if var == "none"
			or var == "ihatethismod"
				player.shieldbutton = 0
			end
			local file = io.openlocal("client/spdconfig.cfg", "w")
			if file
				file:write(player.shieldbutton, "\n")
				file:close()
			end
		end
	else
		CONS_Printf(player, "You need to be in-game!")
	end
end)


for d = 1, 4
freeslot("S_DODGESKID"..d)
end
for p = 1, 9
freeslot("S_PARRYSHIELD"..p, "S_PARRYREVERSE"..p)
end
for s = 1, 8
freeslot("S_SHIELDPARDOG"..s)
end
freeslot("SPR_DDGD", "SPR_GRDP", "SPR_TRIG", "S_TRIANGPARRY", "SPR_SPDS")
states[S_SHIELDPARDOG1] = {SPR_SPDS, A, 2, nil, 0, 0, S_SHIELDPARDOG2}
states[S_SHIELDPARDOG2] = {SPR_SPDS, B, 2, nil, 0, 0, S_SHIELDPARDOG3}
states[S_SHIELDPARDOG3] = {SPR_SPDS, C, 2, nil, 0, 0, S_SHIELDPARDOG4}
states[S_SHIELDPARDOG4] = {SPR_SPDS, D, 2, nil, 0, 0, S_SHIELDPARDOG5}
states[S_SHIELDPARDOG5] = {SPR_SPDS, E, 2, nil, 0, 0, S_SHIELDPARDOG6}
states[S_SHIELDPARDOG6] = {SPR_SPDS, F, 2, nil, 0, 0, S_SHIELDPARDOG7}
states[S_SHIELDPARDOG7] = {SPR_SPDS, G, 2, nil, 0, 0, S_SHIELDPARDOG8}
states[S_SHIELDPARDOG8] = {SPR_SPDS, H, 2, nil, 0, 0, S_NULL}

states[S_DODGESKID1] = {SPR_DDGD, A, 4, nil, 0, 0, S_DODGESKID2}
states[S_DODGESKID2] = {SPR_DDGD, B, 4, nil, 0, 0, S_DODGESKID3}
states[S_DODGESKID3] = {SPR_DDGD, C, 4, nil, 0, 0, S_DODGESKID4}
states[S_DODGESKID4] = {SPR_DDGD, D, 4, nil, 0, 0, S_NULL}

states[S_PARRYSHIELD1] = {SPR_GRDP, A, 1, nil, 0, 0, S_PARRYSHIELD2}
states[S_PARRYSHIELD2] = {SPR_GRDP, B, 1, nil, 0, 0, S_PARRYSHIELD3}
states[S_PARRYSHIELD3] = {SPR_GRDP, C, 1, nil, 0, 0, S_PARRYSHIELD4}
states[S_PARRYSHIELD4] = {SPR_GRDP, D, 2, nil, 0, 0, S_PARRYSHIELD5}
states[S_PARRYSHIELD5] = {SPR_GRDP, E, 2, nil, 0, 0, S_PARRYSHIELD6}
states[S_PARRYSHIELD6] = {SPR_GRDP, F, 2, nil, 0, 0, S_PARRYSHIELD7}
states[S_PARRYSHIELD7] = {SPR_GRDP, G, 2, nil, 0, 0, S_PARRYSHIELD8}
states[S_PARRYSHIELD8] = {SPR_GRDP, H, 2, nil, 0, 0, S_PARRYSHIELD9}
states[S_PARRYSHIELD9] = {SPR_GRDP, I, 2, nil, 0, 0, S_NULL}

states[S_PARRYREVERSE1] = {SPR_GRDP, I, 2, nil, 0, 0, S_PARRYREVERSE2}
states[S_PARRYREVERSE2] = {SPR_GRDP, H, 2, nil, 0, 0, S_PARRYREVERSE3}
states[S_PARRYREVERSE3] = {SPR_GRDP, G, 2, nil, 0, 0, S_PARRYREVERSE4}
states[S_PARRYREVERSE4] = {SPR_GRDP, F, 2, nil, 0, 0, S_PARRYREVERSE5}
states[S_PARRYREVERSE5] = {SPR_GRDP, E, 2, nil, 0, 0, S_PARRYREVERSE6}
states[S_PARRYREVERSE6] = {SPR_GRDP, D, 2, nil, 0, 0, S_PARRYREVERSE7}
states[S_PARRYREVERSE7] = {SPR_GRDP, C, 2, nil, 0, 0, S_PARRYREVERSE8}
states[S_PARRYREVERSE8] = {SPR_GRDP, B, 2, nil, 0, 0, S_PARRYREVERSE9}
states[S_PARRYREVERSE9] = {SPR_GRDP, A, 2, nil, 0, 0, S_NULL}

states[S_TRIANGPARRY] = {SPR_TRIG, A|FF_FULLBRIGHT, 10, nil, 0, 0, S_NULL}

for i = 1, 9
spriteinfo[SPR_GRDP].pivot[i] = {x = 0, y = 0}
if i < 9
spriteinfo[SPR_SPDS].pivot[i] = {x = 0, y = 0}
end
end

local function SpawnSkidDodge(mo, ang) 
	for i = 1, 2
		local dust = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_PARTICLE)
		dust.state = S_DODGESKID1
		dust.renderflags = $|RF_PAPERSPRITE
		if i == 1
			dust.angle = ang + (ANG30*2)
		else
			dust.angle = ang - (ANG30*2)
		end
		P_InstaThrust(dust, dust.angle, 2*FRACUNIT)
	end
end

local function P_FlyTo(mo, fx, fy, fz, sped, addques)
	if mo.valid
		local flyto = P_AproxDistance(P_AproxDistance(fx - mo.x, fy - mo.y), fz - mo.z)
		if flyto < 1
			flyto = 1
		end
		local anglesucc = R_PointToAngle2(mo.x, mo.y, fx, fy)
		
		if addques
			mo.momx = $ + FixedMul(FixedDiv(fx - mo.x, flyto), sped)
			mo.momy = $ + FixedMul(FixedDiv(fy - mo.y, flyto), sped)
			mo.momz = $ + FixedMul(FixedDiv(fz - mo.z, flyto), sped)
		else
			mo.momx = FixedMul(FixedDiv(fx - mo.x, flyto), sped)
			mo.momy = FixedMul(FixedDiv(fy - mo.y, flyto), sped)
			mo.momz = FixedMul(FixedDiv(fz - mo.z, flyto), sped)
		end	
	end	
end

local GUARDTIME = 16 //You get 16 frames of shield
local DMGTIME = 25
local TRIGSTARTMOVE = 5
local PARRYTIME = 3

local function GuardParticle(mo, perf, startmove, overq, nopart, startpos) //Yomi Hustle parry thing
	local startran = (P_RandomRange(0, 360)*ANG1)
	for i = 1, 20
		if not nopart
			local dust = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_SPINDUST)
			dust.fuse = 12 + P_RandomRange(-2, 2)
			dust.scale = P_RandomRange(FRACUNIT/2, FRACUNIT-1)*P_RandomRange(1, 2)
			dust.destscale = FRACUNIT
			dust.scalespeed = FRACUNIT/7
			local ranang = (P_RandomRange(0, 360)*ANG1) + (((360/20)*i)*ANG1) + (P_RandomRange(-5, 5)*ANG1)
			local ranangz = (P_RandomRange(-90, 90)*ANG1) + (ANGLE_90-(((180/20)*i)*ANG1)) + (P_RandomRange(-5, 5)*ANG1)
			local ranx = FixedMul(cos(ranang), sin(ranangz))*25
			local rany = FixedMul(sin(ranang), sin(ranangz))*25
			local ranz = FixedMul(sin(ranang), sin(ranang))*15
			dust.momx = ranx
			dust.momy = rany
			dust.momz = ranz
		end
		if perf and perf > GUARDTIME-PARRYTIME
			local overqes = MT_PARTICLE
			if overq
				overqes = MT_OVERLAY
			end
			local trig = P_SpawnMobjFromMobj(mo, 0, 0, -mo.height, MT_PARTICLE)
			trig.state = S_TRIANGPARRY
			trig.target = mo
			if (i%4)==0
				trig.frame = B|FF_FULLBRIGHT
				trig.color = SKINCOLOR_CYAN
				trig.spriteyscale = (FRACUNIT/3*4)/2*3
				trig.spritexscale = (FRACUNIT/3*4)/2*3
			else
				trig.frame = A|FF_FULLBRIGHT
				trig.color = SKINCOLOR_CERULEAN
				trig.spriteyscale = P_RandomRange(FRACUNIT/4*3, FRACUNIT-1)
				trig.spritexscale = P_RandomRange(FRACUNIT/2, FRACUNIT-1)
			end
			trig.rollangle = startran + (((360/20)*i)*ANG1) + (P_RandomRange(-5, 5)*ANG1) //Random start offset + each angle + random offset
			local starpos = -10*FRACUNIT
			if startpos
				starpos = startpos
			end
			trig.spriteyoffset = FixedMul(starpos, cos(trig.rollangle))
			trig.spritexoffset = FixedMul(starpos, sin(trig.rollangle))
			trig.tics = 10
			trig.fuse = trig.tics
			trig.moveang = trig.rollangle
			local movestart = TRIGSTARTMOVE
			if startmove
				movestart = startmove
			end
			trig.startmove = movestart*FRACUNIT
		end
	end
end

addHook("PlayerThink", function(player)
	if player.valid and player.playerstate == PST_LIVE
	and not player.spectator and player.powers[pw_carry] != CR_NIGHTSMODE
		player.guardtimer = $ or 0
		player.dodgetime = $ or 0
		player.guarded = $ or 0
		player.throwmissile = $ or 0
		player.hitstop = $ or 0
		player.dmgtimer = $ or 0
		if player.dmgtimer 
			player.dmgtimer = $ - 1
			if player.dmgtimer < DMGTIME-PARRYTIME
				if player.dmgtimer == (DMGTIME-PARRYTIME)-1
					player.mo.momx = $/3
					player.mo.momy = $/3
					player.mo.momz = $/3
				end
				player.pflags = $|PF_FULLSTASIS
				if not P_IsObjectOnGround(player.mo)
					player.pflags = $|PF_JUMPED|PF_THOKKED|PF_NOJUMPDAMAGE
				end
				player.drawangle = player.stopang
				if player.mo.state != S_PLAY_SKID
					player.mo.state = S_PLAY_SKID
				end
				player.mo.frame = A
				player.mo.tics = -1
				player.hmmm = true
			end
			player.vulnerable = true
		else
			if player.vulnerable
				if player.mo.state == S_PLAY_SKID
				and player.hmmm
					if P_IsObjectOnGround(player.mo)
						player.mo.state = S_PLAY_STND
					else
						player.mo.state = S_PLAY_FALL
					end
				end
			end
			player.hmmm = false
			player.vulnerable = false
		end
		if player.shieldbutton == nil
			player.shieldbutton = BT_CUSTOM3
			local file = io.openlocal("client/spdconfig.cfg", "r")
			if file //I/O is pretty weird. And some people made a Gameboy emulator with it
				local readresult = file:read("*l")
				player.shieldbutton = readresult
				file:close()
			end
		end
		if player.hitstop
			player.hitstop = $ - 1
			if player.stopang
				player.pflags = $|PF_FULLSTASIS
				player.drawangle = player.stopang
				/*local cam = P_SpawnMobjFromMobj(player.mo, P_ReturnThrustX(nil, player.drawangle, -100*FRACUNIT), P_ReturnThrustY(nil, player.drawangle, -100*FRACUNIT), player.mo.height*P_MobjFlip(player.mo), MT_THOK)
				cam.flags2 = $|MF2_DONTDRAW
				cam.angle = player.drawangle
				player.awayviewmobj = cam //Teleport near the player
				player.awayviewtics = 3
				player.awayviewaiming = 0
				player.lastcampos = {
				x = cam.x,
				y = cam.y,
				z = cam.z
				}*/
				
				player.mo.momx = 0
				player.mo.momy = 0
				player.mo.momz = 0
				if player.mo.state != S_PLAY_SKID
					player.mo.state = S_PLAY_SKID
				end
				player.mo.frame = A
				player.mo.tics = -1
			end
			player.wasstopped = true
		else
			if player.wasstopped
				/*if player.lastcampos //Make camera move towards its position
					camera.momx = (player.lastcampos.x-camera.x)
					camera.momy = (player.lastcampos.y-camera.y)
					camera.momz = (player.lastcampos.z-camera.z)
				end*/
				if player.premomhitstop
					player.mo.momx = player.premomhitstop.x
					player.mo.momy = player.premomhitstop.y
					player.mo.momz = player.premomhitstop.z
				end
				if player.mo.state == S_PLAY_SKID
					if P_IsObjectOnGround(player.mo)
						player.mo.state = S_PLAY_STND
					else
						player.mo.state = S_PLAY_FALL
					end
				end
			end
			player.geercary = false
			player.wasstopped = false
		end
		if player.throwmissile
			player.throwmissile = $ - 1
			/*if consoleplayer == player //[Confusing II] Camera shit
				for i = 1, 5
					local aim = P_SpawnMobjFromMobj(player.mo, P_ReturnThrustX(nil, player.mo.angle, (10*FRACUNIT)*i),P_ReturnThrustY(nil, player.mo.angle, (10*FRACUNIT)*i), 0, MT_THOK)
					aim.fuse = 2
					aim.blendmode = AST_ADD
					aim.color = skincolors[player.mo.color].invcolor
					aim.scale = (FRACUNIT+(FRACUNIT/5)) - (i*(FRACUNIT/5))
				end
			end*/
		elseif (player.missiletype and ((not player.trackmissile) or (player.trackmissile and not player.trackmissile.valid) or (player.trackmissile and player.trackmissile.valid and player.trackmissile.health <= 0)))
			local targ = P_LookForEnemies(player, false, true)
			local misl
			if targ and targ.valid
				misl = P_SpawnMissile(player.mo, targ, player.missiletype)
			else
				misl = P_SPMAngle(player.mo, player.missiletype, player.mo.angle)
			end
			if misl and misl.valid
				local parry = P_SpawnMobjFromMobj(misl, 0, 0, 0, MT_OVERLAY)
				parry.target = misl
				parry.state = S_PARRYSHIELD1
				parry.parryover = true
				parry.spriteyoffset = misl.height/3
				parry.spriteyscale = FRACUNIT/2*3
				parry.spritexscale = FRACUNIT/2*3
				S_StartSound(misl, sfx_s3k7c)
			end
			player.missiletype = nil
		end
		if player.dodgetime
			player.dodgetime = $ - 1
			if not P_IsObjectOnGround(player.mo)
				if player.dodgeang
					player.drawangle = player.dodgeang
				end
				if player.mo.state != S_PLAY_SKID
					player.mo.state = S_PLAY_SKID
				end
				player.mo.frame = A
				player.mo.tics = -1
				player.pflags = $|PF_JUMPED|PF_THOKKED|PF_NOJUMPDAMAGE|PF_STASIS
				if (player.dodgetime%5) == 0
					local ghost = P_SpawnGhostMobj(player.mo)
					ghost.fuse = 5
				end
				player.nosked = true
			else
				player.dodgetime = 0
				if player.mo.state == S_PLAY_SKID
					player.mo.state = S_PLAY_STND
				end
			end
		else
			if player.mo.state == S_PLAY_SKID
			and player.nosked
				if P_IsObjectOnGround(player.mo)
					player.mo.state = S_PLAY_STND
				else
					player.mo.state = S_PLAY_FALL
				end
			end
			player.nosked = false
		end
		if player.dodgetime and player.dodgetime < 0
			player.dodgetime = 0
		end
		if player.guardtimer
			player.guardtimer = $ - 1 
		end
		if player.guarded 
			player.guarded = $ - 1
			player.pflags = $|PF_FULLSTASIS
			if player.mo.state != S_PLAY_SKID
				player.mo.state = S_PLAY_SKID
			end
			player.mo.frame = A
			player.mo.tics = -1
			player.justshat = true
		else
			if player.mo.state == S_PLAY_SKID
			and player.justshat
				if P_IsObjectOnGround(player.mo)
					player.mo.state = S_PLAY_STND
				else
					player.mo.state = S_PLAY_FALL
				end
			end
			player.justshat = false
		end
		player.grabtime = $ or 0
		player.addang = $ or 0
		if player.grabobj and player.grabobj.valid
			player.hadmobj = true
			player.addang = $ + ANG30
			if player.grabtime and player.startgrabtime
				player.grabtime = $ - 1
				local sgtime = player.startgrabtime
				local gtime = player.grabtime
				
				local invtime = (sgtime-gtime)
				local zang = FixedAngle((invtime*((90*FRACUNIT)/sgtime))) //I HATE ANGLES1!!1!!111!!
				
				local t = {}
				local rads = FixedMul(player.mo.radius*2, cos(zang))
				t.x = FixedMul(rads, cos(player.drawangle+player.addang))
				t.y = FixedMul(rads, sin(player.drawangle+player.addang))
				t.z = FixedMul(player.mo.height*P_MobjFlip(player.mo), cos(zang+ANGLE_270))
				if player.grabobj and player.grabobj.valid
					local enetarg = P_SpawnMobjFromMobj(player.grabobj, P_ReturnThrustX(nil, player.mo.angle, FRACUNIT*5), P_ReturnThrustY(nil, player.mo.angle, FRACUNIT*5), 0, MT_THOK)
					enetarg.flags2 = $|MF2_DONTDRAW
					enetarg.fuse = 2
					if (player.grabobj.flags & MF_MISSILE) //Try to make the enemy aim towards the player aim
					and not (player.grabobj.type == MT_PLAYER)
						player.grabobj.tracer = enetarg
					elseif not (player.grabobj.flags & MF_MISSILE)
						player.grabobj.target = enetarg
					end
					if not player.grabobj.player
						player.grabobj.movedir = -1
						player.grabobj.angle = player.mo.angle
					elseif player.grabobj.player and player.grabobj.player.valid
					and player.grabobj.player.playerstate == PST_LIVE
						player.grabobj.player.drawangle = player.mo.angle
						player.grabobj.state = S_PLAY_PAIN
						player.grabobj.player.pflags = $|PF_JUMPED & ~PF_NOJUMPDAMAGE
					end
					player.grabbedobject = true
					player.grabobj.isgrabbed = 15 //Have some rest before realizing you are flying across the level
					
					player.grabobj.momx = player.mo.momx
					player.grabobj.momy = player.mo.momy
					player.grabobj.momz = player.mo.momz
					P_TeleportMove(player.grabobj, player.grabobj.x, player.grabobj.y, player.mo.z+(player.mo.height/2)+t.z)
					P_TryMove(player.grabobj, player.mo.x+t.x, player.mo.y+t.y, true)
				end
			elseif player.grabbedobject
				if player.grabobj and player.grabobj.valid
					local mo = player.grabobj
					P_Thrust(mo, player.mo.angle, 15*FRACUNIT)
					P_SetObjectMomZ(mo, 5*FRACUNIT, true)
					S_StartSound(mo, sfx_s23c)
					player.plsthrowmissile = false
					player.grabtime = 0
					player.grabobj = 0
				end
				player.grabbedobject = false
			end
		else
			if player.hadmobj
				player.grabtime = 0
			end
			player.hadmobj = false
		end
		player.brake = $ or 0
		player.dododge = $ or 0
		player.stopbrake = $ or 0
		if player.brake
			player.brake = $ - 1
		end
		if player.dododge
			player.dododge = $ - 1
		end
		if P_GetPlayerControlDirection(player) == 2
			player.brake = 15
		elseif P_GetPlayerControlDirection(player) == 0
			if player.stopbrake > 15
				player.brake = 0
				player.stopbrake = 0
			else
				player.stopbrake = $ + 1
			end
		end
		if P_IsObjectOnGround(player.mo)
			player.airdodgebutitscool = false
			player.dodgedyes = 0
		end
		if player.cmd.buttons & BT_CUSTOM2
			if P_IsObjectOnGround(player.mo)
				player.dododge = 5
			elseif not player.airdodgebutitscool
				player.dododge = 5
			end
		end
		if player.shieldbutton and (player.cmd.buttons & player.shieldbutton)
			if not player.c1
			and not player.guardtimer
				if (player.brake or (player.dododge and (player.cmd.forwardmove or player.cmd.sidemove))) //Skidding? Dodging!
				and player.dodgedyes <= 15 //You can only do 15 of dodges (Metal no longer op af)
					player.dodgetime = 25
					local cmdang = player.cmd.angleturn<<16 + R_PointToAngle2(0, 0, player.cmd.forwardmove*FRACUNIT, -player.cmd.sidemove<<16)
					player.pflags = $ & ~PF_SPINNING
					player.dodgeang = cmdang+ANGLE_180
					SpawnSkidDodge(player.mo, cmdang+ANGLE_180)
					P_InstaThrust(player.mo, cmdang, 15*FRACUNIT)
					P_SetObjectMomZ(player.mo, 5*FRACUNIT, true)
					player.powers[pw_flashing] = player.dodgetime-5
					if player.dododge
						player.airdodgebutitscool = true
					end
					if not player.dodgedyes //Removing this will result in an OP situation
						player.dodgedyes = 1
					else
						player.dodgedyes = $ + 1
					end
					player.dododge = 0
					S_StartSound(player.mo, sfx_s3k47)
				elseif not player.dodgetime //Imma keep the funny bug
					player.guardtimer = GUARDTIME
					player.dmgtimer = DMGTIME
					player.stopang = player.drawangle
					S_StartSound(player.mo, sfx_s3k42)
					player.powers[pw_flashing] = 1
					if not P_IsObjectOnGround(player.mo)
						player.pflags = $|PF_JUMPED|PF_THOKKED|PF_NOJUMPDAMAGE
					end
					local shield = P_SpawnMobjFromMobj(player.mo, 0, 0, 0, MT_OVERLAY)
					shield.target = player.mo
					shield.state = S_SHIELDPARDOG1
					shield.spriteyscale = FRACUNIT/2*3
					shield.spritexscale = FRACUNIT/2*3
				end
			end
			player.c1 = true
		else
			player.c1 = false
		end
	end
end)

addHook("MobjThinker", function(mo)
	if mo and mo.valid
	and (mo.type == MT_PARTICLE
	or mo.type == MT_OVERLAY)
	and mo.state == S_TRIANGPARRY
		mo.startmove = $ or 0 
		if mo.startmove
			if mo.startmove > 0
				mo.startmove = $ - 1
			elseif mo.startmove < 0
				mo.startmove = $ + 1
			end
			if mo.moveang
				mo.spriteyoffset = $+FixedMul(mo.startmove,cos(mo.moveang))
				mo.spritexoffset = $+FixedMul(mo.startmove,sin(mo.moveang))
			end
			if mo.startmove == TRIGSTARTMOVE-3
				mo.spriteyscale = $/3
				//local addoff = 5*FRACUNIT
				//mo.spriteyoffset = $+FixedMul(addoff,cos(mo.moveang))
				//mo.spritexoffset = $+FixedMul(addoff,sin(mo.moveang))
			elseif mo.startmove < TRIGSTARTMOVE-3
				mo.spriteyscale = $ - ((TRIGSTARTMOVE*FRACUNIT)-mo.startmove)/25
			end
		end
	end
end)

addHook("PlayerCmd", function(player, cmd)
	if player and player.valid
	and player.mo.isgrabbed
		cmd.forwardmove = 0
		cmd.sidemove = 0
		cmd.buttons = $ & (~(BT_CAMLEFT|BT_CAMRIGHT|BT_JUMP|BT_SPIN|BT_CUSTOM1|BT_CUSTOM2|BT_CUSTOM3|BT_ATTACK|BT_FIRENORMAL|BT_TOSSFLAG))
	end
end)
addHook("MobjThinker", function(mo)
	if mo and mo.valid
	and ((mo.flags & MF_SHOOTABLE)
	or (mo.flags & MF_MISSILE)
	or (mo.type == MT_PLAYER))
		mo.isgrabbed = $ or 0
		if mo.isgrabbed
			mo.isgrabbed = $ - 1
		end
	end
end)
addHook("MobjDamage", function(mo) if mo and mo.valid and ((mo.flags & MF_SHOOTABLE) or (mo.flags & MF_MISSILE) or (mo.type == MT_PLAYER)) and mo.isgrabbed then return true end end)

addHook("MobjDamage", function(mo, mobj, src, dmg, dmgtype)
	if mo and mo.valid
	and mo.player and mo.player.valid
	and not (dmgtype & DMG_DEATHMASK)
		if mo.player.guardtimer
			local player = mo.player
			if player.guardtimer > GUARDTIME-PARRYTIME
				player.guarded = 1
				player.powers[pw_flashing] = flashingtics/2
				GuardParticle(mo, player.guardtimer) //Yomi Hustle parry no way!
				if mobj and mobj.valid
				and ((mobj.flags & MF_SHOOTABLE)
				or (mobj.flags & MF_MISSILE)
				or (mobj.type == MT_PLAYER)
				or (mobj.type == MT_TARGETDUMMY))
				and not mobj.isgrabbed
					if (mobj.flags & MF_BOSS)
						P_DamageMobj(mobj, mo, mo, 2)
						P_InstaThrust(mobj, R_PointToDist2(mobj.x+mo.momx, mobj.y+mo.momx, mo.x-mo.momx, mo.y-mo.momx), -20*FRACUNIT)
					else
						S_StartSound(mo, sfx_shattr)
						S_StartSound(mo, sfx_iceb)
						player.dmgtimer = 0
						if (mobj.flags & MF_MISSILE)
						and not ((mobj.type == MT_PLAYER))
							player.hitstop = 15
							player.stopang = player.drawangle
							player.premomhitstop = {}
							player.premomhitstop.x = player.mo.momx
							player.premomhitstop.y = player.mo.momy
							player.premomhitstop.z = player.mo.momz
							if player.guardtimer
								player.guardtimer = $ + player.hitstop //I hope nothing messes up
							end
							if player.powers[pw_flashing]
								player.powers[pw_flashing] = $ + player.hitstop
							end
							player.throwmissile = player.guardtimer/2
							player.missiletype = mobj.type
							player.trackmissile = mobj
							S_StartSound(mobj, sfx_s3k6d)
						end
						player.grabobj = mobj //Unidos go fly!
						if mobj.type == MT_TARGETDUMMY
							player.grabobj = mobj.target
						end
						player.startgrabtime = 3*TICRATE/2
						player.grabtime = (3*TICRATE/2)-1
						//player.startgrabtime = player.speed/FRACUNIT
						//player.grabtime = (player.speed/FRACUNIT)-1
						
						if not (mobj.flags & MF_MISSILE)
						and ((mobj.type == MT_PLAYER) or (mobj.type == MT_TARGETDUMMY))
							local parry = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY)
							parry.target = mobj
							parry.state = S_PARRYSHIELD1
							parry.parryover = true
							parry.spriteyoffset = mobj.height/3
							parry.spriteyscale = FRACUNIT/2*3
							parry.spritexscale = FRACUNIT/2*3
							
							S_StartSound(mobj, sfx_s23e)
						end
					end
				end
			else
				S_StartSound(player.mo, sfx_s3k82)
				player.guarded = 15
				player.powers[pw_flashing] = flashingtics/3
				GuardParticle(mo, player.guardtimer)
				if mobj and mobj.valid
					if R_PointToDist2(0, 0, mo.momx, mo.momx) > FRACUNIT
						P_InstaThrust(mo, R_PointToDist2(0, 0, mo.momx, mo.momx), -5*FRACUNIT)
						P_InstaThrust(mobj, R_PointToDist2(0, 0, mo.momx, mo.momx), 15*FRACUNIT)
					else
						P_InstaThrust(mo, player.drawangle, -5*FRACUNIT)
						P_InstaThrust(mobj, player.drawangle, 15*FRACUNIT)
					end
				end
				mo.momz = 0
			end
			return true
		end
		if mobj and mobj.valid
		and ((mobj.flags & MF_SHOOTABLE)
		or (mobj.flags & MF_MISSILE)
		or (mobj.type == MT_PLAYER)
		or (mobj.type == MT_TARGETDUMMY))
		and mobj.isgrabbed
			return true
		end
	end
end, MT_PLAYER)

addHook("MobjThinker", function(mo) if mo and mo.valid and mo.target and mo.target.valid and mo.parryover then mo.spriteyoffset = mo.target.height/3 end end, MT_OVERLAY)