--add wind up to frogroller
--render smaller cleaner dragonfly

freeslot(
	"MT_DRAGONFLY",
	"MT_DRAGONFLYWINGS",
	"SPR_DRFL",
	"SPR_DRFW",
	"S_DRFL01",
	"S_DRFL02",
	"S_DRFL03",
	"S_DRFL04",
	"S_DRFL05",
	"S_DRFL06",
	"MT_FROGLING",
	"MT_FROGTONGUE",
	"SPR_FGLG",
	"SPR_FGTG",
	"S_FRLG01",
	"S_FRLG02",
	"S_FRLG03",
	"S_FRLG04",
	"S_FRLG05",
	"S_FRLG06",
	"S_FRLG07",
	"S_FRLG08",
	"S_FRLG09",
	"S_FRLG10",
	"S_FRLG11",
	"MT_TOADROLLER",
	"MT_TOADBALL",
	"SPR_TDRL",
	"S_TDBL01",
	"S_TDBL02",
	"S_TDBL03",
	"S_TDBL04",
	"S_TDBL05",
	"S_TDBL06",
	"S_TDBL07",
	"S_TDBL08",
	"MT_CRYSTAL",
	"SPR_S500",
	"SPR_CRYS",
	"S_CRYS1",
	"S_CRYS2",
	"S_CRYS3",
	"S_CRYS4",
	"S_CRYS5",
	"S_CRYS6",
	"S_CRYS7"
)

mobjinfo[MT_CRYSTAL] = {
	doomednum = 663,
	spawnstate = S_CRYS1,
	reactiontime = 500,
	deathstate = S_CRYS7,
	deathsound = sfx_antiri,
	mass = 1000,
	damage = 1,
	speed = 0*FRACUNIT,
	radius = 24*FRACUNIT,
	height = 24*FRACUNIT,
	flags = MF_SPECIAL|MF_RUNSPAWNFUNC|MF_NOGRAVITY|MF_NOCLIP
}

states[S_CRYS1] = {SPR_CRYS, FF_FULLBRIGHT|FF_ANIMATE|A, 16, A_None, 8, 2, S_CRYS1}
states[S_CRYS7] = {SPR_NULL, FF_FULLBRIGHT|A, 1, A_AwardScore, 0, 0, S_CRYS2}
states[S_CRYS2] = {SPR_CRYS, FF_FULLBRIGHT|A, 1, A_SpawnObjectRelative, MT_SUPERSPARK, 0+(0*65536), S_CRYS3}
states[S_CRYS3] = {SPR_S500, FF_FULLBRIGHT|A, 5, A_BunnyHop, 2, 0, S_CRYS4}
states[S_CRYS4] = {SPR_S500, FF_FULLBRIGHT|A, 5, A_BunnyHop, 1, 0, S_CRYS5}
states[S_CRYS5] = {SPR_S500, FF_FULLBRIGHT|A, 5, A_BunnyHop, 0, 0, S_CRYS6}
states[S_CRYS6] = {SPR_S500, FF_FULLBRIGHT|A, 15, A_None, 0, 0, S_NULL}

mobjinfo[MT_DRAGONFLY] = {
	doomednum = 2300,
	spawnstate = S_DRFL01,
	deathstate = S_DRFL05,
	painstate = S_DRFL05,
	reactiontime = TICRATE,
	radius = 32*FRACUNIT,
	height = 32*FRACUNIT,
	flags = MF_SPECIAL|MF_NOGRAVITY|MF_SHOOTABLE|MF_BOUNCE
}
mobjinfo[MT_DRAGONFLYWINGS] = {
	doomednum = -1,
	spawnstate = S_DRFL03,
	flags = MF_SPECIAL|MF_RUNSPAWNFUNC|MF_NOGRAVITY|MF_NOCLIP
}

states[S_DRFL01] = {SPR_DRFL, A, 1, A_None, 0, 0, S_DRFL04}
states[S_DRFL02] = {SPR_DRFL, B, 1, A_None, 0, 0, S_DRFL02}
states[S_DRFL03] = {SPR_DRFW, FF_ANIMATE|A, 4, A_None, 2, 2, S_NULL}
states[S_DRFL04] = {SPR_DRFL, A, 1, A_None, 0, 0, S_DRFL01}
states[S_DRFL05] = {SPR_DRFL, C, 15, A_None, 0, 0, S_DRFL06}
states[S_DRFL06] = {SPR_NULL, A, 1, A_NapalmScatter, MT_BOXSPARKLE+(8*65536), 40+(0*65536), S_NULL}







local wandertimemax = 70
local wandertimeslow = 55
local wandertimemove = 35
local wingchargemax = 85
local wingchargeslow = 70
local wingchargemove  = 45
local fly_randomangle = FixedAngle(P_RandomRange(0,359))

addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	for player in players.iterate
		
		
		if mobj.wandertimer == nil	
			mobj.wandertimer = 0
		end
		if mobj.wingchargetimer == nil	
			mobj.wingchargetimer = 0
		end		

	
----death
		if mobj.state == S_DRFL05	--if death frame appears...
			mobj.flags = MF_SPECIAL
			mobj.wandertimer = 0
			mobj.wingchargetimer = 0
			mobj.momz = $ - 1*FRACUNIT
			
			if P_IsObjectOnGround(mobj) 
				mobj.state = S_DRFL06
				P_SpawnMobj(mobj.x , mobj.y, mobj.z, MT_ARIDDUST)
				P_SpawnMobj(mobj.x , mobj.y, mobj.z, MT_IVSP)
				P_SpawnMobj(mobj.x , mobj.y, mobj.z, MT_SEED)
				S_StartSound(player.mo, 151, player) --CORKH
			end

		return end

		
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		local mobjlook = R_PointToAngle2(mobj.x, mobj.y, player.mo.x, player.mo.y)
			

		if mobjrange > 2000*FRACUNIT
		return end
		
-----wandering	

		if (mobj.state == S_DRFL01
		or mobj.state == S_DRFL02)
		and mobj.wingchargetimer < wingchargeslow
			P_SpawnMobj(mobj.x, mobj.y-FixedAngle(cos(mobj.angle))/4, mobj.z, MT_DRAGONFLYWINGS)
		end
		
		if player.deadtimer > 0
		return end
		
		
		if mobj.wandertimer >= wandertimemax
			mobj.wandertimer = 0
		end

		if mobj.wandertimer < wandertimemax
		and mobj.wingchargetimer == 0
			mobj.wandertimer = $ + 1
			S_StartSound(mobj, 706, player)
		end
		
		if mobj.wandertimer == wandertimemove
		and mobj.wingchargetimer == 0
		
			
			
			P_InstaThrust(mobj, fly_randomangle, 3*FRACUNIT)	
			mobj.angle = fly_randomangle
			
			P_SetObjectMomZ(mobj, P_RandomRange(1,-1)*FRACUNIT, nil)
		end

		if mobj.wandertimer > wandertimeslow
			P_Thrust(mobj, mobj.angle, 0*FRACUNIT)	
			P_SetObjectMomZ(mobj, 0*FRACUNIT, nil)
		end

----detect player						
		--if P_LookForEnemies(player)
		if (mobjrange < 600*FRACUNIT
		or (mobjrange < 1200*FRACUNIT 
		and (player.powers[pw_tailsfly] > 0 or player.pflags & PF_GLIDING)))
		and player.mo.eflags != MFE_UNDERWATER
		and mobj.wingchargetimer == 0
			mobj.wingchargetimer = 1
			mobj.wandertimer = 0
		end
		
		if mobj.wingchargetimer > 0	
		
			mobj.state = S_DRFL02
			
			mobj.wingchargetimer = $ + 1
			
			
			
			if mobj.wingchargetimer < wingchargemove	
				P_SetObjectMomZ(mobj, 0*FRACUNIT, nil)
				P_InstaThrust(mobj, mobj.angle, -3*FRACUNIT)	
				mobj.angle = mobjlook
				S_StartSound(mobj, 606, player)
			end
	
	
