User:Golden/How to make a Lua-calling PolyObject

From SRB2 Wiki
Jump to navigation Jump to search

So ya wanna make the CNZ barrel do ya?

Or maybe you just want to kill the player or something when someone lands on a specific PolyObject.

Wait no more because I'm the madman who found out how to do all of this in at least three easy steps!

And I'm willing to document it!

Let's get started, shall we?

To start off, before your PolyObject can call Lua, you have to go make yourself a PolyObject to call Lua (easier said than done). Tag its First Line to some number you'll remember later. I generally use the PolyObject's ID; but any number you haven't previously used with this method should work.

Next, we will be making use of an obscure feature of PolyObjects; triggering Trigger Linedefs when a mobj lands atop them. Create a new sector and in it make a trigger linedef with a tag of 32000 plus your PolyObject's ID, and check Not Climbable on your PolyObject's parameters linedef (the one with Linedef type 22.) I've had good luck with trigger linedef 300 and 302; 301 doesn't seem to work.

Lastly, pick one of the unused lines in the same Control Sector as your Trigger Linedef and give it Linedef type 443, and tag it to that number you tagged your PolyObject's First Line to. Don't forget to give the linedef a function name to call!

Tagging the Linedef Executor and your PolyObject's First Line like this is necessary for your Lua script to easily find the PolyObject that called it. It might be possible to do this without tagging these linedefs together in this fashion, by using Lua trickery to attain the PolyObject's ID from the Trigger Linedef, but that is outside the scope of this tutorial.

Now everything on the mapping side should be all set up!

But it doesn't do anything yet!

That's because we don't got a Lua ready to receive these calls from our new Lua-calling PolyObject.

So.. let's create one!

Note
The rest of this section talks about how I added functionality to a Lua-calling PolyObject.

You can stop reading if you want to use a different method or do the Lua side on your own.

Start by creating a new function that hooks into LinedefExecute, with the third argument of addHook being the same as what you've set as the function name for the linedef executor you set up.

Create a new local variable to store your PolyObject once it's been found, then iterate through the lines of the map using lines.iterate, checking each line to see if the tag is the same as the linedef executor's. If the linedef happens to be Linedef type 20 (In other words, a PolyObject's First Line), the line's backsector should be a PolyObject (assuming the PolyObject is set up correctly.)

This is the code I've ended up with:

local function linedefExecute(linedef, mo, sector)
	local poly

	for line in lines.iterate do
		if line == linedef then
			continue
		end
		
		if line.tag == linedef.tag
		and line.special == 20 then
			poly = line.backsector
			break
		end
	end
end

addHook("LinedefExecute", linedefExecute, "FUNCTIONNAME")

Remember, "FUNCTIONNAME" is the name you've entered into the linedef executor.

From here:

  • linedef is the linedef executor,
  • mo is the object that touched the PolyObject,
  • sector is completely useless and nonexistant,
  • and poly is the PolyObject which called the trigger linedef in the first place.

Conclusion

From here, you have the power to control what happens with the PolyObject and where it moves to.

Before you ask, changing the floor and ceiling heights of the PolyObject automatically moves the textures up and down with it.

And with that, I have given far too many people the power to create a CNZ barrel.

You're welcome.