// PTG Player Lua
// From Pizza Tower Discord
// Scripted by Basinga

// Sounds
freeslot(
// General
"sfx_ptgtlp","sfx_ptgbrt", "sfx_ptgbrc","sfx_ptgjmp",
"sfx_ptghel","sfx_ptgvom",
"sfx_ptgrg1","sfx_ptgrg2","sfx_ptgrg3","sfx_ptgrg4","sfx_ptgrg5","sfx_ptgrg6",
"sfx_ptgrgs", "sfx_ptgswy",
"sfx_ptglch", "sfx_ptglat",
"sfx_ptgjs1","sfx_ptgjs2","sfx_ptgjs3",
"sfx_ptgpn1","sfx_ptgpn2","sfx_ptgpn3","sfx_ptgpn4",
"sfx_ptgpc1","sfx_ptgpc2","sfx_ptgpc3","sfx_ptgpc4",
"sfx_ptgch1","sfx_ptgch2","sfx_ptgch3")

// Closed captions
sfxinfo[sfx_ptgtlp].caption = "Teleport"
sfxinfo[sfx_ptgjmp].caption = "Jump"
sfxinfo[sfx_ptgbrt].caption = "Beer thrown"
sfxinfo[sfx_ptgbrc].caption = "Beer impact"
sfxinfo[sfx_ptghel].caption = "Bible heal"
sfxinfo[sfx_ptgvom].caption = "Vomit"
sfxinfo[sfx_ptgswy].caption = "Fist swing"
sfxinfo[sfx_ptgrgs].caption = "Quad damage sound?"
sfxinfo[sfx_ptgrg1].caption = "Anger issues"
sfxinfo[sfx_ptgrg2].caption = "Anger issues"
sfxinfo[sfx_ptgrg3].caption = "Anger issues"
sfxinfo[sfx_ptgrg4].caption = "Anger issues"
sfxinfo[sfx_ptgrg5].caption = "Anger issues"
sfxinfo[sfx_ptgrg6].caption = "Anger issues"
sfxinfo[sfx_ptgjs1].caption = "JUMP!"
sfxinfo[sfx_ptgjs2].caption = "JUMP!"
sfxinfo[sfx_ptgjs3].caption = "JUMP!"
sfxinfo[sfx_ptgpn1].caption = "Punch connected!"
sfxinfo[sfx_ptgpn2].caption = "Punch connected!"
sfxinfo[sfx_ptgpn3].caption = "Punch connected!"
sfxinfo[sfx_ptgpn4].caption = "Punch connected!"
sfxinfo[sfx_ptgch1].caption = "Fart"
sfxinfo[sfx_ptgch2].caption = "Burp"
sfxinfo[sfx_ptgch3].caption = "Fart with Reverb"

//Graphics
freeslot(

"SPR2_VOMT",
"SPR2_RAGE",
"SPR2_BIBL",
"SPR2_GOKU",

"SPR_PTB1",
"SPR_PTB2",

"SPR_PTV1",
"SPR_PTV2",

"MT_THROWNBEER",
"S_THROWNBEER1",
"S_THROWNBEER2",
"S_THROWNBEERCYCLE",

"S_THROWNBEERCRASH1",
"S_THROWNBEERCRASH2",
"S_THROWNBEERCRASH3",


"MT_THROWNSUPERBEER",
"S_THROWNSUPERBEER1",
"S_THROWNSUPERBEER2",
"S_THROWNSUPERBEERCYCLE",

"S_THROWNSUPERBEERCRASH1",
"S_THROWNSUPERBEERCRASH2",
"S_THROWNSUPERBEERCRASH3",


"SPR_PTGT",
"MT_PTGTELEPORTFOG",
"S_PTGTELEPORTFOG",

"SPR_PTGF",
"MT_PTGFIST",
"S_PTGFIST1",
"S_PTGFIST2",
"S_PTGFIST3",
"S_PTGFISTSUCCESS1",
"S_PTGFISTSUCCESS2",
"S_PTGFISTFAIL",

"SPR_PTGL",
'MT_PTG_LASER',
'S_PTGLASER'

)

//Objects

//Laser
mobjinfo[MT_PTG_LASER] = {
	doomednum = -1,
	spawnstate = S_PTGLASER,
	SpawnHealth = 1000,
	ReactionTime = 8,
	Mass = 0,
  Damage = 0,
	speed = 200*FRACUNIT,
	radius = 16*FRACUNIT,
	height = 10*FRACUNIT,
	Damage = 80*FRACUNIT,
	flags = MF_MISSILE|MF_NOGRAVITY|MF_NOBLOCKMAP,
}

states[S_PTGLASER] = {SPR_PTGL, A|FF_FULLBRIGHT, -1, A_nil, 0, 0, S_PTGLASER}


//Beer
mobjinfo[MT_THROWNBEER] = {
	doomednum = -1,
	spawnstate = S_THROWNBEER1,
	deathstate = S_THROWNBEERCRASH1,
	xdeathstate = S_THROWNBEERCRASH1,
	SeeState = S_NULL,
	spawnhealth = 1,
	SeeSound = sfx_ptgbrt,
	deathsound = sfx_ptgbrc,
	xdeathsound = sfx_ptgbrc,
	speed = 60*FRACUNIT,
	radius = 16*FRACUNIT,
	height = 16*FRACUNIT,
	Damage = 80*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY,
	RaiseState = S_NULL,
	scale = 2*FRACUNIT/3
}


states[S_THROWNBEER1] = {SPR_PTB1, A|FF_FULLBRIGHT, 3, A_GhostMe, 4, 0, S_THROWNBEER2}
states[S_THROWNBEER2] = {SPR_PTB1, B|FF_FULLBRIGHT, 3, A_GhostMe, 4, 0, S_THROWNBEER1} 
states[S_THROWNBEERCRASH1] = {SPR_PTB2, A|FF_FULLBRIGHT, 3, nil, 0, 0, S_THROWNBEERCRASH2}
states[S_THROWNBEERCRASH2] = {SPR_PTB2, B|FF_FULLBRIGHT, 3, A_explode, 128, 0, S_THROWNBEERCRASH3}
states[S_THROWNBEERCRASH3] = {NULL, A|FF_FULLBRIGHT, 60, nil, 0, 0, S_NULL}


addHook("MobjThinker", function(mobj)

	if mobj.state == S_THROWNBEERCRASH1
		S_StartSound(mobj, sfx_ptgbrc)
		mobj.state = S_THROWNBEERCRASH2
	end

end,MT_THROWNBEER)


//Super Beer
mobjinfo[MT_THROWNSUPERBEER] = {
	doomednum = -1,
	spawnstate = S_THROWNSUPERBEER1,
	deathstate = S_THROWNSUPERBEERCRASH1,
	xdeathstate = S_THROWNSUPERBEERCRASH1,
	SeeState = S_NULL,
	spawnhealth = 1,
	SeeSound = sfx_ptgbrt,
	deathsound = sfx_ptgbrc,
	xdeathsound = sfx_ptgbrc,
	speed = 120*FRACUNIT,
	radius = 16*FRACUNIT,
	height = 16*FRACUNIT,
	Damage = 80*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY,
	RaiseState = S_NULL,
	scale = 2*FRACUNIT/3
}