----charge at player		
			if mobj.wingchargetimer >= wingchargemove	
			and mobj.wingchargetimer <= wingchargeslow
			
				--P_SetObjectMomZ(mobj, 5*FRACUNIT, nil)
				mobj.flags = MF_SHOOTABLE|MF_PAIN|MF_NOGRAVITY|MF_SHOOTABLE|MF_BOUNCE
				if (player.pflags & PF_THOKKED or (player.pflags & PF_SPINNING and player.speed > 0))
				and (player.mo.z > mobj.z - 48*FRACUNIT and player.mo.z < mobj.z + 48*FRACUNIT)
				and	player.powers[pw_tailsfly] == 0
					mobj.flags = MF_SPECIAL|MF_ENEMY|MF_SHOOTABLE|MF_NOGRAVITY|MF_BOUNCE
					S_StartSound(mobj, 152, player) --crying
					S_StartSound(mobj, 258, player) --bump
					
				end
				P_InstaThrust(mobj, mobj.angle, 20*FRACUNIT)
				S_StartSound(mobj, 27, player)
				mobj.state = S_DRFL01
				if ((player.powers[pw_tailsfly] > 0 or player.pflags & PF_GLIDING) and player.mo.eflags != MFE_UNDERWATER)
					mobj.wingchargetimer = wingchargemove
					mobj.angle = mobjlook
					P_InstaThrust(mobj, mobj.angle, 20*FRACUNIT)
				end
			
				P_SpawnGhostMobj(mobj)
				
				if player.mo.z > mobj.z
					P_SetObjectMomZ(mobj, 5*FRACUNIT, nil)
				end
				if player.mo.z < mobj.z
					P_SetObjectMomZ(mobj, -5*FRACUNIT, nil)
				end
			end
		end

-----slow down after charging		
		if mobj.wingchargetimer > wingchargeslow
		and mobj.wingchargetimer < wingchargemax	
			P_InstaThrust(mobj, mobj.angle, 10*FRACUNIT)
			mobj.flags = MF_SPECIAL|MF_ENEMY|MF_SHOOTABLE|MF_NOGRAVITY
		end
			
		if mobj.wingchargetimer >= wingchargemax	
			mobj.wingchargetimer = 0	
			mobj.wandertimer = 0
			P_SetObjectMomZ(mobj, 0*FRACUNIT, nil)
		end
		
				
		if mobj.eflags & MFE_UNDERWATER 
			P_SetObjectMomZ(mobj, 3*FRACUNIT, nil)
		end
	end
end,MT_DRAGONFLY
)
addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	for player in players.iterate
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		local mobjlook = R_PointToAngle2(mobj.x, mobj.y, player.mo.x, player.mo.y)
		
		mobj.angle = fly_randomangle
		if (mobjrange < 600*FRACUNIT
		or (mobjrange < 1200*FRACUNIT 
		and ((player.powers[pw_tailsfly] > 0 or player.pflags & PF_GLIDING) and player.mo.eflags != MFE_UNDERWATER)))
			mobj.angle = mobjlook
		end	
				
	end
end,MT_DRAGONFLYWINGS
)	

mobjinfo[MT_FROGLING] = {
	doomednum = 2301,
	spawnstate = S_FRLG01,
	deathstate = S_FRLG05,
	painstate = S_FRLG05,
	reactiontime = 1*FRACUNIT,
	radius = 32*FRACUNIT,
	height = 48*FRACUNIT,
	flags = MF_SPECIAL|MF_ENEMY|MF_SHOOTABLE|MF_BOUNCE
}


mobjinfo[MT_FROGTONGUE] = {
	doomednum = -1,
	spawnstate = S_FRLG07,
	radius = 48*FRACUNIT,
	height = 32*FRACUNIT,
	flags = MF_SPECIAL|MF_PAIN
}

states[S_FRLG01] = {SPR_FGLG, A, 1, A_None, 0, 0, S_FRLG01}
states[S_FRLG09] = {SPR_FGLG, B, 1, A_None, 0, 0, S_FRLG09}
states[S_FRLG10] = {SPR_FGLG, C, 1, A_None, 0, 0, S_FRLG10}
states[S_FRLG11] = {SPR_FGLG, D, 1, A_None, 0, 0, S_FRLG11}
states[S_FRLG02] = {SPR_FGLG, E, 1, A_None, 0, 0, S_FRLG02}

states[S_FRLG07] = {SPR_FGTG, A, 1, A_None, 0, 0, S_FRLG03}
states[S_FRLG03] = {SPR_FGTG, A, 4, A_None, 0, 0, S_FRLG04}
states[S_FRLG04] = {SPR_FGTG, B, 4, A_None, 0, 0, S_NULL}

states[S_FRLG05] = {SPR_FGLG, F, 1, A_None, 0, 0, S_FRLG08}
states[S_FRLG08] = {SPR_FGLG, F, 15, A_None, 0, 0, S_FRLG06}
states[S_FRLG06] = {SPR_NULL, A, 1, A_NapalmScatter, MT_BOXSPARKLE+(8*65536), 40+(0*65536), S_NULL}

local hoptimemax = 70
--local hoptimeslow = 55
local hoptimemove = 35
local tonguechargemax = 70
--local tonguechargeslow = 60
local tonguechargemove  = 15

addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	for player in players.iterate
		

		
		if mobj.hoptimer == nil	
			mobj.hoptimer = 0
		end
		if mobj.tonguechargetimer == nil	
			mobj.tonguechargetimer = 0
		end		
		if player.deadtimer > 0
			mobj.state = S_FRLG01
		return end


		if mobj.state == S_FRLG06
			mobj.state = S_NULL
		return end
		if mobj.state == S_FRLG08
			mobj.momz = $ - 1*FRACUNIT/10
			--if P_IsObjectOnGround(mobj) 
			
			
				mobj.state = S_FRLG06
				
				P_SpawnMobj(mobj.x , mobj.y, mobj.z, MT_ARIDDUST)
				P_SpawnMobj(mobj.x , mobj.y, mobj.z, MT_IVSP)
				P_SpawnMobj(mobj.x , mobj.y, mobj.z, MT_SEED)
				S_StartSound(player.mo, 151, player) --CORKH
			--return end
		return end
		
		if mobj.state == S_FRLG05	--if death frame appears...
			S_StartSound(mobj, 152, player) --crying
			S_StartSound(mobj, 258, player) --bump
			
			mobj.state = S_FRLG08
			mobj.flags = MF_SPECIAL
			mobj.hoptimer = 0
			mobj.tonguechargetimer = 0
			P_SetObjectMomZ(mobj, 7*FRACUNIT, nil)
			P_InstaThrust(mobj, player.mo.angle, -5*FRACUNIT+player.speed/2)
		return end
		
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		local mobjlook = R_PointToAngle2(mobj.x, mobj.y, player.mo.x, player.mo.y)

		if mobjrange > 1000*FRACUNIT
		return end
		
		mobj.flags = MF_SPECIAL|MF_ENEMY|MF_SHOOTABLE|MF_BOUNCE


							
		if mobj.hoptimer < hoptimemax	
		and mobj.tonguechargetimer == 0
			mobj.hoptimer = $ + 1
			mobj.state = S_FRLG01
			
		end
		
		if not P_IsObjectOnGround(mobj)
			if mobjrange < 64*FRACUNIT
			and (player.mo.z > mobj.z - 64*FRACUNIT and player.mo.z < mobj.z + 64*FRACUNIT)
			and (player.pflags & PF_THOKKED or (player.pflags & PF_SPINNING and player.speed > 0))
				mobj.state = S_FRLG05
			end
			if mobj.momz > 1*FRACUNIT
				mobj.state = S_FRLG09
			end
			if mobj.momz < -1*FRACUNIT
				mobj.state = S_FRLG10
			end
		end

							
		if ((mobj.hoptimer >= hoptimemax or mobj.tonguechargetimer > 0)
		and P_IsObjectOnGround(mobj))
			mobj.hoptimer = 0
			S_StartSound(mobj, 570, player) --ribbit/croak
		end
				
		if mobj.hoptimer == hoptimemove
			local randomangle = FixedAngle(P_RandomRange(0,359))
			
			P_InstaThrust(mobj, randomangle, 3*FRACUNIT)	
			mobj.angle = randomangle
			P_SetObjectMomZ(mobj, 5*FRACUNIT, nil)
			S_StartSound(mobj, 695, player) --hopping
			

		end
		
		if mobjrange < 500*FRACUNIT
		and mobjrange > 175*FRACUNIT
		and (player.mo.z > mobj.z - 16*FRACUNIT and player.mo.z < mobj.z + 256*FRACUNIT)
			if mobj.eflags & MFE_UNDERWATER 
				mobj.angle = mobjlook
				P_InstaThrust(mobj, mobj.angle, 10*FRACUNIT)
			end
			if mobj.tonguechargetimer == 0
				mobj.hoptimer = $ + 5
				if mobj.hoptimer == hoptimemove
					mobj.angle = mobjlook
					S_StartSound(mobj, 695, player)
					P_InstaThrust(mobj, mobj.angle, 10*FRACUNIT)	
					P_SetObjectMomZ(mobj, 7*FRACUNIT, nil)
					if mobj.eflags & MFE_UNDERWATER 
						P_SetObjectMomZ(mobj, 3*FRACUNIT, nil)
					end
				end
			end
		end
		
		if mobjrange <= 175*FRACUNIT
		and mobj.tonguechargetimer == 0
		and (mobj.z < player.mo.z + 256*FRACUNIT and player.mo.z > mobj.z - 16*FRACUNIT)
			mobj.hoptimer = 0
			mobj.tonguechargetimer = 1
			P_InstaThrust(mobj, mobj.angle, 0*FRACUNIT)	
		end
		
		if mobj.tonguechargetimer > 0
			if mobj.tonguechargetimer <= tonguechargemax
				--mobj.flags = MF_SHOOTABLE|MF_PAIN
				mobj.angle = mobjlook
				mobj.tonguechargetimer = $ + 1
				mobj.state = S_FRLG02
			end
		
			if mobj.tonguechargetimer < tonguechargemove
				mobj.state = S_FRLG11
			end
		end
		
		if mobj.tonguechargetimer == tonguechargemove
			P_SpawnMobj(mobj.x, mobj.y, mobj.z+16*FRACUNIT, MT_FROGTONGUE)
			S_StartSound(mobj, 496, player) --lick/tongue
			S_StartSound(mobj, 257, player) --tongue
		end
		
		if mobj.tonguechargetimer > tonguechargemax
			mobj.tonguechargetimer = 0
		end
	end
