<?xml version="1.0" ?><!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.1-Based Variant V1.0//EN" "dtd/kdex.dtd" [
  <!ENTITY kappname "TaxiPilot">
  <!ENTITY % addindex "IGNORE">
  <!ENTITY % English "INCLUDE" > <!-- change language only here -->
  
  
]>
<!-- The language must NOT be changed here. -->

<book lang="&language;">

<!-- This header contains all of the meta-information for the document such
as Authors, publish date, the abstract, and Keywords -->

<bookinfo>
<title>The &kappname; Handbook</title>

<authorgroup>
<author>
<firstname>Thomas</firstname>
<surname>Friedrichsmeier</surname>
<affiliation>
<address><email>Thomas.Friedrichsmeier@ruhr-uni-bochum.de</email></address>
</affiliation>
</author>
</authorgroup>


<copyright>
<year>2001</year>
<year>2002</year>
<holder>Thomas Friedrichsmeier</holder>
</copyright>
<!-- Translators: put here the copyright notice of the translation -->
<!-- Put here the FDL notice.  Read the explanation in fdl-notice.docbook 
     and in the FDL itself on how to use it. -->
<legalnotice>&FDLNotice;</legalnotice>

<!-- Date and version information of the documentation
Don't forget to include this last date and this last revision number, we
need them for translation coordination !
Please respect the format of the date (DD/MM/YYYY) and of the version
(V.MM.LL), it could be used by automation scripts.
Do NOT change these in the translation. -->

<date>19/05/2002</date>
<releaseinfo>0.7.2</releaseinfo>

<!-- Abstract about this handbook -->

<abstract>
<para>
&kappname; is a silly little game, based on what I remember of Spacetaxi for the C64.
</para>
</abstract>

<!-- This is a set of Keywords for indexing by search engines.
Please at least include KDE, the KDE package it is in, the name
 of your application, and a few relevant keywords. -->

<keywordset>
<keyword>KDE</keyword>
<keyword>kdegames</keyword>
<keyword>Taxipilot</keyword>
</keywordset>

</bookinfo>

<!-- The contents of the documentation begin here.  Label
each chapter so with the id attribute. This is necessary for two reasons: it
allows you to easily reference the chapter from other chapters of your
document, and if there is no ID, the name of the generated HTML files will vary
from time to time making it hard to manage for maintainers and for the CVS
system. Any chapter labelled (OPTIONAL) may be left out at the author's
discretion. Other chapters should not be left out in order to maintain a
consistent documentation style across all KDE apps. -->

<chapter id="introduction">
<title>Introduction</title>

<!-- The introduction chapter contains a brief introduction for the
application that explains what it does and where to report
problems. Basically a long version of the abstract.  Don't include a
revision history. (see installation appendix comment) -->

<para>
&kappname; is just a silly little game. It's based on
what I remember of the Spacetaxi-game on the C64.
The objective is to pick up passengers waiting on a number of platforms and to
drop them where they want to go. That's basically it. Please report
any problems or feature requests to the author.
</para>
</chapter>

<chapter id="story">
<title>The &kappname; Story</title>
<para>
It is the year 4017 A.D. - or rather, that's the official date, but after that terrible desaster
at the temporal power plant in New New Atlantis, which still serves as a popular excuse for being
late on any occasion, nobody is quite sure about that anymore. However in the year 3999, scientists
agreed that the year 3999 could not be off by more than some 787.3 years in the past or 543.7 in the
future with a confidence of some 94% and hence took the temporal statistical mean. Since hardly
anybody has too positive memories of temporal statistics in school, that settled it for the great
majority of people, even some (assumed) two centuries after the desaster experiencing enough
troubles in measuring medium time-intervals to be seriously worried about the exact year.
</para>
<para>
So - it's the year 4017 A.D. and for people in our time trying to understand 41st century mentality is
somewhat comparable to stone age man trying to make sense of a commercial for internet banking. This
might for us be a good enough explanation, why in a time when nobody can even remember who invented
teleportation there exists such an utterly useless job as a taxi-pilot.
</para>
<para>
It is noteworthy though, that even under those 41st century people that ever came to think about this,
there exist at least a few thousand completely different explanations for this fact, none of which
being accepted by more than a handful of people. Most people do however agree, that this must have to
do something with the taxi-pilots having done something very, very bad in a past or future life to
deserve such a pitiful fate (this particular view is of course only held by those believing in some
flavor of reincarnation, but the general direction of thought is widely shared).
</para>
<para>
To pick out just one of the especially absurd views: While it is once again becoming more and more
en vogue on the segwitch-parties of the would-be-intellectual to claim that the world is really just
the thing that we see, and we can - among the dozens of virtual realities - positely and correctly
perceive one as the real one, there is a few people still insisting that the whole world is just
a big computer simulation and so are all live-forms in it.
</para>
<para>
When the founder of this school of thought, her name now no longer being named, one day proposed,
that actually, there might be a world outside the simulating computer, with some people actually
steering the simulation - and yes, even taking the role of a taxi-pilot - just for fun ...
... well, anyway, her name is no longer being named.
</para>
</chapter>

<chapter id="using-taxipilot">
<title>Using Taxipilot</title>

<!-- This chapter should tell the user how to use your app. You should use as
many sections (Chapter, Sect1, Sect3, etc...) as is necessary to fully document
your application. -->

<para>
&kappname; is a game, and really you shouldn't be reading the instructions, but simply play. But then, here is a short
description of how to play. At some points this description is rather vague, saying "may or may not" and the like. This is
due to the fact, that much of &kappname;'s behavior is configurable.
</para>
<para>
<!-- Note that all graphics should be in .png format. Use no gifs because of
patent issues. -->
The arrow-keys (or whichever keys you chose in the Settings) allow you to accelerate into any direction.
Most levels will also have gravity, that
will generally pull you downwards. You may however also be pulled to or pushed away from certain points
in many ways, few of which have to do anything with real-life physics.
</para>
<para>
Some taxis have fixed landing-flaps, while other taxis can draw in and out their landing-flaps. Obviously you can not
land without your landing-flaps fully lowered. But then, some taxis are not able to accelerate left or right with the
landing-flaps out. The default key to toggle the landing-flaps is currently 'F'. It is inactive for taxis with fixed flaps.
</para>
<para>
Passengers will appear from time to time. Land on the platform they wait on and wait unitl they have
boarded the ship. The "Destination:"-display on the bottom of the window will tell you, where
the passenger wants to go. While the passenger is waiting to be delivered, you will see the "Tip"-display
counting down. This is how much the passenger will give you in addition to the regular fare. If the
tip is negative, the passenger will not even pay the entire regular fare. But you will never be paid less
than nothing for your services.
</para>
<para>
Passengers differ both in the amount of tip they will maximally give to you and in their impatience.
The tip will count down faster for very impatient passengers.
</para>
<para>
The regular fare consists of a fixed base amount, which may differ from level to level and an amount that
increases every time you accelerate. Therefore the fare is fairly based on your fuel consumption for the trip.
In order to make money, you should be fast however and earn some tips.
</para>
<para>
Watch your fuel! When it's empty, you will no longer be able to accelerate. Most likely this means that
you will crash very soon. You may fuel your ship on special platforms, which will generally, but not
necessarily be platforms where no passengers ever appear or want to go to. Fuel does have a price, though,
you can't refuel without money.
</para>
<para>
Some levels will have teleporters in them. Teleporters may take you to any other teleporter or nowhere
at all. Teleporters need not work both ways and not the same way. Some teleporters may cost money. You
can only use them, if you have enough funds.
</para>
<para>
In order to complete a level you have to do a number of "successful" deliveries, i.e. deliveries that
you do get a non-negative tip for. So this is another reason to hurry. The number of "successful"
deliveries required may differ from level to level. Upon completion of some levels, you will be
awarded an extra ship (life).
<!--<screenshot>
<screeninfo>Here's a screenshot of &Taxipilot;</screeninfo>
	<mediaobject>
	  <imageobject>
	    <imagedata fileref="screenshot.png" format="PNG"/>
	  </imageobject>
	  <imageobject>
	    <imagedata fileref="screenshot.eps" format="EPS"/>
	  </imageobject>
	  <textobject>
	    <phrase>Screenshot</phrase>
	  </textobject>
	</mediaobject>
</screenshot>-->
</para>


<sect1 id="Taxipilot-features">
<title>More &kappname; features</title>

<para>Currently &kappname; contains only three levels, two of which look strangely similar. Also there
are only two passengers, one of which can't really walk.
&kappname; is highly configurable, though, without having to recompile. See
the <link linkend="developers">developers sections</link> for
details on writing your own levels.</para>

</sect1>
</chapter>