states[S_THROWNSUPERBEER1] = {SPR_PTV1, A|FF_FULLBRIGHT, 3, A_GhostMe, 4, 0, S_THROWNSUPERBEER2}
states[S_THROWNSUPERBEER2] = {SPR_PTV1, B|FF_FULLBRIGHT, 3, A_GhostMe, 4, 0, S_THROWNSUPERBEER1} 
states[S_THROWNSUPERBEERCRASH1] = {SPR_PTV2, A|FF_FULLBRIGHT, 3, nil, 0, 0, S_THROWNSUPERBEERCRASH2}
states[S_THROWNSUPERBEERCRASH2] = {SPR_PTV2, B|FF_FULLBRIGHT, 3, A_explode, 128, 0, S_THROWNSUPERBEERCRASH3}
states[S_THROWNSUPERBEERCRASH3] = {NULL, A|FF_FULLBRIGHT, 60, nil, 0, 0, S_NULL}


addHook("MobjThinker", function(mobj)

	if mobj.state == S_THROWNBEERCRASH1
		S_StartSound(mobj, sfx_ptgbrc)
		mobj.state = S_THROWNBEERCRASH2
	end

end,MT_THROWNBEER)


//Fist
mobjinfo[MT_PTGFIST] = {
	doomednum = -1,
	spawnstate = S_PTGFIST1,
	deathstate = S_PTGFISTFAIL,
	xdeathstate = S_PTGFISTSUCCESS1,
	SeeState = S_NULL,
	spawnhealth = 1,
  deathsound = nil,
	xdeathsound = nil,
	speed = 60*FRACUNIT,
	radius = 16*FRACUNIT,
	height = 16*FRACUNIT,
	Damage = 80*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_MISSILE|MF_NOGRAVITY,
	RaiseState = S_NULL,
	scale = 2*FRACUNIT/4,
	reactionTime = 6
}


states[S_PTGFIST1] = {SPR_PTGF, A, 2, A_Explode, 128, 2, S_PTGFIST2}
states[S_PTGFIST2] = {SPR_PTGF, B, 2, A_GhostMe, 3, 2, S_PTGFIST3}
states[S_PTGFIST3] = {SPR_PTGF, C, 2, A_GhostMe, 3, 2, S_PTGFISTFAIL}
states[S_PTGFISTSUCCESS1] = {NULL, A, 50, nil, 0, 0, S_PTGFISTSUCCESS2} 
states[S_PTGFISTSUCCESS2] = {NULL, A, 50, nil, 0, 0, S_NULL}
states[S_PTGFISTFAIL] = {NULL, A, 3, nil, 0, 0, S_NULL}


addHook("MobjThinker", function(mobj)
	
	if mobj.state == S_PTGFISTSUCCESS1
	
		local randomNumber = P_RandomRange(1, 4)

		local table = {
		[1] = sfx_ptgpc1,
		[2] = sfx_ptgpc2,
		[3] = sfx_ptgpc3,
		[4] = sfx_ptgpc4
		}
		
		S_StartSound(mobj, table[randomNumber])
		mobj.state = S_PTGFISTSUCCESS2
	end

end,MT_PTGFIST)

//Teleport Fog
mobjinfo[MT_PTGTELEPORTFOG] = {
	doomednum = -1,
	spawnstate = S_PTGTELEPORTFOG,
	deathstate = S_NULL,
	SeeState = S_NULL,
	SeeSound = sfx_ptgtlp,
	spawnhealth = 1,
	speed = 0*FRACUNIT,
	radius = 1*FRACUNIT,
	height = 1*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY,
}

states[S_PTGTELEPORTFOG] = {SPR_PTGT, A|FF_ANIMATE, 60, NIL, 10, 6, S_NULL}

//Tier UI
//Graphics
freeslot(

"SPR_PTT1",
"SPR_PTT2",
"SPR_PTT3",
"SPR_PTT4",
"SPR_PTT5",
"SPR_PTT6",
"SPR_PTTG",

"MT_THROWNBEER",
"S_THROWNBEER1",
"S_THROWNBEER2",
"S_THROWNBEERCYCLE",

"S_THROWNBEERCRASH1",
"S_THROWNBEERCRASH2"

)

//States
freeslot(
"S_PTG_THROWBOTTLE",
"S_PTG_HEAL1",
"S_PTG_HEAL2",
"S_PTG_HEAL3",

"S_PTG_VOMIT1",
"S_PTG_VOMIT2",
"S_PTG_VOMIT3",

"S_PTG_RAGE",
"S_PTG_LASER1"

)




states[S_PTG_THROWBOTTLE] = {
	sprite = SPR_PLAY,
	frame = SPR2_MLEE,
	tics = 20,
	action = nil,
	var1 = 0,
	var2 = 0,
	nextstate = S_PLAY_FALL
}

states[S_PTG_HEAL1] = {
	sprite = SPR_PLAY,
	frame = SPR2_BIBL,
	tics = 1000,
	action = nil,
	var1 = 0,
	var2 = 0,
	nextstate = S_PTG_HEAL2
}
states[S_PTG_HEAL2] = {
	sprite = SPR_PLAY,
	frame = SPR2_BIBL,
	tics = 15,
	action = nil,
	var1 = 0,
	var2 = 0,
	nextstate = S_PTG_HEAL3
}
states[S_PTG_HEAL3] = {
	sprite = SPR_PLAY,
	frame = SPR2_BIBL,
	tics = 15,
	action = nil,
	var1 = 0,
	var2 = 0,
	nextstate = S_PLAY_FALL
}

states[S_PTG_VOMIT1] = {
	sprite = SPR_PLAY,
	frame = SPR2_VOMT,
	tics = 1000,
	action = nil,
	var1 = 0,
	var2 = 0,
	nextstate = S_PTG_VOMIT2
}
states[S_PTG_VOMIT2] = {
	sprite = SPR_PLAY,
	frame = SPR2_VOMT,
	tics = 10,
	action = nil,
	var1 = 0,
	var2 = 0,
	nextstate = S_PTG_VOMIT3
}
states[S_PTG_VOMIT3] = {
	sprite = SPR_PLAY,
	frame = SPR2_VOMT,
	tics = 10,
	action = nil,
	var1 = 0,
	var2 = 0,
	nextstate = S_PLAY_FALL
}

states[S_PTG_RAGE] = {
	sprite = SPR_PLAY,
	frame = SPR2_RAGE,
	tics = 1000,
	action = nil,
	var1 = 0,
	var2 = 0,
	nextstate = S_PLAY_FALL
}

states[S_PTG_LASER1] = {
	sprite = SPR_PLAY,
	frame = SPR2_GOKU,
	tics = 1000,
	action = nil,
	var1 = 0,
	var2 = 0,
	nextstate = S_PLAY_FALL
}




