@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
<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">
        <pcfactory>cel.pcfactory.billboard</pcfactory>
        <pcfactory>cel.pcfactory.timer</pcfactory>
        <pcfactory>cel.pcfactory.properties</pcfactory>

        <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="pcbillboard">
            <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="pcbillboard">
            <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="pctimer">
            <action name="WakeUp">
                    <par name="time" long="500" />
                    <par name="repeat" bool="true" />
            </action>
        </propclass>
        <behaviour name="chair_mover" />
    </addon>
</world>
@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
<var name="variable" value="1000" />
@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
<print value="?variable" />
@end example

You can combine this in complex expressions:

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

Global variables have one big advantage: they are persistent. 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
<var entity="other_entity" name="variable" value="'some string'" />
<print value="'x in other_entity is equal to '+?other_entity.x" />
@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
<lvar name="localvar" value="3.1415" />
<print value="'Our local variable is equal to '+#localvar"/>
@end example

This can become pretty complex. For example take this:

@example
<print value="?#entity.#variable" />
@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
<call event="myevent" />
@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
<call entity="other_entities" event="myevent" />
@end example

You can also pass parameters in an event call:

@example
<call event="myevent">
    <par id="parid(x)" value="100" />
    <par id="parid(y)" value="50" />
</call>
@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
<event name="addsomething">
    <print value="@@x+@@y" />
</event>
@end example

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

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

Then you can use this function as follows:

@example
<print value="addsomething(x=3,y=5)" />
@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
<print value="otherentity::addsomething(x=3,y=5)" />
@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
<event name="process">
    <return value="addsomething(...)*3" />
</event>
@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
<lvar name="index" value="1000" />
<var name="bla[#index,3]" value="100" />
<print value="?bla[#index,3]" />
@end example


