rawset(_G, "TakisButtonStuff", function(p,takis)
	local btn = p.cmd.buttons

	if btn & BT_JUMP
		takis.jump = $+1
	else
		takis.jump = 0
	end
	
	if btn & BT_USE
		takis.use = $+1
	else
		takis.use = 0
	end

	if btn & BT_TOSSFLAG
		takis.tossflag = $+1
	else
		takis.tossflag = 0
	end
	
	if btn & BT_CUSTOM1
		takis.c1 = $+1
	else
		takis.c1 = 0
	end

	if btn & BT_CUSTOM2
		takis.c2 = $+1
	else
		takis.c2 = 0
	end

	if btn & BT_CUSTOM3
		takis.c3 = $+1
	else
		takis.c3 = 0
	end

end)

rawset(_G, "TakisBooleans", function(p,me,takis,SKIN)
	local posz = p.realmo.floorz
	if P_MobjFlip(p.realmo) == -1
		posz = p.realmo.ceilingz
	end
	
	if ((P_IsObjectOnGround(me))
	or (me.z == posz))
	and (not (P_CheckDeathPitCollide(me)))
		takis.onGround = true
	else
		takis.onGround = false
	end
	
	if P_PlayerInPain(p)
		takis.inPain = true
	else
		takis.inPain = false
	end
	
	if me.skin == SKIN
	or (skins[p.skin].name == SKIN)
		takis.isTakis = true
	else
		takis.isTakis = false
	end
	
	if (not netgame)
	and (not splitscreen)
		takis.isSinglePlayer = true
	else
		takis.isSinglePlayer = false
	end
	
	takis.inWater = (me.eflags&MFE_UNDERWATER) and not (me.eflags & MFE_TOUCHLAVA)
	takis.inGoop = P_IsObjectInGoop(me)
	takis.notCarried = ((p.powers[pw_carry] == CR_NONE) and not (takis.inwaterslide))
	
end)

