@c -*-texinfo-*-
@node XML Behaviour Layer, , Addons, Using CEL
@section The XML Behaviour Layer
@cindex @sc{xml}
@cindex behaviour layer
One of the predefined behaviour layers in Crystal Entity Layer is the
@sc{xml} behaviour layer. In this behaviour layer @sc{xml} is used a
simple scripting language. This allows one to create game logic using
@sc{xml} that one can embed in a map file.
@subheading Example
The easiest way to describe the basics behind the @sc{xml} behaviour
layer is with an example:
@example
/cellib/images/chair5.gif
chair
yes
cel.pcfactory.billboard
cel.pcfactory.timer
cel.pcfactory.properties
@end example
To run this example you can put this @sc{xml} file in the current
directory and then do this on Windows:
@example
bootstrap.exe cel.behaviourlayer.xml bootstrap load //this testscript.xml
@end example
Or on GNU/Linux:
@example
./bootstrap cel.behaviourlayer.xml bootstrap load /this testscript.xml
@end example
In this example we create two entities using the @samp{cel.addons.celentity}
addon (@pxref{Addons CelEntity}). The @samp{red_chair} entity just
has one property class which is the @samp{pcbillboard} 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 @sc{hud} elements in a 3D game. The @samp{green_chair} entity has
a @samp{pcbillboard} property class and a @samp{pctimer}
(@pxref{PropClass Timer}).
@subheading Scripts
When using the @sc{xml} behaviour layer you basically create @dfn{scripts}.
Every script corresponds to a behaviour for an entity (multiple entities
can use it of course). In this particular example we use the
@samp{cel.addons.xmlscripts} addon (@pxref{Addons XmlScripts}) to create the
two scripts that we will use for the two entities. The @samp{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 @samp{chair_mover} script simply waits until the timer
fires and then it initiates a move of the billboard to another location.
The @samp{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).
@subheading 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 @samp{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 @samp{chair_clicker} script reacted on billboard selection which is
a message from the billboard property class that is named
@samp{pcbillboard_select}. The @samp{chair_mover} script reacted on timer
events which is a message from the timer property class that is named
@samp{pctimer_wakeup}.
@subheading 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:
@example
@end example
Note that variables are typed. The following types are possible:
@itemize @bullet
@item @samp{int32} (signed 32-bit integer):
This is recognized by a value like @samp{345} or @samp{-398}.
@item @samp{uint32} (unsigned 32-bit integer):
This is recognized by a value like @samp{345u}.
@item @samp{float} (floating point number):
Possibilities are @samp{342.33} or @samp{-2.33e-33}.
@item @samp{bool} (true or false):
Possible values are @samp{true} or @samp{false}.
@item @samp{vector2} (two dimensional vector):
Written as @samp{[x,y]}.
@item @samp{vector3} (three dimensional vector):
Written as @samp{[x,y,z]}.
@item @samp{string} (a string):
Written as a simple token with no spaces or special tokens (like 'bla321')
or else surrounded by single quotes.
@end itemize
To use a global variable you use the @samp{?} operator like this:
@example
@end example
You can combine this in complex expressions:
@example
@end example
Global variables have one big advantage: they are persistant. Internally
the @sc{xml} behaviour layer will automatically use a @samp{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
@samp{?} operator is combined with the @samp{.} operator to access the
variable from another entity):
@example
@end example
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:
@example
@end example
This can become pretty complex. For example take this:
@example
@end example
This will print out the variable which has the name given in the local
variable called @samp{variable} from the entity which has the name given
in the local variable called @samp{entity}.
@subheading Calling Events
Some events (like @samp{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:
@example
@end example
This is the simplest example. In this case we will simply pass control
to the @samp{myevent} event and when that finishes execution will resume
at the operation after the @code{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:
@example
@end example
You can also pass parameters in an event call:
@example
@end example
This will pass the @samp{x} and @samp{y} parameters to the event. In the
event you can access these parameters with the @samp{@@} operator like this:
@example
@end example
Events can also be used as functions that return a value. In that case
you write the event like this:
@example
@end example
Then you can use this function as follows:
@example
@end example
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 (@samp{::}) operator:
@example
@end example
A special case for function calling is the @samp{...} operator. If you use
that then the parameters for the function will be the same as the parameters
that called this function. For example:
@example
@end example
This function will call @samp{addsomething} with the same parameters that
are given to @samp{process} and then multiply the result with 3.
@subheading Arrays
The @sc{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: @samp{bla['testing',3]} actually corresponds with a normal
variable that is called @samp{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:
@example
@end example