<chapter id="commands">
<title>Command Reference</title>

<!-- (OPTIONAL, BUT RECOMMENDED) This chapter should list all of the
application windows and their menubar and toolbar commands for easy reference.
Also include any keys that have a special function but have no equivalent in the
menus or toolbars. This may not be necessary for small apps or apps with no tool
or menu bars. -->

<sect1 id="Taxipilot-mainwindow">
<title>The main &kappname; window</title>
<para></para>

<sect2>
<title>The Game Menu</title>
<para>
<variablelist>
<varlistentry>
<term><menuchoice>
<shortcut>
<keycombo><keycap>Ctrl</keycap><keycap>n</keycap></keycombo>
</shortcut>
<guimenu>Game</guimenu>
<guimenuitem>New</guimenuitem>
</menuchoice></term>
<listitem><para><action>Starts a new game</action></para></listitem>
</varlistentry>
<varlistentry>
<term><menuchoice>
<shortcut>
<keycombo><keycap>Ctrl</keycap><keycap>w</keycap></keycombo>
</shortcut>
<guimenu>File</guimenu>
<guimenuitem>Stop</guimenuitem>
</menuchoice></term>
<listitem><para><action>Aborts the current game</action></para></listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term><menuchoice>
<guimenu>File</guimenu>
<guimenuitem>Pause</guimenuitem>
</menuchoice></term>
<listitem><para><action>Pauses the game, without leaving it</action></para></listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term><menuchoice>
<shortcut>
<keycombo><keycap>Ctrl</keycap><keycap>q</keycap></keycombo>
</shortcut>
<guimenu>File</guimenu>
<guimenuitem>Quit</guimenuitem>
</menuchoice></term>
<listitem><para><action>Quits</action> &kappname;</para></listitem>
</varlistentry>
</variablelist>
</para>

</sect2>

<sect2>
<title>The Settings Menu</title>
<para>
<variablelist>
<varlistentry>
<term><menuchoice>
<guimenu>Settings</guimenu>
<guimenuitem>Select Mission</guimenuitem>
</menuchoice></term>
<listitem><para><action>Lets you select a mission description file</action></para></listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term><menuchoice>
<guimenu>Settings</guimenu>
<guimenuitem>Configure Key Bindings</guimenuitem>
</menuchoice></term>
<listitem><para><action>Lets you change the key bindings</action></para></listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term><menuchoice>
<guimenu>Settings</guimenu>
<guimenuitem>Configure Taxipilot</guimenuitem>
</menuchoice></term>
<listitem><para><action>Here you can specify a few options concerning the startup-behavior,
where to look for your missions (useful if you design your own missions) and tune the refresh-rate, in order
to make Taxipilot run as good as possible on your hardware.</action></para></listitem>
</varlistentry>
</variablelist>
</para>

</sect2>

</sect1>
</chapter>

<chapter id="developers">
<title>Enhancing &kappname;</title>

<!-- (OPTIONAL) A Programming/Scripting reference chapter should be
used for apps that use plugins or that provide their own scripting hooks
and/or development libraries. -->