//Player counting script by Flame
local function countPlayers()
    local playercount = 0
    for p in players.iterate
        playercount = $ + 1
    end
    return playercount 
end

//Kirby junk
if not kirbyabilitytable
    rawset(_G, "kirbyabilitytable", {})
end

kirbyabilitytable["ptg"] = 13

// Recharge exists
local function initPTGTables(mobj)
		  mobj.meter = 0
			mobj.metermax = 525
		  mobj.tier = 0
			mobj.prayerTimer =  0
			mobj.vomitTimer = 0
			mobj.rageTimer = 0
			mobj.ragePowerUpTimer = 0
			mobj.laserTimer = 0
			mobj.teleportTimer = 0
			mobj.springReference = nil
end

//Function for resetting/throwing bottles 
local throwBottle = function(player, objectThrown)
	if not player.mo and player.mo.valid
		print("The PTG executing this doesn't exist!")
	end
	
	if  player.mo.state == S_PTG_VOMIT1 or player.mo.state == S_PTG_RAGE
		return
	end
	
	player.mo.state = S_PTG_THROWBOTTLE
	S_StartSound(player.mo, sfx_ptgbrt)
	
	if player.mo.meter > 50
		player.mo.meter = $ - 50
	else
		player.mo.meter = 0
	end
			
	//Aim your throw
	//You can only aim players at objects if they're on your team
	//Pushables and bots can't be aimed at monitors
	local lockon = P_LookForEnemies(player, false)
	if lockon and lockon.valid and !player.aiming
		player.mo.angle = R_PointToAngle2(player.mo.x, player.mo.y, lockon.x, lockon.y)
		player.drawangle = player.mo.angle
		P_SpawnMissile(player.mo,lockon,objectThrown)	
		
	else
		P_SpawnPlayerMissile(player.mo,objectThrown)
	end

end

//Teleporting
local teleporting = function(player)
	
	local xPosition = 0
	local yPosition = 0
	local zPosition = 0
	
	//Check if there's more than 1 player in the server
	

	local playerCount = countPlayers()
	if(playerCount > 1)
		local choosePlayerNumber = P_RandomRange(0,playerCount-1)
		local needCheck = true
		while (needCheck) do
			local playercount2 = 0
			local chosenPlayer = nil

			for otherPlayer in players.iterate
				//If this is the number I want
				if playercount2 == choosePlayerNumber
					if otherPlayer == player
						choosePlayerNumber = P_RandomRange(0,playerCount-1)
						break
					else
						xPosition = otherPlayer.mo.x/FRACUNIT
						yPosition = otherPlayer.mo.y/FRACUNIT
						zPosition = otherPlayer.mo.z/FRACUNIT
						needCheck = false
						break
					end
				end
			
				playercount2 = $ + 1
			end
		end		
	else
		xPosition = player.starpostx
		yPosition = player.starposty
		zPosition = player.starpostz
	
	end
	
	
	//Get the last checkpoint's location

	
	if (xPosition == 0 and yPosition == 0 and zPosition == 0)
		//CancelTeleport
-- 		xPosition = player.starpostx
-- 		yPosition = player.starposty
-- 		zPosition = player.starpostz
		return
	end
	
		if not P_IsObjectOnGround(player.mo)
	
	local randomNumber = P_RandomRange(1, 4)

		local table = {
		[1] = sfx_ptgpn1,
		[2] = sfx_ptgpn2,
		[3] = sfx_ptgpn3,
		[4] = sfx_ptgpn4
		}
		
		S_StartSound(mobj, table[randomNumber])
		
		player.rings = 0
		player.mo.tier = 0
		player.mo.meter = 0
		
	end

	P_SpawnPlayerMissile(player.mo,MT_PTGTELEPORTFOG)
	S_StartSound(player.mo, sfx_ptgtlp)	
	P_TeleportMove(player.mo,xPosition*FRACUNIT,yPosition*FRACUNIT,zPosition*FRACUNIT)
	P_SpawnPlayerMissile(player.mo,MT_PTGTELEPORTFOG)
	

	
	player.mo.teleportTimer = 100
	S_StartSound(player.mo, sfx_ptgtlp)

	

end

local function squishedCheck(player)
	local height = FixedMul(player.height, player.mo.scale)
	if(player.mo.ceilingz - player.mo.floorz < FixedMul(height, player.mo.scale))
		return true
	end
	return false
end

local function randomJumpSound()

	local randomNumber = P_RandomRange(1, 8)

	local table = {
	[1] = sfx_ptgjs1,
	[2] = sfx_ptgjs2,
	[3] = sfx_ptgjs3,
	[4] = nil,
	[5] = nil,
	[6] = nil,
	[7] = nil,
	[8] = nil,
	}
	
	return table[randomNumber]
	
end

//JumpCharge
local jumpCharging = function(player)
	
	local jumpMaxCharge = 25
	local absolutelyCantMove =
				((gametyperules & GTR_RACE) and leveltime < 4*TICRATE)
				or ((player.pflags & PF_FINISHED) > 0 and CV_FindVar("exitmove").value == 0)
				or player.exiting
				or player.powers[pw_carry] == CR_NIGHTSMODE
				or false
	local canMove = not absolutelyCantMove and P_IsObjectOnGround(player.mo)
	
	local canSquish = true

	local jumpForce = FRACUNIT*18
	local minimumJumpForce = FRACUNIT*5
	local isrevgrav = (player.mo.eflags & MFE_VERTICALFLIP) > 0
	local gravdir = not isrevgrav and 1 or -1
	local gravdirz = isrevgrav and 1 or 0
	local ngravdirz = not isrevgrav and 1 or 0
	
	//Check if button is being pressed
	if not canSquish
		player.buttons.jump = 0
	end
	
	player.jumpcharge = player.buttons.jump or $ 
	
	if player.jumpcharge and player.jumpcharge > 1 
		and player.powers[pw_carry] ~= CR_MINECART
		and player.powers[pw_carry] ~= CR_ZOOMTUBE
		and player.powers[pw_carry] ~= CR_NIGHTSMODE
		local squish =  FixedDiv(FRACUNIT/2, FRACUNIT/2 +(FRACUNIT/jumpMaxCharge*min(player.jumpcharge,jumpMaxCharge))/2 )
		player.mo.spriteyscale = squish
		
		if(player.jumpcharge >= jumpMaxCharge)
			player.height = $1 / 6
		end 
		
	else
		player.mo.spriteyscale = FRACUNIT
	end
	
	if player.buttonsRelease.jump == 1  then
		local cpow = player.powers[pw_carry]
		if not squishedCheck(player)
			if (canMove or cpow) or (player.powers[pw_super] and not(absolutelyCantMove) )  then
				if cpow > 0
				and cpow ~= CR_MINECART
				and cpow ~= CR_ZOOMTUBE
				and cpow ~= CR_NIGHTSMODE
				then
					player.powers[pw_carry] = CR_NONE
					player.mo.tracer.target = nil
					player.mo.tracer = nil
					player.powers[pw_flashing] = 4
				end
				local force = FixedMul(jumpForce, FRACUNIT/jumpMaxCharge*min(player.jumpcharge,jumpMaxCharge))*gravdir
				if abs(force) < minimumJumpForce
					force = minimumJumpForce*gravdir
				end
				
				
				
				if  cpow ~= CR_MINECART
				and cpow ~= CR_ZOOMTUBE
				and cpow ~= CR_NIGHTSMODE
				then 

					S_StartSound(player.mo, sfx_ptgjmp) 
					
					if abs(force) > 15
						local getSound = randomJumpSound()
						if getSound and force > jumpMaxCharge-minimumJumpForce
							S_StartSound(player.mo, getSound) 
						end
					end
					
					if (player.mo.eflags & MFE_UNDERWATER)
						force = 2*force/3
					end
					
					player.mo.momz = force
					player.pflags = $|PF_JUMPED
					player.jumpcharge = 0
				else
					player.jumpcharge = 0
				end
			else
				player.jumpcharge = 0
			end
		end
		
	end
		
