@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