Object collision check

WellDoneSnake

Yoko Shimomura
Is there a way to use lua in order to check if an object has collided with a wall or ceiling?

Also, can strafing controls be disabled using lua?

Update
I've found a way to check if an object has touched (or come close to touching a ceiling).

I've been trying to make an air glider using lua, it is supposed to function similarly to what chi.miru's air glider wad did.
My aim was to have the air glider be destroyed when it comes into contact with a wall or ceiling, thus ending the gliding sequence (since the glider gets destroyed).

The script below can be tested instantly if you copy and save it as a lua file.
I've also made it so that in GFZ1 the glider spawns above and in front of you at the start of the level.

Code:
//Custom Glider Script By TSDude
//A lua based version of an air glider inspired by chi.miru's air glider wad on MB.

//NOTES:
//1) Checking for "P_IsObjectOnGround" and "P_IsObjectInGoop" is not used on the player, this is because the player is often unable to interact with the ground,
//when using the glider. Hence why their interaction is done indirectly through checking if the glider touching the ground.
//2) If you plan on making or using different sprites for the air glider, make sure that you modify the vertical offsets of those sprites. That way you can
//make it look like the player is hanging off of an object rather than cling their whole body to one.

freeslot (
"MT_GLIDESPAWNER",
"MT_VULTUREGLIDER",
"S_GLIDE_SPAWN",
"S_VULTURE_SPAWN",
"S_VULTURE_MOVE",
"S_VULTURE_DIE"
)

mobjinfo[MT_GLIDESPAWNER] = {
	doomednum = 455,
	spawnstate = S_GLIDE_SPAWN,
	spawnhealth = 1,
	reactiontime = 8,
	deathstate = S_XPLD1,
	speed = 2,
	radius = 16*FRACUNIT,
	height = 48*FRACUNIT,
	dispoffset = 0,
	mass = 100,
	flags = MF_SPECIAL|MF_NOBLOCKMAP|MF_NOGRAVITY
}

mobjinfo[MT_VULTUREGLIDER] = {
	doomednum = -1,
	spawnstate = S_VULTURE_SPAWN,
	spawnhealth = 1,
	reactiontime = 8,
	deathstate = S_VULTURE_DIE,
	speed = 2,
	radius = 16*FRACUNIT,
	height = 16*FRACUNIT,
	dispoffset = 0,
	mass = 100,
	flags = MF_NOGRAVITY|MF_FLOAT|MF_NOCLIPTHING
}

//You can modify the values in these states to your hearts content.
//For example, changing the A_Thrust value from "20" to a higher number, would make the glider move faster,
//whereas a lower value would make the glider move slower.

states[S_GLIDE_SPAWN] = {SPR_VLTR, TR_TRANS50|A, 1, nil, 0, 0, S_GLIDE_SPAWN} //Glide Spawner object spawn state
states[S_VULTURE_SPAWN] = {SPR_VLTR, A, 1, nil, 0, 0, S_VULTURE_SPAWN} //Glider object spawn state
states[S_VULTURE_MOVE] = {SPR_VLTR, A, 1, A_Thrust, 15, 1, S_VULTURE_MOVE} //This state determines the horizontal speed of the air glider.
states[S_VULTURE_DIE] = {SPR_VLTR, A, 1, nil, 0, 0, S_XPLD1} //Death state of air glider.

local function SpawnGlider(mobj)
	A_SpawnObjectRelative(mobj, (64*65536)+-64, (100*65536)+MT_GLIDESPAWNER) //Spawns a Glide Spawner object above the player at the start of a level.
end
addHook("MobjSpawn", SpawnGlider, MT_PLAYER)

local startglide = 0

local function GlideStart(gldr, plyr)
	for player in players.iterate
		A_SpawnObjectRelative(plyr, (0*65536)+0, (0*65536)+MT_VULTUREGLIDER) //Spawn the air glider relative to the player.
		A_SetObjectTypeState(plyr, 1965, MT_VULTUREGLIDER+(0<<16)) //Set the air glider's state to its movement state.
		P_ResetPlayer(player) 	//Necessary for making sure that the player cannot damage enemies while gliding, thus they are not semi-invulnerable.
		player.pflags = $1 | PF_ITEMHANG //Player is hanging from an object.
		A_SetObjectTypeState(gldr, 49, MT_PLAYER+(0<<16)) //Put the player into their hanging state.
		startglide = 1
	end
end
addHook("TouchSpecial", GlideStart, MT_GLIDESPAWNER)