end

//Sleep Sliding

//JumpCharge
local sleepSlidingCheck = function(player)
		
		//Spin Dust!
		player.spinitem = MT_NULL
		if player.pflags & PF_SPINNING
		and not (player.pflags & PF_STARTDASH)
		and P_IsObjectOnGround(player.mo)
			if leveltime & 2
				S_StartSound(player.mo, sfx_s3k7e)
			end
			for i=(leveltime%7)/2,(leveltime%7) do
				local particle = P_SpawnMobj(player.mo.x, player.mo.y,
				player.mo.z + ((player.mo.eflags & MFE_VERTICALFLIP)/MFE_VERTICALFLIP * (player.mo.height - mobjinfo[MT_SPINDUST].height)), MT_SPINDUST)
				if (player.powers[pw_shield] == SH_ELEMENTAL and not (player.mo.eflags & MFE_TOUCHWATER or player.mo.eflags & MFE_UNDERWATER)) then
					particle.state = S_SPINDUST_FIRE1
					particle.bubble = false
				elseif (player.mo.eflags & MFE_TOUCHWATER or player.mo.eflags & MFE_UNDERWATER) then
					particle.state = S_SPINDUST_BUBBLE1
					particle.bubble = true
				else
					particle.state = S_SPINDUST1
					particle.bubble = false
				end
				particle.target = player.mo
				particle.eflags = $1 | (player.mo.eflags & MFE_VERTICALFLIP)
				particle.scale = player.mo.scale*2/3
				P_SetObjectMomZ(particle, player.speed/FRACUNIT*FRACUNIT/50+P_RandomByte()<<10, false)
				P_InstaThrust(particle, player.drawangle+(P_RandomRange(-ANG30/FRACUNIT, ANG30/FRACUNIT)*FRACUNIT), FixedMul(-player.speed/FRACUNIT*FRACUNIT/6-1*FRACUNIT-P_RandomByte()<<11, player.mo.scale))
				P_TryMove(particle, particle.x+particle.momx, particle.y+particle.momy, true)
			end
		end
			
		
		if player.speed <= FixedMul(4*FRACUNIT+FRACUNIT/2, player.mo.scale)
		and not (player.pflags & PF_SPINNING)
			player.charability2 = CA2_NONE
		else
			if 	(player.mo.tier == 0)	and (player.buttons.spin < 1 or player.buttons.custom2 < 1)
				player.charability2 = CA2_SPINDASH
			else
				player.charability2 = CA2_NONE
			end
			
		end
		if player.pflags & PF_STARTDASH
			player.pflags = $1 & ~PF_SPINNING
			player.pflags = $1 & ~PF_STARTDASH
		end
		
end
	