end,MT_FROGLING
)


addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	for player in players.iterate
		local mobjlook = R_PointToAngle2(mobj.x, mobj.y, player.mo.x, player.mo.y)
		if mobj.state == S_FRLG07
			mobj.angle = mobjlook
		end
		if mobj.state == S_FRLG03
			P_InstaThrust(mobj, mobj.angle, 60*FRACUNIT)
			
		end
		if mobj.state == S_FRLG04
			P_InstaThrust(mobj, mobj.angle, -55*FRACUNIT)	
		end
	end
end,MT_FROGTONGUE
)



mobjinfo[MT_TOADROLLER] = {
	doomednum = 2302,
	spawnstate = S_TDBL01,
	deathstate = S_TDBL05,
	painstate = S_TDBL05,
	reactiontime = TICRATE,
	radius = 48*FRACUNIT,
	height = 80*FRACUNIT,
	flags = MF_SPECIAL
}

mobjinfo[MT_TOADBALL] = {
	doomednum = -1,
	spawnstate = S_TDBL07,
	radius = 64*FRACUNIT,
	height = 64*FRACUNIT,
	flags = MF_SPECIAL|MF_PAIN|MF_MISSILE|MF_GRENADEBOUNCE
}

states[S_TDBL01] = {SPR_TDRL, A, 1, A_None, 0, 0, S_TDBL01}
states[S_TDBL02] = {SPR_TDRL, B, 1, A_None, 0, 0, S_TDBL02}
states[S_TDBL07] = {SPR_TDRL, D, 1, A_None, 0, 0, S_TDBL03}
states[S_TDBL03] = {SPR_TDRL, D, 1, A_None, 0, 0, S_TDBL03}
states[S_TDBL04] = {SPR_TDRL, A, 4, A_None, 0, 0, S_TDBL04}
states[S_TDBL05] = {SPR_TDRL, C, 4, A_None, 0, 0, S_TDBL08}
states[S_TDBL08] = {SPR_TDRL, C, 15, A_None, 0, 0, S_TDBL06}
states[S_TDBL06] = {SPR_NULL, A, 1, A_NapalmScatter, MT_BOXSPARKLE+(8*65536), 40+(0*65536), S_NULL}

local frogballmaxhp = 1

local frogballmax = 70
local frogballslow = 55
local frogballmove = 35
local frogrollmax = 70
local frogrollslow = 60
local frogrollmove  = 35


addHook("MobjThinker", function(mobj,player)
	
	if not (mobj and mobj.valid)
		return end	
	for player in players.iterate
		
		
		if mobj.frogballtimer == nil	
			mobj.frogballtimer = 0
		end
		if mobj.frogballchargetimer == nil	
			mobj.frogballchargetimer = 0
		end		
		if mobj.frogballhealth == nil	
			mobj.frogballhealth = 0
		end		
	

		

		if mobj.state == S_TDBL06
			mobj.state = S_NULL
		return end
		if mobj.state == S_TDBL08
			mobj.momz = $ - 1/10*FRACUNIT
			--if P_IsObjectOnGround(mobj) 
				mobj.state = S_TDBL06
				P_SpawnMobj(mobj.x , mobj.y, mobj.z, MT_ARIDDUST)
				P_SpawnMobj(mobj.x , mobj.y, mobj.z, MT_IVSP)
				P_SpawnMobj(mobj.x , mobj.y, mobj.z, MT_SEED)
				S_StartSound(player.mo, 151, player) --CORKH
			--return end
		return end
		
	
		if mobj.state == S_TDBL05
			mobj.frogballhealth = $ + 1
			mobj.flags = MF_SPECIAL
			mobj.frogballhealth = 0
			mobj.frogballchargetimer = 0
			mobj.frogballtimer = 0
			P_SetObjectMomZ(mobj, 7*FRACUNIT, nil)
			P_InstaThrust(mobj, player.mo.angle, player.speed/2)
			S_StartSound(mobj, 152, player) --crying
			S_StartSound(mobj, 258, player) --bump
		return end
						
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		local mobjlook = R_PointToAngle2(mobj.x, mobj.y, player.mo.x, player.mo.y)
		
		mobj.state = S_TDBL01

		if mobjrange > 6000*FRACUNIT
		return end
			
		
		if mobjrange <= 5000*FRACUNIT
		and (player.mo.z < mobj.z + 64*FRACUNIT and player.mo.z > mobj.z - 500*FRACUNIT)
			mobj.angle = mobjlook
			mobj.frogballtimer = $ + 1
			
			
			if mobj.frogballtimer >= frogballmove
				mobj.state = S_TDBL02
			end
			
			if mobj.frogballtimer >= frogballmax
				mobj.frogballtimer = 0
			end

			if mobj.frogballtimer == frogballmove
				P_SpawnMobj(mobj.x, mobj.y, mobj.z+32*FRACUNIT, MT_TOADBALL)
				S_StartSound(mobj, 257, player) --tongue
				S_StartSound(mobj, 496, player) --lick/tongue
			end		
		end
	end
end,MT_TOADROLLER
)


addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	for player in players.iterate	

		local mobjlook = R_PointToAngle2(mobj.x, mobj.y, player.mo.x, player.mo.y)

		if mobj.state == S_TDBL07
			mobj.angle = mobjlook

		end
			
		P_InstaThrust(mobj, mobj.angle,10*FRACUNIT)	
		

		if P_IsObjectOnGround(mobj) 
		and mobj.momz > 0
			--P_SetObjectMomZ(mobj, 5*FRACUNIT, nil)
			P_SpawnMobj(mobj.x , mobj.y , mobj.z , MT_DUST)
			S_StartSound(mobj, 614, player)	--roll ball thump
		end
		
		
