[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5 The XML Behaviour Layer

One of the predefined behaviour layers in Crystal Entity Layer is the XML behaviour layer. In this behaviour layer XML is used a simple scripting language. This allows one to create game logic using XML that one can embed in a map file.

Example

The easiest way to describe the basics behind the XML behaviour layer is with an example:

 
<world>
    <textures>
        <texture name="chair">
            <file>/cellib/images/chair5.gif</file>
        </texture>
    </textures>
    <materials>
        <material name="chair">
	    <texture>chair</texture>
	</material>
    </materials>
    <settings>
        <clearscreen>yes</clearscreen>
    </settings>

    <addon plugin="cel.addons.xmlscripts">
        <script name="chair_clicker">
            <event name="init">
                <var name="counter" value="0" />
            </event>
            <event name="pcbillboard_select">
                <var name="counter" value="?counter+1" />
                <if eval="?counter < 10">
                    <true>
                       <print value="'You clicked '+?counter+' times.'" />
                    </true>
                    <false>
                        <print value="'It is time you stopped clicking!'" />
                    </false>
                </if>
            </event>
        </script>

        <script name="chair_mover">
            <event name="pctimer_wakeup">
                <bb_move x="rand(1)*250000" y="rand(1)*250000" delta="500" />
            </event>
        </script>
    </addon>

    <addon plugin="cel.addons.celentity" entityname="red_chair">
        <propclass name="pc2d.billboard">
            <property name="name" string="red_chair" />
            <property name="materialname" string="chair" />
            <property name="clickable" bool="1" />
            <property name="movable" bool="1" />
            <property name="restack" bool="1" />
            <property name="color" color="1,1,1" />
            <property name="widthpct" float=".7" />
            <property name="heightpct" float=".7" />
        </propclass>
        <behaviour name="chair_clicker" />
    </addon>

    <addon plugin="cel.addons.celentity" entityname="green_chair">
        <propclass name="pc2d.billboard">
            <property name="name" string="green_chair" />
            <property name="materialname" string="chair" />
            <property name="clickable" bool="1" />
            <property name="movable" bool="0" />
            <property name="restack" bool="1" />
            <property name="color" color="0,1,0" />
            <property name="widthpct" float=".7" />
            <property name="heightpct" float=".7" />
            <property name="x" long="100000" />
            <property name="y" long="100000" />
        </propclass>
        <propclass name="pctools.timer">
            <action name="WakeUp">
                    <par name="time" long="500" />
                    <par name="repeat" bool="true" />
            </action>
        </propclass>
        <behaviour name="chair_mover" />
    </addon>
</world>

To run this example you can put this XML file in the current directory and then do this on Windows:

 
bootstrap.exe cel.behaviourlayer.xml bootstrap load //this testscript.xml

Or on GNU/Linux:

 
./bootstrap cel.behaviourlayer.xml bootstrap load /this testscript.xml

In this example we create two entities using the ‘cel.addons.celentity’ addon (see section CelEntity Addon). The ‘red_chair’ entity just has one property class which is the ‘pc2d.billboard’ property class. This property class is designed for simple 2D graphics. You can use it to build a complete 2D game (like the Boulderdash game that is included with Crystal Entity Layer) or else you can use it for HUD elements in a 3D game. The ‘green_chair’ entity has a ‘pc2d.billboard’ property class and a ‘pctools.timer’ (see section Timer).

Scripts

When using the XML behaviour layer you basically create scripts. Every script corresponds to a behaviour for an entity (multiple entities can use it of course). In this particular example we use the ‘cel.addons.xmlscripts’ addon (see section XML Scripts Addon) to create the two scripts that we will use for the two entities. The ‘chair_clicker’ script simply waits until the billboard is clicked and increments a counter. If the counter is less than 10 then it will print out the count. Otherwise it issues a warning. The ‘chair_mover’ script simply waits until the timer fires and then it initiates a move of the billboard to another location. The ‘bb_move’ will make sure the billboard keeps moving gradually to the desired location (side note, the location system for billboards uses a coordinate system where 0,0 it top-left and 307200,307200 is bottom-right, independent of window resolution).

Events

Every event in a script roughly corresponds with a method call in a normal programming language. You can make as many events as you want but there are a few special cases. First there is the ‘init’ event which is called when the entity with that script is first executed. It is a kind of constructor. Secondly when the entity gets a message from one of the property classes this message is also translated to an event. In the example above the ‘chair_clicker’ script reacted on billboard selection which is a message from the billboard property class that is named ‘pcbillboard_select’. The ‘chair_mover’ script reacted on timer events which is a message from the timer property class that is named ‘pctimer_wakeup’.

Variables

You can use two kinds of variables in an event. First there are global variables. To assign a value to such a variable you use:

 
<var name="variable" value="1000" />

Note that variables are typed. The following types are possible:

To use a global variable you use the ‘?’ operator like this:

 
<print value="?variable" />

You can combine this in complex expressions:

 
<print value="3.14*(?variable+?othervar)" />

Global variables have one big advantage: they are persistent. Internally the XML behaviour layer will automatically use a ‘pcproperties’ property class to store these variables (such a property class will be created on the entity if it doesn't already exist). This also means you can set and access variables from other entities (notice how the ‘?’ operator is combined with the ‘.’ operator to access the variable from another entity):

 
<var entity="other_entity" name="variable" value="'some string'" />
<print value="'x in other_entity is equal to '+?other_entity.x" />

In contrast with global variables you also have local variables. Local variables don't remember their value and you can't access local variables from other entities either. On the other hand they are considerably more performant to work with. Here is how you set and use a local variable:

 
<lvar name="localvar" value="3.1415" />
<print value="'Our local variable is equal to '+#localvar"/>

This can become pretty complex. For example take this:

 
<print value="?#entity.#variable" />

This will print out the variable which has the name given in the local variable called ‘variable’ from the entity which has the name given in the local variable called ‘entity’.

Calling Events

Some events (like ‘init’ and messages from property classes) are automatically called but you can also define your own events and in that case you need to be able to call them (like you would call functions). Here is an example on how to call an event:

 
<call event="myevent" />

This is the simplest example. In this case we will simply pass control to the ‘myevent’ event and when that finishes execution will resume at the operation after the call.

It is also possible to call an event in another entity. Basically what this will do is call the event in the script (behaviour) that is attached to that other entity:

 
<call entity="other_entities" event="myevent" />

You can also pass parameters in an event call:

 
<call event="myevent">
    <par id="parid(x)" value="100" />
    <par id="parid(y)" value="50" />
</call>

This will pass the ‘x’ and ‘y’ parameters to the event. In the event you can access these parameters with the ‘@’ operator like this:

 
<event name="addsomething">
    <print value="@x+@y" />
</event>

Events can also be used as functions that return a value. In that case you write the event like this:

 
<event name="addsomething">
    <return value="@x+@y" />
</event>

Then you can use this function as follows:

 
<print value="addsomething(x=3,y=5)" />

You can see how the parameters are passed by name.

It is also possible to call an event in another entity as a function by using the scope (‘::’) operator:

 
<print value="otherentity::addsomething(x=3,y=5)" />

A special case for function calling is the ‘...’ operator. If you use that then the parameters for the function will be the same as the parameters that called this function. For example:

 
<event name="process">
    <return value="addsomething(...)*3" />
</event>

This function will call ‘addsomething’ with the same parameters that are given to ‘process’ and then multiply the result with 3.

Arrays

The XML behaviour layer supports sparse one and two dimensional arrays. They are sparse in the sense that only elements that are assigned really exist and consume memory. So you can put a value in the array at index 5 and one at index 1000000 and the array will be essentially only two items big. Also the indices don't have to be numeric. You can use any kind of type. Internally arrays work by concatenating the array name with the index. For example: ‘bla['testing',3]’ actually corresponds with a normal variable that is called ‘bla_testing_3’. So every element in an array is actually just a normal variable. The array syntax is just syntax to help you write arrays more easily. Here is an example on how to assign a value in an array and how to use it:

 
<lvar name="index" value="1000" />
<var name="bla[#index,3]" value="100" />
<print value="?bla[#index,3]" />

Commands

In this section we give a summary of all commands available in the XML behaviour layer:

Debugging and Reporting

* reporterror

Attributes: ‘message’.
Report an error to the user.

* callstack

Show the callstack of the current executing XML script.

* variables

Show the variables of the current executing XML script.

* traceon

Enable trace mode. When this is on every time a property or variable changes it is dumped on standard output.

* traceoff

Disable trace mode.

* print

Attributes: ‘value’.
Print out the given value on standard output.

Variables and Expressions

* var

Attributes: ‘entity’ (optional), ‘name’, ‘value’.
Set a variable for this (or optionally another) entity to the given value.

* lvar

Attributes: ‘name’, ‘value’.
Set a local variable to the given value.

* expr

Attributes: ‘eval’.
Evaluate an expression and do nothing with the result.

Program Flow

* if (attribute version)

Attributes: ‘eval’, ‘true’, ‘false’.
This command evaluates an expression and depending on the result the respective event handlers are called.

* if (child version)

Attributes: ‘eval’.
Children: one or both of ‘true’, ‘false’.
This command evaluates an expression and depending on the result the code in the respective child is executed.

* if (inline version)

Attributes: ‘eval’.
This command evaluates an expression and if the result is true the code inside the ‘if’ statement will be executed.

* while (attribute version)

Attributes: ‘eval’, ‘exec’.
This command evaluates an expression and executes the given handler for as long as the expression is true.

* while (inline version)

Attributes: ‘eval’.
This command evaluates an expression and execute the embedded code for as long as the expression is true.

* for (attribute version)

Attributes: ‘var’, ‘start’, ‘end’, ‘exec’.
This command loops an integer value from ‘start’ to ‘end’ (inclusive). Every value is set to ‘var’. The handler will be called for every loop instance.

* for (inline version)

Attributes: ‘var’, ‘start’, ‘end’.
This command loops an integer value from ‘start’ to ‘end’ (inclusive). Every value is set to ‘var’. The embedded code will be called for every loop instance.

* for (bag version)

Attributes: ‘var’, ‘bag’.
This command loops over all strings in a bag. Every string is set to ‘var’. The embedded code will be called for every loop instance. The ‘bag’ should be a bag property class.

* switch

Atributes: ‘eval’.
Children: multiple ‘case’ (attributes ‘value’, children represents code to be executed in that case), optional ‘default’ (children represents code).
Evaluate the given expression and depending on the result execute the ‘case’ that corresponds with the exact value. If no case matches then optionally execute the ‘default’ branch.

* call

Attributes: ‘entity’ (optional), ‘event’.
Children: multiple ‘par’ (attributes ‘id’, ‘value’), optional ‘inherit’, optional ‘return’ (attributes ‘var’).
Call an event in this or another entity. The given parameters will be passed to that event. If ‘inherit’ is given then the parameters which were given to the current code will also be passed along to the event. If ‘return’ is given then the return value of the event will be put in the given variable.

* super

Call the event with the same name of the superclass.

* return

Attributes: ‘value’.
Return the specified value to the caller of this event.

* stop

Stop the current XML script.

* quit

Exit the program.

Entity and Property Class Management

* destroyentity (single version)

Attributes: ‘name’.
Destroy the entity with the given name.

* destroyentity (class version)

Attributes: ‘class’.
Destroy all entities with the given class.

* createentity (template version)

Attributes: ‘template’, ‘name’.
Children: multiple ‘par’ (attributes ‘id’, ‘value’).
Create a named entity from the given template. The parameters are passed to the template.

* createentity (normal version)

Attributes: ‘name’, ‘behaviour’, ‘layer’ (optional).
Create a named entity and assigned it the specified behaviour from either the default behaviour layer or otherwise the behaviourlayer specified by the ‘layer’ attribute.

* createpropclass

Attributes: ‘name’, ‘entity’ (optional), ‘tag’ (optional).
Create a property class for the given entity (or this entity) with a given tag (or no tag).

* destroypropclass

Attributes: ‘name’, ‘tag’ (optional).
Destroy the given property class for the current entity.

* default

Attributes: ‘propclass’
Make the given property class default. This is used by various operations.

* property

Attributes: ‘propclass’ (optional), ‘id’, ‘value’.
Set a property on the given property class (or default if not given).

* action

Attributes: ‘propclass’ (optional), ‘id’.
Children: multiple ‘par’ (attributes ‘id’, ‘value’).
Perform an action on the given property class (or default if not given).

* class_add

Attributes: ‘entity’, ‘class’.
Add a given class (given as ID) to the entity.

* class_rem

Attributes: ‘entity’, ‘class’.
Remove a given class (given as ID) from the entity.

Inventory Handling

* inventory

Attributes: ‘propclass’.
Set the given property class (which should be an inventory property class) as the default inventory.

* inventory_add

Attributes: ‘child’.
Add the given child (entity) to the current inventory.

* inventory_rem

Attributes: ‘child’.
Remove the given child (entity) from the current inventory.

Configuration Handling

* config_add

Attributes: ‘file’.
Add the given file (VFS path) to the config system.

* config_rem

Attributes: ‘file’.
Remove the given file (VFS path) from the config system.

* config_set

Attributes: ‘key’, ‘value’.
Set the given configuration key to the value.

* config_save

Save the current configuration.

Navigation and Mesh Selection

* hitbeam

Attributes: ‘sector’, ‘start’, ‘end’, ‘isectvar’, ‘entvar’, ‘meshvar’.
Trace a beam starting in the given sector at the ‘start’ location. The beam ends at ‘end’. The three output variables will be set to the intersection point, the entity that was hit and the mesh that was hit (useful in case a mesh was hit that has no corresponding entity).

* selectentity

Attributes: ‘pc’, ‘screenx’, ‘screeny’, ‘maxdist’,
‘isectvar’, ‘entvar’. The given property class should be from a camera property class. Given the screen location and maximum distance it will try to find the first entity that is in the way. It will return the intersection point and resulting entity.

* navigationinfo

Attributes: ‘navigator’, ‘successvar’, ‘anglevar’, ‘distancevar’, ‘visiblevar’, ‘targetvector’ (optional), ‘targetentity’ (optional), ‘targetnode’ (optional).
The navigator represents an entity that wants to navigate somewhere. This command will fill in the variables with the navigation info to get from the navigator position to the desired target position (either a position, entity, or node).

Sound

* sound

Attributes: ‘name’, ‘loop’ (optional), ‘volume’ (optional), ‘mode’ (optional).
Play the given sound. ‘loop’ is false by default. ‘volume’ is 1.0 by default and ‘mode’ is 2d by default.

* sound_stop

Attributes: ‘source’.
Stop playing the specified sound source.

* sound_pause

Attributes: ‘source’.
Pause playing the specified sound source.

* sound_unpause

Attributes: ‘source’.
Unpause playing the specified sound source.

* sound_restart

Attributes: ‘source’.
Restart playing the specified sound source.

* sound_volume

Attributes: ‘source’, ‘volume’.
Change the volume of the given sound source.

* sound_speed

Attributes: ‘source’, ‘rate’.
Change the speed of the given sound source.

Billboards

* bb_movelayer

Attributes: ‘layer’, ‘x’, ‘y’.
Move the given billboard layer to the absolute location given by ‘x’ and ‘y’.

* bb_move

Attributes: ‘pc’ (optional), ‘x’, ‘y’, ‘delta’ (optional).
Move the given billboard ot the absolute location given by ‘x’ and ‘y’.

* bb_tofront

Attributes: ‘pc’ (optional)
Move the given billboard to the front of the render queue.

* bb_toback

Attributes: ‘pc’ (optional)
Move the given billboard to the back of the render queue.

* bb_up

Attributes: ‘pc’ (optional)
Move the given billboard one up in the render queue.

* bb_down

Attributes: ‘pc’ (optional)
Move the given billboard one down in the render queue.

Various

* strsplit

Attributes: ‘string’, ‘left’, ‘delimiter’, ‘right’.
Split the given input string in a left and a right part (‘left’ and ‘right’ are variable names). The ‘delimiter’ will be used to decide where to split.

* randomize

Randomize the randomizer.

* hidemouse

Hide the mouse.

* showmouse

Show the mouse.

Functions

In this section we give a summary of all functions available in the XML behaviour layer:

ID Functions

* id( idname )

Calculate the ID from the given string.

* parid( idname )

Calculate the ID from the given string. The substring ‘cel.parameter.’ is added in front of ‘idname’.

* actid( idname )

Calculate the ID from the given string. The substring ‘cel.action.’ is added in front of ‘idname’.

* propid( idname )

Calculate the ID from the given string. The substring ‘cel.property.’ is added in front of ‘idname’.

Entity and Property Class Functions

* pc( [entity,] pcname )

Get the given property class from this (or the specified) entity.

* pctag( [entity,] pcname, tag )

Get the given property class with the given tag from this (or the specified) entity.

* property( [pc,] id )

Get the property from the specified (or default) property class.

* hasclass( entity, id )

Return true if the entity has the given class (specified as ID).

* entname( [entity] )

Return the name of the current (or given) entity.

* ent( [name] )

Return the current entity or find the entity with the given name.

Variable and Expression Functions

* param( id )

Dereference a parameter (equivalent to @parname).

* if( expression, truevalue, falsevalue )

Evaluate the given expression and return the ‘truevalue’ in case that expression is true. Otherwise ‘falsevalue’ is returned. Note that both expressions will always be evaluated!

* testvar( [entity,] variable )

Test if the variable exists in this (or the specified) entity.

Mathematical Functions

* abs( value )

Calculate the absolute value of the given input. Works for integer and floating point.

* min( value1, value2 )

Calculate the minimum value of the given inputs. Works for strings, floats, and integers.

* max( value1, value2 )

Calculate the maximum value of the given inputs. Works for strings, floats, and integers.

* cos( angle )

Return the cosinus of the given angle (in radians).

* sin( angle )

Return the sinus of the given angle (in radians).

* tan( angle )

Return the tangent of the given angle (in radians).

* acos( value )

Return the arc-cosinus (in radians) of the given value.

* asin( value )

Return the arc-sinus (in radians) of the given value.

* atan( value )

Return the arc-tangent (in radians) of the given value.

* sign( value )

Return 1 if the input is positive, -1 if negative, and 0 otherwise. This works for integer and floating point.

* sqrt( value )

Return the square root of the given value.

* normalize( vector )

Normalize the given 3D vector.

* sqdist( vector1, vector2 )

Return the squared distance between vector1 and vector2. Vectors can be 2D or 3D.

* intpol( delta, value1, value2 )

Interpolate the two values with the delta. When delta is 0 then ‘value1’ is returned. If delta is 1 then ‘value2’ is returned. Otherwise an interpolated value. This function works for integers, floating point values, 2D and 3D vectors, and colors.

* int( value )

Convert the value to an integer. This works for integers, floating point numbers, booleans, and strings. In the last case the string will be parsed as an integer and the resulting value will be returned.

* float( value )

Convert the value to a float point number. This works for integers, floating point numbers, booleans, and strings. In the last case the string will be parsed as a floating point and the resulting value will be returned.

* bool( value )

Convert the value to a boolean. This works for integers, floating point numbers, booleans, strings, entities, and property classes. The semantic meaning is that if the value is 0 then false is returned. Otherwise true. In case of string the input string is parsed and interprested as a boolean value. The parser understands ‘0’, ‘1’, ‘false’, ‘true’, ‘yes’, ‘no’, ‘on’, and ‘off’.

* rand( value )

Return a random number between 0 and the given value (exclusive). If the input value is an integer then the result will be an integer. If the input value is a floating point number then the result will also be floating point.

* getyrot( vector1, vector2 )

Calculate the angle between the two given 3D vectors.

* vecx( vector )

Get the x component from the given 2D or 3D vector.

* vecy( vector )

Get the y component from the given 2D or 3D vector.

* vecz( vector )

Get the z component from the given 3D vector.

String Functions

* strsub( string, position, length )

Calculate the substring of the input string starting at the given position (positions count at 0) and the specific length.

* stridx( string, substring )

Calculate the first position of the substring in the string. Return -1 if not found (positions start counting at 0).

* strlen( string )

Return the length of the string.

Inventory Functions

* inventory_get( index )

Return the given entity from the current inventory (with index).

* inventory_count( )

Return the number of items in the current inventory.

* inventory_in( entity )

Check if the entity is part of the current inventory.

* inventory_inname( name )

Check if the named entity is part of the current inventory.

* inventory_find( entity )

Find the entity in the current inventory and return the index (or -1 if not found).

* inventory_findname( name )

Find the named entity in the current inventory and return the index (or -1 if not found).

Billboard and Screen Functions

* mousex( )

Return the x mouse position in screen coordinates.

* mousey( )

Return the y mouse position in screen coordinates.

* bb_mousex( )

Return the x mouse position in billboard coordinates.

* bb_mousey( )

Return the y mouse position in billboard coordinates.

* scr_width( )

Return the width of the window or screen in pixels.

* scr_height( )

Return the height of the window or screen in pixels.

* bb_testcollide( pc )

The given property class should be a billboard property class. This function will test if the given billboard collides with the billboard of this entity.

File Functions

* chdirauto( directory, file )

Set the current VFS directory to the given directory. If the directory is a ZIP file then the given file will be used to help mount the given path.

* readfile( vararray, file )

Read the given file from VFS and put every line in the input array. Return the number of lines that were read or -1 in case of error.

* writefile( vararray, file, start, stop )

Write the given file in VFS and put the lines starting at ‘start’ until ‘stop’ in that file.

Key Pair Functions

* keynode( sector, node, key [, valuename] )

Find a named node in the given sector and locate the ‘key’ in that node. If ‘valuename’ is given then additionally locate the right value. The result of this function is the value associated with that key (and valuename).

* keymeshobj( mesh, key [, valuename] )

Locate the ‘key’ in the given mesh. If ‘valuename’ is given then additionally locate the right value. The result of this function is the value associated with that key (and valuename).

* keysector( sector, key [, valuename] )

Locate the ‘key’ in the given sector. If ‘valuename’ is given then additionally locate the right value. The result of this function is the value associated with that key (and valuename).

* keymeshfact( meshfact, key [, valuename] )

Locate the ‘key’ in the given mesh factory. If ‘valuename’ is given then additionally locate the right value. The result of this function is the value associated with that key (and valuename).

* keytexture( texture, key [, valuename] )

Locate the ‘key’ in the given texture. If ‘valuename’ is given then additionally locate the right value. The result of this function is the value associated with that key (and valuename).

* keymaterial( material, key [, valuename] )

Locate the ‘key’ in the given material. If ‘valuename’ is given then additionally locate the right value. The result of this function is the value associated with that key (and valuename).

* keylight( light, key [, valuename] )

Locate the ‘key’ in the given light. If ‘valuename’ is given then additionally locate the right value. The result of this function is the value associated with that key (and valuename).

Sound Functions

* sound( name [,loop [,volume [,play [,mode3d] ] ] ] )

Create a sound source for the given sound name. ‘loop’ is false by default, ‘volume’ is 1.0 by default, ‘play’ is true by default (if set to false the sound will not be played but the source is still created). ‘mode3d’ is set to 2D by default.

* soundpaused( source )

Return true if the sound source is paused.

Various

* rgb( red, green, blue )

Calculate the color for the given red, green, and blue values (values between 0 and 1).

* config( key, default )

Read the given configuration key from the configuration system. If the key is not present then the default will be returned.

* colred( color )

Get the red component from the given color.

* colgreen( color )

Get the green component from the given color.

* colblue( color )

Get the blue component from the given color.

* getmsg( message )

Use the translator to translate this message to the default language of the user.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated using texi2html 1.76.