rawset(_G, "TakisDoShorts", function(p,me,takis)
	//fake pw_flashing
	if takis.fakeflashing > 0
		p.powers[pw_flashing] = takis.fakeflashing
		takis.fakeflashing = $-1
	end
	
	if takis.ticsforpain > 0
		if me.state ~= S_PLAY_PAIN
			me.state = S_PLAY_PAIN
		end
		takis.ticsforpain = $-1
	end
	
	//no more spinning while jumping
	if p.pflags & PF_JUMPED
		p.pflags = $ &~PF_SPINNING
	end

	//clutch stuff
	if takis.clutchtime > 0
		takis.clutchtime = $-1
	elseif takis.clutchingtime == 0
		takis.clutchcombo = 0
	end
	
	if me.eflags & MFE_SPRUNG
		takis.dived = false
		takis.thokked = false
		takis.inFakePain = false
	end
	
	local t = P_LookForEnemies(p,true,false)
	if (p.powers[pw_shield]&SH_NOSTACK) == SH_ATTRACT
	and t and t.valid
		P_SpawnLockOn(p, t, S_LOCKON2)
	end
			
			if ((takis.hammerblasthitbox) and (takis.hammerblasthitbox.valid))
				takis.hammerblasthitbox.scale = me.scale
			end
			
			if takis.accspeed <= FU*8
				takis.clutchtime = 0
				takis.clutchcombo = 0
				takis.clutchingtime = 0
			end
			
			if (p.pflags & PF_SPINNING)
				if takis.slidetime
					takis.slidetime = $+1
				end
			else
				takis.slidetime = 0
			end
			
			//cancel slide when slow
			if (p.pflags & PF_SPINNING)
			and takis.accspeed <= 24*FU
			and takis.slidetime >= TR
				p.pflags = $ &~PF_SPINNING
				if takis.accspeed >= p.runspeed
					me.state = S_PLAY_RUN
				else
					me.state = S_PLAY_WALK
				end
			end

			if takis.stasistic
				p.pflags = $|PF_FULLSTASIS
				takis.stasistic = $-1
			end
			
			if takis.clutchcombotime > 0
				if takis.clutchcombotime == 1
					takis.clutchcombo = 0
				end
				takis.clutchcombotime = $-1
			end
			
	if takis.clutchingtime < 0
		takis.clutchingtime = 0
	end
	
	if takis.combo.intro ~= 0
		takis.combo.intro = $*4/5
	end
	
	if takis.combo.outrotics
		takis.combo.outrotics = $-1
		if takis.combo.outro ~= 200*FU
			if takis.combo.outro == 0
				takis.combo.outro = (4*FU/5)
			else
				takis.combo.outro = $*6/5
			end
		end
	else
		takis.combo.outro = 0
	end
	
	if (p.powers[pw_sneakers] > 0)
		local rad = me.radius/FRACUNIT
		local hei = me.height/FRACUNIT
		local x = P_RandomRange(-rad,rad)*FRACUNIT
		local y = P_RandomRange(-rad,rad)*FRACUNIT
		local z = P_RandomRange(0,hei)*FRACUNIT
		local spark = P_SpawnMobjFromMobj(me,x,y,z,MT_SOAP_SUPERTAUNT_FLYINGBOLT)
		spark.tracer = me
		spark.state = P_RandomRange(S_SOAP_SUPERTAUNT_FLYINGBOLT1,S_SOAP_SUPERTAUNT_FLYINGBOLT5)			
		spark.blendmode = AST_ADD
		spark.color = me.color
		spark.angle = p.drawangle+(FixedAngle( P_RandomRange(-337,337)*FRACUNIT ))
		
	end

	if p.playerstate == PST_REBORN
		if me.rollangle then me.rollangle = 0 end
	end

			local spd = 6*skins[me.skin].runspeed/5
			//wind effect
			if takis.accspeed >= 8*spd/5
				TakisDoWindLines(me)
			elseif takis.accspeed >= 7*spd/5
				if not (leveltime % 2)
					TakisDoWindLines(me)
				end
			elseif takis.accspeed >= 6*spd/5
				if not (leveltime % 5)
					TakisDoWindLines(me)
				end
			elseif takis.accspeed >= spd
				if not (leveltime % 7)
					TakisDoWindLines(me)
				end
			end
		
	if takis.yeahed
		if me.sprite2 ~= SPR2_THUP
			me.frame = A
			me.sprite2 = SPR2_THUP
		end
		
		takis.tauntid = 0
		takis.taunttime = 0
		
		takis.HUD.statusface.happyfacetic = 2
		
		if P_RandomChance(FRACUNIT-((p.exiting*655)+36))
			me.frame = B
		else
			me.frame = A
		end
	end

	if me.sprite2 == SPR2_THUP
		takis.tauntid = 0
		takis.taunttime = 0
		
		takis.HUD.statusface.happyfacetic = 2
	
	end
	
	if takis.yeahwait
		takis.yeahwait = $-1
		if (p.pflags & PF_FINISHED)
			// shouldve just kept this at 99 :/
			// thanks for the help SMS Alfredo!
			p.exiting = 99
		end
	end
	
	if takis.HUD.heartcards.add > 0
		takis.HUD.heartcards.add = $*20/22
	end

	if takis.HUD.heartcards.shake > 0
		takis.HUD.heartcards.shake = $-1
	end
	
	if p.deadtimer
		TakisDeathThinker(p,me,takis)
	end
	
	if takis.HUD.statusface.evilgrintic > 0
		takis.HUD.statusface.evilgrintic = $-1
	end
	
	if takis.HUD.statusface.happyfacetic > 0
		takis.HUD.statusface.happyfacetic = $-1
	end

	if takis.HUD.statusface.painfacetic > 0
		takis.HUD.statusface.painfacetic = $-1
	end
	
	if (me.health)
		if takis.heartcards <= (TAKIS_MAX_HEARTCARDS/TAKIS_MAX_HEARTCARDS)
			if not (leveltime%TR)
				takis.HUD.heartcards.shake = $+TAKIS_HEARTCARDS_SHAKETIME/3
			end
		
		elseif takis.heartcards <= (TAKIS_MAX_HEARTCARDS/2)
			if not (leveltime%(TR*2))
				takis.HUD.heartcards.shake = $+TAKIS_HEARTCARDS_SHAKETIME/2
			end
		
		elseif takis.heartcards == 0

			if not (leveltime%(3*TR/5))
				takis.HUD.heartcards.shake = $+TAKIS_HEARTCARDS_SHAKETIME/4
			end
		
		end
	end
	
	if takis.crushtime ~= 0
		takis.crushtime = $-1
	else
		takis.timescrushed = 0
	end
	
	--debug
	/*
	print("sweat",takis.goingfast,takis.wentfast,TAKIS_NET.texasarea)
	if ((takis.sweat) and (takis.sweat.valid))
		print(((takis.sweat.state == S_TAKIS_SWEAT2) or (takis.sweat.state == S_TAKIS_SWEAT4)))
	end
	print("sun",takis.sunstroked,takis.sunstrokecount,TAKIS_NET.texasarea)
	print("net",TAKIS_NET.texasarea,TAKIS_NET.donotsunstroke)
	print("freeze",takis.aliments.timetoice,takis.aliments.timetoice/TR,takis.aliments.iced,takis.aliments.icecount)
	*/

	--

	if ((me.subsector) and (me.subsector.sector))
		local sec = me.subsector.sector
		
		if sec.lightlevel >= TAKIS_SHADE_BRIGHTNESS
		or (sec.ceilingpic == "F_SKY1")
			takis.inshade = false
		else
			takis.inshade = true
		end
		
		if (sec.ceilingpic ~= "F_SKY1")
			takis.inshade = true
		end
		
		for rover in sec.ffloors() 
			
			if ((rover) and (rover.valid))
				if not (rover.bottomheight > me.z+me.height)
					continue
				end
				
				if rover.toplightlevel < TAKIS_SHADE_BRIGHTNESS
					takis.inshade = true
				else
					takis.inshade = false
				end
			end
			
		end
	end
	
	if takis.accspeed >= 60*FU
		if not TAKIS_NET.icyarea
			takis.goingfast = true
			takis.wentfast = 10*TR
		else
			if ((takis.aliments.iceremove > 0)
			or (takis.aliments.icecount > 0))
			and not takis.inWater
				takis.aliments.iceremove = $-2
				if takis.aliments.icecount >= 7
					takis.aliments.icecount = $-7
				else
					takis.aliments.icecount = 0
				end
			end
		end
	else
		takis.goingfast = false
		if TAKIS_NET.icyarea
		and (takis.aliments.iceremove > 0)
		and (takis.aliments.iceremove ~= TAKIS_MAX_UNFREEZE)
			if not (leveltime % (TR))
				takis.aliments.iceremove = $+1
			end
		end
	end
	
	if takis.aliments.iceremove < 0
		takis.aliments.iceremove = 0
	end
	if takis.aliments.iceremove > TAKIS_MAX_UNFREEZE
		takis.aliments.iceremove = TAKIS_MAX_UNFREEZE
	end
	
	//check for sunstroke
	if TAKIS_NET.texasarea
	and (TAKIS_NET.donotsunstroke == false)
		TakisResetAliments(takis,"freezing")
		
		if ((me.subsector) and (me.subsector.sector))
			local sec = me.subsector.sector
			
			if not takis.inshade
				takis.wentfast = 4*TR
				
				if (leveltime > 0)
				and not (leveltime % (8*TR))
				
					if not takis.aliments.sunstroked
					and not (p.pflags & PF_FINISHED)
						takis.aliments.sunstroked = true
						DoFlash(p,PAL_NUKE,2)
					end
					
				end
				
			end
		end
		
		if takis.aliments.sunstroked
		
			if not (leveltime % (3*TR))
			and (not ((p.exiting) or (p.pflags & PF_FINISHED) or (me.health)))
			
				takis.aliments.sunstrokecount = $+1
			end
			
			if takis.aliments.sunstrokecount == TAKIS_MAX_SUNSTROKE
				
				//hurt the player without calling the heal func
				if takis.heartcards
					takis.heartcards = $-1
					takis.HUD.heartcards.shake = $+TAKIS_HEARTCARDS_SHAKETIME
					S_StartSound(nil,sfx_antiri,p)
				else
					if p.rings > 0
						p.rings = $-1
						S_StartSound(nil,sfx_antiri,p)
					else
						if (p.powers[pw_shield] == SH_NONE)
							P_DamageMobj(me,nil,nil,1,DMG_INSTAKILL)
						else
							P_RemoveShield(p)
							S_StartSound(nil,sfx_antiri,p)
						end
					end
				end
				
				takis.aliments.sunstrokecount = 0
			end
		else
			takis.aliments.sunstrokecount = 0
		end
		
	//check for freezing
	elseif TAKIS_NET.icyarea
	and (TAKIS_NET.donotfreeze == false)
		TakisResetAliments(takis,"sunstroke")
		
		if not takis.aliments.iced
			takis.aliments.icecount = 0
			
			if takis.inWater
				takis.aliments.timetoice = $+2
			else
				//if the ceiling isnt f_sky1, theres a good change
				//we're inside that has ac
				if me.subsector.sector.ceilingpic == "F_SKY1"
					if ((leveltime) and not (leveltime % TR))
						takis.aliments.timetoice = $+4
					end
				end
			end
			
			if takis.aliments.timetoice >= TAKIS_MAX_ICETIME
				takis.aliments.iced = true
				takis.aliments.timetoice = 0
				takis.aliments.iceremove = TAKIS_MAX_UNFREEZE
				DoFlash(p,PAL_WHITE,2)
			end
		else
			
			if not takis.inWater
				
				if ((leveltime) and not (leveltime % TR))
					takis.aliments.iceremove = $+1
				end
			else
				if takis.aliments.iceremove ~= TAKIS_MAX_UNFREEZE
					takis.aliments.iceremove = $+2
				end
				if takis.aliments.icecount ~= TAKIS_MAX_ICECOUNT
					takis.aliments.icecount = $+1
				end
			end
			
			//if the ceiling isnt f_sky1, theres a good change
			//we're inside that has ac
			if me.subsector.sector.ceilingpic ~= "F_SKY1"
				if ((leveltime) and not (leveltime % TR))
					takis.aliments.icecount = $-3
					takis.aliments.iceremove = $-2
				end
			else
				takis.aliments.icecount = $+1				
			end

			if takis.aliments.iceremove == 0
				takis.aliments.iced = false
			end
		end
	else
		TakisResetAliments(takis)
	end
	
	//spawn sweat mobj
	if takis.wentfast ~= 0
		if not ((takis.sweat) and (takis.sweat.valid))
			takis.sweat = P_SpawnMobjFromMobj(me,0,0,0,MT_TAKIS_SWEAT)
			takis.sweat.tracer = me
		end
		takis.wentfast = $-1
	else
		if ((takis.sweat) and (takis.sweat.valid))
		and ((takis.sweat.state == S_TAKIS_SWEAT2) or (takis.sweat.state == S_TAKIS_SWEAT4))
			P_RemoveMobj(takis.sweat)
			if takis.aliments.sunstroked
				takis.aliments.sunstroked = false
			end
		end
	end
	
	if takis.aliments.icecount < 0
		takis.aliments.icecount = 0
	end
	if takis.aliments.icecount > TAKIS_MAX_ICECOUNT
		takis.aliments.icecount = TAKIS_MAX_ICECOUNT
	end
	
	if (p.pflags & PF_FINISHED)
		TakisResetAliments(takis)
	/*
	else
		takis.yeahwait = 0
		takis.yeahed = false
	*/
	end
	
	if takis.inWater
		if TAKIS_NET.texasarea
			takis.aliments.sunstroked = false
			takis.aliments.sunstrokecount = 0
		elseif TAKIS_NET.icyarea
			if takis.aliments.iced
				takis.aliments.icecount = $+2
			end
		end
		
		if ((takis.sweat) and (takis.sweat.valid))
			P_RemoveMobj(takis.sweat)
			takis.wentfast = 0
		end
	end
	
	//elfilin cheers refill combo
	if (p.elfride)
	and (p.elfride.cheerdur/5 > 0)
		TakisGiveCombo(p,takis,false,true)
	end
	
	if p.powers[pw_carry] == CR_NIGHTSMODE
	or ((TAKIS_NET.usesheartcards == false) and (leveltime >3))
		takis.heartcards = 0
		takis.heartcardpieces = 0
	end
	
	if (p.powers[pw_shield] & (SH_PROTECTFIRE|SH_PROTECTWATER))
		TakisResetAliments(takis,"freezing")
	end
	
	if P_CheckDeathPitCollide(me)
	and not me.health
		me.flags = $|MF_NOCLIPHEIGHT
	end

	//ffoxd's smoothspintrilas
	if not me.prevz
	or not me.prevleveltime 
	or (me.prevleveltime ~= leveltime - 1) then
	   me.prevz = me.z
	end

	local rmomz = me.z - me.prevz
	me.prevz = me.z
	me.prevleveltime = leveltime
	
	takis.rmomz = rmomz
	
	if takis.HUD.funny.tics > 0
		takis.HUD.funny.y = $*4/5
		takis.HUD.funny.tics = $-1
	end
	
	//animate slide
	if me.state == S_PLAY_TAKIS_SLIDE
		/*
		local speed = FixedDiv(FixedMul(takis.accspeed,me.scale),FixedMul(me.scale,me.movefactor))
		if speed > 16<<FRACBITS
			me.tics = 1
		else
			me.tics = 2
		end
		*/
		me.frame = ((takis.accspeed/FU) % 2)
	end
	
	if takis.fakesprung
		me.eflags = $ &~MFE_SPRUNG
		takis.fakesprung = false
	end
	
	
	takis.HUD.happyhour.its.frame = ((leveltime/3)%2)
	takis.HUD.happyhour.happy.frame = ((leveltime/3)%2)
	takis.HUD.happyhour.hour.frame = ((leveltime/3)%2)
	takis.HUD.happyhour.face.frame = ((leveltime/3)%2)
	
	if takis.HUD.happyhour.doingit
		if not takis.HUD.happyhour.falldown
			if takis.HUD.happyhour.its.yadd ~= 0
				takis.HUD.happyhour.its.yadd = 2*$/5
				
			elseif takis.HUD.happyhour.happy.yadd ~= 0
				takis.HUD.happyhour.happy.yadd = 2*$/5
			
			elseif takis.HUD.happyhour.hour.yadd ~= 0
				takis.HUD.happyhour.hour.yadd = 2*$/5
			end
			
			//elseif takis.HUD.happyhour.face.yadd ~= 0
				takis.HUD.happyhour.face.yadd = 4*$/5
		else
		
			takis.HUD.happyhour.its.yadd = $*8/5
			takis.HUD.happyhour.happy.yadd = $*7/5
			takis.HUD.happyhour.hour.yadd = $*6/5
			takis.HUD.happyhour.face.yadd = $*8/7
		
		end
	end
	
	//happy hour hud and stuff
	if (JISK_PIZZATIMETICS)
	or ((PTJE) and (PTJE.pizzatime_tics))
	and takis.io.nohappyhour == 0
		local tics = JISK_PIZZATIMETICS or PTJE.pizzatime_tics
		
		if (tics == 1)
			S_StartSound(nil,sfx_mclang)
			takis.HUD.happyhour.its.yadd = -100*FU
			takis.HUD.happyhour.happy.yadd = -100*FU
			takis.HUD.happyhour.hour.yadd = -100*FU
			takis.HUD.happyhour.face.yadd = -200*FU
		end
		
		if (me.health)
		//how convienient that 8 tics just so happens to be
		//exactly 22 centiseconds!
		and (tics == 8)
			S_StartSound(nil,sfx_hapyhr,p)
		end
		
		if (tics <= TR)
			DoQuake(p,(36-tics)*FU,1)
		end
	end
	
	if ( ((CV_PTJE) and (CV_PTJE.timelimit.value))
	or ((JISK_TIMELIMIT) and (JISK_TIMELIMIT.value)) )
		
		if ( ((PTJE) and (PTJE.timeleft))
		or (JISK_TIMELEFT) )
			local tics = JISK_TIMELEFT or PTJE.timeleft
			
			if tics <= (56*TR)
				if not takis.sethappyend
					S_ChangeMusic("HPYHRE",false,p,0,0,3*MUSICRATE)
					takis.sethappyend = true
				end
			end
			
		else
			takis.sethappyend = false
		end
		
	else
		takis.sethappyend = false
	end

	if takis.glowyeffects
		
		//ffoxd's smooth spintrails
		
		local freq = FRACUNIT*30
		local mospeed = R_PointToDist2(0, 0, R_PointToDist2(0, 0, me.momx, me.momy), me.momz)
		local dist = (mospeed/freq)
		
		if dist >= 25
			dist = 25
		end

		-- The loop, repeats until it spawns all the thok objects.			
		for i = dist, 1, -1 do

		//	local ghost = P_SpawnMobjFromMobj(me, (me.momx/dist)*i, (me.momy/dist)*i, (me.momz/dist)*i, MT_THOK)
			local ghost = P_SpawnGhostMobj(me)
			ghost.scale = 7*me.scale/5
			ghost.fuse = 8
			
		/*
			ghost.skin = me.skin
			ghost.sprite = me.sprite
			ghost.sprite2 = me.sprite2
			ghost.state = me.state
			ghost.frame = me.frame|TR_TRANS50
			ghost.angle = p.drawangle
		*/	
			ghost.color = me.color
			ghost.colorized = true
			ghost.destscale = me.scale/3
			ghost.blendmode = AST_ADD
			P_SetOrigin(ghost, 
			ghost.x-(me.momx/dist)*i, 
			ghost.y-(me.momy/dist)*i, 
			ghost.z-(me.momz/dist)*i
			)
			
		end
		
		takis.glowyeffects = $-1
	end

end)