---If stopped in place----------
		if mobj.xcheck == nil
			mobj.xcheck = 0
			mobj.ycheck = 0
			mobj.xychecktics = 0
		end	
		
		mobj.xychecktics = $ + 1
		
		if mobj.xychecktics >= 2
			mobj.xychecktics = 0
			mobj.xcheck = mobj.x
			mobj.ycheck = mobj.y
		end
		
		
		if mobj.x == mobj.xcheck
		and mobj.y == mobj.ycheck
		and mobj.xychecktics == 1
			S_StartSound(mobj, 462, player) 	--roll ball vanish
			P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z + P_RandomRange(-32,32), MT_TNTDUST)
			P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z + P_RandomRange(-32,32), MT_TNTDUST)
			P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z + P_RandomRange(-32,32), MT_TNTDUST)
			P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z + P_RandomRange(-32,32), MT_TNTDUST)
			P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z + P_RandomRange(-32,32), MT_TNTDUST)
			P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z + P_RandomRange(-32,32), MT_TNTDUST)
			if not (mobj and mobj.valid)
			return end	
			P_KillMobj(mobj)
			
		end	
-----------------------

	end
end,MT_TOADBALL
)



freeslot(
	"MT_FROGSTATUEA",
	"S_FGST",
	"SPR_FGST",
	"MT_FROGSTATUEB",
	"S_FGSM",
	"SPR_FGSM",
	"MT_PAINTARROW",
	"S_PARR",
	"SPR_PARR",
	"S_PARR2",
	"MT_BOUNCEWEB",
	"S_BWEB",
	"MT_POSTPOUND",
	"S_PPND",
	"MT_WATERWHIRL",
	"S_WTWH",
	"MT_WHIRLBUBBLE",
	"S_WTWB",
	"SPR_SWIR",
	"MT_H",
	"S_H",
	"S_H2",
	"S_H3",
	"MT_I",
	"S_I",
	"S_I2",
	"S_I3",
	"S_I4",
	"MT_J",
	"S_J",
	"MT_K",
	"MT_L",
	"SPR_ROLL",
	"MT_SPINFAN",
	"S_SPNF",
	"MT_PAD",
	"SPR_LPAD",
	"S_PAD1",
	"MT_BOARDSPAWN",
	"S_BSPWN",
	"S_BSPWN2",
	"S_BSPWN3",
	"MT_BOARD",
	"SPR_BORD",
	"S_BOARD",
	"S_BOARD2",
	"MT_UNLOCK",
	"S_UNLK1",
	"S_UNLK2",
	"MT_UNLOCK2",
	"S_UNLK3",
	"S_UNLK4",
	"SPR_BTTN",
	"MT_DRSH",
	"S_DRSH",
	"MT_TKDR",
	"S_TKDR",
	"SPR_TKDR",
	"S_TKDR2",
	"S_TKDR3",
	"sfx_tkdr",
	"MT_GKEY",
	"SPR_GKEY",
	"S_GKEY",
	"S_GKEY2",
	"S_GKEY3",
	"MT_HINTTIPS",
	"MT_HINTTIPS2",
	"SPR_HELP",
	"S_HINT1",
	"S_HINT2",
	"S_HINT3",
	"S_HINT4",
	"MT_CROAKS",
	"S_CROAKS",
	"sfx_croaks",
	"MT_GREENSPRING",
	"S_GSPR",
	"S_GSPR2",
	"S_GSPR3",
	"S_GSPR4",
	"S_GSPR5",
	"SPR_GSPR",
	"MT_BLUEFLAME",
	"MT_BLUELIGHT",
	"MT_BLUECLUSTER1",
	"MT_BLUECLUSTER2",
	"SPR_BLFL",
	"SPR_BLCL",
	"SPR_BLCR",
	"S_BLFL1",
	"S_BLFL2",
	"S_BLFL3",
	"S_BLCL1",
	"S_BLCL2",
	"S_BLCR",
	"MT_OBJECT"
)
---automate spinning waterwhirl
addHook("PlayerThink", function(player)
	P_LinedefExecute(10, player.mo, nil)
	
	if player.mo.z > 4500*FRACUNIT
	and player.powers[pw_tailsfly] > 1 
		player.powers[pw_tailsfly] = $ - 1
	end
end
)


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




mobjinfo[MT_BLUEFLAME] = {
	doomednum = 958,
	spawnstate = S_BLFL1,
	seestate = S_BLFL1,
	reactiontime = TICRATE,
	speed = 0*FRACUNIT,
	radius = 32*FRACUNIT,
	height = 24*FRACUNIT,
	flags = MF_NOGRAVITY|MF_FIRE|MF_PAIN
}

states[S_BLFL1] = {SPR_BLFL, FF_FULLBRIGHT|FF_TRANS30|A, 1, A_None, 0, 0, S_BLFL2}
states[S_BLFL2] = {SPR_BLFL, FF_FULLBRIGHT|FF_ANIMATE|FF_TRANS30|A, 18, A_None, 6, 3, S_BLFL3}
states[S_BLFL3] = {SPR_BLFL, FF_FULLBRIGHT|FF_TRANS30|A, 1, A_None, 0, 0, S_BLFL2}

addHook("MobjThinker", function(mobj)
	mobj.scale = 3*FRACUNIT/2
	for player in players.iterate	
	local mobjlook = R_PointToAngle2(mobj.x, mobj.y, player.mo.x, player.mo.y)
	
		if mobjlook > 5000*FRACUNIT
		or player.deadtimer > 0
		return end
		if mobj.state == S_BLFL3
			P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z, MT_BLUECLUSTER1)	
			P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z, MT_BLUECLUSTER2)	
		end
		if mobj.state == S_BLFL1

			P_SpawnMobj(mobj.x, mobj.y, mobj.z, MT_BLUELIGHT)
		end
	end
end,MT_BLUEFLAME
)

mobjinfo[MT_BLUELIGHT] = {
	doomednum = -1,
	spawnstate = S_BLCR,
	seestate = S_BLCR,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY
}
states[S_BLCR] = {SPR_BLCR, FF_TRANS80|A, 1, A_None, 0, 0, S_BLCR}

addHook("MobjThinker", function(mobj)
	mobj.scale = 4*FRACUNIT
end,MT_BLUELIGHT
)

mobjinfo[MT_BLUECLUSTER1] = {
	doomednum = -1,
	spawnstate = S_BLCL1,
	seestate = S_BLCL1,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY
}
states[S_BLCL1] = {SPR_BLCL, FF_TRANS50|A, 64, A_None, 0, 0, S_NULL}

addHook("MobjThinker", function(mobj)
	P_SetObjectMomZ(mobj, P_RandomRange(1/10,3)*FRACUNIT)
	P_InstaThrust(mobj, mobj.angle, P_RandomRange(-3,3)*FRACUNIT)
	mobj.angle = $ + ANG1
end,MT_BLUECLUSTER1
)

mobjinfo[MT_BLUECLUSTER2] = {
	doomednum = -1,
	spawnstate = S_BLCL2,
	seestate = S_BLCL2,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY
}
states[S_BLCL2] = {SPR_BLCL, FF_TRANS50|B, 64, A_None, 0, 0, S_NULL}


addHook("MobjThinker", function(mobj)
	P_SetObjectMomZ(mobj, P_RandomRange(1/10,3)*FRACUNIT)
	P_InstaThrust(mobj, mobj.angle, P_RandomRange(-5,5)*FRACUNIT)
	mobj.angle = $ + ANG1
	mobj.scale = 3*FRACUNIT/2
end,MT_BLUECLUSTER2
)

mobjinfo[MT_TKDR] = {
	doomednum = 698,
	spawnstate = S_TKDR,
	deathstate = S_TKDR,
	reactiontime = TICRATE,
	radius = 32*FRACUNIT,
	height = 128*FRACUNIT,
	flags = MF_NOGRAVITY|MF_SOLID
}

states[S_TKDR] = {SPR_TKDR, FF_PAPERSPRITE|A, 1, A_None, 0, 0, S_TKDR}
states[S_TKDR2] = {SPR_TKDR, FF_PAPERSPRITE|A, 1, A_None, 0, 0, S_TKDR3}
states[S_TKDR3] = {SPR_TKDR, FF_PAPERSPRITE|B, 12, A_None, 0, 0, S_NULL}

addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	for player in players.iterate
		
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		
		if mobj.state > S_TKDR
			P_SpawnMobj(mobj.x + P_RandomRange(-64,64)*mobj.scale, mobj.y + P_RandomRange(-64,64)*mobj.scale, mobj.z + P_RandomRange(0,128)*mobj.scale, MT_IVSP)
		end
		
		if mobjrange <= 100*FRACUNIT		---if youre at a certain distance...
		and player.keynum > 2
		and mobj.state == S_TKDR
			--P_KillMobj(mobj,mobj,nil)
			S_StartSound(player.mo, sfx_tkdr, player)
			S_StartSound(player.mo, 194, player)
			S_StartSound(player.mo, 195, player)
			P_SpawnGhostMobj(mobj)
			mobj.state = S_TKDR2
		end
		
	end
end,MT_TKDR
)



mobjinfo[MT_DRSH] = {
	doomednum = 699,
	spawnstate = S_DRSH,
	deathstate = S_DRSH,
	reactiontime = TICRATE,
	radius = 1*FRACUNIT,
	height = 1*FRACUNIT,
	flags = MF_NOGRAVITY|MF_NOCLIP|MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_SCENERY
}

states[S_DRSH] = {SPR_NULL, A, 1, A_None, 0, 0, S_DRSH}

addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	for player in players.iterate
		if mobj.tkdrstate == nil
			mobj.tkdrstate = 0
		end
		
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		local mobjlook = R_PointToAngle2(mobj.x, mobj.y, player.mo.x, player.mo.y)
		local playerlook = R_PointToAngle2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		
		
		
		mobj.tkdrstate = 0
		if mobjrange <= 600*FRACUNIT		---if youre at a certain distance...
		and player.keynum < 3
			mobj.tkdrstate = 1
			
		end
		
		if mobj.tkdrstate == 1
			player.mo.angle = playerlook	---stare at the player
			P_InstaThrust(player.mo, player.mo.angle, -10*FRACUNIT)
		end
	end
end,MT_DRSH
)


mobjinfo[MT_GKEY] = { --Holdable button
	doomednum = 789,
	spawnstate = S_GKEY,
	seestate = S_GKEY,
	reactiontime = TICRATE,
	speed = 0*FRACUNIT,
	radius = 32*FRACUNIT,
	height = 2*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY
}

states[S_GKEY] = {SPR_GKEY,  FF_ANIMATE|A, 32, A_None, 16, 2, S_GKEY}
states[S_GKEY2] = {SPR_GKEY, Q , 1, A_None, 0, 0, S_GKEY3}
states[S_GKEY3] = {SPR_GKEY, Q , 1, A_None, 0, 0, S_NULL}

addHook("MobjThinker", function(mobj,player)
	for player in players.iterate
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		
		
		if player.keynum == nil
			player.keynum = 0
		end
		
		if mobj.tics & 4*TICRATE
		and mobjrange <= 4096*FRACUNIT		---if youre at a certain distance...
			P_SpawnMobj(mobj.x + P_RandomRange(-60,60), mobj.y + P_RandomRange(-60,60), mobj.z + P_RandomRange(60,-60), MT_BOXSPARKLE)	
		end
		
		if player.mo.z <= mobj.z + 128*FRACUNIT
		and player.mo.z >= mobj.z - 128*FRACUNIT
		and mobjrange <= 64*FRACUNIT		---if youre at a certain distance...
			P_SpawnGhostMobj(mobj)
			if mobj.state == S_GKEY
				mobj.state = S_GKEY2
			end
			if mobj.state == S_GKEY2
				player.keynum = $ + 1
				S_StartSound(mobj, 196, player)
				S_StartSound(mobj, 188, player)
			end
		end
	end
end,MT_GKEY
)


mobjinfo[MT_HINTTIPS] = {
	doomednum = 957,
	spawnstate = S_HINT1,
	seestate = S_HINT1,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY
}

states[S_HINT1] = {SPR_HELP, FF_FULLBRIGHT|FF_PAPERSPRITE|A, 1, A_None, 0, 0, S_HINT1}
states[S_HINT2] = {SPR_HELP, FF_FULLBRIGHT|FF_PAPERSPRITE|A, 350, A_None, 0, 0, S_HINT2}
states[S_HINT3] = {SPR_HELP, FF_FULLBRIGHT|FF_PAPERSPRITE|A, 1, A_None, 0, 0, S_HINT1}
mobjinfo[MT_HINTTIPS2] = {
	doomednum = -1,
	spawnstate = S_HINT4,
	seestate = S_HINT4,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP
}
states[S_HINT4] = {SPR_HELP,  FF_FULLBRIGHT|FF_PAPERSPRITE|B, 71, A_None, 0, 0, S_NULL}

local tab = "cecho \\\\\\\\\\\\\\\\\\\\\\ "
local hint1 = "Here's some advice. These logs can be \\pounded into the ground with enough force. \\ Are you able to hit it hard enough?"
local hint2 = "This lift can only be raised by those \\who can roll into a ball..."
local hint3 = "You may be able to use the giant \\webs as trampolines!"
local hint4 = "These platforms are for quick, frog-like \\hoppers! Only bouncing and no walking!"
local hint5 = "Here's a friendly reminder that bubble \\ bouncing is immune to spike floors."
local hint12 = "Only these kind of walls ahead are climbable! \\Any other wall cannot be climbed."
local hint8 = "Dragonflies will attack maliciously \\if you fly like them. Be careful."

local tag01 = 1
local tag02 = 2
local tag03 = 3
local tag04 = 4
local tag05 = 5
local tag12 = 12
local tag8 = 8

addHook("MobjThinker", function(mobj)
	--mobj.rollangle = $ + ANG1*5
	mobj.angle = $ + ANG1*5
end,MT_HINTTIPS2
)

--HINTS CAN CHANGE DEPENDING ON THE MOBJ ANGLE

addHook("MobjThinker", function(mobj,player)
	for player in players.iterate
	
		mobj.scale = 2*FRACUNIT/3
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		local getangle = mobj.angle/(59500*200)

		if mobjrange > 1000*FRACUNIT
		return end
		
		P_LinedefExecute(getangle, player.mo)
		
		if mobj.hinttics == nil
			mobj.hinttics = 0
		end
		
		mobj.hinttics = $ + 1
		--mobj.rollangle = $ - ANG1*5
		
		if mobj.hinttics == 71
			mobj.hinttics = 0
			P_SpawnMobj(mobj.x, mobj.y, mobj.z+64*FRACUNIT, MT_HINTTIPS2)	
		end
		
		if (player.mo.z > mobj.z + 64*FRACUNIT
		or mobjrange > 64*FRACUNIT)		---if youre at a certain distance...
		and mobj.state == S_HINT3
			mobj.state = S_HINT1
			
		end
		
		if (player.mo.z <= mobj.z + 64*FRACUNIT
		and player.mo.z >= mobj.z)
		and mobjrange <= 64*FRACUNIT		---if youre at a certain distance...
			
			if getangle == tag01
				COM_BufInsertText(player,tab+hint1)
			end
			if getangle == tag02
				COM_BufInsertText(player,tab+hint2)
			end
			if getangle == tag03
				COM_BufInsertText(player,tab+hint3)
			end			
			if getangle == tag04
				COM_BufInsertText(player,tab+hint4)
			end	
			if getangle == tag05
				COM_BufInsertText(player,tab+hint5)
			end	
			if getangle == tag12
				COM_BufInsertText(player,tab+hint12)
			end	
			if getangle == tag8
				COM_BufInsertText(player,tab+hint8)
			end	
															
			if mobj.state == S_HINT1	
				
				
				P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z + P_RandomRange(0,64), MT_BOXSPARKLE)
				P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z + P_RandomRange(0,64), MT_BOXSPARKLE)
				P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z + P_RandomRange(0,64), MT_BOXSPARKLE)
				P_SpawnMobj(mobj.x + P_RandomRange(-32,32), mobj.y + P_RandomRange(-32,32), mobj.z + P_RandomRange(0,64), MT_IVSP)
				
				S_StartSound(mobj, 720, player)
				mobj.state = S_HINT2	
			end
		end

	end