<para>
&kappname; is still very limited. It only consists of three levels and about one and a half
passengers - not to mention that graphics rather suck. However, &kappname; allows you to configure
a whole lot of things without having to dig through the code and recompile. This chapter describes
the four types of XML-based configuration-files that currently exist, explaining what you can
configure already and what still is to come.
</para>
<para>
As more and more features have been added and will continue to be added over time, this documentation, too, is
growing more and more complex. I try to explain all the possibilities, but chances are you will never need all of those
at once. Therefore, don't get frustrated with this lengthy description - probably you can get a good start by looking
at the configuration-files provided with the distribution and later check back in the documentation to find out what
possibilities there are and what exactly one attribute or the other does. Comments on how to make this documentation
more readable are always welcome.
</para>
<para>
Version 0.3.0 introduced some sanity-checks on the configuration-files you write. Image-files are checked
for being existent and readable (but not for being in the correct format!), the parameters you
can specify have been assigned upper and lower limits (for numeric attributes), that should be
wide enough to allow everything that might make sense (please let me know, if they aren't) but
hopefully catch a few mistakes. Default values will be assigned for missing or invalid parameters.
These default values sometimes make sense, sometimes they probably don't - so look for debugging
messages. Debugging messages are printed to stderr, using 5 levels:
</para>
<literallayout class="monospaced">
0: Error		These are critical errors that would cause &kappname; to crash.
						&kappname; might exit on those errors.
1: Serious Warning  	A default value was inserted that probably doesn't make a lot of sense
2: Warning 		(default level) A default value was inserted that probably makes sense,
						but you should still better fix this.
3: Info			A default value was inserted where you are explicitly allowed to omit
						parameters, or other harmless messages.
4: Translations		A string was translated, a string could not be translated, a translations-file was not found...
						may generate a LOT of output, that will generally only be useful for translators.
</literallayout>
<para>
You may change the debug-level using the commandline option --debug-level (level) to change the
verbosity. If your configuration does not work and you can't figure out the reason, try setting
debug-level to 3. The default debug-level is 2, and I'd consider it good style for the configuration
files, that no debug messages are generated at this level.
</para>
<para>
Before distributing a (large) mission, you may want to start Taxipilot with the --thorough_check -option, which
will make it parse all configuration-files belonging to the mission thoroughly once the mission is selected. This should
output any errors, without having to go through all the levels.
</para>
<para>
All files install to the subdir "taxipilot/game_data/" (config-files) or
"taxipilot/game_data/images/" (images) of the KDE-Standard-data-directory
(for me that's "/opt/kde2/share/apps/").
Whenever you put in a non-absoulte path in your configuration files, &kappname; will first try to
find those files in (or rather relative to) the directory where the selected mission-configuration
files resides (sub-dir images for image-files). If the files can't be found there, &kappname; will
check in the above-named installation-directories.
</para>
<para>
What this means practically is, that you should state the file-names of your configuration-files
as relative to the directory your mission-file (and as a matter of fact, I'd recommend placing them
in the same directory). All image-files should be located in a subdirectory "images" of the
directory of you mission-file. Do not specify the "images/"-path in your file-names. You might
want to have a look at the configuration-files provided to see what I mean.
</para>
<para>
Now, if you want to use some configuration- or image-files of the distribution (e.g. you want to
create an own level, but want to use the passengers and taxi provided), you specify those file-names
relative to the installation-directories. Therefore, &kappname; will first check in your mission's
directory and then fall back to the files provided with the distribution. What you can not do,
however, is to have some files of one single animation in your mission-directory and some other
files of the same animation in the installation-directory!
</para>
<para>
You may also use absolute paths in your configuration files. These will be left untouched, but I'd
recommend to do so only for testing purposes.
</para>
<para>
Hopefully, things will get clearer, when you read on. Otherwise, please contact me.
</para>
<para>
Starting with version 0.3.0, you may use "true" and "false" instead of "yes" and "no" for all
attributes taking yes/no-parameters. "yes" and "no" still work, though.
</para>

<sect1 id="missions">
<title>Configuration of missions</title>
<para>
A mission is a succession of levels, using a number of passengers and a particular taxi. To illustrate
what I'm trying to say, you might define two missions, which differ in the sets of passenger-sprites
they use (like one with aliens, one with normal human beings, one with your favorite cartoon-characters).
More importantly, you can define which levels (see below) the player will have to go through and in
which order, so you can easily reuse a level you or somebody else already created for a different mission.
Furthermore you may specify a particular taxi, that will be used in the mission.</para>
<para>
Let's have a walk through an example mission:
</para>
<literallayout class="monospaced">
&lt;!DOCTYPE mission_data &gt;
&lt;document author="Thomas Friedrichsmeier" title="Mission 1" startscreen="mission1_start_screen.png"&gt;
</literallayout>
<para>
The "author" and "title"-attributes should be self-explanatory. The values in those attributes
are shown in the credits on the start-screen (see below).</para><para>
The startscreen-attribute specifies an image file that will be used as a sort of welcome screen to
your mission. Note that if you omit this attribute, a default screen will be used. This is only to
ensure backwards-compatibility, please do specify some kind of startscreen. Also make sure, you
leave some blank space (preferrably some dark color) on the bottom of this picture, since this is,
where the credits will be shown.
</para>
<literallayout class="monospaced">
	&lt;initials ships="5" /&gt;
</literallayout>
<para>
This simply specifies, how many ships the player will start out with.
</para>
<literallayout class="monospaced">
	&lt;levels&gt;
		&lt;data file="level1.level" /&gt;
		&lt;data file="level2.level" /&gt;
		&lt;data file="level3.level" /&gt;
	&lt;/levels&gt;
</literallayout>
<para>
The levels-section simply lists all levels in the oder they are to be played. These are just plain
filenames (see above) for the level-description-files explained below.
</para>
<literallayout class="monospaced">
	&lt;passengers&gt;
		&lt;data file="passenger1.passenger" on_start_screen="yes" start_screen_x="55" start_screen_y="420" /&gt;
	&lt;/passengers&gt;
</literallayout>
<para>
The passenger-section is basically the same. Passengers will be selected at random, however.</para>
<para>
The additional parameters specify whether the passenger will appear on the startscreen and - if so -
where. If you omit those parameters, the passenger will not appear on the startscreen. The passenger
will always show up in the credits, though.
</para>
<literallayout class="monospaced">
	&lt;taxi file="taxi1.taxi" on_start_screen="yes" start_screen_x="55" start_screen_y="55" /&gt;
</literallayout>
<para>
Not much to be explained on this one either. Note that this is different from the 0.3.x-versions.
The taxi can now be animated and therefore has a configuration file of its own.
</para>
<para>
The "start_screen"-related attributes work the same way as for the passenger.
</para>
<literallayout class="monospaced">
&lt;/document&gt;

</literallayout>
</sect1>

<sect1 id="passengers">
<title>Configuration of passengers</title>
<para>
Passengers are the creatures you have to transport around. They are easy to configure, but a lot of
work to draw.
</para>
<para>
Let's look at the configuration:
</para>
<literallayout class="monospaced">
&lt;!DOCTYPE passenger_data &gt;
&lt;document author="Thomas Friedrichsmeier" title="Mr. Right" &gt;
</literallayout>
<para>
The "author"- and "title"-attributes will again be shown in the credits for the missions this
passenger appears in.
</para>
<literallayout class="monospaced">
	&lt;idle&gt;
		&lt;data frames="4" file_pattern="passenger1_idle1_%1.png" repetitions="5" /&gt;
		&lt;data frames="4" file_pattern="passenger1_idle2_%1.png" repetitions="8" /&gt;
	&lt;/idle&gt;
</literallayout>
<para>
Passengers may do different stuff while waiting on you to pick them up. Let's call these idle-animations.
For each animation you have to specify the number of frames, it contains (make sure you really have all
these frames, of &kappname; will abort with an error). The frames are stored in seperate files, that you have to name like
this: your_file_name0000.png your_file_name_0001.png ... your_file_name[frames-1].png .
For certain idle-animations (like waving) it makes sense to get repeated several times to form an
"action". That's what the "repetitions"-paramter is used for.</para>
<para>
You may define as many idle-animations as you like, but at least one. If you create more than one,
the animation will be picked at random. Use frames="1" and a static image, if you don't want any
idle animations. Likely a parameter sound="filename" will be implemented some day.
</para><para>
Additionally, all passenger-animations (including those described below) take a paramenter "anim_frame_period".
So, for example
</para>
<literallayout class="monospaced">
		&lt;data frames="4" file_pattern="passenger1_idle1_%1.png" repetitions="5" anim_frame_period="100" /&gt;
</literallayout>
<para>
would make the specified animation run at half the default speed (50 msec per frame).
</para>
<literallayout class="monospaced">
	&lt;walking speed="0.6" /&gt;
</literallayout>
<para>
This specifies, how many pixels the passenger moves per advancement frame. Note that the time period for an advancement
frame is different from that of the animation-frames, which you may configure. The advancement-frame-period is
currently 50 msec (i.e. 20 fps) fixed divided by passenger impatience. This is admittedly rather awkward, and will
hopefully be changed some day.	
</para>
<literallayout class="monospaced">
	&lt;walking_left frames="14" file_pattern="passenger1_walking%1.png" /&gt;
	&lt;walking_right frames="14" file_pattern="passenger1_walking%1.png" /&gt;
</literallayout>
<para>
The format is basically the same as above. Obviously there is no repetions-parameter and you can only
specify one animation for walking left and one for walking right.
</para>
<literallayout class="monospaced">
	&lt;teleporting frames="10" file_pattern="passenger1_teleporting%1.png" /&gt;
</literallayout>
<para>
Just like above, there is only one teleportation-animation. It will be reversed for reappearing.
</para>
<literallayout class="monospaced">
	&lt;still frames="1" file_pattern="passenger1_still0000.png" /&gt;
</literallayout>
<para>
I hardly need to explain the syntax. It's the animation (or in this case still image) you see, when
the passenger is neither performing idle-actions, nor walking, nor teleporting. Warning: As of
version 0.4.0, animations are not yet supported in this section. Only the first picture of the
series you specify will ever be used, so for now, you'll probably want to save the drawing and
put frames to "1".
</para>
<literallayout class="monospaced">
&lt;/document&gt;
</literallayout>
<para>
You may not omit any of these sections. You may always use frames="1" and a constant "file_pattern",
in order to create a very simple passenger, however.
</para>
</sect1>

<sect1 id="taxi">
<title>Configuration of the taxi</title>
<para>
The taxi is the central sprite on the screen. It is - so to speak - you, the player. The reason
I'm introducing it's configuration after that of the passenger is, that it's rather similar.
</para>
<para>
An here it is:
</para>
<literallayout class="monospaced">
&lt;!DOCTYPE taxi_data &gt;
&lt;document author="Thomas Friedrichsmeier" title="AirCab 301" &gt;
</literallayout>
<para>
Once again, the "author"- and "title"-attributes will be shown in the credits for any mission
that uses this taxi.
</para>
<literallayout class="monospaced">
	&lt;fuel max="800" initial="800" /&gt;
</literallayout>
<para>
Specifies how much fuel the taxi starts out with and how much it can have at maximum. 800 is a
good value, I think, but you can make your missions harder or easier by changing it to lower
or higher values.
</para>
<literallayout class="monospaced">
	&lt;still frames="1" file_pattern="taxi1/still0000.png" /&gt;
</literallayout>
<para>
This is the animation (or in this case still image) the taxi is doing all of the time (if not
doing idle-actions or teleporting).
</para>
<literallayout class="monospaced">
	&lt;idle&gt;
		&lt;data frames="6" file_pattern="taxi1/idle1_%1.png" repetitions="2" /&gt;
	&lt;/idle&gt;
</literallayout>
<para>
Even while flying, the taxi may do "idle"-animations. So obviously this term is not quite
correct, but it's in analogy to the passengers' idle-animations (See there for the explanation).
</para><para>
You may define as many idle-animations as you like, but at least one. If you create more than one,
the animation will be picked at random. Use frames="1" and a static image, if you don't want any
idle animations. Likely a parameter sound="filename" will be implemented some day.
</para>
<literallayout class="monospaced">
	&lt;flying_left frames="2" file_pattern="taxi1/flying_left%1.png" /&gt;
	&lt;flying_right frames="2" file_pattern="taxi1/flying_right%1.png" /&gt;
	&lt;flying_up frames="2" file_pattern="taxi1/flying_up%1.png" /&gt;
	&lt;flying_down frames="2" file_pattern="taxi1/flying_down%1.png" /&gt;
</literallayout>
<para>
The meaning of these should be easy to guess. They change your taxi's appearance when you
accelerate with the cursor keys. These are not independend images however, but really these
images are just draw over the taxi image (so it can continue doing it's idle-stuff). Technically
these are a different sprite. Have a look at the animations provided in the distribution, if
you can't see, what I'm trying to say.</para>
<para>
By the way, hitting something with these "flying-animations" doesn't crash your taxi, that means
they are not to be understood as part of the taxi itself. They are however harmful to the passenger.
</para>
<literallayout class="monospaced">
	&lt;teleporting frames="10" file_pattern="taxi1/teleporting%1.png" /&gt;
</literallayout>
<para>
This is really the same as for the passenger. See there for details.
</para>
<literallayout class="monospaced">
	&lt;landing_flaps offset_x1="3" offset_x2="30" /&gt;
</literallayout>
<para>
This tag was introduced in Version 0.4.2, and specifies the x-positions of the taxi's landing-flaps
(Is this the correct term? The poles, you stand on when landed, is what I mean) relative to the
left corner of the taxi-sprite. If you omit this tag, the very left and right pixels of your taxi will
be assumed as the position of the landing-flaps. This may result in the taxi crashing, when landing
close to the platforms edges, while it actually looks to the player like the taxi is properly standing
on the platform. So you should really specify these attributes.
</para>
<para>
Starting with Version 0.4.3 you may also create taxis with moveable landing-flaps. For those, the landing_flaps-tag
would look like this:
</para>
<literallayout class="monospaced">
	&lt;landing_flaps offset_x1="3" offset_x2="30" moveable="true" frames="6" file_pattern="taxi2/flaps%1.png" blocking="false" /&gt;
</literallayout>
<para>
Note that the offset-attributes do NOT change their meaning in this context. The flaps-image is always aligned top-left
with the taxi-image. Have a look at taxi2 and its images. The boolean attribute "blocking" specifies, whether you can still
accelearte left/right with the landing-flaps out (false, default, if you are able to do so), or whether left/right-acceleration
is blocked with the flaps out.
</para>
<literallayout class="monospaced">
&lt;/document&gt;
</literallayout>
<para>
You may not omit any of these sections. You may always use frames="1" and a constant "file_pattern",
in order to create a very simple taxi, however.
</para>
<para>
Version 0.4.4 introduces the possibility to specify different animations dependent on whether the taxi is heading (or
has last accelerated) to the left or to the right. I'm discussing this seperately, as this is probably less confusing. And
here is how you can get that to work:
</para>
<para>
Whereever you can specify an attribute "file_pattern" in the taxi-config, you may instead specify the two attributes
"file_pattern_left" and "file_pattern_right" for different animations when heading left or right. Note that you can not
specify "frames" seperately for such a pair of animations - so they must always have the same number of frames.
</para>
<para>
You need not specify direction-dependent pairs of animations in all of the tags. You may well have, say,
direction-dependent animations for the still-image and the idle-animations but not for the teleportation-animation,
or you may even have direction-dependency on one idle-animation but not on a different one. Likely however,
this would look rather strange.
</para>
<para>
Of course the flying-animations may also change with direction. Obviously, however, that makes little sense for the
flying_left and flying_right-animations (you may still specify that, though). And of course, the landing-flaps may also
be direction-dependent. For the landing-flaps, you may also specify seperate "offset_x1_left", "offset_x1_right" and
"offset_x2_left", "offset_x2_right" instead of "offset_x1" and "offset_x2", if the x-position of your landing-flaps
changes.
</para>
<para>
Note that although it would be functionally equivalent to specify "file_pattern_left" and "file_pattern_right" with the
same value or to specify "file_pattern", if you do not want direction-dependency on an animation, the latter form is
not only shorter, but also saves some memory.
</para>
<para>
Finally, starting with version 0.6.0 you can use the "anim_frame_period"-parameter as described for the passenger. Same
as with the "frames"-parameter, you can only specify this attribute once, even if you have different animations for
going left and going right.
</para>
<para>
As always, having a look at the configuration-files provided will probably help making this clear.
</para>
</sect1>


<sect1 id="levels">
<title>Configuration of levels</title>
<para>
A level is... well, I don't think I have to explain this. Let's have a walk through a sample config-file.
</para>
<literallayout class="monospaced">
&lt;!DOCTYPE level_data &gt;
&lt;document author="Thomas Friedrichsmeier" caption="Plain Level 1"&gt;
</literallayout>
<para>
The "author"- and "caption"-attributes should be self-explanatory by now. Only thing is, that here
you have to specify "caption" instead of "title" for historical reasons. The "caption" is also
shown in &kappname;'s window-caption when the level is on.
</para>
<literallayout class="monospaced">
	&lt;completion deliveries="5" extra_life="no" /&gt;
</literallayout>
<para>
This specifies, that you will have to complete 5 deliveries successfully (get a tip for the
delivery) in order to compelete this
level. Upon completion of this level you will not be awarded an extra life.
</para>
<literallayout class="monospaced">
	&lt;image background="testbackgr2.png" level="testlevel3.png" /&gt;
</literallayout>
<para>
I'm not quite sure, whether this is such a good idea, but every level may have a unique background.
Choose .png or any other file-format, QT supports. The background image is not solid/harmful, you can
fly right over it. Make sure it doesn't look too much like the real level.</para><para>
The level itself is first of all a simple image with transparancies. You can fly over the transparency,
you can crash into everything else (+ land on the designated platforms, see below). For right now,
the level-image has to have a solid frame. Currently there is not other mechanism of keeping the taxi
inside the visible area.</para><para>
You may want to have a look at the background- and level-images provided. It's really not that complicated.
The only restrictions on the size of level- and background-images is that they should have the
same size and should not be too large for a user with, say 800x600-screen-resolution to display
(take into account the space the game-displays take up).
</para>
<para>
Starting with version 0.4.2 you may however also create oversized levels. The syntax is as follows:
</para>
<literallayout class="monospaced">
	&lt;oversize visible_width="640" visible_height="480" initial_offset_x="0" initial_offset_y="0" margin="80" /&gt;
</literallayout>
<para>
This specifies that the portion of the level that will be visible to the player is 640x480 pixels
(your level should of course be bigger than that, if you use this option), you will initially see
the top-left corner of the level, and finally "margin"-means the distance the taxi may have to any
side of the visible area, before the level is scrolled.
</para>
<literallayout class="monospaced">
	&lt;platforms&gt;
		&lt;data y="265" passengers="yes" has_fuel="no" x1="94" passenger_base_x="190" x2="194" /&gt;
		&lt;data y="265" passengers="yes" has_fuel="no" x1="236" passenger_base_x="240" x2="356" /&gt;
		&lt;data y="355" passengers="yes" has_fuel="no" x1="116" passenger_base_x="120" x2="195" /&gt;
		&lt;data y="355" passengers="yes" has_fuel="no" x1="234" passenger_base_x="240" x2="337" /&gt;
		&lt;data y="389" passengers="yes" has_fuel="no" x1="420" passenger_base_x="425" x2="585" label="Residential area" /&gt;
		&lt;data y="71" passengers="no" has_fuel="yes" fuel_price="0.1000" fuel_step="3" x1="440" x2="540" /&gt;
	&lt;/platforms&gt;
</literallayout>
<para>
This section defines, where you can land in this level. Note that you can't land in the void.
&kappname; first checks, whether you collided yith the level-image, and only after that, whether this
means you're landed. Make sure the landing-areas are really even, otherwise you might get "stuck" on
them. The "label"-Attribute allows you to specify, what Spacetaxi will call the platform. If you omit
the label-Attribute, the Platforms will will be numbered in the order of their definition, starting with
1 (and called "Platform &lt;number&gt;". It's your job to provided the user with information
(in the level-image), which platform is which. Also don't forget to provide valid information
about where the pilot can land. Therefore I'd recommend to explicitely label all platform in the
level image.</para><para>
You have to measure (2 or 3 pixels error won't harm) the y-coordinates of the surface of the platforms
(y), and the x-coordinates of the left (x1) and right (x2) boundaries of the platform. Make sure the
platform is large engouh to land on it (the taxi has to be compeletely within the boundaries). Of course
you should be careful with these measures, to make sure the player can land everywhere, they expect to.
</para><para>
You may find the command-line-option "--highlight" useful during development. What it
does is draw a (yellow) horizontal line from "x1" to "x2" at height "y". So this allows you to see,
whether you really specified the platform-coordinates correctly.
</para><para>
The remaining parameters specify, whether there are passengers waiting on this platform (or demanding to
be taken there) (passenger, default is "no"), if so, where exactly they appear / disappear on (passenger_base_x) (y
coordinates are always right on top of the platform).</para><para>
Furthermore, you can specify, whether you will get fuel on this platform (has_fuel, default is "no") and what the price of a
unit of fuel is. I guess it is generally a good idea to keep passenger- and fuel-paltforms separate,
but you don't have to.</para><para>
"fuel_step" specifies, how fast the taxi will be fueled, i. e. how many units of fuel (see taxi-configuration)
will be fueled up per unit of time (50 msec). "fuel_step" can take integer values from 1 (pretty slow)
to 8000 (should amount to instant fueling to max for about any taxi). Personally I'd think values from
2 through 6 to be reasonable, as long as you don't want this "instant"-fueling effect.
</para>
<literallayout class="monospaced">
	&lt;gravity base_gravity="0.0" horiz_gravity="0.0"&gt;
		&lt;data x="640" y="480" gravity="100" potential="2" /&gt;
		&lt;data x="0" y="0" gravity="100" potential="2" /&gt;
		&lt;data x="640" y="0" gravity="100" potential="2" /&gt;
		&lt;data x="0" y="480" gravity="100" potential="2" /&gt;
	&lt;/gravity&gt;
</literallayout>
<para>
You have control over gravity far more than physics would allow. The simple parameters
"base_gravity" and "horiz_gravity" specify the simple downward / sideward pull, you would expect in any
game like this (independend of you current position). Start exprimenting with values around 0.005.
Of course you may use negative values in order to reverse direction.</para><para>
The following tags are "centers of gravity". Those allow you to make the force acting on the taxi
depend on it's current position on the screen. Obviously you need to specify the location of the
center of gravity. Next is a constant of gravity. Reasonable values (double) for this constant may vary
dramatically depending on the following parameter. Use negative values to achieve a "pushing away".
The parameter "potential" affords you a lot of control.
</para><para>
The allowed values and their effects are:</para><para>
0: force does not depend on distance (but direction of force depends on direction)</para><para>
1: force depends on plain distance</para><para>
2: "physical gravity" - force is reverse of distance squared</para><para>
4: "dangerous spot" - force is reverse of distance to the fourth power</para><para>
There is no value "3"! You may have as many centers of gravity as you like, but I'm afraid, having real
lots of them could slow down the game on old machines. You may of course omit specifying centers of
gravity.
</para>
<literallayout class="monospaced">
	&lt;teleporters&gt;
		&lt;data x="100" y="100" destination="2" fare="0" factor_x="1" factor_y="1" image="teleporter1.png" /&gt;
		&lt;data x="200" y="200" destination="3" fare="0" factor_x="-2.5" factor_y="-2.5" image="teleporter1.png" /&gt;
		&lt;data x="400" y="200" destination="1" fare="1.50" factor_x="0" factor_y="0" image="teleporter1.png" /&gt;
	&lt;/teleporters&gt;
</literallayout>
<para>
Have a look at level 3 of the current distribution, if you want to know, what teleporters do. They may
have unique images, and of course they need to be placed on some coordinates. The other parameters are
as follows:</para><para>
"destination": Teleporters are numbered in the order of definition starting with 1. You can only
teleport from a TP and only to another TP. This specifies the number of the TP, you will arrive at.
If you want a TP to serve as an arrival-point only, set this value to "0".</para><para>
"fare": Teleporting may cost money. This parameter specifies how much. If you don't have engouh money,
the TP will be inactive. So make sure, vital TPs don't cost anything.</para><para>
"factor_x", "factor_y": These parameters might be very nasty, they change the speed (and direction) when you
arrive. Putting these values to 0 will obiviously stop the taxi. Putting them to large values might
be very dangerous to the pilot.</para>
<para>
Since generally, the active-region of a teleporter is determined by whether the taxi touches the teleporter,
if you want to have an invisible teleporter (or one where the active-region does not correspond to the image),
you will have to additionally specify the parameters "width" and "height" (in pixels). For an invisible teleporter,
you could then specify a transparent 1x1-image. You may not omit the image-parameter, however. As a matter of fact,
specifying a "width" and "height" for your teleporter, may save some resources, since in this case no collision-detection
needs to be performed.
</para>
<para>
You may of course omit the teleporters-section, if you don't want any teleporters.
</para>
<literallayout class="monospaced">
	&lt;tips min="10.00" max="30.00" /&gt;
</literallayout>
<para>
This simply specifies the range of tips, passengers may start out with...
</para>
<literallayout class="monospaced">
	&lt;fare base="5.40" step="0.050000" /&gt;
</literallayout>
<para>
... while this parameter is used to control the taxi-pricing. "base" is the base-fare, "step" determines,
how fast the fare will increase.
</para>
<literallayout class="monospaced">
	&lt;initial_position x="50" y="50" /&gt;
</literallayout>
<para>
Finally, this is, where the taxi starts out at in the level.
</para>
<literallayout class="monospaced">
&lt;/document&gt;
</literallayout>
<sect2 id="objects">
<title>Bringing life to your levels: Moving objects</title>
<para>
Version 0.5.0 finally introduced support for moving objects in the levels. As of this version, there is still a lot to do,
but also, a lot of flexibility is implemented already. And here is how that works:
</para>
<literallayout class="monospaced">
	&lt;objects&gt;
		&lt;object class="background" frames="5" file_pattern="some_object%1.png"
				z="90" anim_frame_period="50" looping="yes" initial_vx="10" initial_vy="10" &gt;
			&lt;path x="100" y="100" time="500" accel="linear" /&gt;
			&lt;path x="110" y="100" time="500" accel="abrupt" /&gt;
			&lt;path x="130" y="100" time="500" accel="linear" /&gt;
			&lt;path x="140" y="100" time="500" accel="linear" /&gt;
			&lt;path x="170" y="100" time="1500" accel="linear" visible="no" /&gt;
		&lt;/object&gt;
		&lt;object class="harmful" frames="10" file_pattern="another_object%1.png" looping="no" z="90" &gt;
			&lt;path x="100" y="100" time="5000" accel="linear" /&gt;
			&lt;path x="100" y="300" time="5000" accel="linear" frames="5" file_pattern"animation_override%1.png" /&gt;
			&lt;path x="100" y="400" time="5000" accel="linear" /&gt;
		&lt;/object&gt;
	&lt;/objects&gt;
</literallayout>
<para>
So first of all an objects may belong to different classes. Two basic classes are supported: Either the object
is "harmful" i.e. you crash when you collide with it, or "background" i.e. it does not do anything to you, and is merely
decoration. There is a number of special classes, which will be dealt with in the next section.
Then of course, an object has an image or animation with the well-known parameters "frames" and "file_pattern".
The (optional) parameter "anim_frame_period" will probably soon be implemented for other animations, too, and specifies
how fast the animation is running or rather, the time in msecs needed for one frame. A higher value gives a slower
animation. The movement-frame-rate is independend of this parameter. It only deals with the animation.
</para>
<para>
Further, you may specify the z-Position of the object. The higher the value, the closer is the object, i.e. it will cover
objects with a lower z, when the two overlap. BTW, the taxi is at z="75", the level at z="50", passengers at z=40".
Of course the object can not be behind the level's background, however.
</para>
<para>
An object may either be "looping" (going from A to B to C to A) or
"bouncing" (going from A to B to C to B to A and then back). Note that this also affects the way that the last path-segment
is treated. For looping objects, it will be taken as the way back, i.e. the first object above will be invisible for
1.5 seconds and return to the position 100/100 during that time. For bouncing objects, the way is the same in both
directions, so here the last path-segment describes the way the object takes starting from the last key-position, until it
reaches that same key-position again. So it will spend 5 seconds in the third path-segment and then go back to the second.
</para>
<para>
You may specify an inital speed for the object. This only has an effect, if the first segment of the path has accel="linear"
given. See below.
</para>
<para>
Next we will have to specify the path of the object: Therefore we define key-frames, with starting-coordinates,
time needed to reach next key-point (milliseconds), mode of acceleration, and whether it
will be visible on the way (while invisible it is never harmful).
</para>
<para>
There are three possible modes of acceleration:
</para>
<para>
accel="abrupt": The object moves from the starting-coordinates of the current path-segment to the startin-coordinates
of the next at a constant speed on a straight line. Therefore the speed and direction of the object may change abruptly
with respect to the previous path-segment.
</para>
<para>
accel="linear": The object starts out with the speed and direction it had on the last frame of the previous segment of the
path (or with initial_vx and initial_vy). It then uses just that constant acceleration that will make it arrive at the next
key-position in the specified time. Most of the time this should give nice smooth movements.
</para>
<para>
accel="custom": The tough way, but of course the one with the most flexibility. If you specify accel="custom", you may also
specify the parameters "vx" and "vy" (starting velocity (in pixels per second)), "ax" and "ay" (starting acceleration
in pixels per second squared) and "dax" and "day" (change in acceleartion over time in pixels per second cube).
Of course you don't have to specify all these. Any parameter you omit will be assumed to be zero. Therefore, if you
omit "ax", "ay", "day", and "dax", you will get a movement with a constant velocity "vx" and "vy". Using this mode, it
is entirely your responsibility to make sure that using these parameters, the object will reach the next key-frame in the
specified time. If it does not, it will simply be put there, making the object jump. So this is for those who love maths.
Even in this mode, if you specify a "bouncing" object, the way back will be exactly the reverse of the way forth.
</para>
<para>
Finally you can otherride the following parameters on a per path-segment basis:
"z", "frames", "file_pattern", "anim_frame_period".
</para>
<para>
I admit, this is quite complex already, but as always, you can start out with simple objects and slowly experiment with
more difficult ones.
</para>
<para>
Version 0.6.1 introduces the possibility to create textual moving objects. Of course you can always put text in an
image-file and this would not even cause a loss in performance + allow you more flexibility, but of course it would make
life even harder for potential translators. So whenever you want to display text in a level, I suggest you create a
textual moving object. Actually this is a completely normal moving object, except for that you don't specify the
image-/animation-specific attributes, but the following ones:
</para>
<literallayout class="monospaced">
		&lt;object text="Sorry, this is it, this is the last level!" align="left" font="helvetica" size="24"
				r="10" g="255" b="150" anim_frame_period="10000" class="background" z="90"
				looping ="true"&gt;
...
</literallayout>
<para>
Actually you can specify a different text for each path-segment, and you can even have text on one path-segment
and an animation on the next. Since text can not be animated, however, you will probably only define a global text.
The "r", "g", and "b"-attributes define the color of the text, the other attributes should be self-explanatory.
The "align"-attribute takes "left", "center" or "right" as values, and obviously only has an effect, when there is more
than one line of text. To insert a newline into your text, put in a "\n". I.e. : text="This is the first line\nThis is the second
line". Technically, if Taxipilot finds a "text"-attribute in any path-segment, it will assume that there is to be a text, and will
ignore any image-/animation-specific attributes such as "frames".
</para>
<para>
Note that although textual objects could theoretically also be platforms, this probably isn't a good idea.
</para>
</sect2>
<sect2 id="special_objects">
<title>Everything's moving now: Special moving objects</title>
<para>
Version 0.5.1 greatly extends the support for moving objects in the levels. You can now also define platforms,
teleporters and centers of gravity to be moving objects. In order to do so, first of all you assign an identification label
to the platform/teleporter/center of gravity (example for a moving teleporter):
</para>
<literallayout class="monospaced">
		&lt;data ident="tp1" destination="2" fare="0" factor_x="1" factor_y="1" /&gt;
</literallayout>
<para>
Of course now, you do not need to specify a (static) x- and y-position and also, you don't have to specify a (static)
image. After all, the teleporter now is a moving object, that may change it's position and appearance.
</para>
<para>
Note: You may of course mix "normal" and "moving" teleporters in the teleporters' section.
</para>
<para>
Next, the teleporter needs to be tied to a moving object. You do this simply by declaring an object to be of class
"teleporter" and having the same idenification label you used when defining the teleporter:
</para>
<literallayout class="monospaced">
		&lt;object class="teleporter" frames="5" file_pattern="some_object%1.png"
				z="90" anim_frame_period="50" looping="yes" ident="tp1" &gt;
			&lt;path x="100" y="100" time="500" accel="linear" /&gt;
			...
		&lt;/object&gt;
</literallayout>
<para>
Everything else works the usual way. So, to sum it up, you define the parameters specific to a teleporter in the
teleporters' section and those specific to a moving object in the object's section, then you tie both sections together
with the "ident"-paramenter.
</para>
<para>
Note: The one thing that is different is, that x- and y-position-parameters for a (normal) static teleporter are
interpreted to be the center of the image, objects' positions always refer to the top-left corner of the image!
</para>
<para>
For moving platforms and centers of gravity, the procedure is basically the same. What is left to be said is that objects
tied to centers of gravity may either be defined with class="harmful center" or class="harmless center". Obviously, the
two differ in whether the taxi can crash into them. Also obviously, the x- and y-position-parameters (in the definition
of the center of gravity) are not interpreted for moving centers.
</para>
<para>
Moving platforms still take the "x1", "x2", "passenger_base_x" and "y"-paramenters. For moving platforms, those
parameters are interpreted as relative to the top left of the image of the platform. The belonging moving object has to
be classified as class="platform".
</para>
<para>
Finally, it needs to be said, that the "tying up" of platforms/teleporters/centers of gravity with moving objects fails, the
object does not have the same "ident"-parameter, or if it is not classified appopriately. You can only ever tie up one
of these functions with a single moving object, and you cannot tie several moving objects to one function.
</para>
<para>
As always, having a look at the configuration-files provided might help understanding the procedure.
</para>
</sect2>
<sect2 id="events">
<title>Advanced level programming: Events and States</title>
<para>
An arcade game of this sort, without doors and switches? Of course not! Version 0.7.0 introduces a framework
for creating doors and switches and eventually many other things. Not everything that this framework allows for
has been implemented yet, but new features are soon to follow.
</para>
<para>
Let me start by giving you a general overview of "events" and "states": A "state" is basically a variable which may
either be on or off. E.g. you might have a state labled "door_open", which may either be on or off, and of course a
door (a moving object) which will act according to this state (how to accomplish this will be described some paragraphs
below).</para>
<para>
The whole thing would of course be pointless, if the "door_open"-state would never change. Changing states is
accomplished by events. Think of events as actions, which may be triggered when something happens. As of
version 0.7.0, there is only one sort of objects, the "hot_area", which can fire events, but eventually platforms will
be able to trigger events, when you land on them, when a passenger appears on them, teleporters, when you
arrive at them...
</para>
<para>
So actually, opening a door is not all that easy to do: You need a moving object, that depends on a state, a state,
which it depends on, an event, that changes the state and finally something to trigger the event. This framework
does however allow for a maximum of flexibility. Let's have a more detailed look:
</para>
<sect3 id="state_syntax">
<title>Syntax of "States"</title>
<para>
The syntax for declaring a state is relatively straightforward. All state-declarations are grouped together in a
"states"-tag and individual "states" are given a label ("ident") and initial value ("initial"):
</para>
<literallayout class="monospaced">
	&lt;states&gt;
		&lt;state ident="door_open" initial="off"/&gt;
		&lt;state ident="some_other_state" initial="on"/&gt;
	&lt;/states&gt;
</literallayout>
</sect3>
<sect3 id="event_syntax">
<title>Syntax of "Events"</title>
<para>
Similarily events are grouped in an "events"-tag and of course also need a label. Events, generally, also change some
state(s), which is accomplished via a "change"-tag:
</para>
<literallayout class="monospaced">
	&lt;events&gt;
		&lt;event ident="toggle_door"&gt;
			&lt;change state="door_open" to="toggle"/&gt;
		&lt;/event&gt;
	&lt;/events&gt;
</literallayout>
<para>
What happens in this example is, that the event, when triggered, changes the state "door_open" to is opposite
value, i.e. to "on" when it was "off" and vice versa. Of course you may also specify to="on" (or to="off"), if you
want your event to only open (close) the door.
</para>
<para>
This, however, isn't all there is to events. You may make the execution of your event depend on a condition. E.g.
you might have a state "door_can_be_opened", which is to control, whether your "toggle_door"-event takes any
effect. In the following example, if "door_can_be_opened" is "off", and the event "toggle_door" is triggered,
nothing wil happen, because the condition is not met:
</para>
<literallayout class="monospaced">
		&lt;event ident="toggle_door"&gt;
			&lt;condition&gt;
				&lt;requires state="door_can_be_opened" to_be="on"/&gt;
			&lt;/condition&gt;
			&lt;change state="door_open" to="toggle"/&gt;
		&lt;/event&gt;
</literallayout>
<para>
The "condition"-syntax is described in more detail, below. There may be only one condition-tag per event, but it
may involve several states.
</para>
<para>
Another thing, that can be done in events is to trigger some further events. E.g. you could have two doors, A and B,
and you want door B to get shut, whenever door A gets opened, but not necessarily the other way around.
You could accomplish this using the following two events:
</para>
<literallayout class="monospaced">
	&lt;events&gt;
		&lt;event ident="open_door_a"&gt;
			&lt;change state="door_a_open" to="on"/&gt;
			&lt;child_event ident="close_door_b"/&gt;
		&lt;/event&gt;
		&lt;event ident="close_door_b"&gt;
			&lt;change state="door_b_open" to="off"/&gt;
		&lt;/event&gt;
	&lt;/events&gt;
</literallayout>
<para>
What's left to say is that each event may have only one condition-tag and any number of "change"- and
"child_event"-tags. When the event gets triggered, first the condition (if any) will be checked. If the condition
fails, nothing will happen. If the condition is fulfilled, the event will process all "change"-tags in the order they
are specified. Only after that all "child_event"s will be triggered in the order the appear in the config. Triggering
means, that the "child_events" will each be processed fully one at a time. I.e. if you have an event A with child-events
B, C and D, and C has child-event E, first A will be triggered, then B, then C, then E and only then D. (This
is just to confuse you, probably you'll never need to know about it).
</para>
<para>
Note that events perform strict checking for recursions. If an event notices, that it is called again (from some
child_event), before it has finished all its actions, it will ignore that call and output an error message. Whenever
timers do get implemented, you will however be able to have a recursion with a certain delay between each cycle.
</para>
</sect3>
<sect3 id="conditions">
<title>A closer look on conditions</title>
<para>
Conditions are not all that complicated, but since they may appear in several places, they deserve a section of their
own. A condition is really a sequence of "requires"-tags with all the specified "state"s required to be in the specified
state. All "requires"-statements have to be fulfilled at once. They therefore constitue a logical AND.
</para>
<literallayout class="monospaced">
			&lt;condition&gt;
				&lt;requires state="has_key" to_be="on"/&gt;
				&lt;requires state="can_handle_key" to_be="on"/&gt;
				&lt;requires state="key_broken" to_be="off"/&gt;
			&lt;/condition&gt;
</literallayout>
</sect3>
<sect3 id="hotarea_syntax">
<title>Hot Areas</title>
<para>
Starting with version 0.7.2 there are a number of other ways to trigger events besides "hot_areas". Those other ways will
be discussed later, since "hot_areas" probably the most important way.
Hot "area"s are
rectangular regions on the screen (invisible by themselves) which can trigger events, if the taxi touches ("touch_event",
stops to touch ("untouch_event"), enters ("enter_event") or leaves ("leave_event") this region. Note that hot-areas
currently don't perform an exact check for these events, i.e. do no real collision-detection, but merely check, whether
the bounding-rectangle of the taxi-sprite touches, enters, ... the area. I believe this is a reasonable compromise
with performance. One helpful thing when creating levels with  hot-areas is the commandline-option --highlight,
which not only hightlights the platforms as mentioned above, but also oultines the hot_areas, so you can see, whether
they are positioned correctly.
</para>
<para>
The following example should illustrate the syntax. Note that all hot-areas in a level are grouped in a single
"hot_areas"-tag (analogous to events and states).
</para>
<literallayout class="monospaced">
	&lt;hot_areas&gt;
		&lt;area x1="558" x2="640" y1="0" y2="68" enter_event="unlock"/&gt;
		&lt;area x1="0" x2="78" y1="320" y2="340" touch_event="toggle_left_door" untouch_event="toggle_left_door"/&gt;
		&lt;area x1="0" x2="78" y1="354" y2="375" leave_event="close_all_doors"/&gt;
	&lt;hot_areas&gt;
</literallayout>
</sect3>
<sect3 id="mo_actions">
<title>Conditional behavior in Moving Objects</title>
<para>
So far events and states have remained dry theory, wth no visible results. The ultimate purpose of "states" is of course
that they affect the behavior of objects in the game. Moving Objects are the first kind of objects that can have
conditional behavior. You can add special actions to each path-segment, that will be processed at the end of that
path-segment. Lets have a look at a concrete example:
</para>
<literallayout class="monospaced">
		&lt;object frames="1" file_pattern="objects/door.png" class="harmful" z="1" looping ="true"&gt;
			&lt;path x="84" y="343" time="500" accel="abrupt"/&gt;
			&lt;path x="0" y="343" time="50" accel="abrupt"&gt;
				&lt;stop&gt;
					&lt;condition&gt;
						&lt;requires state="door_open" to_be="off"/&gt;
					&lt;/condition&gt;
				&lt;/stop&gt;
			&lt;/path&gt;
			&lt;path x="0" y="343" time="500" accel="abrupt"/&gt;
			&lt;path x="84" y="343" time="50" accel="abrupt"&gt;
				&lt;stop&gt;
					&lt;condition&gt;
						&lt;requires state="door_open" to_be="on"/&gt;
					&lt;/condition&gt;
				&lt;/stop&gt;
			&lt;/path&gt;
		&lt;/object&gt;
</literallayout>
<para>
What this example is meant to accomplish is to have a door that will be in x-position 0 when the state "door_open"
is "off", and in position 84 when the state is "on". In the example, the door will start out opened (at x 84) and
move to closed from the first to the second-path-segment. Next, it will move all the way of the second path-segment,
which actually simply tells the door to remain in place for a brief period of time. At the end of the second
path-segment, however a "stop" is to be processed. This "stop" tells the object to simply wait without moving
as long as the given condition is fullfilled, i.e. as long as "door_open" is "off".
</para>
<para>
If "door_open" happens to be "on" when the object finishes the path-segment, it simply moves on to the next
segment, like it normally would. If "door_open" is "off" however, it will not continue to move until "door_open"
changes to "on". It is important to understand, that the object will only ever stop at the end of a path-segment,
never in between.
</para>
<para>
There are three more tag besides "stop" that version 0.7.2 supports: "freeze", "trigger" and "jump".
"freeze" is used in exactly the same way as "stop" and does almost exactly the same thing (stop the object),
but also stops any animation the object might have. "trigger" and "jump" will be discussed below.
</para>
<para>
A few things remain to be said about conditional movements. First, you may have wondered, why I specified
four path-segments for really only two positions. The reason is that at the end of a path-segment, the object is
generally some way before reaching it's target position. The next key-position will only be reached at the start of
the new path-segment. Therefore, if you want very exact control over where the object stops, you should insert
"dummy-path-segments", where no movement occurs. Second, you should note, that the "linear"-accel mode does
not work as might be expected over a "stop". Rather, the object will come to an abrupt halt if it is to stop, and
when released, starts with the speed it would have had, if there had been no "stop"-tag in between. This is
because the movement-velocities are calculated beforehand, not during the game. Therefore, you should make sure
not to introduce stops at points where the object would normally be moving very fast - that would simply look
awkward. "jump"s, discussed below give you a neat way to circumvent this limitation.
</para>
<para>
The syntax for "jump"s is basically the same as for "stop"s:
</para>
<literallayout class="monospaced">
			&lt;path x="0" y="343" time="50" accel="abrupt"&gt;
				&lt;jump target="5"&gt;
					&lt;condition&gt;
						&lt;requires state="go_somewhere" to_be="on"/&gt;
					&lt;/condition&gt;
				&lt;/stop&gt;
			&lt;/path&gt;
			...
</literallayout>
<para>
What a "jump" does, is that - if the condition is met - the object will continue it's movement at the specified "target". Target
is the number of a path-segment for this object (path-segments are counted starting with 1). So in the above example, if
the state "go_somewhere" is "on", instead of proceeding to the next path-segment, the object will continue it's movement
at the fifth path-segment. Any further actions like "stop"s or other "jump"s that follow the "jump"-tag will be ignored, if the
jump-condition is met. If it is not met, the "jump"-tag will simply be ignored.</para>
<para>
It might not be easy to understand the "jump"-tag, but it is indeed very powerful, giving you the option of not only
stopping an object, but making it move entirely differently. If you are familiar with a programming language that has
GOTO-statements, it will probably help, thinking of "jump"s as GOTO-statements.
</para>
<para>
Two things remain to the said about jumps. First, &kappname; will not take them into account when doing path-calculations
(when putting meaning to accel="linear" or accel="abrupt"), and instead calculate acceleration-rates as though the
path would continue normally. In many situations it will therefore be adviseable to use accel="custom" for best results.
</para>
<para>
Second, when using "bouncing" objects, there will internally be twice as many path-segments than you specified (for the
way back). You are allowed to address those in the "target"-attribute, making your object jump to a position on the way back.
E.g. you might have an object going for A to B (path-segment 1) to C (2) to D (3) to E (4), then bouncing back to
D (internal segment 5) to C (6) to B (7) to A (8). Now you could insert a jump between after 2 (when the object has arrived at C) with
target="7". Then if the jump-condition is met, the object will jump to the path-segment taking it back form C to B, i.e.
effectively return back before going to E.
</para>
<para>
Finally the "trigger"-action can be used to trigger an event, when the object arrives at a certain key-posiiton:
</para>
<literallayout class="monospaced">
			&lt;path x="0" y="343" time="50" accel="abrupt"&gt;
				&lt;trigger event="do_something"&gt;
					&lt;condition&gt;
						&lt;requires state="inform" to_be="on"/&gt;
					&lt;/condition&gt;
				&lt;/stop&gt;
			&lt;/path&gt;
			...
</literallayout>
<para>
Here, after teh object finishes the path-segment, the event "do_something" will be triggered. This might be useful for
syncing the movement of several objects. As with all other types of actions, the "condition"-tag is mandatory.
</para>
<para>
As always, having a look at the level-files in the distribution might be more instructive than this document. Go
ahead and try, e-mail me, if you experience problems or find bugs!
</para>
</sect3>
<sect3 id="further_events">
<title>Further ways to trigger events</title>
<para>
Version 0.7.2 of &kappname; introduced a number of additional ways of firing events.
</para>
<sect4>
<title>Platforms</title>
<para>
Platforms may single four different events: (1) The taxis has landed on the platform (2) the taxis has taken off (3) a
passenger appeared on the platform (3) a passenger has left the platform. Using these events is really rather
straight-forward:
</para>
<literallayout class="monospaced">
	&lt;platforms&gt;
		&lt;data y="100" passengers="yes" has_fuel="no" x1="100" passenger_base_x="110" x2="140" label="Special platform"
				land_event="do_something" take_off_event="do_something_else"
				arrive_event="yet_another_event" leave_event="and_another_one" /&gt;
		...
	&lt;/platforms&gt;
</literallayout>
<para>
So this platform would fire four different events in the four above-mentioned cases.
</para>
</sect4>
<sect4>
<title>Teleporters</title>
<para>
Teleporters can trigger event, when (1) the taxi gets teleported away from this teleporter and (2) the taxi gets teleported
to this teleporter:
</para>
<literallayout class="monospaced">
	&lt;teleporters&gt;
		&lt;data x="461" y="273" destination="2" fare="0" factor_x="0" factor_y="0" image="teleporter.png"
				arrive_event="open_door" leave_event="close_door" /&gt;
		...
	&lt;teleporters&gt;
</literallayout>
</sect4>
<sect4>
<title>Timers: Delayed events</title>
<para>
Timers essentially behave like events and are defined and used in much the same way. The difference being that when triggered,
the timer will not immediately do it's stuff (checking it's condition, then changing states and firing child-events), but rather
wait for a specified period of time before doing so. Let's have a look at the definition of a timer:
</para>
<literallayout class="monospaced">
	&lt;timers&gt;
		&lt;timer ident="timer1" period="500" triggered_while_active="restart" loop_state="some_state" trigger_initially="true" &gt;
			&lt;condition&gt;
				&lt;requires state="door_can_be_opened" to_be="on"/&gt;
			&lt;/condition&gt;
			&lt;change state="door_open" to="toggle"/&gt;
			&lt;child_event ident="some_event_or_timer"/&gt;
		&lt;/timer&gt;
	&lt;/timers&gt;
</literallayout>
<para>
So first of all, you should note, that a timer takes all the attributes and tags that a normal event does. In fact it internally
is an event, and whereever you are allowed to specify an event to be triggered, you could specify a timer in exactly
the same way. The additional parameters for a timer are:
</para>
<para>
"period": The duration of the delay in msecs.
</para>
<para>
"triggered_while_active": Specifies, what will happen, when the timer is triggered, while it is already actively counting
down. Possible values are (1) "ignore" (default), the timer will simply ignore the triggering and continue counting down
(2) "restart", the timer will start over with the count-down (3) "stop", the timer will be stopped.
</para>
<para>
"loop_state": Here you may specify the name of a state, that controls, whether the timer behaves as a single-shot-timer,
i.e. stops after it has finished it's countdown and done its actions or whether the timer starts over automatically. The default
is to behave as a single-shot-timer, but if you specify a valid state, each time the timer finishes it's countdown, it will
check the specified state and restart itself if the state is set to "on".
</para>
<para>
"trigger_initially": Controls, whether the timer will be triggered initially (when the level is started). Default is false/no.
</para>
</sect4>
</sect3>
<sect3 id="further_states">
<title>Further ways to use states</title>
<para>
Besides affecting the movement of moving objects, states may control a few other things:
</para>
<sect4>
<title>Teleporters</title>
<para>
States can be used to (de)activate teleporters, i.e. to control (1) whether the teleporter will take the taxi anywhere and
(2), whether a taxi can be teleported to the teleporter:
</para>
<literallayout class="monospaced">
	&lt;teleporters&gt;
		&lt;data x="461" y="273" destination="2" fare="0" factor_x="0" factor_y="0" image="teleporter.png"
				arrive_state="state1" leave_state="state2" /&gt;
		...
	&lt;teleporters&gt;
</literallayout>
<para>
So, if "state1" is "off", you can not teleport to this teleporter, i.e. all teleporters that have this teleporter a their destination
will be blocked. If "state2" is "off", the teleporter itself is blocked, i.e. will not take you anywhere (but depending on "state1"
you can still arrive on it).
</para>
</sect4>
<sect4>
<title>Centers of Gravity</title>
<para>
The attribute "active_state" allows you to specify a state that controls, whether the center-of-gravity is active (i.e.
attracting or pushing away the taxi). This way, you can turn on and off centers-of-gravity:
</para>
<literallayout class="monospaced">
	&lt;gravity&gt;
		&lt;data x="320" y="240" gravity="200" potential="2" active_state="has_gravity"/&lt;
		...
	&lt;/gravity&gt;
</literallayout>
</sect4>
</sect3>
</sect2>
</sect1>

</chapter>

<chapter id="translating">
<title>How to translate &kappname;</title>
<para>Translating the actual application should not be different from compiling any other application. However, since
all the levels are defined in seperate file that are read at runtime (and may contain language-specific strings), you
should provide translations for the strings in those files, too. Here's how to do so (version 0.7.1 and above):</para>
<para>Somewhere in cdp.cpp there is an i18n()ed string "en_US", that you will have "translate" to your language code
(e.g. "fi" or "de"). Now, whenever &kappname; starts parsing a configuration file, it will try to find a translations-file with
the language code as a filename-extension. I.e. when &kappname; reads the file "level1.level", and your language code
is "fr" it will look for a file called "level1.level.fr" (in the same directory). If it doesn't find this file, all strings in "level1.level"
will be used untranslated.</para>
<para>If &kappname; does find the translations file, it expects it to look like this:</para>
<literallayout class="monospaced">
some string to be translated:::::translated version of the string
another string that should be translated:::::translation for that one
...
</literallayout>
<para>
I.e. you simply list those strings that should be translated, five colons and then the translated version. Order of the
strings is irrelevant, but be sure to copy the left-hand-side (i.e. the not yet translated strings) exactly as they are, since
otherwise &kappname; will not be able to match them to their translations. There is no need to translate strings, that
are not shown to the user, or are the same in your language. If the translations-file does not contain a certain string
of the configuration-file on the left-hand-side, the string will be used untranslated.
</para>
<para>
Although this is not exactly good style, there are a number of images that contain language-specific information
(i.e. strings that are realized as graphics). Although of course, it's a lot harder to translate those, you can do so, by
simply "translating" the filename of the image. I.e if the file "levelx.png" contains text, you could edit that image,
save it as "levelx.fr.png" (leave the extension ".png" untouched!) and add a line
</para>
<literallayout class="monospaced">
levelx.png:::::levelx.fr.png
</literallayout>
<para>
in the translations-file.
</para>
<para>
When done, you should test your translations, and especially have &kappname; parse all config-file thoroughly, to
make sure you did not break anything (command-line option --thorough_check). In case you get unexpected results,
try the command-line option --debug-level 4 , which will generate a lot of output, among other things listing all the
strings &kappname; translated (or failed to find a translation for). A basic understanding of &kappname;s configuration
files (see previous chapter) will probably help in deciding, which strings should be translated and which should not.
</para>
</chapter>

<chapter id="faq">
<title>Questions and Answers</title>

&reporting.bugs;
&updating.documentation;

<qandaset id="faqlist">

<qandaentry>
<question>
<para>Why aren't there any questions in this faq?</para>
</question>
<answer>
<para>'Cause I haven't yet been asked any. Go ahead and contact me in person.</para>
</answer>
</qandaentry>

</qandaset>
</chapter>

<chapter id="credits">

<!-- Include credits for the programmers, documentation writers, and
contributors here. The license for your software should then be included below
the credits with a reference to the appropriate license file included in the KDE
distribution. -->

<title>Credits and License</title>

<para>
&kappname;
</para>
<para>
Program copyright 2001, 2002 Thomas Friedrichsmeier <email>thomas.friedrichsmeier@ruhr-uni-bochum.de</email>
</para>
<para>
Documentation copyright 2001, 2002 Thomas Friedrichsmeier <email>thomas.friedrichsmeier@ruhr-uni-bochum.de</email>
</para>
<para>
</para>

&underFDL;               <!-- FDL: do not remove -->


&underGPL;        	 <!-- GPL License -->
</chapter>

<appendix id="programmers">
<title>A note to anybody who read the code</title>
<para>
This is my first KDE-App. As a matter of fact, it is my first C++ or even object-oriented program.
Actually it is my first program to ever really see the light of the world (although some small programs
and scripts do good deeds in their niches).</para><para>
So if you look at the code, there's probably a whole lot of silly things in there, not to mention, that
the documentation could be better. Please don't blame me for it - give me a hand, show me how to do it
right. I'd really appreciate your comments.</para><para>
Some three months after I wrote the above two paragraphs, I might add that as the code keeps growing,
inconsistencies keep creeping into the API. Also, while I trie to documentate each new function I create, I'm afraid
some functions have changed in lots of little ways, without the API-documentation reflecting those changes.
I've even been playing with the thought of rewriting some classes entirely. But then, if I had that time...
</para>
</appendix>

<appendix id="acknowledgments">
<title>Acknowledgments</title>
<para>
I'd like to thank:
</para>
<para>
- Josef Spillner for several helpful comments and suggestions
</para>
<para>
- Stefan Bruens for a number of bug-reports and useful suggestions, and for being the first person to contribute a level
</para>
</appendix>

&documentation.index;
</book>
<!--
Local Variables:
mode: sgml
sgml-minimize-attributes: nil
sgml-general-insert-case: lower
End:
-->

