User:RedEnchilada/Lua/Interacting with SOC

From SRB2 Wiki
Jump to navigation Jump to search
This article or section is incomplete. However, RedEnchilada has requested that this article be untouched until it's completed. Please discuss this article on its talk page.

SRB2's main methods of modifying object behavior, SOC and Lua, are heavily intertwined. Lua functions can be referenced by SOCs, and objects can be created in Lua as easily as through SOC. This tutorial will cover some of the basics of integrating Lua into SOCs, and vice versa. (This tutorial assumes that you have read Lua/Getting started, and that you have some basic knowledge of Lua scripting.)

Overriding built-in SOC actions

In addition to simply using SOC actions, Lua can also override them to do entirely different things. This allows scripters to change object behaviors without ever touching states. Start by entering the following into a new Lua script:

function A_JetBThink(mo, var1, var2)
end

This creates a (currently empty) global function called A_JetBThink. SRB2's Lua implementation normally doesn't allow for global variables or functions to be created, but a special exception is made for SOC actions (functions whose names begin with A_) to allow scripts to create and override SOC actions. In this case, we are overriding a default action with a function that currently does nothing. The arguments passed to an SOC function are, in order:

  • mo: The mobj_t performing the action.
  • var1: The Var1 value of the state that called this action.
  • var2: The Var2 value of the state that called this action.

If you were to load this script into SRB2 and find a Jetty-Syn Bomber (the enemy that uses this action), it would stand still and do nothing, since its main action has been overridden. This can be fixed by adding a call to super in the function as such:

function A_JetBThink(mo, var1, var2)
	super(mo, var1, var2)
end

super is a function available only inside SOC functions that, when called, runs the game's original function with the arguments passed. Note that the arguments do not have to be the same ones passed to the function! You can, for instance, run the action on an entirely different object, or with an entirely different set of variables.

Now the original behavior has been restored, but the function still doesn't do anything special. This can be easily fixed, however, by modifying the script to do something like this:

function A_JetBThink(mo, var1, var2)
	if mo.target and mo.target.valid then
		P_SpawnMissile(mo, mo.target, MT_BLUECRAWLA)
	end
	super(mo, var1, var2)
end

Now our function is checking to see if the calling object has a target - by checking if mo.target is set, then checking if the value set is still valid (since references to objects can still exist in Lua scripts even if the object in question no longer exists) - and using P_SpawnMissile to launch a Blue Crawla at them. super is still called regardless, so the original behavior is never overridden.

Test the script by loading into any map that has a Jetty-Syn Bomber. An easy place to find one is in Egg Rock Zone 2, on the right path.