end,MT_HINTTIPS
)




mobjinfo[MT_UNLOCK] = {
	doomednum = 796,
	spawnstate = S_UNLK1,
	seestate = S_UNLK1,
	reactiontime = TICRATE,
	speed = 0*FRACUNIT,
	radius = 64*FRACUNIT,
	height = 2*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY
}

states[S_UNLK1] = {SPR_BTTN,  FF_PAPERSPRITE|FF_FULLBRIGHT|A, 1, A_None, 0, 0, S_UNLK1}
states[S_UNLK2] = {SPR_BTTN,  FF_PAPERSPRITE|FF_FULLBRIGHT|B, 1, A_None, 0, 0, S_UNLK2}



addHook("MobjThinker", function(mobj,player)
	for player in players.iterate
	
		if player.gate1 == nil
			player.gate1 = 0
		end
		
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		local getangle = mobj.angle/(59500*200)
		
		mobj.renderflags =  $|RF_FLOORSPRITE|RF_NOSPLATBILLBOARD
		
		if player.mo.z <= mobj.z
		and mobjrange <= 64*FRACUNIT		---if youre at a certain distance...
		and mobj.state == S_UNLK1
			P_LinedefExecute(getangle, player.mo)
			mobj.state = S_UNLK2
			S_StartSound(player.mo, 319, player)	
			S_StartSound(player.mo, 192, player)	
		end
	end
end,MT_UNLOCK
)

addHook("LinedefExecute",function(line,mo)
	local player = mo.player
	player.gate1 = 1
end,27 --linedef number activated for wood gates
)

mobjinfo[MT_BOARDSPAWN] = {
	doomednum = 956,
	spawnstate = S_BSPWN,
	seestate = S_BSPWN,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY
}
states[S_BSPWN] = {SPR_NULL, A, 1, A_None, 0, 0, S_BSPWN}
states[S_BSPWN3] = {SPR_NULL, A, 1, A_None, 0, 0, S_BSPWN3}
states[S_BSPWN2] = {SPR_NULL, A, 1, A_None, 0, 0, S_NULL}

mobjinfo[MT_BOARD] = {
	doomednum = -1,
	spawnstate = S_BOARD,
	seestate = S_BOARD,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP
}
states[S_BOARD] = {SPR_BORD,  FF_PAPERSPRITE|A, 9, A_None, 0, 0, S_BOARD2}
states[S_BOARD2] = {SPR_BORD,  FF_PAPERSPRITE|A, 16, A_None, 0, 0, S_NULL}

addHook("MobjThinker", function(mobj)
	for player in players.iterate
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
			
		if mobjrange > 1000*FRACUNIT
		return end
		P_SpawnMobj(mobj.x, mobj.y, mobj.z ,MT_BOARD)
		if mobj.state == S_BSPWN
			player.gate1 = 0
			mobj.state = S_BSPWN3
		end
		
		if player.gate1 == 1
		and mobj.state == S_BSPWN3
			mobj.state = S_BSPWN2
		end
	end
end,MT_BOARDSPAWN
)

addHook("MobjThinker", function(mobj)
	for player in players.iterate
	
		if not (mobj and mobj.valid)
			return end	
		P_InstaThrust(mobj, mobj.angle, 0*FRACUNIT)
		
		if mobj.state == S_BOARD
		and player.gate1 == 0
			P_InstaThrust(mobj, mobj.angle, 60*FRACUNIT)
		end
		if mobj.state == S_BOARD2
			mobj.angle = $ + ANG1*22
			
			P_SetObjectMomZ(mobj, -15*FRACUNIT)
			if player.gate1 == 0
				mobj.state = S_NULL
			end
		end
	end
end,MT_BOARD
)

mobjinfo[MT_PAD] = {
	doomednum = 797,
	spawnstate = S_PAD1,
	seestate = S_PAD1,
	reactiontime = TICRATE,
	speed = 0*FRACUNIT,
	radius = 128*FRACUNIT,
	height = 2*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY
}

states[S_PAD1] = {SPR_LPAD,  FF_PAPERSPRITE|A, 1, A_None, 0, 0, S_PAD1}

addHook("MobjThinker", function(mobj)
	mobj.scale = 2*FRACUNIT/3
	mobj.renderflags =  $|RF_FLOORSPRITE|RF_NOSPLATBILLBOARD

end,MT_PAD
)


mobjinfo[MT_FROGSTATUEB] = {
	doomednum = 950,
	spawnstate = S_FGSM,
	--speed = 0*FRACUNIT,
	radius = 24*FRACUNIT,
	height = 80*FRACUNIT,
	flags = MF_SOLID|MF_NOTHINK
}
states[S_FGSM] = {SPR_FGSM,  A, 1, A_None, 0, 0, S_FGSM}

mobjinfo[MT_FROGSTATUEA] = {
	doomednum = 951,
	spawnstate = S_FGST,
	flags = MF_SOLID|MF_NOTHINK
}


states[S_FGST] = {SPR_FGST,  A, 1, A_None, 0, 0, S_FGST}

mobjinfo[MT_PAINTARROW] = {
	doomednum = 979,
	spawnstate = S_PARR,
	--speed = 0*FRACUNIT,
	--radius = 64*FRACUNIT,
	--height = 512*FRACUNIT,
	flags = MF_NOCLIP|MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_SCENERY|MF_NOGRAVITY
}

states[S_PARR] = {SPR_PARR,  FF_PAPERSPRITE|A, 1, A_None, 0, 0, S_PARR}
states[S_PARR2] = {SPR_PARR,  FF_PAPERSPRITE|B, 1, A_None, 0, 0, S_PARR2}

addHook("MobjThinker", function(mobj,mapthing)
	mobj.scale = 2*FRACUNIT
	if mobj.angle <= ANGLE_MAX
		mobj.renderflags = $|RF_HORIZONTALFLIP
	end
end,MT_PAINTARROW
)

mobjinfo[MT_BOUNCEWEB] = {
	doomednum = 952,
	radius = 64*FRACUNIT,
	spawnstate = S_BWEB,
	flags = MF_NOCLIP|MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_SCENERY|MF_NOGRAVITY
}
states[S_BWEB] = {SPR_NULL, A, 1, A_None, 0, 0, S_BWEB}


addHook("MobjThinker", function(mobj,player)



	if not (mobj and mobj.valid)
		return end	
	for player in players.iterate
		if player.deadtimer > 0
		return end
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		--local anglevalue = tonumber(mobj.angle>>21)/10
		if mobjrange >= 86*FRACUNIT return end
		if (player.mo.z <= mobj.z + 0*FRACUNIT
		and player.mo.z >= mobj.z - 32*FRACUNIT
		and player.mo.momz < 0*FRACUNIT)
			S_StartSound(mobj,448, player) --web sfx stiffness --694
			S_StartSound(mobj,708, player) --web sfx boingy --,442
			if player.mo.state != S_PLAY_SPRING
				player.mo.state = S_PLAY_SPRING
			end
			if player.cmd.buttons & BT_SPIN
			and player.mo.momz < 0*FRACUNIT
				P_SetObjectMomZ(player.mo, ((player.mo.momz+ 10*FRACUNIT)*-1), nil)
			end
			if player.mo.momz < -30*FRACUNIT
				P_SetObjectMomZ(player.mo, 30*FRACUNIT, nil)
			return end
			if player.cmd.buttons != BT_SPIN
				P_SetObjectMomZ(player.mo, (player.mo.momz*-1) + 5*FRACUNIT, nil)
			end
		end
	end
end,MT_BOUNCEWEB
)



	

mobjinfo[MT_POSTPOUND] = {
	doomednum = 953,
	radius = 32*FRACUNIT,
	spawnstate = S_PPND,
	flags = MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_SCENERY|MF_NOGRAVITY
}
states[S_PPND] = {SPR_NULL, A, 1, A_None, 0, 0, S_PPND}