addHook("ThinkFrame", do
	for player in players.iterate
		if startglide == 1
			A_FindTarget(player.mo, 418, 0) //Player finds the air glider object. You can change the target if necessary.
			A_CapeChase(player.mo, 0, 0) //Player's position will continuously be set to the air glider's position.
			A_SetObjectFlags(player.mo, MF_NOGRAVITY, 2) //Player has no gravity.
			A_SetObjectFlags(player.mo, MF_FLOAT, 2) //Player can float.
		else
			A_SetObjectFlags(player.mo, MF_NOGRAVITY, 1) //Player has gravity.
			A_SetObjectFlags(player.mo, MF_FLOAT, 1) //Player can no longer float. :(
		return
		end
	end
end)

local aboveceiling = 0

local function GlideThinker(mobj)
	for sector in sectors.iterate
		if (mobj.subsector.sector.ceilingheight < mobj.height+(mobj.z+2*FRACUNIT))
			aboveceiling = 1
		end
	end
	for player in players.iterate
		mobj.angle = player.mo.angle //Sets the air glider's angle to the player's angle, so whenever the player turns, the glider turns.
		//The glider's vertical momentum values can be changed if necessary.
		if mobj.momz > 10*FRACUNIT
			mobj.momz = 10*FRACUNIT //Air glider's upward vertical momentum has been set to not exceed "10*FRACUNIT".
		elseif mobj.momz < -10*FRACUNIT
			mobj.momz = -10*FRACUNIT //Air glider's downward vertical momentum has been set to not exceed "-10*FRACUNIT".
		end
		if player.cmd.forwardmove > 0 //Is the player pressing the forwardmove key?
			A_ZThrust(mobj, 1, 0) //If so then make the glider move upwards.
		elseif player.cmd.forwardmove < 0 //Is the player pressing the backwardmove key?
			A_ZThrust(mobj, -1, 0) //If so then make the glider move downwards.
		end
		if (player.pflags & PF_USEDOWN) //Is the player pressing the spin button while using the glider?
			A_Thrust(mobj, 30, 1) //GIVE HIM SOME BOOST!!!
			player.boost = 1
		else
			player.boost = 0
		end
		if startglide == 1 then
			if (player.pflags & PF_JUMPDOWN) //Has the player jumped?
			or P_IsObjectOnGround(mobj) or P_IsObjectInGoop(mobj) //Using the glider mobj instead of the player's, see notes.
			or P_PlayerInPain(player) //Did the player get hurt?
			or player.exiting == 1 //Has the player finished the level?
			or (player.playerstate & PST_DEAD)
			or aboveceiling == 1
				//If any of these are true then stop using the air glider.
				A_ForceStop(player.mo, 1)
				if not P_PlayerInPain(player) and not (player.playerstate & PST_DEAD) then
					if player.boost == 0
						A_Thrust(player.mo, 10, 1)
					elseif player.boost == 1
						A_Thrust(player.mo, 20, 1)
						player.boost = 0
					end
				end
				P_KillMobj(mobj, mobj, mobj)
				startglide = 0 //Reset "startglide" value
				aboveceiling = 0
				if (player.pflags & PF_ITEMHANG) //Was the player hanging onto an object?
					player.pflags = $1 ^^ PF_ITEMHANG //Reset the player flag for hanging on an object.
				end
			end
		end
	end
end
addHook("MobjThinker", GlideThinker, MT_VULTUREGLIDER)

What I haven't figured out yet is how to make an object detect a wall.

As well as checking if the bottom of the nearest FOF above the object, has been touched by the said object or is very close to it (since FOFs can serve as ceilings too).

Another Update

I've figured out how to check if an object has collided with the bottom of an FOF that is above them:
Code:
for rover in sector.ffloors()
	if (mobj.subsector.sector == rover.target) then
		if (rover.topheight > mobj.z) and (rover.bottomheight < mobj.height+(mobj.z+2*FRACUNIT))
			abovefof = 1
		end
	end
end
I just need to edit this part to make sure that it doesn't count intangible FOFs (like water blocks).
Also "abovefof" is actually supposed to be "abovefofbottom", just thought I should clarify.

The things I haven't figured out yet are how to make an object detect a wall on or before collision and how to disable strafing while using the air glider.

Probably my last update since I'm not too bothered about the strafing thing

I've found solutions to the ceiling collision problems and the wall collision detection, the latter was with the help of this post.

I've got the current code working, however I'm not sure how to stop the camera's subtle weird shifts during the gliding sequence when the player turns or when you press the strafe keys.

But I'm sure I can figure that out eventually.
This thread's question has mostly been solved regardless.

NOTE: I've just realised that by using P_TryMove and giving the glider an "MF_NOCLIPHEIGHT" flag, that I no longer need to have the object check every tic if it has touched a ceiling or touched an FOFs bottom... Boy did that save me some lag in levels that have a lot of sectors or FOFs.
 
Last edited:

Who is viewing this thread (Total: 1, Members: 0, Guests: 1)

Back
Top