Difference between revisions of "Dynamic SEXPs"

From FreeSpace Wiki
Jump to: navigation, search
m (Update documentation of ship parameter type)
m (Fix outdated example script)
Line 120: Line 120:
 
mn.LuaSEXPs["dynamic-sexp"].Action = function (arg1, arg2, arg3, ...)
 
mn.LuaSEXPs["dynamic-sexp"].Action = function (arg1, arg2, arg3, ...)
 
ba.print(tostring(arg1)
 
ba.print(tostring(arg1)
ba.print(mn.Ships[arg2].Name)
+
ba.print(arg2.Name)
 
ba.print(tostring(mn.SEXPVariables[arg3].Value))
 
ba.print(tostring(mn.SEXPVariables[arg3].Value))
  

Revision as of 18:29, 2 January 2018

Since version 3.8.2 FSO supports adding custom SEXPs to a mod which have a user defined effect. Currently there is only one way to add such a SEXP but more may be added in the future.

Dynamic SEXPs are only added in modular table files which end with -sexp.tbm

Table syntax

This section will describe the syntax and effects of the individual options.

#Lua SEXPs

Specifies a list of dynamic SEXPs implemented using a Lua function (see Lua interface for how to use the implementation function). This section must end with #End

$Operator:

  • Adds a new SEXP operator with the specified name. The name may not contain the following characters: ()\"'. Furthermore, any whitespace (tab characters or spaces) are also not permitted. This is the name under which this operator will appear in the SEXP code. While the name is mostly up to you it would be a good idea to keep it in line with how the other SEXPs are named. To avoid conflicts with other custom SEXPs you should also use a unique prefix. For example, if you want to have some SEXP operators that control a cloaking script then you could use cloak- as the common prefix for all the operators that are related to this system. A SEXP that disables the cloak system could be named something like cloak-disable.
  • This name must be unique among all operators that are known to the SEXP system. That includes built-in SEXPs and operators added before. If there is a conflict then the new operator definition will be ignored. Built-in operators always take precedence.
  • Syntax: String

$Category:

  • Specifies in which category this SEXP will appear in the context menu in the FRED event editor. Only one of the existing categories may be used. These are all the currently defined categories:
    • Objectives
    • Time
    • Logical
    • Arithmetic
    • Status
    • Change
    • Conditionals
    • Ai goals
    • Event/Goals
    • Training
  • Syntax: String

$Subcategory:

  • Specifies into which subcategory this SEXP should be put. This is the second level in the context menu of the FRED event editor. New subcategories can be added by specifying a new name here but all subcategory names must be globally unique (you can't have the same subcategory name under two different categories).
  • Syntax: String

$Minimum Arguments:

  • Specifies ht minimum number of parameters this SEXP needs to work. If less parameters are specified then the SEXP parser will treat this as an error.
  • Must be at least 0.
  • Syntax: Integer

$Maximum Arguments:

  • Specifies the maximum number of parameters this SEXP can process.
  • Optional. If this option is not present then the SEXP can process an unlimited number of parameters.
  • Must be at least 0 and greater or equal to $Minimum Arguments.

$Return Type:

  • Specifies what data type this SEXP will return when invoked. Can be one of the following:
    • number
      The SEXP will return an integer. The scripting function needs to return a number value.
      boolean
      The SEXP will return a boolean. The scripting function must return a boolean value.
      nothing
      The SEXP will return nothing. The scripting function may not return anything.
  • Optional. Defaults to nothing
  • Syntax: String

$Description:

  • Sets the help text displayed in the FRED help box. This should be the generic description of what this SEXP does but should not include the documentation for the individual parameters.
  • Syntax: String

$Repeat

  • This option must be combined with the parameter documentation below to specify a repeating pattern in a SEXP with a variable number of parameters. See the example below for how exactly this will work. All parameters specified after this option will be grouped together. The script will receive these groups of parameters as a single entity (see Lua interface) to make it easier to use the values without having to separate them again in the script.

$Parameter:

  • Adds documentation for the parameters and specifies what type they need to have. This option may appear multiple times and should match the number of parameters specified by $Minimum Arguments and $Maximum Arguments.
  • This option has no value.

+Description:

  • Sets the description of this parameter. This will be used for the documentation text.
  • Syntax: String

+Type:

  • Sets the type this parameter requires. The currently supported types are:
    • number
      This parameter is a number. The SEXP system will evaluate the expression for this parameter (which may be another SEXP operator) and pass the result to the script.
      boolean
      This parameter is a boolean. The SEXP system will evaluate the expression for this parameter (which may be another SEXP operator) and pass the result to the script.
      ship
      This parameter is the name of a ship. The script will receive this value as a ship handle. If the name provided by the mission is invalid (if the ship has not arrived yet or if it is not present anymore) then the script will receive an invalid ship handle.
      string
      This parameter is a generic string with no special format. In Unicode mode this string may contain Unicode characters.
      team
      This parameter is a handle to a specific team. The script will receive this value as a team handle.
      waypointpath
      This parameter is a reference to a specific waypoint path. The script will receive this as a waypointlist handle.
      variable
      This is a reference to a SEXP variable. This is a reference to the actual variable and not its contents. The script will receive this as a sexpvariable handle.
  • Syntax: String

Example

#Lua SEXPs

$Operator: dynamic-sexp
$Category: Change
$Subcategory: Scripted
$Minimum Arguments: 3
; No maximum arguments means that it accepts a variable number of arguments
$Return Type: Nothing
$Description: This is a dynamic parameter test SEXP
$Parameter:
	+Description: Number parameter
	+Type: Number
$Parameter:
	+Description: Ship parameter
	+Type: Ship
$Parameter:
	+Description: Variable name parameter
	+Type: variable
$Repeat ; This starts the part of the parameter list where the parameter pattern repeats
$Parameter:
	+Description: Variable string parameter
	+Type: string
$Parameter:
	+Description: Variable number parameter
	+Type: Number

#End

Lua interface

So far, all the SEXP table has done is specify that a new Lua SEXP exists but there is no actual action which will be executed when the SEXP is called. For the Lua language this can be done using the mn.LuaSEXPs variable. This is a variable which can be indexed using the SEXP name. The returned value is of type LuaSEXP which only has a single field, Action. This is the function that will be executed once the SEXP is called in a mission. You can use it to retrieve the function of a LuaSEXP but the more common use case is that it is written in the $On Game Init hook to set the action function.

The action function will receive the values as normal parameters. If the SEXP will receive a variable number of parameters then you can use ... as the last parameter to also capture these values. If a parameter is optional and not specified by the SEXP invocation then it will be nil in the script. Parameters in the repeat pattern of the parameter list will be grouped into a array of arrays where each array instance contains the individual values. See below for an example of how this can be handled in the Lua code.

#Conditional Hooks

$Application: FS2_Open
$On Game Init: [
mn.LuaSEXPs["dynamic-sexp"].Action = function (arg1, arg2, arg3, ...)
	ba.print(tostring(arg1)
	ba.print(arg2.Name)
	ba.print(tostring(mn.SEXPVariables[arg3].Value))

	for val in {...} do
		ba.print(val[1])
		ba.print(tostring(val[2]))
	done
end
]

#End