local function SectorHijack(player,sector,subsector)	
	local crush = R_PointInSubsector(player.mo.x+FixedMul(26*FRACUNIT, cos(player.mo.angle)), player.mo.y+FixedMul(26*FRACUNIT, sin(player.mo.angle))).sector
		
	if (crush and crush.valid)
		crush.floorheight = $ - 60*FRACUNIT
	end
end
addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	for player in players.iterate
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)

		if mobjrange >= 32*FRACUNIT return end
		if player.mo.state == S_PLAY_MELEE
		or (player.mo.momz <= -20*FRACUNIT and player.mo.z <= mobj.z + 7*FRACUNIT)
		--or player.mo.state == S_PLAY_MELEE_FINISH
		--or player.mo.state == S_PLAY_MELEE_LANDING
			P_InstaThrust(player.mo, player.mo.angle, 0*FRACUNIT)
			P_TeleportMove(player.mo, mobj.x, mobj.y ,mobj.z-2*FRACUNIT)
		end
			
		if player.mo.z <= mobj.z + 7*FRACUNIT
		--and player.mo.floorz >= mobj.z - 16*FRACUNIT
		and (player.mo.momz <= -20*FRACUNIT
		or player.mo.state == S_PLAY_MELEE_LANDING)
			
			P_SpawnMobj(player.mo.x + P_RandomRange(-48,48)*FRACUNIT, player.mo.y + P_RandomRange(-48,48)*FRACUNIT, player.mo.z + P_RandomRange(8,16)*FRACUNIT, MT_ARIDDUST)
			P_SpawnMobj(player.mo.x + P_RandomRange(-48,48)*FRACUNIT, player.mo.y + P_RandomRange(-48,48)*FRACUNIT, player.mo.z + P_RandomRange(8,16)*FRACUNIT, MT_ARIDDUST)
			P_SpawnMobj(player.mo.x + P_RandomRange(-48,48)*FRACUNIT, player.mo.y + P_RandomRange(-48,48)*FRACUNIT, player.mo.z + P_RandomRange(8,16)*FRACUNIT, MT_ARIDDUST)
			P_SpawnMobj(player.mo.x + P_RandomRange(-48,48)*FRACUNIT, player.mo.y + P_RandomRange(-48,48)*FRACUNIT, player.mo.z + P_RandomRange(8,16)*FRACUNIT, MT_ARIDDUST)
			P_SpawnMobj(player.mo.x + P_RandomRange(-48,48)*FRACUNIT, player.mo.y + P_RandomRange(-48,48)*FRACUNIT, player.mo.z + P_RandomRange(8,16)*FRACUNIT, MT_ARIDDUST)
			
			P_TeleportMove(mobj, mobj.x, mobj.y ,mobj.z-20*FRACUNIT)
			P_TeleportMove(player.mo, player.mo.x, player.mo.y ,player.mo.z+5*FRACUNIT)
			P_SetObjectMomZ(player.mo, 5*FRACUNIT, nil)
			S_StartSound(player.mo, 614, player)	--roll ball thump
			P_ResetPlayer(player)
			SectorHijack(player)
			P_KillMobj(mobj)
			
		end
	end
end,MT_POSTPOUND
)


mobjinfo[MT_CROAKS] = {
	doomednum = 770,
	spawnstate = S_CROAKS,
	seestate = S_CROAKS,
	radius = 512*FRACUNIT,
	flags = MF_NOGRAVITY|MF_NOCLIP|MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_SCENERY|MF_SPECIAL
}

states[S_CROAKS] = {SPR_NULL, A, 1, A_None, 0, 0, S_CROAKS}

addHook("MobjThinker", function(mobj,player)
	for player in players.iterate
		
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		
		if mobjrange <= 2000*FRACUNIT		---if youre at a certain distance...
		and not S_SoundPlaying(player.mo, sfx_croaks)
			S_StartSound(player.mo, sfx_croaks, player)
		end
	end
end,MT_CROAKS
)


mobjinfo[MT_WATERWHIRL] = {
	doomednum = 954,
	radius = 64*FRACUNIT,
	spawnstate = S_WTWH,
	flags = MF_NOCLIP|MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_SCENERY|MF_NOGRAVITY
}
states[S_WTWH] = {SPR_SWIR, FF_TRANS20|A, 1, A_None, 0, 0, S_WTWH}


addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	for player in players.iterate

		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		local playerlook = R_PointToAngle2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		
		if mobjrange > 1500*FRACUNIT
		return end 
		mobj.scale = 3*FRACUNIT/2
		mobj.flags = MF_NOCLIP|MF_NOBLOCKMAP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_SCENERY|MF_NOGRAVITY
		mobj.renderflags =  $|RF_FLOORSPRITE|RF_NOSPLATBILLBOARD
		mobj.angle = $ + ANG1*8
		

		if mobjrange <= 768*FRACUNIT
		and player.mo.eflags & MFE_UNDERWATER
			player.powers[pw_underwater] = 999
			player.mo.state = S_PLAY_PAIN
			player.mo.angle = playerlook + ANG1*315
			player.drawangle = $ + ANG1*20

			if mobj.bubbletics == nil
				mobj.bubbletics = 0
			end
			if mobj.bubbletics < 14
				mobj.bubbletics = $ + 1
			end
			if mobj.bubbletics == 14
				mobj.bubbletics = 0
				P_SpawnMobj(mobj.x + P_RandomRange(-450,450), mobj.y + P_RandomRange(-450,450), -450 ,MT_WHIRLBUBBLE)
			end
					
			if P_IsObjectOnGround(player.mo)
				P_SetObjectMomZ(player.mo, 3*FRACUNIT, nil)
			end
			if player.mo.momz < -7*FRACUNIT
				P_SetObjectMomZ(player.mo, player.mo.momz + 9*FRACUNIT/10, nil)
			end
			if (player.mo.momz < 7*FRACUNIT
			and player.cmd.buttons & BT_JUMP)
			or (player.mo.floorz >= player.mo.z - 80*FRACUNIT)
				P_SetObjectMomZ(player.mo, player.mo.momz + 20*FRACUNIT/40, nil)
			end
					
			if player.speed < 15*FRACUNIT
				P_Thrust(player.mo, player.mo.angle+ANG1*10, 1*FRACUNIT)
			end			
		end

	end
end,MT_WATERWHIRL
)


mobjinfo[MT_WHIRLBUBBLE] = {
	doomednum = -1,
	radius = 1*FRACUNIT,
	spawnstate = S_WTWB,
	flags = MF_NOCLIP|MF_NOCLIPTHING|MF_NOCLIPHEIGHT|MF_SCENERY|MF_NOGRAVITY
}
states[S_WTWB] = {SPR_BUBL, A, 1, A_None, 0, 0, S_WTWB}


addHook("MobjThinker", function(mobj)
	if not (mobj and mobj.valid) return end	
	mobj.scale = P_RandomRange(1,4)
	P_SetObjectMomZ(mobj, mobj.scale, nil)
	mobj.angle = $ + ANG1*10
	P_InstaThrust(mobj, mobj.angle, 5*FRACUNIT)
	
	if mobj.z >= mobj.floorz + (P_RandomRange(300,650))
		P_KillMobj(mobj,nil,nil)
	end




end,MT_WHIRLBUBBLE
)


mobjinfo[MT_SPINFAN] = {
	doomednum = 955,
	radius = 64*FRACUNIT,
	spawnstate = S_SPNF,
	flags = MF_NOCLIP|MF_NOCLIPTHING|MF_SCENERY|MF_NOGRAVITY
}
states[S_SPNF] = {SPR_NULL, A, 1, A_None, 0, 0, S_SPNF}

local function SectorHijackB(player,sector,subsector)	

	
	local crush = R_PointInSubsector(player.mo.x+FixedMul(8*FRACUNIT, cos(player.mo.angle)), player.mo.y+FixedMul(8*FRACUNIT, sin(player.mo.angle))).sector
	--for crush2 in crush.ffloors()
	if (crush and crush.valid)
		if (player.mo.state != S_PLAY_SPINDASH)
			crush.floorheight = $ - 2*FRACUNIT
		end
		if (player.mo.state == S_PLAY_SPINDASH)
			crush.floorheight = $ + 2*FRACUNIT
		end
	end