//from clairebun
//https://wiki.srb2.org/wiki/User:Clairebun/Sandbox/Common_Lua_Functions#L_Choose
local function choosething(...)
	local args = {...}
	local choice = P_RandomRange(1,#args)
	return args[choice]
end

//soaps createafterimage modified to include multiple colors
rawset(_G, "TakisCreateAfterimage", function(p,me)
	if not me
	or not me.valid
		return
	end
	
	local ghost = P_SpawnMobjFromMobj(me,0,0,0,MT_TAKIS_AFTERIMAGE)
	ghost.target = me
	//ghost.fuse = SoapFetchConstant("afterimages_fuse")
	
	ghost.skin = me.skin
	ghost.scale = me.scale
	
	ghost.sprite = me.sprite
	
	ghost.state = me.state
	ghost.sprite2 = me.sprite2
	ghost.frame = me.frame|TR_TRANS70
	
	ghost.angle = p.drawangle
	
	local color = P_RandomRange(1,#skincolors-1)
	//keep rolling until we get an accessable color!
	if skincolors[color].accessible == false
		P_RandomRange(1,#skincolors-1)
	end
	ghost.color = color
	ghost.spritexscale,ghost.spriteyscale = me.spritexscale, me.spriteyscale
	
	return ghost
end)

rawset(_G, "CreateWindRing", function(p,me)
	//trig NOO!OOOO
	local x = cos(me.angle)
	local y = sin(me.angle)
	
	//thanks rebound dash!	
	local circle = P_SpawnMobjFromMobj(me, 0, 0, me.scale * 24, MT_WINDRINGLOL)
	circle.angle = p.drawangle + ANGLE_90
	circle.fuse = 14
	circle.scale = FU / 3
	circle.destscale = 10*FU
	circle.scalespeed = FU/10
	circle.colorized = true
	circle.color = SKINCOLOR_WHITE
	circle.momx = -me.momx/2
	circle.momy = -me.momy/2
end)

rawset(_G, "DoTakisSquashAndStretch", function(p, me, takis)
		//dont do this in nights
		if (p.powers[pw_carry] == CR_NIGHTSMODE)
		or (p.powers[pw_carry] == CR_PLAYER)
		or (p.powers[pw_carry] == CR_ZOOMTUBE)
		or (p.powers[pw_carry] == CR_PTERABYTE)
		or (p.powers[pw_carry] == CR_MINECART)
		or (p.powers[pw_carry] == CR_ROPEHANG)
			return
		end
		if p.jt == nil then
			p.jt = 0
			p.jp = 0
			p.sp = 0
			p.tk = 0
			p.tr = 0
		end
		if p.jt > 0 then
			p.jt = p.jt - 1
		end
		if p.jt < 0 then
			p.jt = p.jt + 1
		end
		if me.momz*takis.gravflip < 1 then
			p.jp = 0
		end
		if me.state != S_PLAY_CLIMB and me.eflags != me.eflags | MFE_GOOWATER then
			if me.momz*takis.gravflip > 0 and p.jp == 0 and me.state != S_PLAY_FLY and me.state != S_PLAY_SWIM and me.state != S_PLAY_FLY_TIRED and me.state != S_PLAY_WALK and me.state != S_PLAY_RUN and me.state != S_PLAY_WALK and me.state != S_PLAY_BOUNCE_LANDING then
				p.jp = 1
				p.jt = 5
			end
			if me.momz*takis.gravflip > 0 and p.jt < 0 and me.state != S_PLAY_FLY and me.state != S_PLAY_SWIM and me.state != S_PLAY_FLY_TIRED and me.state != S_PLAY_WALK and me.state != S_PLAY_RUN and me.state != S_PLAY_WALK and me.state != S_PLAY_BOUNCE_LANDING then
				p.jp = 1
				p.jt = 5
			end
		elseif me.eflags == me.eflags | MFE_GOOWATER
			p.jp = 1
		end
		if me.state == S_PLAY_BOUNCE_LANDING then
			p.jt = -5
		end
		/*
		if p.pflags != p.pflags | PF_SPINNING or p.pflags == p.pflags | PF_JUMPED then
			p.sp = 0
		end
		if p.pflags == p.pflags | PF_SPINNING and p.pflags != p.pflags | PF_JUMPED and p.sp == 0 and p.jt < 1 then
			p.sp = 1
			p.jt = -5
		end
		*/
		if p.pflags != p.pflags | PF_THOKKED then
			p.tk = 0
		end
		if p.pflags == p.pflags | PF_THOKKED and p.tk == 0 then
			p.tk = 1
			p.jt = 5
		end
		if me.state != S_PLAY_FLY_TIRED then
			p.tr = 0
		end
		if me.state == S_PLAY_FLY_TIRED and p.tr == 0 then
			p.tr = 1
			p.jt = 5
		end
		p.maths = p.jt*FU
		p.maths = p.maths / 10
		me.spriteyscale = p.maths + FU
		
		p.maths = p.jt*p.spinheight
		if me.state != S_PLAY_ROLL then
			p.maths = p.jt*p.height
		end
		p.maths = p.maths / 20
		me.spriteyoffset = -1*p.maths
		
		p.maths = p.jt*FU
		p.maths = p.maths / 10
		p.maths = p.maths*-1
		me.spritexscale = p.maths + FU
end)

//thank you Tatsuru for this thing on the srb2 discord!
local function CheckAndCrumble(me, sec)
	for fof in sec.ffloors()
		if not (fof.flags & FF_EXISTS) continue end -- Does it exist?
		if not (fof.flags & FF_BUSTUP) continue end -- Is it bustable?
		
		if me.z + me.height < fof.bottomheight continue end -- Are we too low?
		if me.z > fof.topheight continue end -- Are we too high?

		EV_CrumbleChain(fof) -- Crumble
	end
end

//function so bounce and dive can use this without having to copypaste
rawset(_G, "TakisBreakAndBust", function(p, me)
	CheckAndCrumble(me, me.subsector.sector)
end)

rawset(_G, "DoQuake", function(p, int, tic, rad)
	if rad == nil
		rad = 36*p.mo.scale
	end
	if displayplayer == p
		local pos = {p.mo.x,p.mo.y,p.mo.z}
		P_StartQuake(int,tic,pos,rad)
	end
end)

rawset(_G, "DoFlash", function(p, pal, tic)
	P_FlashPal(p,pal,tic)
end)

rawset(_G, "S_StartAntonOw", function(source)
	if source == nil
		return
	end
	S_StartSound(source, P_RandomRange(sfx_antow1,sfx_antow5))
end)

local function collide2(me,mob)
	if me.z > (mob.height*2)+mob.z then return false end
	if mob.z > me.height+me.z then return false end
	return true
end

rawset(_G, "TakisHammerSearch", function(me,found)
	local p = me.player
	local takis = p.takistable
	
	if not found
	or not found.valid
	or not found.health
		return
	end
	
	local dx = me.x-found.x
	local dy = me.y-found.y
	
	if FixedHypot(dx,dy) > 15*me.scale
		return
	end
	
	if not collide2(me,found)
		return
	end
	
	local flg = found.flags
	
	if ((found.type == MT_SPIKE) or (found.type == MT_WALLSPIKE) or 
	(found.type == MT_SPIKEBALL) or (found.type == MT_BOMBSPHERE))
		P_KillMobj(found,me,me)
	end

	if found.type == MT_PLAYER
	
		CONS_Printf(p,"player kill")
		
		local ff = CV_FindVar("friendlyfire").value
	
	elseif flg & (MF_MONITOR|MF_ENEMY|MF_BOSS)
		S_StartSound(found,sfx_cdfm16)
		P_DamageMobj(found,me,me,1)
		P_SetObjectMomZ(me,13*FU)
	end

end)

rawset(_G, "CanPlayerHurtPlayer", function(p1,p2)

	local ff = CV_FindVar("friendlyfire").value
	
	if not p1.mo.health
		return false
	end
	if not p2.mo.health
		return false
	end
	
	if (p1.powers[pw_flashing] > 2*TR)
		return false
	end
	if ((p2.powers[pw_flashing]) or (p2.powers[pw_invulnerability]) or (p2.powers[pw_super]))
		return false
	end
	
	if (gametyperules & GTR_FRIENDLY)
		if ff
			return true
		end
	else
		if (gametyperules & (GTR_TEAMS|GTR_TEAMFLAGS))
			if p1.ctfteam ~= p2.ctfteam
				return true
			end
			if p1.ctfteam == p2.ctfteam
			and ff
				return true
			end
		end
		if (gametyperules & (GTR_FRIENDLYFIRE|GTR_RINGSLINGER))
		or ff
			return true
		end
		
	end
	return false

end)

rawset(_G, "TakisTeamNewShields", function(player)
		local s = player.powers[pw_shield]
		local f = s&SH_NOSTACK
		local takis = player.takistable
		
		if player.pflags & PF_JUMPED
		and (f or player.powers[pw_super])
		and not (player.mo.state >= 59 and player.mo.state <= 64)
			local t = P_LookForEnemies(player,true,false)
			
				if s & SH_FORCE
					local me = player.mo
					S_StartSound(me,sfx_ngskid)
					me.momx = 0
					me.momy = 0
					me.momz = 0
				end
				if f == SH_WHIRLWIND
				or f == SH_THUNDERCOIN
					P_DoJumpShield(player)
				end
				if f == SH_ARMAGEDDON
					player.pflags = $|PF_THOKKED|PF_SHIELDABILITY
					P_BlackOw(player)
				end
				if f == SH_ATTRACT
					player.pflags = $|PF_THOKKED|PF_SHIELDABILITY
					player.homing = 2
					if t and t.valid
						player.mo.target = t
						player.mo.tracer = t
						P_HomingAttack(player.mo,player.mo.target)
						player.mo.angle = R_PointToAngle2(player.mo.x,player.mo.y,t.x,t.y)
						player.pflags = $&~PF_NOJUMPDAMAGE
						player.mo.state = S_PLAY_ROLL
						S_StartSound(player.mo, sfx_s3k40)
						player.homing = 3*TR
						player.pflags = $ &~PF_THOKKED
						takis.thokked = false
					else
						S_StartSound(player.mo, sfx_s3ka6)
						player.pflags = $ &~PF_THOKKED
						takis.thokked = false
					end
				end
				if f == SH_BUBBLEWRAP
				or f == SH_ELEMENTAL
					local elem = ((player.powers[pw_shield]&SH_NOSTACK) == SH_ELEMENTAL)
					player.pflags = $|PF_THOKKED|PF_SHIELDABILITY
					if elem
						player.mo.momx = 0
						player.mo.momy = 0
						S_StartSound(player.mo, sfx_s3k43)
					else
						player.mo.momx = $-(player.mo.momx/3)
						player.mo.momy = $-(player.mo.momy/3)
						player.pflags = $&~(PF_NOJUMPDAMAGE|PF_SHIELDABILITY)
						player.mo.state = S_PLAY_ROLL
						S_StartSound(player.mo,sfx_s3k44)
					end
					player.secondjump = 0
					P_SetObjectMomZ(player.mo, -24*FRACUNIT, false)
				end
				if f == SH_FLAMEAURA
					player.pflags = $|PF_THOKKED|PF_SHIELDABILITY
					P_Thrust(player.mo, player.mo.angle, FixedMul(30*FRACUNIT-FixedSqrt(FixedDiv(player.speed,player.mo.scale)),player.mo.scale))
					player.drawangle = player.mo.angle
					player.pflags = $&~PF_NOJUMPDAMAGE
					player.mo.state = S_PLAY_ROLL
					S_StartSound(player.mo,sfx_s3k43)
				end
			
		end

end)

rawset(_G, "TakisHealPlayer", function(p,me,takis,healtype,healamt)
	if healamt == nil
		healamt = 1
	end
	
	if TAKIS_NET.usesheartcards == false
		return
	end
	
	//hurt
	if healtype == 3
		if takis.heartcards ~= 0
			takis.heartcards = $-(abs(healamt))
		end
		if takis.heartcards < 0
			takis.heartcards = 0
		end
		takis.HUD.heartcards.shake = TAKIS_HEARTCARDS_SHAKETIME
		return
	//full heal
	elseif healtype == 2
		if takis.heartcards == TAKIS_MAX_HEARTCARDS
			return
		end
		takis.heartcards = TAKIS_MAX_HEARTCARDS
		takis.heartcardpieces = 0
		takis.HUD.heartcards.add = 5*FU
	elseif healtype == 1
		if takis.heartcards == TAKIS_MAX_HEARTCARDS
			return
		end
		takis.heartcards = $+healamt
		takis.HUD.heartcards.add = (healamt*FU)*3/2
		if takis.heartcards >= TAKIS_MAX_HEARTCARDS
			takis.heartcardpieces = 0
		end
	else
		error("\x85".."TakisHealPlayer has an invalid healtype.\x80("..healtype..")",2)
		return
	end
	
	S_StartSound(me,sfx_takhel,p)
	for i = 0, 8
		local mt = MT_THOK
		local fa = (i*ANGLE_45)
		local dust = P_SpawnMobjFromMobj(me,-20*cos(fa),-20*sin(fa),((me.scale)*i)*takis.gravflip,mt)
		dust.state = S_LHRT
		dust.frame = A|TR_TRANS10
		dust.blendmode = AST_ADD
		
		dust.angle = me.angle
		dust.momz = (me.scale*takis.gravflip)*(8-i)
		
		dust.destscale = dust.scale/2
		dust.fuse = 14
		
		
	end
end)

local function lookforenemy(me,prevangle)
	local px = me.x
	local py = me.y
	local br = 75*me.scale
	
	local z = me.z+(7*me.scale)
	local z2 = me.z-(7*me.scale)
	
	local ang = prevangle

	searchBlockmap("objects", function(me, found)
		if found and found.valid
		and found.health
		and P_CheckSight(me,found)
		and ((found.z >= z2) and (found.z <= z))
		
			if ( (found.type == MT_PLAYER)
			and (CanPlayerHurtPlayer(me.parent2.player,found.player)) )
			or (found.flags & (MF_MONITOR|MF_ENEMY))

				ang = R_PointToAngle2(found.x,found.y, me.x,me.y)
				return true, ang
				
			end
		end
	end, me, px-br, px+br, py-br, py+br)
	
	return ang
end

rawset(_G, "SpawnRagThing",function(tm,t)
	if t.player
		DoQuake(t.player,t.scale*10,10)
	end

	if not (tm.flags & MF_BOSS)
		if (tm.flags & MF_ENEMY)
			//spawn ragdoll thing here
			local ragdoll = P_SpawnMobjFromMobj(tm,0,0,0,MT_TAKIS_BADNIK_RAGDOLL)
			tm.tics = -1
			ragdoll.sprite = tm.sprite
			ragdoll.color = tm.color
			ragdoll.angle = R_PointToAngle2(tm.x,tm.y, t.x,t.y)
			ragdoll.frame = tm.frame
			ragdoll.height = tm.height*2
			ragdoll.radius = tm.radius*2
			ragdoll.scale = tm.scale
			ragdoll.timealive = 1
			ragdoll.angle = tm.angle+t.player.takistable.accspeed
			ragdoll.parent2 = t
			
			P_SetObjectMomZ(ragdoll,7*t.scale)
			
			P_Thrust(ragdoll,ragdoll.angle,-63*t.scale-FixedMul(t.player.takistable.accspeed,t.scale))
			
			if P_RandomChance(FRACUNIT/13)
				S_StartSound(ragdoll,sfx_takoww)
			end
		elseif (tm.flags & MF_MONITOR)
			//spawn ragdoll thing here
			local ragdoll = P_SpawnMobjFromMobj(tm,0,0,0,MT_TAKIS_BADNIK_RAGDOLL)
			tm.tics = -1
			ragdoll.sprite = tm.sprite
			ragdoll.color = tm.color
			ragdoll.angle = R_PointToAngle2(tm.x,tm.y, t.x,t.y)
			ragdoll.frame = tm.frame
			ragdoll.height = tm.height*2
			ragdoll.radius = tm.radius*2
			ragdoll.scale = tm.scale
			ragdoll.timealive = 1
			
			P_SetObjectMomZ(ragdoll,7*t.scale)
			P_Thrust(ragdoll,ragdoll.angle,-63*t.scale-FixedMul(t.player.takistable.accspeed,t.scale))
			for i = 0, 34
				A_BossScream(ragdoll,1,MT_SONIC3KBOSSEXPLODE)
			end
			local f = P_SpawnGhostMobj(ragdoll)
			f.flags2 = $|MF2_DONTDRAW
			f.fuse = 2*TR
			S_StartSound(f,sfx_tkapow)
			P_RemoveMobj(ragdoll)
		end
		
		P_KillMobj(tm,t,t)
		if ((tm) and (tm.valid))
		and (tm.flags & MF_ENEMY)
			//hide deathstate
			tm.flags2 = $|MF2_DONTDRAW
		end
	else
	
		S_StartSound(t,sfx_tacrit)
		local ghost = P_SpawnGhostMobj(tm)
		ghost.color = tm.color
		ghost.colorized = true
		ghost.scale = tm.scale*7/5
		ghost.destscale = ghost.scale*3/2
		ghost.frame = $|TR_TRANS80
		ghost.blendmode = AST_ADD

		P_DamageMobj(tm,t,t,2)
	end
end)
rawset(_G, "TakisGiveCombo",function(p,takis,add,max)
	if add == nil
		add = false
	end
	if max == nil
		max = false
	end
	
	if add == true
		takis.combo.count = $+1
		
		if takis.combo.count == 1
			S_StartSound(nil,sfx_kc3c,p)
			if not takis.combo.outro
				takis.combo.intro = -200*FU
			else
				takis.combo.intro = takis.combo.outro
			end
		end
		
		if not (takis.combo.count % TAKIS_COMBO_UP)
			takis.combo.intro = (-FU/2)*(takis.combo.count/TAKIS_COMBO_UP)
			takis.combo.rank = $+1
			S_StartSound(nil,sfx_s3kcas,p)
		end
		
		takis.combo.time = TAKIS_MAX_COMBOTIME
	else
		if max == true
			takis.combo.time = TAKIS_MAX_COMBOTIME
		else
			takis.combo.time = $+TAKIS_PART_COMBOTIME
		end
	end
end)

//delf!!
rawset(_G, "TakisDoWindLines", function(mobj)
	if not mobj.health then return end
	
	local p = mobj.player
	
    local r = mobj.radius / FRACUNIT
    local explosion = P_SpawnMobj(
        (mobj.x+(50*cos(p.drawangle))) + (P_RandomRange(r, -r) * FRACUNIT),
        (mobj.y+(50*sin(p.drawangle))) + (P_RandomRange(r, -r) * FRACUNIT),
        mobj.z + (P_RandomKey(mobj.height / FRACUNIT) * FRACUNIT) - mobj.height/2,
        MT_THOK)
    explosion.sprite = SPR_RAIN
    explosion.renderflags = $|RF_PAPERSPRITE
    explosion.angle = R_PointToAngle2(0, 0, mobj.momx, mobj.momy)
		
	//remove the "-" beforfe the "mobj.momz" or else the wind will point down
	//when you go up
	//and vice versa
    explosion.rollangle = R_PointToAngle2(0, 0, R_PointToDist2(0, 0, mobj.momx, mobj.momy), mobj.player.takistable.rmomz) + ANGLE_90
    
	explosion.source = mobj
    explosion.blendmode = AST_ADD
	local x = cos(mobj.angle)
	local y = sin(mobj.angle)
end)

rawset(_G, "TakisSpawnDeadBody", function(p, me, soap)
	if (p.deadtimer >= 3*TR) and not (soap.body and soap.body.valid)
		soap.body = P_SpawnMobjFromMobj(me, 0, 0, 0, MT_THOK)
		soap.body.tics = -1
		soap.body.skin = me.skin
		soap.body.scale = me.scale
		soap.body.state = me.state
		soap.body.sprite2 = me.sprite2
		soap.body.angle = p.drawangle
		soap.body.rollangle = me.rollangle
		soap.body.color = me.color
		soap.body.frame = me.frame
		
		soap.body.flags = me.flags
		soap.body.eflags = me.eflags
		soap.body.momx = me.momx
		soap.body.momy = me.momy
		soap.body.momz = me.momz
		soap.body.target = me
		
		soap.body.colorized = me.colorized
		
		soap.body.shadowscale = me.shadowscale
	end
end)

rawset(_G, "TakisDeathThinker",function(p,me,takis)
	
	if p.deadtimer == 1
		DoFlash(p,PAL_NUKE,7)
	end
	
	if takis.saveddmgt
		if takis.saveddmgt == "DMG_FROZEN"
			me.sprite2 = SPR2_TICE
			me.flags = $ &~MF_NOCLIPHEIGHT
			me.color = SKINCOLOR_ICY
			
			if not (takis.onGround)
				if p.deadtimer > TR
					p.deadtimer = TR
				end
			end
			
			TakisSpawnDeadBody(p,me,takis)
			return
		elseif takis.saveddmgt == DMG_DEATHPIT
			//me.flags = $|MF_NOCLIPHEIGHT
			return
		end
	else
		
	end
	
	//explosion anim
	if me.sprite2 == SPR2_TDED
		if p.deadtimer < 21
			A_BossScream(me,0,MT_SONIC3KBOSSEXPLODE)
		end
		if not takis.stoprolling
			me.rollangle = $-(ANG2*2)
		end
	end
	
	
	me.flags = $ &~MF_NOCLIPHEIGHT

	if (me.rollangle ~= 0)
	or not (takis.onGround)
		if p.deadtimer > TR
			p.deadtimer = TR
		end
	end
	
	if me.eflags & MFE_JUSTHITFLOOR
	and (me.sprite2 ~= SPR2_TDD2)
	and takis.onGround
		if (me.rollangle == 0)
			me.sprite2 = SPR2_TDD2
		else
			P_SetObjectMomZ(me,10*FU)
			me.rollangle = 0
			takis.stoprolling = true
			me.eflags = $ &~MFE_JUSTHITFLOOR
		end
		
		DoFlash(p,PAL_NUKE,5)
		S_StartSound(me,sfx_slam)
	end
	TakisSpawnDeadBody(p,me,takis)
	
end)

local lerp0 = {
	["SUNSTROKE"] = 0,
	["FREEZING"] = 0,
}
local lerp1 = {
	["SUNSTROKE"] = 0,
	["FREEZING"] = 0,
}

local function FixedLerp(val1,val2,amt)
	local p = FixedMul(FRACUNIT-amt,val1) + FixedMul(amt,val2)
	return p
end

rawset(_G,"TakisDrawAliments", function(v, p, x, y, scale, flags, sx, sy, salign, dist, angle)

	local lerp = 0
	if (p == displayplayer)
		lerp = lerp0
	else
		lerp = lerp1
	end
	
	local takis = p.takistable
	
	local lerpx, lerpy = 0, 0
	
	local function DoShift(val, ang)
		lerpx = $+P_ReturnThrustX(nil, ang, val)
		lerpy = $+P_ReturnThrustY(nil, ang, val)
	end
	local function DoLerp(kind, retract, val)
		if (p == displayplayer) then
			if (retract)
				lerp0[kind] = FixedLerp(lerp0[kind], 0, FU*60/100)
			else
				lerp0[kind] = FixedLerp(lerp0[kind], val, FU*60/100)
			end
		else
			if (retract)
				lerp1[kind] = FixedLerp(lerp1[kind], 0, FU*60/100)
			else
				lerp1[kind] = FixedLerp(lerp1[kind], val, FU*60/100)
			end
		end
	end
	
	local sspatch = v.cachePatch("TA_SUNS")
	local ipatch = v.cachePatch("TA_FREZ")
	
	if takis.aliments.sunstroked
		v.drawScaled(x+lerpx, y+lerpy, scale, sspatch, flags)
		
		DoShift(lerp["SUNSTROKE"], angle)
		DoLerp("SUNSTROKE", false, dist)
	else
		DoShift(lerp["SUNSTROKE"], angle)
		DoLerp("SUNSTROKE", true, dist)
	end

	if takis.aliments.iced
		v.drawScaled(x+lerpx, y+lerpy, scale, ipatch, flags)
		
		DoShift(lerp["FREEZING"], angle)
		DoLerp("FREEZING", false, dist)
	else
		DoShift(lerp["FREEZING"], angle)
		DoLerp("FREEZING", true, dist)
	end
	
	
	if takis.aliments.icecount
		local max = TAKIS_MAX_ICECOUNT*FU
		local erm = FixedDiv(takis.aliments.icecount*FU,max)
		
		local scale2 = (30*FU)-FixedMul(erm,30*FU)
		
		if scale2 < 0 then scale2 = FU end
		
		v.drawCropped(
		(hudinfo[HUD_LIVES].x)*FU, (hudinfo[HUD_LIVES].y*FU)+(scale2/2),
		scale,scale,v.cachePatch("TA_ICE"), flags,nil,
		0,scale2,30*FU,30*FU)	
	end
	
end)

rawset(_G,"TakisResetAliments", function(takis,which)
	if which == nil
		which = "all"
	end
	
	which = string.lower(which)
	
	if which == "all"
		takis.aliments.sunstroked = false
		takis.aliments.sunstrokecount = 0
		takis.aliments.iced = false
		takis.aliments.icecount = 0
		takis.aliments.timetoice = 0
		takis.aliments.iceremove = 0
	else
	
		if which == "sunstroke"
			takis.aliments.sunstroked = false
			takis.aliments.sunstrokecount = 0
		elseif which == "freezing"
			takis.aliments.iced = false
			takis.aliments.icecount = 0
			takis.aliments.timetoice = 0
			takis.aliments.iceremove = 0
		end
		
	end
end)