//Deepcopy from amberbee
rawset(_G, "deepcopy", function(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in next, orig, nil do
            copy[deepcopy(orig_key)] = deepcopy(orig_value)
        end
        setmetatable(copy, deepcopy(getmetatable(orig)))
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end)

//Button checking from amberbee
local buttonChecking = function(player)
	if deepcopy == nil then error("deepcopy missing", 2) end
	
	if not player.buttonsTimestamp then player.buttonsTimestamp = leveltime-1 end
	
	local cmdButtons = player.cmd.buttons
	
	if player.buttonsTimestamp ~= leveltime then
	
		
		if not player.buttons then
				player.buttons = {
					spin = 0,
					jump = 0,
					custom2 = 0,

				}
				player.buttonsRelease = deepcopy(player.buttons)
				for k,v in pairs(player.buttonsRelease) do
					player.buttonsRelease[k] = 999
				end
		end
		player.buttons.spin = (cmdButtons & BT_USE) > 0 and $+1 or 0
		player.buttons.custom2 = (cmdButtons & BT_CUSTOM2) > 0 and $+1 or 0
		player.buttons.jump = (cmdButtons & BT_JUMP) > 0 and $+1 or 0
		player.buttonsRelease.spin = player.buttons.spin == 0 and $+1 or 0
		player.buttonsRelease.custom2 = player.buttons.custom2 == 0 and $+1 or 0
		player.buttonsRelease.jump = player.buttons.jump == 0 and $+1 or 0
		
		player.buttonsTimestamp = leveltime

	end
	
	
end

//Get everything nearby
local function giveRingsToAllNearby(player)
	local range = 368*FRACUNIT
	local m = player.realmo
	
	//Return random shield name
	local randomNumber = P_RandomRange(1, 8)
	local table = 
	{
	[1] =  SH_WHIRLWIND,
	[2] =  SH_ARMAGEDDON,
	[3] =  SH_PINK,
	[4] =  SH_ELEMENTAL,
	[5] =  SH_ATTRACT,
	[6] =  SH_FLAMEAURA,
	[7] =  SH_BUBBLEWRAP,
	[8] =  SH_THUNDERCOIN
	}
	
	P_SwitchShield(player, table[randomNumber])
	randomNumber = P_RandomRange(1, 8)
	
	//This checks for every 
	searchBlockmap("objects", function(ref, found)
			
		-- We only care about rings
		if found.type == MT_PLAYER then
				P_SwitchShield(found.player, table[randomNumber])
				if player.powers[pw_super]
					P_GivePlayerRings(found.player,10)
				else
					P_GivePlayerRings(found.player,50)
				end
				
				
		end

	end, m, m.x-range, m.x+range, m.y-range, m.y+range)


end

//PrayerStateChecker
local function prayerTick (player)

	if (player.mo.prayerTimer > 0)
	
		if P_PlayerInPain(player)
		or (player.pflags & PF_SLIDING)
		or (player.pflags & PF_SPINNING)
		or player.exiting
		or player.powers[pw_carry]
		or not player.mo.health
		or (player.panim == PA_PAIN and not (player.pflags&PF_JUMPED))
		or P_SuperReady(player)
		//or not P_IsObjectOnGround(mo)
		or player.mo.state == S_PTG_THROWBOTTLE
		or player.mo.state == S_PLAY_MELEE or player.mo.state == S_PLAY_FIRE
			player.mo.prayerTimer = 0
			return
		end
		
		player.mo.prayerTimer = $ - 1
		player.mo.state = S_PTG_HEAL1
		
		if (player.mo.prayerTimer <= 0)
			
			player.mo.state = S_PLAY_FALL
			
		end
		
	end

end

//Prayer
local function prayer(player)
	
	S_StartSound(player.mo, sfx_ptghel)
	player.mo.tier = 0
	player.mo.meter = 0
	player.mo.prayerTimer = 50
	giveRingsToAllNearby(player)
	

end

COM_AddCommand("giveTier", function(player)
    player.mo.tier = 1
end)

//Aiming From egg robo by CobaltBW

local function PlayerCanBeDamaged(player)
	if not(player.playerstate == PST_LIVE) then return false end
	if player.powers[pw_invulnerability] then return false end
	if player.powers[pw_super] then return false end
	if player.powers[pw_flashing] then return false end
	return true
end

local function GetZAngle(x1,y1,z1,x2,y2,z2)
	local xydist = R_PointToDist2(x1,y1,x2,y2)
	local zdist = z2-z1
	return R_PointToAngle2(0,0,xydist,zdist)
end

local function MyTeam(player,myplayer)
	//Check yourself before you wreck yourself
	if myplayer == player then return true end
	//SP/coop checks
	if G_PlatformGametype() return true end
	//CTF checks
	if G_GametypeHasTeams() then
		if player.ctfteam == myplayer.ctfteam then return true
		else return false
		end
	end
	//Tag checks
	if G_TagGametype() then
		if player.pflags&PF_TAGIT == myplayer.pflags&PF_TAGIT then return true
		else return false
		end
	end
	return false
end

local function GetNearestPlayer(mo,fov,teamcheck,aim,ignorepain)
	if not(mo.player) and not (teamcheck == nil or teamcheck == 0) then return nil end //Teamchecks aren't allowed on nonplayer objects
	local nearest
	local neardist
	//Cycle through players
	for player in players.iterate
		//Failchecks
		if not (player.mo and player.playerstate == PST_LIVE) then continue end //Invalid player object
		if player.mo == mo then continue end // Don't count ourselves!
		if (teamcheck == 1 and not(MyTeam(player,mo.player))) //Need teammate
			or (teamcheck == -1 and MyTeam(player,mo.player)) //Need opponent
			or not(P_CheckSight(player.mo,mo)) //Not in view
			or player.mo.flags&MF_NOCLIPTHING //Can't target!
			then continue
		end
		if ignorepain == true and not(PlayerCanBeDamaged(player)) then continue end //Ignore invulnerable players
		if fov != nil then
			if aim == nil then aim = mo.angle end
			//Get angle
			local ang = R_PointToAngle2(mo.x,mo.y,player.mo.x,player.mo.y)-aim
			if ang > 180*ANG1 then ang = $-360*ANG1
			elseif ang < -180*ANG1 then ang = $+360*ANG1
			end
			//Check field of view
			if (ang < -fov/2*ANG1 or ang > fov/2*ANG1) then continue end
		end
		//Get distance
		local dist = R_PointToDist2(player.mo.x,player.mo.y,mo.x,mo.y)
		if nearest == nil or neardist > dist then
			nearest = player
			neardist = dist
		end
	end
	return nearest
end

local function SearchObject(mo,aim,fov,range,searchflags,refmo,teamcheck)
		if refmo == nil then refmo = mo end
		local team
		if not(teamcheck == nil or teamcheck == 0) then
			if (mo.player) then
				team = mo.player.ctfteam
			else
				team = mo.ctfteam
			end
			if team == nil or team == 0 then
				team = 0
				teamcheck = 0
			end
		end
		local m = nil
		searchBlockmap('objects',function(mo,found)
			local dist = R_PointToAngle2(mo.x,mo.y,found.x,found.y)
			local angle = abs(dist-aim)
			if found != refmo and found.flags&searchflags and P_CheckSight(mo,found) and found.health and abs(angle) < fov/2*ANG1
				and (
					(teamcheck == nil or teamcheck == 0) or (teamcheck == 1 and team == found.ctfteam) or (teamcheck == -1 and team != found.ctfteam)
				)
				and (
					not(m and m.valid) 
					or (R_PointToDist2(mo.x,mo.y,m.x,m.y)+abs(mo.z-m.z) > R_PointToDist(mo.x,mo.y,found.x,found.y)+abs(mo.z-found.z))
				) then
				m = found
			end
		end,mo,mo.x-range,mo.x+range,mo.y-range,mo.y+range)
		return m
end

local function InstaThrustZAim(mo,xyangle,zangle,speed)
	local xythrust = P_ReturnThrustX(nil,zangle,speed)
	local zthrust = P_ReturnThrustY(nil,zangle,speed)
	P_InstaThrust(mo,xyangle,xythrust)		
	mo.momz = $+zthrust	
end

local function ERLShift(laser)
	if laser.target and laser.target.valid and laser.target.player  then
		local dist = FRACUNIT*76
		local angle = -ANGLE_22h
		if laser.target.player.storeangle != nil then angle = $+laser.target.player.storeangle
		else angle = $+laser.target.angle
		end
		local x = laser.target.x+P_ReturnThrustX(nil,angle,dist)
		local y = laser.target.y+P_ReturnThrustY(nil,angle,dist)
		local z = laser.target.z+laser.target.scale*48
		P_TeleportMove(laser,x,y,z)
	else
		P_RemoveMobj(laser)
	end
end

local function createLaserPart(mo,aim,fov,teamcheck,ignorepain,projectile,speed,searchflags)
	local p = GetNearestPlayer(mo,fov,teamcheck,aim,ignorepain)
	if p then 
		local dist = FixedHypot(FixedHypot(p.mo.momx,p.mo.momy),p.mo.momz)
		local x1,y1,z1 = projectile.x,projectile.y,projectile.z
		local x2,y2,z2 = p.mo.x+p.mo.momx,p.mo.y+p.mo.momy,p.mo.z+p.mo.height/2+p.mo.momz
		local zang = GetZAngle(x1,y1,z1,x2,y2,z2)
		local xyang = R_PointToAngle2(x1,y1,x2,y2)
		InstaThrustZAim(projectile,xyang,zang,speed)
		return p.mo
	else
		local p = SearchObject(mo,aim,fov,mo.scale*640,searchflags,nil,teamcheck)
		if p then
			local x1,y1,z1 = projectile.x,projectile.y,projectile.z
			local x2,y2,z2 = p.x+p.momx,p.y+p.momy,p.z+p.momz
			local zang = GetZAngle(projectile.x,projectile.y,projectile.z,p.x,p.y,p.z+projectile.height/2)
			local xyang = R_PointToAngle2(x1,y1,x2,y2)
			InstaThrustZAim(projectile,xyang,zang,speed)
			return p
		end
	end
	return false

end

local function generateLaser(player,xSpeedDifference)
			local laser1 = P_SPMAngle(player.mo,MT_PTG_LASER,player.drawangle)
-- 			local laser1 = P_SpawnMobjFromMobj(player.mo,xRelativeOffset,0,24,MT_PTG_LASER)
			
			//P_InstaThrust(player.mo,player.drawangle+ANGLE_180,player.mo.scale*3)
			if laser1 and laser1.valid then
			laser1.scale = player.mo.scale*3
				ERLShift(laser1)
-- 			if mo.player.autoaim then
				createLaserPart(player.mo,player.drawangle,60,-1,true,laser1,(player.mo.scale*110+xSpeedDifference),MF_MONITOR|MF_BOSS|MF_ENEMY)			
-- 			end
			end
end

//laserStateChecker
local function laserTick (player)
	
		if (player.mo.laserTimer > 0)
	
		if P_PlayerInPain(player)
		or (player.pflags & PF_SLIDING)
		or (player.pflags & PF_SPINNING)
		or player.exiting
		or player.powers[pw_carry]
		or not player.mo.health
		or (player.panim == PA_PAIN and not (player.pflags&PF_JUMPED))
		or P_SuperReady(player)
		//or not P_IsObjectOnGround(mo)
		or player.mo.state == S_PTG_THROWBOTTLE
		or player.mo.state == S_PLAY_MELEE or player.mo.state == S_PLAY_FIRE
			player.mo.laserTimer = 0
			return
		end
		
		player.mo.laserTimer = $ - 1
		player.mo.state = S_PTG_LASER1

		
		if (player.mo.laserTime == 35)
			S_StartSound(player.mo, sfx_ptglch)
		end
		
		if (player.mo.laserTimer > 25 and player.mo.laserTimer < 35)
		
			generateLaser(player,-5)
			generateLaser(player,0)
			generateLaser(player,5)
			generateLaser(player,10)
			

		end
		
		
		
		if (player.mo.laserTimer <= 0)
			
			player.mo.state = S_PLAY_FALL
			
		end
		
	end
	


end

local function  laser(player)

	player.mo.laserTimer = 50
	player.mo.tier = 0
	player.mo.state = S_PTG_LASER1
	S_StartSound(player.mo, sfx_ptglch)

end





//Vomit Table

local function getVomit()
	local randomNumber = P_RandomRange(1, 8)
		local table = 
		{
		[1] = MT_MYSTERY_BOX,
		[2] = MT_RING_BOX,
		[3] = MT_MINIPIG,
		[4] = MT_SNEAKERS_BOX,
		[5] = MT_PITY_GOLDBOX,
		[6] = MT_YELLOWSPRING,
		[7] = MT_REDSPRING,
		[8] = MT_INVULN_BOX
		}
		
		return table[randomNumber]
end

//Vomit
local function vomit (player)
	
	player.mo.vomitTimer = 50
	player.mo.tier = 0
	player.mo.state = S_PTG_VOMIT1
	S_StartSound(player.mo, sfx_ptgvom)
	
	
	local i = P_RandomRange(0, 2)
-- 	local projectile = P_SPMAngle(player.mo,getVomit(),(player.mo.angle+(ANGLE_11hh/2)-((ANGLE_11hh/2)*i)), 0, MF2_BOSSNOTRAP)
	
	
	
	local projectile = nil
	
	if(player.speed > 3)
		if (player.mo.springReference and player.mo.springReference.valid)
				P_RemoveMobj(player.mo.springReference)
		end
		
		if player.powers[pw_super]
			player.mo.springReference = P_SpawnMobjFromMobj(player.mo,0,0,0,MT_REDSPRING)
		else
			player.mo.springReference = P_SpawnMobjFromMobj(player.mo,0,0,0,MT_YELLOWSPRING)
		end
		
	else
		if player.powers[pw_super]
			player.mo.springReference = P_SpawnMobjFromMobj(player.mo,24*FRACUNIT,0,0,MT_MYSTERY_BOX)
		end
		
	end
	
-- 	projectile = P_SpawnMobjFromMobj(player.mo,24*FRACUNIT,P_RandomRange(-4, 4)*FRACUNIT,0,getVomit())
	
	
	
-- 	local projectile = P_SpawnMobjFromMobj(player.mo,24*FRACUNIT,P_RandomRange(-4, 4)*FRACUNIT,0,MT_MINIPIG)
	if projectile and projectile.valid
		player.mo.flags = $|MF_NOCLIPTHING
		P_TryMove(projectile, player.mo.x+P_ReturnThrustX(nil, player.drawangle, player.mo.radius*4),
								player.mo.y+P_ReturnThrustY(nil, player.drawangle, player.mo.radius*4), true)
		player.mo.flags = $&~MF_NOCLIPTHING
		projectile.flags = $&~MF_NOGRAVITY
		projectile.momZ = 3 *FRACUNIT
		projectile.speed = 3
	end
	
	
	
	
	
end

//VomitStateChecker
local function vomitTick (player)

	if (player.mo.vomitTimer > 0)
	
		if P_PlayerInPain(player)
		or (player.pflags & PF_SLIDING)
		or (player.pflags & PF_SPINNING)
		or player.exiting
		or player.powers[pw_carry]
		or not player.mo.health
		or (player.panim == PA_PAIN and not (player.pflags&PF_JUMPED))
		or P_SuperReady(player)
		//or not P_IsObjectOnGround(mo)
		or player.mo.state == S_PTG_THROWBOTTLE
		or player.mo.state == S_PLAY_MELEE or player.mo.state == S_PLAY_FIRE
			player.mo.vomitTimer = 0
			return
		end
		
		player.mo.vomitTimer = $ - 1
		player.mo.state = S_PTG_VOMIT1
		
		//Vomit a flurry of rings
		if (leveltime % 5 == 0 and not player.powers[pw_super])
			local ring = P_SpawnMobjFromMobj(player.mo,0,0,0,MT_FLINGRING)
			local vomitForce = 10*FRACUNIT
			P_InstaThrust(ring, player.drawangle+(P_RandomRange(-ANG30/FRACUNIT, ANG30/FRACUNIT)*FRACUNIT),FixedMul(vomitForce, player.mo.scale))
			ring.momz = 9
		end
		
		if (leveltime % 2 == 0 and player.powers[pw_super])
			local ring = P_SpawnMobjFromMobj(player.mo,0,0,0,MT_FLINGRING)
			local vomitForce = 12*FRACUNIT
			P_InstaThrust(ring, player.drawangle+(P_RandomRange(-ANG30/FRACUNIT, ANG30/FRACUNIT)*FRACUNIT),FixedMul(vomitForce, player.mo.scale))
			ring.momz = 9
		end
		
		
		
		
		if (leveltime % 13 == 0) and P_RandomByte() > 200
			local pig = P_SpawnMobjFromMobj(player.mo,0,0,0,MT_MINIPIG)
			pig.color = player.mo.color
			local vomitForce = 2*FRACUNIT
			P_InstaThrust(pig, player.drawangle+(P_RandomRange(-ANG30/FRACUNIT, ANG30/FRACUNIT)*FRACUNIT),FixedMul(vomitForce, player.mo.scale))
			pig.scale = FRACUNIT/2
			pig.momz = 7
		end
		
		
		if (player.mo.vomitTimer <= 0)
			
			player.mo.state = S_PLAY_FALL
			
		end
		
	end

end

//rage
local function rage(player)
	
	player.mo.tier = 0
	player.mo.meter = 0
	player.mo.state = S_PTG_RAGE
	S_StartSound(player.mo, sfx_ptgrgs)
	player.mo.rageTimer = 50

end

//RageStateChecker
local function rageTick (player)

	if (player.mo.rageTimer > 0)
	
		if P_PlayerInPain(player)
		or (player.pflags & PF_SLIDING)
		or (player.pflags & PF_SPINNING)
		or player.exiting
		or player.powers[pw_carry]
		or not player.mo.health
		or (player.panim == PA_PAIN and not (player.pflags&PF_JUMPED))
		or P_SuperReady(player)
		//or not P_IsObjectOnGround(mo)
		or player.mo.state == S_PTG_THROWBOTTLE
		or player.mo.state == S_PLAY_MELEE or player.mo.state == S_PLAY_FIRE
			player.mo.rageTimer = 0
			return
		end
		
		player.mo.rageTimer = $ - 1
		player.mo.state = S_PTG_RAGE
		
		if (player.mo.rageTimer <= 0)
			player.mo.ragePowerUpTimer = 350
			player.mo.state = S_PLAY_FALL
			
		end
		
	end

end

//Actual raging tick
local function rageTickAttack(player)

	if (player.mo.ragePowerUpTimer > 0)
	
		if  player.exiting
		or player.powers[pw_carry]
		or not player.mo.health
		//or not P_IsObjectOnGround(mo)
		or player.mo.state == S_PLAY_MELEE or player.mo.state == S_PLAY_FIRE
			player.mo.ragePowerUpTimer = 0
			
			return
		end
		
		player.mo.ragePowerUpTimer = $ - 1
		player.acceleration = 96
		player.accelstart = 40
		
		if (leveltime % 3 == 0)
			S_StartSound(player.mo, sfx_ptgswy)
			local projectile = P_SpawnPlayerMissile(player.mo,MT_PTGFIST)
			if projectile and projectile.valid
					projectile.scale = 2*FRACUNIT/3 
			end
		end
		
		
		if (player.mo.ragePowerUpTimer <= 0)
			
			player.mo.state = S_PLAY_FALL
			player.acceleration = skins[player.mo.skin].acceleration
			player.accelstart = skins[player.mo.skin].accelstart
			
		end
		
	end


end

//Teleport Timer
local function teleportTick(player)

	if (player.mo.teleportTimer > 0)
			player.mo.teleportTimer = $ - 1
			
			if (player.mo.teleportTimer == 0)
			local randomNumber = P_RandomRange(1, 3)

			local table = {
			[1] = sfx_ptgch1,
			[2] = sfx_ptgch2,
			[3] = sfx_ptgch3
			}
			
			S_StartSound(mobj, table[randomNumber])
		
		end
		
	end

end


local function inputangle(player) 
	if (twodlevel or player.mo.flags2 & MF2_TWOD)
		return player.mo.angle
	else
		return (player.cmd.angleturn<<16 + R_PointToAngle2(0, 0, player.cmd.forwardmove*FRACUNIT, -player.cmd.sidemove*FRACUNIT))
	end
end	


local function lockControl(player)
	player.pflags = $1|PF_STASIS
end

//Obtain the magnitude of momx and momy
local function getMagnitudeMoM(player)
	return abs(R_PointToDist2(0,0,player.mo.momx,player.mo.momy))
end

local function setMaxSpeed(player)
				//Set his current speed to the new max speed
				if getMagnitudeMoM(player) > skins[player.mo.skin].normalspeed and player.speed < 100*FRACUNIT 
					player.normalspeed = getMagnitudeMoM(player)
-- 					print ("Speed change!")
-- 					print (getMagnitudeMoM(player)/FRACUNIT)
-- 					print (player.normalspeed/FRACUNIT)
				end
				
end

//Produce trail
local function particleGhost(player)
	if not player.powers[pw_super]
			local ghost = P_SpawnGhostMobj(player.mo)
			ghost.frame = 0
			ghost.colorized = true
			ghost.momx = player.mo.momx/2
			ghost.momy = player.mo.momy/2
			ghost.color = SKINCOLOR_RED
	end

end

//Activate/deactivate wall breaking properties
local function enableBreakingWallsAndFloors(player)
			P_SpawnThokMobj(player)
			player.charability = CA_GLIDEANDCLIMB
			player.charability2 = CA2_NONE
			player.panim = PA_ABILITY2
			breakfloor(player.mo)
end

//Activate/deactivate wall breaking properties
local function disableBreakingWallsAndFloors(player)
			P_SpawnThokMobj(player)
			player.charability = CA_NONE
			player.charability2 = CA2_NONE
			player.panim = PA_ABILITY2
end



addHook("PlayerSpawn", function(player)
		initPTGTables(player.mo)
		player.acceleration = skins[player.mo.skin].acceleration
		player.accelstart = skins[player.mo.skin].accelstart
end)


//Tier related attacks

addHook("SpinSpecial", function(player, mobj)
	if not (player.mo and player.mo.valid and player.mo.skin == "ptg") then return end
	
	if P_PlayerInPain(player)
	or (player.pflags & PF_SLIDING)
	or (player.pflags & PF_SPINNING)
	or player.exiting
	or player.powers[pw_carry]
	or not player.mo.health
	or player.powers[pw_carry] == CR_NIGHTSMODE
	or (player.panim == PA_PAIN and not (player.pflags&PF_JUMPED))
	or P_SuperReady(player)
	//or not P_IsObjectOnGround(mo)
	or player.mo.state == S_PTG_THROWBOTTLE
	or player.mo.state == S_PLAY_MELEE or player.mo.state == S_PLAY_FIRE
		return
	end
	
	
	if not (player.pflags&PF_SPINDOWN)
	
		if(player.mo.tier == 0) 
			if not P_IsObjectOnGround(player.mo) //Throw Bottle
				
				
				if player.powers[pw_super]
					throwBottle(player,MT_THROWNSUPERBEER)
				else
					throwBottle(player,MT_THROWNBEER)
				end
	
			end // Sliding check done by other script
		elseif (player.mo.tier == 1)
			if P_IsObjectOnGround(player.mo) //Teleport
				//teleporting(player)
				laser(player)
			else //Vomit
				vomit(player)
			end
		else
			if P_IsObjectOnGround(player.mo) //Bible
				
				prayer(player)
			else //RAGE
				rage(player)
				
			end
			
		end

	end
	
	

	
end)

addHook("PlayerThink", function(player)
	if not (player.mo and player.mo.valid and player.mo.skin == "ptg") then return end
	
		player.height = skins[player.mo.skin].height
		
		//Spawn a lockon reticle if we can	
		if (player.mo.tier < 2)
			local lockon = P_LookForEnemies(player)
			if lockon and lockon.valid
				P_SpawnLockOn(player, lockon, S_LOCKON1)
			end
		end
		
		
		
		//Tier charging
		
		if not (player.pflags & PF_SPINNING)
			
			if (player.mo.tier < 2)
		
				//Rise meter
				player.mo.meter = $ + 1
				if(leveltime % 5 == 0 )
					player.mo.meter = $ + 1
				end
				//Up a tier
				if(player.mo.meter > player.mo.metermax)		
					player.mo.tier = $ + 1
					//Only reset the meter if your tier is below 2
					if(player.mo.tier < 2)
						player.mo.meter = 0
					end
				end
			
			end
			
		end
	
		//Jump Charge
		jumpCharging(player)
		
		//Sliding charge
		sleepSlidingCheck(player)
		
		//Vomit check
		vomitTick(player)
		
		//Prayer check
		prayerTick(player)
		
		//Rage checks
		rageTick(player)
		rageTickAttack(player)
		
		//Laser checks
		laserTick(player)
		
		//Teleport checks
		teleportTick(player)
				
		
		//Return same conditions spin special would...
			if P_PlayerInPain(player)
			or (player.pflags & PF_SLIDING)
			or (player.pflags & PF_SPINNING)
			or player.exiting
			or player.powers[pw_carry]
			or not player.mo.health
			or player.powers[pw_carry] == CR_NIGHTSMODE
			or (player.panim == PA_PAIN and not (player.pflags&PF_JUMPED))
			//or not P_IsObjectOnGround(mo)
			or player.mo.state == S_PTG_THROWBOTTLE
			or player.mo.state == S_PLAY_MELEE or player.mo.state == S_PLAY_FIRE
				return
			end
		
		//Attacking with the shoot button
		if (player.cmd.buttons & BT_ATTACK)		
			
			if(player.mo.tier == 0) 

					if player.powers[pw_super]
						throwBottle(player,MT_THROWNSUPERBEER)
					else
						throwBottle(player,MT_THROWNBEER)
					end
		
			elseif (player.mo.tier == 1)
					vomit(player)
			else
					rage(player)
			end
		end
		
		//Attacking with the custom2 button
		if (player.cmd.buttons & BT_CUSTOM2)		
			
		if (player.mo.tier == 1)
					laser(player)
			elseif (player.mo.tier == 2)
					prayer(player)
			end
		end
		
		//Teleporting with the custom 1 button
		
		if (player.cmd.buttons & BT_CUSTOM1 and player.mo.teleportTimer <= 0)
		
			teleporting(player)
			
		
		
		end
		
	
end)




addHook("TouchSpecial", function(otherMobj,mobj)
	

	if mobj and mobj.valid and mobj.skin == "ptg" and not P_PlayerInPain(mobj.player)

		if mobj.state == S_PTG_VOMIT1
			return true
			
		end
	end
	
end,MT_FLINGRING)

addHook("TouchSpecial", function(otherMobj,mobj)
	if mobj and mobj.valid and mobj.skin == "ptg" and not P_PlayerInPain(mobj.player)

		mobj.meter = $ + mobj.metermax/30
		if mobj.meter > mobj.metermax
			mobj.meter = mobj.metermax
		end
	end
	
end,MT_RING)



addHook("PreThinkFrame", function()
	for player in players.iterate do
		if player.mo and player.mo.valid and player.mo.skin == "ptg" then
-- 			local isSpin = (player.cmd.buttons & BT_USE) > 0
-- 			local isJump = (player.cmd.buttons & BT_JUMP) > 0
-- 			player.cmd.buttons = ($ & ~(BT_USE|BT_JUMP)) | (isSpin and BT_JUMP or 0) | (isJump and BT_USE or 0)
			buttonChecking(player)
		end
		
		
	end
end)

hud.add(function(v, player, cam)
	
	if player.mo and player.mo.valid and player.mo.skin == "ptg"
		local ypos = 168
		if player.powers[pw_super]
			v.drawString(74,ypos+8,"P_G",
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_YELLOWMAP, "right")
		end
		
-- 		v.drawString(299,ypos-42,player.mo.tier+1,
-- 		V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, "right")
-- 		v.drawString(299,ypos-42,"TIER    ",
-- 		V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, "right")
-- 		v.drawString(299,ypos-52,player.mo.meter,
-- 		V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, "right")
-- 		v.drawString(299-30,ypos-52,"Meter",
-- 		V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT, "right")
		
		//PTTG
		
				//Draw Bar holder
		v.draw(299-37-37,ypos+28,v.cachePatch("RCHRGBAR"),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS)
		
		//Draw tiers
		v.draw(299,ypos+28,v.getSpritePatch(SPR_PTTG),
		V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT)
		//Tier 1 
		if player.mo.tier == 0
			v.draw(299,ypos+28,v.getSpritePatch(SPR_PTT1),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT)
			
			v.draw(299-37,ypos+28,v.getSpritePatch(SPR_PTT4),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT)
			
			v.draw(299-37-37,ypos+28,v.cachePatch("RCHRGBN1"),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT)
		elseif player.mo.tier == 1
			v.draw(299,ypos+28,v.getSpritePatch(SPR_PTT2),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT)
			
			v.draw(299-37,ypos+28,v.getSpritePatch(SPR_PTT5),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT)
			
			v.draw(299-37-37,ypos+28,v.cachePatch("RCHRGBN2"),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT)
		else
			v.draw(299,ypos+28,v.getSpritePatch(SPR_PTT3),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT)
			
			v.draw(299-37,ypos+28,v.getSpritePatch(SPR_PTT6),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT)
			
			v.draw(299-37-37,ypos+28,v.cachePatch("RCHRGBN3"),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT)
		end
		

		
		if (player.mo.meter >= 525)
			v.draw(299-37-37,ypos+28,v.cachePatch("RCHRGBR1"),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, v.getColormap(player.mo.skin, player.mo.color))
		elseif (player.mo.meter >= 420)
			v.draw(299-37-37,ypos+28,v.cachePatch("RCHRGBR2"),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, v.getColormap(player.mo.skin, player.mo.color))
		elseif (player.mo.meter >= 315)
			v.draw(299-37-37,ypos+28,v.cachePatch("RCHRGBR3"),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, v.getColormap(player.mo.skin, player.mo.color))
		elseif (player.mo.meter >= 210)
			v.draw(299-37-37,ypos+28,v.cachePatch("RCHRGBR4"),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, v.getColormap(player.mo.skin, player.mo.color))
		elseif (player.mo.meter >= 105)
			v.draw(299-37-37,ypos+28,v.cachePatch("RCHRGBR5"),
			V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, v.getColormap(player.mo.skin, player.mo.color))
		end
		
-- 		v.drawString(299-37-37,ypos+20,player.mo.tier+1,
-- 		V_PERPLAYER|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_YELLOWMAP, "small-right")
		
	end
	
		
end)