end

	
local maxraiserate = 180
addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	if mobj.raiserate == nil
		mobj.raiserate = 0
	end


	
	for player in players.iterate

		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)

		if ((player.mo.state != S_PLAY_SPINDASH)
		or mobj.raiserate >= maxraiserate)
		and S_SoundPlaying(mobj, 551)
			S_StopSound(mobj)
		end	
		if player.mo.state != S_PLAY_SPINDASH 
		--and player.mo.state != S_PLAY_ROLL 
			P_SpawnMobj(mobj.x, mobj.y, mobj.z ,MT_H)
		end
		

				
		if mobjrange >= 26*FRACUNIT return end


		if (player.cmd.forwardmove > 0
		or player.cmd.sidemove > 0)
		and player.mo.state == S_PLAY_ROLL
			player.mo.state = S_PLAY_STND
		return end
		
		if mobj.raiserate > 0
		and (player.mo.state != S_PLAY_SPINDASH)
			mobj.raiserate = $ - 1
		end
		
		if player.mo.state == S_PLAY_STND
		and player.cmd.buttons & BT_SPIN
			player.mo.state = S_PLAY_SPINDASH
		end
		
		if player.mo.state == S_PLAY_ROLL
		and player.cmd.buttons != BT_SPIN 
			P_InstaThrust(player.mo, player.mo.angle, player.normalspeed)
		end
				
		P_SetObjectMomZ(mobj, -1*FRACUNIT)
		
		if (player.mo.state == S_PLAY_SPINDASH or player.mo.state == S_PLAY_ROLL)
		and mobj.raiserate == 0
		
			mobj.raiserate = 1
		end
		
		if mobj.raiserate > 0	
		and mobj.raiserate < maxraiserate
		
			
			SectorHijackB(player)
			
			if (player.mo.state == S_PLAY_SPINDASH or player.mo.state == S_PLAY_ROLL)
			and player.cmd.buttons & BT_SPIN
				if not S_SoundPlaying(mobj, 551)
					S_StartSound(mobj,551, player) --roll machine sfx motor --534,449
				end
				if mobj.raiserate < 10
					P_InstaThrust(player.mo, player.mo.angle, 0*FRACUNIT)

				end
				
				mobj.raiserate = $ + 1
			end
		end
	end
end,MT_SPINFAN
)



mobjinfo[MT_GREENSPRING] = { --Holdable button
	doomednum = 793,
	spawnstate = S_GSPR,
	seestate = S_GSPR,
	reactiontime = TICRATE,
	speed = 0*FRACUNIT,
	radius = 32*FRACUNIT,
	height = 2*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_SPRING
}

states[S_GSPR] = {SPR_GSPR,  A, 1, A_None, 0, 0, S_GSPR}
addHook("MobjThinker", function(mobj,player)
	for player in players.iterate
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		

		if player.mo.z <= mobj.z + 32*FRACUNIT
		and player.mo.z >= mobj.z - 32*FRACUNIT
		and mobjrange <= 32*FRACUNIT		---if youre at a certain distance...
			player.mo.angle = mobj.angle
			P_InstaThrust(player.mo, mobj.angle, 50*FRACUNIT)
			P_SetObjectMomZ(player.mo,25*FRACUNIT, nil)
			player.powers[pw_justsprung] = 1
			player.mo.state = S_PLAY_SPRING
			P_ResetPlayer(player)
			mobj.state = S_GSPR
			S_StartSound(player.mo, 288, player)
		end
	end
end,MT_GREENSPRING
)


mobjinfo[MT_H] = {
	doomednum = -1,
	spawnstate = S_H,
	flags = MF_NOCLIP|MF_NOCLIPTHING|MF_SCENERY|MF_NOGRAVITY
}
states[S_H] = {SPR_ROLL, E, 3, A_None, 0, 0, S_NULL}
states[S_H2] = {SPR_ROLL, FF_ANIMATE|F, 2, A_None, 2, 1, S_H2}
states[S_H3] = {SPR_ROLL, G, 1, A_None, 0, 0, S_H3}

mobjinfo[MT_I] = {
	doomednum = -1,
	spawnstate = S_I,
	flags = MF_NOCLIP|MF_NOCLIPTHING|MF_SCENERY|MF_NOGRAVITY
}
mobjinfo[MT_J] = {
	doomednum = -1,
	spawnstate = S_I,
	flags = MF_NOCLIP|MF_NOCLIPTHING|MF_SCENERY|MF_NOGRAVITY
}
mobjinfo[MT_K] = {
	doomednum = -1,
	spawnstate = S_I,
	flags = MF_NOCLIP|MF_NOCLIPTHING|MF_SCENERY|MF_NOGRAVITY
}
mobjinfo[MT_L] = {
	doomednum = -1,
	spawnstate = S_I,
	flags = MF_NOCLIP|MF_NOCLIPTHING|MF_SCENERY|MF_NOGRAVITY
}
states[S_I] = {SPR_ROLL, A, 2, A_None, 0, 0, S_NULL}
states[S_I2] = {SPR_ROLL, FF_ANIMATE|B, 3, A_None, 3, 1, S_NULL}

addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	
		if mobj.altxp == nil
			mobj.altxp = 0
			mobj.altxn = 0
			mobj.altyp = 0
			mobj.altyn = 0
			mobj.alt = 0
		end
	for player in players.iterate

		
		mobj.altxp = 36*FRACUNIT
		mobj.altxn = -28*FRACUNIT
		mobj.altyp = 0
		mobj.altyn = 0
		mobj.alt = 0
		
		if mobj.angle == ANGLE_90
		or mobj.angle == ANGLE_270
			mobj.alt = 2
			mobj.altxp = 0
			mobj.altxn = 0
			mobj.altyp = 36*FRACUNIT
			mobj.altyn = -28*FRACUNIT
		end	
		
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		
		if mobjrange > 5000*FRACUNIT
		return end 
		
		P_SpawnMobj(mobj.x+mobj.altxp, mobj.y+mobj.altyp, mobj.z ,MT_I+mobj.alt)
		P_SpawnMobj(mobj.x+mobj.altxn, mobj.y+mobj.altyn, mobj.z ,MT_J+mobj.alt)
		mobj.z = mobj.floorz

		mobj.renderflags =  $|RF_FLOORSPRITE|RF_NOSPLATBILLBOARD

		if (player.mo.state != S_PLAY_SPINDASH)
		and mobj.state == S_H2
			P_KillMobj(mobj)
		return end
		
		

		if (player.mo.state == S_PLAY_SPINDASH)
			mobj.state = S_H
			if mobjrange <= 25*FRACUNIT
				if mobj.state == S_H
					mobj.state = S_H2
				end
			end
		end
	end
end,MT_H
)
local function R0198345(mobj,player)
	
	mobj.z = mobj.floorz
	mobj.renderflags =  $|RF_PAPERSPRITE|RF_NOSPLATBILLBOARD
	for player in players.iterate
		local mobjrange = R_PointToDist2(player.mo.x, player.mo.y, mobj.x, mobj.y)
		if (player.mo.state != S_PLAY_SPINDASH)
		and mobj.state == S_I2
			P_KillMobj(mobj)
		return end
		if not (mobj and mobj.valid) return end	
		if (player.mo.state == S_PLAY_SPINDASH)
		and player.mo.z == mobj.z
		and player.mo.frame == B
			if not S_SoundPlaying(mobj, 392)
				S_StartSound(mobj,392, player) --roll machine sfx clank --395
			end	
			if mobj.state == S_I
				mobj.state = S_I2
			end
		end
	end	
end

addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	mobj.angle = ANGLE_90
	R0198345(mobj,player)
end,MT_I
)

addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	
	mobj.angle = ANGLE_90
	R0198345(mobj,player) 
end,MT_J
)

addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	

	R0198345(mobj,player)
end,MT_K
)

addHook("MobjThinker", function(mobj,player)
	if not (mobj and mobj.valid)
		return end	

	R0198345(mobj,player) 
end,MT_L
)
