Index: branches/heathaze/AUTHORS
===================================================================
--- branches/heathaze/AUTHORS	(revision 9940)
+++ branches/heathaze/AUTHORS	(revision 9940)
@@ -0,0 +1,24 @@
+orxonox-crew: <orxonox-dev@mail.datacore.ch>
+
+------------
+Maintainers:
+------------
+Patrick Boenzli <patrick@orxonox.ethz.ch>
+Benjamin Grauer <bensch@orxonox.ethz.ch>
+
+------------------
+Developers/Coders:
+------------------
+Adrian Buerli
+Andreas Maechler
+Benjamin Knecht
+Benjamin Wuest
+Christian Meyer
+Christoph Renner
+Claudio Botta
+David Gruetter
+David Hasenfratz
+Johannes Bader
+Silvan Nellen
+Simon Hofmann
+Stefan Lienhard
Index: branches/heathaze/CODING-STANDARDS
===================================================================
--- branches/heathaze/CODING-STANDARDS	(revision 9940)
+++ branches/heathaze/CODING-STANDARDS	(revision 9940)
@@ -0,0 +1,188 @@
+CODING-STANDARTS FOR ORXONOX
+-==============--==---+++++-
+In this file it is described how a orxonox-developer should structure his code.
+Every developer has to read it and follow the rules, and orxonox will grow.
+
+Contents:
+---------
+1.Coding Conventions
+2.How to format your Code
+3.Example
+
+1.Coding Conventions
+====================
+==> If you are beginning a new code-file: copy the proto_class.{cc,h}
+==> and work with these files.
+
+1.1.What has to be there:
+-------------------------
+  a) in every code file, there must be a GNU copyright header.
+
+  b) under the (c) header write your name as main-programmer, if
+     you are just bugfixing or extending write it under co-programmer.
+
+  c) Every element of the code must be documented with doxygen-tags (see 1.2).
+
+1.2.Doxygen Tags:
+-----------------
+Doxygen tags in general are comments inside a file, that look just a bit different.
+most of the time they extend the /* or // with a second star or a !
+
+  a) h-files:
+   1) every h-file you want to be documented you have to tag. (tag looks like /*! \file somefile */ )
+   2) every class has to be Documented. ( //! what it does)
+   3) special variables can be documented. ( //!< wow this member is cool because )
+
+  b) cc-files:
+   1) all the methods must be documented, and all their parameters and return value must be covered.
+
+  c) look out for this: Doxygen parses preprocessor arguments,
+     so if some comments is excluded by a #ifdef, #endif
+     doxygen will not parse it. And ther will be nothing in the docu.
+
+
+2.How to format your Code
+=========================
+We use the GNU conding convention (which is also used in xemacs etc.):
+
+-- Put a space after every comma.
+-- Put a space before the parenthesis that begins a function call,
+   macro call, function declaration or definition, or control
+   statement (if, while, switch, for). (DO NOT do this for macro
+   definitions; this is invalid preprocessor syntax.)
+-- The brace that begins a control statement (if, while, for, switch,
+   do) or a function definition should go on a line by itself.
+-- In function definitions, put the return type and all other
+   qualifiers on a line before the function name.  Thus, the function
+   name is always at the beginning of a line.
+-- Indentation level is two spaces.  (However, the first and following
+   statements of a while/for/if/etc. block are indented four spaces
+   from the while/for/if keyword.  The opening and closing braces are
+   indented two spaces.)
+-- Variable and function names should be all lowercase, with underscores
+   separating words, except for a prefixing tag, which may be in
+   uppercase.  Do not use the mixed-case convention (e.g.
+   SetVariableToValue ()) and *especially* do not use Microsoft
+   Hungarian notation (char **rgszRedundantTag).
+-- preprocessor and enum constants should be all uppercase, and should
+   be prefixed with a tag that groups related constants together.
+
+
+
+
+3.Example
+=========
+3.1.Header
+----------
+A standard header has the same name as the Class it handles.
+
+someclass.h
+-----------
+/*!
+ * @file someclass.h
+ * @brief Some short description of the someclass
+ * @todo maybe there remains something to do in this entire file
+ *
+ * Here comes a longer description
+ * this can also be longer than one line
+ */
+
+#ifndef _SOMECLASS_H
+#define _SOMECLASS_H
+
+#include "project_headers"
+#include <many_external_headers>
+
+//! short description of the class
+/**
+ * @todo what remains to be done here
+ *
+ * longer description
+ */
+class SomeClass
+{
+  public: /* functions */
+   SomeClass();
+   ~SomeClass();
+
+   int mightyFunction(const std::string& name, int value);
+
+  private: /* functions */
+   void recompileInternalState();
+
+  protected: /* variables */
+    std::string someOtherMember; //!< some member, that can be touched by derived classes.
+
+  private: /* variables */
+   int usefullVariable;    //!< Usefull because
+   int coolVariable;       //!< this variable is cool, because...
+
+
+};
+
+#endif /* _SOMECLASS_H */
+
+
+
+3.2.CC-Files
+------------
+CC-files must be named the same as the .h-files they belong to.
+
+someclass.cc
+------------
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: The Name of the author
+   co-programmer: ...
+*/
+
+#include "someclass.h"
+
+
+/**
+ * @brief <a brief description>
+ * @todo I think you get it.
+ *
+ * <more description>
+ */
+SomeClass::SomeClass (void)
+{
+   //constructor-stuff
+}
+
+/**
+ * @brief <a brief description>
+ * @todo if something is not destructed it will be here
+ *
+ * <more description>
+*/
+~SomeClass::~SomeClass (void)
+{
+  //destroy all te allocated space of the Class
+}
+
+/**
+ * @brief <a brief description>
+ * @param name <what is this parameter for>
+ * @param valuse <what for...>
+ * @returns <what it returns>
+ *
+ *  <more description>
+ */
+int SomeClass::mightyFuncion (const std::string& name, int value)
+{
+  this->coolVariable = value;
+  // and so on.....
+}
+
+// ... i think you get it :)
Index: branches/heathaze/COPYING
===================================================================
--- branches/heathaze/COPYING	(revision 9940)
+++ branches/heathaze/COPYING	(revision 9940)
@@ -0,0 +1,340 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: branches/heathaze/ChangeLog
===================================================================
--- branches/heathaze/ChangeLog	(revision 9940)
+++ branches/heathaze/ChangeLog	(revision 9940)
@@ -0,0 +1,246 @@
+2006-09-22	Benjamin Grauer <bensch@orxonox.net>
+	Complete reimplementation of the ResourceManager.
+	Now all resourceable Classes have a SubClass, that handles via Resources.
+	The approach is scaleable and modular, and conforms with shared libraries.
+
+2006-09-16	Benjamin Grauer <bensch@orxonox.net>
+	Total templated and typesafe approach to the Executor paradigm.
+	Now there is only one implementation of the Executor-construct,
+	and all special types of executors (e.g SubString, lua_State*)
+	are created via Explicit Specialization and an Evaluater.
+
+2006-09-01	Benjamin Grauer <bensch@orxonox.net>
+	Reimplementation of the ObjectList Class
+	Removed old constructs
+	Waiting for adaptions in Network and CollisionReaction
+
+2006-07-21	Benjamin Grauer <bensch@orxonox.net>
+	New implementation of the signal/slot paradigm
+	For this the nice implementation sigslot from Sarah Thompson was adapted.
+	Also adopted the GL-Gui callback.
+	One other thing done was the switch from const char* to const std::string&
+	 in the return value from BaseObject::getName and BaseObject::getClassName.
+	Also removed GTK completely (man i am happy about this one :) )
+
+2006-08-04      Patrick Boenzli <patrick@orxonox.net>
+	Proxy Server topology for the Multi-player game.
+	Now it is possible to play with millions of Players in one World.
+
+2006-07-21	orxonox <info@orxonox.net>
+	All implementations from the PPS-team in the Summer-semester integrated:
+	 Network (update) [Christoph Renner]
+	 Weather engine [David Hasenfratz, Andreas Maechler]
+	 Water with a very nice shader implementation. [Stefan Lienhard]
+	 Scripting Engine (LUA-interface) [Silvan Nellen]
+	 Story book (mostly within of the WIKI) [Benjamin Knecht]
+	 Binary Space Partitioning [Claudio Botta]
+
+2006-06-10	Benjamin Grauer <bensch@orxonox.net>
+	Introduced new GL-style Gui
+
+2006-05-19	Benjamin Grauer <bensch@orxonox.net>
+	New Design of the Executor (constant instead of linear time)
+
+2006-05-18	Patrick Boenzli <patrick@orxonox.net>
+	Total redesign of the Collision-Detection Engine.
+
+2006-05-17      Benjamin Grauer <bensch@orxonox.net>
+	Introduced new QT-style Gui.
+
+2006-03-12	orxonox <info@orxonox.net>
+	Mayor switch to std::string (almost complete)
+	All implementations from the PPS-team integrated:
+	 Network
+	 MoviePlayer
+	 HeightMap
+	 New SpaceShip Helicopter and Hover
+	 PowerUps
+	 Water
+	 many many more...
+
+2005-12-10	Benjamin Grauer <bensch@orxonox.net>
+	Implemented LOD (level of detail)
+	Implemented it through loading of Objects
+
+
+2005-11-20      Benjamin Grauer <bensch@orxonox.net>
+        Implemented a new Class: Executor
+        This is an abstract Superclass, that is able to execute any function with parameters.
+        Used it in LoadParam and ShellCommand so far.
+
+2005-09-24      Benjamin Grauer <bensch@orxonox.net>
+        Finished implementing the Shell.
+
+2005-09-20      orxonox <info@orxonox.net>
+        Begin of Valgrind cleanup.
+
+2005-08-16      orxonox <info@orxonox.net>
+        Realesed 0.3.1_alpha, on the grounds of collision detection
+        Working on a Windows-Realease...
+
+2005-08-16      Patrick Boenzli <boenzli@orxonox.net>
+        Integrated the collision detection into the orxonox framework. It
+        bases on object-oriented-bounding boxes. The tree is spawned out of
+        any polygon soup.
+
+2005-08-15      Benjamin Grauer <bensch@orxonox.net>
+        Reimplemented the IniParser.
+        Now it is possible, to read and write with it, in an easy c++ style.
+        Performance update due to preparsing.
+
+2005-08-14      Benjamin Grauer <bensch@orxonox.net>
+        Enhanced PNode, SmoothPNode, softReparenting, better display.
+        Major Speed-update to Vector and Quaternion.
+
+2005-07-23      Benjamin Grauer <bensch@orxonox.net>
+        Reimplemeted the ObjectManager, and the GarbageCollector.
+        Features:
+        modularity: easily adding new Creatable Classes through
+        the Factory-style.
+        Faster algorithm in the GarbageCollector, that only checks collectables.
+
+2005-07-23      Patrick Boenzli <boenzli@orxonox.net>
+        Implemented a spatial separation algorithm that separates any polygon
+        soup into a quadtree. The tree leafs are hold in a hash table for
+        fast lookup.
+
+2005-07-14      Benjamin Grauer <bensch@orxonox.net>
+        Implementd Render2D and Element2D, that handles 2D-shapes overlay
+        This is a new Engine, enabling us to render to layers.
+
+2005-07-01      Benjamin Grauer <bensch@orxonox.net>
+        Implemented ClassList.h:
+        an interface to BaseObject saving all instances in Lists.
+        It also enables loadability-identifiers.
+        To decide is, if this approach is fast enough.
+
+2005-06-20      Patrick Boenzli <patrick@orxonox.net>
+        Implemented an OBB collision detection system, injected into the
+        WorldEntity framework. Object - Object Collision Detection works
+        fine. Still work on the Object - Ground CD.
+
+2005-06-10      Benjamin Grauer <bensch@orxonox.net>
+        Established a try on class-derivation and isA function.
+
+2005-06-09      orxonox <info@orxonox.net>
+        created new Tag 0.3.0-pre-alpha
+
+2005-06-04      Benjamin Grauer <bensch@orxonox.net>
+        Merged the SoundEngine (openAL-version) into the trunk
+        this is one of the major steps up to version 0.3-pre-alpha
+
+2005-06-03      Benjamin Grauer <bensch@orxonox.net>
+        Implemented cycling loading procedures used for
+        the TrackManager and Animations
+
+2005-06-01      orxonox <info@orxonox.net>
+        serious cleanup of most files
+        design and doxygen tags
+        deleted old unused fucntions
+
+2005-05-30      Patrick Boenzli <patrick@oroxnox.ethz.ch>
+        Implemented new EventSystem for orxonox
+        Highly advanced, and much faster.
+
+2005-05-27      Benjamin Grauer <bensch@orxonox.net>
+        Intorducing new Subprojects with a new modular framework.
+        Introducing ParticlesFun
+        Introducing new Importer (this was easy :))
+
+2005-05-10      Benjamin Grauer <bensch@orxonox.net>
+        Merged the gui into the executable
+        Windows compiles again.
+
+2005-04-27      orxonox <info@orxonox.net>
+        Tagged Version 0.2.3-pre-alpha
+
+2005-04-23      Patrick Boenzli <patrick@orxonox.net>
+        Finished most work on Animation-classes
+
+2005-04-21      Benjamin Grauer <bensch@orxonox.net>
+        Material Class update: possibility for transparency.
+
+2005-04-15      Patrick Boenzli <partick@orxonox.net>
+        Added AnimationPlayer and two animation classes.
+
+2005-04-07      Patrick Boenzli <patrick@orxonox.net>
+        Reimplemeted the Weapon and shoot-functions
+
+2005-03-31      Benjamin Grauer <bensch@orxonox.net>
+        Added Text Engine
+
+2005-03-26      Benjamin Grauer <bensch@orxonox.net>
+        Added ResourceManager
+
+2005-03-24      Patrick Boenzli <patrick@orxonox.net>
+        Reimplemented shooting.
+
+2005-03-16      orxonox <info@orxonox.net>
+        Finished work on version 0.2.1-pre-alpha released 0.2.2-pre-alpha
+
+2005-03-15      Patrick Boenzli <patrick@orxonox.net>
+        parenting finished
+
+2005-03-09      Patrick Boenzli <patrick@orxonox.net>
+        Big Cleanup again
+
+2005-03-01      Benjamin Grauer <bensch@orxonox.net>
+        Added Light Class
+
+2005-02-27      Benjamin Grauer <bensch@orxonox.net>
+        Big Configure.ac-cleanup
+
+2005-02-22      David Gruetter <davgr@gmx.ch>
+        Added Skysphere
+
+2005-01-07      Patrick Boenzli <patrick@orxonox.net>
+        LoadScreen implemented
+
+2004-12-20      Patrick Boenzli <patrick@orxonox.net>
+        New Version out 0.2.1-pre-alpha
+
+2004-12-20      Patrick Boenzli <patrick@orxonox.net>
+        HEAVY cleanup of the framework
+
+2004-12-18      Patrick Boenzli <patrick@orxonox.net>
+        enhanced the Command Node
+
+2004-12-15      Nico Benold <bernoldn@ee.ethz.ch>
+        OS X support
+
+2004-12-15      Benjamin Grauer <bensch@orxonox.net>
+        Defined standard coding rules
+
+2004-12-15      Benjamin Grauer <bensch@orxonox.net>
+        Added Importer for showing 3D Object.
+
+2004-11-07      David Gruetter <davgr@gmx.ch>
+        Shaded Terrain
+
+2004-10-23      Adrian Buerli <buerlia@ee.ethz.ch>
+        Dynamic Mountains, dynamic movement.
+
+2004-10-18      Patrick Boenzli <patrick@orxonox.net>
+        Release 0.1-pre-alpha
+
+2004-07-17      Christian Meyer <cmeyer@ee.ethz.ch>
+        SDL-Framework
+
+2004-06-09      Tom of ethz
+        Added endless Mountains
+
+2004-06-02      Benjamin Grauer <bensch@orxonox.net>
+        Added Console
+
+2004-05-20      Patrick Boenzli <patrick@orxonox.net>
+        Added the ability to shoot
+
+2004-05-05      Benjamin Grauer <bensch@orxonox.net>
+        Added the GUI.
+
+2004-04-21      Patrik Boenzli <patrick@orxonox.net>
+        Added Makefile to orxonox
+
+2004-04-25      Amir Guindehi <amir@guindehi.ch>
+        Created Project orxonox.
+        Thanks a lot. (from all the Orxonox-dev-team)
Index: branches/heathaze/IDEAS
===================================================================
--- branches/heathaze/IDEAS	(revision 9940)
+++ branches/heathaze/IDEAS	(revision 9940)
@@ -0,0 +1,9 @@
+        ====================
+        ====== IDEAS =======
+        ====================
+
+
+Please have a look at the Wiki for more information about this:
+-------------------------------------------------------
+---------      https://dev.orxonox.net      -----------
+-------------------------------------------------------
Index: branches/heathaze/INSTALL
===================================================================
--- branches/heathaze/INSTALL	(revision 9940)
+++ branches/heathaze/INSTALL	(revision 9940)
@@ -0,0 +1,280 @@
+
+INSTALLATION INSTRUCTIONS FOR ORXONOX
+=====================================
+
+INSTALLATION
+============
+
+To make it quite easy for those of you who just want to install orxonox:
+
+1. ./configure
+2. make
+3. make install
+
+(For further Information please take a look below at autoconf information)
+
+DEPENDENCIES
+============
+
+There are some dependencies for orxonox you have to install:
+
+01. SDL           (http://www.libsdl.org)
+02. OPENGL        (http://www.opengl.org)
+03. OPENAL        (http://www.openal.org)
+04. SDL_image     (http://www.libsdl.org/projects/SDL_image)
+05. SDL_ttf       (http://www.libsdl.org/projects/SDL_ttf)
+ a) needs libttf (http://www.freetype.org/)
+
+Nice to Have:
+06. Doxygen       (http://www.stack.nl/~dimitri/doxygen/)
+07. Automake      (http://www.gnu.org/software/automake/)
+08. Autoconf      (http://www.gnu.org/software/autoconf/)
+
+Windows Users also need the following:
+09. mingw         (http://mingw.org/)
+
+10. more answers to your questions can be found under section
+    wiki on our webpage http://www.orxonox.net
+
+BUGS
+====
+Send bug reports to <orxonox-dev@mail.datacore.ch>
+
+
+
+
+<-ORXONOX
+##########################################################
+                                                AUTOCONF->
+
+
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
Index: branches/heathaze/Makefile.am
===================================================================
--- branches/heathaze/Makefile.am	(revision 9940)
+++ branches/heathaze/Makefile.am	(revision 9940)
@@ -0,0 +1,33 @@
+AUTOMAKE_OPTIONS = foreign no-installman no-installinfo
+
+SUBDIRS = src
+
+EXTRA_DIST = CODING-STANDARDS \
+             IDEAS \
+             NEWS \
+             doc/CREDITS \
+             doc/doxyconf/build \
+             doc/doxyconf/confopts \
+             doc/doxyconf/input \
+             doc/doxyconf/preprocessor \
+             doc/doxyconf/progress \
+             doc/doxyconf/project
+
+## doxygen stuff
+if DOXYGEN
+DOXYGEN_INPUT = "src"
+
+## Exclude the application wizard templates, and some file templates
+DOXYGEN_EXCLUDE =
+
+DOXYGEN_EXAMPLE_PATH =
+
+## Use Search engine (Versions 1.3.4 and above only!)
+DOXYGEN_SEARCHENGINE = YES
+
+include doc/documentation.am
+endif
+
+
+version:
+	echo VERSION: $(PACKAGE_VERSION)
Index: branches/heathaze/NEWS
===================================================================
--- branches/heathaze/NEWS	(revision 9940)
+++ branches/heathaze/NEWS	(revision 9940)
@@ -0,0 +1,121 @@
+Date: September 1, 2006
+Topic: New Server Topology
+Body: Once again, all Services on Nautilus, our nice little Orxonox-Server have been updated. <br> With this we also changed some locations of the pages (old pages still valid) <br> <a href="https://dev.orxonox.net">https://dev.orxonox.net</a> : Development page.<br> <a href="http://doc.orxonox.net">http://doc.orxonox.net</a>: the mighty Orxonox Framework documentation.
+
+Date: August 31, 2006
+Topic: Orxonox PPS WS2006
+Body: We just received the permission from the ETHZ to make another of our PPS in the next semester for the students in the second year. Thanks to the the ITET departement and the secratary!
+
+Date: August 24, 2006
+Topic: Server Downtime
+Body: We had a hardware failure in our project server. After reparation and new installation almost everything is up and running again.
+
+Date: July 3, 2006
+Topic: Convention 4.
+Body: Witness the next stage in our development, join us Wednessday fifth of July in the ETH ETZ H81 for our fourth convention-session.
+
+Date: April 24, 2006
+Topic: New Forum installed
+Body: Today we added a new Forum. Here you can discuss everithing in and around orxonox. <a href="https://www.orxonox.net/forum">https://www.orxonox.net/forum</a>
+
+
+Date: May 10, 2006
+Topic: Work, work!
+Body: The time of exams is over, there is now fresh motivation after this painfull time and the will to make Orxonox rule... 
+
+Date: Feb 02, 2006
+Topic: Orxonox Convention 03 is comming in Town
+Body: We will have our next Orxonox Convention Feb 08 at the ETH: ETZ E81. For more information, visit the <a href="http://www.orxonox.net/index.php?site=conventions">link</a>.
+
+Date: Jan, 01, 2006
+Topic: Happy New Year
+Body: We from the Orxonox Team wish you all the best for the new year 2006, may the release dates for this year be true.
+
+Date: Dez 23, 2005
+Topic: Christmas
+Body: Tschingel your bells, and shoot some stuff in our new ORXONOX-CHRISTMAS-EDITION-LEVEL. All you Windows gamers find the newest Binary version <a href="http://www.orxonox.net/files/snapshots/orxonox-win32-latest.zip">here</a>. For all the others, have a good holyday, and so long. (PS: to change into the new level push 'x', and to change the vehicle push 'l' (like L))
+
+Date: Dez 17, 2005
+Topic: New Drum'n'Bass Tunes in Development
+Body: They are two men from London, and their mission is to make drum'n'bass tunes: shiv&incey! And now, they want to make some massive rolling tunes for Orxonox! Check out <a href="http://www.aurorasoftware.co.uk/s&i/shiv&incey.htm">their homepage</a>. We are looking forward to the sounds; greetings to London from Switzerland!
+
+Date: Dez 05, 2005
+Topic: Homepage Corrections
+Body: Simon did take some time to read through our webpage and corrected all the english errors he found. Thanks!
+
+Date: Okt 19, 2005
+Topic: Biggest debug session ever in orxonox
+Body: We spent a lot of time to debugging Orxonox engine. Thanks to <a href="http://www.valgrind.org">valgrind</a> :D. Orxonox now plays again on Linux, OSX and Windows!
+
+Date: Sept 05, 2005
+Topic: Integrated a expendable shell
+Body: Now orxonox has a shell, similar to the quake shell... just cooler... You can directly interface the orxonox API through the shell as described in <a href="https://www.orxonox.net/cgi-bin/trac.cgi/wiki/Shell">the ShellDocumentatioWiki</a>. And yes, we will implement our first cheats like invulnerability :D
+
+Date: Aug 14, 2005
+Topic: Implemented and finaly integrated the collision detection algorithm
+Body: This was some hard work... but it now is part of orxonox: object-object collision detection. Now is the time, to shoot other the Enemies! enjoy!
+
+Date: July 21, 2005
+Topic: new domain is registered <a href="http://www.orxonox.net">www.orxonox.net</a>
+Body: Finally we have our own domain for orxonox: <a href="http://www.orxonox.net">http://www.orxonox.net</a>
+
+Date: June 25, 2005
+Topic: orxonox development for win32-patch
+Body: Included the major libraries and tool to develop orxonox on win32 to the webdev repository. Now one might download everything from <a href="http://svn.orxonox.ethz.ch/webdev/develop/">http://svn.orxonox.ethz.ch/webdev/develop/</a>
+
+Date: June 25, 2005
+Topic: Big demo in physically-based animations
+Body: on Monday we have a big demo on orxonox's physical capabilities. We will show some major new features like the ParticleEngine, the PhysicsInterface, and last but not least the longly expected CollisionDetection. Of course all the new Features are in the new trunk, and are downloadable at the  <a href="/files/snapshots">snapshot-section</a>.
+
+Date: June 09, 2005
+Topic: tag 0.3.0-pre-alpha released
+Body: new Tag release. visit the <a href="/files/snapshots">snapshot-section</a> for more detail.
+
+Date: June 04, 2005
+Topic: SoundEngine
+Body: just merged the SoundEngine into the project. This is a major step toward a new aera, of interaction, because it really gets the player a feeling, of what is happening. check <a href="https://www.orxonox.ethz.ch/cgi-bin/trac.cgi/wiki/SoundEngine">this</a> link for a description on how to use it.
+
+Date: June 01, 2005
+Topic: New Features
+Body: Orxonox now supports the MD2Model. We have implemented a physics engine and a particle system.
+
+Date: May 28, 2005
+Topic: Webpage Update
+Body: We did remaster our webpage, take a look at the new <a href="index?site=screenShots">screenshots gallery</a> and make a <a href="index?site=voting">vote</a>.
+
+Date: March 05, 2005
+Topic: Orxonox Convention 2005
+Body: We are going to make a new Convention, that you are all invited to. Visit the convention section for more details. <A href="http://www.orxonox.ethz.ch/index.php?site=conventions">link.</A>
+
+Date: February 21, 2005
+Topic: New Webpage Release
+Body: We are proud to announce our new webpage. Thanks to nico and his php skills :)
+
+Date: December 14, 2004
+Topic: Repository Moved
+Body: Today we moved the repository. The new location of the repository is <A href="https://svn.orxonox.ethz.ch/reporx">http://svn.orxonox.ethz.ch/reporx</A>.
+
+Date:   November 16, 2004
+Topic:  Importer
+Body:   There now exists a possibility to import .obj-files (alias wavefront format) into the Game. You can find some test models here: <A href="/files/models">models</a>. You can also test them with the included importer which is locates in trunk/importer. enjoy.
+
+Date:   June 22, 2004
+Topic:  Develop on Win32 - bg
+Body:   Now the moment you have all been waiting for has arrived. Orxonox can finally be compiled on Windows machines. We know that it is no good idea to do this, but since there are some people interessted in working with Windows, we will give you a chance: read <A href = "/index.php?site=additional.sites/howto.dev.win/howto.dev.win.cc.php" >the manual </A>.
+
+Date:   June 04, 2004
+Topic:  Orxonox Convention - pb
+Body:   Here you can find all the information you need, to join us at the <A href="index.php?site=additional.sites/convention01/convention01.php"> Orxonox Convention </A>, that takes Place at Stuz June 9. 2004.
+
+Date:   June 04, 2004
+Topic:  Manual for Subversion@DataCore.ch
+Body:   A manual for <A href="/files/subversion/subversion.pdf"> Subversion at DataCore</A> is made. Now we need someone, to correct all the errors. Please someone Checkout the Source of this at http://orxonox.ethz.ch/repos/latex/subversion an do the repairs.
+
+Date:   June 02, 2004
+Topic:  New homepage released - pb
+Body:   New homepage released, thanks to the power of subversion. And thanks to the VSETH to give us webspace on their server
+
+Date:   May 26, 2004
+Topic:  New ship models - bg
+Body:   Some new space models are now ready for download. You'll find them in the download section or try it <A href="/files/orx_pictures.tar.bz2">here</A>
+
Index: branches/heathaze/README
===================================================================
--- branches/heathaze/README	(revision 9940)
+++ branches/heathaze/README	(revision 9940)
@@ -0,0 +1,135 @@
+
+This is the offical README file for the game project
+
+--------------------------------------------------------
+                       orxOnox
+--------------------------------------------------------
+
+1.Preface:
+----------
+Orxonox is a open-source vertical scroller game programed
+in c++ and OpenGL.
+If we manage to be sober enough, this game shall definitly
+become _the_ open-source vertical scroller ever.
+
+2.Manifesto:
+------------
+1) Alien is a great film
+2) Guiness is the most delicious beer
+3) If you think there is anything missing specialy in terms of story: you can be shure it's an arcade game
+4) Wanna chill: ask Boozoo Bajou
+
+to be continoued...
+
+
+3.Overview:
+---------
+1.Preface
+2.Manifesto
+3.Overview
+3.Contributing To The Project
+4.Howto C++ Programming
+5.Howto SVN
+6.Coding conventions
+
+
+4.Contributing To The project:
+------------------------------
+People who want to help us working on orxonox are always
+welcome:) Feel free to chip in anything you like. Wine, beer,
+coffee... If you like to help us programming orxonox, you:
+- join the developer community mailing lists
+- read this README file
+then you have multiple ways to get started.
+a) Read the hole source code and choose a topic you like
+b) check the TODO file to get a knowledge of what we need
+c) ask us for more information
+To get more informations about programming and project specs
+read the programming sections below.
+
+To start programming on orxonox you first have to download the
+newest svn tree of orxonox. You can do this by enterning following
+lines in the linux console (ensure svn to be installed with ssl
+support enabled):
+
+svn co https://svn.orxonox.net/reporx/orxonox orxonox
+
+If you haven't got ssl support in you svn tool, recompile it
+./configure --with-ssl
+make
+make install
+
+
+5.Howto C++ Programming:
+------------------------
+If you are new to c/c++ programming, this project is probably
+not the best starting place to learn it. For you and the rest who
+need "refreshment" check out these guides:
+
+www.cplusplus.com/doc/tutorial
+www.4p8.com/eric.brasseur/cppcen.html
+
+
+6.Howto SVN:
+------------
+For a more complete guide about this topic read the documentation
+avaiable at subversion.tigris.org.
+
+SVN (=subversion) is a version control program similar to CVS but
+newer. This program enables us to work all at the same program at
+the same time - tricky.
+
+subversion checkout https://svn.orxonox.net/reporx/orxonox orxonox
+same as: subversion co https://svn.orxonox.net.....
+
+this makes a directory orxonox at your current place in and gets
+the hole brand new source code from the server.
+
+now you can work. Remember to use 'svn copy instead of 'cp',
+'svn mv' instead of 'mv', 'svn rm' instead of 'rm'... - you got it
+I think.
+After you have made your changes to the files enter
+svn status
+or with more details: svn status -vv
+which will show you the changes you did locally on your computer.
+svn diff
+is similar but shows you all the changes in detail.
+
+svn diff > patchfile
+the patchfile you can use later in conjunction with the patch program.
+You could, for example, email this patchfile to another developer for
+review or testing prior to commit.
+
+To add a new file type
+svn add <filename>
+and to publish all your changes type
+svn commit --message "Corrected number of chees slices."
+svn commit will send all of your changs to the repository. When you
+commit a change, you need to supply a log message, describing your
+change. The message can also be read from a file:
+svn commit --file logmsg
+
+If you accidently make a change you like to revert, you just can do this
+by typing:
+svn revert <filename>
+
+To keep track about the work that is running on the project use the
+command: svn log. This will show you a bref summary of all changes.
+
+
+Most of the programmer will do their work on a branch. A Branch is
+a line of development that exists independently of another line, yet
+still shares a common history. A branch always begins life as a copy
+of something, and moves on trom there, generating its own history. Later
+the two versions will merge.
+
+If you are working on orxonox you will have your own branch in which you
+will program, some sort of sand-box. If you finish your work on your
+topic, it will be revised by us and merged with the trunk
+
+7.Coding Conventions
+--------------------
+Read the File CODING-STANDARDS
+
+
+#EOF
Index: branches/heathaze/ToDo
===================================================================
--- branches/heathaze/ToDo	(revision 9940)
+++ branches/heathaze/ToDo	(revision 9940)
@@ -0,0 +1,24 @@
+ToDo:
+-----
+There are many tasks still open in orxonox.
+
+1. TASKS
+--------
+Best idea is, to visit our Webpage at: http://www.orxonox.net and
+under the wiki link follow RoadMap, and from there on you will find many tasks
+or just use this link:
+https://www.orxonox.net/cgi-bin/trac.cgi/roadmap
+
+2. ToDo-list
+------------
+see the Doxygen documetation for a List of todo's
+or visit the Code, you have with you (or a more actual version found at
+http://svn.orxonox.net/reporx/orxonox/trunk) for all the ToDo's
+The easiest way to find ToDo's is to make the following in the trunk:
+grep @todo * -R
+
+3. FIXME
+--------
+They can be found with
+grep FIXME * -R
+in the trunk.
Index: branches/heathaze/acinclude.m4
===================================================================
--- branches/heathaze/acinclude.m4	(revision 9940)
+++ branches/heathaze/acinclude.m4	(revision 9940)
@@ -0,0 +1,354 @@
+
+
+dnl AX_CHECK_HEADER_LIB([HEADER-NAME], [LIBRARY-NAME], [FUNCTION-IN-LIB], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [LIB-WEB-PAGE])
+AC_DEFUN([AX_CHECK_HEADER_LIB], [
+    _header_check=""
+    _lib_check=""
+
+    AC_CHECK_HEADER([$1], [_header_check="yes"], [_header_check="no"])
+    AC_CHECK_LIB([$2], [$3], [_lib_check="yes"], [_lib_check="no"])
+    if [test "x$_header_check" = "xyes" && test "x$_lib_check" = "xyes"] ; then
+         LIBS="$LIBS -l$2"
+         $4
+    else
+         echo "no Support for $2"
+         $5
+    fi
+])
+
+
+
+dnl AX_CHECK_REQUIRED_HEADER_LIB([HEADER-NAME], [LIBRARY-NAME], [FUNCTION-IN-LIB], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [LIB-WEB-PAGE], [CFLAGS], [OTHER_LIBS])
+AC_DEFUN([AX_CHECK_REQUIRED_HEADER_LIB], [
+    _header_check=""
+    _lib_check=""
+    LAST_FOUND_LIB=""
+
+    _lib_USED=""
+    _header_USED=""
+
+    for _header in $1
+    do
+      AC_CHECK_HEADER([${_header}], [_header_check="yes" ; _header_USED=${_header}], [_header_check="no"], $7)
+      if  test "x${_header_check}" = "xyes" ; then
+        break
+      fi
+    done
+    for _check_library in $2
+    do
+      AC_CHECK_LIB([${_check_library}], [$3], [_lib_check="yes"; _lib_USED=${_check_library}], [_lib_check="no"], $8)
+      if test "x${_lib_check}" = "xyes" ; then
+        LAST_FOUND_LIB=${_lib_USED}
+        break
+      fi
+    done
+    if [test "x${_header_check}" = "xyes" && test "x${_lib_check}" = "xyes"] ; then
+        m4_ifval([$4], [$4], [
+         LIBS="${LIBS} -l${_lib_USED}"])
+    else
+        m4_ifval([$5], [$5], [
+         echo "------------------"
+         echo "LIBRARY $2 not found."
+         echo "please install the $2-LIBRARY-package which can be found at $6"
+         echo "------------------"
+         exit -1])
+    fi
+])
+
+
+
+dnl AX_CHECK_REQUIRED_LIB([LIBRARY-NAME], [FUNCTION-IN-LIB], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [LIB-WEB-PAGE])
+AC_DEFUN([AX_CHECK_REQUIRED_LIB], [
+    _lib_check=""
+    _found_lib=""
+
+
+    for _lib in $1
+    do
+      AC_CHECK_LIB([$_lib], [$2], [_lib_check="yes"], [_lib_check="no"])
+      if test "x$_lib_check" = "xyes" ; then
+        _found_lib=$_lib
+        break
+      fi
+    done
+
+    if [test "x$_lib_check" = "xyes"] ; then
+         LIBS="$LIBS -l$_found_lib"
+         $3
+    else
+         echo "------------------"
+         echo "LIBRARY $1 not found."
+         echo "please install the $1-LIBRARY-package which can be found at $5"
+         echo "------------------"
+         $4
+         exit -1
+    fi
+])
+
+
+
+
+dnl AX_CHECK_QT([QTDIR], [LIBRARIES], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [LIB-WEB-PAGE])
+AC_DEFUN([AX_CHECK_QT], [
+    _lib_check=""
+    _found_lib=""
+    QT_PREFIX="$1"
+    QT_INCLUDE_DIRECTORY=""
+    QT_LIB_DIRECTORY=""
+    QT_BIN_DIRECTORY=""
+
+    QT_COMMON_INCLUDE_DIRECTORIES="
+      `ls -dr ${QT_PREFIX}/include     2>/dev/null`
+      /usr/include
+      `ls -dr /usr/include/qt*         2>/dev/null`
+      `ls -dr /usr/lib/qt*/include     2>/dev/null`
+      `ls -dr /usr/local/qt*/include   2>/dev/null`
+      `ls -dr /opt/qt*/include         2>/dev/null`
+      `ls -dr /Developer/qt*/include   2>/dev/null`
+      `ls -dr /c/Qt/*/include          2>/dev/null`
+    "
+
+    QT_COMMON_LIB_DIRECTORIES="
+      `ls -dr ${QT_PREFIX}/lib         2>/dev/null`
+      /usr/lib
+      `ls -dr /usr/lib/qt*             2>/dev/null`
+      `ls -dr /usr/local/qt*/lib       2>/dev/null`
+      `ls -dr /opt/qt*/lib             2>/dev/null`
+      `ls -dr /Developer/qt*/lib       2>/dev/null`
+      `ls -dr /c/Qt/*/lib              2>/dev/null`
+    "
+
+    QT_COMMON_BIN_DIRECTORIES="
+      `ls -dr ${QT_PREFIX}/bin         2>/dev/null`
+      /usr/bin
+      `ls -dr /usr/bin/qt*             2>/dev/null`
+      `ls -dr /usr/local/qt*/bin       2>/dev/null`
+      `ls -dr /opt/qt*/bin             2>/dev/null`
+      `ls -dr /Developer/qt*/bin       2>/dev/null`
+      `ls -dr /c/Qt/*/bin              2>/dev/null`
+    "
+
+## Search in all IncludeDirectories for QT-includes
+    for _qt_include_directory in ${QT_COMMON_INCLUDE_DIRECTORIES}
+    do
+      if test -e ${_qt_include_directory}/QtCore/QCoreApplication ; then
+        QT_INCLUDE_DIRECTORY="${_qt_include_directory}"
+        break
+      fi
+    done
+    if test -n ${QT_INCLUDE_DIRECTORY} ; then
+      echo "Qt-Include Directory is: ${QT_INCLUDE_DIRECTORY}"
+    else
+      AC_MSG_ERROR([Qt Headers not found])
+    fi
+
+## Search in all LibraryDirectories for QT-includes
+    for _lib_directory in ${QT_COMMON_LIB_DIRECTORIES}
+    do
+      if test -e ${_lib_directory}/libQtCore.so || test -e ${_lib_directory}/libQtCore4.a || \
+			test -e ${_lib_directory}/QtCore.framework ; then
+        QT_LIB_DIRECTORY=${_lib_directory}
+        break
+	  fi
+    done
+    if test -n ${QT_LIB_DIRECTORY} ; then
+      echo "Qt-Library Directory is: ${QT_LIB_DIRECTORY}"
+    else
+      AC_MSG_ERROR([Qt LIB not found])
+    fi
+
+## Search in all BINDirectories for QT-executables
+    for _bin_directory in ${QT_COMMON_BIN_DIRECTORIES}
+    do
+      if test -e ${_bin_directory}/moc || test -e  ${_bin_directory}/moc.exe ; then
+        QT_BIN_DIRECTORY=${_bin_directory}
+        break
+      fi
+    done
+    if test -n ${QT_BIN_DIRECTORY} ; then
+        echo "Qt-Bin Directory is: ${QT_BIN_DIRECTORY}"
+    else
+        QT_BIN_DIRECTORY=${QT_PREFIX}/bin
+    fi
+
+## Setting up the Environment Variables.
+    QT_LIBS=""
+    QT_CXXFLAGS="-I${QT_INCLUDE_DIRECTORY}"
+    LDFLAGS="${LDFLAGS} -L${QT_LIB_DIRECTORY} -Wl,-rpath -Wl,${QT_LIB_DIRECTORY}"
+
+    CACHED_CPPFLAG=${CPPFLAGS}
+    CACHED_LDFLAGS=${LDFLAGS}
+
+    LDFLAGS="${LDFLAGS} ${QT_LDFLAGS}"
+    for _lib in $2
+    do
+      AC_CHECK_LIB([$_lib], [main], [_lib_check="yes"], [_lib_check="no"])
+      if test "x$_lib_check" = "xyes" ; then
+        _found_lib=$_lib
+        break
+      fi
+    done
+
+    if [test "x$_lib_check" = "xyes"] ; then
+         QT_LIBS="${QT_LIBS} -l$_found_lib"
+         AX_CHECK_REQUIRED_LIB([QtCore QtCore4], [main],,,[http://www.trolltech.com] )
+         AX_CHECK_REQUIRED_LIB([QtGui QtGui4], [main],,,[http://www.trolltech.com] )
+         AX_CHECK_REQUIRED_LIB([QtOpenGL QtOpenGL4], [main],,,[http://www.trolltech.com] )
+
+         $3
+    else
+         echo "------------------"
+         echo "LIBRARY $2 not found.in $1"
+         echo "please install the $1-LIBRARY-package which can be found at $5"
+         echo "------------------"
+         $4
+         exit -1
+    fi
+
+    echo "QT_LIBS          = ${QT_LIBS}"
+    echo "QT_CXXFLAGS      = ${QT_CXXFLAGS}"
+    echo "QT_LD_FLAGS      = ${QT_LDFLAGS}"
+    echo "QT_BIN_DIRECTORY = ${QT_BIN_DIRECTORY}"
+
+    AC_SUBST([QT_LIBS])
+    AC_SUBST([QT_CXXFLAGS])
+    AC_SUBST([QT_LDFLAGS])
+
+    #----------#
+    # QT - MOC #
+    #----------#
+    AC_PATH_PROGS([QT_MOC], [moc-qt4 moc], [no], ["${QT_BIN_DIRECTORY}:${PATH}"])
+      if test x${QT_MOC} = xno ; then
+         AC_MSG_ERROR([QT MOC not found])
+      fi
+    AC_SUBST([QT_MOC])
+
+    AC_PATH_PROG([QT_UIC], [uic], [no], ["${QT_BIN_DIRECTORY}:${PATH}"])
+ #     if test x${QT_UIC} = xno ; then
+ #       AC_MSG_WARN([QT UIC not found])
+ #     fi
+    AC_SUBST([QT_UIC])
+
+    AC_PATH_PROG([QT_RCC], [rcc], [no], ["${QT_BIN_DIRECTORY}:${PATH}"])
+#      if test x${QT_RCC} = xno ; then
+#        AC_MSG_WARN([QT RCC not found])
+#      fi
+    AC_SUBST([QT_RCC])
+
+
+
+    # Restore Values of CPPFLAGS and LDFLAGS
+    CPPFLAGS=${CACHED_CPPFLAG}
+    LDFLAGS=${CACHED_LDFLAGS}
+])
+
+
+
+
+
+
+dnl AX_CHECK_LUA([LUA_DIR])
+AC_DEFUN([AX_CHECK_LUA], [
+#dnl checking for LUA.
+LUA_LIBS=
+LUA_INCLUDES=
+dnl Check for Lua.
+
+LUA_INCLUDE_DIRECTORY="/usr/include"
+LUA_COMMON_INCLUDE_DIRECTORIES="
+      `ls -dr $1                       2>/dev/null`
+      /usr/include
+      `ls -dr /usr/include/lua*        2>/dev/null`
+      `ls -dr /usr/lib/lua/include     2>/dev/null`
+      `ls -dr /usr/local/include/lua   2>/dev/null`
+      `ls -dr /opt/lua*/include        2>/dev/null`
+      `ls -dr /Developer/lua*/include  2>/dev/null`
+    "
+
+  for _lua_include_directory in ${LUA_COMMON_INCLUDE_DIRECTORIES}
+    do
+      if test -e ${_lua_include_directory}/lua.h ; then
+        LUA_INCLUDE_DIRECTORY=${_lua_include_directory}
+        CPPFLAGS="${CPPFLAGS} -I${LUA_INCLUDE_DIRECTORY}"
+        break
+      fi
+  done
+    if test -n ${LUA_INCLUDE_DIRECTORY} ; then
+      echo "Lua-Include Directory is: ${LUA_INCLUDE_DIRECTORY}"
+    else
+      AC_MSG_ERROR([Lua Headers not found])
+    fi
+
+
+AC_CHECK_LIB([dl], [dlopen])
+AX_CHECK_REQUIRED_HEADER_LIB([lua.h], [lua lua50], [lua_open],
+dnl libLUA found
+     [LUA_LIBS="${LUA_LIBS} -l${LAST_FOUND_LIB}"  AX_CHECK_REQUIRED_HEADER_LIB([lualib.h], [lualib lualib50], [luaopen_base],
+dnl liblualib found
+      [LUA_LIBS="${LUA_LIBS} -l${LAST_FOUND_LIB}"], [LUA_LIBS="${LUA_LIBS} -llualib"],
+      [http://www.lua.org],, [-llua ${LUA_LIBS} -ldl -lm])],
+dnl liblua not found (download it)
+       [AX_GET_INSTALL_NECESSARY_LIB([http://switch.dl.sourceforge.net/sourceforge/gtksql], [lua-5.0.tar.gz], [lua-5.0], [extern_libs/], [include/*.h lib/*.a])
+       LUA_LIBS="-llualib -llua"  LUA_INCLUDES="-I$(top_build_dir)/extern_libs" ], [http://www.lua.org])
+
+AC_SUBST([LUA_LIBS])
+AC_SUBST([LUA_INCLUDES])
+])
+
+
+
+
+
+
+
+
+
+dnl AX_GET_INSTALL_NECESSARY_LIB([FTP-DIR], [DIST-FILE], [DIST-DIR], [INSTALL-DIR], [INSTALL-FILES], [CONFIG-FLAGS], [MAKE-OPTS])
+AC_DEFUN([AX_GET_INSTALL_NECESSARY_LIB], [
+
+   _get_install_FTP=$1
+   _get_install_DISTFILE=$2
+   _get_install_DISTDIR=$3
+   _get_install_INSTALLDIR=$4
+   dnl $5 is left out (inegrated bellow)
+   _get_install_CONFIGFLAGS=$6
+   _get_install_MAKEOPTS=$7
+
+dnl DOWNLOADING THE FILE
+   if test -f "${_get_install_DISTFILE}" ; then
+     echo "${_get_install_DISTFILE} already downloaded"
+   else
+     echo "Getting ${_get_install_DISTFILE} from ${_get_install_FTP}/${_get_install_DISTFILE}"
+     echo `wget ${_get_install_FTP}/${_get_install_DISTFILE}`
+   fi
+
+dnl UNCOMPRESS STAGE
+   echo "Uncompressing ${_get_install_DISTFILE}"
+   echo `tar xzvf ${_get_install_DISTFILE}`
+
+dnl ENTER DIRECTORY AND EXECUTE CONFIGURE AND MAKE
+   _get_install_PWD=`pwd`
+   cd ${_get_install_DISTDIR}
+dnl configure
+   if test -x "configure" ; then
+    ./configure ${_get_install_CONFIGFLAGS}
+   fi
+   make ${_get_install_MAKEOPTS}
+   cd ${_get_install_PWD}
+
+dnl INSTALL STAGE
+   echo "Installing Libraries and Headers into ${_get_install_INSTALLDIR} local directory"
+
+   mkdir -p ${_get_install_INSTALLDIR}
+   for _get_install_installfile in $5
+    do
+     echo "copy  ${_get_install_DISTDIR}/${_get_install_installfile} to ${_get_install_INSTALLDIR}/"
+     cp `ls -dr ${_get_install_DISTDIR}/${_get_install_installfile}` "${_get_install_INSTALLDIR}/"
+    done
+
+#cleaning up
+  echo "rm -rf ${_get_install_DISTDIR}"
+  rm -rf ${_get_install_DISTDIR}
+  echo "rm ${_get_install_DISTFILE}"
+  rm ${_get_install_DISTFILE}
+])
Index: branches/heathaze/autogen.sh
===================================================================
--- branches/heathaze/autogen.sh	(revision 9940)
+++ branches/heathaze/autogen.sh	(revision 9940)
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+#SETUP_GETTEXT=./setup-gettext
+
+#($SETUP_GETTEXT --gettext-tool) < /dev/null > /dev/null 2>&1 || {
+#	echo;
+#	echo "You must have gettext installed to compile orxonox";
+#	echo;
+#	exit;
+#}
+
+#(libtoolize --version) < /dev/null > /dev/null 2>&1 || {
+#	echo;
+#	echo "You must have libtool installed to compile orxonox";
+#	echo;
+#	exit;
+#}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+	echo;
+	echo "You must have automake installed to compile orxonox";
+	echo;
+	exit;
+}
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+	echo;
+	echo "You must have autoconf installed to compile orxonox";
+	echo;
+	exit;
+}
+
+echo "Generating configuration files for orxonox, please wait...."
+echo;
+
+# Backup the po/ChangeLog. This should prevent the annoying
+# gettext ChangeLog modifications.
+
+#cp -p po/ChangeLog po/ChangeLog.save
+#echo "Running gettextize, please ignore non-fatal messages...."
+#$SETUP_GETTEXT
+#echo "Running libtoolize, please ignore non-fatal messages...."
+#echo n | libtoolize --copy --force || exit;
+
+# Add other directories to this list if people continue to experience
+# brokennesses ...  Obviously the real answer is for them to fix it
+# themselves, but for Luke's sake we have this.
+#for dir in "/usr/local/share/aclocal" \
+#           "/opt/gnome-1.4/share/aclocal"
+#do
+#	if test -d $dir ; then
+#		ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I $dir"
+#	fi
+#done
+
+#aclocal $ACLOCAL_FLAGS -I ./m4 || exit;
+aclocal-1.9 || aclocal || exit;
+autoheader || exit;
+automake-1.9 --add-missing --copy || automake --add-missing --copy;
+autoconf || exit;
+automake-1.9 || automake || exit;
+#./configure $@
Index: branches/heathaze/config.h.in
===================================================================
--- branches/heathaze/config.h.in	(revision 9940)
+++ branches/heathaze/config.h.in	(revision 9940)
@@ -0,0 +1,111 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* in which debug mode we are */
+#undef DEBUG_LEVEL
+
+/* Define to 1 if you have the `bzero' function. */
+#undef HAVE_BZERO
+
+/* if we have CURL */
+#undef HAVE_CURL
+
+/* Define to 1 if you have the <GL/glew.h> header file. */
+#undef HAVE_GL_GLEW_H
+
+/* Define to 1 if you have the <GL/glu.h> header file. */
+#undef HAVE_GL_GLU_H
+
+/* Define to 1 if you have the <GL/gl.h> header file. */
+#undef HAVE_GL_GL_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the `OpenGL' library (-lOpenGL). */
+#undef HAVE_LIBOPENGL
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <OpenAL/al.h> header file. */
+#undef HAVE_OPENAL_AL_H
+
+/* Define to 1 if you have the <OpenGL/glu.h> header file. */
+#undef HAVE_OPENGL_GLU_H
+
+/* Define to 1 if you have the <OpenGL/gl.h> header file. */
+#undef HAVE_OPENGL_GL_H
+
+/* Define to 1 if you have the <SDL/SDL.h> header file. */
+#undef HAVE_SDL_SDL_H
+
+/* Define to 1 if you have the `sqrt' function. */
+#undef HAVE_SQRT
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* if Modular-DUBUG mode is enabled */
+#undef MODULAR_DEBUG
+
+/* Define to the read-only architecture-independent data directory of ORXONOX.
+   */
+#undef ORX_DATADIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
Index: branches/heathaze/configure.ac
===================================================================
--- branches/heathaze/configure.ac	(revision 9940)
+++ branches/heathaze/configure.ac	(revision 9940)
@@ -0,0 +1,653 @@
+
+##########################################################################
+#   orxonox - the future of 3D-vertical-scrollers                        #
+#                                                                        #
+#   Copyright (C) 2004 orx                                               #
+#                                                                        #
+#   This program is free software; you can redistribute it and/or modify #
+#   it under the terms of the GNU General Public License as published by #
+#   the Free Software Foundation; either version 2, or (at your option)  #
+#   any later version.                                                   #
+#                                                                        #
+#   ### File Specific:                                                   #
+#   main-programmer: Benjamin Grauer                                     #
+#   co-programmer: ...                                                   #
+#                                                                        #
+#   This is the main configuration File of autoconf.                     #
+#   Please edit this file only, if you exactly know what you are doing.  #
+#   It is quite fragile, and compiling orxonox on different Platforms    #
+#   is only guarantied, if build with the right config.                  #
+#                                                                        #
+#   You might also have a look at the acinclude.m4, where many macros    #
+#   for this configuration files are stored                              #
+#                                                                        #
+#   be sure to visit us at http://www.orxonox.net                        #
+##########################################################################
+
+#########################
+## AUTOCONF INIT PHASE ##
+#########################
+AC_PREREQ(2.56)
+AC_INIT([orxonox], [0.3.6_alpha], [orxonox at orxonox dot net])
+
+## Detect the canonical host and target build environment.
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+AM_INIT_AUTOMAKE
+
+AC_CONFIG_SRCDIR([src/orxonox.cc])
+AC_CONFIG_HEADER([config.h])
+
+#########################
+## Checks for programs ##
+#########################
+AC_PROG_CXX
+AC_PROG_RANLIB
+AC_HEADER_STDC
+
+## THIS IS OUR DEFAULT-DATA-DIRECTORY
+
+##################################
+## CHECKING  OPTIONAL ARGUMENTS ##
+##################################
+#----------------#
+# Data-Directory #
+#----------------#
+DATA_DIR=$datadir
+if test $DATA_DIR = \$\{prefix\}/share ; then
+        echo "not given"
+        DATA_DIR=/usr/share
+else
+        echo "given: $DATA_DIR"
+fi
+AC_DEFINE_UNQUOTED([ORX_DATADIR], ["$DATA_DIR"],
+                   [Define to the read-only architecture-independent
+                    data directory of ORXONOX.])
+
+#-----------------#
+# shared-lib-path #
+#-----------------#
+SHARED_LIB_PATH=no
+AC_MSG_CHECKING([shared lib path])
+AC_ARG_WITH([shared-lib-path],
+        AC_HELP_STRING(--with-shared-lib-path,Tells the executable, where to look for the shared libraries.),
+         SHARED_LIB_PATH=$withval)
+if test x$SHARED_LIB_PATH != xno; then
+        echo "set to $SHARED_LIB_PATH"
+else
+        echo "no"
+fi
+
+
+#-----------------#
+# DEBUG-statement #
+#-----------------#
+DEBUG_LEVEL=no
+AC_MSG_CHECKING([if DEBUG-mode should be enabled])
+AC_ARG_ENABLE([debug],
+        AC_HELP_STRING(--enable-debug,compiles in debug mode. Lots of debug info about the game.),
+         DEBUG_LEVEL=$enableval)
+
+if test x$DEBUG_LEVEL = xno; then
+        echo "no"
+        echo " -> Setting debuglevel to 4. (orxonox is still in Development. It really is needed."
+        DEBUG_LEVEL=4
+elif test x$DEBUG_LEVEL = xyes; then
+        echo "yes"
+        echo " -> Setting debuglevel to 4. HARD DEBUG MODE!!."
+        DEBUG_LEVEL=4
+else
+  if test x$DEBUG_LEVEL = x0 || test x$DEBUG_LEVEL = x1 || test x$DEBUG_LEVEL = x2 || test x$DEBUG_LEVEL = x3 || test x$DEBUG_LEVEL = x4 || test x$DEBUG_LEVEL = x5 ; then
+        echo "yes: setting debuglevel to to $DEBUG_LEVEL"
+  else
+        echo "yes: invalid Value for Debug ($DEBUG_LEVEL). setting to 4(DEBUG)"
+        DEBUG_LEVEL=4
+  fi
+fi
+
+if test ${DEBUG_LEVEL} -gt 3 ; then
+  CPPFLAGS="${CPPFLAGS} -g -Wall"
+fi
+AC_DEFINE_UNQUOTED(DEBUG_LEVEL, ${DEBUG_LEVEL}, [in which debug mode we are])
+AC_SUBST(DEBUG_LEVEL)
+
+#---------------#
+# Modular Debug #
+#---------------#
+MODULAR_DEBUG=yes
+AC_MSG_CHECKING([if Modular-DEBUG-mode should be ebabled])
+AC_ARG_ENABLE([modular-debug],
+        AC_HELP_STRING(--disable-modular-debug,compiles in modular-debug mode, that logs differently on the many modules of orxonox.),
+         MODULAR_DEBUG=$enableval)
+
+if test x$MODULAR_DEBUG = xno; then
+        echo "no"
+elif test x$MODULAR_DEBUG = xyes; then
+        echo "yes"
+        AC_DEFINE_UNQUOTED(MODULAR_DEBUG, 1, [if Modular-DUBUG mode is enabled])
+fi
+
+
+#------------------#
+# libCurl-disabled #
+#------------------#
+AC_MSG_CHECKING([if libcURL should be enabled])
+AC_ARG_ENABLE([curl],
+        AC_HELP_STRING(--disable-curl,Prevents libcURL from being loaded), [def_curl=no], [def_curl=yes])
+if test x$def_curl = xyes; then
+  echo "yes"
+fi
+if test x$def_curl = xno; then
+  echo "no"
+fi
+
+
+#-------------------#
+# SubProject-enable #
+#-------------------#
+def_sub_projects=no
+AC_MSG_CHECKING([if the SubProjects should be built])
+AC_ARG_WITH([sub-projects],
+        AC_HELP_STRING(--with-sub-projects,also builds the subProjects while make from srcdir), [def_sub_projects=yes])
+if test x$def_sub_projects = xyes; then
+  echo "yes"
+fi
+if test x$def_sub_projects = xno; then
+  echo "no"
+fi
+AM_CONDITIONAL(SUB_PROJECTS, test x$def_sub_projects = xyes)
+
+#-------------------#
+# Profiling Enabled #
+#-------------------#
+def_profiling=no
+AC_MSG_CHECKING([if Profiling should be enabled])
+AC_ARG_ENABLE([profile],
+        AC_HELP_STRING(--enable-profile,builds orxonox with profiling support), [def_profiling=yes])
+if test x$def_profiling = xyes; then
+  echo "yes"
+  CXXFLAGS="$CXXFLAGS -pg"
+fi
+if test x$def_profiling = xno; then
+  echo "no"
+fi
+
+#----------------#
+# efence Enabled #
+#----------------#
+def_efence=no
+AC_MSG_CHECKING([if efence should be enabled])
+AC_ARG_ENABLE([efence],
+        AC_HELP_STRING(--enable-efence,builds orxonox with efence support), [def_efence=yes])
+if test x$def_efence = xyes; then
+  echo "yes"
+fi
+if test x$def_efence = xno; then
+  echo "no"
+fi
+
+#----------------------#
+# Documentation-enable #
+#----------------------#
+def_documentation=no
+AC_MSG_CHECKING([if the Documentation should be build by default])
+AC_ARG_ENABLE([documentation],
+        AC_HELP_STRING(--enable-documentation,also builds the sDocumentation while make from srcdir), [def_documentation=yes])
+if test x$def_documentation = xyes; then
+  echo "yes"
+fi
+if test x$def_documentation = xno; then
+  echo "no"
+fi
+AM_CONDITIONAL(DOCUMENTATION, test x$def_documentation = xyes)
+
+#---------------------------#
+# WITH TARDIS (convenience) #
+#---------------------------#
+def_tardis=no
+AC_MSG_CHECKING([convenience flag for working at the taris in the ETH zurich])
+AC_ARG_WITH([tardis],
+        AC_HELP_STRING(--with-tardis,sets all the necesary environment flags for linux-TARDIS boxes at the ETH Zurich), [def_tardis=yes])
+if test x$def_tardis = xyes; then
+  ARCH=i686-debian-linux3.1
+   ## GAMELIBS
+  PREFIX=/usr/pack/gamelibs-1.0-to
+  CPPFLAGS="${CPPFLAGS} -I${PREFIX}/include"
+  LDFLAGS="${LDFLAGS} -L$PREFIX/${ARCH}/lib -Wl,-rpath -Wl,${PREFIX}/${ARCH}/lib"
+
+## QT on Tardis
+  QT_PREFIX=/usr/pack/qt-4.1.1-mo/${ARCH}
+#  CPPFLAGS="${CPPFLAGS} -I${PREFIX_QT}/include"
+#  LDFLAGS="${LDFLAGS} -L${QT_PREFIX}/lib -Wl,-rpath -Wl,${QT_PREFIX}/${ARCH}/lib"
+
+fi
+if test x$def_tardis = xno; then
+  echo "no"
+fi
+
+
+
+#######################
+## PROGRAMM CHECKING ##
+## 3. party Programs ##
+#######################
+
+#----------------------#
+# checking for Doxygen #
+#----------------------#
+AC_PATH_PROG(DOXYGEN, doxygen)
+AM_CONDITIONAL(DOXYGEN, test $DOXYGEN)
+
+#--------------------#
+# checking for gprof #
+#--------------------#
+AC_PATH_PROG(GPROF, gprof)
+
+
+#########################
+## CHECKING FOR SYSTEM ##
+#########################
+## here the system is checked, and openGL is included
+## also checking for SDL on differen Systems
+
+AC_MSG_CHECKING([for System])
+## checking for openGL-environment and other sys-specific parameters
+case "$target" in
+
+
+#########
+#-------#
+# LINUX #
+#-------#
+#########
+ *-*-linux*)
+echo "Linux detected"
+
+ Linux="yes"
+
+##CPPFLAGS="-I/usr/include $CPPFLAGS"
+##LDFLAGS="-L/usr/lib $LDFLAGS"
+if test x$SHARED_LIB_PATH != xno; then
+        echo "setting new LDFLAGS with $SHARED_LIB_PATH"
+        LDFLAGS="-Wl,-rpath,$SHARED_LIB_PATH -L$SHARED_LIB_PATH $LDFLAGS"
+fi
+
+#--------#
+# openGL #
+#--------#
+AX_CHECK_REQUIRED_HEADER_LIB([GL/gl.h], [GL], [main],,, [http://www.opengl.org])
+AX_CHECK_REQUIRED_HEADER_LIB([GL/glu.h], [GLU], [main],,, [http://www.opengl.org])
+AX_CHECK_REQUIRED_HEADER_LIB([GL/glew.h], [GLEW], [main],,, [http://glew.sourceforge.net])
+
+#--------#
+# openAL #
+#--------#
+AX_CHECK_REQUIRED_HEADER_LIB([AL/al.h], [openal], [main],,, [http://www.openal.org])
+
+#-----#
+# SDL #
+#-----#
+# checking for SDL
+  AC_MSG_CHECKING([for SDL-version])
+  SDL_VERSION=`sdl-config --version`
+  echo $SDL_VERSION
+   CPPFLAGS="${CPPFLAGS} `sdl-config --cflags`"
+
+  AX_CHECK_REQUIRED_HEADER_LIB([SDL.h SDL/SDL.h], [SDL], [main],,, [http://www.libsdl.org])
+
+    ;;
+
+###########
+#---------#
+# WINDOWS #
+#---------#
+###########
+  *-*-mingw32*)
+echo "mingw-WINDOWS detected"
+
+CPPFLAGS="-I/usr/include -I/mingw/include ${CPPFLAGS}"
+LDFLAGS="${LDFLAGS} -L/mingw/lib"
+    mingw="yes"
+    MSBITFIELDS="-mms-bitfields"
+    MWINDOWS="-mwindows"
+
+#--------#
+# MIN-GW #
+#--------#
+# checking for mingw32
+    AC_CHECK_LIB([mingw32], [main], FOUND_mingw32=yes)
+    if test x$FOUND_mingw32 = xyes; then
+        LIBS="$LIBS -lmingw32"
+    fi
+
+    AC_CHECK_LIB([winmm], [main], [FOUND_winmm=yes])
+    if test x${FOUND_winmm} = xyes ; then
+        LIBS="$LIBS -lwinmm"
+    fi
+
+#---------------#
+# open-GL (win) #
+#---------------#
+# checking gl header
+   AC_CHECK_HEADERS(GL/gl.h ,,
+      [AC_MSG_ERROR([cannot find opengl headers])])
+#   checking for Windows openGl library
+    AC_CHECK_LIB([opengl32], [main], [FOUND_GL=yes; LIBS="$LIBS -lopengl32"])
+    if test x$FOUND_GL != xyes ; then
+         echo "------------------"
+         echo "opengl not found."
+         echo "please install the opengl package which can be found at http://www.opengl.org"
+         echo "------------------"
+         exit -1
+    fi
+
+# cheking for GLU-header
+    AC_CHECK_HEADERS([GL/glu.h] ,,
+      [AC_MSG_ERROR([cannot find opengl headers]) ])
+
+# checking for libGLU
+    AC_CHECK_LIB([glu32], [main], [FOUND_GLU=yes; LIBS="$LIBS -lGLU32"])
+    if test x$FOUND_GLU != xyes ; then
+         echo "------------------"
+         echo "GLU library not found."
+         echo "please install the GLU library, that should come with openGL, which can be found at http://www.opengl.org"
+         echo "------------------"
+         exit -1
+    fi
+
+# checking glew header
+   AC_CHECK_HEADERS(GL/glew.h ,,
+      [AC_MSG_ERROR([cannot find opengl extension wrangler headers]) ])
+#   checking for Windows glew library
+    AC_CHECK_LIB([glew32], [main], [FOUND_GLEW=yes; LIBS="$LIBS -lglew32"])
+    if test x$FOUND_GLEW != xyes ; then
+         echo "------------------"
+         echo "opengl extension wrangler not found."
+         echo "please install the glew package which can be found at http://glew.sourceforge.net"
+         echo "------------------"
+         exit -1
+    fi
+
+#--------#
+# openAL #
+#--------#
+AX_CHECK_REQUIRED_HEADER_LIB([AL/al.h], [OpenAL32], [main],,, [http://www.openal.org])
+
+#-----------#
+# SDL(win) #
+#-----------#
+# checking for SDL-headers
+    AC_CHECK_HEADERS([SDL/SDL.h] ,,
+      [AC_MSG_ERROR([cannot find SDL headers]) ])
+
+#checking for libSDL
+    AC_CHECK_LIB([sdlmain], [main], [FOUND_sdlmain=yes; LIBS="$LIBS -lsdlmain"])
+    if test x$FOUND_sdlmain != xyes ; then
+        echo "------------------"
+        echo "SDL library not found."
+        echo "please install the SDL library, which can be found at http://www.libsdl.org"
+        echo "------------------"
+        exit 1
+    fi
+    AC_CHECK_LIB([sdl], [main], [FOUND_SDL=yes; LIBS="$LIBS -lsdl"])
+    if test x$FOUND_SDL != xyes ; then
+        echo "------------------"
+        echo "SDL library not found."
+        echo "please install the SDL library, which can be found at http://www.libsdl.org"
+        echo "------------------"
+        exit -1
+    fi
+
+  ;;
+
+#############
+#-----------#
+# MAC -OS X #
+#-----------#
+#############
+ *darwin*)
+ echo "OS X detected"
+ osX="yes"
+
+ QT_PREFIX="$prefix"
+ CPPFLAGS="-I/$prefix/include $CPPFLAGS -F$prefix/lib -I/opt/local"
+ LDFLAGS="$LDFLAGS -L$prefix/lib -F$prefix/lib -L/opt/local"
+ PCK_CONFIG_PATH='/opt/local'
+
+# checking gl header
+   AC_CHECK_HEADERS([OpenGL/gl.h] ,,
+      [AC_MSG_ERROR([cannot find opengl headers]) ])
+# checking for GLU-header
+    AC_CHECK_HEADERS([OpenGL/glu.h] ,,
+      [AC_MSG_ERROR([cannot find opengl headers]) ])
+        AC_CHECK_LIB( OpenGL, main, , )
+   LIBS="$LIBS -framework OpenGL"
+
+
+
+# checking for GLEW-headers
+   AC_CHECK_HEADERS([GL/glew.h] ,,
+      [AC_MSG_ERROR([cannot find glew headers]) ])
+# checking for GLEW-lib
+  AC_CHECK_LIB([GLEW], [main], [FOUND_GLEW=yes; LIBS="$LIBS -lGLEW"])
+   if test x$FOUND_GLEW != xyes ; then
+         echo "------------------"
+         echo "glew not found."
+         echo "please install the glew package which can be found at http://glew.sourceforge.net"
+         echo "------------------"
+         exit -1
+   fi
+
+ LIBS="$LIBS"
+   AC_CHECK_HEADERS([OpenAL/al.h] ,,
+      [AC_MSG_ERROR([cannot find opengl headers]) ])
+  HAVE_OPENAL=yes
+  LIBS="$LIBS -framework OpenAL"
+
+
+## SDL-check
+       SDL_CFLAGS=`sdl-config --cflags`
+       SDL_LIBS=`sdl-config --libs`
+       CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
+       LIBS="$LIBS $SDL_LIBS"
+   AC_CHECK_HEADERS([SDL/SDL.h] ,,
+      [AC_MSG_ERROR([cannot find SDL headers]) ])
+   HAVE_SDL=yes
+#   LIBS="$LIBS -framework SDL"
+
+# checking for SDL-headers
+#    AC_CHECK_HEADERS(SDL/SDL.h ,,
+#      [AC_MSG_ERROR([cannot find SDL headers]) ])
+
+## checking for SDL
+#    SDL_VERSION=1.2.7
+#    AM_PATH_SDL($SDL_VERSION,
+#      :,
+#      AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
+#      )
+
+
+    ;;
+
+  *)
+    ;;
+esac
+
+AC_SUBST(MSBITFIELDS)
+
+###################################
+## CHECKING FOR HEADERS AND LIBS ##
+###################################
+
+#---------#
+# SDL_ttf #
+#---------#
+AX_CHECK_REQUIRED_HEADER_LIB([SDL_ttf.h SDL/SDL_ttf.h], [SDL_ttf], [TTF_OpenFont],,, [http://www.libsdl.org/projects/SDL_ttf])
+#-----------#
+# SDL_Image #
+#-----------#
+AX_CHECK_REQUIRED_HEADER_LIB([SDL_image.h SDL/SDL_image.h], [SDL_image], [main],,, [http://www.libsdl.org/projects/SDL_image])
+#---------#
+# SDL_Net #
+#---------#
+AX_CHECK_REQUIRED_HEADER_LIB([SDL_net.h SDL/SDL_net.h], [SDL_net], [main],,, [http://www.libsdl.org/projects/SDL_net])
+
+#--------#
+# FFmpeg #
+#--------#
+
+## THIS IS FOR SURE A BUG (-llualib)
+# checking for FFmpeg-headers
+  AX_CHECK_REQUIRED_HEADER_LIB([avformat.h ffmpeg/avformat.h] ,[avformat], [main],
+   [AX_CHECK_REQUIRED_HEADER_LIB([avcodec.h ffmpeg/avcodec.h], [avcodec], [main],,, [http://ffmpeg.sourceforge.net]) LIBS="${LIBS} -lavformat -lavcodec"],
+     [AX_GET_INSTALL_NECESSARY_LIB([http://svn.orxonox.net/webdev/develop/ext_libs], [ffmpeg.tar.gz], [ffmpeg], [extern_libs/], [include/*.h lib/*.a])
+       LIBS="-llualib -llua"  CPPFLAGS="${CPPFLAGS} -I$(top_build_dir)/extern_libs" ],
+  [http://ffmpeg.sourceforge.net])
+
+
+
+
+  AC_CHECK_LIB([avutil], [main], [FOUND_avutil=yes; LIBS="$LIBS -lavutil"])
+  AC_CHECK_LIB([xvid], [main], [FOUND_xvid=yes; LIBS="$LIBS -lxvid"])
+  AC_CHECK_LIB([gcj], [main], [FOUND_gcj=yes; LIBS="$LIBS -lgcj"])
+  AC_CHECK_LIB([theora], [main], [FOUND_theora=yes; LIBS="$LIBS -ltheora"])
+  AC_CHECK_LIB([dts], [main], [FOUND_dts=yes; LIBS="$LIBS -ldts"])
+  AC_CHECK_LIB([gsm], [main], [FOUND_gsm=yes; LIBS="$LIBS -lgsm"])
+  AC_CHECK_LIB([dc1394_control], [main], [FOUND_dc1394_control=yes; LIBS="$LIBS -ldc1394_control"])
+  AC_CHECK_LIB([vorbisenc], [main], [FOUND_vorbisenc=yes; LIBS="$LIBS -lvorbisenc"])
+
+
+#--------#
+# vorbis #
+#--------#
+AX_CHECK_REQUIRED_HEADER_LIB([vorbis/vorbisfile.h], [vorbisfile], [main],,, [http://www.xiph.org/ogg/vorbis/index.html])
+AX_CHECK_REQUIRED_HEADER_LIB([vorbis/codec.h], [vorbis], [main],,, [http://www.xiph.org/ogg/vorbis/index.html])
+
+#-----#
+# ogg #
+#-----#
+AX_CHECK_REQUIRED_HEADER_LIB([ogg/ogg.h], [ogg], [main],,, [http://www.xiph.org/ogg/vorbis/index.html])
+
+
+#----#
+# QT #
+#----#
+if test x$osX = xyes ; then
+#       PKG_CONFIG_PATH="$prefix"
+#       PKG_CHECK_MODULES( QT, QtOpenGL >= 4.01 QtCore >= 4.01 QtGui >= 4.0.1 )
+#       QT_INCLUDE_DIR=`$PKG_CONFIG --variable=includedir QtOpenGL QtCore QtGui`
+#----------#
+            AC_PATH_PROG([QT_MOC], [moc], [no], ["${QT_BIN_DIRECTORY}:${PATH}"])
+              if test x${QT_MOC} = xno ; then
+                AC_MSG_ERROR([QT MOC not found])
+              fi
+        AC_SUBST([QT_MOC])
+
+        AC_PATH_PROG([QT_UIC], [uic], [no], ["${QT_BIN_DIRECTORY}:${PATH}"])
+        AC_SUBST([QT_UIC])
+
+        AC_PATH_PROG([QT_RCC], [rcc], [no], ["${QT_BIN_DIRECTORY}:${PATH}"])
+
+        AC_SUBST([QT_RCC])
+        AC_SUBST( QT_INCLUDE_DIR )
+        AC_SUBST( QT_CFLAGS )
+        AC_SUBST( QT_LDFLAGS )
+        AC_SUBST( QT_LIBS )
+        echo "QT_LIBS                   = $QT_LIBS"
+        echo "QT_CFLAGS                 = $QT_CFLAGS"
+        echo "QT_INCLUDE_DIR    = $QT_INCLUDE_DIR"
+else
+        AX_CHECK_QT([${QT_PREFIX}], [QtCore QtCore4],, [http://www.trolltech.com])
+        if test x$have_qt = xno ; then
+                WITH_QT=no
+        fi
+fi
+
+#---------#
+# libcURL #
+#---------#
+AX_CHECK_HEADER_LIB([curl/curl.h], [curl], [main], [
+ have_curl=yes
+  CURL_LIBS=`curl-config --libs`
+  CURLCFLAGS=`curl-config --cflags`
+  AC_DEFINE_UNQUOTED(HAVE_CURL, 1, [if we have CURL]) ]
+  ,, [http://curl.haxx.se/])
+
+AC_SUBST(CURL_LIBS)
+AC_SUBST(CURL_CFLAGS)
+AM_CONDITIONAL(HAVE_CURL, test "x$have_curl" = "xyes")
+
+
+ AX_CHECK_REQUIRED_HEADER_LIB([zlib.h], [z], [zlibVersion],,, [http://www.zlib.net])
+ AX_CHECK_REQUIRED_HEADER_LIB([math.h], [m], [sqrt])
+
+
+#-----#
+# LUA #
+#-----#
+LUA_DIR="/usr/include/lua"
+AX_CHECK_LUA([${LUA_DIR}])
+
+#--------#
+# efence #
+#--------#
+if test x$def_efence = xyes ; then
+  AC_CHECK_LIB([efence], [main], [FOUND_efence=yes; LIBS="$LIBS -lefence"])
+   if test x$FOUND_efence != xyes ; then
+     echo "efence was requested, but is not installed!! going on"
+   fi
+fi
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([stdlib.h string.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_CHECK_FUNCS([bzero sqrt])
+
+######################
+## OUTPUT CONFIGURE ##
+######################
+AC_CONFIG_FILES([Makefile
+                 src/Makefile
+                 src/lib/Makefile
+                 src/lib/math/Makefile
+                 src/lib/lang/Makefile
+                 src/lib/util/Makefile
+                 src/lib/graphics/Makefile
+                 src/lib/graphics/importer/Makefile
+                 src/lib/graphics/spatial_separation/Makefile
+                 src/lib/sound/Makefile
+                 src/lib/event/Makefile
+                 src/lib/physics/Makefile
+                 src/lib/collision_detection/Makefile
+                 src/lib/collision_reaction/Makefile
+                 src/lib/network/Makefile
+                 src/lib/shell/Makefile
+                 src/lib/gui/Makefile
+                 src/lib/gui/gl/Makefile
+                 src/lib/gui/qt/Makefile
+                 src/lib/script_engine/Makefile
+                 src/lib/parser/Makefile
+                 src/lib/parser/tinyxml/Makefile
+                 src/lib/parser/ini_parser/Makefile
+                 src/lib/parser/cmdline_parser/Makefile
+                 src/lib/parser/preferences/Makefile
+                 src/util/Makefile
+                 src/world_entities/Makefile
+                 src/subprojects/Makefile
+                 src/subprojects/testmain/Makefile
+                 src/subprojects/importer/Makefile
+                 src/subprojects/particles/Makefile
+                 src/subprojects/collision_detection/Makefile
+                 src/subprojects/network/Makefile
+                 src/subprojects/recapture_mouse/Makefile
+                 ])
+
+AC_OUTPUT
Index: branches/heathaze/depcomp
===================================================================
--- branches/heathaze/depcomp	(revision 9940)
+++ branches/heathaze/depcomp	(revision 9940)
@@ -0,0 +1,529 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2005-02-09.22
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+  stat=$?
+
+  if test -f "$tmpdepfile"; then :
+  else
+    stripped=`echo "$stripped" | sed 's,^.*/,,'`
+    tmpdepfile="$stripped.u"
+  fi
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    outname="$stripped.o"
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mecanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+	set fnord "$@"
+	shift
+	shift
+	;;
+    *)
+	set fnord "$@" "$arg"
+	shift
+	shift
+	;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
Index: branches/heathaze/doc/CREDITS
===================================================================
--- branches/heathaze/doc/CREDITS	(revision 9940)
+++ branches/heathaze/doc/CREDITS	(revision 9940)
@@ -0,0 +1,20 @@
+The orxonox Team Thanks the following brethren.
+-----------------------------------------------
+
+Programmers:
+------------
+Patrick Boenzli
+Benjamin Grauer
+
+Infrastructure:
+---------------
+amir@datacore.ch        for giving us access to subversion and mailing lists
+
+The Great Orx Sound:
+--------------------
+Luke Grey               for making the orxonox sound
+Thierry Zaugg           many songs
+
+
+
+And many many more....
Index: branches/heathaze/doc/documentation.am
===================================================================
--- branches/heathaze/doc/documentation.am	(revision 9940)
+++ branches/heathaze/doc/documentation.am	(revision 9940)
@@ -0,0 +1,62 @@
+DX_CONFIG_FILE = "$(top_srcdir)/orxodox"
+DX_CONF_DIR = "$(top_srcdir)/doc/doxyconf"
+
+doc:
+	if test ! -e $(DX_CONFIG_FILE); then \
+	 make doc-config; \
+	fi
+	@echo "Generating doxygen Documentation"; \
+	$(DOXYGEN) $(DX_CONFIG_FILE)
+
+doc-config:
+	@echo "Generationg doxygen configuration File." ; \
+	if test -e  "$(top_srcdir)/orxodox"; then \
+	  echo "deleting existing Configuration File" ; \
+	  rm $(top_srcdir)/orxodox ; \
+	fi ; \
+	touch $(DX_CONFIG_FILE) ; \
+	$(DX_CONF_DIR)/project						>> $(DX_CONFIG_FILE); \
+	echo "PROJECT_NAME		= \"$(PACKAGE_NAME)\"" 		>> $(DX_CONFIG_FILE); \
+	echo "PROJECT_NUMBER	   	= \"$(PACKAGE_VERSION)\"" 	>> $(DX_CONFIG_FILE); \
+	echo "OUTPUT_DIRECTORY  	= \"$(top_srcdir)/doc/\"" 	>> $(DX_CONFIG_FILE); \
+	echo " " >> $(DX_CONFIG_FILE); \
+\
+	$(DX_CONF_DIR)/build						>> $(DX_CONFIG_FILE); \
+\
+	$(DX_CONF_DIR)/progress						>> $(DX_CONFIG_FILE); \
+	if test $(DEBUG) -ge 2 ; then \
+	 echo "QUIET			= \"NO\""			>> $(DX_CONFIG_FILE); \
+	else \
+	 echo "QUIET			= \"YES\""			>> $(DX_CONFIG_FILE); \
+	fi ;\
+\
+	$(DX_CONF_DIR)/input						>> $(DX_CONFIG_FILE); \
+	echo "INPUT                  	= $(DOXYGEN_INPUT)"  		>> $(DX_CONFIG_FILE); \
+\
+	$(DX_CONF_DIR)/preprocessor					>> $(DX_CONFIG_FILE); \
+	echo "INCLUDE_PATH           	= \"$(top_srcdir)\""		>> $(DX_CONFIG_FILE); \
+	echo "PREDEFINED             	= \"HAVE_CONFIG_H= \""		>> $(DX_CONFIG_FILE); \
+	\
+	$(DX_CONF_DIR)/confopts						>> $(DX_CONFIG_FILE) 
+
+doc-delete: 
+	@echo "Deleting doxygen Documentation" 
+	rm -rf $(top_srcdir)/doc/html 
+	rm -rf $(top_srcdir)/doc/latex 
+
+distclean-local: doc-delete
+	rm -f $(top_srcdir)/orxodox
+
+clean-local:  doc-delete
+
+if DOCUMENTATION
+all-local: doc
+else
+all-local: 
+endif
+
+.PHONY: doc doc-config doc-delete
+
+# Local Variables:
+# mode: makefile
+# End:
Index: branches/heathaze/doc/doxyconf/build
===================================================================
--- branches/heathaze/doc/doxyconf/build	(revision 9940)
+++ branches/heathaze/doc/doxyconf/build	(revision 9940)
@@ -0,0 +1,28 @@
+echo "
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES"
Index: branches/heathaze/doc/doxyconf/confopts
===================================================================
--- branches/heathaze/doc/doxyconf/confopts	(revision 9940)
+++ branches/heathaze/doc/doxyconf/confopts	(revision 9940)
@@ -0,0 +1,121 @@
+echo "
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = YES
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 0
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO"
Index: branches/heathaze/doc/doxyconf/input
===================================================================
--- branches/heathaze/doc/doxyconf/input	(revision 9940)
+++ branches/heathaze/doc/doxyconf/input	(revision 9940)
@@ -0,0 +1,15 @@
+echo "
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+FILE_PATTERNS          = 
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_SOURCE_FILES    = NO"
Index: branches/heathaze/doc/doxyconf/preprocessor
===================================================================
--- branches/heathaze/doc/doxyconf/preprocessor	(revision 9940)
+++ branches/heathaze/doc/doxyconf/preprocessor	(revision 9940)
@@ -0,0 +1,11 @@
+echo "
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_FILE_PATTERNS  = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES"
Index: branches/heathaze/doc/doxyconf/progress
===================================================================
--- branches/heathaze/doc/doxyconf/progress	(revision 9940)
+++ branches/heathaze/doc/doxyconf/progress	(revision 9940)
@@ -0,0 +1,9 @@
+echo "
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = \"\$file:\$line: \$text\"
+WARN_LOGFILE           = "
Index: branches/heathaze/doc/doxyconf/project
===================================================================
--- branches/heathaze/doc/doxyconf/project	(revision 9940)
+++ branches/heathaze/doc/doxyconf/project	(revision 9940)
@@ -0,0 +1,26 @@
+echo "
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+CREATE_SUBDIRS         = YES
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = 
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES"
Index: branches/heathaze/doc/orxodox.src
===================================================================
--- branches/heathaze/doc/orxodox.src	(revision 9940)
+++ branches/heathaze/doc/orxodox.src	(revision 9940)
@@ -0,0 +1,213 @@
+# Doxyfile 1.3.7
+## SAMPLE FILE (to be executed from orxonox/trunk/)
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = Orxonox
+PROJECT_NUMBER         = 1
+OUTPUT_DIRECTORY       = doxygen/
+CREATE_SUBDIRS         = YES
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = 
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = .
+FILE_PATTERNS          = 
+RECURSIVE              = NO
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = YES
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 0
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
Index: branches/heathaze/doc/orxodox.this
===================================================================
--- branches/heathaze/doc/orxodox.this	(revision 9940)
+++ branches/heathaze/doc/orxodox.this	(revision 9940)
@@ -0,0 +1,213 @@
+# Doxyfile 1.3.7
+## SAMPLE FILE (to be executed from orxonox/trunk/)
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = Orxonox
+PROJECT_NUMBER         = 1
+OUTPUT_DIRECTORY       = doxygen
+CREATE_SUBDIRS         = YES
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = 
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = .
+FILE_PATTERNS          = 
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = YES
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 0
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
Index: branches/heathaze/doc/orxonox.1
===================================================================
--- branches/heathaze/doc/orxonox.1	(revision 9940)
+++ branches/heathaze/doc/orxonox.1	(revision 9940)
@@ -0,0 +1,63 @@
+.\"                              hey, Emacs:   -*- nroff -*-
+.\" orxonox is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; either version 2 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; see the file COPYING.  If not, write to
+.\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+.\"
+.TH ORXONOX 1 "March 2, 2004"
+.\" Please update the above date whenever this man page is modified.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh        disable hyphenation
+.\" .hy        enable hyphenation
+.\" .ad l      left justify
+.\" .ad b      justify to both left and right margins (default)
+.\" .nf        disable filling
+.\" .fi        enable filling
+.\" .br        insert line break
+.\" .sp <n>    insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+orxonox \-  High-End Vertical Scroller
+.SH SYNOPSIS
+.B orxonox
+.RI [ options ]
+.SH DESCRIPTION
+\fBorxonox\fP is an open-source vertical scroller game programmed in C++,OpenGL and SDL. It's designed to run on all important platforms like Linux, MacOS X, Windows.
+.PP
+It washes your windows, mends your fences, mows your lawn...
+.SH OPTIONS
+\fBorxonox\fP accepts the following options:
+.TP
+.B \-h, \-\-help
+Show summary of options.
+.TP
+.B \-v=<i>, \-\-verbose=\<i\>
+Prints out: 0: nothing, 1: error, 2: warnings, 3: information, 4+: debug
+.TP
+.B \-g, \-\-gui 
+displays the gui prior to starting orxonox. (this is also the case, if the configuration-files do not exist in your home).
+.TP
+.B \-q, \-\-windowed
+starts orxonox in windowed mode. (not fullscreen)
+.TP
+.B \-\-no\-sound 
+Disables audio completely
+.TP
+.B \-w, \-\-wireframe 
+Renders everything in Wireframe mode.
+.TP
+.\" .SH "SEE ALSO"
+.\" .BR foo (1), 
+.\" .BR bar (1).
+.SH AUTHOR
+orx-crew <orxonox@orxonox.ethz.ch>.
Index: branches/heathaze/install-sh
===================================================================
--- branches/heathaze/install-sh	(revision 9940)
+++ branches/heathaze/install-sh	(revision 9940)
@@ -0,0 +1,323 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2005-02-02.21
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c         (ignored)
+-d         create directories instead of installing files.
+-g GROUP   $chgrpprog installed files to GROUP.
+-m MODE    $chmodprog installed files to MODE.
+-o USER    $chownprog installed files to USER.
+-s         $stripprog installed files.
+-t DIRECTORY  install into DIRECTORY.
+-T         report an error if DSTFILE is a directory.
+--help     display this help and exit.
+--version  display version info and exit.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+  case $1 in
+    -c) shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) chmodcmd="$chmodprog $2"
+        shift
+        shift
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t) dstarg=$2
+	shift
+	shift
+	continue;;
+
+    -T) no_target_directory=true
+	shift
+	continue;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    *)  # When -d is used, all remaining arguments are directories to create.
+	# When -t is used, the destination is already specified.
+	test -n "$dir_arg$dstarg" && break
+        # Otherwise, the last argument is the destination.  Remove it from $@.
+	for arg
+	do
+          if test -n "$dstarg"; then
+	    # $@ is not empty: it contains at least $arg.
+	    set fnord "$@" "$dstarg"
+	    shift # fnord
+	  fi
+	  shift # arg
+	  dstarg=$arg
+	done
+	break;;
+  esac
+done
+
+if test -z "$1"; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src ;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    src=
+
+    if test -d "$dst"; then
+      mkdircmd=:
+      chmodcmd=
+    else
+      mkdircmd=$mkdirprog
+    fi
+  else
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dstarg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dstarg: Is a directory" >&2
+	exit 1
+      fi
+      dst=$dst/`basename "$src"`
+    fi
+  fi
+
+  # This sed command emulates the dirname command.
+  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
+
+  # Make sure that the destination directory exists.
+
+  # Skip lots of stat calls in the usual case.
+  if test ! -d "$dstdir"; then
+    defaultIFS='
+	 '
+    IFS="${IFS-$defaultIFS}"
+
+    oIFS=$IFS
+    # Some sh's can't handle IFS=/ for some reason.
+    IFS='%'
+    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+    shift
+    IFS=$oIFS
+
+    pathcomp=
+
+    while test $# -ne 0 ; do
+      pathcomp=$pathcomp$1
+      shift
+      if test ! -d "$pathcomp"; then
+        $mkdirprog "$pathcomp"
+	# mkdir can fail with a `File exist' error in case several
+	# install-sh are creating the directory concurrently.  This
+	# is OK.
+	test -d "$pathcomp" || exit
+      fi
+      pathcomp=$pathcomp/
+    done
+  fi
+
+  if test -n "$dir_arg"; then
+    $doit $mkdircmd "$dst" \
+      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+  else
+    dstfile=`basename "$dst"`
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+    trap '(exit $?); exit' 1 2 13 15
+
+    # Copy the file name to the temp name.
+    $doit $cpprog "$src" "$dsttmp" &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+    # Now rename the file to the real destination.
+    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+      || {
+	   # The rename failed, perhaps because mv can't rename something else
+	   # to itself, or perhaps because mv is so ancient that it does not
+	   # support -f.
+
+	   # Now remove or move aside any old file at destination location.
+	   # We try this two ways since rm can't unlink itself on some
+	   # systems and the destination file might be busy for other
+	   # reasons.  In this case, the final cleanup might fail but the new
+	   # file should still install successfully.
+	   {
+	     if test -f "$dstdir/$dstfile"; then
+	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+	       || {
+		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+		 (exit 1); exit 1
+	       }
+	     else
+	       :
+	     fi
+	   } &&
+
+	   # Now rename the file to the real destination.
+	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+	 }
+    }
+  fi || { (exit 1); exit 1; }
+done
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+  (exit 0); exit 0
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
Index: branches/heathaze/missing
===================================================================
--- branches/heathaze/missing	(revision 9940)
+++ branches/heathaze/missing	(revision 9940)
@@ -0,0 +1,357 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2005-02-08.22
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
+#   Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+  lex|yacc)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f y.tab.h ]; then
+	echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+	file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit 1
+    fi
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    touch $file
+    ;;
+
+  tar)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case "$firstarg" in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case "$firstarg" in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
Index: branches/heathaze/mkinstalldirs
===================================================================
--- branches/heathaze/mkinstalldirs	(revision 9940)
+++ branches/heathaze/mkinstalldirs	(revision 9940)
@@ -0,0 +1,150 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2005-02-02.21
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage"
+      exit $?
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --version)
+      echo "$0 $scriptversion"
+      exit $?
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error.  This is a problem when calling mkinstalldirs
+# from a parallel make.  We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+  '')
+    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    else
+      # On NextStep and OpenStep, the `mkdir' command does not
+      # recognize any option.  It will interpret all options as
+      # directories to create, and then abort because `.' already
+      # exists.
+      test -d ./-p && rmdir ./-p
+      test -d ./--version && rmdir ./--version
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+       test ! -d ./--version; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    else
+      # Clean up after NextStep and OpenStep mkdir.
+      for d in ./-m ./-p ./--version "./$dirmode";
+      do
+        test -d $d && rmdir $d
+      done
+    fi
+    ;;
+esac
+
+for file
+do
+  set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+  shift
+
+  pathcomp=
+  for d
+  do
+    pathcomp="$pathcomp$d"
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+	errstatus=$lasterr
+      else
+	if test ! -z "$dirmode"; then
+	  echo "chmod $dirmode $pathcomp"
+	  lasterr=""
+	  chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+	  if test ! -z "$lasterr"; then
+	    errstatus=$lasterr
+	  fi
+	fi
+      fi
+    fi
+
+    pathcomp="$pathcomp/"
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
Index: branches/heathaze/scripts/data.genlist.pl
===================================================================
--- branches/heathaze/scripts/data.genlist.pl	(revision 9940)
+++ branches/heathaze/scripts/data.genlist.pl	(revision 9940)
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+##########################################################################
+#   orxonox - the future of 3D-vertical-scrollers                        #
+#                                                                        #
+#   Copyright (C) 2004 orx                                               #
+#                                                                        #
+#   This program is free software; you can redistribute it and/or modify #
+#   it under the terms of the GNU General Public License as published by #
+#   the Free Software Foundation; either version 2, or (at your option)  #
+#   any later version.                                                   #
+#                                                                        #
+#   ### File Specific:                                                   #
+#   main-programmer: Benjamin Grauer                                     #
+#   co-programmer: ...                                                   #
+#                                                                        #
+#   This is a simple perl script, that generates a List of all files     #
+#   contained in a Folder checked out with SVN and writes into an output #
+#   file.                                                                #
+##########################################################################
+
+if (@ARGV[0] eq "-h" || $ARGV[0] eq "--help" || @ARGV != 2)
+  {
+    die ("usage: data.genlist.pl <data-directory> <output-file>\n");
+  }
+
+
+if (! -d @ARGV[0])
+  {
+    die ("@ARGV[0] is not regular Directory.\n");
+  }
+
+open(FD, "> @ARGV[1]") or die("Couldn't open @ARGV[1]\n") ;
+
+
+&createFileList(@ARGV[0]);
+
+close(FD);
+
+
+sub createFileList
+  {
+   my ($folderName) = @_;
+   my ($fullName);
+   my ($inputFile);
+   my ($printFile);
+   my (@folderList);
+
+   open(FOLDERLIST, "ls $folderName -1 |");
+   @folderList = <FOLDERLIST>;
+
+   foreach $inputFile (@folderList)
+     {
+       if ($inputFile eq "." || $inputFile eq "..")
+         {
+
+         }
+       chomp($inputFile);
+       $fullName = "$folderName/$inputFile";
+
+       $printFile = $fullName;
+       $printFile =~ s/@ARGV[0]//;
+       print FD "$printFile\n";
+       if (-d $fullName )
+         {
+           &createFileList($fullName);
+         }
+     }
+ }
Index: branches/heathaze/scripts/gentoo/install_notes
===================================================================
--- branches/heathaze/scripts/gentoo/install_notes	(revision 9940)
+++ branches/heathaze/scripts/gentoo/install_notes	(revision 9940)
@@ -0,0 +1,30 @@
+INSTALLATION NOTES
+==================
+To install this script as long as it is not in portage,
+you can follow this guide.
+
+Dependencies:
+-------------
+gentoo linux :)
+http://www.gentoo.org
+
+
+1. INSTALLATION INTO PORTAGE:
+-----------------------------
+a) get root (su - )
+b) mkdir /usr/portage/games-action/orxonox
+c) cp orxonox-[*].ebuild /usr/portage/games-action/orxonox
+d) cd /usr/portage/games-action/orxonox
+e) ebuild orxonox-[*].ebuild digest
+
+[*]: the version of the ebuild to install (ex. 0.3.0-r4969)
+
+
+2. EMERGING:
+------------
+a) emerge orxonox -pv     
+	##(this is to see, if the dependencies are alright)
+b) emerge orxonox
+
+
+#EOF
Index: branches/heathaze/scripts/gentoo/orxonox-0.3.0_alpha-r4969.ebuild
===================================================================
--- branches/heathaze/scripts/gentoo/orxonox-0.3.0_alpha-r4969.ebuild	(revision 9940)
+++ branches/heathaze/scripts/gentoo/orxonox-0.3.0_alpha-r4969.ebuild	(revision 9940)
@@ -0,0 +1,64 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit eutils games
+
+DATA_VERSION=73
+
+DESCRIPTION="orxonox is an open-source vertical scroller game programmed in C++, OpenGL, OpenAL and SDL"
+HOMEPAGE="http://www.orxonox.net"
+SRC_URI="http://www.orxonox.net/files/snapshots/${P}-${PR}.tar.bz2
+         http://www.orxonox.net/files/snapshots/${PN}-data-r${DATA_VERSION}.tar.bz2"
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="x86"
+IUSE="gtk+-2"
+
+DEPEND="virtual/opengl
+        virtual/x11
+        media-libs/openal
+        media-libs/libsdl
+        media-libs/sdl-image
+        media-libs/sdl-ttf"
+
+# Run-time dependencies, same as DEPEND if RDEPEND isn't defined:
+#RDEPEND=""
+S=${WORKDIR}/${P}
+
+src_unpack() {
+        unpack ${P}-${PR}.tar.bz2
+        cd "${S}"
+        unpack ${PN}-data-r${DATA_VERSION}.tar.bz2
+}
+
+src_compile() {
+        egamesconf || die
+
+        emake || die "emake failed"
+}
+
+src_install() {
+        make DESTDIR=${D} install || die
+
+        dodir ${GAMES_DATADIR}/${PN}
+        cp -r data/* ${D}/${GAMES_DATADIR}/${PN}/ \
+                || die "data copy failed"
+
+        dodoc AUTHORS ChangeLog README
+
+        prepgamesdirs
+
+        #make \
+        #       prefix=${D}/usr \
+        #       mandir=${D}/usr/share/man \
+        #       infodir=${D}/usr/share/info \
+        #       libdir=${D}/usr/$(get_libdir) \
+        #       install || die
+
+        #einstall || die
+}
+
+pkg_postinst() {
+        games_pkg_postinst
+}
Index: branches/heathaze/scripts/gentoo/orxonox-0.3.1_alpha-r5273.ebuild
===================================================================
--- branches/heathaze/scripts/gentoo/orxonox-0.3.1_alpha-r5273.ebuild	(revision 9940)
+++ branches/heathaze/scripts/gentoo/orxonox-0.3.1_alpha-r5273.ebuild	(revision 9940)
@@ -0,0 +1,65 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit eutils games
+
+DATA_VERSION=83
+
+DESCRIPTION="orxonox is an open-source 3D-action game programmed in C++, OpenGL, OpenAL and SDL"
+HOMEPAGE="http://www.orxonox.net"
+SRC_URI="http://www.orxonox.net/files/snapshots/${P}-${PR}.tar.bz2
+         http://www.orxonox.net/files/snapshots/${PN}-data-r${DATA_VERSION}.tar.bz2"
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="x86"
+IUSE="gtk+-2"
+
+DEPEND="virtual/opengl
+        virtual/x11
+        media-libs/openal
+        media-libs/libsdl
+        media-libs/sdl-image
+        media-libs/sdl-ttf
+        media-libs/glew"
+
+# Run-time dependencies, same as DEPEND if RDEPEND isn't defined:
+#RDEPEND=""
+S=${WORKDIR}/${P}
+
+src_unpack() {
+        unpack ${P}-${PR}.tar.bz2
+        cd "${S}"
+        unpack ${PN}-data-r${DATA_VERSION}.tar.bz2
+}
+
+src_compile() {
+        egamesconf || die
+
+        emake || die "emake failed"
+}
+
+src_install() {
+        make DESTDIR=${D} install || die
+
+        dodir ${GAMES_DATADIR}/${PN}
+        cp -r data/* ${D}/${GAMES_DATADIR}/${PN}/ \
+                || die "data copy failed"
+
+        dodoc AUTHORS ChangeLog README
+
+        prepgamesdirs
+
+        #make \
+        #       prefix=${D}/usr \
+        #       mandir=${D}/usr/share/man \
+        #       infodir=${D}/usr/share/info \
+        #       libdir=${D}/usr/$(get_libdir) \
+        #       install || die
+
+        #einstall || die
+}
+
+pkg_postinst() {
+        games_pkg_postinst
+}
Index: branches/heathaze/scripts/gentoo/orxonox-0.3.2_alpha-r5702.ebuild
===================================================================
--- branches/heathaze/scripts/gentoo/orxonox-0.3.2_alpha-r5702.ebuild	(revision 9940)
+++ branches/heathaze/scripts/gentoo/orxonox-0.3.2_alpha-r5702.ebuild	(revision 9940)
@@ -0,0 +1,66 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit eutils games
+
+DATA_VERSION=106
+
+DESCRIPTION="orxonox is an open-source 3D-action game programmed in C++, OpenGL, OpenAL and SDL"
+HOMEPAGE="http://www.orxonox.net"
+SRC_URI="http://www.orxonox.net/files/snapshots/${P}-${PR}.tar.bz2
+         http://www.orxonox.net/files/snapshots/${PN}-data-r${DATA_VERSION}.tar.bz2"
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="x86"
+IUSE="gtk+-2"
+
+DEPEND="virtual/opengl
+        virtual/x11
+        media-libs/openal
+        media-libs/libsdl
+        media-libs/sdl-image
+        media-libs/sdl-ttf
+        media-libs/glew"
+
+# Run-time dependencies, same as DEPEND if RDEPEND isn't defined:
+#RDEPEND=""
+S=${WORKDIR}/${P}
+
+src_unpack() {
+        unpack ${P}-${PR}.tar.bz2
+        cd "${S}"
+        unpack ${PN}-data-r${DATA_VERSION}.tar.bz2
+}
+
+src_compile() {
+	./autogen.sh
+        egamesconf || die
+
+        emake || die "emake failed"
+}
+
+src_install() {
+        make DESTDIR=${D} install || die
+
+        dodir ${GAMES_DATADIR}/${PN}
+        cp -r data/* ${D}/${GAMES_DATADIR}/${PN}/ \
+                || die "data copy failed"
+
+        dodoc AUTHORS ChangeLog README
+
+        prepgamesdirs
+
+        #make \
+        #       prefix=${D}/usr \
+        #       mandir=${D}/usr/share/man \
+        #       infodir=${D}/usr/share/info \
+        #       libdir=${D}/usr/$(get_libdir) \
+        #       install || die
+
+        #einstall || die
+}
+
+pkg_postinst() {
+        games_pkg_postinst
+}
Index: branches/heathaze/scripts/gentoo/orxonox-0.3.2_alpha-r7122.ebuild
===================================================================
--- branches/heathaze/scripts/gentoo/orxonox-0.3.2_alpha-r7122.ebuild	(revision 9940)
+++ branches/heathaze/scripts/gentoo/orxonox-0.3.2_alpha-r7122.ebuild	(revision 9940)
@@ -0,0 +1,80 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+# original comes from http://www.orxonox.net/ , 2006-02-11
+# modified/tested by S. Fuchs, http://srf.ch/ , 2006-02-11
+#
+# put this ebuild into your portage overlay: games-action/orxonox/
+# see /etc/make.conf to configure the portage overlay.
+# then cd into that games-action/orxonox/ directory and do:
+# $ ebuild orxonox-0.3.2_alpha-r7122.ebuild digest
+# $ emerge -av --oneshot orxonox
+# to install it (ommit the --oneshot to get an entry in your world file).
+#
+# put http://fuchs.dnsalias.net/public/orxonox/orxonox-0.3.2_alpha-r7122.tar.bz2
+# manually into your distfiles directory (usually /usr/portage/distfiles)
+# if it's not available from http://www.orxonox.net/files/snapshots/
+
+inherit eutils games
+
+DATA_VERSION=372
+
+DESCRIPTION="orxonox is an open-source 3D-action game programmed in C++, OpenGL, OpenAL and SDL"
+HOMEPAGE="http://www.orxonox.net"
+SRC_URI="http://www.orxonox.net/files/snapshots/${P}-${PR}.tar.bz2
+         http://www.orxonox.net/files/snapshots/${PN}-data-r${DATA_VERSION}.tar.bz2"
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="x86"
+IUSE="gtk+-2"
+
+DEPEND="virtual/opengl
+        virtual/x11
+        media-libs/openal
+        media-libs/libsdl
+        media-libs/sdl-image
+        media-libs/sdl-ttf
+        media-libs/sdl-net
+        media-libs/glew"
+
+# Run-time dependencies, same as DEPEND if RDEPEND isn't defined:
+#RDEPEND=""
+S=${WORKDIR}/${P}
+
+src_unpack() {
+        unpack ${P}-${PR}.tar.bz2
+        cd "${S}"
+        unpack ${PN}-data-r${DATA_VERSION}.tar.bz2
+}
+
+src_compile() {
+        egamesconf || die
+
+        emake || die "emake failed"
+}
+
+src_install() {
+        make DESTDIR=${D} install || die
+
+        dodir ${GAMES_DATADIR}/${PN}
+        cp -r data/* ${D}/${GAMES_DATADIR}/${PN}/ \
+                || die "data copy failed"
+
+        dodoc AUTHORS ChangeLog README
+
+        prepgamesdirs
+
+        #make \
+        #       prefix=${D}/usr \
+        #       mandir=${D}/usr/share/man \
+        #       infodir=${D}/usr/share/info \
+        #       libdir=${D}/usr/$(get_libdir) \
+        #       install || die
+
+        #einstall || die
+}
+
+pkg_postinst() {
+        games_pkg_postinst
+}
Index: branches/heathaze/scripts/gentoo/orxonox-0.3.2_alpha-rXXXX.ebuild
===================================================================
--- branches/heathaze/scripts/gentoo/orxonox-0.3.2_alpha-rXXXX.ebuild	(revision 9940)
+++ branches/heathaze/scripts/gentoo/orxonox-0.3.2_alpha-rXXXX.ebuild	(revision 9940)
@@ -0,0 +1,66 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit eutils games
+
+DATA_VERSION=83
+
+DESCRIPTION="orxonox is an open-source 3D-action game programmed in C++, OpenGL, OpenAL and SDL"
+HOMEPAGE="http://www.orxonox.net"
+SRC_URI="http://www.orxonox.net/files/snapshots/${P}-${PR}.tar.bz2
+         http://www.orxonox.net/files/snapshots/${PN}-data-r${DATA_VERSION}.tar.bz2"
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="x86"
+IUSE="gtk+-2"
+
+DEPEND="virtual/opengl
+        virtual/x11
+        media-libs/openal
+        media-libs/libsdl
+        media-libs/sdl-image
+        media-libs/sdl-ttf
+        media-libs/sdl-net
+        media-libs/glew"
+
+# Run-time dependencies, same as DEPEND if RDEPEND isn't defined:
+#RDEPEND=""
+S=${WORKDIR}/${P}
+
+src_unpack() {
+        unpack ${P}-${PR}.tar.bz2
+        cd "${S}"
+        unpack ${PN}-data-r${DATA_VERSION}.tar.bz2
+}
+
+src_compile() {
+        egamesconf || die
+
+        emake || die "emake failed"
+}
+
+src_install() {
+        make DESTDIR=${D} install || die
+
+        dodir ${GAMES_DATADIR}/${PN}
+        cp -r data/* ${D}/${GAMES_DATADIR}/${PN}/ \
+                || die "data copy failed"
+
+        dodoc AUTHORS ChangeLog README
+
+        prepgamesdirs
+
+        #make \
+        #       prefix=${D}/usr \
+        #       mandir=${D}/usr/share/man \
+        #       infodir=${D}/usr/share/info \
+        #       libdir=${D}/usr/$(get_libdir) \
+        #       install || die
+
+        #einstall || die
+}
+
+pkg_postinst() {
+        games_pkg_postinst
+}
Index: branches/heathaze/scripts/gtk-config.osXframework
===================================================================
--- branches/heathaze/scripts/gtk-config.osXframework	(revision 9940)
+++ branches/heathaze/scripts/gtk-config.osXframework	(revision 9940)
@@ -0,0 +1,112 @@
+#!/bin/sh
+
+glib_libs="-framework GLib"
+glib_cflags="-I/Library/Frameworks/GLib.framework/Headers"
+glib_thread_libs="-framework GLib -lpthread"
+glib_thread_cflags="-I/Library/Frameworks/GLib.framework/Headers"
+
+prefix=/Library/Frameworks
+gtk_fw_prefix=/Library/Frameworks
+exec_prefix=${prefix}
+exec_prefix_set=no
+
+usage()
+{
+        cat <<EOF
+Usage: gtk-config [OPTIONS] [LIBRARIES]
+Options:
+        [--prefix[=DIR]]
+        [--exec-prefix[=DIR]]
+        [--version]
+        [--libs]
+        [--cflags]
+Libraries:
+        gtk
+        gthread
+EOF
+        exit $1
+}
+
+if test $# -eq 0; then
+        usage 1 1>&2
+fi
+
+lib_gtk=yes
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      if test $exec_prefix_set = no ; then
+        exec_prefix=$optarg
+      fi
+      ;;
+    --prefix)
+      echo_prefix=yes
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      exec_prefix_set=yes
+      ;;
+    --exec-prefix)
+      echo_exec_prefix=yes
+      ;;
+    --version)
+      echo 1.2.10
+      ;;
+    --cflags)
+      echo_cflags=yes
+      ;;
+    --libs)
+      echo_libs=yes
+      ;;
+    gtk)
+      lib_gtk=yes
+      ;;
+    gthread)
+      lib_gthread=yes
+      ;;
+    *)
+      usage 1 1>&2
+      ;;
+  esac
+  shift
+done
+
+if test "$echo_prefix" = "yes"; then
+        echo $prefix
+fi
+
+if test "$echo_exec_prefix" = "yes"; then
+        echo $exec_prefix
+fi
+
+if test "$lib_gthread" = "yes"; then
+      glib_cflags="$glib_thread_cflags"
+      glib_libs="$glib_thread_libs"
+fi
+
+if test "$echo_cflags" = "yes"; then
+      echo -F${gtk_fw_prefix} ${glib_cflags} -I${gtk_fw_prefix}/GDK.framework/Headers -I${gtk_fw_prefix}/GTK.framework/Headers
+fi
+
+if test "$echo_libs" = "yes"; then
+      my_glib_libs=
+      libdirs=-F${exec_prefix}
+      for i in $glib_libs ; do
+        if test $i != -F${exec_prefix} ; then
+          if test -z "$my_glib_libs" ; then
+            my_glib_libs="$i"
+          else
+            my_glib_libs="$my_glib_libs $i"
+          fi
+        fi
+      done
+
+      echo $libdirs -F${gtk_fw_prefix} -framework GLib -framework GDK -framework GTK ${glib_cflags} -lm
+fi
Index: branches/heathaze/scripts/orxodox_checkFiles.pl
===================================================================
--- branches/heathaze/scripts/orxodox_checkFiles.pl	(revision 9940)
+++ branches/heathaze/scripts/orxodox_checkFiles.pl	(revision 9940)
@@ -0,0 +1,294 @@
+#!/usr/bin/perl
+##########################################################################
+#   orxonox - the future of 3D-vertical-scrollers                        #
+#                                                                        #
+#   Copyright (C) 2004 orx                                               #
+#                                                                        #
+#   This program is free software; you can redistribute it and/or modify #
+#   it under the terms of the GNU General Public License as published by #
+#   the Free Software Foundation; either version 2, or (at your option)  #
+#   any later version.                                                   #
+#                                                                        #
+#   ### File Specific:                                                   #
+#   main-programmer: Benjamin Grauer                                     #
+#   co-programmer: ...                                                   #
+#                                                                        #
+#   This Script is for parsing single or multiple files for their        #
+#   doxygeb-tags, and outputs the warnings and errors, but prehibits     #
+#   the progress from being displayed.                                   #
+#   Usage: ./orxodox.checkFiles.pl [fileName1 [fileName2 [...]]]         #
+#   This script ignores file-extensions, and assumes that either         #
+#   .h, .cc or both may exist, and searches for them.                    #
+##########################################################################
+
+$inputFiles = @ARGV[0];
+$tempDoxFile = "TMPorxodox";
+
+unless (open (DOXfile, ">$tempDoxFile"))
+ {
+   die("cannot open file\n");
+ }
+
+$processFiles = "";
+$numberOfFiles = 0;
+foreach $inputFile (@ARGV)
+  {
+    $tmpNumber = $numberOfFiles;
+
+    $inputFile =~ s/\.cc$//;
+    $inputFile =~ s/\.h$//;
+
+    print "checking file $inputFile: ";
+
+    $inputFile =~ s/$/\.h/;
+    if (-e $inputFile)
+      {
+        $processFiles = "$processFiles $inputFile";
+        $numberOfFiles++;
+        print "found .h ";
+      }
+    $inputFile =~ s/\.h$/\.cc/;
+    if (-e $inputFile)
+      {
+        $processFiles = "$processFiles $inputFile";
+        $numberOfFiles++;
+        print "...found .cc ";
+      }
+    if ($tmpNumber == $numberOfFiles) {print "no matching files found";}
+    print "\n";
+  }
+
+if ($numberOfFiles == 0 && @ARGV !=0){
+  die("no Files have been found\n");}
+
+print "==================================================================\n";
+print "Generating temporary Documentation File\n";
+print "==================================================================\n";
+
+print DOXfile "# THIS IS A DEFAULT FILE FOR DOXYGEN DOCUMENTATION";
+
+printf DOXfile "# Doxyfile 1.3.7 \
+## SAMPLE FILE (to be executed from orxonox/trunk/) \
+ \
+#--------------------------------------------------------------------------- \
+# Project related configuration options \
+#--------------------------------------------------------------------------- \
+PROJECT_NAME           = orxonox \
+PROJECT_NUMBER         = 1 \
+OUTPUT_DIRECTORY       = doxygen/ \
+CREATE_SUBDIRS         = YES \
+OUTPUT_LANGUAGE        = English \
+USE_WINDOWS_ENCODING   = YES \
+BRIEF_MEMBER_DESC      = YES \
+REPEAT_BRIEF           = YES \
+ABBREVIATE_BRIEF       =  \
+ALWAYS_DETAILED_SEC    = NO \
+INLINE_INHERITED_MEMB  = NO \
+FULL_PATH_NAMES        = NO \
+STRIP_FROM_PATH        =  \
+STRIP_FROM_INC_PATH    =  \
+SHORT_NAMES            = NO \
+JAVADOC_AUTOBRIEF      = NO \
+MULTILINE_CPP_IS_BRIEF = NO \
+DETAILS_AT_TOP         = NO \
+INHERIT_DOCS           = YES \
+DISTRIBUTE_GROUP_DOC   = NO \
+TAB_SIZE               = 8 \
+ALIASES                =  \
+OPTIMIZE_OUTPUT_FOR_C  = NO \
+OPTIMIZE_OUTPUT_JAVA   = NO \
+SUBGROUPING            = YES \
+#--------------------------------------------------------------------------- \
+# Build related configuration options \
+#--------------------------------------------------------------------------- \
+EXTRACT_ALL            = NO \
+EXTRACT_PRIVATE        = YES \
+EXTRACT_STATIC         = YES \
+EXTRACT_LOCAL_CLASSES  = YES \
+EXTRACT_LOCAL_METHODS  = NO \
+HIDE_UNDOC_MEMBERS     = NO \
+HIDE_UNDOC_CLASSES     = NO \
+HIDE_FRIEND_COMPOUNDS  = NO \
+HIDE_IN_BODY_DOCS      = NO \
+INTERNAL_DOCS          = NO \
+CASE_SENSE_NAMES       = YES \
+HIDE_SCOPE_NAMES       = NO \
+SHOW_INCLUDE_FILES     = YES \
+INLINE_INFO            = YES \
+SORT_MEMBER_DOCS       = YES \
+SORT_BRIEF_DOCS        = NO \
+SORT_BY_SCOPE_NAME     = NO \
+GENERATE_TODOLIST      = YES \
+GENERATE_TESTLIST      = YES \
+GENERATE_BUGLIST       = YES \
+GENERATE_DEPRECATEDLIST= YES \
+ENABLED_SECTIONS       =  \
+MAX_INITIALIZER_LINES  = 30 \
+SHOW_USED_FILES        = YES \
+#--------------------------------------------------------------------------- \
+# configuration options related to warning and progress messages \
+#--------------------------------------------------------------------------- \
+QUIET                  = YES \
+WARNINGS               = YES \
+WARN_IF_UNDOCUMENTED   = YES \
+WARN_IF_DOC_ERROR      = YES \
+WARN_FORMAT            = \"\$file:\$line: \$text\" \
+WARN_LOGFILE           =  \
+#--------------------------------------------------------------------------- \
+# configuration options related to the input files \
+#--------------------------------------------------------------------------- \
+INPUT                  = $processFiles \
+FILE_PATTERNS          =  \
+RECURSIVE              = NO \
+EXCLUDE                =  \
+EXCLUDE_SYMLINKS       = NO \
+EXCLUDE_PATTERNS       =  \
+EXAMPLE_PATH           =  \
+EXAMPLE_PATTERNS       =  \
+EXAMPLE_RECURSIVE      = NO \
+IMAGE_PATH             =  \
+INPUT_FILTER           =  \
+FILTER_SOURCE_FILES    = NO \
+#--------------------------------------------------------------------------- \
+# configuration options related to source browsing \
+#--------------------------------------------------------------------------- \
+SOURCE_BROWSER         = NO \
+INLINE_SOURCES         = NO \
+STRIP_CODE_COMMENTS    = YES \
+REFERENCED_BY_RELATION = YES \
+REFERENCES_RELATION    = YES \
+VERBATIM_HEADERS       = YES \
+#--------------------------------------------------------------------------- \
+# configuration options related to the alphabetical class index \
+#--------------------------------------------------------------------------- \
+ALPHABETICAL_INDEX     = NO \
+COLS_IN_ALPHA_INDEX    = 5 \
+IGNORE_PREFIX          =  \
+#--------------------------------------------------------------------------- \
+# configuration options related to the HTML output \
+#--------------------------------------------------------------------------- \
+GENERATE_HTML          = YES \
+HTML_OUTPUT            = html \
+HTML_FILE_EXTENSION    = .html \
+HTML_HEADER            =  \
+HTML_FOOTER            =  \
+HTML_STYLESHEET        =  \
+HTML_ALIGN_MEMBERS     = YES \
+GENERATE_HTMLHELP      = NO \
+CHM_FILE               =  \
+HHC_LOCATION           =  \
+GENERATE_CHI           = NO \
+BINARY_TOC             = NO \
+TOC_EXPAND             = NO \
+DISABLE_INDEX          = NO \
+ENUM_VALUES_PER_LINE   = 4 \
+GENERATE_TREEVIEW      = NO \
+TREEVIEW_WIDTH         = 250 \
+#--------------------------------------------------------------------------- \
+# configuration options related to the LaTeX output \
+#--------------------------------------------------------------------------- \
+GENERATE_LATEX         = NO \
+LATEX_OUTPUT           = latex \
+LATEX_CMD_NAME         = latex \
+MAKEINDEX_CMD_NAME     = makeindex \
+COMPACT_LATEX          = NO \
+PAPER_TYPE             = a4wide \
+EXTRA_PACKAGES         =  \
+LATEX_HEADER           =  \
+PDF_HYPERLINKS         = NO \
+USE_PDFLATEX           = NO \
+LATEX_BATCHMODE        = NO \
+LATEX_HIDE_INDICES     = NO \
+#--------------------------------------------------------------------------- \
+# configuration options related to the RTF output \
+#--------------------------------------------------------------------------- \
+GENERATE_RTF           = NO \
+RTF_OUTPUT             = rtf \
+COMPACT_RTF            = NO \
+RTF_HYPERLINKS         = NO \
+RTF_STYLESHEET_FILE    =  \
+RTF_EXTENSIONS_FILE    =  \
+#--------------------------------------------------------------------------- \
+# configuration options related to the man page output \
+#--------------------------------------------------------------------------- \
+GENERATE_MAN           = NO \
+MAN_OUTPUT             = man \
+MAN_EXTENSION          = .3 \
+MAN_LINKS              = NO \
+#--------------------------------------------------------------------------- \
+# configuration options related to the XML output \
+#--------------------------------------------------------------------------- \
+GENERATE_XML           = NO \
+XML_OUTPUT             = xml \
+XML_SCHEMA             =  \
+XML_DTD                =  \
+XML_PROGRAMLISTING     = YES \
+#--------------------------------------------------------------------------- \
+# configuration options for the AutoGen Definitions output \
+#--------------------------------------------------------------------------- \
+GENERATE_AUTOGEN_DEF   = NO \
+#--------------------------------------------------------------------------- \
+# configuration options related to the Perl module output \
+#--------------------------------------------------------------------------- \
+GENERATE_PERLMOD       = NO \
+PERLMOD_LATEX          = NO \
+PERLMOD_PRETTY         = YES \
+PERLMOD_MAKEVAR_PREFIX =  \
+#--------------------------------------------------------------------------- \
+# Configuration options related to the preprocessor    \
+#--------------------------------------------------------------------------- \
+ENABLE_PREPROCESSING   = YES \
+MACRO_EXPANSION        = NO \
+EXPAND_ONLY_PREDEF     = NO \
+SEARCH_INCLUDES        = YES \
+INCLUDE_PATH           =  \
+INCLUDE_FILE_PATTERNS  =  \
+PREDEFINED             =  \
+EXPAND_AS_DEFINED      =  \
+SKIP_FUNCTION_MACROS   = YES \
+#--------------------------------------------------------------------------- \
+# Configuration::additions related to external references    \
+#--------------------------------------------------------------------------- \
+TAGFILES               =  \
+GENERATE_TAGFILE       =  \
+ALLEXTERNALS           = NO \
+EXTERNAL_GROUPS        = YES \
+PERL_PATH              = /usr/bin/perl \
+#--------------------------------------------------------------------------- \
+# Configuration options related to the dot tool    \
+#--------------------------------------------------------------------------- \
+CLASS_DIAGRAMS         = YES \
+HIDE_UNDOC_RELATIONS   = YES \
+HAVE_DOT               = NO \
+CLASS_GRAPH            = YES \
+COLLABORATION_GRAPH    = YES \
+UML_LOOK               = NO \
+TEMPLATE_RELATIONS     = NO \
+INCLUDE_GRAPH          = YES \
+INCLUDED_BY_GRAPH      = YES \
+CALL_GRAPH             = NO \
+GRAPHICAL_HIERARCHY    = YES \
+DOT_IMAGE_FORMAT       = png \
+DOT_PATH               =  \
+DOTFILE_DIRS           =  \
+MAX_DOT_GRAPH_WIDTH    = 1024 \
+MAX_DOT_GRAPH_HEIGHT   = 1024 \
+MAX_DOT_GRAPH_DEPTH    = 0 \
+GENERATE_LEGEND        = YES \
+DOT_CLEANUP            = YES \
+#--------------------------------------------------------------------------- \
+# Configuration::additions related to the search engine    \
+#--------------------------------------------------------------------------- \
+SEARCHENGINE           = NO \
+ \
+";
+
+close DOXfile;
+
+print "==================================================================\n";
+print "Generating Documentation of $processFiles\n";
+print "==================================================================\n";
+exec("doxygen $tempDoxFile");
+
+
+unlink $tmpDoxFile;
Index: branches/heathaze/scripts/orxonoxServer.sh
===================================================================
--- branches/heathaze/scripts/orxonoxServer.sh	(revision 9940)
+++ branches/heathaze/scripts/orxonoxServer.sh	(revision 9940)
@@ -0,0 +1,45 @@
+#!/bin/bash
+##########################################################################
+#   orxonox - the future of 3D-vertical-scrollers                        #
+#                                                                        #
+#   Copyright (C) 2004 orx                                               #
+#                                                                        #
+#   This program is free software; you can redistribute it and/or modify #
+#   it under the terms of the GNU General Public License as published by #
+#   the Free Software Foundation; either version 2, or (at your option)  #
+#   any later version.                                                   #
+#                                                                        #
+#   ### File Specific:                                                   #
+#   main-programmer: Christoph Renner                                    #
+#   co-programmer: ...                                                   #
+#                                                                        #
+#                                                                        #
+#   This script starts an orxonox server and restarts it when it crashes.#
+#   it also creates a logfile for each start                             #
+#                                                                        #
+##########################################################################
+
+
+PORT="9999"
+
+ORXONOXBINARY="./orxonox"
+LOGDIR="/tmp/orxonox_log"
+LOGPREFIX="orxonox"
+SLEEPTIME="5"
+
+ORXONOXOPTIONS=" --dedicated-server $PORT"
+
+while true; do
+	SD=$(date +'%Y-%m-%d-%H:%M:%S');
+	CMDLINE="$ORXONOXBINARY $ORXONOXOPTIONS"
+	LOGFILE="$LOGDIR/$LOGPREFIX-$SD.log"
+	echo $CMDLINE;
+	nice $CMDLINE &> "$LOGFILE";
+
+	echo "Now is $(date +'%Y-%m-%d-%H:%M:%S')" >> "$LOGFILE";
+
+	echo -e "\n\n\nyou have $SLEEPTIME s to kill this script\n\n\n";
+	sleep $SLEEPTIME
+done
+
+
Index: branches/heathaze/scripts/tardis-scratch-checkout.pl
===================================================================
--- branches/heathaze/scripts/tardis-scratch-checkout.pl	(revision 9940)
+++ branches/heathaze/scripts/tardis-scratch-checkout.pl	(revision 9940)
@@ -0,0 +1,61 @@
+#!/usr/bin/perl
+
+
+
+$source = @ARGV[0];
+if ($source eq "help" || $source eq "h"){
+    print "ORXONOX checkout script for Tardis:\n usage:\n tardis-scratch-checkout.pl [branche]\n";
+    exit;
+  }
+if ($source eq "") {
+    $source = "trunk";
+  }
+
+$username = `whoami`;
+chomp $username;
+
+
+$URL = "https://svn.orxonox.net/orxonox/$source";
+$destination = "/scratch/$username\/orxonox/$source";
+
+  mkdir ("/scratch/$username");
+  mkdir ("/scratch/$username\/orxonox");
+
+  print("Checking out ORXONOX from '$URL' to '$destination'\n");
+
+  if (-e $destination)
+  {
+   open(SVN_UP, "svn up $destination |");
+   while(<SVN_UP>) {
+   print $_;
+   }
+  }
+  else
+  {
+   open(SVN_CO, "svn co $URL $destination |");
+   while(<SVN_CO>){
+    print $_;
+   }
+  }
+  chdir("$destination");
+
+
+  print "executing autogen.sh\n";
+  open( AUTOGEN , "./autogen.sh |");
+  while(<AUTOGEN>){
+   print $_;
+  }
+
+  print "executing configure for tardis\n";
+  open(CONFIGURE, "./configure --with-tardis |");
+  while(<CONFIGURE>){
+    printf $_;
+  }
+
+  print ("Executing make with opts -j3\n");
+  open(MAKE, "make -j3|");
+  while(<MAKE>) {
+    print $_;
+  }
+  printf("Finished checking out '$URL' to '$destination'\n");
+
Index: branches/heathaze/scripts/valgrind/nv.sup
===================================================================
--- branches/heathaze/scripts/valgrind/nv.sup	(revision 9940)
+++ branches/heathaze/scripts/valgrind/nv.sup	(revision 9940)
@@ -0,0 +1,81 @@
+{
+   Nvidia01
+   Memcheck:Param
+   ioctl(generic)
+   fun:ioctl
+   obj:/usr/lib/nvidia-7676/lib/libGL.so.1.0.7676
+}
+
+{
+   NVidia02
+   Memcheck:Cond
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+}
+{
+   NVidia03
+   Memcheck:Addr4
+   obj:/usr/lib/nvidia-7676/lib/libGL.so.1.0.7676
+}
+{
+   NV04
+   Memcheck:Cond
+   fun:_nv000027gl
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+}
+{
+   NV05
+   Memcheck:Param
+   ioctl(generic)
+   fun:ioctl
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+   obj:*
+}
+{
+   NV06
+   Memcheck:Cond
+   fun:_nv000028gl
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+   obj:*
+}
+
+{
+   NV07
+   Memcheck:Param
+   ioctl(generic)
+   fun:ioctl
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+   obj:*
+}
+{
+   NV08
+   Memcheck:Cond
+   fun:_nv000028gl
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+   obj:*
+}
+{
+   NV09
+   Memcheck:Cond
+   fun:strcat
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+}
+
+{
+   GFX-Engine
+   Memcheck:Param
+   writev(vector[...])
+   obj:/lib/tls/libc-2.3.2.so
+   fun:writev
+   obj:/usr/X11R6/lib/libX11.so.6.2
+   fun:_X11TransWritev
+   fun:_XSend
+   fun:XStoreColors
+   fun:X11_SetGammaRamp
+   fun:X11_CreateWindow
+   fun:X11_SetVideoMode
+   fun:SDL_SetVideoMode
+   fun:_ZN14GraphicsEngine13setResolutionEiii
+   fun:_ZN14GraphicsEngine9initVideoEjjj
+}
+
+
Index: branches/heathaze/src/INSTALL
===================================================================
--- branches/heathaze/src/INSTALL	(revision 9940)
+++ branches/heathaze/src/INSTALL	(revision 9940)
@@ -0,0 +1,41 @@
+
+INSTALLATION INSTRUCTIONS FOR ORXONOX
+=====================================
+
+INSTALLATION
+============
+
+To make it quite easy for those of you who just want to install orxonox:
+
+1. ./configure
+2. make
+3. make install
+
+DEPENDENCIES
+============
+
+There are some dependencies for orxonox you have to install:
+
+1. SDL           (http://www.libsdl.org)
+2. OPENGL        (http://www.opengl.org)
+3. SDL_mixer     (http://www.libsdl.org/projects/SDL_mixer)
+4. SDL_image     (http://www.libsdl.org/projects/SDL_image)
+5. SDL_ttf       (http://www.libsdl.org/projects/SDL_ttf)
+ a) needs libttf (http://www.freetype.org/)
+
+Nice to Have:
+6. Doxygen       (http://www.stack.nl/~dimitri/doxygen/)
+7. Automake	 (http://www.gnu.org/software/automake/)
+8. Autoconf      (http://www.gnu.org/software/autoconf/)
+
+Windows Users also need the following:
+9. mingw         (http://mingw.org/)
+
+
+BUGS
+====
+Send bug reports to orxonox-dev@mail.datacore.ch
+
+
+
+#EOF
Index: branches/heathaze/src/Makefile.am
===================================================================
--- branches/heathaze/src/Makefile.am	(revision 9940)
+++ branches/heathaze/src/Makefile.am	(revision 9940)
@@ -0,0 +1,100 @@
+MAINSRCDIR=.
+include $(MAINSRCDIR)/defs/include_paths.am
+
+include world_entities/WorldEntities.am
+include story_entities/Makefile.am
+
+LIB_PREFIX=lib
+include lib/BuildLibs.am
+
+#"-O3 -pedantic -fPIC -ffast-math -I/usr/X11R6/include"
+
+bin_PROGRAMS = orxonox
+
+orxonox_CPPFLAGS = \
+		-DIS_ORXONOX \
+		@QT_CXXFLAGS@
+
+orxonox_LDFLAGS = @QT_LDFLAGS@
+
+orxonox_DEPENDENCIES = \
+		world_entities/libORXwe.a \
+		util/libORXutils.a \
+		$(libORXlibs_a_LIBRARIES_)
+
+orxonox_LDADD = \
+		world_entities/libORXwe.a \
+		util/libORXutils.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(CURL_LIBS) \
+		@QT_LIBS@ \
+		-L../extern_libs @LUA_LIBS@
+
+orxonox_SOURCES = \
+		$(WorldEntities_SOURCES_) \
+		$(StoryEntities_SOURCES_) \
+		lib/shell/some_shell_commands.cc \
+		orxonox.cc \
+		\
+		util/multiplayer_team_deathmatch.cc \
+		util/singleplayer_shootemup.cc \
+		\
+		util/kill_target.cc \
+		\
+		subprojects/benchmark.cc
+
+noinst_HEADERS = \
+		$(StoryEntities_HEADERS_) \
+		orxonox.h \
+		ability.h \
+		defs/message_structures.h \
+		defs/stdincl.h \
+		defs/stdlibincl.h \
+		defs/sdlincl.h \
+		defs/glincl.h \
+		defs/alincl.h \
+		defs/comincl.h \
+		defs/confincl.h \
+		defs/error.h \
+		defs/globals.h \
+		defs/compiler.h \
+		defs/class_id_DEPRECATED.h \
+		subprojects/benchmark.h
+
+## orxonox.conf will be used from home-dir instead.
+EXTRA_DIST = \
+		proto/proto_class.h \
+		proto/proto_class.cc \
+		proto/proto_singleton.h \
+		proto/proto_singleton.cc \
+		proto/proto_world_entity.h \
+		proto/proto_world_entity.cc \
+		defs/include_paths.am \
+		story_entities/Makefile.am
+
+if SUB_PROJECTS
+  SUB_PROGS = subprojects
+else
+  SUB_PROGS =
+endif
+
+SUBDIRS = \
+		lib \
+		util \
+		world_entities \
+		. \
+		$(SUB_PROGS)
+
+
+#EXTRA_DIST=orxonox.lsm.in orxonox.spec.in orxonox.texinfo
+
+#  if you write a self-test script named `chk', uncomment the
+#  following and add `chk' to the EXTRA_DIST list
+#TESTS=chk
+
+#  build and install the .info pages
+#info_TEXINFOS = orxonox.texinfo
+#orxonox_TEXINFOS = gpl.texinfo
+
+#  install the man pages
+#man_MANS=orxonox.1
Index: branches/heathaze/src/ability.cc
===================================================================
--- branches/heathaze/src/ability.cc	(revision 9940)
+++ branches/heathaze/src/ability.cc	(revision 9940)
@@ -0,0 +1,32 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+#include "ability.h"
+
+
+
+
+
+
+Ability::Ability () {}
+
+
+
+Ability::~Ability () {}
+
+
Index: branches/heathaze/src/ability.h
===================================================================
--- branches/heathaze/src/ability.h	(revision 9940)
+++ branches/heathaze/src/ability.h	(revision 9940)
@@ -0,0 +1,16 @@
+
+#ifndef _ABILITY_H
+#define _ABILITY_H
+
+#include "data_tank.h"
+
+
+class Ability {
+
+ public:
+  Ability ();
+  virtual ~Ability ();
+
+};
+
+#endif /* _ABILITY_H */
Index: branches/heathaze/src/ai/ai.cc
===================================================================
--- branches/heathaze/src/ai/ai.cc	(revision 9940)
+++ branches/heathaze/src/ai/ai.cc	(revision 9940)
@@ -0,0 +1,32 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+#include "ai.h"
+
+
+
+
+
+
+AI::AI () {}
+
+
+
+AI::~AI () {}
+
+
Index: branches/heathaze/src/ai/ai.h
===================================================================
--- branches/heathaze/src/ai/ai.h	(revision 9940)
+++ branches/heathaze/src/ai/ai.h	(revision 9940)
@@ -0,0 +1,14 @@
+
+#ifndef _AI_H
+#define _AI_H
+
+
+class AI {
+
+ public:
+  AI ();
+  virtual ~AI ();
+
+};
+
+#endif /* _AI_H */
Index: branches/heathaze/src/defs/alincl.h
===================================================================
--- branches/heathaze/src/defs/alincl.h	(revision 9940)
+++ branches/heathaze/src/defs/alincl.h	(revision 9940)
@@ -0,0 +1,17 @@
+/*!
+ * This file includes openAL-Headers.
+ * @file alincl.h
+*/
+
+#ifndef _ALINCL_H
+#define _ALINCL_H
+
+#ifdef __APPLE__
+#include <OpenAL/al.h>
+#include <OpenAL/alc.h>
+#else
+#include <AL/al.h>
+#include <AL/alc.h>
+#endif
+
+#endif /* _ALINCL_H */
Index: branches/heathaze/src/defs/class_id_DEPRECATED.h
===================================================================
--- branches/heathaze/src/defs/class_id_DEPRECATED.h	(revision 9940)
+++ branches/heathaze/src/defs/class_id_DEPRECATED.h	(revision 9940)
@@ -0,0 +1,465 @@
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+
+   2005-06-10: (bensch) added new sturcture to support multiple inheritance
+*/
+
+/*!
+ * @file class_id_DEPRECATED.h
+ * @brief contains a list of orxonox ClassID's (identities to register classes and their SuperClasses)
+ *
+ *  this File is used to identify an Object with its Class and also with its sub/super-classes.
+ *  this is also used by the ObjectManager/Factory to identify and load important classes
+ *
+ *  !! important !!
+ *  When adding a new CLASS be sure about the following:
+ *    1. if it is a (SUB)SUPERCLASS make sure there is still space left (if not think of a new approach)
+ *    2. check if the Number you add is not refered twice, and that with (SUB)SUPERCLASSES there are no intersections
+ *    3. be sure to add you stuff in the right section, and don't interest yourself for the order of things. :)
+ */
+
+#ifndef _CLASS_ID___DEPRECATED___H
+#define _CLASS_ID___DEPRECATED___H
+
+//! list of all classes to be loadable in via the ObjectManager
+/**
+ *
+ * -------------------------------------------------------------------------------------------
+ * Consider the Identifiers 0xABCDEFGH
+ * The first two: A and B are superclass Identifiers !! THEY ARE ALREADY FULL !!
+ *
+ * The second three are for sub-superclass-groups inheritance:
+ *  C: a Group identifier: can be anything from 1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h
+ *  D,E: Member within the Group, to specify further deriavtions within the Group.
+ *       These may be anything from 1,2,4,8 (at D and E)
+ *  !! consider, that you __may not__ have a derivated class from group a and group b.
+ *
+ * The last three entries F,G,H are for any leaf classes in existence.
+ * they are ordered in the following way:
+ *  F: LEAF-GroupSpecifier
+ *  G,H: UNIQUE NUMBER eithin F-Group.
+ *
+ * You only have to extend the Class with your ClassID-tag.
+ * If something goes Wrong, you get an Assertion-Warning in BaseObject.
+ * !! Abstrace/Non-total-leaf classes do not have a LEAF-part.
+ * -------------------------------------------------------------------------------------------
+ *
+ * COUNT:
+ * -> # max SuperClass-count        = 7 (not intersecting)
+ *    # max SubSuperClass-count     = 15*7 = 105 (the 7 classes will be able to get derived from each other, but not over the SubSuperClass.)
+ *    # max lowerClasses-count      = 3^16 = enough (they are Leaves, and may NOT be derived by any other class.)
+ */
+typedef enum ClassID_DEPRICATED
+{
+  // the Nothing CLASS (NULL)
+  CL_NULL                       =    0x00000000,
+
+  /// SUPER-classes
+  CL_MASK_SUPER_CLASS           =    0xff000000,
+  CL_BASE_OBJECT                =    0x00000000,
+
+  CL_PARENT_NODE                =    0x01000000,
+
+  CL_STORY_ENTITY               =    0x02000000,
+
+  CL_PHYSICS_INTERFACE          =    0x04000000,
+
+  CL_EVENT_LISTENER             =    0x08000000,
+
+  CL_ELEMENT_2D                 =    0x10000000,
+
+  CL_SYNCHRONIZEABLE            =    0x20000000,
+
+  CL_WORLD_ENTITY               =    0x40000000,
+
+  /// subsuper-classes
+  // subsuper-classes derivations taken : 1, 2, 5, a, b, c.   << THIS IS A LIST OF ALL THE DCL_MASK_SUBSUPERCLASS_ID's taken
+  CL_MASK_SUBSUPER_CLASS        =    0x00fff000,
+  CL_MASK_SUBSUPER_CLASS_IDA    =    0x00f00000,
+  CL_MASK_SUBSUPER_CLASS_IDB    =    0x000ff000,
+
+  // lowest level classes
+  // These are also referenced to as Leaf-classes
+  CL_MASK_LOWLEVEL_CLASS        =    0x00000fff,
+
+  CL_PREFERENCES                =    0X00000f51,
+
+  /// SINGLETON classes (range from 0x00000000 to 0x000000ff)
+  CL_MASK_SINGLETON             =    0x00000000,
+  CL_ORXONOX                    =    0x00000001,
+  CL_NULL_PARENT                =    0x00000002,
+  CL_PILOT_PARENT               =    0x00000003,
+  CL_OBJECT_MANAGER             =    0x00000004,
+  CL_RESOURCE_MANAGER           =    0x00000005,
+  CL_GARBAGE_COLLECTOR          =    0x00000006,
+  CL_GAME_LOADER                =    0x00000007,
+  CL_GRAPHICS_ENGINE            =    0x00000008,
+  CL_TEXT_ENGINE                =    0x00000009,
+  CL_LIGHT_MANAGER              =    0x0000000a,
+  CL_EVENT_HANDLER              =    0x0000000b,
+  CL_PHYSICS_ENGINE             =    0x0000000c,
+  CL_CD_ENGINE                  =    0x0000000d,
+  CL_PARTICLE_ENGINE            =    0x0000000e,
+  CL_SOUND_ENGINE               =    0x0000000f,
+  CL_ANIMATION_PLAYER           =    0x00000010,
+  CL_TRACK_MANAGER              =    0x00000011,
+  CL_TRACK_NODE                 =    0x00000012,
+  CL_STATE                      =    0x00000013,
+  CL_FRAMEWORK                  =    0x00000014,
+  CL_CR_ENGINE                  =    0x00000015,
+  CL_RENDER_2D                  =    0x00000021,
+  CL_NULL_ELEMENT_2D            =    0x00000022,
+  CL_SHELL_BUFFER               =    0x00000032,
+  CL_GLGUI_HANDLER              =    0x00000040,
+  CL_GLGUI_MAIN_WIDGET          =    0x00000041,
+  CL_NETWORK_MANAGER            =    0x00000050,
+  CL_SHARED_NETWORK_DATA        =    0x00000051,
+  CL_NETWORK_SETTINGS           =    0x00000052,
+  CL_ATMOSPHERIC_ENGINE         =    0x00000061,
+
+  /// StoryEntities (range from 0x00000100 to 0x000001ff)
+  CL_GAME_WORLD                 =    0x00101000,
+  CL_GAME_WORLD_DATA            =    0x00102000,
+  CL_GAME_RULES                 =    0x00104000,
+  CL_NETWORK_GAME_RULES         =    0x00108000,
+  CL_MISSION_GOAL               =    0x00110000,
+
+  CL_CAMPAIGN                   =    0x00000101,
+  CL_CAMPAIGN_DATA              =    0x00000102,
+  CL_SIMPLE_GAME_MENU           =    0x00000103,
+  CL_SIMPLE_GAME_MENU_DATA      =    0x00000104,
+  CL_SINGLE_PLAYER_WORLD        =    0x00000105,
+  CL_SINGLE_PLAYER_WORLD_DATA   =    0x00000106,
+  CL_MULTI_PLAYER_WORLD         =    0x00000107,
+  CL_MULTI_PLAYER_WORLD_DATA    =    0x00000108,
+  CL_MOVIE_LOADER               =    0x00000109,
+
+  CL_GAME_MENU                  =    0x00000110,
+  CL_GAME_MENU_DATA             =    0x00000111,
+
+
+  CL_MULTIPLAYER_TEAM_DEATHMATCH=    0x00000121,
+  CL_SINGLEPLAYER_SHOOTEMUP     =    0x00000122,
+
+  CL_KILL_TARGET                =    0x00105001,
+
+
+  /// SUPER-PNodes
+  CL_FIELD                      =    0x00201000,
+
+  /// PNodes
+  CL_CAMERA                     =    0x00000201,
+  CL_CAMERA_TARGET              =    0x00000202,
+
+
+  /// SUPER-WorldEntities
+  CL_PLAYER                     =    0x00302000,
+
+  CL_PLAYABLE                   =    0x00301000,
+  CL_NPC                        =    0x00304000,
+  CL_PROJECTILE                 =    0x00308000,
+  CL_WEAPON                     =    0x00310000,
+  CL_POWER_UP                   =    0x00320000,
+  CL_EXTENDABLE                 =    0x00340000,
+
+  /// WorldEntities (range from 0x00000300 to 0x000005ff)
+  // Environments
+  CL_ENVIRONMENT                =    0x00000303,
+  CL_SATELLITE                  =    0x00000304,
+  CL_SKYBOX                     =    0x00000305,
+  CL_SKYSPHERE                  =    0x00000306,
+  CL_TERRAIN                    =    0x00000307,
+  CL_WATER                      =    0x00000308,
+  CL_PLANET                     =    0x00000309,
+  CL_BUILDING                   =    0x00000310,
+  CL_MAPPED_WATER               =    0x00000311,
+  CL_BSP_ENTITY                 =    0x00000312,
+  CL_SKYDOME                    =    0x00000313,
+  CL_DOOR                       =    0x00000314,
+  CL_REPAIR_STATION             =    0x00000315,
+  CL_CRANE                      =    0x00000316,
+  CL_BRAKING_WALL               =    0X00000317,
+  CL_AIMING_SYSTEM              =    0x00000318,
+  CL_GATE                       =    0x00000319,
+
+  // Playables
+  CL_SPACE_SHIP                 =    0x0000035a,
+  CL_HELICOPTER                 =    0x0000035b,
+  CL_SPAWNING_POINT             =    0x0000035c,
+  CL_MD2_CREATURE               =    0x0000035d,
+  CL_HOVER                      =    0x0000035e,
+  CL_TURBINE_HOVER              =    0x0000035f,
+  CL_SPACECRAFT_2D              =    0x00000360,
+  CL_CRUIZER                    =    0x00000361,
+  CL_SPECTATOR                  =    0x0000036a,
+  CL_COLLISION_PROBE            =    0x0000036b,
+  CL_FPS_PLAYER                 =    0x0000036c,
+
+  // Powerups
+  CL_TURRET_POWER_UP            =    0x00000381,
+  CL_LASER_POWER_UP             =    0x00000382,
+  CL_WEAPON_POWER_UP            =    0x00000383,
+  CL_PARAM_POWER_UP             =    0x00000384,
+
+  // Weapons
+  CL_TEST_GUN                   =    0x000003a0,
+  CL_LASER_CANNON               =    0x000003a1,
+  CL_TURRET                     =    0x000003a2,
+  CL_AIMING_TURRET              =    0x000003a3,
+  CL_CANNON                     =    0x000003a4,
+  CL_TARGETING_TURRET           =    0x000003a5,
+  CL_HYPERBLASTER               =    0x000003a6,
+  CL_FPS_SNIPER_RIFLE           =    0x000003a7,
+  CL_FPS_LASER_RIFLE            =    0x000003a8,
+  CL_BOOMERANG_GUN              =    0x000003a9,
+
+  // Projectiles
+  CL_TEST_BULLET                =    0x000003e0,
+  CL_ROCKET                     =    0x000003e1,
+  CL_LASER                      =    0x000003e2,
+  CL_RAIL_PROJECTILE            =    0x000003e3,
+  CL_BOMB                       =    0x000003e4,
+  CL_GROUND_TURRET              =    0x000003e5,
+  CL_SPACE_TURRET               =    0x000003e6,
+  CL_NETWORK_TURRET             =    0x000003e7,
+  CL_GUIDED_MISSILE             =    0x000003e8,
+  CL_HYPERBLAST                 =    0x000003e9,
+  CL_BOOMERANG_PROJECTILE       =    0x000003ea,
+
+  // NPC's
+  CL_NPC_TEST1                  =    0x00000401,
+  CL_NPC_TEST2                  =    0x00000402,
+  CL_GENERIC_NPC                =    0x00000403,
+  CL_ATTRACTOR_MINE             =    0x00000404,
+
+  // Testing Entities
+  CL_TEST_ENTITY                =    0x00000409,
+
+  // misc
+  CL_MOVIE_ENTITY               =    0x00000511,
+  CL_RECORDER                   =    0x00000512,
+
+  CL_IMAGE_ENTITY               =    0x00000513,
+  CL_IMAGE_PLANE                =    0x00000518,
+  CL_MODEL_ENTITY               =    0x00000515,
+  CL_TEXT_ELEMENT               =    0x00000516, /// TODO MOVE
+
+
+  /// GamePlay (range from 0x00000600 0x000006ff)
+  CL_EVENT                      =    0x00000601,
+  CL_KEY_MAPPER                 =    0x00000602,
+  CL_CROSSHAIR                  =    0x00000612,
+
+  CL_WEAPON_MANAGER             =    0x00000603,
+  CL_AMMO_CONTAINER             =    0x00000604,
+  CL_HUD                        =    0x00000620,
+
+
+  CL_SCRIPT_MANAGER             =    0x00000650,
+  CL_SCRIPT                     =    0x00000651,
+  CL_SCRIPT_CLASS               =    0x00000652,
+  CL_SCRIPT_TRIGGER             =    0x00000653,
+
+
+  /// Physics stuff (range from 0x00000700 to 0x000008ff)
+  CL_PHYSICS_CONNECTION         =    0x00000701,
+  CL_FIELD_GRAVITY              =    0x00000710,
+  CL_FIELD_POINT_GRAVITY        =    0x00000711,
+  CL_FIELD_TWIRL                =    0x00000712,
+
+
+  /// Collision
+  CL_COLLISION                  =    0x00780000,
+  CL_COLLISION_HANDLE           =    0x00000712,
+  CL_COLLISION_REACTION         =    0X00000713,
+  CL_CR_PHYSICS_MOMENTUM        =    0X00000714,
+  CL_CR_PHYSICS_GROUND_WALK     =    0X00000715,
+  CL_CR_PHYSICS_FULL_WALK       =    0X00000716,
+  CL_CR_OBJECT_DAMAGE           =    0X00000717,
+  CL_CR_OBJECT_PICKUP           =    0X00000718,
+  CL_CR_VERTEX_TRAFO            =    0X00000719,
+  CL_CR_SPECIAL_CALLBACK        =    0X00000720,
+
+
+  CL_BV_TREE                    =    0x00701000,
+  CL_BV_TREE_NODE               =    0x00702000,
+  CL_OBB_TREE                   =    0x00000721,
+  CL_OBB_TREE_NODE              =    0x00000722,
+  CL_BOUNDING_VOLUME            =    0x00710000,
+  CL_OBB                        =    0x00720000,
+  CL_BOUNDING_SPHERE            =    0x00740000,
+  CL_AABB_TREE_NODE             =    0x00000724,                //FIXME: is this correct? AABB_TREE_NODE isA BV_TREE_NODE
+  CL_AABB                       =    0x00780000,                //FIXME: is this correct? AABB isA BOUNDING_VOLUME
+
+
+
+  /// Graphical stuff (range from 0x00000800 to 0x00000aff)
+  /// SUPER-Textures
+  CL_MATERIAL                   =    0x00801000,
+  CL_TEXTURE                    =    0x00802000,
+  CL_TEXTURE_SEQUENCE           =    0x00804000,
+  CL_TEXT                       =    0x00808000,
+  CL_MULTI_LINE_TEXT            =    0x00000840,
+  CL_LIMITED_WIDTH_TEXT         =    0x00000841,
+
+  // Texutres.
+  CL_FONT                       =    0x00000802,
+  CL_MOVIE_PLAYER               =    0x00000805,
+  CL_MEDIA_CONTAINER            =    0x00000806,
+
+  /// Super-Models
+  CL_MODEL                      =    0x00901000,
+  CL_STATIC_MODEL               =    0x00902000,
+  CL_VERTEX_ARRAY_MODEL         =    0x00904000,
+  CL_INTERACTIVE_MODEL          =    0x00908000,        ///FIXME: is this ok bensch?
+
+  // Models
+  CL_OBJ_MODEL                  =    0x00000907,
+
+  CL_PRIMITIVE_MODEL            =    0x00000908,
+  CL_MD2_MODEL                  =    0x00000909,
+  CL_HEIGHT_MAP                 =    0x0000090a,
+  CL_GRID                       =    0x0000090b,
+  CL_BSP_MODEL                  =    0x0000090c, //!FIXME
+
+  CL_SHADER                     =    0x00000811,
+  CL_LIGHT                      =    0x00000821,
+
+  CL_BILLBOARD                  =    0x00000a01,
+
+  CL_GRAPHICS_EFFECT            =    0x00a01000,
+  CL_WEATHER_EFFECT             =    0x00a10000,
+  CL_FOG_EFFECT                 =    0x00000a10,
+  CL_VOLFOG_EFFECT              =    0x00000a11,
+  CL_LENSE_FLARE                =    0x00000a12,
+  CL_RAIN_EFFECT                =    0x00000a13,
+  CL_SNOW_EFFECT                =    0x00000a14,
+  CL_CLOUD_EFFECT               =    0x00000a15,
+  CL_LIGHTNING_EFFECT          =    0x00000a16,
+  CL_EXPLOSION                  =    0x00000a20,
+  CL_LIGHTNING_BOLT             =    0x00000a21,
+
+
+
+  // Particles
+  CL_PARTICLE_SYSTEM            =    0x00a02000,
+  CL_DOT_PARTICLES              =    0x00000aa1,
+  CL_SPARK_PARTICLES            =    0x00000aa2,
+  CL_SPRITE_PARTICLES           =    0x00000aa3,
+  CL_MODEL_PARTICLES            =    0x00000aa4,
+  //  CL_PNODE_PARTICLES            =    0x00a20000,
+
+  CL_PARTICLE_EMITTER           =    0x00a04000,
+  CL_DOT_EMITTER                =    0x00000ab1,
+  CL_PLANE_EMITTER              =    0x00000ab2,
+  CL_BOX_EMITTER                =    0x00000ab3,
+  CL_SPHERE_EMITTER             =    0x00000ab4,
+  //  CL_MODEL_EMITTER              =    0x00000a25,
+
+  // Element2D's  (range from 0x00000b00 to 0x00000bff)
+  /// GL-GUI
+  CL_GLGUI_WIDGET               =    0x00b01000,
+  CL_GLGUI_BUTTON               =    0x00b02000,
+  CL_GLGUI_PUSHBUTTON           =    0x00000b03,
+  CL_GLGUI_CHECKBUTTON          =    0x00000b04,
+  CL_GLGUI_RADIOBUTTON          =    0x00000b05,
+  CL_GLGUI_SLIDER               =    0x00000b06,
+  CL_GLGUI_PROGRESSBAR          =    0x00000b07,
+  CL_GLGUI_CONTAINER            =    0x00b04000,
+  CL_GLGUI_BOX                  =    0x00000b17,
+  CL_GLGUI_FRAME                =    0x00000b18,
+  CL_GLGUI_WINDOW               =    0x00000b19,
+  CL_GLMENU_IMAGE_SCREEN        =    0x00000b20,
+  CL_GLGUI_BAR                  =    0x00000b30,
+  CL_GLGUI_CURSOR               =    0x00000b50,
+  CL_GLGUI_TEXT                 =    0x00000b51,
+  CL_GLGUI_INPUTLINE            =    0x00000b60,
+  CL_GLGUI_TEXTFIELD            =    0x00000b61,
+  CL_GLGUI_IMAGE                =    0x00000b70,
+  CL_GLGUI_TABLE                =    0x00000b71,
+
+  CL_GLGUI_NOTIFIER             =    0x00000b80,
+
+  // QT_GUI
+  CL_GUI_SAVEABLE               =    0x00b10000,
+  CL_QTGUI_BUTTON               =    0x00000ba0,
+  CL_QTGUI_PUSHBUTTON           =    0x00000ba3,
+  CL_QTGUI_CHECKBUTTON          =    0x00000ba4,
+  CL_QTGUI_RADIOBUTTON          =    0x00000ba5,
+  CL_QTGUI_CONTAINER            =    0x00b200a0,
+  CL_QTGUI_BOX                  =    0x00000ba7,
+  CL_QTGUI_FRAME                =    0x00000ba8,
+  CL_QTGUI_WINDOW               =    0x00000ba9,
+  CL_QTMENU_IMAGE_SCREEN        =    0x00000ba0,
+  CL_QTGUI_BAR                  =    0x00000ba0,
+
+  /// AUDIO stuff (range from 0x00000c00 to 0x00000cff)
+  CL_SOUND_BUFFER               =    0x00000c01,
+  CL_SOUND_SOURCE               =    0x00000c02,
+  CL_SOUND_OGG_PLAYER           =    0x00000c11,
+
+
+  /// NETWORK stuff (range from 0x00000d00 to 0x00000dff)
+  CL_DATA_STREAM                =    0x00d01000,
+  CL_NETWORK_STREAM             =    0x00000d01,
+  CL_NETWORK_PROTOCOL           =    0x00000d02,
+  CL_NETWORK_SOCKET             =    0x00000d03,
+  CL_SERVER_SOCKET              =    0X00000d04,
+  CL_CONNECTION_MONITOR         =    0x00000d05,
+  CL_HANDSHAKE                  =    0x00000d06,
+  CL_NETWORK_GAME_MANAGER       =    0x00000d07,
+  CL_MESSAGE_MANAGER            =    0x00000d08,
+  CL_PLAYER_STATS               =    0x00000d09,
+  CL_SIMPLE_SYNC                =    0x00000d0a,
+  CL_NETWORK_MONITOR            =    0x00000d0b,
+  CL_PROXY_CONTROL              =    0x00000d0c,
+
+
+
+  /// MISCELANEOUS: (range from 0x00000e00 to 0x00000fff)
+  CL_ANIMATION                  =    0x00000e01,
+  //  CL_ANIMATION3D                =    0x00000b02,
+  CL_QUICK_ANIMATION            =    0x00000e02,
+
+  CL_FACTORY                    =    0x00e01000,
+  CL_FAST_FACTORY               =    0x00000ea2,
+  CL_LOAD_PARAM                 =    0x00000ea3,
+  CL_DYNAMIC_LOADER             =    0x00000ea8,
+
+  CL_INI_PARSER                 =    0x00000e04,
+
+  CL_SHELL                      =    0x00000e10,
+  CL_SHELL_COMMAND              =    0x00000e11,
+  CL_SHELL_COMMAND_CLASS        =    0x00000e12,
+  CL_SHELL_INPUT                =    0x00000e13,
+  CL_SHELL_COMPLETION           =    0x00000e14,
+  CL_SHELL_COMMAND_ALIAS        =    0x00000e15,
+
+  CL_TRACK_ELEMENT              =    0x00000e2b,
+  CL_LIST                       =    0x00000e25,
+  CL_SUBSTRING                  =    0x00000e26,
+  CL_CURVE                      =    0x00000e28,
+  CL_CHARACTER_ATTRIBUTES       =    0x00000e2a,
+  CL_NUMBER                     =    0x00000e2c,
+  CL_EXECUTOR                   =    0x00000e2d,
+
+  // Spatial Data Separation
+  CL_SPATIAL_SEPARATION         =    0x00000e0d,
+  CL_QUADTREE                   =    0x00000e0e,
+  CL_QUADTREE_NODE              =    0x00000e0f,
+};
+
+
+#endif /* _CLASS_ID___DEPRECATED___H */
Index: branches/heathaze/src/defs/comincl.h
===================================================================
--- branches/heathaze/src/defs/comincl.h	(revision 9940)
+++ branches/heathaze/src/defs/comincl.h	(revision 9940)
@@ -0,0 +1,13 @@
+/*!
+  \file glincl.h
+  \brief This file includes gl Headers.
+  
+  no Class is defined here, but the opengl Headers
+*/
+
+#ifndef _COMINCL_H
+#define _COMINCL_H
+
+#include "message_structures.h"
+
+#endif /* _COMINCL_H */
Index: branches/heathaze/src/defs/compiler.h
===================================================================
--- branches/heathaze/src/defs/compiler.h	(revision 9940)
+++ branches/heathaze/src/defs/compiler.h	(revision 9940)
@@ -0,0 +1,14 @@
+
+#ifndef _COMPILER_H
+#define _COMPILER_H
+
+/* performance tweaking stuff */
+#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
+#define __builtin_expect(x, expected_value) (x)
+#endif
+
+#define likely(x)       __builtin_expect((x),1)
+#define unlikely(x)     __builtin_expect((x),0)
+
+
+#endif /* _COMPILER_H */
Index: branches/heathaze/src/defs/confincl.h
===================================================================
--- branches/heathaze/src/defs/confincl.h	(revision 9940)
+++ branches/heathaze/src/defs/confincl.h	(revision 9940)
@@ -0,0 +1,13 @@
+/*!
+  \file confincl.h
+  \brief includes the configure-headers, if config should be loaded
+*/
+
+#ifndef _CONFINCL_H
+#define _CONFINCL_H
+
+#if HAVE_CONFIG_H 
+#include <config.h> 
+#endif
+
+#endif /*_CONFINCL_H */
Index: branches/heathaze/src/defs/error.h
===================================================================
--- branches/heathaze/src/defs/error.h	(revision 9940)
+++ branches/heathaze/src/defs/error.h	(revision 9940)
@@ -0,0 +1,65 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Christian Meyer
+*/
+
+
+/*!
+ * @file error.h
+  *  A compendium of Error codes used in the program
+*/
+
+
+#ifndef _ERROR_H
+#define _ERROR_H
+
+// these are the two undefined error nr. Don't use them ...
+#define oERROR -1
+
+#define oNOERROR 0
+
+/*!
+  *  Error Definitions:
+
+    Error Classes:
+    0xx application framework codes
+    1xx graphics codes
+    2xx file/FS codes
+    3xx network codes
+    4xx general codes
+
+    Error Specifier 1:
+    x0x action finsished as desired
+    x1x initialisation error
+    x2x execution error
+    x3x uninitialisation error
+
+    Error Specifier 2:
+    xx0 no further informations
+    xx1 only a warning - feel free to ignore, the program will proceed
+    xx2 this could lead unexpected behaviour
+    xx3 this is a fatal error - you are invited to quit the program - panic!
+*/
+
+struct ErrorMessage
+{
+  ErrorMessage(int code = 0, char* message = NULL, char* location = NULL)
+    : code(code), message(message), location(location) {};
+  int code;
+  char* message;
+  char* location;
+};
+
+#endif /* _ERROR_H */
Index: branches/heathaze/src/defs/glincl.h
===================================================================
--- branches/heathaze/src/defs/glincl.h	(revision 9940)
+++ branches/heathaze/src/defs/glincl.h	(revision 9940)
@@ -0,0 +1,21 @@
+/*!
+  \file glincl.h
+  \brief This file includes gl Headers.
+
+  no Class is defined here, but the opengl Headers
+*/
+
+#ifndef _GLINCL_H
+#define _GLINCL_H
+
+#ifndef __APPLE__
+#include <GL/glew.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#else
+#include <GL/glew.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#endif
+
+#endif /* _GLINCL_H */
Index: branches/heathaze/src/defs/globals.h
===================================================================
--- branches/heathaze/src/defs/globals.h	(revision 9940)
+++ branches/heathaze/src/defs/globals.h	(revision 9940)
@@ -0,0 +1,464 @@
+/*!
+  \file globals.h
+  \brief This file defines some global default values.
+
+  no Class is defined here.
+*/
+
+#ifndef _GLOBALS_H
+#define _GLOBALS_H
+
+#include "confincl.h"
+
+
+#define   ORXONOX_STAFF "Patrick Boenzli - Captain\n" \
+                        "Benjamin Grauer - First Officer\n" \
+                        "Christian Meyer - Engeneer\n" \
+                        "Nico Bernold - Physics\n" \
+                        "David Gruetter - The ProtoType\n" \
+                        "Aaron von Schroeder - Sensors\n" \
+                        "Lukas Grauer - Phasers\n" \
+                        "many more...\n"
+
+#define   ORXONOX_WEBPAGE                  "http://www.orxonox.net"
+
+#define   DEFAULT_CONFIG_FILE              "~/.orxonox/orxonox.conf"
+#define   DEFAULT_LOCK_FILE                "~/.orxonox/orxonox.lock"
+#define   DEFAULT_DATA_DIR                 ORX_DATADIR "/orxonox/"
+#define   DEFAULT_DATA_DIR_CHECKFILE       "data.oxd"
+
+#define   DEFAULT_ORXONOX_PORT             9999
+
+// Defines all the Sections of the Config (in Gui and orxonox)
+//! Name of Section Misc in the config-File
+#define   CONFIG_SECTION_MISC              "misc"
+#define   CONFIG_SECTION_CONTROL           "control"
+#define   CONFIG_SECTION_VIDEO             "video"
+#define   CONFIG_SECTION_VIDEO_ADVANCED    "video_advanced"
+#define   CONFIG_SECTION_AUDIO             "audio"
+#define   CONFIG_SECTION_GENERAL           "general"
+
+/*
+  TAGS for all the Configuration Options
+  Consider they may __not__ have any WhiteSpaces inside
+*/
+#define   CONFIG_NAME_DATADIR              "DataDir"
+#define   CONFIG_NAME_AUTO_UPDATE          "Auto-Update"
+
+#define   CONFIG_NAME_FULLSCREEN           "Fullscreen-mode"
+#define   CONFIG_NAME_NO_RENDER            "Norender-mode"
+#define   CONFIG_NAME_RESOLUTION           "Resolution"
+#define   CONFIG_NAME_WIREFRAME            "WireFrame-mode"
+#define   CONFIG_NAME_SHADOWS              "Shadows"
+#define   CONFIG_NAME_FOG                  "Fog"
+#define   CONFIG_NAME_REFLECTIONS          "Reflections"
+#define   CONFIG_NAME_TEXTURES             "Textures"
+#define   CONFIG_NAME_TEXTURE_DETAIL       "Texture-Detail"
+#define   CONFIG_NAME_MODEL_DETAIL         "Model-Detail"
+#define   CONFIG_NAME_PARTICLES_ENABLED    "Particles Enabled"
+#define   CONFIG_NAME_ANTI_ALIASING        "Anti-Aliasing"
+#define   CONFIG_NAME_FILTER_METHOD        "Filtering-Method"
+
+#define   CONFIG_NAME_SOUNDCARD            "Soundcard"
+#define   CONFIG_NAME_DISABLE_AUDIO        "Disable-Audio"
+#define   CONFIG_NAME_AUDIO_CHANNELS       "Audio-Channels"
+#define   CONFIG_NAME_MUSIC_VOLUME         "Music-Volume"
+#define   CONFIG_NAME_EFFECTS_VOLUME       "Effects-Volume"
+
+#define   CONFIG_NAME_SAVE_SETTINGS        "Save-Settings"
+#define   CONFIG_NAME_VERBOSE_MODE         "Verbose-Mode"
+#define   CONFIG_NAME_ALWAYS_SHOW_GUI      "Always-Show-The-Gui"
+#define   CONFIG_NAME_DEBUG_LEVEL          "Debug-Level"
+
+// evenets
+#define   CONFIG_NAME_PLAYER_FORWARD       "Forward"
+#define   CONFIG_NAME_PLAYER_BACKWARD      "Backward"
+#define   CONFIG_NAME_PLAYER_LEFT          "Left"
+#define   CONFIG_NAME_PLAYER_RIGHT         "Right"
+#define   CONFIG_NAME_PLAYER_ROLL_RIGHT    "RollR"
+#define   CONFIG_NAME_PLAYER_ROLL_LEFT     "RollL"
+#define   CONFIG_NAME_PLAYER_UP            "Up"
+#define   CONFIG_NAME_PLAYER_DOWN          "Down"
+
+#define   CONFIG_NAME_PLAYER_FIRE          "Fire"
+#define   CONFIG_NAME_PLAYER_NEXT_WEAPON   "Next-Weapon"
+#define   CONFIG_NAME_PLAYER_PREV_WEAPON   "Previous-Weapon"
+#define   CONFIG_NAME_PLAYER_CHANGE_SHIP   "Change-Ship"
+
+#define   CONFIG_NAME_QUIT                 "Quit"
+#define   CONFIG_NAME_PAUSE                "Pause"
+#define   CONFIG_NAME_NEXT_WORLD           "Next-World"
+#define   CONFIG_NAME_PREV_WORLD           "Prev-World"
+#define   CONFIG_NAME_VIEW0                "view0"
+#define   CONFIG_NAME_VIEW1                "view1"
+#define   CONFIG_NAME_VIEW2                "view2"
+#define   CONFIG_NAME_VIEW3                "view3"
+#define   CONFIG_NAME_VIEW4                "view4"
+#define   CONFIG_NAME_VIEW5                "view5"
+
+
+#define  ORXONOX_LICENSE_SHORT \
+    "Orxonox - The Future of 3D-Action-Game\n" \
+    "\n" \
+    "Copyright (C) 2004 orx\n" \
+    "\n" \
+    "This program is free software; you can redistribute it and/or modify\n" \
+    "it under the terms of the GNU General Public License as published by\n" \
+    "the Free Software Foundation; either version 2, or (at your option)\n" \
+    "any later version.\n" \
+    "\n" \
+    "This program is distributed in the hope that it will be useful,\n" \
+    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"  \
+    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"   \
+    "GNU General Public License for more details.\n" \
+    "\n" \
+    "You should have received a copy of the GNU General Public License\n" \
+    "along with this program; if not, write to the Free Software Foundation,\n" \
+    "Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"
+
+
+
+#define GNU_LICENCE_LONG \
+"                    GNU GENERAL PUBLIC LICENSE\n" \
+"                       Version 2, June 1991\n" \
+"\n" \
+" Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n" \
+"     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n" \
+" Everyone is permitted to copy and distribute verbatim copies\n" \
+" of this license document, but changing it is not allowed.\n" \
+"\n" \
+"                            Preamble\n" \
+"\n" \
+"  The licenses for most software are designed to take away your\n" \
+"freedom to share and change it.  By contrast, the GNU General Public\n" \
+"License is intended to guarantee your freedom to share and change free\n" \
+"software--to make sure the software is free for all its users.  This\n" \
+"General Public License applies to most of the Free Software\n" \
+"Foundation's software and to any other program whose authors commit to\n" \
+"using it.  (Some other Free Software Foundation software is covered by\n" \
+"the GNU Library General Public License instead.)  You can apply it to\n" \
+"your programs, too.\n" \
+"\n" \
+"  When we speak of free software, we are referring to freedom, not\n" \
+"price.  Our General Public Licenses are designed to make sure that you\n" \
+"have the freedom to distribute copies of free software (and charge for\n" \
+"this service if you wish), that you receive source code or can get it\n" \
+"if you want it, that you can change the software or use pieces of it\n" \
+"in new free programs; and that you know you can do these things.\n" \
+"\n" \
+"  To protect your rights, we need to make restrictions that forbid\n" \
+"anyone to deny you these rights or to ask you to surrender the rights.\n" \
+"These restrictions translate to certain responsibilities for you if you\n" \
+"distribute copies of the software, or if you modify it.\n" \
+"\n" \
+"  For example, if you distribute copies of such a program, whether\n" \
+"gratis or for a fee, you must give the recipients all the rights that\n" \
+"you have.  You must make sure that they, too, receive or can get the\n" \
+"source code.  And you must show them these terms so they know their\n" \
+"rights.\n" \
+"\n" \
+"  We protect your rights with two steps: (1) copyright the software, and\n" \
+"(2) offer you this license which gives you legal permission to copy,\n" \
+"distribute and/or modify the software.\n" \
+"\n" \
+"  Also, for each author's protection and ours, we want to make certain\n" \
+"that everyone understands that there is no warranty for this free\n" \
+"software.  If the software is modified by someone else and passed on, we\n" \
+"want its recipients to know that what they have is not the original, so\n" \
+"that any problems introduced by others will not reflect on the original\n" \
+"authors' reputations.\n" \
+"\n" \
+"  Finally, any free program is threatened constantly by software\n" \
+"patents.  We wish to avoid the danger that redistributors of a free\n" \
+"program will individually obtain patent licenses, in effect making the\n" \
+"program proprietary.  To prevent this, we have made it clear that any\n" \
+"patent must be licensed for everyone's free use or not licensed at all.\n" \
+"\n" \
+"  The precise terms and conditions for copying, distribution and\n" \
+"modification follow.\n" \
+"\n" \
+"                    GNU GENERAL PUBLIC LICENSE\n" \
+"   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n" \
+"\n" \
+"  0. This License applies to any program or other work which contains\n" \
+"a notice placed by the copyright holder saying it may be distributed\n" \
+"under the terms of this General Public License.  The \"Program\", below,\n" \
+"refers to any such program or work, and a \"work based on the Program\"\n" \
+"means either the Program or any derivative work under copyright law:\n" \
+"that is to say, a work containing the Program or a portion of it,\n" \
+"either verbatim or with modifications and/or translated into another\n" \
+"language.  (Hereinafter, translation is included without limitation in\n" \
+"the term \"modification\".)  Each licensee is addressed as \"you\".\n" \
+"\n" \
+"Activities other than copying, distribution and modification are not\n" \
+"covered by this License; they are outside its scope.  The act of\n" \
+"running the Program is not restricted, and the output from the Program\n" \
+"is covered only if its contents constitute a work based on the\n" \
+"Program (independent of having been made by running the Program).\n" \
+"Whether that is true depends on what the Program does.\n" \
+"\n" \
+"  1. You may copy and distribute verbatim copies of the Program's\n" \
+"source code as you receive it, in any medium, provided that you\n" \
+"conspicuously and appropriately publish on each copy an appropriate\n" \
+"copyright notice and disclaimer of warranty; keep intact all the\n" \
+"notices that refer to this License and to the absence of any warranty;\n" \
+"and give any other recipients of the Program a copy of this License\n" \
+"along with the Program.\n" \
+"\n" \
+"You may charge a fee for the physical act of transferring a copy, and\n" \
+"you may at your option offer warranty protection in exchange for a fee.\n" \
+"\n" \
+"  2. You may modify your copy or copies of the Program or any portion\n" \
+"of it, thus forming a work based on the Program, and copy and\n" \
+"distribute such modifications or work under the terms of Section 1\n" \
+"above, provided that you also meet all of these conditions:\n" \
+"\n" \
+"    a) You must cause the modified files to carry prominent notices\n" \
+"    stating that you changed the files and the date of any change.\n" \
+"\n" \
+"    b) You must cause any work that you distribute or publish, that in\n" \
+"    whole or in part contains or is derived from the Program or any\n" \
+"    part thereof, to be licensed as a whole at no charge to all third\n" \
+"    parties under the terms of this License.\n" \
+"\n" \
+"    c) If the modified program normally reads commands interactively\n" \
+"    when run, you must cause it, when started running for such\n" \
+"    interactive use in the most ordinary way, to print or display an\n" \
+"    announcement including an appropriate copyright notice and a\n" \
+"    notice that there is no warranty (or else, saying that you provide\n" \
+"    a warranty) and that users may redistribute the program under\n" \
+"    these conditions, and telling the user how to view a copy of this\n" \
+"    License.  (Exception: if the Program itself is interactive but\n" \
+"    does not normally print such an announcement, your work based on\n" \
+"    the Program is not required to print an announcement.)\n" \
+"\n" \
+"These requirements apply to the modified work as a whole.  If\n" \
+"identifiable sections of that work are not derived from the Program,\n" \
+"and can be reasonably considered independent and separate works in\n" \
+"themselves, then this License, and its terms, do not apply to those\n" \
+"sections when you distribute them as separate works.  But when you\n" \
+"distribute the same sections as part of a whole which is a work based\n" \
+"on the Program, the distribution of the whole must be on the terms of\n" \
+"this License, whose permissions for other licensees extend to the\n" \
+"entire whole, and thus to each and every part regardless of who wrote it.\n" \
+"\n" \
+"Thus, it is not the intent of this section to claim rights or contest\n" \
+"your rights to work written entirely by you; rather, the intent is to\n" \
+"exercise the right to control the distribution of derivative or\n" \
+"collective works based on the Program.\n" \
+"\n" \
+"In addition, mere aggregation of another work not based on the Program\n" \
+"with the Program (or with a work based on the Program) on a volume of\n" \
+"a storage or distribution medium does not bring the other work under\n" \
+"the scope of this License.\n" \
+"\n" \
+"  3. You may copy and distribute the Program (or a work based on it,\n" \
+"under Section 2) in object code or executable form under the terms of\n" \
+"Sections 1 and 2 above provided that you also do one of the following:\n" \
+"\n" \
+"    a) Accompany it with the complete corresponding machine-readable\n" \
+"    source code, which must be distributed under the terms of Sections\n" \
+"    1 and 2 above on a medium customarily used for software interchange; or,\n" \
+"\n" \
+"    b) Accompany it with a written offer, valid for at least three\n" \
+"    years, to give any third party, for a charge no more than your\n" \
+"    cost of physically performing source distribution, a complete\n" \
+"    machine-readable copy of the corresponding source code, to be\n" \
+"    distributed under the terms of Sections 1 and 2 above on a medium\n" \
+"    customarily used for software interchange; or,\n" \
+"\n" \
+"    c) Accompany it with the information you received as to the offer\n" \
+"    to distribute corresponding source code.  (This alternative is\n" \
+"    allowed only for noncommercial distribution and only if you\n" \
+"    received the program in object code or executable form with such\n" \
+"    an offer, in accord with Subsection b above.)\n" \
+"\n" \
+"The source code for a work means the preferred form of the work for\n" \
+"making modifications to it.  For an executable work, complete source\n" \
+"code means all the source code for all modules it contains, plus any\n" \
+"associated interface definition files, plus the scripts used to\n" \
+"control compilation and installation of the executable.  However, as a\n" \
+"special exception, the source code distributed need not include\n" \
+"anything that is normally distributed (in either source or binary\n" \
+"form) with the major components (compiler, kernel, and so on) of the\n" \
+"operating system on which the executable runs, unless that component\n" \
+"itself accompanies the executable.\n" \
+"\n" \
+"If distribution of executable or object code is made by offering\n" \
+"access to copy from a designated place, then offering equivalent\n" \
+"access to copy the source code from the same place counts as\n" \
+"distribution of the source code, even though third parties are not\n" \
+"compelled to copy the source along with the object code.\n" \
+"\n" \
+"  4. You may not copy, modify, sublicense, or distribute the Program\n" \
+"except as expressly provided under this License.  Any attempt\n" \
+"otherwise to copy, modify, sublicense or distribute the Program is\n" \
+"void, and will automatically terminate your rights under this License.\n" \
+"However, parties who have received copies, or rights, from you under\n" \
+"this License will not have their licenses terminated so long as such\n" \
+"parties remain in full compliance.\n" \
+"\n" \
+"  5. You are not required to accept this License, since you have not\n" \
+"signed it.  However, nothing else grants you permission to modify or\n" \
+"distribute the Program or its derivative works.  These actions are\n" \
+"prohibited by law if you do not accept this License.  Therefore, by\n" \
+"modifying or distributing the Program (or any work based on the\n" \
+"Program), you indicate your acceptance of this License to do so, and\n" \
+"all its terms and conditions for copying, distributing or modifying\n" \
+"the Program or works based on it.\n" \
+"\n" \
+"  6. Each time you redistribute the Program (or any work based on the\n" \
+"Program), the recipient automatically receives a license from the\n" \
+"original licensor to copy, distribute or modify the Program subject to\n" \
+"these terms and conditions.  You may not impose any further\n" \
+"restrictions on the recipients' exercise of the rights granted herein.\n" \
+"You are not responsible for enforcing compliance by third parties to\n" \
+"this License.\n" \
+"\n" \
+"  7. If, as a consequence of a court judgment or allegation of patent\n" \
+"infringement or for any other reason (not limited to patent issues),\n" \
+"conditions are imposed on you (whether by court order, agreement or\n" \
+"otherwise) that contradict the conditions of this License, they do not\n" \
+"excuse you from the conditions of this License.  If you cannot\n" \
+"distribute so as to satisfy simultaneously your obligations under this\n" \
+"License and any other pertinent obligations, then as a consequence you\n" \
+"may not distribute the Program at all.  For example, if a patent\n" \
+"license would not permit royalty-free redistribution of the Program by\n" \
+"all those who receive copies directly or indirectly through you, then\n" \
+"the only way you could satisfy both it and this License would be to\n" \
+"refrain entirely from distribution of the Program.\n" \
+"\n" \
+"If any portion of this section is held invalid or unenforceable under\n" \
+"any particular circumstance, the balance of the section is intended to\n" \
+"apply and the section as a whole is intended to apply in other\n" \
+"circumstances.\n" \
+"\n" \
+"It is not the purpose of this section to induce you to infringe any\n" \
+"patents or other property right claims or to contest validity of any\n" \
+"such claims; this section has the sole purpose of protecting the\n" \
+"integrity of the free software distribution system, which is\n" \
+"implemented by public license practices.  Many people have made\n" \
+"generous contributions to the wide range of software distributed\n" \
+"through that system in reliance on consistent application of that\n" \
+"system; it is up to the author/donor to decide if he or she is willing\n" \
+"to distribute software through any other system and a licensee cannot\n" \
+"impose that choice.\n" \
+"\n" \
+"This section is intended to make thoroughly clear what is believed to\n" \
+"be a consequence of the rest of this License.\n" \
+"\n" \
+"  8. If the distribution and/or use of the Program is restricted in\n" \
+"certain countries either by patents or by copyrighted interfaces, the\n" \
+"original copyright holder who places the Program under this License\n" \
+"may add an explicit geographical distribution limitation excluding\n" \
+"those countries, so that distribution is permitted only in or among\n" \
+"countries not thus excluded.  In such case, this License incorporates\n" \
+"the limitation as if written in the body of this License.\n" \
+"\n" \
+"  9. The Free Software Foundation may publish revised and/or new versions\n" \
+"of the General Public License from time to time.  Such new versions will\n" \
+"be similar in spirit to the present version, but may differ in detail to\n" \
+"address new problems or concerns.\n" \
+"\n" \
+"Each version is given a distinguishing version number.  If the Program\n" \
+"specifies a version number of this License which applies to it and \"any\n" \
+"later version\", you have the option of following the terms and conditions\n" \
+"either of that version or of any later version published by the Free\n" \
+"Software Foundation.  If the Program does not specify a version number of\n" \
+"this License, you may choose any version ever published by the Free Software\n" \
+"Foundation.\n" \
+"\n" \
+"  10. If you wish to incorporate parts of the Program into other free\n" \
+"programs whose distribution conditions are different, write to the author\n" \
+"to ask for permission.  For software which is copyrighted by the Free\n" \
+"Software Foundation, write to the Free Software Foundation; we sometimes\n" \
+"make exceptions for this.  Our decision will be guided by the two goals\n" \
+"of preserving the free status of all derivatives of our free software and\n" \
+"of promoting the sharing and reuse of software generally.\n" \
+"\n" \
+"                            NO WARRANTY\n" \
+"\n" \
+"  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n" \
+"FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n" \
+"OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n" \
+"PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n" \
+"OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" \
+"MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n" \
+"TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n" \
+"PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n" \
+"REPAIR OR CORRECTION.\n" \
+"\n" \
+"  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n" \
+"WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n" \
+"REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n" \
+"INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n" \
+"OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n" \
+"TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n" \
+"YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n" \
+"PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n" \
+"POSSIBILITY OF SUCH DAMAGES.\n" \
+"\n" \
+"                     END OF TERMS AND CONDITIONS\n" \
+"\n" \
+"            How to Apply These Terms to Your New Programs\n" \
+"\n" \
+"  If you develop a new program, and you want it to be of the greatest\n" \
+"possible use to the public, the best way to achieve this is to make it\n" \
+"free software which everyone can redistribute and change under these terms.\n" \
+"\n" \
+"  To do so, attach the following notices to the program.  It is safest\n" \
+"to attach them to the start of each source file to most effectively\n" \
+"convey the exclusion of warranty; and each file should have at least\n" \
+"the \"copyright\" line and a pointer to where the full notice is found.\n" \
+"\n" \
+"    <one line to give the program's name and a brief idea of what it does.>\n" \
+"    Copyright (C) <year>  <name of author>\n" \
+"\n" \
+"    This program is free software; you can redistribute it and/or modify\n" \
+"    it under the terms of the GNU General Public License as published by\n" \
+"    the Free Software Foundation; either version 2 of the License, or\n" \
+"    (at your option) any later version.\n" \
+"\n" \
+"    This program is distributed in the hope that it will be useful,\n" \
+"    but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
+"    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" \
+"    GNU General Public License for more details.\n" \
+"\n" \
+"    You should have received a copy of the GNU General Public License\n" \
+"    along with this program; if not, write to the Free Software\n" \
+"    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n" \
+"\n" \
+"\n" \
+"Also add information on how to contact you by electronic and paper mail.\n" \
+"\n" \
+"If the program is interactive, make it output a short notice like this\n" \
+"when it starts in an interactive mode:\n" \
+"\n" \
+"    Gnomovision version 69, Copyright (C) year  name of author\n" \
+"    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n" \
+"    This is free software, and you are welcome to redistribute it\n" \
+"    under certain conditions; type `show c' for details.\n" \
+"\n" \
+"The hypothetical commands `show w' and `show c' should show the appropriate\n" \
+"parts of the General Public License.  Of course, the commands you use may\n" \
+"be called something other than `show w' and `show c'; they could even be\n" \
+"mouse-clicks or menu items--whatever suits your program.\n" \
+"\n" \
+"You should also get your employer (if you work as a programmer) or your\n" \
+"school, if any, to sign a \"copyright disclaimer\" for the program, if\n" \
+"necessary.  Here is a sample; alter the names:\n" \
+"\n" \
+"  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n" \
+"  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n" \
+"\n" \
+"  <signature of Ty Coon>, 1 April 1989\n" \
+"  Ty Coon, President of Vice\n" \
+"\n" \
+"This General Public License does not permit incorporating your program into\n" \
+"proprietary programs.  If your program is a subroutine library, you may\n" \
+"consider it more useful to permit linking proprietary applications with the\n" \
+"library.  If this is what you want to do, use the GNU Library General\n" \
+"Public License instead of this License.\n"
+
+
+#endif /* _GLOBALS_H */
Index: branches/heathaze/src/defs/include_paths.am
===================================================================
--- branches/heathaze/src/defs/include_paths.am	(revision 9940)
+++ branches/heathaze/src/defs/include_paths.am	(revision 9940)
@@ -0,0 +1,31 @@
+AM_CXXFLAGS=-I$(MAINSRCDIR)
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/world_entities
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/story_entities
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/coord
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/data
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/event
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics/md2
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics/md3
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics/text_engine
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics/importer
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics/spatial_separation
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics/render2D
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/gui/gl
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/gui/gl/glmenu
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/lang
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/shell
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/util
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/math
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/network
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/physics
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/collision_detection
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/collision_reaction
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/sound
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/script_engine
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/defs
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/util
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/util/animation
+
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/../extern_libs
Index: branches/heathaze/src/defs/message_structures.h
===================================================================
--- branches/heathaze/src/defs/message_structures.h	(revision 9940)
+++ branches/heathaze/src/defs/message_structures.h	(revision 9940)
@@ -0,0 +1,30 @@
+/*!
+	\file message_structures.h
+	\brief contains defintitons of messages that can be passed between classes
+*/
+
+#ifndef _MESSAGE_STRUCTURES_H
+#define _MESSAGE_STRUCTURES_H
+
+#include "stdincl.h"
+
+#define CMD_LENGHT 16
+
+//! structure that contains a command message
+typedef struct
+{
+	char cmd[CMD_LENGHT];	//!< the command delivered
+	bool bUp;	//!< false = command was activated / true = command was deactivated
+	
+	//! if cmd is "cursor" the coordinates of the mouse cursor are stored here
+	//!@{
+	Uint16 x, y;
+	//!@}
+	
+	//! if cmd is "cursor" the relative motion of the mouse cursor is stored here
+	//!@{
+	Sint16 xrel, yrel; 
+	//!@}
+} Command;
+
+#endif /* _MESSAGE_STRUCTURES_H */
Index: branches/heathaze/src/defs/sdlincl.h
===================================================================
--- branches/heathaze/src/defs/sdlincl.h	(revision 9940)
+++ branches/heathaze/src/defs/sdlincl.h	(revision 9940)
@@ -0,0 +1,20 @@
+/*!
+ * @file sdlincl.h
+ * This file includes sdl Headers.
+ *
+ * no Class is defined here, but the SDL Headers
+*/
+
+#ifndef _SDLINCL_H
+#define _SDLINCL_H
+
+#include "confincl.h"
+
+#ifdef HAVE_SDL_H
+#include <SDL.h>
+#else
+#include <SDL/SDL.h>
+#endif
+
+#endif /* _SDLINCL_H */
+
Index: branches/heathaze/src/defs/stdincl.h
===================================================================
--- branches/heathaze/src/defs/stdincl.h	(revision 9940)
+++ branches/heathaze/src/defs/stdincl.h	(revision 9940)
@@ -0,0 +1,26 @@
+/*!
+  \file stdincl.h
+  \brief This file includes default headers that nearly every Class needs.
+
+  no Class is defined here, but many headers to classes, and more general Headers like the openGL-header.
+*/
+
+#ifndef _STDINCL_H
+#define _STDINCL_H
+
+typedef unsigned char byte;
+
+#include "confincl.h"
+
+#ifdef __WIN32__
+//#include <windows.h>
+#endif
+
+#include "stdlibincl.h"
+
+#include "sdlincl.h"
+#include "glincl.h"
+
+#include "compiler.h"
+
+#endif /* _STDINCL_H */
Index: branches/heathaze/src/defs/stdlibincl.h
===================================================================
--- branches/heathaze/src/defs/stdlibincl.h	(revision 9940)
+++ branches/heathaze/src/defs/stdlibincl.h	(revision 9940)
@@ -0,0 +1,15 @@
+/*!
+ * @file stdlibincl.h
+ * some headers of the stdlib
+ *
+ * no Class is defined here.
+ */
+
+#ifndef _STDLIBINCL_H
+#define _STDLIBINCL_H
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#endif /* _STDLIBINCL_H */
Index: branches/heathaze/src/lib/BuildLibs.am
===================================================================
--- branches/heathaze/src/lib/BuildLibs.am	(revision 9940)
+++ branches/heathaze/src/lib/BuildLibs.am	(revision 9940)
@@ -0,0 +1,28 @@
+
+libORXlibs_a_LIBRARIES_ = \
+                $(LIB_PREFIX)/event/libORXevent.a \
+                $(LIB_PREFIX)/gui/qt/libORXqtgui.a \
+                $(LIB_PREFIX)/gui/gl/libORXglgui.a \
+                $(LIB_PREFIX)/gui/libORXbasegui.a \
+                $(LIB_PREFIX)/graphics/libORXgraphics.a \
+                $(LIB_PREFIX)/collision_detection/libORXcd.a \
+                $(LIB_PREFIX)/collision_reaction/libORXcr.a \
+                $(LIB_PREFIX)/network/libORXnet.a \
+                $(LIB_PREFIX)/graphics/spatial_separation/libORXquadtree.a \
+                $(LIB_PREFIX)/parser/tinyxml/libtinyxml.a \
+                $(LIB_PREFIX)/parser/preferences/libPrefsParser.a \
+                $(LIB_PREFIX)/parser/cmdline_parser/libCmdLineParser.a \
+                $(LIB_PREFIX)/parser/ini_parser/libIniParser.a \
+                $(LIB_PREFIX)/physics/libORXphysics.a \
+                $(LIB_PREFIX)/gui/gl/libORXglgui.a \
+                \
+                $(LIB_PREFIX)/graphics/importer/libORXimporter.a \
+                $(LIB_PREFIX)/graphics/importer/libtc.a \
+                $(LIB_PREFIX)/sound/libORXsound.a \
+                $(LIB_PREFIX)/shell/libORXshell.a \
+                $(LIB_PREFIX)/script_engine/libORXscript.a \
+                $(LIB_PREFIX)/util/libORXexecutor.a \
+                $(LIB_PREFIX)/util/libORXlibutil.a \
+                $(LIB_PREFIX)/lang/libORXlang.a \
+                $(LIB_PREFIX)/libORXlibs.a \
+                $(LIB_PREFIX)/math/libORXmath.a
Index: branches/heathaze/src/lib/Makefile.am
===================================================================
--- branches/heathaze/src/lib/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/Makefile.am	(revision 9940)
@@ -0,0 +1,33 @@
+MAINSRCDIR=..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXlibs.a
+
+libORXlibs_a_SOURCES = \
+		\
+		coord/p_node.cc \
+		\
+		data/data_tank.cc
+
+noinst_HEADERS = \
+		\
+		coord/p_node.h \
+		\
+		data/data_tank.h
+
+SUBDIRS = \
+	. \
+	math \
+	lang \
+	util \
+	graphics \
+	sound \
+	event \
+	physics \
+	collision_detection \
+	collision_reaction \
+	gui \
+	network \
+	shell \
+	parser \
+	script_engine
Index: branches/heathaze/src/lib/collision_detection/Makefile.am
===================================================================
--- branches/heathaze/src/lib/collision_detection/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/Makefile.am	(revision 9940)
@@ -0,0 +1,29 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXcd.a
+
+libORXcd_a_SOURCES = cd_engine.cc \
+                     obb.cc \
+                     obb_tree.cc \
+                     obb_tree_node.cc \
+                     bv_tree.cc \
+                     bv_tree_node.cc \
+                     bounding_volume.cc \
+                     bounding_sphere.cc \
+                     aabb_tree_node.cc \
+                     aabb.cc
+
+
+noinst_HEADERS =     cd_engine.h \
+                     collision_defs.h \
+                     obb.h \
+                     obb_tree.h \
+                     obb_tree_node.h \
+                     bv_tree.h \
+                     bv_tree_node.h \
+                     bounding_volume.h \
+                     bounding_sphere.h \
+                     aabb_tree_node.h \
+                     aabb.h
+
Index: branches/heathaze/src/lib/collision_detection/aabb.cc
===================================================================
--- branches/heathaze/src/lib/collision_detection/aabb.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/aabb.cc	(revision 9940)
@@ -0,0 +1,52 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_DETECTION
+
+#include "aabb.h"
+#include "vector.h"
+
+
+
+ObjectListDefinition(AABB);
+/**
+ *  standard constructor
+*/
+AABB::AABB ()
+{
+  this->registerObject(this, AABB::_objectList);
+   this->halfLength[0] = this->halfLength[1] = this->halfLength[2] = 0.0f;
+   this->bCollided = false;
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+AABB::~AABB ()
+{
+}
+
+
+
+void AABB::mergeWith(const BoundingVolume &bv)
+{}
+
+
+void AABB::drawBV(int currentDepth, int drawMode) const
+{}
+
+
Index: branches/heathaze/src/lib/collision_detection/aabb.h
===================================================================
--- branches/heathaze/src/lib/collision_detection/aabb.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/aabb.h	(revision 9940)
@@ -0,0 +1,43 @@
+/*!
+ * @file aabb.h
+  *  Definition of an AABB (Axix Aligned Bounding Box)
+
+*/
+
+#ifndef _AABB_H
+#define _AABB_H
+
+#include "base_object.h"
+#include "bounding_volume.h"
+
+//! A class representing an extended bounding volume tree: an obb tree
+class AABB : public BoundingVolume {
+  ObjectListDeclaration(AABB);
+
+ public:
+  AABB();
+  virtual ~AABB();
+
+
+  inline Vector getAxisX () const { return this->axis[0]; }
+  inline Vector getAxisY () const { return this->axis[1]; }
+  inline Vector getAxisZ () const { return this->axis[2]; }
+
+  inline const float* getHalfLength() const { return this->halfLength; }
+
+  virtual void mergeWith(const BoundingVolume &bv);
+
+  virtual void drawBV(int currentDepth, int drawMode) const;
+
+
+
+ public:
+  Vector           axis[3];                    //!< Axes of oriented box [x,y,z]
+  float            halfLength[3];              //!< Half lengths of the box along the axis
+  float            covarianceMatrix[3][3];     //!< the covariance matrix
+
+  bool             bCollided;                  //!< is true if this obb has collided
+
+};
+
+#endif /* _AABB_H */
Index: branches/heathaze/src/lib/collision_detection/aabb_tree_node.cc
===================================================================
--- branches/heathaze/src/lib/collision_detection/aabb_tree_node.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/aabb_tree_node.cc	(revision 9940)
@@ -0,0 +1,932 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE 3/* DEBUG_MODULE_COLLISION_DETECTION*/
+
+#include "aabb_tree_node.h"
+#include "aabb.h"
+
+#include "bv_tree.h"
+
+#include "matrix.h"
+#include "model.h"
+#include "world_entity.h"
+#include "plane.h"
+
+#include "color.h"
+#include "glincl.h"
+
+#include <list>
+#include <vector>
+#include "debug.h"
+
+GLUquadricObj* AABBTreeNode_sphereObj = NULL;
+
+ObjectListDefinition(AABBTreeNode);
+/**
+ *  standard constructor
+ * @param tree: reference to the obb tree
+ * @param depth: the depth of the obb tree to generate
+ */
+AABBTreeNode::AABBTreeNode (const OBBTree& tree, AABBTreeNode* prev, int depth)
+    : BVTreeNode()
+{
+  this->registerObject(this, AABBTreeNode::_objectList);
+
+  this->obbTree = &tree;
+  this->nodePrev = prev;
+  this->depth = depth;
+  this->nextID = 0;
+
+  this->init();
+}
+
+
+/**
+ *  standard constructor
+ * @param depth: the depth of the obb tree to generate
+ */
+AABBTreeNode::AABBTreeNode(int depth)
+{
+  this->depth = depth;
+
+  this->init();
+}
+
+/**
+ *  init funciton
+ */
+void AABBTreeNode::init()
+{
+  this->nodeLeft = NULL;
+  this->nodeRight = NULL;
+  this->bvElement = NULL;
+
+  this->triangleIndexList1 = NULL;
+  this->triangleIndexList2 = NULL;
+
+  this->modelInf = NULL;
+  this->triangleIndexes = NULL;
+
+  if( AABBTreeNode_sphereObj == NULL)
+    AABBTreeNode_sphereObj = gluNewQuadric();
+
+  this->owner = NULL;
+}
+
+/**
+ *  standard deconstructor
+ */
+AABBTreeNode::~AABBTreeNode ()
+{
+  if( this->nodeLeft)
+    delete this->nodeLeft;
+  if( this->nodeRight)
+    delete this->nodeRight;
+
+  if( this->bvElement)
+    delete this->bvElement;
+}
+
+
+
+void AABBTreeNode::spawnBVTree(Model* model)
+{
+
+  const modelInfo* modelInf = model->getModelInfo();
+
+  int* triangleIndexes = new int[modelInf->numTriangles];
+  for(unsigned int i = 0; i < modelInf->numTriangles; ++i)
+    triangleIndexes[i] = i;
+
+  this->spawnBVTree(*modelInf, triangleIndexes, modelInf->numTriangles);
+}
+
+
+/**
+ *  creates a new BVTree or BVTree partition
+ * @param depth: how much more depth-steps to go: if == 1 don't go any deeper!
+ * @param modInfo: model informations from the abstrac model
+ *
+ * this function creates the Bounding Volume tree from a modelInfo struct and bases its calculations
+ * on the triangle informations (triangle soup not polygon soup)
+ */
+void AABBTreeNode::spawnBVTree(const modelInfo& modelInf, const int* triangleIndexes, int length)
+{
+  PRINTF(4)("\n==============================Creating AABB Tree Node==================\n");
+  PRINT(4)(" AABB Tree Infos: \n");
+  PRINT(4)("\tDepth: %i \n\tTree Index: %i \n\tNumber of Triangles: %i\n", depth, this->treeIndex, length);
+  this->depth = depth;
+
+  this->bvElement = new AABB();
+  this->bvElement->modelInf = &modelInf;
+  this->bvElement->triangleIndexes = triangleIndexes;
+  this->bvElement->triangleIndexesLength = length;
+
+  /* create the bounding boxes in three steps */
+  this->calculateBoxCovariance(*this->bvElement, modelInf, triangleIndexes, length);
+  this->calculateBoxEigenvectors(*this->bvElement, modelInf, triangleIndexes, length);
+  this->calculateBoxAxis(*this->bvElement, modelInf, triangleIndexes, length);
+
+  /* do we need to descent further in the obb tree?*/
+  if( likely( this->depth > 0))
+  {
+    this->forkBox(*this->bvElement);
+
+    if( this->triangleIndexLength1 >= 3)
+    {
+      this->nodeLeft = new AABBTreeNode(*this->obbTree, this, depth - 1);
+      this->nodeLeft->spawnBVTree(modelInf, this->triangleIndexList1, this->triangleIndexLength1);
+    }
+    if( this->triangleIndexLength2 >= 3)
+    {
+      this->nodeRight = new AABBTreeNode(*this->obbTree, this, depth - 1);
+      this->nodeRight->spawnBVTree(modelInf, this->triangleIndexList2, this->triangleIndexLength2);
+    }
+  }
+}
+
+
+
+/**
+ *  calculate the box covariance matrix
+ * @param box: reference to the box
+ * @param modelInf: the model info structure of the model
+ * @param tirangleIndexes: an array with the indexes of the triangles inside this
+ * @param length: the length of the indexes array
+ */
+void AABBTreeNode::calculateBoxCovariance(AABB& box, const modelInfo& modelInf, const int* triangleIndexes, int length)
+{
+  float     facelet[length];                         //!< surface area of the i'th triangle of the convex hull
+  float     face = 0.0f;                             //!< surface area of the entire convex hull
+  Vector    centroid[length];                        //!< centroid of the i'th convex hull
+  Vector    center;                                  //!< the center of the entire hull
+  Vector    p, q, r;                                 //!< holder of the polygon data, much more conveniant to work with Vector than sVec3d
+  Vector    t1, t2;                                  //!< temporary values
+  float     covariance[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}};//!< the covariance matrix
+
+  /* fist compute all the convex hull face/facelets and centroids */
+  for( int i = 0; i < length ; ++i)
+  {
+    p = &modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[0]];
+    q = &modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[1]];
+    r = &modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[2]];
+
+    /* finding the facelet surface via cross-product */
+    t1 = p - q;
+    t2 = p - r;
+    facelet[i] = 0.5f * /*fabs*/( t1.cross(t2).len() );
+    /* update the entire convex hull surface */
+    face += facelet[i];
+
+    /* calculate the cetroid of the hull triangles */
+    centroid[i] = (p + q + r) / 3.0f;
+    /* now calculate the centroid of the entire convex hull, weighted average of triangle centroids */
+    center += centroid[i] * facelet[i];
+    /* the arithmetical center */
+  }
+  /* take the average of the centroid sum */
+  center /= face;
+
+
+  /* now calculate the covariance matrix - if not written in three for-loops,
+     it would compute faster: minor */
+  for( int j = 0; j < 3; ++j)
+  {
+    for( int k = 0; k < 3; ++k)
+    {
+      for( int i = 0; i < length; ++i)
+      {
+        p = (&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[0]]);
+        q = (&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[1]]);
+        r = (&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[2]]);
+
+        covariance[j][k] = facelet[i] * (9.0f * centroid[i][j] * centroid[i][k] + p[j] * p[k] +
+                           q[j] * q[k] + r[j] * r[k]);
+      }
+      covariance[j][k] = covariance[j][k] / (12.0f * face) - center[j] * center[k];
+    }
+  }
+  for( int i = 0; i < 3; ++i)
+  {
+    box.covarianceMatrix[i][0] = covariance[i][0];
+    box.covarianceMatrix[i][1] = covariance[i][1];
+    box.covarianceMatrix[i][2] = covariance[i][2];
+  }
+  box.center = center;
+
+  /* debug output section*/
+  PRINTF(4)("\nOBB Covariance Matrix:\n");
+  for(int j = 0; j < 3; ++j)
+  {
+    PRINT(4)("\t\t");
+    for(int k = 0; k < 3; ++k)
+    {
+      PRINT(4)("%11.4f\t", covariance[j][k]);
+    }
+    PRINT(4)("\n");
+  }
+  PRINTF(4)("\nWeighteed AABB Center:\n\t\t%11.4f\t %11.4f\t %11.4f\n", center.x, center.y, center.z);
+}
+
+
+
+/**
+ *  calculate the eigenvectors for the object oriented box
+ * @param box: reference to the box
+ * @param modelInf: the model info structure of the model
+ * @param tirangleIndexes: an array with the indexes of the triangles inside this
+ * @param length: the length of the indexes array
+ */
+void AABBTreeNode::calculateBoxEigenvectors(AABB& box, const modelInfo& modelInf,
+    const int* triangleIndexes, int length)
+{
+  Matrix         covMat(  box.covarianceMatrix  );   //!< covariance matrix (in the matrix dataform)
+
+  /*
+  now getting spanning vectors of the sub-space:
+  the eigenvectors of a symmertric matrix, such as the
+  covarience matrix are mutually orthogonal.
+  after normalizing them, they can be used as a the basis
+  vectors
+  */
+
+
+  // this is for axis aligned bouning boxes only
+   box.axis[0] = Vector(1,0,0);
+   box.axis[1] = Vector(0,1,0);
+   box.axis[2] = Vector(0,0,1);
+
+   PRINTF(4)("Eigenvectors:\n");
+   PRINT(4)("\t\t%11.2f \t%11.2f \t%11.2f\n", box.axis[0].x, box.axis[0].y, box.axis[0].z);
+   PRINT(4)("\t\t%11.2f \t%11.2f \t%11.2f\n", box.axis[1].x, box.axis[1].y, box.axis[1].z);
+   PRINT(4)("\t\t%11.2f \t%11.2f \t%11.2f\n", box.axis[2].x, box.axis[2].y, box.axis[2].z);
+}
+
+
+
+
+/**
+ *  calculate the eigenvectors for the object oriented box
+ * @param box: reference to the box
+ * @param modelInf: the model info structure of the model
+ * @param tirangleIndexes: an array with the indexes of the triangles inside this
+ * @param length: the length of the indexes array
+ */
+void AABBTreeNode::calculateBoxAxis(AABB& box, const modelInfo& modelInf, const int* triangleIndexes, int length)
+{
+
+  PRINTF(4)("Calculate Box Axis\n");
+  /* now get the axis length */
+  float               tmpLength;                             //!< tmp save point for the length
+  Plane               p0(box.axis[0], box.center);           //!< the axis planes
+  Plane               p1(box.axis[1], box.center);           //!< the axis planes
+  Plane               p2(box.axis[2], box.center);           //!< the axis planes
+  float               maxLength[3];                          //!< maximal lenth of the axis
+  float               minLength[3];                          //!< minimal length of the axis
+  const float*        tmpVec;                                //!< variable taking tmp vectors
+  float               centerOffset[3];
+
+  /* get the maximal dimensions of the body in all directions */
+  /* for the initialisation the value just has to be inside of the polygon soup -> first vertices (rand) */
+  for( int k = 0; k  < 3; k++)
+  {
+    tmpVec = (&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[0]].indexToVertices[0]]);
+    Plane* p;
+    if( k == 0)
+      p = &p0;
+    else if( k == 1)
+      p = &p1;
+    else
+      p = &p2;
+    maxLength[k] = p->distancePoint(tmpVec);
+    minLength[k] = p->distancePoint(tmpVec);
+
+    for( int j = 0; j < length; ++j) {
+      for( int i = 0; i < 3; ++i) {
+        tmpVec = &modelInf.pVertices[modelInf.pTriangles[triangleIndexes[j]].indexToVertices[i]];
+        tmpLength = p->distancePoint(tmpVec);
+
+        if( tmpLength > maxLength[k])
+          maxLength[k] = tmpLength;
+        else if( tmpLength < minLength[k])
+          minLength[k] = tmpLength;
+      }
+    }
+  }
+
+
+
+  /* calculate the real centre of the body by using the axis length */
+  for( int i = 0; i < 3; ++i)
+  {
+    if( maxLength[i] > 0.0f && minLength[i] > 0.0f)  // both axis positiv
+      centerOffset[i] = minLength[i] + (maxLength[i] - minLength[i]) / 2.0f;
+    else if( maxLength[i] > 0.0f && maxLength[i] < 0.0f) // positiv and negativ
+      centerOffset[i] = (maxLength[i] + minLength[i]) / 2.0f;
+    else //both negativ
+     centerOffset[i] = minLength[i] + (maxLength[i] - minLength[i]) / 2.0f;
+
+    box.halfLength[i] = (maxLength[i] - minLength[i]) / 2.0f;
+  }
+
+  box.center += (box.axis[0] * centerOffset[0]);
+  box.center += (box.axis[1] * centerOffset[1]);
+  box.center += (box.axis[2] * centerOffset[2]);
+
+
+  PRINTF(4)("\n");
+  PRINT(4)("\tAxis halflength x: %11.2f (max: %11.2f, \tmin: %11.2f), offset: %11.2f\n", box.halfLength[0], maxLength[0], minLength[0], centerOffset[0]);
+  PRINT(4)("\tAxis halflength y: %11.2f (max: %11.2f, \tmin: %11.2f), offset: %11.2f\n", box.halfLength[1], maxLength[1], minLength[1], centerOffset[1] );
+  PRINT(4)("\tAxis halflength z: %11.2f (max: %11.2f, \tmin: %11.2f), offset: %11.2f\n", box.halfLength[2], maxLength[2], minLength[2], centerOffset[2]);
+}
+
+
+
+/**
+ *  this separates an ob-box in the middle
+ * @param box: the box to separate
+ *
+ * this will separate the box into to smaller boxes. the separation is done along the middle of the longest axis
+ */
+void AABBTreeNode::forkBox(AABB& box)
+{
+
+  PRINTF(4)("Fork Box\n");
+  PRINTF(4)("Calculating the longest Axis\n");
+  /* get the longest axis of the box */
+  float               longestAxis = -1.0f;                 //!< the length of the longest axis
+  int                 longestAxisIndex = 0;                //!< this is the nr of the longest axis
+
+
+  /* now get the longest axis of the three exiting */
+  for( int i = 0; i < 3; ++i)
+  {
+    if( longestAxis < box.halfLength[i])
+    {
+      longestAxis = box.halfLength[i];
+      longestAxisIndex = i;
+    }
+  }
+  PRINTF(4)("\nLongest Axis is: Nr %i with a half-length of:%11.2f\n", longestAxisIndex, longestAxis);
+
+
+  PRINTF(4)("Separating along the longest axis\n");
+  /* get the closest vertex near the center */
+  float               tmpDist;                             //!< variable to save diverse distances temporarily
+  Plane               middlePlane(box.axis[longestAxisIndex], box.center); //!< the middle plane
+
+
+  /* now definin the separation plane through this specified nearest point and partition
+  the points depending on which side they are located
+  */
+  std::list<int>           partition1;                           //!< the vertex partition 1
+  std::list<int>           partition2;                           //!< the vertex partition 2
+  float*                   triangleCenter = new float[3];        //!< the center of the triangle
+  const float*             a;                                    //!< triangle  edge a
+  const float*             b;                                    //!< triangle  edge b
+  const float*             c;                                    //!< triangle  edge c
+
+
+  /* find the center of the box */
+  this->separationPlane = Plane(box.axis[longestAxisIndex], box.center);
+  this->sepPlaneCenter[0] = box.center.x;
+  this->sepPlaneCenter[1] = box.center.y;
+  this->sepPlaneCenter[2] = box.center.z;
+  this->longestAxisIndex = longestAxisIndex;
+
+  for( int i = 0; i < box.triangleIndexesLength; ++i)
+  {
+    /* first calculate the middle of the triangle */
+    a = &box.modelInf->pVertices[box.modelInf->pTriangles[box.triangleIndexes[i]].indexToVertices[0]];
+    b = &box.modelInf->pVertices[box.modelInf->pTriangles[box.triangleIndexes[i]].indexToVertices[1]];
+    c = &box.modelInf->pVertices[box.modelInf->pTriangles[box.triangleIndexes[i]].indexToVertices[2]];
+
+    triangleCenter[0] = (a[0] + b[0] + c[0]) / 3.0f;
+    triangleCenter[1] = (a[1] + b[1] + c[1]) / 3.0f;
+    triangleCenter[2] = (a[2] + b[2] + c[2]) / 3.0f;
+    tmpDist = this->separationPlane.distancePoint(*((sVec3D*)triangleCenter));
+
+    if( tmpDist > 0.0f)
+      partition1.push_back(box.triangleIndexes[i]); /* positive numbers plus zero */
+    else if( tmpDist < 0.0f)
+      partition2.push_back(box.triangleIndexes[i]); /* negatice numbers */
+    else {
+      partition1.push_back(box.triangleIndexes[i]); /* 0.0f? unprobable... */
+      partition2.push_back(box.triangleIndexes[i]);
+    }
+  }
+  PRINTF(4)("\nPartition1: got \t%i Vertices \nPartition2: got \t%i Vertices\n", partition1.size(), partition2.size());
+
+
+  /* now comes the separation into two different sVec3D arrays */
+  int                index;                                //!< index storage place
+  int*               triangleIndexList1;                   //!< the vertex list 1
+  int*               triangleIndexList2;                   //!< the vertex list 2
+  std::list<int>::iterator element;                        //!< the list iterator
+
+  triangleIndexList1 = new int[partition1.size()];
+  triangleIndexList2 = new int[partition2.size()];
+
+  for( element = partition1.begin(), index = 0; element != partition1.end(); element++, index++)
+    triangleIndexList1[index] = (*element);
+
+  for( element = partition2.begin(), index = 0; element != partition2.end(); element++, index++)
+    triangleIndexList2[index] = (*element);
+
+  if( this->triangleIndexList1!= NULL)
+    delete[] this->triangleIndexList1;
+  this->triangleIndexList1 = triangleIndexList1;
+  this->triangleIndexLength1 = partition1.size();
+
+  if( this->triangleIndexList2 != NULL)
+    delete[] this->triangleIndexList2;
+  this->triangleIndexList2 = triangleIndexList2;
+  this->triangleIndexLength2 = partition2.size();
+}
+
+
+
+/**
+ * collides one tree with an other
+ *  @param treeNode the other bv tree node
+ *  @param nodeA  the worldentity belonging to this bv
+ *  @param nodeB the worldentity belonging to treeNode
+ */
+void AABBTreeNode::collideWith(BVTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB)
+{
+  if( unlikely(treeNode == NULL || nodeA == NULL || nodeB == NULL))
+    return;
+
+  PRINTF(4)("collideWith\n");
+  PRINTF(5)("Checking AABB %i vs %i: ", this->getIndex(), treeNode->getIndex());
+
+  // for now only collide with AABBTreeNodes
+  this->collideWithOBB((AABBTreeNode*)treeNode, nodeA, nodeB);
+}
+
+
+
+/**
+ * collides one obb tree with an other
+ *  @param treeNode the other bv tree node
+ *  @param nodeA  the worldentity belonging to this bv
+ *  @param nodeB the worldentity belonging to treeNode
+ */
+void AABBTreeNode::collideWithOBB(AABBTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB)
+{
+
+  if( this->overlapTest(this->bvElement, treeNode->bvElement, nodeA, nodeB))
+  {
+    PRINTF(5)("collision @ lvl %i, object %s::%s vs. %s::%s, (%p, %p)\n", this->depth, nodeA->getClassCName(), nodeA->getCName(), nodeB->getClassCName(), nodeA->getCName(), this->nodeLeft, this->nodeRight);
+
+
+    // left node
+    if( this->nodeLeft != NULL )
+    {
+      if( this->overlapTest(this->nodeLeft->bvElement, treeNode->bvElement, nodeA, nodeB))
+      {
+        if( treeNode->nodeLeft != NULL)
+          this->nodeLeft->collideWith(treeNode->nodeLeft, nodeA, nodeB);
+        if( treeNode->nodeRight != NULL)
+          this->nodeLeft->collideWith(treeNode->nodeRight, nodeA, nodeB);
+      }
+    }
+
+    // right node
+    if( this->nodeRight != NULL )
+    {
+      if( this->overlapTest(this->nodeRight->bvElement, treeNode->bvElement, nodeA, nodeB))
+      {
+        if( treeNode->nodeLeft != NULL)
+          this->nodeRight->collideWith(treeNode->nodeLeft, nodeA, nodeB);
+        if( treeNode->nodeRight != NULL)
+          this->nodeRight->collideWith(treeNode->nodeRight, nodeA, nodeB);
+      }
+    }
+
+
+    // hybrid mode: we reached the end of this obbtree, now reach the end of the other tree
+    if( this->nodeLeft == NULL && this->nodeRight == NULL)
+    {
+      if( treeNode->nodeLeft != NULL)
+        this->collideWith(treeNode->nodeLeft, nodeA, nodeB);
+      if( treeNode->nodeRight != NULL)
+        this->collideWith(treeNode->nodeRight, nodeA, nodeB);
+    }
+
+
+    // now check if we reached the end of both trees
+    if( unlikely((this->nodeRight == NULL && this->nodeLeft == NULL) &&
+        (treeNode->nodeRight == NULL && treeNode->nodeLeft == NULL)) )
+    {
+      nodeA->registerCollision(nodeA, nodeB, (BoundingVolume*)this->bvElement, (BoundingVolume*)treeNode->bvElement);
+    }
+
+  }
+}
+
+
+/**
+ * this actualy checks if one obb box touches the other
+ * @param boxA the box from nodeA
+ * @param boxB the box from nodeB
+ * @param nodeA the node itself
+ * @param nodeB the node itself
+ */
+bool AABBTreeNode::overlapTest(AABB* boxA, AABB* boxB, WorldEntity* nodeA, WorldEntity* nodeB)
+{
+  //HACK remove this again
+  this->owner = nodeA;
+  //   if( boxB == NULL || boxA == NULL)
+  //     return false;
+
+  /* first check all axis */
+  Vector      t;
+  float       rA = 0.0f;
+  float       rB = 0.0f;
+  Vector      l;
+  Vector      rotAxisA[3];
+  Vector      rotAxisB[3];
+
+  rotAxisA[0] =  nodeA->getAbsDir().apply(boxA->axis[0]);
+  rotAxisA[1] =  nodeA->getAbsDir().apply(boxA->axis[1]);
+  rotAxisA[2] =  nodeA->getAbsDir().apply(boxA->axis[2]);
+
+  rotAxisB[0] =  nodeB->getAbsDir().apply(boxB->axis[0]);
+  rotAxisB[1] =  nodeB->getAbsDir().apply(boxB->axis[1]);
+  rotAxisB[2] =  nodeB->getAbsDir().apply(boxB->axis[2]);
+
+  t = nodeA->getAbsCoor() + nodeA->getAbsDir().apply(boxA->center) - ( nodeB->getAbsCoor() + nodeB->getAbsDir().apply(boxB->center));
+
+  /* All 3 axis of the object A */
+  for( int j = 0; j < 3; ++j)
+  {
+    rA = 0.0f;
+    rB = 0.0f;
+    l = rotAxisA[j];
+
+    rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
+    rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
+    rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
+
+    rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
+    rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
+    rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
+
+    PRINTF(5)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
+
+    if( (rA + rB) < fabs(t.dot(l)))
+    {
+      PRINTF(4)("no Collision\n");
+      return false;
+    }
+  }
+
+  /* All 3 axis of the object B */
+  for( int j = 0; j < 3; ++j)
+  {
+    rA = 0.0f;
+    rB = 0.0f;
+    l = rotAxisB[j];
+
+    rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
+    rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
+    rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
+
+    rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
+    rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
+    rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
+
+    PRINTF(5)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
+
+    if( (rA + rB) < fabs(t.dot(l)))
+    {
+      PRINTF(4)("no Collision\n");
+      return false;
+    }
+  }
+
+
+  /* Now check for all face cross products */
+
+  for( int j = 0; j < 3; ++j)
+  {
+    for(int k = 0; k < 3; ++k )
+    {
+      rA = 0.0f;
+      rB = 0.0f;
+      l = rotAxisA[j].cross(rotAxisB[k]);
+
+      rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
+      rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
+      rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
+
+      rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
+      rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
+      rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
+
+      PRINTF(5)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
+
+      if( (rA + rB) < fabs(t.dot(l)))
+      {
+        PRINTF(4)("keine Kollision\n");
+        return false;
+      }
+    }
+  }
+
+  /* FIXME: there is no collision mark set now */
+     boxA->bCollided = true; /* use this ONLY(!!!!) for drawing operations */
+     boxB->bCollided = true;
+
+
+  PRINTF(4)("Kollision!\n");
+  return true;
+}
+
+
+/**
+ *
+ * draw the BV tree - debug mode
+ */
+void AABBTreeNode::drawBV(int depth, int drawMode, const Vector& color,  bool top) const
+{
+  /* this function can be used to draw the triangles and/or the points only  */
+  if( 1 /*drawMode & DRAW_MODEL || drawMode & DRAW_ALL*/)
+  {
+    if( depth == 0/*!(drawMode & DRAW_SINGLE && depth != 0)*/)
+    {
+      if( 1 /*drawMode & DRAW_POINTS*/)
+      {
+        glBegin(GL_POINTS);
+        glColor3f(0.3, 0.8, 0.54);
+        for(unsigned int i = 0; i < this->bvElement->modelInf->numVertices*3; i+=3)
+          glVertex3f(this->bvElement->modelInf->pVertices[i],
+                     this->bvElement->modelInf->pVertices[i+1],
+                     this->bvElement->modelInf->pVertices[i+2]);
+        glEnd();
+      }
+    }
+  }
+
+  if (top)
+  {
+    glPushAttrib(GL_ENABLE_BIT);
+    glDisable(GL_LIGHTING);
+    glDisable(GL_TEXTURE_2D);
+  }
+  glColor3f(color.x, color.y, color.z);
+
+
+  /* draw world axes */
+  if( 1 /*drawMode & DRAW_BV_AXIS*/)
+  {
+    glBegin(GL_LINES);
+    glColor3f(1.0, 0.0, 0.0);
+    glVertex3f(0.0, 0.0, 0.0);
+    glVertex3f(3.0, 0.0, 0.0);
+
+    glColor3f(0.0, 1.0, 0.0);
+    glVertex3f(0.0, 0.0, 0.0);
+    glVertex3f(0.0, 3.0, 0.0);
+
+    glColor3f(0.0, 0.0, 1.0);
+    glVertex3f(0.0, 0.0, 0.0);
+    glVertex3f(0.0, 0.0, 3.0);
+    glEnd();
+  }
+
+
+  if( 1/*drawMode & DRAW_BV_AXIS || drawMode & DRAW_ALL*/)
+  {
+    if( 1/*drawMode & DRAW_SINGLE && depth != 0*/)
+    {
+      /* draw the obb axes */
+      glBegin(GL_LINES);
+      glColor3f(1.0, 0.0, 0.0);
+      glVertex3f(this->bvElement->center.x, this->bvElement->center.y, this->bvElement->center.z);
+      glVertex3f(this->bvElement->center.x + this->bvElement->axis[0].x * this->bvElement->halfLength[0],
+                 this->bvElement->center.y + this->bvElement->axis[0].y * this->bvElement->halfLength[0],
+                 this->bvElement->center.z + this->bvElement->axis[0].z * this->bvElement->halfLength[0]);
+
+      glColor3f(0.0, 1.0, 0.0);
+      glVertex3f(this->bvElement->center.x, this->bvElement->center.y, this->bvElement->center.z);
+      glVertex3f(this->bvElement->center.x + this->bvElement->axis[1].x * this->bvElement->halfLength[1],
+                 this->bvElement->center.y + this->bvElement->axis[1].y * this->bvElement->halfLength[1],
+                 this->bvElement->center.z + this->bvElement->axis[1].z * this->bvElement->halfLength[1]);
+
+      glColor3f(0.0, 0.0, 1.0);
+      glVertex3f(this->bvElement->center.x, this->bvElement->center.y, this->bvElement->center.z);
+      glVertex3f(this->bvElement->center.x + this->bvElement->axis[2].x * this->bvElement->halfLength[2],
+                 this->bvElement->center.y + this->bvElement->axis[2].y * this->bvElement->halfLength[2],
+                 this->bvElement->center.z + this->bvElement->axis[2].z * this->bvElement->halfLength[2]);
+      glEnd();
+    }
+  }
+
+
+  /* DRAW POLYGONS */
+  if( drawMode & DRAW_BV_POLYGON || drawMode & DRAW_ALL || drawMode & DRAW_BV_BLENDED)
+  {
+    if (top)
+    {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+    }
+
+    if( this->nodeLeft == NULL && this->nodeRight == NULL)
+      depth = 0;
+
+    if( depth == 0 /*!(drawMode & DRAW_SINGLE && depth != 0)*/)
+    {
+
+
+      Vector cen = this->bvElement->center;
+      Vector* axis = this->bvElement->axis;
+      float* len = this->bvElement->halfLength;
+
+      if( this->bvElement->bCollided)
+      {
+        glColor4f(1.0, 1.0, 1.0, .5); // COLLISION COLOR
+      }
+      else if( drawMode & DRAW_BV_BLENDED)
+      {
+        glColor4f(color.x, color.y, color.z, .5);
+      }
+
+
+      /* draw bounding box */
+      if( drawMode & DRAW_BV_BLENDED)
+        glBegin(GL_QUADS);
+      else
+        glBegin(GL_LINE_LOOP);
+      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+      glEnd();
+
+      if( drawMode & DRAW_BV_BLENDED)
+        glBegin(GL_QUADS);
+      else
+        glBegin(GL_LINE_LOOP);
+      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+      glEnd();
+
+      if( drawMode & DRAW_BV_BLENDED)
+        glBegin(GL_QUADS);
+      else
+        glBegin(GL_LINE_LOOP);
+      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+      glEnd();
+
+      if( drawMode & DRAW_BV_BLENDED)
+        glBegin(GL_QUADS);
+      else
+        glBegin(GL_LINE_LOOP);
+      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+      glEnd();
+
+
+      if( drawMode & DRAW_BV_BLENDED)
+      {
+        glBegin(GL_QUADS);
+        glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                   cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                   cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+        glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                   cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                   cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+        glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                   cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                   cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+        glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                   cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                   cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+        glEnd();
+
+        glBegin(GL_QUADS);
+        glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                   cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                   cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+        glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                   cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                   cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+        glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                   cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                   cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+        glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                   cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                   cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+        glEnd();
+      }
+
+      if( drawMode & DRAW_BV_BLENDED)
+        glColor3f(color.x, color.y, color.z);
+    }
+  }
+
+  /* DRAW SEPARATING PLANE */
+  if( drawMode & DRAW_SEPARATING_PLANE || drawMode & DRAW_ALL)
+  {
+    if( !(drawMode & DRAW_SINGLE && depth != 0))
+    {
+      if( drawMode & DRAW_BV_BLENDED)
+        glColor4f(color.x, color.y, color.z, .6);
+
+      /* now draw the separation plane */
+      Vector a1 = this->bvElement->axis[(this->longestAxisIndex + 1)%3];
+      Vector a2 = this->bvElement->axis[(this->longestAxisIndex + 2)%3];
+      Vector c = this->bvElement->center;
+      float l1 = this->bvElement->halfLength[(this->longestAxisIndex + 1)%3];
+      float l2 = this->bvElement->halfLength[(this->longestAxisIndex + 2)%3];
+      glBegin(GL_QUADS);
+      glVertex3f(c.x + a1.x * l1 + a2.x * l2, c.y + a1.y * l1+ a2.y * l2, c.z + a1.z * l1 + a2.z * l2);
+      glVertex3f(c.x - a1.x * l1 + a2.x * l2, c.y - a1.y * l1+ a2.y * l2, c.z - a1.z * l1 + a2.z * l2);
+      glVertex3f(c.x - a1.x * l1 - a2.x * l2, c.y - a1.y * l1- a2.y * l2, c.z - a1.z * l1 - a2.z * l2);
+      glVertex3f(c.x + a1.x * l1 - a2.x * l2, c.y + a1.y * l1- a2.y * l2, c.z + a1.z * l1 - a2.z * l2);
+      glEnd();
+
+      if( drawMode & DRAW_BV_BLENDED)
+        glColor4f(color.x, color.y, color.z, 1.0);
+
+    }
+  }
+
+
+
+  if (depth > 0)
+  {
+    if( this->nodeLeft != NULL)
+      this->nodeLeft->drawBV(depth - 1, drawMode, Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(15.0,0.0,0.0)), false);
+    if( this->nodeRight != NULL)
+      this->nodeRight->drawBV(depth - 1, drawMode, Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(30.0,0.0,0.0)), false);
+  }
+  this->bvElement->bCollided = false;
+
+  if (top)
+    glPopAttrib();
+}
+
+
+
+void AABBTreeNode::debug() const
+{
+  PRINT(0)("========AABBTreeNode::debug()=====\n");
+  PRINT(0)(" Current depth: %i", this->depth);
+  PRINT(0)(" ");
+  PRINT(0)("=================================\n");
+}
Index: branches/heathaze/src/lib/collision_detection/aabb_tree_node.h
===================================================================
--- branches/heathaze/src/lib/collision_detection/aabb_tree_node.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/aabb_tree_node.h	(revision 9940)
@@ -0,0 +1,87 @@
+/*!
+ * @file aabb_tree_node.h
+ *  Definition of a bounding volume tree
+ */
+
+#ifndef _AABB_TREE_NODE_H
+#define _AABB_TREE_NODE_H
+
+
+#include "bv_tree_node.h"
+#include "plane.h"
+
+class BoundingVolume;
+class AABB;
+class OBBTree;
+class Plane;
+class PNode;
+
+
+//! A class that represents a bounding volume tree
+class AABBTreeNode : public BVTreeNode
+{
+  ObjectListDeclaration(AABBTreeNode);
+
+
+  public:
+    AABBTreeNode(const OBBTree& tree, AABBTreeNode* prev, int depth);
+    AABBTreeNode(int depth = 0);
+    virtual ~AABBTreeNode();
+    void init();
+
+    /**  this function returns the bounding volume of this tree node @return: returns the BV */
+    virtual inline const BoundingVolume* getBV() const { return (BoundingVolume*)this->bvElement; }
+
+    void spawnBVTree(Model* model);
+    virtual void spawnBVTree(const modelInfo& modelInf, const int* triangleIndexes, int length);
+
+    virtual void collideWith(BVTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB);
+    virtual void drawBV(int depth, int drawMode, const Vector& color = Vector(1,0,0), bool top = true) const;
+    void debug() const;
+
+    /**  gets the id of the current child @return id of the child */
+    inline const int getID() { return this->nextID++; }
+    inline AABB* getAABB() { return this->bvElement; }
+
+  private:
+    void calculateBoxAxis(AABB& box, const sVec3D* verticesList, unsigned int length);
+
+    void calculateBoxCovariance(AABB& box, const modelInfo& modelInf, const int* triangleIndexes, int length);
+    void calculateBoxEigenvectors(AABB& box, const modelInfo& modelInf, const int* triangleIndexes, int length);
+    void calculateBoxAxis(AABB& box, const modelInfo& modelInf, const int* triangleIndexes, int length);
+    void forkBox(AABB& box);
+
+    void collideWithOBB(AABBTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB);
+    bool overlapTest(AABB* boxA, AABB* boxB, WorldEntity* nodeA, WorldEntity* nodeB);
+
+
+  protected:
+    AABB*                bvElement;                  //!< the obb element
+    AABBTreeNode*        nodePrev;                   //!< ref to the previous (parent) tree node = NULL if first
+    AABBTreeNode*        nodeLeft;                   //!< ref to the left tree node
+    AABBTreeNode*        nodeRight;                  //!< ref to the right tree node
+
+
+  private:
+    int                 treeIndex;                  //!< Index number of the BV in the tree
+    int                 nextID;                     //!< the id of the next child
+    int                 depth;                      //!< the depth of the node in the tree
+    const OBBTree*      obbTree;                    //!< reference to the obb tree
+
+    const modelInfo*    modelInf;                   //!< pointer to the models modelInfo object
+    const int*          triangleIndexes;            //!< indexes to the used model triangles
+
+    Plane               separationPlane;            //!< the separation plane of the obb
+    sVec3D              sepPlaneCenter;             //!< only needed to draw plane
+    int                 longestAxisIndex;           //!< only needed to draw plane
+
+    /* tmp saving place for obb variables */
+    int*                triangleIndexList1;         //!< pointer to the vert data of obbox1
+    int*                triangleIndexList2;         //!< pointer to the vert data of obbox1
+    int                 triangleIndexLength1;       //!< len vert data obbox1
+    int                 triangleIndexLength2;       //!< len vert data obbox2
+
+    WorldEntity*        owner;
+};
+
+#endif /* _AABB_TREE_NODE_H */
Index: branches/heathaze/src/lib/collision_detection/bounding_sphere.cc
===================================================================
--- branches/heathaze/src/lib/collision_detection/bounding_sphere.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/bounding_sphere.cc	(revision 9940)
@@ -0,0 +1,39 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_DETECTION
+
+#include "bounding_sphere.h"
+
+
+
+ObjectListDefinition(BoundingSphere);
+/**
+ *  standard constructor
+*/
+BoundingSphere::BoundingSphere ()
+{
+  this->registerObject(this, BoundingSphere::_objectList);
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+BoundingSphere::~BoundingSphere ()
+{
+  // delete what has to be deleted here
+}
Index: branches/heathaze/src/lib/collision_detection/bounding_sphere.h
===================================================================
--- branches/heathaze/src/lib/collision_detection/bounding_sphere.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/bounding_sphere.h	(revision 9940)
@@ -0,0 +1,28 @@
+/*!
+ * @file bounding_sphere.h
+  *  Definition of a bounding sphere
+
+*/
+
+#ifndef _BOUNDING_SPHERE_H
+#define _BOUNDING_SPHERE_H
+
+#include "base_object.h"
+#include "bounding_volume.h"
+
+
+//! A class representing an extended bounding volume tree: an sphere
+class BoundingSphere : public BoundingVolume {
+  ObjectListDeclaration(BoundingSphere);
+
+ public:
+  BoundingSphere();
+  virtual ~BoundingSphere();
+
+  inline const float getRadius () const { return this->radius; }
+
+ private:
+  float radius;
+};
+
+#endif /* _BOUNDING_SPHERE_H */
Index: branches/heathaze/src/lib/collision_detection/bounding_volume.cc
===================================================================
--- branches/heathaze/src/lib/collision_detection/bounding_volume.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/bounding_volume.cc	(revision 9940)
@@ -0,0 +1,43 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_DETECTION
+
+#include "bounding_volume.h"
+
+
+
+ObjectListDefinition(BoundingVolume);
+/**
+ *  standard constructor
+*/
+BoundingVolume::BoundingVolume ()
+{
+  this->registerObject(this, BoundingVolume::_objectList);
+  this->modelInf = NULL;
+  this->triangleIndexes = NULL;
+  this->triangleIndexesLength = 0;
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+BoundingVolume::~BoundingVolume ()
+{
+  if( this->triangleIndexes)
+    delete[] this->triangleIndexes;
+}
Index: branches/heathaze/src/lib/collision_detection/bounding_volume.h
===================================================================
--- branches/heathaze/src/lib/collision_detection/bounding_volume.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/bounding_volume.h	(revision 9940)
@@ -0,0 +1,45 @@
+/*!
+ * @file bounding_volume.h
+  *  Definition of a bounding volume for collision detection algorithms
+
+ */
+
+#ifndef _BOUNDING_VOLUME_H
+#define _BOUNDING_VOLUME_H
+
+#include "base_object.h"
+#include "model.h"
+
+
+template<class T> class tList;
+
+
+//! An abstract class representing a bounding volume
+class BoundingVolume : public BaseObject {
+  ObjectListDeclaration(BoundingVolume);
+
+  public:
+    BoundingVolume();
+    virtual ~BoundingVolume();
+
+    inline const Vector& getCenter() const { return this->center; }
+    inline const modelInfo* getModelInfo() const { return this->modelInf; }
+
+    virtual void mergeWith(const BoundingVolume &bv) = 0;
+
+    virtual void drawBV(int currentDepth, int drawMode) const = 0;
+
+
+
+  public:
+    Vector              center;                     //!< Weighter average center point of box
+    Vector              arithCenter;                //!< Arithmetical center of the box
+
+    const modelInfo*    modelInf;                   //!< Reference to the model's ModelInfo
+    const int*          triangleIndexes;            //!< Array with the triangle indexes in modelInfo
+    int                 triangleIndexesLength;      //!< length of the indexes array
+
+    float               radius;                     //!< the radius of the box (longest axis)
+};
+
+#endif /* _BOUNDING_VOLUME_H */
Index: branches/heathaze/src/lib/collision_detection/bv_tree.cc
===================================================================
--- branches/heathaze/src/lib/collision_detection/bv_tree.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/bv_tree.cc	(revision 9940)
@@ -0,0 +1,43 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_DETECTION
+
+#include "bv_tree.h"
+
+
+
+
+ObjectListDefinition(BVTree);
+/**
+ *  standard constructor
+*/
+BVTree::BVTree ()
+{
+  this->registerObject(this, BVTree::_objectList);
+
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+BVTree::~BVTree ()
+{
+  // delete what has to be deleted here
+}
+
+
Index: branches/heathaze/src/lib/collision_detection/bv_tree.h
===================================================================
--- branches/heathaze/src/lib/collision_detection/bv_tree.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/bv_tree.h	(revision 9940)
@@ -0,0 +1,52 @@
+/*!
+ * @file bv_tree.h
+  *  Definition of a bounding volume tree
+
+*/
+
+#ifndef _BV_TREE_H
+#define _BV_TREE_H
+
+
+#include "base_object.h"
+#include "model.h"
+
+// FORWARD DECLARATION
+class BoundingVolume;
+class BVTreeNode;
+class PNode;
+class WorldEntity;
+
+//! draw mode for the bounding volume
+typedef enum DrawMode
+{
+  DRAW_ALL               = 1<<0,
+  DRAW_SINGLE            = 1<<1,
+
+  DRAW_SEPARATING_PLANE  = 1<<2,
+  DRAW_BV_AXIS           = 1<<3,
+  DRAW_BV_BLENDED        = 1<<4,
+  DRAW_BV_POLYGON        = 1<<5,
+  DRAW_MODEL             = 1<<6,
+  DRAW_POINTS            = 1<<7
+};
+
+
+//! A class that represents a bounding volume tree
+class BVTree : public BaseObject
+{
+  ObjectListDeclaration(BVTree);
+
+  public:
+    BVTree();
+    virtual ~BVTree();
+
+    virtual void spawnBVTree(const modelInfo& modelInf) = 0;
+    virtual void flushTree() = 0;
+
+    virtual void collideWith(WorldEntity* entity1, WorldEntity* entity2) = 0;
+
+    virtual void drawBV(int depth, int drawMode) const = 0;
+};
+
+#endif /* _BV_TREE_H */
Index: branches/heathaze/src/lib/collision_detection/bv_tree_node.cc
===================================================================
--- branches/heathaze/src/lib/collision_detection/bv_tree_node.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/bv_tree_node.cc	(revision 9940)
@@ -0,0 +1,41 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_DETECTION
+
+#include "bv_tree_node.h"
+
+
+
+ObjectListDefinition(BVTreeNode);
+/**
+ *  standard constructor
+*/
+BVTreeNode::BVTreeNode ()
+{
+  this->registerObject(this, BVTreeNode::_objectList);
+
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+BVTreeNode::~BVTreeNode ()
+{
+}
+
+
Index: branches/heathaze/src/lib/collision_detection/bv_tree_node.h
===================================================================
--- branches/heathaze/src/lib/collision_detection/bv_tree_node.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/bv_tree_node.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file bv_tree.h
+  *  Definition of a bounding volume tree
+
+*/
+
+#ifndef _BV_TREE_NODE_H
+#define _BV_TREE_NODE_H
+
+
+#include "base_object.h"
+#include "model.h"
+#include "vector.h"
+
+
+// forward declarations
+class BoundingVolume;
+class BVTree;
+class PNode;
+class WorldEntity;
+template<class T> class tList;
+
+
+//! A class that represents a bounding volume tree
+class BVTreeNode : public BaseObject {
+  ObjectListDeclaration(BVTreeNode);
+
+
+ public:
+  BVTreeNode();
+  virtual ~BVTreeNode();
+
+  virtual const BoundingVolume* getBV() const = 0;
+  /** returns the index of this bounding volume tree node @returns index of this index */
+  inline const int getIndex() const { return this->treeIndex; }
+
+  virtual void spawnBVTree(const modelInfo& modInfo, const int* triangleIndexes, int length) = 0;
+  virtual void collideWith(BVTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB) = 0;
+  virtual void drawBV(int depth, int drawMode, const Vector& color = Vector(1,0,0), bool top = true) const = 0;
+
+
+
+ private:
+  unsigned int        treeIndex;                  //!< Index number of the BV in the tree
+
+
+};
+
+#endif /* _BV_TREE_NODE_H */
Index: branches/heathaze/src/lib/collision_detection/cd_engine.cc
===================================================================
--- branches/heathaze/src/lib/collision_detection/cd_engine.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/cd_engine.cc	(revision 9940)
@@ -0,0 +1,155 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_DETECTION
+
+#include "cd_engine.h"
+#include "obb_tree.h"
+#include "debug.h"
+
+#include "model.h"
+#include "world_entity.h"
+#include "terrain.h"
+// #include "player.h"
+
+//#include "spatial_separation.h"
+#include "quadtree.h"
+//#include "quadtree_node.h"
+
+#include "bsp_manager.h"
+#include "bsp_entity.h"
+
+
+
+ObjectListDefinition(CDEngine);
+/**
+ * @brief standard constructor
+ */
+CDEngine::CDEngine ()
+{
+  this->registerObject(this, CDEngine::_objectList);
+
+  this->bAbordOnFirstCollision = false;
+
+  this->terrain = NULL;
+}
+
+
+/**
+ *  the singleton reference to this class
+ */
+CDEngine* CDEngine::singletonRef = NULL;
+
+
+/**
+ *  standard deconstructor
+ */
+CDEngine::~CDEngine ()
+{
+  CDEngine::singletonRef = NULL;
+}
+
+
+/**
+ *
+ */
+void CDEngine::checkCollisions(ObjectManager::EntityList& list1, ObjectManager::EntityList& list2)
+{
+  BVTree* tree;
+  ObjectManager::EntityList::iterator entity1, entity2, pre1, pre2;
+  PRINTF(5)("checking for collisions\n");
+
+  pre1 = list1.begin();
+  while (pre1 != list1.end())
+  {
+    entity1 = pre1++;
+    if( likely((*entity1) != this->terrain))
+    {
+      pre2 = list2.begin();
+      while (pre2 != list2.end())
+      {
+        entity2 = pre2++;
+        if( likely((*entity2) != this->terrain))
+        {
+          PRINTF(5)("checking object %s (%s) against %s (%s)\n",
+            (*entity1)->getClassCName(), (*entity1)->getCName(), (*entity2)->getClassCName(), (*entity2)->getCName());
+          tree = (*entity1)->getOBBTree();
+          if( likely(tree != NULL) && (*entity2)->getOBBTree() != NULL)
+            tree->collideWith(*entity1, *entity2);
+        }
+      }
+    }
+  }
+}
+
+
+/**
+ *  this checks the collisions with the ground
+ */
+void CDEngine::checkCollisionGround(std::list<WorldEntity*>& list1)
+{
+  std::list<WorldEntity*>::iterator entityIterator;
+  // for all bsp managers check all entities
+  for( ObjectList<BspEntity>::const_iterator bspIterator = BspEntity::objectList().begin();
+       bspIterator != BspEntity::objectList().end();
+       bspIterator++) {
+      for(entityIterator = list1.begin(); entityIterator != list1.end(); entityIterator++)
+      {
+//         PRINTF(0)("Checking: %s a %s\n", (*entityIterator)->getName(), (*entityIterator)->getClassCName());
+        (dynamic_cast<BspEntity*>(*bspIterator)->getBspManager())->checkCollision(*entityIterator);
+      }
+  }
+}
+
+
+/**
+ * some debug output on the class
+ */
+void CDEngine::debug()
+{
+  PRINT(0)("\n=============================| CDEngine::debug() |===\n");
+  PRINT(0)("=  CDEngine: Spawning Tree Start\n");
+  //this->rootTree->debug();
+  PRINT(0)("=  CDEngine: Spawning Tree: Finished\n");
+  PRINT(0)("=======================================================\n");
+}
+
+
+/**
+ * this spawns a tree for debug purposes only
+ */
+void CDEngine::debugSpawnTree(int depth, sVec3D* vertices, int numVertices)
+{
+//   if ( this->rootTree == NULL)
+//     this->rootTree = new OBBTree(depth, vertices, numVertices);
+}
+
+
+void CDEngine::drawBV(const ObjectManager::EntityList& drawList, int level) const
+{
+  ObjectManager::EntityList::const_iterator entity;
+  for (entity = drawList.begin(); entity != drawList.end(); entity++)
+    (*entity)->drawBVTree(level, 226);
+}
+
+
+/**
+ * this draws the debug spawn tree
+ */
+void CDEngine::debugDraw(int depth, int drawMode)
+{
+//   if(this-> rootTree != NULL)
+//     this->rootTree->drawBV(depth, drawMode);
+}
Index: branches/heathaze/src/lib/collision_detection/cd_engine.h
===================================================================
--- branches/heathaze/src/lib/collision_detection/cd_engine.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/cd_engine.h	(revision 9940)
@@ -0,0 +1,90 @@
+/*!
+ * @file cd_engine.h
+  *  Definition of the collision detection engine
+
+*/
+
+#ifndef _CD_ENGINE_H
+#define _CD_ENGINE_H
+
+#include "base_object.h"
+#include "collision_defs.h"
+#include "model.h"
+
+#include <list>
+
+class WorldEntity;
+class OBBTree;
+class Terrain;
+class BspManager;
+//class Player;
+
+
+//! featured state options, they are all additive
+typedef enum cdState
+  {
+    CD_DEBUG_DRAW_ALL = 1,
+    CD_DEBUG_DRAW_POLYGONS = 1<<1,
+    CD_DEBUG_DRAW_BLENDED = 1<<2,
+    CD_DEBUG_DRAW_HIT_BV = 1<<3,
+    CD_DEBUG_VERBOSE = 1<<4,
+
+    CD_STORE_VERTICES = 1<<5
+  };
+
+
+//! The class representing the collision detection system of orxonox
+class CDEngine : public BaseObject {
+  ObjectListDeclaration(CDEngine);
+
+  friend class WorldEntity;
+
+ public:
+  virtual ~CDEngine();
+  /** @returns a Pointer to the only object of this Class */
+  static CDEngine* getInstance() { if (!singletonRef) singletonRef = new CDEngine(); return singletonRef; }
+  void init();
+
+  inline void setState(const int newState) { this->state = newState; }
+  inline const int getState() const { return this->state; }
+  inline void enable(const int options) { this->state |= options; }
+  inline void disable(const int options) { int temp = this->state & options; this->state ^= temp; }
+
+  inline void setTerrain(Terrain* terrain) { this->terrain = terrain; }
+  inline void setBSPModel(BspManager* bspManager) { this->bspManager = bspManager; }
+
+  void checkCollisions(std::list<WorldEntity*>& list1, std::list<WorldEntity*>& list2);
+  void checkCollisionGround(std::list<WorldEntity*>& list1);
+
+  void drawBV(const std::list<WorldEntity*>& drawList, int level) const;
+  void debug();
+
+  /** @returns true if cd alg returns after detecting first error (default behavour) */
+  inline bool isAbordOnFirstCollision() const { return this->bAbordOnFirstCollision; }
+  /** sets @param flag true if the alg should return after detection of the first error */
+  inline void setAbordOnFirstCollision(bool flag) { this->bAbordOnFirstCollision = flag; }
+
+
+ private:
+  CDEngine();
+  static CDEngine* singletonRef;
+
+  void spawnBVTree(int depth = MAX_BV_TREE_DEPTH);
+
+  void checkCollisionObjects();
+
+
+  void debugSpawnTree(int depth, sVec3D* vertices, int numVertices);
+  void debugDraw(int depth, int drawMode);
+
+
+ private:
+  int                     state;                            //!< the current state of the cd engine
+  bool                    bAbordOnFirstCollision;           //!< abords the collision detection on first collision event => more speed but less accurate infomations
+  OBBTree*                rootTree;                         //!< for testing purposes a root tree
+
+  Terrain*                terrain;                          //!< this it a ref to the terrain, serving as a ground for all WE
+  BspManager*             bspManager;
+};
+
+#endif /* _CD_ENGINE_H */
Index: branches/heathaze/src/lib/collision_detection/collision_defs.h
===================================================================
--- branches/heathaze/src/lib/collision_detection/collision_defs.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/collision_defs.h	(revision 9940)
@@ -0,0 +1,23 @@
+/*! 
+ * @file collision_defs.h
+  *  Definition of some global collision data
+
+*/
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define MAX_BV_TREE_DEPTH 10
+#define MIN_VERT_PER_BV 3
Index: branches/heathaze/src/lib/collision_detection/obb.cc
===================================================================
--- branches/heathaze/src/lib/collision_detection/obb.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/obb.cc	(revision 9940)
@@ -0,0 +1,52 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_DETECTION
+
+#include "obb.h"
+#include "vector.h"
+
+
+
+ObjectListDefinition(OBB);
+/**
+ *  standard constructor
+*/
+OBB::OBB ()
+{
+  this->registerObject(this, OBB::_objectList);
+   this->halfLength[0] = this->halfLength[1] = this->halfLength[2] = 0.0f;
+   this->bCollided = false;
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+OBB::~OBB ()
+{
+}
+
+
+
+void OBB::mergeWith(const BoundingVolume &bv)
+{}
+
+
+void OBB::drawBV(int currentDepth, int drawMode) const
+{}
+
+
Index: branches/heathaze/src/lib/collision_detection/obb.h
===================================================================
--- branches/heathaze/src/lib/collision_detection/obb.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/obb.h	(revision 9940)
@@ -0,0 +1,45 @@
+/*!
+ * @file obb.h
+  *  Definition of an OBB (object Oriented Bounding Box)
+
+*/
+
+#ifndef _OBB_H
+#define _OBB_H
+
+#include "base_object.h"
+#include "bounding_volume.h"
+
+template<class T> class tList;
+
+//! A class representing an extended bounding volume tree: an obb tree
+class OBB : public BoundingVolume {
+  ObjectListDeclaration(OBB);
+
+ public:
+  OBB();
+  virtual ~OBB();
+
+
+  inline Vector getAxisX () const { return this->axis[0]; }
+  inline Vector getAxisY () const { return this->axis[1]; }
+  inline Vector getAxisZ () const { return this->axis[2]; }
+
+  inline const float* getHalfLength() const { return this->halfLength; }
+
+  virtual void mergeWith(const BoundingVolume &bv);
+
+  virtual void drawBV(int currentDepth, int drawMode) const;
+
+
+
+ public:
+  Vector           axis[3];                    //!< Axes of oriented box [x,y,z]
+  float            halfLength[3];              //!< Half lengths of the box along the axis
+  float            covarianceMatrix[3][3];     //!< the covariance matrix
+
+  bool             bCollided;                  //!< is true if this obb has collided
+
+};
+
+#endif /* _OBB_H */
Index: branches/heathaze/src/lib/collision_detection/obb_tree.cc
===================================================================
--- branches/heathaze/src/lib/collision_detection/obb_tree.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/obb_tree.cc	(revision 9940)
@@ -0,0 +1,162 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_DETECTION
+
+#include "obb_tree.h"
+#include "obb_tree_node.h"
+#include "obb.h"
+#include "debug.h"
+#include "compiler.h"
+#include "material.h"
+#include "world_entity.h"
+#include "p_node.h"
+
+
+
+ObjectListDefinition(OBBTree);
+/**
+ *  standard constructor
+*/
+OBBTree::OBBTree(int depth, const modelInfo* modelInf, WorldEntity* owner)
+  : BVTree()
+{
+  this->depth = depth;
+  this->init();
+  this->spawnBVTree(*modelInf);
+  this->owner = owner;
+}
+
+
+/**
+ *  standard constructor
+ */
+OBBTree::OBBTree()
+  : BVTree()
+{}
+
+
+void OBBTree::init()
+{
+  this->registerObject(this, OBBTree::_objectList);
+  this->rootNode = NULL;
+  this->id = 0;
+}
+
+/**
+ *  standard deconstructor
+
+*/
+OBBTree::~OBBTree ()
+{
+  delete this->rootNode;
+}
+
+
+/**
+ *  this function creates a bv tree out of a modelInf structure
+ * @param modelInf the model info of a model (modelInfo), containing vertices, triangle and normal infos
+ */
+void OBBTree::spawnBVTree(const modelInfo& modelInf)
+{
+  if( unlikely(this->rootNode != NULL))
+  {
+    PRINTF(2)("The BVTree has already been spawned, flushing and respawning again...\n");
+    this->flushTree();
+  }
+  this->rootNode = new OBBTreeNode(*this, NULL, depth-1);
+
+  /* triangles indexes created */
+  int* triangleIndexes = new int[modelInf.numTriangles];
+  for(unsigned int i = 0; i < modelInf.numTriangles; ++i)
+    triangleIndexes[i] = i;
+
+  this->rootNode->spawnBVTree(modelInf, triangleIndexes, modelInf.numTriangles);
+}
+
+
+void OBBTree::createBox(Vector start, Vector end)
+{
+  this->rootNode = new OBBTreeNode(*this, NULL, 1);
+
+  this->rootNode->createBox(start, end);
+}
+
+
+/**
+ *  release the current bv tree if any
+ */
+void OBBTree:: flushTree()
+{}
+
+
+/**
+ * this collides two bvtrees together. the trees are attached to pnodes Objects A and B
+ * @param nodeA: PNode of object A
+ * @param nodeB: Pnode of object B
+ */
+void OBBTree::collideWith(WorldEntity* entity1, WorldEntity* entity2)
+{
+  if( likely(entity2->getOBBTree() != NULL) )
+    this->rootNode->collideWith(((OBBTree*)entity2->getOBBTree())->getRootNode(), entity1, entity2);
+}
+
+
+/**
+ *  draw bv tree
+ */
+void OBBTree::drawBV(int depth, int drawMode) const
+{
+  if( likely(this->rootNode != NULL))
+  {
+    this->rootNode->drawBV(depth, drawMode);
+  }
+}
+
+
+/**
+ *  some debug output and creation function
+ *
+ * doesn't work at the moment
+ */
+void OBBTree::debug()
+{
+  PRINT(0)("\n==============================| OBBTree::debug() |===\n");
+  PRINT(0)("=  Spawning Tree: Start\n");
+
+  /* generate some test vertices */
+  int const length = 9;
+  sVec3D* vertList = new sVec3D[length];
+//   sVec3D data[length]  = {{0.0, 0.0, 0.0},{1.0, 2.0, 5.0},{0.0, 6.0, 9.0},
+//                           {1.0, 4.0, 12.0}, {1.0, 2.0, 16.0}, {0.0, 0.0, 19.0},
+//                           {0.0, 3.0, 23.0}, {1.0, 5.0, 30.0}, {0.0, 10.0, 35.0}};
+
+  sVec3D data[length]  = {{0.0, 0.0, 0.0},{1.0, 2.0, 5.0},{1.0, 5.0, 30.0},
+                          {0.0, 3.0, 23.0}, {0.0, 6.0, 9.0}, {0.0, 10.0, 35.0},
+                          {1.0, 4.0, 12.0}, {1.0, 2.0, 16.0}, {0.0, 0.0, 19.0}};
+
+  for(int i = 0; i < length; ++i)
+    {
+      vertList[i][0] = data[i][0];
+      vertList[i][1] = data[i][1];
+      vertList[i][2] = data[i][2];
+    }
+
+//   this->spawnBVTree(vertList, length);
+
+  PRINT(0)("=  Spawning Tree: Finished\n");
+  PRINT(0)("=======================================================\n");
+
+}
Index: branches/heathaze/src/lib/collision_detection/obb_tree.h
===================================================================
--- branches/heathaze/src/lib/collision_detection/obb_tree.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/obb_tree.h	(revision 9940)
@@ -0,0 +1,53 @@
+/*!
+ * @file obb_tree.h
+  *  Definition of an obb tree (object oriented Bounding Box)
+
+*/
+
+#ifndef _OBB_TREE_H
+#define _OBB_TREE_H
+
+#include "bv_tree.h"
+#include "model.h"
+#include "material.h"
+
+class Material;
+class OBBTreeNode;
+class PNode;
+class WorldEntity;
+
+//! A class for representing an obb tree
+class OBBTree : public BVTree
+{
+  ObjectListDeclaration(OBBTree);
+
+  public:
+    OBBTree(int depth, const modelInfo* modInfo, WorldEntity* entity);
+    OBBTree();
+    virtual ~OBBTree();
+    void init();
+
+    virtual void spawnBVTree(const modelInfo& modelInf);
+    virtual void flushTree();
+
+    void createBox(Vector start, Vector end);
+
+    virtual void collideWith(WorldEntity* entity1, WorldEntity* entity2);
+    virtual void drawBV(int depth, int drawMode) const;
+
+    /** returns the next if for the obb tree node @return integer id number of the next node */
+    inline const int getID() { return ++this->id;}
+    /** returns the root node of the bounding volume tree @return reference to the root node */
+    inline OBBTreeNode* getRootNode() const { return this->rootNode; }
+    inline WorldEntity* getOwner() const { return this->owner; }
+
+    void debug();
+
+  private:
+    OBBTreeNode*         rootNode;                        //!< reference to the root node of the tree
+    int                  id;                              //!< the next id of a obb tree node
+    int                  depth;                           //!< the depth of the tree to generate
+    WorldEntity*         owner;                           //!< owner
+};
+
+#endif /* _OBB_TREE_H */
Index: branches/heathaze/src/lib/collision_detection/obb_tree_node.cc
===================================================================
--- branches/heathaze/src/lib/collision_detection/obb_tree_node.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/obb_tree_node.cc	(revision 9940)
@@ -0,0 +1,977 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE 3/* DEBUG_MODULE_COLLISION_DETECTION*/
+
+#include "obb_tree_node.h"
+#include "obb_tree.h"
+#include "obb.h"
+
+#include "matrix.h"
+#include "model.h"
+#include "world_entity.h"
+#include "plane.h"
+
+#include "color.h"
+#include "glincl.h"
+
+#include <list>
+#include <vector>
+#include "debug.h"
+
+
+
+
+
+
+GLUquadricObj* OBBTreeNode_sphereObj = NULL;
+
+ObjectListDefinition(OBBTreeNode);
+/**
+ *  standard constructor
+ * @param tree: reference to the obb tree
+ * @param depth: the depth of the obb tree to generate
+ */
+OBBTreeNode::OBBTreeNode (const OBBTree& tree, OBBTreeNode* prev, int depth)
+    : BVTreeNode()
+{
+  this->registerObject(this, OBBTreeNode::_objectList);
+
+  this->obbTree = &tree;
+  this->nodePrev = prev;
+  this->depth = depth;
+  this->nextID = 0;
+
+  this->nodeLeft = NULL;
+  this->nodeRight = NULL;
+  this->bvElement = NULL;
+
+  this->triangleIndexList1 = NULL;
+  this->triangleIndexList2 = NULL;
+
+  this->modelInf = NULL;
+  this->triangleIndexes = NULL;
+
+  if( OBBTreeNode_sphereObj == NULL)
+    OBBTreeNode_sphereObj = gluNewQuadric();
+
+  this->owner = NULL;
+
+  /* debug ids */
+  if( this->nodePrev)
+    this->treeIndex = 100 * this->depth + this->nodePrev->getID();
+  else
+    this->treeIndex = 0;
+}
+
+
+/**
+ *  standard deconstructor
+ */
+OBBTreeNode::~OBBTreeNode ()
+{
+  if( this->nodeLeft)
+    delete this->nodeLeft;
+  if( this->nodeRight)
+    delete this->nodeRight;
+
+  if( this->bvElement)
+    delete this->bvElement;
+}
+
+
+
+void OBBTreeNode::createBox(Vector start, Vector end)
+{
+
+  this->bvElement = new OBB();
+  this->nodeLeft = NULL;
+  this->nodeRight = NULL;
+//   this->depth = 0;
+
+  this->bvElement->center = (end - start) * 0.5f;
+  this->bvElement->halfLength[0] = (end.x - start.x) * 0.5f;
+  this->bvElement->halfLength[1] = (end.y - start.y) * 0.5f;
+  this->bvElement->halfLength[2] = (end.z - start.z) * 0.5f;
+
+  this->bvElement->axis[0] = Vector(1,0,0);
+  this->bvElement->axis[1] = Vector(0,1,0);
+  this->bvElement->axis[2] = Vector(0,0,1);
+}
+
+
+
+/**
+ *  creates a new BVTree or BVTree partition
+ * @param depth: how much more depth-steps to go: if == 1 don't go any deeper!
+ * @param modInfo: model informations from the abstrac model
+ *
+ * this function creates the Bounding Volume tree from a modelInfo struct and bases its calculations
+ * on the triangle informations (triangle soup not polygon soup)
+ */
+void OBBTreeNode::spawnBVTree(const modelInfo& modelInf, const int* triangleIndexes, int length)
+{
+  PRINTF(4)("\n==============================Creating OBB Tree Node==================\n");
+  PRINT(4)(" OBB Tree Infos: \n");
+  PRINT(4)("\tDepth: %i \n\tTree Index: %i \n\tNumber of Triangles: %i\n", depth, this->treeIndex, length);
+  this->depth = depth;
+
+  this->bvElement = new OBB();
+  this->bvElement->modelInf = &modelInf;
+  this->bvElement->triangleIndexes = triangleIndexes;
+  this->bvElement->triangleIndexesLength = length;
+
+  /* create the bounding boxes in three steps */
+  this->calculateBoxCovariance(*this->bvElement, modelInf, triangleIndexes, length);
+  this->calculateBoxEigenvectors(*this->bvElement, modelInf, triangleIndexes, length);
+  this->calculateBoxAxis(*this->bvElement, modelInf, triangleIndexes, length);
+
+  /* do we need to descent further in the obb tree?*/
+  if( likely( this->depth > 0))
+  {
+    this->forkBox(*this->bvElement);
+
+    if( this->triangleIndexLength1 >= 3)
+    {
+      this->nodeLeft = new OBBTreeNode(*this->obbTree, this, depth - 1);
+      this->nodeLeft->spawnBVTree(modelInf, this->triangleIndexList1, this->triangleIndexLength1);
+    }
+    if( this->triangleIndexLength2 >= 3)
+    {
+      this->nodeRight = new OBBTreeNode(*this->obbTree, this, depth - 1);
+      this->nodeRight->spawnBVTree(modelInf, this->triangleIndexList2, this->triangleIndexLength2);
+    }
+  }
+}
+
+
+
+/**
+ *  calculate the box covariance matrix
+ * @param box: reference to the box
+ * @param modelInf: the model info structure of the model
+ * @param tirangleIndexes: an array with the indexes of the triangles inside this
+ * @param length: the length of the indexes array
+ */
+void OBBTreeNode::calculateBoxCovariance(OBB& box, const modelInfo& modelInf, const int* triangleIndexes, int length)
+{
+  float     facelet[length];                         //!< surface area of the i'th triangle of the convex hull
+  float     face = 0.0f;                             //!< surface area of the entire convex hull
+  Vector    centroid[length];                        //!< centroid of the i'th convex hull
+  Vector    center;                                  //!< the center of the entire hull
+  Vector    p, q, r;                                 //!< holder of the polygon data, much more conveniant to work with Vector than sVec3d
+  Vector    t1, t2;                                  //!< temporary values
+  float     covariance[3][3] = {{0,0,0}, {0,0,0}, {0,0,0}};//!< the covariance matrix
+
+  /* fist compute all the convex hull face/facelets and centroids */
+  for( int i = 0; i < length ; ++i)
+  {
+    p = &modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[0]];
+    q = &modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[1]];
+    r = &modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[2]];
+
+    /* finding the facelet surface via cross-product */
+    t1 = p - q;
+    t2 = p - r;
+    facelet[i] = 0.5f * /*fabs*/( t1.cross(t2).len() );
+    /* update the entire convex hull surface */
+    face += facelet[i];
+
+    /* calculate the cetroid of the hull triangles */
+    centroid[i] = (p + q + r) / 3.0f;
+    /* now calculate the centroid of the entire convex hull, weighted average of triangle centroids */
+    center += centroid[i] * facelet[i];
+    /* the arithmetical center */
+  }
+  /* take the average of the centroid sum */
+  center /= face;
+
+
+  /* now calculate the covariance matrix - if not written in three for-loops,
+     it would compute faster: minor */
+  for( int j = 0; j < 3; ++j)
+  {
+    for( int k = 0; k < 3; ++k)
+    {
+      for( int i = 0; i < length; ++i)
+      {
+        p = (&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[0]]);
+        q = (&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[1]]);
+        r = (&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[i]].indexToVertices[2]]);
+
+        covariance[j][k] = facelet[i] * (9.0f * centroid[i][j] * centroid[i][k] + p[j] * p[k] +
+                           q[j] * q[k] + r[j] * r[k]);
+      }
+      covariance[j][k] = covariance[j][k] / (12.0f * face) - center[j] * center[k];
+    }
+  }
+  for( int i = 0; i < 3; ++i)
+  {
+    box.covarianceMatrix[i][0] = covariance[i][0];
+    box.covarianceMatrix[i][1] = covariance[i][1];
+    box.covarianceMatrix[i][2] = covariance[i][2];
+  }
+  box.center = center;
+
+  /* debug output section*/
+  PRINTF(4)("\nOBB Covariance Matrix:\n");
+  for(int j = 0; j < 3; ++j)
+  {
+    PRINT(4)("\t\t");
+    for(int k = 0; k < 3; ++k)
+    {
+      PRINT(4)("%11.4f\t", covariance[j][k]);
+    }
+    PRINT(4)("\n");
+  }
+  PRINTF(4)("\nWeighteed OBB Center:\n\t\t%11.4f\t %11.4f\t %11.4f\n", center.x, center.y, center.z);
+}
+
+
+
+/**
+ *  calculate the eigenvectors for the object oriented box
+ * @param box: reference to the box
+ * @param modelInf: the model info structure of the model
+ * @param tirangleIndexes: an array with the indexes of the triangles inside this
+ * @param length: the length of the indexes array
+ */
+void OBBTreeNode::calculateBoxEigenvectors(OBB& box, const modelInfo& modelInf,
+    const int* triangleIndexes, int length)
+{
+
+  Vector         axis[3];                            //!< the references to the obb axis
+  Matrix         covMat(  box.covarianceMatrix  );   //!< covariance matrix (in the matrix dataform)
+
+  /*
+  now getting spanning vectors of the sub-space:
+  the eigenvectors of a symmertric matrix, such as the
+  covarience matrix are mutually orthogonal.
+  after normalizing them, they can be used as a the basis
+  vectors
+  */
+
+  /* calculate the axis */
+  covMat.getEigenVectors(axis[0], axis[1], axis[2] );
+  box.axis[0] = axis[0];
+  box.axis[1] = axis[1];
+  box.axis[2] = axis[2];
+
+  // this is for axis aligned bouning boxes only
+//   box.axis[0] = Vector(1,0,0);
+//   box.axis[1] = Vector(0,1,0);
+//   box.axis[2] = Vector(0,0,1);
+
+  PRINTF(4)("Eigenvectors:\n");
+  PRINT(4)("\t\t%11.2f \t%11.2f \t%11.2f\n", box.axis[0].x, box.axis[0].y, box.axis[0].z);
+  PRINT(4)("\t\t%11.2f \t%11.2f \t%11.2f\n", box.axis[1].x, box.axis[1].y, box.axis[1].z);
+  PRINT(4)("\t\t%11.2f \t%11.2f \t%11.2f\n", box.axis[2].x, box.axis[2].y, box.axis[2].z);
+}
+
+
+
+
+/**
+ * @brief calculate the eigenvectors for the object oriented box
+ * @param box: reference to the box
+ * @param modelInf: the model info structure of the model
+ * @param tirangleIndexes: an array with the indexes of the triangles inside this
+ * @param length: the length of the indexes array
+ */
+void OBBTreeNode::calculateBoxAxis(OBB& box, const modelInfo& modelInf, const int* triangleIndexes, int length)
+{
+
+  PRINTF(4)("Calculate Box Axis\n");
+  /* now get the axis length */
+  float               tmpLength;                             //!< tmp save point for the length
+  Plane               p0(box.axis[0], box.center);           //!< the axis planes
+  Plane               p1(box.axis[1], box.center);           //!< the axis planes
+  Plane               p2(box.axis[2], box.center);           //!< the axis planes
+  float               maxLength[3];                          //!< maximal lenth of the axis
+  float               minLength[3];                          //!< minimal length of the axis
+  const float*        tmpVec;                                //!< variable taking tmp vectors
+  float               centerOffset[3];
+
+  /* get the maximal dimensions of the body in all directions */
+  /* for the initialisation the value just has to be inside of the polygon soup -> first vertices (rand) */
+  for( int k = 0; k  < 3; k++)
+  {
+    tmpVec = (&modelInf.pVertices[modelInf.pTriangles[triangleIndexes[0]].indexToVertices[0]]);
+    Plane* p;
+    if( k == 0)
+      p = &p0;
+    else if( k == 1)
+      p = &p1;
+    else
+      p = &p2;
+    maxLength[k] = p->distancePoint(tmpVec);
+    minLength[k] = p->distancePoint(tmpVec);
+
+    for( int j = 0; j < length; ++j) {
+      for( int i = 0; i < 3; ++i) {
+        tmpVec = &modelInf.pVertices[modelInf.pTriangles[triangleIndexes[j]].indexToVertices[i]];
+        tmpLength = p->distancePoint(tmpVec);
+
+        if( tmpLength > maxLength[k])
+          maxLength[k] = tmpLength;
+        else if( tmpLength < minLength[k])
+          minLength[k] = tmpLength;
+      }
+    }
+  }
+
+
+
+  /* calculate the real centre of the body by using the axis length */
+  for( int i = 0; i < 3; ++i)
+  {
+    if( maxLength[i] > 0.0f && minLength[i] > 0.0f)  // both axis positiv
+      centerOffset[i] = minLength[i] + (maxLength[i] - minLength[i]) / 2.0f;
+    else if( maxLength[i] > 0.0f && maxLength[i] < 0.0f) // positiv and negativ
+      centerOffset[i] = (maxLength[i] + minLength[i]) / 2.0f;
+    else //both negativ
+     centerOffset[i] = minLength[i] + (maxLength[i] - minLength[i]) / 2.0f;
+
+    box.halfLength[i] = (maxLength[i] - minLength[i]) / 2.0f;
+  }
+
+  box.center += (box.axis[0] * centerOffset[0]);
+  box.center += (box.axis[1] * centerOffset[1]);
+  box.center += (box.axis[2] * centerOffset[2]);
+
+
+  PRINTF(4)("\n");
+  PRINT(4)("\tAxis halflength x: %11.2f (max: %11.2f, \tmin: %11.2f), offset: %11.2f\n", box.halfLength[0], maxLength[0], minLength[0], centerOffset[0]);
+  PRINT(4)("\tAxis halflength y: %11.2f (max: %11.2f, \tmin: %11.2f), offset: %11.2f\n", box.halfLength[1], maxLength[1], minLength[1], centerOffset[1] );
+  PRINT(4)("\tAxis halflength z: %11.2f (max: %11.2f, \tmin: %11.2f), offset: %11.2f\n", box.halfLength[2], maxLength[2], minLength[2], centerOffset[2]);
+}
+
+
+
+/**
+ * @brief this separates an ob-box in the middle
+ * @param box: the box to separate
+ *
+ * this will separate the box into to smaller boxes. the separation is done along the middle of the longest axis
+ */
+void OBBTreeNode::forkBox(OBB& box)
+{
+
+  PRINTF(4)("Fork Box\n");
+  PRINTF(4)("Calculating the longest Axis\n");
+  /* get the longest axis of the box */
+  float               longestAxis = -1.0f;                 //!< the length of the longest axis
+  int                 longestAxisIndex = 0;                //!< this is the nr of the longest axis
+
+
+  /* now get the longest axis of the three exiting */
+  for( int i = 0; i < 3; ++i)
+  {
+    if( longestAxis < box.halfLength[i])
+    {
+      longestAxis = box.halfLength[i];
+      longestAxisIndex = i;
+    }
+  }
+  this->bvElement->radius = longestAxis;
+  PRINTF(4)("\nLongest Axis is: Nr %i with a half-length of:%11.2f\n", longestAxisIndex, longestAxis);
+
+
+  PRINTF(4)("Separating along the longest axis\n");
+  /* get the closest vertex near the center */
+  float               tmpDist;                             //!< variable to save diverse distances temporarily
+  Plane               middlePlane(box.axis[longestAxisIndex], box.center); //!< the middle plane
+
+
+  /* now definin the separation plane through this specified nearest point and partition
+  the points depending on which side they are located
+  */
+  std::list<int>           partition1;                           //!< the vertex partition 1
+  std::list<int>           partition2;                           //!< the vertex partition 2
+  float*                   triangleCenter = new float[3];        //!< the center of the triangle
+  const float*             a;                                    //!< triangle  edge a
+  const float*             b;                                    //!< triangle  edge b
+  const float*             c;                                    //!< triangle  edge c
+
+
+  /* find the center of the box */
+  this->separationPlane = Plane(box.axis[longestAxisIndex], box.center);
+  this->sepPlaneCenter[0] = box.center.x;
+  this->sepPlaneCenter[1] = box.center.y;
+  this->sepPlaneCenter[2] = box.center.z;
+  this->longestAxisIndex = longestAxisIndex;
+
+  for( int i = 0; i < box.triangleIndexesLength; ++i)
+  {
+    /* first calculate the middle of the triangle */
+    a = &box.modelInf->pVertices[box.modelInf->pTriangles[box.triangleIndexes[i]].indexToVertices[0]];
+    b = &box.modelInf->pVertices[box.modelInf->pTriangles[box.triangleIndexes[i]].indexToVertices[1]];
+    c = &box.modelInf->pVertices[box.modelInf->pTriangles[box.triangleIndexes[i]].indexToVertices[2]];
+
+    triangleCenter[0] = (a[0] + b[0] + c[0]) / 3.0f;
+    triangleCenter[1] = (a[1] + b[1] + c[1]) / 3.0f;
+    triangleCenter[2] = (a[2] + b[2] + c[2]) / 3.0f;
+    tmpDist = this->separationPlane.distancePoint(*((sVec3D*)triangleCenter));
+
+    if( tmpDist > 0.0f)
+      partition1.push_back(box.triangleIndexes[i]); /* positive numbers plus zero */
+    else if( tmpDist < 0.0f)
+      partition2.push_back(box.triangleIndexes[i]); /* negatice numbers */
+    else {
+      partition1.push_back(box.triangleIndexes[i]); /* 0.0f? unprobable... */
+      partition2.push_back(box.triangleIndexes[i]);
+    }
+  }
+  delete [] triangleCenter;
+  PRINTF(4)("\nPartition1: got \t%i Vertices \nPartition2: got \t%i Vertices\n", partition1.size(), partition2.size());
+
+
+  /* now comes the separation into two different sVec3D arrays */
+  int                index;                                //!< index storage place
+  int*               triangleIndexList1;                   //!< the vertex list 1
+  int*               triangleIndexList2;                   //!< the vertex list 2
+  std::list<int>::iterator element;                        //!< the list iterator
+
+  triangleIndexList1 = new int[partition1.size()];
+  triangleIndexList2 = new int[partition2.size()];
+
+  for( element = partition1.begin(), index = 0; element != partition1.end(); element++, index++)
+    triangleIndexList1[index] = (*element);
+
+  for( element = partition2.begin(), index = 0; element != partition2.end(); element++, index++)
+    triangleIndexList2[index] = (*element);
+
+  if( this->triangleIndexList1!= NULL)
+    delete[] this->triangleIndexList1;
+  this->triangleIndexList1 = triangleIndexList1;
+  this->triangleIndexLength1 = partition1.size();
+
+  if( this->triangleIndexList2 != NULL)
+    delete[] this->triangleIndexList2;
+  this->triangleIndexList2 = triangleIndexList2;
+  this->triangleIndexLength2 = partition2.size();
+}
+
+
+
+/**
+ * collides one tree with an other
+ *  @param treeNode the other bv tree node
+ *  @param nodeA  the worldentity belonging to this bv
+ *  @param nodeB the worldentity belonging to treeNode
+ */
+void OBBTreeNode::collideWith(BVTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB)
+{
+  if( unlikely(treeNode == NULL || nodeA == NULL || nodeB == NULL))
+    return;
+
+//   float distanceMax = this->bvElement->radius + ((OBBTreeNode*)treeNode)->bvElement->radius;
+//   float distance = fabs((nodeA->getAbsCoor() - nodeB->getAbsCoor()).len());
+
+
+//   if( distance < distanceMax)
+//     PRINTF(0)(" %s (%s: group %i) vs %s (%s: group %i): distanceMax: %f, distance: %f\n", nodeA->getClassCName(), nodeA->getName(), nodeA->getOMListNumber(), nodeB->getClassCName(),  nodeB->getName(), nodeB->getOMListNumber(), distanceMax, distance);
+
+
+  PRINTF(4)("collideWith\n");
+  PRINTF(5)("Checking OBB %i vs %i: ", this->getIndex(), treeNode->getIndex());
+
+  // for now only collide with OBBTreeNodes
+  this->collideWithOBB((OBBTreeNode*)treeNode, nodeA, nodeB);
+}
+
+
+
+/**
+ * collides one obb tree with an other
+ *  @param treeNode the other bv tree node
+ *  @param nodeA  the worldentity belonging to this bv
+ *  @param nodeB the worldentity belonging to treeNode
+ */
+void OBBTreeNode::collideWithOBB(OBBTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB)
+{
+
+  if( this->overlapTest(this->bvElement, treeNode->bvElement, nodeA, nodeB))
+  {
+    PRINTF(5)("collision @ lvl %i, object %s vs. %s, (%p, %p)\n", this->depth, nodeA->getClassCName(), nodeB->getClassCName(), this->nodeLeft, this->nodeRight);
+
+
+    // left node
+    if( this->nodeLeft != NULL )
+    {
+      if( this->overlapTest(this->nodeLeft->bvElement, treeNode->bvElement, nodeA, nodeB))
+      {
+        bool bAdvance = false;
+        if( treeNode->nodeLeft != NULL)
+          this->nodeLeft->collideWith(treeNode->nodeLeft, nodeA, nodeB);
+        else
+          bAdvance = true;
+
+        if( treeNode->nodeRight != NULL)
+          this->nodeLeft->collideWith(treeNode->nodeRight, nodeA, nodeB);
+        else
+          bAdvance = true;
+
+        if( bAdvance)
+          this->nodeLeft->collideWith(treeNode, nodeA, nodeB);  // go down the other tree also
+      }
+    }
+
+    // right node
+    if( this->nodeRight != NULL )
+    {
+      if( this->overlapTest(this->nodeRight->bvElement, treeNode->bvElement, nodeA, nodeB))
+      {
+        bool bAdvance = false;
+
+        if( treeNode->nodeLeft != NULL)
+          this->nodeRight->collideWith(treeNode->nodeLeft, nodeA, nodeB);
+        else
+          bAdvance = true;
+
+        if( treeNode->nodeRight != NULL)
+          this->nodeRight->collideWith(treeNode->nodeRight, nodeA, nodeB);
+        else
+          bAdvance = true;
+
+        if( bAdvance)
+          this->nodeRight->collideWith(treeNode, nodeA, nodeB);  // go down the other tree also
+      }
+    }
+
+
+    // hybrid mode: we reached the end of this obbtree, now reach the end of the other tree
+    if( this->nodeLeft == NULL && this->nodeRight == NULL)
+    {
+      if( treeNode->nodeLeft != NULL)
+        this->collideWith(treeNode->nodeLeft, nodeA, nodeB);
+      if( treeNode->nodeRight != NULL)
+        this->collideWith(treeNode->nodeRight, nodeA, nodeB);
+    }
+
+
+    // now check if we reached the end of both trees
+    if( unlikely((this->nodeRight == NULL && this->nodeLeft == NULL) &&
+        (treeNode->nodeRight == NULL && treeNode->nodeLeft == NULL)) )
+    {
+//       PRINTF(0)("----------------------------------------------\n\n\n\n\n\n--------------------------------\n\n\n");
+      nodeA->registerCollision(nodeA, nodeB, (BoundingVolume*)this->bvElement, (BoundingVolume*)treeNode->bvElement);
+    }
+
+  }
+}
+
+
+/**
+ * this actualy checks if one obb box touches the other
+ * @param boxA the box from nodeA
+ * @param boxB the box from nodeB
+ * @param nodeA the node itself
+ * @param nodeB the node itself
+ */
+bool OBBTreeNode::overlapTest(OBB* boxA, OBB* boxB, WorldEntity* nodeA, WorldEntity* nodeB)
+{
+
+  //HACK remove this again
+  this->owner = nodeA;
+  //   if( boxB == NULL || boxA == NULL)
+  //     return false;
+
+  /* first check all axis */
+  Vector      t;
+  float       rA = 0.0f;
+  float       rB = 0.0f;
+  Vector      l;
+  Vector      rotAxisA[3];
+  Vector      rotAxisB[3];
+
+  rotAxisA[0] =  nodeA->getAbsDir().apply(boxA->axis[0]);
+  rotAxisA[1] =  nodeA->getAbsDir().apply(boxA->axis[1]);
+  rotAxisA[2] =  nodeA->getAbsDir().apply(boxA->axis[2]);
+
+  rotAxisB[0] =  nodeB->getAbsDir().apply(boxB->axis[0]);
+  rotAxisB[1] =  nodeB->getAbsDir().apply(boxB->axis[1]);
+  rotAxisB[2] =  nodeB->getAbsDir().apply(boxB->axis[2]);
+
+  t = nodeA->getAbsCoor() + nodeA->getAbsDir().apply(boxA->center) - ( nodeB->getAbsCoor() + nodeB->getAbsDir().apply(boxB->center));
+
+  /* All 3 axis of the object A */
+  for( int j = 0; j < 3; ++j)
+  {
+    rA = 0.0f;
+    rB = 0.0f;
+    l = rotAxisA[j];
+
+    rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
+    rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
+    rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
+
+    rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
+    rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
+    rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
+
+    PRINTF(5)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
+
+    if( (rA + rB) < fabs(t.dot(l)))
+    {
+      PRINTF(4)("no Collision\n");
+      return false;
+    }
+  }
+
+  /* All 3 axis of the object B */
+  for( int j = 0; j < 3; ++j)
+  {
+    rA = 0.0f;
+    rB = 0.0f;
+    l = rotAxisB[j];
+
+    rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
+    rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
+    rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
+
+    rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
+    rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
+    rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
+
+    PRINTF(5)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
+
+    if( (rA + rB) < fabs(t.dot(l)))
+    {
+      PRINTF(4)("no Collision\n");
+      return false;
+    }
+  }
+
+
+  /* Now check for all face cross products */
+
+  for( int j = 0; j < 3; ++j)
+  {
+    for(int k = 0; k < 3; ++k )
+    {
+      rA = 0.0f;
+      rB = 0.0f;
+      l = rotAxisA[j].cross(rotAxisB[k]);
+
+      rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
+      rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
+      rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
+
+      rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
+      rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
+      rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
+
+      PRINTF(5)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
+
+      if( (rA + rB) < fabs(t.dot(l)))
+      {
+        PRINTF(4)("keine Kollision\n");
+        return false;
+      }
+    }
+  }
+
+  /* FIXME: there is no collision mark set now */
+     boxA->bCollided = true; /* use this ONLY(!!!!) for drawing operations */
+     boxB->bCollided = true;
+
+
+  PRINTF(4)("Kollision!\n");
+  return true;
+}
+
+
+/**
+ *
+ * draw the BV tree - debug mode
+ */
+void OBBTreeNode::drawBV(int depth, int drawMode, const Vector& color,  bool top) const
+{
+
+  /* this function can be used to draw the triangles and/or the points only  */
+  if( 1 /*drawMode & DRAW_MODEL || drawMode & DRAW_ALL*/)
+  {
+    if( depth == 0/*!(drawMode & DRAW_SINGLE && depth != 0)*/)
+    {
+      if( 0 /*drawMode & DRAW_POINTS*/)
+      {
+        glBegin(GL_POINTS);
+        glColor3f(0.3, 0.8, 0.54);
+        for(unsigned int i = 0; i < this->bvElement->modelInf->numVertices*3; i+=3)
+          glVertex3f(this->bvElement->modelInf->pVertices[i],
+                     this->bvElement->modelInf->pVertices[i+1],
+                     this->bvElement->modelInf->pVertices[i+2]);
+        glEnd();
+      }
+    }
+  }
+
+  if (top)
+  {
+    glPushAttrib(GL_ENABLE_BIT);
+    glDisable(GL_LIGHTING);
+    glDisable(GL_TEXTURE_2D);
+  }
+  glColor3f(color.x, color.y, color.z);
+
+
+  /* draw world axes */
+//   if( 1 /*drawMode & DRAW_BV_AXIS*/)
+//   {
+//     glBegin(GL_LINES);
+//     glColor3f(1.0, 0.0, 0.0);
+//     glVertex3f(0.0, 0.0, 0.0);
+//     glVertex3f(3.0, 0.0, 0.0);
+//
+//     glColor3f(0.0, 1.0, 0.0);
+//     glVertex3f(0.0, 0.0, 0.0);
+//     glVertex3f(0.0, 3.0, 0.0);
+//
+//     glColor3f(0.0, 0.0, 1.0);
+//     glVertex3f(0.0, 0.0, 0.0);
+//     glVertex3f(0.0, 0.0, 3.0);
+//     glEnd();
+//   }
+
+
+  if( 1/*drawMode & DRAW_BV_AXIS || drawMode & DRAW_ALL*/)
+  {
+    if( 1/*drawMode & DRAW_SINGLE && depth != 0*/)
+    {
+      /* draw the obb axes */
+      glBegin(GL_LINES);
+      glColor3f(1.0, 0.0, 0.0);
+      glVertex3f(this->bvElement->center.x, this->bvElement->center.y, this->bvElement->center.z);
+      glVertex3f(this->bvElement->center.x + this->bvElement->axis[0].x * this->bvElement->halfLength[0],
+                 this->bvElement->center.y + this->bvElement->axis[0].y * this->bvElement->halfLength[0],
+                 this->bvElement->center.z + this->bvElement->axis[0].z * this->bvElement->halfLength[0]);
+
+      glColor3f(0.0, 1.0, 0.0);
+      glVertex3f(this->bvElement->center.x, this->bvElement->center.y, this->bvElement->center.z);
+      glVertex3f(this->bvElement->center.x + this->bvElement->axis[1].x * this->bvElement->halfLength[1],
+                 this->bvElement->center.y + this->bvElement->axis[1].y * this->bvElement->halfLength[1],
+                 this->bvElement->center.z + this->bvElement->axis[1].z * this->bvElement->halfLength[1]);
+
+      glColor3f(0.0, 0.0, 1.0);
+      glVertex3f(this->bvElement->center.x, this->bvElement->center.y, this->bvElement->center.z);
+      glVertex3f(this->bvElement->center.x + this->bvElement->axis[2].x * this->bvElement->halfLength[2],
+                 this->bvElement->center.y + this->bvElement->axis[2].y * this->bvElement->halfLength[2],
+                 this->bvElement->center.z + this->bvElement->axis[2].z * this->bvElement->halfLength[2]);
+      glEnd();
+    }
+  }
+
+
+  /* DRAW POLYGONS */
+  if( drawMode & DRAW_BV_POLYGON || drawMode & DRAW_ALL || drawMode & DRAW_BV_BLENDED)
+  {
+    if (top)
+    {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+    }
+
+    if( this->nodeLeft == NULL && this->nodeRight == NULL)
+      depth = 0;
+
+    if( depth == 0 /*!(drawMode & DRAW_SINGLE && depth != 0)*/)
+    {
+
+
+      Vector cen = this->bvElement->center;
+      Vector* axis = this->bvElement->axis;
+      float* len = this->bvElement->halfLength;
+
+      if( this->bvElement->bCollided)
+      {
+        glColor4f(1.0, 1.0, 1.0, .5); // COLLISION COLOR
+      }
+      else if( drawMode & DRAW_BV_BLENDED)
+      {
+        glColor4f(color.x, color.y, color.z, .5);
+      }
+
+      // debug out
+      if( this->obbTree->getOwner() != NULL)
+      {
+        PRINTF(4)("debug poly draw: depth: %i, mode: %i, entity-name: %s, class: %s\n", depth, drawMode, this->obbTree->getOwner()->getCName(), this->obbTree->getOwner()->getClassCName());
+      }
+      else
+        PRINTF(4)("debug poly draw: depth: %i, mode: %i\n", depth, drawMode);
+
+
+      /* draw bounding box */
+      if( drawMode & DRAW_BV_BLENDED)
+        glBegin(GL_QUADS);
+      else
+        glBegin(GL_LINE_LOOP);
+      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+      glEnd();
+
+      if( drawMode & DRAW_BV_BLENDED)
+        glBegin(GL_QUADS);
+      else
+        glBegin(GL_LINE_LOOP);
+      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+      glEnd();
+
+      if( drawMode & DRAW_BV_BLENDED)
+        glBegin(GL_QUADS);
+      else
+        glBegin(GL_LINE_LOOP);
+      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+      glEnd();
+
+      if( drawMode & DRAW_BV_BLENDED)
+        glBegin(GL_QUADS);
+      else
+        glBegin(GL_LINE_LOOP);
+      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+      glEnd();
+
+
+      if( drawMode & DRAW_BV_BLENDED)
+      {
+        glBegin(GL_QUADS);
+        glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                   cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                   cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+        glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                   cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                   cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+        glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                   cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                   cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+        glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                   cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                   cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+        glEnd();
+
+        glBegin(GL_QUADS);
+        glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                   cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                   cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+        glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                   cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                   cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+        glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                   cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                   cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+        glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                   cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                   cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+        glEnd();
+      }
+
+      if( drawMode & DRAW_BV_BLENDED)
+        glColor3f(color.x, color.y, color.z);
+    }
+  }
+
+  /* DRAW SEPARATING PLANE */
+  if( drawMode & DRAW_SEPARATING_PLANE || drawMode & DRAW_ALL)
+  {
+    if( !(drawMode & DRAW_SINGLE && depth != 0))
+    {
+      if( drawMode & DRAW_BV_BLENDED)
+        glColor4f(color.x, color.y, color.z, .6);
+
+      /* now draw the separation plane */
+      Vector a1 = this->bvElement->axis[(this->longestAxisIndex + 1)%3];
+      Vector a2 = this->bvElement->axis[(this->longestAxisIndex + 2)%3];
+      Vector c = this->bvElement->center;
+      float l1 = this->bvElement->halfLength[(this->longestAxisIndex + 1)%3];
+      float l2 = this->bvElement->halfLength[(this->longestAxisIndex + 2)%3];
+      glBegin(GL_QUADS);
+      glVertex3f(c.x + a1.x * l1 + a2.x * l2, c.y + a1.y * l1+ a2.y * l2, c.z + a1.z * l1 + a2.z * l2);
+      glVertex3f(c.x - a1.x * l1 + a2.x * l2, c.y - a1.y * l1+ a2.y * l2, c.z - a1.z * l1 + a2.z * l2);
+      glVertex3f(c.x - a1.x * l1 - a2.x * l2, c.y - a1.y * l1- a2.y * l2, c.z - a1.z * l1 - a2.z * l2);
+      glVertex3f(c.x + a1.x * l1 - a2.x * l2, c.y + a1.y * l1- a2.y * l2, c.z + a1.z * l1 - a2.z * l2);
+      glEnd();
+
+      if( drawMode & DRAW_BV_BLENDED)
+        glColor4f(color.x, color.y, color.z, 1.0);
+
+    }
+  }
+
+
+
+  if (depth > 0)
+  {
+    if( this->nodeLeft != NULL)
+      this->nodeLeft->drawBV(depth - 1, drawMode, Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(15.0,0.0,0.0)), false);
+    if( this->nodeRight != NULL)
+      this->nodeRight->drawBV(depth - 1, drawMode, Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(30.0,0.0,0.0)), false);
+  }
+  this->bvElement->bCollided = false;
+
+  if (top)
+    glPopAttrib();
+}
+
+
+
+void OBBTreeNode::debug() const
+{
+  PRINT(0)("========OBBTreeNode::debug()=====\n");
+  PRINT(0)(" Current depth: %i", this->depth);
+  PRINT(0)(" ");
+  PRINT(0)("=================================\n");
+}
Index: branches/heathaze/src/lib/collision_detection/obb_tree_node.h
===================================================================
--- branches/heathaze/src/lib/collision_detection/obb_tree_node.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_detection/obb_tree_node.h	(revision 9940)
@@ -0,0 +1,83 @@
+/*!
+ * @file bv_tree.h
+ *  Definition of a bounding volume tree
+ */
+
+#ifndef _OBB_TREE_NODE_H
+#define _OBB_TREE_NODE_H
+
+
+#include "bv_tree_node.h"
+#include "plane.h"
+
+class BoundingVolume;
+class OBB;
+class OBBTree;
+class Plane;
+class PNode;
+
+//! A class that represents a bounding volume tree
+class OBBTreeNode : public BVTreeNode
+{
+  ObjectListDeclaration(OBBTreeNode);
+  public:
+    OBBTreeNode(const OBBTree& tree, OBBTreeNode* prev, int depth);
+    virtual ~OBBTreeNode();
+
+    /**  this function returns the bounding volume of this tree node @return: returns the BV */
+    virtual inline const BoundingVolume* getBV() const { return (BoundingVolume*)this->bvElement; }
+
+    virtual void spawnBVTree(const modelInfo& modelInf, const int* triangleIndexes, int length);
+    void createBox(Vector start, Vector end);
+
+    virtual void collideWith(BVTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB);
+    virtual void drawBV(int depth, int drawMode, const Vector& color = Vector(1,0,0), bool top = true) const;
+    void debug() const;
+
+    /**  gets the id of the current child @return id of the child */
+    inline const int getID() { return this->nextID++; }
+
+
+  private:
+    void calculateBoxAxis(OBB& box, const sVec3D* verticesList, unsigned int length);
+
+    void calculateBoxCovariance(OBB& box, const modelInfo& modelInf, const int* triangleIndexes, int length);
+    void calculateBoxEigenvectors(OBB& box, const modelInfo& modelInf, const int* triangleIndexes, int length);
+    void calculateBoxAxis(OBB& box, const modelInfo& modelInf, const int* triangleIndexes, int length);
+    void forkBox(OBB& box);
+
+    void collideWithOBB(OBBTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB);
+    bool overlapTest(OBB* boxA, OBB* boxB, WorldEntity* nodeA, WorldEntity* nodeB);
+
+
+  protected:
+    OBB*                bvElement;                  //!< the obb element
+    OBBTreeNode*        nodePrev;                   //!< ref to the previous (parent) tree node = NULL if first
+    OBBTreeNode*        nodeLeft;                   //!< ref to the left tree node
+    OBBTreeNode*        nodeRight;                  //!< ref to the right tree node
+
+
+  private:
+    int                 treeIndex;                  //!< Index number of the BV in the tree
+    int                 nextID;                     //!< the id of the next child
+    int                 depth;                      //!< the depth of the node in the tree
+    const OBBTree*      obbTree;                    //!< reference to the obb tree
+
+    const modelInfo*    modelInf;                   //!< pointer to the models modelInfo object
+    const int*          triangleIndexes;            //!< indexes to the used model triangles
+
+    Plane               separationPlane;            //!< the separation plane of the obb
+    sVec3D              sepPlaneCenter;             //!< only needed to draw plane
+    int                 longestAxisIndex;           //!< only needed to draw plane
+
+    /* tmp saving place for obb variables */
+    int*                triangleIndexList1;         //!< pointer to the vert data of obbox1
+    int*                triangleIndexList2;         //!< pointer to the vert data of obbox1
+    int                 triangleIndexLength1;       //!< len vert data obbox1
+    int                 triangleIndexLength2;       //!< len vert data obbox2
+
+    WorldEntity*        owner;
+
+};
+
+#endif /* _OBB_TREE_NODE_H */
Index: branches/heathaze/src/lib/collision_reaction/Makefile.am
===================================================================
--- branches/heathaze/src/lib/collision_reaction/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/Makefile.am	(revision 9940)
@@ -0,0 +1,26 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXcr.a
+
+libORXcr_a_SOURCES = cr_engine.cc \
+                     collision.cc \
+                     collision_event.cc \
+                     collision_handle.cc \
+                     collision_reaction.cc \
+                     cr_object_damage.cc \
+                     cr_physics_ground_walk.cc \
+                     cr_physics_full_walk.cc
+
+
+
+noinst_HEADERS =     cr_engine.h \
+                     collision.h \
+                     collision_event.h \
+                     collision_handle.h \
+                     cr_defs.h \
+                     collision_reaction.h \
+                     cr_object_damage.h \
+                     cr_physics_ground_walk.h \
+                     cr_physics_full_walk.h
+
Index: branches/heathaze/src/lib/collision_reaction/collision.cc
===================================================================
--- branches/heathaze/src/lib/collision_reaction/collision.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/collision.cc	(revision 9940)
@@ -0,0 +1,53 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
+
+#include "collision.h"
+#include "debug.h"
+
+/**
+ *  standard constructor
+ */
+Collision::Collision ()
+{
+  this->flushCollisionEvents();
+}
+
+
+/**
+ *  standard deconstructor
+ */
+Collision::~Collision ()
+{
+}
+
+
+/**
+ * flushes the CollisionEvent list
+ */
+void Collision::flushCollisionEvents()
+{
+  this->entityA = NULL;
+  this->entityB = NULL;
+
+  this->entityACollide = false;
+  this->entityBCollide = false;
+
+  this->bDispatched = true;
+
+  this->collisionEvents.clear();
+}
+
Index: branches/heathaze/src/lib/collision_reaction/collision.h
===================================================================
--- branches/heathaze/src/lib/collision_reaction/collision.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/collision.h	(revision 9940)
@@ -0,0 +1,70 @@
+/*!
+ * @file collision.h
+ *  Definition of a collision as a two WE hit each other
+ *
+ *  A is shared between two WorldEntity's CollisionHandles if both are subscribed to this event. In this case only one
+ *  of the two CollisionHandles will calculate the CollisionReaction and the bDispatched flag will be set afterwards
+ *  to signal that it's already cared about and should be ignored.
+ */
+
+#ifndef _COLLISION_H
+#define _COLLISION_H
+
+#include "vector.h"
+#include <vector>
+
+class WorldEntity;
+class BoundingVolume;
+class CollisionEvent;
+
+//! A class representing a simple collision
+class Collision
+{
+  public:
+    Collision();
+    virtual ~Collision();
+
+    /** collides two WorldEntities @param entityA world entity A, @param entityB world entity B, @param bvA volume A @param bvB volumeB */
+    inline void collide(WorldEntity* entityA, WorldEntity* entityB) { this->entityA = entityA; this->entityB = entityB; this->bDispatched = false; }
+
+
+    /** @return Collision WorldEntity A */
+    inline WorldEntity* getEntityA() const { return this->entityA; }
+    /** @return Collision WorldEntity B */
+    inline WorldEntity* getEntityB() const { return this->entityB; }
+    /** @return true if Entity A collides */
+    inline bool isEntityACollide() const { return this->entityACollide; }
+    /** sets the flag if it reacts @param flag true if it should react on entityA*/
+    inline void setEntityACollide(bool flag) { this->entityACollide = flag; }
+    /** @return true if Entity B collides */
+    inline bool isEntityBCollide() const { return this->entityBCollide; }
+    /** sets the flag if it reacts @param flag true if it should react on entityB*/
+    inline void setEntityBCollide(bool flag) { this->entityACollide = flag; }
+
+
+    /** @returns true if this Collision has already been dispatched */
+    inline bool isDispatched() { return this->bDispatched; }
+    /** sets the dispatched flag to true */
+    inline void dispatched() { this->bDispatched = true; }
+
+    /** registers a @param event CollisionEvent to take place */
+    inline void registerCollisionEvent(CollisionEvent* event) { this->collisionEvents.push_back(event); this->bDispatched = false;}
+    /** @returns a vector of collision events */
+    inline const std::vector<CollisionEvent*>& getCollisionEvents() const { return this->collisionEvents; }
+
+
+    void flushCollisionEvents();
+
+
+  private:
+    WorldEntity*                 entityA;                       //!< the collision body A
+    WorldEntity*                 entityB;                       //!< the collision body B
+    bool                         entityACollide;                //!< true if entity A is subscribed for collision reaction
+    bool                         entityBCollide;                //!< true if entity B is subscribed for collision reaction
+
+    bool                         bDispatched;                   //!< true if this collision has already been dispatched
+
+    std::vector<CollisionEvent*> collisionEvents;               //!< the collision event list
+};
+
+#endif /* _COLLISION_H */
Index: branches/heathaze/src/lib/collision_reaction/collision_event.cc
===================================================================
--- branches/heathaze/src/lib/collision_reaction/collision_event.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/collision_event.cc	(revision 9940)
@@ -0,0 +1,41 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
+
+#include "collision_event.h"
+#include "debug.h"
+
+/**
+ *  standard constructor
+ */
+CollisionEvent::CollisionEvent ()
+{
+  this->entityA = NULL;
+  this->entityB = NULL;
+  this->bvA = NULL;
+  this->bvB = NULL;
+}
+
+
+/**
+ *  standard deconstructor
+ */
+CollisionEvent::~CollisionEvent ()
+{
+}
+
+
+
Index: branches/heathaze/src/lib/collision_reaction/collision_event.h
===================================================================
--- branches/heathaze/src/lib/collision_reaction/collision_event.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/collision_event.h	(revision 9940)
@@ -0,0 +1,70 @@
+/*!
+ * @file collision_event.h
+ *  Definition of a collision event
+ */
+
+#ifndef _COLLISION_EVENT_H
+#define _COLLISION_EVENT_H
+
+#include "vector.h"
+
+#include "cr_defs.h"
+
+
+class WorldEntity;
+class BoundingVolume;
+class Plane;
+
+
+
+//! A class representing a simple collision
+class CollisionEvent {
+ public:
+   CollisionEvent();
+  virtual ~CollisionEvent();
+
+  /** collides two WorldEntities @param entityA world entity A, @param entityB world entity B, @param bvA volume A @param bvB volumeB */
+  inline void collide(int type, WorldEntity* entityA, WorldEntity* entityB, BoundingVolume* bvA, BoundingVolume* bvB)
+  { this->collisionType = type; this->entityA = entityA; this->entityB = entityB; this->bvA = bvA; this->bvB = bvB; }
+  /** collides two WorldEntities @param entity world entity , @param ground ground plane, @param position position on the ground */
+  inline void collide(int type, WorldEntity* entity, WorldEntity* groundEntity, Vector normal, Vector position, bool bInWall)
+  { this->collisionType = type; this->entityA = entity; this->entityB = groundEntity, this->groundNormal = normal; this->position = position; this->bInWall = bInWall; }
+
+
+  /** @return CollisionEvent WorldEntity A */
+  inline WorldEntity* getEntityA() const { return this->entityA; }
+  /** @return CollisionEvent WorldEntity B */
+  inline WorldEntity* getEntityB() const { return this->entityB; }
+  /** @return Bounding Volume from EntityA */
+  inline BoundingVolume* getBVA() const { return this->bvA; }
+  /** @return Bounding Volume from EntityB */
+  inline BoundingVolume* getBVB() const { return this->bvB; }
+
+  /** @return ground plane if collided with bsp model */
+  inline Vector getGroundNormal() { return this->groundNormal; }
+
+  /** @return position of the position, only accurate if this is a collision with the ground!!! */
+  inline Vector getCollisionPosition() { return this->position; }
+
+  /** @return the type of the collision */
+  inline int getType() { return this->collisionType; }
+
+  /** @return true if the entity is in the wall */
+  inline bool isInWall() { return this->bInWall; }
+
+
+ private:
+  WorldEntity*      entityA;                       //!< the collision body A
+  WorldEntity*      entityB;                       //!< the collision body B
+
+  BoundingVolume*   bvA;                           //!< reference to the bounding volume A
+  BoundingVolume*   bvB;                           //!< reference to the bounding volume B
+
+  Vector            groundNormal;                  //!< the ground plane with which it collides (only for bsp-model collisions
+  Vector            position;                      //!< position of the collision on the ground plane
+
+  bool              bInWall;                       //!< true if is in wall
+  int               collisionType;                 //!< collision type
+};
+
+#endif /* _COLLISION_EVENT_H */
Index: branches/heathaze/src/lib/collision_reaction/collision_handle.cc
===================================================================
--- branches/heathaze/src/lib/collision_reaction/collision_handle.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/collision_handle.cc	(revision 9940)
@@ -0,0 +1,319 @@
+/*
+   orxonox - the future of 3D-vertical-scrollersf
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
+
+#include "collision_handle.h"
+
+#include "world_entity.h"
+
+#include "collision.h"
+#include "collision_event.h"
+#include "collision_reaction.h"
+
+#include "cr_object_damage.h"
+#include "cr_physics_ground_walk.h"
+#include "cr_physics_full_walk.h"
+
+#include "debug.h"
+
+
+ObjectListDefinition(CollisionHandle);
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+CollisionHandle::CollisionHandle (WorldEntity* owner, CREngine::CRType type)
+{
+  this->registerObject(this, CollisionHandle::_objectList);
+
+  this->owner = owner;
+  this->type = type;
+
+  this->bCollided = false;
+  this->bDispatched = true;
+
+  this->collisionReaction = NULL;
+  this->bContinuousPoll = false;
+  this->bStopOnFirstCollision = false;
+
+
+  switch( type)
+  {
+    case CREngine::CR_PHYSICS_FULL_WALK:
+      this->collisionReaction = new CRPhysicsFullWalk();
+      this->bContinuousPoll = true;
+      break;
+    case CREngine::CR_PHYSICS_GROUND_WALK:
+      this->collisionReaction = new CRPhysicsGroundWalk();
+      this->bContinuousPoll = true;
+      break;
+    case CREngine::CR_OBJECT_DAMAGE:
+      this->collisionReaction = new CRObjectDamage();
+      this->bStopOnFirstCollision = true;
+      break;
+    default:
+      break;
+  };
+}
+
+
+/**
+ * standard deconstructor
+*/
+CollisionHandle::~CollisionHandle ()
+{
+  // delete what has to be deleted here
+  if( this->collisionReaction != NULL)
+    delete this->collisionReaction;
+}
+
+/**
+ * restores the CollisionHandle to its initial state
+ */
+void CollisionHandle::reset()
+{
+  this->flushCollisions();
+}
+
+
+/**
+ * add more filter targets to this collision handle
+ *  @param classID the classid to look for
+ */
+void CollisionHandle::addTarget(const ClassID& target)
+{
+  // make sure there is no dublicate
+  std::vector<ClassID>::iterator it = this->targetList.begin();
+  for( ; it < this->targetList.end(); it++)
+    if( (*it) == target)
+      return;
+
+
+  // add element
+  this->targetList.push_back(target);
+   PRINTF(5)("addTarget: %i \n", target.id());
+}
+
+
+/**
+ * registers a new Collision Object
+ *  @param entityA WorldEntity A of the collision
+ *  @param entityB WorldEntity B of the collision
+ * if a there is already a collision object with the same stats
+ * registration will be skipped and the last collision object is returned
+ */
+Collision* CollisionHandle::registerCollision(WorldEntity* entityA, WorldEntity* entityB)
+{
+  //first get the collision object, multiple sources
+  Collision* c;
+  if( this->collisionList.empty() ||
+      ((this->collisionList.back())->getEntityA() != entityA && (this->collisionList.back())->getEntityB() != entityB )) {
+    c = CREngine::getInstance()->popCollisionObject();
+    c->collide(entityA, entityB);
+    this->collisionList.push_back(c);
+
+    // now register it as a shared collision with the other collision entity
+    CollisionHandle* ch = entityB->getCollisionHandle(this->type);
+    if( ch != NULL)
+      ch->registerSharedCollision(c);
+  }
+  else
+    c = this->collisionList.back();
+
+  return c;
+}
+
+
+/**
+ * register a Collision to the Collision handle.
+ *  @param collision the collision object to register
+ *
+ * This is used for internal collision registration: sharing the collision objects between Collision Reactions
+ * Therefore dispatching it only once
+ */
+void CollisionHandle::registerSharedCollision(Collision* collision)
+{
+  // fist check if we are listening for this Collision
+  if( !this->filterCollision(collision))
+    return;
+
+  // set the state to not dispatched
+  this->bDispatched = false;
+  this->bCollided = true;
+  collision->setEntityBCollide(true);
+
+  this->collisionList.push_back(collision);
+}
+
+
+/**
+ * this is the function to be called on a collision event for this handle
+ *  @param collision the collision objects containing all collision informations
+ */
+void CollisionHandle::registerCollisionEvent(CollisionEvent* collisionEvent)
+{
+  if( !this->filterCollisionEvent(collisionEvent))
+    return;
+
+  // set the state to not dispatched
+  this->bDispatched = false;
+  this->bCollided = true;
+
+  // checks if these WorldEntities have already collided or if its a new collision -> create a new Collision object
+ Collision* c = this->registerCollision(collisionEvent->getEntityA(), collisionEvent->getEntityB());
+ c->setEntityACollide(true);
+
+ c->registerCollisionEvent(collisionEvent);
+ PRINTF(5)("Registering Collision Event: %s, %s\n", collisionEvent->getEntityA()->getClassCName(), collisionEvent->getEntityB()->getClassCName());
+}
+
+
+/**
+ * flushes the collision list
+ */
+void CollisionHandle::flushCollisions()
+{
+  this->collisionList.clear();
+}
+
+
+/**
+ * handles the collisions and react according to algorithm
+ */
+void CollisionHandle::handleCollisions()
+{
+  // if continuous poll poll the reaction
+  if( this->bContinuousPoll && !this->bCollided)
+  {
+    this->collisionReaction->update(this->owner);
+    return;
+  }
+
+  // collision reaction calculations (for every collision there will be a reaction)
+  std::vector<Collision*>::iterator it = this->collisionList.begin();
+  for(; it < this->collisionList.end(); it++) {
+    if( !(*it)->isDispatched())
+    {
+      this->collisionReaction->reactToCollision(*it);
+      (*it)->flushCollisionEvents();
+    }
+  }
+
+  // now set state to dispatched
+  this->bDispatched = true;
+  this->bCollided = false;
+
+  this->flushCollisions();
+}
+
+
+/**
+ * filter out the CollisionEvents that are not wanted
+ *  @param collisionEvent the collision event to filter
+ */
+bool CollisionHandle::filterCollisionEvent(CollisionEvent* collisionEvent)
+{
+  std::vector<ClassID>::iterator it = this->targetList.begin();
+  for(; it < this->targetList.end(); it++)
+  {
+//     if(collisionEvent->getEntityB()->isA(CL_AIMING_SYSTEM) || collisionEvent->getEntityA()->isA(CL_AIMING_SYSTEM))
+//     {
+//        PRINTF(0)("I am: %s colliding with: %s\n", owner->getClassCName(), collisionEvent->getEntityB()->getClassCName(), *it);
+//        if( collisionEvent->getEntityA() == this->owner) {
+//          PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
+//          collisionEvent->getEntityB()->getClassCName(), *it);
+//          if( collisionEvent->getEntityB()->isA((ClassID)(*it))) {
+//            PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
+//            collisionEvent->getEntityB()->getClassCName(), *it);
+//             }
+//        }
+//        else {
+//          PRINTF(0)("I am not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
+//          collisionEvent->getEntityB()->getClassCName(), *it);
+//          if( collisionEvent->getEntityA()->isA((ClassID)(*it))) {
+//            PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
+//            collisionEvent->getEntityA()->getClassCName(), *it);
+//             }
+//        }
+//
+//     }
+
+    if( collisionEvent->getEntityA() == this->owner) {
+      if( collisionEvent->getEntityB()->isA((*it))) {
+        PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
+	collisionEvent->getEntityB()->getClassCName(), (*it).id());
+        return true; }
+    }
+    else {
+      if( collisionEvent->getEntityA()->isA((*it))) {
+        PRINTF(5)("I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
+	collisionEvent->getEntityA()->getClassCName(), (*it).id());
+      return true; }
+    }
+  }
+
+  return false;
+}
+
+
+/**
+ * filter Collisions that are not wanted to be reacted to
+ *  @param collision the collision object to filter
+ */
+bool CollisionHandle::filterCollision(Collision* collision)
+{
+  std::vector<ClassID>::iterator it = this->targetList.begin();
+  for(; it < this->targetList.end(); it++)
+  {
+
+//     if(collision->getEntityB()->isA(CL_AIMING_SYSTEM) || collision->getEntityA()->isA(CL_AIMING_SYSTEM))
+//     {
+//       PRINTF(0)("Shared!!! I am: %s colliding with: %s\n", owner->getClassCName(), collision->getEntityB()->getClassCName(), *it);
+//       if( collision->getEntityA() == this->owner) {
+//         PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
+//         collision->getEntityB()->getClassCName(), *it);
+//         if( collision->getEntityB()->isA((ClassID)(*it))) {
+//           PRINTF(0)("I am owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
+//           collision->getEntityB()->getClassCName(), *it);
+//         }
+//       }
+//       else {
+//         PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter?\n", owner->getClassCName(),
+//         collision->getEntityB()->getClassCName(), *it);
+//         if( collision->getEntityA()->isA((ClassID)(*it))) {
+//           PRINTF(0)("I'm not owner -> I am: %s colliding with: %s is a %i filter ok\n", owner->getClassCName(),
+//           collision->getEntityA()->getClassCName(), *it);
+//         }
+//       }
+//     }
+
+    if( collision->getEntityA() == this->owner) {
+      if( collision->getEntityA()->isA(*it))
+        return true; }
+      else {
+        if( collision->getEntityB()->isA(*it))
+          return true; }
+  }
+
+  return false;
+}
+
+
+
+
+
+
+
Index: branches/heathaze/src/lib/collision_reaction/collision_handle.h
===================================================================
--- branches/heathaze/src/lib/collision_reaction/collision_handle.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/collision_handle.h	(revision 9940)
@@ -0,0 +1,73 @@
+/*!
+ * @file collision_handle.h
+ * @brief Definition of a collision handle: used for accesing per world entity collision events and reactions
+*/
+
+#ifndef _COLLISION_HANDLE_H
+#define _COLLISION_HANDLE_H
+
+#include "base_object.h"
+#include "cr_engine.h"
+
+#include <vector>
+#include <list>
+
+
+class Collision;
+class WorldEntity;
+class CollisionReaction;
+
+
+
+//! A class for defining collision reactions and storing events
+class CollisionHandle : public BaseObject
+{
+  ObjectListDeclaration(CollisionHandle);
+  public:
+    CollisionHandle(WorldEntity* owner, CREngine::CRType type);
+    virtual ~CollisionHandle();
+
+    void reset();
+
+    void addTarget(const ClassID& target);
+    Collision* registerCollision(WorldEntity* entityA, WorldEntity* entityB);
+    void registerSharedCollision(Collision* collision);
+    void registerCollisionEvent(CollisionEvent* collisionEvent);
+
+    /** @returns true if regiestered some new collision events in this tick frame */
+    inline bool isCollided() const { return this->bCollided; }
+    /** @returns true if this collision handle has already been dispatched */
+    inline bool isDispatched() const { return this->bDispatched; }
+    /** @returns true if this handle should be pulled also if there are no collisions */
+    inline bool isContinuousPoll() const { return this->bContinuousPoll; }
+    /** @returns the type */
+    inline CREngine::CRType getType() const { return this->type; }
+
+    void handleCollisions();
+
+
+  private:
+    void flushCollisions();
+    bool filterCollisionEvent(CollisionEvent* collisionEvent);
+    bool filterCollision(Collision* collision);
+
+
+
+  private:
+    WorldEntity*                  owner;                   //!< the worldenity this reaction will be applied on
+    CREngine::CRType              type;                    //!< the reaction type
+
+    bool                          bContinuousPoll;         //!< if this is true
+    bool                          bDispatched;             //!< true if this handle has already been dispatched
+    bool                          bStopOnFirstCollision;   //!< true if the cd of this object should be terminated after one match
+    bool                          bCollided;               //!< true if the CollsionHandle has registered some new collisions
+
+    std::vector<Collision*>       collisionList;           //!< a list full of collisions
+    /// TODO Take a std::set here!
+    std::vector<ClassID>          targetList;              //!< a list of target classes for filtering @TODO TAKE SET INSTEAD OF VECTOR HERE
+
+    CollisionReaction*            collisionReaction;       //!< reference to the collision reaction object
+
+};
+
+#endif /* _COLLISION_HANDLE_H */
Index: branches/heathaze/src/lib/collision_reaction/collision_reaction.cc
===================================================================
--- branches/heathaze/src/lib/collision_reaction/collision_reaction.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/collision_reaction.cc	(revision 9940)
@@ -0,0 +1,40 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
+
+#include "collision_reaction.h"
+
+
+
+ObjectListDefinition(CollisionReaction);
+
+/**
+ *  standard constructor
+ */
+CollisionReaction::CollisionReaction ()
+  : BaseObject()
+{
+  this->registerObject(this, CollisionReaction::_objectList);
+}
+
+
+/**
+ *  standard deconstructor
+ */
+CollisionReaction::~CollisionReaction ()
+{
+}
+
Index: branches/heathaze/src/lib/collision_reaction/collision_reaction.h
===================================================================
--- branches/heathaze/src/lib/collision_reaction/collision_reaction.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/collision_reaction.h	(revision 9940)
@@ -0,0 +1,36 @@
+/*!
+ * @file collision_reaction.h
+ *  Definition of a generic collision reaction
+ */
+
+#ifndef _COLLISION_REACTION_H
+#define _COLLISION_REACTION_H
+
+#include "base_object.h"
+
+
+
+class Collision;
+class WorldEntity;
+
+
+//! A class representing a simple collision
+class CollisionReaction : public BaseObject
+{
+  ObjectListDeclaration(CollisionReaction);
+  public:
+    CollisionReaction();
+    virtual ~CollisionReaction();
+
+    virtual void reactToCollision(Collision* collision) = 0;
+
+    virtual void update(WorldEntity* owner) {}
+
+    /** use this to do some collision offline calculations, only called for bContinuousPoll == true */
+    inline bool isContinuousPoll() const { return this->bContinuousPoll; }
+
+  private:
+    bool                    bContinuousPoll;       //!< if true the collision rection function is also called, if there was no collision
+};
+
+#endif /* _COLLISION_REACTION_H */
Index: branches/heathaze/src/lib/collision_reaction/cr_defs.h
===================================================================
--- branches/heathaze/src/lib/collision_reaction/cr_defs.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/cr_defs.h	(revision 9940)
@@ -0,0 +1,43 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+/*!
+ * @file cr_defs.h
+ *  some global collision reaction definitions
+ */
+
+#ifndef _CR_DEFS_H
+#define _CR_DEFS_H
+
+//!< the maximal number of touching objects (collisions) per frame
+#define CR_MAX_COLLISIONS          500
+
+//!< the maximal number of bounding volumes collision events per frame
+#define CR_MAX_COLLISION_EVENTS   3000
+
+
+//!< the collision axis x collision event
+#define COLLISION_TYPE_AXIS_X      1
+#define COLLISION_TYPE_AXIS_X_NEG  2
+//!< the collision axis y collision event
+#define COLLISION_TYPE_AXIS_Y      3
+#define COLLISION_TYPE_AXIS_Y_NEG  4
+//!< the collision axis z collision event
+#define COLLISION_TYPE_AXIS_Z      5
+#define COLLISION_TYPE_AXIS_Z_NEG  6
+//!< the collision is a obb collision
+#define COLLISION_TYPE_OBB      8
+
+
+#endif /* _NETWORK_MANAGER */
Index: branches/heathaze/src/lib/collision_reaction/cr_engine.cc
===================================================================
--- branches/heathaze/src/lib/collision_reaction/cr_engine.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/cr_engine.cc	(revision 9940)
@@ -0,0 +1,178 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
+
+
+
+#include "collision.h"
+#include "collision_event.h"
+#include "collision_handle.h"
+#include "cr_defs.h"
+
+#include "cr_engine.h"
+
+#include "debug.h"
+
+
+
+ObjectListDefinition(CREngine);
+/**
+ * standard constructor
+ */
+CREngine::CREngine ()
+  : BaseObject()
+{
+  this->registerObject(this, CREngine::_objectList);
+   this->setName("CREngine");
+
+   this->init();
+}
+
+/**
+ *  the singleton reference to this class
+ */
+CREngine* CREngine::singletonRef = NULL;
+
+/**
+   @brief standard deconstructor
+ */
+CREngine::~CREngine ()
+{
+  CREngine::singletonRef = NULL;
+
+  if( this->collisionsUnused.size() != CR_MAX_COLLISIONS)
+    PRINTF(0)("CollisionReaction Error: Collision cache size missmatch: %i of %i\n", this->collisionsUnused.size(), CR_MAX_COLLISIONS);
+  if( this->collisionEventsUnused.size() != CR_MAX_COLLISION_EVENTS)
+    PRINTF(0)("CollisionReaction Error: CollisionEvent cache size missmatch: %i of %i\n", this->collisionEventsUnused.size(), CR_MAX_COLLISION_EVENTS);
+
+  this->reset();
+
+  std::vector<Collision*>::iterator it1 = this->collisionsUnused.begin();
+  for(; it1 < this->collisionsUnused.end(); it1++)
+    delete *it1;
+  std::vector<CollisionEvent*>::iterator it2 = this->collisionEventsUnused.begin();
+  for(; it2 < this->collisionEventsUnused.end(); it2++)
+    delete *it2;
+
+  this->collisionsUnused.clear();
+  this->collisionEventsUnused.clear();
+}
+
+/**
+ * inits the CREngine to a working state
+ */
+void CREngine::init()
+{
+  // create a list of Collision events (precaching)
+  for( int i = 0; i < CR_MAX_COLLISIONS; i++)
+    this->collisionsUnused.push_back(new Collision());
+  for( int i = 0; i < CR_MAX_COLLISION_EVENTS; i++)
+    this->collisionEventsUnused.push_back(new CollisionEvent());
+}
+
+
+/**
+ * flushes the CollisionHandles and restores the CREngine to the initial state
+ */
+void CREngine::reset()
+{
+  // first clear all CollisionHandles
+
+  std::vector<CollisionHandle*>::iterator it = this->collisionHandles.begin();
+  for(; it < this->collisionHandles.end(); it++)
+  {
+    (*it)->reset();
+    delete *it;
+  }
+
+  this->collisionHandles.clear();
+}
+
+
+/**
+ * subscribes a WorldEntity for a CollisionReaction
+ *  @param owner: the WE to subscribe
+ *  @param type: the type of collision reaction to perform
+ *  @return the newly created CollisionHandle
+ */
+CollisionHandle* CREngine::subscribeReaction(WorldEntity* owner, CRType type)
+{
+  CollisionHandle* ch = new CollisionHandle(owner, type);
+  this->collisionHandles.push_back(ch);
+
+  return ch;
+}
+
+
+/**
+ * unsubscribe reaction from the reaction list
+ *  @param collisionHandle the CollisionHandle to remove
+ *  @param returns true if worked collrectly
+ */
+bool CREngine::unsubscribeReaction(CollisionHandle* collisionHandle)
+{
+  std::vector<CollisionHandle*>::iterator it;
+  for( it = this->collisionHandles.begin(); it != this->collisionHandles.end(); it++)  {
+    if( *it == collisionHandle) {
+      this->collisionHandles.erase(it);
+      delete collisionHandle;
+      return true;
+    }
+  }
+  return false;
+}
+
+
+/**
+ * processes the collisions by calling the EventHandlers
+ */
+void CREngine::handleCollisions()
+{
+  std::vector<CollisionHandle*>::iterator it;
+  for( it = this->collisionHandles.begin(); it != this->collisionHandles.end(); it++)
+  {
+    if( !(*it)->isDispatched() || (*it)->isContinuousPoll())  //does it have any collisions to report at all
+    {
+      (*it)->handleCollisions();
+    }
+  }
+  this->flushCollisions();
+}
+
+
+/**
+ * flushes all the collision lists and puts them to their initial state
+ */
+void CREngine::flushCollisions()
+{
+  std::vector<Collision*>::iterator it1 = this->collisionsUsed.begin();
+  for(; it1 < this->collisionsUsed.end(); it1++)
+    this->collisionsUnused.push_back(*it1);
+
+  std::vector<CollisionEvent*>::iterator it2 = this->collisionEventsUsed.begin();
+  for(; it2 < this->collisionEventsUsed.end(); it2++)
+    this->collisionEventsUnused.push_back(*it2);
+
+  this->collisionsUsed.clear();
+  this->collisionEventsUsed.clear();
+}
+
+
+void CREngine::debug()
+{
+
+}
+
Index: branches/heathaze/src/lib/collision_reaction/cr_engine.h
===================================================================
--- branches/heathaze/src/lib/collision_reaction/cr_engine.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/cr_engine.h	(revision 9940)
@@ -0,0 +1,94 @@
+/*!
+ * @file cr_engine.h
+ * @brief The collision reaction engine, defining generic collision reactions to collision events
+ *
+ * some parts of this module are tuned for efficiency. They are probably not self-explenatory anymore :D
+ *  - Collision/ CollisionEvent objects recycling: This class contains a class of precached objects of these types
+ *      they are used for fast registration of collision events: These objects can be get by the interface functions and
+ *      are returned after one cycle automaticly by reseting the cached lists to its initial state. So do not wonder :D
+ */
+
+#ifndef _CR_ENGINE_
+#define _CR_ENGINE_
+
+#include "base_object.h"
+
+#include <vector>
+
+// FORWARD DECLARATION
+class CollisionHandle;
+class Collision;
+class CollisionEvent;
+class WorldEntity;
+
+//! A default singleton class.
+class CREngine : public BaseObject
+{
+  ObjectListDeclaration(CREngine);
+
+  public:
+  typedef enum CRType {
+    CR_PHYSICS_MOMENTUM   = 0,    //!< physical reaction: conservervation of momentum
+    CR_PHYSICS_STEP_BACK,         //!< physical reaction: just go to the last position without collisions
+    CR_PHYSICS_GROUND_WALK,       //!< physical reaction: stand on the ground, no movement: simulating simple normal force away from the gravity force
+    CR_PHYSICS_FULL_WALK,         //!< physical reaction: walking on the ground (inkl. hills etc)
+    CR_PHYSICS_DAMAGE,            //!< physical reaction: daling damage according to the object energy and their structural stability
+
+    CR_OBJECT_DAMAGE,             //!< object raction: deals damage according to the objects specific damage potential (like weapons, nukes, etc.)
+    CR_OBJECT_PICKUP,             //!< object rection: calling the objects pickup functions, let them handle the collision (once!)
+
+    CR_VERTEX_TRAFO,              //!< vertex trafo: transforming the vertex according to the damage
+
+    CR_SPECIAL_CALLBACK,          //!< special: call a callback function
+
+    CR_NUMBER
+  };
+
+  virtual ~CREngine(void);
+
+  /** @returns a Pointer to the only object of this Class */
+  inline static CREngine* getInstance() { if (!singletonRef) singletonRef = new CREngine();  return singletonRef; };
+
+  void reset();
+
+
+  CollisionHandle* subscribeReaction(WorldEntity* worldEntity, CRType type);
+
+  bool unsubscribeReaction(CollisionHandle* collisionHandle);
+
+  void handleCollisions();
+
+  /** @returns an instance to a collision object. instead of creating new object this ones can be resycled */
+  inline Collision* popCollisionObject() {
+    if( !this->collisionsUnused.empty()) {
+      this->collisionsUsed.push_back(this->collisionsUnused.back()); this->collisionsUnused.pop_back(); return this->collisionsUsed.back(); } else return NULL; }
+
+
+  /** @return an instanco of a CollisionEvent object. instead of creating a new object this ones can be used and resycled */
+  inline CollisionEvent* popCollisionEventObject() {
+    if( !this->collisionEventsUnused.empty()) {
+      this->collisionEventsUsed.push_back(this->collisionEventsUnused.back()); this->collisionEventsUnused.pop_back(); return this->collisionEventsUsed.back(); } else return NULL; }
+
+  void debug();
+
+
+private:
+  CREngine();
+  void init();
+
+  void flushCollisions();
+
+
+private:
+  std::vector<CollisionHandle*>       collisionHandles;         //!< list with the collision handles
+
+  std::vector<Collision*>             collisionsUsed;           //!< a list of used, cached collisions
+  std::vector<Collision*>             collisionsUnused;         //!< a list of unused, cached collisions
+
+  std::vector<CollisionEvent*>        collisionEventsUsed;      //!< a list of used, cached collision events
+  std::vector<CollisionEvent*>        collisionEventsUnused;    //!< a list of unused, cached collision events
+
+  static CREngine*                    singletonRef;             //!< the reference to the CREngine object (singleton)
+};
+
+#endif /* _CR_ENGINE_ */
Index: branches/heathaze/src/lib/collision_reaction/cr_object_damage.cc
===================================================================
--- branches/heathaze/src/lib/collision_reaction/cr_object_damage.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/cr_object_damage.cc	(revision 9940)
@@ -0,0 +1,86 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
+
+#include "collision.h"
+#include "collision_event.h"
+
+#include "physics_interface.h"
+
+#include "world_entity.h"
+#include "cr_object_damage.h"
+
+#include "debug.h"
+
+
+
+ObjectListDefinition(CRObjectDamage);
+/**
+ *  standard constructor
+ */
+CRObjectDamage::CRObjectDamage ()
+  : CollisionReaction()
+{
+  this->registerObject(this, CRObjectDamage::_objectList);
+}
+
+
+/**
+ *  standard deconstructor
+ */
+CRObjectDamage::~CRObjectDamage ()
+{
+}
+
+
+/**
+ * caluculates and applys the reaction to a specific collision
+ *  @param collision the collision
+ */
+void CRObjectDamage::reactToCollision(Collision* collision)
+{
+  float damage = 0.0f;
+
+  PRINTF(4)("Dealing damage - Handling collision: %s vs %s\n",
+            collision->getEntityA()->getClassCName(),
+            collision->getEntityB()->getClassCName());
+
+  // the collision damage been dealed by the entity
+  if( collision->isEntityACollide()) {
+    damage = collision->getEntityB()->getDamage();
+    collision->getEntityA()->hit(damage, collision->getEntityB());
+    PRINTF(4)("Dealing damage - %f damage to %s \n", damage, collision->getEntityA()->getClassCName());
+  }
+
+  if( collision->isEntityBCollide()) {
+    damage = collision->getEntityA()->getDamage();
+    collision->getEntityB()->hit(damage, collision->getEntityA());
+    PRINTF(4)("Dealing damage - %f damage to %s \n", damage, collision->getEntityB()->getClassCName());
+  }
+
+  collision->flushCollisionEvents();
+  collision->dispatched();
+
+//   const std::vector<CollisionEvent*>* collisionEvents = &(collision->getCollisionEvents());
+//   std::vector<CollisionEvent*>::const_iterator it = collisionEvents->begin();
+//   for(; it != collisionEvents->end(); it++)
+//   {
+//     // go through the collisions and try to estimate the damage
+//     mass = (*it)->getEntityA()->getMass();
+//   }
+
+}
+
Index: branches/heathaze/src/lib/collision_reaction/cr_object_damage.h
===================================================================
--- branches/heathaze/src/lib/collision_reaction/cr_object_damage.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/cr_object_damage.h	(revision 9940)
@@ -0,0 +1,28 @@
+/*!
+ * @file cr_object_damage.h
+ *  Definition of a collision reaction: dealing damage to an object
+ */
+
+#ifndef _CR_OBJECT_DAMAGE_H
+#define _CR_OBJECT_DAMAGE_H
+
+#include "collision_reaction.h"
+
+
+class Collision;
+
+//! A class representing a reaction to a collision: dealing damage to an object
+class CRObjectDamage : public CollisionReaction
+{
+  ObjectListDeclaration(CRObjectDamage);
+  public:
+    CRObjectDamage();
+    virtual ~CRObjectDamage();
+
+    virtual void reactToCollision(Collision* collision);
+
+  private:
+
+};
+
+#endif /* _CR_OBJECT_DAMAGE_H */
Index: branches/heathaze/src/lib/collision_reaction/cr_physics_full_walk.cc
===================================================================
--- branches/heathaze/src/lib/collision_reaction/cr_physics_full_walk.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/cr_physics_full_walk.cc	(revision 9940)
@@ -0,0 +1,228 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
+
+#include "collision.h"
+#include "collision_event.h"
+
+#include "physics_interface.h"
+
+#include "world_entity.h"
+#include "cr_physics_full_walk.h"
+#include "collision_reaction.h"
+
+#include <vector>
+
+#include "debug.h"
+
+#include "aabb.h"
+
+#include "cr_defs.h"
+
+
+
+ObjectListDefinition(CRPhysicsFullWalk);
+/**
+ *  standard constructor
+ */
+CRPhysicsFullWalk::CRPhysicsFullWalk ()
+    : CollisionReaction()
+{
+  this->registerObject(this, CRPhysicsFullWalk::_objectList);
+}
+
+
+/**
+ *  standard deconstructor
+ */
+CRPhysicsFullWalk::~CRPhysicsFullWalk ()
+{}
+
+
+/**
+ * caluculates and applys the reaction to a specific collision
+ *  @param collision the collision
+ */
+void CRPhysicsFullWalk::reactToCollision(Collision* collision)
+{
+
+  AABB* box = collision->getEntityB()->getModelAABB();
+  WorldEntity* entity = collision->getEntityB();
+
+  if( box == NULL)
+  {
+    PRINTF(2)("this model has no aabb box so there is no correct collision reaction implemented. skipping\n");
+    return;
+  }
+
+
+  float CR_MAX_WALK_HEIGHT = 15.0f;
+  float CR_THRESHOLD = 0.2f;
+
+  float height = 0.0f;
+  float front = 0.0f;
+  float back = 0.0f;
+  float right = 0.0f;
+  float left = 0.0f;
+
+
+  const std::vector<CollisionEvent*>* collisionEvents = &(collision->getCollisionEvents());
+  std::vector<CollisionEvent*>::const_iterator it = collisionEvents->begin();
+  for(; it != collisionEvents->end(); it++)
+  {
+
+    CollisionEvent* ce = (*it);
+    Vector normal = ce->getGroundNormal();
+
+    // calculate the collision position
+    Vector collPos =  collision->getEntityB()->getAbsCoor()  + box->center - ce->getCollisionPosition();
+
+    // test the 3 axis differently
+    switch( ce->getType())
+    {
+        /* collision in the X-AXIS */
+      case COLLISION_TYPE_AXIS_X:
+        front = collPos.len() - box->halfLength[0];
+
+        // object is beneath the plane (ground)
+        if( front <= 0.0f )
+        {
+          Vector dirX = entity->getAbsDirX();
+          dirX.y = 0.0f;
+          dirX.normalize();
+          Vector backoff = dirX * front;
+
+          entity->shiftCoor(backoff);
+        }
+        else if( ce->isInWall())
+        {
+          // object is already in the wall
+          entity->setAbsCoor(entity->getLastAbsCoor());
+        }
+        break;
+
+      case COLLISION_TYPE_AXIS_X_NEG:
+        back = collPos.len() - box->halfLength[0];
+
+        // object is beneath the plane (ground)
+        if( back <= 0.0f)
+        {
+          Vector dirX = entity->getAbsDirX();
+          dirX.y = 0.0f;
+          dirX.normalize();
+          Vector backoff = dirX * back * -1.0f;
+
+          entity->shiftCoor(backoff);
+        }
+        else if( ce->isInWall())
+        {
+          // object is already in the wall
+          entity->setAbsCoor(entity->getLastAbsCoor());
+        }
+        break;
+
+
+        /* collision in the Y-AXIS */
+      case COLLISION_TYPE_AXIS_Y_NEG:
+        // calulate the height above ground
+        height = collPos.len() - box->halfLength[1];
+
+
+        // object is beneath the plane (ground)
+        //         if(height >= 0.0f && height <= 0.0001f) break ;// Do nothing
+        if( height < 0.0f && -height < CR_MAX_WALK_HEIGHT)
+        {
+          entity->shiftCoor(Vector(0.0f, -height + 0.00001, 0.0f));
+          entity->setOnGround(true);
+        }
+        // object is already in the wall
+        else if( ce->isInWall())
+        {
+          entity->setAbsCoor(entity->getLastAbsCoor());
+          PRINTF(0)("ground collision: reset pos\n");
+        }
+        else
+        {
+          // entity is not on ground
+          entity->setOnGround(false);
+        }
+        break;
+
+
+        /* collision in the Z-AXIS */
+      case COLLISION_TYPE_AXIS_Z:
+
+        right = collPos.len()  - box->halfLength[2];
+
+        // object is beneath the plane (ground)
+        if( right <= 0.0f )
+        {
+          Vector dirZ = entity->getAbsDirZ();
+          dirZ.y = 0.0f;
+          dirZ.normalize();
+          Vector backoff = dirZ * right;
+          entity->shiftCoor(backoff);
+        }
+        else if( ce->isInWall())
+        {
+          // object is already in the wall
+          entity->setAbsCoor(entity->getLastAbsCoor());
+        }
+        break;
+
+
+        // collision in the z-axis
+      case COLLISION_TYPE_AXIS_Z_NEG:
+
+        left = collPos.len()  - box->halfLength[2];
+
+        // object is beneath the plane (ground)
+        if( left <= 0.0f )
+        {
+          Vector dirZ = entity->getAbsDirZ();
+          dirZ.y = 0.0f;
+          dirZ.normalize();
+          Vector backoff = dirZ * left*-1.0f;
+          entity->shiftCoor(backoff);
+        }
+        // object is already in the wall
+        else if( ce->isInWall())
+        {
+          entity->setAbsCoor(entity->getLastAbsCoor());
+        }
+        break;
+    }
+  }
+  //PRINTF(0)("collision distances: x: %f, y: %f, z: %f\n", front, height, side);
+
+
+
+
+
+
+
+}
+
+
+
+
+/**
+ * use this to do some collision offline calculations, only called for bContinuousPoll == true
+ */
+void CRPhysicsFullWalk::update(WorldEntity* owner)
+{}
+
+
Index: branches/heathaze/src/lib/collision_reaction/cr_physics_full_walk.h
===================================================================
--- branches/heathaze/src/lib/collision_reaction/cr_physics_full_walk.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/cr_physics_full_walk.h	(revision 9940)
@@ -0,0 +1,31 @@
+/*!
+ * @file cr_object_damage.h
+ *  Definition of a collision reaction: dealing damage to an object
+ */
+
+#ifndef _CR_PHYSICS_FULL_WALK_H
+#define _CR_PHYSICS_FULL_WALK_H
+
+#include "collision_reaction.h"
+
+
+class Collision;
+
+//! A class representing a reaction to a collision: dealing damage to an object
+class CRPhysicsFullWalk : public CollisionReaction
+{
+  ObjectListDeclaration(CRPhysicsFullWalk);
+  public:
+    CRPhysicsFullWalk();
+    virtual ~CRPhysicsFullWalk();
+
+    virtual void reactToCollision(Collision* collision);
+
+    virtual void update(WorldEntity* entity);
+
+
+  private:
+    float        downspeed;
+};
+
+#endif /* _CR_PHYSICS_FULL_WALK_H */
Index: branches/heathaze/src/lib/collision_reaction/cr_physics_ground_walk.cc
===================================================================
--- branches/heathaze/src/lib/collision_reaction/cr_physics_ground_walk.cc	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/cr_physics_ground_walk.cc	(revision 9940)
@@ -0,0 +1,132 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
+
+#include "collision.h"
+#include "collision_event.h"
+
+#include "physics_interface.h"
+
+#include "world_entity.h"
+#include "cr_physics_ground_walk.h"
+#include "collision_reaction.h"
+
+#include <vector>
+
+#include "debug.h"
+
+#include "aabb.h"
+
+#include "cr_defs.h"
+
+
+
+ObjectListDefinition(CRPhysicsGroundWalk);
+/**
+ *  standard constructor
+ */
+CRPhysicsGroundWalk::CRPhysicsGroundWalk ()
+    : CollisionReaction()
+{
+  this->registerObject(this, CRPhysicsGroundWalk::_objectList);
+}
+
+
+/**
+ *  standard deconstructor
+ */
+CRPhysicsGroundWalk::~CRPhysicsGroundWalk ()
+{}
+
+
+/**
+ * caluculates and applys the reaction to a specific collision
+ *  @param collision the collision
+ */
+void CRPhysicsGroundWalk::reactToCollision(Collision* collision)
+{
+
+  AABB* box = collision->getEntityB()->getModelAABB();
+  WorldEntity* entity = collision->getEntityB();
+
+  if( box == NULL)
+  {
+    PRINTF(2)("this model has no aabb box so there is no correct collision reaction implemented. skipping\n");
+    return;
+  }
+
+
+  float CR_MAX_WALK_HEIGHT = 15.0f;
+
+  float height = 0.0f;
+
+
+  const std::vector<CollisionEvent*>* collisionEvents = &(collision->getCollisionEvents());
+  std::vector<CollisionEvent*>::const_iterator it = collisionEvents->begin();
+  for(; it != collisionEvents->end(); it++)
+  {
+
+    CollisionEvent* ce = (*it);
+    Vector normal = ce->getGroundNormal();
+
+    // calculate the collision position
+    Vector collPos =  collision->getEntityB()->getAbsCoor()  + box->center - ce->getCollisionPosition();
+
+    // test the 3 axis differently
+    switch( ce->getType())
+    {
+        /* collision in the Y-AXIS */
+      case COLLISION_TYPE_AXIS_Y_NEG:
+        // calulate the height above ground
+        height = collPos.len() - box->halfLength[1];
+
+
+        // object is beneath the plane (ground)
+        //         if(height >= 0.0f && height <= 0.0001f) break ;// Do nothing
+        if( height < 0.0f && -height < CR_MAX_WALK_HEIGHT)
+        {
+          entity->shiftCoor(Vector(0.0f, -height + 0.00001, 0.0f));
+          entity->setOnGround(true);
+        }
+        // object is already in the wall
+        else if( ce->isInWall())
+        {
+          entity->setAbsCoor(entity->getLastAbsCoor());
+        }
+        else
+        {
+          // entity is not on ground
+          entity->setOnGround(false);
+        }
+        break;
+
+
+    }
+  }
+  //PRINTF(0)("collision distances: x: %f, y: %f, z: %f\n", front, height, side);
+
+}
+
+
+
+
+/**
+ * use this to do some collision offline calculations, only called for bContinuousPoll == true
+ */
+void CRPhysicsGroundWalk::update(WorldEntity* owner)
+{}
+
+
Index: branches/heathaze/src/lib/collision_reaction/cr_physics_ground_walk.h
===================================================================
--- branches/heathaze/src/lib/collision_reaction/cr_physics_ground_walk.h	(revision 9940)
+++ branches/heathaze/src/lib/collision_reaction/cr_physics_ground_walk.h	(revision 9940)
@@ -0,0 +1,31 @@
+/*!
+ * @file cr_object_damage.h
+ *  Definition of a collision reaction: dealing damage to an object
+ */
+
+#ifndef _CR_PHYSICS_GROUND_WALK_H
+#define _CR_PHYSICS_GROUND_WALK_H
+
+#include "collision_reaction.h"
+
+
+class Collision;
+
+//! A class representing a reaction to a collision: dealing damage to an object
+class CRPhysicsGroundWalk : public CollisionReaction
+{
+  ObjectListDeclaration(CRPhysicsGroundWalk);
+  public:
+    CRPhysicsGroundWalk();
+    virtual ~CRPhysicsGroundWalk();
+
+    virtual void reactToCollision(Collision* collision);
+
+    virtual void update(WorldEntity* entity);
+
+
+  private:
+    float        downspeed;
+};
+
+#endif /* _CR_PHYSICS_GROUND_WALK_H */
Index: branches/heathaze/src/lib/coord/p_node.cc
===================================================================
--- branches/heathaze/src/lib/coord/p_node.cc	(revision 9940)
+++ branches/heathaze/src/lib/coord/p_node.cc	(revision 9940)
@@ -0,0 +1,1122 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PNODE
+
+#include "p_node.h"
+
+#include "util/loading/load_param.h"
+
+#include "netdefs.h"
+
+#include <algorithm>
+#include "compiler.h"
+#include "debug.h"
+
+#include "glincl.h"
+#include "color.h"
+
+
+ObjectListDefinition(PNode);
+/**
+ * @brief standard constructor
+ * @param parent the Parent of this Node. __NULL__ if __No Parent__ requested, PNode::getNullParent(), if connected to NullParent directly (default)
+ * @param nodeFlags all flags to set. THIS_WILL_OVERWRITE Default_Values.
+ */
+PNode::PNode (PNode* parent, long nodeFlags)
+  : BaseObject(), Synchronizeable()
+{
+  this->registerObject(this, PNode::_objectList);
+
+  this->bRelCoorChanged = true;
+  this->bRelDirChanged = true;
+  this->parent = NULL;
+  this->parentMode = nodeFlags;
+  this->bActive = true;
+
+  // smooth-movers
+  this->toCoordinate = NULL;
+  this->toDirection = NULL;
+  this->bias = 1.0;
+
+  if (parent != NULL)
+    parent->addChild(this);
+
+  this->relCoordinate_handle = this->registerVarId( new SynchronizeableVector( &relCoordinate, &relCoordinate_write, "coordinate", PERMISSION_SERVER ) );
+  this->relDirection_handle = this->registerVarId( new SynchronizeableQuaternion( &relDirection, &relDirection_write, "direction", PERMISSION_SERVER ) );
+}
+
+// NullParent Reference
+PNode* PNode::nullParent = NULL;
+
+/**
+ * @brief standard deconstructor
+ *
+ * There are two general ways to delete a PNode
+ * 1. delete instance;
+ *   -> result
+ *    delete this Node and all its children and children's children...
+ *    (danger if you still need the children's instance somewhere else!!)
+ *
+ * 2. instance->removeNode(); delete instance;
+ *   -> result:
+ *    moves its children to the NullParent
+ *    then deletes the Element.
+ */
+PNode::~PNode ()
+{
+  PRINTF(4)("delete %s::%s\n", this->getClassCName(), this->getCName());
+  // remove the Node, delete it's children (if required).
+  PNode* last = NULL;
+  //this->debugNode(0);
+
+  while(!this->children.empty())
+  {
+    PNode* deleteNode = this->children.front();
+    if (deleteNode == last)
+    {
+      PRINTF(1)("Node same as last that was tried to be deleted. FORCE reparent to NULL of %p\n", deleteNode);
+      (deleteNode->setParent( NULL));
+      continue;
+    }
+    if ((this->parentMode & PNODE_PROHIBIT_CHILD_DELETE) ||
+        (deleteNode->parentMode & PNODE_PROHIBIT_DELETE_WITH_PARENT))
+    {
+      if (this == PNode::nullParent && deleteNode->parentMode & PNODE_REPARENT_TO_NULL)
+      {
+        PRINTF(4)("%s::%s deletes %s::%s\n",
+                  this->getClassCName(), this->getCName(),
+                  deleteNode->getClassCName(), deleteNode->getCName());
+        delete deleteNode;
+      }
+      else
+      {
+        PRINTF(4)("%s::%s reparents %s::%s\n",
+                  this->getClassCName(), this->getCName(),
+                  deleteNode->getClassCName(), deleteNode->getCName());
+        deleteNode->reparent();
+      }
+    }
+    else
+    {
+      PRINTF(4)("%s::%s deletes PNode: %s::%s\n",
+                this->getClassCName(), this->getCName(),
+                deleteNode->getClassCName(), deleteNode->getCName());
+      delete deleteNode;
+    }
+    last = deleteNode;
+  }
+
+  if (this->parent != NULL)
+  {
+    this->parent->eraseChild(this);
+    this->parent = NULL;
+  }
+
+  // remove all other allocated memory.
+  if (this->toCoordinate != NULL)
+    delete this->toCoordinate;
+  if (this->toDirection != NULL)
+    delete this->toDirection;
+
+  if (this == PNode::nullParent)
+    PNode::nullParent = NULL;
+}
+
+
+/**
+ * @brief loads parameters of the PNode
+ * @param root the XML-element to load the properties of
+ */
+void PNode::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+
+  LoadParam(root, "rel-coor", this, PNode, setRelCoor)
+  .describe("Sets The relative position of the Node to its parent.");
+
+  LoadParam(root, "abs-coor", this, PNode, setAbsCoor)
+  .describe("Sets The absolute Position of the Node.");
+
+  LoadParam(root, "rel-dir", this, PNode, setRelDir)
+  .describe("Sets The relative rotation of the Node to its parent.");
+
+  LoadParam(root, "abs-dir", this, PNode, setAbsDir)
+  .describe("Sets The absolute rotation of the Node.");
+
+  LoadParam(root, "parent", this, PNode, setParent)
+  .describe("the Name of the Parent to set for this PNode");
+
+  LoadParam(root, "parent-mode", this, PNode, setParentMode)
+  .describe("the mode to connect this node to its parent ()");
+
+  // cycling properties
+  if (root != NULL)
+  {
+    LOAD_PARAM_START_CYCLE(root, element);
+    {
+      LoadParam_CYCLE(element, "child", this, PNode, addChild)
+      .describe("adds a new Child to the current Node.");
+
+    }
+    LOAD_PARAM_END_CYCLE(element);
+  }
+}
+
+
+/**
+ *  init the pnode to a well definied state
+ *
+ * this function actualy only updates the PNode tree
+ */
+void PNode::init()
+{
+  /* just update all aboslute positions via timestep 0.001ms */
+  this->updateNode(0.001f);
+  this->updateNode(0.001f);
+}
+
+
+/**
+ * @brief set relative coordinates
+ * @param relCoord relative coordinates to its parent
+ *
+ *
+ * it is very importand, that you use this function, if you want to update the
+ * relCoordinates. If you don't use this, the PNode won't recognize, that something
+ * has changed and won't update the children Nodes.
+ */
+void PNode::setRelCoor (const Vector& relCoord)
+{
+  if (this->toCoordinate!= NULL)
+  {
+    delete this->toCoordinate;
+    this->toCoordinate = NULL;
+  }
+
+  this->relCoordinate = relCoord;
+  this->bRelCoorChanged = true;
+}
+
+/**
+ * @brief set relative coordinates
+ * @param x x-relative coordinates to its parent
+ * @param y y-relative coordinates to its parent
+ * @param z z-relative coordinates to its parent
+ * @see  void PNode::setRelCoor (const Vector& relCoord)
+ */
+void PNode::setRelCoor (float x, float y, float z)
+{
+  this->setRelCoor(Vector(x, y, z));
+}
+
+/**
+ * @brief sets a new relative position smoothely
+ * @param relCoordSoft the new Position to iterate to
+ * @param bias how fast to iterate to this position
+ */
+void PNode::setRelCoorSoft(const Vector& relCoordSoft, float bias)
+{
+  if (likely(this->toCoordinate == NULL))
+    this->toCoordinate = new Vector();
+
+  *this->toCoordinate = relCoordSoft;
+  this->bias = bias;
+}
+
+
+/**
+ * @brief set relative coordinates smoothely
+ * @param x x-relative coordinates to its parent
+ * @param y y-relative coordinates to its parent
+ * @param z z-relative coordinates to its parent
+ * @see  void PNode::setRelCoorSoft (const Vector&, float)
+ */
+void PNode::setRelCoorSoft (float x, float y, float z, float bias)
+{
+  this->setRelCoorSoft(Vector(x, y, z), bias);
+}
+
+
+/**
+ * @param absCoord set absolute coordinate
+ */
+void PNode::setAbsCoor (const Vector& absCoord)
+{
+  if (this->toCoordinate!= NULL)
+  {
+    delete this->toCoordinate;
+    this->toCoordinate = NULL;
+  }
+
+  if( likely(this->parentMode & PNODE_MOVEMENT))
+  {
+    /* if you have set the absolute coordinates this overrides all other changes */
+    if (likely(this->parent != NULL))
+      this->relCoordinate = absCoord - parent->getAbsCoor ();
+    else
+      this->relCoordinate = absCoord;
+  }
+  if( this->parentMode & PNODE_ROTATE_MOVEMENT)
+  {
+    if (likely(this->parent != NULL))
+      this->relCoordinate = absCoord - parent->getAbsCoor ();
+    else
+      this->relCoordinate = absCoord;
+  }
+
+  this->bRelCoorChanged = true;
+  //  this->absCoordinate = absCoord;
+}
+
+
+/**
+ * @param x x-coordinate.
+ * @param y y-coordinate.
+ * @param z z-coordinate.
+ * @see void PNode::setAbsCoor (const Vector& absCoord)
+ */
+void PNode::setAbsCoor(float x, float y, float z)
+{
+  this->setAbsCoor(Vector(x, y, z));
+}
+
+
+/**
+ * @param absCoord set absolute coordinate
+ * @todo check off
+ */
+void PNode::setAbsCoorSoft (const Vector& absCoordSoft, float bias)
+{
+  if (this->toCoordinate == NULL)
+    this->toCoordinate = new Vector;
+
+  if( likely(this->parentMode & PNODE_MOVEMENT))
+  {
+    /* if you have set the absolute coordinates this overrides all other changes */
+    if (likely(this->parent != NULL))
+      *this->toCoordinate = absCoordSoft - parent->getAbsCoor ();
+    else
+      *this->toCoordinate = absCoordSoft;
+  }
+  if( this->parentMode & PNODE_ROTATE_MOVEMENT)
+  {
+    if (likely(this->parent != NULL))
+      *this->toCoordinate = absCoordSoft - parent->getAbsCoor ();
+    else
+      *this->toCoordinate = absCoordSoft;
+  }
+}
+
+
+/**
+ * @brief shift coordinate relative
+ * @param shift shift vector
+ *
+ * this function shifts the current coordinates about the vector shift. this is
+ * usefull because from some place else you can:
+ * PNode* someNode = ...;
+ * Vector objectMovement = calculateShift();
+ * someNode->shiftCoor(objectMovement);
+ *
+ * this is the internal method of:
+ * PNode* someNode = ...;
+ * Vector objectMovement = calculateShift();
+ * Vector currentCoor = someNode->getRelCoor();
+ * Vector newCoor = currentCoor + objectMovement;
+ * someNode->setRelCoor(newCoor);
+ *
+ */
+void PNode::shiftCoor (const Vector& shift)
+{
+  this->relCoordinate += shift;
+  this->bRelCoorChanged = true;
+}
+
+
+/**
+ * @brief set relative direction
+ * @param relDir to its parent
+ */
+void PNode::setRelDir (const Quaternion& relDir)
+{
+  if (this->toDirection!= NULL)
+  {
+    delete this->toDirection;
+    this->toDirection = NULL;
+  }
+  this->relDirection = relDir;
+
+  this->bRelCoorChanged = true;
+}
+
+
+/**
+ * @see void PNode::setRelDir (const Quaternion& relDir)
+ * @param x the x direction
+ * @param y the y direction
+ * @param z the z direction
+ *
+ * main difference is, that here you give a directional vector, that will be translated into a Quaternion
+ */
+void PNode::setRelDir (float angle, float x, float y, float z)
+{
+  this->setRelDir(Quaternion(angle, Vector(x,y,z)));
+}
+
+
+/**
+ * @brief sets the Relative Direction of this node to its parent in a Smoothed way
+ * @param relDirSoft the direction to iterate to smoothely.
+ * @param bias how fast to iterate to the new Direction
+ */
+void PNode::setRelDirSoft(const Quaternion& relDirSoft, float bias)
+{
+  if (likely(this->toDirection == NULL))
+    this->toDirection = new Quaternion();
+
+  *this->toDirection = relDirSoft;
+  this->bias = bias;
+  this->bRelDirChanged = true;
+}
+
+
+/**
+ * @see void PNode::setRelDirSoft (const Quaternion& relDir)
+ * @param x the x direction
+ * @param y the y direction
+ * @param z the z direction
+ *
+ * main difference is, that here you give a directional vector, that will be translated into a Quaternion
+ */
+void PNode::setRelDirSoft(float angle, float x, float y, float z, float bias)
+{
+  this->setRelDirSoft(Quaternion(angle, Vector(x,y,z)), bias);
+}
+
+
+/**
+ * @brief sets the absolute direction
+ * @param absDir absolute coordinates
+ */
+void PNode::setAbsDir (const Quaternion& absDir)
+{
+  if (this->toDirection!= NULL)
+  {
+    delete this->toDirection;
+    this->toDirection = NULL;
+  }
+
+  if (likely(this->parent != NULL))
+    this->relDirection = absDir / this->parent->getAbsDir();
+  else
+    this->relDirection = absDir;
+
+  this->bRelDirChanged = true;
+}
+
+
+/**
+ * @see void PNode::setAbsDir (const Quaternion& relDir)
+ * @param x the x direction
+ * @param y the y direction
+ * @param z the z direction
+ *
+ * main difference is, that here you give a directional vector, that will be translated into a Quaternion
+ */
+void PNode::setAbsDir (float angle, float x, float y, float z)
+{
+  this->setAbsDir(Quaternion(angle, Vector(x,y,z)));
+}
+
+
+/**
+ * @brief sets the absolute direction
+ * @param absDir absolute coordinates
+ * @param bias how fast to iterator to the new Position
+ */
+void PNode::setAbsDirSoft (const Quaternion& absDirSoft, float bias)
+{
+  if (this->toDirection == NULL)
+    this->toDirection = new Quaternion();
+
+  if (likely(this->parent != NULL))
+    *this->toDirection = absDirSoft / this->parent->getAbsDir();
+  else
+    *this->toDirection = absDirSoft;
+
+  this->bias = bias;
+  this->bRelDirChanged = true;
+}
+
+
+/**
+ * @see void PNode::setAbsDir (const Quaternion& relDir)
+ * @param x the x direction
+ * @param y the y direction
+ * @param z the z direction
+ *
+ * main difference is, that here you give a directional vector, that will be translated into a Quaternion
+ */
+void PNode::setAbsDirSoft (float angle, float x, float y, float z, float bias)
+{
+  this->setAbsDirSoft(Quaternion(angle, Vector(x,y,z)), bias);
+}
+
+
+/**
+ * @brief shift Direction
+ * @param shift the direction around which to shift.
+ */
+void PNode::shiftDir (const Quaternion& shift)
+{
+  this->relDirection = this->relDirection * shift;
+  this->bRelDirChanged = true;
+}
+
+
+/**
+ * @brief adds a child and makes this node to a parent
+ * @param child child reference
+ * use this to add a child to this node.
+ */
+void PNode::addChild (PNode* child)
+{
+  if (unlikely(child->parent == this))
+    return;
+  if( likely(child->parent != NULL))
+    child->parent->eraseChild(child);
+  if (this->checkIntegrity(child))
+  {
+    child->parent = this;
+    if (unlikely(this != NULL))
+      this->children.push_back(child);
+    child->parentCoorChanged();
+
+    //     if(this->getUniqueID() == NET_UID_UNASSIGNED)
+    //     {
+    //       PRINTF(1)("Adding to an UNASSIGNED PNode - looking for next assigned Node\n");
+    //       PNode* node = this->seekNextAssignedPNode(this);
+    //       if( node == NULL)
+    //         PRINTF(1)("    Got NULL - Is this the NULLParent - uid %i\n", this->getUniqueID());
+    //       else
+    //         PRINTF(1)("    Found next assigned node: %i\n", node->getUniqueID());
+    //     }
+  }
+  else
+  {
+    PRINTF(1)("Tried to reparent to own child '%s::%s' to '%s::%s'.\n",
+              this->getClassCName(), this->getCName(), child->getClassCName(), child->getCName());
+    child->parent = NULL;
+    child->parentCoorChanged();
+  }
+}
+
+
+PNode* PNode::seekNextAssignedPNode(PNode* node) const
+{
+  PNode* tmpNode = node->parent;
+  printf("entering seek PNode loop for name: %s, uid: %i\n", node->getCName(), node->getUniqueID());
+  if(tmpNode)
+    printf("  @node name: %s, uid: %d\n", tmpNode->getCName(), tmpNode->getUniqueID());
+  while( tmpNode != NULL && tmpNode->getUniqueID() == NET_UID_UNASSIGNED)
+  {
+    printf("  @node name: %s, uid: %d\n", tmpNode->getCName(), tmpNode->getUniqueID());
+    tmpNode = tmpNode->parent;
+  }
+  printf("leaving PNode loop\n\n");
+
+  return tmpNode;
+}
+
+
+/**
+ * @see PNode::addChild(PNode* child);
+ * @param childName the name of the child to add to this PNode
+ */
+void PNode::addChild (const std::string& childName)
+{
+  PNode* childNode = PNode::objectList().getObject(childName);
+  //  PRINTF(0)("Adding the Child: %s to: %s\n", childName, this->getName());
+  //  assert( childNode != NULL );
+  if (childNode != NULL)
+  {
+    this->addChild(childNode);
+  }
+}
+
+
+/**
+ * @brief removes a child from the node
+ * @param child the child to remove from this pNode.
+ *
+ * Children from pNode will not be lost, they are Reparented by the rules of the ParentMode
+ */
+void PNode::removeChild (PNode* child)
+{
+  if (child != NULL)
+    child->removeNode();
+}
+
+
+/**
+ * !! PRIVATE FUNCTION
+ * @brief reparents a node (happens on Parents Node delete or remove and Flags are set.)
+ */
+void PNode::reparent()
+{
+  if (this->parentMode & PNODE_REPARENT_TO_NULL)
+    this->setParent((PNode*)NULL);
+  else if (this->parentMode & PNODE_REPARENT_TO_PARENTS_PARENT && this->parent != NULL)
+    this->setParent(this->parent->getParent());
+  else
+    this->setParent(PNode::getNullParent());
+}
+
+/**
+ * ereases child from the nodes children
+ * @param chuld the child to remove
+ */
+void PNode::eraseChild(PNode* child)
+{
+  std::list<PNode*>::iterator childRemover = std::find(this->children.begin(), this->children.end(), child);
+  if(childRemover != this->children.end())
+    this->children.erase(childRemover);
+}
+
+
+/**
+ * @brief remove this pnode from the tree and adds all following to NullParent
+ *
+ * this can be the case, if an entity in the world is being destroyed.
+ */
+void PNode::removeNode()
+{
+  std::list<PNode*>::iterator child = this->children.begin();
+  std::list<PNode*>::iterator reparenter;
+  while (child != this->children.end())
+  {
+    reparenter = child;
+    child++;
+    if (this->parentMode & PNODE_REPARENT_CHILDREN_ON_REMOVE ||
+        (*reparenter)->parentMode & PNODE_REPARENT_ON_PARENTS_REMOVE)
+    {
+      printf("TEST----------------%s ---- %s\n", this->getClassCName(), (*reparenter)->getClassCName());
+      (*reparenter)->reparent();
+      printf("REPARENTED TO: %s::%s\n",(*reparenter)->getParent()->getClassCName(),(*reparenter)->getParent()->getCName());
+    }
+  }
+  if (this->parent != NULL)
+  {
+    this->parent->eraseChild(this);
+    this->parent = NULL;
+  }
+}
+
+
+/**
+ * @see PNode::setParent(PNode* parent);
+ * @param parentName the name of the Parent to set to this PNode
+ */
+void PNode::setParent (const std::string& parentName)
+{
+  PNode* parentNode = PNode::objectList().getObject(parentName);
+  if (parentNode != NULL)
+    parentNode->addChild(this);
+  else
+    PRINTF(2)("Not Found PNode's (%s::%s) new Parent by Name: %s\n",
+        this->getClassCName(), this->getCName(), parentName.c_str());
+}
+
+
+/**
+ * @brief does the reparenting in a very smooth way
+ * @param parentNode the new Node to connect this node to.
+ * @param bias the speed to iterate to this new Positions
+ */
+void PNode::setParentSoft(PNode* parentNode, float bias)
+{
+  // return if the new parent and the old one match
+  if (this->parent == parentNode )
+    return;
+  if (parentNode == NULL)
+    parentNode = PNode::getNullParent();
+
+  // store the Valures to iterate to.
+  if (likely(this->toCoordinate == NULL))
+  {
+    this->toCoordinate = new Vector();
+    *this->toCoordinate = this->getRelCoor();
+  }
+  if (likely(this->toDirection == NULL))
+  {
+    this->toDirection = new Quaternion();
+    *this->toDirection = this->getRelDir();
+  }
+  this->bias = bias;
+
+  Vector tmpV = this->getAbsCoor();
+  Quaternion tmpQ = this->getAbsDir();
+
+  parentNode->addChild(this);
+
+  if (this->parentMode & PNODE_ROTATE_MOVEMENT && this->parent != NULL)
+    this->relCoordinate = this->parent->getAbsDir().inverse().apply(tmpV - this->parent->getAbsCoor());
+  else
+    this->relCoordinate = tmpV - parentNode->getAbsCoor();
+
+  this->relDirection = tmpQ / parentNode->getAbsDir();
+}
+
+
+/**
+ * @brief does the reparenting in a very smooth way
+ * @param parentName the name of the Parent to reconnect to
+ * @param bias the speed to iterate to this new Positions
+ */
+void PNode::setParentSoft(const std::string& parentName, float bias)
+{
+  PNode* parentNode = PNode::objectList().getObject(parentName);
+  if (parentNode != NULL)
+    this->setParentSoft(parentNode, bias);
+}
+
+/**
+ * @param parentMode sets the parentingMode of this Node
+ */
+void PNode::setParentMode(PARENT_MODE parentMode)
+{
+  this->parentMode = ((this->parentMode & 0xfff0) | parentMode);
+}
+
+/**
+ * @brief sets the mode of this parent manually
+ * @param parentMode a String representing this parentingMode
+ */
+void PNode::setParentMode (const std::string& parentingMode)
+{
+  this->setParentMode(PNode::stringToParentingMode(parentingMode));
+}
+
+/**
+ * @brief adds special mode Flags to this PNode
+ * @see PARENT_MODE
+ * @param nodeFlags a compsition of PARENT_MODE-flags, split by the '|' (or) operator.
+ */
+void PNode::addNodeFlags(unsigned short nodeFlags)
+{
+  this->parentMode |= nodeFlags;
+}
+
+/**
+ * @brief removes special mode Flags to this PNode
+ * @see PARENT_MODE
+ * @param nodeFlags a compsition of PARENT_MODE-flags, split by the '|' (or) operator.
+ */
+void PNode::removeNodeFlags(unsigned short nodeFlags)
+{
+  this->parentMode &= !nodeFlags;
+}
+
+/**
+ * @returns the NullParent (and if needed creates it)
+ */
+PNode* PNode::createNullParent()
+{
+  if (likely(PNode::nullParent == NULL))
+  {
+    PNode::nullParent = new NullParent();
+    //PNode::nullParent->registerObject(, CL_NULL_PARENT);
+    PNode::nullParent->setName("NullParent");
+    PNode::nullParent->setSynchronized(true);
+  }
+  return PNode::nullParent;
+}
+
+
+/**
+ * !! PRIVATE FUNCTION
+ * @brief checks the upward integrity (e.g if PNode is somewhere up the Node tree.)
+ * @param checkParent the Parent to check.
+ * @returns true if the integrity-check succeeds, false otherwise.
+ *
+ * If there is a second occurence of checkParent before NULL, then a loop could get
+ * into the Tree, and we do not want this.
+ */
+bool PNode::checkIntegrity(const PNode* checkParent) const
+{
+  const PNode* parent = this;
+  if (this == NULL)
+    return true;
+  while ( (parent = parent->getParent()) != NULL)
+    if (unlikely(parent == checkParent))
+      return false;
+  return true;
+}
+
+
+/**
+ * @brief updates the absCoordinate/absDirection
+ * @param dt The time passed since the last update
+ *
+ * this is used to go through the parent-tree to update all the absolute coordinates
+ * and directions. this update should be done by the engine, so you don't have to
+ * worry, normaly...
+ */
+void PNode::updateNode (float dt)
+{
+  if (!(this->parentMode & PNODE_STATIC_NODE))
+  {
+    if( likely(this->parent != NULL))
+    {
+      // movement for nodes with smoothMove enabled
+      if (unlikely(this->toCoordinate != NULL))
+      {
+        float shiftLen = fabsf(dt)*bias;
+        if (unlikely(shiftLen >= 1.0))
+          shiftLen = 1.0;
+        Vector moveVect = (*this->toCoordinate - this->relCoordinate) * shiftLen;
+        if (likely(moveVect.len() >= PNODE_ITERATION_DELTA))
+        {
+          this->shiftCoor(moveVect);
+        }
+        else
+        {
+          delete this->toCoordinate;
+          this->toCoordinate = NULL;
+          PRINTF(5)("SmoothMove of %s finished\n", this->getCName());
+        }
+      }
+      if (unlikely(this->toDirection != NULL))
+      {
+        float shiftLen = fabsf(dt)*bias;
+        if (unlikely (shiftLen >= 1.0))
+          shiftLen = 1.0;
+        //printf("%s::%s %f\n", this->getClassCName(), this->getName(), this->toStep );
+        Quaternion rotQuat = Quaternion::quatSlerp(this->relDirection,*this->toDirection, shiftLen);
+        if (this->relDirection.distance(rotQuat) > PNODE_ITERATION_DELTA)
+        {
+          this->relDirection = rotQuat;
+          this->bRelDirChanged = true;
+        }
+        else
+        {
+          delete this->toDirection;
+          this->toDirection = NULL;
+          PRINTF(5)("SmoothRotate of %s finished\n", this->getCName());
+          this->bRelDirChanged = true;
+        }
+      }
+
+      // MAIN UPDATE /////////////////////////////////////
+      this->lastAbsCoordinate = this->absCoordinate;
+
+      PRINTF(5)("PNode::update - '%s::%s' - (%f, %f, %f)\n", this->getClassCName(), this->getCName(),
+                this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
+
+
+      if(this->bRelDirChanged && this->parentMode & PNODE_LOCAL_ROTATE )
+      {
+        /* update the current absDirection - remember * means rotation around sth.*/
+        this->prevRelCoordinate = this->relCoordinate;
+        this->absDirection = parent->getAbsDir() * this->relDirection;
+      }
+
+      if(likely(this->bRelCoorChanged && this->parentMode & PNODE_MOVEMENT))
+      {
+        /* update the current absCoordinate */
+        this->prevRelCoordinate = this->relCoordinate;
+        this->absCoordinate = this->parent->getAbsCoor() + this->relCoordinate;
+      }
+      else if( this->parentMode & PNODE_ROTATE_MOVEMENT && (this->bRelCoorChanged || this->bRelDirChanged))
+      {
+        /* update the current absCoordinate */
+        this->prevRelCoordinate = this->relCoordinate;
+        this->absCoordinate = this->parent->getAbsCoor() + parent->getAbsDir().apply(this->relCoordinate);
+      }
+      /////////////////////////////////////////////////
+    }
+
+    else // Nodes without a Parent are handled faster :: MOST LIKELY THE NULLPARENT
+    {
+      PRINTF(4)("update ParentLess Node (%s::%s) - (%f, %f, %f)\n", this->getClassCName(), this->getCName(),
+                this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
+      if (this->bRelCoorChanged)
+      {
+        this->prevRelCoordinate = this->relCoordinate;
+        this->absCoordinate = this->relCoordinate;
+      }
+      if (this->bRelDirChanged)
+      {
+        this->prevRelDirection = this->relDirection;
+        this->absDirection = this->getAbsDir () * this->relDirection;
+      }
+    }
+  }
+
+  if(!this->children.empty() && (this->bActive || this->parentMode & PNODE_UPDATE_CHILDREN_IF_INACTIVE ))
+  {
+    std::list<PNode*>::iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child ++)
+    {
+      /* if this node has changed, make sure, that all children are updated also */
+      if( likely(this->bRelCoorChanged))
+        (*child)->parentCoorChanged ();
+      if( likely(this->bRelDirChanged))
+        (*child)->parentDirChanged ();
+
+      (*child)->updateNode(dt);
+    }
+  }
+  this->velocity = (this->absCoordinate - this->lastAbsCoordinate) / dt;
+  this->bRelCoorChanged = false;
+  this->bRelDirChanged = false;
+}
+
+
+
+
+
+/*************
+ * DEBUGGING *
+ *************/
+/**
+ * @brief counts total amount the children walking through the entire tree.
+ * @param nodes the counter
+ */
+void PNode::countChildNodes(int& nodes) const
+{
+  nodes++;
+  std::list<PNode*>::const_iterator child;
+  for (child = this->children.begin(); child != this->children.end(); child ++)
+    (*child)->countChildNodes(nodes);
+}
+
+
+/**
+ * @brief displays some information about this pNode
+ * @param depth The deph into which to debug the children of this PNode to.
+ * (0: all children will be debugged, 1: only this PNode, 2: this and direct children, ...)
+ * @param level !! INTERNAL !! The n-th level of the Node we draw (this is internal and only for nice output).
+ */
+void PNode::debugNode(unsigned int depth, unsigned int level) const
+{
+  for (unsigned int i = 0; i < level; i++)
+    PRINT(0)(" |");
+  if (this->children.size() > 0)
+    PRINT(0)(" +");
+  else
+    PRINT(0)(" -");
+
+  int childNodeCount = 0;
+  this->countChildNodes(childNodeCount);
+  printf("%p:", this);
+  PRINT(0)("PNode(%s::%s) - absCoord: (%0.2f, %0.2f, %0.2f), relCoord(%0.2f, %0.2f, %0.2f), direction(%0.2f, %0.2f, %0.2f) - %s - %d childs\n",
+           this->getClassCName(),
+           this->getCName(),
+           this->absCoordinate.x,
+           this->absCoordinate.y,
+           this->absCoordinate.z,
+           this->relCoordinate.x,
+           this->relCoordinate.y,
+           this->relCoordinate.z,
+           this->getAbsDirV().x,
+           this->getAbsDirV().y,
+           this->getAbsDirV().z,
+           this->parentingModeToString(parentMode),
+           childNodeCount);
+  if (depth >= 2 || depth == 0)
+  {
+    std::list<PNode*>::const_iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child ++)
+    {
+      if (depth == 0)
+        (*child)->debugNode(0, level + 1);
+      else
+        (*child)->debugNode(depth - 1, level +1);
+    }
+  }
+}
+
+/**
+ * @brief displays the PNode at its position with its rotation as a cube.
+ * @param  depth The deph into which to debug the children of this PNode to.
+ * (0: all children will be displayed, 1: only this PNode, 2: this and direct children, ...)
+ * @param size the Size of the Box to draw.
+ * @param color the color of the Box to display.
+ * @param level !! INTERNAL !! The n-th level of the Node we draw (this is internal and only for nice output).
+ */
+void PNode::debugDraw(unsigned int depth, float size, const Vector& color, unsigned int level) const
+{
+  // if this is the first Element we draw
+  if (level == 0)
+  {
+    glPushAttrib(GL_ENABLE_BIT); // save the Enable-attributes
+    glMatrixMode(GL_MODELVIEW);  // goto the ModelView Matrix
+
+    glDisable(GL_LIGHTING);      // disable lighting (we do not need them for just lighting)
+    glDisable(GL_BLEND);         // ''
+    glDisable(GL_TEXTURE_2D);    // ''
+    glDisable(GL_DEPTH_TEST);    // ''
+  }
+
+  glPushMatrix();                // repush the Matrix-stack
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  //  this->getAbsDir ().matrix (matrix);
+
+  /* rotate */
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  /* set the new Color */
+  glColor3f(color.x, color.y, color.z);
+  { /* draw a cube of size size */
+    glBegin(GL_LINE_STRIP);
+    glVertex3f(-.5*size, -.5*size,  -.5*size);
+    glVertex3f(+.5*size, -.5*size,  -.5*size);
+    glVertex3f(+.5*size, -.5*size,  +.5*size);
+    glVertex3f(-.5*size, -.5*size,  +.5*size);
+    glVertex3f(-.5*size, -.5*size,  -.5*size);
+    glEnd();
+    glBegin(GL_LINE_STRIP);
+    glVertex3f(-.5*size, +.5*size,  -.5*size);
+    glVertex3f(+.5*size, +.5*size,  -.5*size);
+    glVertex3f(+.5*size, +.5*size,  +.5*size);
+    glVertex3f(-.5*size, +.5*size,  +.5*size);
+    glVertex3f(-.5*size, +.5*size,  -.5*size);
+    glEnd();
+
+    glBegin(GL_LINES);
+    glVertex3f(-.5*size, -.5*size,  -.5*size);
+    glVertex3f(-.5*size, +.5*size,  -.5*size);
+    glVertex3f(+.5*size, -.5*size,  -.5*size);
+    glVertex3f(+.5*size, +.5*size,  -.5*size);
+    glVertex3f(+.5*size, -.5*size,  +.5*size);
+    glVertex3f(+.5*size, +.5*size,  +.5*size);
+    glVertex3f(-.5*size, -.5*size,  +.5*size);
+    glVertex3f(-.5*size, +.5*size,  +.5*size);
+    glEnd();
+  }
+  glPopMatrix();
+
+  if (depth >= 2 || depth == 0)
+  {
+    /* rotate the current color in HSV space around 20 degree */
+    Vector childColor =  Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(20,0,.0));
+    std::list<PNode*>::const_iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child ++)
+    {
+      // drawing the Dependency graph
+      if (this != PNode::getNullParent())
+      {
+        glBegin(GL_LINES);
+        glColor3f(color.x, color.y, color.z);
+        glVertex3f(this->getAbsCoor ().x,
+                   this->getAbsCoor ().y,
+                   this->getAbsCoor ().z);
+        glColor3f(childColor.x, childColor.y, childColor.z);
+        glVertex3f((*child)->getAbsCoor ().x,
+                   (*child)->getAbsCoor ().y,
+                   (*child)->getAbsCoor ().z);
+        glEnd();
+      }
+
+      /* if we want to draw the children too */
+      if (depth == 0) /* -> all of them */
+        (*child)->debugDraw(0, size, childColor, level+1);
+      else            /* -> only the Next one */
+        (*child)->debugDraw(depth - 1, size, childColor, level +1);
+    }
+  }
+  if (level == 0)
+    glPopAttrib(); /* pop the saved attributes back out */
+}
+
+
+
+/////////////////////
+// HELPER_FUCTIONS //
+/////////////////////
+
+/**
+ * @brief converts a parentingMode into a string that is the name of it
+ * @param parentingMode the ParentingMode to convert
+ * @return the converted string
+ */
+const char* PNode::parentingModeToString(int parentingMode)
+{
+  if (parentingMode == PNODE_LOCAL_ROTATE)
+    return "local-rotate";
+  else if (parentingMode == PNODE_ROTATE_MOVEMENT)
+    return "rotate-movement";
+  else if (parentingMode == PNODE_MOVEMENT)
+    return "movement";
+  else if (parentingMode == PNODE_ALL)
+    return "all";
+  else if (parentingMode == PNODE_ROTATE_AND_MOVE)
+    return "rotate-and-move";
+  else
+    return "all";
+}
+
+/**
+ * @brief converts a parenting-mode-string into a int
+ * @param parentingMode the string naming the parentingMode
+ * @return the int corresponding to the named parentingMode
+ */
+PARENT_MODE PNode::stringToParentingMode(const std::string& parentingMode)
+{
+  if (parentingMode == "local-rotate")
+    return (PNODE_LOCAL_ROTATE);
+  else  if (parentingMode == "rotate-movement")
+    return (PNODE_ROTATE_MOVEMENT);
+  else  if (parentingMode == "movement")
+    return (PNODE_MOVEMENT);
+  else  if (parentingMode == "all")
+    return (PNODE_ALL);
+  else  if (parentingMode == "rotate-and-move")
+    return (PNODE_ROTATE_AND_MOVE);
+  else
+    return PNODE_ALL;
+}
+
+/**
+ * handles changes in synchronizable variables
+ * @param id id's which changed
+ */
+void PNode::varChangeHandler( std::list< int > & id )
+{
+  Synchronizeable::varChangeHandler( id );
+
+  if ( std::find( id.begin(), id.end(), relCoordinate_handle ) != id.end() )
+  {
+    setRelCoor( relCoordinate_write );
+  }
+
+  if ( std::find( id.begin(), id.end(), relDirection_handle ) != id.end() )
+  {
+    setRelDir( relDirection_write );
+  }
+}
+
+ObjectListDefinition(NullParent);
+
+NullParent::NullParent()
+  : PNode(NULL, PNODE_PARENT_MODE_DEFAULT | PNODE_REPARENT_TO_NULL)
+{
+  this->registerObject(this, NullParent::_objectList);
+}
Index: branches/heathaze/src/lib/coord/p_node.h
===================================================================
--- branches/heathaze/src/lib/coord/p_node.h	(revision 9940)
+++ branches/heathaze/src/lib/coord/p_node.h	(revision 9940)
@@ -0,0 +1,271 @@
+/*!
+ * @file p_node.h
+ * @brief Definition of THE Parenting Node
+ *
+ *  parenting is how coordinates are handled in orxonox, meaning, that all coordinates
+ *  are representet relative to another parent node. this nodes build a parenting
+ *  tree of one-sided references (from up to down referenced).
+ *  Every node manages itself a list of childrens (of whos it is parent - easy...).
+ *
+ *  absCoordinate, absDirection have to be recalculated as soon as there was a change in
+ *  place or ortientation. this is only the case if
+ *  o bRelCoorChanged is true (so moved)
+ *  o bRelDirChanged is true (so changed)
+ *  this conditions make it cheaper to recalculate the tree (reduces redundant work).
+ */
+
+
+#ifndef _P_NODE_H
+#define _P_NODE_H
+
+#include "base_object.h"
+#include "synchronizeable.h"
+
+#include "vector.h"
+#include "quaternion.h"
+#include <list>
+
+// FORWARD DECLARATION
+class TiXmlElement;
+
+#define PNODE_ITERATION_DELTA    .001
+
+//! Parental linkage modes
+typedef enum
+{
+  // PARENTAL FOLLOWING
+  PNODE_LOCAL_ROTATE                   = 0x0001,    //!< Rotates all the children around their centers.
+  PNODE_ROTATE_MOVEMENT                = 0x0002,    //!< Moves all the children around the center of their parent, without the rotation around their own centers.
+
+  PNODE_MOVEMENT                       = 0x0004,    //!< Moves all children along with the parent.
+  // special linkage modes
+  PNODE_ALL                            = 0x0003,    //!< Moves all children around the center of their parent, and also rotates their centers
+  PNODE_ROTATE_AND_MOVE                = 0x0005,    //!< Rotates all children around their axis, and moves them as the Parent Moves, but does not rotate around the center of their parent.
+
+
+  // REPARENTING
+  PNODE_REPARENT_TO_NULL               = 0x0010,    //!< Reparents to the Null, if the Parent is Removed. Meaning the Node wont have a parent anymore.
+  PNODE_REPARENT_TO_PARENTS_PARENT     = 0x0020,    //!< Reparents the Node to the parents (old) parent it the parent gets removed.
+  /////////////////////////////////////////////     //  ELSE: Reparents to the NullParent.
+  PNODE_REPARENT_DELETE_CHILDREN       = 0x0040,    //!< Deletes the Children of the node when This Node is Removed. (Use with care).
+  /// FIXME
+  PNODE_REPARENT_KEEP_POSITION         = 0x0080,    //!< Tries to keep the Position if the Node is reparented.
+
+
+  // DELETION
+  PNODE_PROHIBIT_CHILD_DELETE          = 0x0100,    //!< Prohibits the Children from being deleted if this Node gets deleted.
+  PNODE_PROHIBIT_DELETE_WITH_PARENT    = 0x0200,    //!< Prohibits the Node to be deleted if the Parent is. Child will be reparented according to the Repaenting-Rules
+  PNODE_REPARENT_CHILDREN_ON_REMOVE    = 0x0400,    //!< Reparents the Children of the Node if the Node gets Removed.
+  PNODE_REPARENT_ON_PARENTS_REMOVE     = 0x0800,    //!< The Node gets Reparented if its Parent gets removed. Child will be reparented according to the Reparenting-Rules.
+
+  // VISIBILITY/ACTIVITY
+  PNODE_HIDE_CHILDREN_IF_HIDDEN        = 0x1000,    //!< Prohibits the Children from being drawn if this node isn't visible. (used for Draw))
+  PNODE_HIDE_IF_PARENT_HIDDEN          = 0x2000,    //!< Prohibits the node from being drawn if the Parent is invisible.
+  PNODE_UPDATE_CHILDREN_IF_INACTIVE    = 0x4000,    //!< Updates the Children of this Node even if the Parent is Inactive (note if this's parent is inactive children won't be updated.)
+  PNODE_STATIC_NODE                    = 0x8000,    //!< Used for nodes that do not have any moving children, and that do not move.
+
+} PARENT_MODE;
+
+//! The default mode of the translation-binding.
+#define PNODE_PARENT_MODE_DEFAULT PNODE_ALL | \
+                                  PNODE_REPARENT_KEEP_POSITION
+
+
+//! Patent Node is a Engine to calculate the position of an Object in respect to the position of its parent.
+class PNode : virtual public BaseObject, virtual public Synchronizeable
+{
+  ObjectListDeclaration(PNode);
+
+public:
+  PNode (PNode* parent = PNode::getNullParent(), long nodeFlags = PNODE_PARENT_MODE_DEFAULT);
+  virtual ~PNode ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void init();
+
+  // ACTIVATION //
+  inline void activateNode() { this->bActive = this->bRelCoorChanged = this->bRelDirChanged = true; };
+  inline void deactivateNode() { this->bActive = false; };
+  inline bool getNodeActiveState() { return this->bActive; };
+
+  // POSITION //
+  void setRelCoor (const Vector& relCoord);
+  void setRelCoor (float x, float y, float z);
+  void setRelCoorSoft(const Vector& relCoordSoft, float bias = 1.0);
+  void setRelCoorSoft(float x, float y, float z, float bias = 1.0);
+  /** @returns the relative position */
+  inline const Vector& getRelCoor () const { return this->prevRelCoordinate; };
+  /** @returns the Relative Coordinate Destination */
+inline const Vector& getRelCoorSoft2D() const { return (this->toCoordinate)? *this->toCoordinate : this->relCoordinate; };
+  void setAbsCoor (const Vector& absCoord);
+  void setAbsCoor (float x, float y, float z);
+  void setAbsCoorSoft(const Vector& absCoordSoft, float bias = 1.0);
+  void setAbsCoorSoft(float x, float y, float z, float bias = 1.0);
+  /** @returns the absolute position */
+  inline const Vector& getAbsCoor () const { return this->absCoordinate; };
+  /** @returns the absolute X coordinate. */
+  inline float getAbsCoorX() { return this->absCoordinate.x; };
+  /** @returns the absolute Y Coordinate */
+  inline float getAbsCoorY() { return this->absCoordinate.y; };
+  /** @returns the absolute Z Coordinate */
+  inline float getAbsCoorZ() { return this->absCoordinate.z; };
+
+  /** @returns the absolute position */
+  inline const Vector& getLastAbsCoor () const { return this->lastAbsCoordinate; };
+
+  void shiftCoor (const Vector& shift);
+  void shiftCoor (float x, float y, float z) { this->shiftCoor(Vector(x, y, z)); };
+
+  // SPEED //
+  /** @returns the Speed of the Node */
+  inline float getSpeed() const { return this->velocity.len(); };
+  /** @returns the Velocity of the Node */
+  inline const Vector& getVelocity() const { return this->velocity; };
+
+
+  // ROTATION //
+  void setRelDir (const Quaternion& relDir);
+  void setRelDir (float angle, float x, float y, float z);
+  void setRelDirSoft(const Quaternion& relDirSoft, float bias = 1.0);
+  void setRelDirSoft(float angle, float x, float y, float z, float bias = 1.0);
+  /** @returns the relative Direction */
+  inline const Quaternion& getRelDir () const { return this->prevRelDirection; };
+  /** @returns the Relative Directional Destination */
+inline const Quaternion& getRelDirSoft2D() const { return (this->toDirection)? *this->toDirection : this->relDirection; };
+  /** @returns a Vector pointing into the relative Direction */
+  inline Vector getRelDirV() const { return this->prevRelDirection.apply(Vector(0,1,0)); };
+  void setAbsDir (const Quaternion& absDir);
+  void setAbsDir (float angle, float x, float y, float z);
+  void setAbsDirSoft(const Quaternion& absDirSoft, float bias = 1.0);
+  void setAbsDirSoft(float angle, float x, float y, float z, float bias = 1.0);
+  void shiftDir (const Quaternion& shift);
+  /** @returns the absolute Direction */
+  inline const Quaternion& getAbsDir () const { return this->absDirection; };
+  /** @returns a Vector pointing into the absolute Direction */
+  inline Vector getAbsDirV() const { return this->absDirection.apply(Vector(0,1,0)); };
+  /** @returns A Vector pointing into the forward direction (X) of the Node */
+  inline Vector getAbsDirX() const { return this->absDirection.apply(Vector(1,0,0)); };
+  /** @returns A Vector pointing into the upward direction (Y) of the Node */
+  inline Vector getAbsDirY() const { return this->absDirection.apply(Vector(0,1,0)); };
+  /** @returns A Vector pointing into the right direction (Z) of the Node */
+  inline Vector getAbsDirZ() const { return this->absDirection.apply(Vector(0,0,1)); };
+
+
+  // PARENTING //
+  void addChild (PNode* child);
+  void addChild (const std::string& childName);
+  void removeChild (PNode* child);
+  void removeNode();
+
+  PNode* seekNextAssignedPNode(PNode* node) const;
+
+  /** @param parent the new parent of this node */
+  inline void setParent (PNode* parent) { parent->addChild(this); };
+  void setParent (const std::string& parentName);
+  /** @returns the parent of this PNode */
+  inline PNode* getParent () const { return this->parent; };
+  /** @returns the List of Children of this PNode */
+  const std::list<PNode*>& getNodesChildren() const { return this->children; };
+
+  void setParentSoft(PNode* parentNode, float bias = 1.0);
+  void setParentSoft(const std::string& parentName, float bias = 1.0);
+
+  // PARENTING_MODE AND OTHER FLAGS //
+  void setParentMode (PARENT_MODE parentMode);
+  void setParentMode (const std::string& parentingMode);
+  /** @returns the Parenting mode of this node */
+  int getParentMode() const { return 0x000f & this->parentMode; };
+
+  void addNodeFlags(unsigned short nodeFlags);
+  void removeNodeFlags(unsigned short nodeFlags);
+
+  /** @returns the NullParent, the (main) ROOT of the PNode Tree. If it does not yet exist, it will be created. */
+static PNode* getNullParent()  { return (PNode::nullParent != NULL) ? PNode::nullParent : PNode::createNullParent(); };
+
+  // UPDATING //
+  void updateNode (float dt);
+
+  // DEBUG //
+  void countChildNodes(int& nodes) const;
+  void debugNode (unsigned int depth = 1, unsigned int level = 0) const;
+  void debugDraw(unsigned int depth = 1, float size = 1.0, const Vector& color = Vector(1, 0, 0), unsigned int level = 0) const;
+
+  // HELPER_FUNCTIONS //
+  static const char* parentingModeToString(int parentingMode);
+  static PARENT_MODE stringToParentingMode(const std::string& parentingMode);
+  float distance(const PNode* node) const { return (this->getAbsCoor() - node->getAbsCoor()).len(); };
+
+private:
+  /** tells the child that the parent's Coordinate has changed */
+  inline void parentCoorChanged () { this->bRelCoorChanged = true; }
+  /** tells the child that the parent's Direction has changed */
+  inline void parentDirChanged () { this->bRelDirChanged = true; }
+public:
+  /** @returns the last calculated coordinate */
+  inline Vector getLastAbsCoor() { return this->lastAbsCoordinate; }
+private:
+  static PNode* createNullParent();
+  void reparent();
+  bool checkIntegrity(const PNode* checkParent) const;
+  void eraseChild(PNode* child);
+
+private:
+  bool               bRelCoorChanged;    //!< If Relative Coordinate has changed since last time we checked
+  bool               bRelDirChanged;     //!< If Relative Direction has changed since last time we checked
+
+  Vector             relCoordinate;      //!< coordinates relative to the parent
+  Vector             absCoordinate;      //!< absolute coordinates in the world ( from (0,0,0) )
+  Quaternion         relDirection;       //!< direction relative to the parent
+  Quaternion         absDirection;       //!< absolute direvtion in the world ( from (0,0,1) )
+
+  Vector             prevRelCoordinate;  //!< The last Relative Coordinate from the last update-Cycle.
+  Vector             lastAbsCoordinate;  //!< this is used for speedcalculation, it stores the last coordinate
+  Quaternion         prevRelDirection;   //!< The last Relative Direciton from the last update-Cycle.
+  //  Quaternion         lastAbsDirection;
+
+  Vector             velocity;           //!< Saves the velocity.
+
+  Vector*            toCoordinate;       //!< a position to which to iterate. (This is used in conjunction with setParentSoft.and set*CoorSoft)
+  Quaternion*        toDirection;        //!< a direction to which to iterate. (This is used in conjunction with setParentSoft and set*DirSoft)
+  float              bias;               //!< how fast to iterate to the given position (default is 1)
+
+  PNode*             parent;             //!< a pointer to the parent node.
+  std::list<PNode*>  children;           //!< list of the children of this PNode.
+
+  bool               bActive;            //!< If the Node is Active (for cutting off the rest of the tree in update).
+  unsigned short     parentMode;         //!< the mode of the binding
+
+
+  static PNode*      nullParent;         //!< The ROOT of the main PNode Tree.
+
+private:
+  float coorx;
+  float coory;
+  float coorz;
+
+  float rotw;
+  float rotx;
+  float roty;
+  float rotz;
+
+private:
+  int relCoordinate_handle;
+  int relDirection_handle;
+  Vector relCoordinate_write;
+  Quaternion relDirection_write;
+
+public:
+  virtual void varChangeHandler( std::list<int> & id );
+};
+
+// NULL_PARENT //
+class NullParent : public PNode
+{
+  ObjectListDeclaration(NullParent);
+  friend class PNode;
+  NullParent();
+};
+
+
+#endif /* _P_NODE_H */
Index: branches/heathaze/src/lib/data/data_tank.h
===================================================================
--- branches/heathaze/src/lib/data/data_tank.h	(revision 9940)
+++ branches/heathaze/src/lib/data/data_tank.h	(revision 9940)
@@ -0,0 +1,33 @@
+/*!
+ * @file data_tank.h
+ *  container for all data and data loadings. Its absolutily abstract and therefore generic.
+ *  if there is something to load, this class will serve as a good base class since it
+ *  gives you a basic structure for data loading
+ */
+
+#ifndef _DATA_TANK_H
+#define _DATA_TANK_H
+
+
+#include "base_object.h"
+#include "error.h"
+
+
+//! The DataTank
+class DataTank : public BaseObject
+{
+
+  public:
+    DataTank() {}
+    virtual ~DataTank() {}
+
+    /** initializes the DataTank to be able to load the data */
+    virtual ErrorMessage init() { return ErrorMessage(); }
+    /** loads the data into the DataTank @param root is the xml root parameter for for loadParams() connection */
+    virtual ErrorMessage loadData(const TiXmlElement* root = NULL) { return ErrorMessage(); }
+    /** unloads the data again from the DataTank */
+    virtual ErrorMessage unloadData() { return ErrorMessage(); }
+};
+
+
+#endif /* _DATA_TANK_H */
Index: branches/heathaze/src/lib/event/Makefile.am
===================================================================
--- branches/heathaze/src/lib/event/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/event/Makefile.am	(revision 9940)
@@ -0,0 +1,18 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXevent.a 
+
+libORXevent_a_SOURCES = event_handler.cc \
+			event_listener.cc \
+			key_mapper.cc \
+			key_names.cc
+
+
+noinst_HEADERS = event.h \
+		 event_handler.h \
+		 event_listener.h \
+		 key_mapper.h \
+		 key_names.h \
+		 event_def.h
+
Index: branches/heathaze/src/lib/event/event.h
===================================================================
--- branches/heathaze/src/lib/event/event.h	(revision 9940)
+++ branches/heathaze/src/lib/event/event.h	(revision 9940)
@@ -0,0 +1,41 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+
+   Benjamin Grauer: added SDL_ResizeEvent resize (for the GraphicsEngine)
+*/
+
+/*!
+ * @file event.h
+ * an abstract event
+ */
+
+#ifndef _EVENT_H
+#define _EVENT_H
+
+#include "sdlincl.h"
+
+//! An abstract event class
+struct Event {
+  int      type;                        //!< the type field
+  bool     bPressed;                    //!< is true, if the button/mouse was pressed, false if released
+
+  Uint16   x;                           //!< x coordinate
+  Uint16   y;                           //!< y coordinate
+  Sint16   xRel;                        //!< relative x movement to last point
+  Sint16   yRel;                        //!< relative y movement to last point
+
+  SDL_ResizeEvent resize;
+};
+
+#endif /* _EVENT_H */
Index: branches/heathaze/src/lib/event/event_def.h
===================================================================
--- branches/heathaze/src/lib/event/event_def.h	(revision 9940)
+++ branches/heathaze/src/lib/event/event_def.h	(revision 9940)
@@ -0,0 +1,54 @@
+/*!
+ * @file event_def.h
+ * some central definitions
+*/
+
+#ifndef _EVENT_DEF_H
+#define _EVENT_DEF_H
+
+#ifdef HAVE_SDL_H
+ #include "SDL_keysym.h"
+#else
+ #include "SDL/SDL_keysym.h"
+#endif
+
+//! these are the extended event types, that are not included in SDL_keysym
+typedef enum {
+  EV_MOUSE_BUTTON_LEFT           = SDLK_LAST + 1,
+  EV_MOUSE_BUTTON_MIDDLE,
+  EV_MOUSE_BUTTON_RIGHT,
+  EV_MOUSE_BUTTON_WHEELUP,
+  EV_MOUSE_BUTTON_WHEELDOWN,
+  EV_MOUSE_MOTION,
+  EV_JOY_AXIS_MOTION,
+  EV_JOY_BALL_MOTION,
+  EV_JOY_HAT_MOTION,
+  EV_JOY_BUTTON,
+
+  EV_WINDOW_FOCUS,
+  EV_VIDEO_RESIZE,
+
+  EV_LEAVE_STATE,
+  EV_MAIN_QUIT,
+
+  EV_UNKNOWN,
+
+  EV_NUMBER
+} extEventTyes;
+
+
+//! this is an enumeration of all states of the event_handler/game
+typedef enum
+{
+  ES_NULL         = -1,
+  ES_GAME         = 0,       //!< the state during the game plays
+  ES_GAME_MENU    = 1,       //!< state when the menu is called during game
+  ES_MENU         = 2,       //!< orxonox menu state
+  ES_SHELL        = 3,       //!< if we are in shell Modus
+  
+  ES_ALL          = 4,       //!< you want to register events for all states
+
+  ESTATE_NUMBER   = 5        //!< the number of states < Namespace-problem in windows.
+} elState;
+
+#endif /* _EVENT_DEF_H */
Index: branches/heathaze/src/lib/event/event_handler.cc
===================================================================
--- branches/heathaze/src/lib/event/event_handler.cc	(revision 9940)
+++ branches/heathaze/src/lib/event/event_handler.cc	(revision 9940)
@@ -0,0 +1,574 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_EVENT
+
+#include "event_handler.h"
+
+#include "event_listener.h"
+#include "event.h"
+#include "key_mapper.h"
+#include "key_names.h"
+
+#include "compiler.h"
+#include "debug.h"
+
+#include <algorithm>
+
+
+ObjectListDefinition(EventHandler);
+/**
+ * @brief standard constructor
+ */
+EventHandler::EventHandler ()
+{
+  this->registerObject(this, EventHandler::_objectList);
+  this->setName("EventHandler");
+
+  SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+  SDL_InitSubSystem(SDL_INIT_EVENTTHREAD);
+  SDL_SetEventFilter(EventHandler::eventFilter);
+
+
+  /* now initialize them all to zero */
+  for (unsigned int i = 0; i < ESTATE_NUMBER; i++)
+    this->bUNICODE[i] = false;
+  this->grabEvents(false);
+
+  this->state = ES_GAME;
+  this->eventsGrabbed = false;
+
+  this->keyState = SDL_GetKeyState(NULL);
+}
+
+
+/**
+ * @brief the singleton reference to this class
+*/
+EventHandler* EventHandler::singletonRef = NULL;
+
+
+/**
+ * @brief standard deconstructor
+ */
+EventHandler::~EventHandler ()
+{
+  bool forgotToUnsubscribe = false;
+
+  for(int i = 0; i < ESTATE_NUMBER; ++i)
+  {
+    for(int j = 0; j < EV_NUMBER; ++j)
+    {
+      if(!this->listeners[i][j].empty())
+      {
+        if (!forgotToUnsubscribe)
+        {
+          forgotToUnsubscribe = true;
+          PRINTF(2)("forgot to unsubscribe an EventListener!\n");// %s!\n", this->listeners[i][j]->getName());
+        }
+      }
+    }
+  }
+
+  if (forgotToUnsubscribe)
+  {
+    PRINTF(2)("Listing still subscribed EventListeners\n");
+    PRINTF(2)("========================================\n");
+    this->debug();
+    PRINTF(2)("========================================\n");
+  }
+
+  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+
+  EventHandler::singletonRef = NULL;
+}
+
+
+/**
+ * @brief initializes the event handler
+ *
+ * this has to be called before the use of the event handler
+*/
+void EventHandler::init()
+{
+  this->keyMapper.loadKeyBindings();
+}
+
+/**
+ * @param state: to which the event handler shall change
+ */
+void EventHandler::setState(elState state)
+{
+  if (state == this->state)
+    return;
+
+  PRINTF(4)("Switching to State %s\n", EventHandler::ELStateToString(state).c_str());
+
+  /// When Changing the State, all the keys will be released.
+  /// This is done by sending each eventListener, that still
+  /// has an Event subscribed, a Release Event.
+  int keyCount;
+  Uint8 * pressedKeys = SDL_GetKeyState(&keyCount);
+  for (unsigned int i = 0; i < SDLK_LAST; i++)
+  {
+    if (pressedKeys[i])
+    {
+      Event ev;
+      ev.bPressed = false;
+      ev.type = i;
+      if (unlikely(this->bUNICODE[this->state]))
+        ev.x = i;
+      this->dispachEvent(this->state, ev );
+    }
+  }
+
+  // switching to the new State.
+  elState oldState = this->state;
+  this->state = state;
+
+  // in the End the Corresponding handler will be notified.
+  Event stateSwitchEvent;
+  stateSwitchEvent.type = EV_LEAVE_STATE;
+  this->dispachEvent(oldState, stateSwitchEvent);
+
+  SDL_EnableUNICODE(this->bUNICODE[state]);
+};
+
+
+/**
+ * @brief pushes the current State in the State-stack, and selects state
+ * @param state the new State to set
+ */
+void EventHandler::pushState(elState state)
+{
+  if (likely(state != ES_NULL && state != ES_ALL ))
+  {
+    this->stateStack.push(this->state);
+    this->setState(state);
+  }
+  else
+  {
+    PRINTF(2)("unable to push State\n");
+  }
+}
+
+/**
+ * @brief this removes the topmost stack-entry and select the underlying one
+ * @returns the next stack-entry
+ */
+elState EventHandler::popState()
+{
+  if (stateStack.empty())
+    return ES_NULL;
+  elState state =  (elState)stateStack.top();
+  this->stateStack.pop();
+  if (state == ES_NULL)
+  {
+    PRINTF(2)("No more states availiable. (unable to pop state)\n");
+    return ES_NULL;
+  }
+  else
+  {
+    this->setState(state);
+    return state;
+  }
+}
+
+
+/**
+ * @brief subscribe to an event
+ * @param el: the event listener that wants to subscribe itself, the listener that will be called when the evetn occures
+ * @param state: for which the listener wants to receive events
+ * @param eventType: the event type that wants to be listened for.
+
+   This is one of the most important function of the EventHandler. If you would like to subscribe for more
+   than one state, you have to subscribe for each state again. If you want to subscribe for all states, use
+   state = ES_ALL, which will subscribe your listener for all states together.
+ */
+void EventHandler::subscribe(EventListener* el, elState state, int eventType)
+{
+  PRINTF(4)("Subscribing event type: %i\n", eventType);
+  if( state == ES_ALL )
+  {
+    for(unsigned int i = 0; i < ESTATE_NUMBER; i++)
+      if (!this->findListener( NULL, (elState)i, eventType, el))
+        this->listeners[i][eventType].push_back(el);
+      else
+      {
+        PRINTF(2)("%s::%s was already subscribed to state %d event %d\n", el->getClassCName(), el->getCName(), i, eventType);
+      }
+  }
+  else
+  {
+    if (!this->findListener( NULL, state, eventType, el))
+      this->listeners[state][eventType].push_back(el);
+    else
+    {
+      PRINTF(2)("%s::%s was already subscribed to state %d event %d\n", el->getClassCName(), el->getCName(), state, eventType);
+    }
+  }
+}
+
+
+/**
+ * @brief unsubscribe from the EventHandler
+ * @param state: the stat in which it has been subscribed
+ * @param eventType: the event, that shall be unsubscribed
+ *
+ * if you want to unsubscribe an event listener from all subscribed events, just use the
+ * unsubscribe(EventListener* el, elState state) function
+ */
+void EventHandler::unsubscribe(EventListener* el, elState state, int eventType)
+{
+  PRINTF(4)("Unsubscribing event type nr: %i\n", eventType);
+  if (state == ES_ALL)
+    for (unsigned int i = 0; i < ESTATE_NUMBER; i++)
+    {
+      std::vector<EventListener*>::iterator listener;
+      if (this->findListener(&listener, (elState)i, eventType, el))
+        this->listeners[i][eventType].erase(listener);
+    }
+  else
+  {
+    std::vector<EventListener*>::iterator listener;
+    if (this->findListener(&listener, state, eventType, el))
+      this->listeners[state][eventType].erase(listener);
+  }
+}
+
+
+/**
+ * @brief unsubscribe all events from a specific listener
+ * @param el: the listener that wants to unsubscribe itself
+ * @param state: the state in which the events shall be unsubscribed
+ */
+void EventHandler::unsubscribe(EventListener* el, elState state)
+{
+  assert( el != NULL && state < ESTATE_NUMBER && state != ES_NULL);
+  if( state == ES_ALL)
+  {
+    for(unsigned int i = 0; i < ESTATE_NUMBER; i++)
+    {
+      for(unsigned int j = 0; j < EV_NUMBER; j++)
+      {
+        std::vector<EventListener*>::iterator deller = std::find (this->listeners[i][j].begin(), this->listeners[i][j].end(), el);
+        if( deller != this->listeners[i][j].end())
+          this->listeners[i][j].erase(deller);
+      }
+    }
+  }
+  else
+  {
+    for(int j = 0; j < EV_NUMBER; j++)
+    {
+      std::vector<EventListener*>::iterator deller =  std::find (this->listeners[state][j].begin(), this->listeners[state][j].end(), el);
+      if( deller != this->listeners[state][j].end())
+        this->listeners[state][j].erase(deller);
+    }
+  }
+}
+
+/**
+ * @brief returns true if at state and eventType there is something subscribed.
+ * @param state the state to check in.
+ * @param eventType the eventtype to check.
+ * @returns true if a event is subscibed.
+ */
+bool EventHandler::isSubscribed(elState state, int eventType)
+{
+  return(listeners[state][eventType].empty()) ? false : true;
+};
+
+
+
+/**
+ * @brief flush all registered events
+ * @param state: a specific state
+*/
+void EventHandler::flush(elState state)
+{
+  if( state == ES_ALL)
+  {
+    for(int i = 0; i < ESTATE_NUMBER; ++i)
+    {
+      for(int j = 0; j < EV_NUMBER; ++j)
+      {
+        this->listeners[i][j].clear();
+      }
+    }
+  }
+  else
+  {
+    for(int j = 0; j < EV_NUMBER; ++j)
+    {
+      this->listeners[state][j].clear();
+    }
+  }
+}
+
+
+bool EventHandler::findListener(std::vector<EventListener*>::iterator* it, elState state, int eventType, EventListener* listener)
+{
+  std::vector<EventListener*>::iterator findIterator =
+    std::find(this->listeners[state][eventType].begin(), this->listeners[state][eventType].end(), listener);
+  if (it != NULL)
+    *it = findIterator;
+  return ( findIterator != this->listeners[state][eventType].end());
+
+}
+
+
+
+/**
+ * @brief if the unicode characters should be recorded.
+ * @param state the State in whitch to set the new Value.
+ * @param enableUNICODE: enabled, or disabled.
+ */
+void EventHandler::withUNICODE(elState state, bool enableUNICODE)
+{
+  this->bUNICODE[state] = enableUNICODE;
+  if (this->state == state)
+    SDL_EnableUNICODE(enableUNICODE);
+}
+
+/**
+ * @brief grabs InputEvents.
+ * @param grabEvents if the Events should be grabbed(true) or released(false)
+ */
+void EventHandler::grabEvents(bool grabEvents)
+{
+  this->eventsGrabbed = grabEvents;
+  if(!grabEvents)
+  {
+    SDL_ShowCursor(SDL_ENABLE);
+    SDL_WM_GrabInput(SDL_GRAB_OFF);
+  }
+  else
+  {
+     SDL_WM_GrabInput(SDL_GRAB_ON);
+     SDL_ShowCursor(SDL_DISABLE);
+  }
+}
+
+
+
+/**
+ * @brief core function of event handler: receives all events from SDL
+ *
+ * The event from the SDL framework are collected here and distributed to all listeners.
+ */
+void EventHandler::process() const
+{
+  SDL_Event event;
+  Event ev;
+  while( SDL_PollEvent (&event))
+  {
+    switch( event.type)
+    {
+      case SDL_KEYDOWN:
+        ev.bPressed = true;
+        ev.type = event.key.keysym.sym;
+        if (unlikely(this->bUNICODE[this->state]))
+          ev.x = event.key.keysym.unicode;
+        break;
+      case SDL_KEYUP:
+        ev.bPressed = false;
+        ev.type = event.key.keysym.sym;
+        if (unlikely(this->bUNICODE[this->state]))
+          ev.x = event.key.keysym.unicode;
+        break;
+      case SDL_MOUSEMOTION:
+        ev.bPressed = false;
+        ev.type = EV_MOUSE_MOTION;
+        ev.x = event.motion.x;
+        ev.y = event.motion.y;
+        ev.xRel = event.motion.xrel;
+        ev.yRel = event.motion.yrel;
+        break;
+      case SDL_MOUSEBUTTONUP:
+        ev.bPressed = false;
+        ev.x = event.motion.x;
+        ev.y = event.motion.y;
+        ev.type = event.button.button + SDLK_LAST;
+        break;
+      case SDL_MOUSEBUTTONDOWN:
+        ev.bPressed = true;
+        ev.x = event.motion.x;
+        ev.y = event.motion.y;
+        ev.type = event.button.button + SDLK_LAST;
+        break;
+      case SDL_JOYAXISMOTION:
+        ev.bPressed = false;
+        ev.type = EV_JOY_AXIS_MOTION;
+        break;
+      case SDL_JOYBALLMOTION:
+        ev.bPressed = false;
+        ev.type = EV_JOY_BALL_MOTION;
+        break;
+      case SDL_JOYHATMOTION:
+        ev.bPressed = false;
+        ev.type = EV_JOY_HAT_MOTION;
+        break;
+      case SDL_JOYBUTTONDOWN:
+        ev.bPressed = true;
+        ev.type = EV_JOY_BUTTON;
+        break;
+      case SDL_JOYBUTTONUP:
+        ev.bPressed = true;
+        ev.type = EV_JOY_BUTTON;
+        break;
+      case SDL_ACTIVEEVENT:
+        ev.type = EV_WINDOW_FOCUS;
+        ev.bPressed = (event.active.gain != 0);
+        break;
+      case SDL_VIDEORESIZE:
+        ev.resize = event.resize;
+        ev.type = EV_VIDEO_RESIZE;
+        break;
+      case SDL_QUIT:
+        ev.type = EV_MAIN_QUIT;
+        break;
+      default:
+        ev.type = EV_UNKNOWN;
+        break;
+    }
+    this->dispachEvent(this->state, ev);
+  }
+}
+
+
+/**
+ * @brief dispaches an Event.
+ * @param event the Event to dispach.
+ */
+void EventHandler::dispachEvent(elState state, const Event& event) const
+{
+  /* small debug routine: shows all events dispatched by the event handler */
+  PRINT(4)("\n==========================| EventHandler::process () |===\n");
+  PRINT(4)("=  Got Event nr %i, for state %i\n", event.type, state);
+
+  /// setting a temporary state in case of an EventListener's process changes the state.
+  for (unsigned int i = 0; i < this->listeners[state][event.type].size(); i++)
+  {
+    PRINT(4)("=  Event dispatcher msg: This event has been consumed\n");
+    PRINT(4)("=  Got Event nr %i, for state %i (%d registered) to %s::%s(%p)\n",
+      event.type,
+      i, state,
+      this->listeners[state][event.type][i]->getClassCName(),
+      this->listeners[state][event.type][i]->getCName(),
+      this->listeners[state][event.type][i]);
+    PRINT(4)("=======================================================\n");
+    this->listeners[state][event.type][i]->process(event);
+  }
+  /*    else
+  {
+        PRINT(4)("=  Event dispatcher msg: This event has NOT been consumed\n");
+        PRINT(4)("=======================================================\n");
+  }*/
+}
+
+
+
+/**
+ * @brief An eventFilter.
+ * @param event the Event to be filtered.
+ * @returns 0 on filtered Event. 1 Otherwise.
+ */
+int EventHandler::eventFilter(const SDL_Event *event)
+{
+  if (likely(EventHandler::getInstance()->eventsGrabbed))
+  {
+    if (event->type == SDL_KEYDOWN &&  event->key.keysym.sym == SDLK_TAB && SDL_GetKeyState(NULL)[SDLK_LALT])
+    {
+      PRINTF(3)("Not sending event to the WindowManager\n");
+      EventHandler::getInstance()->grabEvents(false);
+      return 0;
+    }
+  }
+  else
+  {
+    if (event->type == SDL_MOUSEBUTTONDOWN)
+    {
+      EventHandler::getInstance()->grabEvents( true);
+      return 1;
+    }
+  }
+
+  return 1;
+}
+
+
+int EventHandler::releaseMouse(void* p)
+{
+  SDL_ShowCursor(SDL_ENABLE);
+  SDL_WM_GrabInput(SDL_GRAB_OFF);
+  return 0;
+}
+
+
+/**
+ * @param state The State to get the Name of.
+ * @returns the Name of the State.
+ */
+const std::string& EventHandler::ELStateToString(elState state)
+{
+  if (state < ESTATE_NUMBER)
+    return EventHandler::stateNames[state];
+  else
+    return EventHandler::stateNames[5];
+}
+
+/**
+ * @param stateName the Name of the State to retrieve.
+ * @return the State given by the name
+ */
+elState EventHandler::StringToELState(const std::string& stateName)
+{
+  for (unsigned int i = 0 ; i < ESTATE_NUMBER; i++)
+    if (stateName == EventHandler::stateNames[i])
+      return (elState)i;
+  return ES_NULL;
+}
+
+const std::string  EventHandler::stateNames[] =
+{
+  "game",
+  "game_menu",
+  "menu",
+  "shell",
+  "all",
+  "unknown",
+};
+
+
+/**
+ * @brief outputs some nice information about the EventHandler
+ */
+void EventHandler::debug() const
+{
+  PRINT(0)("===============================\n");
+  PRINT(0)(" EventHandle Debug Information \n");
+  PRINT(0)("===============================\n");
+  for(int i = 0; i < ESTATE_NUMBER; ++i)
+  {
+    for(int j = 0; j < EV_NUMBER; ++j)
+      for (unsigned int evl = 0; evl < this->listeners[i][j].size(); evl++)
+        PRINT(0)("Event %s(%d) of State %s(%d) subscribed to %s (%p)\n",
+        EVToKeyName(j).c_str(), j,
+        ELStateToString((elState)i).c_str(), i,
+        this->listeners[i][j][evl]->getCName(), this->listeners[i][j][evl]);
+  }
+  PRINT(0)("============================EH=\n");
+}
Index: branches/heathaze/src/lib/event/event_handler.h
===================================================================
--- branches/heathaze/src/lib/event/event_handler.h	(revision 9940)
+++ branches/heathaze/src/lib/event/event_handler.h	(revision 9940)
@@ -0,0 +1,85 @@
+/*!
+ * @file event_handler.h
+ * Definition of the EventHandler
+ *
+ */
+
+#ifndef _EVENT_HANDLER_H
+#define _EVENT_HANDLER_H
+
+#include "base_object.h"
+#include "key_mapper.h"
+#include "event_def.h"
+#include "event.h"
+#include <stack>
+#include <vector>
+
+// FORWARD DECLARATION
+class EventListener;
+
+//! The one Event Handler from Orxonox
+class EventHandler : public BaseObject
+{
+  ObjectListDeclaration(EventHandler);
+public:
+  virtual ~EventHandler();
+  /** @returns a Pointer to the only object of this Class */
+  inline static EventHandler* getInstance() { if (!singletonRef) singletonRef = new EventHandler();  return singletonRef; };
+  void init();
+
+  void setState(elState state);
+  /** @returns the current state */
+inline elState getState() const { return this->state; };
+
+  void pushState(elState state);
+  elState popState();
+
+  void subscribe(EventListener* el, elState state, int eventType);
+  void unsubscribe(EventListener* el, elState state, int eventType);
+  void unsubscribe(EventListener* el, elState state = ES_ALL);
+  void flush(elState state);
+  /** @returns true, if the @param state has @param eventType subscribed?? */
+  bool isSubscribed(elState state, int eventType);
+
+  /** @param key the key to check @returns true if key is pressed */
+  bool isPressed(SDLKey key) const { return this->keyState[key]; };
+
+  void withUNICODE(elState state, bool enableUNICODE);
+  void grabEvents(bool grabEvents);
+  bool grabbedEvents() const { return this->eventsGrabbed; };
+
+  void process() const;
+  void dispachEvent(elState state, const Event& event) const;
+
+  static int eventFilter(const SDL_Event *event);
+  void debug() const;
+
+  static const std::string& ELStateToString(elState state);
+  static elState StringToELState(const std::string& stateName);
+
+  static int releaseMouse(void* p);
+
+private:
+  EventHandler();
+
+  bool findListener(std::vector<EventListener*>::iterator* it, elState state, int eventType, EventListener* listener);
+
+public:
+  static const std::string     stateNames[];
+
+private:
+  static EventHandler*         singletonRef;                    //!< the singleton reference
+
+  std::vector<EventListener*>  listeners[ESTATE_NUMBER][EV_NUMBER]; //!< a list of registered listeners.
+  elState                      state;                           //!< the state of the event handlder.
+  std::stack<short>            stateStack;                      //!< a stack for the States we are in.
+  KeyMapper                    keyMapper;                       //!< reference to the key mapper.
+
+  bool                         bUNICODE[ESTATE_NUMBER];             //!< If unicode should be enabled.
+  bool                         eventsGrabbed;                   //!< If the events should be grabbed
+
+  Uint8*                       keyState;
+};
+
+
+#endif /* _EVENT_HANDLER_H */
Index: branches/heathaze/src/lib/event/event_listener.cc
===================================================================
--- branches/heathaze/src/lib/event/event_listener.cc	(revision 9940)
+++ branches/heathaze/src/lib/event/event_listener.cc	(revision 9940)
@@ -0,0 +1,73 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_EVENT
+
+#include "event_listener.h"
+#include "event_handler.h"
+
+ObjectListDefinition(EventListener);
+/**
+ * @brief standard constructor
+ */
+EventListener::EventListener ()
+{
+  this->registerObject(this, EventListener::_objectList);
+}
+
+
+/**
+ * @brief standard deconstructor
+ *
+ * Unsubscribes all Subscribed Events, of this EventListener.
+ */
+EventListener::~EventListener ()
+{
+  /* unsubscribes itself from the event listener */
+  EventHandler::getInstance()->unsubscribe(this, ES_ALL);
+}
+
+bool EventListener::isEventSubscribed(elState state, int eventType) const
+{
+  return EventHandler::getInstance()->isSubscribed(state, eventType);
+}
+
+
+/**
+ * @brief Subscribes an Events to this EventListener.
+ * @param state the state to subscribe to.
+ * @param eventType the Type of Event to subscribe.
+ */
+void EventListener::subscribeEvent(elState state, int eventType)
+{
+  EventHandler::getInstance()->subscribe(this, state, eventType);
+}
+
+
+/**
+ * @brief Unubscribes an Event from this EventListener.
+ * @param state the state to unsubscribe from.
+ * @param eventType the Type of Event to unsubscribe.
+ */
+void EventListener::unsubscribeEvent(elState state, int eventType)
+{
+  EventHandler::getInstance()->unsubscribe(this, state, eventType);
+}
+
+void EventListener::unsubscribeEvents(elState state)
+{
+  EventHandler::getInstance()->unsubscribe(this, state);
+}
+
Index: branches/heathaze/src/lib/event/event_listener.h
===================================================================
--- branches/heathaze/src/lib/event/event_listener.h	(revision 9940)
+++ branches/heathaze/src/lib/event/event_listener.h	(revision 9940)
@@ -0,0 +1,35 @@
+/*!
+ * @file event_listener.h
+ *  Definition of an event listener base class
+*/
+
+#ifndef _EVENT_LISTENER_H
+#define _EVENT_LISTENER_H
+
+#include "base_object.h"
+#include "event_def.h"
+#include "event.h"
+
+//! A class for event listener
+class EventListener : virtual public BaseObject
+{
+  ObjectListDeclaration(EventListener);
+public:
+  EventListener();
+  virtual ~EventListener();
+
+  bool isEventSubscribed(elState state, int eventType) const;
+
+  void subscribeEvent(elState state, int eventType);
+  void unsubscribeEvent(elState state, int eventType);
+  void unsubscribeEvents(elState state = ES_ALL);
+
+  /**
+   * @brief abstract function that processes events from the handler
+   * @param event: the event
+   */
+  virtual void process(const Event &event) = 0;
+
+};
+
+#endif /* _EVENT_LISTENER_H */
Index: branches/heathaze/src/lib/event/key_mapper.cc
===================================================================
--- branches/heathaze/src/lib/event/key_mapper.cc	(revision 9940)
+++ branches/heathaze/src/lib/event/key_mapper.cc	(revision 9940)
@@ -0,0 +1,261 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Christian Meyer
+
+   This code was inspired by the command_node.cc code from Christian Meyer in revision
+   4386 and earlier.
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_EVENT
+
+#include "key_mapper.h"
+
+#include "event_def.h"
+
+#include "globals.h"
+#include "parser/ini_parser/ini_parser.h"
+#include "parser/preferences/preferences.h"
+#include "key_names.h"
+#include "event_def.h"
+#include "debug.h"
+
+
+
+ObjectListDefinition(KeyMapper);
+
+/* initialize all variables to a reasonable value*/
+int KeyMapper::PEV_FORWARD           = EV_UNKNOWN;
+int KeyMapper::PEV_BACKWARD          = EV_UNKNOWN;
+int KeyMapper::PEV_LEFT              = EV_UNKNOWN;
+int KeyMapper::PEV_RIGHT             = EV_UNKNOWN;
+int KeyMapper::PEV_UP                = EV_UNKNOWN;
+int KeyMapper::PEV_DOWN              = EV_UNKNOWN;
+int KeyMapper::PEV_ROLL_LEFT         = EV_UNKNOWN;
+int KeyMapper::PEV_ROLL_RIGHT        = EV_UNKNOWN;
+int KeyMapper::PEV_STRAFE_LEFT       = EV_UNKNOWN;
+int KeyMapper::PEV_STRAFE_RIGHT      = EV_UNKNOWN;
+int KeyMapper::PEV_JUMP              = EV_UNKNOWN;
+
+int KeyMapper::PEV_FIRE1             = EV_UNKNOWN;
+int KeyMapper::PEV_FIRE2             = EV_UNKNOWN;
+int KeyMapper::PEV_PREVIOUS_WEAPON   = EV_UNKNOWN;
+int KeyMapper::PEV_NEXT_WEAPON       = EV_UNKNOWN;
+
+int KeyMapper::PEV_CHANGE_SHIP       = EV_UNKNOWN;
+
+int KeyMapper::PEV_VIEW0             = EV_UNKNOWN;
+int KeyMapper::PEV_VIEW1             = EV_UNKNOWN;
+int KeyMapper::PEV_VIEW2             = EV_UNKNOWN;
+int KeyMapper::PEV_VIEW3             = EV_UNKNOWN;
+int KeyMapper::PEV_VIEW4             = EV_UNKNOWN;
+int KeyMapper::PEV_VIEW5             = EV_UNKNOWN;
+
+int KeyMapper::PEV_NEXT_WORLD        = EV_UNKNOWN;
+int KeyMapper::PEV_PREVIOUS_WORLD    = EV_UNKNOWN;
+
+int KeyMapper::PEV_PAUSE             = EV_UNKNOWN;
+int KeyMapper::PEV_QUIT              = EV_UNKNOWN;
+
+
+
+//! this is the mapping array from names to ids: enter all orxonox.conf keys here
+/** @todo use globals.h for this.... everything is done there for those Options,
+ * and you do not have to care about The namings, as they might change
+ */
+KeyMapper::KeyMapping KeyMapper::map[] = {
+      {&KeyMapper::PEV_FORWARD,              CONFIG_NAME_PLAYER_FORWARD,         SDLK_w},
+      {&KeyMapper::PEV_BACKWARD,             CONFIG_NAME_PLAYER_BACKWARD,        SDLK_s},
+      {&KeyMapper::PEV_UP,                   CONFIG_NAME_PLAYER_UP,              SDLK_r},
+      {&KeyMapper::PEV_DOWN,                 CONFIG_NAME_PLAYER_DOWN,            SDLK_f},
+      {&KeyMapper::PEV_LEFT,                 CONFIG_NAME_PLAYER_LEFT,            SDLK_a},
+      {&KeyMapper::PEV_RIGHT,                CONFIG_NAME_PLAYER_RIGHT,           SDLK_d},
+      {&KeyMapper::PEV_ROLL_RIGHT,           CONFIG_NAME_PLAYER_ROLL_LEFT,       SDLK_z},
+      {&KeyMapper::PEV_ROLL_LEFT,            CONFIG_NAME_PLAYER_ROLL_RIGHT,      SDLK_c},
+      {&KeyMapper::PEV_STRAFE_LEFT,          "StrafeLeft",                       SDLK_q},
+      {&KeyMapper::PEV_STRAFE_RIGHT,         "StrafeRight",                      SDLK_e},
+      {&KeyMapper::PEV_JUMP,                 "Jump",                             SDLK_SPACE},
+
+      {&KeyMapper::PEV_FIRE1,                CONFIG_NAME_PLAYER_FIRE,            EV_MOUSE_BUTTON_LEFT},
+      {&KeyMapper::PEV_FIRE2,                "Fire2",                            EV_MOUSE_BUTTON_RIGHT},
+      {&KeyMapper::PEV_NEXT_WEAPON,          CONFIG_NAME_PLAYER_NEXT_WEAPON,     EV_MOUSE_BUTTON_WHEELUP},
+      {&KeyMapper::PEV_PREVIOUS_WEAPON,      CONFIG_NAME_PLAYER_PREV_WEAPON,     EV_MOUSE_BUTTON_WHEELDOWN},
+
+      {&KeyMapper::PEV_CHANGE_SHIP,          CONFIG_NAME_PLAYER_CHANGE_SHIP,     SDLK_g},
+
+
+      {&KeyMapper::PEV_VIEW0,                CONFIG_NAME_VIEW0,                  SDLK_1},
+      {&KeyMapper::PEV_VIEW1,                CONFIG_NAME_VIEW1,                  SDLK_2},
+      {&KeyMapper::PEV_VIEW2,                CONFIG_NAME_VIEW2,                  SDLK_3},
+      {&KeyMapper::PEV_VIEW3,                CONFIG_NAME_VIEW3,                  SDLK_4},
+      {&KeyMapper::PEV_VIEW4,                CONFIG_NAME_VIEW4,                  SDLK_5},
+      {&KeyMapper::PEV_VIEW5,                CONFIG_NAME_VIEW5,                  SDLK_6},
+
+      {&KeyMapper::PEV_NEXT_WORLD,           CONFIG_NAME_NEXT_WORLD,             SDLK_x},
+      {&KeyMapper::PEV_PREVIOUS_WORLD,       CONFIG_NAME_PREV_WORLD,             SDLK_z},
+
+      {&KeyMapper::PEV_PAUSE,                CONFIG_NAME_PAUSE,                  SDLK_p},
+      {&KeyMapper::PEV_QUIT,                 CONFIG_NAME_QUIT,                   SDLK_ESCAPE},
+      {NULL, "", 0}
+    };
+
+
+
+/**
+ *  standard constructor
+*/
+KeyMapper::KeyMapper ()
+{
+  this->registerObject(this, KeyMapper::_objectList);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+KeyMapper::~KeyMapper ()
+{}
+
+
+/**
+ *  loads new key bindings from a file
+ * @param filename: The path and name of the file to load the bindings from
+*/
+void KeyMapper::loadKeyBindings (const std::string& fileName)
+{
+  IniParser parser(fileName);
+  this->loadKeyBindings(&parser);
+}
+
+void KeyMapper::loadKeyBindings(IniParser* iniParser)
+{
+  IniParser::Section* section = iniParser->getSection (CONFIG_SECTION_CONTROL);
+  if( section == NULL)
+  {
+    PRINTF(1)("Could not find key bindings " CONFIG_SECTION_CONTROL "\n");
+    return;
+  }
+  int* index;
+
+
+  for(IniParser::Entry::iterator entry = section->begin();
+      entry != section->end();
+      ++entry)
+  {
+    PRINTF(3)("Keys: Parsing %s, %s now.\n", (*entry).name().c_str(), (*entry).value().c_str());
+    // map the name to an sdl index
+    index = nameToIndex ((*entry).value());
+    // map the index to a internal name
+    this->mapKeys((*entry).name(), index);
+  }
+
+
+  // PARSE MISC SECTION
+  //   if( !iniParser->getSection (CONFIG_SECTION_MISC_KEYS))
+  //   {
+  //     PRINTF(1)("Could not find key bindings" CONFIG_SECTION_MISC_KEYS "\n");
+  //     return;
+  //   }
+  //
+  //   iniParser->firstVar();
+  //   while( iniParser->getCurrentName() != "" )
+  //   {
+  //     PRINTF(3)("MISC: Parsing %s, %s now.\n", iniParser->getCurrentName(), iniParser->getCurrentValue());
+  //     index = nameToIndex (iniParser->getCurrentValue());
+  //     this->mapKeys(iniParser->getCurrentName(), index);
+  //     iniParser->nextVar();
+  //   }
+}
+
+void KeyMapper::loadKeyBindings()
+{
+  if( !Preferences::getInstance()->sectionExists(CONFIG_SECTION_CONTROL))
+  {
+    PRINTF(1)("Could not find key bindings " CONFIG_SECTION_CONTROL "\n");
+    return;
+  }
+  int* index;
+
+  std::list<std::string> keys = Preferences::getInstance()->listKeys(CONFIG_SECTION_CONTROL);
+  for ( std::list<std::string>::const_iterator it = keys.begin(); it!=keys.end(); it++ )
+  {
+    PRINTF(3)("Keys: Parsing %s, %s now.\n", it->c_str(), Preferences::getInstance()->getString(CONFIG_SECTION_CONTROL, *it, "").c_str());
+    // map the name to an sdl index
+    index = nameToIndex (Preferences::getInstance()->getString(CONFIG_SECTION_CONTROL, *it, ""));
+    // map the index to a internal name
+    this->mapKeys(*it, index);
+  }
+}
+
+/**
+ *  this function looks up name to key index
+ * @param the name of the button
+*/
+int* KeyMapper::nameToIndex (const std::string& name)
+{
+  coord[0] = -1;
+  coord[1] = -1;
+  int c;
+  if( (c = keynameToSDLK (name)) != -1)
+  {
+    coord[1] = c;
+    coord[0] = 0;
+  }
+  if( (c = buttonnameToSDLB (name)) != -1)
+  {
+    coord[1] = c;
+    coord[0] = 1;
+  }
+  return coord;
+}
+
+
+/**
+ *  the function maps name to key ids
+ * @param name of the key
+ * @param id of the key
+*/
+void KeyMapper::mapKeys(const std::string& name, int* index)
+{
+  for( int i = 0; map[i].pValue != NULL; ++i )
+  {
+    if( name == map[i].pName)
+    {
+      if( index[0] == 0)
+      {
+        *map[i].pValue = index[1];
+        PRINTF(4)("Mapping %s to '%s' (id %i)\n", name.c_str(), SDLKToKeyname(index[1]).c_str(), index[1]);
+        break;
+      }
+      else
+      {
+        *map[i].pValue = index[1];
+        PRINTF(4)("Mapping %s to '%s' (id %i)\n", name.c_str(), SDLBToButtonname(index[1]).c_str(), index[1]);
+        break;
+      }
+    }
+  }
+}
+
+
+/**
+ *  this function gives some debug information about the key mapper class
+*/
+void KeyMapper::debug()
+{
+  PRINT(0)("\n==========================| KeyMapper::debug() |===\n");
+  for(int i = 0; map[i].pValue != NULL; ++i)
+  {
+    PRINT(0)("%s = %i\n",map[i].pName.c_str(), *map[i].pValue);
+  }
+  PRINT(0)("=======================================================\n");
+}
Index: branches/heathaze/src/lib/event/key_mapper.h
===================================================================
--- branches/heathaze/src/lib/event/key_mapper.h	(revision 9940)
+++ branches/heathaze/src/lib/event/key_mapper.h	(revision 9940)
@@ -0,0 +1,88 @@
+/*!
+ * @file key_mapper.h
+  *  a construct to map player defined keys to SDL keys
+
+*/
+
+#ifndef _KEY_MAPPER_H
+#define _KEY_MAPPER_H
+
+
+#include "base_object.h"
+#include <string>
+class IniParser;
+
+//! The map class functionalities
+class KeyMapper : public BaseObject
+{
+  ObjectListDeclaration(KeyMapper);
+public:
+  //! A mapping from key-name to key-id
+  typedef struct KeyMapping
+  {
+    int*              pValue;
+    const std::string pName;
+    int               defaultValue;
+  };
+
+public:
+  KeyMapper();
+  virtual ~KeyMapper();
+
+  void loadKeyBindings(const std::string& fileName );
+  void loadKeyBindings();
+  void loadKeyBindings(IniParser* iniParser);
+
+  static const KeyMapping* getKeyMapping() { return KeyMapper::map; };
+
+  void debug();
+
+private:
+  int* nameToIndex (const std::string& name);
+  void mapKeys(const std::string& name, int* index);
+
+public:
+  static int PEV_FORWARD;           //!< forward button
+  static int PEV_BACKWARD;          //!< backward buttton
+  static int PEV_LEFT;              //!< left button
+  static int PEV_RIGHT;             //!< right button
+  static int PEV_UP;                //!< up button
+  static int PEV_DOWN;              //!< down button
+
+  static int PEV_ROLL_LEFT;         //!< rolls left
+  static int PEV_ROLL_RIGHT;        //!< rolls right
+
+  static int PEV_STRAFE_LEFT;       //!< strafe left button
+  static int PEV_STRAFE_RIGHT;      //!< strafe right button
+
+  static int PEV_JUMP;              //!< jump
+
+  static int PEV_FIRE1;             //!< fire button 1
+  static int PEV_FIRE2;             //!< fire button 2
+  static int PEV_PREVIOUS_WEAPON;   //!< prev weapon button
+  static int PEV_NEXT_WEAPON;       //!< next weapon button
+
+  static int PEV_CHANGE_SHIP;       //!< The button to change the Ship.
+
+  static int PEV_VIEW0;             //!< view 0 button
+  static int PEV_VIEW1;             //!< view 1 button
+  static int PEV_VIEW2;             //!< view 2 button
+  static int PEV_VIEW3;             //!< view 3 button
+  static int PEV_VIEW4;             //!< view 4 button
+  static int PEV_VIEW5;             //!< view 5 button
+
+  static int PEV_NEXT_WORLD;        //!< next world button
+  static int PEV_PREVIOUS_WORLD;    //!< prev world button
+
+  static int PEV_PAUSE;             //!< pause button
+  static int PEV_QUIT;              //!< quit button
+
+private:
+  int                coord[2];      //!< temp place to save variables in nameToIndex() function
+  static KeyMapping  map[];         //!< The KeyMapping that maps strings to ID's and Vice Versa
+};
+
+
+
+
+#endif /* _KEY_MAPPER_H */
Index: branches/heathaze/src/lib/event/key_names.cc
===================================================================
--- branches/heathaze/src/lib/event/key_names.cc	(revision 9940)
+++ branches/heathaze/src/lib/event/key_names.cc	(revision 9940)
@@ -0,0 +1,332 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+#include "key_names.h"
+#include "event_def.h"
+
+std::string EVToKeyName(int key)
+{
+  std::string name = SDLBToButtonname( key );
+  if (name != "UNKNOWN")
+    return name;
+  else
+    return SDLKToKeyname( key );
+}
+
+int KeyNameToEV(const std::string& keyName)
+{
+  int key = buttonnameToSDLB( keyName );
+  if (key != -1)
+    return key;
+  else
+    return keynameToSDLK( keyName );
+}
+
+
+int buttonnameToSDLB(const std::string& name)
+{
+        if((name == "BUTTON_LEFT")) return EV_MOUSE_BUTTON_LEFT;
+        if((name == "BUTTON_MIDDLE")) return EV_MOUSE_BUTTON_MIDDLE;
+        if((name == "BUTTON_RIGHT")) return EV_MOUSE_BUTTON_RIGHT;
+        if((name == "BUTTON_WHEELUP")) return EV_MOUSE_BUTTON_WHEELUP;
+        if((name == "BUTTON_WHEELDOWN")) return EV_MOUSE_BUTTON_WHEELDOWN;
+        return -1;
+}
+
+std::string SDLBToButtonname( int button)
+{
+        if( button == EV_MOUSE_BUTTON_LEFT) return "BUTTON_LEFT";
+        if( button == EV_MOUSE_BUTTON_MIDDLE) return "BUTTON_MIDDLE";
+        if( button == EV_MOUSE_BUTTON_RIGHT) return "BUTTON_RIGHT";
+        if( button == EV_MOUSE_BUTTON_WHEELUP) return "BUTTON_WHEELUP";
+        if( button == EV_MOUSE_BUTTON_WHEELDOWN) return "BUTTON_WHEELDOWN";
+        return "UNKNOWN";
+}
+
+int keynameToSDLK(const std::string& name)
+{
+        if((name == "BACKSPACE")) return SDLK_BACKSPACE;
+        if((name == "TAB")) return SDLK_TAB;
+        if((name == "CLEAR")) return SDLK_CLEAR;
+        if((name == "RETURN")) return SDLK_RETURN;
+        if((name == "ESCAPE")) return SDLK_ESCAPE;
+        if((name == "SPACE")) return SDLK_SPACE;
+        if((name == "EXCLAIM")) return SDLK_EXCLAIM;
+        if((name == "QUOTEDBL")) return SDLK_QUOTEDBL;
+        if((name == "HASH")) return SDLK_HASH;
+        if((name == "PAUSE")) return SDLK_PAUSE;
+        if((name == "DOLLAR")) return SDLK_DOLLAR;
+        if((name == "AMPERSAND")) return SDLK_AMPERSAND;
+        if((name == "QUOTE")) return SDLK_QUOTE;
+        if((name == "LEFTPAREN")) return SDLK_LEFTPAREN;
+        if((name == "RIGHTPAREN")) return SDLK_RIGHTPAREN;
+        if((name == "ASTERISK")) return SDLK_ASTERISK;
+        if((name == "PLUS")) return SDLK_PLUS;
+        if((name == "COMMA")) return SDLK_COMMA;
+        if((name == "MINUS")) return SDLK_MINUS;
+        if((name == "PERIOD")) return SDLK_PERIOD;
+        if((name == "SLASH")) return SDLK_SLASH;
+        if((name == "0")) return SDLK_0;
+        if((name == "1")) return SDLK_1;
+        if((name == "2")) return SDLK_2;
+        if((name == "3")) return SDLK_3;
+        if((name == "4")) return SDLK_4;
+        if((name == "5")) return SDLK_5;
+        if((name == "6")) return SDLK_6;
+        if((name == "7")) return SDLK_7;
+        if((name == "8")) return SDLK_8;
+        if((name == "9")) return SDLK_9;
+        if((name == "COLON")) return SDLK_COLON;
+        if((name == "SEMICOLON")) return SDLK_SEMICOLON;
+        if((name == "LESS")) return SDLK_LESS;
+        if((name == "EQUALS")) return SDLK_EQUALS;
+        if((name == "GREATER")) return SDLK_GREATER;
+        if((name == "QUESTION")) return SDLK_QUESTION;
+        if((name == "AT")) return SDLK_AT;
+        if((name == "LEFTBRACKET")) return SDLK_LEFTBRACKET;
+        if((name == "BACKSLASH")) return SDLK_BACKSLASH;
+        if((name == "RIGHTBRACKET")) return SDLK_RIGHTBRACKET;
+        if((name == "CARET")) return SDLK_CARET;
+        if((name == "UNDERSCORE")) return SDLK_UNDERSCORE;
+        if((name == "BACKQUOTE")) return SDLK_BACKQUOTE;
+        if((name == "a")) return SDLK_a;
+        if((name == "b")) return SDLK_b;
+        if((name == "c")) return SDLK_c;
+        if((name == "d")) return SDLK_d;
+        if((name == "e")) return SDLK_e;
+        if((name == "f")) return SDLK_f;
+        if((name == "g")) return SDLK_g;
+        if((name == "h")) return SDLK_h;
+        if((name == "i")) return SDLK_i;
+        if((name == "j")) return SDLK_j;
+        if((name == "k")) return SDLK_k;
+        if((name == "l")) return SDLK_l;
+        if((name == "m")) return SDLK_m;
+        if((name == "n")) return SDLK_n;
+        if((name == "o")) return SDLK_o;
+        if((name == "p")) return SDLK_p;
+        if((name == "q")) return SDLK_q;
+        if((name == "r")) return SDLK_r;
+        if((name == "s")) return SDLK_s;
+        if((name == "t")) return SDLK_t;
+        if((name == "u")) return SDLK_u;
+        if((name == "v")) return SDLK_v;
+        if((name == "w")) return SDLK_w;
+        if((name == "x")) return SDLK_x;
+        if((name == "y")) return SDLK_y;
+        if((name == "z")) return SDLK_z;
+        if((name == "DELETE")) return SDLK_DELETE;
+        if((name == "KP0")) return SDLK_KP0;
+        if((name == "KP1")) return SDLK_KP1;
+        if((name == "KP2")) return SDLK_KP2;
+        if((name == "KP3")) return SDLK_KP3;
+        if((name == "KP4")) return SDLK_KP4;
+        if((name == "KP5")) return SDLK_KP5;
+        if((name == "KP6")) return SDLK_KP6;
+        if((name == "KP7")) return SDLK_KP7;
+        if((name == "KP8")) return SDLK_KP8;
+        if((name == "KP9")) return SDLK_KP9;
+        if((name == "KP_PERIOD")) return SDLK_KP_PERIOD;
+        if((name == "KP_DIVIDE")) return SDLK_KP_DIVIDE;
+        if((name == "KP_MULTIPLY")) return SDLK_KP_MULTIPLY;
+        if((name == "KP_MINUS")) return SDLK_KP_MINUS;
+        if((name == "KP_PLUS")) return SDLK_KP_PLUS;
+        if((name == "KP_ENTER")) return SDLK_KP_ENTER;
+        if((name == "KP_EQUALS")) return SDLK_KP_EQUALS;
+        if((name == "UP")) return SDLK_UP;
+        if((name == "DOWN")) return SDLK_DOWN;
+        if((name == "RIGHT")) return SDLK_RIGHT;
+        if((name == "LEFT")) return SDLK_LEFT;
+        if((name == "INSERT")) return SDLK_INSERT;
+        if((name == "HOME")) return SDLK_HOME;
+        if((name == "END")) return SDLK_END;
+        if((name == "PAGEUP")) return SDLK_PAGEUP;
+        if((name == "PAGEDOWN")) return SDLK_PAGEDOWN;
+        if((name == "F1")) return SDLK_F1;
+        if((name == "F2")) return SDLK_F2;
+        if((name == "F3")) return SDLK_F3;
+        if((name == "F4")) return SDLK_F4;
+        if((name == "F5")) return SDLK_F5;
+        if((name == "F6")) return SDLK_F6;
+        if((name == "F7")) return SDLK_F7;
+        if((name == "F8")) return SDLK_F8;
+        if((name == "F9")) return SDLK_F9;
+        if((name == "F10")) return SDLK_F10;
+        if((name == "F11")) return SDLK_F11;
+        if((name == "F12")) return SDLK_F12;
+        if((name == "F13")) return SDLK_F13;
+        if((name == "F14")) return SDLK_F14;
+        if((name == "F15")) return SDLK_F15;
+        if((name == "NUMLOCK")) return SDLK_NUMLOCK;
+        if((name == "CAPSLOCK")) return SDLK_CAPSLOCK;
+        if((name == "SCROLLOCK")) return SDLK_SCROLLOCK;
+        if((name == "RSHIFT")) return SDLK_RSHIFT;
+        if((name == "LSHIFT")) return SDLK_LSHIFT;
+        if((name == "RCTRL")) return SDLK_RCTRL;
+        if((name == "LCTRL")) return SDLK_LCTRL;
+        if((name == "RALT")) return SDLK_RALT;
+        if((name == "LALT")) return SDLK_LALT;
+        if((name == "RMETA")) return SDLK_RMETA;
+        if((name == "LMETA")) return SDLK_LMETA;
+        if((name == "LSUPER")) return SDLK_LSUPER;
+        if((name == "RSUPER")) return SDLK_RSUPER;
+        if((name == "MODE")) return SDLK_MODE;
+        if((name == "HELP")) return SDLK_HELP;
+        if((name == "PRINT")) return SDLK_PRINT;
+        if((name == "SYSREQ")) return SDLK_SYSREQ;
+        if((name == "BREAK")) return SDLK_BREAK;
+        if((name == "MENU")) return SDLK_MENU;
+        if((name == "POWER")) return SDLK_POWER;
+        if((name == "EURO")) return SDLK_EURO;
+        return -1;
+}
+
+std::string SDLKToKeyname(int key)
+{
+        if( key == SDLK_BACKSPACE) return "BACKSPACE";
+        if( key == SDLK_TAB) return "TAB";
+        if( key == SDLK_CLEAR) return "CLEAR";
+        if( key == SDLK_RETURN) return "RETURN";
+        if( key == SDLK_SPACE) return "SPACE";
+        if( key == SDLK_ESCAPE) return "ESCAPE";
+        if( key == SDLK_EXCLAIM) return "EXCLAIM";
+        if( key == SDLK_QUOTEDBL) return "QUOTEDBL";
+        if( key == SDLK_HASH) return "HASH";
+        if( key == SDLK_PAUSE) return "PAUSE";
+        if( key == SDLK_DOLLAR) return "DOLLAR";
+        if( key == SDLK_AMPERSAND) return "AMPERSAND";
+        if( key == SDLK_QUOTE) return "QUOTE";
+        if( key == SDLK_LEFTPAREN) return "LEFTPAREN";
+        if( key == SDLK_RIGHTPAREN) return "RIGHTPAREN";
+        if( key == SDLK_ASTERISK) return "ASTERISK";
+        if( key == SDLK_PLUS) return "PLUS";
+        if( key == SDLK_COMMA) return "COMMA";
+        if( key == SDLK_MINUS) return "MINUS";
+        if( key == SDLK_PERIOD) return "PERIOD";
+        if( key == SDLK_SLASH) return "SLASH";
+        if( key == SDLK_0) return "0";
+        if( key == SDLK_1) return "1";
+        if( key == SDLK_2) return "2";
+        if( key == SDLK_3) return "3";
+        if( key == SDLK_4) return "4";
+        if( key == SDLK_5) return "5";
+        if( key == SDLK_6) return "6";
+        if( key == SDLK_7) return "7";
+        if( key == SDLK_8) return "8";
+        if( key == SDLK_9) return "9";
+        if( key == SDLK_COLON) return "COLON";
+        if( key == SDLK_SEMICOLON) return "SEMICOLON";
+        if( key == SDLK_LESS) return "LESS";
+        if( key == SDLK_EQUALS) return "EQUALS";
+        if( key == SDLK_GREATER) return "GREATER";
+        if( key == SDLK_QUESTION) return "QUESTION";
+        if( key == SDLK_AT) return "AT";
+        if( key == SDLK_LEFTBRACKET) return "LEFTBRACKET";
+        if( key == SDLK_BACKSLASH) return "BACKSLASH";
+        if( key == SDLK_RIGHTBRACKET) return "RIGHTBRACKET";
+        if( key == SDLK_CARET) return "CARET";
+        if( key == SDLK_UNDERSCORE) return "UNDERSCORE";
+        if( key == SDLK_BACKQUOTE) return "BACKQUOTE";
+        if( key == SDLK_a) return "a";
+        if( key == SDLK_b) return "b";
+        if( key == SDLK_c) return "c";
+        if( key == SDLK_d) return "d";
+        if( key == SDLK_e) return "e";
+        if( key == SDLK_f) return "f";
+        if( key == SDLK_g) return "g";
+        if( key == SDLK_h) return "h";
+        if( key == SDLK_i) return "i";
+        if( key == SDLK_j) return "j";
+        if( key == SDLK_k) return "k";
+        if( key == SDLK_l) return "l";
+        if( key == SDLK_m) return "m";
+        if( key == SDLK_n) return "n";
+        if( key == SDLK_o) return "o";
+        if( key == SDLK_p) return "p";
+        if( key == SDLK_q) return "q";
+        if( key == SDLK_r) return "r";
+        if( key == SDLK_s) return "s";
+        if( key == SDLK_t) return "t";
+        if( key == SDLK_u) return "u";
+        if( key == SDLK_v) return "v";
+        if( key == SDLK_w) return "w";
+        if( key == SDLK_x) return "x";
+        if( key == SDLK_y) return "y";
+        if( key == SDLK_z) return "z";
+        if( key == SDLK_DELETE) return "DELETE";
+        if( key == SDLK_KP0) return "KP0";
+        if( key == SDLK_KP1) return "KP1";
+        if( key == SDLK_KP2) return "KP2";
+        if( key == SDLK_KP3) return "KP3";
+        if( key == SDLK_KP4) return "KP4";
+        if( key == SDLK_KP5) return "KP5";
+        if( key == SDLK_KP6) return "KP6";
+        if( key == SDLK_KP7) return "KP7";
+        if( key == SDLK_KP8) return "KP8";
+        if( key == SDLK_KP9) return "KP9";
+        if( key == SDLK_KP_PERIOD) return "KP_PERIOD";
+        if( key == SDLK_KP_DIVIDE) return "KP_DIVIDE";
+        if( key == SDLK_KP_MULTIPLY) return "KP_MULTIPLY";
+        if( key == SDLK_KP_MINUS) return "KP_MINUS";
+        if( key == SDLK_KP_PLUS) return "KP_PLUS";
+        if( key == SDLK_KP_ENTER) return "KP_ENTER";
+        if( key == SDLK_KP_EQUALS) return "KP_EQUALS";
+        if( key == SDLK_UP) return "UP";
+        if( key == SDLK_DOWN) return "DOWN";
+        if( key == SDLK_RIGHT) return "RIGHT";
+        if( key == SDLK_LEFT) return "LEFT";
+        if( key == SDLK_INSERT) return "INSERT";
+        if( key == SDLK_HOME) return "HOME";
+        if( key == SDLK_END) return "END";
+        if( key == SDLK_PAGEUP) return "PAGEUP";
+        if( key == SDLK_PAGEDOWN) return "PAGEDOWN";
+        if( key == SDLK_F1) return "F1";
+        if( key == SDLK_F2) return "F2";
+        if( key == SDLK_F3) return "F3";
+        if( key == SDLK_F4) return "F4";
+        if( key == SDLK_F5) return "F5";
+        if( key == SDLK_F6) return "F6";
+        if( key == SDLK_F7) return "F7";
+        if( key == SDLK_F8) return "F8";
+        if( key == SDLK_F9) return "F9";
+        if( key == SDLK_F10) return "F10";
+        if( key == SDLK_F11) return "F11";
+        if( key == SDLK_F12) return "F12";
+        if( key == SDLK_F13) return "F13";
+        if( key == SDLK_F14) return "F14";
+        if( key == SDLK_F15) return "F15";
+        if( key == SDLK_NUMLOCK) return "NUMLOCK";
+        if( key == SDLK_CAPSLOCK) return "CAPSLOCK";
+        if( key == SDLK_SCROLLOCK) return "SCROLLOCK";
+        if( key == SDLK_RSHIFT) return "RSHIFT";
+        if( key == SDLK_LSHIFT) return "LSHIFT";
+        if( key == SDLK_RCTRL) return "RCTRL";
+        if( key == SDLK_LCTRL) return "LCTRL";
+        if( key == SDLK_RALT) return "RALT";
+        if( key == SDLK_LALT) return "LALT";
+        if( key == SDLK_RMETA) return "RMETA";
+        if( key == SDLK_LMETA) return "LMETA";
+        if( key == SDLK_LSUPER) return "LSUPER";
+        if( key == SDLK_RSUPER) return "RSUPER";
+        if( key == SDLK_MODE) return "MODE";
+        if( key == SDLK_HELP) return "HELP";
+        if( key == SDLK_PRINT) return "PRINT";
+        if( key == SDLK_SYSREQ) return "SYSREQ";
+        if( key == SDLK_BREAK) return "BREAK";
+        if( key == SDLK_MENU) return "MENU";
+        if( key == SDLK_POWER) return "POWER";
+        if( key == SDLK_EURO) return "EURO";
+        return "UNKNOWN";
+}
Index: branches/heathaze/src/lib/event/key_names.h
===================================================================
--- branches/heathaze/src/lib/event/key_names.h	(revision 9940)
+++ branches/heathaze/src/lib/event/key_names.h	(revision 9940)
@@ -0,0 +1,55 @@
+/*!
+ * @file keynames.h
+ *  Key/button naming functions
+ *
+ * Converts strings to SDLK/SDL_BUTTON values and vice versa
+ */
+#ifndef _KEY_NAMES_H
+#define _KEY_NAMES_H
+
+#include <string>
+
+/**
+ * @brief converts an EVKey into a String, naming the Event.
+ * @param key the Key (either key or button) to convert.
+ * @returns the String containing the Event.
+ */
+std::string EVToKeyName(int key);
+/**
+ * @brief converts a KeyName into an Event.
+ * @param keyName the Key to transform.
+ * @returns the Event-Number
+ */
+int KeyNameToEV(const std::string& keyName);
+
+
+/**
+ * @brief converts a button name string to a integer representing the corresponding SDL mouse button identifier
+ * @param name: the name of the mouse button
+ * @return an int containing the SDL identifier of the mouse button or -1 if the button name is not valid
+ */
+int buttonnameToSDLB(const std::string& name);
+
+/**
+ * @brief converst a SDL mouse button identifier to a name string
+ * @param button: an SDL mouse button identifier
+ * @return a pointer to a string containing the name of the mouse button
+ */
+std::string SDLBToButtonname( int button);
+
+/**
+ * @brief converts a key name string to a integer representing the corresponding SDLK sym
+ * @param name: the name of the key
+ * @return the SDLK sym of the named key or -1 if the key name is not valid
+ */
+int keynameToSDLK(const std::string& name);
+
+/**
+ * @brief converts an SDLK sym to a name string
+ * @param key: the SDLK sym
+ * @return a pointer to a string containig the name of the key
+ */
+std::string SDLKToKeyname( int key);
+
+
+#endif /* _KEY_NAMES_H */
Index: branches/heathaze/src/lib/graphics/Makefile.am
===================================================================
--- branches/heathaze/src/lib/graphics/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/graphics/Makefile.am	(revision 9940)
@@ -0,0 +1,50 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXgraphics.a
+
+libORXgraphics_a_SOURCES = \
+		graphics_engine.cc \
+		graphics_effect.cc \
+		light.cc \
+		shader.cc \
+		shader_data.cc \
+		resource_shader.cc \
+		\
+		render2D/render_2d.cc \
+		render2D/element_2d.cc \
+		render2D/image_plane.cc \
+		\
+		text_engine/text_engine.cc \
+		text_engine/text.cc \
+		text_engine/multi_line_text.cc \
+		text_engine/limited_width_text.cc \
+		text_engine/font.cc \
+		text_engine/font_data.cc \
+		text_engine/resource_font.cc
+
+noinst_HEADERS =\
+ 		graphics_engine.h \
+ 		graphics_effect.h \
+		light.h \
+		shader.h \
+		shader_data.h \
+		resource_shader.h \
+		\
+		render2D/render_2d.h \
+		render2D/element_2d.h \
+		render2D/image_plane.h \
+		\
+		text_engine/text_engine.h \
+		text_engine/text.h \
+		text_engine/multi_line_text.h \
+		text_engine/limited_width_text.h \
+		text_engine/font.h \
+		text_engine/font_data.h \
+		text_engine/resource_font.h \
+		text_engine/default_font.xpm
+
+
+SUBDIRS = 	importer \
+          	spatial_separation
+EXTRA_DIST =
Index: branches/heathaze/src/lib/graphics/graphics_effect.cc
===================================================================
--- branches/heathaze/src/lib/graphics/graphics_effect.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/graphics_effect.cc	(revision 9940)
@@ -0,0 +1,69 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+
+#include "graphics_effect.h"
+
+#include "util/loading/load_param.h"
+
+ObjectListDefinition(GraphicsEffect);
+
+/**
+ * @param root The XML-element to load the GraphicsEffect from
+
+  @todo what to do, if no GraphicsEffect-Slots are open anymore ???
+ */
+GraphicsEffect::GraphicsEffect(const TiXmlElement* root) {
+  this->registerObject(this, GraphicsEffect::_objectList);
+    this->bActivated = false;
+}
+
+
+/**
+ *  destroys a GraphicsEffect
+ */
+GraphicsEffect::~GraphicsEffect() {
+}
+
+
+/**
+ * @param root The XML-element to load the GraphicsEffect from
+ */
+void GraphicsEffect::loadParams(const TiXmlElement* root) {
+    BaseObject::loadParams(root);
+}
+
+
+/**
+ *  initializes the graphics effect
+ */
+void GraphicsEffect::init() {}
+
+
+
+/**
+ * draws the effect, if needed
+ */
+void GraphicsEffect::draw() const {}
+
+
+
+/**
+ * ticks the effect if there is any time dependancy
+ */
+void GraphicsEffect::tick(float dt) {}
Index: branches/heathaze/src/lib/graphics/graphics_effect.h
===================================================================
--- branches/heathaze/src/lib/graphics/graphics_effect.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/graphics_effect.h	(revision 9940)
@@ -0,0 +1,40 @@
+/**
+ * @file graphics_effect.h
+ *  abstract type of graphical effects
+ */
+
+#ifndef _GRAPHICS_EFFECT
+#define _GRAPHICS_EFFECT
+
+#include "base_object.h"
+
+class TiXmlElement;
+
+//! A class that handles GraphicsEffects. The GraphicsEffectManager operates on this.
+class GraphicsEffect : public BaseObject {
+  ObjectListDeclaration(GraphicsEffect);
+  public:
+    GraphicsEffect(const TiXmlElement* root = NULL);
+    virtual ~GraphicsEffect();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void init();
+
+    virtual void activate() = 0;
+    virtual void deactivate() = 0;
+
+    virtual void draw() const;
+    virtual void tick(float dt);
+
+    inline bool isActivated() const {
+        return this->bActivated;
+    }
+
+
+protected:
+    bool              bActivated;
+};
+
+
+#endif /* _GRAPHICS_EFFECT */
Index: branches/heathaze/src/lib/graphics/graphics_engine.cc
===================================================================
--- branches/heathaze/src/lib/graphics/graphics_engine.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/graphics_engine.cc	(revision 9940)
@@ -0,0 +1,683 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "graphics_engine.h"
+#include "state.h"
+
+#include "world_entity.h"
+
+#include "render_2d.h"
+#include "text_engine.h"
+#include "light.h"
+#include "shader.h"
+#include "debug.h"
+
+#include "parser/preferences/preferences.h"
+#include "substring.h"
+#include "text.h"
+
+#include "globals.h"
+#include "texture.h"
+
+#include "graphics_effect.h"
+
+#include "shell_command.h"
+#include "loading/load_param_xml.h"
+
+#include "parser/tinyxml/tinyxml.h"
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#ifdef __WIN32__
+ #include "static_model.h"
+#endif
+
+SHELL_COMMAND(wireframe, GraphicsEngine, wireframe);
+SHELL_COMMAND(fps, GraphicsEngine, toggleFPSdisplay);
+
+ObjectListDefinition(GraphicsEngine);
+
+/**
+ * @brief standard constructor
+ */
+GraphicsEngine::GraphicsEngine ()
+{
+  this->registerObject(this, GraphicsEngine::_objectList);
+  this->setName("GraphicsEngine");
+
+  this->isInit = false;
+
+  this->bDisplayFPS = false;
+  this->bAntialiasing = false;
+  this->bDedicated = false;
+  this->minFPS = 9999;
+  this->maxFPS = 0;
+
+  this->geTextCFPS = NULL;
+  this->geTextMaxFPS = NULL;
+  this->geTextMinFPS = NULL;
+
+  this->fullscreenFlag = 0;
+  this->videoFlags = 0;
+  this->screen = NULL;
+
+  // initialize the Modules
+  TextEngine::getInstance();
+  this->graphicsEffects = NULL;
+
+}
+
+/**
+ * @brief The Pointer to this GraphicsEngine
+ */
+GraphicsEngine* GraphicsEngine::singletonRef = NULL;
+
+/**
+ * @brief destructs the graphicsEngine.
+*/
+GraphicsEngine::~GraphicsEngine ()
+{
+  // delete what has to be deleted here
+  this->displayFPS( false );
+
+  //TextEngine
+  delete TextEngine::getInstance();
+  // render 2D
+  delete Render2D::getInstance();
+
+  SDL_QuitSubSystem(SDL_INIT_VIDEO);
+  //   if (this->screen != NULL)
+  //     SDL_FreeSurface(this->screen);
+
+  GraphicsEngine::singletonRef = NULL;
+}
+
+
+/**
+ * @brief loads the GraphicsEngine Specific Parameters.
+ * @param root: the XML-Element to load the Data From
+ */
+void GraphicsEngine::loadParams(const TiXmlElement* root)
+{
+  LoadParamXML(root, "GraphicsEffect", this, GraphicsEngine, loadGraphicsEffects)
+   .describe("loads a graphics effect");
+}
+
+
+
+
+/**
+ * @param root The XML-element to load GraphicsEffects from
+ */
+void GraphicsEngine::loadGraphicsEffects(const TiXmlElement* root)
+{
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    PRINTF(4)("element is: %s\n", element->Value());
+    Factory::fabricate(element);
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+
+
+/**
+ * @brief initializes the GraphicsEngine with default settings.
+ */
+int GraphicsEngine::init()
+{
+  if (this->isInit)
+    return -1;
+  this->initVideo(640, 480, 16);
+  return 1;
+}
+
+/**
+ * @brief loads the GraphicsEngine's settings from a given ini-file and section
+ * @returns nothing usefull
+ */
+int GraphicsEngine::initFromPreferences()
+{
+  // looking if we are in fullscreen-mode
+  MultiType fullscreen = Preferences::getInstance()->getString(CONFIG_SECTION_VIDEO, CONFIG_NAME_FULLSCREEN, "0");
+
+  if (fullscreen.getBool())
+    this->fullscreenFlag = SDL_FULLSCREEN;
+
+  // looking if we are in fullscreen-mode
+  MultiType textures = Preferences::getInstance()->getString(CONFIG_SECTION_VIDEO_ADVANCED, CONFIG_NAME_TEXTURES, "1");
+  Texture::setTextureEnableState(textures.getBool());
+
+  // check it is a dedicated network node: so no drawings are made
+  MultiType dedicated = Preferences::getInstance()->getString(CONFIG_SECTION_VIDEO, CONFIG_NAME_NO_RENDER, "0");
+  this->bDedicated = dedicated.getBool();
+
+  // searching for a usefull resolution
+  SubString resolution(Preferences::getInstance()->getString(CONFIG_SECTION_VIDEO, CONFIG_NAME_RESOLUTION, "640x480").c_str(), 'x'); ///FIXME
+  //resolution.debug();
+  MultiType x = resolution.getString(0), y = resolution.getString(1);
+  return this->initVideo(x.getInt(), y.getInt(), 16);
+
+  //   GraphicsEffect* fe = new FogEffect(NULL);
+  //   this->loadGraphicsEffect(fe);
+  //   fe->activate();
+  //   PRINTF(0)("--------------------------------------------------------------\n");
+
+  //LenseFlare* ge = new LenseFlare();
+  //this->loadGraphicsEffect(ge);
+
+  //ge->addFlare("pictures/lense_flare/sun.png"); //sun
+  //ge->addFlare("pictures/lense_flare/lens2.png"); //first halo
+  //ge->addFlare("pictures/lense_flare/lens1.png"); //small birst
+  //ge->addFlare("pictures/lense_flare/lens3.png"); //second halo
+  //ge->addFlare("pictures/lense_flare/lens4.png");
+  //ge->addFlare("pictures/lense_flare/lens1.png");
+  //ge->addFlare("pictures/lense_flare/lens3.png");
+
+  //ge->activate();
+}
+
+
+
+/**
+ * @brief initializes the Video for openGL.
+ *
+ * This has to be done only once when starting orxonox.
+ */
+int GraphicsEngine::initVideo(unsigned int resX, unsigned int resY, unsigned int bbp)
+{
+  if (this->isInit)
+    return -1;
+  //   initialize SDL_VIDEO
+  if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1)
+  {
+    PRINTF(1)("could not initialize SDL Video\n");
+    return -1;
+  }
+  // initialize SDL_GL-settings
+  this->setGLattribs();
+
+  // setting the Video Flags.
+  this->videoFlags = SDL_OPENGL | SDL_HWPALETTE | SDL_RESIZABLE ;
+
+  /* query SDL for information about our video hardware */
+  const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo ();
+  if( videoInfo == NULL)
+  {
+    PRINTF(1)("Failed getting Video Info :%s\n", SDL_GetError());
+    SDL_Quit ();
+  }
+  if( videoInfo->hw_available)
+    this->videoFlags |= SDL_HWSURFACE;
+  else
+    this->videoFlags |= SDL_SWSURFACE;
+  /*
+  if(VideoInfo -> blit_hw)
+    VideoFlags |= SDL_HWACCEL;
+  */
+  // setting up the Resolution
+  this->setResolution(resX, resY, bbp);
+
+  // GRABBING ALL GL-extensions
+  this->grabHardwareSettings();
+
+  // Enable default GL stuff
+  glEnable(GL_DEPTH_TEST);
+
+  Render2D::getInstance();
+
+  this->isInit = true;
+  return 1;
+}
+
+/**
+ * @brief sets the Window Captions and the Name of the icon.
+ * @param windowName The name of the Window
+ * @param icon The name of the Icon on the Disc
+ */
+void GraphicsEngine::setWindowName(const std::string& windowName, const std::string& icon)
+{
+  SDL_Surface* iconSurf = SDL_LoadBMP(icon.c_str());
+  if (iconSurf != NULL)
+  {
+    Uint32 colorkey = SDL_MapRGB(iconSurf->format, 0, 0, 0);
+    SDL_SetColorKey(iconSurf, SDL_SRCCOLORKEY, colorkey);
+    SDL_WM_SetIcon(iconSurf, NULL);
+    SDL_FreeSurface(iconSurf);
+  }
+
+  SDL_WM_SetCaption (windowName.c_str(), icon.c_str());
+}
+
+
+/**
+ * @brief Sets the GL-attributes
+ */
+void GraphicsEngine::setGLattribs()
+{
+  // Set video mode
+  // TO DO: parse arguments for settings
+  //SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+  //SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
+  //SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+  //SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
+
+
+  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16);
+  SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0);
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_RED_SIZE, 0);
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 0);
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 0);
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, 0);
+
+  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);      //Use at least 5 bits of Red
+  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);    //Use at least 5 bits of Green
+  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);     //Use at least 5 bits of Blue
+  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);   //Use at least 16 bits for the depth buffer
+  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);  //Enable double buffering
+
+  // enable antialiasing?
+  if( this->bAntialiasing)
+  {
+    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,4);
+    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,1);
+  }
+
+  glEnable(GL_CULL_FACE);
+  glCullFace(GL_FRONT);
+}
+
+/**
+ * @brief grabs the Hardware Specifics
+ *
+ * checks for all the different HW-types
+ */
+void GraphicsEngine::grabHardwareSettings()
+{
+  const char* renderer = (const char*) glGetString(GL_RENDERER);
+  const char* vendor   = (const char*) glGetString(GL_VENDOR);
+  const char* version  = (const char*) glGetString(GL_VERSION);
+  const char* extensions = (const char*) glGetString(GL_EXTENSIONS);
+
+  //  printf("%s %s %s\n %s", renderer, vendor, version, extensions);
+
+  if (renderer != NULL)
+  {
+    this->hwRenderer == renderer;
+  }
+  if (vendor != NULL)
+  {
+    this->hwVendor == vendor;
+  }
+  if (version != NULL)
+  {
+    this->hwVersion == version;
+  }
+
+  if (extensions != NULL)
+    this->hwExtensions.split(extensions, " \n\t,");
+
+  PRINT(4)("Running on : vendor: %s,  renderer: %s,  version:%s\n", vendor, renderer, version);
+  PRINT(4)("Extensions:\n");
+  for (unsigned int i = 0; i < this->hwExtensions.size(); i++)
+    PRINT(4)("%d: %s\n", i, this->hwExtensions[i].c_str());
+
+
+  // inizializing GLEW
+  GLenum err = glewInit();
+  if (GLEW_OK != err)
+  {
+    /* Problem: glewInit failed, something is seriously wrong. */
+    PRINTF(1)("%s\n", glewGetErrorString(err));
+  }
+  PRINTF(4)("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
+}
+
+
+/**
+ * @brief sets the Resolution of the Screen to display the Graphics to.
+ * @param width The width of the window
+ * @param height The height of the window
+ * @param bpp bits per pixel
+ */
+int GraphicsEngine::setResolution(int width, int height, int bpp)
+{
+  this->resolutionX = width;
+  this->resolutionY = height;
+  this->bitsPerPixel = bpp;
+  State::setResolution( width, height);
+
+  if (this->screen != NULL)
+    SDL_FreeSurface(screen);
+  if((this->screen = SDL_SetVideoMode(this->resolutionX, this->resolutionY, this->bitsPerPixel, this->videoFlags | this->fullscreenFlag)) == NULL)
+  {
+    PRINTF(1)("Could not SDL_SetVideoMode(%d, %d, %d, %d): %s\n", this->resolutionX, this->resolutionY, this->bitsPerPixel, this->videoFlags, SDL_GetError());
+    //    SDL_Quit();
+    //    return -1;
+    return -1;
+  }
+  glViewport(0, 0, width, height);                     // Reset The Current Viewport
+
+#ifdef __WIN32__
+  // REBUILDING TEXTURES (ON WINDOWS CONTEXT SWITCH)
+  ObjectList<Texture>::const_iterator retex;
+  for (retex = Texture::objectList().begin(); retex != Texture::objectList().end(); ++retex)
+    (*retex)->rebuild();
+
+  // REBUILDING MODELS
+  ObjectList<StaticModel>::const_iterator remod;
+  for (remod = StaticModel::objectList().begin(); remod != StaticModel::objectList().end(); ++remod)
+    (*remod)->rebuild();
+
+#endif /* __WIN32__ */
+  return 1;
+}
+
+/**
+ * @brief sets Fullscreen mode
+ * @param fullscreen true if fullscreen, false if windowed
+*/
+void GraphicsEngine::setFullscreen(bool fullscreen)
+{
+  if (fullscreen)
+    this->fullscreenFlag = SDL_FULLSCREEN;
+  else
+    this->fullscreenFlag = 0;
+  this->setResolution(this->resolutionX, this->resolutionY, this->bitsPerPixel);
+}
+
+void GraphicsEngine::toggleFullscreen()
+{
+  if (this->fullscreenFlag == SDL_FULLSCREEN)
+    this->fullscreenFlag = 0;
+  else
+    this->fullscreenFlag = SDL_FULLSCREEN;
+  this->setResolution(this->resolutionX, this->resolutionY, this->bitsPerPixel);
+}
+
+
+/**
+ * @brief sets the background color
+ * @param red the red part of the background
+ * @param blue the blue part of the background
+ * @param green the green part of the background
+ * @param alpha the alpha part of the background
+ */
+void GraphicsEngine::setBackgroundColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+  glClearColor(red, green, blue, alpha);
+}
+
+/**
+ * @brief Signalhandler, for when the resolution has changed
+ * @param resizeInfo SDL information about the size of the new screen size
+ */
+void GraphicsEngine::resolutionChanged(const SDL_ResizeEvent& resizeInfo)
+{
+  this->setResolution(resizeInfo.w, resizeInfo.h, this->bitsPerPixel);
+}
+
+/**
+ * @brief entering 2D Mode
+ * this is a GL-Projection-mode, that is orthogonal, for placing the font in fron of everything else
+ */
+void GraphicsEngine::enter2DMode()
+{
+  //GraphicsEngine::storeMatrices();
+  SDL_Surface *screen = SDL_GetVideoSurface();
+
+  /* Note, there may be other things you need to change,
+     depending on how you have your OpenGL state set up.
+  */
+  glPushAttrib(GL_ENABLE_BIT);
+  glDisable(GL_DEPTH_TEST);
+  glDisable(GL_CULL_FACE);
+  glDisable(GL_LIGHTING);  // will be set back when leaving 2D-mode
+
+  glMatrixMode(GL_PROJECTION);
+  glPushMatrix();
+  glLoadIdentity();
+  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
+
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity();
+}
+
+/**
+ * @brief leaves the 2DMode again also @see Font::enter2DMode()
+ */
+void GraphicsEngine::leave2DMode()
+{
+
+  glMatrixMode(GL_MODELVIEW);
+  glPopMatrix();
+
+  glMatrixMode(GL_PROJECTION);
+  glPopMatrix();
+
+  glPopAttrib();
+}
+
+/**
+ * @brief changes to wireframe-mode.
+ */
+void GraphicsEngine::wireframe()
+{
+  glPolygonMode(GL_FRONT, GL_LINE);
+}
+
+/**
+ * @brief stores the GL_matrices
+ */
+void GraphicsEngine::storeMatrices()
+{
+  glGetDoublev(GL_PROJECTION_MATRIX, GraphicsEngine::projMat);
+  glGetDoublev(GL_MODELVIEW_MATRIX, GraphicsEngine::modMat);
+  glGetIntegerv(GL_VIEWPORT, GraphicsEngine::viewPort);
+}
+
+//! the stored ModelView Matrix.
+GLdouble GraphicsEngine::modMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+//! the stored Projection Matrix
+GLdouble GraphicsEngine::projMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+//! The ViewPort
+GLint GraphicsEngine::viewPort[4] = {0,0,0,0};
+
+
+
+/**
+ * @brief outputs all the Fullscreen modes.
+ */
+void GraphicsEngine::listModes()
+{
+  /* Get available fullscreen/hardware modes */
+  this->videoModes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
+
+  /* Check is there are any modes available */
+  if(this->videoModes == (SDL_Rect **)0)
+  {
+    PRINTF(1)("No modes available!\n");
+    exit(-1);
+  }
+
+  /* Check if our resolution is restricted */
+  if(this->videoModes == (SDL_Rect **)-1)
+  {
+    PRINTF(2)("All resolutions available.\n");
+  }
+  else
+  {
+    /* Print valid modes */
+    PRINT(0)("Available Resoulution Modes are\n");
+    for(int i = 0; this->videoModes[i]; ++i)
+      PRINT(4)(" |  %d x %d\n", this->videoModes[i]->w, this->videoModes[i]->h);
+  }
+}
+
+/**
+ * @brief checks wether a certain extension is availiable
+ * @param extension the Extension to check for (ex. GL_ARB_texture_env_dot3)
+ * @return true if it is, false otherwise
+ */
+bool GraphicsEngine::hwSupportsEXT(const std::string& extension)
+{
+  for (unsigned int i = 0; i < this->hwExtensions.size(); i++)
+    if ( this->hwExtensions.getString(i) == extension)
+      return true;
+  return false;
+}
+
+/**
+ * @brief updates everything that is to be updated in the GraphicsEngine
+ */
+void GraphicsEngine::update(float dt)
+{
+  Render2D::getInstance()->update(dt);
+}
+
+
+/**
+ * @brief ticks the Text
+ * @param dt the time passed
+ */
+void GraphicsEngine::tick(float dt)
+{
+  if( unlikely(this->bDisplayFPS))
+  {
+    this->currentFPS = 1.0/dt;
+    if( unlikely(this->currentFPS > this->maxFPS)) this->maxFPS = this->currentFPS;
+    if( unlikely(this->currentFPS < this->minFPS)) this->minFPS = this->currentFPS;
+
+#ifndef NO_TEXT
+    char tmpChar1[20];
+    sprintf(tmpChar1, "Current:  %4.0f", this->currentFPS);
+    this->geTextCFPS->setText(tmpChar1);
+    char tmpChar2[20];
+    sprintf(tmpChar2, "Max:    %4.0f", this->maxFPS);
+    this->geTextMaxFPS->setText(tmpChar2);
+    char tmpChar3[20];
+    sprintf(tmpChar3, "Min:    %4.0f", this->minFPS);
+    this->geTextMinFPS->setText(tmpChar3);
+#endif /* NO_TEXT */
+
+  }
+
+  Render2D::getInstance()->tick(dt);
+
+  // tick the graphics effects
+  for (ObjectList<GraphicsEffect>::const_iterator it = GraphicsEffect::objectList().begin();
+       it != GraphicsEffect::objectList().end();
+       ++it)
+    (*it)->tick(dt);
+}
+
+/**
+ * @brief draws all Elements that should be displayed on the Background.
+ */
+void GraphicsEngine::drawBackgroundElements() const
+{
+  GraphicsEngine::storeMatrices();
+
+  Render2D::getInstance()->draw(E2D_LAYER_BELOW_ALL, E2D_LAYER_BELOW_ALL);
+}
+
+/**
+ * this draws the graphics engines graphics effecs
+ */
+void GraphicsEngine::draw() const
+{
+  if( this->graphicsEffects != NULL)
+  {
+    //draw the graphics effects
+    std::list<BaseObject*>::const_iterator it;
+    for (it = this->graphicsEffects->begin(); it != this->graphicsEffects->end(); it++)
+      dynamic_cast<GraphicsEffect*>(*it)->draw();
+  }
+  Shader::suspendShader();
+  Render2D::getInstance()->draw(E2D_LAYER_BOTTOM, E2D_LAYER_ABOVE_ALL);
+  Shader::restoreShader();
+}
+
+
+void GraphicsEngine::toggleFPSdisplay()
+{
+  this->displayFPS(!this->bDisplayFPS);
+}
+
+
+/**
+ * @brief displays the Frames per second
+ * @param display if the text should be displayed
+*/
+void GraphicsEngine::displayFPS(bool display)
+{
+#ifndef NO_TEXT
+  if( display )
+  {
+    if (this->geTextCFPS == NULL)
+    {
+      this->geTextCFPS = new Text("fonts/arial_black.ttf", 15);
+      this->geTextCFPS->setName("curFPS");
+      this->geTextCFPS->setAlignment(TEXT_ALIGN_LEFT);
+      this->geTextCFPS->setAbsCoor2D(5, 0);
+    }
+    if (this->geTextMaxFPS == NULL)
+    {
+      this->geTextMaxFPS = new Text("fonts/arial_black.ttf", 15);
+      this->geTextMaxFPS->setName("MaxFPS");
+      this->geTextMaxFPS->setAlignment(TEXT_ALIGN_LEFT);
+      this->geTextMaxFPS->setAbsCoor2D(5, 20);
+    }
+    if (this->geTextMinFPS == NULL)
+    {
+      this->geTextMinFPS = new Text("fonts/arial_black.ttf", 15);
+      this->geTextMinFPS->setName("MinFPS");
+      this->geTextMinFPS->setAlignment(TEXT_ALIGN_LEFT);
+      this->geTextMinFPS->setAbsCoor2D(5, 40);
+    }
+  }
+  else
+  {
+    delete this->geTextCFPS;
+    this->geTextCFPS = NULL;
+    delete this->geTextMaxFPS;
+    this->geTextMaxFPS = NULL;
+    delete this->geTextMinFPS;
+    this->geTextMinFPS = NULL;
+  }
+  this->bDisplayFPS = display;
+#else
+  this->bDisplayFPS = false;
+#endif /* NO_TEXT */
+}
+
+
+/**
+ * @brief processes the events for the GraphicsEngine class
+ * @param the event to handle
+ */
+void GraphicsEngine::process(const Event &event)
+{
+  switch (event.type)
+  {
+    case EV_VIDEO_RESIZE:
+    this->resolutionChanged(event.resize);
+    break;
+  }
+}
Index: branches/heathaze/src/lib/graphics/graphics_engine.h
===================================================================
--- branches/heathaze/src/lib/graphics/graphics_engine.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/graphics_engine.h	(revision 9940)
@@ -0,0 +1,148 @@
+/*!
+ * @file graphics_engine.h
+
+  *  defines a Interface between orxonox and graphical input
+
+    handles graphical SDL-initialisation, textures, resolutions, and so on
+ */
+
+#ifndef _GRAPHICS_ENGINE_H
+#define _GRAPHICS_ENGINE_H
+
+#include "event_listener.h"
+
+#include "sdlincl.h"
+#include "glincl.h"
+#include <list>
+
+#include "substring.h"
+
+// Forward Declaration
+class Text;
+class WorldEntity;
+class GraphicsEffect;
+class TiXmlElement;
+
+//! class to handle graphics
+/**
+   handles graphical SDL-initialisation, textures, resolutions, and so on
+ */
+class GraphicsEngine : public EventListener
+{
+  ObjectListDeclaration(GraphicsEngine);
+  public:
+    virtual ~GraphicsEngine();
+    /** @returns a Pointer to the only object of this Class */
+    inline static GraphicsEngine* getInstance() { if (!GraphicsEngine::singletonRef) GraphicsEngine::singletonRef = new GraphicsEngine();  return GraphicsEngine::singletonRef; };
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    int init();
+    int initFromPreferences();
+
+    void setWindowName(const std::string& windowName, const std::string& icon);
+
+    int setResolution(int width, int height, int bpp);
+    void setFullscreen(bool fullscreen = false);
+    void toggleFullscreen();
+    static void setBackgroundColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha = 1.0);
+    inline bool isDedicated() { return this->bDedicated; }
+
+    inline void setAntialiasing(bool flag) { this->bAntialiasing = flag; }
+    inline bool getAntialiasing() { return this->bAntialiasing; }
+
+    /** @returns the x resolution */
+    inline int getResolutionX() const { return this->resolutionX; };
+    /** @returns the y resolution */
+    inline int getResolutionY() const { return this->resolutionY; };
+    /** @returns the Bits Per Pixel */
+    inline int getbbp() const { return this->bitsPerPixel; };
+
+    void resolutionChanged(const SDL_ResizeEvent& resizeInfo);
+
+    static void enter2DMode();
+    static void leave2DMode();
+
+    void wireframe();
+
+    static void storeMatrices();
+    static GLdouble modMat[16];
+    static GLdouble projMat[16];
+    static GLint viewPort[4];
+
+    void update(float dt);
+    void tick(float dt);
+
+    void drawBackgroundElements() const;
+    void draw() const;
+    void toggleFPSdisplay();
+    void displayFPS(bool display);
+
+    void listModes();
+    bool hwSupportsEXT(const std::string& extension);
+
+    /** @brief swaps the GL_BUFFERS */
+    inline static void swapBuffers() { SDL_GL_SwapBuffers(); };
+
+    void process(const Event  &event);
+
+    void loadGraphicsEffects(const TiXmlElement* root);
+
+
+
+  private:
+    GraphicsEngine();
+    int initVideo(unsigned int resX, unsigned int resY, unsigned int bbp);
+    void setGLattribs();
+    void grabHardwareSettings();
+
+  public:
+
+  private:
+    static GraphicsEngine*     singletonRef;       //!< Pointer to the only instance of this Class
+    bool                       isInit;             //!< if the GraphicsEngine is initialized.
+
+    // state.
+    SDL_Surface*               screen;             //!< the screen we draw to
+    int                        resolutionX;        //!< the X-resoultion of the screen
+    int                        resolutionY;        //!< the Y-resolution of the screen
+    int                        bitsPerPixel;       //!< the bits per pixels of the screen
+    Uint32                     fullscreenFlag;     //!< if we are in fullscreen mode
+    Uint32                     videoFlags;         //!< flags for video
+    SDL_Rect**                 videoModes;         //!< list of resolutions
+
+    bool                       fogEnabled;         //!< If Fog should be enabled.
+    bool                       shadowsEnabled;     //!< If Shadows should be enabled.
+    bool                       particlesEnabled;   //!< If particles should be enabled.
+    bool                       bAntialiasing;      //!< true if antialiasing enabled
+    bool                       bDedicated;         //!< true if this server is a dedicated server and should not render the scene
+
+    int                        particlesValue;     //!< How many particles
+    int                        textureQuality;     //!< the quality of Textures
+    int                        filteringMethod;    //!< The filtering Method of textures.
+    int                        modelQuality;       //!< The quality of the Models loaded.
+    int                        antialiasingDepth;  //!< the Depth of the AntiAlias-Filter.
+
+    // HARDWARE-Settings:
+    std::string                hwRenderer;         //!< HW-renderer-string
+    std::string                hwVendor;           //!< HW-vendor-string
+    std::string                hwVersion;          //!< HW-version-string
+    SubString                  hwExtensions;       //!< All suported Extensions.
+
+    // FPS-related
+    bool                       bDisplayFPS;        //!< is true if the fps should be displayed
+    float                      currentFPS;         //!< the current frame rate: frames per seconds
+    float                      maxFPS;             //!< maximal frame rate we ever got since start of the game
+    float                      minFPS;             //!< minimal frame rate we ever got since start.
+
+    const std::list<BaseObject*>* graphicsEffects; //!< list of graphics effects
+
+
+#ifndef NO_TEXT
+  Text*          geTextCFPS;                    //!< Text for the current FPS
+  Text*          geTextMaxFPS;                  //!< Text for the max FPS
+  Text*          geTextMinFPS;                  //!< Text for the min FPS
+#endif /* NO_TEXT */
+};
+
+#endif /* _GRAPHICS_ENGINE_H */
Index: branches/heathaze/src/lib/graphics/importer/Makefile.am
===================================================================
--- branches/heathaze/src/lib/graphics/importer/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/Makefile.am	(revision 9940)
@@ -0,0 +1,93 @@
+MAINSRCDIR=../../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXimporter.a libtc.a
+
+libORXimporter_a_SOURCES = \
+		model.cc \
+		interactive_model.cc \
+		md_model_structure.cc \
+		vertex_array_model.cc \
+		grid.cc \
+		static_model.cc \
+		static_model_data.cc \
+		objModel.cc \
+		resource_obj.cc \
+		primitive_model.cc \
+		height_map.cc \
+		bsp_manager.cc \
+		bsp_file.cc \
+		bsp_tree_node.cc \
+		bsp_tree_leaf.cc \
+		\
+		material.cc \
+		texture.cc \
+		texture_data.cc \
+		resource_texture.cc \
+		texture_sequence.cc \
+		media_container.cc \
+		movie_player.cc \
+		\
+		bsp_manager.cc \
+		bsp_file.cc \
+		bsp_tree_node.cc \
+		bsp_tree_leaf.cc \
+		\
+		md2/md2Model.cc \
+		md2/resource_md2.cc
+#		\
+		md3/md3_model.cc \
+		md3/md3_animation.cc \
+		md3/md3_animation_cfg.cc \
+		md3/md3_bone_frame.cc \
+		md3/md3_mesh.cc \
+		md3/md3_data.cc \
+		md3/md3_tag.cc
+
+
+
+
+libtc_a_SOURCES  = tc.cc
+
+
+noinst_HEADERS = \
+		model.h \
+		interactive_model.h \
+		md_model_structure.cc \
+		tc.h \
+		vertex_array_model.h \
+		grid.h \
+		static_model.h \
+		static_model_data.h \
+		objModel.h \
+		resource_obj.h \
+		primitive_model.h \
+		anorms.h \
+		anormtab.h \
+		height_map.h \
+		\
+		material.h \
+		texture.h \
+		texture_data.h \
+		resource_texture.h \
+		texture_sequence.h \
+		\
+		media_container.h \
+		movie_player.h\
+		\
+		bsp_manager.h \
+		bsp_file.h \
+		bsp_tree_node.h \
+		bsp_tree_leaf.h \
+		\
+                md2/md2Model.h \
+		md2/resource_md2.h \
+                \
+                md3/md3_model.h \
+                md3/md3_animation.h \
+                md3/md3_animation_cfg.h \
+                md3/md3_bone_frame.h \
+                md3/md3_mesh.h \
+                md3/md3_data.h \
+                md3/md3_tag.h
+
Index: branches/heathaze/src/lib/graphics/importer/anorms.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/anorms.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/anorms.h	(revision 9940)
@@ -0,0 +1,181 @@
+/*
+Copyright (C) 1996-1997 Id Softwaref, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the Licensef, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if notf, write to the Free Software
+Foundationf, Inc.f, 59 Temple Place - Suite 330f, Bostonf, MA  02111-1307f, USA.
+*/
+
+{-0.525731f, 0.000000f, 0.850651f}, 
+{-0.442863f, 0.238856f, 0.864188f}, 
+{-0.295242f, 0.000000f, 0.955423f}, 
+{-0.309017f, 0.500000f, 0.809017f}, 
+{-0.162460f, 0.262866f, 0.951056f}, 
+{0.000000f, 0.000000f, 1.000000f}, 
+{0.000000f, 0.850651f, 0.525731f}, 
+{-0.147621f, 0.716567f, 0.681718f}, 
+{0.147621f, 0.716567f, 0.681718f}, 
+{0.000000f, 0.525731f, 0.850651f}, 
+{0.309017f, 0.500000f, 0.809017f}, 
+{0.525731f, 0.000000f, 0.850651f}, 
+{0.295242f, 0.000000f, 0.955423f}, 
+{0.442863f, 0.238856f, 0.864188f}, 
+{0.162460f, 0.262866f, 0.951056f}, 
+{-0.681718f, 0.147621f, 0.716567f}, 
+{-0.809017f, 0.309017f, 0.500000f}, 
+{-0.587785f, 0.425325f, 0.688191f}, 
+{-0.850651f, 0.525731f, 0.000000f}, 
+{-0.864188f, 0.442863f, 0.238856f}, 
+{-0.716567f, 0.681718f, 0.147621f}, 
+{-0.688191f, 0.587785f, 0.425325f}, 
+{-0.500000f, 0.809017f, 0.309017f}, 
+{-0.238856f, 0.864188f, 0.442863f}, 
+{-0.425325f, 0.688191f, 0.587785f}, 
+{-0.716567f, 0.681718f, -0.147621f}, 
+{-0.500000f, 0.809017f, -0.309017f}, 
+{-0.525731f, 0.850651f, 0.000000f}, 
+{0.000000f, 0.850651f, -0.525731f}, 
+{-0.238856f, 0.864188f, -0.442863f}, 
+{0.000000f, 0.955423f, -0.295242f}, 
+{-0.262866f, 0.951056f, -0.162460f}, 
+{0.000000f, 1.000000f, 0.000000f}, 
+{0.000000f, 0.955423f, 0.295242f}, 
+{-0.262866f, 0.951056f, 0.162460f}, 
+{0.238856f, 0.864188f, 0.442863f}, 
+{0.262866f, 0.951056f, 0.162460f}, 
+{0.500000f, 0.809017f, 0.309017f}, 
+{0.238856f, 0.864188f, -0.442863f}, 
+{0.262866f, 0.951056f, -0.162460f}, 
+{0.500000f, 0.809017f, -0.309017f}, 
+{0.850651f, 0.525731f, 0.000000f}, 
+{0.716567f, 0.681718f, 0.147621f}, 
+{0.716567f, 0.681718f, -0.147621f}, 
+{0.525731f, 0.850651f, 0.000000f}, 
+{0.425325f, 0.688191f, 0.587785f}, 
+{0.864188f, 0.442863f, 0.238856f}, 
+{0.688191f, 0.587785f, 0.425325f}, 
+{0.809017f, 0.309017f, 0.500000f}, 
+{0.681718f, 0.147621f, 0.716567f}, 
+{0.587785f, 0.425325f, 0.688191f}, 
+{0.955423f, 0.295242f, 0.000000f}, 
+{1.000000f, 0.000000f, 0.000000f}, 
+{0.951056f, 0.162460f, 0.262866f}, 
+{0.850651f, -0.525731f, 0.000000f}, 
+{0.955423f, -0.295242f, 0.000000f}, 
+{0.864188f, -0.442863f, 0.238856f}, 
+{0.951056f, -0.162460f, 0.262866f}, 
+{0.809017f, -0.309017f, 0.500000f}, 
+{0.681718f, -0.147621f, 0.716567f}, 
+{0.850651f, 0.000000f, 0.525731f}, 
+{0.864188f, 0.442863f, -0.238856f}, 
+{0.809017f, 0.309017f, -0.500000f}, 
+{0.951056f, 0.162460f, -0.262866f}, 
+{0.525731f, 0.000000f, -0.850651f}, 
+{0.681718f, 0.147621f, -0.716567f}, 
+{0.681718f, -0.147621f, -0.716567f}, 
+{0.850651f, 0.000000f, -0.525731f}, 
+{0.809017f, -0.309017f, -0.500000f}, 
+{0.864188f, -0.442863f, -0.238856f}, 
+{0.951056f, -0.162460f, -0.262866f}, 
+{0.147621f, 0.716567f, -0.681718f}, 
+{0.309017f, 0.500000f, -0.809017f}, 
+{0.425325f, 0.688191f, -0.587785f}, 
+{0.442863f, 0.238856f, -0.864188f}, 
+{0.587785f, 0.425325f, -0.688191f}, 
+{0.688191f, 0.587785f, -0.425325f}, 
+{-0.147621f, 0.716567f, -0.681718f}, 
+{-0.309017f, 0.500000f, -0.809017f}, 
+{0.000000f, 0.525731f, -0.850651f}, 
+{-0.525731f, 0.000000f, -0.850651f}, 
+{-0.442863f, 0.238856f, -0.864188f}, 
+{-0.295242f, 0.000000f, -0.955423f}, 
+{-0.162460f, 0.262866f, -0.951056f}, 
+{0.000000f, 0.000000f, -1.000000f}, 
+{0.295242f, 0.000000f, -0.955423f}, 
+{0.162460f, 0.262866f, -0.951056f}, 
+{-0.442863f, -0.238856f, -0.864188f}, 
+{-0.309017f, -0.500000f, -0.809017f}, 
+{-0.162460f, -0.262866f, -0.951056f}, 
+{0.000000f, -0.850651f, -0.525731f}, 
+{-0.147621f, -0.716567f, -0.681718f}, 
+{0.147621f, -0.716567f, -0.681718f}, 
+{0.000000f, -0.525731f, -0.850651f}, 
+{0.309017f, -0.500000f, -0.809017f}, 
+{0.442863f, -0.238856f, -0.864188f}, 
+{0.162460f, -0.262866f, -0.951056f}, 
+{0.238856f, -0.864188f, -0.442863f}, 
+{0.500000f, -0.809017f, -0.309017f}, 
+{0.425325f, -0.688191f, -0.587785f}, 
+{0.716567f, -0.681718f, -0.147621f}, 
+{0.688191f, -0.587785f, -0.425325f}, 
+{0.587785f, -0.425325f, -0.688191f}, 
+{0.000000f, -0.955423f, -0.295242f}, 
+{0.000000f, -1.000000f, 0.000000f}, 
+{0.262866f, -0.951056f, -0.162460f}, 
+{0.000000f, -0.850651f, 0.525731f}, 
+{0.000000f, -0.955423f, 0.295242f}, 
+{0.238856f, -0.864188f, 0.442863f}, 
+{0.262866f, -0.951056f, 0.162460f}, 
+{0.500000f, -0.809017f, 0.309017f}, 
+{0.716567f, -0.681718f, 0.147621f}, 
+{0.525731f, -0.850651f, 0.000000f}, 
+{-0.238856f, -0.864188f, -0.442863f}, 
+{-0.500000f, -0.809017f, -0.309017f}, 
+{-0.262866f, -0.951056f, -0.162460f}, 
+{-0.850651f, -0.525731f, 0.000000f}, 
+{-0.716567f, -0.681718f, -0.147621f}, 
+{-0.716567f, -0.681718f, 0.147621f}, 
+{-0.525731f, -0.850651f, 0.000000f}, 
+{-0.500000f, -0.809017f, 0.309017f}, 
+{-0.238856f, -0.864188f, 0.442863f}, 
+{-0.262866f, -0.951056f, 0.162460f}, 
+{-0.864188f, -0.442863f, 0.238856f}, 
+{-0.809017f, -0.309017f, 0.500000f}, 
+{-0.688191f, -0.587785f, 0.425325f}, 
+{-0.681718f, -0.147621f, 0.716567f}, 
+{-0.442863f, -0.238856f, 0.864188f}, 
+{-0.587785f, -0.425325f, 0.688191f}, 
+{-0.309017f, -0.500000f, 0.809017f}, 
+{-0.147621f, -0.716567f, 0.681718f}, 
+{-0.425325f, -0.688191f, 0.587785f}, 
+{-0.162460f, -0.262866f, 0.951056f}, 
+{0.442863f, -0.238856f, 0.864188f}, 
+{0.162460f, -0.262866f, 0.951056f}, 
+{0.309017f, -0.500000f, 0.809017f}, 
+{0.147621f, -0.716567f, 0.681718f}, 
+{0.000000f, -0.525731f, 0.850651f}, 
+{0.425325f, -0.688191f, 0.587785f}, 
+{0.587785f, -0.425325f, 0.688191f}, 
+{0.688191f, -0.587785f, 0.425325f}, 
+{-0.955423f, 0.295242f, 0.000000f}, 
+{-0.951056f, 0.162460f, 0.262866f}, 
+{-1.000000f, 0.000000f, 0.000000f}, 
+{-0.850651f, 0.000000f, 0.525731f}, 
+{-0.955423f, -0.295242f, 0.000000f}, 
+{-0.951056f, -0.162460f, 0.262866f}, 
+{-0.864188f, 0.442863f, -0.238856f}, 
+{-0.951056f, 0.162460f, -0.262866f}, 
+{-0.809017f, 0.309017f, -0.500000f}, 
+{-0.864188f, -0.442863f, -0.238856f}, 
+{-0.951056f, -0.162460f, -0.262866f}, 
+{-0.809017f, -0.309017f, -0.500000f}, 
+{-0.681718f, 0.147621f, -0.716567f}, 
+{-0.681718f, -0.147621f, -0.716567f}, 
+{-0.850651f, 0.000000f, -0.525731f}, 
+{-0.688191f, 0.587785f, -0.425325f}, 
+{-0.587785f, 0.425325f, -0.688191f}, 
+{-0.425325f, 0.688191f, -0.587785f}, 
+{-0.425325f, -0.688191f, -0.587785f}, 
+{-0.587785f, -0.425325f, -0.688191f}, 
+{-0.688191f, -0.587785f, -0.425325f},
Index: branches/heathaze/src/lib/graphics/importer/anormtab.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/anormtab.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/anormtab.h	(revision 9940)
@@ -0,0 +1,37 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+{1.23,1.30,1.47,1.35,1.56,1.71,1.37,1.38,1.59,1.60,1.79,1.97,1.88,1.92,1.79,1.02,0.93,1.07,0.82,0.87,0.88,0.94,0.96,1.14,1.11,0.82,0.83,0.89,0.89,0.86,0.94,0.91,1.00,1.21,0.98,1.48,1.30,1.57,0.96,1.07,1.14,1.60,1.61,1.40,1.37,1.72,1.78,1.79,1.93,1.99,1.90,1.68,1.71,1.86,1.60,1.68,1.78,1.86,1.93,1.99,1.97,1.44,1.22,1.49,0.93,0.99,0.99,1.23,1.22,1.44,1.49,0.89,0.89,0.97,0.91,0.98,1.19,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.19,0.98,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.87,0.93,0.94,1.02,1.30,1.07,1.35,1.38,1.11,1.56,1.92,1.79,1.79,1.59,1.60,1.72,1.90,1.79,0.80,0.85,0.79,0.93,0.80,0.85,0.77,0.74,0.72,0.77,0.74,0.72,0.70,0.70,0.71,0.76,0.73,0.79,0.79,0.73,0.76,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.26,1.26,1.48,1.23,1.50,1.71,1.14,1.19,1.38,1.46,1.64,1.94,1.87,1.84,1.71,1.02,0.92,1.00,0.79,0.85,0.84,0.91,0.90,0.98,0.99,0.77,0.77,0.83,0.82,0.79,0.86,0.84,0.92,0.99,0.91,1.24,1.03,1.33,0.88,0.94,0.97,1.41,1.39,1.18,1.11,1.51,1.61,1.59,1.80,1.91,1.76,1.54,1.65,1.76,1.70,1.70,1.85,1.85,1.97,1.99,1.93,1.28,1.09,1.39,0.92,0.97,0.99,1.18,1.26,1.52,1.48,0.83,0.85,0.90,0.88,0.93,1.00,0.77,0.73,0.78,0.72,0.71,0.74,0.75,0.79,0.86,0.81,0.75,0.81,0.79,0.96,0.88,0.94,0.86,0.93,0.92,0.85,1.08,1.33,1.05,1.55,1.31,1.01,1.05,1.27,1.31,1.60,1.47,1.70,1.54,1.76,1.76,1.57,0.93,0.90,0.99,0.88,0.88,0.95,0.97,1.11,1.39,1.20,0.92,0.97,1.01,1.10,1.39,1.22,1.51,1.58,1.32,1.64,1.97,1.85,1.91,1.77,1.74,1.88,1.99,1.91,0.79,0.86,0.80,0.94,0.84,0.88,0.74,0.74,0.71,0.82,0.77,0.76,0.70,0.73,0.72,0.73,0.70,0.74,0.85,0.77,0.82,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.34,1.27,1.53,1.17,1.46,1.71,0.98,1.05,1.20,1.34,1.48,1.86,1.82,1.71,1.62,1.09,0.94,0.99,0.79,0.85,0.82,0.90,0.87,0.93,0.96,0.76,0.74,0.79,0.76,0.74,0.79,0.78,0.85,0.92,0.85,1.00,0.93,1.06,0.81,0.86,0.89,1.16,1.12,0.97,0.95,1.28,1.38,1.35,1.60,1.77,1.57,1.33,1.50,1.58,1.69,1.63,1.82,1.74,1.91,1.92,1.80,1.04,0.97,1.21,0.90,0.93,0.97,1.05,1.21,1.48,1.37,0.77,0.80,0.84,0.85,0.88,0.92,0.73,0.71,0.74,0.74,0.71,0.75,0.73,0.79,0.84,0.78,0.79,0.86,0.81,1.05,0.94,0.99,0.90,0.95,0.92,0.86,1.24,1.44,1.14,1.59,1.34,1.02,1.27,1.50,1.49,1.80,1.69,1.86,1.72,1.87,1.80,1.69,1.00,0.98,1.23,0.95,0.96,1.09,1.16,1.37,1.63,1.46,0.99,1.10,1.25,1.24,1.51,1.41,1.67,1.77,1.55,1.72,1.95,1.89,1.98,1.91,1.86,1.97,1.99,1.94,0.81,0.89,0.85,0.98,0.90,0.94,0.75,0.78,0.73,0.89,0.83,0.82,0.72,0.77,0.76,0.72,0.70,0.71,0.91,0.83,0.89,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.46,1.34,1.60,1.16,1.46,1.71,0.94,0.99,1.05,1.26,1.33,1.74,1.76,1.57,1.54,1.23,0.98,1.05,0.83,0.89,0.84,0.92,0.87,0.91,0.96,0.78,0.74,0.79,0.72,0.72,0.75,0.76,0.80,0.88,0.83,0.94,0.87,0.95,0.76,0.80,0.82,0.97,0.96,0.89,0.88,1.08,1.11,1.10,1.37,1.59,1.37,1.07,1.27,1.34,1.57,1.45,1.69,1.55,1.77,1.79,1.60,0.93,0.90,0.99,0.86,0.87,0.93,0.96,1.07,1.35,1.18,0.73,0.76,0.77,0.81,0.82,0.85,0.70,0.71,0.72,0.78,0.73,0.77,0.73,0.79,0.82,0.76,0.83,0.90,0.84,1.18,0.98,1.03,0.92,0.95,0.90,0.86,1.32,1.45,1.15,1.53,1.27,0.99,1.42,1.65,1.58,1.93,1.83,1.94,1.81,1.88,1.74,1.70,1.19,1.17,1.44,1.11,1.15,1.36,1.41,1.61,1.81,1.67,1.22,1.34,1.50,1.42,1.65,1.61,1.82,1.91,1.75,1.80,1.89,1.89,1.98,1.99,1.94,1.98,1.92,1.87,0.86,0.95,0.92,1.14,0.98,1.03,0.79,0.84,0.77,0.97,0.90,0.89,0.76,0.82,0.82,0.74,0.72,0.71,0.98,0.89,0.97,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.60,1.44,1.68,1.22,1.49,1.71,0.93,0.99,0.99,1.23,1.22,1.60,1.68,1.44,1.49,1.40,1.14,1.19,0.89,0.96,0.89,0.97,0.89,0.91,0.98,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.91,0.83,0.89,0.72,0.76,0.76,0.89,0.89,0.82,0.82,0.98,0.96,0.97,1.14,1.40,1.19,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.70,0.72,0.73,0.77,0.76,0.79,0.70,0.72,0.71,0.82,0.77,0.80,0.74,0.79,0.80,0.74,0.87,0.93,0.85,1.23,1.02,1.02,0.93,0.93,0.87,0.85,1.30,1.35,1.07,1.38,1.11,0.94,1.47,1.71,1.56,1.97,1.88,1.92,1.79,1.79,1.59,1.60,1.30,1.35,1.56,1.37,1.38,1.59,1.60,1.79,1.92,1.79,1.48,1.57,1.72,1.61,1.78,1.79,1.93,1.99,1.90,1.86,1.78,1.86,1.93,1.99,1.97,1.90,1.79,1.72,0.94,1.07,1.00,1.37,1.21,1.30,0.86,0.91,0.83,1.14,0.98,0.96,0.82,0.88,0.89,0.79,0.76,0.73,1.07,0.94,1.11,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.74,1.57,1.76,1.33,1.54,1.71,0.94,1.05,0.99,1.26,1.16,1.46,1.60,1.34,1.46,1.59,1.37,1.37,0.97,1.11,0.96,1.10,0.95,0.94,1.08,0.89,0.82,0.88,0.72,0.76,0.75,0.80,0.80,0.88,0.87,0.91,0.83,0.87,0.72,0.76,0.74,0.83,0.84,0.78,0.79,0.96,0.89,0.92,0.98,1.23,1.05,0.86,0.92,0.95,1.11,0.98,1.22,1.03,1.34,1.42,1.14,0.79,0.77,0.84,0.78,0.76,0.82,0.82,0.89,0.97,0.90,0.70,0.71,0.71,0.73,0.72,0.74,0.73,0.76,0.72,0.86,0.81,0.82,0.76,0.79,0.77,0.73,0.90,0.95,0.86,1.18,1.03,0.98,0.92,0.90,0.83,0.84,1.19,1.17,0.98,1.15,0.97,0.89,1.42,1.65,1.44,1.93,1.83,1.81,1.67,1.61,1.36,1.41,1.32,1.45,1.58,1.57,1.53,1.74,1.70,1.88,1.94,1.81,1.69,1.77,1.87,1.79,1.89,1.92,1.98,1.99,1.98,1.89,1.65,1.80,1.82,1.91,1.94,1.75,1.61,1.50,1.07,1.34,1.27,1.60,1.45,1.55,0.93,0.99,0.90,1.35,1.18,1.07,0.87,0.93,0.96,0.85,0.82,0.77,1.15,0.99,1.27,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.86,1.71,1.82,1.48,1.62,1.71,0.98,1.20,1.05,1.34,1.17,1.34,1.53,1.27,1.46,1.77,1.60,1.57,1.16,1.38,1.12,1.35,1.06,1.00,1.28,0.97,0.89,0.95,0.76,0.81,0.79,0.86,0.85,0.92,0.93,0.93,0.85,0.87,0.74,0.78,0.74,0.79,0.82,0.76,0.79,0.96,0.85,0.90,0.94,1.09,0.99,0.81,0.85,0.89,0.95,0.90,0.99,0.94,1.10,1.24,0.98,0.75,0.73,0.78,0.74,0.72,0.77,0.76,0.82,0.89,0.83,0.73,0.71,0.71,0.71,0.70,0.72,0.77,0.80,0.74,0.90,0.85,0.84,0.78,0.79,0.75,0.73,0.92,0.95,0.86,1.05,0.99,0.94,0.90,0.86,0.79,0.81,1.00,0.98,0.91,0.96,0.89,0.83,1.27,1.50,1.23,1.80,1.69,1.63,1.46,1.37,1.09,1.16,1.24,1.44,1.49,1.69,1.59,1.80,1.69,1.87,1.86,1.72,1.82,1.91,1.94,1.92,1.95,1.99,1.98,1.91,1.97,1.89,1.51,1.72,1.67,1.77,1.86,1.55,1.41,1.25,1.33,1.58,1.50,1.80,1.63,1.74,1.04,1.21,0.97,1.48,1.37,1.21,0.93,0.97,1.05,0.92,0.88,0.84,1.14,1.02,1.34,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.94,1.84,1.87,1.64,1.71,1.71,1.14,1.38,1.19,1.46,1.23,1.26,1.48,1.26,1.50,1.91,1.80,1.76,1.41,1.61,1.39,1.59,1.33,1.24,1.51,1.18,0.97,1.11,0.82,0.88,0.86,0.94,0.92,0.99,1.03,0.98,0.91,0.90,0.79,0.84,0.77,0.79,0.84,0.77,0.83,0.99,0.85,0.91,0.92,1.02,1.00,0.79,0.80,0.86,0.88,0.84,0.92,0.88,0.97,1.10,0.94,0.74,0.71,0.74,0.72,0.70,0.73,0.72,0.76,0.82,0.77,0.77,0.73,0.74,0.71,0.70,0.73,0.83,0.85,0.78,0.92,0.88,0.86,0.81,0.79,0.74,0.75,0.92,0.93,0.85,0.96,0.94,0.88,0.86,0.81,0.75,0.79,0.93,0.90,0.85,0.88,0.82,0.77,1.05,1.27,0.99,1.60,1.47,1.39,1.20,1.11,0.95,0.97,1.08,1.33,1.31,1.70,1.55,1.76,1.57,1.76,1.70,1.54,1.85,1.97,1.91,1.99,1.97,1.99,1.91,1.77,1.88,1.85,1.39,1.64,1.51,1.58,1.74,1.32,1.22,1.01,1.54,1.76,1.65,1.93,1.70,1.85,1.28,1.39,1.09,1.52,1.48,1.26,0.97,0.99,1.18,1.00,0.93,0.90,1.05,1.01,1.31,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.97,1.92,1.88,1.79,1.79,1.71,1.37,1.59,1.38,1.60,1.35,1.23,1.47,1.30,1.56,1.99,1.93,1.90,1.60,1.78,1.61,1.79,1.57,1.48,1.72,1.40,1.14,1.37,0.89,0.96,0.94,1.07,1.00,1.21,1.30,1.14,0.98,0.96,0.86,0.91,0.83,0.82,0.88,0.82,0.89,1.11,0.87,0.94,0.93,1.02,1.07,0.80,0.79,0.85,0.82,0.80,0.87,0.85,0.93,1.02,0.93,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.82,0.76,0.79,0.72,0.73,0.76,0.89,0.89,0.82,0.93,0.91,0.86,0.83,0.79,0.73,0.76,0.91,0.89,0.83,0.89,0.89,0.82,0.82,0.76,0.72,0.76,0.86,0.83,0.79,0.82,0.76,0.73,0.94,1.00,0.91,1.37,1.21,1.14,0.98,0.96,0.88,0.89,0.96,1.14,1.07,1.60,1.40,1.61,1.37,1.57,1.48,1.30,1.78,1.93,1.79,1.99,1.92,1.90,1.79,1.59,1.72,1.79,1.30,1.56,1.35,1.38,1.60,1.11,1.07,0.94,1.68,1.86,1.71,1.97,1.68,1.86,1.44,1.49,1.22,1.44,1.49,1.22,0.99,0.99,1.23,1.19,0.98,0.97,0.97,0.98,1.19,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.94,1.97,1.87,1.91,1.85,1.71,1.60,1.77,1.58,1.74,1.51,1.26,1.48,1.39,1.64,1.99,1.97,1.99,1.70,1.85,1.76,1.91,1.76,1.70,1.88,1.55,1.33,1.57,0.96,1.08,1.05,1.31,1.27,1.47,1.54,1.39,1.20,1.11,0.93,0.99,0.90,0.88,0.95,0.88,0.97,1.32,0.92,1.01,0.97,1.10,1.22,0.84,0.80,0.88,0.79,0.79,0.85,0.86,0.92,1.02,0.94,0.82,0.76,0.77,0.72,0.73,0.70,0.72,0.71,0.74,0.74,0.88,0.81,0.85,0.75,0.77,0.82,0.94,0.93,0.86,0.92,0.92,0.86,0.85,0.79,0.74,0.79,0.88,0.85,0.81,0.82,0.83,0.77,0.78,0.73,0.71,0.75,0.79,0.77,0.74,0.77,0.73,0.70,0.86,0.92,0.84,1.14,0.99,0.98,0.91,0.90,0.84,0.83,0.88,0.97,0.94,1.41,1.18,1.39,1.11,1.33,1.24,1.03,1.61,1.80,1.59,1.91,1.84,1.76,1.64,1.38,1.51,1.71,1.26,1.50,1.23,1.19,1.46,0.99,1.00,0.91,1.70,1.85,1.65,1.93,1.54,1.76,1.52,1.48,1.26,1.28,1.39,1.09,0.99,0.97,1.18,1.31,1.01,1.05,0.90,0.93,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.86,1.95,1.82,1.98,1.89,1.71,1.80,1.91,1.77,1.86,1.67,1.34,1.53,1.51,1.72,1.92,1.91,1.99,1.69,1.82,1.80,1.94,1.87,1.86,1.97,1.59,1.44,1.69,1.05,1.24,1.27,1.49,1.50,1.69,1.72,1.63,1.46,1.37,1.00,1.23,0.98,0.95,1.09,0.96,1.16,1.55,0.99,1.25,1.10,1.24,1.41,0.90,0.85,0.94,0.79,0.81,0.85,0.89,0.94,1.09,0.98,0.89,0.82,0.83,0.74,0.77,0.72,0.76,0.73,0.75,0.78,0.94,0.86,0.91,0.79,0.83,0.89,0.99,0.95,0.90,0.90,0.92,0.84,0.86,0.79,0.75,0.81,0.85,0.80,0.78,0.76,0.77,0.73,0.74,0.71,0.71,0.73,0.74,0.74,0.71,0.76,0.72,0.70,0.79,0.85,0.78,0.98,0.92,0.93,0.85,0.87,0.82,0.79,0.81,0.89,0.86,1.16,0.97,1.12,0.95,1.06,1.00,0.93,1.38,1.60,1.35,1.77,1.71,1.57,1.48,1.20,1.28,1.62,1.27,1.46,1.17,1.05,1.34,0.96,0.99,0.90,1.63,1.74,1.50,1.80,1.33,1.58,1.48,1.37,1.21,1.04,1.21,0.97,0.97,0.93,1.05,1.34,1.02,1.14,0.84,0.88,0.92,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.74,1.89,1.76,1.98,1.89,1.71,1.93,1.99,1.91,1.94,1.82,1.46,1.60,1.65,1.80,1.79,1.77,1.92,1.57,1.69,1.74,1.87,1.88,1.94,1.98,1.53,1.45,1.70,1.18,1.32,1.42,1.58,1.65,1.83,1.81,1.81,1.67,1.61,1.19,1.44,1.17,1.11,1.36,1.15,1.41,1.75,1.22,1.50,1.34,1.42,1.61,0.98,0.92,1.03,0.83,0.86,0.89,0.95,0.98,1.23,1.14,0.97,0.89,0.90,0.78,0.82,0.76,0.82,0.77,0.79,0.84,0.98,0.90,0.98,0.83,0.89,0.97,1.03,0.95,0.92,0.86,0.90,0.82,0.86,0.79,0.77,0.84,0.81,0.76,0.76,0.72,0.73,0.70,0.72,0.71,0.73,0.73,0.72,0.74,0.71,0.78,0.74,0.72,0.75,0.80,0.76,0.94,0.88,0.91,0.83,0.87,0.84,0.79,0.76,0.82,0.80,0.97,0.89,0.96,0.88,0.95,0.94,0.87,1.11,1.37,1.10,1.59,1.57,1.37,1.33,1.05,1.08,1.54,1.34,1.46,1.16,0.99,1.26,0.96,1.05,0.92,1.45,1.55,1.27,1.60,1.07,1.34,1.35,1.18,1.07,0.93,0.99,0.90,0.93,0.87,0.96,1.27,0.99,1.15,0.77,0.82,0.85,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.60,1.78,1.68,1.93,1.86,1.71,1.97,1.99,1.99,1.97,1.93,1.60,1.68,1.78,1.86,1.61,1.57,1.79,1.37,1.48,1.59,1.72,1.79,1.92,1.90,1.38,1.35,1.60,1.23,1.30,1.47,1.56,1.71,1.88,1.79,1.92,1.79,1.79,1.30,1.56,1.35,1.37,1.59,1.38,1.60,1.90,1.48,1.72,1.57,1.61,1.79,1.21,1.00,1.30,0.89,0.94,0.96,1.07,1.14,1.40,1.37,1.14,0.96,0.98,0.82,0.88,0.82,0.89,0.83,0.86,0.91,1.02,0.93,1.07,0.87,0.94,1.11,1.02,0.93,0.93,0.82,0.87,0.80,0.85,0.79,0.80,0.85,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.72,0.76,0.73,0.82,0.79,0.76,0.73,0.79,0.76,0.93,0.86,0.91,0.83,0.89,0.89,0.82,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.44,1.19,1.22,0.99,0.98,1.49,1.44,1.49,1.22,0.99,1.23,0.98,1.19,0.97,1.21,1.30,1.00,1.37,0.94,1.07,1.14,0.98,0.96,0.86,0.91,0.83,0.88,0.82,0.89,1.11,0.94,1.07,0.73,0.76,0.79,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.46,1.65,1.60,1.82,1.80,1.71,1.93,1.91,1.99,1.94,1.98,1.74,1.76,1.89,1.89,1.42,1.34,1.61,1.11,1.22,1.36,1.50,1.61,1.81,1.75,1.15,1.17,1.41,1.18,1.19,1.42,1.44,1.65,1.83,1.67,1.94,1.81,1.88,1.32,1.58,1.45,1.57,1.74,1.53,1.70,1.98,1.69,1.87,1.77,1.79,1.92,1.45,1.27,1.55,0.97,1.07,1.11,1.34,1.37,1.59,1.60,1.35,1.07,1.18,0.86,0.93,0.87,0.96,0.90,0.93,0.99,1.03,0.95,1.15,0.90,0.99,1.27,0.98,0.90,0.92,0.78,0.83,0.77,0.84,0.79,0.82,0.86,0.73,0.71,0.73,0.72,0.70,0.73,0.72,0.76,0.81,0.76,0.76,0.82,0.77,0.89,0.85,0.82,0.75,0.80,0.80,0.94,0.88,0.94,0.87,0.95,0.96,0.88,0.72,0.74,0.76,0.83,0.78,0.84,0.79,0.87,0.91,0.83,0.89,0.98,0.92,1.23,1.34,1.05,1.16,0.99,0.96,1.46,1.57,1.54,1.33,1.05,1.26,1.08,1.37,1.10,0.98,1.03,0.92,1.14,0.86,0.95,0.97,0.90,0.89,0.79,0.84,0.77,0.82,0.76,0.82,0.97,0.89,0.98,0.71,0.72,0.74,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.34,1.51,1.53,1.67,1.72,1.71,1.80,1.77,1.91,1.86,1.98,1.86,1.82,1.95,1.89,1.24,1.10,1.41,0.95,0.99,1.09,1.25,1.37,1.63,1.55,0.96,0.98,1.16,1.05,1.00,1.27,1.23,1.50,1.69,1.46,1.86,1.72,1.87,1.24,1.49,1.44,1.69,1.80,1.59,1.69,1.97,1.82,1.94,1.91,1.92,1.99,1.63,1.50,1.74,1.16,1.33,1.38,1.58,1.60,1.77,1.80,1.48,1.21,1.37,0.90,0.97,0.93,1.05,0.97,1.04,1.21,0.99,0.95,1.14,0.92,1.02,1.34,0.94,0.86,0.90,0.74,0.79,0.75,0.81,0.79,0.84,0.86,0.71,0.71,0.73,0.76,0.73,0.77,0.74,0.80,0.85,0.78,0.81,0.89,0.84,0.97,0.92,0.88,0.79,0.85,0.86,0.98,0.92,1.00,0.93,1.06,1.12,0.95,0.74,0.74,0.78,0.79,0.76,0.82,0.79,0.87,0.93,0.85,0.85,0.94,0.90,1.09,1.27,0.99,1.17,1.05,0.96,1.46,1.71,1.62,1.48,1.20,1.34,1.28,1.57,1.35,0.90,0.94,0.85,0.98,0.81,0.89,0.89,0.83,0.82,0.75,0.78,0.73,0.77,0.72,0.76,0.89,0.83,0.91,0.71,0.70,0.72,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.26,1.39,1.48,1.51,1.64,1.71,1.60,1.58,1.77,1.74,1.91,1.94,1.87,1.97,1.85,1.10,0.97,1.22,0.88,0.92,0.95,1.01,1.11,1.39,1.32,0.88,0.90,0.97,0.96,0.93,1.05,0.99,1.27,1.47,1.20,1.70,1.54,1.76,1.08,1.31,1.33,1.70,1.76,1.55,1.57,1.88,1.85,1.91,1.97,1.99,1.99,1.70,1.65,1.85,1.41,1.54,1.61,1.76,1.80,1.91,1.93,1.52,1.26,1.48,0.92,0.99,0.97,1.18,1.09,1.28,1.39,0.94,0.93,1.05,0.92,1.01,1.31,0.88,0.81,0.86,0.72,0.75,0.74,0.79,0.79,0.86,0.85,0.71,0.73,0.75,0.82,0.77,0.83,0.78,0.85,0.88,0.81,0.88,0.97,0.90,1.18,1.00,0.93,0.86,0.92,0.94,1.14,0.99,1.24,1.03,1.33,1.39,1.11,0.79,0.77,0.84,0.79,0.77,0.84,0.83,0.90,0.98,0.91,0.85,0.92,0.91,1.02,1.26,1.00,1.23,1.19,0.99,1.50,1.84,1.71,1.64,1.38,1.46,1.51,1.76,1.59,0.84,0.88,0.80,0.94,0.79,0.86,0.82,0.77,0.76,0.74,0.74,0.71,0.73,0.70,0.72,0.82,0.77,0.85,0.74,0.70,0.73,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}
+
Index: branches/heathaze/src/lib/graphics/importer/bsp_file.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/bsp_file.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/bsp_file.cc	(revision 9940)
@@ -0,0 +1,1117 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: bottac@ee.ethz.ch
+
+   Inspired by:
+   Rendering Q3 Maps by Morgan McGuire                  http://graphics.cs.brown.edu/games/quake/quake3.html
+   Unofficial Quake 3 Map Specs by Kekoa Proudfoot      http://graphics.stanford.edu/~kekoa/q3/
+   Quake 3 Collision Detection by Nathan Ostgard        http://www.devmaster.net/articles/quake3collision/
+*/
+
+
+#include "bsp_file.h"
+#include "bsp_tree_node.h"
+#include <fstream>
+#include "util/loading/resource_manager.h"
+
+#include <sys/stat.h>
+#include <string.h>
+#include "debug.h"
+#include "material.h"
+#include "vertex_array_model.h"
+// Necessary ?
+#include "base_object.h"
+#include "vector.h"
+#include "movie_player.h"
+
+#include <SDL/SDL_endian.h>
+#include <SDL/SDL_image.h>
+
+// STL Containers
+#include <vector>
+
+
+
+
+// Constructor
+BspFile::BspFile()
+{}
+
+BspFile::~ BspFile()
+{
+  delete [] nodes;
+  delete [] leaves;
+  delete [] planes;
+  delete [] bspModels;
+  delete [] leafFaces;
+  delete [] faces;
+  delete [] leafBrushes;
+  delete [] brushes;
+  delete [] brushSides;
+  delete [] vertice;
+  delete [] meshverts;
+  delete [] visData;
+  delete [] textures;
+  delete [] patchVertice;
+  delete [] patchIndexes;
+ // delete [] patchTrianglesPerRow;
+  delete [] lightMaps;
+
+  for(int i = 0; i < this->numPatches; ++i) delete this->VertexArrayModels[i];
+ // delete  [] VertexArrayModels;
+
+  for(int i = 0; i < this->numTextures; ++i)
+  {
+    delete this->Materials[i].mat;
+    //delete this->Materials[i].aviMat;
+  }
+  delete [] this->Materials;
+  //delete [] testSurf;
+
+
+
+}
+
+/**
+ *  Loads a quake3 level (*.bsp)
+ * @param name the Name of the *.bsp file
+ */
+int BspFile::read(const char* name)
+{
+  this->scale = 1.0;
+  int offset;
+  int size;
+  struct stat results;
+
+
+  if (stat( name , &results) == 0) {
+    PRINTF(0)("BSP FILE: Datei %s gefunden. \n", name);
+    std::ifstream bspFile (name, std::ios::in | std::ios::binary);
+    bspFile.read(this->header, 260);
+    PRINTF(0)("BSP FILE: BSPVersion: %i. \n", ((int *)(header) )[1]);
+    if(SDL_SwapLE32(((int *)(header) )[1]) == 46)    PRINTF(0)("BSP FILE: This is the good one! :-)  \n");
+    else  PRINTF(0)("BSP FILE: Wrong BSPVersion.\n");   //!< now, we should do some error handling
+
+    // Get the Nodes
+    offset = SDL_SwapLE32(((int *)(header) )[8]);
+    size    = SDL_SwapLE32(((int *)(header))[9]);
+    PRINTF(4)("BSP FILE: NodeSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumNodes: %i. \n", size / sizeof(node));
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % sizeof(node));
+    PRINTF(4)("BSP FILE: NodeOffset: %i. \n", offset);
+    this->numNodes = size/sizeof(node);
+    this->nodes = new node [this->numNodes];
+    bspFile.seekg(offset);
+    bspFile.read((char*)this->nodes, size);
+
+    // and their Planes
+    offset = SDL_SwapLE32(((int *)(header) )[6]);
+    size    = SDL_SwapLE32(((int *)(header))[7]);
+    PRINTF(4)("BSP FILE: PlanesSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumPlanes: %i. \n", size / sizeof(plane));
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", sizeof(plane));
+    PRINTF(4)("BSP FILE: PlanesOffset: %i. \n", offset);
+    this->numPlanes = size/sizeof(plane);
+    this->planes = new plane [this->numPlanes];
+    bspFile.seekg(offset);
+    bspFile.read((char*)this->planes, size);
+
+    // Get the Leafs
+    offset = SDL_SwapLE32(((int *)(header) )[10]);
+    size    = SDL_SwapLE32(((int *)(header))[11]);
+    PRINTF(4)("BSP FILE: LeaveSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumLeaves: %i. \n", size / sizeof(leaf));
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % sizeof(leaf));
+    PRINTF(4)("BSP FILE: LeaveOffset: %i. \n", offset);
+    this->numLeafs = size/sizeof(leaf);
+    this->leaves = new leaf [this->numLeafs];
+    bspFile.seekg(offset);
+    bspFile.read((char*)this->leaves, size);
+
+    // Get the Models
+    offset = SDL_SwapLE32(((int *)(header))[16]);
+    size    = SDL_SwapLE32(((int *)(header))[17]);
+    PRINTF(4)("BSP FILE: ModelsSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumModels: %i. \n", size / sizeof(model));
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % sizeof(model));
+    PRINTF(4)("BSP FILE: ModelsOffset: %i. \n", offset);
+    this->numBspModels = size/sizeof(model);
+    this->bspModels = new model [this->numBspModels];
+    bspFile.seekg(offset);
+    bspFile.read((char*)this->bspModels, size);
+
+    // Get the leafFaces
+    offset = SDL_SwapLE32(((int *)(header))[12]);
+    size    = SDL_SwapLE32(((int *)(header))[13]);
+    PRINTF(4)("BSP FILE: leafFacesSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumleafFaces: %i. \n", size / 4);
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % 4);
+    PRINTF(4)("BSP FILE: leafFacesOffset: %i. \n", offset);
+    this->numLeafFaces = size/4;
+    this->leafFaces = new char [size];
+    bspFile.seekg(offset);
+    bspFile.read(this->leafFaces, size);
+
+    // Get the leafBrushes
+    offset = SDL_SwapLE32(((int *)(header))[14]);
+    size    = SDL_SwapLE32(((int *)(header))[15]);
+    PRINTF(4)("BSP FILE: leafBrushesSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumleafBrushes: %i. \n", size / 4);
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % 4);
+    PRINTF(4)("BSP FILE: leafBrushesOffset: %i. \n", offset);
+    this->numLeafBrushes = size/4;
+    this->leafBrushes = new char [size];
+    bspFile.seekg(offset);
+    bspFile.read(this->leafBrushes, size);
+
+    // Get the brushes
+    offset = SDL_SwapLE32(((int *)(header))[18]);
+    size    = SDL_SwapLE32(((int *)(header))[19]);
+    PRINTF(4)("BSP FILE: BrushesSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumBrushes: %i. \n", size / sizeof(brush));
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % sizeof(brush));
+    PRINTF(4)("BSP FILE: BrushesOffset: %i. \n", offset);
+    this->brushes = new brush [size/sizeof(brush)];
+    bspFile.seekg(offset);
+    bspFile.read((char*)this->brushes, size);
+
+    // Get the brushSides
+    offset =   SDL_SwapLE32(((int *)(header))[20]);
+    size    = SDL_SwapLE32(((int *)(header))[21]);
+    PRINTF(4)("BSP FILE: BrushSidesSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumBrushSides: %i. \n", size / 8);
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % 8);
+    PRINTF(4)("BSP FILE: BrushSidesOffset: %i. \n", offset);
+    this->numBrushSides = size/sizeof(brushside);
+    this->brushSides = new brushside [this->numBrushSides];
+    bspFile.seekg(offset);
+    bspFile.read((char*)this->brushSides, size);
+
+    // Get the Vertice
+    offset = SDL_SwapLE32(((int *)(header))[22]);
+    size    = SDL_SwapLE32(((int *)(header))[23]);
+    PRINTF(4)("BSP FILE: VerticeSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumVertice: %i. \n", size / 44);
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % 44);
+    PRINTF(4)("BSP FILE: VerticeOffset: %i. \n", offset);
+    this->numVertex = size/44;
+    this->vertice = new char [size];
+    bspFile.seekg(offset);
+    bspFile.read(this->vertice, size);
+
+    // Get the MeshVerts
+    offset = SDL_SwapLE32(((int *)(header))[24]);
+    size    = SDL_SwapLE32(((int *)(header))[25]);
+    PRINTF(4)("BSP FILE: MeshVertsSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumMeshVerts: %i. \n", size / sizeof(meshvert));
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % sizeof(meshvert));
+    PRINTF(4)("BSP FILE: MeshVertsOffset: %i. \n", offset);
+    this->meshverts = new meshvert [size / sizeof(meshvert)];
+    bspFile.seekg(offset);
+    bspFile.read((char*)this->meshverts, size);
+
+    // Get the Faces
+    offset = SDL_SwapLE32(((int *)(header))[28]);
+    size    = SDL_SwapLE32(((int *)(header))[29]);
+    PRINTF(4)("BSP FILE: FacesSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumFaces: %i. \n", size / sizeof(face));
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % sizeof(face));
+    PRINTF(4)("BSP FILE: FacesOffset: %i. \n", offset);
+    this->numFaces = size/sizeof(face);
+    this->faces = new face [this->numFaces];
+    bspFile.seekg(offset);
+    bspFile.read((char*)this->faces, size);
+
+    //Get the lightmaps
+    offset = SDL_SwapLE32(((int *)(header))[30]);
+    size    = SDL_SwapLE32(((int *)(header))[31]);
+    this->numLightMaps = size/ sizeof(lightmap);
+    this->lightMaps = new lightmap [this->numLightMaps];
+    bspFile.seekg(offset);
+    bspFile.read((char*)this->lightMaps, size);
+
+
+    // Get the Visdata
+    offset = SDL_SwapLE32(((int *)(header))[34]);
+    size    = SDL_SwapLE32(((int *)(header))[35]);
+
+    this->visData = new char [size];
+    bspFile.seekg(offset);
+    bspFile.read(this->visData, size);
+
+    PRINTF(4)("BSP FILE: VisDataSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumVisData: %i. \n", size /1 - 8);
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % 1);
+    PRINTF(4)("BSP FILE: VisDataOffset: %i. \n", offset);
+
+    // Get the Textures
+    offset = SDL_SwapLE32(((int *)(header))[4]);
+    size    = SDL_SwapLE32(((int *)(header))[5]);
+
+    this->textures= new char [size];
+    bspFile.seekg(offset);
+    bspFile.read(this->textures, size);
+
+    PRINTF(4)("BSP FILE: TextureSize: %i Bytes. \n", size);
+    PRINTF(4)("BSP FILE: NumTextures: %i. \n", size /72);
+    PRINTF(4)("BSP FILE: Remainder: %i. \n", size % 72);
+    PRINTF(4)("BSP FILE: TextureOffset: %i. \n", offset);
+    this->numTextures = size/72;
+
+    bspFile.close();
+
+    for(int i = 0 ; i < this->numTextures; i++)
+      PRINTF(4)("BSP FILE: Texture 0: %s. \n", &this->textures[8+ 72*i]);
+    this->load_textures();
+
+    // Load the lightMaps
+    this->glLightMapTextures = new GLuint[this->numLightMaps];
+    for(int i = 0; i < this->numLightMaps; i++)
+      this->glLightMapTextures[i] = this->loadLightMapToGL(this->lightMaps[i]);
+
+    //Create white texture for if no lightmap specified
+    glGenTextures(1, &this->whiteLightMap);
+    glBindTexture(GL_TEXTURE_2D, this->whiteLightMap);
+        //Create texture
+    this->whiteTexture[0]=255;
+    this->whiteTexture[1]=255;
+    this->whiteTexture[2]=255;
+
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+    glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_PRIORITY, 2);
+
+
+
+    /* control the mipmap levels */
+    glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MIN_LOD, 5);
+    glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MAX_LOD, 0);
+
+    /* build the Texture  OpenGL V >= 1.1 */
+    glTexImage2D(GL_TEXTURE_2D,
+                 0,
+                 GL_RGBA8,
+                 1,
+                 1,
+                 0,
+                 GL_RGB,
+                 GL_UNSIGNED_BYTE,
+                 (const GLvoid *)&(this->whiteTexture));
+
+   gluBuild2DMipmaps(   GL_TEXTURE_2D, GL_RGBA8, 1, 1,
+                      GL_RGB, GL_UNSIGNED_BYTE,(const GLvoid *) &(this->whiteTexture));
+
+
+
+    // Get the number of patches
+    this->numPatches = 0;
+    this->patchOffset   = 0;
+
+    for( int i = 0; i < this->numFaces; i++) {
+      face& cFace = ((face *)(this->faces))[i];
+      if (SDL_SwapLE32(cFace.type) == 2)
+        this->numPatches += (SDL_SwapLE32(cFace.size[0]) -1 ) / 2  * (SDL_SwapLE32(cFace.size[1]) -1) / 2;
+    }
+
+    // Allocate Memory
+    this->patchVertice = new char[8*8*44*(this->numPatches+10)];
+    this->patchIndexes = new char[7*8*2*4*(this->numPatches+10)];
+ // this->patchRowIndexes = new int*[7*4*this->numPatches]; Not needed?
+    this->patchTrianglesPerRow = new char[7*4*this->numPatches];
+    this->VertexArrayModels  = new VertexArrayModel*[this->numPatches];
+
+    PRINTF(4)("BSP FILE:NumberOfPatches: %i . \n", numPatches);
+
+    this->swapAllBspCoordinates();
+
+    // Do tesselation for all Faces of type 2
+    for( int i = 0; i < this->numFaces; i++) {
+      if (SDL_SwapLE32((this->faces)[i].type) == 2)
+        this->tesselate(i);
+    }
+
+    PRINTF(4)("BSP FILE:PatchOffset: %i . \n", this->patchOffset);
+
+    return  1;
+  } else {
+    PRINTF(4)("BSP FILE: Datei nicht gefunden. \n");
+    return -1;
+  }
+
+
+
+}
+
+void BspFile::build_tree()
+{
+
+  PRINTF(4)("BSP FILE:\n");
+  PRINTF(4)("BSP FILE: Building Tree...\n");
+  root = this->build_tree_rec(0);
+  PRINTF(4)("BSP FILE: ...done. \n");
+  PRINTF(4)("BSP FILE:  \n");
+  PRINTF(4)("BSP FILE: Node #0: \n");
+  PRINTF(4)("BSP FILE:  x: %f \n",root->plane.x);
+  PRINTF(4)("BSP FILE:  y: %f\n",root->plane.y);
+  PRINTF(4)("BSP FILE:  z: %f\n",root->plane.z);
+}
+
+/**
+ *  Called by BspFile::build_tree() only.
+ */
+BspTreeNode*   BspFile::build_tree_rec(int i)
+{
+  // PRINTF(0)("BSP FILE: Node #%i\n", i);
+  BspTreeNode* thisNode = new BspTreeNode();
+  int left =(((node *) nodes) [i]).left;
+  int right =(((node *) nodes) [i]).right;
+  int planeIndex = (((node *) nodes) [i]).plane;
+  float x1 =(((plane *) this->planes) [planeIndex]).x;
+  float y1 =(((plane *) this->planes) [planeIndex]).y;
+  float z1 =(((plane *) this->planes) [planeIndex]).z;
+  thisNode->leafIndex = 0;
+  thisNode->d          = (((plane *) this->planes) [planeIndex]).d;
+
+  thisNode->plane = Vector(x1,y1,z1);
+  thisNode->isLeaf = false;
+
+  if(left >= 0) {
+    thisNode->left = this->build_tree_rec(left);
+  } else {
+    //BspTreeLeaf tmp =  BspTreeLeaf();
+    //tmp.isLeaf = true;
+    //tmp.leafIndex = -left -1;
+    //thisNode->left = (BspTreeNode*) (&tmp);
+    thisNode->left  = new BspTreeNode();
+    thisNode->left->isLeaf = true;
+    thisNode->left->leafIndex = - (left +1);
+    //PRINTF(0)("BSP FILE:  LeafIndex: %i\n",-left);
+  } // assign leav
+  if(right >= 0) {
+    thisNode->right =  this->build_tree_rec(right);
+  } else {
+    //BspTreeLeaf tmp =  BspTreeLeaf();
+    //tmp.isLeaf = true;
+    //tmp.leafIndex = -right -1;
+    //thisNode->right = (BspTreeNode*) (&tmp);
+    thisNode->right = new BspTreeNode();
+    thisNode->right->isLeaf = true;
+    thisNode->right->leafIndex = -(right +1);
+    //PRINTF(0)("BSP FILE:  LeafIndex: %i\n",-right);
+  } // assign leaf
+  return thisNode;
+}
+
+/**
+ *  returns the root node of the bsp-tree
+ */
+BspTreeNode* BspFile::get_root()
+{
+  return root;
+}
+
+void BspFile::load_textures()
+{
+  ::std::string absFileName;
+  char* baseName = "/worlds/bsp/";
+
+  char fileName [500];
+  char ext [500];
+  struct stat results;
+
+
+  this->Materials = new AMat[this->numTextures];
+  for(int i = 0 ; i < this->numTextures; i++) {
+    PRINTF(4)("BSP FILE: Texture : %s. \n", &this->textures[8+ 72*i]);
+
+
+    strcpy(fileName, &this->textures[8+ 72*i]);
+    if(strlen(fileName) == 0)
+    {
+
+     //         Default Material
+    this->Materials[i].mat = new Material();
+    this->Materials[i].mat->setDiffuse(0.1,0.1,1.0);
+    this->Materials[i].mat->setAmbient(0.1,0.1,1.0 );
+    this->Materials[i].mat->setSpecular(0.4,0.4,1.0);
+    //this->Materials[i]->setShininess(100.0);
+   // this->Materials[i].mat->setTransparency(1.0);
+    this->Materials[i].mat->setDiffuseMap("pictures/ground.tga");
+    this->Materials[i].mat->setAmbientMap("pictures/ground.tga");
+    this->Materials[i].mat->setSpecularMap("pictures/ground.tga");
+    this->Materials[i].alpha = false;
+    this->Materials[i].animated = false;
+     continue;
+    }
+
+      // Check for mov
+    strcpy(fileName, baseName);
+    strcpy(ext, &this->textures[8+ 72*i]);
+    strncat(fileName, ext, strlen(fileName) + strlen(&this->textures[8+ 72*i]) );
+    strcpy(ext, ".mov");
+    strncat (fileName, ext, strlen(fileName) );
+
+    PRINTF(4)("BSP FILE: Name %s . \n", fileName);
+
+    absFileName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+
+    if(File(absFileName).exists()) {
+      PRINTF(4)("BSP FILE: gefunden . \n");
+      this->Materials[i] = this->loadAVI(fileName);
+      continue;
+    }
+
+    // Check for avi
+    strcpy(fileName, baseName);
+    strcpy(ext, &this->textures[8+ 72*i]);
+    strncat(fileName, ext, strlen(fileName) + strlen(&this->textures[8+ 72*i]) );
+    strcpy(ext, ".avi");
+    strncat (fileName, ext, strlen(fileName));
+
+    absFileName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+
+    if(File(absFileName).exists()) {
+      PRINTF(4)("BSP FILE: gefunden . \n");
+      this->Materials[i] = this->loadAVI(fileName);
+      continue;
+    }
+
+       // Check for mpg
+    strcpy(fileName, baseName);
+    strcpy(ext, &this->textures[8+ 72*i]);
+    strncat(fileName, ext, strlen(fileName) + strlen(&this->textures[8+ 72*i]) );
+    strcpy(ext, ".mpg");
+    strncat (fileName, ext, strlen(fileName));
+
+    absFileName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+
+    if(File(absFileName).exists()) {
+      PRINTF(4)("BSP FILE: gefunden . \n");
+      this->Materials[i] = this->loadAVI(fileName);
+      continue;
+    }
+
+    // Check for tga
+    strcpy(fileName, baseName);
+    strcpy(ext, &this->textures[8+ 72*i]);
+    strncat(fileName, ext, strlen(fileName) + strlen(&this->textures[8+ 72*i]) );
+    strcpy(ext, ".tga");
+    strncat (fileName, ext, strlen(fileName));
+
+    absFileName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+
+    if(File(absFileName).exists()) {
+      PRINTF(4)("BSP FILE: gefunden . \n");
+      this->Materials[i] = this->loadMat(fileName);
+      continue;
+    }
+    // Check for TGA
+    strcpy(fileName, baseName);
+    strcpy(ext, &this->textures[8+ 72*i]);
+    strncat(fileName, ext, strlen(fileName) + strlen(&this->textures[8+ 72*i]) );
+    strcpy(ext, ".TGA");
+    strncat (fileName, ext, strlen(fileName));
+    absFileName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+
+    if(File(absFileName).exists()/*stat( absFileName.c_str() , &results) == 0*/) {
+      PRINTF(4)("BSP FILE: gefunden . \n");
+      this->Materials[i] = this->loadMat(fileName);
+      continue;
+    }
+    // Check for jpg
+    strcpy(fileName, baseName);
+    strcpy(ext, &this->textures[8+ 72*i]);
+    strncat(fileName, ext, strlen(fileName) + strlen(&this->textures[8+ 72*i]) );
+    strcpy(ext, ".jpg");
+    strncat (fileName, ext, strlen(fileName));
+    absFileName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+    if(File(absFileName).exists()) {
+      PRINTF(4)("BSP FILE: gefunden . \n");
+      this->Materials[i] =this->loadMat(fileName);
+      continue;
+    }
+
+
+    // Check for JPG
+    strcpy(fileName, baseName);
+    strcpy(ext, &this->textures[8+ 72*i]);
+    strncat(fileName, ext, strlen(fileName) + strlen(&this->textures[8+ 72*i]) );
+    strcpy(ext, ".JPG");
+    strncat (fileName, ext, strlen(fileName));
+    absFileName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+    if(File(absFileName).exists()) {
+      PRINTF(4)("BSP FILE: gefunden . \n");
+      this->Materials[i] =this->loadMat(fileName);
+      continue;
+    }
+
+
+
+    // Check for bmp
+    strcpy(fileName, baseName);
+    strcpy(ext, &this->textures[8+ 72*i]);
+    strncat(fileName, ext, strlen(fileName) + strlen(&this->textures[8+ 72*i]) );
+    strcpy(ext, ".bmp");
+    strncat (fileName, ext, strlen(fileName));
+    absFileName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+
+    if(File(absFileName).exists()) {
+      PRINTF(4)("BSP FILE: gefunden . \n");
+      this->Materials[i] =this->loadMat(fileName);
+      continue;
+    }
+
+    // Check for BMP
+    strcpy(fileName, baseName);
+    strcpy(ext, &this->textures[8+ 72*i]);
+    strncat(fileName, ext, strlen(fileName) + strlen(&this->textures[8+ 72*i]) );
+    strcpy(ext, ".BMP");
+    strncat (fileName, ext, strlen(fileName));
+    absFileName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+
+    if(File(absFileName).exists()) {
+      PRINTF(4)("BSP FILE: gefunden . \n");
+      this->Materials[i] = this->loadMat(fileName);
+      continue;
+    }
+
+    PRINTF(0)("BSP FILE: Texture %s not found.\n",&this->textures[8+ 72*i] );
+    //  Default Material
+    this->Materials[i].mat = new Material();
+    this->Materials[i].mat->setDiffuse(0.1,0.1,0.1);
+    this->Materials[i].mat->setAmbient(0.1,0.1,0.1 );
+    this->Materials[i].mat->setSpecular(0.4,0.4,0.4);
+    //this->Materials[i]->setShininess(100.0);
+    //this->Materials[i].mat->setTransparency(1.0);
+    this->Materials[i].mat->setDiffuseMap("pictures/error_texture.png");
+    this->Materials[i].mat->setAmbientMap("pictures/error_texture.png");
+    this->Materials[i].mat->setSpecularMap("pictures/error_texture.png");
+    this->Materials[i].alpha = true;
+    this->Materials[i].animated = false;
+
+  }
+}
+
+
+AMat BspFile::loadMat(char* mat)
+{
+  AMat tmpAMat;
+  this->testSurf = NULL;
+
+  this->testSurf = IMG_Load(Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(mat).c_str());
+  if(this->testSurf != NULL) {
+    if(this->testSurf->format->Amask != 0 ) tmpAMat.alpha = true;
+    else                                       tmpAMat.alpha = false;
+  } else   tmpAMat.alpha = false;
+
+  Material* tmp = new Material();
+   tmp->setDiffuse(1.0,1.0,1.0);
+   tmp->setAmbient(1.0,1.0,1.0 );
+  tmp->setSpecular(1.0,1.0,1.0);
+  //    tmp->setShininess(.5);
+  //    tmp->setTransparency(0.0);
+
+  tmp->setDiffuseMap(mat);
+
+  tmpAMat.mat = tmp;
+  tmpAMat.animated = false;
+  return tmpAMat;
+}
+
+AMat BspFile::loadAVI(char* mat)
+{
+  AMat tmpAMat;
+
+
+  MoviePlayer * testMC = new MoviePlayer(mat);
+  testMC->start(0);
+
+  this->MovieMaterials.push_back(testMC);
+
+  //Material* tmp = new Material();
+ // tmp->setDiffuse(1.0,1.0,1.0);
+  //tmp->setAmbient(1.0,1.0,1.0 );
+  //tmp->setSpecular(1.0,1.0,1.0);
+  //    tmp->setShininess(.5);tmpAMat
+  //    tmp->setTransparency(0.0);
+
+  //tmp->setDiffuseMap(mat);
+
+  tmpAMat.aviMat = testMC;
+  tmpAMat.animated = true;
+  tmpAMat.alpha = true;
+  return tmpAMat;
+}
+
+unsigned int BspFile::loadLightMapToGL(lightmap& lightMapTexture)
+{
+  int      errorCode = 0;           //!< the error code for the texture loading functions
+  unsigned int   lightMap;          //!< the OpenGL texture handle
+  int      mipmapLevel = 0;         //!< the maximum mipmap level for this texture
+  int      mipmapWidth = 0;         //!< the width of the mipmap
+  int      mipmapHight = 0;         //!< the height of the mipmap3
+  float sc, scale, temp;
+  for(int i = 0; i < 128*128*3 ; i++)
+  {
+  sc =  ((unsigned char *)(&lightMapTexture))[i];
+  sc *= 1/255.0;
+
+  scale = 1.0f; // Adjust brightness here
+
+  if(sc > 1.0f && (temp = (1.0f/sc)) < scale) scale=temp;
+  scale*=255.0;
+  sc*=scale;
+  if(false)
+    ((unsigned char *)(&lightMapTexture))[i] = (unsigned char)sc + 75;
+  else
+    ((unsigned char *)(&lightMapTexture))[i] = (unsigned char)sc ;
+  }
+
+  glGenTextures(1, &lightMap);
+  glBindTexture(GL_TEXTURE_2D,  lightMap);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_PRIORITY, 2);
+
+
+  /* control the mipmap levels */
+  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MIN_LOD, 5);
+  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MAX_LOD, 0);
+
+  /* build the Texture  OpenGL V >= 1.1 */
+   glTexImage2D(GL_TEXTURE_2D,
+                   0,
+                   GL_RGBA8,
+                   128,
+                   128,
+                   0,
+                   GL_RGB,
+                   GL_UNSIGNED_BYTE,
+                   (const GLvoid *)&lightMapTexture);
+
+
+   // build the MipMaps automaticaly
+   errorCode = gluBuild2DMipmaps(GL_TEXTURE_2D,
+GL_RGBA8,
+                                 128,
+                                 128,
+                                 GL_RGB,
+                                 GL_UNSIGNED_BYTE,
+                                 (const GLvoid *)&lightMapTexture
+                                );
+
+
+
+
+  return lightMap;
+
+}
+
+/**
+ * Generates a vertex-array, a indice-array and a texture-coordinates-array for iface.
+ * @param iface integer index of face
+ * @todo cleanup this function, let the user choose the level of tesselation
+ */
+
+
+void BspFile::tesselate(int iface)
+{
+  face*  Face =  &((this->faces)[iface]);
+  BspVertex *  BspVrtx = (BspVertex*)this->vertice;
+  int level = 7;
+  int level1 = 8;
+  int size0 = (Face->size[0]);
+  int size1 = (Face->size[1]);
+  // For each patch...
+  for(int i = 0; i <  ( size0 - 1)    ; i+=2) {
+    for(int j = 0; j < ( size1 -1)    ; j+=2) {
+
+
+      // Make a patch...
+      // Get controls[9];
+      BspVec controls[9];
+      BspVec controlsTmp[9];
+      BspVertex VControls[9];
+      for(int k = 0; k < 3; k++) {
+        for(int l = 0; l < 3; l++) {
+          controls[k +3*l]. position[0] =   (    BspVrtx[Face->vertex + (j * size0)+ i + l+ size0*k].position[0]);
+          controls[k +3*l]. position[1] =   (    BspVrtx[Face->vertex + (j * size0)+ i +l+ size0*k].position[1]);
+          controls[k +3*l]. position[2] =   (    BspVrtx[Face->vertex + (j * size0)+ i + l+ size0*k].position[2]); /*Face->n_vertexes*/
+
+          controlsTmp[2-k +6-3*l]. position[0] =   (    BspVrtx[Face->vertex +( j * size0)+ i + l+ size0*k].position[0]);
+          controlsTmp[2-k +6-3*l]. position[1] =   (    BspVrtx[Face->vertex + (j * size0)+ i +l+ size0*k].position[1]);
+          controlsTmp[2-k +6-3*l]. position[2] =   (    BspVrtx[Face->vertex + (j * size0)+ i + l+ size0*k].position[2]); /*Face->n_vertexes*/
+
+          VControls[k +3*l]. position[0] =   (    BspVrtx[Face->vertex +( j * size0)+ i + l+ size0*k].position[0]);
+          VControls[k +3*l]. position[1] =   (    BspVrtx[Face->vertex + (j * size0)+ i +l+ size0*k].position[1]);
+          VControls[k +3*l]. position[2] =   (    BspVrtx[Face->vertex + (j * size0)+ i + l+ size0*k].position[2]);
+
+          VControls[k +3*l]. normal[0] =   (    BspVrtx[Face->vertex +( j * size0)+ i + l+ size0*k].normal[0]);
+          VControls[k +3*l]. normal[1] =   (    BspVrtx[Face->vertex + (j * size0)+ i +l+ size0*k].normal[1]);
+          VControls[k +3*l]. normal[2] =   (    BspVrtx[Face->vertex + (j * size0)+ i + l+ size0*k].normal[2]);
+
+          VControls[k +3*l]. texcoord[0][0]=    (    BspVrtx[Face->vertex +( j * size0)+ i + l+ size0*k].texcoord[0][0]);
+          VControls[k +3*l]. texcoord[0][1] =   (    BspVrtx[Face->vertex + (j * size0)+ i +l+ size0*k].texcoord[0][1]);
+          VControls[k +3*l]. texcoord[1][0] =   (    BspVrtx[Face->vertex +( j * size0)+ i + l+ size0*k].texcoord[1][0]);
+          VControls[k +3*l]. texcoord[1][1] =   (    BspVrtx[Face->vertex + (j * size0)+ i +l+ size0*k].texcoord[1][1]);
+
+
+        }
+      }
+      //***********************************************************************************************************************
+      // Compute the vertice
+      //***********************************************************************************************************************
+      float px, py;
+      BspVertex temp[3];
+      BspVertex* Vertice = &(((BspVertex*)this->patchVertice)[level1*level1*this->patchOffset]);
+
+      for(int v=0; v<=level; ++v) {
+        px=(float)v/level;
+
+        Vertice[v].position[0]=VControls[0].position[0]*((1.0f-px)*(1.0f-px))+VControls[3].position[0]*((1.0f-px)*px*2)+VControls[6].position[0]*(px*px);
+        Vertice[v].position[1]=VControls[0].position[1]*((1.0f-px)*(1.0f-px))+VControls[3].position[1]*((1.0f-px)*px*2)+VControls[6].position[1]*(px*px);
+        Vertice[v].position[2]=VControls[0].position[2]*((1.0f-px)*(1.0f-px))+VControls[3].position[2]*((1.0f-px)*px*2)+VControls[6].position[2]*(px*px);
+
+        Vertice[v].normal[0]=VControls[0].normal[0]*((1.0f-px)*(1.0f-px))+VControls[3].normal[0]*((1.0f-px)*px*2)+VControls[6].normal[0]*(px*px);
+        Vertice[v].normal[1]=VControls[0].normal[1]*((1.0f-px)*(1.0f-px))+VControls[3].normal[1]*((1.0f-px)*px*2)+VControls[6].normal[1]*(px*px);
+        Vertice[v].normal[2]=VControls[0].normal[2]*((1.0f-px)*(1.0f-px))+VControls[3].normal[2]*((1.0f-px)*px*2)+VControls[6].normal[2]*(px*px);
+
+        Vertice[v].texcoord[0][0]=VControls[0].texcoord[0][0]*((1.0f-px)*(1.0f-px))+VControls[3].texcoord[0][0]*((1.0f-px)*px*2)+VControls[6].texcoord[0][0]*(px*px);
+        Vertice[v].texcoord[0][1]=VControls[0].texcoord[0][1]*((1.0f-px)*(1.0f-px))+VControls[3].texcoord[0][1]*((1.0f-px)*px*2)+VControls[6].texcoord[0][1]*(px*px);
+        Vertice[v].texcoord[1][0]=VControls[0].texcoord[1][0]*((1.0f-px)*(1.0f-px))+VControls[3].texcoord[1][0]*((1.0f-px)*px*2)+VControls[6].texcoord[1][0]*(px*px);
+        Vertice[v].texcoord[1][1]=VControls[0].texcoord[1][1]*((1.0f-px)*(1.0f-px))+VControls[3].texcoord[1][1]*((1.0f-px)*px*2)+VControls[6].texcoord[1][1]*(px*px);
+
+      }
+
+
+      for(int u=1; u<=level; ++u) {
+        py=(float)u/level;
+
+        // temp[0]=controlPoints[0]*((1.0f-py)*(1.0f-py))+ controlPoints[1]*((1.0f-py)*py*2)+ controlPoints[2]*(py*py);
+        temp[0].position[0]=VControls[0].position[0]*((1.0f-py)*(1.0f-py))+VControls[1].position[0]*((1.0f-py)*py*2)+VControls[2].position[0]*(py*py);
+        temp[0].position[1]=VControls[0].position[1]*((1.0f-py)*(1.0f-py))+VControls[1].position[1]*((1.0f-py)*py*2)+VControls[2].position[1]*(py*py);
+        temp[0].position[2]=VControls[0].position[2]*((1.0f-py)*(1.0f-py))+VControls[1].position[2]*((1.0f-py)*py*2)+VControls[2].position[2]*(py*py);
+
+        temp[0].normal[0]=VControls[0].normal[0]*((1.0f-py)*(1.0f-py))+VControls[1].normal[0]*((1.0f-py)*py*2)+VControls[2].normal[0]*(py*py);
+        temp[0].normal[1]=VControls[0].normal[1]*((1.0f-py)*(1.0f-py))+VControls[1].normal[1]*((1.0f-py)*py*2)+VControls[2].normal[1]*(py*py);
+        temp[0].normal[2]=VControls[0].normal[2]*((1.0f-py)*(1.0f-py))+VControls[1].normal[2]*((1.0f-py)*py*2)+VControls[2].normal[2]*(py*py);
+
+        temp[0].texcoord[0][0]=VControls[0].texcoord[0][0]*((1.0f-py)*(1.0f-py))+VControls[1].texcoord[0][0]*((1.0f-py)*py*2)+VControls[2].texcoord[0][0]*(py*py);
+        temp[0].texcoord[0][1]=VControls[0].texcoord[0][1]*((1.0f-py)*(1.0f-py))+VControls[1].texcoord[0][1]*((1.0f-py)*py*2)+VControls[2].texcoord[0][1]*(py*py);
+        temp[0].texcoord[1][0]=VControls[0].texcoord[1][0]*((1.0f-py)*(1.0f-py))+VControls[1].texcoord[1][0]*((1.0f-py)*py*2)+VControls[2].texcoord[1][0]*(py*py);
+        temp[0].texcoord[1][1]=VControls[0].texcoord[1][1]*((1.0f-py)*(1.0f-py))+VControls[1].texcoord[1][1]*((1.0f-py)*py*2)+VControls[2].texcoord[1][1]*(py*py);
+
+
+
+        // temp[1]=controlPoints[3]*((1.0f-py)*(1.0f-py))+ controlPoints[4]*((1.0f-py)*py*2)+ controlPoints[5]*(py*py);
+        temp[1].position[0]=VControls[3].position[0]*((1.0f-py)*(1.0f-py))+VControls[4].position[0]*((1.0f-py)*py*2)+VControls[5].position[0]*(py*py);
+        temp[1].position[1]=VControls[3].position[1]*((1.0f-py)*(1.0f-py))+VControls[4].position[1]*((1.0f-py)*py*2)+VControls[5].position[1]*(py*py);
+        temp[1].position[2]=VControls[3].position[2]*((1.0f-py)*(1.0f-py))+VControls[4].position[2]*((1.0f-py)*py*2)+VControls[5].position[2]*(py*py);
+
+        temp[1].normal[0]=VControls[3].normal[0]*((1.0f-py)*(1.0f-py))+VControls[4].normal[0]*((1.0f-py)*py*2)+VControls[5].normal[0]*(py*py);
+        temp[1].normal[1]=VControls[3].normal[1]*((1.0f-py)*(1.0f-py))+VControls[4].normal[1]*((1.0f-py)*py*2)+VControls[5].normal[1]*(py*py);
+        temp[1].normal[2]=VControls[3].normal[2]*((1.0f-py)*(1.0f-py))+VControls[4].normal[2]*((1.0f-py)*py*2)+VControls[5].normal[2]*(py*py);
+
+        temp[1].texcoord[0][0]=VControls[3].texcoord[0][0]*((1.0f-py)*(1.0f-py))+VControls[4].texcoord[0][0]*((1.0f-py)*py*2)+VControls[5].texcoord[0][0]*(py*py);
+        temp[1].texcoord[0][1]=VControls[3].texcoord[0][1]*((1.0f-py)*(1.0f-py))+VControls[4].texcoord[0][1]*((1.0f-py)*py*2)+VControls[5].texcoord[0][1]*(py*py);
+        temp[1].texcoord[1][0]=VControls[3].texcoord[1][0]*((1.0f-py)*(1.0f-py))+VControls[4].texcoord[1][0]*((1.0f-py)*py*2)+VControls[5].texcoord[1][0]*(py*py);
+        temp[1].texcoord[1][1]=VControls[3].texcoord[1][1]*((1.0f-py)*(1.0f-py))+VControls[4].texcoord[1][1]*((1.0f-py)*py*2)+VControls[5].texcoord[1][1]*(py*py);
+
+
+        // temp[2]=controlPoints[6]*((1.0f-py)*(1.0f-py))+controlPoints[7]*((1.0f-py)*py*2)+controlPoints[8]*(py*py);
+        temp[2].position[0]=VControls[6].position[0]*((1.0f-py)*(1.0f-py))+VControls[7].position[0]*((1.0f-py)*py*2)+VControls[8].position[0]*(py*py);
+        temp[2].position[1]=VControls[6].position[1]*((1.0f-py)*(1.0f-py))+VControls[7].position[1]*((1.0f-py)*py*2)+VControls[8].position[1]*(py*py);
+        temp[2].position[2]=VControls[6].position[2]*((1.0f-py)*(1.0f-py))+VControls[7].position[2]*((1.0f-py)*py*2)+VControls[8].position[2]*(py*py);
+
+        temp[2].normal[0]=VControls[6].normal[0]*((1.0f-py)*(1.0f-py))+VControls[7].normal[0]*((1.0f-py)*py*2)+VControls[8].normal[0]*(py*py);
+        temp[2].normal[1]=VControls[6].normal[1]*((1.0f-py)*(1.0f-py))+VControls[7].normal[1]*((1.0f-py)*py*2)+VControls[8].normal[1]*(py*py);
+        temp[2].normal[2]=VControls[6].normal[2]*((1.0f-py)*(1.0f-py))+VControls[7].normal[2]*((1.0f-py)*py*2)+VControls[8].normal[2]*(py*py);
+
+        temp[2].texcoord[0][0]=VControls[6].texcoord[0][0]*((1.0f-py)*(1.0f-py))+VControls[7].texcoord[0][0]*((1.0f-py)*py*2)+VControls[8].texcoord[0][0]*(py*py);
+        temp[2].texcoord[0][1]=VControls[6].texcoord[0][1]*((1.0f-py)*(1.0f-py))+VControls[7].texcoord[0][1]*((1.0f-py)*py*2)+VControls[8].texcoord[0][1]*(py*py);
+        temp[2].texcoord[1][0]=VControls[6].texcoord[1][0]*((1.0f-py)*(1.0f-py))+VControls[7].texcoord[1][0]*((1.0f-py)*py*2)+VControls[8].texcoord[1][0]*(py*py);
+        temp[2].texcoord[1][1]=VControls[6].texcoord[1][1]*((1.0f-py)*(1.0f-py))+VControls[7].texcoord[1][1]*((1.0f-py)*py*2)+VControls[8].texcoord[1][1]*(py*py);
+
+
+
+
+        for(int v=0; v<=level; ++v) {
+          px=(float)v/level;
+
+
+
+
+
+          //Vertice[u*(tesselation+1)+v]=       temp[0]*((1.0f-px)*(1.0f-px))+ temp[1]*((1.0f-px)*px*2)+ temp[2]*(px*px);
+          Vertice[u*(level1)+v].position[0]=temp[0].position[0]*((1.0f-px)*(1.0f-px))+temp[1].position[0]*((1.0f-px)*px*2)+temp[2].position[0]*(px*px);
+          Vertice[u*(level1)+v].position[1]=temp[0].position[1]*((1.0f-px)*(1.0f-px))+temp[1].position[1]*((1.0f-px)*px*2)+temp[2].position[1]*(px*px);
+          Vertice[u*(level1)+v].position[2]=temp[0].position[2]*((1.0f-px)*(1.0f-px))+temp[1].position[2]*((1.0f-px)*px*2)+temp[2].position[2]*(px*px);
+
+          Vertice[u*(level1)+v].normal[0]=temp[0].normal[0]*((1.0f-px)*(1.0f-px))+temp[1].normal[0]*((1.0f-px)*px*2)+temp[2].normal[0]*(px*px);
+          Vertice[u*(level1)+v].normal[1]=temp[0].normal[1]*((1.0f-px)*(1.0f-px))+temp[1].normal[1]*((1.0f-px)*px*2)+temp[2].normal[1]*(px*px);
+          Vertice[u*(level1)+v].normal[2]=temp[0].normal[2]*((1.0f-px)*(1.0f-px))+temp[1].normal[2]*((1.0f-px)*px*2)+temp[2].normal[2]*(px*px);
+
+          Vertice[u*(level1)+v].texcoord[0][0]=temp[0].texcoord[0][0]*((1.0f-px)*(1.0f-px))+temp[1].texcoord[0][0]*((1.0f-px)*px*2)+temp[2].texcoord[0][0]*(px*px);
+          Vertice[u*(level1)+v].texcoord[0][1]=temp[0].texcoord[0][1]*((1.0f-px)*(1.0f-px))+temp[1].texcoord[0][1]*((1.0f-px)*px*2)+temp[2].texcoord[0][1]*(px*px);
+          Vertice[u*(level1)+v].texcoord[1][0]=temp[0].texcoord[1][0]*((1.0f-px)*(1.0f-px))+temp[1].texcoord[1][0]*((1.0f-px)*px*2)+temp[2].texcoord[1][0]*(px*px);
+          Vertice[u*(level1)+v].texcoord[1][1]=temp[0].texcoord[1][1]*((1.0f-px)*(1.0f-px))+temp[1].texcoord[1][1]*((1.0f-px)*px*2)+temp[2].texcoord[1][1]*(px*px);
+
+
+
+        }
+      }
+
+      //Create indices
+      GLuint* indices= & ((GLuint*)(this->patchIndexes))[level*level1*2*this->patchOffset];
+
+      for(int row=0; row<level; ++row) {
+        for(int point=0; point<=level; ++point) {
+          //calculate indices
+          //reverse them to reverse winding
+          indices[(row*(level1)+point)*2+1]=row*(level1)+point;
+          indices[(row*(level1)+point)*2]=(row+1)*(level1)+point;
+        }
+      }
+
+
+      //***********************************************************************************************************************
+      // Debug Model
+      //***********************************************************************************************************************
+
+      this->VertexArrayModels[this->patchOffset] = new VertexArrayModel();
+      VertexArrayModel*  tmp = this->VertexArrayModels[this->patchOffset];
+      tmp->newStripe();
+      int a = 0;
+      int b = -1;
+      tmp->addVertex(controlsTmp[0].position[0],controlsTmp[0].position[1], controlsTmp[0].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(0.0,0.0);
+      tmp->addColor(0.3,0.0,0.0);
+      tmp->addIndice(1+b);
+      tmp->addIndice(4+a);
+      tmp->addVertex(controlsTmp[1].position[0],controlsTmp[1].position[1], controlsTmp[1].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(0.0,0.4);
+      tmp->addColor(0.3,0.0,0.0);
+      tmp->addIndice(2+b);
+      tmp->addIndice(5+a);
+      tmp->addVertex(controlsTmp[2].position[0],controlsTmp[2].position[1], controlsTmp[2].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(0.0,1.0);
+      tmp->addColor(0.1,0.0,0.0);
+      tmp->addIndice(3+b);
+      tmp->addIndice(6+a);
+
+      tmp->addVertex(controlsTmp[2].position[0],controlsTmp[2].position[1], controlsTmp[2].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(0.0,1.0);
+      tmp->addColor(0.1,0.0,0.0);
+      tmp->addIndice(7+a);
+      //tmp->addIndice(6);
+
+      tmp->newStripe();
+
+      tmp->addVertex(controlsTmp[0].position[0],controlsTmp[0].position[1], controlsTmp[0].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(0.0,0.0);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(5+b);
+      tmp->addIndice(8+a);
+      tmp->addVertex(controlsTmp[1].position[0],controlsTmp[1].position[1], controlsTmp[1].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(0.0,0.4);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(6+b);
+      tmp->addIndice(9+a);
+      tmp->addVertex(controlsTmp[2].position[0],controlsTmp[2].position[1], controlsTmp[2].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(0.0,1.0);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(7+b);
+      tmp->addIndice(10+a);
+      tmp->addVertex(controlsTmp[2].position[0],controlsTmp[2].position[1], controlsTmp[2].position[2]+0.01);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(0.0,1.0);
+      tmp->addColor(0.1,0.1,0.1);
+      //tmp->addIndice(5);
+      tmp->addIndice(11+a);
+
+      tmp->newStripe();
+
+
+
+      tmp->addVertex(controlsTmp[3].position[0],controlsTmp[3].position[1], controlsTmp[3].position[2]);
+      tmp->addNormal(0,1,0);
+      tmp->addTexCoor(0.5,0.0);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(9+b);
+      tmp->addIndice(12+a);
+      tmp->addVertex(controlsTmp[4].position[0],controlsTmp[4].position[1], controlsTmp[4].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(0.5,0.5);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(10+b);
+      tmp->addIndice(13+a);
+      tmp->addVertex(controlsTmp[5].position[0],controlsTmp[5].position[1], controlsTmp[5].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(0.5,1.0);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(11+b);
+      tmp->addIndice(14+a);
+      tmp->addVertex(controlsTmp[5].position[0],controlsTmp[5].position[1], controlsTmp[5].position[2]+0.01);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(0.5,1.0);
+      tmp->addColor(0.1,0.1,0.1);
+
+      tmp->addIndice(15+a);
+      //tmp->addIndice(9);
+      tmp->newStripe();
+
+      tmp->addVertex(controlsTmp[6].position[0],controlsTmp[6].position[1], controlsTmp[6].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(1.0,0.0);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(13+b);
+      tmp->addIndice(16+a);
+
+      tmp->addVertex(controlsTmp[7].position[0],controlsTmp[7].position[1], controlsTmp[7].position[2]);
+      tmp->addNormal(0,1,0);
+      tmp->addTexCoor(1.0,0.5);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(14+b);
+      tmp->addIndice(17+a);
+      tmp->addVertex(controlsTmp[8].position[0],controlsTmp[8].position[1], controlsTmp[8].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(1.0,1.0);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(15+b);
+      tmp->addIndice(18+a);
+      tmp->addVertex(controlsTmp[8].position[0],controlsTmp[8].position[1], controlsTmp[8].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(1.0,1.0);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(19+a);
+      //tmp->addIndice(13);
+
+      tmp->newStripe();
+      tmp->addVertex(controlsTmp[6].position[0],controlsTmp[6].position[1], controlsTmp[6].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(1.0,0.0);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(17+b);
+
+      tmp->addVertex(controlsTmp[7].position[0],controlsTmp[7].position[1], controlsTmp[7].position[2]);
+      tmp->addNormal(0,1,0);
+      tmp->addTexCoor(1.0,0.5);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(18+b);
+
+      tmp->addVertex(controlsTmp[8].position[0],controlsTmp[8].position[1], controlsTmp[8].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(1.0,1.0);
+      tmp->addColor(0.1,0.1,0.1);
+      tmp->addIndice(19+b);
+
+      tmp->addVertex(controlsTmp[8].position[0],controlsTmp[8].position[1], controlsTmp[8].position[2]);
+      tmp->addNormal(1,0,0);
+      tmp->addTexCoor(1.0,1.0);
+      tmp->addColor(0.1,0.1,0.1);
+
+      tmp->newStripe();
+
+      tmp->finalize();
+      // End of DebugModel
+
+      this->patchOffset++;
+    }// For
+  } // For
+
+  // Overwrite Face->meshvert;
+  // Overwrite Face->n_meshverts;
+  int sz = (size0 -1)/2 * (size1 -1)/2; // num patches
+  Face->meshvert = patchOffset -sz;  //3*(patchOffset-sz)*level1*level1;
+  Face->n_meshverts = sz;
+  PRINTF(0)("BSP FILE: sz: %i. \n", sz);
+  PRINTF(0)("BSP FILE: Face->meshvert %i . \n", Face->meshvert);
+
+  //Face->n_meshverts = sz;
+}
+
+//!TODO: This is a good place to do LittleEndian to BigEndian conversion!
+void BspFile::swapAllBspCoordinates()
+{
+
+  for(int i = 0; i < this->numVertex ; ++i)
+  {
+    this->swapCoords(&((BspVertex *)this->vertice)[i].position[0]);
+    this->swapCoords(&((BspVertex *)this->vertice)[i].normal[0]);
+
+
+  }
+
+  for(int i = 0; i < this->numLeafs ; ++i)
+  {
+    this->swapCoords(this->leaves[i].mins);
+    this->swapCoords(this->leaves[i].maxs);
+
+  }
+
+  for(int i = 0; i < this->numPlanes; ++i)
+  {
+    float sto = this->planes[i].x;
+    this->planes[i].x =  this->planes[i].y;
+    this->planes[i].y =  this->planes[i].z;
+    this->planes[i].z = sto;
+    this->planes[i].d = scale * this->planes[i].d ;
+  }
+
+
+  for(int i = 0; i < this->numFaces; ++i)
+  {
+    this->swapCoords(this->faces[i].normal);
+  }
+
+}
+
+void BspFile::swapCoords(int *array)
+{
+  if( scale < 1)
+  {
+  int sto  =  array[0];
+  array[0] =  array[1] / (int) ( 1/ scale);
+  array[1] = array[2] / (int) (1/scale);
+  array[2] =  sto / (int) (1/scale);
+  }
+  else
+  {
+    int sto  =  array[0];
+    array[0] =  scale * array[1] ;
+    array[1] =  scale * array[2];
+    array[2] =  scale * sto ;
+  }
+
+}
+
+void BspFile::swapCoords(float * array)
+{
+  float sto  =  array[0];
+  array[0] =  scale * array[1];
+  array[1] =  scale * array[2];
+  array[2] =  scale * sto;
+}
+
Index: branches/heathaze/src/lib/graphics/importer/bsp_file.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/bsp_file.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/bsp_file.h	(revision 9940)
@@ -0,0 +1,218 @@
+/*
+ orxonox - the future of 3D-vertical-scrollers
+ 
+ Copyright (C) 2006 orx
+ 
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+ 
+ ### File Specific:
+ main-programmer: bottac@ee.ethz.ch
+ 
+  Inspired by:
+  Rendering Q3 Maps by Morgan McGuire                  http://graphics.cs.brown.edu/games/quake/quake3.html
+  Unofficial Quake 3 Map Specs by Kekoa Proudfoot      http://graphics.stanford.edu/~kekoa/q3/
+  Quake 3 Collision Detection by Nathan Ostgard        http://www.devmaster.net/articles/quake3collision/
+*/
+
+#include <vector>
+class SDL_Surface;
+class BspTreeNode;
+class Vector;
+class Material;
+class MoviePlayer;
+class VertexArrayModel;
+
+
+ struct plane
+{
+  float x;     //!< 1st component of the plane's normal
+  float y;     //!< 2nd component of the plane's normal
+  float z;     //!< 3rd component of the plane's normal
+  float d;     //!< distance of the plane to the origin
+};
+
+typedef struct
+{
+  float mins [ 3 ]; //!< Bounding box min coord.
+  float maxs [ 3 ]; //!< Bounding box max coord.
+  int face;         //!< First face for model.
+  int n_faces;      //!< Number of faces for model.
+  int brush;        //!< First brush for model.
+  int n_brushes;    //!< Number of brushes
+}
+model;
+
+typedef struct
+{
+  int plane;        //!< Plane index.
+  int left;         //!< 1st Child index. Negative numbers are leaf indices: -(leaf+1).
+  int right;        //!< 2nd Child index. Negative numbers are leaf indices: -(leaf+1).
+  int mins[ 3 ];    //!< Integer bounding box min coord.
+  int maxs[ 3 ];    //!< Integer bounding box max coord.
+}
+node;
+
+typedef struct
+{
+  int cluster;            //!< Visdata cluster index.
+  int area;               //!< Areaportal area.
+  int mins[ 3 ];          //!< Integer bounding box min coord.
+  int maxs[ 3 ];          //!< Integer bounding box max coord.
+  int leafface;           //!< First leafface for leaf.
+  int n_leaffaces;        //!< Number of leaffaces for leaf.
+  int leafbrush_first;    //!< leafbrush for leaf.
+  int n_leafbrushes;      //!< Number of leafbrushes for leaf.
+}
+leaf;
+
+struct brush
+{
+  int brushside; 	//!< First brushside for brush.
+  int n_brushsides; 	//!< Number of brushsides for brush.
+  int texture; 	        //!< Texture index.
+};
+
+typedef struct
+{
+  int plane;    //!< Plane index.
+  int texture; 	//!< Texture index.
+}
+brushside;
+
+struct face
+{
+  int texture;    	//!< Texture index.
+  int effect; 	        //!< Index into lump 12 (Effects), or -1.
+  int type; 	        //!< Face type. 1=polygon, 2=patch, 3=mesh, 4=billboard
+  int vertex; 	        //!< Index of first vertex.
+  int n_vertexes;       //!< Number of vertices.
+  int meshvert;         //!< Index of first meshvert.
+  int n_meshverts;      //!< Number of meshverts.
+  int lm_index;         //!< Lightmap index.
+  int lm_start [ 2 ];   //!< Corner of this face's lightmap image in lightmap.
+  int lm_size [ 2 ];     //!< Size of this face's lightmap image in lightmap.
+  float lm_origin [ 3 ] ;    //!<  World space origin of lightmap.
+  float lm_vecs [ 2 ][ 3 ];  //!< World space lightmap s and t unit vectors.
+  float normal[ 3 ];         //!< Surface normal.
+  int size [ 2 ] ;           //!< Patch dimensions.
+} ;
+
+typedef struct
+{
+  float position[ 3 ];        //!< Vertex position.
+  float texcoord[ 2 ][ 2 ];   //!< Vertex texture coordinates. [0][x]=surface, [1][x]=lightmap.
+  float normal[ 3 ];          //!< Vertex normal.
+  unsigned char color [ 4 ];  //!< Vertex color. RGBA.
+}
+BspVertex;
+
+typedef struct
+{
+  int offset;
+}
+meshvert;                    //!< Integer offset to mesh vertex
+
+typedef struct
+{
+  float position [ 3 ];
+}
+BspVec;
+
+typedef struct
+{
+  Material* mat;
+  MoviePlayer* aviMat;
+  bool alpha;
+  bool animated;
+}
+AMat;
+
+typedef struct
+{
+  unsigned char map [128][128][3];
+}
+lightmap;
+
+typedef struct
+{
+  char name[64];
+  int flags;
+  int contents;
+}
+BspTexture;
+
+class BspFile
+{
+  friend class BspManager;
+
+public:
+  BspFile();
+  ~BspFile();
+  int read(const char* name );
+  void build_tree();
+  void load_textures();
+  void tesselate( int iface );
+  BspTreeNode* get_root();
+  AMat loadMat( char* mat );
+  AMat loadAVI(char * mat);
+ 
+
+private:
+  BspTreeNode* root;
+  char header [ 280 ];       //!< Buffer for header of BSP-File
+  node* nodes;               //!< Buffer to store BSP-Tree-Nodes
+  leaf* leaves;              //!< Buffer to store BSP-Tree-Leaves
+  plane* planes;             //!< Buffer to store planes separateing the space
+  model* bspModels;          //!< Buffer to store BSP-Model-List
+  char* leafFaces;           //!< Buffer to store leafFaces
+  face* faces;               //!<
+  char* leafBrushes;         //!< Buffer to store brush indice
+  brush* brushes;            //!< Buffer to store  brushes
+  brushside* brushSides;     //!<
+  char* vertice;             //!<
+  meshvert* meshverts;       //!< Buffer to store meshverice
+  char* visData;             //!< Buffer to store visibility data
+  char* textures;            //!< Holds all the texture filename strings
+  char* patchVertice;        //!<
+  char* patchIndexes;
+  char* patchTrianglesPerRow;
+  lightmap* lightMaps;       //!< Buffer to store lightmap-images
+
+
+  int** patchRowIndexes;
+  VertexArrayModel** VertexArrayModels; 
+  int patchOffset;
+
+  int numNodes;
+  int numLeafs;
+  int numVertex;
+  int numPlanes;
+  int numBspModels;
+  int numLeafFaces;
+  int numFaces;
+  int numLeafBrushes;
+  int numTextures;
+  int numPatches;
+  int numBrushSides;
+  int numLightMaps;
+  
+  float  scale;
+
+  BspTreeNode* build_tree_rec( int i );
+  unsigned int loadLightMapToGL(lightmap&);
+  AMat* Materials;
+  unsigned int* glLightMapTextures;
+  unsigned int whiteLightMap;
+  unsigned char whiteTexture[3];
+  void swapAllBspCoordinates();
+  void swapCoords(int * array);
+  void swapCoords(float * array);
+  SDL_Surface* testSurf;
+
+ 
+  ::std::vector<MoviePlayer* > MovieMaterials; //!< Movieplayer Materials
+};
+
Index: branches/heathaze/src/lib/graphics/importer/bsp_manager.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/bsp_manager.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/bsp_manager.cc	(revision 9940)
@@ -0,0 +1,1677 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: bottac@ee.ethz.ch
+
+   Inspired by:
+   Rendering Q3 Maps by Morgan McGuire                  http://graphics.cs.brown.edu/games/quake/quake3.html
+   Unofficial Quake 3 Map Specs by Kekoa Proudfoot      http://graphics.stanford.edu/~kekoa/q3/
+
+   Collision detection adapted from:
+   Quake 3 Collision Detection by Nathan Ostgard        http://www.devmaster.net/articles/quake3collision/
+*/
+
+
+#include "vector.h"
+#include "bsp_file.h"
+#include "bsp_manager.h"
+#include "bsp_tree_leaf.h"
+#include "p_node.h"
+#include "state.h"
+#include "debug.h"
+#include "material.h"
+#include "camera.h"
+#include "vertex_array_model.h"
+#include "world_entities/player.h"
+#include "world_entities/playable.h"
+
+// STL Containers
+#include <vector>
+#include <deque>
+#include "movie_player.h"
+
+#include "world_entity.h"
+
+#include "util/loading/resource_manager.h"
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "aabb.h"
+#include "cr_defs.h"
+
+
+//CREATE_FACTORY( BspManager, CL_BSP_MODEL);
+
+BspManager::BspManager(WorldEntity* parent)
+{
+
+  this->lastTex = -1;
+  this->parent = parent;
+  /*// open a BSP file
+  this->bspFile = new BspFile();
+  this->bspFile->scale = 0.4f;
+  this->bspFile->read(ResourceManager::getFullName("test.bsp").c_str());
+  this->bspFile->build_tree();
+  this->root  = this->bspFile->get_root();
+  this->alreadyVisible = new bool [this->bspFile->numFaces];
+  */
+
+}
+
+
+/*
+BspManager::BspManager(const TiXmlElement* root)
+{
+
+
+  if( root != NULL)
+    this->loadParams(root);
+
+  CDEngine::getInstance()->setBSPModel(this);
+} */
+
+BspManager::~BspManager()
+{
+  if(this->bspFile)
+    delete this->bspFile;
+}
+
+int BspManager::load(const char* fileName, float scale)
+{
+  // open a BSP file
+
+
+  this->bspFile = new BspFile();
+  this->bspFile->scale =  scale;
+  if(this->bspFile->read(Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName).c_str()) == -1)
+    return -1;
+
+  this->bspFile->build_tree();
+  this->root  = this->bspFile->get_root();
+  this->alreadyVisible = new bool [this->bspFile->numFaces];
+
+  this->outputFraction = 1.0f;
+
+  return 0;
+}
+
+
+/*
+BspManager::BspManager(const char* fileName, float scale)
+{
+  // open a BSP file
+  this->bspFile = new BspFile();
+  this->bspFile->scale =  scale;
+  this->bspFile->read(fileName);
+  this->bspFile->build_tree();
+  this->root  = this->bspFile->get_root();
+  this->alreadyVisible = new bool [this->bspFile->numFaces];
+
+  CDEngine::getInstance()->setBSPModel(this);
+}
+*/
+
+const void BspManager::tick(float time)
+{
+
+  if(!this->bspFile->MovieMaterials.empty()) {
+    ::std::vector<MoviePlayer *>::iterator it = this->bspFile->MovieMaterials.begin() ;
+    while(it != this->bspFile->MovieMaterials.end()) {
+      (*it)->tick(time);
+      it++;
+    }
+    //this->bspFile->MovieMaterials.front()->tick(time );
+
+
+  }
+
+}
+const void BspManager::draw()
+{
+
+  /*
+  this->drawDebugCube(&this->out);
+  this->out1 = this->out;
+  this->out2 = this->out;
+  if(this->collPlane != NULL) {
+    this->out1.x += this->collPlane->x*5.0;
+    this->out1.y += this->collPlane->y*5.0;
+    this->out1.z += this->collPlane->z*5.0;
+
+    this->out2.x += this->collPlane->x*10.0;
+    this->out2.y += this->collPlane->y*10.0;
+    this->out2.z += this->collPlane->z*10.0;
+  }
+  this->drawDebugCube(&this->out1);
+  this->drawDebugCube(&this->out2);
+
+  */
+
+
+  // Draw Debug Terrain
+  /*
+  this->bspFile->Materials[0]->select();
+  for(int i = 0; i <  this->bspFile->numPatches ; i++)
+        {
+                this->bspFile->VertexArrayModels[i]->draw();
+
+        }
+  */
+
+
+
+  // erase alreadyVisible
+  for(int i = 0; i < this->bspFile->numFaces; i++) this->alreadyVisible[i] = false;
+  float tmp = 0;
+  //this->opal.clear();
+  //this->trasparent.clear();
+  // Find all visible faces...
+
+  this->cam = State::getCamera()->getAbsCoor() ;
+  //this->ship = State::getCameraTargetNode()->getAbsCoor();
+
+
+
+
+
+  this->viewDir=    State::getCamera()->getAbsDirX();
+  float d = (cam.x*viewDir.x + cam.y*viewDir.y + cam.z * viewDir.z);
+
+  BspTreeNode*  ActLeaf = this->getLeaf(this->bspFile->root, &ship);
+  int viscluster = -1;
+  viscluster =((leaf*)(this->bspFile->leaves))[ ActLeaf->leafIndex].cluster; // get the players cluster (viscluster)
+
+
+
+
+  // this->checkCollision(this->root, &this->cam);   //!< Test Collision Detection
+
+
+  this->outputStartsOut = true;
+  this->outputAllSolid = false;
+  this->outputFraction = 1.0f;
+
+  if ( viscluster < 0  || ((int *)(this->bspFile->header))[35] == 0 )  //!< if (sizeof(Visdata) == 0)
+  {
+
+
+
+    // Iterate through all Leafs
+    for(int i = 0; i <  this->bspFile->numLeafs   ; i++ )
+    {
+      // cluster =  (this->bspFile->leaves)[i].cluster;
+      leaf& curLeaf = (this->bspFile->leaves)[i];
+      if(curLeaf.cluster<0) continue;
+
+      /** Do Frustum culling and draw 'em all **/
+
+      Vector dir = State::getCameraNode()->getAbsDirX();
+
+      float dist =  dir.x*this->cam.x +dir.y*this->cam.y +dir.z*this->cam.z;
+      //if(dist < 0) dist = -dist;
+      const float dMins = dir.x*(float)curLeaf.mins[0] +dir.y*(float)curLeaf.mins[1] +dir.z*(float)curLeaf.mins[2] - dist ;
+      const float dMaxs = dir.x*(float)curLeaf.maxs[0] +dir.y*(float)curLeaf.maxs[1] +dir.z*(float)curLeaf.maxs[2] - dist ;
+
+      if(dMins < -300.0 && dMaxs < -300.0) {
+        continue;
+      }
+      if( (this->cam - Vector(curLeaf.mins[0],curLeaf.mins[1], curLeaf.mins[2])).len() > 2000  && (this->cam - Vector(curLeaf.maxs[0],curLeaf.maxs[1], curLeaf.maxs[2])).len() > 2000) {
+        continue;
+      }
+
+
+      // Iterate through all faces
+      for (int j = 0; j < curLeaf.n_leaffaces ; ++j) {
+        const int g = (j +  curLeaf.leafface);
+        const int f = ((int *)this->bspFile->leafFaces)[g];
+        if (f >=0 && !this->isAlreadyVisible(f)) {
+          this->alreadyVisible[f] = true;
+          addFace(f); // "visibleFaces.append(f)"
+        }
+      }
+
+
+
+
+    } //for
+  } else {
+
+
+    unsigned int v;
+    unsigned char  visSet;
+
+    // Iterate through all Leafs
+
+    for(int i = 0; i <  this->bspFile->numLeafs   ; ++i ) {
+      leaf& camLeaf =  (this->bspFile->leaves)[ActLeaf->leafIndex] ;
+      leaf& curLeaf =  (this->bspFile->leaves)[i] ;
+      int& cluster =  curLeaf.cluster;
+
+      if(cluster < 0) continue;
+      v = ((viscluster *  ( ((int *)this->bspFile->visData)[1]) ) + (cluster / 8));
+      visSet =((char*) (this->bspFile->visData))[v + 8];
+
+      // gets bit of visSet
+      if( ((visSet) & (1 << (cluster &  7))) != 0 ) {
+
+        // Frustum culling
+
+        Vector dir;
+        dir.x = State::getCameraNode()->getAbsDirX().x;
+        dir.y =  State::getCameraNode()->getAbsDirX().y;
+        dir.z =  State::getCameraNode()->getAbsDirX().z;
+        const float dist =  dir.x*this->cam.x +dir.y*this->cam.y +dir.z*this->cam.z;
+        //if(dist < 0) dist = -dist;
+        const float dMins = dir.x*(float)curLeaf.mins[0] +dir.y*(float)curLeaf.mins[1] +dir.z*(float)curLeaf.mins[2] - dist;
+        const float dMaxs = dir.x*(float)curLeaf.maxs[0] +dir.y*(float)curLeaf.maxs[1] +dir.z*(float)curLeaf.maxs[2] - dist;
+
+        if(dMins < -70.0 && dMaxs < -70.0) {
+          continue;
+        }
+
+
+        // Iterate through all faces
+        for (int j = 0; j < curLeaf.n_leaffaces ; ++j) {
+          const int g = (j +  curLeaf.leafface);
+          const int f = ((int *)this->bspFile->leafFaces)[g];
+
+          if (!this->isAlreadyVisible(f) && f>=0) {
+            this->addFace(f);
+            this->alreadyVisible[f] = true;
+          }
+
+        }
+
+      }// if
+
+    }//for
+
+  }//else
+
+  while(!this->opal.empty()) {
+    this->draw_face(this->opal.front());
+    this->opal.pop_front();
+  }
+  while(!this->trasparent.empty()) {
+    this->draw_face(this->trasparent.back());
+    this->trasparent.pop_back();
+  }
+  //glEnable(GL_TEXTURE_2D);
+  glActiveTextureARB(GL_TEXTURE1_ARB);
+  glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap);
+
+
+
+}//draw
+
+
+
+void BspManager::draw_face(int curface)
+{
+  face& curFace =  (this->bspFile->faces)[curface];
+  const BspVertex* curVertex = (BspVertex *) this->bspFile->vertice;
+  int stride = sizeof(BspVertex);  // sizeof(Vertex)
+  int offset    = curFace.vertex;
+  if (curFace.effect != -1) return;
+  // PRINTF(0)("BSP Manager: ");
+  // PRINTF(0)("BSP Manager: type: %i  \n", curFace.texture);
+
+  //  if(  curFace.texture < 0 ) return;
+  if(curFace.type == 2) {
+    this->draw_patch( &curFace);
+    return;
+  }
+  // if(curFace.type != 1) return;
+  if((char*)(this->bspFile->textures)[curFace.texture*72]== 0) return;
+
+  if(this->lastTex != curFace.texture) {
+    if(this->bspFile->Materials[curFace.texture].animated) {
+      // glBlendFunc(GL_ZERO,GL_ONE);
+
+
+
+      if(this->bspFile->Materials[curFace.texture].aviMat->getStatus() == 2) this->bspFile->Materials[curFace.texture].aviMat->start(0);
+      //this->bspFile->Materials[curFace.texture].aviMat->tick(0.005);
+      int n =  this->bspFile->Materials[curFace.texture].aviMat->getTexture();
+      glActiveTextureARB(GL_TEXTURE0_ARB);
+      glBindTexture(GL_TEXTURE_2D, n );
+      this->lastTex = curFace.texture;
+
+    } else {
+      this->bspFile->Materials[curFace.texture].mat->select();
+      this->lastTex = curFace.texture;
+    }
+  }
+
+  if(curFace.lm_index < 0) {
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glActiveTextureARB(GL_TEXTURE1_ARB);
+    glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap );
+    glEnable(GL_TEXTURE_2D);
+  } else {
+    // glEnable(GL_BLEND);
+    //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glActiveTextureARB(GL_TEXTURE1_ARB);
+    glBindTexture(GL_TEXTURE_2D, this->bspFile->glLightMapTextures[curFace.lm_index]);
+    glEnable(GL_TEXTURE_2D);
+    //  glDisable(GL_BLEND);
+  }
+
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+  // glColor4f(3.0,3.0,3.0,1.0);
+  glEnableClientState(GL_VERTEX_ARRAY );
+  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
+  glEnableClientState(GL_NORMAL_ARRAY );
+  //  glEnableClientState(GL_COLOR_ARRAY);
+
+
+  glVertexPointer(3, GL_FLOAT, stride, &(curVertex[offset].position[0]));
+
+  glClientActiveTextureARB(GL_TEXTURE0_ARB);
+  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[0]));
+  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+  glClientActiveTextureARB(GL_TEXTURE1_ARB);
+  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[1]));
+  //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+
+  glNormalPointer( GL_FLOAT, stride, &(curVertex[offset].normal[0]));
+  // glColorPointer(4, GL_BYTE, stride, &(curVertex[offset].color[0]));
+  glDrawElements(GL_TRIANGLES, curFace.n_meshverts,
+                 GL_UNSIGNED_INT, &(((meshvert *)this->bspFile->meshverts) [curFace.meshvert]));
+
+  glDisableClientState(GL_TEXTURE0_ARB);
+  glDisableClientState(GL_TEXTURE1_ARB);
+  glDisableClientState(GL_VERTEX_ARRAY );
+  glDisableClientState(GL_TEXTURE_COORD_ARRAY );
+  glDisableClientState(GL_NORMAL_ARRAY );
+  // glDisableClientState(GL_COLOR_ARRAY);
+
+}
+
+
+void BspManager::draw_debug_face(int curface)
+{
+  face& curFace =  (this->bspFile->faces)[curface];
+  const BspVertex* curVertex = (BspVertex *) this->bspFile->vertice;
+  int stride = 44;  // sizeof(Vertex)
+  int offset    = curFace.vertex;
+
+  // PRINTF(0)("BSP Manager: ");
+  // PRINTF(0)("BSP Manager: type: %i  \n", curFace.texture);
+
+  //  if(  curFace.texture < 0 ) return;
+  if(curFace.type == 2) {
+    this->draw_patch( &curFace);
+    return;
+  }
+  if(curFace.type == 3) return;
+  // if(this->bspFile->Materials[curFace.texture] != NULL)
+
+  this->bspFile->Materials[2].mat->select();
+  this->lastTex = 2;
+
+  glEnableClientState(GL_VERTEX_ARRAY );
+  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
+  glEnableClientState(GL_NORMAL_ARRAY );
+  //glEnableClientState(GL_COLOR_ARRAY);
+  // glEnableClientState(GL_VERTEX_ARRAY );
+  glClientActiveTextureARB(GL_TEXTURE0_ARB);
+  glVertexPointer(3, GL_FLOAT, stride, &(curVertex[offset].position[0]));
+  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+  // glClientActiveTextureARB(GL_TEXTURE0_ARB);
+  glClientActiveTextureARB(GL_TEXTURE1_ARB);
+  glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[0]));
+  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+  // glClientActiveTextureARB(GL_TEXTURE1_ARB);
+  // glTexCoordPointer(2, GL_FLOAT, stride, &(curVertex[offset].texcoord[1]));
+  //glEnableClientState(GL_NORMAL_ARRAY );
+
+  glNormalPointer( GL_FLOAT, stride, &(curVertex[offset].normal[0]));
+  //  glColorPointer(4, GL_BYTE, stride, &(curVertex[offset].color[0]));
+  glDrawElements(GL_TRIANGLES, curFace.n_meshverts,
+                 GL_UNSIGNED_INT, &(((meshvert *)this->bspFile->meshverts) [curFace.meshvert]));
+
+}
+
+void BspManager::draw_patch(face* Face)
+{
+  if(this->lastTex != Face->texture) {
+    this->bspFile->Materials[Face->texture].mat->select();
+    this->lastTex = Face->texture;
+  }
+  if (Face->effect != -1) return;
+
+
+  if(Face->lm_index < 0) {
+    glActiveTextureARB(GL_TEXTURE1_ARB);
+    glBindTexture(GL_TEXTURE_2D, this->bspFile->whiteLightMap);
+    glEnable(GL_TEXTURE_2D);
+  } else {
+    glActiveTextureARB(GL_TEXTURE1_ARB);
+    glBindTexture(GL_TEXTURE_2D, this->bspFile->glLightMapTextures[Face->lm_index]);
+    glEnable(GL_TEXTURE_2D);
+  }
+  //glColor4f(3.0,3.0,3.0,1.0);
+
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  glEnable( GL_AUTO_NORMAL);
+  glEnableClientState(GL_VERTEX_ARRAY );
+  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
+  for(int i = Face->n_meshverts -1; i >=0   ; i--) {
+    //glFrontFace(GL_CW);
+    //PRINTF(0)("BSP Manager: Face->size[0]: %i . \n", Face->size[0]);
+
+
+    //glEnableClientState(GL_NORMAL_ARRAY );
+
+    glVertexPointer(3, GL_FLOAT,44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).position[0]));
+
+
+    glClientActiveTextureARB(GL_TEXTURE0_ARB);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glTexCoordPointer(2, GL_FLOAT, 44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).texcoord[0][0]));
+
+
+
+    glClientActiveTextureARB(GL_TEXTURE1_ARB);
+    glTexCoordPointer(2, GL_FLOAT, 44, &((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).texcoord[1][0]));
+    //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+
+    //  glNormalPointer( GL_FLOAT, 44,&((((BspVertex*)(this->bspFile->patchVertice))[8*8*(Face->meshvert+i)]).normal[0]) );
+
+
+
+
+    for(int row=6; row>=0; --row) {
+      glDrawElements(GL_TRIANGLE_STRIP, 2*(8), GL_UNSIGNED_INT,
+                     & (     (((GLuint*)  (this->bspFile->patchIndexes))[7*8*2*(Face->meshvert+i)+ row*2*8]  ))  );
+    }
+
+    //glFrontFace(GL_CCW);
+  }
+  glDisableClientState(GL_TEXTURE0_ARB);
+  glDisableClientState(GL_TEXTURE1_ARB);
+  glDisable(GL_AUTO_NORMAL);
+  glDisableClientState(GL_VERTEX_ARRAY );
+  glDisableClientState(GL_TEXTURE_COORD_ARRAY );
+
+
+}
+
+bool BspManager::isAlreadyVisible(int Face)
+{
+  return this->alreadyVisible[Face];
+}
+
+
+BspTreeNode*  BspManager::getLeaf(BspTreeNode* node, Vector* cam)
+{
+  float dist = 0;
+  while(!(node->isLeaf)) {
+    dist = (node->plane.x * this->cam.x + node->plane.y*this->cam.y + node->plane.z*this->cam.z) - node->d;
+    if(dist >= 0.0f) {
+      node = node->left;
+    } else {
+      node = node->right;
+    }
+  }
+  return  node;
+}
+
+void BspManager::checkBrushRay(brush* curBrush)
+{
+  float EPSILON = 0.000001;
+  float startDistance;
+  float endDistance;
+
+  float startFraction = -1.0f;
+  float endFraction = 1.0f;
+  bool startsOut = false;
+  bool endsOut = false;
+
+  Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
+  Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
+
+  for (int i = 0; i < curBrush->n_brushsides; i++) {
+    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
+    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
+
+    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
+    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
+
+    if (startDistance > 0)
+      startsOut = true;
+    if (endDistance > 0)
+      endsOut = true;
+
+    // make sure the trace isn't completely on one side of the brush
+    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
+      return;
+    }
+    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
+      continue;
+    }
+
+    // MMM... BEEFY
+    if (startDistance > endDistance) {   // line is entering into the brush
+      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
+      if (fraction > startFraction)
+        startFraction = fraction;
+      // don't store plane
+      // this->collPlane = &curPlane;
+
+    } else {   // line is leaving the brush
+      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
+      if (fraction < endFraction)
+        endFraction = fraction;
+      // don't store plane
+      //this->collPlane = & curPlane;
+
+    }
+
+  }
+  if (startsOut == false) {
+    this->outputStartsOut = false;
+    if (endsOut == false)
+      this->outputAllSolid = true;
+    return;
+  }
+
+  if (startFraction < endFraction) {
+    if (startFraction > -1.0f && startFraction < outputFraction) {
+      if (startFraction < 0)
+        startFraction = 0;
+      this->outputFraction = startFraction;
+    }
+  }
+
+}
+
+void BspManager::checkBrushRayN(brush* curBrush)
+{
+  float EPSILON = 0.000001;
+  float startDistance;
+  float endDistance;
+
+  float startFraction = -1.0f;
+  float endFraction = 1.0f;
+  bool  startsOut = false;
+  bool  endsOut = false;
+
+  // Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
+  // Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
+
+  for (int i = 0; i < curBrush->n_brushsides; i++) {
+    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
+    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
+
+    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
+    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
+
+    if (startDistance > 0)
+      startsOut = true;
+    if (endDistance > 0)
+      endsOut = true;
+
+    // make sure the trace isn't completely on one side of the brush
+    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
+      return;
+    }
+    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
+      continue;
+    }
+
+    // MMM... BEEFY
+    if (startDistance > endDistance) {   // line is entering into the brush
+      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
+      if (fraction > startFraction)
+        startFraction = fraction;
+      // store plane
+      this->collPlane = &curPlane;
+
+    } else {   // line is leaving the brush
+      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
+      if (fraction < endFraction)
+        endFraction = fraction;
+      // store plane
+      this->collPlane = & curPlane;
+
+    }
+
+  }
+  if (startsOut == false) {
+    this->outputStartsOut = false;
+    if (endsOut == false)
+      this->outputAllSolid = true;
+    return;
+  }
+
+  if (startFraction < endFraction) {
+    if (startFraction > -1.0f && startFraction < outputFraction) {
+      if (startFraction < 0)
+        startFraction = 0;
+      this->outputFraction = startFraction;
+    }
+  }
+
+}
+
+void BspManager::checkBrushRayN(brush* curBrush, Vector& inputStart, Vector& inputEnd)
+{
+  float EPSILON = 0.000001;
+  float startDistance;
+  float endDistance;
+
+  float startFraction = -1.0f;
+  float endFraction = 1.0f;
+  bool  startsOut = false;
+  bool  endsOut = false;
+
+  //Vector inputStart = State::getCameraTargetNode()->getLastAbsCoor();
+  //Vector inputEnd   = State::getCameraTargetNode()->getAbsCoor();
+
+  for (int i = 0; i < curBrush->n_brushsides; i++) {
+    brushside& curBrushSide =   this->bspFile->brushSides[curBrush->brushside + i]   ;
+    plane& curPlane  =   this->bspFile->planes[curBrushSide.plane] ;
+
+    startDistance = inputStart.x * curPlane.x + inputStart.y * curPlane.y+ inputStart.z * curPlane.z - curPlane.d;
+    endDistance = inputEnd.x * curPlane.x +inputEnd.y * curPlane.y +inputEnd.z * curPlane.z -curPlane.d;
+
+    if (startDistance > 0)
+      startsOut = true;
+    if (endDistance > 0)
+      endsOut = true;
+
+    // make sure the trace isn't completely on one side of the brush
+    if (startDistance > 0 && endDistance > 0) {   // both are in front of the plane, its outside of this brush
+      return;
+    }
+    if (startDistance <= 0 && endDistance <= 0) {   // both are behind this plane, it will get clipped by another one
+      continue;
+    }
+
+    // MMM... BEEFY
+    if (startDistance > endDistance) {   // line is entering into the brush
+      float fraction = (startDistance - EPSILON) / (startDistance - endDistance);  // *
+      if (fraction > startFraction)
+        startFraction = fraction;
+      // store plane
+      this->collPlane = &curPlane;
+
+    } else {   // line is leaving the brush
+      float fraction = (startDistance + EPSILON) / (startDistance - endDistance);  // *
+      if (fraction < endFraction)
+        endFraction = fraction;
+      // store plane
+      this->collPlane = & curPlane;
+
+    }
+
+  }
+  if (startsOut == false) {
+    this->outputStartsOut = false;
+    if (endsOut == false)
+      this->outputAllSolid = true;
+    return;
+  }
+
+  if (startFraction < endFraction) {
+    if (startFraction > -1.0f && startFraction < outputFraction) {
+      if (startFraction < 0)
+        startFraction = 0;
+      this->outputFraction = startFraction;
+    }
+  }
+
+}
+
+
+void BspManager::checkCollisionRay(BspTreeNode* node, float startFraction, float endFraction, Vector* start, Vector* end)
+{
+
+
+  float EPSILON = 0.000001;
+  float  endDistance = (end)->x * (node->plane.x) +(end)->y * (node->plane.y) +(end)->z * (node->plane.z)  - node->d;
+  float  startDistance = (start)->x * (node->plane.x)+ (start)->y * (node->plane.y)+ (start)->z * (node->plane.z)- node->d;
+
+
+  if(node->isLeaf) {
+    leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
+    for (int i = 0; i <  curLeaf.n_leafbrushes ; i++) {
+      brush& curBrush = this->bspFile->brushes[((int*)(this->bspFile->leafBrushes))[curLeaf.leafbrush_first+i]];
+      //object *brush = &BSP.brushes[BSP.leafBrushes[leaf->firstLeafBrush + i]];
+      if (curBrush.n_brushsides > 0   &&
+          ((((BspTexture*)(this->bspFile->textures))[curBrush.texture]).contents & 1))
+        // CheckBrush( brush );
+        this->checkBrushRay(&curBrush);
+      if(curBrush.n_brushsides <=0) this->outputAllSolid = true;
+    }
+    return;
+  }
+
+
+  if (startDistance >= 0 && endDistance >= 0)     // A
+  {   // both points are in front of the plane
+    // so check the front child
+    this->checkCollisionRay(node->left,0,0,start,end);
+  } else if (startDistance < 0 && endDistance < 0)  // B
+  {   // both points are behind the plane
+    // so check the back child
+    this->checkCollisionRay(node->right,0,0,start,end);
+  } else                                            // C
+  {   // the line spans the splitting plane
+    int side;
+    float fraction1, fraction2, middleFraction;
+    Vector middle;
+
+    // STEP 1: split the segment into two
+    if (startDistance < endDistance) {
+      side = 1; // back
+      float inverseDistance = 1.0f / (startDistance - endDistance);
+      fraction1 = (startDistance + EPSILON) * inverseDistance;
+      fraction2 = (startDistance + EPSILON) * inverseDistance;
+    } else if (endDistance < startDistance) {
+      side = 0; // front(start)->x * (node->plane.x)+
+      float inverseDistance = 1.0f / (startDistance - endDistance);
+      fraction1 = (startDistance + EPSILON) * inverseDistance;
+      fraction2 = (startDistance - EPSILON) * inverseDistance;
+    } else {
+      side = 0; // front
+      fraction1 = 1.0f;
+      fraction2 = 0.0f;
+    }
+
+    // STEP 2: make sure the numbers are valid
+    if (fraction1 < 0.0f) fraction1 = 0.0f;
+    else if (fraction1 > 1.0f) fraction1 = 1.0f;
+    if (fraction2 < 0.0f) fraction2 = 0.0f;
+    else if (fraction2 > 1.0f) fraction2 = 1.0f;
+
+    // STEP 3: calculate the middle point for the first side
+    middleFraction = startFraction +
+                     (endFraction - startFraction) * fraction1;
+
+    middle.x = start->x + fraction1 * (end->x - start->x);
+    middle.y = start->y + fraction1 * (end->y - start->y);
+    middle.z = start->z + fraction1 * (end->z - start->z);
+
+    // STEP 4: check the first side
+    //CheckNode( node->children[side], startFraction, middleFraction, start, middle );
+    if(side == 0) this->checkCollisionRay(node->left,startFraction, middleFraction, start, &middle );
+
+    else this->checkCollisionRay(node->right,startFraction, middleFraction,
+                                   start, &middle );
+
+    // STEP 5: calculate the middle point for the second side
+    middleFraction = startFraction +
+                     (endFraction - startFraction) * fraction2;
+
+    middle.x = start->x + fraction2 * (end->x - start->x);
+    middle.y = start->y + fraction2 * (end->y - start->y);
+    middle.z = start->z + fraction2 * (end->z - start->z);
+
+    // STEP 6: check the second side
+    if(side == 1)this->checkCollisionRay(node->left,middleFraction, endFraction, &middle, end);
+
+    else this->checkCollisionRay(node->right,middleFraction, endFraction,&middle, end );
+
+
+  }
+
+}
+
+
+
+void BspManager::checkCollisionRayN(BspTreeNode* node, float startFraction, float endFraction, Vector* start, Vector* end)
+{
+
+
+  float EPSILON = 0.000001;
+
+  float endDistance = end->dot(node->plane) - node->d;
+  float startDistance = start->dot(node->plane) - node->d;
+
+
+  if( node->isLeaf) {
+    leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
+    for (int i = 0; i <  curLeaf.n_leafbrushes ; i++) {
+      brush& curBrush = this->bspFile->brushes[((int*)(this->bspFile->leafBrushes))[curLeaf.leafbrush_first+i]];
+      //object *brush = &BSP.brushes[BSP.leafBrushes[leaf->firstLeafBrush + i]];
+      if (curBrush.n_brushsides > 0   &&
+          ((((BspTexture*)(this->bspFile->textures))[curBrush.texture]).contents & 1))
+        // CheckBrush( brush );
+        this->checkBrushRayN(&curBrush);
+      if(curBrush.n_brushsides <=0) this->outputAllSolid = true;
+    }
+
+    return;
+  }
+
+
+  if (startDistance >= 0 && endDistance >= 0)     // A
+  {   // both points are in front of the plane
+    // so check the front child
+    this->checkCollisionRayN(node->left,0,0,start,end);
+  } else if (startDistance < 0 && endDistance < 0)  // B
+  {   // both points are behind the plane
+    // so check the back child
+    this->checkCollisionRayN(node->right,0,0,start,end);
+  } else                                            // C
+  {   // the line spans the splitting plane
+    int side;
+    float fraction1, fraction2, middleFraction;
+    Vector middle;
+
+    // STEP 1: split the segment into two
+    if (startDistance < endDistance) {
+      side = 1; // back
+      float inverseDistance = 1.0f / (startDistance - endDistance);
+      fraction1 = (startDistance + EPSILON) * inverseDistance;
+      fraction2 = (startDistance + EPSILON) * inverseDistance;
+    } else if (endDistance < startDistance) {
+      side = 0; // front(start)->x * (node->plane.x)+
+      float inverseDistance = 1.0f / (startDistance - endDistance);
+      fraction1 = (startDistance + EPSILON) * inverseDistance;
+      fraction2 = (startDistance - EPSILON) * inverseDistance;
+    } else {
+      side = 0; // front
+      fraction1 = 1.0f;
+      fraction2 = 0.0f;
+    }
+
+    // STEP 2: make sure the numbers are valid
+    if (fraction1 < 0.0f) fraction1 = 0.0f;
+    else if (fraction1 > 1.0f) fraction1 = 1.0f;
+    if (fraction2 < 0.0f) fraction2 = 0.0f;
+    else if (fraction2 > 1.0f) fraction2 = 1.0f;
+
+    // STEP 3: calculate the middle point for the first side
+    middleFraction = startFraction + (endFraction - startFraction) * fraction1;
+    middle = (*start) + ((*end) - (*start)) * fraction1;
+
+
+    // STEP 4: check the first side
+    //CheckNode( node->children[side], startFraction, middleFraction, start, middle );
+    if(side == 0) this->checkCollisionRayN(node->left,startFraction, middleFraction, start, &middle );
+
+    else this->checkCollisionRayN(node->right,startFraction, middleFraction,
+                                    start, &middle );
+
+    // STEP 5: calculate the middle point for the second side
+    middleFraction = startFraction + (endFraction - startFraction) * fraction2;
+    middle = (*start) + ((*end) - (*start)) * fraction2;
+
+    // STEP 6: check the second side
+    if(side == 1)this->checkCollisionRayN(node->left,middleFraction, endFraction, &middle, end);
+
+    else this->checkCollisionRayN(node->right,middleFraction, endFraction,&middle, end );
+
+
+  }
+
+}
+
+float BspManager::checkPatchAltitude(BspTreeNode* node)
+{
+  leaf& curLeaf = this->bspFile->leaves[node->leafIndex];
+  for(int i = 0; i < curLeaf.n_leaffaces ; i++) {}
+  return 10.0f;
+}
+
+void BspManager::checkCollisionBox(void)
+{}
+
+
+void BspManager::TraceBox( Vector& inputStart, Vector& inputEnd,
+                           Vector& inputMins, Vector& inputMaxs )
+{
+  if (inputMins.x == 0 && inputMins.y == 0 && inputMins.z == 0 &&
+      inputMaxs.x == 0 && inputMaxs.y == 0 && inputMaxs.z == 0) {   // the user called TraceBox, but this is actually a ray
+    //!> FIXME TraceRay( inputStart, inputEnd );
+  } else {   // setup for a box
+    //traceType = TT_BOX;
+    this->traceMins = inputMins;
+    this->traceMaxs = inputMaxs;
+    this->traceExtents.x = -traceMins.x > traceMaxs.x ?
+                           -traceMins.x : traceMaxs.x;
+    this->traceExtents.y = -traceMins.y > traceMaxs.y ?
+                           -traceMins.y : traceMaxs.y;
+    this->traceExtents.z = -traceMins.z > traceMaxs.z ?
+                           -traceMins.z : traceMaxs.z;
+    //!> FIXME Trace( inputStart, inputEnd );
+  }
+}
+
+void BspManager::checkCollision(WorldEntity* worldEntity)
+{
+
+  // Init  Collision Detection
+  this->outputStartsOut = true;
+  this->outputAllSolid = false;
+  this->outputFraction = 1.0f;
+
+
+  this->checkCollisionX(worldEntity);
+  this->checkCollisionY(worldEntity);
+  this->checkCollisionZ(worldEntity);
+
+
+#if 0
+  // Retrieve Bounding box
+  AABB* box = worldEntity->getModelAABB();
+
+
+  Vector forwardDir = Vector(0.0,0.0,1.0);
+  Vector upDir = Vector(0.0,1.0,0.0);
+  Vector position = worldEntity->getAbsCoor();
+
+  bool SolidFlag = false;
+  bool collision = false;
+  Vector position1 = position;
+  Vector position2 = position + Vector(0.0,1.0,0.0);
+  Vector position3 = position;
+  Vector position4 = position + Vector(0.0,1.0,0.0);
+  Vector dest = worldEntity->getAbsCoor() - upDir*40.0f; //
+  Vector dest1 = position + forwardDir*4.0f;
+  Vector dest2 = position2 + forwardDir*4.0;
+  Vector dest3 = position + forwardDir*4.0f;
+  Vector dest4 = position2 + forwardDir*4.0;
+  dest = position - Vector(0.0, 40.0,0.0);
+  Vector out = dest;
+  Vector out1;
+  Vector out2;
+
+
+  plane* testPlane;
+
+  bool xCollision = false;
+  bool zCollision = false;
+
+
+  float height = 40;
+
+
+  if( box != NULL) {
+    position = worldEntity->getAbsCoor() +  box->center; // + Vector(0.0, 1.0, 0.0) * box->halfLength[1] * 1.0f;
+    dest     = worldEntity->getAbsCoor() +  box->center - Vector(0.0, 1.0, 0.0) * (box->halfLength[1] + BSP_Y_OFFSET) *   100;
+
+    Vector dirX =  worldEntity->getAbsDirX(); dirX.y = 0.0f; dirX.normalize();
+
+    //position1 = worldEntity->getAbsCoor() +  box->center - dirX * (box->halfLength[0]  + BSP_X_OFFSET);
+    dest1     = worldEntity->getAbsCoor() +  box->center + dirX * (box->halfLength[0]  + BSP_X_OFFSET);
+    dest2     = worldEntity->getAbsCoor() -  box->center + dirX * (box->halfLength[0]  + BSP_X_OFFSET);
+
+    Vector dirZ =  worldEntity->getAbsDirZ(); dirX.y = 0.0f; dirZ.normalize();
+    //position2 = worldEntity->getAbsCoor() +  box->center - dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
+    dest3     = worldEntity->getAbsCoor() +  box->center + dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
+    dest4     = worldEntity->getAbsCoor() -  box->center + dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
+  } else {
+    // Init positions and destinations to anything useful!
+
+  }
+
+
+
+  // 1st Ray: Y RAY
+  this->inputStart =  position;
+  this->inputEnd =   dest;
+  this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &dest );
+
+
+  //
+  if(!this->outputStartsOut ) {
+    this->collPlane = new plane;
+    this->collPlane->x = 0.0f;
+    this->collPlane->y = 0.0f;
+    this->collPlane->z = 0.0f;
+    collision = true;
+  } else {
+
+    if( this->outputFraction == 1.0f) {
+      if(this->outputAllSolid ) {
+        this->collPlane = new plane;
+        this->collPlane->x = 0.0f;
+        this->collPlane->y = 0.0f;
+        this->collPlane->z = 0.0f;
+        collision = true;
+        SolidFlag = true;
+      } else
+        collision = false;
+
+
+      out = dest;
+
+    } else {
+      collision = true;
+      out.x = position.x + (dest.x -position.x) * this->outputFraction;
+      out.y = position.y + (dest.y -position.y) * this->outputFraction;
+      out.z = position.z + (dest.z -position.z) * this->outputFraction;
+
+      Vector out3 = out + Vector(height*this->collPlane->x,height*this->collPlane->y,height*this->collPlane->z);
+      this->out = out;
+    }
+  }
+    testPlane = this->collPlane;
+
+
+  bool xCollisionNeg = false;
+  bool zCollisionNeg = false;
+
+
+
+    // 2nd Collision Detection X-RAY
+    this->outputStartsOut = true;
+    this->outputAllSolid = false;
+    this->outputFraction = 1.0f;
+    this->inputStart =  position1;
+    this->inputEnd =   dest1;
+    this->checkCollisionRayN(this->root,0.0f,1.0f, &position1, &dest1 );
+
+    if(this->outputFraction < 1.0f) {
+      out.x = dest1.x + (dest1.x -position1.x) * this->outputFraction;
+      dest1 = position1 + (dest1 -position1) * this->outputFraction;
+      xCollision = true;
+      testPlane = this->collPlane;
+    }
+    if(this->outputAllSolid ) {
+
+      this->collPlane = new plane;
+      this->collPlane->x = 0.0f;
+      this->collPlane->y = 0.0f;
+      this->collPlane->z = 0.0f;
+      testPlane = this->collPlane;
+      SolidFlag = true;
+      xCollision = true;
+    }
+    //out.z = this->outputFraction;
+
+
+
+      // 3rd Collision Detection Z-RAY
+      this->outputStartsOut = true;
+      this->outputAllSolid = false;
+      this->outputFraction = 1.0f;
+      this->inputStart =  position2;
+      this->inputEnd =   dest2;
+
+      this->checkCollisionRayN(this->root,0.0f,1.0f, &position2, &dest2 );
+      //out.x = this->outputFraction;
+
+      if(this->outputFraction < 1.0f ) {
+        out.z = out.z = dest2.z + (dest2.z -position2.z) * this->outputFraction;
+        dest2 = position2 + (dest2 -position2) * this->outputFraction;
+        zCollision = true;
+        testPlane = this->collPlane;
+
+      }
+      if(this->outputAllSolid ) {
+        this->collPlane = new plane;
+        this->collPlane->x = 0.0f;
+        this->collPlane->y = 0.0f;
+        this->collPlane->z = 0.0f;
+        testPlane = this->collPlane;
+
+        SolidFlag = true;
+        zCollision = true;
+      }
+
+
+  // Return the normal here: Normal's stored in this->collPlane;
+  if( collision) {
+    worldEntity->registerCollision(COLLISION_TYPE_AXIS_Y , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z), out, SolidFlag);
+}
+  if(xCollision) {
+    worldEntity->registerCollision(COLLISION_TYPE_AXIS_X , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z),dest1 , SolidFlag);
+  }
+
+  if(zCollision) {
+    worldEntity->registerCollision(COLLISION_TYPE_AXIS_Z , this->parent, worldEntity, Vector(testPlane->x, testPlane->y, testPlane->z), dest2 , SolidFlag);
+  }
+#endif
+
+}
+
+
+
+/**
+ * check the collision in the x direction (forward, backward)
+ */
+void BspManager::checkCollisionX(WorldEntity* entity)
+{
+  // Retrieve Bounding box
+  AABB* box = entity->getModelAABB();
+
+
+  plane*            testPlane          = NULL;  //!< the collision test plane
+
+  Vector            forward;                    //!< left collision ray
+  Vector            backward;                   //!< right collision ray
+  Vector            collPos;                    //!< the collision position
+
+  bool              xCollisionForward  = false; //!< flag true if right collision
+  bool              xCollisionBackward = false; //!< flag true if left collision
+  bool              SolidFlag          = false; //!< flag set true if solid
+
+  Vector            position;                   //!< current position of the entity
+  Vector            dirX;                       //!< direction x
+
+  position = entity->getAbsCoor();
+  dirX =  entity->getAbsDirX(); dirX.y = 0.0f; dirX.normalize();
+
+  // calculate the rays
+  if( box != NULL)
+  {
+    forward  = entity->getAbsCoor() +  box->center + dirX * (box->halfLength[0]  + BSP_X_OFFSET);
+    backward = entity->getAbsCoor() +  box->center - dirX * (box->halfLength[0]  + BSP_X_OFFSET);
+  }
+  else
+  {
+    forward  = position + dirX * 4.0f;
+    backward = position + Vector(0.0, 1.0, 0.0) + dirX * 4.0;
+  }
+
+
+  /*   X Ray forward  */
+  // init some member variables before collision check
+  this->outputStartsOut = true;
+  this->outputAllSolid = false;
+  this->outputFraction = 1.0f;
+  this->inputStart =  position;
+  this->inputEnd =   forward;
+  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &forward );
+
+  // collision occured
+  if( this->outputFraction < 1.0f)
+  {
+    collPos = position + (forward - position) * this->outputFraction;
+    xCollisionForward = true;
+    testPlane = this->collPlane;
+  }
+  if(this->outputAllSolid )
+  {
+    this->collPlane = new plane;
+    this->collPlane->x = 0.0f;
+    this->collPlane->y = 0.0f;
+    this->collPlane->z = 0.0f;
+    testPlane = this->collPlane;
+    SolidFlag = true;
+    xCollisionForward = true;
+  }
+
+  // collision registration
+  if( xCollisionForward)
+  {
+    entity->registerCollision(COLLISION_TYPE_AXIS_X ,
+                              this->parent, entity,
+                              Vector(testPlane->x, testPlane->y, testPlane->z),
+                              collPos,
+                              SolidFlag);
+  }
+
+
+
+  /*   X Ray backward  */
+  // init some member variables before collision check
+  this->outputStartsOut = true;
+  this->outputAllSolid = false;
+  this->outputFraction = 1.0f;
+  this->inputStart =  position;
+  this->inputEnd =   backward;
+  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &backward );
+
+  // collision occured
+  if( this->outputFraction < 1.0f)
+  {
+    collPos = position + (backward - position) * this->outputFraction;
+    xCollisionBackward = true;
+    testPlane = this->collPlane;
+  }
+  if( this->outputAllSolid)
+  {
+    this->collPlane = new plane;
+    this->collPlane->x = 0.0f;
+    this->collPlane->y = 0.0f;
+    this->collPlane->z = 0.0f;
+    testPlane = this->collPlane;
+    SolidFlag = true;
+    xCollisionBackward = true;
+  }
+
+  // collision registration
+  if( xCollisionBackward)
+  {
+    entity->registerCollision(COLLISION_TYPE_AXIS_X_NEG ,
+                              this->parent, entity,
+                              Vector(testPlane->x, testPlane->y, testPlane->z),
+                              collPos,
+                              SolidFlag);
+  }
+}
+
+
+/**
+ * check the collision in the z direction (up, down)
+ */
+void BspManager::checkCollisionY(WorldEntity* entity)
+{
+
+  // Retrieve Bounding box
+  AABB* box = entity->getModelAABB();
+
+
+  plane*            testPlane          = NULL;  //!< the collision test plane
+
+  Vector            up;                         //!< up collision ray
+  Vector            down;                       //!< down collision ray
+  Vector            collPos;                    //!< the collision position
+
+  bool              yCollisionUp       = false; //!< flag true if right collision
+  bool              yCollisionDown     = false; //!< flag true if left collision
+  bool              SolidFlag          = false; //!< flag set true if solid
+
+  Vector            position;                   //!< current position of the entity
+  Vector            dirY;                       //!< direction x
+
+  position = entity->getAbsCoor();
+  collPos = position;
+  dirY =  Vector(0.0, 1.0, 0.0);
+
+  // calculate the rays
+  if( box != NULL)
+  {
+    up   = position +  box->center + dirY * (box->halfLength[1]/*  + BSP_Y_OFFSET*/);
+    down = position +  box->center - dirY * (box->halfLength[1]  + BSP_Y_OFFSET);
+  }
+  else
+  {
+    up   = position + dirY * 4.0f;
+    down = position + Vector(0.0, 1.0, 0.0) + dirY * 4.0;
+  }
+
+
+
+
+  /*   Y Ray up */
+  // init some member variables before collision check
+  this->inputStart = position;
+  this->inputEnd   = up;
+  this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &up );
+
+  if( !this->outputStartsOut )
+  {
+    this->collPlane = new plane;
+    this->collPlane->x = 0.0f;
+    this->collPlane->y = 0.0f;
+    this->collPlane->z = 0.0f;
+    yCollisionUp = true;
+  }
+  else
+  {
+    if( this->outputFraction == 1.0f)
+    {
+      if( this->outputAllSolid )
+      {
+        this->collPlane = new plane;
+        this->collPlane->x = 0.0f;
+        this->collPlane->y = 0.0f;
+        this->collPlane->z = 0.0f;
+        yCollisionUp = true;
+        SolidFlag = true;
+      }
+      else
+      {
+        yCollisionUp = false;
+        collPos = up;
+      }
+    }
+    else
+    {
+      yCollisionUp = true;
+      collPos = position + (up - position) * this->outputFraction;
+      this->out = collPos;        // why this????
+    }
+  }
+  testPlane = this->collPlane;
+
+  // collision registration
+  if( yCollisionUp)
+  {
+    entity->registerCollision(COLLISION_TYPE_AXIS_Y , this->parent,
+                              entity,
+                              Vector(testPlane->x, testPlane->y, testPlane->z),
+                              collPos, SolidFlag);
+  }
+
+
+
+
+  /*   Y Ray down */
+  // init some member variables before collision check
+  this->inputStart = position;
+  this->inputEnd   = down;
+  this->checkCollisionRayN(this->root,0.0f,1.0f, &position, &down );
+
+  if( !this->outputStartsOut )
+  {
+    this->collPlane = new plane;
+    this->collPlane->x = 0.0f;
+    this->collPlane->y = 0.0f;
+    this->collPlane->z = 0.0f;
+    yCollisionDown = true;
+  }
+  else
+  {
+    if( this->outputFraction == 1.0f) // No collision Detected
+    {
+      if( this->outputAllSolid )
+      {
+        this->collPlane = new plane;
+        this->collPlane->x = 0.0f;
+        this->collPlane->y = 0.0f;
+        this->collPlane->z = 0.0f;
+        yCollisionDown = true;
+        SolidFlag = true;
+      }
+      else      // No collision happened
+      {
+        yCollisionDown = false;
+        collPos = down;
+      }
+    }
+    else           // A collision has happended
+    {
+      yCollisionDown = true;
+      collPos = position + (down - position) * this->outputFraction;
+    }
+  }
+  testPlane = this->collPlane;
+
+  // collision registration
+  if( yCollisionDown)
+  {
+    entity->registerCollision(COLLISION_TYPE_AXIS_Y_NEG , this->parent,
+                              entity,
+                              Vector(testPlane->x, testPlane->y, testPlane->z),
+                              collPos, SolidFlag);
+  }
+
+
+}
+
+
+
+
+/**
+ * check the collision in the z direction (left, right)
+ */
+void BspManager::checkCollisionZ(WorldEntity* entity)
+{
+  // Retrieve Bounding box
+  AABB* box = entity->getModelAABB();
+
+
+  plane*            testPlane          = NULL;  //!< the collision test plane
+
+  Vector            right;                      //!< right collision ray
+  Vector            left;                       //!< left collision ray
+  Vector            collPos;                    //!< the collision position
+
+  bool              zCollisionRight    = false; //!< flag true if right collision
+  bool              zCollisionLeft     = false; //!< flag true if left collision
+  bool              SolidFlag          = false; //!< flag set true if solid
+
+  Vector            position;                   //!< current position of the entity
+  Vector            dirZ;                       //!< direction x
+
+  position = entity->getAbsCoor();
+  dirZ =  entity->getAbsDirZ(); dirZ.y = 0.0f; dirZ.normalize();
+
+  // calculate the rays
+  if( box != NULL)
+  {
+    right = entity->getAbsCoor() +  box->center + dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
+    left  = entity->getAbsCoor() +  box->center - dirZ * (box->halfLength[2]  + BSP_Z_OFFSET);
+  }
+  else
+  {
+    right = position + dirZ * 4.0f;
+    left  = position + Vector(0.0, 1.0, 0.0) + dirZ * 4.0;
+  }
+
+
+  /*   Z Ray right */
+  // init some member variables before collision check
+  this->outputStartsOut = true;
+  this->outputAllSolid = false;
+  this->outputFraction = 1.0f;
+  this->inputStart =  position;
+  this->inputEnd =   right;
+  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &right );
+
+
+  // collision occured
+  if( this->outputFraction < 1.0f )
+  {
+    collPos = position + (right - position) * this->outputFraction;
+    zCollisionRight = true;
+    testPlane = this->collPlane;
+  }
+  if(this->outputAllSolid )
+  {
+    this->collPlane = new plane;
+    this->collPlane->x = 0.0f;
+    this->collPlane->y = 0.0f;
+    this->collPlane->z = 0.0f;
+    testPlane = this->collPlane;
+
+    SolidFlag = true;
+    zCollisionRight = true;
+  }
+
+
+  if( zCollisionRight) {
+    entity->registerCollision(COLLISION_TYPE_AXIS_Z , this->parent,
+                              entity,
+                              Vector(testPlane->x, testPlane->y, testPlane->z),
+                              collPos , SolidFlag);
+  }
+
+
+
+  /*   Z Ray left */
+  // init some member variables before collision check
+  this->outputStartsOut = true;
+  this->outputAllSolid = false;
+  this->outputFraction = 1.0f;
+  this->inputStart =  position;
+  this->inputEnd =    left;
+  this->checkCollisionRayN(this->root, 0.0f, 1.0f, &position, &left);
+
+
+  // collision occured
+  if( this->outputFraction < 1.0f )
+  {
+    collPos = position + (left - position) * this->outputFraction;
+    zCollisionLeft = true;
+    testPlane = this->collPlane;
+  }
+  if(this->outputAllSolid )
+  {
+    this->collPlane = new plane;
+    this->collPlane->x = 0.0f;
+    this->collPlane->y = 0.0f;
+    this->collPlane->z = 0.0f;
+    testPlane = this->collPlane;
+
+    SolidFlag = true;
+    zCollisionLeft = true;
+  }
+
+
+  if( zCollisionLeft) {
+    entity->registerCollision(COLLISION_TYPE_AXIS_Z_NEG , this->parent,
+                              entity,
+                              Vector(testPlane->x, testPlane->y, testPlane->z),
+                              collPos , SolidFlag);
+  }
+
+}
+
+
+
+
+void  BspManager::checkCollision(BspTreeNode* node, Vector* cam)
+{
+  Vector next = this->cam;
+  next.x =   (State::getCameraTargetNode()->getLastAbsCoor()).x ;
+  next.y =   (State::getCameraTargetNode()->getLastAbsCoor()).y ;
+  next.z =   (State::getCameraTargetNode()->getLastAbsCoor()).z ;
+
+  float dist = 0;
+  if(!(node->isLeaf)) {
+    dist = (node->plane.x * this->cam.x + node->plane.y*this->cam.y + node->plane.z*this->cam.z) - node->d;
+    if(dist > 4.0f) {
+      checkCollision(node->left,cam);
+      return;
+    }
+    if(dist < -4.0f) {
+      checkCollision(node->right,cam);
+      return;
+    }
+    if(dist<=4.0f && dist >= -4.0f) {
+      checkCollision(node->left,cam);
+      checkCollision(node->right,cam);
+      return;
+    }
+    return;
+  } else {
+
+    leaf& camLeaf =  ((leaf *)(this->bspFile->leaves))[(node->leafIndex ) ];
+
+    if (camLeaf.cluster < 0) {
+      this->drawDebugCube(&this->cam);
+      this->drawDebugCube(&next);
+      // State::getPlayer()->getPlayable()->setRelCoor(-100,-100,-100);
+      //State::getPlayer()->getPlayable()->collidesWith(NULL, State::getCameraTargetNode()->getLastAbsCoor());
+    }
+
+
+    /*
+        for(int i = 0; i < camLeaf.n_leafbrushes && i < 10; i++ )
+        {
+                brush& curBrush = ((brush*)(this->bspFile->brushes))[(camLeaf.leafbrush_first +i)%this->bspFile->numLeafBrushes];
+                if(curBrush.n_brushsides < 0) return;
+                for(int j = 0; j < curBrush.n_brushsides; j++)
+                {
+                float dist = -0.1;
+                brushside& curBrushSide = ((brushside*)(this->bspFile->brushSides))[(curBrush.brushside +j)%this->bspFile->numBrushSides];
+                plane&      testPlane = ((plane*)(this->bspFile->planes))[curBrushSide.plane % this->bspFile->numPlanes];
+                dist = testPlane.x * this->cam.x +  testPlane.y * this->cam.y  +  testPlane.z * this->cam.z   -testPlane.d ;
+
+                if(dist < -0.01f) dist = -1.0f *dist;
+                if(dist < 1.0f){
+                                this->drawDebugCube(&this->cam);
+                                return;
+                              }
+                }
+
+        } */
+
+  }
+  return;
+}
+
+void BspManager::drawDebugCube(Vector* cam)
+{
+  glBegin(GL_QUADS);
+
+  // Bottom Face.  Red, 75% opaque, magnified texture
+
+  glNormal3f( 0.0f, -1.0f, 0.0f); // Needed for lighting
+  glColor4f(0.9,0.2,0.2,.75); // Basic polygon color
+
+  glTexCoord2f(0.800f, 0.800f); glVertex3f(cam->x-1.0f, cam->y-1.0f,cam->z -1.0f);
+  glTexCoord2f(0.200f, 0.800f); glVertex3f(cam->x+1.0f, cam->y-1.0f,cam->z -1.0f);
+  glTexCoord2f(0.200f, 0.200f); glVertex3f(cam->x+ 1.0f,cam->y -1.0f,cam->z +  1.0f);
+  glTexCoord2f(0.800f, 0.200f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z + 1.0f);
+
+
+  // Top face; offset.  White, 50% opaque.
+
+  glNormal3f( 0.0f, 1.0f, 0.0f);  glColor4f(0.5,0.5,0.5,.5);
+
+  glTexCoord2f(0.005f, 1.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.0f);
+  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
+  glTexCoord2f(1.995f, 0.005f); glVertex3f(cam->x+ 1.0f,  cam->y+1.0f,  cam->z +1.0f);
+  glTexCoord2f(1.995f, 1.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z -1.0f);
+
+
+  // Far face.  Green, 50% opaque, non-uniform texture cooridinates.
+
+  glNormal3f( 0.0f, 0.0f,-1.0f);  glColor4f(0.2,0.9,0.2,.5);
+
+  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z -1.3f);
+  glTexCoord2f(2.995f, 2.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.3f);
+  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x+ 1.0f,cam->y+  1.0f, cam->z -1.3f);
+  glTexCoord2f(0.005f, 0.005f); glVertex3f( cam->x+1.0f,cam->y -1.0f, cam->z -1.3f);
+
+
+  // Right face.  Blue; 25% opaque
+
+  glNormal3f( 1.0f, 0.0f, 0.0f);  glColor4f(0.2,0.2,0.9,.25);
+
+  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y -1.0f, cam->z -1.0f);
+  glTexCoord2f(0.995f, 0.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z -1.0f);
+  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x+ 1.0f, cam->y+ 1.0f, cam->z + 1.0f);
+  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y-1.0f,  cam->z +1.0f);
+
+
+  // Front face; offset.  Multi-colored, 50% opaque.
+
+  glNormal3f( 0.0f, 0.0f, 1.0f);
+
+  glColor4f( 0.9f, 0.2f, 0.2f, 0.5f);
+  glTexCoord2f( 0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f,  cam->z +1.0f);
+  glColor4f( 0.2f, 0.9f, 0.2f, 0.5f);
+  glTexCoord2f( 0.995f, 0.005f); glVertex3f(cam->x+ 1.0f, cam->y-1.0f,  cam->z +1.0f);
+  glColor4f( 0.2f, 0.2f, 0.9f, 0.5f);
+  glTexCoord2f( 0.995f, 0.995f); glVertex3f( cam->x+1.0f,  cam->y+1.0f,  cam->z +1.0f);
+  glColor4f( 0.1f, 0.1f, 0.1f, 0.5f);
+  glTexCoord2f( 0.005f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
+
+
+  // Left Face; offset.  Yellow, varying levels of opaque.
+
+  glNormal3f(-1.0f, 0.0f, 0.0f);
+
+  glColor4f(0.9,0.9,0.2,0.0);
+  glTexCoord2f(0.005f, 0.005f); glVertex3f(cam->x-1.0f, cam->y-1.0f, cam->z -1.0f);
+  glColor4f(0.9,0.9,0.2,0.66);
+  glTexCoord2f(0.995f, 0.005f); glVertex3f(cam->x-1.0f,cam->y -1.0f,  cam->z +1.0f);
+  glColor4f(0.9,0.9,0.2,1.0);
+  glTexCoord2f(0.995f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f,  cam->z +1.0f);
+  glColor4f(0.9,0.9,0.2,0.33);
+  glTexCoord2f(0.005f, 0.995f); glVertex3f(cam->x-1.0f, cam->y+ 1.0f, cam->z -1.0f);
+
+  glEnd();
+}
+
+void BspManager::addFace(int f)
+{
+  face& curFace =  ((face *)(this->bspFile->faces))[f];
+  if(this->bspFile->Materials[curFace.texture].alpha) this->trasparent.push_back(f);
+  else this->opal.push_back(f);
+}
Index: branches/heathaze/src/lib/graphics/importer/bsp_manager.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/bsp_manager.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/bsp_manager.h	(revision 9940)
@@ -0,0 +1,140 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: bottac@ee.ethz.ch
+
+   Inspired by:
+   Rendering Q3 Maps by Morgan McGuire                  http://graphics.cs.brown.edu/games/quake/quake3.html
+   Unofficial Quake 3 Map Specs by Kekoa Proudfoot      http://graphics.stanford.edu/~kekoa/q3/
+
+   Collision detection adapted from:
+   Quake 3 Collision Detection by Nathan Ostgard        http://www.devmaster.net/articles/quake3collision/
+*/
+
+#ifndef _BSP_MANAGER_H
+#define _BSP_MANAGER_H
+
+
+#include <vector>
+#include <deque>
+
+
+#define BSP_X_OFFSET 20.0f
+#define BSP_Y_OFFSET 40.0f
+#define BSP_Z_OFFSET 20.0f
+
+
+// FORWARD DECLARATIONS
+class  BspFile;
+class BspTreeLeaf;
+class BspTreeNode;
+class Vector;
+class set;
+struct face;
+struct brush;
+struct plane;
+
+class WorldEntity;
+
+
+// Obsolete
+struct BspCollisionEvent
+{
+  Vector normal; //!< normal Vector, length 1
+  Vector place;  //!< Absoloute coordinates of collision
+};
+
+class BspManager
+{
+public:
+  // Constructors
+  BspManager(WorldEntity* parent);
+
+  BspManager(const char* fileName, float scale = 0.4f);
+
+  // Deconstructor
+  ~BspManager();
+
+
+
+  // Functions
+  int load(const char* fileName, float scale);
+  const void draw();
+  const void tick(float time);
+  void draw_debug_face(int Face);
+  void draw_face(int Face);
+  void draw_patch(face* Face);
+
+
+  void checkCollision(WorldEntity* worldEntity); /*!< WorldEntities use this function to check wheter they collided with the BspEntity.
+                                                      If a collision has been detected, the collides-function of worldEntity will be called.*/
+
+private:
+  // collision functions
+  BspTreeNode* getLeaf(BspTreeNode*  node,   Vector* cam) ;  //!< Traverses the tree
+  void  checkCollision(BspTreeNode* node, Vector* cam); //!< Obsolete. Use this function for debugging only!
+  void  checkCollisionRay(BspTreeNode * node,float startFraction, float endFraction, Vector* start, Vector* end);
+  void  checkCollisionRayN(BspTreeNode * node,float startFraction, float endFraction, Vector* start, Vector* end);
+
+  void checkCollisionX(WorldEntity* entity);
+  void checkCollisionY(WorldEntity* entity);
+  void checkCollisionZ(WorldEntity* entity);
+
+  void  checkCollisionBox(void);
+  void  checkBrushRay(brush* curBrush);
+  void  checkBrushRayN(brush* curBrush);
+  void  checkBrushRayN(brush* curBrush, Vector& inputStart, Vector& inputEnd);
+  float checkPatchAltitude(BspTreeNode* node); //! To be implemented...
+
+  void  TraceBox( Vector& inputStart, Vector& inputEnd,Vector& inputMins, Vector& inputMaxs );
+
+
+  // visibility functions
+  void drawDebugCube(Vector* cam);
+  bool isAlreadyVisible(int Face);
+  void addFace(int Face);
+
+  // Data
+  BspFile*  bspFile;
+  BspTreeNode* root;
+  Vector cam;
+  Vector ship;
+  Vector  viewDir;
+  plane* collPlane;
+  int lastTex;
+
+  //obsolete: global variables for collision detection
+  bool  outputStartsOut;
+  bool  outputAllSolid;
+  float outputFraction;
+  Vector inputStart;
+  Vector inputEnd;
+
+  Vector traceMins; //!< Mins of current bbox
+  Vector traceMaxs; //!< Maxs of current bbox
+  Vector traceExtents; /*!< Stores the maximum of the absolute value of each axis in the box.
+                            For example, if traceMins was (-100,-3,-15) and traceMaxs was (55,22,7), traceExtents */
+
+  WorldEntity* parent;          //!< the parent entity of the bspManager: interface to this
+
+  bool * alreadyVisible;
+  // Deques to store the visible faces
+  ::std::deque<int> trasparent; //!< the ones with transparancy go here
+  ::std::deque<int> opal; //!< the others here.
+
+  Vector out;  //!< Stores collision coordinates
+  Vector out1; //!< For debugging only
+  Vector out2; //!< For debugging only
+
+  int tgl;
+};
+
+#endif /* _BSP_MANAGER_H */
Index: branches/heathaze/src/lib/graphics/importer/bsp_tree_leaf.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/bsp_tree_leaf.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/bsp_tree_leaf.cc	(revision 9940)
@@ -0,0 +1,20 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: bottac@ee.ethz.ch
+*/
+
+#include "bsp_tree_leaf.h"
+
+BspTreeLeaf::BspTreeLeaf()
+{
+  this->isLeaf = true;
+}
Index: branches/heathaze/src/lib/graphics/importer/bsp_tree_leaf.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/bsp_tree_leaf.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/bsp_tree_leaf.h	(revision 9940)
@@ -0,0 +1,30 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: bottac@ee.ethz.ch
+*/
+#include "bsp_tree_node.h"
+class BspTreeLeaf : public BspTreeNode
+{
+  public:
+  BspTreeLeaf();
+  int leafIndex;
+/*
+  int cluster; //Visdata cluster index.
+  int area;   // Areaportal area.
+  int* mins;  // Integer bounding box min coord.
+  int* maxs; // Integer bounding box max coord.
+  int leafface; // First leafface for leaf.
+  int n_leaffaces; // Number of leaffaces for leaf.
+  int leafbrush; 	// First leafbrush for leaf.
+  int n_leafbrushes; // Number of leafbrushes for leaf.
+*/
+};
Index: branches/heathaze/src/lib/graphics/importer/bsp_tree_node.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/bsp_tree_node.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/bsp_tree_node.cc	(revision 9940)
@@ -0,0 +1,20 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: bottac@ee.ethz.ch
+*/
+
+#include "bsp_tree_node.h"
+
+BspTreeNode::BspTreeNode()
+{
+   this->isLeaf = false;
+}
Index: branches/heathaze/src/lib/graphics/importer/bsp_tree_node.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/bsp_tree_node.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/bsp_tree_node.h	(revision 9940)
@@ -0,0 +1,26 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: bottac@ee.ethz.ch
+*/
+
+#include "vector.h"
+class BspTreeNode
+{
+ public:
+ BspTreeNode();
+ bool isLeaf;
+ int leafIndex;
+ BspTreeNode* left;
+ BspTreeNode* right; 
+ Vector plane;
+ float d;
+};
Index: branches/heathaze/src/lib/graphics/importer/grid.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/grid.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/grid.cc	(revision 9940)
@@ -0,0 +1,83 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "grid.h"
+
+
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+Grid::Grid(float sizeX, float sizeY, unsigned int rows, unsigned int columns)
+{
+  this->planeModel(sizeX, sizeY, rows, columns);
+
+  this->_rows = rows;
+  this->_columns = columns;
+  this->_sizeX = sizeX;
+  this->_sizeY = sizeY;
+  this->_gridSpacingX = sizeX / (float)rows;
+  this->_gridSpacingY = sizeY / (float)columns;
+}
+
+
+/**
+ * standard deconstructor
+*/
+Grid::~Grid ()
+{
+  // delete what has to be deleted here
+}
+
+
+void Grid::rebuildNormals(float maxHeight)
+{
+  for (unsigned int i = 1; i < this->_rows-1; i++)
+  {
+    for (unsigned int j = 1; j < this->_columns-1; j++)
+    {
+/*
+      Vector test( this->_gridSpacingX/(this->vertex(i*_columns+j).y - this->vertex(i*_columns+j-1).y) +
+          this->_gridSpacingX/(this->vertex(i*_columns+j+1).y - this->vertex(i*_columns+j).y)
+          ,
+      _gridSpacingX,
+      this->_gridSpacingY/(this->vertex(i*_columns+j).y - this->vertex((i-1)*_columns+j).y) +
+          this->_gridSpacingX/(this->vertex((i+1)*_columns+j).y - this->vertex(i*_columns+j).y)
+                 );*/
+
+
+
+      Vector test  (
+          (-this->vertex(i*_columns+j-1).y - this->vertex(i*_columns+j+1).y)/maxHeight,
+            1.0,
+            (-this->vertex((i-1)*_columns+j).y - this->vertex((i+1)*_columns+j).y)/maxHeight
+          );
+
+
+//      Vector test(
+//           (this->vertex(i*_columns+j).y + this->vertex((i-1)*_columns+j).y - this->vertex((i+1)*_columns+j).y ) /maxHeight,
+//           1.0,
+//           (this->vertex(i*_columns+j).y - this->vertex(i*_columns+j-1).y + this->vertex(i*_columns+j+1).y)/maxHeight
+//                 );
+      this->normal( i*_columns+j) = test.getNormalized();
+    }
+
+  }
+
+}
Index: branches/heathaze/src/lib/graphics/importer/grid.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/grid.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/grid.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file grid.h
+ * @brief Definition of ...
+*/
+
+#ifndef _GRID_H
+#define _GRID_H
+
+#include "vertex_array_model.h"
+
+// FORWARD DECLARATION
+
+
+
+//! A class for ...
+class Grid : public VertexArrayModel
+{
+
+public:
+  Grid(float sizeX, float sizeY, unsigned int resolutionX, unsigned int resolutionY);
+  virtual ~Grid();
+
+  float gridSpacing() const { return this->_gridSpacingX; };
+  float sizeX() const { return this->_sizeX; };
+  float sizeY() const { return this->_sizeY; };
+  unsigned int rows() const { return this->_rows; };
+  unsigned int columns() const { return this->_columns; };
+
+  float& height(unsigned int row, unsigned int column) { return this->vertex(row*this->_columns + column).y;};
+  Vector& vertexG(unsigned int row, unsigned int column) { return this->vertex(row*this->_columns + column); };
+  Vector& normalG(unsigned int row, unsigned int column) { return this->normal(row*this->_columns + column); };
+
+
+  void rebuildNormals(float maxHeight);
+
+private:
+  float             _sizeX;
+  float             _sizeY;
+
+  float             _gridSpacingX;
+  float             _gridSpacingY;
+
+  unsigned int      _rows;
+  unsigned int      _columns;
+};
+
+#endif /* _GRID_H */
Index: branches/heathaze/src/lib/graphics/importer/height_map.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/height_map.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/height_map.cc	(revision 9940)
@@ -0,0 +1,608 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: bottac@ee.ethz.ch
+
+   review: patrick boenzli, patrick@orxonox.ethz.ch
+*/
+
+#include "height_map.h"
+#include "model.h"
+#include "texture.h"
+#include "vector.h"
+#include "material.h"
+#include "p_node.h"
+#include "state.h"
+#include "debug.h"
+
+// INCLUDING SDL_Image
+#ifdef HAVE_SDL_IMAGE_H
+#include <SDL_image.h>
+#else
+#include <SDL/SDL_image.h>
+#endif
+
+
+/**
+ * default constructor
+ *  @param xOffset
+ */
+Tile::Tile(int xOffset, int yOffset, int i2, int j2, HeightMap* heightMapReference )
+{
+  PRINTF(0)("Tile Constructor\n");
+
+  this->highResModel = new VertexArrayModel();
+  this->lowResModel  = new VertexArrayModel();
+
+  this->heightMapReference = heightMapReference;
+
+  // create high res model
+  this->load(xOffset, yOffset, i2, j2, this->highResModel, 4);
+  // create low res model
+  this->load(xOffset, yOffset, i2, j2, this->lowResModel, 8);
+}
+
+
+Tile::~Tile()
+{
+  if( highResModel)
+    delete highResModel;
+  if( lowResModel)
+    delete lowResModel;
+}
+
+
+/**
+ * this darws the tile in diefferent resolutions
+ */
+void Tile::draw()
+{
+  // draw the tile depending on the distance from the camera with different LOD (level of details)
+  float cameraDistance = fabs((State::getCameraNode()->getAbsCoor() - Vector(this->x, heightMapReference->offsetY , this->z) ).len());
+
+  if (cameraDistance < HM_LOD_HIGH_RES )
+  {
+    this->drawHighRes();
+  }
+  else if( cameraDistance < HM_LOD_LOW_RES)
+  {
+    this->drawLowRes();
+  }
+}
+
+
+/**
+ * loads a tile
+ */
+void Tile::load(int xOffset, int yOffset, int i2, int j2, VertexArrayModel* model, int sampleRate)
+{
+
+// #define heightMap this->heightMapReference->heightMap
+#define colors   this->heightMapReference->colors
+#define scaleX this->heightMapReference->scaleX
+#define scaleY this->heightMapReference->scaleY
+#define scaleZ this->heightMapReference->scaleZ
+#define shiftX this->heightMapReference->shiftX
+#define shiftY this->heightMapReference->shiftY
+#define shiftZ this->heightMapReference->shiftZ
+#define normalVectorField this->heightMapReference->normalVectorField
+
+
+  //FIXME: OLD implementation
+  this->x = this->heightMapReference->offsetX + ( this->heightMapReference->heightMap->h - ((xOffset + i2) / 2)) * scaleX;
+  this->z = this->heightMapReference->offsetZ + ((yOffset + j2 ) / 2 ) * scaleZ;
+  //NEW:
+  this->setAbsCoor(this->heightMapReference->offsetX + ( this->heightMapReference->heightMap->h - ((xOffset + i2) / 2)) * scaleX,
+                   0,
+                   this->heightMapReference->offsetZ + ((yOffset + j2 ) / 2 ) * scaleZ);
+
+
+  float height = 0;
+
+  float r = 0.0;
+  float g = 0.0;
+  float b = 0.0;
+
+
+  //if( this->heightMapReference->heightMap != NULL && this->heightMapReference->heightMap->format->BitsPerPixel == 8 )
+
+  SDL_LockSurface(this->heightMapReference->heightMap);
+  SDL_LockSurface(this->heightMapReference->colorMap);
+
+  for( int i = xOffset ; i <= i2  ; i +=sampleRate)
+  {
+    int w = 0;
+
+    // adjust the colors acoring to the color map
+    if( this->heightMapReference->hasColourMap)
+    {
+      r = colors[3 * w + 2 + 3 * i * this->heightMapReference->heightMap->w];
+      g = colors[3 * w + 1 + 3 * i * this->heightMapReference->heightMap->w];
+      b = colors[3 * w + 0 + 3 * i * this->heightMapReference->heightMap->w];
+    }
+
+    w = yOffset;
+
+//    PRINTF(0)("Values: i = %i, w = %i\n", i, w);
+
+    // add a vertex to the list
+    model->addVertex(scaleX * (this->heightMapReference->heightMap->h - i) + shiftX, shiftY, scaleZ * w + shiftZ); // Top Right
+    model->addNormal(normalVectorField[i % this->heightMapReference->heightMap->h][w % this->heightMapReference->heightMap->w].y,
+                     normalVectorField[i % this->heightMapReference->heightMap->h][w % this->heightMapReference->heightMap->w].z,
+                     normalVectorField[i % this->heightMapReference->heightMap->h][w % this->heightMapReference->heightMap->w].x);
+    model->addTexCoor((float)(yOffset-sampleRate) /(HM_TEX_RATE), (float)(i %this->heightMapReference->heightMap->h)/(HM_TEX_RATE));
+    model->addColor(r/255.0f, g/255.0f, b/255.0f);
+
+
+    for(int j = yOffset; j <= j2; j += sampleRate)
+    {
+      // adjust the colors acording to the color map
+      if( this->heightMapReference->hasColourMap)
+      {
+        r = colors[3 * j + 2 + 3 * i * this->heightMapReference->heightMap->w];
+        g = colors[3 * j + 1 + 3 * i * this->heightMapReference->heightMap->w];
+        b = colors[3 * j + 0 + 3 * i * this->heightMapReference->heightMap->w];
+      }
+      height =  (float)(unsigned char)this->heightMapReference->heights[j + sampleRate + i * (this->heightMapReference->heightMap->w)];
+      height += (float)(unsigned char)this->heightMapReference->heights[j + 1 + sampleRate + (i + 1) *
+                                                                        this->heightMapReference->heightMap->w];
+      height += (float)(unsigned char)this->heightMapReference->heights[j - 1 + sampleRate + (i + 1) *
+                                                                        this->heightMapReference->heightMap->w];
+      height += (float)(unsigned char)this->heightMapReference->heights[j + sampleRate + (i + 2) *
+                                                                        this->heightMapReference->heightMap->w];
+      height += (float)(unsigned char)this->heightMapReference->heights[j + sampleRate + i * (this->heightMapReference->heightMap->w)];
+      height /= 5.0;
+
+      model->addVertex(scaleX * (this->heightMapReference->heightMap->h -i) + shiftX ,
+                       ((double)(height)*scaleY) + shiftY ,
+                       scaleZ*(j) + shiftZ); // Top Right
+      model->addNormal(normalVectorField[i % this->heightMapReference->heightMap->h][j % this->heightMapReference->heightMap->w].y,
+                       normalVectorField[i % this->heightMapReference->heightMap->h][j % this->heightMapReference->heightMap->w].z,
+                       normalVectorField[i % this->heightMapReference->heightMap->h][j % this->heightMapReference->heightMap->w].x);
+      model->addTexCoor((float)(j) /(HM_TEX_RATE), (float)(i %this->heightMapReference->heightMap->h)/(HM_TEX_RATE));
+      model->addColor(r/255.0f, g/255.0f, b/255.0f);
+      //PRINTF(0)("TexCoord:  %f %f \n",(float)j / 100.0, (float)(i %this->heightMapReference->h)/100.0);
+
+      w = j;
+    }
+    model->addVertex(scaleX*(this->heightMapReference->heightMap->h -i)+ shiftX,shiftY,scaleZ*(w)+ shiftZ); // Top Right
+    model->addNormal(normalVectorField[i % this->heightMapReference->heightMap->h][w % this->heightMapReference->heightMap->w].y,
+                     normalVectorField[i % this->heightMapReference->heightMap->h][w % this->heightMapReference->heightMap->w].z,
+                     normalVectorField[i% this->heightMapReference->heightMap->h][w % this->heightMapReference->heightMap->w].x);
+    model->addTexCoor((float)(j2+sampleRate) /(HM_TEX_RATE), (float)(i %this->heightMapReference->heightMap->h)/(HM_TEX_RATE));
+    model->addColor(r/255.0f, g/255.0f, b/255.0f);
+  }
+
+  SDL_UnlockSurface(this->heightMapReference->heightMap);
+  int cnt = 0;
+
+  for( int i = xOffset; i < i2; i +=sampleRate)
+  {
+    for( int j = yOffset-sampleRate; j < j2  + 2 * sampleRate; j += sampleRate)
+    {
+      model->addIndice(cnt);
+      model->addIndice(cnt  + (j2 -yOffset + 3* sampleRate  )/ sampleRate );
+      cnt++;
+    }
+    model->newStripe();
+  }
+  cnt += (j2 -yOffset + 3* sampleRate)/ sampleRate;
+
+  for( int j = yOffset; j <= j2; j += sampleRate)
+  {
+    int i = xOffset;
+
+    // To be fixed
+    if(this->heightMapReference->hasColourMap)
+    {
+      r = (float)colors[3 * j + 2 + 3 * i * this->heightMapReference->heightMap->w];
+      g = (float)colors[3 * j + 1 + 3 * i * this->heightMapReference->heightMap->w];
+      b = (float)colors[3 * j + 0 + 3 * i * this->heightMapReference->heightMap->w];
+    }
+
+    model->addVertex(scaleX*(this->heightMapReference->heightMap->h -i) + shiftX ,
+                     shiftY ,
+                     scaleZ*(j) + shiftZ); // Top Right
+    model->addNormal(normalVectorField[i % this->heightMapReference->heightMap->h][j % this->heightMapReference->heightMap->w].y,
+                     normalVectorField[i % this->heightMapReference->heightMap->h][j % this->heightMapReference->heightMap->w].z,
+                     normalVectorField[i % this->heightMapReference->heightMap->h][j % this->heightMapReference->heightMap->w].x);
+    model->addTexCoor((float)j /(HM_TEX_RATE), (float)((i - sampleRate) %this->heightMapReference->heightMap->h)/(HM_TEX_RATE));
+    model->addColor(r/255.0f, g/255.0f, b/255.0f);
+  }
+
+
+  for(int j = yOffset  ; j <= j2    ;  j += sampleRate)
+  {
+    int i = xOffset;
+    height =  (float)(unsigned char)this->heightMapReference->heights[j + sampleRate + i * this->heightMapReference->heightMap->w];
+    height += (float)(unsigned char)this->heightMapReference->heights[j + 1 + sampleRate + (i + 1) *
+                                                                      this->heightMapReference->heightMap->w];
+    height += (float)(unsigned char)this->heightMapReference->heights[j - 1 + sampleRate + (i + 1) *
+                                                                      this->heightMapReference->heightMap->w];
+    height += (float)(unsigned char)this->heightMapReference->heights[j + sampleRate + (i + 2) *
+                                                                      this->heightMapReference->heightMap->w];
+    height += (float)(unsigned char)this->heightMapReference->heights[j + sampleRate + i * this->heightMapReference->heightMap->w];
+    height=height/5.0;
+
+    model->addVertex(scaleX*(this->heightMapReference->heightMap->h -i) + shiftX ,
+                     ((double)(height)*scaleY) +shiftY ,
+                     scaleZ*(j) + shiftZ); // Top Right
+    model->addNormal(normalVectorField[i % this->heightMapReference->heightMap->h][j % this->heightMapReference->heightMap->w].y,
+                     normalVectorField[i % this->heightMapReference->heightMap->h][j% this->heightMapReference->heightMap->w].z,
+                     normalVectorField[i%this->heightMapReference->heightMap->h][j%this->heightMapReference->heightMap->w].x);
+    model->addTexCoor((float)j /(HM_TEX_RATE), (float)(i %this->heightMapReference->heightMap->h)/(HM_TEX_RATE));
+    model->addColor(r/255.0f, g/255.0f, b/255.0f);
+  }
+
+
+  for(int j = yOffset; j <= j2; j += sampleRate)
+  {
+    int i = i2;
+    // To be fixed
+    if( this->heightMapReference->hasColourMap)
+    {
+      r = (float)colors[3 * j + 2 + 3 * i * this->heightMapReference->heightMap->w];
+      g = (float)colors[3 * j + 1 + 3 * i * this->heightMapReference->heightMap->w];
+      b = (float)colors[3 * j + 0 + 3 * i * this->heightMapReference->heightMap->w];
+    }
+
+    model->addVertex(scaleX*(this->heightMapReference->heightMap->h -i) + shiftX ,
+                     shiftY ,
+                     scaleZ*(j) + shiftZ); // Top Right
+    model->addNormal(normalVectorField[i%this->heightMapReference->heightMap->h][j%this->heightMapReference->heightMap->w].y,
+                     normalVectorField[i%this->heightMapReference->heightMap->h][j%this->heightMapReference->heightMap->w].z,
+                     normalVectorField[i%this->heightMapReference->heightMap->h][j%this->heightMapReference->heightMap->w].x);
+    model->addTexCoor((float)j /(HM_TEX_RATE), (float)((i+ sampleRate) %this->heightMapReference->heightMap->h)/(HM_TEX_RATE));
+    model->addColor(r/255.0f, g/255.0f, b/255.0f);
+  }
+
+
+  for(int j = yOffset; j <= j2; j += sampleRate)
+  {
+    int i = i2;
+    height =  (float)(unsigned char)this->heightMapReference->heights[j + sampleRate + i * this->heightMapReference->heightMap->w];
+    height += (float)(unsigned char)this->heightMapReference->heights[j + 1 + sampleRate + (i + 1)
+                                                                      * this->heightMapReference->heightMap->w];
+    height += (float)(unsigned char)this->heightMapReference->heights[j - 1 + sampleRate + (i + 1) *
+                                                                      this->heightMapReference->heightMap->w];
+    height += (float)(unsigned char)this->heightMapReference->heights[j + sampleRate + (i + 2) *
+                                                                      this->heightMapReference->heightMap->w];
+    height +=  (float)(unsigned char)this->heightMapReference->heights[j + sampleRate + i * this->heightMapReference->heightMap->w];
+    height /= 5.0;
+    model->addVertex(scaleX*(this->heightMapReference->heightMap->h -i) + shiftX ,
+                     ((double)(height)*scaleY) +shiftY ,
+                     scaleZ*(j) + shiftZ); // Top Right
+    model->addNormal(normalVectorField[i%this->heightMapReference->heightMap->h][j%this->heightMapReference->heightMap->w].y,
+                     normalVectorField[i%this->heightMapReference->heightMap->h][j%this->heightMapReference->heightMap->w].z,
+                     normalVectorField[i%this->heightMapReference->heightMap->h][j%this->heightMapReference->heightMap->w].x);
+    model->addTexCoor((float)j /(HM_TEX_RATE), (float)(i %this->heightMapReference->heightMap->h)/(HM_TEX_RATE));
+    model->addColor(r/255.0f, g/255.0f, b/255.0f);
+  }
+
+  // link Boarder Stripe
+  for(int j = yOffset - sampleRate; j < j2; j += sampleRate)
+  {
+    model->addIndice(cnt);
+    model->addIndice(cnt + (j2 - yOffset + sampleRate) / sampleRate );
+    cnt++;
+  }
+  cnt++;
+
+
+  model->newStripe();
+
+
+  cnt += (j2-yOffset)/ sampleRate;
+  // link 2nd BoarderStripe
+  for(int j = yOffset-sampleRate; j < j2;  j += sampleRate)
+  {
+    model->addIndice(cnt);
+    model->addIndice(cnt + (j2 - yOffset + sampleRate) / sampleRate);
+    cnt++;
+  }
+
+  SDL_UnlockSurface(this->heightMapReference->colorMap);
+
+  model->finalize();
+
+// #undef heightMap
+        #undef colors
+        #undef scaleX
+        #undef scaleY
+        #undef scaleZ
+        #undef shiftX
+        #undef shiftY
+        #undef shiftZ
+        #undef normalVectorField
+}
+
+
+ObjectListDefinition(HeightMap);
+
+
+/**
+ * constructor
+ *  @param heightMapName file name of the height map
+ */
+HeightMap::HeightMap(const std::string& heightMapName)
+    : VertexArrayModel()
+{
+  this->init(heightMapName);
+
+  this->colorMap = NULL;
+}
+
+
+/**
+ * constructor
+ *  @param heightMapName file name of the height map
+ *  @param colorMapName file name of the color map
+ */
+HeightMap::HeightMap(const std::string& heightMapName, const std::string& colorMapName)
+    : VertexArrayModel()
+{
+  this->init(heightMapName);
+
+  this->colorMap = IMG_Load(colorMapName.c_str());
+  if( this->colorMap != NULL)
+  {
+    PRINTF(0)("loading Image %s\n", colorMapName.c_str());
+    PRINTF(0)("width : %i\n", this->colorMap->w);
+    PRINTF(0)("height : %i\n", this->colorMap->h);
+    PRINTF(0)("%i Byte(s) per Pixel \n", this->colorMap->format->BytesPerPixel);
+    PRINTF(0)("Rshift : %i\n", this->colorMap->format->Rshift);
+    PRINTF(0)("Bshift: %i\n", this->colorMap->format->Bshift);
+    PRINTF(0)("Gshift: %i\n", this->colorMap->format->Gshift);
+    PRINTF(0)("Rmask: %i\n", this->colorMap->format->Rmask);
+    PRINTF(0)("Gmask: %i\n", this->colorMap->format->Gmask);
+
+    this->colors = (unsigned char *) colorMap->pixels;
+    this->hasColourMap = true;
+  }
+  else
+  {
+    PRINTF(0)("oops! couldn't load colorMap for some reason.\n");
+    this->hasColourMap = false;
+  }
+}
+
+
+/**
+ * deconstructor
+ */
+HeightMap::~HeightMap()
+{
+  if( heightMap)
+    delete heightMap;
+  if( colorMap)
+    delete colorMap;
+
+  if( this->tiles)
+  {
+    for( int i = 0; i < heightMap->h / HM_TILE_SIZE; i++) {
+      for( int j = 0; j < heightMap->w / HM_TILE_SIZE; j++) {
+        delete tiles [i][j];
+      }
+    }
+
+    for( int i = 0; i < heightMap->h / HM_TILE_SIZE; i++)
+      delete[] tiles[i];
+    delete[] tiles;
+  }
+
+  if( this->normalVectorField)
+  {
+    for(int i = 0; i < heightMap->h; i++)
+      delete[] normalVectorField[i];
+    delete[] normalVectorField;
+  }
+}
+
+
+/**
+ * this is the init function with stuff shared between all constructors
+ */
+void HeightMap::init(const std::string& heightMapName)
+{
+  this->registerObject(this, HeightMap::_objectList);
+
+  this->shiftX = 0;
+  this->shiftY = 0;
+  this->shiftZ = 0;
+
+  heightMap =  IMG_Load(heightMapName.c_str());
+  if( heightMap != NULL)
+  {
+    /*
+    WHAT about following checks:
+    - image size (rectangular?)
+    - image file type (bw?)
+    */
+    PRINTF(1)("loading Image %s\n", heightMapName.c_str());
+    PRINTF(1)("width : %i\n", heightMap->w);
+    PRINTF(1)("height : %i\n", heightMap->h);
+    PRINTF(1)("%i Byte(s) per Pixel \n", heightMap->format->BytesPerPixel);
+    PRINTF(1)("Rshift : %i\n", heightMap->format->Rshift);
+    PRINTF(1)("Bshift: %i\n", heightMap->format->Bshift);
+    PRINTF(1)("Gshift: %i\n", heightMap->format->Gshift);
+    PRINTF(1)("Rmask: %i\n", heightMap->format->Rmask);
+    PRINTF(1)("Gmask: %i\n", heightMap->format->Gmask);
+  }
+  else
+    PRINTF(1)("oops! couldn't load %s for some reason.\n", heightMapName.c_str());
+
+  this->generateNormalVectorField();
+
+  this->heights = (unsigned char*)heightMap->pixels;
+}
+
+
+/**
+ * this function loads the heightmap by creatin tiles
+ */
+void HeightMap::load()
+{
+  // create a dynamicly sized 2D-array for tiles
+  this->tiles =  new Tile**[this->heightMap->h / HM_TILE_SIZE];
+
+  for( int i = 0;i < heightMap->h / HM_TILE_SIZE; i++)
+    this->tiles [i]= new Tile*[this->heightMap->w / HM_TILE_SIZE];
+
+  // setup arrays
+  for( int i = 0; i < this->heightMap->h / HM_TILE_SIZE; i++)  {
+    for( int j = 0; j < this->heightMap->w / HM_TILE_SIZE; j++) {
+      this->tiles[i][j] = new Tile( i * HM_TILE_SIZE ,  j * HM_TILE_SIZE , (i+1) * HM_TILE_SIZE, (j+1) * HM_TILE_SIZE , this);
+    }
+  }
+}
+
+
+/**
+ * this function draws the height map
+ */
+void HeightMap::draw() const
+{
+  Vector v = State::getCameraNode()->getAbsCoor();
+
+  int i_max = (heightMap->h )/ HM_TILE_SIZE;
+  int j_max= (heightMap->w  ) / HM_TILE_SIZE;
+
+
+
+  /* process the draw command to the tiles, FIXME: think of something more efficient*/
+  for( int i = 0; i < i_max; i++)  {
+    for( int j = 0; j < j_max; j++)  {
+      tiles[i][j]->draw();
+    }
+  }
+}
+
+
+/**
+ * this function generates the normal vector field
+ */
+void HeightMap::generateNormalVectorField()
+{
+  int delta = 1;
+  heights  = (unsigned char*) heightMap->pixels;
+
+  //Create a Dynamicly sized 2D-Array to store our normals
+  normalVectorField =  new Vector* [heightMap->h];
+  for(int i=0;i<heightMap->h;i++)
+    normalVectorField [i]= new (Vector [heightMap->w]);
+
+  // Initialize
+  for(int i=0; i< heightMap->h; i++)
+  {
+    for(int j = 0; j> heightMap->w; j++)
+    {
+      Vector v = Vector(0.0, 1.0, 0.0);
+      normalVectorField[i][j] = v;
+    }
+  }
+
+  // !!! Does not yet calculate the normals of some border points!!!!!
+
+  if(heightMap != NULL && heightMap->format->BitsPerPixel == 8 )
+  {
+    SDL_LockSurface(heightMap);
+    for(int i = 0 ; i < heightMap->h - 1  ; i ++)
+    {
+      for(int j = 0; j < heightMap->w  - 1  ;  j ++)
+      {
+
+
+        delta = (int)heights[j + (i+1)*(heightMap->w )] -  (int) heights[j + i*(heightMap->w )];
+        Vector a =  Vector(-scaleX,(float)delta*scaleY  ,0.0f);
+
+        delta = (int)heights[j+1 + i*(heightMap->w )] - (int)heights[j + i*(heightMap->w )];
+        Vector b =  Vector(0.0f,(float) delta*scaleY ,scaleZ);
+
+
+        normalVectorField[i][j] = b.cross(a);
+        normalVectorField[i][j].normalize();
+
+      }
+    }
+    SDL_UnlockSurface(heightMap);
+
+  }
+}
+
+
+/**
+ * scales the height map about a vector
+ *  @param v scaling vector
+ */
+void HeightMap::scale(Vector v)
+{
+  scaleX = v.x;
+  scaleY = v.y;
+  scaleZ = v.z;
+  generateNormalVectorField();
+}
+
+
+/**
+ * sets the absolute coordinates of the height map
+ *  @param v the moving vector
+ */
+void HeightMap::setAbsCoor(Vector v)
+{
+  offsetX = v.x;
+  offsetY = v.y;
+  offsetZ = v.z;
+}
+
+
+/**
+ * returns the height at a given 2D coordinate
+ *  @param x x coordinate of the height map (world space)
+ *  @param y y coordinate of the height map (world space)
+ *  @return the height (z)
+ */
+float HeightMap::getHeight(float x, float y)
+{
+  x -= offsetX;
+  y -= offsetZ;
+
+  int xInt = (int)( x / scaleX);
+  x -= (float)((int)x);
+  xInt = heightMap->h - xInt;
+  int yInt = (int)( y / scaleZ);
+  y -= (float) ((int) y); /*yInt = heightMap->w - yInt;*/
+
+  //PRINTF(0)("xInt: %i, yInt: %i, x: %f, y: %f\n", xInt, yInt, x, y);
+
+  if(xInt <= 0 || xInt >= heightMap->h || yInt <= 0 || yInt >= heightMap->w  )
+    return 0;
+  if( y >= 0.5*x)
+  {
+    // Check for ...
+  }
+
+  float height = heights[yInt + (xInt)*heightMap->w]*scaleY;
+
+  float a = normalVectorField[(xInt)][yInt].x;
+  float b = normalVectorField [(xInt)][yInt].z;
+  float c = normalVectorField [(xInt)][yInt].y;
+
+//  PRINTF(0)("a: %f \n" ,a);
+//  PRINTF(0)("b: %f \n" ,b);
+//  PRINTF(0)("c: %f \n" ,c);
+
+
+  height -= ( (a/c)*(x) + (b/c)*(y));
+
+  // PRINTF(0)("height: %f \n" ,height );
+  return (height + offsetZ);
+
+}
Index: branches/heathaze/src/lib/graphics/importer/height_map.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/height_map.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/height_map.h	(revision 9940)
@@ -0,0 +1,136 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: bottac@ee.ethz.ch
+
+   review: patrick boenzli, patrick@orxonox.ethz.ch
+*/
+
+
+#include "vertex_array_model.h"
+#include "p_node.h"
+
+
+#define HM_TEX_RATE      32
+#define HM_TILE_SIZE     64
+
+//!< define the LOD level distances. later this could be dynamicaly adjusted
+#define HM_LOD_LOW_RES     5000         //!< low resolution unless farther away than LOW_RES
+#define HM_LOD_HIGH_RES    1000
+
+
+class SDL_Surface;
+class Material;
+class Texture;
+class HeightMap;
+
+
+//!< one part of the height map
+class Tile : public PNode
+{
+  public:
+    Tile(int i1, int j1, int i2, int j2, HeightMap* hm) ;
+    virtual ~Tile();
+
+    int getRes();
+    int setHighRes(bool b);
+
+    void draw();
+    inline void drawHighRes() const { highResModel->draw(); }
+    inline void drawLowRes() const { lowResModel->draw(); }
+
+
+  private:
+    void load(int i1, int j1, int i2, int i2, VertexArrayModel* model, int Res);
+
+
+  public:
+    float x;
+    float z;
+
+
+  private:
+    VertexArrayModel*                          highResModel;                      //!< heigh resolution model of the tile
+    VertexArrayModel*                          lowResModel;                       //!< low resolution model of the tile
+
+    HeightMap*                                 heightMapReference;                //!< reference to the heightmap this tile belongs to
+    int                                        highRes;                           //!<
+    int                                        lowRes;                            //!<
+};
+
+
+
+//!< the height map representation itself
+class HeightMap : public VertexArrayModel
+{
+  ObjectListDeclaration(HeightMap);
+  friend class Tile;
+
+  public:
+    HeightMap(const std::string& heightMapName);
+    HeightMap(const std::string& heightMapName, const std::string& colorMapName);
+    virtual ~HeightMap();
+
+    void setAbsCoor(Vector V);
+    float getHeight(float x, float y);
+    float getNormal(float x, float y);
+
+    void load();
+    void load(int Mode);
+    void load(const std::string&, int Mode);
+    void scale( Vector V);
+
+    void draw() const;
+
+
+  private:
+    void init(const std::string& heightMapName);
+
+    void generateNormalVectorField();
+    void drawRect(int xBottomLeft, int yBottomLeft, int xTopRight, int yTopRight );
+    void fixBoarder(int xBottomLeft, int yBottomLeft, int xTopRight, int yTopRight);
+
+    /** helper function absolute value @param val value*/
+    inline int abs(int val) { return (val<0)?-val:val; }
+    /** returns the max of two numbers @param x value 1 @param y value 2*/
+    inline int max(int x, int y) { return (x>y)? x:y; }
+    /** returns the min of two numbers @param x value 1 @param y value 2*/
+    inline int min(int x, int y) { return (x<y)? x: y; }
+
+
+  private:
+    SDL_Surface*                          heightMap;                          //!< image of the height map
+    SDL_Surface*                          colorMap;                           //!< image of the color map
+    unsigned char*                        heights;
+    unsigned char*                        colors;
+
+    Vector**                              normalVectorField;
+    Tile***                               tiles;
+    Vector                                camCoords;
+    Vector                                offsetCoords;
+    Material*                             tmp_mat;
+    Material*                             red_mat;
+    Texture*                              texture;
+    const PNode*                          camera;
+
+    float                                 scaleX ;
+    float                                 scaleY ;
+    float                                 scaleZ ;
+    float                                 shiftX ; // to be removed
+    float                                 shiftY ; // to be removed
+    float                                 shiftZ ; // to be removed
+    float                                 offsetX;
+    float                                 offsetY;
+    float                                 offsetZ;
+    int                                   cmScaleX;
+    int                                   cmScaleY;
+    bool                                  hasColourMap;
+};
Index: branches/heathaze/src/lib/graphics/importer/interactive_model.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/interactive_model.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/interactive_model.cc	(revision 9940)
@@ -0,0 +1,42 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MODEL
+
+#include "interactive_model.h"
+
+#include "glincl.h"
+
+
+
+ObjectListDefinition(InteractiveModel);
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+InteractiveModel::InteractiveModel()
+{
+  this->registerObject(this, InteractiveModel::_objectList);
+}
+
+
+/**
+ * standard deconstructor
+*/
+InteractiveModel::~InteractiveModel()
+{}
+
+
Index: branches/heathaze/src/lib/graphics/importer/interactive_model.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/interactive_model.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/interactive_model.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+
+/*!
+ * @file interactive_model.h
+ *  Definition of an abstract interactive model.
+ *   it offers a skeletton for choosing animations, ticking the model a.s.o
+ */
+
+#ifndef _INTERACTIVE_MODEL_H
+#define _INTERACTIVE_MODEL_H
+
+#include "model.h"
+#include "vector.h"
+
+
+
+class InteractiveModel : public Model
+{
+  ObjectListDeclaration(InteractiveModel);
+  public:
+    InteractiveModel();
+    ~InteractiveModel();
+
+    virtual void tick(float) = 0;
+
+    virtual void setAnimation(int animNum, int playbackMode = 0) = 0;
+    virtual void setAnimation(int firstFrame, int lastFrame, int fps, int bStoppable, int animPlayback) {}
+    virtual int getAnimation() const = 0;
+
+    virtual bool isAnimationFinished() { return false; }
+
+    virtual void setAnimationSpeed(float speed) {}
+};
+
+
+#endif /* _INTERACTIVE_MODEL_H */
Index: branches/heathaze/src/lib/graphics/importer/material.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/material.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/material.cc	(revision 9940)
@@ -0,0 +1,506 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "material.h"
+
+#include "texture.h"
+#include "debug.h"
+#include "compiler.h"
+
+#include "loading/load_param.h"
+
+#include "resource_texture.h"
+
+ObjectListDefinition(Material);
+
+/**
+ * @brief creates a Material.
+ * @param mtlName Name of the Material to be added to the Material List
+ */
+Material::Material (const std::string& mtlName)
+{
+  this->registerObject(this, Material::_objectList);
+
+  this->setIllum(3);
+  this->setDiffuse(1,1,1);
+  this->setAmbient(0,0,0);
+  this->setSpecular(.5,.5,.5);
+  this->setShininess(2.0);
+  this->setTransparency(1.0);
+
+  this->ambientTexture = NULL;
+  this->specularTexture = NULL;
+  this->sFactor = GL_SRC_ALPHA;
+  this->tFactor = GL_ONE;
+
+  this->setName(mtlName);
+}
+
+Material& Material::operator=(const Material& material)
+{
+  this->illumModel = material.illumModel;
+  this->diffuse = material.diffuse;
+  this->specular = material.specular;
+  this->ambient = material.ambient;
+  this->shininess = material.shininess;
+
+  this->textures = material.textures;
+  this->sFactor = material.sFactor;
+  this->tFactor = material.tFactor;
+  this->setName(material.getName());
+
+  return *this;
+}
+
+
+
+void Material::loadParams(const TiXmlElement* root)
+{
+  LoadParam(root, "illum", this, Material, setIllum);
+
+  LoadParam(root, "diffuse-color", this, Material , setDiffuse);
+  LoadParam(root, "ambient-color", this, Material , setAmbient);
+  LoadParam(root, "specular-color", this, Material , setSpecular);
+  LoadParam(root, "transparency", this, Material , setTransparency);
+
+  LoadParam(root, "tex", this, Material, setDiffuseMap);
+  LoadParam(root, "blendfunc", this, Material, setBlendFuncS)
+  .defaultValues("ZERO", "ZERO");
+}
+
+
+/**
+ * @brief deletes a Material
+ */
+Material::~Material()
+{
+  PRINTF(5)("delete Material %s.\n", this->getCName());
+
+  if (this == Material::selectedMaterial)
+    Material::selectedMaterial = NULL;
+}
+
+
+const Material* Material::selectedMaterial = NULL;
+
+/**
+ * @brief sets the material with which the following Faces will be painted
+ */
+bool Material::select() const
+{
+  if (unlikely(this == Material::selectedMaterial))
+    return true;
+
+  /// !!  HACK !!! FIX THIS IN MODEL ///
+  else if (likely(Material::selectedMaterial != NULL))
+  {
+    Material::unselect();
+    //     for(unsigned int i = 0; i < Material::selectedMaterial->textures.size(); ++i)
+    //     {
+    //         glActiveTexture(Material::glTextureArbs[i]);
+    //         glBindTexture(GL_TEXTURE_2D, 0);
+    //         glDisable(GL_TEXTURE_2D);
+    //     }
+  }
+
+  if (likely(Material::selectedMaterial != NULL))
+  {
+    for(unsigned int i = 0; i < Material::selectedMaterial->textures.size(); ++i)
+    {
+      if (GLEW_ARB_multitexture)
+        glActiveTexture(Material::glTextureArbs[i]);
+      //glBindTexture(GL_TEXTURE_2D, 0);
+      glDisable(GL_TEXTURE_2D);
+    }
+  }
+
+  // setting diffuse color
+  glColor4f (diffuse.r(), diffuse.g(), diffuse.b(), diffuse.a());
+  // setting ambient color
+  glMaterialfv(GL_FRONT, GL_AMBIENT, &this->ambient[0]);
+  // setting up Sprecular
+  glMaterialfv(GL_FRONT, GL_SPECULAR, &this->specular[0]);
+  // setting up Shininess
+  glMaterialf(GL_FRONT, GL_SHININESS, this->shininess);
+
+  // setting the transparency
+  if (this->diffuse.a() < 1.0 ||       /* This allows alpha blending of 2D textures with the scene */
+      (likely(!this->textures.empty() && this->textures[0].hasAlpha())))
+  {
+    glEnable(GL_BLEND);
+    glBlendFunc(this->sFactor, this->tFactor);
+  }
+  else
+  {
+    glDisable(GL_BLEND);
+  }
+
+
+  // setting illumination Model
+  if (this->illumModel == 1) //! @todo make this work, if no vertex-normals are read.
+    glShadeModel(GL_FLAT);
+  else if (this->illumModel >= 2)
+    glShadeModel(GL_SMOOTH);
+
+  for(unsigned int i = 0; i < this->textures.size(); ++i)
+  {
+    if (GLEW_ARB_multitexture)
+      glActiveTexture(Material::glTextureArbs[i]);
+    glEnable(GL_TEXTURE_2D);
+    if(this->textures[i].hasAlpha())
+    {
+      glEnable(GL_BLEND);
+    }
+    glBindTexture(GL_TEXTURE_2D, this->textures[i].getTexture());
+  }
+  Material::selectedMaterial = this;
+
+  return true;
+}
+/**
+ * @brief Deselect Material (if one is selected).
+ */
+void Material::unselect()
+{
+  Material::selectedMaterial = NULL;
+  for(unsigned int i = 0; i < 8; ++i)
+  {
+    glActiveTexture(Material::glTextureArbs[i]);
+    glBindTexture(GL_TEXTURE_2D, 0);
+    glDisable(GL_TEXTURE_2D);
+  }
+}
+
+/**
+ * @brief Sets the Material Illumination Model.
+ * @param illu illumination Model in int form
+ */
+void Material::setIllum (int illum)
+{
+  PRINTF(4)("setting illumModel of Material %s to %i\n", this->getCName(), illum);
+  this->illumModel = illum;
+}
+
+/**
+ * @brief Sets the Material Diffuse Color.
+ * @param r Red Color Channel.a
+ * @param g Green Color Channel.
+ * @param b Blue Color Channel.
+ */
+void Material::setDiffuse (float r, float g, float b)
+{
+  PRINTF(4)("setting Diffuse Color of Material %s to r=%f g=%f b=%f.\n", this->getCName(), r, g, b);
+  this->diffuse = Color(r, g, b, this->diffuse.a() );
+}
+
+
+/**
+ * @brief Sets the Material Ambient Color.
+ * @param r Red Color Channel.
+ * @param g Green Color Channel.
+ * @param b Blue Color Channel.
+*/
+void Material::setAmbient (float r, float g, float b)
+{
+  PRINTF(4)("setting Ambient Color of Material %s to r=%f g=%f b=%f.\n", this->getCName(), r, g, b);
+  this->ambient = Color(r, g, b, 1.0);
+}
+
+/**
+ * @brief Sets the Material Specular Color.
+ * @param r Red Color Channel.
+ * @param g Green Color Channel.
+ * @param b Blue Color Channel.
+ */
+void Material::setSpecular (float r, float g, float b)
+{
+  PRINTF(4)("setting Specular Color of Material %s to r=%f g=%f b=%f.\n", this->getCName(), r, g, b);
+  this->specular = Color (r, g, b, 1.0);
+}
+
+/**
+ * @brief Sets the Material Shininess.
+ * @param shini stes the Shininess from float.
+*/
+void Material::setShininess (float shini)
+{
+  this->shininess = shini;
+}
+
+/**
+ * @brief Sets the Material Transparency.
+ * @param trans stes the Transparency from int.
+*/
+void Material::setTransparency (float trans)
+{
+  PRINTF(4)("setting Transparency of Material %s to %f.\n", this->getCName(), trans);
+  this->diffuse.a() = trans;
+}
+
+/**
+ * @brief sets the Blend-Function Parameters
+ * @param sFactor the Source Parameter.
+ * @param tFactor the Desitnation Parameter.
+ */
+void Material::setBlendFuncS(const std::string& sFactor, const std::string& tFactor)
+{
+  this->setBlendFunc(Material::stringToBlendFunc(sFactor), Material::stringToBlendFunc(tFactor));
+}
+
+
+/**
+ * @brief Sets the Diffuse map of this Texture.
+ * @param texture The Texture to load
+ * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS
+ */
+void Material::setDiffuseMap(const Texture& texture, unsigned int textureNumber)
+{
+  assert(textureNumber < Material::getMaxTextureUnits());
+
+  if (this->textures.size() <= textureNumber)
+    this->textures.resize(textureNumber+1, Texture());
+
+  //! @todo check if RESOURCE MANAGER is availiable
+  this->textures[textureNumber] = texture;
+}
+
+/**
+ * @brief Sets the Diffuse map of this Texture by a Texture-pointer.
+ * @param textureDataPointer The Texture-Data-Pointer to load.
+ * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS
+ */
+void Material::setDiffuseMap(const TextureData::Pointer& textureDataPointer, unsigned int textureNumber)
+{
+  assert(textureNumber < Material::getMaxTextureUnits());
+
+  if (this->textures.size() <= textureNumber)
+    this->textures.resize(textureNumber+1, Texture());
+
+  this->textures[textureNumber] = textureDataPointer;
+}
+
+
+/**
+ * @brief Sets the Materials Diffuse Map
+ * @param dMap the Name of the Image to Use
+ * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS
+ */
+void Material::setDiffuseMap(const std::string& dMap, GLenum target, unsigned int textureNumber)
+{
+  assert(textureNumber < Material::getMaxTextureUnits());
+
+  PRINTF(5)("setting Diffuse Map %s\n", dMap.c_str());
+  if (this->textures.size() <= textureNumber)
+    this->textures.resize(textureNumber+1, Texture());
+
+  //! @todo check if RESOURCE MANAGER is availiable
+  if (!dMap.empty())
+  {
+    this->textures[textureNumber] = ResourceTexture(dMap);
+    //dynamic_cast<Texture*>(ResourceManager::getInstance()->load(dMap, IMAGE, RP_GAME, (int)target));
+    /*    if (tex != NULL)
+          this->textures[textureNumber] = tex;
+        else
+          this->textures[textureNumber] = Texture();*/
+  }
+  else
+  {
+    this->textures[textureNumber] = Texture();
+  }
+}
+
+/**
+ * @brief Sets the Materials Diffuse Map
+ * @param surface pointer to SDL_Surface which shall be used as texture.
+ * @param target the GL-Target to load the Surface to.
+ * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS.
+ */
+void Material::setSDLDiffuseMap(SDL_Surface *surface, GLenum target, unsigned int textureNumber)
+{
+  assert(textureNumber < Material::getMaxTextureUnits());
+
+
+  if (this->textures.size() <= textureNumber)
+    this->textures.resize(textureNumber+1, Texture());
+
+  if(surface != NULL)
+  {
+    this->textures[textureNumber] = Texture(surface, GL_TEXTURE_2D);
+  }
+  else
+  {
+    this->textures[textureNumber] = Texture();
+  }
+
+}
+
+/**
+ * @brief Renders to a Texture.
+ * @param textureNumber The Texture-Number from 0 to GL_MAX_TEXTURE_UNITS.
+ * @param target The GL-Target.
+ * @param level the MipMap-Level to render to.
+ * @param xoffset The offset in the Source from the left.
+ * @param yoffset The offset in the Source from the top (or bottom).
+ * @param x The Offset in the Destination from the left.
+ * @param y The Offset in the Destination from the top (or bottom).
+ * @param width The width of the region to copy.
+ * @param height The height of the region to copy.
+ */
+void Material::renderToTexture(unsigned int textureNumber, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+  assert(textureNumber < Material::getMaxTextureUnits());
+  assert(textureNumber < this->textures.size());
+
+  // HACK
+  glActiveTexture(textureNumber);
+  glEnable(GL_TEXTURE_2D);
+  glBindTexture(GL_TEXTURE_2D, this->textures[textureNumber].getTexture());
+  glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+
+}
+
+/**
+ * @brief Sets the Materials Ambient Map
+ * @todo implement this
+ */
+void Material::setAmbientMap(const std::string& aMap, GLenum target)
+{
+  /// FIXME SDL_Surface* ambientMap;
+
+}
+
+/**
+ * @brief Sets the Materials Specular Map
+ * @param sMap the Name of the Image to Use
+ * @todo implement this
+ */
+void Material::setSpecularMap(const std::string& sMap, GLenum target)
+{
+  /// FIXME SDL_Surface* specularMap;
+
+}
+
+/**
+ * @brief Sets the Materials Bumpiness
+ * @param bump the Name of the Image to Use
+ * @todo implemet this
+ */
+void Material::setBump(const std::string& bump)
+{}
+
+
+/**
+ * @returns the Maximim Texture Unit the users OpenGL-Implementation supports.
+ */
+unsigned int Material::getMaxTextureUnits()
+{
+  int maxTexUnits = 0;
+  glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTexUnits);
+  return maxTexUnits;
+}
+
+
+
+void Material::debug() const
+{
+  PRINT(0)("Debug Material: %s\n", this->getCName());
+  PRINT(0)("illumModel: %d ; ShiniNess %f\n", this->illumModel, shininess);
+  PRINT(0)("diffuseColor: "); diffuse.debug();
+  PRINT(0)("ambientColor: "); ambient.debug();
+  PRINT(0)("diffuseColor: "); specular.debug();
+  PRINT(0)("Blending Properties: Source: %s, Destination: %s\n", blendFuncToString(sFactor).c_str(), blendFuncToString(tFactor).c_str());
+
+  PRINT(0)("Textures: %d loaded", textures.size());
+  if (!this->textures.empty())
+  {
+    PRINT(0)(" - ID's: ");
+    for (unsigned int i = 0; i < textures.size(); ++i)
+    {
+      PRINT(0)("%d ", textures[i].getTexture());
+    }
+  }
+  PRINT(0)("\n");
+}
+
+
+const GLenum Material::glTextureArbs[] =
+  {
+    GL_TEXTURE0,
+    GL_TEXTURE1,
+    GL_TEXTURE2,
+    GL_TEXTURE3,
+    GL_TEXTURE4,
+    GL_TEXTURE5,
+    GL_TEXTURE6,
+    GL_TEXTURE7
+  };
+
+
+/**
+ * @param blendFunc the Enumerator to convert to a String.
+ * @returns the matching String if found
+ */
+const std::string& Material::blendFuncToString(GLenum blendFunc)
+{
+  for (unsigned int i = 0; i < 9; ++i)
+    if (blendFunc == Material::glBlendFuncParams[i])
+      return Material::blendFuncNames[i];
+  PRINTF(2)("Supplied an Invalid Enumerator to blendfunc %d\n", blendFunc);
+  return Material::blendFuncNames[0];
+}
+
+/**
+ * @param blendFuncString the String to convert into a gl-enumeration
+ * @returns the matching GL-enumeration if found.
+ */
+GLenum Material::stringToBlendFunc(const std::string& blendFuncString)
+{
+  for (unsigned int i = 0; i < 9; ++i)
+    if (blendFuncString == Material::blendFuncNames[i])
+      return Material::glBlendFuncParams[i];
+  PRINTF(2)("BlendFunction %s not recognized using %s\n", blendFuncString.c_str(), Material::blendFuncNames[0].c_str());
+  return Material::glBlendFuncParams[0];
+}
+
+
+const GLenum Material::glBlendFuncParams[] =
+  {
+    GL_ZERO,
+    GL_ONE,
+    GL_DST_COLOR,
+    GL_ONE_MINUS_DST_COLOR,
+    GL_SRC_ALPHA,
+    GL_ONE_MINUS_SRC_ALPHA,
+    GL_DST_ALPHA,
+    GL_ONE_MINUS_DST_ALPHA,
+    GL_SRC_ALPHA_SATURATE
+  };
+
+const std::string Material::blendFuncNames[] =
+  {
+    "ZERO",
+    "ONE",
+    "DST_COLOR",
+    "ONE_MINUS_DST_COLOR",
+    "SRC_ALPHA",
+    "ONE_MINUS_SRC_ALPHA",
+    "DST_ALPHA",
+    "ONE_MINUS_DST_ALPHA",
+    "SRC_ALPHA_SATURATE"
+
+  };
Index: branches/heathaze/src/lib/graphics/importer/material.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/material.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/material.h	(revision 9940)
@@ -0,0 +1,99 @@
+/*!
+ * @file material.h
+ * @brief Contains the Material Class that handles Material for 3D-Objects.
+ * @todo free SDL-surface when deleting Material.
+ * @todo delete imgNameWithPath after use creation.
+ */
+
+#ifndef _MATERIAL_H
+#define _MATERIAL_H
+#include "base_object.h"
+
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <vector>
+#include "texture.h"
+#include "color.h"
+
+// FORWARD DECLARATIONS //
+
+//! Class to handle Materials.
+class Material : public BaseObject
+{
+  ObjectListDeclaration(Material);
+public:
+  Material (const std::string& mtlName = "");
+  virtual ~Material ();
+
+  Material& operator=(const Material& material);
+
+  void loadParams(const TiXmlElement* root);
+
+  bool select () const;
+  bool activateTextureUnit(unsigned int textureNumber);
+  static void unselect();
+
+  void setIllum (int illum);
+  int getIllumModel() const { return this->illumModel; };
+
+  void setDiffuse (float r, float g, float b);
+  void setDiffuseColor(const Color& diffuseColor) { this->diffuse = diffuseColor; };
+  void setAmbient (float r, float g, float b);
+  void setSpecular (float r, float g, float b);
+  void setShininess (float shini);
+  void setTransparency (float trans);
+  void setBlendFunc(GLenum sFactor, GLenum tFactor) { this->sFactor = sFactor; this->tFactor = tFactor; };
+  void setBlendFuncS(const std::string& sFactor, const std::string& tFactor);
+
+  Color& diffuseColor() { return diffuse; };
+  const Color& diffuseColor() const { return diffuse; };
+
+  // MAPPING //
+  void setDiffuseMap(const Texture& texture, unsigned int textureNumber = 0);
+  void setDiffuseMap(const TextureData::Pointer& texturePointer, unsigned int textureNumber = 0);
+  void setDiffuseMap(const std::string& dMap, GLenum target = GL_TEXTURE_2D, unsigned int textureNumber = 0);
+  void setSDLDiffuseMap(SDL_Surface *surface, GLenum target = GL_TEXTURE_2D, unsigned int textureNumber = 0);
+  void renderToTexture(unsigned int textureNumber, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+
+  void setAmbientMap(const std::string& aMap, GLenum target = GL_TEXTURE_2D);
+  void setSpecularMap(const std::string& sMap, GLenum target = GL_TEXTURE_2D);
+  void setBump(const std::string& bump);
+
+  GLuint diffuseTextureID(unsigned int i = 0) const { return (this->textures.size() > i)? this->textures[i].getTexture() : 0; };
+
+  const Texture& diffuseTexture(unsigned int i = 0) const { return this->textures[i]; };
+
+  static const std::string& blendFuncToString(GLenum blendFunc);
+  static GLenum stringToBlendFunc(const std::string& blendFuncString);
+
+  void debug() const;
+
+public:
+  static const GLenum glTextureArbs[];  //!< The Texture ARB's
+
+  static const GLenum glBlendFuncParams[];
+  static const std::string blendFuncNames[];
+
+  static unsigned int getMaxTextureUnits();
+
+private:
+  static const Material* selectedMaterial; //!< The currently selected material.
+
+  int              illumModel;       //!< The IlluminationModel is either flat or smooth.
+  Color            diffuse;          //!< The diffuse color of the Material. (also transparency.)
+  Color            ambient;          //!< The ambient color of the Material.
+  Color            specular;         //!< The specular color of the Material.
+  float            shininess;        //!< The shininess of the Material.
+  GLenum           sFactor;          //!< The Blending Factor for the Source.
+  GLenum           tFactor;          //!< The Blending Factor for the Destination.
+
+  std::vector<Texture> textures;     //!< An Array of Textures.
+
+  Texture*         ambientTexture;   //!< The ambient texture of the Material.
+  Texture*         specularTexture;  //!< The specular texture of the Material.
+};
+
+#endif
Index: branches/heathaze/src/lib/graphics/importer/md2/md2Model.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md2/md2Model.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md2/md2Model.cc	(revision 9940)
@@ -0,0 +1,594 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "md2Model.h"
+#include "material.h"
+
+#include "debug.h"
+#include "resource_md2.h"
+
+
+ObjectListDefinition(MD2Model);
+
+//! the model anorms
+sVec3D MD2Model::anorms[NUM_VERTEX_NORMALS] = {
+#include "anorms.h"
+    };
+
+//! anormal dots, no idea of how this shall work, but it does
+float MD2Model::anormsDots[SHADEDOT_QUANT][256] = {
+#include "anormtab.h"
+    };
+
+
+//! the angle under which the model is viewd, used internaly
+float md2Angle = 0.0f;
+
+
+//! list of all different animations a std md2model supports
+sAnim MD2Model::animationList[22] =
+  {
+    // begin, end, fps, interruptable
+    {   0,  39,  9, 1 },   //!< STAND
+    {  40,  45, 10, 1 },   //!< RUN
+    {  46,  53, 10, 0 },   //!< ATTACK
+    {  54,  57,  7, 1 },   //!< PAIN_A
+    {  58,  61,  7, 1 },   //!< PAIN_B
+    {  62,  65,  7, 1 },   //!< PAIN_C
+    {  66,  71,  7, 0 },   //!< JUMP
+    {  72,  83,  7, 1 },   //!< FLIP
+    {  84,  94,  7, 1 },   //!< SALUTE
+    {  95, 111, 10, 1 },   //!< FALLBACK
+    { 112, 122,  7, 1 },   //!< WAVE
+    { 123, 134,  6, 1 },   //!< POINTT
+    { 135, 153, 10, 1 },   //!< CROUCH_STAND
+    { 154, 159,  7, 1 },   //!< CROUCH_WALK
+    { 160, 168, 10, 1 },   //!< CROUCH_ATTACK
+    { 196, 172,  7, 1 },   //!< CROUCH_PAIN
+    { 173, 177,  5, 0 },   //!< CROUCH_DEATH
+    { 178, 183,  10, 0 },   //!< DEATH_FALLBACK
+    { 184, 189,  10, 0 },   //!< DEATH_FALLFORWARD
+    { 190, 197,  10, 0 },   //!< DEATH_FALLBACKSLOW
+    { 198, 198,  5, 1 },   //!< BOOM
+    {  199, 204, 10, 1 },  //!< WALK (only for spectial models)
+  };
+
+
+
+/********************************************************************************
+ *   MD2Model                                                                   *
+ ********************************************************************************/
+
+MD2Model::MD2Model()
+  : data(new MD2Data())
+{
+  this->init();
+}
+
+#include "resource_md2.h"
+/**
+  \brief simple constructor initializing all variables
+*/
+MD2Model::MD2Model(const std::string& modelFileName, const std::string& skinFileName, float scale)
+    : data(new MD2Data())
+{
+  this->init();
+  this->scaleFactor = scale;
+
+  this->data = ResourceMD2(modelFileName, skinFileName, scale).data;
+  rebuildInfo();
+
+  //this->debug();
+}
+
+MD2Model::MD2Model(const MD2Model& model)
+  : data(model.data)
+{
+  this->init();
+  this->rebuildInfo();
+}
+
+MD2Model& MD2Model::operator=(const MD2Model& md2model)
+{
+  this->data = md2model.data;
+  this->rebuildInfo();
+  return *this;
+}
+
+void MD2Model::rebuildInfo()
+{
+  //write the modelinfo information
+  this->pModelInfo.numVertices = this->data->numVertices;
+  this->pModelInfo.numTriangles = this->data->numTriangles;
+  this->pModelInfo.numNormals = 0;
+  this->pModelInfo.numTexCoor = this->data->numTexCoor;
+  this->pModelInfo.pVertices = (float*)this->data->pVertices;
+  this->pModelInfo.pNormals = NULL;
+  this->pModelInfo.pTexCoor = (float*)this->data->pTexCoor;
+
+
+  // triangle conversion
+  if (this->pModelInfo.pTriangles != NULL)
+    delete[] this->pModelInfo.pTriangles;
+  this->pModelInfo.pTriangles = new sTriangleExt[this->data->numTriangles];
+  for( int i = 0; i < this->data->numTriangles; i++)
+  {
+    this->pModelInfo.pTriangles[i].indexToVertices[0] = this->data->pTriangles[i].indexToVertices[0];
+    this->pModelInfo.pTriangles[i].indexToVertices[1] = this->data->pTriangles[i].indexToVertices[1];
+    this->pModelInfo.pTriangles[i].indexToVertices[2] = this->data->pTriangles[i].indexToVertices[2];
+
+    this->pModelInfo.pTriangles[i].indexToTexCoor[0] = this->data->pTriangles[i].indexToTexCoor[0];
+    this->pModelInfo.pTriangles[i].indexToTexCoor[1] = this->data->pTriangles[i].indexToTexCoor[1];
+    this->pModelInfo.pTriangles[i].indexToTexCoor[2] = this->data->pTriangles[i].indexToTexCoor[2];
+  }
+}
+
+bool MD2Model::load(const std::string& modelFileName, const std::string& skinFileName, float scale)
+{
+  this->data = MD2Data::Pointer(new MD2Data(modelFileName, skinFileName, scale));
+  this->rebuildInfo();
+}
+
+
+/**
+  \brief simple destructor, dereferencing all variables
+
+  this is where the ressource manager is cleaning the stuff
+*/
+MD2Model::~MD2Model()
+{
+  this->pModelInfo.pVertices = NULL;
+  this->pModelInfo.pNormals = NULL;
+  this->pModelInfo.pTexCoor = NULL;
+  this->pModelInfo.pTriangles = NULL;
+}
+
+
+void MD2Model::init()
+{
+  this->registerObject(this, MD2Model::_objectList);
+  /* this creates the data container via ressource manager */
+  if( unlikely(this->data.isNull()))
+    PRINTF(0)("The model was not found, MD2Model Loader finished abnormaly. Update the data-repos\n");
+
+  this->scaleFactor = 1.0f;
+  this->animationSpeed = 1.0f;
+
+  shadeDots = MD2Model::anormsDots[0];
+  /* set the animation stat mannualy */
+  this->animationState.type = STAND;
+  this->animationState.numPlays = 1;
+  this->setAnimation(STAND);
+}
+
+/**
+ *  initializes an array of vert with the current frame scaled vertices
+ * @param this->verticesList: the list of vertices to interpolate between
+
+   we won't use the pVertices array directly, since its much easier and we need
+   saving of data anyway
+*/
+void MD2Model::interpolate(/*sVec3D* this->verticesList*/)
+{
+  sVec3D* currVec;
+  sVec3D* nextVec;
+
+  currVec = &this->data->pVertices[this->data->numVertices * this->animationState.currentFrame];
+  nextVec = &this->data->pVertices[this->data->numVertices * this->animationState.nextFrame];
+
+  for( int i = 0; i < this->data->numVertices; ++i)
+  {
+    this->verticesList[i][0] = currVec[i][0] + this->animationState.interpolationState * (nextVec[i][0] - currVec[i][0]);
+    this->verticesList[i][1] = currVec[i][1] + this->animationState.interpolationState * (nextVec[i][1] - currVec[i][1]);
+    this->verticesList[i][2] = currVec[i][2] + this->animationState.interpolationState * (nextVec[i][2] - currVec[i][2]);
+  }
+}
+
+
+/**
+ * sets the animation type
+ * @param firstFrame: index of the first frame
+ * @param lastFrame: index of the last frame
+ * @param fps: frames per second
+ * @param bStoppable: is 1 if so, 0 else
+ */
+void MD2Model::setAnimation(int firstFrame, int lastFrame, int fps, int bStoppable, int animPlayback)
+{
+  this->animationState.startFrame = firstFrame;
+  this->animationState.endFrame = lastFrame;
+  this->animationState.nextFrame = firstFrame + 1;
+  this->animationState.fps = fps;
+  this->animationState.type = 0;
+  this->animationState.numPlays = 0;
+  this->animationState.animPlaybackMode = animPlayback;
+
+  this->animationState.interpolationState = 0.0f;
+  this->animationState.localTime = 0.0f;
+  this->animationState.lastTime = 0.0f;
+  this->animationState.currentFrame = firstFrame;
+}
+
+/**
+  \brief sets the animation type
+* @param type: animation type
+
+  the animation types can be looked up in the animationType table
+*/
+void MD2Model::setAnimation(int type, int animPlayback)
+{
+  if( (type < 0) || (type > MAX_ANIMATIONS) )
+    type = STAND;
+
+  if( MD2Model::animationList[this->animationState.type].bStoppable == 0)
+  {
+    if( this->animationState.numPlays == 0 )
+      return;
+  }
+
+  this->animationState.startFrame = animationList[type].firstFrame;
+  this->animationState.endFrame = animationList[type].lastFrame;
+  this->animationState.nextFrame = animationList[type].firstFrame + 1;
+  this->animationState.fps = animationList[type].fps;
+  this->animationState.type = type;
+  this->animationState.numPlays = 0;
+  this->animationState.animPlaybackMode = animPlayback;
+
+  this->animationState.interpolationState = 0.0f;
+  this->animationState.localTime = 0.0f;
+  this->animationState.lastTime = 0.0f;
+  this->animationState.currentFrame = animationList[type].firstFrame;
+}
+
+
+/**
+  \brief sets the time in seconds passed since the last tick
+* @param time: in sec
+*/
+void MD2Model::tick(float time)
+{
+  this->animate(time * this->animationSpeed);
+  this->processLighting();
+  this->interpolate(/*this->verticesList*/);
+}
+
+
+/**
+ * @brief draws the model: interface for all other classes out in the world
+ * @todo make it const and virtual
+ * FIXME
+ */
+void MD2Model::draw() const
+{
+  glPushMatrix();
+  this->renderFrame();
+  // renderFrameTriangles();
+  glPopMatrix();
+}
+
+
+/**
+  \brief this is an internal function to render this special frame selected by animate()
+*/
+void MD2Model::renderFrame() const
+{
+  int* pCommands = this->data->pGLCommands;
+
+  /* some face culling stuff */
+  glPushAttrib(GL_POLYGON_BIT);
+  glFrontFace(GL_CW);
+  glEnable(GL_CULL_FACE);
+  glCullFace(GL_BACK);
+
+  this->data->material.select();
+
+  /* draw the triangles */
+  while( int i = *(pCommands++)) /* strange looking while loop for maximum performance */
+  {
+    if( i < 0)
+    {
+      glBegin(GL_TRIANGLE_FAN);
+      i = -i;
+    }
+    else
+    {
+      glBegin(GL_TRIANGLE_STRIP);
+    }
+
+    for(; i > 0; i--, pCommands += 3) /* down counting for loop, next 3 gl commands */
+    {
+      glTexCoord2f( ((float *)pCommands)[0], ((float *)pCommands)[1] );
+      glNormal3fv(anorms[this->data->pLightNormals[pCommands[2]]]);
+      glVertex3fv(this->verticesList[pCommands[2]]);
+    }
+    glEnd();
+
+  }
+  glDisable(GL_CULL_FACE);
+  glPopAttrib();
+}
+
+
+void MD2Model::renderFrameTriangles() const
+{
+  //static sVec3D this->verticesList[MD2_MAX_VERTICES]; /* performance: created only once in a lifetime */
+  int* pCommands = this->data->pGLCommands;
+  /* some face culling stuff */
+  //   glPushAttrib(GL_POLYGON_BIT);
+  //   glFrontFace(GL_CW);
+  //   glEnable(GL_CULL_FACE);
+  //   glCullFace(GL_BACK);
+  //
+  //   this->processLighting();
+  //   this->interpolate(/*this->verticesList*/);
+  this->data->material.select();
+
+  /* draw the triangles */
+  glBegin(GL_TRIANGLES);
+
+  for( int i = 0, k = 0; i < this->data->numTriangles; ++i, k += 3)
+  {
+    float* v = this->data->pVertices[this->data->pTriangles[i].indexToVertices[0]];
+
+    printf("triangle: %i\n", i);
+    printf("     v0: (%f, %f, %f)\n", v[0], v[1], v[2]);
+    v = this->data->pVertices[this->data->pTriangles[i].indexToVertices[1]];
+    printf("     v1: (%f, %f, %f)\n", v[0], v[1], v[2]);
+    v = this->data->pVertices[this->data->pTriangles[i].indexToVertices[2]];
+    printf("     v2: (%f, %f, %f)\n", v[0], v[1], v[2]);
+
+
+    glNormal3f(anorms[i][0], anorms[i][1], anorms[i][2]);
+    glVertex3fv(this->data->pVertices[this->data->pTriangles[i].indexToVertices[0]]);
+
+    glNormal3f(anorms[i][0], anorms[i][1], anorms[i][2]);
+    glVertex3fv(this->data->pVertices[this->data->pTriangles[i].indexToVertices[1]]);
+
+    glNormal3f(anorms[i][0], anorms[i][1], anorms[i][2]);
+    glVertex3fv(this->data->pVertices[this->data->pTriangles[i].indexToVertices[2]]);
+  }
+
+  glEnd();
+}
+
+
+/**
+  \brief animates the current model
+
+  depending on the time passed (tick function), the player will select another model
+*/
+void MD2Model::animate(float time)
+{
+  this->animationState.localTime += time;
+
+  if( this->animationState.localTime - this->animationState.lastTime > (1.0f / this->animationState.fps))
+  {
+    this->animationState.currentFrame = this->animationState.nextFrame;
+    this->animationState.nextFrame++;
+
+    if( this->animationState.nextFrame > this->animationState.endFrame )
+    {
+      if( this->animationState.animPlaybackMode == MD2_ANIM_LOOP)
+      {
+        this->animationState.nextFrame = this->animationState.startFrame;
+        this->animationState.numPlays++;
+      }
+      else
+      {
+        this->animationState.nextFrame = this->animationState.endFrame;
+      }
+    }
+    this->animationState.lastTime = this->animationState.localTime;
+  }
+
+  //     if( this->animationState.currentFrame > (this->data->numFrames - 1) )
+  //       this->animationState.currentFrame = 0;
+
+  //     if( (this->animationState.nextFrame > (this->data->numFrames - 1)) && this->animationState.animPlaybackMode == MD2_ANIM_LOOP)
+  //     this->animationState.nextFrame = 0;
+
+  this->animationState.interpolationState = this->animationState.fps *
+      (this->animationState.localTime - this->animationState.lastTime);
+}
+
+
+/**
+  \brief this is how id is precessing their lightning
+
+  the details of how the whole lighting process is beeing handled - i have no idea... :)
+*/
+void MD2Model::processLighting()
+{
+  shadeDots = anormsDots[((int)(md2Angle*(SHADEDOT_QUANT / 360.0)))&(SHADEDOT_QUANT - 1)];
+}
+
+
+/**
+  \brief prints out debug informations
+*/
+void MD2Model::debug()
+{
+  PRINT(0)("\n==========================| MD2Model::debug() |===\n");
+  PRINT(0)("=  Model FileName:\t%s\n", this->data->fileName.c_str());
+  PRINT(0)("=  Skin FileName:\t%s\n", this->data->skinFileName.c_str());
+  PRINT(0)("=  Size in Memory:\t%i Bytes\n", this->data->header->frameSize * this->data->header->numFrames + 64); // 64bytes is the header size
+  PRINT(0)("=  Number of Vertices:\t%i\n", this->data->header->numVertices);
+  PRINT(0)("=  Number of Frames: \t%i\n", this->data->header->numFrames);
+  PRINT(0)("=  Height, Width:\t%i, %i\n", this->data->header->skinHeight, this->data->header->skinWidth);
+  //PRINT(0)("=  Pointer to the data object: %p\n", this->data);
+  PRINT(0)("===================================================\n\n");
+}
+
+
+/********************************************************************************
+ *   MD2Data                                                                    *
+ ********************************************************************************/
+
+MD2Data::MD2Data()
+{
+  this->init();
+}
+
+/**
+  \brief simple constructor
+*/
+MD2Data::MD2Data(const std::string& modelFileName, const std::string& skinFileName, float scale)
+{
+  this->init();
+  this->scaleFactor = scale * .1;
+
+  this->loadModel(modelFileName);
+  this->loadSkin(skinFileName);
+}
+
+void MD2Data::init()
+{
+  this->scaleFactor = 1.0;
+  this->pVertices = NULL;
+  this->pGLCommands = NULL;
+  this->pLightNormals = NULL;
+  this->pTexCoor = NULL;
+  this->header = NULL;
+
+  this->numFrames = 0;
+  this->numVertices = 0;
+  this->numGLCommands = 0;
+  this->numTexCoor = 0;
+}
+
+/**
+  \brief simple destructor
+
+  this will clean out all the necessary data for a specific md2model
+*/
+MD2Data::~MD2Data()
+{
+  delete this->header;
+
+  delete [] this->pVertices;
+  delete [] this->pGLCommands;
+  delete [] this->pLightNormals;
+  delete [] this->pTexCoor;
+}
+
+
+
+/**
+  \brief this will load the whole model data (vertices, opengl command list, ...)
+* @param fileName: the name of the model file
+  \return true if success
+*/
+bool MD2Data::loadModel(const std::string& fileName)
+{
+  FILE *pFile;                            //file stream
+  char* buffer;                           //buffer for frame data
+  sFrame* frame;                          //temp frame
+  sVec3D *pVertex;
+  int* pNormals;
+
+  //! @todo this chek should include deleting a loaded model (eventually)
+  if (fileName.empty())
+    return false;
+
+  pFile = fopen(fileName.c_str(), "rb");
+  if( unlikely(!pFile))
+  {
+    PRINTF(1)("Couldn't open the MD2 File for loading. Exiting.\n");
+    return false;
+  }
+  this->header = new MD2Header;
+  fread(this->header, 1, sizeof(MD2Header), pFile);
+  /* check for the header version: make sure its a md2 file :) */
+  if( unlikely(this->header->version != MD2_VERSION) && unlikely(this->header->ident != MD2_IDENT))
+  {
+    PRINTF(1)("Couldn't load file %s: invalid file format: stop loading\n", fileName.c_str());
+    return false;
+  }
+
+  this->fileName =fileName;
+  /* got the data: map it to locals */
+  this->numFrames = this->header->numFrames;
+  this->numVertices = this->header->numVertices;
+  this->numTriangles = this->header->numTriangles;
+  this->numGLCommands = this->header->numGlCommands;
+  this->numTexCoor = this->header->numTexCoords;
+  /* allocate memory for the data storage */
+  this->pVertices = new sVec3D[this->numVertices * this->numFrames];
+  this->pGLCommands = new int[this->numGLCommands];
+  this->pLightNormals = new int[this->numVertices * this->numFrames];
+  this->pTriangles = new sTriangle[this->numTriangles];
+  this->pTexCoor = new sTexCoor[this->numTexCoor];
+  buffer = new char[this->numFrames * this->header->frameSize];
+
+
+  /* read frame data from the file to a temp buffer */
+  fseek(pFile, this->header->offsetFrames, SEEK_SET);
+  fread(buffer, this->header->frameSize, this->numFrames, pFile);
+  /* read opengl commands */
+  fseek(pFile, this->header->offsetGlCommands, SEEK_SET);
+  fread(this->pGLCommands, sizeof(int), this->numGLCommands, pFile);
+  /* triangle list */
+  fseek(pFile, this->header->offsetTriangles, SEEK_SET);
+  fread(this->pTriangles, sizeof(sTriangle), this->numTriangles, pFile);
+  /*  read in texture coordinates */
+  fseek(pFile, this->header->offsetTexCoords, SEEK_SET);
+  fread(this->pTexCoor, sizeof(sTexCoor), this->numTexCoor, pFile);
+
+
+  for(int i = 0; i < this->numFrames; ++i)
+  {
+    frame = (sFrame*)(buffer + this->header->frameSize * i);
+    pVertex = this->pVertices + this->numVertices  * i;
+    pNormals = this->pLightNormals + this->numVertices * i;
+
+    for(int j = 0; j < this->numVertices; ++j)
+    {
+      /* SPEEDUP: *(pVerts + i + 0) = (*(frame->pVertices + i + 0)...  */
+      pVertex[j][0] = ((frame->pVertices[j].v[0] * frame->scale[0] ) + frame->translate[0] )* this->scaleFactor;
+      pVertex[j][1] = ((frame->pVertices[j].v[2] * frame->scale[2]) + frame->translate[2]) * this->scaleFactor;
+      pVertex[j][2] = (-1.0 * (frame->pVertices[j].v[1] * frame->scale[1] + frame->translate[1])) * this->scaleFactor;
+
+      //printf("vertex %i/%i: (%f, %f, %f)\n", j, this->numVertices, pVertex[j][0], pVertex[j][1], pVertex[j][2]);
+
+      pNormals[j] = frame->pVertices[j].lightNormalIndex;
+    }
+  }
+  PRINTF(4)("Finished loading the md2 file\n");
+
+  delete [] buffer;
+  fclose(pFile);
+}
+
+
+/**
+  \brief loads the skin/material stuff
+* @param fileName: name of the skin file
+  \return true if success
+*/
+bool MD2Data::loadSkin(const std::string& fileName)
+{
+  if( fileName.empty())
+  {
+    this->skinFileName = "";
+    return false;
+  }
+
+  this->skinFileName = fileName;
+
+  this->material.setName("md2ModelMaterial");
+  this->material.setDiffuseMap(fileName);
+  this->material.setIllum(3);
+  this->material.setAmbient(1.0, 1.0, 1.0);
+}
Index: branches/heathaze/src/lib/graphics/importer/md2/md2Model.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md2/md2Model.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md2/md2Model.h	(revision 9940)
@@ -0,0 +1,218 @@
+/*!
+ * @file md2Model.h
+  *  Definition of an MD2 Model, a model format invented by ID Software.
+
+    We are deeply thankfull for all the wunderfull things id software made for us gamers!
+
+    The md2 file format is structured in a very simple way: it contains animations which are made out of
+    frames (so called keyframes). Each frame is a complete draweable model in a specific position.
+    A frame is a collection of vertex and its compagnions (normals, texture coordinates).
+
+    A typical model has about 200 frames, the maximum frame count is fixed by MD2_MAX_FRAMES to currently
+    512 frames. The maximal vetices count is set to 2048 verteces, not enough?
+    You just have to change the MD2_MAX_* values if it doesn't fit your purposes...
+
+    Surface Culling is fully implemented in md2 models: quake2 uses front face culling.
+*/
+
+#ifndef _MD2MODEL_H
+#define _MD2MODEL_H
+
+#include "base_object.h"
+#include "count_pointer.h"
+
+#include "interactive_model.h"
+#include "material.h"
+
+#include "md_model_structure.h"
+
+//! These are the needed defines for the max values when loading .MD2 files
+#define MD2_IDENT                       (('2'<<24) + ('P'<<16) + ('D'<<8) + 'I') //!< the md2 identifier tag in the bin file
+#define MD2_VERSION                     8                                        //!< the md2 version in the header
+#define MD2_MAX_TRIANGLES               4096                                     //!< maximal triangles count
+#define MD2_MAX_VERTICES                3048                                     //!< maximal vertices count
+#define MD2_MAX_TEXCOORDS               3048                                     //!< maximal tex coordinates
+#define MD2_MAX_FRAMES                  512                                      //!< maximal frames
+#define MD2_MAX_SKINS                   32                                       //!< maximal skins
+#define MD2_MAX_FRAMESIZE               (MD2_MAX_VERTICES * 4 + 128)             //!< maximal framesize
+
+#define NUM_VERTEX_NORMALS              162                                      //!< number of vertex normals
+#define SHADEDOT_QUANT                  16                                       //!< shade dot quantity - no idea what it is
+
+//! This stores the speed of the animation between each key frame - currently conflicting with the animation framework
+#define kAnimationSpeed                 12.0f                                    //!< animation speed
+
+//! This holds the header information that is read in at the beginning of the file: id software definition
+struct MD2Header
+{
+  int ident;                           //!< This is used to identify the file
+  int version;                         //!< The version number of the file (Must be 8)
+
+  int skinWidth;                       //!< The skin width in pixels
+  int skinHeight;                      //!< The skin height in pixels
+  int frameSize;                       //!< The size in bytes the frames are
+
+  int numSkins;                        //!< The number of skins associated with the model
+  int numVertices;                     //!< The number of vertices (constant for each frame)
+  int numTexCoords;                    //!< The number of texture coordinates
+  int numTriangles;                    //!< The number of faces (polygons)
+  int numGlCommands;                   //!< The number of gl commands
+  int numFrames;                       //!< The number of animation frames
+
+  int offsetSkins;                     //!< The offset in the file for the skin data
+  int offsetTexCoords;                 //!< The offset in the file for the texture data
+  int offsetTriangles;                 //!< The offset in the file for the face data
+  int offsetFrames;                    //!< The offset in the file for the frames data
+  int offsetGlCommands;                //!< The offset in the file for the gl commands data
+  int offsetEnd;                       //!< The end of the file offset
+};
+
+
+//! animation names enumeration
+typedef enum MD2animType
+{
+  STAND,                       //0
+  RUN,                         //1
+  ATTACK,                      //2
+  PAIN_A,                      //3
+  PAIN_B,                      //4
+  PAIN_C,          //5
+  JUMP,            //6
+  FLIP,            //7
+  SALUTE,          //8
+  FALLBACK,        //9
+  WAVE,            //10
+  MD2_POINT,           //11
+  CROUCH_STAND,
+  CROUCH_WALK,
+  CROUCH_ATTACK,
+  CROUCH_PAIN,
+  CROUCH_DEATH,
+  DEATH_FALLBACK,
+  DEATH_FALLFORWARD,
+  DEATH_FALLBACKSLOW,
+  BOOM,
+  WALK,
+
+  MAX_ANIMATIONS
+};
+
+
+typedef enum animPlayback
+{
+  MD2_ANIM_LOOP = 0,
+  MD2_ANIM_ONCE,
+
+  MD2_ANIM_NUM
+};
+
+
+
+/* forward definitions */
+class Material;
+
+
+
+//! class to store the md2 data in
+class MD2Data : public BaseObject
+{
+public:
+  typedef CountPointer<MD2Data>    Pointer;
+public:
+  MD2Data();
+  MD2Data(const std::string& modelFileName, const std::string& skinFileName, float scale = 1.0f);
+  virtual ~MD2Data();
+
+private:
+  void init();
+  bool loadModel(const std::string& fileName);
+  bool loadSkin(const std::string& fileName = "");
+
+public:
+  int                numFrames;             //!< number of frames
+  int                numVertices;           //!< number of vertices
+  int                numTriangles;          //!< number of triangles
+  int                numTexCoor;            //!< number of texture coordinates
+  int                numGLCommands;         //!< number of gl commands in the glList (tells how to draw)
+  std::string        fileName;              //!< file name of the model File
+  std::string        skinFileName;          //!< file name of the skin file
+  MD2Header*         header;                //!< the header file
+
+  sVec3D*            pVertices;             //!< pointer to the vertices data block
+  sTriangle*         pTriangles;            //!< pointer to the triangles data
+  sTexCoor*          pTexCoor;              //!< pointer to the texture coordinate data
+  int*               pGLCommands;           //!< pointer to the gllist data block
+  int*               pLightNormals;         //!< pointer to the light normals
+
+  Material           material;              //!< pointer to the material
+  float              scaleFactor;           //!< the scale factor of the model, (global)
+};
+
+
+
+
+//! This is a MD2 Model class
+class MD2Model : public InteractiveModel
+{
+  ObjectListDeclaration(MD2Model);
+public:
+  MD2Model();
+  MD2Model(const std::string& modelFileName, const std::string& skinFileName = "", float scale = 1.0f);
+  MD2Model(const MD2Model& model);
+  virtual ~MD2Model();
+
+  MD2Model& operator=(const MD2Model& md2model);
+
+  bool load(const std::string& modelFileName, const std::string& skinFileName = "", float scale = 1.0f);
+
+  virtual void draw() const;
+  void renderFrameTriangles() const;
+
+  virtual void setAnimation(int type, int animPlayback = MD2_ANIM_LOOP);
+  virtual void setAnimation(int firstFrame, int lastFrame, int fps, int bStoppable, int animPlayback);
+  /**  returns the current animation @returns animation type */
+  inline int getAnimation() const { return this->animationState.type; }
+  virtual void setAnimationSpeed(float speed) { this->animationSpeed = speed; }
+virtual bool isAnimationFinished() const { return (this->animationState.currentFrame == this->animationState.endFrame )?true:false; }
+  /**  scales the current model @param scaleFactor: the factor [0..1] to use for scaling */
+  void scaleModel(float scaleFactor) { this->scaleFactor = scaleFactor;}
+
+
+  void acquireData(const MD2Data::Pointer& data) { this->data = data; rebuildInfo(); };
+  const MD2Data::Pointer& dataPointer() const { return this->data; };
+  virtual void tick(float dtS);
+  void debug();
+
+
+private:
+  void init();
+  void rebuildInfo();
+
+  void animate(float time);
+  void processLighting();
+  void interpolate(/*sVec3D* verticesList*/);
+  void renderFrame() const ;
+
+
+public:
+  /* these variables are static, because they are all the same for every model */
+  static sVec3D         anorms[NUM_VERTEX_NORMALS];       //!< the anormals
+  static float          anormsDots[SHADEDOT_QUANT][256];  //!< the anormals dot products
+  static sAnim          animationList[22];                //!< the anomation list
+  //! again one of these strange id software parts
+  float*                shadeDots;
+
+  CountPointer<MD2Data> data;                           //!< the md2 data pointer
+
+private:
+  float                 scaleFactor;                      //!< the scale factor (individual)
+  float                 animationSpeed;                   //!< the speed of the animation (factor for the time)
+  sAnimState            animationState;                   //!< animation state of the model
+  sVec3D                verticesList[MD2_MAX_VERTICES];   //!< place to temp sav the vert
+};
+
+
+
+
+
+#endif /* _MD2MODEL_H */
Index: branches/heathaze/src/lib/graphics/importer/md2/resource_md2.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md2/resource_md2.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md2/resource_md2.cc	(revision 9940)
@@ -0,0 +1,61 @@
+
+#include "resource_md2.h"
+#include "substring.h"
+#include "multi_type.h"
+#include "debug.h"
+
+
+ResourceMD2::ResourceMD2(const std::string& modelName, const std::string& skinName, float scale, const Resources::KeepLevel& keepLevel)
+    : Resource(&ResourceMD2::type)
+{
+  Resources::StorePointer* ptr = this->acquireResource(loadString(modelName, skinName, scale));
+
+  if (ptr)
+  {
+    PRINTF(0)("FOUND MD2: %s\n", modelName.c_str());
+    this->acquireData(static_cast<ResourceMD2::MD2ResourcePointer*>(ptr)->ptr());
+  }
+  else
+  {
+    PRINTF(0)("NOT FOUND MD2: %s\n", modelName.c_str());
+    std::string modelFileName = this->Resource::locateFile(modelName);
+    //std::string skinFileName = this->Resource::locateFile(skinName);
+    this->MD2Model::load(modelFileName, skinName, scale);
+    this->Resource::addResource(new ResourceMD2::MD2ResourcePointer(loadString(modelName, skinName, scale), keepLevel, this->MD2Model::dataPointer()));
+  }
+
+}
+
+ResourceMD2 ResourceMD2::createFromString(const std::string& loadString, const Resources::KeepLevel& keepLevel)
+{
+  SubString loadValues(loadString, ',');
+  std::string modelName;
+  std::string skinName;
+  float scale = 1.0f;
+  if (loadValues.size() > 0)
+    modelName = loadValues[0];
+  if (loadValues.size() > 1)
+    skinName = loadValues[1];
+  if (loadValues.size() > 2)
+    scale = MultiType(loadValues[2]).getFloat();
+
+  return ResourceMD2(modelName, skinName, scale, keepLevel);
+}
+
+std::string ResourceMD2::loadString(const std::string& modelName, const std::string& skinName, float scale)
+{
+  return modelName + ',' + skinName + ',' + MultiType(scale).getString();
+}
+
+
+Resources::tType<ResourceMD2> ResourceMD2::type("MD2");
+
+
+
+
+
+ResourceMD2::MD2ResourcePointer::MD2ResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const MD2Data::Pointer& data)
+    : Resources::StorePointer(loadString, keepLevel) , pointer(data)
+{}
+
+
Index: branches/heathaze/src/lib/graphics/importer/md2/resource_md2.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md2/resource_md2.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md2/resource_md2.h	(revision 9940)
@@ -0,0 +1,40 @@
+/*!
+ * @file resource_md2.h
+ * @brief Contains the ResourceMD2 class, that handles the Resource-specific loading part of the MD2.
+ *
+ */
+
+#ifndef _RESOURCE_MD2_H
+#define _RESOURCE_MD2_H
+
+#include "util/loading/resource.h"
+#include "md2Model.h"
+
+
+class ResourceMD2 : public MD2Model, public Resources::Resource
+{
+public:
+  ResourceMD2(const std::string& modelName,
+	      const std::string& skinName = "",
+	      float scale = 1.0f,
+	      const Resources::KeepLevel& keepLevel = Resources::KeepLevel());
+  static ResourceMD2 createFromString(const std::string& loadString, const Resources::KeepLevel& keepLevel = Resources::KeepLevel());
+  static std::string loadString(const std::string& modelName, const std::string& skinName = "", float scale = 1.0f);
+
+private:
+class MD2ResourcePointer : public Resources::StorePointer
+  {
+  public:
+    MD2ResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const MD2Data::Pointer& data);
+    inline const MD2Data::Pointer& ptr() const { return pointer; }
+    virtual bool last() const { return pointer.count() == 1; }
+  private:
+    MD2Data::Pointer pointer;
+  };
+
+private:
+  static Resources::tType<ResourceMD2> type;
+};
+
+
+#endif /* _RESOURCE_MD2_H */
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_animation.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_animation.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_animation.cc	(revision 9940)
@@ -0,0 +1,80 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "md3_animation.h"
+
+
+
+namespace md3
+{
+
+
+
+  MD3AnimationMap MD3Animation::animationList[25] = {
+    { "Death 1",                 BOTH  },
+    { "Dead 1",                  BOTH  },
+    { "Death 2",                 BOTH  },
+    { "Dead 2",                  BOTH  },
+    { "Death 3",                 BOTH  },
+    { "Dead 3",                  BOTH  },
+    { "Gesture",                 BOTH  },
+    { "Shoot",                   TORSO },
+    { "Hit",                     TORSO },
+    { "Drop Weapon",             TORSO },
+    { "Raise Weapon",            TORSO },
+    { "Stand With Weapon",       TORSO },
+    { "Stand with Gauntlet",     TORSO },
+    { "Crouched Walk",           LEGS  },
+    { "Walk",                    LEGS  },
+    { "Run",                     LEGS  },
+    { "Backpedal",               LEGS  },
+    { "Swim",                    LEGS  },
+    { "Jump Forward",            LEGS  },
+    { "Land Forward",            LEGS  },
+    { "Jump Backward",           LEGS  },
+    { "Land Backward",           LEGS  },
+    { "Stand Idle",              LEGS  },
+    { "Crouched Idle",           LEGS  },
+    { "Turn In Place",           LEGS  }
+  };
+
+
+  /**
+   * create an empty MD3Animation object
+   */
+  MD3Animation::MD3Animation()
+  {
+    this->init();
+  }
+
+
+  /**
+   * deconstructor
+   */
+  MD3Animation::~MD3Animation()
+  {}
+
+
+  void MD3Animation::init()
+  {
+    this->first = 0;
+    this->numFrames = 0;
+    this->fps = 0;
+  }
+
+
+}
+
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_animation.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_animation.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_animation.h	(revision 9940)
@@ -0,0 +1,63 @@
+/*!
+ * @file md3_animation.h
+ *
+ * Code heavely inspired by: JAVA MD3 Model Viewer - A Java based Quake 3 model viewer
+ * Copyright (C) 1999 Erwin 'KLR8' Vervaet
+ */
+
+#ifndef _MD3_ANIMATION_H
+#define _MD3_ANIMATION_H
+
+#include <string>
+
+namespace md3
+{
+
+typedef enum MD3AnimationType {
+  LEGS      = 0,             //!< animation only applicatble to the legs. top level model loaded from lower.md3
+  TORSO,                     //!< animation only applicatboe to the torso. normaly loaded from upper.md3
+  BOTH,                      //!< animation is applicable on both
+  ALL,                       //!< animation is applicable to all submodels
+
+  NUM_ANIMATION_TYPE         //!< number of animations
+};
+
+
+typedef struct MD3AnimationMap {
+  std::string        animationName;
+  MD3AnimationType   animationType;
+};
+
+
+
+
+/**
+ * a class with metadata describing an MD3 model animation
+ */
+class MD3Animation
+{
+
+  public:
+    MD3Animation();
+    virtual ~MD3Animation();
+
+    void init();
+
+    std::string toString() { return std::string("Name: " + this->name); }
+
+
+  public:
+    MD3AnimationType      type;                      //!< specifies for what parts of a model this animation is appilcable (e.g. LEGS)
+    std::string           name;                      //!< name of the animation
+
+    int                   offset;                    //!< for LEGS animation, this is the offset value to skip TORSO frames
+    int                   first;                     //!< first frame
+    int                   numFrames;                 //!< the number of frames in the anumation. < 0 means that all available frames used
+    int                   numLoopFrames;             //!< number of looping frames
+    int                   fps;                       //!< frames per second
+
+    static MD3AnimationMap animationList[25];         //!< the animation list
+};
+
+}
+#endif /* _MD3_ANIMATION_H */
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_animation_cfg.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_animation_cfg.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_animation_cfg.cc	(revision 9940)
@@ -0,0 +1,226 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "md3_animation_cfg.h"
+
+#include "md3_animation.h"
+
+#include "substring.h"
+#include "helper_functions.h"
+
+#include "debug.h"
+
+
+
+
+
+namespace md3
+{
+
+  /**
+   * create an empty MD3AnimationCfg object
+   */
+  MD3AnimationCfg::MD3AnimationCfg()
+  {
+  }
+
+
+  /**
+   * create a new MD3 Anumation object and initialize it with the data on the given line
+   * @param line: the line to read from
+   */
+  MD3AnimationCfg::MD3AnimationCfg(std::string filename)
+  {
+
+
+    this->loadConfig(filename);
+  }
+
+
+  /**
+   * deconstructor
+   */
+  MD3AnimationCfg::~MD3AnimationCfg()
+  {}
+
+
+  /**
+   * loads the configuration file
+   */
+  void MD3AnimationCfg::loadConfig(std::string filename)
+  {
+//     BufferedReader bin=new BufferedReader(new InputStreamReader(in));
+
+    int      i = 0;                //!< last read animation, animation order is hard coded!
+    int      torsoOffset = -1;     //!< torso offset
+    int      firstTorsoFrame = -1; //!< first of the TORSO animation frames
+    bool     inHeader = true;      //!< are we still in the header of the .cfg file?
+
+
+    FILE* pFile;
+    char* cLine;
+    size_t len = 0;
+    ssize_t read = 0;
+
+    PRINTF(0)("opening file: %s\n", filename.c_str());
+    pFile = fopen(filename.c_str(), "r");
+    if( !pFile) {
+      PRINTF(1)("Error: file could not be opened: %s\n", filename.c_str());
+      return;
+    }
+
+
+    // parse file
+    /// @FIXME FIXME bensch took this out, cause: not portable
+      //    while( (read = getline(&cLine, &len, pFile)) != -1) { /*( !this->dataStream.eof()) {*/
+      /*
+      std::string line(cLine);
+
+//       PRINTF(0)("size = %i, line = |%s|\n", read, line.c_str());
+
+      //ignore empty lines and comments
+      if( line.length() > 2 && line.find("//") != 0) {
+
+        // find the gender section
+        if( inHeader && line.find("sex") == 0) {
+          //parse line: sex [m | f | ...]
+          SubString tokens(line, " \t\n\r\f/");
+
+          std::string sexStr = tokens.back();
+          // probably error in the file format
+          if( sexStr.length() != 1) {
+            this->sex = '?';
+            PRINTF(2)("no section \"sex\" in the config file %s found\n", filename.c_str());
+          }
+          else {
+            this->sex = sexStr[0];
+          }
+
+          PRINTF(0)("sex of the md3 model: %c\n", this->sex);
+        }
+        else if( inHeader && line.find("headoffset") == 0) {
+          // parse line: headoffset X Y Z
+          SubString tokens(line, " \t\n\r\f/");
+
+          float z = atof(tokens.back().c_str()); tokens.pop_back();
+          float y = atof(tokens.back().c_str()); tokens.pop_back();
+          float x = atof(tokens.back().c_str()); tokens.pop_back();
+
+          this->headOffset = Vector(x, y, z);
+
+          PRINTF(0)("got head offset: %f, %f, %f\n", x, y, z);
+        }
+        else if( inHeader && line.find("footsteps") == 0) {
+          //parse line: footsteps [normal | mech | ...]
+          SubString tokens (line, " \t\n\r\f/");
+
+          this->footsteps = tokens.back();
+
+          //check if value is ok
+          if (!(nocaseCmp(this->footsteps, "default")   ||
+                nocaseCmp(this->footsteps, "normal")    ||
+                nocaseCmp(this->footsteps, "boot")      ||
+                nocaseCmp(this->footsteps, "flesh")     ||
+                nocaseCmp(this->footsteps, "mech")      ||
+                nocaseCmp(this->footsteps, "energy")) ) {
+            this->footsteps="illegal footsteps value (" + this->footsteps + ")";
+          }
+          PRINTF(0)("got footsteps: %s\n", this->footsteps.c_str());
+        }
+        else
+        {
+          // assume it's an animation line
+          inHeader = false;
+
+          MD3Animation* animation = new MD3Animation();
+          this->loadAnimation(animation, line);
+
+          if( i < 25)
+          {
+            animation->name = MD3Animation::animationList[i].animationName;
+            animation->type = MD3Animation::animationList[i++].animationType;
+          }
+
+          // workaround for strange numbering in animation.cfg: skip TORSO frames
+          // for LEGS animation lines...
+          if( animation->type == LEGS)
+          {
+            //when first LEGS animation is found, calc # of TORSO frames
+            if( torsoOffset == -1)
+              torsoOffset = animation->first - firstTorsoFrame;
+
+            animation->first -= torsoOffset;
+            animation->offset = torsoOffset;
+          }
+          else if( animation->type == TORSO)
+            if( firstTorsoFrame == -1)
+              firstTorsoFrame = animation->first;
+
+          this->putAnimation(animation);
+        }
+	}
+    }
+      */
+  }
+
+
+  /**
+   * loading the animation data itself
+   */
+  void MD3AnimationCfg::loadAnimation(MD3Animation* anim, std::string line)
+  {
+    // parse the line:
+    // first frame, num frames, looping frames, frames per second (fps)
+    SubString tokens(line, " \t\n\r\f/");
+
+    anim->fps = atoi(tokens.back().c_str()); tokens.pop_back();
+    anim->numLoopFrames = atoi(tokens.back().c_str()); tokens.pop_back();
+    anim->numFrames = atoi(tokens.back().c_str()); tokens.pop_back();
+    anim->first = atoi(tokens.back().c_str()); tokens.pop_back();
+
+    //some adjustements:
+    if( anim->fps == 0)
+      anim->fps = 33;
+
+    PRINTF(0)("Animation: first frame: %i, num frames: %i, num loops: %i, fps: %i\n", anim->first, anim->numFrames, anim->numLoopFrames, anim->fps);
+  }
+
+
+  /**
+  * Look up the animation data for the animation with the specified name.
+  *
+  * @param name Name of the animation.
+  * @return The animation data associated with the name or null if no data was found.
+  */
+  MD3Animation* MD3AnimationCfg::getAnimation(std::string name)
+  {
+    return this->animations[name];
+  }
+
+
+  /**
+   * Add the specified animation to the list of known animations.
+   */
+   void MD3AnimationCfg::putAnimation(MD3Animation* anim)
+   {
+      this->animations[anim->name] = anim;
+   }
+
+
+}
+
+
+
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_animation_cfg.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_animation_cfg.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_animation_cfg.h	(revision 9940)
@@ -0,0 +1,61 @@
+/*!
+ * @file md3_animation.h
+ *
+ * Code heavely inspired by: JAVA MD3 Model Viewer - A Java based Quake 3 model viewer
+ * Copyright (C) 1999 Erwin 'KLR8' Vervaet
+ */
+
+#ifndef _MD3_ANIMATION_CFG_H
+#define _MD3_ANIMATION_CFG_H
+
+#include "vector.h"
+
+#include "base_object.h"
+
+#include <string>
+#include <map>
+
+#include <iostream>
+#include <fstream>
+
+
+
+namespace md3
+{
+  class MD3Animation;
+
+
+  /**
+   * a class with metadata describing an MD3 model animation
+   */
+  class MD3AnimationCfg : public BaseObject
+  {
+
+    public:
+      MD3AnimationCfg();
+      MD3AnimationCfg(std::string filename);
+      virtual ~MD3AnimationCfg();
+
+      void loadConfig(std::string filename);
+
+      MD3Animation* getAnimation(std::string name);
+      void putAnimation(MD3Animation* animation);
+
+    private:
+      void loadAnimation(MD3Animation* anim, std::string line);
+
+
+    public:
+      std::string             filename;            //!< filename of the config file
+
+      char                    sex;                 //!< sex of animated model: 'm' for male, 'f' for female
+      Vector                  headOffset;          //!< head offset. this is the offset of the head model in the HUD x,y,z
+      std::string             footsteps;           //!< type of the footstep sounds associated with anumations (e.g. "mech", "default")
+
+      std::ifstream           dataStream;          //!< the data stream
+
+      std::map<std::string, MD3Animation*>     animations;          //!< mapping of animation names to MD3Animation objects.
+  };
+}
+
+#endif /* _MD3_ANIMATION_CFG_H */
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_bone_frame.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_bone_frame.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_bone_frame.cc	(revision 9940)
@@ -0,0 +1,41 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "md3_bone_frame.h"
+
+
+
+namespace md3
+{
+
+
+  /**
+   * create a MD3BoneFrame object with the data coming from the specified input stream
+   */
+  MD3BoneFrame::MD3BoneFrame(int tagNum /*, DataInput din*/)
+  { /* loadBoneFrame(this, din) */ }
+
+
+  MD3BoneFrame::MD3BoneFrame(/*int tagNum*/)
+  { /* this->tags = new MD3Tag[tagNum] */ }
+
+
+  MD3BoneFrame::~MD3BoneFrame()
+  {}
+
+
+
+};
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_bone_frame.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_bone_frame.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_bone_frame.h	(revision 9940)
@@ -0,0 +1,53 @@
+/*!
+ * @file md3_bone_frame.h
+ *
+ * Code heavely inspired by: JAVA MD3 Model Viewer - A Java based Quake 3 model viewer
+ * Copyright (C) 1999 Erwin 'KLR8' Vervaet
+ */
+
+#ifndef _MD3_BONE_FRAME_ANIMATION_H
+#define _MD3_BONE_FRAME_ANIMATION_H
+
+#include "vector.h"
+
+#include <string>
+
+namespace md3
+{
+
+typedef struct MD3BoneFrameData {
+  sVec3D  mins;
+  sVec3D  maxs;
+  sVec3D  position;
+  float   scale;
+  char    creator[16];
+};
+
+
+class MD3Tag;
+
+class MD3BoneFrame
+{
+  public:
+    /** create a MD3BoneFrame object with the data coming from the specified input stream */
+    MD3BoneFrame(int tagNum /*, DataInput din*/);
+    MD3BoneFrame(/*int tagNum*/);
+    virtual ~MD3BoneFrame();
+
+
+  public:
+    Vector              mins;              //!< lower extrema of the bounding box of this bone anumation frame
+    Vector              maxs;              //!< upper extrema of the bounding box of this bone anumation frame
+    Vector              position;          //!< coordinate origin within the bounding box
+
+    std::string         cratorName;        //!< the name of the creator
+    float               scale;             //!< scale of the box
+
+    MD3Tag**            tags;              //!< arrays of tags size
+
+    MD3BoneFrameData*   data;              //!< reference md3 bone frames data
+};
+
+}
+
+#endif /* _MD3_BONE_FRAME_ANIMATION_H */
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_data.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_data.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_data.cc	(revision 9940)
@@ -0,0 +1,501 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "md3_data.h"
+
+#include "md3_bone_frame.h"
+#include "md3_tag.h"
+#include "md3_mesh.h"
+
+#include "material.h"
+
+#include "debug.h"
+
+namespace md3
+{
+
+/********************************************************************************
+ *   MD3Data                                                                    *
+ ********************************************************************************/
+
+/**
+  \brief simple constructor
+*/
+MD3Data::MD3Data(const std::string& modelFileName, const std::string& skinFileName, float scale)
+{
+  this->filename = modelFileName;
+
+  this->parentTagIndex = -1;
+  this->parent = NULL;
+
+  this->animationState.currentFrame = 0;
+  this->animationState.nextFrame = 1;
+  this->animationState.interpolationFraction = 0.0f;
+
+  this->animation = NULL;
+  this->bInterpolate = false;
+  this->upperBound = 0;
+
+  this->loadModel(modelFileName);
+//   this->loadSkin(skinFileName);
+  this->init();
+}
+
+
+/**
+  \brief simple destructor
+
+  this will clean out all the necessary data for a specific md2model
+*/
+MD3Data::~MD3Data()
+{
+  delete this->header;
+}
+
+
+/**
+ * init data
+ */
+void MD3Data::init()
+{
+  // create the temporary data to work with (interpolation data)
+  this->tmpBoneFrame = new MD3BoneFrame();
+
+  this->tmpMesh = new sVec3D*[this->header->meshNum];
+  for( int i = 0; i < this->header->meshNum; i++)
+    this->tmpMesh[i] = new sVec3D[this->meshes[i]->header->vertexNum];
+
+  this->tmpNormal = new MD3Normal*[this->header->meshNum];
+  for( int i = 0; i < this->header->meshNum; i++)
+    this->tmpNormal[i] = new MD3Normal[this->meshes[i]->header->vertexNum];
+
+  // there are at most 4 different models and submodels
+  this->tmpMatrix = new float*[4];
+  for( int i = 0; i < 4; i++)
+    this->tmpMatrix[i] = new float[16];
+
+}
+
+
+/**
+ * link a model at the specified tag position to this model. if the position is already
+ * occupied, the old submodel will be replaced
+ *
+ *  @param tagIndex: tag to link the submodel to
+ *  @param child: the submodel that should be linked to this model
+ */
+void MD3Data::addLinkedModel(int tagIndex, MD3Data* child)
+{
+  this->sortedMap[tagIndex] = child;
+  child->parentTagIndex = tagIndex;
+}
+
+
+
+/**
+ * Return the index of the tag with the given name for this model.
+ *
+ * This will return -1 if their is no such tag.
+ */
+ int MD3Data::getTagIndexByName(std::string tagName)
+{
+   int res = -1;
+
+   if( this->header->boneFrameNum > 0) {
+     MD3Tag** tags = this->boneFrames[0]->tags;
+     for( int i = 0; i < this->header->tagNum; i++)
+       if( tags[i]->name.find(tagName) == std::string::npos)
+         return i;
+   }
+
+   return res;
+ }
+
+
+
+/**
+  \brief this will load the whole model data (vertices, opengl command list, ...)
+* @param fileName: the name of the model file
+  \return true if success
+*/
+bool MD3Data::loadModel(const std::string& fileName)
+{
+  FILE *pFile;                            //file stream
+//  char* buffer;                           //buffer for frame data
+  int fileOffset = 0;                     // file data offset
+
+
+  //! @todo this chek should include deleting a loaded model (eventually)
+  if (fileName.empty())
+    return false;
+
+  PRINTF(0)("opening file: %s\n", fileName.c_str());
+  pFile = fopen(fileName.c_str(), "rb");
+  if( unlikely(!pFile))
+    {
+      PRINTF(1)("Couldn't open the MD3 File for loading. Exiting.\n");
+      return false;
+    }
+  fileOffset += this->readHeader(pFile, fileOffset);
+  /* check for the header version: make sure its a md2 file :) */
+  if( unlikely(this->header->version != MD3_VERSION) && unlikely(this->header->ident != MD3_IDENT))
+    {
+      PRINTF(1)("Couldn't load file %s: invalid file format: stop loading\n", fileName.c_str());
+      return false;
+    }
+
+
+    // check if the filesize is correct
+    if( this->header->fileSize > this->header->tagStart &&
+        this->header->fileSize >= this->header->meshStart)
+    {
+      bool bBoneFrames, bTags, bMeshes;
+      bBoneFrames = ( this->header->boneFrameNum == 0);
+      bTags = ( this->header->tagNum == 0);
+      bMeshes = ( this->header->meshNum == 0);
+
+      // read different parts of the model in correct order
+      while( !(bBoneFrames && bTags && bMeshes))
+      {
+        printf("while, fileOffset = %i\n", fileOffset);
+        if( fileOffset == this->header->boneFrameStart && !bBoneFrames)
+        {
+          fileOffset += this->readBoneFrames(pFile, fileOffset);
+          bBoneFrames = true;
+        }
+        else if( fileOffset == this->header->tagStart && !bTags)
+        {
+          fileOffset += this->readTags(pFile, fileOffset);
+          bTags = true;
+        }
+        else if( fileOffset == this->header->meshStart && !bMeshes)
+        {
+          fileOffset += this->readMeshes(pFile, fileOffset);
+          bMeshes = true;
+        }
+      }
+
+    }
+
+  fclose(pFile);
+
+  return true;
+}
+
+
+/**
+  \brief loads the skin/material stuff
+* @param fileName: name of the skin file
+  \return true if success
+*/
+bool MD3Data::loadSkin(const std::string& fileName)
+{
+//   if( fileName.empty())
+//     {
+//       this->skinFileName = "";
+//       return false;
+//     }
+//
+//   this->skinFileName = fileName;
+//
+//   this->material.setName("md2ModelMaterial");
+//   this->material.setDiffuseMap(fileName);
+//   this->material.setIllum(3);
+//   this->material.setAmbient(1.0, 1.0, 1.0);
+
+  return true;
+}
+
+
+/**
+ * read heaader
+ */
+int MD3Data::readHeader(FILE* pFile, int fileOffset)
+{
+  PRINTF(0)("Reading Header\n");
+
+  this->header = new MD3Header;
+  fread(this->header, 1, sizeof(MD3Header), pFile);
+
+    //header debug:
+  PRINTF(0)("MD3 Header debug section======================================\n");
+  printf("ident: %i\n", this->header->ident);
+  printf("version: %i\n", this->header->version);
+  printf("filename: %s\n", this->header->filename);
+  printf("boneFrameNum: %i\n", this->header->boneFrameNum);
+  printf("tag number: %i\n", this->header->tagNum);
+  printf("mesh number: %i\n", this->header->meshNum);
+  printf("max tex num: %i\n", this->header->maxTexNum);
+  printf("bone frame start: %i\n", this->header->boneFrameStart);
+  printf("tag start: %i\n", this->header->tagStart);
+  printf("mesh start: %i\n", this->header->meshStart);
+  printf("fileSize: %i\n", this->header->fileSize);
+
+  return sizeof(MD3Header);
+}
+
+
+/**
+ * read bone frames
+ */
+int MD3Data::readBoneFrames(FILE* pFile, int fileOffset)
+{
+  PRINTF(0)("Reading Bone Frames\n");
+
+  this->boneFrames = new MD3BoneFrame*[this->header->boneFrameNum];
+
+  for( int i = 0; i < this->header->boneFrameNum; i++)
+  {
+    this->boneFrames[i] = new MD3BoneFrame(i);
+
+    MD3BoneFrameData* md = new MD3BoneFrameData;
+    fread(md, 1, sizeof(MD3BoneFrameData), pFile);
+    this->boneFrames[i]->data = md;
+  }
+
+  return this->header->boneFrameNum * sizeof(MD3BoneFrameData);
+}
+
+
+/**
+ * read the tags
+ */
+int MD3Data::readTags(FILE* pFile, int fileOffset)
+{
+  PRINTF(0)("Reading Tags\n");
+
+  for( int i = 0; i < this->header->boneFrameNum; i++)
+  {
+    this->boneFrames[i]->tags = new MD3Tag*[this->header->tagNum];
+
+    for( int j = 0; j < this->header->tagNum; j++)
+    {
+      this->boneFrames[i]->tags[j] = new MD3Tag();
+      MD3TagData* md = new MD3TagData;
+      fread(md, 1, sizeof(MD3TagData), pFile);
+      this->boneFrames[i]->tags[j]->data = md;
+
+      this->boneFrames[i]->tags[j]->name = std::string(this->boneFrames[i]->tags[j]->data->name);
+      this->boneFrames[i]->tags[j]->position = Vector( this->boneFrames[i]->tags[j]->data->position[0],
+                                                       this->boneFrames[i]->tags[j]->data->position[1],
+                                                       this->boneFrames[i]->tags[j]->data->position[2]);
+      for( int k = 0; k < 3; k++)
+        for( int l = 0; l < 3; l++)
+          this->boneFrames[i]->tags[j]->matrix[k][l] = this->boneFrames[i]->tags[j]->data->matrix[k][l];
+
+      //PRINTF(0)("Tag name: %s\n", this->boneFrames[i]->tags[j]->name.c_str());
+    }
+  }
+
+  return this->header->boneFrameNum * this->header->tagNum * sizeof(MD3TagData);
+}
+
+
+/**
+ * read meshes
+ */
+int MD3Data::readMeshes(FILE* pFile, int fileOffset)
+{
+  PRINTF(0)("Reading Mesh Data\n");
+
+  fileOffset = 0;
+
+  this->meshes = new MD3Mesh*[this->header->meshNum];
+
+  for( int i = 0; i < this->header->meshNum; i++)
+  {
+    this->meshes[i] = new MD3Mesh();
+
+    int localFileOffset = 0;
+    bool   bTriangles, bTexVecs, bVertices, bTextures;            //!< the parts that have been read so far
+
+    //start reading mesh data
+    MD3MeshHeader* md = new MD3MeshHeader;
+    fread(md, 1, sizeof(MD3MeshHeader), pFile);
+    this->meshes[i]->header = md;
+    localFileOffset += sizeof(MD3MeshHeader);
+
+    PRINTF(0)("MD3 Mesh Header debug section\n");
+    printf("ident: %i\n", md->id);
+    printf("filename: %s\n", md->name);
+    printf("meshFrameNum: %i\n", md->meshFrameNum);
+    printf("textureNum: %i\n", md->textureNum);
+    printf("vertexNum: %i \n", md->vertexNum);
+    printf("triangleNum: %i\n", md->triangleNum);
+    printf("triangleStart: %i\n", md->triangleStart);
+    printf("textureStart: %i\n", md->textureStart);
+    printf("texVecStart: %i\n", md->texVecStart);
+    printf("vertexStart: %i\n", md->vertexStart);
+    printf("fileSize: %i\n", md->meshSize);
+
+    if( unlikely(this->meshes[i]->header->id != MD3_IDENT))
+    {
+      PRINTF(1)("Wrong MD3 mesh file tag, file %s could be corrupt\n", this->filename.c_str());
+      return false;
+    }
+
+    // check which parts to be loaded
+    bTriangles = ( this->meshes[i]->header->triangleNum == 0);
+    bTexVecs = ( this->meshes[i]->header->vertexNum == 0);
+    bVertices = ( this->meshes[i]->header->meshFrameNum == 0);
+    bTextures = ( this->meshes[i]->header->textureNum == 0);
+
+    // now read the data block whise
+    while( !(bTriangles && bTexVecs && bVertices && bTextures))
+    {
+      PRINTF(0)("while2: localOffset = %i\n", localFileOffset);
+      if( localFileOffset == this->meshes[i]->header->triangleStart  && !bTriangles)
+      {
+        localFileOffset += this->readMeshTriangles(pFile, localFileOffset, i);
+        bTriangles = true;
+      }
+      else if( localFileOffset == this->meshes[i]->header->textureStart && !bTextures)
+      {
+        localFileOffset += this->readMeshTextures(pFile, localFileOffset, i);
+        bTextures = true;
+      }
+      else if( localFileOffset == this->meshes[i]->header->texVecStart && !bTexVecs)
+      {
+        localFileOffset += this->readMeshTexVecs(pFile, localFileOffset, i);
+        bTexVecs = true;
+      }
+      else if( localFileOffset == this->meshes[i]->header->vertexStart && !bVertices)
+      {
+        localFileOffset += this->readMeshVertices(pFile, localFileOffset, i);
+        bVertices = true;
+      }
+    }
+    fileOffset += localFileOffset;
+    PRINTF(0)("finished reading mesh %i, got %i of %i byes\n", i, localFileOffset, md->meshSize);
+  }
+  return fileOffset;
+}
+
+
+
+/**
+ * reading in the mesh triangles
+ */
+int MD3Data::readMeshTriangles(FILE* pFile, int fileOffset, int mesh)
+{
+  PRINTF(0)("Reading Mesh Triangles\n");
+  // create the memomry to save the triangles
+  this->meshes[mesh]->triangles = new MD3Triangle[this->meshes[mesh]->header->triangleNum];
+  fread(this->meshes[mesh]->triangles, 1, sizeof(MD3Triangle) * this->meshes[mesh]->header->triangleNum, pFile);
+
+//   for( int i = 0; i < this->meshes[mesh]->header->triangleNum; i++) {
+//     PRINTF(0)("Triangle read: %i, %i, %i\n", this->meshes[mesh]->triangles[i].vertexOffset[0], this->meshes[mesh]->triangles[i].vertexOffset[1]
+//         , this->meshes[mesh]->triangles[i].vertexOffset[2]);
+//   }
+
+  return this->meshes[mesh]->header->triangleNum * sizeof(MD3Triangle);
+}
+
+
+/**
+ * reading in the mesh textures
+ */
+int MD3Data::readMeshTextures(FILE* pFile, int fileOffset, int mesh)
+{
+  PRINTF(0)("Reading Mesh Textures\n");
+
+  // create the textures
+  this->meshes[mesh]->material = new Material[this->meshes[mesh]->header->textureNum];
+
+  MD3Texture* tex = new MD3Texture[this->meshes[mesh]->header->textureNum];
+  fread(tex, 1, sizeof(MD3Texture) * this->meshes[mesh]->header->textureNum, pFile);
+
+  for( int i = 0; i < this->meshes[mesh]->header->textureNum; i++) {
+    PRINTF(0)(" texture file: %s\n", tex[i].fileName);
+#warning texture stuff hard coded. make this again
+    std::string path("/home/boenzlip/tmp/q3/Downloads/MOH/q3mdl-alien3/");
+    std::string path1(tex[i].fileName);
+    std::string fullPath( path + path1);
+    this->meshes[mesh]->material[i].setDiffuseMap(/*tex[i].fileName*/ /*fullPath.c_str()*/ "maps/creatures/gork/gorkup.tga");
+    this->meshes[mesh]->material[i].setAmbient(1, 1, 1);
+  }
+
+  return this->meshes[mesh]->header->textureNum * sizeof(MD3Texture);
+}
+
+
+/**
+ * reading in the mesh tex vecs
+ */
+int MD3Data::readMeshTexVecs(FILE* pFile, int fileOffset, int mesh)
+{
+  PRINTF(0)("Reading Mesh TexVecs\n");
+
+  this->meshes[mesh]->texVecs = new MD3TexVecs[this->meshes[mesh]->header->vertexNum];
+  fread(this->meshes[mesh]->texVecs, 1, sizeof(MD3TexVecs) * this->meshes[mesh]->header->vertexNum, pFile);
+
+//   for( int i = 0; i < this->meshes[mesh]->header->vertexNum; i++)  {
+//     PRINTF(0)("TexVec read: %f, %f\n", this->meshes[mesh]->texVecs[i].textureCoord[0], this->meshes[mesh]->texVecs[i].textureCoord[0]);
+//   }
+
+  return this->meshes[mesh]->header->vertexNum * sizeof(MD3TexVecs);
+}
+
+
+/**
+ * reading in the mesh vertices
+ */
+int MD3Data::readMeshVertices(FILE* pFile, int fileOffset, int mesh)
+{
+  PRINTF(0)("Reading Mesh Vertices\n");
+
+  // reserver memory for the vertex informations
+  this->meshes[mesh]->meshFrames = new sVec3D*[this->meshes[mesh]->header->meshFrameNum]; // * this->meshes[mesh]->header->vertexNum
+  this->meshes[mesh]->normals = new MD3Normal*[this->meshes[mesh]->header->meshFrameNum];
+
+  for( int i = 0; i < this->meshes[mesh]->header->meshFrameNum; i++)
+  {
+    this->meshes[mesh]->meshFrames[i] = new sVec3D[this->meshes[mesh]->header->vertexNum];
+    this->meshes[mesh]->normals[i] = new MD3Normal[this->meshes[mesh]->header->vertexNum];
+
+    for( int j = 0; j < this->meshes[mesh]->header->vertexNum; j++)
+    {
+      // read out the compressed data
+      MD3VertexCompressed* vc = new MD3VertexCompressed;
+      fread(vc, 1, sizeof(MD3VertexCompressed), pFile);
+
+      this->meshes[mesh]->meshFrames[i][j][0] = (float)vc->vector[0] / 64.0f;
+      this->meshes[mesh]->meshFrames[i][j][1] = (float)vc->vector[1] / 64.0f;
+      this->meshes[mesh]->meshFrames[i][j][2] = (float)vc->vector[2] / 64.0f;
+
+      this->meshes[mesh]->normals[i][j].vertexNormal[0] = (int)vc->vertexNormal[0];
+      this->meshes[mesh]->normals[i][j].vertexNormal[1] = (int)vc->vertexNormal[1];
+
+//     PRINTF(0)("nr: %i, meshframes: %f, %f, %f, normal: %f, %f\n", i, this->meshes[mesh]->meshFrames[i][0], this->meshes[mesh]->meshFrames[i][1],
+//     this->meshes[mesh]->meshFrames[i][2], this->meshes[mesh]->normals[i].vertexNormal[0], this->meshes[mesh]->normals[i].vertexNormal[1]);
+
+      delete vc;
+    }
+  }
+
+  return this->meshes[mesh]->header->meshFrameNum * this->meshes[mesh]->header->vertexNum * sizeof(MD3VertexCompressed);
+}
+
+
+
+}
+
+
+
+
+
+
+
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_data.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_data.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_data.h	(revision 9940)
@@ -0,0 +1,134 @@
+/*!
+ * @file md2Model.h
+  *  Definition of an MD2 Model, a model format invented by ID Software.
+
+    We are deeply thankfull for all the wunderfull things id software made for us gamers!
+
+    The md2 file format is structured in a very simple way: it contains animations which are made out of
+    frames (so called keyframes). Each frame is a complete draweable model in a specific position.
+    A frame is a collection of vertex and its compagnions (normals, texture coordinates).
+
+    A typical model has about 200 frames, the maximum frame count is fixed by MD2_MAX_FRAMES to currently
+    512 frames. The maximal vetices count is set to 2048 verteces, not enough?
+    You just have to change the MD2_MAX_* values if it doesn't fit your purposes...
+
+    Surface Culling is fully implemented in md2 models: quake2 uses front face culling.
+*/
+
+#ifndef _MD3_DATA_H
+#define _MD3_DATA_H
+
+#include "base_object.h"
+
+#include "model.h"
+#include "material.h"
+#include "md_model_structure.h"
+
+#include <map>
+
+
+//! These are the needed defines for the max values when loading .MD2 files
+#define MD3_IDENT                       (('3'<<24) + ('P'<<16) + ('D'<<8) + 'I') //!< the md3 identifier tag in the bin file
+#define MD3_VERSION                     15                                       //!< the md2 version in the header
+
+
+
+namespace md3
+{
+
+  class MD3BoneFrame;
+  class MD3Mesh;
+  class MD3Normal;
+  class MD3Animation;
+
+  //! This holds the header information that is read in at the beginning of the file: id software definition
+  typedef struct MD3Header
+  {
+    int ident;                           //!< This is used to identify the file
+    int version;                         //!< The version number of the file (Must be 8)
+
+    char filename[68];                   //!< The filename of the model
+
+    int boneFrameNum;                    //!< number of frames
+    int tagNum;                          //!< number of tags
+    int meshNum;                         //!< number of mesh
+    int maxTexNum;                       //!< number of texture
+
+    int boneFrameStart;                  //!< start of bone frames
+    int tagStart;                        //!< start of the tag
+    int meshStart;                       //!< mesh start
+
+    int fileSize;                        //!< file size
+  };
+
+  //!< holding the informations about the current animation state
+  typedef struct MD3AnimationState
+  {
+    int     currentFrame;          //!< currently rendered animation key frame of this model. Every part has its own current frame!
+    int     nextFrame;             //!< next animation key frame of the model.
+    float   interpolationFraction; //!< interpolation position between currentFrame and nextFrame [0,1]
+  };
+
+
+  //! class to store the md2 data in
+  class MD3Data : public BaseObject
+  {
+    public:
+      MD3Data(const std::string& modelFileName, const std::string& skinFileName, float scale = 1.0f);
+      virtual ~MD3Data();
+
+      void addLinkedModel(int tagIndex, MD3Data* child);
+      int getTagIndexByName(std::string name);
+
+    private:
+      bool loadModel(const std::string& fileName);
+      bool loadSkin(const std::string& fileName = "");
+
+      void init();
+
+      int readHeader(FILE* pFile, int fileOffset);
+      int readBoneFrames(FILE* pFile, int fileOffset);
+      int readTags(FILE* pFile, int fileOffset);
+      int readMeshes(FILE* pFile, int fileOffset);
+
+
+      int readMeshTriangles(FILE* pFile, int fileOffset, int mesh);
+      int readMeshTextures(FILE* pFile, int fileOffset, int mesh);
+      int readMeshTexVecs(FILE* pFile, int fileOffset, int mesh);
+      int readMeshVertices(FILE* pFile, int fileOffset, int mesh);
+
+
+    public:
+
+      MD3Header*                header;            //!< the header file
+
+      std::map<int, MD3Data*>   sortedMap;         //!< map
+      int                       parentTagIndex;    //!< the tag index of the parent model
+      MD3Data*                  parent;            //!< the parent model
+
+      std::string               filename;          //!< the name of the file as recorded in the .md3 file
+
+      MD3AnimationState         animationState;    //!< the animation state of this model
+
+      MD3BoneFrame**            boneFrames;        //!< array of bone frames, contains the metadata (bounding box, tags,...) for each frame
+      MD3Mesh**                 meshes;            //!< array of meshes in the model. each containing the mesh for each of the animation
+
+      MD3BoneFrame*             tmpBoneFrame;      //!< a temporary bone frame
+      sVec3D**                  tmpMesh;           //!< a temporary mesh frame
+      MD3Normal**               tmpNormal;         //!< a temporary normals frame
+      float**                   tmpMatrix;         //!< a temporary matrix
+
+
+     /* the animation part */
+     MD3Animation*              animation;         //!< animation
+     int                        op;                //!< the current operation
+     int                        upperBound;        //!< the upper bound
+     bool                       bInterpolate;      //!< interpolate the frames
+  };
+
+
+}
+
+
+
+#endif /* _MD3_DATA_H */
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_mesh.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_mesh.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_mesh.cc	(revision 9940)
@@ -0,0 +1,38 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "md3_mesh.h"
+
+
+namespace md3
+{
+
+/**
+ *  md3 mesh constructor
+ */
+MD3Mesh::MD3Mesh()
+{
+}
+
+
+/**
+ * md3 mesh deconstructor
+ */
+MD3Mesh::~MD3Mesh()
+{}
+
+}
+
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_mesh.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_mesh.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_mesh.h	(revision 9940)
@@ -0,0 +1,86 @@
+/*!
+ * @file md3_mesh.h
+ *
+ * Code heavely inspired by: JAVA MD3 Model Viewer - A Java based Quake 3 model viewer
+ * Copyright (C) 1999 Erwin 'KLR8' Vervaet
+ */
+
+#ifndef _MD3_MESH_H
+#define _MD3_MESH_H
+
+
+#include <string>
+
+#include "md_model_structure.h"
+
+#include "vector.h"
+
+class Material;
+
+
+namespace md3
+{
+
+  typedef struct MD3MeshHeader {
+
+    int     id;                             //!< individual id, must be IDP3
+    char    name[68];                       //!< the name of the mesh
+
+    int     meshFrameNum;                   //!< numbers of frames
+    int     textureNum;                     //!< numbers of textures
+    int     vertexNum;                      //!< numbers of verteces
+    int     triangleNum;                    //!< number of triangles
+
+    int     triangleStart;                  //!< triangle start offset
+    int     textureStart;                   //!< texture start offset
+    int     texVecStart;                    //!< tex vec start offset
+    int     vertexStart;                    //!< vertex start offset
+
+    int     meshSize;                       //!< total mesh size
+  };
+
+
+  typedef struct MD3Triangle  {
+    int     vertexOffset[3];                //!< the vertex offsets of the triangles in the vertex array
+  };
+
+  typedef struct MD3Texture {
+    char    fileName[68];                   //!< the filename of the texture. path relativly to the model file
+  };
+
+  typedef struct MD3TexVecs {
+    float   textureCoord[2];                //!< the texture u/v coordinates
+  };
+
+  typedef struct MD3Normal {
+    int     vertexNormal[2];                //!< vertex normals
+  };
+
+  typedef struct MD3VertexCompressed {
+    short   vector[3];                      //!< compressed vertex information
+    unsigned char vertexNormal[2];          //!< vertex normals compressed
+  };
+
+
+
+class MD3Mesh
+{
+  public:
+    MD3Mesh();
+    virtual ~MD3Mesh();
+
+
+  public:
+    MD3MeshHeader*     header;                  //!< the header of the mesh
+
+    Material*          material;                //!< the material/textures of the models
+    MD3Triangle*       triangles;               //!< indices into mesh frames and texture coord arrays
+    MD3TexVecs*        texVecs;                 //!< tex vecs coordinates
+    sVec3D**           meshFrames;              //!< mesh frames
+    MD3Normal**        normals;                 //!< 3d array of normals with spherical coordinates giving the dir of the vertex normal
+
+};
+
+}
+
+#endif /* _MD3_MESH_H */
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_model.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_model.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_model.cc	(revision 9940)
@@ -0,0 +1,718 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "md3_model.h"
+
+#include "md3_data.h"
+#include "md3_mesh.h"
+#include "md3_tag.h"
+#include "md3_bone_frame.h"
+#include "md3_animation.h"
+
+#include "md3_animation_cfg.h"
+
+#include "material.h"
+#include "quaternion.h"
+
+#include "loading/resource_manager.h"
+
+#include "debug.h"
+
+namespace md3
+{
+
+  /**
+   * md3 model
+   */
+  MD3Model::MD3Model(std::string filename, float scaling)
+  {
+    this->autoAssemblePlayerModel(filename, scaling);
+
+    this->bDrawBones = false;
+    this->bDrawNormals = false;
+
+    this->time = 0.0f;
+
+    // set the animation
+    this->interpolate(this->md3Data, this->config->getAnimation("Dead 1"), MD3_ANIM_NEXT, true);
+  }
+
+
+
+  MD3Model::~MD3Model()
+  {
+//     delete this->tmpBoneFrame;
+//     delete [] this->tmpMesh;
+
+    ///TODO deleting mesh
+    ///TODO deleting matrices
+  }
+
+
+  /**
+   * auto assemples a player model
+   * @param filename is the name to the directory of the modelzzzzzz
+   */
+  void MD3Model::autoAssemblePlayerModel(std::string filename, float scaling)
+  {
+    // loading the config file
+    std::string cfgName(filename + "/animation.cfg");
+    this->config = (MD3AnimationCfg*)ResourceManager::getInstance()->load(cfgName, MD3_CONFIG, RP_GAME);
+
+    //first load the torso or the upper part
+    std::string nameUpper(filename + "/upper.md3");
+    if( (this->md3Data = (MD3Data*)ResourceManager::getInstance()->load(nameUpper, MD3, RP_GAME, nameUpper, scaling)) == NULL)
+    {
+      std::string nameTorso(filename + "/torso.md3");
+      this->md3Data = (MD3Data*)ResourceManager::getInstance()->load(nameTorso, MD3, RP_GAME, nameTorso, scaling);
+    }
+
+    if( this->md3Data == NULL)
+    {
+      PRINTF(1)("Problems loading the MD3Model. Abording\n");
+      return;
+    }
+
+    // load lower
+    std::string nameLower(filename + "/lower.md3");
+    MD3Data* lower = (MD3Data*)ResourceManager::getInstance()->load(nameLower, MD3, RP_GAME, nameLower, scaling);
+    if( lower != NULL)
+    {
+      int tag = this->md3Data->getTagIndexByName("tag_lower");
+      PRINTF(0)("Loaded the %s model on index %i\n", nameLower.c_str(), tag);
+      if( tag >= 0)
+       this->md3Data->addLinkedModel(tag, lower);
+      else
+        PRINTF(0)("Could not add %s\n", nameLower.c_str());
+
+    }
+
+
+    // load head
+    std::string nameHead(filename + "/head.md3");
+    MD3Data* head = (MD3Data*)ResourceManager::getInstance()->load(nameHead, MD3, RP_GAME, nameLower, scaling);
+    if( head != NULL)
+    {
+      int tag = this->md3Data->getTagIndexByName("tag_head");
+      PRINTF(0)("Loaded the %s model on index %i\n", nameHead.c_str(), tag);
+      if( tag >= 0)
+        this->md3Data->addLinkedModel(tag, head);
+      else
+        PRINTF(0)("Could not add %s\n", nameHead.c_str());
+    }
+
+  }
+
+
+
+  /**
+   * tick float
+   * @param time: time elapsed
+   */
+  void MD3Model::tick(float time)
+  {
+    if(this->md3Data == NULL)
+      return;
+
+    this->visit(this->md3Data, time);
+
+    this->tick(time, this->md3Data);
+  }
+
+
+  /**
+   * tick each data
+   */
+  void MD3Model::tick(float time, MD3Data* data)
+  {
+    // draw the bones if needed#
+    if( this->bDrawBones)
+    {
+      // get bone frame, interpolate if necessary
+      if( data->animationState.interpolationFraction != 0.0 &&
+          data->animationState.currentFrame != data->animationState.nextFrame)
+      {
+        //interpolate bone frame
+        data->tmpBoneFrame = this->interpolateBoneFrame(data, data->boneFrames[data->animationState.currentFrame],
+                                                        data->boneFrames[data->animationState.nextFrame],
+                                                        data->animationState.interpolationFraction);
+      }
+      else
+      {
+        data->tmpBoneFrame = data->boneFrames[data->animationState.currentFrame];
+      }
+    }
+
+
+    //draw all meshes of current frame of this model
+    for( int i = 0;  i < data->header->meshNum; i++)
+    {
+      MD3Mesh* mesh = data->meshes[i];
+
+      //interpolate mesh frame between the 2 current mesh frames
+      if( data->header->boneFrameNum > 1)
+        this->interpolateMeshFrame( data,
+                                    mesh->meshFrames[data->animationState.currentFrame],
+                                    mesh->meshFrames[data->animationState.nextFrame],
+                                    data->animationState.interpolationFraction, mesh, i);
+      else
+        this->interpolateMeshFrame( data,
+                                    mesh->meshFrames[data->animationState.currentFrame],
+                                    mesh->meshFrames[data->animationState.currentFrame],
+                                    0.0f, mesh, i);
+
+      // draw vertex normals if needed
+      if( this->bDrawNormals)
+      {
+        // get vertex normals, interpolate if necessary
+        if( data->animationState.interpolationFraction != 0.0 &&
+            data->animationState.currentFrame != data->animationState.nextFrame)
+        {
+          //interpolate vertex normals
+          this->interpolateVertexNormals(data,
+                                         mesh->normals[data->animationState.currentFrame],
+                                         mesh->normals[data->animationState.nextFrame],
+                                         data->animationState.interpolationFraction, mesh, i);
+        }
+      }
+    }
+
+
+    // draw all models linked to this model
+    std::map<int, MD3Data*>::iterator it = data->sortedMap.begin();
+    int i = 0;
+    while( it != data->sortedMap.end())
+    {
+      MD3Data* child = it->second;
+
+      //build transformation array m from matrix, interpolate if necessary
+
+      MD3Tag* currFrameTag = data->boneFrames[data->animationState.currentFrame]->tags[child->parentTagIndex];
+
+      if( data->animationState.interpolationFraction != 0.0 &&
+          data->animationState.currentFrame != data->animationState.nextFrame)
+      {
+        //we need to interpolate
+        MD3Tag* nextFrameTag = data->boneFrames[data->animationState.nextFrame]->tags[child->parentTagIndex];
+        this->interpolateTransformation(child, currFrameTag, nextFrameTag, data->animationState.interpolationFraction, i);
+      }
+      else
+      {
+        //no interpolation needed, stay with last transformation
+        //OpenGL matrix is in column-major order
+        data->tmpMatrix[i][0] = currFrameTag->matrix[0][0];
+        data->tmpMatrix[i][1] = currFrameTag->matrix[1][0];
+        data->tmpMatrix[i][2] = currFrameTag->matrix[2][0];
+        data->tmpMatrix[i][3] = 0.0f;
+        data->tmpMatrix[i][4] = currFrameTag->matrix[0][1];
+        data->tmpMatrix[i][5] = currFrameTag->matrix[1][1];
+        data->tmpMatrix[i][6] = currFrameTag->matrix[2][1];
+        data->tmpMatrix[i][7] = 0.0f;
+        data->tmpMatrix[i][8] = currFrameTag->matrix[0][2];
+        data->tmpMatrix[i][9] = currFrameTag->matrix[1][2];
+        data->tmpMatrix[i][10]= currFrameTag->matrix[2][2];
+        data->tmpMatrix[i][11]= 0.0f;
+        data->tmpMatrix[i][12] = currFrameTag->position.x;
+        data->tmpMatrix[i][13] = currFrameTag->position.y;
+        data->tmpMatrix[i][14] = currFrameTag->position.z;
+        data->tmpMatrix[i][15] = 1.0f;
+      }
+
+      // switch to child coord system
+
+      // and tick child
+      this->tick(time, child);
+
+      i++;
+      it++;
+    }
+  }
+
+
+  /**
+   * this draws the md3 model
+   */
+  void MD3Model::draw() const
+  {
+    //draw current bone frame
+    this->draw(this->md3Data);
+  }
+
+
+  /**
+   * draw the md3model
+   * @param data: the data to be drawn
+   */
+  void MD3Model::draw(MD3Data* data) const
+  {
+
+    // draw the bones if needed
+    if( this->bDrawBones)
+    {
+      // get bone frame, interpolate if necessary
+      if( data->animationState.interpolationFraction != 0.0 &&
+          data->animationState.currentFrame != data->animationState.nextFrame) {
+        //interpolate bone frame
+        this->drawBoneFrame(data->tmpBoneFrame);
+      }
+      else {
+        //stick with current bone frame
+        this->drawBoneFrame(data->boneFrames[data->animationState.currentFrame]);
+      }
+    }
+
+
+    //draw all meshes of current frame of this model
+    for( int i = 0;  i < data->header->meshNum; i++)
+    {
+      MD3Mesh* mesh = data->meshes[i];
+      sVec3D* frame = data->tmpMesh[i];
+
+      if( mesh->header->textureNum > 0 && &mesh->material[0] != NULL)
+        mesh->material[0].select();
+
+      this->drawMesh(mesh, frame);
+
+      // draw vertex normals if needed
+      if( this->bDrawNormals)
+      {
+        // get vertex normals, interpolate if necessary
+        if( data->animationState.interpolationFraction != 0.0 &&
+            data->animationState.currentFrame != data->animationState.nextFrame)
+        {
+          //interpolate vertex normals
+          this->drawVertexNormals(frame, data->tmpNormal[i]);
+        }
+        else {
+          //stick with current vertex normals
+          this->drawVertexNormals(frame, mesh->normals[data->animationState.currentFrame]);
+        }
+      }
+    }
+
+
+    // draw all models linked to this model
+    int i = 0;
+    std::map<int, MD3Data*>::iterator it = data->sortedMap.begin();
+    while( it != data->sortedMap.end())
+    {
+      MD3Data* child = it->second;
+
+      //switch to child coord system
+      glPushMatrix();
+      glMultMatrixf(data->tmpMatrix[i]);
+
+      // and draw child
+      this->draw(child);
+
+      glPopMatrix();
+
+      i++;
+      it++;
+    }
+
+  }
+
+
+  /**
+   * draws the mesh
+   */
+  void MD3Model::drawMesh(MD3Mesh* mesh, sVec3D* frame) const
+  {
+    Vector tmpVec1, tmpVec2;
+
+    glColor3f(1.0f, 1.0f, 1.0f);
+    glBegin( GL_TRIANGLES);
+
+    // upload all triangles in the frame to OpenGL
+    for( int t = 0; t < mesh->header->triangleNum; t++)
+    {
+      // calc normal vector
+      tmpVec1.x = frame[mesh->triangles[t].vertexOffset[1]][0] - frame[mesh->triangles[t].vertexOffset[0]][0];
+      tmpVec1.y = frame[mesh->triangles[t].vertexOffset[1]][1] - frame[mesh->triangles[t].vertexOffset[0]][1];
+      tmpVec1.z = frame[mesh->triangles[t].vertexOffset[1]][2] - frame[mesh->triangles[t].vertexOffset[0]][2];
+
+      tmpVec2.x = frame[mesh->triangles[t].vertexOffset[2]][0] - frame[mesh->triangles[t].vertexOffset[0]][0];
+      tmpVec2.y = frame[mesh->triangles[t].vertexOffset[2]][1] - frame[mesh->triangles[t].vertexOffset[0]][1];
+      tmpVec2.z = frame[mesh->triangles[t].vertexOffset[2]][2] - frame[mesh->triangles[t].vertexOffset[0]][2];
+
+      Vector normal = tmpVec1.cross(tmpVec2);
+      normal.normalize();
+
+//       PRINTF(0)("normal: %f, %f, %f\n", normal.x, normal.y, normal.z);
+
+      glNormal3f(normal.x, normal.y, normal.z);
+      glTexCoord2fv( mesh->texVecs[mesh->triangles[t].vertexOffset[0]].textureCoord);
+      glVertex3f( frame[mesh->triangles[t].vertexOffset[0]][0],
+                  frame[mesh->triangles[t].vertexOffset[0]][2],
+                  frame[mesh->triangles[t].vertexOffset[0]][1]);
+
+      glNormal3f(normal.x, normal.y, normal.z);
+      glTexCoord2fv( mesh->texVecs[mesh->triangles[t].vertexOffset[1]].textureCoord);
+      glVertex3f( frame[mesh->triangles[t].vertexOffset[1]][0],
+                  frame[mesh->triangles[t].vertexOffset[1]][2],
+                  frame[mesh->triangles[t].vertexOffset[1]][1]);
+
+      glNormal3f(normal.x, normal.y, normal.z);
+      glTexCoord2fv( mesh->texVecs[mesh->triangles[t].vertexOffset[2]].textureCoord);
+      glVertex3f( frame[mesh->triangles[t].vertexOffset[2]][0],
+                  frame[mesh->triangles[t].vertexOffset[2]][2],
+                  frame[mesh->triangles[t].vertexOffset[2]][1]);
+    }
+    glEnd();
+  }
+
+
+  /**
+   *  drawo vertex normals
+   */
+  void MD3Model::drawVertexNormals(sVec3D* frame, MD3Normal* normals) const
+  {}
+
+
+  /**
+   * draw bone frame
+   */
+  void MD3Model::drawBoneFrame(MD3BoneFrame* frame) const
+  {
+    float x1 = frame->mins.x;
+    float y1 = frame->mins.y;
+    float z1 = frame->mins.z;
+    float x2 = frame->maxs.x;
+    float y2 = frame->maxs.y;
+    float z2 = frame->maxs.z;
+
+    glPushAttrib(GL_TEXTURE_2D);
+    glPushAttrib(GL_LIGHTING);
+
+    glColor3f(1.0f,0.0f,0.0f);
+    glPointSize(6.0f);
+
+    glBegin(GL_POINTS);
+    glVertex3f(frame->position.x, frame->position.y, frame->position.z);
+    glEnd();
+    glPointSize(1.0f);
+
+    glColor3f(0.0f,1.0f,0.0f);
+    glBegin(GL_LINE_LOOP);
+    glVertex3f(x1,y1,z1);
+    glVertex3f(x1,y1,z2);
+    glVertex3f(x1,y2,z2);
+    glVertex3f(x1,y2,z1);
+    glEnd();
+
+    glBegin(GL_LINE_LOOP);
+    glVertex3f(x2,y2,z2);
+    glVertex3f(x2,y1,z2);
+    glVertex3f(x2,y1,z1);
+    glVertex3f(x2,y2,z1);
+    glEnd();
+
+    glBegin(GL_LINES);
+    glVertex3f(x1,y1,z1);
+    glVertex3f(x2,y1,z1);
+
+    glVertex3f(x1,y1,z2);
+    glVertex3f(x2,y1,z2);
+
+    glVertex3f(x1,y2,z2);
+    glVertex3f(x2,y2,z2);
+
+    glVertex3f(x1,y2,z1);
+    glVertex3f(x2,y2,z1);
+    glEnd();
+
+     glPopAttrib();
+     glPopAttrib();
+  }
+
+
+  /**
+   *  interpolate bone frame
+   * @param currBoneFrame Start bone frame.
+   * @param nextBoneFrame End bone frame.
+   * @param frac Interpolation fraction, in [0,1].
+   */
+  MD3BoneFrame* MD3Model::interpolateBoneFrame(MD3Data* data, MD3BoneFrame* currBoneFrame, MD3BoneFrame* nextBoneFrame, float frac)
+  {
+    data->tmpBoneFrame->mins.x      = (1.0f - frac) * currBoneFrame->mins.x       + frac * nextBoneFrame->mins.x;
+    data->tmpBoneFrame->maxs.x      = (1.0f - frac) * currBoneFrame->maxs.x       + frac * nextBoneFrame->maxs.x;
+    data->tmpBoneFrame->position.x  = (1.0f - frac) * currBoneFrame->position.x   + frac * nextBoneFrame->position.x;
+    data->tmpBoneFrame->mins.y      = (1.0f - frac) * currBoneFrame->mins.y       + frac * nextBoneFrame->mins.y;
+    data->tmpBoneFrame->maxs.y      = (1.0f - frac) * currBoneFrame->maxs.y       + frac * nextBoneFrame->maxs.y;
+    data->tmpBoneFrame->position.y  = (1.0f - frac) * currBoneFrame->position.y   + frac * nextBoneFrame->position.y;
+    data->tmpBoneFrame->mins.z      = (1.0f - frac) * currBoneFrame->mins.z       + frac * nextBoneFrame->mins.z;
+    data->tmpBoneFrame->maxs.z      = (1.0f - frac) * currBoneFrame->maxs.z       + frac * nextBoneFrame->maxs.z;
+    data->tmpBoneFrame->position.z  = (1.0f - frac) * currBoneFrame->position.z   + frac * nextBoneFrame->position.z;
+
+    return data->tmpBoneFrame;
+  }
+
+
+
+  /**
+   * interpolate mesh frame
+   */
+  sVec3D* MD3Model::interpolateMeshFrame(MD3Data* data, sVec3D* currMeshFrame, sVec3D* nextMeshFrame, float frac, MD3Mesh* mesh, int i)
+  {
+    int vertexNum = mesh->header->vertexNum;
+
+    if( /*frac == 0.0f*/ true)
+    {
+      // just copy the vertices
+      for( int t = 0; t < vertexNum; t++)
+      {
+        data->tmpMesh[i][t][0]  = currMeshFrame[t][0];
+        data->tmpMesh[i][t][1]  = currMeshFrame[t][1];
+        data->tmpMesh[i][t][2]  = currMeshFrame[t][2];
+      }
+    }
+    else
+    {
+      // calc interpolated vertices
+      for( int t = 0; t < vertexNum; t++)
+      {
+        data->tmpMesh[i][t][0]  = (1.0f - frac)   * currMeshFrame[t][0]  + frac * nextMeshFrame[t][0];
+        data->tmpMesh[i][t][1]  = (1.0f - frac)   * currMeshFrame[t][1]  + frac * nextMeshFrame[t][1];
+        data->tmpMesh[i][t][2]  = (1.0f - frac)   * currMeshFrame[t][2]  + frac * nextMeshFrame[t][2];
+      }
+    }
+
+    return data->tmpMesh[i];
+  }
+
+
+  /**
+   * interpolate vertex normal
+   */
+  MD3Normal* MD3Model::interpolateVertexNormals(MD3Data* data, MD3Normal* currNormals, MD3Normal* nextNormals, float frac, MD3Mesh* mesh, int i)
+  {
+    for( int j = 0; j < mesh->header->vertexNum; j++)
+    {
+      data->tmpNormal[i][j].vertexNormal[0] = (int)((1.0f - frac) * currNormals[j].vertexNormal[0] + frac * nextNormals[j].vertexNormal[0]);
+      data->tmpNormal[i][j].vertexNormal[1] = (int)((1.0f - frac) * currNormals[j].vertexNormal[1] + frac * nextNormals[j].vertexNormal[1]);
+    }
+
+    return data->tmpNormal[i];
+  }
+
+
+  /**
+   * interpolate transformation
+   */
+  float* MD3Model::interpolateTransformation(MD3Data* data, MD3Tag* currFrameTag, MD3Tag* nextFrameTag, float frac, int i)
+  {
+    // interpolate position
+    Vector interpolatedPosition = currFrameTag->position * (1.0f - frac) + nextFrameTag->position * frac;
+
+
+    // interpolate rotation matrix
+    float  currRot[4][4];
+    float  nextRot[4][4];
+    float  interpolatedMatrix[4][4];
+
+    /// TODO CHANGED BY BENSCH TO MATCH NEW QUATERNION FUNCTIONALITY
+    Quaternion currQuat; currQuat.from3x3(currFrameTag->matrix); currQuat.matrix(currRot);
+    Quaternion nextQuat; nextQuat.from3x3(nextFrameTag->matrix); nextQuat.matrix(nextRot);
+
+    Quaternion interpolatedQuat = Quaternion::quatSlerp(currQuat, nextQuat, frac); interpolatedQuat.matrix(interpolatedMatrix);
+
+    // quaternion code is column based, so use transposed matrix when spitting out to gl
+    data->tmpMatrix[i][0] = interpolatedMatrix[0][0];
+    data->tmpMatrix[i][4] = interpolatedMatrix[1][0];
+    data->tmpMatrix[i][8] = interpolatedMatrix[2][0];
+    data->tmpMatrix[i][12] = interpolatedPosition.x;
+    data->tmpMatrix[i][1] = interpolatedMatrix[0][1];
+    data->tmpMatrix[i][5] = interpolatedMatrix[1][1];
+    data->tmpMatrix[i][9] = interpolatedMatrix[2][1];
+    data->tmpMatrix[i][13] = interpolatedPosition.y;
+    data->tmpMatrix[i][2] = interpolatedMatrix[0][2];
+    data->tmpMatrix[i][6] = interpolatedMatrix[1][2];
+    data->tmpMatrix[i][10]= interpolatedMatrix[2][2];
+    data->tmpMatrix[i][14] = interpolatedPosition.z;
+    data->tmpMatrix[i][3] = 0.0f;
+    data->tmpMatrix[i][7] = 0.0f;
+    data->tmpMatrix[i][11]= 0.0f;
+    data->tmpMatrix[i][15] = 1.0f;
+
+    return data->tmpMatrix[i];
+
+  }
+
+
+
+  /**
+   * visit the model
+   */
+  void MD3Model::visit(MD3Data* data, float time)
+  {
+    if ( (data->filename.find("lower") == std::string::npos &&
+          (data->animation->type == LEGS || data->animation->type == BOTH)) // this is the LEGS model and the animation is applicable
+          ||
+          (data->filename.find("upper") == std::string::npos &&
+          (data->animation->type == TORSO || data->animation->type == BOTH)) // this is the TORSO model and the animation is applicable
+          ||
+          data->animation->type == ALL // the animation is allways applicable
+       )
+      this->doOp(data, time);
+
+    // visit children
+//     std::map<int, MD3Data*>::iterator it = data->sortedMap.begin();
+//     while( it != data->sortedMap.end())
+//     {
+//       this->visit(it->second);
+//       it++;
+//     }
+  }
+
+
+  /**
+   * Create a new visitor to apply an animation operation (NEXT, REWIND, ...)
+   * to a MD3 model. The operation is executed in the context of the specified
+   * animation.
+   *
+   * @param anim The animation that provides the context for the operation.
+   * @param op The operation to apply.
+   * @param interpolate Should interpolation be done?
+   */
+  void MD3Model::interpolate(MD3Data* data, MD3Animation* anim, int op, bool bInterpolate)
+  {
+     data->animation = anim;
+     if( op == MD3_ANIM_NEXT || op == MD3_ANIM_PREVIOUS || op == MD3_ANIM_REWIND)
+      data->op = op;
+
+     data->bInterpolate = bInterpolate;
+  }
+
+
+  /**
+   * calc next frame number
+   */
+  int MD3Model::next(MD3Data* data, int nr)
+  {
+    if( nr < (data->upperBound - 1))
+      return nr + 1;
+    else
+    { //rewind needed
+      if( data->animation->numFrames < 0)
+        return data->animation->first;
+      else {
+        nr = (data->animation->numLoopFrames != 0)?(data->animation->numFrames - data->animation->numLoopFrames):0;
+        return data->animation->first + nr;
+      }
+    }
+  }
+
+
+  /**
+   * calc prev frame number
+   */
+  int MD3Model::prev(MD3Data* data, int nr)
+  {
+    if( nr == data->animation->first)
+      return data->upperBound - 1;
+    else
+      return nr - 1;
+  }
+
+
+  /**
+   * apply the specified operation to the animation state data members of the model
+   * taking the specified animation into account
+   *
+   * @param data: the data of the model
+   */
+  void MD3Model::doOp(MD3Data* data, float time)
+  {
+    // animation to be applied could have illegal data with respect to this model,
+    // ignore anim in this case
+
+    if( data->animation->first >= data->animation->numFrames || data->animation->first < 0)
+    {
+      PRINTF(0)("MD3: this animation type seems to be invalid, no animation calculated\n");
+      return;
+    }
+
+
+    //calc upper bound for animation frames in this model
+    if( data->animation->numFrames < 0)
+      data->upperBound = data->header->boneFrameNum; //use all available frames
+    else
+    {
+      if( data->header->boneFrameNum < (data->animation->first + data->animation->numFrames))
+        data->upperBound = data->header->boneFrameNum;
+      else
+        data->upperBound = (data->animation->first + data->animation->numFrames);
+    }
+
+
+    switch( data->op) {
+
+      case MD3_ANIM_NEXT:
+        if( data->bInterpolate)
+        {
+          // keyframe interpolation animation
+          data->animationState.interpolationFraction += time * data->animation->fps;
+
+          if( data->animationState.interpolationFraction >= 1.0f)
+          {
+            data->animationState.currentFrame = data->animationState.nextFrame;
+            data->animationState.nextFrame = next(data, data->animationState.nextFrame);
+            data->animationState.interpolationFraction = 0.0f;
+          }
+        }
+        else
+        {
+          // only keyframe animation
+          this->time += time * data->animation->fps;
+          if( this->time > 1.0f)
+          {
+            data->animationState.currentFrame = data->animationState.nextFrame;
+            data->animationState.nextFrame = next(data, data->animationState.nextFrame);
+            this->time = 0.0f;
+          }
+        }
+        break;
+
+      case MD3_ANIM_PREVIOUS:
+        if( data->bInterpolate)
+        {
+          data->animationState.interpolationFraction -= time / data->animation->fps;
+          if( data->animationState.interpolationFraction < 0.0f)
+          {
+            data->animationState.nextFrame = data->animationState.currentFrame;
+            data->animationState.currentFrame = prev(data, data->animationState.currentFrame);
+            data->animationState.interpolationFraction = 0.8f;
+          }
+        }
+        else
+        {
+          data->animationState.nextFrame = data->animationState.currentFrame;
+          data->animationState.currentFrame = prev(data, data->animationState.currentFrame);
+        }
+        break;
+
+      case MD3_ANIM_REWIND:
+        data->animationState.currentFrame = data->animation->first;
+        data->animationState.nextFrame = next(data, data->animationState.currentFrame);
+        data->animationState.interpolationFraction = 0.0f;
+        break;
+    }
+
+  }
+
+
+}
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_model.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_model.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_model.h	(revision 9940)
@@ -0,0 +1,95 @@
+/*!
+ * @file md3_model.h
+ *
+ * Code heavely inspired by: JAVA MD3 Model Viewer - A Java based Quake 3 model viewer
+ * Copyright (C) 1999 Erwin 'KLR8' Vervaet
+ */
+
+#ifndef _MD3_MODEL_H
+#define _MD3_MODEL_H
+
+#include <string>
+#include "interactive_model.h"
+
+
+#define FRACTION 0.34f
+
+
+namespace md3
+{
+
+
+class MD3Data;
+class MD3BoneFrame;
+class MD3Mesh;
+class MD3Tag;
+class MD3AnimationCfg;
+class MD3Animation;
+
+struct MD3Normal;
+
+
+typedef enum MD3FrameHandling {
+  MD3_ANIM_NEXT = 0,          //!< swith to the next frame
+  MD3_ANIM_PREVIOUS,          //!< swith to the previous frame
+  MD3_ANIM_REWIND             //!< rewind the animation
+};
+
+
+class MD3Model : public InteractiveModel
+{
+
+  public:
+    MD3Model(std::string filename, float scaling);
+    ~MD3Model();
+
+    virtual void setAnimation(int animNum, int playbackMode = 0) {}
+    virtual int getAnimation() const { return 0;}
+
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+
+  private:
+
+    void autoAssemblePlayerModel(std::string filename, float scaling);
+
+    void draw(MD3Data* data) const;
+    void tick(float dt, MD3Data* data);
+
+
+    void drawMesh(MD3Mesh* mesh, sVec3D* frame) const;
+    void drawVertexNormals(sVec3D* frame, MD3Normal* normals) const;
+    void drawBoneFrame(MD3BoneFrame* frame) const;
+
+
+    MD3BoneFrame* interpolateBoneFrame(MD3Data* data, MD3BoneFrame* currBoneFrame, MD3BoneFrame* nextBoneFrame, float frac);
+    sVec3D* interpolateMeshFrame(MD3Data* data, sVec3D* currMeshFrame, sVec3D* nextMeshFrame, float frac, MD3Mesh* mesh, int i);
+    MD3Normal* interpolateVertexNormals(MD3Data* data, MD3Normal* curNormals, MD3Normal* nextNormals, float frac, MD3Mesh* mesh, int i);
+    float* interpolateTransformation(MD3Data* data, MD3Tag* currFrameTag, MD3Tag* nextFrameTag, float frac, int i);
+
+
+    void interpolate(MD3Data* data, MD3Animation* anim, int op, bool bInterpolate);
+
+    void visit(MD3Data* data, float time);
+    int next(MD3Data* data, int nr);
+    int prev(MD3Data* data, int nr);
+    void doOp(MD3Data* data, float time);
+
+
+  private:
+    MD3Data*            md3Data;           //!< reference to the md3 model data
+
+    bool                bDrawBones;        //!< draws the bone frames too
+    bool                bDrawNormals;      //!< draw the normals
+
+    MD3AnimationCfg*    config;            //!< the config file parsed
+
+    float               time;
+
+};
+
+
+}
+
+#endif /* _MD3_MODEL_H */
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_tag.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_tag.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_tag.cc	(revision 9940)
@@ -0,0 +1,35 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "md3_tag.h"
+
+
+
+namespace md3
+{
+
+
+
+  MD3Tag::MD3Tag()
+  { /* loadMesh(this, din) */ }
+
+
+  MD3Tag::~MD3Tag()
+  {}
+
+
+}
+
Index: branches/heathaze/src/lib/graphics/importer/md3/md3_tag.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md3/md3_tag.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md3/md3_tag.h	(revision 9940)
@@ -0,0 +1,43 @@
+/*!
+ * @file md3_mesh.h
+ *
+ * Code heavely inspired by: JAVA MD3 Model Viewer - A Java based Quake 3 model viewer
+ * Copyright (C) 1999 Erwin 'KLR8' Vervaet
+ */
+
+#ifndef _MD3_TAG_H
+#define _MD3_TAG_H
+
+#include <string>
+
+#include "vector.h"
+
+namespace md3
+{
+
+typedef struct MD3TagData
+{
+  char       name[64];                                //!< name of the tag
+  sVec3D     position;                                //!< position of the tag
+  float      matrix[3][3];                            //!< matrix of the rotation
+};
+
+
+class MD3Tag
+{
+  public:
+    MD3Tag();
+    virtual ~MD3Tag();
+
+
+  public:
+    std::string               name;                   //!< name of tag as its usualy called in the md3 file
+    Vector                    position;               //!< the position of the tag reltive to the models containing that tag
+    float                     matrix[3][3];           //!< 3x3 rotation matrix
+
+    MD3TagData*               data;                   //!< data reference
+};
+
+}
+
+#endif /* _MD3_TAG_H */
Index: branches/heathaze/src/lib/graphics/importer/md_model_structure.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/md_model_structure.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/md_model_structure.h	(revision 9940)
@@ -0,0 +1,88 @@
+/*!
+ * @file md_model_structure.h
+ */
+
+
+
+#ifndef _MD3_MODEL_STRUCTURE_H
+#define _MD3_MODEL_STRUCTURE_H
+
+
+#include "vector.h"
+
+
+//! compressed vertex data: char insetead of float, the value will be expanded by the scale value. only for loading
+typedef struct
+{
+  unsigned char    v[3];                 //!< the vector of the vertex
+  unsigned char    lightNormalIndex;     //!< the index of the light normal
+} sVertex;
+
+
+//! compressed texture offset data: coords scaled by the texture size. Only for loading
+typedef struct
+{
+  short            s;                    //!< the s,t coordinates of a texture
+  short            t;                    //!< the s,t coordinates of a texture
+} sTexCoor;
+
+
+//! holds tha informations about a md2 frame
+typedef struct
+{
+  sVec3D           scale;                //!< scales values of the model
+  sVec3D           translate;            //!< translates the model
+  char             name[16];             //!< frame name: something like "run32"
+  sVertex          pVertices[1];         //!< first vertex of thes frame
+} sFrame;
+
+
+//! holds the information about a triangle
+typedef struct
+{
+  unsigned short   indexToVertices[3];   //!< index to the verteces of the triangle
+  unsigned short   indexToTexCoor[3];    //!< index to the texture coordinates
+} sTriangle;
+
+
+
+//! the command list of the md2 model, very md2 specific
+typedef struct
+{
+  float            s;                    //!< texture coordinate 1
+  float            t;                    //!< texture coordinate 2
+  int              vertexIndex;          //!< index of the vertex in the vertex list
+} glCommandVertex;
+
+
+//! a md2 animation definition
+typedef struct
+{
+  int              firstFrame;           //!< first frame of the animation
+  int              lastFrame;            //!< last frame of the animation
+  int              fps;                  //!< speed: number of frames per second
+  int              bStoppable;           //!< 1 if the animation is stoppable 0 else
+} sAnim;
+
+
+//! animation state definition
+typedef struct
+{
+  int              startFrame;           //!< the start frame of an animation
+  int              endFrame;             //!< last frame of the animation
+  int              fps;                  //!< fps of the animaion (speed)
+
+  float            localTime;            //!< the local time
+  float            lastTime;             //!< last time stamp
+  float            interpolationState;   //!< the state of the animation [0..1]
+
+  int              type;                 //!< animation type
+
+  int              currentFrame;         //!< the current frame
+  int              nextFrame;            //!< the next frame in the list
+  int              numPlays;             //!< the number of times, this has been played in series
+
+  int              animPlaybackMode;     //!< the playback mode
+} sAnimState;
+
+#endif /* _MD3_MODEL_STRUCTURE_H */
Index: branches/heathaze/src/lib/graphics/importer/media_container.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/media_container.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/media_container.cc	(revision 9940)
@@ -0,0 +1,261 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: David Hasenfratz, Stephan Lienhard
+   co-programmer:
+*/
+
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_MEDIA module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+
+/* include your own header */
+#include "media_container.h"
+
+#include "util/loading/resource_manager.h"
+/* header for debug output */
+#include "debug.h"
+
+ObjectListDefinition(MediaContainer);
+
+/**
+ * Default constructor
+ */
+MediaContainer::MediaContainer(const std::string& filename)
+{
+  // set the class id for the base object
+  this->registerObject(this, MediaContainer::_objectList);
+
+  fps = 0;
+  mediaLoaded = false;
+  if (!filename.empty())
+    this->loadMedia(filename);
+}
+
+/**
+ * Default destructor
+ */
+MediaContainer::~MediaContainer()
+{
+  this->unloadMedia();
+}
+
+void MediaContainer::unloadMedia()
+{
+  // check whether a movie is already loaded
+  if(!mediaLoaded)
+    return;
+
+  fps = 0;
+
+  // clear texturelist
+  this->clearLists();
+
+  if (glIsTexture(texture))
+  glDeleteTextures(1, &texture);
+
+  // Free the RGB image
+  delete [] buffer;
+  av_free(RGB_frame);
+
+  // Free the frame
+  av_free(frame);
+
+  // Close the codec
+  avcodec_close(codec_context);
+
+  // Close the video file
+  av_close_input_file(format_context);
+
+  mediaLoaded = false;
+
+}
+
+bool MediaContainer::loadMedia(const std::string& filename)
+{
+  this->unloadMedia();
+
+  if(filename.empty())
+    return false;
+  // check whether file exists
+  if(!Resources::ResourceManager::getInstance()->checkFileInMainPath(filename))
+  {
+    PRINTF(1)("Could not find %s\n", filename.c_str());
+    return false;
+  }
+
+  // register all formats and codecs
+  av_register_all();
+
+  // Open video file
+  if (av_open_input_file(&format_context, Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(filename).c_str(), NULL, 0, NULL) !=0 )
+  {
+    PRINTF(1)("Could not open %s\n", Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(filename).c_str());
+    return false;
+  }
+
+  // Retrieve stream information
+  if (av_find_stream_info(format_context) < 0)
+  {
+    PRINTF(1)("Could not find stream information in %s\n", Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(filename).c_str());
+    return false;
+  }
+
+  // Find the first video stream and take it
+  video_stream = av_find_default_stream_index(format_context);
+
+  if(video_stream == -1)
+  {
+    PRINTF(1)("Could not find a video stream in %s\n", Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(filename).c_str());
+    return false;
+  }
+
+  // Get a pointer to the codec context for the video stream
+  codec_context = format_context->streams[video_stream]->codec;
+
+  // Find the decoder for the video stream
+  codec = avcodec_find_decoder(codec_context->codec_id);
+  if (codec == NULL)
+  {
+    PRINTF(1)("Could not find codec\n");
+    return false;
+  }
+
+  // Open codec
+  if (avcodec_open(codec_context, codec) < 0)
+  {
+    PRINTF(1)("Could not open codec\n");
+    return false;
+  }
+
+  // Allocate video frame
+  frame = avcodec_alloc_frame();
+  RGB_frame = avcodec_alloc_frame();
+
+  // Determine required buffer size and allocate buffer
+  num_bytes = avpicture_get_size(PIX_FMT_RGB24, codec_context->width, codec_context->height);
+  buffer=new uint8_t[num_bytes];
+
+  // data buffer for the texture
+  data = new uint8_t[codec_context->width*codec_context->height*3*sizeof(uint8_t)];
+
+  // Assign appropriate parts of buffer to image planes in RGB_frame
+  avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);
+
+  // Calculate fps
+  fps = av_q2d(format_context->streams[video_stream]->r_frame_rate);
+  // NOTE: fix this fps problem!!
+  if(fps < 0 || fps > 1000)
+    fps = 30;
+
+  // read the frames and save them in a sequence as textures
+  this->loadFrames();
+  mediaLoaded = true;
+
+  return true;
+}
+
+double MediaContainer::getFPS()
+{
+  return this->fps;
+}
+
+void MediaContainer::loadFrames()
+{
+  // empty texture list
+  this->clearLists();
+
+  // go to the begin of the video
+  av_seek_frame(format_context, video_stream, 0, AVSEEK_FLAG_BACKWARD);
+
+  // get all the frames and save them in the sequence
+  while(this->addFrame(this->getNextFrame()) != 0);
+}
+
+
+GLuint MediaContainer::getNextFrame()
+{
+
+  // get next frame
+  if(av_read_frame(format_context, &packet) >= 0)
+  {
+    // Is this a packet from the video stream?
+    if(packet.stream_index == video_stream)
+    {
+      int frame_finished;
+      // Decode video frame
+      avcodec_decode_video(codec_context, frame, &frame_finished,
+                           packet.data, packet.size);
+
+      // Free the packet that was allocated by av_read_frame
+      av_free_packet(&packet);
+
+      // Did we get a video frame?
+      if(frame_finished)
+      {
+        // Conversion from YUV to RGB
+        // Most codecs return images in YUV 420 format
+        // (one luminance and two chrominance channels, with the chrominance
+        // channels samples at half the spatial resolution of the luminance channel)
+        img_convert((AVPicture*)RGB_frame, PIX_FMT_RGB24, (AVPicture*)frame,
+                    codec_context->pix_fmt, codec_context->width, codec_context->height);
+
+        for(int i = 0; i < codec_context->height; i++)
+          memcpy(&data[i*codec_context->width*3],
+                 ((AVPicture*)RGB_frame)->data[0]+i *
+                 ((AVPicture*)RGB_frame)->linesize[0],
+                  codec_context->width*sizeof(uint8_t)*3);
+
+        // Create an OpenGL texture
+        glGenTextures(1, &texture);
+        glBindTexture(GL_TEXTURE_2D, texture);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        // create the texture
+        glTexImage2D(GL_TEXTURE_2D,
+                    0,
+                    GL_RGB,
+                    codec_context->width, codec_context->height,
+                    0,
+                    GL_RGB,
+                    GL_UNSIGNED_BYTE,
+                    data);
+        // build the MipMaps
+        gluBuild2DMipmaps(GL_TEXTURE_2D,
+                        GL_RGB,
+                        codec_context->width,
+                        codec_context->height,
+                        GL_RGB,
+                        GL_UNSIGNED_BYTE,
+                        data);
+        glBindTexture(GL_TEXTURE_2D, 0);
+
+        return texture;
+      }
+      else
+      {
+        av_free_packet(&packet);
+        return this->getNextFrame();
+      }
+    }
+    else
+    {
+      av_free_packet(&packet);
+      return this->getNextFrame();
+    }
+  }
+  else
+    return 0;
+}
Index: branches/heathaze/src/lib/graphics/importer/media_container.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/media_container.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/media_container.h	(revision 9940)
@@ -0,0 +1,61 @@
+/*!
+ * @file media_container.h
+  *  Manages the media files
+
+*/
+
+#ifndef _MEDIA_CONTAINER
+#define _MEDIA_CONTAINER
+
+#include "sdlincl.h"
+
+#ifdef HAVE_AVFORMAT_H
+  #include <avformat.h>
+#else
+  #include <ffmpeg/avformat.h>
+#endif
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+#include "texture_sequence.h"
+
+#include "glincl.h"
+
+class MediaContainer : public TextureSequence
+{
+  ObjectListDeclaration(MediaContainer);
+private:
+
+  AVFormatContext* format_context;
+  AVCodecContext* codec_context;
+  AVCodec* codec;
+  AVFrame* frame;
+  AVPacket packet;
+  AVFrame* RGB_frame;
+
+  GLuint texture;
+  uint8_t* data;
+  uint8_t* buffer;
+  int num_bytes;
+  int video_stream;
+  double fps;
+  bool mediaLoaded;
+
+public:
+
+  MediaContainer(const std::string& filename = "");
+  virtual ~MediaContainer();
+
+  bool loadMedia(const std::string& filename);
+  void loadFrames();
+
+  double getFPS();
+
+private:
+
+  GLuint getNextFrame();
+  void unloadMedia();
+};
+
+
+#endif /* _MEDIA_CONTAINER */
Index: branches/heathaze/src/lib/graphics/importer/model.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/model.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/model.cc	(revision 9940)
@@ -0,0 +1,89 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MODEL
+
+#include "model.h"
+
+#include "glincl.h"
+
+ObjectListDefinition(Model);
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+Model::Model()
+{
+  this->registerObject(this, Model::_objectList);
+  this->pModelInfo.numVertices = 0;
+  this->pModelInfo.numTriangles = 0;
+  this->pModelInfo.numNormals = 0;
+  this->pModelInfo.numTexCoor = 0;
+
+  this->pModelInfo.pVertices = NULL;
+  this->pModelInfo.pTriangles = NULL;
+  this->pModelInfo.pNormals = NULL;
+  this->pModelInfo.pTexCoor = NULL;
+}
+
+
+/**
+ * standard deconstructor
+*/
+Model::~Model()
+{
+  if( this->pModelInfo.pVertices != NULL)
+    delete [] this->pModelInfo.pVertices;
+
+  if( this->pModelInfo.pTriangles != NULL)
+    delete [] this->pModelInfo.pTriangles;
+
+  if( this->pModelInfo.pNormals != NULL)
+    delete [] this->pModelInfo.pNormals;
+
+  if( this->pModelInfo.pTexCoor != NULL)
+    delete [] this->pModelInfo.pTexCoor;
+}
+
+
+
+void Model::draw() const
+{
+  const GLfloat* pVertices = NULL;
+  const GLfloat* pNorm = NULL;
+
+  glBegin(GL_TRIANGLES);
+  for(unsigned int i = 0; i < this->pModelInfo.numTriangles; ++i)
+    {
+      //printf("int i = %i\n", i);
+      pNorm = &this->pModelInfo.pNormals[this->pModelInfo.pTriangles[i].indexToNormals[0]];
+      pVertices = &this->pModelInfo.pVertices[this->pModelInfo.pTriangles[i].indexToVertices[0]];
+      glNormal3f(pNorm[0], pNorm[1], pNorm[2]);
+      glVertex3f(pVertices[0], pVertices[1], pVertices[2]);
+
+      pNorm = &this->pModelInfo.pNormals[this->pModelInfo.pTriangles[i].indexToNormals[1]];
+      pVertices = &this->pModelInfo.pVertices[this->pModelInfo.pTriangles[i].indexToVertices[1]];
+      glNormal3f(pNorm[0], pNorm[1], pNorm[2]);
+      glVertex3f(pVertices[0], pVertices[1], pVertices[2]);
+
+      pNorm = &this->pModelInfo.pNormals[this->pModelInfo.pTriangles[i].indexToNormals[2]];
+      pVertices = &this->pModelInfo.pVertices[this->pModelInfo.pTriangles[i].indexToVertices[2]];
+      glNormal3f(pNorm[0], pNorm[1], pNorm[2]);
+      glVertex3f(pVertices[0], pVertices[1], pVertices[2]);
+
+    }
+  glEnd();
+}
Index: branches/heathaze/src/lib/graphics/importer/model.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/model.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/model.h	(revision 9940)
@@ -0,0 +1,93 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+
+/*!
+ * @file model.h
+ *  Definition of an abstract model.
+ *  containing all needed for other models
+ */
+
+#ifndef _MODEL_H
+#define _MODEL_H
+
+#include "base_object.h"
+#include "vector.h"
+
+
+//! holds the information about a triangle
+typedef struct
+{
+  unsigned int   indexToVertices[3];   //!< index to the vertices of the triangle
+  unsigned int   indexToNormals[3];    //!< index to the normals of the triangle
+  unsigned int   indexToTexCoor[3];    //!< index to the texture coordinates
+} sTriangleExt;
+
+
+//! Model Information definitions
+typedef struct
+{
+  unsigned int     numVertices;          //!< number of Vertices in the Model
+  unsigned int     numTriangles;         //!< number of triangles in the Model
+  unsigned int     numNormals;           //!< how many Normals in the Model
+  unsigned int     numTexCoor;           //!< how many Texture Coordinates in the Model
+
+  const float*     pVertices;            //!< array of the Vertices
+  sTriangleExt*    pTriangles;           //!< array of all triangles
+  const float*     pNormals;             //!< array of the Normals
+  const float*     pTexCoor;             //!< array of the Texture Coordinates
+
+} modelInfo;
+
+
+//! This class defines the basic components of a model
+class Model : virtual public BaseObject {
+  ObjectListDeclaration(Model);
+
+  public:
+    virtual ~Model();
+
+    virtual void draw() const;
+
+    inline const modelInfo* getModelInfo() const { return &this->pModelInfo; }
+
+    /** @returns a Pointer to the Vertex-Array, if it was deleted it returns NULL */
+    inline const float* getVertexArray() const { return this->pModelInfo.pVertices; };
+    /** @returns the VertexCount of this Model */
+    inline unsigned int getVertexCount() const { return this->pModelInfo.numVertices; };
+
+    /** @returns a Pointer to the Normals-Array, if it was deleted it returns NULL */
+    inline const float* getNormalsArray() const { return this->pModelInfo.pNormals; };
+    /** @returns the NormalsCount of this Model */
+    inline unsigned int getNormalsCount() const { return this->pModelInfo.numNormals; };
+
+    /** @returns a Pointer to the TexCoord-Array, if it was deleted it returns NULL */
+    inline const float* getTexCoordArray() const { return this->pModelInfo.pTexCoor; };
+    /** @returns the TexCoord-Count of this Model */
+    inline unsigned int getTexCoordCount() const { return this->pModelInfo.numTexCoor; };
+
+    /** @returns the Array of triangles */
+    inline sTriangleExt* getTriangles() const { return this->pModelInfo.pTriangles; };
+    /** @returns the Count of Faces of this Model */
+    inline unsigned int getTriangleCount() const { return this->pModelInfo.numTriangles; };
+
+  protected:
+    Model();
+
+
+  protected:
+    modelInfo      pModelInfo;      //!< Reference to the modelInfo
+};
+
+#endif /* _MODEL_H */
Index: branches/heathaze/src/lib/graphics/importer/movie_player.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/movie_player.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/movie_player.cc	(revision 9940)
@@ -0,0 +1,439 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: David Hasenfratz
+   co-programmer:
+*/
+
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_MEDIA module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_MEDIA
+
+
+// include your own header
+#include "movie_player.h"
+#include "util/loading/resource_manager.h"
+
+// header for debug output
+#include "debug.h"
+
+ObjectListDefinition(MoviePlayer);
+
+MoviePlayer::MoviePlayer(const std::string& filename)
+{
+  // set the class id for the base object
+  this->registerObject(this, MoviePlayer::_objectList);
+  status = STOP;
+  timer = 0;
+  frame_number = 0;
+
+  mediaLoaded = false;
+
+  if (!filename.empty())
+    this->loadMovie(filename);
+}
+
+
+MoviePlayer::~MoviePlayer()
+{
+  this->unloadMedia();
+}
+
+void MoviePlayer::unloadMedia()
+{
+  // check whether a movie is already loaded
+  if(!mediaLoaded)
+    return;
+
+  if (glIsTexture(texture))
+    glDeleteTextures(1, &texture);
+
+  // Free the RGB image
+  delete [] buffer;
+  av_free(RGB_frame);
+
+  // Free the frame
+  av_free(frame);
+
+  // Close the codec
+  avcodec_close(codec_context);
+
+  // Close the video file
+  av_close_input_file(format_context);
+
+  status = STOP;
+  timer = 0;
+  frame_number = 0;
+
+  mediaLoaded = false;
+
+}
+
+
+bool MoviePlayer::loadMovie(const std::string& filename)
+{
+  this->unloadMedia();
+
+  if(filename.empty())
+    return false;
+  // check whether file exists
+  if(!Resources::ResourceManager::getInstance()->checkFileInMainPath(filename))
+  {
+    PRINTF(1)("Could not find %s\n", filename.c_str());
+    return false;
+  }
+
+  // register all formats and codecs
+  av_register_all();
+
+  // Open video file
+  if (av_open_input_file(&format_context, Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(filename).c_str(), NULL, 0, NULL) !=0 )
+  {
+    PRINTF(1)("Could not open %s\n", Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(filename).c_str());
+    return false;
+  }
+
+  // Retrieve stream information
+  if (av_find_stream_info(format_context) < 0)
+  {
+    PRINTF(1)("Could not find stream information in %s\n", Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(filename).c_str());
+    return false;
+  }
+
+  // Find the first video stream and take it
+  video_stream = av_find_default_stream_index(format_context);
+
+  if(video_stream == -1)
+  {
+    PRINTF(1)("Could not find a video stream in %s\n", Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(filename).c_str());
+    return false;
+  }
+
+  // Get a pointer to the codec context for the video stream
+  codec_context = format_context->streams[video_stream]->codec;
+
+  // Find the decoder for the video stream
+  codec = avcodec_find_decoder(codec_context->codec_id);
+  if (codec == NULL)
+  {
+    PRINTF(1)("Could not find codec\n");
+    return false;
+  }
+
+  // Open codec
+  if (avcodec_open(codec_context, codec) < 0)
+  {
+    PRINTF(1)("Could not open codec\n");
+    return false;
+  }
+
+  // Allocate video frame
+  frame = avcodec_alloc_frame();
+  RGB_frame = avcodec_alloc_frame();
+
+  // Determine required buffer size and allocate buffer
+  num_bytes = avpicture_get_size(PIX_FMT_RGB24, codec_context->width, codec_context->height);
+  buffer=new uint8_t[num_bytes];
+
+  // Assign appropriate parts of buffer to image planes in RGB_frame
+  avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);
+
+  // data buffer for the texture
+  data = new uint8_t[codec_context->width*codec_context->height*3*sizeof(uint8_t)];
+
+  // Calculate fps
+  fps = av_q2d(format_context->streams[video_stream]->r_frame_rate);
+  // NOTE: fix this fps problem!!
+  if(fps < 0 || fps > 1000)
+    fps = 30;
+
+  // duration
+  duration = format_context->duration / 1000000LL;
+
+  // create texture
+  glGenTextures(1, &texture);
+  glBindTexture(GL_TEXTURE_2D, texture);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  glTexImage2D(GL_TEXTURE_2D,
+              0,
+              GL_RGB,
+              0, 0,
+              0,
+              GL_RGB,
+              GL_UNSIGNED_BYTE,
+              NULL);
+  glBindTexture(GL_TEXTURE_2D, 0);
+
+  mediaLoaded = true;
+  return true;
+}
+
+void MoviePlayer::getNextFrame()
+{
+  // get next frame
+  if(av_read_frame(format_context, &packet) >= 0)
+  {
+    // Is this a packet from the video stream?
+    if(packet.stream_index == video_stream)
+    {
+      int frame_finished;
+      // Decode video frame
+      avcodec_decode_video(codec_context, frame, &frame_finished,
+                           packet.data, packet.size);
+
+      // Free the packet that was allocated by av_read_frame
+      av_free_packet(&packet);
+
+      // Did we get a video frame?
+      if(frame_finished)
+      {
+        frame_number++;
+        //PRINTF(0)("frame_number: %i\n", frame_number);
+        // Conversion from YUV to RGB
+        // Most codecs return images in YUV 420 format
+        // (one luminance and two chrominance channels, with the chrominance
+        // channels samples at half the spatial resolution of the luminance channel)
+        img_convert((AVPicture*)RGB_frame, PIX_FMT_RGB24, (AVPicture*)frame,
+                    codec_context->pix_fmt, codec_context->width, codec_context->height);
+
+        for(int i = 0; i < codec_context->height; i++)
+          memcpy(&data[i*codec_context->width*3], ((AVPicture*)RGB_frame)->data[0]+i *
+                 ((AVPicture*)RGB_frame)->linesize[0],
+                 codec_context->width*sizeof(uint8_t)*3);
+
+        glBindTexture(GL_TEXTURE_2D, texture);
+        // update the texture
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+                          codec_context->width, codec_context->height,
+                          GL_RGB, GL_UNSIGNED_BYTE,
+                          data);
+        // build the MipMaps
+        gluBuild2DMipmaps(GL_TEXTURE_2D,
+                        GL_RGB,
+                        codec_context->width,
+                        codec_context->height,
+                        GL_RGB,
+                        GL_UNSIGNED_BYTE,
+                        data);
+        glBindTexture(GL_TEXTURE_2D, 0);
+
+      }
+      else
+      {
+        av_free_packet(&packet);
+        this->getNextFrame();
+      }
+    }
+    else
+    {
+      av_free_packet(&packet);
+      this->getNextFrame();
+    }
+  }
+  else
+    this->stop();
+}
+
+void MoviePlayer::skipFrame(int frames)
+{
+
+  while(frames != 0)
+  {
+    if(av_read_frame(format_context, &packet) < 0)
+      break;
+    if(packet.stream_index == video_stream)
+    {
+      int frame_finished;
+      // We have to decode the frame to not get ugly fragments
+      avcodec_decode_video(codec_context, frame, &frame_finished,
+                            packet.data, packet.size);
+
+      // Did we get a video frame?
+      if(frame_finished)
+      {
+        frames--;
+        frame_number++;
+      }
+    }
+    av_free_packet(&packet);
+  }
+
+  this->getNextFrame();
+
+}
+
+bool MoviePlayer::gotoFrame(int frames)
+{
+  if(!mediaLoaded)
+  {
+    PRINTF(0)("Load first the media file with loadMovie\n");
+    return false;
+  }
+
+  int err;
+  // seek doesnt work for the first two frames
+  // you will get ugly fragments
+  if(frames < 2)
+  {
+    // go to the begin of the video
+    err = av_seek_frame(format_context, video_stream, 0, AVSEEK_FLAG_BACKWARD);
+    if(err < 0)
+    {
+      PRINTF(1)("Could not seek to frame 0\n");
+      return false;
+    }
+
+    this->frame_number = 0;
+  }
+  else
+  {
+    // seeks to the nearest keyframe
+    // NOTE: there is only about every 5s a keyframe!
+    err = av_seek_frame(format_context, video_stream, frames, AVSEEK_FLAG_BACKWARD);
+    if(err < 0)
+    {
+      PRINTF(1)("Could not seek to frame %i\n", frames);
+      return false;
+    }
+
+    // go from the keyframe to the exact position
+    codec_context->hurry_up = 1;
+    do {
+      if(av_read_frame(format_context, &packet) < 0)
+      {
+        PRINTF(1)("Could not seek to frame %i\n", frames);
+        return false;
+      }
+
+      if(packet.stream_index == video_stream)
+      {
+        if(packet.pts >= frames-1)
+          break;
+        int frame_finished;
+        avcodec_decode_video(codec_context, frame, &frame_finished, packet.data, packet.size);
+        av_free_packet(&packet);
+      }
+    } while(1);
+    codec_context->hurry_up = 0;
+
+    this->frame_number = frames;
+  }
+
+  return true;
+}
+
+void MoviePlayer::start(float start_time)
+{
+  //start_frame = start_time * fps;
+  start_frame = 0;
+
+  if(this->gotoFrame(start_frame))
+  {
+    status = PLAY;
+    timer = 0;
+  }
+}
+
+void MoviePlayer::resume()
+{
+  if(status == PAUSE)
+    status = PLAY;
+}
+
+void MoviePlayer::pause()
+{
+  if(status == PLAY)
+    status = PAUSE;
+}
+
+void MoviePlayer::stop()
+{
+  status = STOP;
+}
+
+void MoviePlayer::tick(float dt)
+{
+  if(status == PLAY)
+  {
+    timer += dt;
+    actual_frame = (int)(timer * fps + start_frame);
+    if(actual_frame != frame_number)
+    {
+      if(actual_frame - frame_number == 1)
+        this->getNextFrame();
+      else
+        this->skipFrame(actual_frame - frame_number - 1);
+    }
+  }
+}
+
+GLuint MoviePlayer::getTexture()
+{
+  return this->texture;
+}
+
+void MoviePlayer::setFPS(float fps)
+{
+  if(fps > 0)
+    this->fps = fps;
+}
+
+float MoviePlayer::getFPS()
+{
+  return this->fps;
+}
+
+const MP_STATUS MoviePlayer::getStatus()
+{
+  return this->status;
+}
+
+void MoviePlayer::printInformation()
+{
+  if(!mediaLoaded)
+  {
+    PRINTF(0)("Load first the media file with loadMovie\n");
+    return;
+  }
+
+  PRINTF(0)("========================\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("=    MEDIACONTAINER    =\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("=    AVFormatContext   =\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("filename: %s\n", format_context->filename);
+  PRINTF(0)("nb_streams: %i\n", format_context->nb_streams);
+  PRINTF(0)("duration: (%02d:%02d:%02d)\n", duration/3600, (duration%3600)/60, duration%60);
+  PRINTF(0)("file_size: %ikb\n", format_context->file_size/1024);
+  PRINTF(0)("bit_rate: %ikb/s\n", format_context->bit_rate/1000);
+  PRINTF(0)("nb_frames: %i\n", format_context->streams[video_stream]->nb_frames);
+  PRINTF(0)("r_frame_rate: %i\n", format_context->streams[video_stream]->r_frame_rate.num);
+  PRINTF(0)("fps: %0.2f\n", fps);
+  PRINTF(0)("========================\n");
+  PRINTF(0)("=    AVCodecContext    =\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("width: %i\n", codec_context->width);
+  PRINTF(0)("height: %i\n", codec_context->height);
+  PRINTF(0)("time_base.den: %i\n", codec_context->time_base.den);
+  PRINTF(0)("time_base.num: %i\n", codec_context->time_base.num);
+  PRINTF(0)("========================\n");
+  PRINTF(0)("=       AVCodec        =\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("codec name: %s\n", codec->name);
+  PRINTF(0)("========================\n");
+  PRINTF(0)("========================\n");
+}
Index: branches/heathaze/src/lib/graphics/importer/movie_player.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/movie_player.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/movie_player.h	(revision 9940)
@@ -0,0 +1,89 @@
+/*!
+ * @file movie_player.h
+  *  Manages the media files
+
+*/
+
+#ifndef _MOVIE_PLAYER
+#define _MOVIE_PLAYER
+
+#include "sdlincl.h"
+
+#ifdef HAVE_AVFORMAT_H
+  #include <avformat.h>
+#else
+  #include <ffmpeg/avformat.h>
+#endif
+
+#include "glincl.h"
+#include "texture.h"
+
+// include base_object.h since all classes are derived from this one
+#include "base_object.h"
+
+// The state of the MoviePlayer
+typedef enum MP_STATUS {
+  PLAY,
+  PAUSE,
+  STOP
+};
+
+class MoviePlayer : public BaseObject
+{
+  ObjectListDeclaration(MoviePlayer);
+
+private:
+
+  AVFormatContext* format_context;
+  AVCodecContext* codec_context;
+  AVCodec* codec;
+  AVFrame* frame;
+  AVPacket packet;
+  AVFrame* RGB_frame;
+
+  GLuint texture;
+  uint8_t* data;
+  uint8_t* buffer;
+  int num_bytes;
+  int video_stream;
+
+  MP_STATUS status;
+  float timer;
+  int start_frame;
+  int actual_frame;
+  int frame_number;
+  float fps;
+  int duration;
+  bool mediaLoaded;
+
+public:
+
+  MoviePlayer(const std::string& filename = "");
+  virtual ~MoviePlayer();
+
+  bool loadMovie(const std::string& filename);
+
+  void start(float start_time);
+  void resume();
+  void pause();
+  void stop();
+
+  void tick(float dt);
+  GLuint getTexture();
+
+  void setFPS(float fps);
+  float getFPS();
+  const MP_STATUS getStatus();
+  void printInformation();
+
+private:
+
+  void getNextFrame();
+  void skipFrame(int frames);
+  bool gotoFrame(int frames);
+
+  void unloadMedia();
+
+};
+
+#endif // _MOVIE_PLAYER
Index: branches/heathaze/src/lib/graphics/importer/objModel.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/objModel.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/objModel.cc	(revision 9940)
@@ -0,0 +1,324 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "objModel.h"
+
+#include <string.h>
+#include "loading/resource_manager.h"
+
+#define PARSELINELENGTH 8192
+
+#include "debug.h"
+#include "compiler.h"
+
+ObjectListDefinition(OBJModel);
+/**
+ * @brief Crates a 3D-Model, loads in a File and scales it.
+ * @param fileName file to parse and load (must be a .obj file)
+ * @param scaling The factor that the model will be scaled with.
+*/
+OBJModel::OBJModel(const std::string& fileName, float scaling)
+  : StaticModel(fileName)
+{
+  this->registerObject(this, OBJModel::_objectList);
+
+  this->objPath = "./";
+
+  this->setScaleFactor(scaling);
+
+  this->importFile (fileName);
+
+  this->finalize();
+}
+
+/**
+ * @brief deletes an OBJModel.
+ */
+OBJModel::~OBJModel()
+{ }
+
+/**
+ *  Imports a obj file and handles the the relative location
+ * @param fileName The file to import
+
+   Splits the FileName from the DirectoryName
+*/
+bool OBJModel::importFile (const std::string& fileNameInput)
+{
+  const char* fileName = fileNameInput.c_str();
+  PRINTF(4)("preparing to read in file: %s\n", fileName);
+  // splitting the
+  char* split = NULL;
+
+  if (!(split = strrchr(fileName, '/')))
+    split = strrchr(fileName, '\\'); // windows Case
+  if (split)
+    {
+      int len = split - fileName+1;
+      this->objPath =  fileName;
+      this->objPath.erase(len, this->objPath.size());
+      this->objPath[len] = '\0';
+      PRINTF(4)("Resolved file %s to Path %s.\n", fileName, this->objPath.c_str());
+    }
+  else
+    this->objPath = "./";
+  Resources::ResourceManager::getInstance()->addResourcePath("Texture", this->objPath);
+
+  this->readFromObjFile (fileName);
+  return true;
+}
+
+/**
+ * @brief Reads in the .obj File and sets all the Values.
+ * @param fileName the FileName of the Model.
+ *
+ * This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
+ */
+bool OBJModel::readFromObjFile(const std::string& fileName)
+{
+  FILE* stream;
+  if( (stream = fopen (fileName.c_str(), "r")) == NULL)
+    {
+      PRINTF(2)("Object File Could not be Opened %s\n", fileName.c_str());
+      return false;
+    }
+
+  char buffer[PARSELINELENGTH];
+  while(fgets(buffer, PARSELINELENGTH, stream))
+    {
+      // line termiated with \0 not \n
+      if (buffer[strlen(buffer)-1] == '\n')
+        buffer[strlen(buffer)-1] = '\0';
+
+      // case vertice
+      if (!strncmp(buffer, "v ", 2))
+        {
+          this->addVertex(buffer+2);
+        }
+
+      // case face
+      else if (!strncmp(buffer, "f ", 2))
+        {
+          this->addFace (buffer+2);
+        }
+
+      else if (!strncmp(buffer, "mtllib ", 7))
+        {
+          this->readMtlLib (buffer+7);
+        }
+
+      else if (!strncmp(buffer, "usemtl ", 7))
+        {
+          this->setMaterial (buffer+7);
+        }
+
+      // case VertexNormal
+      else if (!strncmp(buffer, "vn ", 3))
+        {
+          this->addVertexNormal(buffer+3);
+        }
+
+      // case VertexTextureCoordinate
+      else if (!strncmp(buffer, "vt ", 3))
+        {
+          this->addVertexTexture(buffer+3);
+        }
+      // case group
+      else if (!strncmp(buffer, "g ", 2))
+        {
+          this->addGroup (buffer+2);
+        }
+      else if (!strncmp(buffer, "s ", 2)) //! @todo smoothing groups have to be implemented
+        {
+          PRINTF(3)("smoothing groups not supportet yet. line: %s\n", buffer);
+        }
+    }
+  fclose (stream);
+  return true;
+}
+
+/**
+ * @brief Function to read in a mtl File.
+ * @param mtlFile The .mtl file to read
+ *
+ * This Function parses all Lines of an mtl File.
+ * The reason for it not to be in the materials-class is,
+ * that a material does not have to be able to read itself in from a File.
+ */
+bool OBJModel::readMtlLib (const std::string& mtlFile)
+{
+  std::string fileName = this->objPath + mtlFile;
+
+  FILE* stream;
+  if( (stream = fopen (fileName.c_str(), "r")) == NULL)
+    {
+      PRINTF(2)("MaterialLibrary could not be opened %s\n", fileName.c_str());
+      return false;
+    }
+
+  char buffer[PARSELINELENGTH];
+  Material* tmpMat = NULL;
+
+  while(fgets(buffer, PARSELINELENGTH, stream) != NULL)
+    {
+      PRINTF(5)("found line in mtlFile: %s\n", buffer);
+
+      // line termiated with \0 not \n
+      if (buffer[strlen(buffer)-1] == '\n')
+        buffer[strlen(buffer)-1] = '\0';
+
+      // create new Material
+      if (!strncmp(buffer, "newmtl ", 7))
+        {
+          tmpMat = this->addMaterial(buffer+7);//tmpMat->addMaterial(buffer+7);
+        }
+      // setting a illumMode
+      else if (!strncmp(buffer, "illum ", 6))
+        {
+          if (likely(tmpMat != NULL))
+            setIllum(tmpMat, buffer+6);
+
+        }
+      // setting Diffuse Color
+      else if (!strncmp(buffer, "Kd ", 3))
+        {
+          if (likely(tmpMat != NULL))
+            setDiffuse(tmpMat, buffer+3);
+        }
+      // setting Ambient Color
+      else if (!strncmp(buffer, "Ka ", 3))
+        {
+          if (likely(tmpMat != NULL))
+            setAmbient(tmpMat, buffer+3);
+        }
+      // setting Specular Color
+      else if (!strncmp(buffer, "Ks ", 3))
+        {
+          if (likely(tmpMat != NULL))
+            setSpecular(tmpMat, buffer+3);
+        }
+      // setting The Specular Shininess
+      else if (!strncmp(buffer, "Ns ", 3))
+        {
+          if (likely(tmpMat != NULL))
+            setShininess(tmpMat, buffer+3);
+        }
+      // setting up transparency
+      else if (!strncmp(buffer, "d ", 2))
+        {
+          if (likely(tmpMat != NULL))
+            setTransparency(tmpMat, buffer+2);
+        }
+      else if (!strncmp(buffer, "Tf ", 3))
+        {
+          if (likely(tmpMat != NULL))
+            setTransparency(tmpMat, buffer+3);
+        }
+
+      else if (!strncmp(buffer, "map_Kd ", 7))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setDiffuseMap(buffer+7);
+        }
+      else if (!strncmp(buffer, "map_Ka ", 7))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setAmbientMap(buffer+7);
+        }
+      else if (!strncmp(buffer, "map_Ks ", 7))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setSpecularMap(buffer+7);
+        }
+      else if (!strncmp(buffer, "bump ", 5))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setBump(buffer+7);
+        }
+
+
+    }
+  fclose(stream);
+  return true;
+}
+
+
+/**
+ * @brief Sets the Material Illumination Model.
+ * @param material: the Material to apply the change to.
+ * @param illu: illumination Model in char* form
+ */
+void OBJModel::setIllum (Material* material, const char* illum)
+{
+  material->setIllum (atoi(illum));
+}
+
+/**
+ * @brief Sets the Material Diffuse Color.
+ * @param material: the Material to apply the change to.
+ * @param rgb The red, green, blue channel in char format (with spaces between them)
+ */
+void OBJModel::setDiffuse (Material* material, const char* rgb)
+{
+  float r,g,b;
+  sscanf (rgb, "%f %f %f", &r, &g, &b);
+  material->setDiffuse (r, g, b);
+}
+
+/**
+ * @brief Sets the Material Ambient Color.
+ * @param material: the Material to apply the change to.
+ * @param rgb The red, green, blue channel in char format (with spaces between them)
+ */
+void OBJModel::setAmbient (Material* material, const char* rgb)
+{
+  float r,g,b;
+  sscanf (rgb, "%f %f %f", &r, &g, &b);
+  material->setAmbient (r, g, b);
+}
+
+/**
+ * @brief Sets the Material Specular Color.
+ * @param material: the Material to apply the change to.
+ * @param rgb The red, green, blue channel in char format (with spaces between them)
+ */
+void OBJModel::setSpecular (Material* material, const char* rgb)
+{
+  float r,g,b;
+  sscanf (rgb, "%f %f %f", &r, &g, &b);
+  material->setSpecular (r, g, b);
+}
+
+/**
+ * @brief Sets the Material Shininess.
+ * @param material: the Material to apply the change to.
+ * @param shini stes the Shininess from char*.
+ */
+void OBJModel::setShininess (Material* material, const char* shini)
+{
+  material->setShininess (atof(shini));
+}
+
+/**
+ * @brief Sets the Material Transparency.
+ * @param material: the Material to apply the change to.
+ * @param trans stes the Transparency from char*.
+ */
+void OBJModel::setTransparency (Material* material, const char* trans)
+{
+  material->setTransparency (atof(trans));
+}
Index: branches/heathaze/src/lib/graphics/importer/objModel.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/objModel.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/objModel.h	(revision 9940)
@@ -0,0 +1,37 @@
+/*!
+  \file objModel.h
+  \brief Contains the OBJ-model Class, that reads in a Model from a .obj-file
+*/
+
+#ifndef _OBJMODEL_H
+#define _OBJMODEL_H
+
+#include "static_model.h"
+
+//! A Class, that handles the parsing of an obj-file, and inclusion as a Model.
+class OBJModel : public StaticModel
+{
+  ObjectListDeclaration(OBJModel);
+public:
+  OBJModel(const std::string& fileName, float scaling = 1.0);
+  virtual ~OBJModel();
+
+private:
+  ///// readin /////
+  bool importFile (const std::string& fileName);
+  bool readFromObjFile (const std::string& fileName);
+  bool readMtlLib (const std::string& matFile);
+
+private:
+  void setIllum (Material* material, const char* illum);
+  void setDiffuse (Material* material, const char* rgb);
+  void setAmbient (Material* material, const char* rgb);
+  void setSpecular (Material* material, const char* rgb);
+  void setShininess (Material* material, const char* shini);
+  void setTransparency (Material* material, const char* trans);
+
+private:
+  std::string       objPath;     //!< The Path where the obj and mtl-file are located.
+};
+
+#endif /* _OBJ_MODEL_H */
Index: branches/heathaze/src/lib/graphics/importer/primitive_model.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/primitive_model.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/primitive_model.cc	(revision 9940)
@@ -0,0 +1,246 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_MODEL
+
+#include "primitive_model.h"
+
+#include "vector.h"
+#include "debug.h"
+
+
+
+/**
+ *  Creates a 3D-Model of Primitive-Type type
+
+   if you want to just display a Cube/Sphere/Cylinder/... without any material.
+
+   @todo implement Cube/Sphere/Cylinder/...
+*/
+PrimitiveModel::PrimitiveModel(PRIMITIVE type, float size, unsigned int detail)
+{
+  switch (type)
+  {
+    default:
+    case PRIM_CUBE:
+      this->cubeModel();
+      break;
+    case PRIM_SPHERE:
+      this->sphereModel(size, detail);
+      break;
+    case PRIM_CYLINDER:
+      this->cylinderModel();
+      break;
+    case PRIM_CONE:
+      this->coneModel(size, detail);
+      break;
+    case PRIM_PLANE:
+      this->planeModel(size, detail);
+      break;
+  }
+  this->finalize();
+}
+
+/**
+ *  standard deconstructor
+
+*/
+PrimitiveModel::~PrimitiveModel ()
+{
+  // delete what has to be deleted here
+}
+
+/**
+ *  Builds a Sphere into the Model.
+ * @param size The diameter of the Sphere.
+ * @param detail The detail of the Sphere.
+*/
+void PrimitiveModel::sphereModel(float size, unsigned int detail)
+{
+  if (detail <= 0)
+    detail = 1;
+  size /= 2.0;
+  //  detail = 2; // make it even
+  float df = (float)detail;
+
+  // defining the Vertices
+  for (float i = 0; i < df *2.0; i+=1.0)
+  {
+    float vi = i/df * PI;
+    for (float j = -df / 2.0 +1.0; j <= df / 2.0; j+=1.0 *df/(df+1.0))
+    {
+      float vj = j/df *PI;
+      this->addVertexNormal(cos(vi) * cos(vj),
+                            sin(vj),
+                            sin(vi) * cos(vj));
+
+      this->addVertex(size * cos(vi) * cos(vj),
+                      size * sin(vj),
+                      size * sin(vi) * cos(vj));
+
+      this->addVertexTexture( i / (df *2.0),
+                              (j-1.0)/(df)+.5);
+    }
+  }
+  this->addVertex(0, -size, 0);
+  this->addVertexNormal(0, -1, 0);
+  this->addVertexTexture(0,0);
+  this->addVertex(0, size, 0);
+  this->addVertexNormal(0, 1, 0);
+  this->addVertexTexture(0 ,1);
+
+  // defining the binding Faces.
+  int v1, v2, v3, v4;
+  for (unsigned int i = 0; i <= detail * 2 -1; i++)
+  {
+    for (unsigned int j = 0; j <= detail; j++)
+    {
+
+      v1 = i*detail + j-1;
+      v4 = i*detail + j;
+
+      if (i == detail*2 -1)
+      {
+        v2 = j-1;
+        v3 = j;
+      }
+      else
+      {
+        v2 = (i+1)*detail + j-1;
+        v3 = (i+1)*detail + j;
+      }
+
+      if (j == 0)
+      {
+        v1 = this->getVertexCount() - 2;
+        this->addFace(3, VERTEX_TEXCOORD_NORMAL, v1, v1, v1, v3, v3, v3, v4, v4, v4);
+      }
+      else if (j == detail)
+      {
+        v3 = this->getVertexCount()-1;
+        this->addFace(3, VERTEX_TEXCOORD_NORMAL, v1, v1, v1, v2, v2, v2, v3, v3, v3);
+      }
+      else
+        this->addFace(4, VERTEX_TEXCOORD_NORMAL, v1, v1, v1, v2, v2, v2, v3, v3, v3, v4, v4, v4);
+    }
+  }
+}
+/**
+ *  Creates a Cylinder.
+*/
+void PrimitiveModel::cylinderModel(float size, unsigned int detail)
+{
+  // check if devision by zero
+  if (detail <= 3)
+    detail = 3;
+  unsigned int count = 0;
+  // defining Points of the Cylinder.
+  for (float phi = 0.0; phi < 2.0*PI; phi += 2.0*PI/(float)detail)
+  {
+    this->addVertex(size*cos(phi), size*sin(phi), -size);
+    this->addVertex(size*cos(phi), size*sin(phi), size);
+    count ++;
+  }
+  this->addVertex(0, 0, -size);
+  this->addVertex(0, 0, size);
+
+  if (count != detail)
+  {
+    PRINTF(1)("calculation error, count should be %d but is %d.\n", detail, count);
+  }
+  // adding Faces
+  for (unsigned int i = 0; i < detail-1; i++)
+  {
+    int p1, p2, p3, p4;
+    p1 = 2*i;
+    p2 = 2*i+1;
+    p3 = 2*i+3;
+    p4 = 2*i+2;
+    // something is wrong here
+    this->addFace(4, VERTEX_ONLY, p1, p2, p3, p4);
+    this->addFace(3, VERTEX_ONLY, p4, p1, 2*detail);
+    this->addFace(3, VERTEX_ONLY, p2, p3, 2*detail+1);
+  }
+  // caps
+  this->addFace(4, VERTEX_ONLY, 2*detail-2, 2*detail-1, 1, 0);
+  this->addFace(3, VERTEX_ONLY, 0, 2*detail-2, 2*detail);
+  this->addFace(3, VERTEX_ONLY, 2*detail-1, 1, 2*detail+1);
+}
+
+/**
+ *  creates a cone inside of this Model
+ * @param size The size of the cone
+ * @param detail the Detail-level of this cone
+*/
+void PrimitiveModel::coneModel(float size, unsigned int detail)
+{
+  this->addVertex(0,-size,0);
+  this->addVertex(0,size,0);
+  if (detail <= 0)
+    detail = 1;
+  float df = (float)detail;
+
+  // defining the Vertices
+  for (float i = 0; i < df; i+=1.0)
+  {
+    float vi = i/df *2.0*PI;
+    this->addVertex(size* sin(vi),
+                    -size,
+                    size* cos(vi));
+  }
+
+  //defining Faces
+  for (unsigned int i = 0; i < detail; i++)
+  {
+    unsigned int v1, v2;
+    v1 = i+2;
+    if (i+1 == detail)
+      v2 = 2;
+    else
+      v2 = i+3;
+    this->addFace(3, VERTEX_ONLY, 0, v1, v2);
+    this->addFace(3, VERTEX_ONLY, 1, v1, v2);
+  }
+}
+
+/**
+ *  creates a Plane inside of this Model
+ * @param size The size of this plane
+ * @param detail the Detail-level of this plane.
+*/
+void PrimitiveModel::planeModel(float size, unsigned int detail)
+{
+  //defining vertices
+  for (unsigned int i = 0; i < detail; i++)
+    for (unsigned int j = 0; j < detail; j++)
+    {
+      this->addVertex(((float)i/(float)(detail-1) -.5)*size,
+                      0,
+                      ((float)j/(float)(detail-1) -.5)*size);
+      this->addVertexTexture((float)i/(float)(detail-1),
+                             (float)j/(float)(detail-1));
+    }
+  //defining Faces
+  int v1, v2, v3, v4;
+  for (unsigned int i = 0; i < detail-1; i++)
+    for (unsigned int j = 0; j < detail-1; j++)
+    {
+      v1 = i*detail + j;
+      v2 = (i+1)*detail + j;
+      v3 = (i+1)*detail + (j+1);
+      v4 = i*detail + (j+1);
+      this->addFace(4, VERTEX_TEXCOORD, v1, v1, v2, v2, v3, v3, v4, v4);
+    }
+}
Index: branches/heathaze/src/lib/graphics/importer/primitive_model.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/primitive_model.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/primitive_model.h	(revision 9940)
@@ -0,0 +1,33 @@
+/*! 
+ * @file primitive_model.h 
+  *  a Class to handle different simple models like planes cubes spheres and so on.
+    (cube is also an option of Model, but is extended here.
+*/
+
+#ifndef _PRIMITIVE_MODEL_H
+#define _PRIMITIVE_MODEL_H
+
+#include "static_model.h"
+
+//! Specification of different primitives the Model knows
+enum PRIMITIVE { PRIM_CUBE,
+		 PRIM_SPHERE,
+		 PRIM_PLANE,
+		 PRIM_CYLINDER,
+		 PRIM_CONE };
+
+//! A Class to create some default Models
+class PrimitiveModel : public StaticModel {
+
+ public:
+  PrimitiveModel(PRIMITIVE type, float size = 1.0, unsigned int detail = 10);
+  virtual ~PrimitiveModel();
+
+ protected:
+  void sphereModel(float size = 1.0, unsigned int detail = 10);
+  void cylinderModel(float size = 1.0, unsigned int detail = 10);
+  void coneModel(float size = 1.0, unsigned int detail = 10);
+  void planeModel(float size = 1.0, unsigned int detail = 1);
+};
+
+#endif /* _PRIMITIVE_MODEL_H */
Index: branches/heathaze/src/lib/graphics/importer/resource_obj.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/resource_obj.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/resource_obj.cc	(revision 9940)
@@ -0,0 +1,52 @@
+
+#include "resource_obj.h"
+#include "substring.h"
+#include "multi_type.h"
+#include "debug.h"
+
+
+ResourceOBJ::ResourceOBJ(const std::string& imageName, float scaling, const Resources::KeepLevel& keepLevel)
+    : Resource(&ResourceOBJ::type)
+{
+  Resources::StorePointer* ptr = this->acquireResource(imageName + ',' + MultiType(scaling).getString());
+
+  if (ptr)
+  {
+    PRINTF(5)("FOUND OBJ: %s\n", imageName.c_str());
+    this->acquireData(static_cast<ResourceOBJ::OBJResourcePointer*>(ptr)->ptr());
+  }
+  else
+  {
+    PRINTF(5)("NOT FOUND OBJ: %s\n", imageName.c_str());
+    std::string fileName = this->Resource::locateFile(imageName);
+    this->acquireData(OBJModel(fileName, scaling).dataPointer());
+    this->Resource::addResource(new ResourceOBJ::OBJResourcePointer(imageName + ',' + MultiType(scaling).getString(), keepLevel, this->StaticModel::dataPointer()));
+  }
+}
+
+ResourceOBJ ResourceOBJ::createFromString(const std::string& loadString, const Resources::KeepLevel& keepLevel)
+{
+  SubString loadValues(loadString, ',');
+  std::string imageName;
+  float scaling = 1.0f;
+  if (loadValues.size() > 0)
+    imageName = loadValues[0];
+  if (loadValues.size() > 1)
+    scaling = (GLenum)MultiType(loadValues[2]).getFloat();
+
+  return ResourceOBJ(imageName, scaling, keepLevel);
+}
+
+
+
+Resources::tType<ResourceOBJ> ResourceOBJ::type("OBJ");
+
+
+
+
+
+ResourceOBJ::OBJResourcePointer::OBJResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const StaticModelData::Pointer& data)
+    : Resources::StorePointer(loadString, keepLevel) , pointer(data)
+{}
+
+
Index: branches/heathaze/src/lib/graphics/importer/resource_obj.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/resource_obj.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/resource_obj.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file resource_obj.h
+ * @brief Contains the ResourceOBJ class, that handles the Resource-specific loading part of the OBJ.
+ *
+ */
+
+#ifndef _RESOURCE_OBJ_H
+#define _RESOURCE_OBJ_H
+
+#include "util/loading/resource.h"
+#include "objModel.h"
+
+class ResourceOBJ : public StaticModel, public Resources::Resource
+{
+public:
+  ResourceOBJ(const std::string& imageName,
+	      float scaling = 1.0f,
+	      const Resources::KeepLevel& keepLevel = Resources::KeepLevel());
+  static ResourceOBJ createFromString(const std::string& loadString,
+				      const Resources::KeepLevel& keepLevel = Resources::KeepLevel());
+
+private:
+class OBJResourcePointer : public Resources::StorePointer
+  {
+  public:
+    OBJResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const StaticModelData::Pointer& data);
+    inline const StaticModelData::Pointer& ptr() const { return pointer; }
+    virtual bool last() const { return pointer.count() == 1; }
+private:
+    StaticModelData::Pointer pointer;
+  };
+
+private:
+  static Resources::tType<ResourceOBJ> type;
+};
+
+
+#endif /* _RESOURCE_OBJ_H */
Index: branches/heathaze/src/lib/graphics/importer/resource_texture.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/resource_texture.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/resource_texture.cc	(revision 9940)
@@ -0,0 +1,52 @@
+
+#include "resource_texture.h"
+#include "substring.h"
+#include "multi_type.h"
+#include "debug.h"
+
+
+ResourceTexture::ResourceTexture(const std::string& imageName, GLenum target, const Resources::KeepLevel& keepLevel)
+    : Resource(&ResourceTexture::type)
+{
+  Resources::StorePointer* ptr = this->acquireResource(imageName + ',' + MultiType((int)target).getString());
+
+  if (ptr)
+  {
+    PRINTF(5)("FOUND TEXTURE: %s\n", imageName.c_str());
+    this->acquireData(static_cast<ResourceTexture::TextureResourcePointer*>(ptr)->ptr());
+  }
+  else
+  {
+    PRINTF(5)("NOT FOUND TEXTURE: %s\n", imageName.c_str());
+    std::string fileName = this->Resource::locateFile(imageName);
+    this->Texture::loadImage(fileName, target);
+    this->Resource::addResource(new ResourceTexture::TextureResourcePointer(imageName + ',' + MultiType((int)target).getString(), keepLevel, this->Texture::dataPointer()));
+  }
+}
+
+ResourceTexture ResourceTexture::createFromString(const std::string& loadString, const Resources::KeepLevel& keepLevel)
+{
+  SubString loadValues(loadString, ',');
+  std::string imageName;
+  GLenum target = GL_TEXTURE_2D;
+  if (loadValues.size() > 0)
+    imageName = loadValues[0];
+  if (loadValues.size() > 1)
+    target = (GLenum)MultiType(loadValues[2]).getInt();
+
+  return ResourceTexture(imageName, target, keepLevel);
+}
+
+
+
+Resources::tType<ResourceTexture> ResourceTexture::type("Texture");
+
+
+
+
+
+ResourceTexture::TextureResourcePointer::TextureResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const TextureData::Pointer& data)
+    : Resources::StorePointer(loadString, keepLevel) , pointer(data)
+{}
+
+
Index: branches/heathaze/src/lib/graphics/importer/resource_texture.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/resource_texture.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/resource_texture.h	(revision 9940)
@@ -0,0 +1,39 @@
+/*!
+ * @file resource_texture.h
+ * @brief Contains the ResourceTexture class, that handles the Resource-specific loading part of the Texture.
+ *
+ */
+
+#ifndef _RESOURCE_TEXTURE_H
+#define _RESOURCE_TEXTURE_H
+
+#include "util/loading/resource.h"
+#include "texture.h"
+
+
+class ResourceTexture : public Texture, public Resources::Resource
+{
+public:
+  ResourceTexture(const std::string& imageName,
+                  GLenum target = GL_TEXTURE_2D,
+		  const Resources::KeepLevel& keepLevel = Resources::KeepLevel());
+  static ResourceTexture createFromString(const std::string& loadString,
+					  const Resources::KeepLevel& keepLevel = Resources::KeepLevel());
+
+private:
+class TextureResourcePointer : public Resources::StorePointer
+  {
+  public:
+    TextureResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const TextureData::Pointer& data);
+    inline const TextureData::Pointer& ptr() const { return pointer; }
+    virtual bool last() const { return pointer.count() == 1; }
+  private:
+    TextureData::Pointer pointer;
+  };
+
+private:
+  static Resources::tType<ResourceTexture> type;
+};
+
+
+#endif /* _RESOURCE_TEXTURE_H */
Index: branches/heathaze/src/lib/graphics/importer/static_model.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/static_model.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/static_model.cc	(revision 9940)
@@ -0,0 +1,185 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   2005-07-06: (Patrick) added new function buildTriangleList()
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "static_model.h"
+
+#include "debug.h"
+#include <stdarg.h>
+
+
+
+
+/////////////
+/// MODEL ///
+/////////////
+ObjectListDefinition(StaticModel);
+
+/**
+ * @brief Creates a 3D-Model.
+ *
+ * assigns it a Name and a Type
+ */
+StaticModel::StaticModel(const std::string& modelName)
+    : data(new StaticModelData(modelName))
+{
+  this->registerObject(this, StaticModel::_objectList);
+  PRINTF(4)("new 3D-Model is being created\n");
+  this->setName(modelName);
+}
+
+StaticModel::StaticModel(const StaticModel& staticModel)
+  : data(staticModel.data)
+{
+  this->registerObject(this, StaticModel::_objectList);
+  this->setName(staticModel.getName());
+  this->updateBase();
+}
+
+
+/**
+ * @brief deletes an Model.
+ *
+ * Looks if any from model allocated space is still in use, and if so deleted it.
+ */
+StaticModel::~StaticModel()
+{
+  PRINTF(4)("Deleting Model ");
+
+  // mark this stuff as beeing deleted
+  this->pModelInfo.pVertices = NULL;
+  this->pModelInfo.pNormals = NULL;
+  this->pModelInfo.pTexCoor = NULL;
+  this->pModelInfo.pTriangles = NULL;
+}
+
+StaticModel& StaticModel::operator=(const StaticModel& model)
+{
+  this->data = model.data;
+  this->updateBase();
+  return *this;
+};
+
+
+/**
+ * @brief Finalizes an Object. This can be done outside of the Class.
+ */
+void StaticModel::finalize()
+{
+  data->finalize();
+  this->updateBase();
+}
+
+void StaticModel::acquireData(const StaticModelData::Pointer& data)
+{
+  this->data = data;
+  this->updateBase();
+}
+
+/**
+ * @brief adds a new Face
+ * @param faceElemCount the number of Vertices to add to the Face.
+ * @param type The information Passed with each Vertex
+*/
+bool StaticModel::addFace(int faceElemCount, VERTEX_FORMAT type, ...)
+{
+  va_list itemlist;
+  va_start (itemlist, type);
+  bool retVal = this->data->addFace(faceElemCount, type, itemlist);
+  va_end(itemlist);
+  return retVal;
+}
+
+void StaticModel::updateBase()
+{
+  // write out the modelInfo data used for the collision detection!
+  this->pModelInfo.pVertices = &this->data->getVertices()[0];
+  this->pModelInfo.numVertices = this->data->getVertices().size();
+  this->pModelInfo.pNormals = &this->data->getNormals()[0];
+  this->pModelInfo.numNormals = this->data->getNormals().size();
+  this->pModelInfo.pTexCoor = &this->data->getTexCoords()[0];
+  this->pModelInfo.numTexCoor = this->data->getTexCoords().size();
+
+  this->pModelInfo.pTriangles = this->data->getTrianglesExt();
+  this->pModelInfo.numTriangles = this->data->getTriangles().size();
+}
+
+
+/**
+ *  Includes a default model
+ *
+ * This will inject a Cube, because this is the most basic model.
+ */
+void StaticModel::cubeModel()
+{
+  this->addVertex (-0.5, -0.5, 0.5);
+  this->addVertex (0.5, -0.5, 0.5);
+  this->addVertex (-0.5, 0.5, 0.5);
+  this->addVertex (0.5, 0.5, 0.5);
+  this->addVertex (-0.5, 0.5, -0.5);
+  this->addVertex (0.5, 0.5, -0.5);
+  this->addVertex (-0.5, -0.5, -0.5);
+  this->addVertex (0.5, -0.5, -0.5);
+
+  this->addVertexTexture (0.0, 0.0);
+  this->addVertexTexture (1.0, 0.0);
+  this->addVertexTexture (0.0, 1.0);
+  this->addVertexTexture (1.0, 1.0);
+  this->addVertexTexture (0.0, 2.0);
+  this->addVertexTexture (1.0, 2.0);
+  this->addVertexTexture (0.0, 3.0);
+  this->addVertexTexture (1.0, 3.0);
+  this->addVertexTexture (0.0, 4.0);
+  this->addVertexTexture (1.0, 4.0);
+  this->addVertexTexture (2.0, 0.0);
+  this->addVertexTexture (2.0, 1.0);
+  this->addVertexTexture (-1.0, 0.0);
+  this->addVertexTexture (-1.0, 1.0);
+
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 0,0,0, 1,1,1, 3,3,2, 2,2,3);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,4, 3,3,5, 5,5,6, 4,4,7);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 4,4,8, 5,5,9, 7,7,10, 6,6,11);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,6,12, 7,7,13, 1,9,14, 0,8,15);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,16, 7,10,17, 5,11,18, 3,3,19);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,12,20, 0,0,21, 2,2,22, 4,13,23);
+}
Index: branches/heathaze/src/lib/graphics/importer/static_model.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/static_model.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/static_model.h	(revision 9940)
@@ -0,0 +1,76 @@
+/*!
+ * @file static_model.h
+ * @brief Contains the Model Class that handles Static 3D-Models rendered with glList's
+ */
+
+#ifndef _STATIC_MODEL_H
+#define _STATIC_MODEL_H
+
+#include "model.h"
+
+#include "material.h"
+#include <vector>
+#include "static_model_data.h"
+
+/////////////
+/// MODEL ///
+/////////////
+//! Class that handles static 3D-Models.
+/**
+ * it can also read them in and display them.
+ * All the objects are rendered with glLists
+ */
+class StaticModel : public Model
+{
+  ObjectListDeclaration(StaticModel);
+public:
+  StaticModel(const std::string& modelName = "");
+  StaticModel(const StaticModel& staticModel);
+  virtual ~StaticModel();
+
+  StaticModel& operator=(const StaticModel& model);
+
+  virtual void draw() const { data->draw(); };
+  void draw(int groupNumber) const { data->draw(groupNumber); };
+  void draw(const std::string& groupName) const { data->draw(groupName); };
+
+  void rebuild() { data->rebuild(); };
+
+  Material* addMaterial(Material* material) { return data->addMaterial(material); };
+  Material* addMaterial(const std::string& materialName) { return data->addMaterial(materialName); };
+
+  bool addGroup(const std::string& groupString) { return data->addGroup(groupString); };
+
+  bool addVertex(const std::string& vertexString) { return data->addVertex(vertexString); };
+  bool addVertex(float x, float y, float z) { return data->addVertex(x, y, z); };
+
+  bool addFace(const std::string& faceString) { return data->addFace(faceString); };
+  bool addFace(int faceElemCount, VERTEX_FORMAT type, ...);
+
+  bool addVertexNormal(const std::string& normalString) { return this->data->addVertexNormal(normalString); };
+  bool addVertexNormal(float x, float y, float z) { return this->data->addVertexNormal(x,y,z); };
+
+  bool addVertexTexture(const std::string& vTextureString) { return this->data->addVertexTexture(vTextureString); };
+  bool addVertexTexture(float u, float v) { return this->data->addVertexTexture(u, v); };
+
+  bool setMaterial(const std::string& mtlString) { return data->setMaterial(mtlString); };
+  bool setMaterial(Material* mtl) { return data->setMaterial(mtl);};
+
+  void finalize();
+
+  void acquireData(const StaticModelData::Pointer& data);
+  const StaticModelData::Pointer& dataPointer() const { return this->data; };
+
+  inline void setScaleFactor(float scaleFactor) { this->data->setScaleFactor(scaleFactor); };
+  float getScaleFactor() const { return data->getScaleFactor(); }
+
+protected:
+  void cubeModel();
+
+private:
+  void updateBase();
+private:
+  StaticModelData::Pointer         data;
+};
+
+#endif
Index: branches/heathaze/src/lib/graphics/importer/static_model_data.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/static_model_data.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/static_model_data.cc	(revision 9940)
@@ -0,0 +1,948 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   2005-07-06: (Patrick) added new function buildTriangleList()
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "static_model_data.h"
+
+#include "debug.h"
+#include <stdarg.h>
+
+
+
+
+////////////////////
+/// SUB-Elements ///
+////////////////////
+/**
+ * @brief creates a new ModelFaceElement
+ */
+ModelFaceElement::ModelFaceElement()
+{
+  this->vertexNumber = -1;
+  this->normalNumber = -1;
+  this->texCoordNumber = -1;
+
+  this->next = NULL;
+}
+
+/**
+ * @brief destroys a ModelFaceElement
+ */
+ModelFaceElement::~ModelFaceElement()
+{
+  if (this->next)
+    delete this->next;
+}
+
+/**
+ * @brief creates a new ModelFace
+ */
+ModelFace::ModelFace()
+{
+  this->vertexCount = 0;
+
+  this->firstElem = NULL;
+
+  this->material = NULL;
+
+  this->next = NULL;
+}
+
+/**
+ *  deletes a ModelFace
+*/
+ModelFace::~ModelFace()
+{
+  PRINTF(5)("Cleaning up Face\n");
+
+  if (this->firstElem != NULL)
+    delete this->firstElem;
+
+  if (this->next != NULL)
+    delete this->next;
+}
+
+/**
+ * @brief Creates a new ModelGroup
+ */
+ModelGroup::ModelGroup()
+{
+  PRINTF(4)("Adding new Group\n");
+  this->name = "";
+  this->faceMode = -1;
+  this->faceCount = 0;
+  this->next = NULL;
+  this->listNumber = 0;
+  this->indices = NULL;
+
+  this->firstFace = new ModelFace;
+  this->currentFace = this->firstFace;
+}
+
+/**
+ * @brief deletes a ModelGroup
+ */
+ModelGroup::~ModelGroup()
+{
+  PRINTF(5)("Cleaning up group\n");
+  if (this->firstFace != NULL)
+    delete this->firstFace;
+
+  // deleting the glList
+  if (this->listNumber != 0)
+    glDeleteLists(this->listNumber, 1);
+
+  if (this->next !=NULL)
+    delete this->next;
+
+}
+
+/**
+ * @brief cleans up a ModelGroup
+ *
+ * actually does the same as the delete Operator, but does not delete the predecessing group
+ */
+void ModelGroup::cleanup()
+{
+  PRINTF(5)("Cleaning up group\n");
+  if (this->firstFace)
+    delete this->firstFace;
+  this->firstFace = NULL;
+  if (this->next)
+    this->next->cleanup();
+}
+
+
+
+
+/////////////
+/// MODEL ///
+/////////////
+ObjectListDefinition(StaticModelData);
+
+/**
+ * @brief Creates a 3D-Model.
+ *
+ * assigns it a Name and a Type
+ */
+StaticModelData::StaticModelData(const std::string& modelName)
+{
+  this->registerObject(this, StaticModelData::_objectList);
+  PRINTF(4)("new 3D-Model is being created\n");
+  this->setName(modelName);
+
+  this->finalized = false;
+
+  // setting the start group;
+  this->currentGroup = this->firstGroup = new ModelGroup;
+  this->groupCount = 0;
+  this->faceCount = 0;
+
+  this->scaleFactor = 1.0f;
+}
+
+/**
+ * @brief deletes an Model.
+ *
+ * Looks if any from model allocated space is still in use, and if so deleted it.
+ */
+StaticModelData::~StaticModelData()
+{
+  PRINTF(4)("Deleting Model ");
+  if (!this->getName().empty())
+  {
+    PRINT(4)("%s\n", this->getCName());
+  }
+  else
+  {
+    PRINT(4)("\n");
+  }
+  this->cleanup();
+
+  PRINTF(5)("Deleting display Lists.\n");
+  delete this->firstGroup;
+
+  // deleting the MaterialList
+  PRINTF(5)("Deleting Materials.\n");
+
+  //! @todo do we really have to delete this material??
+  std::list<ModelMaterial*>::iterator modMat;
+  for(modMat = this->materialList.begin(); modMat != this->materialList.end(); modMat++)
+  {
+    if (!(*modMat)->external)
+      delete (*modMat)->material;
+    delete (*modMat);
+  }
+}
+
+/**
+ * @brief Finalizes an Object. This can be done outside of the Class.
+ */
+void StaticModelData::finalize()
+{
+  // this creates the display List.
+  this->importToDisplayList();
+  this->buildTriangleList();
+
+  this->finalized = true;
+}
+
+/**
+ * @brief rebuild the Model from the Information we got.
+ */
+void StaticModelData::rebuild()
+{
+  PRINTF(3)("Rebuilding Model '%s'\n", this->getCName());
+  this->finalize();
+}
+
+//////////
+// DRAW //
+//////////
+/**
+ * @brief Draws the Models of all Groups.
+ *
+ * It does this by just calling the Lists that must have been created earlier.
+ */
+void StaticModelData::draw () const
+{
+  PRINTF(4)("drawing the 3D-Models\n");
+  ModelGroup* tmpGroup = this->firstGroup;
+  while (tmpGroup != NULL)
+  {
+    PRINTF(5)("Drawing model %s\n", tmpGroup->name.c_str());
+    glCallList (tmpGroup->listNumber);
+    tmpGroup = tmpGroup->next;
+  }
+}
+
+
+/**
+ * @brief Draws the Model number groupNumber
+ * @param groupNumber The number of the group that will be displayed.
+ *
+ * It does this by just calling the List that must have been created earlier.
+ */
+void StaticModelData::draw (int groupNumber) const
+{
+  if (unlikely(groupNumber >= this->groupCount))
+  {
+    PRINTF(2)("You requested model number %i, but this File only contains of %i Models.\n", groupNumber-1, this->groupCount);
+    return;
+  }
+  PRINTF(4)("drawing the requested 3D-Models if found.\n");
+  ModelGroup* tmpGroup = this->firstGroup;
+  int counter = 0;
+  while (tmpGroup != NULL)
+  {
+    if (counter == groupNumber)
+    {
+      PRINTF(4)("Drawing model number %i named %s\n", counter, tmpGroup->name.c_str());
+      glCallList (tmpGroup->listNumber);
+      return;
+    }
+    ++counter;
+    tmpGroup = tmpGroup->next;
+  }
+  PRINTF(2)("Model number %i in %s not Found.\n", groupNumber, this->getCName());
+  return;
+}
+
+
+/**
+ * @brief Draws the Model with a specific groupName
+ * @param groupName The name of the group that will be displayed.
+ *
+ * It does this by just calling the List that must have been created earlier.
+ */
+void StaticModelData::draw (const std::string& groupName) const
+{
+  PRINTF(4)("drawing the requested 3D-Models if found.\n");
+  ModelGroup* tmpGroup = this->firstGroup;
+  while (tmpGroup != NULL)
+  {
+    if (tmpGroup->name == groupName)
+    {
+      PRINTF(4)("Drawing model %s\n", tmpGroup->name.c_str());
+      glCallList (tmpGroup->listNumber);
+      return;
+    }
+    tmpGroup = tmpGroup->next;
+  }
+  PRINTF(2)("Model Named %s in %s not Found.\n", groupName.c_str(), this->getCName());
+  return;
+}
+
+//////////
+// INIT //
+//////////
+
+/**
+ * @brief finalizes an Model.
+ *
+ * This funcion is needed, to delete all the Lists, and arrays that are no more
+ * needed because they are already imported into openGL.
+ * This will be applied at the end of the importing Process.
+*/
+bool StaticModelData::cleanup()
+{
+  PRINTF(4)("cleaning up the 3D-Model to save Memory.\n");
+  this->firstGroup->cleanup();
+  return true;
+}
+
+//////////
+// MESH //
+//////////
+/**
+ * @brief adds a new Material to the Material List
+ * @param material the Material to add
+ * @returns the added material
+ *
+ * this also tells this Model, that all the Materials are handled externally
+ * with this option set the Materials will not be deleted with the Model.
+ */
+Material* StaticModelData::addMaterial(Material* material)
+{
+  if (material == NULL)
+    return NULL;
+  ModelMaterial* modMat = new ModelMaterial;
+  modMat->external = true;
+  modMat->material = material;
+  this->materialList.push_back(modMat);
+  return modMat->material;
+}
+
+/**
+ * @brief adds a new Material to the Material List
+ * @param materialName the name of the Material to add
+ * @returns the added material
+ */
+Material* StaticModelData::addMaterial(const std::string& materialName)
+{
+  ModelMaterial* modMat = new ModelMaterial;
+  modMat->external = false;
+  modMat->material = new Material(materialName);
+
+  // adding material to the List of materials
+  this->materialList.push_back(modMat);
+  return modMat->material;
+}
+
+/**
+ * @brief finds a Material by its name and returns it
+ * @param materialName the Name of the material to search for.
+ * @returns the Material if found, NULL otherwise
+ */
+Material* StaticModelData::findMaterialByName(const std::string& materialName)
+{
+  std::list<ModelMaterial*>::iterator modMat;
+  for  (modMat = this->materialList.begin(); modMat != this->materialList.end(); modMat++)
+    if (materialName == (*modMat)->material->getName())
+      return (*modMat)->material;
+  return NULL;
+}
+
+/**
+ * @brief parses a group String
+ * @param groupString the new Group to create
+ *
+ * This function initializes a new Group.
+ * With it you should be able to create Models with more than one SubModel inside
+ */
+bool StaticModelData::addGroup(const std::string& groupString)
+{
+  PRINTF(5)("Read Group: %s.\n", groupString.c_str());
+  if (this->groupCount != 0 && this->currentGroup->faceCount > 0)
+  {
+    // finalizeGroup(currentGroup);
+    this->currentGroup = this->currentGroup->next = new ModelGroup;
+  }
+  // setting the group name if not default.
+  if (groupString == "default")
+  {
+    this->currentGroup->name = groupString;
+  }
+  ++this->groupCount;
+  return true;
+}
+
+/**
+ * @brief parses a vertex-String
+ * @param vertexString The String that will be parsed.
+ *
+ *  If a vertex line is found this function will inject it into the vertex-Array
+ */
+bool StaticModelData::addVertex (const std::string& vertexString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (vertexString.c_str(), "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
+  this->vertices.push_back(subbuffer1*scaleFactor);
+  this->vertices.push_back(subbuffer2*scaleFactor);
+  this->vertices.push_back(subbuffer3*scaleFactor);
+  return true;
+}
+
+/**
+ * @brief parses a vertex-String
+ * @param x the X-coordinate of the Vertex to add.
+ * @param y the Y-coordinate of the Vertex to add.
+ * @param z the Z-coordinate of the Vertex to add.
+ */
+bool StaticModelData::addVertex(float x, float y, float z)
+{
+  PRINTF(5)("reading in a vertex: %f %f %f\n", x, y, z);
+  this->vertices.push_back(x*scaleFactor);
+  this->vertices.push_back(y*scaleFactor);
+  this->vertices.push_back(z*scaleFactor);
+  return true;
+}
+
+/**
+ * @brief parses a vertexNormal-String
+ * @param normalString The String that will be parsed.
+ *
+ * If a vertexNormal line is found this function will inject it into the vertexNormal-Array
+ */
+bool StaticModelData::addVertexNormal (const std::string& normalString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (normalString.c_str(), "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
+  this->normals.push_back(subbuffer1);
+  this->normals.push_back(subbuffer2);
+  this->normals.push_back(subbuffer3);
+  return true;
+}
+
+/**
+ * @brief adds a VertexNormal.
+ * @param x The x coordinate of the Normal.
+ * @param y The y coordinate of the Normal.
+ * @param z The z coordinate of the Normal.
+ *
+ * If a vertexNormal line is found this function will inject it into the vertexNormal-Array
+ */
+bool StaticModelData::addVertexNormal(float x, float y, float z)
+{
+  PRINTF(5)("found vertex-Normal %f, %f, %f\n", x, y, z);
+  this->normals.push_back(x);
+  this->normals.push_back(y);
+  this->normals.push_back(z);
+  return true;
+}
+
+/**
+ * @brief parses a vertexTextureCoordinate-String
+ * @param vTextureString The String that will be parsed.
+ *
+ * If a vertexTextureCoordinate line is found,
+ * this function will inject it into the vertexTexture-Array
+ *
+ * !! WARNING THIS IS DIFFERNT FROM addVervexTexture(float, float); because it changes the second entry to 1-v !!
+ */
+bool StaticModelData::addVertexTexture (const std::string& vTextureString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  sscanf (vTextureString.c_str(), "%f %f", &subbuffer1, &subbuffer2);
+  this->vTexture.push_back(subbuffer1);
+  this->vTexture.push_back(1 - subbuffer2);
+  return true;
+}
+
+/**
+ * @brief adds a Texture Coordinate
+ * @param u The u coordinate of the TextureCoordinate.
+ * @param v The y coordinate of the TextureCoordinate.
+ *
+ * If a TextureCoordinate line is found this function will
+ *  inject it into the TextureCoordinate-Array
+ */
+bool StaticModelData::addVertexTexture(float u, float v)
+{
+  PRINTF(5)("found vertex-Texture %f, %f\n", u, v);
+  this->vTexture.push_back(u);
+  this->vTexture.push_back(v);
+  return true;
+}
+
+/**
+ * @brief parses a face-string
+ * @param faceString The String that will be parsed.
+ *
+ * If a face line is found this function will add it to the glList.
+ *
+ * String is different from the argument addFace,
+ * in this, that the first Vertex/Normal/Texcoord is 1 instead of 0
+ *
+ * @TODO make it std::string conform
+ */
+bool StaticModelData::addFace (const std::string& faceStringInput)
+{
+  const char* faceString = faceStringInput.c_str();
+  if (this->currentGroup->faceCount >0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+
+  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
+  tmpElem->next = NULL;
+  while(strcmp (faceString, "\0"))
+  {
+    if (this->currentGroup->currentFace->vertexCount>0)
+      tmpElem = tmpElem->next = new ModelFaceElement;
+    tmpElem->next = NULL;
+
+    char tmpValue [50];
+    int tmpLen;
+    char* vertex = NULL;
+    char* texture = NULL;
+    char* normal = NULL;
+
+    sscanf (faceString, "%s", tmpValue);
+    tmpLen = strlen(tmpValue);
+    vertex = tmpValue;
+
+    if ((texture = strstr (vertex, "/")) != NULL)
+    {
+      texture[0] = '\0';
+      texture ++;
+
+      if ((normal = strstr (texture, "/")) !=NULL)
+      {
+        normal[0] = '\0';
+        normal ++;
+      }
+    }
+    if (vertex)
+      tmpElem->vertexNumber = atoi(vertex)-1;
+    if (texture)
+      tmpElem->texCoordNumber = atoi(texture)-1;
+    if (normal)
+      tmpElem->normalNumber = atoi(normal)-1;
+
+    faceString += tmpLen;
+    if (strcmp (faceString, "\0"))
+      faceString++;
+    this->currentGroup->currentFace->vertexCount++;
+  }
+
+  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
+  this->faceCount += this->currentGroup->currentFace->vertexCount -2;
+  return true;
+}
+
+/**
+ * @brief adds a new Face
+ * @param faceElemCount the number of Vertices to add to the Face.
+ * @param type The information Passed with each Vertex
+*/
+bool StaticModelData::addFace(int faceElemCount, VERTEX_FORMAT type, va_list args)
+{
+  if (this->currentGroup->faceCount > 0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+
+  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
+
+  for (int i = 0; i < faceElemCount; i++)
+  {
+    if (this->currentGroup->currentFace->vertexCount > 0)
+      tmpElem = tmpElem->next = new ModelFaceElement;
+
+    tmpElem->vertexNumber = va_arg (args, int);
+    if (type & TEXCOORD)
+      tmpElem->texCoordNumber = va_arg (args, int);
+    if (type & NORMAL)
+      tmpElem->normalNumber = va_arg(args, int);
+    this->currentGroup->currentFace->vertexCount++;
+  }
+
+  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount - 2;
+  this->faceCount += this->currentGroup->currentFace->vertexCount -2;
+  return true;
+}
+
+/**
+ * Function that selects a material, if changed in the obj file.
+ * @param matString the Material that will be set.
+*/
+bool StaticModelData::setMaterial(const std::string& matString)
+{
+  if (this->currentGroup->faceCount > 0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+
+  this->currentGroup->currentFace->material = this->findMaterialByName(matString);
+
+  if (this->currentGroup->faceCount == 0)
+    this->currentGroup->faceCount++;
+  return true;
+}
+
+/**
+ * Function that selects a material, if changed in the obj file.
+ * @param mtl the Material that will be set.
+*/
+bool StaticModelData::setMaterial(Material* mtl)
+{
+  if (this->currentGroup->faceCount > 0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+
+  this->currentGroup->currentFace->material = mtl;
+
+  if (this->currentGroup->faceCount == 0)
+    this->currentGroup->faceCount++;
+  return true;
+}
+
+/**
+ * @brief A routine that is able to create normals.
+ *
+ * The algorithm does the following:
+ * 1. It calculates creates Vectors for each normale, and sets them to zero.
+ * 2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements
+ * 3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal.
+ * 4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array.
+ */
+bool StaticModelData::buildVertexNormals ()
+{
+  PRINTF(4)("Normals are being calculated.\n");
+
+  Vector* normArray = new Vector [vertices.size()/3];
+  for (unsigned int i=0; i<vertices.size()/3;i++)
+    normArray[i] = Vector(.0,.0,.0);
+
+  Vector prevV;
+  Vector nextV;
+  Vector curV;
+
+  ModelGroup* tmpGroup = firstGroup;
+  while (tmpGroup != NULL)
+  {
+    ModelFace* tmpFace = tmpGroup->firstFace;
+    while (tmpFace != NULL)
+    {
+      if (tmpFace->firstElem != NULL)
+      {
+        ModelFaceElement* firstElem = tmpFace->firstElem;
+        ModelFaceElement* prevElem;
+        ModelFaceElement* curElem = firstElem;
+        ModelFaceElement* nextElem;
+        ModelFaceElement* lastElem;
+        // find last Element of the Chain. !! IMPORTANT:the last Element of the Chain must point to NULL, or it will resolv into an infinity-loop.
+        while (curElem != NULL)
+        {
+          prevElem = curElem;
+          curElem = curElem->next;
+        }
+        lastElem = prevElem;
+
+        curElem = firstElem;
+        for (unsigned int j = 0; j < tmpFace->vertexCount; j++)
+        {
+          if (!(nextElem = curElem->next))
+            nextElem = firstElem;
+          curElem->normalNumber = curElem->vertexNumber;
+
+          curV = Vector (this->vertices[curElem->vertexNumber*3],
+                         this->vertices[curElem->vertexNumber*3+1],
+                         this->vertices[curElem->vertexNumber*3+2]);
+
+          prevV = Vector (this->vertices[prevElem->vertexNumber*3],
+                          this->vertices[prevElem->vertexNumber*3+1],
+                          this->vertices[prevElem->vertexNumber*3+2]) - curV;
+
+          nextV = Vector (this->vertices[nextElem->vertexNumber*3],
+                          this->vertices[nextElem->vertexNumber*3+1],
+                          this->vertices[nextElem->vertexNumber*3+2]) - curV;
+          normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV);
+
+          prevElem = curElem;
+          curElem = curElem->next;
+        }
+      }
+      tmpFace = tmpFace->next;
+    }
+    tmpGroup = tmpGroup->next;
+  }
+
+  for (unsigned int i=0; i < this->vertices.size()/3;i++)
+  {
+    normArray[i].normalize();
+    PRINTF(5)("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z);
+
+    this->addVertexNormal(normArray[i].x, normArray[i].y, normArray[i].z);
+
+  }
+  delete[] normArray;
+  return true;
+}
+
+////////////
+// openGL //
+////////////
+/**
+ *  reads and includes the Faces/Materials into the openGL state Machine
+*/
+bool StaticModelData::importToDisplayList()
+{
+  // finalize the Arrays
+  if (normals.size() == 0) // vertices-Array must be built for this
+    this->buildVertexNormals();
+
+  this->currentGroup = this->firstGroup;
+
+  while (this->currentGroup != NULL)
+  {
+
+    // creating a glList for the Group
+    if ((this->currentGroup->listNumber = glGenLists(1)) == 0)
+    {
+      PRINTF(2)("glList could not be created for this Model\n");
+      return false;
+    }
+    glNewList (this->currentGroup->listNumber, GL_COMPILE);
+
+    // Putting Faces to GL
+    ModelFace* tmpFace = this->currentGroup->firstFace;
+    while (tmpFace != NULL)
+    {
+      if (tmpFace->vertexCount == 0 && tmpFace->material != NULL)
+      {
+        if (this->currentGroup->faceMode != -1)
+          glEnd();
+        this->currentGroup->faceMode = 0;
+        if (tmpFace->material != NULL)
+        {
+          tmpFace->material->select();
+          PRINTF(5)("using material %s for coming Faces.\n", tmpFace->material->getCName());
+        }
+      }
+
+      else if (tmpFace->vertexCount == 3)
+      {
+        if (this->currentGroup->faceMode != 3)
+        {
+          if (this->currentGroup->faceMode != -1)
+            glEnd();
+          glBegin(GL_TRIANGLES);
+        }
+
+        this->currentGroup->faceMode = 3;
+        PRINTF(5)("found triag.\n");
+      }
+
+      else if (tmpFace->vertexCount == 4)
+      {
+        if (this->currentGroup->faceMode != 4)
+        {
+          if (this->currentGroup->faceMode != -1)
+            glEnd();
+          glBegin(GL_QUADS);
+        }
+        this->currentGroup->faceMode = 4;
+        PRINTF(5)("found quad.\n");
+      }
+
+      else if (tmpFace->vertexCount > 4)
+      {
+        if (this->currentGroup->faceMode != -1)
+          glEnd();
+        glBegin(GL_POLYGON);
+        PRINTF(5)("Polygon with %i faces found.", tmpFace->vertexCount);
+        this->currentGroup->faceMode = tmpFace->vertexCount;
+      }
+
+      ModelFaceElement* tmpElem = tmpFace->firstElem;
+      while (tmpElem != NULL)
+      {
+        //      PRINTF(2)("%s\n", tmpElem->value);
+        this->addGLElement(tmpElem);
+        tmpElem = tmpElem->next;
+      }
+      tmpFace = tmpFace->next;
+    }
+    glEnd();
+    glEndList();
+
+    this->currentGroup = this->currentGroup->next;
+  }
+  return true;
+}
+
+
+/**
+ *  builds an array of triangles, that can later on be used for obb separation and octree separation
+ */
+bool StaticModelData::buildTriangleList()
+{
+  if( unlikely(!this->triangles.empty()))
+    return true;
+  /* make sure, that all the arrays are finalized */
+  if( normals.size() == 0) // vertices-Array must be built for this
+    this->buildVertexNormals();
+
+  int                index = 0;                   //!< the counter for the triangle array
+  ModelFaceElement*  tmpElem;       //!< the temporary faceelement reference
+  ModelFace*         tmpFace;              //!< the temporary face referece
+
+  unsigned int numTriangles = 0;
+  bool warned = false;
+
+  /* count the number of triangles */
+  /* now iterate through all groups and build up the triangle list */
+  this->currentGroup = this->firstGroup;
+  while( this->currentGroup != NULL)
+  {
+    tmpFace = this->currentGroup->firstFace;
+    while( tmpFace != NULL)
+    {
+      /* if its a triangle just add it to the list */
+      if( tmpFace->vertexCount == 3)
+      {
+        ++numTriangles;
+      } /* if the polygon is a quad */
+      else if( tmpFace->vertexCount == 4)
+      {
+        numTriangles += 2;
+      }
+      else if( tmpFace->vertexCount > 4)
+      {
+        if (!warned)
+        {
+          PRINTF(2)("This model (%s) got over 4 vertices per face <=> conflicts in the CD engine!\n", this->getCName());
+          warned = true;
+        }
+      }
+      tmpFace = tmpFace->next;
+    }
+    this->currentGroup = this->currentGroup->next;
+  }
+
+  PRINTF(3)("got %i triangles, %i vertices\n", numTriangles, this->vertices.size());
+
+
+  /* write MODELINFO structure */
+
+  /* allocate memory for the new triangle structures */
+  this->triangles.resize(numTriangles);
+
+  /* now iterate through all groups and build up the triangle list */
+  this->currentGroup = this->firstGroup;
+  while( this->currentGroup != NULL)
+  {
+    tmpFace = this->currentGroup->firstFace;
+    while( tmpFace != NULL)
+    {
+      tmpElem = tmpFace->firstElem;
+
+      /* if its a triangle just add it to the list */
+      if( tmpFace->vertexCount == 3)
+      {
+        for( int j = 0; j < 3; ++j)
+        {
+          this->triangles[index].indexToVertices[j] = (unsigned int)tmpElem->vertexNumber * 3 ;
+          this->triangles[index].indexToNormals[j] = (unsigned int)tmpElem->normalNumber * 3 ;
+          this->triangles[index].indexToTexCoor[j] = (unsigned int)tmpElem->texCoordNumber * 3 ;
+          tmpElem = tmpElem->next;
+
+        }
+        ++index;
+      } /* if the polygon is a quad */
+      else if( tmpFace->vertexCount == 4)
+      {
+
+        this->triangles[index].indexToVertices[0] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index].indexToNormals[0] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index].indexToTexCoor[0] = (unsigned int)tmpElem->texCoordNumber * 3;
+
+        this->triangles[index + 1].indexToVertices[0] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index + 1].indexToNormals[0] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index + 1].indexToTexCoor[0] = (unsigned int)tmpElem->texCoordNumber * 3;
+        tmpElem = tmpElem->next;
+
+        this->triangles[index].indexToVertices[1] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index].indexToNormals[1] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index].indexToTexCoor[1] = (unsigned int)tmpElem->texCoordNumber * 3;
+        tmpElem = tmpElem->next;
+
+        this->triangles[index].indexToVertices[2] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index].indexToNormals[2] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index].indexToTexCoor[2] = (unsigned int)tmpElem->texCoordNumber * 3;
+
+        this->triangles[index + 1].indexToVertices[2] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index + 1].indexToNormals[2] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index + 1].indexToTexCoor[2] = (unsigned int)tmpElem->texCoordNumber * 3;
+        tmpElem = tmpElem->next;
+
+        this->triangles[index + 1].indexToVertices[1] = (unsigned int)tmpElem->vertexNumber * 3;
+        this->triangles[index + 1].indexToNormals[1] = (unsigned int)tmpElem->normalNumber * 3;
+        this->triangles[index + 1].indexToTexCoor[1] = (unsigned int)tmpElem->texCoordNumber * 3;
+
+        index += 2;
+      }
+      tmpFace = tmpFace->next;
+    }
+    this->currentGroup = this->currentGroup->next;
+  }
+  return true;
+}
+
+
+/**
+ *  Adds a Face-element (one vertex of a face) with all its information.
+ * @param elem The FaceElement to add to the OpenGL-environment.
+
+   It does this by searching:
+   1. The Vertex itself
+   2. The VertexNormale
+   3. The VertexTextureCoordinate
+   merging this information, the face will be drawn.
+*/
+bool StaticModelData::addGLElement (ModelFaceElement* elem)
+{
+  PRINTF(5)("importing grafical Element to openGL.\n");
+
+  if (elem->texCoordNumber > -1)
+  {
+    if (likely((unsigned int)elem->texCoordNumber < this->vTexture.size()))
+      glTexCoord2fv(&this->vTexture[0] + elem->texCoordNumber * 2);
+    else
+      PRINTF(2)("TextureCoordinate %d is not in the List (max: %d)\nThe Model might be incomplete\n",
+                elem->texCoordNumber, this->vTexture.size());
+  }
+  if (elem->normalNumber > -1)
+  {
+    if (likely((unsigned int)elem->normalNumber < this->normals.size()))
+      glNormal3fv(&this->normals[0] + elem->normalNumber * 3);
+    else
+      PRINTF(2)("Normal %d is not in the List (max: %d)\nThe Model might be incomplete",
+                elem->normalNumber, this->normals.size());
+  }
+  if (elem->vertexNumber > -1)
+  {
+    if (likely((unsigned int)elem->vertexNumber < this->vertices.size()))
+      glVertex3fv(&this->vertices[0]+ elem->vertexNumber * 3);
+    else
+      PRINTF(2)("Vertex %d is not in the List (max: %d)\nThe Model might be incomplete",
+                elem->vertexNumber, this->vertices.size());
+  }
+
+  return true;
+}
Index: branches/heathaze/src/lib/graphics/importer/static_model_data.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/static_model_data.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/static_model_data.h	(revision 9940)
@@ -0,0 +1,177 @@
+/*!
+ * @file static_model.h
+ * @brief Contains the Model Class that handles Static 3D-Models rendered with glList's
+ */
+
+#ifndef _STATIC_MODEL_DATA_H
+#define _STATIC_MODEL_DATA_H
+
+#include "model.h"
+
+#include "material.h"
+#include <vector>
+#include "count_pointer.h"
+
+
+// definition of different modes for setting up Faces
+#define VERTEX 0       //!< If Faces are created WITH Vertex-Coordinate
+#define NORMAL 1       //!< If Faces are created WITH Normals (otherwise autocalculate)
+#define TEXCOORD 2     //!< If Faces are created WITH TextureCoordinate
+
+//! an enumerator for VERTEX_FORMAT
+typedef enum VERTEX_FORMAT {
+  VERTEX_ONLY = VERTEX,
+  VERTEX_NORMAL = NORMAL,
+  VERTEX_TEXCOORD = TEXCOORD,
+  VERTEX_TEXCOORD_NORMAL = NORMAL | TEXCOORD
+};
+
+////////////////////
+/// SUB-ELEMENTS ///
+////////////////////
+//! This is the placeholder of one Vertex beloning to a Face.
+class ModelFaceElement
+{
+public:
+  ModelFaceElement();
+  ~ModelFaceElement();
+
+  int                 vertexNumber;         //!< The number of the Vertex out of the Array* vertices, this vertex points to.
+  int                 normalNumber;         //!< The number of the Normal out of the Array* normals, this vertex points to.
+  int                 texCoordNumber;       //!< The number of the textureCoordinate out of the Array* vTexture, this vertex points to.
+
+  ModelFaceElement*   next;                 //!< Point to the next FaceElement in this List.
+};
+
+//! This is the placeholder of a Face belonging to a Group of Faces.
+class ModelFace
+{
+public:
+  ModelFace();
+  ~ModelFace();
+
+  unsigned int        vertexCount;     //!< The Count of vertices this Face has.
+  ModelFaceElement*   firstElem;       //!< Points to the first Vertex (FaceElement) of this Face.
+  Material*           material;        //!< The Material to use.
+
+  ModelFace*          next;            //!< Pointer to the next Face.
+};
+
+//! Group to handle multiple Models per obj-file.
+class ModelGroup
+{
+public:
+  ModelGroup();
+  ~ModelGroup();
+
+  void cleanup();
+
+  std::string  name;           //!< the Name of the Group. this is an identifier, that can be accessed via the draw (std::string name) function.
+  GLubyte*     indices;        //!< The indices of the Groups. Needed for vertex-arrays
+  GLuint       listNumber;     //!< The number of the GL-List this Group gets.
+  ModelFace*   firstFace;      //!< The first Face in this group.
+  ModelFace*   currentFace;    //!< The current Face in this Group (the one we are currently working with.)
+  int          faceMode;       //!< The Mode the Face is in: initially -1, 0 for FaceList opened, 1 for Material,  3 for triangle, 4 for Quad, 5+ for Poly @todo ENUM...
+  int          faceCount;      //!< The Number of Faces this Group holds.
+
+  ModelGroup*  next;           //!< Pointer to the next Group.
+};
+
+struct ModelMaterial
+{
+  Material* material;
+  bool external;
+};
+
+/////////////
+/// MODEL ///
+/////////////
+//! Class that handles static 3D-Models.
+/**
+ * it can also read them in and display them.
+ * All the objects are rendered with glLists
+ */
+class StaticModelData : public BaseObject
+{
+  ObjectListDeclaration(StaticModelData);
+  public:
+    typedef CountPointer<StaticModelData> Pointer;
+
+  public:
+  StaticModelData(const std::string& modelName = "");
+  virtual ~StaticModelData();
+
+  void draw() const;
+  void draw(int groupNumber) const;
+  void draw(const std::string& groupName) const;
+
+  void rebuild();
+
+  Material* addMaterial(Material* material);
+  Material* addMaterial(const std::string& materialName);
+
+  bool addGroup(const std::string& groupString);
+
+  void setScaleFactor(float scaleFactor) { this->scaleFactor = scaleFactor; };
+
+  bool addVertex(const std::string& vertexString);
+  bool addVertex(float x, float y, float z);
+
+  bool addFace(const std::string& faceString);
+  bool addFace(int faceElemCount, VERTEX_FORMAT type, va_list args);
+
+  bool addVertexNormal(const std::string& normalString);
+  bool addVertexNormal(float x, float y, float z);
+
+  bool addVertexTexture(const std::string& vTextureString);
+  bool addVertexTexture(float u, float v);
+
+  bool setMaterial(const std::string& mtlString);
+  bool setMaterial(Material* mtl);
+
+  void finalize();
+
+
+  const std::vector<GLfloat>& getVertices() const { return this->vertices; };
+  const std::vector<GLfloat>& getNormals() const { return this->normals; };
+  const std::vector<GLfloat>& getTexCoords() const { return this->vTexture; };
+  const std::vector<sTriangleExt>& getTriangles() const { return this->triangles; };
+  ///! HACK SOLUTION sTriangleExt should be const in the modelInfo.
+  sTriangleExt* getTrianglesExt() { return &this->triangles[0]; };
+
+  float getScaleFactor() const  { return scaleFactor; }
+
+protected:
+  Material* findMaterialByName(const std::string& materialName);
+
+private:
+  bool buildVertexNormals();
+
+  bool importToDisplayList();
+  bool buildTriangleList();
+
+  bool addGLElement(ModelFaceElement* elem);
+
+  bool cleanup();
+
+private:
+  bool                       finalized;       //!< Sets the Object to be finalized.
+
+  float                      scaleFactor;     //!< The Factor with which the Model should be scaled. @todo maybe one wants to scale the Model after Initialisation
+
+  unsigned int               faceCount;       //!< A modelwide Counter for the faces
+
+  std::vector<GLfloat>       vertices;        //!< The Array that handles the Vertices.
+  std::vector<GLfloat>       normals;         //!< The Array that handles the Normals.
+  std::vector<GLfloat>       vTexture;        //!< The Array that handles the VertexTextureCoordinates.
+
+  std::vector<sTriangleExt>  triangles;       //!< The Triangles if built.
+
+  ModelGroup*                firstGroup;      //!< The first of all groups.
+  ModelGroup*                currentGroup;    //!< The currentGroup. this is the one we will work with.
+  int                        groupCount;      //!< The Count of Groups.
+
+  std::list<ModelMaterial*>  materialList;    //!< A list for all the Materials in this Model
+};
+
+#endif /* _STATIC_MODEL_DATA_H */
Index: branches/heathaze/src/lib/graphics/importer/tc.COPYRIGHT
===================================================================
--- branches/heathaze/src/lib/graphics/importer/tc.COPYRIGHT	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/tc.COPYRIGHT	(revision 9940)
@@ -0,0 +1,25 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+  1. Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+  2. Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+  3. All advertising materials mentioning features or use of this software
+     must display the following acknowledgement:
+       This product includes software developed by Brad Grantham and
+       Applied Conjecture.
+  4. Neither the name Brad Grantham nor Applied Conjecture 
+     may be used to endorse or promote products derived from this software
+     without specific prior written permission.
+  5. Notification must be made to Brad Grantham about inclusion of this
+     software in a product including the author of the product and the name
+     and purpose of the product.  Notification can be made using email
+     to Brad Grantham's current address (grantham@plunk.org as of September
+     20th, 2000) or current U.S. mail address.
+
+$Header: /home/grantham/cvsroot/projects/modules/tc/COPYRIGHT,v 1.1 2000/09/21 19:36:56 grantham Exp $
+
+# vi:tabstop=8
+#
Index: branches/heathaze/src/lib/graphics/importer/tc.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/tc.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/tc.cc	(revision 9940)
@@ -0,0 +1,1448 @@
+/*
+ * $Header: /home/grantham/cvsroot/projects/modules/tc/tc.c,v 1.27 2000/10/10 16:09:23 grantham Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "tc.h"
+
+/* SNIPPET "table.c" Inducted Wed Nov 22 09:36:55 2000 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(MEM_CHART)
+#define chartedSetLabel(a)
+#endif
+
+#define LEVEL1COUNT 16384
+#define LEVEL2COUNT 1024
+#define LEVEL3COUNT 256
+
+typedef struct TableLevel3
+{
+    int EntryCount;
+    void *Table[LEVEL3COUNT];
+    char IsSet[LEVEL3COUNT];
+} TableLevel3;
+
+typedef struct TableLevel2
+{
+    int EntryCount;
+    TableLevel3 *Table[LEVEL2COUNT];
+} TableLevel2;
+
+typedef struct TableRoot
+{
+    size_t EntryCount;
+    size_t TotalEntryCount;
+    size_t TotalAllocatedBytes;
+    int EmptyEntryCount;
+    TableLevel2 *Table[LEVEL1COUNT];
+} TableRoot;
+
+typedef struct TableIterator {
+    int i1, i2, i3;
+    unsigned int i;
+    TableLevel3 *CurLevel3;
+    int CheckLevel1, CheckLevel2;
+} TableIterator;
+
+TableRoot *tableNew(void)
+{
+    TableRoot *tr;
+
+    chartedSetLabel("table root");
+    tr = (TableRoot *)calloc(sizeof(TableRoot), 1);
+    return tr;
+}
+
+TableIterator *tableNewIterator(void)
+{
+    TableIterator *ti;
+
+    chartedSetLabel("table iterator");
+    ti = (TableIterator *)malloc(sizeof(TableIterator));
+    return ti;
+}
+
+int tableRetrieve(unsigned int a, TableRoot *table, void **ref)
+{
+    int i1 = a / (LEVEL2COUNT * LEVEL3COUNT);
+    int i2 = (a / LEVEL3COUNT) % LEVEL2COUNT;
+    int i3 = a % LEVEL3COUNT;
+
+    if(table->Table[i1] == NULL)
+        return 0;
+    if(table->Table[i1]->Table[i2] == NULL)
+        return 0;
+    if(!table->Table[i1]->Table[i2]->IsSet[i3])
+        return 0;
+    if(ref != NULL)
+        *ref = table->Table[i1]->Table[i2]->Table[i3];
+    return 1;
+}
+
+int tableInsert(unsigned int a, TableRoot *table, void *ref)
+{
+    int i1 = a / (LEVEL2COUNT * LEVEL3COUNT);
+    int i2 = (a / LEVEL3COUNT) % LEVEL2COUNT;
+    int i3 = a % LEVEL3COUNT;
+
+    if(table->Table[i1] == NULL) {
+	chartedSetLabel("table level 2");
+        table->Table[i1] = (TableLevel2 *)calloc(1, sizeof(TableLevel2));
+	table->TotalAllocatedBytes += sizeof(TableLevel2);
+        if(table->Table[i1] == NULL)
+            return 0;
+    }
+    if(table->Table[i1]->Table[i2] == NULL) {
+	chartedSetLabel("table level 3");
+        table->Table[i1]->Table[i2] =
+	    (TableLevel3 *)calloc(1, sizeof(TableLevel3));
+	table->TotalAllocatedBytes += sizeof(TableLevel3);
+        if(table->Table[i1]->Table[i2] == NULL)
+            return 0;
+	table->Table[i1]->EntryCount++;
+	table->TotalEntryCount += LEVEL3COUNT;
+	table->EmptyEntryCount += LEVEL3COUNT;
+    }
+    if(!table->Table[i1]->Table[i2]->IsSet[i3]) {
+	table->Table[i1]->Table[i2]->EntryCount++;
+	table->EmptyEntryCount --;
+	table->Table[i1]->Table[i2]->IsSet[i3] = 1;
+    }
+    table->Table[i1]->Table[i2]->Table[i3] = ref;
+    return 1;
+}
+
+int tableRemove(unsigned int a, TableRoot *table, void **wasref)
+{
+    int i1 = a / (LEVEL2COUNT * LEVEL3COUNT);
+    int i2 = (a / LEVEL3COUNT) % LEVEL2COUNT;
+    int i3 = a % LEVEL3COUNT;
+
+    if(table->Table[i1] == NULL)
+	return 0;
+    if(table->Table[i1]->Table[i2] == NULL)
+	return 0;
+    if(!table->Table[i1]->Table[i2]->IsSet[i3])
+        return 0;
+    if(wasref != NULL)
+        *wasref = table->Table[i1]->Table[i2]->Table[i3];
+    table->Table[i1]->Table[i2]->IsSet[i3] = 0;
+    table->EmptyEntryCount ++;
+    if(--table->Table[i1]->Table[i2]->EntryCount == 0) {
+	table->EmptyEntryCount -= LEVEL3COUNT;
+	table->TotalEntryCount -= LEVEL3COUNT;
+	free(table->Table[i1]->Table[i2]);
+	table->TotalAllocatedBytes -= sizeof(TableLevel3);
+	table->Table[i1]->Table[i2] = NULL;
+	if(--table->Table[i1]->EntryCount == 0) {
+	    table->TotalAllocatedBytes -= sizeof(TableLevel2);
+	    free(table->Table[i1]);
+	    table->Table[i1] = NULL;
+	}
+    }
+    return 1;
+}
+
+void tableResetIterator(TableIterator *ti)
+{
+    ti->i1 = 0;
+    ti->i2 = 0;
+    ti->i3 = 0;
+    ti->i = 0;
+    ti->CheckLevel1 = 1;
+    ti->CheckLevel2 = 1;
+}
+
+int tableIterate(TableRoot *table, TableIterator *ti, unsigned int *i, void **ref)
+{
+    int done;
+
+    done = 0;
+    while(ti->i1 < LEVEL1COUNT) {
+        if(ti->CheckLevel1 && table->Table[ti->i1] == NULL) {
+	    ti->i += LEVEL2COUNT * LEVEL3COUNT;
+	    ti->i1++;
+	    continue;
+	} else
+	    ti->CheckLevel1 = 0;
+        if(ti->CheckLevel2 && table->Table[ti->i1]->Table[ti->i2] == NULL) {
+	    ti->i += LEVEL3COUNT;
+	    if(++ti->i2 >= LEVEL2COUNT) {
+		ti->i2 = 0;
+		ti->i1++;
+		ti->CheckLevel1 = 1;
+	    }
+	    continue;
+	} else
+	    ti->CheckLevel2 = 0;
+	if(ti->i3 == 0)
+	    ti->CurLevel3 = table->Table[ti->i1]->Table[ti->i2];
+	if(ti->CurLevel3->IsSet[ti->i3]) {
+	    if(ref != NULL)
+		*ref = ti->CurLevel3->Table[ti->i3];
+	    if(i != NULL)
+		*i = ti->i;
+	    done = 1;
+	}
+	ti->i++;
+	if(++ti->i3 >= LEVEL3COUNT) {
+	    ti->i3 = 0;
+	    ti->CheckLevel2 = 1;
+	    if(++ti->i2 >= LEVEL2COUNT) {
+		ti->i2 = 0;
+		ti->i1++;
+		ti->CheckLevel1 = 1;
+	    }
+	}
+	if(done)
+	    return 1;
+    }
+    return 0;
+}
+
+void tableDelete(TableRoot *table, void (*datumDelete)(void *datum))
+{
+    int i1, i2, i3;
+
+    for(i1 = 0; i1 < LEVEL1COUNT; i1++) {
+        if(table->Table[i1] != NULL) {
+	    for(i2 = 0; i2 < LEVEL2COUNT; i2++) {
+		if(table->Table[i1]->Table[i2] != NULL) {
+		    for(i3 = 0; i3 < LEVEL3COUNT; i3++) {
+			if(table->Table[i1]->Table[i2]->IsSet[i3])
+			    datumDelete(table->Table[i1]->Table[i2]->Table[i3]);
+		    }
+		    free(table->Table[i1]->Table[i2]);
+		}
+	    }
+	    free(table->Table[i1]);
+	    table->Table[i1] = NULL;
+	}
+    }
+    table->TotalEntryCount = 0;
+    table->EmptyEntryCount = 0;
+    table->TotalAllocatedBytes = 0;
+}
+
+void tableGetStats(TableRoot *table, size_t *totalBytes, size_t *emptyCount,
+    size_t *totalCount)
+{
+    if(emptyCount != NULL)
+        *emptyCount = table->EmptyEntryCount;
+    if(totalCount != NULL)
+        *totalCount = table->TotalEntryCount;
+    if(totalBytes != NULL)
+        *totalBytes = table->TotalAllocatedBytes;
+}
+
+size_t tableGetIteratorSize(void)
+{
+    return sizeof(TableIterator);
+}
+
+/* "table.c" ENDSNIPPET */
+
+#if !defined(MEM_CHART)
+#define chartedSetLabel(a)
+#endif
+
+#if defined(DEBUG)
+#define ACTC_DEBUG(a) a
+#else
+#define ACTC_DEBUG(a)
+#endif
+
+#if defined(INFO)
+#define ACTC_INFO(a) a
+#else
+#define ACTC_INFO(a)
+#endif
+
+
+#define ACTC_CHECK(a) \
+    { \
+        int theErrorNow; \
+	theErrorNow = (a); \
+	if(theErrorNow < 0) \
+	    return theErrorNow; \
+    }
+
+typedef struct {
+    struct ACTCVertex *FinalVert;
+} ACTCTriangle;
+
+typedef struct {
+    struct ACTCVertex *V2;
+    int Count;
+    int TriangleCount;
+    ACTCTriangle *Triangles;
+} ACTCEdge;
+
+typedef struct ACTCVertex {
+    unsigned int V;
+    int Count;
+    struct ACTCVertex **PointsToMe;
+    struct ACTCVertex *Next;
+    int EdgeCount;
+    ACTCEdge *Edges;
+} ACTCVertex;
+
+/* private tokens */
+#define ACTC_NO_MATCHING_VERT		-0x3000
+#define ACTC_FWD_ORDER			0
+#define ACTC_REV_ORDER			1
+
+#define MAX_STATIC_VERTS		10000000 /* buh? */
+
+struct _ACTCData {
+
+    /* vertex and edge database */
+    int VertexCount;
+    TableRoot *Vertices;
+    TableIterator *VertexIterator;
+    int CurMaxVertValence;
+    int CurMinVertValence;
+    ACTCVertex **VertexBins;
+
+    /* alternate vertex array if range small enough */
+    ACTCVertex *StaticVerts;
+    int UsingStaticVerts;
+    unsigned int VertRange;
+
+    /* During consolidation */
+    int CurWindOrder;
+    int PrimType;
+    ACTCVertex *V1;
+    ACTCVertex *V2;
+    int VerticesSoFar;
+
+    /* Error and state handling */
+    int IsInputting;
+    int IsOutputting;
+    int Error;
+
+    /* actcParam-settable parameters */
+    unsigned int MinInputVert;
+    unsigned int MaxInputVert;
+    int MaxVertShare;
+    int MaxEdgeShare;
+    int MinFanVerts;
+    int MaxPrimVerts;
+    int HonorWinding;
+};
+
+#if defined(DEBUG) || defined(INFO)
+
+static void dumpTriangles(ACTCEdge *e, FILE *fp)
+{
+    int i;
+    int c;
+    char v[12];
+
+    c = fprintf(fp, "      %d triangles: ");
+    for(i = 0; i < e->TriangleCount; i++) {
+	if(c + 1 + sprintf(v, "%u", e->Triangles[i].FinalVert) > 78) {
+	    fputs("\n", fp);
+	    c = fprintf(fp, "        ");
+	}
+	c += fprintf(fp, " %s", v);
+    }
+    fputs("\n", fp);
+}
+
+static void dumpEdges(ACTCVertex *vert, FILE *fp)
+{
+    int i;
+    int c;
+    char v[26]; /* two signed ints plus x plus NUL */
+
+    for(i = 0; i < vert->EdgeCount; i++) {
+	fprintf(fp, "    %u->%u (%d times)\n", vert->V, vert->Edges[i].V2->V,
+	    vert->Edges[i].Count);
+	dumpTriangles(&vert->Edges[i], fp);
+    }
+    fputs("\n", fp);
+}
+
+static void dumpVertices(ACTCData *tc, FILE *fp)
+{
+    int i;
+    ACTCVertex *v;
+
+    if(!tc->UsingStaticVerts)
+        tableResetIterator(tc->VertexIterator);
+
+    fprintf(fp, "%d vertices in valences list\n", tc->VertexCount);
+    if(tc->UsingStaticVerts) {
+        for(i = 0; i < tc->VertRange; i++) {
+	    v = &tc->StaticVerts[i];
+	    if(v->Count > 0) {
+		fprintf(fp, "  vertex %u, valence %d, %d edges\n", v->V,
+		    v->Count, v->EdgeCount);
+		dumpEdges(v, fp);
+	    }
+	}
+    } else {
+	for(i = 0; i < tc->VertexCount; i++) {
+	    if(tableIterate(tc->Vertices, tc->VertexIterator, NULL,
+		(void **)&v) == 0) {
+		fprintf(fp, "ACTC::dumpVertices : fewer vertices in the table "
+		    "than we expected!\n");
+		fprintf(stderr, "ACTC::dumpVertices : fewer vertices in the table "
+		    "than we expected!\n");
+	    }
+	    if(v == NULL) {
+		fprintf(fp, "ACTC::dumpVertices : did not expect to get a NULL"
+		    "Vertex from the table iterator!\n");
+		fprintf(stderr, "ACTC::dumpVertices : did not expect to get a NULL"
+		    "Vertex from the table iterator!\n");
+	    }
+	    fprintf(fp, "  vertex %u, valence %d, %d edges\n", v->V, v->Count,
+		v->EdgeCount);
+	    dumpEdges(v, fp);
+	}
+    }
+}
+
+static void dumpVertexBins(ACTCData *tc, FILE *fp)
+{
+    ACTCVertex *cur;
+    int i;
+    int c;
+    char v[26]; /* two signed ints plus x plus NUL */
+
+    fprintf(fp, "vertex bins:\n");
+    if(tc->VertexBins == NULL) {
+        fprintf(fp, "        empty.\n");
+	return;
+    }
+    for(i = 1; i <= tc->CurMaxVertValence; i++) {
+        cur = tc->VertexBins[i];
+	c = fprintf(fp, "        bin %d -> ", i);
+	while(cur != NULL) {
+	    if(c + 1 + sprintf(v, "%ux%d", cur->V, cur->Count) > 78) {
+		fputs("\n", fp);
+		c = fprintf(fp, "          ");
+	    }
+	    c += fprintf(fp, " %s", v);
+	    cur = cur->Next;
+	}
+	fputs("\n", fp);
+    }
+}
+
+void actcDumpState(ACTCData *tc, FILE *fp)
+{
+    dumpVertices(tc, fp);
+    dumpVertexBins(tc, fp);
+}
+
+#endif /* DEBUG || INFO */
+
+#if defined(DEBUG)
+
+static int abortWithOptionalDump(ACTCData *tc)
+{
+    ACTC_INFO(actcDumpState(tc, stderr));
+    abort();
+}
+
+#endif /* defined(DEBUG) */
+
+int actcGetError(ACTCData *tc)
+{
+    int error = tc->Error;
+    tc->Error = ACTC_NO_ERROR;
+    return error;
+}
+
+static void *reallocAndAppend(void **ptr, unsigned int *itemCount, size_t itemBytes,
+    void *append)
+{
+    void *t;
+
+    t = realloc(*ptr, itemBytes * (*itemCount + 1));
+    if(t == NULL)
+	return NULL;
+    *ptr = t;
+
+    memcpy((unsigned char *)*ptr + *itemCount * itemBytes, append, itemBytes);
+    (*itemCount) += 1;
+
+    return *ptr;
+}
+
+/*
+ * Call only during input; changes vertices' valences and does not
+ * fix the bins that are ordered by vertex valence.  (It's usually cheaper
+ * to traverse the vertex list once after all are added, since that's
+ * linear in the NUMBER OF UNIQUE VERTEX INDICES, which is almost always
+ * going to be less than the number of vertices.)
+ */
+static int incVertexValence(ACTCData *tc, unsigned int v, ACTCVertex **found)
+{
+    ACTCVertex *vertex;
+
+    if(tc->UsingStaticVerts) {
+        vertex = &tc->StaticVerts[v];
+	vertex->Count++;
+	if(vertex->Count == 1) {
+	    vertex->V = v;
+	    tc->VertexCount++;
+	}
+    } else {
+	if(tableRetrieve(v, tc->Vertices, (void **)&vertex) == 1) {
+	    if(vertex->V != v) {
+		ACTC_DEBUG(
+		    fprintf(stderr, "ACTC::incVertexValence : Got vertex %d when "
+			"looking for vertex %d?!?\n", vertex->V, v);
+		    abortWithOptionalDump(tc);
+		)
+		return tc->Error = ACTC_DATABASE_CORRUPT;
+	    }
+	    vertex->Count++;
+	} else {
+	    chartedSetLabel("new Vertex");
+	    vertex = (ACTCVertex *)malloc(sizeof(ACTCVertex));
+	    vertex->V = v;
+	    vertex->Count = 1;
+	    vertex->Edges = NULL;
+	    vertex->EdgeCount = 0;
+	    if(tableInsert(v, tc->Vertices, vertex) == 0) {
+		ACTC_DEBUG(fprintf(stderr, "ACTC::incVertexValence : Failed "
+		    "to insert vertex into table\n");)
+		return tc->Error = ACTC_ALLOC_FAILED;
+	    }
+	    tc->VertexCount++;
+	}
+    }
+    if(vertex->Count > tc->CurMaxVertValence)
+	tc->CurMaxVertValence = vertex->Count;
+
+    *found = vertex;
+
+    return ACTC_NO_ERROR;
+}
+
+static int decVertexValence(ACTCData *tc, ACTCVertex **vptr)
+{
+    ACTCVertex *v = *vptr;
+
+    v->Count--;
+    if(v->Count < 0) {
+	ACTC_DEBUG(
+	    fprintf(stderr, "ACTC::decVertexValence : Valence went "
+		"negative?!?\n");
+	    abortWithOptionalDump(tc);
+	)
+	return tc->Error = ACTC_DATABASE_CORRUPT;
+    }
+
+    if(v->PointsToMe != NULL) {
+	*v->PointsToMe = v->Next;
+	if(v->Next != NULL)
+	    v->Next->PointsToMe = v->PointsToMe;
+	v->Next = NULL;
+    }
+
+    if(v->Count == 0) {
+	tc->VertexCount--;
+	if(v->Edges != NULL)
+	    free(v->Edges);
+        if(!tc->UsingStaticVerts) {
+	    tableRemove(v->V, tc->Vertices, NULL);
+	    free(v);
+	}
+	*vptr = NULL;
+    } else {
+	if(tc->VertexBins != NULL) {
+	    v->Next = tc->VertexBins[v->Count];
+	    v->PointsToMe = &tc->VertexBins[v->Count];
+	    if(v->Next != NULL)
+		v->Next->PointsToMe = &v->Next;
+	    tc->VertexBins[v->Count] = v;
+	    if(v->Count < tc->CurMinVertValence)
+		tc->CurMinVertValence = v->Count;
+	}
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+static int findNextFanVertex(ACTCData *tc, ACTCVertex **vert)
+{
+    if(tc->CurMaxVertValence < tc->MinFanVerts) {
+	return ACTC_NO_MATCHING_VERT;
+    }
+    while(tc->VertexBins[tc->CurMaxVertValence] == NULL) {
+	tc->CurMaxVertValence--;
+	if(tc->CurMaxVertValence < tc->CurMinVertValence) {
+	    if(tc->VertexCount > 0) {
+		ACTC_DEBUG(fprintf(stderr, "tc::findNextFanVertex : no more "
+		    "vertices in bins but VertexCount > 0\n");)
+		return tc->Error = ACTC_DATABASE_CORRUPT;
+	    }
+	    return ACTC_NO_MATCHING_VERT;
+	}
+    }
+    *vert = tc->VertexBins[tc->CurMaxVertValence];
+    return ACTC_NO_ERROR;
+}
+
+static int findNextStripVertex(ACTCData *tc, ACTCVertex **vert)
+{
+    while(tc->VertexBins[tc->CurMinVertValence] == NULL) {
+	tc->CurMinVertValence++;
+	if(tc->CurMinVertValence > tc->CurMaxVertValence) {
+	    if(tc->VertexCount > 0) {
+		ACTC_DEBUG(fprintf(stderr, "tc::findNextStripVertex : no more "
+		    "vertices in bins but VertexCount > 0\n");)
+		return tc->Error = ACTC_DATABASE_CORRUPT;
+	    }
+	    return ACTC_NO_MATCHING_VERT;
+	}
+    }
+    *vert = tc->VertexBins[tc->CurMinVertValence];
+    return ACTC_NO_ERROR;
+}
+
+int actcGetIsDuringInput(ACTCData *tc) {
+    return tc->IsInputting;
+}
+
+int actcBeginInput(ACTCData *tc)
+{
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcBeginInput : called within "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcBeginInput : called within "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    tc->IsInputting = 1;
+    tc->CurMaxVertValence = 0;
+
+    if(tc->MaxInputVert < MAX_STATIC_VERTS - 1) {
+	size_t byteCount;
+	tc->UsingStaticVerts = 1;
+	tc->VertRange = tc->MaxInputVert + 1;
+	byteCount = sizeof(ACTCVertex) * tc->VertRange;
+	chartedSetLabel("static verts");
+	tc->StaticVerts = (ACTCVertex *)calloc(sizeof(ACTCVertex), tc->VertRange);
+	if(tc->StaticVerts == NULL) {
+	    ACTC_INFO(printf("Couldn't allocate static %d vert block of %u "
+		"bytes\n", tc->VertRange, byteCount);)
+	    tc->UsingStaticVerts = 0;
+	}
+    } else
+	tc->UsingStaticVerts = 0;
+
+    return ACTC_NO_ERROR;
+}
+
+int actcEndInput(ACTCData *tc)
+{
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcEndInput : called within "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_DURING_OUTPUT;
+    }
+
+    if(!tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcEndInput : called outside "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_IDLE;
+    }
+
+    tc->IsInputting = 0;
+
+    return ACTC_NO_ERROR;
+}
+
+int actcGetIsDuringOutput(ACTCData *tc) {
+    return tc->IsOutputting;
+}
+
+int actcBeginOutput(ACTCData *tc)
+{
+    ACTCVertex *v;
+    int i;
+
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : called within "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : called within "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_DURING_OUTPUT;
+    }
+
+    tc->IsOutputting = 1;
+
+    tc->CurMinVertValence = INT_MAX;
+    chartedSetLabel("vertex bins");
+    tc->VertexBins = (ACTCVertex **)calloc(sizeof(ACTCVertex *), tc->CurMaxVertValence + 1);
+    if(tc->VertexBins == NULL) {
+	ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : couldn't allocate %d bytes "
+	    "for Vertex Bins\n",
+	    sizeof(ACTCVertex *) * tc->CurMaxVertValence);)
+	return tc->Error = ACTC_ALLOC_FAILED;
+    }
+
+    if(tc->UsingStaticVerts) {
+        double edgeTotal;
+        for(i = 0; i < (int)tc->VertRange; i++) {
+	    v = &tc->StaticVerts[i];
+	    if(v->Count > 0) {
+		v->Next = tc->VertexBins[v->Count];
+		v->PointsToMe = &tc->VertexBins[v->Count];
+		tc->VertexBins[v->Count] = v;
+		if(v->Next != NULL)
+		    v->Next->PointsToMe = &v->Next;
+		if(v->Count < tc->CurMinVertValence)
+		    tc->CurMinVertValence = v->Count;
+		edgeTotal += v->EdgeCount;
+	    }
+	}
+    } else {
+	tableResetIterator(tc->VertexIterator);
+	for(i = 0; i < tc->VertexCount; i++) {
+	    if(tableIterate(tc->Vertices, tc->VertexIterator, NULL, (void **)&v)
+		== 0) {
+		ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : fewer vertices in "
+		    "the table than we expected!\n");)
+		return tc->Error = ACTC_DATABASE_CORRUPT;
+	    }
+	    v->Next = tc->VertexBins[v->Count];
+	    v->PointsToMe = &tc->VertexBins[v->Count];
+	    tc->VertexBins[v->Count] = v;
+	    if(v->Next != NULL)
+		v->Next->PointsToMe = &v->Next;
+	    if(v->Count < tc->CurMinVertValence)
+		tc->CurMinVertValence = v->Count;
+	}
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+int actcEndOutput(ACTCData *tc)
+{
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcEndOutput : called within "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(!tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcEndOutput : called outside "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_IDLE;
+    }
+
+    tc->IsOutputting = 0;
+
+    if(tc->UsingStaticVerts) {
+	free(tc->StaticVerts);
+	tc->StaticVerts = NULL;
+	tc->UsingStaticVerts = 0;
+    }
+
+    free(tc->VertexBins);
+    tc->VertexBins = NULL;
+
+    return ACTC_NO_ERROR;
+}
+
+ACTCData *actcNew(void)
+{
+    ACTCData *tc;
+#if defined(DEBUG) || defined(INFO)
+    static int didPrintVersion = 0;
+
+    if(!didPrintVersion) {
+	int verMinor, verMajor;
+	didPrintVersion = 1;
+
+        actcGetParami(tc, ACTC_MAJOR_VERSION, &verMajor);
+        actcGetParami(tc, ACTC_MINOR_VERSION, &verMinor);
+	fprintf(stderr, "TC Version %d.%d\n", verMajor, verMinor);
+    }
+#endif /* defined(DEBUG) || defined(INFO) */
+
+    chartedSetLabel("the tc struct");
+    tc = (ACTCData *)calloc(sizeof(*tc), 1);
+
+    if(tc == NULL) {
+	ACTC_DEBUG(fprintf(stderr, "actcNew : couldn't allocate %d bytes "
+	    "for new ACTCData\n", sizeof(*tc));)
+	return NULL;
+    }
+
+    tc->Vertices = tableNew();
+    tc->VertexIterator = tableNewIterator();
+
+    tc->MinFanVerts = INT_MAX;
+    tc->MaxPrimVerts = INT_MAX;
+    tc->MaxInputVert = INT_MAX;
+    tc->MaxEdgeShare = INT_MAX;
+    tc->MaxVertShare = INT_MAX;
+    tc->HonorWinding = 1;
+    /* seed = 0 handled by calloc */
+    /* XXX grantham 20000615 - seed ignored for now */
+
+    return tc;
+}
+
+static size_t allocatedForTriangles(ACTCEdge *e)
+{
+    return sizeof(ACTCTriangle) * e->TriangleCount;
+}
+
+static size_t allocatedForEdges(ACTCVertex *vert)
+{
+    int i;
+    size_t size;
+
+    size = sizeof(ACTCEdge) * vert->EdgeCount;
+    for(i = 0; i < vert->EdgeCount; i++) {
+	size += allocatedForTriangles(&vert->Edges[i]);
+    }
+    return size;
+}
+
+static size_t allocatedForVertices(ACTCData *tc)
+{
+    int i;
+    int size = 1;
+    ACTCVertex *v;
+
+    if(!tc->UsingStaticVerts)
+        tableResetIterator(tc->VertexIterator);
+
+    if(tc->UsingStaticVerts) {
+        size = tc->VertRange * sizeof(ACTCVertex);
+        for(i = 0; i < (int)tc->VertRange; i++) {
+	    v = &tc->StaticVerts[i];
+	    if(v->Count > 0)
+	        size += allocatedForEdges(v);
+	}
+    } else {
+	for(i = 0; i < tc->VertexCount; i++) {
+	    tableIterate(tc->Vertices, tc->VertexIterator, NULL, (void **)&v);
+	    size += allocatedForEdges(v);
+	}
+    }
+    return size;
+}
+
+int actcGetMemoryAllocation(ACTCData *tc, size_t *bytesAllocated)
+{
+    size_t tableBytes;
+
+    tableGetStats(tc->Vertices, NULL, NULL, &tableBytes);
+    *bytesAllocated = sizeof(ACTCData);
+    *bytesAllocated += tableBytes;
+    *bytesAllocated += allocatedForVertices(tc); /* recurses */
+
+    return ACTC_NO_ERROR;
+}
+
+static void freeVertex(void *p)
+{
+    ACTCVertex *v = (ACTCVertex *)p;
+    int i;
+
+    for(i = 0; i < v->EdgeCount; i++)
+        free(v->Edges[i].Triangles);
+    free(v->Edges);
+    free(v);
+}
+
+int actcMakeEmpty(ACTCData *tc)
+{
+    tc->VertexCount = 0;
+    if(!tc->UsingStaticVerts)
+        tableDelete(tc->Vertices, freeVertex);
+    if(tc->VertexBins != NULL) {
+        free(tc->VertexBins);
+	tc->VertexBins = NULL;
+    }
+    tc->IsOutputting = 0;
+    tc->IsInputting = 0;
+    return ACTC_NO_ERROR;
+}
+
+void actcDelete(ACTCData *tc)
+{
+    actcMakeEmpty(tc);
+    free(tc->VertexIterator);
+    free(tc->Vertices);
+    free(tc);
+}
+
+int actcParami(ACTCData *tc, int param, int value)
+{
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcParami : within BeginInput/"
+	    "EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcParami : within BeginOutput/"
+	    "EndOutput\n");)
+	return tc->Error = ACTC_DURING_OUTPUT;
+    }
+    switch(param) {
+	case ACTC_OUT_MIN_FAN_VERTS:
+	    tc->MinFanVerts = value;
+	    break;
+
+	case ACTC_IN_MAX_VERT:
+          if(value < (int)tc->MinInputVert) {
+		ACTC_DEBUG(fprintf(stderr, "actcParami : tried to set "
+		    "MAX_INPUT_VERT to %d, less than MIN_INPUT_VERT (%d)\n",
+		    value, tc->MinInputVert);)
+		return tc->Error = ACTC_INVALID_VALUE;
+	    }
+	    tc->MaxInputVert = value;
+	    break;
+
+	case ACTC_IN_MIN_VERT:
+          if(value > (int)tc->MaxInputVert) {
+		ACTC_DEBUG(fprintf(stderr, "actcParami : tried to set "
+		    "MIN_INPUT_VERT to %d, greater than MAX_INPUT_VERT (%d)\n",
+		    value, tc->MaxInputVert);)
+		return tc->Error = ACTC_INVALID_VALUE;
+	    }
+	    tc->MinInputVert = value;
+	    break;
+
+	case ACTC_IN_MAX_EDGE_SHARING:
+	    tc->MaxEdgeShare = value;
+	    break;
+
+	case ACTC_IN_MAX_VERT_SHARING:
+	    tc->MaxVertShare = value;
+	    break;
+
+	case ACTC_OUT_HONOR_WINDING:
+	    tc->HonorWinding = value;
+	    break;
+
+	case ACTC_OUT_MAX_PRIM_VERTS:
+	    if(value < 3) {
+		ACTC_DEBUG(fprintf(stderr, "actcParami : tried to set "
+		    "MAX_PRIM_VERTS to %d (needed to be 3 or more)\n", value);)
+		return tc->Error = ACTC_INVALID_VALUE;
+	    }
+	    tc->MaxPrimVerts = value;
+	    break;
+
+    }
+    return ACTC_NO_ERROR;
+}
+
+int actcParamu(ACTCData *tc, int param, unsigned int value)
+{
+    /*
+     * XXX - yes, this is questionable, but I consulted industry
+     * experts and we agreed that most common behavior is to copy the
+     * bits directly, which is what I want.
+     */
+    return actcParami(tc, param, (int)value);
+}
+
+int actcGetParami(ACTCData *tc, int param, int *value)
+{
+    switch(param) {
+	case ACTC_MAJOR_VERSION:
+	    *value = 1;
+	    break;
+
+	case ACTC_MINOR_VERSION:
+	    *value = 1;
+	    break;
+
+	case ACTC_IN_MAX_VERT:
+	    *value = tc->MaxInputVert;
+	    break;
+
+	case ACTC_IN_MIN_VERT:
+	    *value = tc->MinInputVert;
+	    break;
+
+	case ACTC_IN_MAX_EDGE_SHARING:
+	    *value = tc->MaxEdgeShare;
+	    break;
+
+	case ACTC_IN_MAX_VERT_SHARING:
+	    *value = tc->MaxVertShare;
+	    break;
+
+	case ACTC_OUT_MIN_FAN_VERTS:
+	    *value = tc->MinFanVerts;
+	    break;
+
+	case ACTC_OUT_HONOR_WINDING:
+	    *value = tc->HonorWinding;
+	    break;
+
+	case ACTC_OUT_MAX_PRIM_VERTS:
+	    *value = tc->MaxPrimVerts;
+	    break;
+
+	default:
+	    *value = 0;
+	    return tc->Error = ACTC_INVALID_VALUE;
+	    /* break; */
+    }
+    return ACTC_NO_ERROR;
+}
+
+int actcGetParamu(ACTCData *tc, int param, unsigned int *value)
+{
+    return actcGetParami(tc, param, (int *)value);
+}
+
+static int mapEdgeTriangle(ACTCData *tc, ACTCEdge *edge, ACTCVertex *v3)
+{
+    ACTCTriangle tmp;
+    void *r;
+
+    tmp.FinalVert = v3;
+    chartedSetLabel("triangle list");
+    r = reallocAndAppend((void **)&edge->Triangles, (unsigned int*)&edge->TriangleCount,
+        sizeof(tmp), &tmp);
+    if(r == NULL) {
+	ACTC_DEBUG(fprintf(stderr, "ACTC::mapEdgeTriangle : Couldn't allocate "
+	    "%d bytes for triangles\n", sizeof(tmp) *
+	    (edge->TriangleCount + 1));)
+	return tc->Error = ACTC_ALLOC_FAILED;
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+static int unmapEdgeTriangle(ACTCData *tc, ACTCEdge *edge, ACTCVertex *v3)
+{
+    int i;
+
+    for(i = 0; i < edge->TriangleCount; i++)
+	if(edge->Triangles[i].FinalVert == v3)
+	    break;
+
+    if(i == edge->TriangleCount) {
+	ACTC_DEBUG(
+	    fprintf(stderr, "ACTC::unmapEdgeTriangle : Couldn't find third vertex"
+	        " from edge in order to delete it?!?\n");
+	    abortWithOptionalDump(tc);
+	)
+	return tc->Error = ACTC_DATABASE_CORRUPT;
+    }
+
+    edge->Triangles[i] = edge->Triangles[edge->TriangleCount - 1];
+    edge->TriangleCount --;
+
+    return ACTC_NO_ERROR;
+}
+
+static int mapVertexEdge(ACTCData *tc, ACTCVertex *v1, ACTCVertex *v2, ACTCEdge **edge)
+{
+    int i;
+    ACTCEdge tmp;
+    void *r;
+
+    for(i = 0; i < v1->EdgeCount; i++)
+        if(v1->Edges[i].V2 == v2) {
+	    v1->Edges[i].Count++;
+	    break;
+	}
+
+    if(i == v1->EdgeCount) {
+
+	tmp.V2 = v2;
+	tmp.Count = 1;
+	tmp.Triangles = NULL;
+	tmp.TriangleCount = 0;
+
+	chartedSetLabel("vert-to-edge mapping");
+        r = reallocAndAppend((void **)&v1->Edges, (unsigned int*)&v1->EdgeCount,
+	    sizeof(tmp), &tmp);
+	if(r == NULL) {
+	    ACTC_DEBUG(fprintf(stderr, "ACTC::mapVertexEdge : Couldn't reallocate "
+	        "to %d bytes for vertex's edge list\n", sizeof(tmp) *
+		v1->EdgeCount);)
+	    return tc->Error = ACTC_ALLOC_FAILED;
+	}
+    }
+    *edge = &v1->Edges[i];
+
+    return ACTC_NO_ERROR;
+}
+
+static int unmapVertexEdge(ACTCData *tc, ACTCVertex *v1, ACTCVertex *v2)
+{
+    int i;
+
+    for(i = 0; i < v1->EdgeCount; i++)
+	if(v1->Edges[i].V2 == v2)
+	    break;
+
+    if(i == v1->EdgeCount) {
+	ACTC_DEBUG(
+	    fprintf(stderr, "ACTC::unmapVertexEdge : Couldn't find edge %d,%d"
+	        " from vertex in order to unmap it?!?\n", v1->V, v2->V);
+	    abortWithOptionalDump(tc);
+	)
+	return tc->Error = ACTC_DATABASE_CORRUPT;
+    }
+
+    v1->Edges[i].Count --;
+    if(v1->Edges[i].Count == 0) {
+        if(v1->Edges[i].Triangles != NULL)
+	    free(v1->Edges[i].Triangles);
+	v1->Edges[i] = v1->Edges[v1->EdgeCount - 1];
+	v1->EdgeCount --;
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+int actcAddTriangle(ACTCData *tc, unsigned int v1, unsigned int v2, unsigned int v3)
+{
+    ACTCVertex *vertexRec1;
+    ACTCVertex *vertexRec2;
+    ACTCVertex *vertexRec3;
+
+    ACTCEdge *edge12;
+    ACTCEdge *edge23;
+    ACTCEdge *edge31;
+
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcAddTriangle : inside "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_IDLE;
+    }
+    if(!tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcAddTriangle : outside "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(incVertexValence(tc, v1, &vertexRec1) != ACTC_NO_ERROR) goto returnError1;
+    if(incVertexValence(tc, v2, &vertexRec2) != ACTC_NO_ERROR) goto free1;
+    if(incVertexValence(tc, v3, &vertexRec3) != ACTC_NO_ERROR) goto free2;
+
+    if(mapVertexEdge(tc, vertexRec1, vertexRec2, &edge12) != ACTC_NO_ERROR)
+        goto free3;
+    if(mapVertexEdge(tc, vertexRec2, vertexRec3, &edge23) != ACTC_NO_ERROR)
+        goto free4;
+    if(mapVertexEdge(tc, vertexRec3, vertexRec1, &edge31) != ACTC_NO_ERROR)
+        goto free5;
+
+    if(mapEdgeTriangle(tc, edge12, vertexRec3) != ACTC_NO_ERROR) goto free6;
+    if(mapEdgeTriangle(tc, edge23, vertexRec1) != ACTC_NO_ERROR) goto free7;
+    if(mapEdgeTriangle(tc, edge31, vertexRec2) != ACTC_NO_ERROR) goto free8;
+
+    return ACTC_NO_ERROR;
+
+    /*
+     * XXX Unfortunately, while backing out during the following
+     * statements, we might encounter errors in the database which
+     * will not get returned properly to the caller; I take heart in
+     * the fact that if such an error occurs, TC is just a moment from
+     * core dumping anyway. XXX grantham 20000615
+     */
+
+free8:
+    unmapEdgeTriangle(tc, edge23, vertexRec1);
+free7:
+    unmapEdgeTriangle(tc, edge12, vertexRec3);
+free6:
+    unmapVertexEdge(tc, vertexRec3, vertexRec1);
+free5:
+    unmapVertexEdge(tc, vertexRec2, vertexRec3);
+free4:
+    unmapVertexEdge(tc, vertexRec1, vertexRec2);
+free3:
+    decVertexValence(tc, &vertexRec3);
+free2:
+    decVertexValence(tc, &vertexRec2);
+free1:
+    decVertexValence(tc, &vertexRec1);
+returnError1:
+    return tc->Error;
+}
+
+int actcStartNextPrim(ACTCData *tc, unsigned int *v1Return, unsigned int *v2Return)
+{
+    ACTCVertex *v1 = NULL;
+    ACTCVertex *v2 = NULL;
+    int findResult;
+
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : within "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(!tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : outside "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_IDLE;
+    }
+
+    findResult = findNextFanVertex(tc, &v1);
+    if(findResult == ACTC_NO_ERROR)
+	tc->PrimType = ACTC_PRIM_FAN;
+    else if(findResult != ACTC_NO_MATCHING_VERT) {
+	ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : internal "
+	    "error finding next appropriate vertex\n");)
+	return tc->Error = findResult;
+    } else {
+	findResult = findNextStripVertex(tc, &v1);
+	if(findResult != ACTC_NO_ERROR && findResult != ACTC_NO_MATCHING_VERT) {
+	    ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : internal "
+		"error finding next appropriate vertex\n");)
+	    return tc->Error = findResult;
+	}
+	tc->PrimType = ACTC_PRIM_STRIP;
+    }
+
+    if(findResult == ACTC_NO_MATCHING_VERT) {
+	*v1Return = -1;
+	*v2Return = -1;
+	return tc->Error = ACTC_DATABASE_EMPTY;
+    }
+
+    v2 = v1->Edges[0].V2;
+
+    tc->CurWindOrder = ACTC_FWD_ORDER;
+    tc->VerticesSoFar = 2;
+
+    tc->V1 = v1;
+    tc->V2 = v2;
+
+    *v1Return = v1->V;
+    *v2Return = v2->V;
+
+    ACTC_INFO(printf("starting with edge %u, %u\n", tc->V1->V, tc->V2->V);)
+
+    return tc->PrimType;
+}
+
+static int findEdge(ACTCVertex *v1, ACTCVertex *v2, ACTCEdge **edge)
+{
+    int i;
+
+    for(i = 0; i < v1->EdgeCount; i++)
+        if(v1->Edges[i].V2 == v2) {
+	    *edge = &v1->Edges[i];
+	    return 1;
+	}
+    return 0;
+}
+
+int unmapEdgeTriangleByVerts(ACTCData *tc, ACTCVertex *v1, ACTCVertex *v2,
+    ACTCVertex *v3)
+{
+    ACTCEdge *e;
+
+    ACTC_CHECK(findEdge(v1, v2, &e));
+    unmapEdgeTriangle(tc, e, v3);
+    return ACTC_NO_ERROR;
+}
+
+int actcGetNextVert(ACTCData *tc, unsigned int *vertReturn)
+{
+    ACTCEdge *edge;
+    int wasEdgeFound = 0;
+    ACTCVertex *thirdVertex;
+    int wasFoundReversed;
+
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcGetNextVert : within BeginInput/"
+	    "EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(!tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcGetNextVert : outside BeginOutput/"
+	    "EndOutput\n");)
+	return tc->Error = ACTC_IDLE;
+    }
+    if(tc->PrimType == -1) {
+	ACTC_DEBUG(fprintf(stderr, "actcGetNextVert : Asked for next vertex "
+	    "without a primitive (got last\n    vertex already?)\n");)
+	return tc->Error = ACTC_INVALID_VALUE;
+    }
+
+    if(tc->VerticesSoFar >= tc->MaxPrimVerts) {
+	tc->PrimType = -1;
+	return tc->Error = ACTC_PRIM_COMPLETE;
+    }
+
+    if(tc->V1 == NULL || tc->V2 == NULL) {
+	tc->PrimType = -1;
+	return tc->Error = ACTC_PRIM_COMPLETE;
+    }
+
+    ACTC_INFO(printf("looking for edge %u, %u\n", tc->V1->V, tc->V2->V);)
+
+    wasFoundReversed = 0;
+
+    if(findEdge(tc->V1, tc->V2, &edge) != 0) {
+	wasEdgeFound = 1;
+    } else if(!tc->HonorWinding) {
+	wasFoundReversed = 1;
+	if(findEdge(tc->V2, tc->V1, &edge) != 0) {
+	    wasEdgeFound = 1;
+	}
+    }
+
+    if(!wasEdgeFound) {
+	tc->PrimType = -1;
+	return tc->Error = ACTC_PRIM_COMPLETE;
+    }
+
+    thirdVertex = edge->Triangles[edge->TriangleCount - 1].FinalVert;
+
+    ACTC_INFO(printf("third vertex = %u\n", thirdVertex->V);)
+    *vertReturn = thirdVertex->V;
+
+    if(wasFoundReversed) {
+	ACTC_CHECK(unmapEdgeTriangle(tc, edge, thirdVertex));
+	ACTC_CHECK(unmapEdgeTriangleByVerts(tc, tc->V1, thirdVertex, tc->V2));
+	ACTC_CHECK(unmapEdgeTriangleByVerts(tc, thirdVertex, tc->V2, tc->V1));
+	ACTC_CHECK(unmapVertexEdge(tc, tc->V2, tc->V1));
+	ACTC_CHECK(unmapVertexEdge(tc, tc->V1, thirdVertex));
+	ACTC_CHECK(unmapVertexEdge(tc, thirdVertex, tc->V2));
+    } else {
+	ACTC_CHECK(unmapEdgeTriangle(tc, edge, thirdVertex));
+	ACTC_CHECK(unmapEdgeTriangleByVerts(tc, tc->V2, thirdVertex, tc->V1));
+	ACTC_CHECK(unmapEdgeTriangleByVerts(tc, thirdVertex, tc->V1, tc->V2));
+	ACTC_CHECK(unmapVertexEdge(tc, tc->V1, tc->V2));
+	ACTC_CHECK(unmapVertexEdge(tc, tc->V2, thirdVertex));
+	ACTC_CHECK(unmapVertexEdge(tc, thirdVertex, tc->V1));
+    }
+    ACTC_CHECK(decVertexValence(tc, &tc->V1));
+    ACTC_CHECK(decVertexValence(tc, &tc->V2));
+    ACTC_CHECK(decVertexValence(tc, &thirdVertex));
+
+    if(tc->PrimType == ACTC_PRIM_FAN) {
+        tc->V2 = thirdVertex;
+    } else /* PRIM_STRIP */ {
+	if(tc->CurWindOrder == ACTC_FWD_ORDER)
+	    tc->V1 = thirdVertex;
+	else
+	    tc->V2 = thirdVertex;
+	tc->CurWindOrder = !tc->CurWindOrder;
+    }
+
+    tc->VerticesSoFar++;
+    return ACTC_NO_ERROR;
+}
+
+int actcTrianglesToPrimitives(ACTCData *tc, int triangleCount,
+    unsigned int (*triangles)[3], int primTypes[], int primLengths[], unsigned int vertices[],
+    int maxBatchSize)
+{
+    int r;
+    int curTriangle;
+    int curPrimitive;
+    unsigned int curVertex;
+    int prim;
+    unsigned int v1, v2, v3;
+    int lastPrim;
+    int passesWithoutPrims;
+    int trisSoFar;
+
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcTrianglesToPrimitives : within BeginInput/"
+	    "EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcTrianglesToPrimitives : within"
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_DURING_OUTPUT;
+    }
+    curTriangle = 0;
+    curPrimitive = 0;
+    curVertex = 0;
+    passesWithoutPrims = 0;
+
+    actcMakeEmpty(tc);
+
+    ACTC_CHECK(actcBeginInput(tc));
+    trisSoFar = 0;
+    while(curTriangle < triangleCount) {
+	r = actcAddTriangle(tc, triangles[curTriangle][0],
+	    triangles[curTriangle][1], triangles[curTriangle][2]);
+	trisSoFar++;
+	curTriangle++;
+	if((trisSoFar >= maxBatchSize) ||
+	    (r == ACTC_ALLOC_FAILED && curTriangle != triangleCount) ||
+	    (r == ACTC_NO_ERROR && curTriangle == triangleCount)) {
+
+	    /* drain what we got */
+	    trisSoFar = 0;
+	    ACTC_CHECK(actcEndInput(tc));
+	    ACTC_CHECK(actcBeginOutput(tc));
+	    lastPrim = curPrimitive;
+	    while((prim = actcStartNextPrim(tc, &v1, &v2)) != ACTC_DATABASE_EMPTY) {
+		ACTC_CHECK(prim);
+		primTypes[curPrimitive] = prim;
+		primLengths[curPrimitive] = 2;
+		vertices[curVertex++] = v1;
+		vertices[curVertex++] = v2;
+		while((r = actcGetNextVert(tc, &v3)) != ACTC_PRIM_COMPLETE) {
+		    ACTC_CHECK(r);
+		    vertices[curVertex++] = v3;
+		    primLengths[curPrimitive]++;
+		}
+		curPrimitive++;
+	    }
+	    ACTC_CHECK(actcEndOutput(tc));
+	    if(r == ACTC_ALLOC_FAILED && curPrimitive == lastPrim) {
+	        if(passesWithoutPrims == 0) {
+		    /* not enough memory to add a triangle and */
+		    /* nothing in the database, better free everything */
+		    /* and try again */
+		    actcMakeEmpty(tc);
+		} else {
+		    /* cleaned up and STILL couldn't get a triangle in; */
+		    /* give up */
+		    return tc->Error = ACTC_ALLOC_FAILED;
+		}
+		passesWithoutPrims++;
+	    }
+	    ACTC_CHECK(actcBeginInput(tc));
+	} else
+	    ACTC_CHECK(r);
+	if(r == ACTC_ALLOC_FAILED)
+	    curTriangle--;
+    }
+    ACTC_CHECK(actcEndInput(tc));
+
+    actcMakeEmpty(tc);
+
+    return curPrimitive;
+}
+
+/* vi:tabstop=8
+ */
Index: branches/heathaze/src/lib/graphics/importer/tc.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/tc.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/tc.h	(revision 9940)
@@ -0,0 +1,77 @@
+/*
+ * $Header: /home/grantham/cvsroot/projects/modules/tc/tc.h,v 1.14 2000/10/03 07:19:20 grantham Exp $
+ */
+
+#if !defined(_ACTC_H_)
+#define _ACTC_H_
+
+#include <sys/types.h>
+
+typedef struct _ACTCData ACTCData;
+
+/*
+    Abbreviated:
+        vertex          vert
+        primitive       prim
+        maximum         max
+        minimum         min
+        parameter       param
+ */
+
+#define ACTC_NO_ERROR                   0
+#define ACTC_ALLOC_FAILED               -0x2000
+#define ACTC_DURING_INPUT               -0x2001
+#define ACTC_DURING_OUTPUT              -0x2002
+#define ACTC_IDLE                       -0x2003
+#define ACTC_INVALID_VALUE              -0x2004
+#define ACTC_DATABASE_EMPTY             -0x2005
+#define ACTC_DATABASE_CORRUPT           -0x2006
+#define ACTC_PRIM_COMPLETE              -0x2007
+
+#define ACTC_OUT_MIN_FAN_VERTS          0x1000
+#define ACTC_OUT_HONOR_WINDING          0x1001
+#define ACTC_OUT_MAX_PRIM_VERTS         0x1004
+#define ACTC_IN_MIN_VERT                0x1005
+#define ACTC_IN_MAX_VERT                0x1006
+#define ACTC_IN_MAX_VERT_SHARING        0x1007
+#define ACTC_IN_MAX_EDGE_SHARING        0x1008
+#define ACTC_MINOR_VERSION              0x1009
+#define ACTC_MAJOR_VERSION              0x1010
+
+#define ACTC_PRIM_FAN                   0x2000
+#define ACTC_PRIM_STRIP                 0x2001
+
+#define ACTC_TRUE                       1
+#define ACTC_FALSE                      0
+
+ACTCData *actcNew(void);
+int actcParami(ACTCData *tc, int param, int value);
+int actcGetParami(ACTCData *tc, int param, int *value);
+int actcParamu(ACTCData *tc, int param, unsigned int value);
+int actcGetParamu(ACTCData *tc, int param, unsigned int *value);
+int actcGetError(ACTCData *tc);
+int actcMakeEmpty(ACTCData *tc);
+void actcDelete(ACTCData *tc);
+void actcDumpState(ACTCData *tc, FILE *fp);
+
+int actcBeginInput(ACTCData *tc);
+int actcGetIsDuringInput(ACTCData *tc);
+int actcAddTriangle(ACTCData *tc, unsigned int v1, unsigned int v2, unsigned int v3);
+int actcEndInput(ACTCData *tc);
+
+int actcBeginOutput(ACTCData *tc);
+int actcGetIsDuringOutput(ACTCData *tc);
+int actcStartNextPrim(ACTCData *tc, unsigned int *v1Return, unsigned int *v2Return);
+int actcGetNextVert(ACTCData *tc, unsigned int *vReturn);
+int actcEndOutput(ACTCData *tc);
+
+int actcGetMemoryAllocation(ACTCData *tc, size_t *bytesAllocated);
+
+int actcTrianglesToPrimitives(ACTCData *tc, int triangleCount,
+    unsigned int (*triangles)[3], int primTypes[], int primLengths[], unsigned int vertices[],
+    int maxBatchSize);
+
+#endif /* _ACTC_H_ */
+
+/* vi:tabstop=8
+ */
Index: branches/heathaze/src/lib/graphics/importer/texture.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/texture.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/texture.cc	(revision 9940)
@@ -0,0 +1,392 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "texture.h"
+
+#include "debug.h"
+#include "compiler.h"
+
+#ifdef HAVE_SDL_SDL_H
+#include <SDL/SDL_image.h>
+#include <SDL/SDL_endian.h>
+#include <SDL/SDL_byteorder.h>
+#else
+#include <SDL_endian.h>
+#include <SDL_image.h>
+#include <SDL_byteorder.h>
+#endif
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+/*
+ * On the BIG_ENDIAN architecture, the 24 and 32bit bitmaps have
+ * different masks. If you don't do this distinction properly,
+ * you will get weird-looking textures.
+ */
+Uint32 alphaMask[] = {
+                       0xFF000000,
+                       0x00FF0000,
+                       0x0000FF00,
+                       0x000000FF,
+                     };
+
+Uint32 opaqueMask[] = {
+                        0x00FF0000,
+                        0x0000FF00,
+                        0x000000FF,
+                        0xFF000000
+                      };
+#else
+/*
+* On the LIL_ENDIAN architecture everything is fine and easy. The 24
+* and 32bit bitmaps have the same masks.
+*/
+Uint32 alphaMask[] = {
+                       0x000000FF,
+                       0x0000FF00,
+                       0x00FF0000,
+                       0xFF000000,
+                     };
+
+Uint32 *opaqueMask = alphaMask;
+#endif
+
+ObjectListDefinition(Texture);
+
+/**
+ * @brief creates an Empty Texture,
+ *
+ * onto this Texture you can load non-empty textures with the =
+ * operator.
+ */
+Texture::Texture()
+{
+  this->init();
+}
+
+/**
+ * @brief Creates a Texture from another Texture (copy Constructor)
+ * @param texture the Texture to copy.
+ *
+ * @note only the Data-Pointer will be shared.
+ */
+Texture::Texture(const Texture& texture)
+    : data(texture.data)
+{
+  this->registerObject(this, Texture::_objectList);
+  this->priority = 0.5;
+}
+
+/**
+ * @brief Creates a new empty Texture with the below properties.
+ * @param target: the GL-Target.
+ * @param width: the Width of the Texture.
+ * @param height: The Hight of the Texture.
+ * @param channels: also known as BitsPerPixel.
+ * @param type the Type of Texture.
+ */
+Texture::Texture(GLenum target, unsigned int width, unsigned int height, unsigned int channels, GLenum type)
+{
+  this->init();
+
+  SDL_Surface * surface = SDL_CreateRGBSurface(SDL_HWSURFACE, width, height, channels,
+                          alphaMask[0], alphaMask[1], alphaMask[2], alphaMask[3]);
+
+  if(surface != NULL)
+  {
+    this->data->loadSurface(surface, target);
+    SDL_FreeSurface(surface);
+  }
+}
+
+/**
+ * @brief Constructor for a Texture
+ * @param imageName: the Name of the Texutre (FileName)
+ * @param target: the GL-Target to load the Texture to.
+ */
+Texture::Texture(const std::string& imageName, GLenum target)
+{
+  this->init();
+
+  if (!imageName.empty())
+  {
+    this->setName(imageName);
+    this->loadImage(imageName, target);
+  }
+}
+
+
+/**
+ * @brief creates a Texture out of a SDL_Surface.
+ * @param surface: the Surface to load.
+ * @param target: the GL-Target to load this to.
+ */
+Texture::Texture(SDL_Surface* surface, GLenum target)
+{
+  this->init();
+
+  if(surface != NULL)
+  {
+    this->data->loadSurface(surface, target);
+  }
+}
+
+/**
+ * @brief Initializes the Texture.
+ */
+void Texture::init()
+{
+  this->registerObject(this, Texture::_objectList);
+
+  this->data = TextureData::Pointer(new TextureData());
+
+  this->priority = 0.5;
+}
+
+/**
+ * @brief Destructor of a Texture
+ *
+ * Frees Data, and deletes the textures from GL
+ */
+Texture::~Texture()
+{}
+
+/**
+ * @brief copies the Data from texture to this texture.
+ * @param texture the Texture to copy into this one.
+ * @returns the Texture.
+ */
+Texture& Texture::operator=(const Texture& texture)
+{
+  this->data = texture.data;
+
+  return *this;
+}
+
+Texture& Texture::operator=(const TextureData::Pointer& textureDataPointer)
+{
+  this->data = textureDataPointer;
+  return *this;
+}
+
+
+/**
+ * @brief loads an Image from a file to a Texture
+ * @param imageName The image to load
+*/
+bool Texture::loadImage(const std::string& imageName, GLenum target)
+{
+  if (Texture::texturesEnabled)
+  {
+    if (!imageName.empty())
+    {
+      SDL_Surface* tmpSurf;
+
+      // load the new Image to memory
+      tmpSurf = IMG_Load(imageName.c_str());
+      if(tmpSurf != NULL)
+      {
+        this->data->loadSurface(tmpSurf, target);
+        SDL_FreeSurface(tmpSurf);
+        return true;
+      }
+      else
+      {
+        PRINTF(1)("IMG_Load: %s\n", IMG_GetError());
+        this->setTexture(0);
+        return false;
+      }
+    }
+    else
+    {
+      PRINTF(2)("Image-Name not specified\n");
+      return false;
+    }
+  }
+  return false;
+}
+
+/**
+ * @brief rebuilds the texture.
+ *
+ * reloads the Texture from Memory to OpenGL.
+ */
+bool Texture::rebuild()
+{
+  this->data->setTexture(0);
+
+  if (this->data->getStoredImage() != NULL)
+  {
+    PRINTF(3)("Reloading Texture of %s '%s'\n", this->getClassCName(), this->getCName());
+    this->setTexture(Texture::loadTexToGL(this->data->getStoredImage()));
+  }
+  return true;
+}
+
+bool Texture::texturesEnabled = true;
+
+/**
+ * @brief enables, disables textures
+ * @param texturesEnabled true if the textures should be enabled
+ */
+void Texture::setTextureEnableState(bool texturesEnabled)
+{
+  Texture::texturesEnabled = texturesEnabled;
+}
+
+
+//////////////////////////////////////
+// UTILITY FUNCTIONALITY OF TEXTURE //
+//////////////////////////////////////
+/**
+ * @brief converts surface to a new SDL_Surface, that is loadable by openGL
+ * @param surface the Surface to convert
+ * @param hasAlpha if the newly created Surface has an alpha channel, true is returned otherwise false.
+ * @returns a !!new!! Surface, that is loadable by openGL.
+ */
+SDL_Surface* Texture::prepareSurface(SDL_Surface* surface, bool& hasAlpha)
+{
+  assert(surface != NULL);
+  PRINTF(4)("Loading texture to OpenGL-Environment.\n");
+
+  SDL_Surface* retSurface;
+  SDL_Rect area;
+  Uint32 saved_flags;
+  Uint8  saved_alpha;
+  hasAlpha = false;
+  int pixelDepth = 24;
+
+  Uint32* mask = opaqueMask;
+
+  /* Save the alpha blending attributes */
+  saved_flags = surface->flags&(SDL_SRCALPHA | SDL_RLEACCELOK);
+  saved_alpha = surface->format->alpha;
+  if ( saved_flags & SDL_SRCALPHA )
+  {
+    SDL_SetAlpha(surface, 0, 0);
+    hasAlpha = true;
+    pixelDepth = 32;
+    mask = alphaMask;
+  }
+
+  retSurface = SDL_CreateRGBSurface(SDL_HWSURFACE,
+                                    surface->w, surface->h,
+                                    pixelDepth,
+                                    mask[0], mask[1], mask[2], mask[3] );
+  if ( retSurface == NULL )
+    return NULL;
+
+  /* Copy the surface into the GL texture this->data->getStoredImage() */
+  area.x = 0;
+  area.y = 0;
+  area.w = surface->w;
+  area.h = surface->h;
+  SDL_BlitSurface(surface, &area, retSurface, &area);
+
+  /* Restore the alpha blending attributes */
+  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA )
+  {
+    SDL_SetAlpha(surface, saved_flags | SDL_OPENGL, saved_alpha);
+    hasAlpha = true;
+  }
+
+  return (retSurface);
+}
+
+
+/**
+ * @brief Loads a Texture to the openGL-environment.
+ * @param surface the Image to load to openGL
+ * @returns The ID of the texture.
+ */
+GLuint Texture::loadTexToGL (const SDL_Surface* surface, GLenum target)
+{
+  //   if (this->data->getTexture() != 0 && glIsTexture(this->data->getTexture()))
+  //     glDeleteTextures(1, &this->data->getTexture());
+  //   this->data->getTexture() = 0;
+  assert(surface != NULL);
+
+  int      errorCode = 0;           //!< the error code for the texture loading functions
+  GLuint   texture = 0;             //!< the OpenGL texture handle
+  //int      mipmapLevel = 0;         //!< the maximum mipmap level for this texture
+  //int      mipmapWidth = 0;         //!< the width of the mipmap
+  //int      mipmapHight = 0;         //!< the height of the mipmap
+  GLenum   format = GL_RGB;
+  if (surface->format->BitsPerPixel == 32)
+  {
+    format = GL_RGBA;
+    assert(surface->format->BitsPerPixel == 32);
+  }
+  else
+  {
+    assert(surface->format->BitsPerPixel == 24);
+  }
+
+  /* Create an OpenGL texture for the this->data->getStoredImage() */
+  Texture::generateTexture(texture, target);
+
+  //   glTexImage2D(target,  0,  format,
+  //                surface->w,  surface->h,
+  //                0, format,  GL_UNSIGNED_BYTE,
+  //                surface->pixels);
+
+  ///  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  ///  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
+
+  /// TODO CHECK THIS BACK in
+  //glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_PRIORITY, this->priority);
+
+  /* build the Texture  OpenGL V >= 1.1 */
+
+  //  printf("%s, w:%d h:%d, 0x%x\n", this->getName(), surface->w, surface->h, target);
+
+  /* control the mipmap levels */
+  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MIN_LOD, 5);
+  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MAX_LOD, 0);
+
+  // build the MipMaps automaticaly
+  errorCode = gluBuild2DMipmaps(target, format,
+                                surface->w,  surface->h,
+                                format,  GL_UNSIGNED_BYTE,
+                                surface->pixels
+                               );
+  if(unlikely(errorCode != 0))
+    PRINTF(1)("Error while loading texture (mipmap generation), gluBuild2DMipmaps returned %i\n", errorCode);
+
+  return texture;
+}
+
+/**
+ * @brief creates a new Texture.
+ * @param texture: the Texture is loaded here (should be 0 and will be set to the Value of the New Texture.)
+ * @param target: The GL-Target to generate the texture on.
+ *
+ * @note this is the real GL-texture-creat-wrapper, where the Texture is Created
+ */
+void Texture::generateTexture(GLuint& texture, GLenum target)
+{
+  if (texture == 0 && !glIsTexture(texture))
+  {
+    glGenTextures(1, &texture);
+  }
+  glBindTexture(target, texture);
+
+  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
+
+  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+}
Index: branches/heathaze/src/lib/graphics/importer/texture.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/texture.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/texture.h	(revision 9940)
@@ -0,0 +1,73 @@
+/*!
+ * @file texture.h
+ * @brief Contains the texture class, that handles the reading of Images into Texture-files.
+ */
+
+#ifndef _TEXTURE_H
+#define _TEXTURE_H
+
+#include "base_object.h"
+
+#include "glincl.h"
+#include "count_pointer.h"
+#include "texture_data.h"
+
+
+/* Forward Declaration */
+struct SDL_Surface;
+
+//! A Class, that reads in Textures from different fileformats.
+class Texture : public BaseObject
+{
+  ObjectListDeclaration(Texture);
+public:
+  Texture();
+  Texture(const Texture& texture);
+  Texture(GLenum target, unsigned int width, unsigned int height, unsigned int channels, GLenum type);
+  Texture(const std::string& imageName, GLenum target = GL_TEXTURE_2D);
+  Texture(SDL_Surface* surface, GLenum target = GL_TEXTURE_2D);
+
+  Texture& operator=(const Texture& texture);
+  Texture& operator=(const TextureData::Pointer& textureDataPointer);
+  void acquireData(const TextureData::Pointer& textureDataPointer) { this->data = textureDataPointer; };
+  const TextureData::Pointer& dataPointer() const { return data; }
+
+  virtual ~Texture();
+
+  bool loadImage(const std::string& imageName, GLenum target = GL_TEXTURE_2D);
+  bool loadSurface(SDL_Surface* surface, GLenum target = GL_TEXTURE_2D);
+  virtual bool rebuild();
+
+  /** @returns The textureID of this texture.  */
+  inline GLuint getTexture() const { return this->data->getTexture(); };
+  /** @returns true if texture has alpha, false otherwise */
+  inline bool hasAlpha() const  { return this->data->hasAlpha(); }
+  /** @returns the stored image of this Texture */
+  const SDL_Surface* const getStoredImage() const { return this->data->getStoredImage(); };
+
+
+
+  static void setTextureEnableState(bool texturesEnabled);
+  /** @returns true if Textures are enabled */
+  static bool getTextureEnableState() { return Texture::texturesEnabled; };
+  // Utility functionality:
+  static SDL_Surface* prepareSurface(SDL_Surface* input, bool& hasAlpha);
+  static GLuint loadTexToGL (const SDL_Surface* surface, GLenum target = GL_TEXTURE_2D);
+
+protected:
+  bool setSurface(SDL_Surface* newSurface) { return this->data->setSurface(newSurface); };
+  bool setAlpha(bool hasAlpha) { return this->data->setAlpha(hasAlpha); };
+  bool setTexture(GLuint texture) { return this->data->setTexture(texture); };
+
+private:
+  void init();
+  static void generateTexture(GLuint& texture, GLenum target);
+
+private:
+  TextureData::Pointer          data;               //!< The TextureData
+  GLclampf                      priority;           //!< the priority of the current texture (used for garphics cards with limited mem)
+
+  static bool                   texturesEnabled;    //!< If the Textures are enabled.
+};
+
+#endif /* _TEXTURE_H */
Index: branches/heathaze/src/lib/graphics/importer/texture_data.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/texture_data.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/texture_data.cc	(revision 9940)
@@ -0,0 +1,106 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "texture.h"
+
+#include "debug.h"
+#include "compiler.h"
+
+#include "sdlincl.h"
+
+/**
+ * @brief creates a new Texture Data.
+ */
+TextureData::TextureData()
+{
+  this->bAlpha = false;
+  this->texture = 0;
+  this->image = NULL;
+}
+
+
+/**
+ * @brief Destructor of a Texture
+ *
+ *  Frees Data, and deletes the textures from GL
+ */
+TextureData::~TextureData()
+{
+  if (this->texture != 0)
+    glDeleteTextures(1, &this->texture);
+  if (this->image != NULL)
+    SDL_FreeSurface(this->image);
+}
+
+
+/**
+ * @brief Loads an SDL_Surface.
+ * @param surface the Surface to Load.
+ * @param target the GL-Target to load the Surface to default GL_TEXTURE_2D
+ * @returns true on success, false otherwise.
+ */
+bool TextureData::loadSurface(SDL_Surface* surface, GLenum target)
+{
+  if (Texture::getTextureEnableState())
+  {
+    SDL_Surface* newSurf = Texture::prepareSurface(surface, this->bAlpha);
+    if (newSurf != NULL)
+    {
+      this->setSurface(newSurf);
+      this->setTexture(Texture::loadTexToGL(newSurf, target));
+      return true;
+    }
+  }
+  return false;
+}
+
+
+
+/**
+ * @brief set the surface this Texture handles
+ * @param newSurface the new Surface to set as the image for this Texture.
+ * @returns true on success.
+ *
+ * This deletes the old version of the stored Texture,
+ * and sets the newly given Surface as current.
+ */
+bool TextureData::setSurface(SDL_Surface* newSurface)
+{
+  if (this->image != NULL)
+    SDL_FreeSurface(this->image);
+
+  this->image = newSurface;
+
+  return (this->image != NULL);
+}
+
+
+/**
+ * @brief sets a new Texture to the Data.
+ * @param texture the Texture
+ * @returns true on success.
+ */
+bool TextureData::setTexture(GLuint texture)
+{
+     // unload the old Texture.
+  if (this->texture != 0 && glIsTexture(this->getTexture()))
+  {
+    glDeleteTextures(1, &this->texture);
+  }
+  this->texture = texture;
+  return (texture != 0);
+}
Index: branches/heathaze/src/lib/graphics/importer/texture_data.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/texture_data.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/texture_data.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file texture_data.h
+ * @brief Contains the texture class, that handles the reading of Images into Texutre-files.
+ */
+
+#ifndef _TEXTURE_DATA_H
+#define _TEXTURE_DATA_H
+
+#include "base_object.h"
+
+#include "glincl.h"
+#include "count_pointer.h"
+
+/* Forward Declaration */
+struct SDL_Surface;
+
+
+class TextureData
+{
+  public:
+    typedef CountPointer<TextureData> Pointer;
+  public:
+    TextureData();
+    ~TextureData();
+
+    inline GLuint getTexture() const { return this->texture; };
+    /** @returns true if texture has alpha, false otherwise */
+    inline bool hasAlpha() const  {return this->bAlpha; }
+    /** @returns the stored image of this Texture */
+    const SDL_Surface* const getStoredImage() const { return this->image; };
+
+    bool loadSurface(SDL_Surface* surface, GLenum target = GL_TEXTURE_2D);
+
+    bool rebuild();
+
+    bool setSurface(SDL_Surface* newSurface);
+    /** @returns true if the Surface has an Alpha Value. */
+    bool setAlpha(bool hasAlpha) { this->bAlpha = hasAlpha; return this->bAlpha; };
+    bool setTexture(GLuint texture);
+
+  private:
+    GLuint           texture;            //!< The Texture-ID of opengl from this Texture.
+    bool             bAlpha;             //!< if the texture has an alpha channel.
+    SDL_Surface*     image;              //!< The SDL_Surfce that stores the Texture on it.
+};
+
+#endif /* _TEXTURE_DATA_H */
Index: branches/heathaze/src/lib/graphics/importer/texture_sequence.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/texture_sequence.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/texture_sequence.cc	(revision 9940)
@@ -0,0 +1,243 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "texture_sequence.h"
+
+#include "debug.h"
+#include "graphics_engine.h"
+#include <stdarg.h>
+
+#ifdef HAVE_SDL_IMAGE_H
+#include <SDL_image.h>
+#else
+#include <SDL/SDL_image.h>
+#endif
+
+ObjectListDefinition(TextureSequence);
+
+/**
+ * @brief Constructor for a Texture
+ */
+TextureSequence::TextureSequence(unsigned int count, ...)
+{
+  this->registerObject(this, TextureSequence::_objectList);
+
+  va_list textureNameList;
+  va_start(textureNameList, count);
+
+  for (unsigned int i = 0; i < count; i++)
+  {
+    this->addFrame(va_arg(textureNameList, char*));
+  }
+  va_end(textureNameList);
+
+  this->loadImageSeries(count, textureNameList);
+}
+
+/**
+ * @brief Creates an ImageSeries out of TextureNames.
+ * @param textureNames The Names of the Textures
+ * @param prependFolder Optional you can prepend a Folder of Textures.
+ */
+TextureSequence::TextureSequence(const std::vector<std::string>& textureNames, const std::string& prependFolder)
+{
+  this->registerObject(this, TextureSequence::_objectList);
+  this->loadImageSeries(textureNames, prependFolder);
+}
+
+
+/**
+ * @brief Destructor of a TextureSequence
+ *
+ * Frees Data, and deletes the textures from GL
+ */
+TextureSequence::~TextureSequence()
+{
+  this->clearLists();
+}
+
+void TextureSequence::clearLists()
+{
+  // delete all images
+  while(!this->images.empty())
+  {
+    SDL_FreeSurface(this->images.back());
+    this->images.pop_back();
+  }
+
+  // delete all textures.
+  while(!this->textures.empty())
+  {
+    if (glIsTexture(this->textures.back()))
+      glDeleteTextures(1, &this->textures.back());
+    this->textures.pop_back();
+  }
+}
+
+/**
+ * @brief loads an image Sequence
+ * @param count how many images to load to the TextureSequence
+ * @param ... the names of the Images to load
+ * @returns true on success, false otherwise
+ */
+bool TextureSequence::loadImageSeries(unsigned int count, ...)
+{
+  bool retVal = true;
+  va_list textureNameList;
+  va_start(textureNameList, count);
+
+  for (unsigned int i = 0; i < count; i++)
+  {
+    if( !this->addFrame(va_arg(textureNameList, char*)))
+      retVal = false;
+  }
+  va_end(textureNameList);
+  return retVal;
+}
+
+/**
+ * @brief Load an TextureSeries from TextureNames
+ * @param textureNames The Names of the Textures.
+ * @param prependFolder (optional) the Folder to prepend
+ * @return true on success.
+ */
+bool TextureSequence::loadImageSeries(const std::vector<std::string>& textureNames, const std::string& prependFolder)
+{
+  bool retVal = true;
+  for (unsigned int i = 0; i < textureNames.size(); i++)
+  {
+    if( !this->addFrame(prependFolder + textureNames[i]))
+      retVal = false;
+  }
+  return retVal;
+}
+
+
+/**
+ * @brief Loads an Image-Series into the TextureSequence.
+ * @param imageNameSubstitue The Prefix of the Image
+ * @param from From which image
+ * @param to To which image
+ * @return true on success.
+ *
+ * @example to load the Files image_001.jpg, image_002.jpg, ... image_099.jpg
+ * use loadImageSeries("image_###.jpg", 0, 99);
+ * @note important is, that the count of ###'s is correct.
+ */
+bool TextureSequence::loadImageSeries(const std::string& imageNameSubstitue, unsigned int from, unsigned int to)
+{
+  unsigned int index = 0;
+  unsigned int frameSize = 0;
+  // search for the special character # in the LoadParam
+  if ((index = imageNameSubstitue.find("_#")) != std::string::npos)
+  {
+    std::string _imageNameSubstitue = imageNameSubstitue;
+    index++; // start at #
+    while(imageNameSubstitue[index+frameSize] == '#')
+    {
+      _imageNameSubstitue[index+frameSize] = '0';
+      frameSize++;
+    }
+
+    PRINTF(4)("Found %d '#'s in %s... searching for LOD's\n", frameSize, imageNameSubstitue.c_str());
+    char tmpString[32];
+    for (unsigned int i = from; i < to; i++)
+    {
+      sprintf(tmpString, "%d", i);
+      _imageNameSubstitue.replace(index+frameSize -strlen(tmpString), strlen(tmpString), tmpString);
+      this->addFrame(_imageNameSubstitue);
+    }
+    return true;
+  }
+  return false;
+}
+
+
+/**
+ * @brief adds a new Frame to this Sequence (at the end)
+ * @param imageName the Name of the Image to add
+ * @returns true on success
+ */
+bool TextureSequence::addFrame(const std::string& imageName)
+{
+  SDL_Surface* addSurface = IMG_Load(imageName.c_str());
+  if (addSurface == NULL)
+  {
+    PRINTF(2)("Unable to load Image %s\n", imageName.c_str());
+    return false;
+  }
+  bool success = this->addFrame(addSurface);
+  SDL_FreeSurface(addSurface);
+
+  return success;
+}
+
+/**
+ * @brief adds a new Frame at the end of the Sequence.
+ * @param surface the Surface to add at the end of the Sequence.
+ */
+bool TextureSequence::addFrame(SDL_Surface* surface)
+{
+  if (surface == NULL)
+    return false;
+  bool hasAlpha;
+  SDL_Surface* newSurf = this->prepareSurface(surface, hasAlpha);
+  if (newSurf != NULL)
+  {
+    this->images.push_back(newSurf);
+    this->textures.push_back(Texture::loadTexToGL(newSurf));
+  }
+  this->setAlpha(hasAlpha);
+
+  return true;
+}
+
+/**
+ * @brief adds a new Frame at the end of the Sequence.
+ * @param texture the texture to add at the end of the Sequence.
+ */
+bool TextureSequence::addFrame(GLuint texture)
+{
+  if (texture == 0)
+    return false;
+  this->textures.push_back(texture);
+
+  return true;
+}
+
+
+
+/**
+ * @brief rebuilds all the textures from the Images stored in this FrameSequence
+ */
+bool TextureSequence::rebuild()
+{
+  PRINTF(3)("Reloading TextureSequence of %s '%s'\n", this->getClassCName(), this->getCName());
+
+  for (unsigned int i = 0; i < this->textures.size(); i++)
+  {
+    if (glIsTexture(this->textures[i]))
+    {
+      glDeleteTextures(1, &this->textures[i]);
+      this->textures[i] = 0;
+    }
+
+    if (this->images[i] != NULL)
+      this->textures[i] = loadTexToGL(this->images[i]);
+  }
+  return true;
+}
Index: branches/heathaze/src/lib/graphics/importer/texture_sequence.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/texture_sequence.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/texture_sequence.h	(revision 9940)
@@ -0,0 +1,51 @@
+/*!
+ * @file texture_sequence.h
+ * @brief Contains the texture_sequence class, that handles the reading of Image-files into multiple Texutres.
+ */
+
+#ifndef _TEXTURE_SEQUENCE_H
+#define _TEXTURE_SEQUENCE_H
+
+#include "texture.h"
+
+#include <vector>
+
+
+//! A Class, that reads in Textures from different fileformats.
+class TextureSequence : public Texture
+{
+  ObjectListDeclaration(TextureSequence);
+  public:
+    TextureSequence(unsigned int count = 0, ...);
+    TextureSequence(const std::vector<std::string>& textureNames, const std::string& prependFolder = "");
+    //  Texture(TEXTURE_TYPE type, int resolution);
+    virtual ~TextureSequence();
+
+    bool loadImageSeries(unsigned int count, ...);
+    bool loadImageSeries(const std::vector<std::string>& textureNames, const std::string& prependFolder = "");
+    bool loadImageSeries(const std::string& imageNameSubstitue, unsigned int from, unsigned int to);
+    bool addFrame(const std::string& image);
+    bool addFrame(SDL_Surface* surface);
+    bool addFrame(GLuint texture);
+
+    void clearLists();
+
+    virtual bool rebuild();
+
+    /** @returns the count of frames in this sequence */
+    inline unsigned int getFrameCount() const { return this->textures.size(); };
+    /** @returns true if no Textures are stored inside of this TextureSequence */
+    inline bool empty() const { return textures.empty(); };
+
+    //void gotoFrame(unsigned int frameNumber);
+    /** @returns The textureID of the Frame @param frameNumber the n-th frame this texture-series.  */
+    inline GLuint getFrameTexture(unsigned int frameNumber) const { return (this->textures.size()>frameNumber)?this->textures[frameNumber]:0; };
+    /** @returns The SDL_Surface of the image at Frame @param frameNumber the n-th frame of this image-seriers */
+    const SDL_Surface* const getFrameImage(unsigned int frameNumber) const { return (this->images.size()>frameNumber)?this->images[frameNumber]:NULL; };
+
+  private:
+    std::vector<GLuint>          textures;            //!< The Texture-ID of opengl from this Texture.
+    std::vector<SDL_Surface*>    images;              //!< The SDL_Surfce that stores the Texture on it.
+};
+
+#endif /* _TEXTURE_SEQUENCE_H */
Index: branches/heathaze/src/lib/graphics/importer/vertex_array_model.cc
===================================================================
--- branches/heathaze/src/lib/graphics/importer/vertex_array_model.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/vertex_array_model.cc	(revision 9940)
@@ -0,0 +1,363 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "vertex_array_model.h"
+
+#include <stdarg.h>
+#include "debug.h"
+
+#include "tc.h"
+
+
+ObjectListDefinition(VertexArrayModel);
+
+/////////////
+/// MODEL ///
+/////////////
+/**
+ * @brief Creates a 3D-VertexArrayModel.
+ *
+ * assigns it a Name and a Type
+ */
+VertexArrayModel::VertexArrayModel()
+{
+  this->registerObject(this, VertexArrayModel::_objectList);
+
+  this->newStripe();
+}
+
+/**
+ * @brief special copy constructor for converting Models to VertexArray-Stripes
+ * @param model the Model to produce a VertexArray model from.
+ *
+ * Code that uses Brad Granthams
+ * excelent TC-code for generating stripes out of a mix of ModelCoordinates.
+ */
+VertexArrayModel::VertexArrayModel(const Model& model)
+{
+  this->registerObject(this, VertexArrayModel::_objectList);
+
+  // importing the data to the new Model.
+  this->newStripe();
+
+  for (unsigned int i = 0; i < model.getVertexCount()*3; i+=3)
+    this->addVertex(model.getVertexArray()[i], model.getVertexArray()[i+1], model.getVertexArray()[i+2]);
+  for (unsigned int i = 0; i < model.getVertexCount()*3; i+=3)
+    this->addColor((float)i / (float)model.getVertexCount(), 0, 0);
+
+  for (unsigned int i = 0; i < model.getNormalsCount()*3; i+=3)
+     this->addNormal(model.getNormalsArray()[i], model.getNormalsArray()[i+1], model.getNormalsArray()[i+2]);
+  for (unsigned int i = 0; i < model.getTexCoordCount(); i+=2)
+     this->addTexCoor(model.getTexCoordArray()[i], model.getTexCoordArray()[i+1]);
+
+
+  // The acTC object generating this Model. //
+  ACTCData *tc;
+  tc = actcNew();
+  if(tc == NULL) {
+    /* memory allocation failed */
+    /* print error here and exit or whatever */
+  }
+
+  // inputing the data of model to the tc
+  actcBeginInput(tc);
+  for(unsigned int i = 0; i < model.getTriangleCount(); i++)
+  {
+      actcAddTriangle(tc,
+                      model.getTriangles()[i].indexToVertices[0],
+                      model.getTriangles()[i].indexToVertices[1],
+                      model.getTriangles()[i].indexToVertices[2]);
+  }
+  actcEndInput(tc);
+
+
+
+  int prim;
+  unsigned int v1, v2, v3;
+
+  actcBeginOutput(tc);
+  while((prim = actcStartNextPrim(tc, &v1, &v2) != ACTC_DATABASE_EMPTY))
+  {
+    this->newStripe();
+
+    this->addIndice(v1);
+    this->addIndice(v2);
+    /* start a primitive of type "prim" with v1 and v2 */
+    while(actcGetNextVert(tc, &v3) != ACTC_PRIM_COMPLETE)
+    {
+      /* continue primitive using v3 */
+      this->addIndice(v3);
+    }
+  }
+  actcEndOutput(tc);
+
+  this->finalize();
+}
+
+
+/**
+ * @brief deletes a VertexArrayModel.
+ *
+ * Looks if any from model allocated space is still in use, and if so deleted it.
+ */
+VertexArrayModel::~VertexArrayModel()
+{
+  PRINTF(4)("Deleting VertexArrayModel %s\n", this->getCName());
+}
+
+
+/**
+ * @brief Draws the VertexArrayModels of all Groups.
+ *
+ * It does this by just calling the Lists that must have been created earlier.
+ */
+void VertexArrayModel::draw() const
+{
+  PRINTF(4)("drawing 3D-VertexArrayModel %s\n", this->getCName());
+  glEnableClientState(GL_VERTEX_ARRAY );
+  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
+  glEnableClientState(GL_NORMAL_ARRAY );
+  glEnableClientState(GL_COLOR_ARRAY );
+
+
+  glVertexPointer(3, GL_FLOAT, 0, &this->vertices[0]);
+  glNormalPointer(GL_FLOAT, 0, &this->normals[0]);
+  glTexCoordPointer(2, GL_FLOAT, 0, &this->texCoords[0]);
+  glColorPointer(3, GL_FLOAT, 0, &this->colors[0]);
+
+  for (GLuint i = 1; i < this->stripes.size(); ++i)
+    {
+      glDrawElements( GL_TRIANGLE_STRIP,
+                      this->stripes[i] - this->stripes[i-1],
+                      GL_UNSIGNED_INT,
+                      &this->indices[this->stripes[i-1]] );
+    }
+}
+
+
+//////////
+// MESH //
+//////////
+/**
+ * @brief generates a new Stripe in this Model
+ */
+void VertexArrayModel::newStripe()
+{
+  // no stripes of size 0
+  if (this->stripes.empty() || this->indices.size() != this->stripes.back())
+    this->stripes.push_back(this->indices.size());
+}
+
+
+/**
+ * @brief parses a vertex-String
+ * @param x the X-coordinate of the Vertex to add.
+ * @param y the Y-coordinate of the Vertex to add.
+ * @param z the Z-coordinate of the Vertex to add.
+ */
+void VertexArrayModel::addVertex(float x, float y, float z)
+{
+  this->vertices.push_back(Vector(x,y,z));
+  this->pModelInfo.numVertices++;
+}
+
+
+/**
+ * @brief adds a VertexNormal.
+ * @param x The x coordinate of the Normal.
+ * @param y The y coordinate of the Normal.
+ * @param z The z coordinate of the Normal.
+ *
+ * If a vertexNormal line is found this function will inject it into the vertexNormal-Array
+ */
+void VertexArrayModel::addNormal(float x, float y, float z)
+{
+  this->normals.push_back(Vector(x,y,z));
+  this->pModelInfo.numNormals++;
+}
+
+
+/**
+ * @brief adds a Texture Coordinate
+ * @param u The u coordinate of the TextureCoordinate.
+ * @param v The y coordinate of the TextureCoordinate.
+ *
+ *  If a TextureCoordinate line is found this function will inject it into the TextureCoordinate-Array
+ */
+void VertexArrayModel::addTexCoor(float u, float v)
+{
+  this->texCoords.push_back(Vector2D(u,v));
+  this->pModelInfo.numTexCoor++;
+}
+
+/**
+ * @brief adds a new Color
+ * @param r the Red Component of the VertexColor to add.
+ * @param g the Green Component of the VertexColor to add.
+ * @param b the Blue of the VertexColor to add.
+ */
+void VertexArrayModel::addColor(float r, float g, float b)
+{
+  this->colors.push_back(Vector(r,g,b));
+  // FIXME
+}
+
+
+/**
+ *  adds a new Face
+ * @param faceElemCount the number of Vertices to add to the Face.
+ * @param type The information Passed with each Vertex
+*/
+void VertexArrayModel::addIndice(GLuint indice)
+{
+  this->indices.push_back(indice);
+}
+
+
+/**
+ * @brief Finalizes an Object. This can be done outside of the Class.
+ */
+void VertexArrayModel::finalize()
+{
+  // finalize the Arrays
+  this->newStripe();
+}
+
+
+
+
+/////////////
+// TESTING //
+/////////////
+/**
+* @brief Includes a default model
+*
+* This will inject a Cube, because this is the most basic model.
+*/
+void VertexArrayModel::planeModel(float sizeX, float sizeY, unsigned int resolutionX, unsigned int resolutionY)
+{
+  GLuint i, j;
+  for (i = 0; i < resolutionY; i++)
+    {
+      for (j = 0; j < resolutionX; j++)
+        {
+          this->addVertex( ((float)i - (float)resolutionX/2.0)/(float)resolutionX * sizeX,
+                            0.0,
+                            ((float)j - (float)resolutionY/2.0)/(float)resolutionY * sizeY);
+          this->addNormal(0.0, 1, 0.0);
+          this->addTexCoor((float)i/(float)resolutionX, (float)j/(float)resolutionY);
+          this->addColor(1.0, 1.0, 1.0);
+        }
+    }
+
+  for (i = 0; i < resolutionY-1; i++)
+  {
+    for (j = 0; j < resolutionX; j++)
+    {
+      this->addIndice( resolutionY*i + j );
+      this->addIndice( resolutionY*(i+1) + j );
+    }
+    this->newStripe();
+  }
+}
+
+#include <cmath>
+
+/**
+ * @brief builds a Triangle Stripped sphere
+ * @param radius: radius
+ * @param loops: the count of loops
+ * @param segmentsPerLoop how many Segments per loop
+ */
+void VertexArrayModel::spiralSphere(const float radius, const unsigned int loops, const unsigned int segmentsPerLoop)
+{
+  for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
+  {
+    float theta = 0;
+    float phi = loopSegmentNumber * 2 * PI / segmentsPerLoop;
+    float sinTheta = std::sin(theta);
+    float sinPhi = std::sin(phi);
+    float cosTheta = std::cos(theta);
+    float cosPhi = std::cos(phi);
+    this->addVertex(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta);
+    this->addNormal(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta);
+    this->addTexCoor(0,0); /// FIXME
+    this->addColor(.125,.436,.246); ///FIXME
+  }
+
+  for (unsigned int loopNumber = 0; loopNumber <= loops; ++loopNumber)
+  {
+    for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
+    {
+      float theta = (loopNumber * PI / loops) + ((PI * loopSegmentNumber) / (segmentsPerLoop * loops));
+      if (loopNumber == loops)
+      {
+        theta = PI;
+      }
+      float phi = loopSegmentNumber * 2 * PI / segmentsPerLoop;
+      float sinTheta = std::sin(theta);
+      float sinPhi = std::sin(phi);
+      float cosTheta = std::cos(theta);
+      float cosPhi = std::cos(phi);
+      this->addVertex(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta);
+      this->addNormal(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta);
+      this->addTexCoor(0,0); //FIXME
+      this->addColor(.125,.436,.246);
+
+    }
+  }
+
+  for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
+  {
+    this->addIndice(loopSegmentNumber);
+    this->addIndice(segmentsPerLoop + loopSegmentNumber);
+  }
+
+  for (unsigned int loopNumber = 0; loopNumber < loops; ++loopNumber)
+  {
+    for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
+    {
+      this->addIndice( ((loopNumber + 1) * segmentsPerLoop) + loopSegmentNumber);
+      this->addIndice( ((loopNumber + 2) * segmentsPerLoop) + loopSegmentNumber);
+    }
+  }
+}
+
+
+/**
+ * @brief print out some nice debug information about this VertexArrayModel.
+ */
+void VertexArrayModel::debug() const
+{
+  PRINT(0)("VertexArrayModel (%s): debug\n", this->getCName());
+  PRINT(0)("Stripes: %d; Indices: %d; Vertices: %d; Normals %d; TextCoords %d; Colors %d\n",
+            this->stripes.size(),
+            this->indices.size(),
+            this->vertices.size(),
+            this->normals.size(),
+            this->texCoords.size(),
+            this->colors.size() );
+  for (GLuint i = 1; i < this->stripes.size(); ++i)
+  {
+    PRINT(0)("Stripe-%d (s:%d:e:%d):: ", i, this->stripes[i-1], this->stripes[i]);
+    for (GLuint j = this->stripes[i-1] ; j < this->stripes[i]; j++)
+    {
+      PRINT(0)("->%d", this->indices[j]);
+    }
+    PRINT(0)("\n");
+  }
+}
Index: branches/heathaze/src/lib/graphics/importer/vertex_array_model.h
===================================================================
--- branches/heathaze/src/lib/graphics/importer/vertex_array_model.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/importer/vertex_array_model.h	(revision 9940)
@@ -0,0 +1,81 @@
+/*!
+ * @file vertex_array_model.h
+ * @brief Contains the VertexArrayModel Class that handles 3D-Models rendered out of VertexArrays
+ */
+
+#ifndef _VERTEX_ARRAY_MODEL_H
+#define _VERTEX_ARRAY_MODEL_H
+
+#include "model.h"
+
+#include "glincl.h"
+#include "vector2D.h"
+
+#include <vector>
+
+/* Forward Declaration */
+class Material;
+
+
+/////////////
+/// MODEL ///
+/////////////
+//! Class that handles 3D-Models. it can also read them in and display them.
+/**
+ * this renders models with help of the OpenGL glVertexArray
+ */
+class VertexArrayModel : public Model
+{
+  ObjectListDeclaration(VertexArrayModel);
+  public:
+  VertexArrayModel();
+  VertexArrayModel(const Model& model);
+  virtual ~VertexArrayModel();
+
+  void draw() const;
+
+
+  void newStripe();
+
+  void addVertex(float x, float y, float z);
+  void addNormal(float x, float y, float z);
+  void addTexCoor(float u, float v);
+  void addColor(float r, float g, float b);
+
+  void addIndice(GLuint indice);
+
+  void finalize();
+
+  unsigned int vertexCount() const { return this->vertices.size(); };
+  unsigned int normalCount() const { return this->normals.size(); };
+  unsigned int texCoordCount() const { return this->texCoords.size(); };
+  unsigned int colorCount() const { return this->colors.size(); };
+  unsigned int indiceCount() const { return this->indices.size(); };
+
+  Vector& vertex(unsigned int i) { return this->vertices[i]; };
+  Vector& normal(unsigned int i) { return this->normals[i]; };
+  Vector2D& texCoord(unsigned int i) { return this->texCoords[i]; };
+  Vector& color(unsigned int i) { return this->colors[i]; };
+  GLuint  index(unsigned int i) { return this->indices[i]; };
+  //
+  void planeModel(float sizeX, float sizeY, unsigned int resolutionX, unsigned int resolutionY);
+  void spiralSphere(const float radius, const unsigned int loops, const unsigned int segmentsPerLoop);
+
+  void debug() const;
+
+ private:
+  void importToVertexArray();
+
+ private:
+  std::vector<Vector>        vertices;        //!< The Array that handles the Vertices.
+  std::vector<Vector>        normals;         //!< The Array that handles the Normals.
+  std::vector<Vector2D>      texCoords;       //!< The Array that handles the VertexTextureCoordinates.
+  std::vector<Vector>        colors;          //!< The Array that handles Colors.
+
+  std::vector<GLuint>        indices;         //!< The Array that tells us what Vertex is connected to which other one.
+
+  std::vector<GLuint>        stripes;         //!< A lsit of Stripes of this Model.
+
+};
+
+#endif
Index: branches/heathaze/src/lib/graphics/light.cc
===================================================================
--- branches/heathaze/src/lib/graphics/light.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/light.cc	(revision 9940)
@@ -0,0 +1,380 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "light.h"
+
+#include "glincl.h"
+#include "vector.h"
+#include "util/loading/load_param_xml.h"
+#include "util/loading/factory.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(Light, CL_LIGHT);
+CREATE_FACTORY(Light);
+
+//! Definition of the Lights and their Names
+int lightsV[] =
+  {
+    GL_LIGHT0,
+    GL_LIGHT1,
+    GL_LIGHT2,
+    GL_LIGHT3,
+    GL_LIGHT4,
+    GL_LIGHT5,
+    GL_LIGHT6,
+    GL_LIGHT7
+  };
+
+/**
+ * @param root The XML-element to load the Light from
+
+  @todo what to do, if no Light-Slots are open anymore ???
+ */
+Light::Light(const TiXmlElement* root)
+{
+  PRINTF(4)("initializing Light number %d.\n", this->lightNumber);
+
+  this->registerObject(this, Light::_objectList);
+
+  this->lightNumber = LightManager::getInstance()->registerLight(this);
+
+  char tmpName[10];
+  sprintf(tmpName, "Light[%d]", this->lightNumber);
+  this->setName(tmpName);
+
+  // enable The light
+  glEnable(lightsV[this->lightNumber]); // postSpawn
+
+  // set values (defaults)
+  this->setDiffuseColor(1.0, 1.0, 1.0);
+  this->setSpecularColor(1.0, 1.0, 1.0);
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  destroys a Light
+*/
+Light::~Light()
+{
+  glDisable(lightsV[this->lightNumber]);
+
+  LightManager::getInstance()->unregisterLight(this);
+}
+
+/**
+ * @param root The XML-element to load the Light from
+ */
+void Light::loadParams(const TiXmlElement* root)
+{
+  PNode::loadParams(root);
+
+  LoadParam(root, "diffuse-color", this, Light, setDiffuseColor)
+  .describe("sets the diffuse color of the Light (red [0-1], green [0-1], blue [0-1])");
+
+  LoadParam(root, "specular-color", this, Light, setSpecularColor)
+  .describe("sets the specular color of the Light (red [0-1], green [0-1], blue [0-1])");
+
+  LoadParam(root, "attenuation", this, Light, setAttenuation)
+  .describe("sets the Attenuation of the LightSource (constant Factor, linear Factor, quadratic Factor).");
+
+  LoadParam(root, "spot-direction", this, Light, setSpotDirection)
+  .describe("sets the Direction of the Spot");
+
+  LoadParam(root, "spot-cutoff", this, Light, setSpotCutoff)
+  .describe("the cuttoff of the Spotlight");
+}
+
+/**
+ *  sets an emitting Diffuse color of this Light
+ * @param r red
+ * @param g green
+ * @param b blue
+*/
+void Light::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b)
+{
+  this->diffuseColor[0] = r;
+  this->diffuseColor[1] = g;
+  this->diffuseColor[2] = b;
+  this->diffuseColor[3] = 1.0;
+
+  glLightfv (lightsV[this->lightNumber], GL_DIFFUSE, this->diffuseColor);
+}
+
+/**
+ *  sets an emitting Specular color of this Light
+ * @param r red
+ * @param g green
+ * @param b blue
+*/
+void Light::setSpecularColor(GLfloat r, GLfloat g, GLfloat b)
+{
+  this->specularColor[0] = r;
+  this->specularColor[1] = g;
+  this->specularColor[2] = b;
+  this->specularColor[3] = 1.0;
+
+  glLightfv (lightsV[this->lightNumber], GL_SPECULAR, this->specularColor);
+}
+
+
+/**
+ *  Sets the AttenuationType of this Light Source
+ * @param constantAttenuation The Constant Attenuation of the Light
+ * @param linearAttenuation The Linear Attenuation of the Light
+ * @param quadraticAttenuation The Quadratic Attenuation of the Light
+*/
+void Light::setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation)
+{
+  this->constantAttenuation  = constantAttenuation;
+  this->linearAttenuation    = linearAttenuation;
+  this->quadraticAttenuation = quadraticAttenuation;
+
+  glLightf(lightsV[this->lightNumber], GL_CONSTANT_ATTENUATION,  constantAttenuation);
+  glLightf(lightsV[this->lightNumber], GL_LINEAR_ATTENUATION,    linearAttenuation);
+  glLightf(lightsV[this->lightNumber], GL_QUADRATIC_ATTENUATION, quadraticAttenuation);
+}
+
+
+/**
+ *  stets the direction of the Spot Light.
+ * @param direction The direction of the Spot Light.
+*/
+void Light::setSpotDirection(const Vector& direction)
+{
+  this->spotDirection[0] = direction.x;
+  this->spotDirection[1] = direction.y;
+  this->spotDirection[2] = direction.z;
+
+  glLightfv(lightsV[this->lightNumber], GL_SPOT_DIRECTION, this->spotDirection);
+}
+
+
+/**
+ *  sets the cutoff angle of the Light.
+ * @param cutoff The cutoff angle.
+*/
+void Light::setSpotCutoff(GLfloat cutoff)
+{
+  this->spotCutoff = cutoff;
+  glLightf(lightsV[this->lightNumber], GL_SPOT_CUTOFF, cutoff);
+}
+
+/**
+ *  draws this Light. Being a World-entity the possibility to do this lies at hand.
+*/
+void Light::draw() const
+{
+  float pos[4] = {this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z, 1.0};
+  PRINTF(4)("Drawing The Lights new Position at %f %f %f\n", pos[0], pos[1], pos[2]);
+  glLightfv(lightsV[this->lightNumber], GL_POSITION, pos);
+}
+
+
+/**
+ *  Prints out some nice formated debug information about the Light
+*/
+void Light::debug() const
+{
+  PRINT(0)(":: %d ::  -- reference %p\n", this->lightNumber, this);
+  PRINT(0)(" GL-state: ");
+  GLboolean param;
+  glGetBooleanv(lightsV[this->lightNumber], &param);
+  if (param)
+    PRINT(0)("ON\n");
+  else
+    PRINT(0)("OFF\n");
+
+  PRINT(0)(" DiffuseColor:  %f/%f/%f\n", this->diffuseColor[0], this->diffuseColor[1], this->diffuseColor[2]);
+  PRINT(0)(" SpecularColor: %f/%f/%f\n", this->specularColor[0], this->specularColor[1], this->specularColor[2]);
+  PRINT(0)(" Attenuation: constant=%f linear=%f quadratic=%f\n", this->constantAttenuation, this->linearAttenuation, this->quadraticAttenuation);
+}
+
+
+/******************
+** LIGHT-MANAGER **
+******************/
+ObjectListDefinition(LightManager);
+/**
+ *  standard constructor for a Light
+*/
+LightManager::LightManager ()
+{
+  this->registerObject(this, LightManager::_objectList);
+
+  glEnable (GL_LIGHTING);
+  glEnable ( GL_COLOR_MATERIAL ) ;
+  glColorMaterial ( GL_FRONT, GL_DIFFUSE ) ;
+
+  this->setAmbientColor(.3, .3, .3);
+  this->lights = new Light*[NUMBEROFLIGHTS];
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    lights[i] = NULL;
+  this->currentLight = NULL;
+}
+
+/**
+ *  standard deconstructor
+
+   first disables Lighting
+
+   then deletes the rest of the allocated memory
+   and in the end sets the singleton Reference to zero.
+*/
+LightManager::~LightManager ()
+{
+  glDisable(GL_COLOR_MATERIAL);
+  glDisable(GL_LIGHTING);
+  this->setAmbientColor(.0,.0,.0);
+
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    if (this->lights[i] != NULL)
+      delete lights[i];
+  delete[] lights;
+  LightManager::singletonRef = NULL;
+}
+
+/**
+ *  singleton-Reference to the Light-class
+*/
+LightManager* LightManager::singletonRef = NULL;
+
+/**
+* @param root the XML-element to load the LightManager's settings from
+ */
+void LightManager::loadParams(const TiXmlElement* root)
+{
+  LoadParamXML(root, "Lights", this, LightManager, loadLights)
+  .describe("an XML-Element to load lights from.");
+
+  LoadParam(root, "ambient-color", this, LightManager, setAmbientColor)
+  .describe("sets the ambient Color of the Environmental Light");
+}
+
+/**
+* @param root The XML-element to load Lights from
+ */
+void LightManager::loadLights(const TiXmlElement* root)
+{
+  const TiXmlElement* element = root->FirstChildElement();
+
+  while (element != NULL)
+  {
+    Factory::fabricate(element);
+
+    element = element->NextSiblingElement();
+  }
+}
+
+// set Attributes
+/**
+ *  sets the ambient Color of the Scene
+ * @param r red
+ * @param g green
+ * @param b blue
+*/
+void LightManager::setAmbientColor(GLfloat r, GLfloat g, GLfloat b)
+{
+  this->ambientColor[0] = r;
+  this->ambientColor[1] = g;
+  this->ambientColor[2] = b;
+  this->ambientColor[3] = 1.0;
+
+  glLightfv (GL_LIGHT0, GL_AMBIENT, this->ambientColor);
+}
+
+/**
+* @param light the Light to register to the LightManager
+
+  This is done explicitely by the constructor of a Light
+*/
+int LightManager::registerLight(Light* light)
+{
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    if (!this->lights[i])
+    {
+      this->lights[i]=light;
+      return i;
+    }
+  PRINTF(1)("no more light slots availiable. All %d already taken\n", NUMBEROFLIGHTS);
+  return -1;
+}
+
+/**
+* @param light The light to unregister from the LightManager
+
+  This is done every time a Light is destroyed explicitely by the Light-destructor
+ */
+void LightManager::unregisterLight(Light* light)
+{
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+  {
+    if (this->lights[i] == light)
+    {
+      this->lights[i] = NULL;
+      return;
+    }
+  }
+  PRINTF(2)("Light %p could not be unloaded (this should not heappen\n)");
+  return;
+}
+
+
+Light* LightManager::getLight(int lightNumber) const
+{
+  if( lightNumber < NUMBEROFLIGHTS)
+    return this->lights[lightNumber];
+
+  return NULL;
+}
+
+/**
+ *  draws all the Lights in their appropriate position
+ */
+void LightManager::draw() const
+{
+  PRINTF(4)("Drawing the Lights\n");
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    if (this->lights[i] != NULL)
+      lights[i]->draw();
+}
+
+/**
+ *  outputs debug information about the Class and its lights
+*/
+void LightManager::debug() const
+{
+  PRINT(0)("=================================\n");
+  PRINT(0)("= DEBUG INFORMATION CLASS LIGHT =\n");
+  PRINT(0)("=================================\n");
+  PRINT(0)("Reference: %p\n", LightManager::singletonRef);
+  if (this->currentLight)
+    PRINT(0)("current Light Nr: %d\n", this->currentLight->getLightNumber());
+  PRINT(0)("Ambient Color: %f:%f:%f\n", this->ambientColor[0], this->ambientColor[0], this->ambientColor[0]);
+  PRINT(0)("=== Lights ===\n");
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    if (this->lights[i])
+    {
+      this->lights[i]->debug();
+    }
+  PRINT(0)("-----------------------------LM-\n");
+}
Index: branches/heathaze/src/lib/graphics/light.h
===================================================================
--- branches/heathaze/src/lib/graphics/light.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/light.h	(revision 9940)
@@ -0,0 +1,128 @@
+/*!
+* @file light.h
+*  Handles Lights.
+
+A Light is one of the more important things in a 3D-environment,
+without it one sees nothing :)
+It is here for diffuse-, specular- and Bump-Mappings.
+*/
+
+#ifndef _LIGHT_H
+#define _LIGHT_H
+
+#include "p_node.h"
+#include "glincl.h"
+
+//! The maximum number of Lights this OpenGL-implementation supports.
+#define NUMBEROFLIGHTS GL_MAX_LIGHTS
+
+
+// FORWARD DECLARATIONS //
+class Vector;
+class TiXmlElement;
+
+//! A class that handles Lights. The LightManager operates on this.
+class Light : public PNode
+{
+  ObjectListDeclaration(Light);
+public:
+  Light(const TiXmlElement* root = NULL);
+  virtual ~Light();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setDiffuseColor(GLfloat r, GLfloat g, GLfloat b);
+  void setSpecularColor(GLfloat r, GLfloat g, GLfloat b);
+  void setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation);
+  void setSpotDirection(const Vector& direction);
+  void setSpotDirection(float x, float y, float z) { setSpotDirection(Vector(x,y,z)); };
+  void setSpotCutoff(GLfloat cutoff);
+
+  /** @returns the lightNumber*/
+  int getLightNumber() const {return this->lightNumber;}
+
+  virtual void draw() const;
+
+  void debug() const;
+
+  // attributes
+private:
+  int              lightNumber;               //!< The number of this Light.
+  GLfloat          diffuseColor[4];           //!< The Diffuse Color this Light emmits.
+  GLfloat          specularColor[4];          //!< The specular Color of this Light.
+  float            constantAttenuation;       //!< The Factor of the the Constant Attenuation.
+  float            linearAttenuation;         //!< The Factor of the the Linear Attenuation.
+  float            quadraticAttenuation;      //!< The Factor of the the Quadratic Attenuation.
+  GLfloat          spotDirection[4];          //!< The direction of the Spot Light.
+  GLfloat          spotCutoff;                //!< The cutoff Angle of the Light Source
+};
+
+
+
+//! A class that handles Lights
+/**
+A Light is a source that emits light rays (photons)
+
+<b>Usage:</b>\n
+First you have to get the Light Manager up and running by using LightManager::getInstance().
+This automatically initiates the GL_LIGHTING, and sets some default stuff about the light.\n
+Then you will create a new light using:
+\li new Light();
+
+if you want to operate on this Light just apply the following functions onto it.
+(You can also optain the Light-pointer with LightManager::getInstance()->getLight(lightNumber))
+
+now you can operate on the light as follows:
+\li void setDiffuseColor(GLfloat r, GLfloat g, GLfloat b);
+\li void setSpecularColor(GLfloat r, GLfloat g, GLfloat b);
+\li void setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation);
+\li void setSpotDirection(Vector direction);
+\li void setSpotCutoff(GLfloat cutoff);
+\li all PNode stuff also works
+
+To redraw the light use
+\li void draw() const; (this is automatically done by the LightManager)
+
+for some nice output just use:
+\li void debug() const; (either on LightManager for a resume or on any Light for single information.)
+*/
+class LightManager : public BaseObject
+{
+  ObjectListDeclaration(LightManager);
+
+  friend class Light;
+public:
+  virtual ~LightManager();
+  /** @returns a Pointer to the only object of this Class */
+  inline static LightManager* getInstance() { if (!singletonRef) singletonRef = new LightManager();  return singletonRef; };
+
+  virtual void loadParams(const TiXmlElement* root);
+  void loadLights(const TiXmlElement* root);
+
+  void setAmbientColor(GLfloat r, GLfloat g, GLfloat b);
+  // HACK: Assuming r = g = b values
+inline GLfloat getAmbientColor() {  return this->ambientColor[0]; }
+
+  Light* getLight(int lightNumber) const;
+  inline Light* getLight() const { return this->currentLight; };
+
+  void draw() const;
+
+  void debug() const;
+
+private:
+  LightManager();
+
+  int  registerLight(Light* light);
+  void unregisterLight(Light* light);
+
+private:
+  static LightManager*    singletonRef;       //!< This is the LightHandlers Reference.
+  GLfloat                 ambientColor[4];    //!< The ambient Color of the scene.
+
+  Light**                 lights;             //!< An array of Lenght NUMBEROFLIGHTS, that holds pointers to all LightValues.
+  Light*                  currentLight;       //!< The current Light, we are working with.
+
+};
+
+#endif /* _LIGHT_H */
Index: branches/heathaze/src/lib/graphics/render2D/element_2d.cc
===================================================================
--- branches/heathaze/src/lib/graphics/render2D/element_2d.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/render2D/element_2d.cc	(revision 9940)
@@ -0,0 +1,1254 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "element_2d.h"
+#include "render_2d.h"
+
+#include <algorithm>
+
+// ONLY IF PNODE ENABLED //
+#include "state.h"
+#include "p_node.h"
+#include "camera.h"
+///////////////////////////
+
+#include "graphics_engine.h"
+#include "util/loading/load_param.h"
+
+#include "color.h"
+#include "debug.h"
+#include "shell_command.h"
+
+SHELL_COMMAND(debug, Element2D, debug2D);
+
+ObjectListDefinition(Element2D);
+
+
+/**
+ * @brief standard constructor
+ * @param parent the parent to set for this Element2D
+ *
+ * NullElement2D needs this constructor with parameter NULL to initialize
+ * itself. Otherwise it would result in an endless Loop.
+ */
+Element2D::Element2D (Element2D* parent, E2D_LAYER layer, short nodeFlags)
+{
+  this->registerObject(this, Element2D::_objectList);
+
+  this->setVisibility(true);
+  this->bCurrentlyVisible = true;
+  this->activate2D();
+  this->setAlignment(E2D_ALIGN_NONE);
+  this->bindNode = NULL;
+
+  this->parentMode = nodeFlags;
+  this->parent = NULL;
+  this->absDirection = 0.0;
+  this->relDirection = 0.0;
+  this->bRelCoorChanged = true;
+  this->bRelDirChanged = true;
+  this->toCoordinate = NULL;
+  this->toDirection = NULL;
+
+  this->size = Vector2D(0,0);
+  this->toSize = NULL;
+
+
+  this->layer = layer;
+  if (parent != NULL)
+    parent->addChild2D(this);
+}
+
+
+/**
+ * @brief the mighty NullElement
+ * TopMost Node of them all.
+ */
+Element2D* Element2D::nullElement = NULL;
+
+
+/**
+ * @brief standard deconstructor
+ *
+ * There are two general ways to delete an Element2D
+ * 1. delete instance;
+ *   -> result
+ *    delete this Node and all its children and children's children...
+ *    (danger if you still want the instance!!)
+ *
+ * 2. instance->remove2D(); delete instance;
+ *   -> result:
+ *    moves its children to the NullElement2D
+ *    then deletes the Element.
+ */
+Element2D::~Element2D ()
+{
+  // remove the Element2D, delete it's children (if required).
+  std::list<Element2D*>::iterator tmp = this->children.begin();
+  std::list<Element2D*>::iterator deleteNode;
+  while(!this->children.empty())
+    while (tmp != this->children.end())
+    {
+      deleteNode = tmp;
+      tmp++;
+      //      printf("TEST::%s(%s) %s\n", (*deleteNode)->getName(), (*deleteNode)->getClassCName(), this->getName());
+      if ((this->parentMode & E2D_PROHIBIT_CHILD_DELETE) ||
+          ((*deleteNode)->parentMode & E2D_PROHIBIT_DELETE_WITH_PARENT))
+      {
+        if (this == Element2D::nullElement && (*deleteNode)->parentMode & E2D_REPARENT_TO_NULL)
+          delete (*deleteNode);
+        else
+          (*deleteNode)->reparent2D();
+      }
+      else
+        delete (*deleteNode);
+    }
+
+  if (this->parent != NULL)
+  {
+    this->parent->eraseChild2D(this);
+    this->parent = NULL;
+  }
+
+  // remove all other allocated memory.
+  if (this->toCoordinate != NULL)
+    delete this->toCoordinate;
+  if (this->toDirection != NULL)
+    delete this->toDirection;
+  if (this->toSize != NULL)
+    delete this->toSize;
+
+  if (this == Element2D::nullElement)
+    Element2D::nullElement = NULL;
+}
+
+
+/**
+ * @brief Loads the Parameters of an Element2D from...
+ * @param root The XML-element to load from
+ */
+void Element2D::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+
+  // ELEMENT2D-native settings.
+  LoadParam(root, "alignment", this, Element2D, setAlignment)
+  .describe("loads the alignment: (either: center, left, right or screen-center)");
+
+  LoadParam(root, "layer", this, Element2D, setLayer)
+  .describe("loads the layer onto which to project: (either: top, medium, bottom, below-all)");
+
+  LoadParam(root, "bind-node", this, Element2D, setBindNode)
+  .describe("sets a node, this 2D-Element should be shown upon (name of the node)");
+
+  LoadParam(root, "visibility", this, Element2D, setVisibility)
+  .describe("if the Element is visible or not");
+
+
+  // PNode-style:
+  LoadParam(root, "rel-coor-2d", this, Element2D, setRelCoor2D)
+  .describe("Sets The relative position of the Node to its parent.");
+
+  LoadParam(root, "abs-coor-2d", this, Element2D, setAbsCoor2D)
+  .describe("Sets The absolute Position of the Node.");
+
+  LoadParam(root, "rel-dir-2d", this, Element2D, setRelDir2D)
+  .describe("Sets The relative rotation of the Node to its parent.");
+
+  LoadParam(root, "abs-dir-2d", this, Element2D, setAbsDir2D)
+  .describe("Sets The absolute rotation of the Node.");
+
+  LoadParam(root, "parent", this, Element2D, setParent2D)
+  .describe("the Name of the Parent of this Element2D");
+
+  LoadParam(root, "parent-mode", this, Element2D, setParentMode2D)
+  .describe("the mode to connect this node to its parent ()");
+
+  // cycling properties
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    LoadParam_CYCLE(element, "child", this, Element2D, addChild2D)
+    .describe("adds a new Child to the current Node.");
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ * @brief sets the alignment of the 2D-element in form of a String
+ * @param alignment the alignment @see loadParams
+*/
+void Element2D::setAlignment(const std::string& alignment)
+{
+  if (alignment == "center")
+    this->setAlignment(E2D_ALIGN_CENTER);
+  else if (alignment == "left")
+    this->setAlignment(E2D_ALIGN_LEFT);
+  else if (alignment == "right")
+    this->setAlignment(E2D_ALIGN_RIGHT);
+  else if (alignment == "screen-center")
+    this->setAlignment(E2D_ALIGN_SCREEN_CENTER);
+}
+
+
+/**
+ * @brief moves a Element to another layer
+ * @param layer the Layer this is drawn on
+ */
+void Element2D::setLayer(E2D_LAYER layer)
+{
+  if (unlikely(this->layer == layer)) return;
+
+  if (this->parent != NULL && this->parent->getLayer() > layer)
+  {
+    PRINTF(2)("Unable to set %s to layer %s, because it's parent(%s) is of higher layer %s\n",
+              this->getCName(),
+              Element2D::layer2DToChar(layer),
+              this->parent->getCName(),
+              Element2D::layer2DToChar(this->parent->getLayer()));
+    layer = this->parent->getLayer();
+  }
+  this->layer = layer;
+
+
+  if (this->parent != NULL)
+    this->parent->children.sort(layerSortPredicate);
+}
+
+/**
+ * @brief sets the layer onto which this 2D-element is projected to.
+ * @param layer the layer @see loadParams @see Element2D::charToLayer2D(const std::string& layer)
+ */
+void Element2D::setLayer(const std::string& layer)
+{
+  this->setLayer(Element2D::charToLayer2D(layer));
+}
+
+/**
+ * @brief sets the Size of the Element2D softly.
+ * @param x the x-coordinate
+ * @param y the y-coordinate.
+ * @param bias the bias (bigger = faster).
+ */
+void Element2D::setSizeSoft2D(float x, float y, float bias)
+{
+  if (likely(this->toSize == NULL))
+    this->toSize = new Vector2D();
+
+  *this->toSize = Vector2D(x,y);;
+  this->bias = bias;
+}
+
+
+/**
+ * @brief sets a node, this 2D-Element should be shown upon
+ * @param bindNode the Node of the Node. (if NULL it will be unset).
+ */
+void Element2D::setBindNode(const PNode* bindNode)
+{
+  this->bindNode = bindNode;
+  this->bCurrentlyVisible = (bindNode == NULL);
+}
+
+/**
+ * @brief sets a node, this 2D-Element should be shown upon
+ * @param bindNode the name of the Node (should be existing)
+ */
+void Element2D::setBindNode(const std::string& bindNode)
+{
+  const PNode* tmpBindNode = PNode::objectList().getObject(bindNode);
+  if (tmpBindNode != NULL)
+    this->bindNode = tmpBindNode;
+}
+
+/**
+ * @brief sets the relative coordinate of the Element2D to its parent
+ * @param relCoord the relative coordinate to the parent
+ */
+void Element2D::setRelCoor2D (const Vector2D& relCoord)
+{
+  if (this->toCoordinate!= NULL)
+  {
+    delete this->toCoordinate;
+    this->toCoordinate = NULL;
+  }
+  this->relCoordinate = relCoord;
+  this->bRelCoorChanged = true;
+}
+
+/**
+ * @brief sets the relative coordinate of the Element2D to its Parent
+ * @param x the x coordinate
+ * @param y the y coordinate
+ */
+void Element2D::setRelCoor2D (float x, float y)
+{
+  this->setRelCoor2D(Vector2D(x,y));
+}
+
+/**
+ * @brief updates the Rel - Coordinate in x-direction
+ * @param x the x coordinate
+ */
+void Element2D::setRelCoorX2D(float x)
+{
+  this->setRelCoor2D(Vector2D(x, this->relCoordinate.y));
+}
+
+/**
+ * @brief updates the Rel - Coordinate in y-direction
+ * @param y the y coordinate
+ */
+void Element2D::setRelCoorY2D(float y)
+{
+  this->setRelCoor2D(Vector2D(this->relCoordinate.x, y));
+}
+
+
+/**
+ * @brief sets the Relative coordinate to the parent in Pixels
+ * @param x the relCoord X
+ * @param y the relCoord Y
+ */
+void Element2D::setRelCoor2Dpx (int x, int y)
+{
+  this->setRelCoor2D(Vector2D((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
+                              (float)y/(float)GraphicsEngine::getInstance()->getResolutionY()));
+}
+
+/**
+ * @brief sets a new relative position smoothely
+ * @param relCoordSoft the new Position to iterate to
+ * @param bias how fast to iterate to this position
+ */
+void Element2D::setRelCoorSoft2D(const Vector2D& relCoordSoft, float bias)
+{
+  if (likely(this->toCoordinate == NULL))
+    this->toCoordinate = new Vector2D();
+
+  *this->toCoordinate = relCoordSoft;
+  this->bias = bias;
+}
+
+/**
+ * @brief sets a new relative position smoothely
+ * @param x the new x-coordinate in Pixels of the Position to iterate to
+ * @param y the new y-coordinate in Pixels of the Position to iterate to
+ * @param bias how fast to iterate to this position
+ */
+void Element2D::setRelCoorSoft2Dpx (int x, int y, float bias)
+{
+  this->setRelCoorSoft2D(Vector2D((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
+                                  (float)y/(float)GraphicsEngine::getInstance()->getResolutionY()),
+                         bias);
+}
+
+/**
+ * @brief set relative coordinates smoothely
+ * @param x x-relative coordinates to its parent
+ * @param y y-relative coordinates to its parent
+ * @param z z-relative coordinates to its parent
+ * @see  void PNode::setRelCoorSoft (const Vector2D&, float)
+ */
+void Element2D::setRelCoorSoft2D(float x, float y, float bias)
+{
+  this->setRelCoorSoft2D(Vector2D(x, y), bias);
+}
+
+/**
+ * @param absCoord set absolute coordinate
+ */
+void Element2D::setAbsCoor2D (const Vector2D& absCoord)
+{
+  if (this->toCoordinate!= NULL)
+  {
+    delete this->toCoordinate;
+    this->toCoordinate = NULL;
+  }
+
+  if( likely(this->parentMode & E2D_PARENT_MOVEMENT))
+  {
+    /* if you have set the absolute coordinates this overrides all other changes */
+    if (likely(this->parent != NULL))
+      this->relCoordinate = absCoord - parent->getAbsCoor2D ();
+    else
+      this->relCoordinate = absCoord;
+  }
+  if( this->parentMode & E2D_PARENT_ROTATE_MOVEMENT)
+  {
+    if (likely(this->parent != NULL))
+      this->relCoordinate = absCoord - parent->getAbsCoor2D ();
+    else
+      this->relCoordinate = absCoord;
+  }
+
+  this->bRelCoorChanged = true;
+}
+
+/**
+ * @param x x-coordinate.
+ * @param y y-coordinate.
+ * @param z z-coordinate.
+ * @see void PNode::setAbsCoor (const Vector2D& absCoord)
+ */
+void Element2D::setAbsCoor2D (float x, float y)
+{
+  this->setAbsCoor2D(Vector2D(x, y));
+}
+
+/**
+ * @brief updates the Abs - Coordinate in x-direction
+ * @param x the x coordinate
+ */
+void Element2D::setAbsCoorX2D(float x)
+{
+  this->setAbsCoor2D(x, this->getAbsCoor2D().y);
+}
+
+/**
+ * @brief updates the Abs - Coordinate in y-direction
+ * @param y the y coordinate
+ */
+void Element2D::setAbsCoorY2D(float y)
+{
+  this->setAbsCoor2D(this->getAbsCoor2D().x, y);
+}
+
+
+/**
+ * @param x x-coordinate in Pixels
+ * @param y y-coordinate in Pixels
+ * @see void PNode::setAbsCoor (const Vector2D& absCoord)
+ */
+void Element2D::setAbsCoor2Dpx (int x, int y)
+{
+  this->setAbsCoor2D(Vector2D((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
+                              (float)y/(float)GraphicsEngine::getInstance()->getResolutionY()));
+}
+
+/**
+ * @param absCoordSoft set absolute coordinate
+ * @param bias how fast to iterato to the new Coordinate
+ */
+void Element2D::setAbsCoorSoft2D (const Vector2D& absCoordSoft, float bias)
+{
+  if (this->toCoordinate == NULL)
+    this->toCoordinate = new Vector2D();
+
+  if( likely(this->parentMode & E2D_PARENT_MOVEMENT))
+  {
+    /* if you have set the absolute coordinates this overrides all other changes */
+    if (likely(this->parent != NULL))
+      *this->toCoordinate = absCoordSoft - parent->getAbsCoor2D ();
+    else
+      *this->toCoordinate = absCoordSoft;
+  }
+  if( this->parentMode & E2D_PARENT_ROTATE_MOVEMENT)
+  {
+    if (likely(this->parent != NULL))
+      *this->toCoordinate = absCoordSoft - parent->getAbsCoor2D ();
+    else
+      *this->toCoordinate = absCoordSoft;
+  }
+
+  this->bias = bias;
+}
+
+/**
+ * @param x x-coordinate.
+ * @param y y-coordinate.
+ * @param z z-coordinate.
+ * @see void PNode::setAbsCoor (const Vector2D& absCoord)
+ */
+void Element2D::setAbsCoorSoft2D (float x, float y, float bias)
+{
+  this->setAbsCoorSoft2D(Vector2D(x, y), bias);
+}
+
+/**
+ * @brief shift coordinate ralative
+ * @param shift shift vector
+ *
+ * This simply adds the shift-Vector2D to the relative Coordinate
+ */
+void Element2D::shiftCoor2D (const Vector2D& shift)
+{
+  this->relCoordinate += shift;
+  this->bRelCoorChanged = true;
+}
+
+/**
+ * @brief shifts in PixelSpace
+ * @param x the pixels to shift in X
+ * @param y the pixels to shift in Y
+ */
+void Element2D::shiftCoor2Dpx (int x, int y)
+{
+  this->shiftCoor2D(Vector2D((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
+                             (float)y/(float)GraphicsEngine::getInstance()->getResolutionY()));
+}
+
+/**
+ * @brief set relative direction
+ * @param relDir to its parent
+ */
+void Element2D::setRelDir2D (float relDir)
+{
+  if (this->toDirection!= NULL)
+  {
+    delete this->toDirection;
+    this->toDirection = NULL;
+  }
+
+  this->relDirection = relDir;
+  this->bRelDirChanged = true;
+}
+
+/**
+ * @brief sets the Relative Direction of this node to its parent in a Smoothed way
+ * @param relDirSoft the direction to iterate to smoothely.
+ * @param bias how fast to iterate to the new Direction
+ */
+void Element2D::setRelDirSoft2D(float relDirSoft, float bias)
+{
+  if (likely(this->toDirection == NULL))
+    this->toDirection = new float;
+
+  *this->toDirection = relDirSoft;
+  this->bias = bias;
+}
+
+/**
+ * @brief sets the absolute direction
+ * @param absDir absolute coordinates
+ */
+void Element2D::setAbsDir2D (float absDir)
+{
+  if (this->toDirection!= NULL)
+  {
+    delete this->toDirection;
+    this->toDirection = NULL;
+  }
+
+  if (likely(this->parent != NULL))
+    this->relDirection = absDir - this->parent->getAbsDir2D();
+  else
+    this->relDirection = absDir;
+
+  this->bRelDirChanged = true;
+}
+
+/**
+ * @brief sets the absolute direction softly
+ * @param absDir absolute coordinates
+ */
+void Element2D::setAbsDirSoft2D (float absDirSoft, float bias)
+{
+  if (this->toDirection == NULL)
+    this->toDirection = new float;
+
+  if (likely(this->parent != NULL))
+    *this->toDirection = absDirSoft - this->parent->getAbsDir2D();
+  else
+    *this->toDirection = absDirSoft;
+
+  this->bias = bias;
+}
+
+/**
+ * shift Direction
+ * @param shift the direction around which to shift.
+ */
+void Element2D::shiftDir2D (float shiftDir)
+{
+  this->relDirection = this->relDirection + shiftDir;
+  this->bRelDirChanged = true;
+}
+
+/**
+ * @brief adds a child and makes this node to a parent
+ * @param child child reference
+ * @param parentMode on which changes the child should also change ist state
+ *
+ * use this to add a child to this node.
+ */
+void Element2D::addChild2D (Element2D* child)
+{
+  assert(child != NULL);
+  if( likely(child->parent != NULL))
+  {
+    PRINTF(5)("Element2D::addChild() - reparenting node: removing it and adding it again\n");
+    child->parent->eraseChild2D(child);
+  }
+  if (this->checkIntegrity(child))
+  {
+    // Setting the New Parent.
+    child->parent = this;
+    if (likely(this != NULL))
+    {
+      // Layers of Children that are smaller than this(parents) Layer will be updated, and pushed to the front.
+      if (unlikely(this->layer > child->getLayer()))
+      {
+        PRINTF(2)("Layer '%s' of Child(%s::%s) lower than parents(%s::%s) layer '%s'. updating...\n",
+                  Element2D::layer2DToChar(child->getLayer()),child->getClassCName(), child->getCName(),
+                  this->getClassCName(), this->getCName(), Element2D::layer2DToChar(this->layer));
+        child->layer = this->layer;
+        this->children.push_front(child);
+      }
+      else
+      {
+        // Inserting the Element at the right Layer depth.
+        std::list<Element2D*>::iterator elem;
+        for (elem = this->children.begin(); elem != this->children.end(); elem++)
+        {
+          if ((*elem)->layer <= child->layer)
+          {
+            this->children.insert(elem, child);
+            break;
+          }
+        }
+        // if we are at the Last child push it back.
+        if (elem == this->children.end())
+          this->children.push_back(child);
+      }
+    }
+    else
+    {
+      PRINTF(1)("Tried to reparent2D to own child '%s::%s' to '%s::%s'.\n",
+                this->getClassCName(), this->getCName(), child->getClassCName(), child->getCName());
+      child->parent = NULL;
+    }
+  }
+  child->parentCoorChanged2D();
+}
+
+/**
+ * @see Element2D::addChild(Element2D* child);
+ * @param childName the name of the child to add to this PNode
+ */
+void Element2D::addChild2D (const std::string& childName)
+{
+  Element2D* childNode = Element2D::objectList().getObject(childName);
+  if (childNode != NULL)
+    this->addChild2D(childNode);
+}
+
+/**
+ * @brief removes a child from the node
+ * @param child the child to remove from this Node..
+ *
+ * Children from nodes will not be lost, they are referenced to NullPointer
+ */
+void Element2D::removeChild2D (Element2D* child)
+{
+  if (child != NULL)
+    child->remove2D();
+}
+
+/**
+ * !! PRIVATE FUNCTION
+ * @brief reparents an Element2D (happens on Parents Node delete or remove and Flags are set.)
+ */
+void Element2D::reparent2D()
+{
+  if (this->parentMode & E2D_REPARENT_TO_NULL)
+    this->setParent2D((Element2D*)NULL);
+  else if (this->parentMode & E2D_REPARENT_TO_PARENTS_PARENT && this->parent != NULL)
+    this->setParent2D(this->parent->getParent2D());
+  else
+    this->setParent2D(Element2D::getNullElement());
+}
+
+
+/**
+ * @param child the child to be erased from this Nodes List
+ */
+void Element2D::eraseChild2D(Element2D* child)
+{
+  assert (this != NULL && child != NULL);
+  std::list<Element2D*>::iterator childIT = std::find(this->children.begin(), this->children.end(), child);
+  this->children.erase(childIT);
+}
+
+
+
+/**
+ * @brief remove this Element from the tree and adds all children to NullElement2D
+ *
+ * afterwards this Node is free, and can be reattached, or deleted freely.
+ */
+void Element2D::remove2D()
+{
+  std::list<Element2D*>::iterator child = this->children.begin();
+  std::list<Element2D*>::iterator reparenter;
+  while (child != this->children.end())
+  {
+    reparenter = child;
+    child++;
+    if (this->parentMode & E2D_REPARENT_CHILDREN_ON_REMOVE ||
+        (*reparenter)->parentMode & E2D_REPARENT_ON_PARENTS_REMOVE)
+    {
+      (*reparenter)->reparent2D();
+      PRINTF(5)("REPARENTED TO: %s::%s\n",(*reparenter)->getParent2D()->getClassCName(),(*reparenter)->getParent2D()->getCName());
+    }
+  }
+  if (this->parent != NULL)
+  {
+    this->parent->eraseChild2D(this);
+    this->parent = NULL;
+  }
+}
+
+
+/**
+ * @see Element2D::setParent(Element2D* parent);
+ * @param parentName the name of the Parent to set to this Element2D
+ */
+void Element2D::setParent2D (const std::string& parentName)
+{
+  Element2D* parentNode = Element2D::objectList().getObject(parentName);
+  if (parentNode != NULL)
+    parentNode->addChild2D(this);
+  else
+    PRINTF(2)("Not Found Element2D's (%s::%s) new Parent by Name: %s\n",
+              this->getClassCName(), this->getCName(), parentName.c_str());
+}
+
+/**
+ * @brief does the reparenting in a very smooth way
+ * @param parentNode the new Node to connect this node to.
+ * @param bias the speed to iterate to this new Positions
+ */
+void Element2D::setParentSoft2D(Element2D* parentNode, float bias)
+{
+  if (this->parent == parentNode)
+    return;
+
+  if (likely(this->toCoordinate == NULL))
+  {
+    this->toCoordinate = new Vector2D();
+    *this->toCoordinate = this->getRelCoor2D();
+  }
+  if (likely(this->toDirection == NULL))
+  {
+    this->toDirection = new float;
+    *this->toDirection = this->getRelDir2D();
+  }
+  this->bias = bias;
+
+
+  Vector2D tmpV = this->getAbsCoor2D();
+  float tmpQ = this->getAbsDir2D();
+
+  parentNode->addChild2D(this);
+
+  if (this->parentMode & E2D_PARENT_ROTATE_MOVEMENT) //! @todo implement this.
+    ;//this->setRelCoor(this->parent->getAbsDir().inverse().apply(tmpV - this->parent->getAbsCoor()));
+  else
+    this->relCoordinate = (tmpV - parentNode->getAbsCoor2D());
+  this->bRelCoorChanged = true;
+
+  this->relDirection = (tmpQ - parentNode->getAbsDir2D());
+  this->bRelDirChanged = true;
+}
+
+/**
+ * @brief does the reparenting in a very smooth way
+ * @param parentName the name of the Parent to reconnect to
+ * @param bias the speed to iterate to this new Positions
+ */
+void Element2D::setParentSoft2D(const std::string& parentName, float bias)
+{
+  Element2D* parentNode = Element2D::objectList().getObject(parentName);
+  if (parentNode != NULL)
+    this->setParentSoft2D(parentNode, bias);
+}
+
+/**
+ * @param parentMode sets the parentingMode of this Node
+ */
+void Element2D::setParentMode2D(E2D_PARENT_MODE parentMode)
+{
+  this->parentMode = ((this->parentMode & 0xfff0) | parentMode);
+}
+
+
+/**
+ * @brief sets the mode of this parent manually
+ * @param parentMode a String representing this parentingMode
+ */
+void Element2D::setParentMode2D (const std::string& parentingMode)
+{
+  this->setParentMode2D(Element2D::stringToParentingMode2D(parentingMode));
+}
+
+/**
+ * @brief checks if elem1 is in a deeper layer as elem2
+ * @param elem1 the first Element2D
+ * @param elem2 the second Element2D
+ * @returns true if elem1->layer < elem2->layer
+ */
+bool Element2D::layerSortPredicate(const Element2D* elem1, const Element2D* elem2)
+{
+  return elem1->layer < elem2->layer;
+}
+
+
+/**
+ * @returns the NullElement (and if needed (most probably) creates it)
+ */
+Element2D* Element2D::createNullElement()
+{
+  if (likely(Element2D::nullElement == NULL))
+  {
+    Element2D::nullElement = new Element2D(NULL, E2D_LAYER_BELOW_ALL, E2D_PARENT_MODE_DEFAULT | E2D_REPARENT_TO_NULL);
+    Element2D::nullElement->setName("NullElement");
+  }
+  return Element2D::nullElement;
+}
+
+
+/**
+ * !! PRIVATE FUNCTION
+ * @brief checks the upward integrity (e.g if Element2D is somewhere up the Node tree.)
+ * @param checkParent the Parent to check.
+ * @returns true if the integrity-check succeeds, false otherwise.
+ *
+ * If there is a second occurence of checkParent before NULL, then a loop could get
+ * into the Tree, and we do not want this.
+ */
+bool Element2D::checkIntegrity(const Element2D* checkParent) const
+{
+  const Element2D* parent = this;
+  while ( (parent = parent->getParent2D()) != NULL)
+    if (unlikely(parent == checkParent))
+      return false;
+  return true;
+}
+
+
+/**
+ * @brief updates the absCoordinate/absDirection
+ * @param dt The time passed since the last update
+
+   this is used to go through the parent-tree to update all the absolute coordinates
+   and directions. this update should be done by the engine, so you don't have to
+   worry, normaly...
+ */
+void Element2D::update2D (float dt)
+{
+  // setting the Position of this 2D-Element.
+  if( likely(this->parent != NULL))
+  {
+    // movement for nodes with smoothMove enabled
+    if (unlikely(this->toCoordinate != NULL))
+    {
+      Vector2D moveVect = (*this->toCoordinate - this->relCoordinate) *fabsf(dt)*bias;
+
+      if (likely(moveVect.len() >= .001))//PNODE_ITERATION_DELTA))
+      {
+        this->shiftCoor2D(moveVect);
+      }
+      else
+      {
+        Vector2D tmp = *this->toCoordinate;
+        this->setRelCoor2D(tmp);
+        PRINTF(5)("SmoothMove of %s finished\n", this->getCName());
+      }
+    }
+    if (unlikely(this->toDirection != NULL))
+    {
+      float rotFlot = (*this->toDirection - this->relDirection) *fabsf(dt)*bias;
+      if (likely(fabsf(rotFlot) >= .001))//PNODE_ITERATION_DELTA))
+      {
+        this->shiftDir2D(rotFlot);
+      }
+      else
+      {
+        float tmp = *this->toDirection;
+        this->setRelDir2D(tmp);
+        PRINTF(5)("SmoothRotate of %s finished\n", this->getCName());
+      }
+    }
+    if (unlikely(this->toSize != NULL))
+    {
+      Vector2D shiftSize = (*this->toSize - this->size) *fabsf(dt)*bias;
+      if (likely((shiftSize).len() >= .001))//PNODE_ITERATION_DELTA))
+      {
+        this->size += shiftSize;
+      }
+      else
+      {
+        delete this->toSize;
+        this->toSize = NULL;
+        PRINTF(5)("SmoothRotate of %s finished\n", this->getCName());
+      }
+    }
+
+    // MAIN UPDATE /////////////////////////////////////
+    this->lastAbsCoordinate = this->absCoordinate;
+
+    PRINTF(5)("Element2D::update - %s - (%f, %f)\n", this->getCName(), this->absCoordinate.x, this->absCoordinate.y);
+
+
+    if( this->parentMode & E2D_PARENT_LOCAL_ROTATE && this->bRelDirChanged)
+    {
+      /* update the current absDirection - remember * means rotation around sth.*/
+      this->prevRelDirection = this->relDirection;
+      this->absDirection = this->relDirection + parent->getAbsDir2D();;
+    }
+
+
+    if (unlikely(this->alignment & E2D_ALIGN_SCREEN_CENTER && this->bRelCoorChanged))
+    {
+      this->prevRelCoordinate = this->relCoordinate;
+      this->absCoordinate.x = .5 + this->relCoordinate.x;
+      this->absCoordinate.y = .5 + this->relCoordinate.y;
+    }
+    else if (unlikely(this->bindNode != NULL))
+    {
+      if (State::getCamera()->distance(this->bindNode) < 0)
+        this->bCurrentlyVisible = false;
+      else
+      {
+        this->bCurrentlyVisible = true;
+      }
+
+      /// TODO this should be done on the new Projection Matrix.
+      GLdouble projectPos[3] = {0.0, 0.0, 0.0};
+      gluProject(this->bindNode->getAbsCoor().x,
+                 this->bindNode->getAbsCoor().y,
+                 this->bindNode->getAbsCoor().z,
+                 GraphicsEngine::modMat,
+                 GraphicsEngine::projMat,
+                 GraphicsEngine::viewPort,
+                 projectPos,
+                 projectPos+1,
+                 projectPos+2);
+      //       printf("%s::%s  == %f %f %f :: %f %f\n", this->getClassCName(), this->getName(),
+      //              this->bindNode->getAbsCoor().x,
+      //              this->bindNode->getAbsCoor().y,
+      //              this->bindNode->getAbsCoor().z,
+      //              projectPos[0],
+      //              projectPos[1]);
+
+      this->prevRelCoordinate.x = this->absCoordinate.x = projectPos[0] /* /(float)GraphicsEngine::getInstance()->getResolutionX() */ + this->relCoordinate.x;
+      this->prevRelCoordinate.y = this->absCoordinate.y = (float)GraphicsEngine::getInstance()->getResolutionY() -  projectPos[1] + this->relCoordinate.y;
+      this->bRelCoorChanged = true;
+    }
+    else
+    {
+      if(likely(this->parentMode & PNODE_MOVEMENT && this->bRelCoorChanged))
+      {
+        /* update the current absCoordinate */
+        this->prevRelCoordinate = this->relCoordinate;
+        this->absCoordinate = this->parent->getAbsCoor2D() + this->relCoordinate;
+      }
+      else if( this->parentMode & PNODE_ROTATE_MOVEMENT && this->bRelCoorChanged)
+      {
+        /* update the current absCoordinate */
+        this->prevRelCoordinate = this->relCoordinate;
+//         float sine = sin(this->parent->getAbsDir2D());
+//         float cose = cos(this->parent->getAbsDir2D());
+        //        this->absCoordinate.x = this->relCoordinate.x*cose - this->relCoordinate.y*sine + this->parent->getRelCoor2D().x*(1-cose) +this->parent->getRelCoor2D().y*sine;
+        //        this->absCoordinate.y = this->relCoordinate.x*sine + this->relCoordinate.y*cose + this->parent->getRelCoor2D().y*(1-cose) +this->parent->getRelCoor2D().x*sine;
+
+        this->absCoordinate.x = this->parent->getAbsCoor2D().x + (this->relCoordinate.x*cos(this->parent->getAbsDir2D()) - this->relCoordinate.y * sin(this->parent->getAbsDir2D()));
+        this->absCoordinate.y = this->parent->getAbsCoor2D().y + (this->relCoordinate.x*sin(this->parent->getAbsDir2D()) + this->relCoordinate.y * cos(this->parent->getAbsDir2D()));
+
+      }
+    }
+    /////////////////////////////////////////////////
+  }
+  else
+  {
+    PRINTF(5)("Element2D::update - (%f, %f)\n", this->absCoordinate.x, this->absCoordinate.y);
+    if (this->bRelCoorChanged)
+    {
+      this->prevRelCoordinate = this->relCoordinate;
+      this->absCoordinate = this->relCoordinate;
+    }
+    if (this->bRelDirChanged)
+    {
+      this->prevRelDirection = this->relDirection;
+      this->absDirection = this->getAbsDir2D() + this->relDirection;
+    }
+  }
+
+
+  // UPDATE CHILDREN
+  if(!this->children.empty() || this->parentMode & E2D_UPDATE_CHILDREN_IF_INACTIVE)
+  {
+    std::list<Element2D*>::iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child++)
+    {
+      /* if this node has changed, make sure, that all children are updated also */
+      if( likely(this->bRelCoorChanged))
+        (*child)->parentCoorChanged2D();
+      if( likely(this->bRelDirChanged))
+        (*child)->parentDirChanged2D();
+
+      (*child)->update2D(dt);
+    }
+  }
+
+  // FINISHING PROCESS
+  this->velocity = (this->absCoordinate - this->lastAbsCoordinate) / dt;
+  this->bRelCoorChanged = false;
+  this->bRelDirChanged = false;
+}
+
+
+/**
+ * @brief displays some information about this pNode
+ * @param depth The deph into which to debug the children of this Element2D to.
+ * (0: all children will be debugged, 1: only this Element2D, 2: this and direct children...)
+ * @param level The n-th level of the Node we draw (this is internal and only for nice output)
+ */
+void Element2D::debug2D (unsigned int depth, unsigned int level) const
+{
+  for (unsigned int i = 0; i < level; i++)
+    PRINT(0)(" |");
+  if (this->children.size() > 0)
+    PRINT(0)(" +");
+  else
+    PRINT(0)(" -");
+  PRINT(0)("E2D(%s::%s);AC:(%0.2f, %0.2f);RC:(%0.2f, %0.2f);AD(%0.2f)->%s;Layer:(%s)\n",
+           this->getClassCName(),
+           this->getCName(),
+           this->absCoordinate.x,
+           this->absCoordinate.y,
+           this->relCoordinate.x,
+           this->relCoordinate.y,
+           this->getAbsDir2D(),
+           Element2D::parentingModeToString2D(parentMode),
+           Element2D::layer2DToChar(this->layer));
+
+  if (depth >= 2 || depth == 0)
+  {
+    std::list<Element2D*>::const_iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child++)
+    {
+      if (depth == 0)
+        (*child)->debug2D(0, level + 1);
+      else
+        (*child)->debug2D(depth - 1, level +1);
+    }
+  }
+}
+
+/**
+ * @brief ticks the 2d-Element
+ * @param dt the time elapsed since the last tick
+ *
+ * the element only gets tickt, if it is active.
+ * Be aware, that this walks through the entire Element2D-tree,
+ * searching for Elements to be ticked.
+ */
+void Element2D::tick2D(float dt)
+{
+  if (this->bActive)
+    this->tick(dt);
+  if (this->children.size() > 0)
+  {
+    std::list<Element2D*>::iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child++)
+      (*child)->tick2D(dt);
+  }
+}
+
+/**
+ * @brief draws all the Elements from this element2D downwards
+ * @param from the minimal Layer to draw. @see E2D_LAYER
+ * @param to the maximal Layer to draw. @see E2D_LAYER
+ *
+ */
+void Element2D::draw2D(E2D_LAYER from, E2D_LAYER to) const
+{
+  if (this->isVisible())
+  {
+    this->draw();
+    this->drawChildren(from, to);
+  }
+  else if ((parentMode & E2D_HIDE_CHILDREN_IF_HIDDEN) == 0)
+    this->drawChildren(from, to);
+}
+
+/**
+ * @brief Draws the Children of the Element2D node.
+ * @param param the minimal Layer to draw. @see E2D_LAYER
+ * @param to the maximal Layer to draw. @see E2D_LAYER
+ */
+void Element2D::drawChildren(E2D_LAYER from, E2D_LAYER to) const
+{
+  if (likely(this->children.size() > 0))
+  {
+    std::list<Element2D*>::const_iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child++)
+      if (likely( (*child)->layer >= from && (*child)->layer <= to))
+        (*child)->draw2D(from, to);
+  }
+}
+
+
+/**
+ * @brief displays the Element2D at its position with its rotation as a Plane.
+ */
+void Element2D::debugDraw2D(unsigned int depth, float size, Vector color, unsigned int level) const
+{
+  if (level == 0)
+  {
+    glPushAttrib(GL_ENABLE_BIT);
+    glMatrixMode(GL_MODELVIEW);
+
+    glDisable(GL_LIGHTING);
+    glDisable(GL_BLEND);
+    glDisable(GL_TEXTURE_2D);
+  }
+
+  glPushMatrix();
+  /* translate */
+  /* rotate */
+  glColor3f(color.x, color.y, color.z);
+
+  glTranslatef (this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
+  glRotatef(this->getAbsDir2D(), 0,0,1);
+  glBegin(GL_LINE_LOOP);
+  glVertex2f(0, 0);
+  glVertex2f(0, +this->getSizeY2D());
+  glVertex2f(+this->getSizeX2D(), +this->getSizeY2D());
+  glVertex2f(+this->getSizeX2D(), 0);
+  glEnd();
+
+
+  glPopMatrix();
+  if (depth >= 2 || depth == 0)
+  {
+    Vector childColor =  Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(20,0,.0));
+    std::list<Element2D*>::const_iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child++)
+    {
+      // drawing the Dependency graph
+      if (this != Element2D::getNullElement())
+      {
+        glBegin(GL_LINES);
+        glColor3f(color.x, color.y, color.z);
+        glVertex3f(this->getAbsCoor2D ().x,
+                   this->getAbsCoor2D ().y,
+                   0);
+        glColor3f(childColor.x, childColor.y, childColor.z);
+        glVertex3f((*child)->getAbsCoor2D ().x,
+                   (*child)->getAbsCoor2D ().y,
+                   0);
+        glEnd();
+      }
+      if (depth == 0)
+        (*child)->debugDraw2D(0, size, childColor, level+1);
+      else
+        (*child)->debugDraw2D(depth - 1, size, childColor, level +1);
+    }
+  }
+  if (level == 0)
+    glPopAttrib();
+}
+
+
+// helper functions //
+/**
+ * @brief converts a parentingMode into a string that is the name of it
+ * @param parentingMode the ParentingMode to convert
+ * @return the converted string
+ */
+const char* Element2D::parentingModeToString2D(int parentingMode)
+{
+  if (parentingMode == E2D_PARENT_LOCAL_ROTATE)
+    return "local-rotate";
+  else if (parentingMode == E2D_PARENT_ROTATE_MOVEMENT)
+    return "rotate-movement";
+  else if (parentingMode == E2D_PARENT_MOVEMENT)
+    return "movement";
+  else if (parentingMode == E2D_PARENT_ALL)
+    return "all";
+  else if (parentingMode == E2D_PARENT_ROTATE_AND_MOVE)
+    return "rotate-and-move";
+  else return "all";
+}
+
+/**
+ * @brief converts a parenting-mode-string into a int
+ * @param parentingMode the string naming the parentingMode
+ * @return the int corresponding to the named parentingMode
+ */
+E2D_PARENT_MODE Element2D::stringToParentingMode2D(const std::string& parentingMode)
+{
+  if (parentingMode == "local-rotate")
+    return (E2D_PARENT_LOCAL_ROTATE);
+  else  if (parentingMode == "rotate-movement")
+    return (E2D_PARENT_ROTATE_MOVEMENT);
+  else  if (parentingMode == "movement")
+    return (E2D_PARENT_MOVEMENT);
+  else  if (parentingMode == "all")
+    return (E2D_PARENT_ALL);
+  else  if (parentingMode == "rotate-and-move")
+    return (E2D_PARENT_ROTATE_AND_MOVE);
+  else return E2D_PARENT_ALL;
+}
+
+/**
+ * @brief converts a layer into its corresponding string
+ * @param layer the layer to get the name-String of.
+ * @returns the Name of the Layer (on error the default-layer-string is returned)
+ */
+const char* Element2D::layer2DToChar(E2D_LAYER layer)
+{
+  switch(layer)
+  {
+    case E2D_LAYER_ABOVE_ALL:
+      return "above-all";
+    case E2D_LAYER_TOP:
+      return "top";
+    case E2D_LAYER_MEDIUM:
+      return "medium";
+    case E2D_LAYER_BOTTOM:
+      return "bottom";
+    case E2D_LAYER_BELOW_ALL:
+      return "below-all";
+    default:
+      assert (false);
+      return layer2DToChar(E2D_DEFAULT_LAYER);
+  }
+}
+
+/**
+ * @brief converts a String holding a actual Layer
+ * @param layer the String to convert into a Layer2D
+ * @returns the E2D_LAYER on success, E2D_DEFAULT_LAYER on error.
+ */
+E2D_LAYER Element2D::charToLayer2D(const std::string& layer)
+{
+  if (layer == "above-all")
+    return (E2D_LAYER_ABOVE_ALL);
+  if (layer == "top")
+    return (E2D_LAYER_TOP);
+  else  if (layer == "medium")
+    return (E2D_LAYER_MEDIUM);
+  else  if (layer == "bottom")
+    return (E2D_LAYER_BOTTOM);
+  else  if (layer == "below-all")
+    return (E2D_LAYER_BELOW_ALL);
+  else
+    return (E2D_DEFAULT_LAYER);
+}
Index: branches/heathaze/src/lib/graphics/render2D/element_2d.h
===================================================================
--- branches/heathaze/src/lib/graphics/render2D/element_2d.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/render2D/element_2d.h	(revision 9940)
@@ -0,0 +1,284 @@
+/*!
+ * @file element_2d.h
+ * Definition of the 2D elements rendered on top of all other stuff.
+ */
+
+#ifndef _ELEMENT_2D_H
+#define _ELEMENT_2D_H
+
+#include "base_object.h"
+
+#include "vector.h"
+#include "vector2D.h"
+#include <list>
+
+// FORWARD DECLARATION
+class PNode;
+class TiXmlElement;
+
+//!< An enumerator defining the Depth of a 2D-element.
+typedef enum
+{
+  E2D_LAYER_BELOW_ALL           =     0,        //!< Will be rendered below the 3D-scene. @todo make this work.
+  E2D_LAYER_BOTTOM              =     1,        //!< Will be rendered on the bottom Layer
+  E2D_LAYER_MEDIUM              =     2,        //!< Will be rendered on the medium Layer.
+  E2D_LAYER_TOP                 =     3,        //!< Will be rendered on top of everything else
+  E2D_LAYER_ABOVE_ALL           =     4,        //!< Will be rendered above everything else.
+
+  E2D_LAYER_COUNT               =     5,         //!< The count of Layers.
+} E2D_LAYER;
+#define E2D_DEFAULT_LAYER       E2D_LAYER_MEDIUM
+#define E2D_LAYER_ALL           5
+
+typedef enum
+{
+  E2D_ALIGN_NONE                =     0,
+  E2D_ALIGN_LEFT                =     1,
+  E2D_ALIGN_RIGHT               =     2,
+  E2D_ALIGN_CENTER              =     4,
+  E2D_ALIGN_SCREEN_CENTER       =     8
+} E2D_ALIGNMENT;
+
+typedef enum
+{
+  E2D_PARENT_NONE                    = 0x0000,
+  E2D_PARENT_LOCAL_ROTATE            = 0x0001,    //!< Rotates all the children around their centers.
+  E2D_PARENT_ROTATE_MOVEMENT         = 0x0002,    //!< Moves all the children around the center of their parent, without the rotation around their own centers.
+
+  E2D_PARENT_MOVEMENT                = 0x0004,    //!< Moves all children along with the parent.
+  // special linkage modes
+  E2D_PARENT_ALL                     = 0x0003,    //!< Moves all children around the center of their parent, and also rotates their centers
+  E2D_PARENT_ROTATE_AND_MOVE         = 0x0005,    //!< Rotates all children around their axis, and moves them as the Parent Moves, but does not rotate around the center of their parent.
+
+
+  // REPARENTING
+  E2D_REPARENT_TO_NULL               = 0x0010,    //!< Reparents to the Null, if the Parent is Removed. Meaning the Node wont have a parent anymore.
+  E2D_REPARENT_TO_PARENTS_PARENT     = 0x0020,    //!< Reparents the Node to the parents (old) parent it the parent gets removed.
+  /////////////////////////////////////////////   //  ELSE: Reparents to the NullParent.
+  E2D_REPARENT_DELETE_CHILDREN       = 0x0040,    //!< Deletes the Children of the node when This Node is Removed. (Use with care).
+  /// FIXME
+  E2D_REPARENT_KEEP_POSITION         = 0x0080,   //!< Tries to keep the Position if the Node is reparented.
+
+
+  // DELETION
+  E2D_PROHIBIT_CHILD_DELETE          = 0x0100,    //!< Prohibits the Children from being deleted if this Node gets deleted.
+  E2D_PROHIBIT_DELETE_WITH_PARENT    = 0x0200,    //!< Prohibits the Node to be deleted if the Parent is. Child will be reparented according to the Repaenting-Rules
+  E2D_REPARENT_CHILDREN_ON_REMOVE    = 0x0400,    //!< Reparents the Children of the Node if the Node gets Removed.
+  E2D_REPARENT_ON_PARENTS_REMOVE     = 0x0800,    //!< The Node gets Reparented if its Parent gets removed. Child will be reparented according to the Reparenting-Rules.
+
+  // VISIBILITY/ACTIVITY
+  E2D_HIDE_CHILDREN_IF_HIDDEN        = 0x1000,    //!< Prohibits the Children from being drawn if this node isn't visible. (used for Draw))
+  //E2D_HIDE_IF_PARENT_HIDDEN          = 0x2000,    //!< Prohibits the node from being drawn if the Parent is invisible.
+  E2D_UPDATE_CHILDREN_IF_INACTIVE    = 0x4000,    //!< Updates the Children of this Node even if the Parent is Inactive (note if this's parent is inactive children won't be updated.)
+  E2D_STATIC_NODE                    = 0x8000,    //!< Used for nodes that do not have any moving children, and that do not move.
+
+} E2D_PARENT_MODE;
+#define     E2D_PARENT_MODE_DEFAULT     E2D_PARENT_ALL | \
+                                        E2D_REPARENT_KEEP_POSITION
+
+//! A class for 2D-elements
+/**
+ * this class mainly tries to imitate PNode in its functionality, but on a 2D-level
+ * it extends PNode in the Sense of the tick-ability/draw-alility layering (and size)
+ *
+ * Layering: Layers are sorted into the Tree. e.g:
+ * the roor is in the lowest Layer, the leaves in the highest (of each branche)
+ * the first child of each node is in the lowest layer of all children, the last in the highest
+ * -> the tree is sorted on insertion of a new Child: @see Element2D::addChild2D()
+ */
+class Element2D : virtual public BaseObject
+{
+  ObjectListDeclaration(Element2D);
+
+public:
+  Element2D(Element2D* parent = Element2D::getNullElement(), E2D_LAYER layer = E2D_DEFAULT_LAYER, short nodeFlags = E2D_PARENT_MODE_DEFAULT);
+  virtual ~Element2D();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  // ACTIVATION //
+  inline void activate2D() { this->bActive = this->bRelCoorChanged = this->bRelDirChanged = true; };
+  inline void deactivate2D() { this->bActive = false; };
+  inline bool get2DActiveState() { return this->bActive; };
+
+  // ALIGNMENT //
+  /** @param alignment the new Alignment of the 2D-Element */
+  inline void setAlignment(E2D_ALIGNMENT alignment) { this->alignment = alignment; };
+  void setAlignment(const std::string& alignment);
+  inline E2D_ALIGNMENT getAlignment() const { return this->alignment; };
+
+  // LAYERING //
+  void setLayer(E2D_LAYER layer);
+  void setLayer(const std::string& layer);
+  /** @returns the Layer this Element is drawn to */
+  inline E2D_LAYER getLayer() const { return this->layer; };
+
+  // VISIBILITY //
+  /** @param visible true if the Element should be visible false otherwise (will not be rendered) */
+  inline void setVisibility(bool visible) { this->bVisible = visible; };
+  /** @returns the visibility state */
+  inline bool isVisible() const { return (this->bVisible && this->bCurrentlyVisible);  };
+
+
+  // POSITIONAL (E2D-specials) //
+  /** @param bindNode the Node this 2D-element should follow. if NULL the Element will not follow anything */
+  void setBindNode(const PNode* bindNode);
+  void setBindNode(const std::string& bindNode);
+  inline const PNode* getBindNode() const { return this->bindNode; };
+
+  inline void setSize2D(float x, float y) { this->size = Vector2D(x, y); };
+  inline void setSize2D(const Vector2D& size) { this->size = size; };
+  inline const Vector2D& getSize2D() const { return this->size; };
+  void setSizeSoft2D(float x, float y, float bias = 1.0);
+  inline void setSizeX2D(float x) { this->size.x = x; };
+  inline void setSizeY2D(float y) { this->size.y = y; };
+  inline float getSizeX2D() const { return this->size.x; };
+  inline float getSizeY2D() const { return this->size.y; };
+
+public:
+  virtual void tick(float dt) {};
+  virtual void draw() const  {};
+  void tick2D(float dt);
+  void draw2D(E2D_LAYER from, E2D_LAYER to) const;
+  void drawChildren(E2D_LAYER from, E2D_LAYER to) const;
+
+  // LIKE PNODE
+public:
+  void setRelCoor2D (const Vector2D& relCoord);
+  void setRelCoorX2D(float x);
+  void setRelCoorY2D(float y);
+  void setRelCoor2D (float x, float y);
+  void setRelCoor2Dpx (int x, int y);
+  void setRelCoorSoft2D (const Vector2D& relCoordSoft, float bias = 1.0);
+  void setRelCoorSoft2D (float x, float y, float bias = 1.0);
+  void setRelCoorSoft2Dpx (int x, int y, float bias = 1.0);
+  /** @returns the relative position */
+  inline const Vector2D& getRelCoor2D () const { return this->prevRelCoordinate; };
+  /** @returns the Relative Coordinate Destination */
+inline const Vector2D& getRelCoorSoft2D() const { return (this->toCoordinate)?*this->toCoordinate:this->relCoordinate; };
+  const Vector2D& getRelCoor2Dpx() const;
+  void setAbsCoor2D (const Vector2D& absCoord);
+  void setAbsCoor2D (float x, float y);
+  void setAbsCoorX2D(float x);
+  void setAbsCoorY2D(float y);
+  void setAbsCoor2Dpx (int x, int y);
+  void setAbsCoorSoft2D (const Vector2D& absCoordSoft, float bias = 1.0);
+  void setAbsCoorSoft2D (float x, float y, float bias = 1.0);
+  /** @returns the absolute position */
+  inline const Vector2D& getAbsCoor2D () const { return this->absCoordinate; };
+  const Vector2D& getAbsCoor2Dpx () const;
+
+  void shiftCoor2D (const Vector2D& shift);
+  void shiftCoor2Dpx (int x, int y);
+
+  void setRelDir2D (float relDir);
+  void setRelDirSoft2D(float relDirSoft, float bias = 1.0);
+  /** @returns the relative Direction */
+  inline float getRelDir2D () const { return this->prevRelDirection; };
+  /** @returns the Relative Directional Destination */
+inline float getRelDirSoft2D() const { return (this->toDirection)?*this->toDirection:this->relDirection; };
+  void setAbsDir2D (float absDir);
+  void setAbsDirSoft2D (float absDirSoft, float bias = 1.0);
+  /** @returns the absolute Direction */
+  inline float getAbsDir2D () const { return this->absDirection; };
+  void shiftDir2D (float shiftDir);
+
+  /** @returns the Speed of the Node */
+  inline float getSpeed() const { return 0; };
+  /** @returns the Velocity of the Node */
+  inline const Vector2D& getVelocity() const { return this->velocity; };
+
+
+  void addChild2D (Element2D* child);
+  void addChild2D (const std::string& childName);
+  void removeChild2D (Element2D* child);
+  void remove2D();
+
+  /** @param parent the new parent of this Element2D */
+  void setParent2D (Element2D* parent) { parent->addChild2D(this); };
+  void setParent2D (const std::string& parentName);
+  /** @returns the parent of this Element2D */
+  inline Element2D* getParent2D () const { return this->parent; };
+  /** @returns the List of Children of this Element2D */
+  inline const std::list<Element2D*>& getChildren2D() const { return this->children; };
+
+  void setParentSoft2D(Element2D* parentNode, float bias = 1.0);
+  void setParentSoft2D(const std::string& parentName, float bias = 1.0);
+
+  void setParentMode2D (E2D_PARENT_MODE parentMode);
+  void setParentMode2D (const std::string& parentingMode);
+  /** @returns the Parenting mode of this node */
+  int getParentMode2D() const { return this->parentMode; };
+
+  // NULL_PARENT //
+  /** @returns the NullParent, the (main) ROOT of the PNode Tree. If it does not yet exist, it will be created. */
+static Element2D* getNullElement()  { return (Element2D::nullElement != NULL)? Element2D::nullElement : Element2D::createNullElement(); };
+
+
+  void update2D (float dt);
+
+  void debug2D (unsigned int depth = 1, unsigned int level = 0) const;
+  void debugDraw2D(unsigned int depth = 1, float size = 1.0, Vector color = Vector(1,0,0), unsigned int level = 0) const;
+
+  // helper functions //
+  static const char* parentingModeToString2D(int parentingMode);
+  static E2D_PARENT_MODE stringToParentingMode2D(const std::string& parentingMode);
+
+  static const char* layer2DToChar(E2D_LAYER layer);
+  static E2D_LAYER charToLayer2D(const std::string& layer);
+
+  static bool layerSortPredicate(const Element2D* elem1, const Element2D* elem2);
+
+private:
+  void eraseChild2D(Element2D* child);
+  /** tells the child that the parent's Coordinate has changed */
+  inline void parentCoorChanged2D () { this->bRelCoorChanged = true; }
+  /** tells the child that the parent's Direction has changed */
+  inline void parentDirChanged2D () { this->bRelDirChanged = true; }
+  /** @returns the last calculated coordinate */
+  inline Vector2D getLastAbsCoor2D() { return this->lastAbsCoordinate; }
+
+  void reparent2D();
+  static Element2D* createNullElement();
+  bool checkIntegrity(const Element2D* checkParent) const;
+
+
+private:
+  const PNode*            bindNode;           //!< a node over which to display this 2D-element
+  Vector2D                size;               //!< The size of the rendered item
+  Vector2D*               toSize;             //!< The Size to iterate to.
+
+  E2D_ALIGNMENT           alignment;          //!< How the Element is aligned around its Position
+
+  bool                    bVisible;           //!< If the given Element2D is visible.
+  bool                    bCurrentlyVisible;  //!< Evaluated in the TICK process, to see if the Element is Currently visible.
+  bool                    bActive;            //!< If the given Element2D is active.
+  E2D_LAYER               layer;              //!< What layer this Element2D is on.
+
+  bool                    bRelCoorChanged;    //!< If Relative Coordinate has changed since last time we checked
+  bool                    bRelDirChanged;     //!< If Relative Direction has changed since last time we checked
+
+  Vector2D                relCoordinate;      //!< coordinates relative to the parent
+  Vector2D                absCoordinate;      //!< absolute coordinates in the world ( from (0,0,0) )
+  float                   relDirection;       //!< direction relative to the parent
+  float                   absDirection;       //!< absolute diretion in the world ( from (0,0,1) )
+
+  Vector2D                prevRelCoordinate;  //!< The last Relative Coordinate from the last update-Cycle.
+  Vector2D                lastAbsCoordinate;  //!< this is used for speedcalculation, it stores the last coordinate
+  float                   prevRelDirection;   //!< The last Relative Direciton from the last update-Cycle.
+
+  Vector2D                velocity;           //!< Saves the velocity.
+
+  Vector2D*               toCoordinate;       //!< a position to which to iterate. (This is used in conjunction with setParentSoft.and set*CoorSoft)
+  float*                  toDirection;        //!< a direction to which to iterate. (This is used in conjunction with setParentSoft and set*DirSoft)
+  float                   bias;               //!< how fast to iterate to the given position (default is 1)
+
+  Element2D*              parent;             //!< a pointer to the parent node
+  std::list<Element2D*>   children;           //!< list of the children of this Element2D
+
+  unsigned int            parentMode;         //!< the mode of the binding
+
+  static Element2D*       nullElement;        //!< The top-most Element
+};
+
+#endif /* _ELEMENT_2D_H */
Index: branches/heathaze/src/lib/graphics/render2D/image_plane.cc
===================================================================
--- branches/heathaze/src/lib/graphics/render2D/image_plane.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/render2D/image_plane.cc	(revision 9940)
@@ -0,0 +1,162 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "image_plane.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "graphics_engine.h"
+#include "p_node.h"
+
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(ImagePlane, CL_IMAGE_PLANE);
+CREATE_FACTORY(ImagePlane);
+
+
+/**
+ * standart constructor
+ */
+ImagePlane::ImagePlane (const TiXmlElement* root)
+{
+  this->init();
+
+  if( root)
+    this->loadParams(root);
+}
+
+
+/**
+ * destroys a ImagePlane
+ */
+ImagePlane::~ImagePlane ()
+{
+}
+
+
+/**
+ * initializes the ImagePlane
+ */
+void ImagePlane::init()
+{
+  this->registerObject(this, ImagePlane::_objectList);
+  this->setName("ImagePlane");
+
+  this->setLayer(E2D_LAYER_TOP);
+  this->setSize(GraphicsEngine::getInstance()->getResolutionX()/10.0, GraphicsEngine::getInstance()->getResolutionY()/10.0);
+
+  //this->setBindNode(this);
+  this->setTexture("pictures/error_texture.png");
+}
+
+
+/**
+ *  load params
+ * @param root TiXmlElement object
+ */
+void ImagePlane::loadParams(const TiXmlElement* root)
+{
+  LoadParam(root, "texture", &this->material, Material, setDiffuseMap)
+      .describe("the texture-file to load onto the ImagePlane");
+
+  LoadParam(root, "size", this, ImagePlane, setSize)
+      .describe("the size of the ImagePlane in Pixels");
+}
+
+
+/**
+ * sets the size of the ImagePlane.
+ * @param size the size in pixels
+ */
+void ImagePlane::setSize(float sizeX, float sizeY)
+{
+  this->setSize2D(sizeX, sizeY);
+}
+
+
+/**
+ * sets the material to load
+ * @param textureFile The texture-file to load onto the crosshair
+ */
+void ImagePlane::setTexture(const std::string& textureFile)
+{
+  this->material.setDiffuseMap(textureFile);
+}
+
+
+/**
+ * attaches this image_plane to a parent
+ * @param pNode node to attach to
+ */
+void ImagePlane::attachTo(PNode* pNode)
+{
+  this->source->setParent(pNode);
+}
+
+
+/**
+ * ticks the ImagePlane
+ * @param dt the time to ticks
+ */
+void ImagePlane::tick(float dt)
+{
+  float z = 0.0f;
+  glReadPixels ((int)this->getAbsCoor2D().x,
+                 GraphicsEngine::getInstance()->getResolutionY()-(int)this->getAbsCoor2D().y-1,
+                 1,
+                 1,
+                 GL_DEPTH_COMPONENT,
+                 GL_FLOAT,
+                 &z);
+
+  GLdouble objX=.0, objY=.0, objZ=.0;
+  gluUnProject(this->getAbsCoor2D().x,
+               GraphicsEngine::getInstance()->getResolutionY()-this->getAbsCoor2D().y-1,
+               .99,  // z
+               GraphicsEngine::modMat,
+               GraphicsEngine::projMat,
+               GraphicsEngine::viewPort,
+               &objX,
+               &objY,
+               &objZ );
+}
+
+
+/**
+ * draws the image_plane
+ */
+void ImagePlane::draw() const
+{
+  glPushMatrix();
+
+  glTranslatef(this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
+  this->material.select();
+
+  glBegin(GL_TRIANGLE_STRIP);
+  glTexCoord2f(0, 0);
+  glVertex2f(-this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(1, 0);
+  glVertex2f(this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(0, 1);
+  glVertex2f(-this->getSizeX2D(), this->getSizeY2D());
+  glTexCoord2f(1, 1);
+  glVertex2f(this->getSizeX2D(), this->getSizeY2D());
+  glEnd();
+
+  glPopMatrix();
+}
Index: branches/heathaze/src/lib/graphics/render2D/image_plane.h
===================================================================
--- branches/heathaze/src/lib/graphics/render2D/image_plane.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/render2D/image_plane.h	(revision 9940)
@@ -0,0 +1,43 @@
+/*!
+ * @file image_plane.h
+ *  Definition of a image_plane
+ */
+
+#ifndef _IMAGE_PLANE_H
+#define _IMAGE_PLANE_H
+
+
+#include "element_2d.h"
+
+#include "vector.h"
+#include "material.h"
+
+
+//! A class that enables the
+class ImagePlane :  public Element2D
+{
+  ObjectListDeclaration(ImagePlane);
+  public:
+    ImagePlane(const TiXmlElement* root = NULL);
+    virtual ~ImagePlane();
+
+    void init();
+    void loadParams(const TiXmlElement* root);
+
+    void setSize(float sizeX, float sizeY);
+    void setTexture(const std::string& textureFile);
+    void attachTo(PNode* pnode);
+
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+
+  private:
+    Material         material;             //!< a material for the ImagePlane
+    float            rotationSpeed;        //!< Speed of the Rotation.
+
+    PNode*           source;               //!< the source attached to it
+
+};
+
+#endif /* _IMAGE_PLANE_H */
Index: branches/heathaze/src/lib/graphics/render2D/render_2d.cc
===================================================================
--- branches/heathaze/src/lib/graphics/render2D/render_2d.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/render2D/render_2d.cc	(revision 9940)
@@ -0,0 +1,86 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "render_2d.h"
+
+#include "graphics_engine.h"
+#include "element_2d.h"
+
+ObjectListDefinition(Render2D);
+
+
+/**
+ * @brief standard constructor
+ */
+Render2D::Render2D ()
+{
+  this->registerObject(this, Render2D::_objectList);
+  this->setName("Render2D");
+
+  this->showNodes = false;
+}
+
+/**
+ * @brief the singleton reference to this class
+ */
+Render2D* Render2D::singletonRef = NULL;
+
+/**
+ * @brief standard deconstructor
+ */
+Render2D::~Render2D ()
+{
+  delete Element2D::getNullElement();
+
+  Render2D::singletonRef = NULL;
+}
+
+/**
+ * @brief updates all the 2d-elements
+ * @param dt the timestep since last dt
+ */
+void Render2D::update(float dt)
+{
+  Element2D::getNullElement()->update2D(dt);
+}
+
+
+/**
+ * @brief ticks all the 2d-elements
+ * @param dt the timestep since last dt
+ */
+void Render2D::tick(float dt)
+{
+  Element2D::getNullElement()->tick2D(dt);
+}
+
+/**
+ * @brief renders all the Elements of the Render2D-engine's layer
+ * @param layer the Layer to draw (if E2D_LAYER_ALL then all layers will be drawn)
+ */
+void Render2D::draw(E2D_LAYER from, E2D_LAYER to) const
+{
+  GraphicsEngine::enter2DMode();
+
+  Element2D::getNullElement()->draw2D(from, to);
+  if (this->showNodes)
+    Element2D::getNullElement()->debugDraw2D(0);
+
+  GraphicsEngine::leave2DMode();
+}
+
+
Index: branches/heathaze/src/lib/graphics/render2D/render_2d.h
===================================================================
--- branches/heathaze/src/lib/graphics/render2D/render_2d.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/render2D/render_2d.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file render_2d.h
+ * @brief Definition of the 2D-rendering engine singleton Class
+ */
+
+#ifndef _RENDER_2D_H
+#define _RENDER_2D_H
+
+#include "base_object.h"
+#include "element_2d.h"
+// FORWARD DECLARATION
+
+//! A default singleton class.
+class Render2D : public BaseObject
+{
+  ObjectListDeclaration(Render2D);
+
+  friend class Element2D;
+
+public:
+  virtual ~Render2D();
+  /** @returns a Pointer to the only object of this Class */
+  inline static Render2D* getInstance() { if (!singletonRef) singletonRef = new Render2D();  return singletonRef; };
+
+void toggleNodesVisibility() { this->showNodes = !this->showNodes; };
+
+  void update(float dt);
+  void tick(float dt);
+  void draw(E2D_LAYER from, E2D_LAYER to) const;
+
+private:
+  Render2D();
+  static Render2D*              singletonRef;                    //!< Reference to this class.
+
+  bool                          showNodes;                       //!< If the debug-Nodes should be visible
+};
+
+#endif /* _RENDER_2D_H */
Index: branches/heathaze/src/lib/graphics/resource_shader.cc
===================================================================
--- branches/heathaze/src/lib/graphics/resource_shader.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/resource_shader.cc	(revision 9940)
@@ -0,0 +1,47 @@
+
+#include "resource_shader.h"
+#include "debug.h"
+#include "substring.h"
+
+ResourceShader::ResourceShader(const std::string& vertexShaderName, const std::string& fragmentShaderName, const Resources::KeepLevel& keepLevel)
+    : Resource(&ResourceShader::type)
+{
+  Resources::StorePointer* ptr = this->acquireResource(vertexShaderName +','+fragmentShaderName);
+
+  if (ptr)
+  {
+    PRINTF(5)("FOUND SHADER: %s\n", vertexShaderName.c_str());
+    this->acquireData(static_cast<ResourceShader::ShaderResourcePointer*>(ptr)->ptr());
+  }
+  else
+  {
+    PRINTF(5)("NOT FOUND SHADER: %s\n", vertexShaderName.c_str());
+    std::string vertexFileName = this->Resource::locateFile(vertexShaderName);
+    std::string fragmentFileName;
+    if (!fragmentShaderName.empty())
+      fragmentFileName = this->Resource::locateFile(fragmentShaderName);
+
+    this->Shader::load(vertexFileName, fragmentFileName);
+    this->Resource::addResource(new ResourceShader::ShaderResourcePointer(vertexShaderName+','+fragmentShaderName, keepLevel, this->Shader::dataPointer()));
+  }
+}
+
+ResourceShader ResourceShader::createFromString(const std::string& loadString, const Resources::KeepLevel& keepLevel)
+{
+  std::string vertexShaderName;
+  std::string fragmentShaderName;
+
+  SubString shaderNames(loadString, ',');
+  if (shaderNames.size() > 0)
+    vertexShaderName = shaderNames[0];
+  if (shaderNames.size() > 1)
+    fragmentShaderName = shaderNames[1];
+
+  return ResourceShader(vertexShaderName, fragmentShaderName, keepLevel);
+}
+
+Resources::tType<ResourceShader> ResourceShader::type("Shader");
+
+ResourceShader::ShaderResourcePointer::ShaderResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const ShaderData::Pointer& data)
+    : Resources::StorePointer(loadString, keepLevel) , pointer(data)
+{}
Index: branches/heathaze/src/lib/graphics/resource_shader.h
===================================================================
--- branches/heathaze/src/lib/graphics/resource_shader.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/resource_shader.h	(revision 9940)
@@ -0,0 +1,39 @@
+/*!
+ * @file resource_shader.h
+ * @brief Contains the ResourceShader class, that handles the Resource-specific loading part of the Shader.
+ *
+ */
+
+#ifndef _RESOURCE_SHADER_H
+#define _RESOURCE_SHADER_H
+
+#include "util/loading/resource.h"
+#include "shader.h"
+
+
+class ResourceShader : public Shader, public Resources::Resource
+{
+public:
+  ResourceShader(const std::string& vertexShaderName,
+		 const std::string& fragmentShaderName,
+		 const Resources::KeepLevel& keepLevel = Resources::KeepLevel());
+  static ResourceShader createFromString(const std::string& loadString,
+					 const Resources::KeepLevel& keepLevel = Resources::KeepLevel());
+
+private:
+class ShaderResourcePointer : public Resources::StorePointer
+  {
+  public:
+    ShaderResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const ShaderData::Pointer& data);
+    inline const ShaderData::Pointer& ptr() const { return pointer; }
+    virtual bool last() const { return pointer.count() == 1; }
+  private:
+    ShaderData::Pointer pointer;
+  };
+
+private:
+  static Resources::tType<ResourceShader> type;
+};
+
+
+#endif /* _RESOURCE_SHADER_H */
Index: branches/heathaze/src/lib/graphics/shader.cc
===================================================================
--- branches/heathaze/src/lib/graphics/shader.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/shader.cc	(revision 9940)
@@ -0,0 +1,120 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "shader.h"
+
+#include "compiler.h"
+//#include <stdio.h>
+#include <fstream>
+
+#include "debug.h"
+
+
+
+#ifndef PARSELINELENGTH
+#define PARSELINELENGTH     512       //!< how many chars to read at once
+#endif
+
+
+ObjectListDefinition(Shader);
+
+void Shader::Uniform::setV(unsigned int count, float* vv) const
+{
+  switch (count)
+  {
+    case 1:
+    glUniform1fv(this->uniform, 1, vv);
+    break;
+    case 2:
+    glUniform2fv(this->uniform, 2, vv);
+    break;
+    case 3:
+    glUniform3fv(this->uniform, 3, vv);
+    break;
+    case 4:
+    glUniform4fv(this->uniform, 4, vv);
+    break;
+  }
+}
+void Shader::Uniform::setV(unsigned int count, int* vv) const
+{
+  switch (count)
+  {
+    case 1:
+    glUniform1iv(this->uniform, 1, vv);
+    break;
+    case 2:
+    glUniform2iv(this->uniform, 2, vv);
+    break;
+    case 3:
+    glUniform3iv(this->uniform, 3, vv);
+    break;
+    case 4:
+    glUniform4iv(this->uniform, 4, vv);
+    break;
+  }
+}
+
+
+
+Shader::Shader()
+  : data(new ShaderData)
+{
+
+}
+
+/**
+ * standard constructor
+*/
+Shader::Shader (const std::string& vertexShaderFile, const std::string& fragmentShaderFile)
+  : data(new ShaderData)
+{
+  if (!Shader::checkShaderAbility())
+    PRINTF(2)("Your system does not support shaders\n");
+  this->load(vertexShaderFile, fragmentShaderFile);
+
+}
+
+const Shader* Shader::storedShader = NULL;
+
+void Shader::activateShader() const
+{
+  if (likely (this->getProgram() != 0))
+  {
+    glUseProgramObjectARB(this->getProgram());
+    Shader::storedShader = this;
+  }
+}
+void Shader::deactivateShader()
+{
+  if (storedShader != NULL)
+    glUseProgramObjectARB(0);
+  Shader::storedShader = NULL;
+}
+
+bool Shader::checkShaderAbility()
+{
+  if (GLEW_ARB_shader_objects &&
+      GLEW_ARB_shading_language_100 &&
+      GLEW_ARB_vertex_shader &&
+      GLEW_ARB_fragment_shader)
+    return true;
+  else
+    return false;
+}
+
+
Index: branches/heathaze/src/lib/graphics/shader.h
===================================================================
--- branches/heathaze/src/lib/graphics/shader.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/shader.h	(revision 9940)
@@ -0,0 +1,83 @@
+/*!
+ * @file shader.h
+ * @brief Definition of the Shader rendering class
+*/
+
+#ifndef _SHADER_H
+#define _SHADER_H
+
+#include "base_object.h"
+#include "shader_data.h"
+
+// FORWARD DECLARATION
+
+
+
+//! The Shader is a Class-wrapper around the OpenGL Shader Language (GLSL).
+class Shader : public BaseObject
+{
+  ObjectListDeclaration(Shader);
+public:
+  class Uniform
+  {
+  public:
+    Uniform(const Shader& shader, const std::string& location) { this->uniform = glGetUniformLocation(shader.getProgram(), location.c_str()) ; };
+    Uniform(GLhandleARB shaderProgram, const std::string& location) { this->uniform = glGetUniformLocation(shaderProgram, location.c_str()) ; };
+
+    void set(float v0) const { glUniform1f(this->uniform, v0); }
+    void set(float v0, float v1) const { glUniform2f(this->uniform, v0, v1); }
+    void set(float v0, float v1, float v2) const { glUniform3f(this->uniform, v0, v1, v2); }
+    void set(float v0, float v1, float v2, float v3) const { glUniform4f(this->uniform, v0, v1, v2, v3); }
+
+    void set(int v0) const { glUniform1i(this->uniform, v0); }
+    void set(int v0, int v1) const { glUniform2i(this->uniform, v0, v1); }
+    void set(int v0, int v1, int v2) const { glUniform3i(this->uniform, v0, v1, v2); }
+    void set(int v0, int v1, int v2, int v3) const { glUniform4i(this->uniform, v0, v1, v2, v3); }
+
+    void setV(unsigned int count, float* vv) const;
+    void setV(unsigned int count, int* vv) const;
+
+  private:
+    GLint uniform;
+  };
+
+
+public:
+  Shader();
+  Shader(const std::string& vertexShaderFile, const std::string& fragmentShaderFile = "");
+
+  Shader& operator=(const Shader& shader) { this->data = shader.data; return *this; };
+  const ShaderData::Pointer& dataPointer() const { return data; };
+  void acquireData(const ShaderData::Pointer& pointer) { this->data = pointer; };
+
+  bool load(const std::string& vertexShaderFile, const std::string& fragmentShaderFile = "")
+    { return this->data->load(vertexShaderFile, fragmentShaderFile); }
+
+
+  Shader::Uniform getUniform(const std::string& location) { return Shader::Uniform(*this, location); }
+
+  GLhandleARB getProgram() const { return this->data->getProgram(); }
+  GLhandleARB getVertexS() const { return this->data->getVertexS(); }
+  GLhandleARB getFragmentS() const { return this->data->getFragmentS(); }
+
+  void activateShader() const;
+  static void deactivateShader();
+
+  void debug() const { this->data->debug(); };
+
+
+  static bool checkShaderAbility();
+
+  inline static bool isShaderActive() { return (Shader::storedShader != NULL) ? true : false; };
+  inline static const Shader* getActiveShader() { return Shader::storedShader; };
+
+  inline static void suspendShader() { const Shader* currShader = storedShader; if (storedShader!= NULL) { Shader::deactivateShader(); Shader::storedShader = currShader;} };
+  inline static void restoreShader() { if (storedShader != NULL) storedShader->activateShader(); storedShader = NULL; };
+
+private:
+  ShaderData::Pointer    data;
+
+  static const Shader*         storedShader;
+};
+
+#endif /* _SHADER_H */
Index: branches/heathaze/src/lib/graphics/shader_data.cc
===================================================================
--- branches/heathaze/src/lib/graphics/shader_data.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/shader_data.cc	(revision 9940)
@@ -0,0 +1,267 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "shader_data.h"
+
+#include "stdlibincl.h"
+#include "compiler.h"
+//#include <stdio.h>
+#include <fstream>
+
+#include "debug.h"
+
+
+#ifndef PARSELINELENGTH
+#define PARSELINELENGTH     512       //!< how many chars to read at once
+#endif
+
+
+ObjectListDefinition(ShaderData);
+
+/**
+ * standard constructor
+*/
+ShaderData::ShaderData ()
+{
+  this->registerObject(this, ShaderData::_objectList);
+  this->shaderProgram = 0;
+  this->vertexShader = 0;
+  this->fragmentShader = 0;
+}
+
+
+/// TODO fix that shaders are unloaded first. then loaded
+bool ShaderData::load(const std::string& vertexShaderFile, const std::string& fragmentShaderFile)
+{
+  if (GLEW_ARB_shader_objects && GLEW_ARB_shading_language_100)
+  {
+    this->shaderProgram = glCreateProgramObjectARB();
+
+    if (!vertexShaderFile.empty())
+      this->loadShaderProgramm(ShaderData::Vertex, vertexShaderFile);
+    if (!fragmentShaderFile.empty())
+      this->loadShaderProgramm(ShaderData::Fragment, fragmentShaderFile);
+
+    this->linkShaderProgram();
+
+  }
+  else
+  {
+    PRINTF(2)("Shaders are not supported on your hardware\n");
+  }
+}
+
+/**
+ * standard deconstructor
+ */
+ShaderData::~ShaderData ()
+{
+  if (this->shaderProgram == glGetHandleARB(GL_PROGRAM_OBJECT_ARB))
+    glUseProgramObjectARB(0);
+
+  // delete what has to be deleted here
+  this->deleteProgram(ShaderData::Vertex);
+  this->deleteProgram(ShaderData::Fragment);
+
+  if (this->fragmentShader != 0)
+  {
+    glDetachObjectARB(this->shaderProgram, this->fragmentShader);
+    glDeleteObjectARB(this->fragmentShader);
+  }
+  if (this->vertexShader != 0)
+  {
+    glDetachObjectARB(this->shaderProgram, this->vertexShader);
+    glDeleteObjectARB(this->vertexShader);
+  }
+  if (this->shaderProgram != 0)
+  {
+    GLint status = 0;
+    //glLinkProgramARB(this->shaderProgram);
+    glDeleteObjectARB(this->shaderProgram);
+    // link error checking
+    glGetObjectParameterivARB(this->shaderProgram, GL_OBJECT_DELETE_STATUS_ARB, &status);
+    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
+      this->printError(this->shaderProgram);
+  }
+}
+
+bool ShaderData::loadShaderProgramm(ShaderData::Type type, const std::string& fileName)
+{
+  GLhandleARB shader = 0;
+
+  if (type != ShaderData::Vertex && type != ShaderData::Fragment)
+    return false;
+  this->deleteProgram(type);
+
+
+  std::string program;
+  if (!readShader(fileName, program))
+    return false;
+
+  if (type == ShaderData::Vertex && GLEW_ARB_vertex_shader)
+  {
+    this->vertexShaderFile = fileName;
+
+    shader = this->vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
+  }
+
+  if (type == ShaderData::Fragment && GLEW_ARB_fragment_shader)
+  {
+    this->fragmentShaderFile = fileName;
+
+    shader = this->fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+  }
+
+  if (shader != 0)
+  {
+    GLint status = 0;
+    const char* prog = program.c_str();
+
+    glShaderSourceARB(shader, 1, &prog, NULL);
+    glCompileShaderARB(shader);
+    // checking on error.
+    glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &status);
+    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
+      this->printError(shader);
+    else
+      glAttachObjectARB(this->shaderProgram, shader);
+  }
+  return true;
+}
+
+
+void ShaderData::linkShaderProgram()
+{
+  GLint status = 0;
+
+  glLinkProgramARB(this->shaderProgram);
+  // link error checking
+  glGetObjectParameterivARB(this->shaderProgram, GL_OBJECT_LINK_STATUS_ARB, &status);
+  if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
+    this->printError(this->shaderProgram);
+}
+
+
+bool ShaderData::readShader(const std::string& fileName, std::string& output)
+{
+  char lineBuffer[PARSELINELENGTH];
+
+  std::ifstream shader;
+  shader.open(fileName.c_str());
+  if (!shader.is_open())
+    return false;
+
+
+  while (!shader.eof())
+  {
+    shader.getline(lineBuffer, PARSELINELENGTH);
+    output += lineBuffer;
+    output += "\n";
+  }
+
+
+  shader.close();
+  return true;
+}
+
+void ShaderData::bindShader(const char* name, const float* value, size_t size)
+{
+  if (likely (this->shaderProgram != 0))
+  {
+    glUseProgramObjectARB(this->shaderProgram);
+
+    unsigned int location = glGetUniformLocationARB(this->shaderProgram, name);
+    /* This is EXPENSIVE and should be avoided. */
+
+    if      (size == 1)  glUniform1fvARB(location, 1, value);
+    else if (size == 2)  glUniform2fvARB(location, 1, value);
+    else if (size == 3)  glUniform3fvARB(location, 1, value);
+    else if (size == 4)  glUniform4fvARB(location, 1, value);
+    else if (size == 9)  glUniformMatrix3fvARB(location, 1, false, value);
+    else if (size == 16) glUniformMatrix4fvARB(location, 1, false, value);
+
+  }
+}
+
+void ShaderData::deleteProgram(ShaderData::Type type)
+{
+  GLint status = 0;
+  if (type == ShaderData::Vertex && this->vertexShader != 0)
+  {
+    this->vertexShaderFile = "";
+    glDetachObjectARB(this->shaderProgram, this->vertexShader);
+    glDeleteObjectARB(this->vertexShader);
+    glGetObjectParameterivARB(this->vertexShader, GL_OBJECT_DELETE_STATUS_ARB, &status);
+    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
+      ShaderData::printError(this->vertexShader);
+    this->vertexShader = 0;
+  }
+  else if (type == ShaderData::Fragment && this->fragmentShader != 0)
+  {
+    this->fragmentShaderFile = "";
+    glDetachObjectARB(this->shaderProgram, this->fragmentShader);
+    glDeleteObjectARB(this->fragmentShader);
+    glGetObjectParameterivARB(this->fragmentShader, GL_OBJECT_DELETE_STATUS_ARB, &status);
+    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
+      ShaderData::printError(this->fragmentShader);
+    this->fragmentShader = 0;
+  }
+  else
+    return;
+}
+
+
+void ShaderData::printError(GLhandleARB program)
+{
+  if (program == 0)
+    return;
+
+  int infologLength = 0;
+  int charsWritten  = 0;
+  char *infoLog;
+
+  glGetObjectParameterivARB(program, GL_OBJECT_INFO_LOG_LENGTH_ARB,
+                            &infologLength);
+
+  if (infologLength > 0)
+  {
+    infoLog = new char[infologLength+1];
+    glGetInfoLogARB(program, infologLength, &charsWritten, infoLog);
+    printf("%s\n", infoLog);
+    delete[] infoLog;
+  }
+}
+
+void ShaderData::debug() const
+{
+  PRINT(3)("ShaderData info: (SHADER: %d)\n", this->shaderProgram);
+  if (this->vertexShader != 0)
+  {
+    /*    PRINT(3)("VertexShaderProgramm: number=%d, file='%s'\n", this->vertexShader, this->vertexShaderFile);
+        if (this->vertexShaderSource != NULL)
+          for (unsigned int i = 0; i < this->vertexShaderSource->getCount(); i++)
+            PRINT(3)("%d: %s\n", i, this->vertexShaderSource->getEntry(i));
+      }
+      if (this->fragmentShader != 0)
+      {
+        PRINT(3)("FragmentShaderProgramm: number=%d, file='%s'\n", this->fragmentShader, this->fragmentShaderFile);
+        if (this->fragmentShaderSource != NULL)
+          for (unsigned int i = 0; i < this->fragmentShaderSource->getCount(); i++)
+            PRINT(3)("%d: %s\n", i, this->fragmentShaderSource->getEntry(i));*/
+  }
+}
+
Index: branches/heathaze/src/lib/graphics/shader_data.h
===================================================================
--- branches/heathaze/src/lib/graphics/shader_data.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/shader_data.h	(revision 9940)
@@ -0,0 +1,67 @@
+/*!
+ * @file shader_data.h
+ * @brief Definition of the Shader rendering class
+*/
+
+#ifndef _SHADER_DATA_H
+#define _SHADER_DATA_H
+
+#include "base_object.h"
+
+#include "glincl.h"
+#include <vector>
+#include "count_pointer.h"
+
+// FORWARD DECLARATION
+
+
+
+//! The ShaderData is a Class-wrapper around the OpenGL Shader Language (GLSL).
+class ShaderData : public BaseObject
+{
+  ObjectListDeclaration(ShaderData);
+  //! The Type of Shader.
+  typedef enum  {
+    None       = 0,     //!< No Type at all
+    Fragment   = 1,     //!< Fragment Shader.
+    Vertex     = 2,     //!< Vertex Shader.
+    Program    = 4,     //!< Compiled Shader Programm.
+  }  Type;
+
+ public:
+  typedef CountPointer<ShaderData> Pointer;
+public:
+  ShaderData();
+  virtual ~ShaderData();
+
+  bool load(const std::string& vertexShaderFile = "", const std::string& fragmentShaderFile = "");
+
+
+  GLhandleARB getProgram() const { return this->shaderProgram; }
+  GLhandleARB getVertexS() const { return this->vertexShader; }
+  GLhandleARB getFragmentS() const { return this->fragmentShader; }
+
+  void activateShader();
+
+  void debug() const;
+private:
+  void bindShader(const char* name, const float* value, size_t size);
+  void linkShaderProgram();
+  bool readShader(const std::string& fileName, std::string& output);
+  bool loadShaderProgramm(ShaderData::Type type, const std::string& fileName);
+  void deleteProgram(ShaderData::Type type);
+
+  static void printError(GLhandleARB program);
+
+private:
+
+  std::string            fragmentShaderFile;
+  std::string            vertexShaderFile;
+
+  GLhandleARB            shaderProgram;
+
+  GLhandleARB            vertexShader;
+  GLhandleARB            fragmentShader;
+};
+
+#endif /* _SHADER_DATA_H */
Index: branches/heathaze/src/lib/graphics/spatial_separation/Makefile.am
===================================================================
--- branches/heathaze/src/lib/graphics/spatial_separation/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/graphics/spatial_separation/Makefile.am	(revision 9940)
@@ -0,0 +1,13 @@
+MAINSRCDIR=../../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXquadtree.a
+
+libORXquadtree_a_SOURCES =
+# quadtree.cc \
+                           quadtree_node.cc \
+                           spatial_separation.cc
+
+noinst_HEADERS =  quadtree.h \
+                  quadtree_node.h \
+                  spatial_separation.h
Index: branches/heathaze/src/lib/graphics/spatial_separation/quadtree.cc
===================================================================
--- branches/heathaze/src/lib/graphics/spatial_separation/quadtree.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/spatial_separation/quadtree.cc	(revision 9940)
@@ -0,0 +1,214 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SPATIAL_SEPARATION
+
+#include "quadtree.h"
+
+#include "quadtree_node.h"
+#include "vector.h"
+
+#include "material.h"
+#include "debug.h"
+
+
+#define QUADTREE_MATERIAL_COUNT       4
+
+ObjectListDefinition(Quadtree);
+/**
+ *  standard constructor
+ */
+Quadtree::Quadtree (const modelInfo* pModelInfo, const int treeDepth)
+{
+  this->registerObject(this, Quadtree::_objectList);
+  this->pModelInfo = pModelInfo;
+  this->treeDepth = treeDepth;
+
+  /* initialize the materials for debug draw */
+  this->materials = new Material*[QUADTREE_MATERIAL_COUNT];
+  for(int i = 0; i < QUADTREE_MATERIAL_COUNT; ++i)
+  {
+    materials[i] = new Material();
+    materials[i]->setIllum(3);
+  }
+  materials[0]->setAmbient(0.0, 0.3, 0.0);
+  materials[1]->setAmbient(0.4, 0.0, 0.2);
+  materials[2]->setAmbient(1.0, 0.0, 0.0);
+  materials[3]->setAmbient(5.0, 3.0, 1.0);
+
+  /* build the tree */
+  this->rootNode = new QuadtreeNode(this->pModelInfo, this, this->treeDepth);
+
+  /* make an array with access to the leafs of the Quad-Tree */
+  this->nodes = new QuadtreeNode*[(int)pow(4.0, treeDepth)];
+  int index = 0; //new int; *index = 0; // !!changed by bensch!!
+  for(int i = 0; i < (int)pow(2.0, treeDepth); ++i)
+  {
+    this->rootNode->buildHashTable(this->nodes, &index);
+  }
+  /* sort and revert the hash table to fit the right position */
+  this->sortHashTable(this->nodes);
+  this->revertHashTable(this->nodes);
+
+  /* define some important and often used variables */
+  this->quadLength = this->nodes[0]->getDimension()->getAxis() * 2.0f;
+  Rectangle* r = this->rootNode->getDimension();
+  float xOff = r->getCenter().x - r->getAxis();
+  float yOff = r->getCenter().z - r->getAxis();
+  this->offset = new Vector();
+  this->offset->x = xOff;
+  this->offset->z = yOff;
+  this->maxIndex = (int)pow(2.0, this->treeDepth);
+}
+
+
+/**
+ *  standard deconstructor
+ */
+Quadtree::~Quadtree ()
+{
+  // delete what has to be deleted here
+  if (this->materials != NULL)
+  {
+    for (unsigned int i = 0; i < QUADTREE_MATERIAL_COUNT; i++)
+      delete this->materials[i];
+    delete[] this->materials;
+  }
+
+  delete this->offset;
+
+  delete this->rootNode;
+  delete [] this->nodes;
+}
+
+
+/**
+ *  this function rotates the array and mirrors it in the middle
+ * @param nodes: the nodes to translate
+
+  since the original matrix is counted from the right upper edge to the right lower one, we have to reorganize the elements
+  to be able to easily correlate the hashtable array indexes with the coorindates.
+ */
+void Quadtree::revertHashTable(QuadtreeNode** nodes)
+{
+  int                  len         = (int)pow(2.0, this->treeDepth);          //!< the length of a quadtree side
+  int                  iterator    = 0;                                     //!< iterator used for mapping
+  QuadtreeNode*        tmpNode     = NULL;                                  //!< temp saving place
+  int                  offset      = 0;                                     //!< offset used in the calc
+
+  for(int i = len - 1; i >= 0; --i)
+  {
+    for(int j = len - 1; j >= 0; --j)
+    {
+      offset = j * len + i;
+      /* only swap the elements in one direction */
+      if( offset > iterator)
+      {
+        tmpNode = nodes[offset];
+        nodes[offset] = nodes[iterator];
+        nodes[iterator] = tmpNode;
+      }
+      ++iterator;
+    }
+  }
+}
+
+
+/**
+ *  sorts the hash table using their positions
+ * @param nodes the nodes to use
+ */
+void Quadtree::sortHashTable(QuadtreeNode** nodes)
+{
+  int                  len         = (int)pow(2.0, this->treeDepth);          //!< the length of a quadtree side
+  float                a;                                                   //!< temp place for float a
+  float                b;                                                   //!< temp place for float b
+  QuadtreeNode*        tmpNode;                                             //!< tmp place for a QuadtreeNode
+
+  for( int i = 0; i < len; ++i)
+  {
+    for( int j = 0; j < len; ++j)
+    {
+      for( int k = j + 1; k < len; ++k)
+      {
+        a = this->nodes[i * len + j]->getDimension()->getCenter().z;
+        b = this->nodes[i * len + k]->getDimension()->getCenter().z;
+
+        if( b > a)
+        {
+          tmpNode = this->nodes[i * len + j];
+          this->nodes[i * len + j] = this->nodes[i * len + k];
+          this->nodes[i * len + k] = tmpNode;
+        }
+      }
+    }
+  }
+
+}
+
+
+/**
+ *  maps a position to a quadtree
+ * @param position the position so look for
+ * @return the quadtree
+
+  this function will return the quadtree that contains the position
+ */
+QuadtreeNode* Quadtree::getQuadtreeFromPosition(const Vector& position) const
+{
+  /* shift into model space */
+  Vector v = position - *this->offset;
+  /* map */
+  int i = (int)(v.x / quadLength);
+  int j = (int)(v.z / quadLength);
+
+  /* check if object is still inside the terrain - this check is not complete @todo check all 4 bounds */
+  if( i < this->maxIndex && j < this->maxIndex && i >= 0 && j >= 0)
+    return this->nodes[i + j * this->maxIndex];
+
+
+  PRINTF(4)("Object has left terrain\n");
+  return NULL;
+}
+
+
+/**
+ *  maps a position to a triangle
+ * @param position the position so look for
+ * @return the triangle
+
+  this function will return the quadtree that contains the position
+ */
+sTriangleExt* Quadtree::getTriangleFromPosition(const Vector& position) const
+{
+  QuadtreeNode* q = this->getQuadtreeFromPosition(position);
+
+  if( likely(q != NULL))
+    return q->getTriangle(position - *this->offset);
+  return NULL;
+}
+
+
+/**
+ *  draws the debug quadtree boxes around the model
+ */
+void Quadtree::drawTree() const
+{
+  //this->rootNode->drawTree();
+  for(int i = 0; i < (int)pow(4.0, this->treeDepth); ++i)
+  {
+    this->nodes[i]->draw();
+  }
+}
Index: branches/heathaze/src/lib/graphics/spatial_separation/quadtree.h
===================================================================
--- branches/heathaze/src/lib/graphics/spatial_separation/quadtree.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/spatial_separation/quadtree.h	(revision 9940)
@@ -0,0 +1,54 @@
+/*!
+ * @file quadtree.h
+ *  Definition of a spatial data separation using quadtree
+
+  This is the top element of the quadtree framework. A Quadtree is build of QuadtreeNodes, which are again separated
+  into QuadtreeNodes until a certain depth is reached
+ */
+
+#ifndef _QUADTREE_H
+#define _QUADTREE_H
+
+
+#include "base_object.h"
+#include "model.h"
+
+
+class QuadtreeNode;
+class Material;
+class Vector;
+
+//! A class for quadtree separation of the world
+class Quadtree : public BaseObject {
+  ObjectListDeclaration(Quadtree);
+
+  public:
+    Quadtree(const modelInfo* pModelInfo, const int treeDepth);
+    virtual ~Quadtree();
+
+    QuadtreeNode* getQuadtreeFromPosition(const Vector& position) const;
+    sTriangleExt* getTriangleFromPosition(const Vector& position) const;
+
+    void drawTree() const;
+    inline Material* getMaterial(int indexNode) const { return this->materials[indexNode % 4]; }
+
+
+  private:
+    void revertHashTable(QuadtreeNode** nodes);
+    void sortHashTable(QuadtreeNode** nodes);
+
+
+  private:
+    QuadtreeNode*                   rootNode;              //!< reference to the root node of the quadtree
+    QuadtreeNode**                  nodes;                 //!< reference to all quadtree nodes (only leafs of the quad tree)
+    const modelInfo*                pModelInfo;            //!< reference to the modelInfo of the object
+    int                             treeDepth;             //!< depth of the tree
+
+    float                           quadLength;            //!< length of the leaf quadtree nodes
+    Vector*                         offset;                //!< vector to the left lower corner of the root quadtree node
+    int                             maxIndex;              //!< maximal index for the nodes array
+
+    Material**                      materials;             //!< materials for debug drawing purposes
+};
+
+#endif /* _QUADTREE_H */
Index: branches/heathaze/src/lib/graphics/spatial_separation/quadtree_node.cc
===================================================================
--- branches/heathaze/src/lib/graphics/spatial_separation/quadtree_node.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/spatial_separation/quadtree_node.cc	(revision 9940)
@@ -0,0 +1,555 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SPATIAL_SEPARATION
+
+#include "quadtree_node.h"
+
+#include "glincl.h"
+#include "quadtree.h"
+#include "material.h"
+#include "model.h"
+#include "debug.h"
+
+#include "util/list.h"
+
+
+ObjectListDefinition(QuadtreeNode);
+
+/**
+ *  standard constructor
+ */
+QuadtreeNode::QuadtreeNode (sTriangleExt** triangles, int numTriangles,
+                            const float* pVertices, int numVertices,
+                            Quadtree* quadtree, QuadtreeNode* parent,
+                            Rectangle* rect, int treeDepth, const int maxDepth, int index
+                           )
+{
+  /* save all important variables localy */
+  this->numTriangles = numTriangles;
+  this->pTriangles = triangles;
+  this->numVertices = numVertices;
+  this->pVertices = pVertices;
+
+  this->quadtree = quadtree;
+  this->parent = parent;
+  this->pDimension = rect;
+  this->treeDepth = treeDepth;
+  this->maxDepth = maxDepth;
+  this->indexNode = index;
+
+  /* debug output */
+  for( int i = 0; i < this->treeDepth; ++i)
+    PRINT(3)(" |");
+  PRINT(3)(" | +-| (Event) Building Node Nr. %i Depth: %i/%i, pointer: %p\n", this->indexNode, treeDepth, maxDepth, this);
+
+  for( int i = 0; i < this->treeDepth; ++i)
+    PRINT(3)(" |");
+  PRINT(3)(" | +-| (II) Rectangle Center (%5.2f, %5.2f), half axis length: %5.2f\n",
+  this->pDimension->getCenter().x, this->pDimension->getCenter().z, this->pDimension->getAxis());
+
+  this->init();
+}
+
+
+/**
+ *  standard constructor
+ */
+QuadtreeNode::QuadtreeNode(const modelInfo* pModelInfo, Quadtree* quadtree, const int maxDepth)
+{
+  /* save all important variables localy */
+  this->pModelInfo = pModelInfo;
+  this->quadtree = quadtree;
+  this->maxDepth = maxDepth;
+  this->treeDepth = 0;
+  this->indexNode = 0;
+
+  /* create an array of triangle references */
+  this->pTriangles = new sTriangleExt*[this->pModelInfo->numTriangles];
+  this->numTriangles = this->pModelInfo->numTriangles;
+  this->pVertices = this->pModelInfo->pVertices;
+  this->numVertices = this->pModelInfo->numVertices;
+  for( int i = 0; i < this->pModelInfo->numTriangles; ++i)
+    this->pTriangles[i] = &this->pModelInfo->pTriangles[i];
+
+  /* debug output */
+  for( int i = 0; i < this->treeDepth; ++i)
+    PRINT(3)(" |");
+  PRINT(3)(" | +-| (Event) Building Node Nr. %i Depth: %i/%i, pointer: %p\n", this->indexNode, treeDepth, maxDepth, this);
+
+  /* set some important variables */
+  this->pDimension = this->getDimFromModel();
+
+  this->init();
+}
+
+
+/**
+ *  takes the rest of the initialisation process
+ */
+void QuadtreeNode::init()
+{
+  this->registerObject(this, QuadtreeNode::_objectList);
+
+  /* init the rest of the variables for both init types */
+  this->offset = 0.0f;
+  this->nodeIter = -1;
+  this->bDraw = false;
+
+  this->parent = NULL;
+  this->nodeA = NULL;
+  this->nodeB = NULL;
+  this->nodeC = NULL;
+  this->nodeD = NULL;
+  this->nodes = new QuadtreeNode*[4];
+  for(int i = 0; i < 4; ++i)
+    this->nodes[i] = NULL;
+
+  /* now separate the nodes */
+  if( this->treeDepth < this->maxDepth)
+    this->separateNode();
+}
+
+
+/**
+ *  standard deconstructor
+ */
+QuadtreeNode::~QuadtreeNode ()
+{
+  if( this->nodeA)
+    delete this->nodeA;
+  if( this->nodeB)
+    delete this->nodeB;
+  if( this->nodeC)
+    delete this->nodeC;
+  if( this->nodeD)
+    delete this->nodeD;
+
+  if( this->nodes)
+    delete [] this->nodes;
+
+  if( this->pTriangles)
+    delete [] this->pTriangles;
+
+  if( this->pDimension)
+    delete this->pDimension;
+}
+
+
+
+/**
+ *  this functions builds up a hash table containing all leafs of the Quadtree in a sorted array
+ * @param nodeList the nodelist array to add them
+ * @param index the current index in the array
+
+  The algorithm used for this purpose is home-brown. its not to fast but and the nodes are not always in the right
+  order. this is why there will be needed a quicksort later on.
+ */
+void QuadtreeNode::buildHashTable(QuadtreeNode** nodeList, int* index)
+{
+  if( this->nodeIter == -1)
+    this->nodeIter = *index;
+
+  /*              offset              #of elements in a row            #of rows in a quadtree          */
+  int threshold = this->nodeIter + (int)pow(2.0, this->maxDepth) * (int)pow(2.0, maxDepth - treeDepth - 1);
+  int loopLimit = (*index < threshold)?2:4;
+
+  /* is it a leaf? */
+  if( this->treeDepth < this->maxDepth)
+    for(int i = (*index < threshold)?0:2; i < loopLimit; ++i)
+      this->nodes[i]->buildHashTable(nodeList, index);
+  else
+    nodeList[(*index)++] = this;
+}
+
+
+
+/**
+ *  gives the signal to separate the model into a quadtree
+ * @param treeDepth the max depth, the steps to go if treeDept == 0 leaf reached
+
+ * @todo ATTENION: This function is currently not used and not implemented, but would be a nice addon
+ */
+void QuadtreeNode::separateNode(float minLength)
+{
+  /* dimension calculation & limit checking */
+  if( minLength <= this->pDimension->getAxis())
+    return;
+
+  /* node separation */
+//   this->separateNode();
+//   this->nodeA->separateNode(minLength);
+//   this->nodeB->separateNode(minLength);
+//   this->nodeC->separateNode(minLength);
+//   this->nodeD->separateNode(minLength);
+}
+
+
+/**
+ *  gives the signal to separate the model into a quadtree
+ * @param treeDepth the max depth, the steps to go if treeDept == 0 leaf reached
+ */
+void QuadtreeNode::separateNode()
+{
+  /* separate the four regions into the four lists */
+  tList<sTriangleExt*>*           listA = new tList<sTriangleExt*>();    //!< triangle list of nodeA
+  tList<sTriangleExt*>*           listB = new tList<sTriangleExt*>();    //!< triangle list of nodeB
+  tList<sTriangleExt*>*           listC = new tList<sTriangleExt*>();    //!< triangle list of nodeC
+  tList<sTriangleExt*>*           listD = new tList<sTriangleExt*>();    //!< triangle list of nodeD
+  const float*                    pVert;                                 //!< pointer to the vertices
+  Vector                          rectCenter;                            //!< vector to the center of the rect
+
+  rectCenter = this->pDimension->getCenter();
+  for( int i = 0; i < this->numTriangles; ++i)
+  {
+    for( int j = 0; j < 3; ++j)
+    {
+      pVert = &this->pVertices[this->pTriangles[i]->indexToVertices[j]];
+      if( pVert[0] > rectCenter.x + this->offset && pVert[2] > rectCenter.z + this->offset)
+        listA->add(&this->pTriangles[i]);
+      if( pVert[0] < rectCenter.x + this->offset && pVert[2] > rectCenter.z + this->offset)
+        listB->add(&this->pTriangles[i]);
+      if( pVert[0] < rectCenter.x + this->offset && pVert[2] < rectCenter.z + this->offset)
+        listC->add(&this->pTriangles[i]);
+      if( pVert[0] > rectCenter.x + this->offset && pVert[2] < rectCenter.z + this->offset)
+        listD->add(&this->pTriangles[i]);
+    }
+  }
+  for( int i = 0; i < treeDepth; ++i)
+    PRINT(3)(" |");
+  PRINT(3)(" | +-| (II) Quadtree Counts - separating: A: %i, B: %i, C: %i, D: %i\n", listA->getSize(), listB->getSize(), listC->getSize(), listD->getSize());
+
+
+  /* Separating into to the triangle arrays */
+  sTriangleExt**                 pTriA;                                 //!< Triangle array A
+  sTriangleExt**                 pTriB;                                 //!< Triangle array B
+  sTriangleExt**                 pTriC;                                 //!< Triangle array C
+  sTriangleExt**                 pTriD;                                 //!< Triangle array D
+  int                            lenA;                                  //!< length array A
+  int                            lenB;                                  //!< length array B
+  int                            lenC;                                  //!< length array C
+  int                            lenD;                                  //!< length array D
+  tIterator<sTriangleExt*>*      iterator;                              //!< iterator for the list iterations
+  sTriangleExt**                 tempTri;                               //!< temp save place for triangle pointer
+  int                            counter;                               //!< counter for the while loops
+
+  lenA = listA->getSize();
+  lenB = listB->getSize();
+  lenC = listC->getSize();
+  lenD = listD->getSize();
+
+  pTriA = new sTriangleExt*[lenA];
+  pTriB = new sTriangleExt*[lenB];
+  pTriC = new sTriangleExt*[lenC];
+  pTriD = new sTriangleExt*[lenD];
+
+  counter = 0;
+  iterator = listA->getIterator();
+  tempTri = iterator->firstElement();
+  while( tempTri)
+  {
+    pTriA[counter] = *tempTri;
+    tempTri = iterator->nextElement();
+    ++counter;
+  }
+  delete iterator;
+
+  counter = 0;
+  iterator = listB->getIterator();
+  tempTri = iterator->firstElement();
+  while( tempTri)
+  {
+    pTriB[counter] = *tempTri;
+    tempTri = iterator->nextElement();
+    ++counter;
+  }
+  delete iterator;
+
+  counter = 0;
+  iterator = listC->getIterator();
+  tempTri = iterator->firstElement();
+  while( tempTri)
+  {
+    pTriC[counter] = *tempTri;
+    tempTri = iterator->nextElement();
+    ++counter;
+  }
+  delete iterator;
+
+  counter = 0;
+  iterator = listD->getIterator();
+  tempTri = iterator->firstElement();
+  while( tempTri)
+  {
+    pTriD[counter] = *tempTri;
+    tempTri = iterator->nextElement();
+    ++counter;
+  }
+  delete iterator;
+
+  /* now do cleanup */
+  delete listA;
+  delete listB;
+  delete listC;
+  delete listD;
+
+
+  /* now create the rectangle dimensions */
+  Vector                     v;                                                             //!< temp saving place
+  Rectangle*                 rA;                                                            //!< new size of the node A
+  Rectangle*                 rB;                                                            //!< new size of the node B
+  Rectangle*                 rC;                                                            //!< new size of the node C
+  Rectangle*                 rD;                                                            //!< new size of the node D
+
+
+  v.x = this->pDimension->getCenter().x + this->pDimension->getAxis() / 2.0f;
+  v.y = 0.0;
+  v.z = this->pDimension->getCenter().z + this->pDimension->getAxis() / 2.0f;
+  rA = new Rectangle(v, this->pDimension->getAxis() / 2.0f);
+
+  v.z = this->pDimension->getCenter().z - this->pDimension->getAxis() / 2.0f;
+  rB = new Rectangle(v, this->pDimension->getAxis() / 2.0f);
+
+  v.x = this->pDimension->getCenter().x - this->pDimension->getAxis() / 2.0f;
+  rC = new Rectangle(v, this->pDimension->getAxis() / 2.0f);
+
+  v.z = this->pDimension->getCenter().z + this->pDimension->getAxis() / 2.0f;
+  rD = new Rectangle(v, this->pDimension->getAxis() / 2.0f);
+
+
+  /* now create the new nodes  */
+  this->nodeA = new QuadtreeNode(pTriA, lenA, this->pVertices, this->numVertices, this->quadtree, this, rA, this->treeDepth + 1, this->maxDepth, (this->treeDepth + 1) * 10 + 0);
+  this->nodeB = new QuadtreeNode(pTriB, lenB, this->pVertices, this->numVertices, this->quadtree, this, rB, this->treeDepth + 1, this->maxDepth, (this->treeDepth + 1) * 10 + 1);
+  this->nodeC = new QuadtreeNode(pTriC, lenC, this->pVertices, this->numVertices, this->quadtree, this, rC, this->treeDepth + 1, this->maxDepth, (this->treeDepth + 1) * 10 + 2);
+  this->nodeD = new QuadtreeNode(pTriD, lenD, this->pVertices, this->numVertices, this->quadtree, this, rD, this->treeDepth + 1, this->maxDepth, (this->treeDepth + 1) * 10 + 3);
+
+  /* map the array references, this is for faster and automatical interfacing  \todo: use only array */
+  this->nodes[0] = this->nodeA;
+  this->nodes[1] = this->nodeB;
+  this->nodes[2] = this->nodeC;
+  this->nodes[3] = this->nodeD;
+}
+
+
+/**
+ *  gets the maximal dimension of a model
+ * @return the dimension of the Model as a Rectangle
+
+   The rectangle is x-z axis aligned. ATTENTION: if there are any vertices in the model, that exceed the
+   size of 999999.0, there probably will be some errors in the dimensions calculations. Write an email to
+   patrick@orxonox.ethz.ch if you will ever encounter a model bigger than 999999.0 units, I will realy be
+   happy to see orxonox used to extensivly :)
+ */
+Rectangle* QuadtreeNode::getDimFromModel()
+{
+  float            maxX, maxY;                       //!< the maximal coordinates axis
+  float            minX, minY;                       //!< minimal axis coorindates
+  const float*     pVertices;                        //!< pointer to the current vertices
+
+  maxX = -999999; maxY = -999999;
+  minX =  999999; minY =  999999;
+  /* get maximal/minimal x/y */
+  for( int i = 0; i < this->numTriangles; ++i)
+  {
+    for( int j = 0; j < 3; ++j)
+    {
+
+      pVertices = &this->pVertices[this->pTriangles[i]->indexToVertices[j]];
+      if( pVertices[0] > maxX)
+        maxX = pVertices[0];
+      if( pVertices[2] > maxY)
+        maxY = pVertices[2];
+
+      if( pVertices[0] < minX)
+        minX = pVertices[0];
+      if( pVertices[2] < minY)
+        minY = pVertices[2];
+    }
+  }
+
+  Rectangle* rect = new Rectangle();
+  rect->setCenter((maxX + minX) / 2.0f, 0.0f, (maxY + minY) / 2.0f); /* this is little strange, since y is in opengl the up vector */
+  rect->setAxis(fmax(((fabs(maxX) + fabs(minX)) / 2.0f), ((fabs(maxY) + fabs(minY)) / 2.0f)));
+
+  for( int i = 0; i < this->treeDepth; ++i)
+    PRINT(3)(" |");
+  PRINT(3)(" | +-| (II) Rectangle Dimension  (%5.2f, %5.2f) to (%5.2f, %5.2f), Center (%5.2f, %5.2f)\n", minX, minY, maxX, maxY, rect->getCenter().x, rect->getCenter().z, rect->getAxis());
+  return rect;
+}
+
+
+ /**
+ * checks if a point is included in this quadtree
+ * @param v the vector to be checked
+ * @returns true if the vector is included
+  */
+bool QuadtreeNode::includesPoint(const Vector& v) const
+{
+  Vector center = this->pDimension->getCenter();
+  float ax = this->pDimension->getAxis();
+
+  if( v.x > center.x - ax && v.x < center.x + ax &&
+      v.z > center.z - ax && v.z < center.z + ax )
+    return true;
+  return false;
+}
+
+
+
+float QuadtreeNode::getHeight(const Vector& position) const
+{
+  Vector a, b, c;
+  sTriangleExt* tri;
+
+  for( int i = 0; i < this->numTriangles; ++i)
+  {
+    a = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[0]];
+    b = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[1]];
+    c = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[2]];
+
+    if( unlikely(this->pointInTriangle(position, a, b, c)))
+    {
+      tri = this->pTriangles[i];
+      break;
+    }
+  }
+
+  /* calculate height out of the data collected above */
+
+}
+
+
+/**
+ *  get triangles that includes the position
+ * @param position the position that is going to be checked
+ * @returns the triangle in which the position is included, NULL if there is no such triangle
+
+ There is some random behaviour if there are more than one triangle at the same y
+ coordinate. At the moment the function just takes the first triangle, that included the
+ vector
+ */
+sTriangleExt* QuadtreeNode::getTriangle(const Vector& position) const
+{
+  Vector a, b, c;
+  PRINTF(0)("Get Triangle, %i\n", this->numTriangles);
+
+  for( int i = 0; i < numTriangles; ++i)
+    {
+
+      a = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[0]];
+      b = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[1]];
+      c = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[2]];
+
+      if( unlikely(this->pointInTriangle(position, a, b, c)))
+        return this->pTriangles[i];
+
+    }
+  return NULL;
+}
+
+
+/**
+ *  checks if the point is in the triangle
+ * @param point to be checked
+ * @param rectangle edge a
+ * @param rectangle edge b
+ * @param rectangle edge c
+ * @returns true if the point is inside
+ */
+bool QuadtreeNode::pointInTriangle(const Vector&p, const Vector& a, const Vector& b, const Vector& c) const
+{
+
+  PRINTF(0)("p: (%f, %f, %f)\n", p.x, p.y, p.z);
+  PRINTF(0)("a: (%f, %f, %f)\n", a.x, a.y, a.z);
+  PRINTF(0)("b: (%f, %f, %f)\n", b.x, b.y, b.z);
+  PRINTF(0)("c: (%f, %f, %f)\n", c.x, c.y, c.z);
+
+  if( this->sameSide(p, a, b, c) && this->sameSide(p, b, a, c) && sameSide(p, c, a, b))
+    return true;
+  return false;
+}
+
+
+/**
+ *  checks if two points are on the same side
+ * @param point one to be checked
+ * @param point two to be checked
+ * @param begining point of the line
+ * @param end of the line
+ */
+bool QuadtreeNode::sameSide(const Vector& p1, const Vector&p2, const Vector& a, const Vector& b) const
+{
+  Vector cp1 = (b - a).cross(p1 - a);
+  Vector cp2 = (b - a).cross(p2 - a);
+
+  if( unlikely(cp1.dot(cp2) >= 0)) return true;
+  return false;
+}
+
+
+/**
+ *  draws all the debug quadtree squares
+ */
+void QuadtreeNode::drawTree() const
+{
+  if( this->treeDepth == this->maxDepth)
+  {
+    Vector t1 = this->pDimension->getCenter();
+    float ax = this->pDimension->getAxis();
+    float h = 50.0f;
+
+    this->quadtree->getMaterial(this->indexNode)->select();
+    glBegin(GL_QUADS);
+    glVertex3f(t1.x + ax, h - this->treeDepth * 10.0f, t1.z + ax);
+    glVertex3f(t1.x - ax, h - this->treeDepth * 10.0f, t1.z + ax);
+    glVertex3f(t1.x - ax, h - this->treeDepth * 10.0f, t1.z - ax);
+    glVertex3f(t1.x + ax, h - this->treeDepth * 10.0f, t1.z - ax);
+    glEnd();
+  }
+
+
+  if( this->nodeA != NULL)
+    this->nodeA->drawTree();
+  if( this->nodeB != NULL)
+    this->nodeB->drawTree();
+  if( this->nodeC != NULL)
+    this->nodeC->drawTree();
+  if( this->nodeD != NULL)
+    this->nodeD->drawTree();
+}
+
+
+/**
+ *  draws only this quadtree square
+ */
+void QuadtreeNode::draw() const
+{
+  if( likely(!this->bDraw))
+    return;
+
+  Vector t1 = this->pDimension->getCenter();
+  float ax = this->pDimension->getAxis();
+  float h = 70.0f;
+
+  glBegin(GL_QUADS);
+  this->quadtree->getMaterial(this->indexNode)->select();
+
+  glVertex3f(t1.x + ax, h, t1.z + ax);
+  glVertex3f(t1.x - ax, h, t1.z + ax);
+  glVertex3f(t1.x - ax, h, t1.z - ax);
+  glVertex3f(t1.x + ax, h, t1.z - ax);
+
+  glEnd();
+}
Index: branches/heathaze/src/lib/graphics/spatial_separation/quadtree_node.h
===================================================================
--- branches/heathaze/src/lib/graphics/spatial_separation/quadtree_node.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/spatial_separation/quadtree_node.h	(revision 9940)
@@ -0,0 +1,92 @@
+/*!
+ * @file proto_class.h
+ *  Definition of a QuadtreeNode which represents a quad in a Quadtree
+
+  This struct is used to partition big land scapes into smaller ones for different reasons:
+    - for collision detection: only a subset of all triangles need to be tested vs a given body
+    - for object culling purposes: the quadtrees that are not in the field of view can be ommitted in the draw process
+    - for LOD (level of Detail). The models can be drawn using different LODs depending on the distance
+
+  This struct includes all the triangles, vertices, normal informations needed to make something usefull with
+  a terrain partition.
+ */
+
+#ifndef _QUADTREE_NODE_H
+#define _QUADTREE_NODE_H
+
+#include "base_object.h"
+
+#include "plane.h"
+#include "model.h"
+
+// FORWARD DECLARATION
+class Quadtree;
+
+
+//! A class for a Quadtree Node representation
+class QuadtreeNode : public BaseObject {
+  ObjectListDeclaration(QuadtreeNode);
+
+  public:
+    QuadtreeNode(sTriangleExt** triangles, int numTriangles,
+                 const float* pVertices, int numVertices,
+                 Quadtree* quadtree, QuadtreeNode* parent,
+                 Rectangle* rect, int treeDepth, const int maxDepth, int index
+                );
+    QuadtreeNode(const modelInfo* pModelInfo, Quadtree* quadtree, const int maxDepth);
+    virtual ~QuadtreeNode();
+
+    void buildHashTable(QuadtreeNode** nodeList, int* index);
+    inline Rectangle* getDimension() { return this->pDimension; }
+
+    bool includesPoint(const Vector& v) const;
+    sTriangleExt* getTriangle(const Vector& position) const;
+    float getHeight(const Vector& position) const;
+
+
+    void drawTree() const;
+    void draw() const;
+
+
+  private:
+    void init();
+
+    void separateNode(float minLength);
+    void separateNode();
+    Rectangle* getDimFromModel();
+
+    bool sameSide(const Vector& p1, const Vector&p2, const Vector& a, const Vector& b) const;
+    bool pointInTriangle(const Vector&p, const Vector& a, const Vector& b, const Vector& c) const;
+
+  protected:
+    QuadtreeNode*                   parent;             //!< reference to the paren QuadtreeNode (NULL if rootnode)
+    QuadtreeNode*                   nodeA;              //!< reference to the node A
+    QuadtreeNode*                   nodeB;              //!< reference to the node B
+    QuadtreeNode*                   nodeC;              //!< reference to the node C
+    QuadtreeNode*                   nodeD;              //!< reference to the node D
+    QuadtreeNode**                  nodes;              //!< reference to the quadtree nodes (nodeA, nodeB, nodeC, nodeD=[0..3])
+
+
+  private:
+    Quadtree*                       quadtree;           //!< reference to the quadtree
+    Vector                          center;             //!< center coordinate of the quadtree node - relative coordinates in model space(!)
+    float                           axisLength;         //!< axis length of the quadtree
+    float                           maxHeigth;          //!< max height of the model in the quadtree
+    float                           offset;             //!< offset of the actual quadtree rectangle
+
+    int                             treeDepth;          //!< the depth of the tree
+    int                             maxDepth;           //!< the maximal depth of the tree
+    int                             indexNode;          //!< the index number of the node
+    int                             nodeIter;           //!< temp helping variable for the hashing algorithm
+
+    sTriangleExt**                  pTriangles;         //!< reference to the triangles of the node
+    const float*                    pVertices;          //!< reference to vertices data
+    unsigned int                    numTriangles;       //!< number of triangles of the Node
+    unsigned int                    numVertices;        //!< number of vertices of the node
+    const modelInfo*                pModelInfo;         //!< reference to the modelInfo of the object
+    Rectangle*                      pDimension;         //!< pointer to the local rectangle properties
+
+    bool                            bDraw;              //!< shall it be drawn? DEBUG only
+};
+
+#endif /* _QUADTREE_NODE_H */
Index: branches/heathaze/src/lib/graphics/spatial_separation/spatial_separation.cc
===================================================================
--- branches/heathaze/src/lib/graphics/spatial_separation/spatial_separation.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/spatial_separation/spatial_separation.cc	(revision 9940)
@@ -0,0 +1,119 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SPATIAL_SEPARATION
+
+#include "spatial_separation.h"
+
+#include "model.h"
+#include "quadtree.h"
+#include "debug.h"
+#include "compiler.h"
+
+
+ObjectListDefinition(SpatialSeparation);
+
+/**
+ * @brief standard constructor
+ * @param model the model that is to be separated
+ * @param overlapSize each box will overlap for a given size
+ *
+ * The boxes are overlaping because this makes collision detection a lot simpler
+ *
+ */
+SpatialSeparation::SpatialSeparation (Model* model, float overlapSize)
+{
+  PRINT(3)("+---------Debug Information SpatialSeparation----------\n");
+  PRINT(3)("+-| (Event) Spatial Separation process kicked on\n");
+
+  this->registerObject(this, SpatialSeparation::_objectList);
+  /* debug vice */
+  this->createQuadtree(model);
+}
+
+
+/**
+ * @brief standard constructor
+ * @param model the model that is to be separated
+ * @param overlapSize each box will overlap for a given size
+
+   The boxes are overlaping because this makes collision detection a lot simpler
+ */
+SpatialSeparation::SpatialSeparation (Model* model, Model* playerModel)
+{
+  this->registerObject(this, SpatialSeparation::_objectList);
+
+}
+
+
+/**
+ * @brief standard deconstructor
+ */
+SpatialSeparation::~SpatialSeparation ()
+{
+  if( this->quadtree)
+    delete this->quadtree;
+}
+
+
+/**
+ * @brief creates a quadtree
+ * @param model the model to do a quadtree on
+ * @param minLength the minimal length of a quadtree node
+ * @return the new quadtree
+ */
+Quadtree* SpatialSeparation::createQuadtree(Model* model, float minLength)
+{
+  this->minLength = minLength;
+
+}
+
+
+/**
+ * @brief creates a quadtree
+ * @param model the model to do a quadtree on
+ * @param minLength the minimal length of a quadtree node
+ * @return the new quadtree
+ */
+Quadtree* SpatialSeparation::createQuadtree(Model* model, int treeDepth)
+{
+  this->treeDepth = treeDepth;
+}
+
+
+/**
+ * @brief creates a quadtree
+ * @param model the model to do a quadtree on
+ * @param minLength the minimal length of a quadtree node
+ * @return the new quadtree
+ */
+Quadtree* SpatialSeparation::createQuadtree(Model* model)
+{
+  this->quadtree = new Quadtree(model->getModelInfo(), 4);
+
+  return this->quadtree;
+}
+
+
+/**
+ * @brief draws all the quadtrees
+ */
+void SpatialSeparation::drawQuadtree()
+{
+  if( unlikely( this->quadtree == NULL))
+    return;
+
+  this->quadtree->drawTree();
+}
Index: branches/heathaze/src/lib/graphics/spatial_separation/spatial_separation.h
===================================================================
--- branches/heathaze/src/lib/graphics/spatial_separation/spatial_separation.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/spatial_separation/spatial_separation.h	(revision 9940)
@@ -0,0 +1,54 @@
+/*!
+ * @file spatial_separation.h  Definition of the generic spatial separation process of model data
+ */
+
+#ifndef _SPATIAL_SEPARATION_H
+#define _SPATIAL_SEPARATION_H
+
+#include "base_object.h"
+
+
+class Model;
+class Quadtree;
+
+
+#define SEC_OFFSET 1.0                       //!< the offset added to the overlapSize to ensure that there are no problems in
+
+
+
+//! A class for spatial separation of vertices based arrays
+class SpatialSeparation : public BaseObject {
+  ObjectListDeclaration(SpatialSeparation);
+
+  public:
+    SpatialSeparation(Model* model, float overlapSize);
+    SpatialSeparation(Model* model, Model* playerModel);
+    virtual ~SpatialSeparation();
+
+    void setTreeDepth(int depth) { this->treeDepth = depth; }
+    void setMinLength(int minLength) { this->minLength = minLength; }
+
+    Quadtree* createQuadtree(Model* model, float minLength);
+    Quadtree* createQuadtree(Model* model, int treeDepth);
+    Quadtree* createQuadtree(Model* model);
+
+    inline Quadtree* getQuadtree() { return this->quadtree; }
+
+    void drawQuadtree();
+
+  private:
+    void separateZone();
+
+
+  private:
+    Model*             model;        //!< the reference to the model that has to be handled
+    Quadtree*                  quadtree;     //!< the reference to the created quadtree
+
+    Model*             playerModel;  //!< referece to the player model, if needed for overlap calculations
+    float                      overlapSize;  //!< the size of overlaping
+
+    int                        treeDepth;    //!< depth of the quadtree
+    float                      minLength;    //!< min length of a quadtree node
+};
+
+#endif /* _SPATIAL_SEPARATION_H */
Index: branches/heathaze/src/lib/graphics/text_engine/default_font.xpm
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/default_font.xpm	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/default_font.xpm	(revision 9940)
@@ -0,0 +1,268 @@
+/* XPM */
+static char * font_xpm[] = {
+"256 256 9 1",
+" 	c None",
+".	c #FEFEFE",
+"+	c #FDFDFD",
+"@	c #FAFAFA",
+"#	c #FBFBFB",
+"$	c #F8F8F8",
+"%	c #FCFCFC",
+"&	c #F9F9F9",
+"*	c #F7F7F7",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .               .               .               .               .               .               .               .               .     .         .     .         .     .         .     .         .     .         .     .         .     .       ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .               .               .               .               .               .               .               .               .               .               .               .               .               .               .             ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .               .               .               .               .               .               .               .               .               .               .     .         .     .         .     .         .     .         .     .       ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .               .               .               .               .               .               .               .               .               .               .               .               .               .               .             ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                  ..              ...             .                    ..         .                 +......       ..                 ..            .              .               .               ..              .               ..                   ..       ",
+"                  ..              ...                                 ...                          ........       .+               +...           ...+                                            ..                              ..                  ..        ",
+"                  ..              ...                              .........                       ..              @               ..               ..+                                            #                                                  .+        ",
+"                  ..                                              ..........                        ...                           ...                ..                                                                                              ..$        ",
+"                  ++                                              ... #..                          ...++  .+                      ...                ..                                                                                             #..         ",
+"                                                                  %......%%%.                     ...  %....                      ...                ..                                                                                             ..          ",
+"                  ..                                               +........+                     ..........+                     ...                .+                                                                                            +..          ",
+"                  ..                              .                    ..  ..     .               ...........#                    ...                .+           .               .                               .                                ..           ",
+"                  ..                                              &..........                       .....+                        ...                .+                                                                                            %@           ",
+"                                                                  &.........%                                                     ...                .+                                                                                                         ",
+"                                                                      ...                                                          ..               ..+                                                                                                         ",
+"                                                                                                                                   +...           ....#                                                                                                         ",
+"                                                                                                                                    ++.           ..%                                                                                                           ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"   .+....+#        ....           ..........      ..........             ..       ...........      +%.++%%##      ..........       .......+        +.....+%       ..              ..              .               .               .                ......       ",
+"  ..........      .....           ..........      ........%              ..       ...........      .........      ..........       ........+      &........+      ..              ..                                                               ......+      ",
+"  ...     .+        ...                   %.                      ..     ..                                                        ..    ..+      &..     ..                                                                                           ...      ",
+"  ..      ..        ...            +........             ..+      ..........       ........%      .........                        ........       @.........      ..              ..                                                                .....+      ",
+"  ..      ..        ...           ..........            .....     ..........       .........%     ..........           ..%         ........+       +........      ..              ..                                                                .....       ",
+"  ..      ..        ...                                   ...                             ...     ...     ..          @.+         ...     ..#                                      #                                                                            ",
+"  %......#.+        ...           ..........       ..........            ..        ..........     #..@@%+...         ...          ..........$      ........                                                                                          .          ",
+"   ........         ...           ...........     &.........             ..       &.........+      +........        ..+           ..........      .........                                                                                         ..          ",
+"     ....+           .            ..........       ........              ..        ........+         ......         ..              .......        ......+                                                                                           .          ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .........+      .........%       ........       ........+.       %.........      +........       .+.......      ...      ...    ...                  ...        ...     ..&     ...              .%.       .#.   +#%      ..     %.......+    ",
+"                  ...........     ..........#     .........       ..........+     +..........%    +.........      ..........      ...      ...    ...                  ...        ...   ++.       ...             %...+     ....  %...+     ..     ..........@  ",
+"                           %.%            ...     +..                      ..     @.       +..    +.+             +..             ...      ...    ...                  ...        ...  ..+        ...             ..#..     ..... ... .#    ..    +..      ..%  ",
+"                   ...........    ..........      ..                       ..     &...........    ..........      ...  ....       ... *.......    ...                  ...        ...  ..         ...             ... ..   .. ... ...  .%   ..    ...       ..  ",
+"                  ............    ..........      ..              ...      ..     &.........+     ..........      ...  .....      ... *.......    ...                  ...        ...  .#         ...             ... +.   .. ... ...  $..  ..    ...       ..  ",
+"                  ...      ...    ...      .+     ..              ...      ..     &..             ...             ...     ..      ...      ...    ...                  ...        ...  ...        ...             ...  .% +.  ... ...   +.. ..    +..       ..  ",
+"                  ............    ...........     %.+......       ..........+      ..........     ...             #.........      ...      ...    ...              ......+        ...   #.+       %.........      ...  ....#  ... ...    .....    %........#..  ",
+"  .               .........%..    ...........      +.......       ..........       %..........    ...              .........      ...      ...    ...             .......         ...    ...       .........      ...   ...   ... ...     ...@     +........+   ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .........%.      .+......+.     .........%       .........      ....... ....... ..       ..      ..       ..+   %..    ...    +. ...     ...    ...      ...    ..........         ..            ..              ..             .               ........      ",
+"  ..........+     %..........+    ..........#     ..........      &&&&#.. ....... ..       ..      %..      ..     ..    ...@   ..  ...   ..+     ...      ...     .........       ....            ..              ...                                          ",
+"           ..     %..      ..%            ...     ..+                  .. ..      ..       ..       ..     +.      ...   ....   ..   %.. ...      %..      ...                     ..               ..              ..+                                         ",
+"  ..........+     ..       ...    ..........%     .........+           .. ..      ..       ..       ..+   ..+       ..  .. .+  %..    .....        ..........                     ...               ..               ..                                         ",
+"  .........+.     ..       ...    ........+.       .........+          .. ..      ..       ..        ..   ..        ..  +. ..  +.     ....+         ........$        ....         ...                ..              ..                                         ",
+"  ...             ..%  %%  %..    ...   #.+                ..          .. ..      %..      ..        ..+ %..        ... .. ..+ ..    ... ...                        ..%           ...                ..              ..                                         ",
+"  ..              %......#+..#    ..     +..       ..........          .. ..       .........%         ..#..          +...   ....+   ...   ...         ....         .........      ...                 ..             .+                                         ",
+"  ..               %.........     ..      ..@     &..........          .. ..       #........           +..%          %..+   ....   ...     ...        ....        ...........     ...                 ..             .+                                         ",
+"                       ..                  ..                                                                                                                                     ...                                .+                                         ",
+"                                            ..                                                                                                                                    ...                                .+                                         ",
+"                                             ..                                                                                                                                    ..                               ..+                                         ",
+"                                                                                                                                                                                   +...                           ....                                          ",
+"                                                                                                                                                                                    %+.                            .%                                           ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"   ..             .........+      .........%       ........       ........+.       +........       +........       .+.......      ...      ...    ...                  ...        ...     ..&     ...              .+.       .%.   +%+      ..     %.......++   ",
+"                  .........+.     ..........#     +........        .........+     #.........      +.........      +.........      ...      ...    ...                  ...        ...   ...       ...             %...+     ....  %...+     ..     ..........#  ",
+"                           %.%            ...     +..                      ..     +.              +.+             +..             ...      ...    ...                  ...        ...  ..+        ...             ..#..     ..... ... .%    ..    +..      ..%  ",
+"                   ...........    ..........      ..               .       ..     ..........      ..........      ...  ....       ... *.......    ...                  ...        ...  ..         ...             ... ..   .. ... ...  .+   ..    ...       ..  ",
+"                  ............    ..........      ..              ...      ..     ..........      ..........      ...  .....      ... *.......    ...                  ...        ...  .%         ...             ... +.   .. ... ...  $..  ..    ...       ..  ",
+"                  ...      ...    ...      .+     ...             ...      ..     ...             ...             ...     ..      ...      ...    ...                  ...        ...  ...        ...             ...  .% +.  ... ...   +.. ..    +..       ..  ",
+"                  ............    ...........     %.+......       ..........+     %.........      ...             #.........      ...      ...    ...              ......+        ...   #.+       %.........      ...   ...#  ... ...    .....     ........%..  ",
+"                  .........%..    ...........      +.......       .........+       %........      ...              .........      ...      ...    ...             .......         ...     ..+      .........      ...   ...   ... ...     ...@     +........+   ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .........+.      .+......+.     .........+.      .........      ....... ....... ..       ..      ..       ..+   %..    ...    +. ...     ...    ...      ...    ..........      .               ...             .               .               .             ",
+"  ..........+     %..........%    ..........%     ..........       &&&#.. ....... ..       ..      %..      ..     ..    ...@   ..  ...   ..+     ...      ...     .........                      ...                                                           ",
+"           ..     +..      ..%             ..     ..+                  .. ..      ..       ..       ..     +.      ...   ....   ..   %.. ...      #..      ...                                    ..                                                            ",
+"  ..........+     ..       ...    ..........%     +........+           .. ..      ..       ..       +..   ..+       ..  .. .+  %.+    .....        ..........          ..                                                                                       ",
+"  .........+      ..       ...    .........+       .........+          .. ..      ..       ..        ..   ..        ..  +. ..  +.     ....+         ........$        ....                                                                                       ",
+"  ...             ..%  ++  %..    ...      .%              ..          .. ..      %..      ..         .+ +..        +.. ..  .+ ..    ... ...                        ..#                           &&                                                            ",
+"  ..              #......#+..#    ..       ..     &..........          .. ..       .........+         +.%..          +...   ....+   ...   ...         ....         .........                      ...                                                           ",
+"  ..               %.........     ..       ...    &..........          .. ..       #........           +..           %..+   ....   ...     ...        ....        ...........                     ...                                                           ",
+"                       ..                                                                                                                                                                                                                                       ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .               .               .               .               .               .               .               .               .                                                                                                             ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                  ..                   ..           .+.....                         ..      ...   ...                             .. ..                                                                                                                         ",
+"                  ..                   ...          ......                          ..      ...   ...                             ..  .                                                                                                                         ",
+"                                   %.......         ...                             ..      ...   ..                                                                                                                                                            ",
+"                  ..              +........       #%.....                         . +......... .                                                                                                                                                                ",
+"                  ..              +..  +.         .....%#                         #  .+.....+@ #                                                                                                                                                                ",
+"                  ..              ..   #.           ..                                            &&                                                                                                                                                            ",
+"                  ..              ..   &.           ......                              ...       ...                                                                                                                                                           ",
+"                  ..              ...  @.         +.......                             ....       ...                                                                                                                                                           ",
+"                                  +...@+...                                                                                                                                                                                                                     ",
+"                                   #.......                                                                                                                                                                                                                     ",
+"                                       ...                                                                                                                                                                                                                      ",
+"                                       ..                                                                                                                                                                                                                       ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                   ..                                                              ..+                                                                                                                ..        ",
+"                                                                                                                                                                                                                                                      ..        ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                   +....        ",
+"                                                                                                                                                                                                                                                  +.....        ",
+"                                                                                                                                                                                                                                                  ...           ",
+"                                                                                                                                                                                                                                                  +.......      ",
+"                                                                                                                                                                                                                                                   .......      ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"      .@               ..             ...             ...+           .. ..                        ..........%..... ........           +.                .%            .+.+           ..  .         ..              @.              ..+..           .  .         ",
+"                       *             %% #%           ...&            .  ..                         ...........@   #........                                                           .  .          %%                                             .  .         ",
+"   ........                                                                                                ..+    +..                ......                          ......                                        .                 .                          ",
+"  ...........     .........+      .........+      .........+      .........+                       .......+..%.......              +.........      %.........      +.........      %.........       ...           ...               ...             ..          ",
+"   ........%.     ...........     ...........     ...........     ...........      ........%      ...........#.......             +..........+     ..........%    +..........+     ..........%      ...           ...               ...             ..          ",
+"           ..+             %.%             %.%             %.%             %.%    ...........     ...      ..+    ..+             &..      +..    @..      +..    &..      +..    @..       ..      ...           ...               ...             ..          ",
+"   ...........     ...........     ...........     ...........     ...........             %.%    ........+....   +........       &...........    &...........    &...........    &...........      ...           ...               ...             ..          ",
+"  ............    ............    ............    ............    ............      ...... ...     .......+%...... ++......       &.........%     &.........+     &.........%     &.........+       ...           ...               ...             ..          ",
+"  ..       ...    ...      ...    ...      ...    ...      ...    ...      ...    +...........                        +..         #..             &..             #..             &..               ...           ...               ...             ..          ",
+"  ............    ............    ............    ............    ............    ...      ...                                     ...........     ..........      ...........     ..........       ...           ...               ...             ..          ",
+"   ........%..    .........+..    .........+..    .........+..    .........+..    ...      ...                                      +.........     %..........      +.........     %..........      ...           ...               ...             ..          ",
+"                    ......  .       ......  .       ......  .       ......  .     ............                                                       ........                        ........        .                                              ..          ",
+"                                                                                   .......+ ..                                                                                                                                                                  ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"   .........+          ....           ..+               ..            ....             ...#           .  ..                          .......+..       ..               &+.            ..+.           .@ .+              +.        ...             ..........    ",
+"    .........+        +..                               *                             ...             .  .                          +.........%                                                      .@  +                        .........++     ..+.......+   ",
+"            ..                       ......                          ......                                                        %..    ..%.+   ..       ..     ..       ..     ...      ..      .       ..      ..      ...    ...........     ..%     ...   ",
+"  .......   ..     +#%      ..     +........+      %.......+       +........+      %.......+       %.......+                       ...   %+  ..   ...      ..     ...      ..     ...      ..     ...      ..     ...      ...             ..     ..........    ",
+"  .......   ..    %...%     ..    +..........+    #..........     +..........+    #..........     #..........                      ...  ..   ..   ...      ..     ...      ..     ...      ..     ...      ..     +..      ...            ...     ...........   ",
+"   ...      ..    ..  .#    ..    ..       ..+    +..      ..%    ..       ..+    +..      ..%    +..      ..%                     ... +.    ..   ...      ..     ...      ..     ...      ..     ...      ..      ..........     ..........+     ..&      ..   ",
+"   ...........    ..   .%   ..    ..       ...    ..       ...    ..       ...    ..       ...    ...      ...                      ...++   #..   ...      ..     ...      ..     ...      ..     ...      ..      +........@     .........#      ..&  +.....   ",
+"   .........+     ..   &..  ..    ..       ...    ..       ...    ..       ...    ..       ...    ...      ...                      ..........    ...      ..     ...      ..     +..      ..     ...      ..                     ...             ..&  +.....   ",
+"                  ..    ... ..    +.+      #..    +.       ...    +..      #..    +.       ...    +..      ...                      .@......%     %..      .+     %..      .+     +..     ..+     %..      .+                     ..              ..&           ",
+"                  ..     .....    @..........     %........%..     ..........     %........%..    %........%..                                     ..........      ..........      +........       ..........         ....                        ..            ",
+"                  ..      ...@     %+......%+      +........+      %+......%+      +........+      +........+                                      @+.......       &+.......         .....+        &+.......          ....                                      ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"      .+               ..            .....            ...%          ... ..           .  +         ..........%..... ........           ..+              ..+            .+.#           ..  .          ..             ..%             ..+.%           .  .         ",
+"                                                     ...             .  ..           .  %          ........%..#   #........                                                           .  .                                                         .  .         ",
+"   ........        ........        ........        ........        ........          ...#                  ...    ...                .......         .......         .......                         ..            ..                .                          ",
+"  ...........     ...........     ...........     ...........     ...........                      ..................              +........       +........       +........        ........         ..           ...               ...             ..          ",
+"           %.+             %.+             %.+             %.+             %.+    .........%      ............    ...             %.+             %.+             %.+             #.........         ..           ...               ...             ..          ",
+"           ..+             ..+             ..+             ..+             ..+    ...........     ...      ...    ...             ..              ..              ..#             +.                 ..           ...               ...             ..          ",
+"  %...........    %...........    %...........    %...........    %...........             %.%    .............   +........       ..........      ..........      ..........      ..........         ..           ...               ...             ..          ",
+"  ............    ............    ............    ............    ............     +...... ...     ........%...... ++......       ..........      ..........      ..........      ..........         ..           ...               ...             ..          ",
+"  ..       ...    ..       ...    ..       ...    ..       ...    ...      ...    +...........                        ...         ...             ...             ...             ...                ..           ...               ...             ..          ",
+"  ............    ............    ............    ............    ............    ...      ...                       &@            .........       .........       .........      %.........         ..           ...               ...             ..          ",
+"   ........%..     ........%..     ........%..     ........%..     ........%..    ...      ...                                     @+.......       @+.......       @+.......       %........         ..           ...               ...             ..          ",
+"                                                                                  .........+..                                                                                                                                                                  ",
+"                                                                                   .......+ ..                                                                                                                                                                  ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"   ..........          +..%           %..              ..+            ....             ..++          ..  ..                          .......+..       ..               ...           ..%..           .. ..             ..@        ...                ..  .      ",
+"    .........+        +..                                                             +..             .  .                          +.........%                                                      ..  .                        .........++         .  .      ",
+"            ..      *                ......          ......          ......          ......          ......                        %..    ..#.+   ..       ..     ...      ..     ...      ..     ..       ..     ...      ...    ...........      ..      ..   ",
+"  .......   ..     ..++     ..     +........+      +........+      +........+      +........+      +........+                      ...   ++  ..   ...      ..     ...      ..     ...      ..     ...      ..     ...      ...             ..      ..      ...  ",
+"  .......   ..    +....#    ..    +..      ..+    +..      ..+    +..      ..+    +..      ..+    +..      ..+                     ...  ..   ..   ...      ..     ...      ..     ...      ..     ...      ..     %..      ...    ...........      ..      ...  ",
+"   ...      ..    ..  .+*   ..    ..       ..+    ..       ..+    ..       ..+    ..       ..+    ...      ..+                     ... +.    ..   ...      ..     ...      ..     ...      ..     ...      ..      +.........     ..........+      ..      ..   ",
+"   ...........    ..   ++   ..    ..       ...    ..       ...    ..       ...    ..       ...    ...      ...                      ...++...#..   ...      ..     ...      ..     ...      ..     ...      ..       ........@     ...              +........%   ",
+"   .........+     ..    +.  ..    ..       ...    ..       ...    ..       ...    ..       ...    ...      ...                      .........+    ...      ..     +..      ..     +..      ..     ...      ..                     ...                +.....+    ",
+"                  ..     .....    +.+      #..    +..      #..    +..      #..    +..      #..    +..      #..                      .&......      %..     ..+     +..     ..+     +..     ..+     #..     ..+                      .                            ",
+"                  ..      ...+     ..........      ..........      ..........      ..........      ..........                                      ..........      %........       %........       ..........         ....                            ....      ",
+"                  ..       %+       +......%        +......%        +......%        +......%        +......%                                        +.....+.         .....+          .....+         +.......           ...                            ....      ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                "};
Index: branches/heathaze/src/lib/graphics/text_engine/font.cc
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/font.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/font.cc	(revision 9940)
@@ -0,0 +1,294 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "font.h"
+
+#ifdef HAVE_SDL_IMAGE_H
+#include <SDL_image.h>
+#else
+#include <SDL/SDL_image.h>
+#endif
+
+#include "default_font.xpm"
+
+#include "debug.h"
+#include "compiler.h"
+
+ObjectListDefinition(Font);
+
+Font::Font()
+    : data(Font::defaultFontData)
+{
+  this->init();
+}
+
+/**
+ * @brief constructs a Font out of a TTF-FIle
+ * @param fontFile the File to load the font from
+ * @param fontSize the Size of the Font in Pixels
+ */
+Font::Font(const std::string& fontFile, unsigned int renderSize)
+    : data(Font::defaultFontData)
+{
+  this->init();
+
+  if (!fontFile.empty())
+    this->loadFontFromTTF(fontFile, renderSize);
+}
+
+
+/**
+ * @brief constructs a Font out of an ImageFile
+ * @param imageFile the ImageFile to load the Font From.
+ */
+Font::Font(const std::string& imageFile)
+    : data(Font::defaultFontData)
+{
+  this->init();
+
+  this->setName(imageFile);
+  //  this->setSize(fontSize);
+  SDL_Surface* image = NULL;
+  if (!imageFile.empty())
+    image = IMG_Load(imageFile.c_str());
+  else
+    return;
+  if (image != NULL)
+  {
+    this->loadFontFromSDL_Surface(image);
+    SDL_FreeSurface(image);
+  }
+  else
+    PRINTF(1)("loading from surface %s failed: %s\n", imageFile.c_str(), IMG_GetError());
+}
+
+/**
+ * @brief constructs a Font
+ * @param xpmArray the xpm-ARRAY to load the font from
+ */
+Font::Font(char** xpmArray)
+    : data(Font::defaultFontData)
+{
+  this->init();
+  this->setName("XPM-array-font");
+  //  this->setSize(fontSize);
+  SDL_Surface* image = NULL;
+  if (xpmArray != NULL)
+    image = IMG_ReadXPMFromArray(xpmArray);
+  if (image != NULL)
+  {
+    this->loadFontFromSDL_Surface(image);
+    SDL_FreeSurface(image);
+  }
+  else
+    PRINTF(1)("Loading from XPM-array failed: %s\n", IMG_GetError());
+}
+
+Font::Font(const Font& font)
+{
+  this->init();
+  *this = font;
+}
+
+/**
+ * @brief destructs a font
+ *
+ * this releases the memory a font uses to be opened.
+ * deletes the glLists, and the TTF-handler, if present.
+ */
+Font::~Font()
+{ }
+
+Font& Font::operator=(const Font& font)
+{
+  Material::operator=(font);
+  this->data = font.data;
+  this->setTexture(this->data->textureData());
+
+  return *this;
+};
+
+
+/**
+ * @brief initializes a Font (with default values)
+ */
+void Font::init()
+{
+  this->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+  this->registerObject(this, Font::_objectList);
+  if (Font::defaultFontData.isNull())
+  {
+    Font::initDefaultFont();
+    this->data = Font::defaultFontData;
+  }
+}
+
+FontData::Pointer Font::defaultFontData(NULL);
+
+/**
+ * @brief initializes the default font
+ */
+void Font::initDefaultFont()
+{
+  // temporarily create a Font.
+  Font::defaultFontData = FontData::Pointer(new FontData);
+  // apply the Data.
+  Font::defaultFontData = Font(font_xpm).data;
+}
+
+
+/**
+ * @brief sets The Font.
+ * @param fontFile The file containing the font.
+ * @returns true if loaded, false if something went wrong, or if a font was loaded before.
+ */
+bool Font::loadFontFromTTF(const std::string& fontFile, unsigned int renderSize)
+{
+  this->data = FontData::Pointer (new FontData());
+  bool retVal = this->data->loadFontFromTTF(fontFile, renderSize);
+  if (!retVal)
+    this->data = Font::defaultFontData;
+
+  this->setTexture(this->data->textureData());
+  return retVal;
+}
+
+/**
+ * @brief loads a font From an XPM-array.
+ * @param xpmArray the array of the XPM to load the font from.
+ */
+bool Font::loadFontFromSDL_Surface(SDL_Surface* surface)
+{
+  this->data = FontData::Pointer (new FontData());
+  bool retVal = this->data->loadFontFromSDL_Surface(surface);
+  if (!retVal)
+    this->data = Font::defaultFontData;
+
+  this->setTexture(this->data->textureData());
+  return retVal;
+}
+
+
+/**
+ * @brief sets a specific data->renderStyle
+ * @param data->renderStyle the Style to render: a string (char-array) containing:
+ *   i: italic, b: bold, u, underline
+ */
+void Font::setStyle(const std::string& renderStyle)
+{
+  /// FIXME
+  //this->data->setStyle(renderStyle);
+}
+
+
+void Font::setTexture(const TextureData::Pointer& texDataPointer)
+{
+  this->setDiffuseMap(texDataPointer);
+}
+
+
+/**
+ * @brief creates and exports an Image, that has all the characters
+ * stored in a Array (as an image)
+ * @param fileName the File to write the image into.
+ */
+void Font::createAsciiImage(const std::string& ttfFile, const std::string& fileName, unsigned int size)
+{
+  TTF_Font* fontTTF = TTF_OpenFont(ttfFile.c_str(), size);
+
+  if (fontTTF == NULL)
+    return;
+  int height = TTF_FontHeight(fontTTF);
+
+  //
+  // Surface definition.
+  SDL_Rect tmpRect; // this represents a Rectangle for blitting.
+  SDL_Surface* tmpSurf =  SDL_CreateRGBSurface(SDL_SWSURFACE,
+                          height*size, height*size,
+                          32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
+                          0x000000FF,
+                          0x0000FF00,
+                          0x00FF0000,
+                          0xFF000000
+#else
+                          0xFF000000,
+                          0x00FF0000,
+                          0x0000FF00,
+                          0x000000FF
+#endif
+                                              );
+  tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;
+  SDL_SetClipRect(tmpSurf, &tmpRect);
+
+  int posX, posY;
+  // all the interessting Glyphs
+  for (posY = 0; posY < 16; posY++)
+  {
+    for (posX = 0; posX < 16; posX++)
+    {
+      SDL_Surface* glyphSurf = NULL;
+      SDL_Color white = {255, 255, 255};
+      glyphSurf = TTF_RenderGlyph_Blended(fontTTF, posX+size*posY, white);
+
+      if( glyphSurf != NULL )
+      {
+        tmpRect.x = height*posX;
+        tmpRect.y = height*posY;
+        SDL_SetAlpha(glyphSurf, 0, 0);
+
+        SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);
+        SDL_FreeSurface(glyphSurf);
+      }
+    }
+  }
+  SDL_SaveBMP(tmpSurf, fileName.c_str());
+  SDL_FreeSurface(tmpSurf);
+
+  TTF_CloseFont(fontTTF);
+}
+
+
+
+
+/**
+ * @brief a simple function to get some interesting information about this class
+ */
+void Font::debug() const
+{
+  Material::debug();
+
+  //PRINT(0)("TEST %p and %p\n", this->data.get(), this->data->textureData().get());
+  // print the loaded font's style
+/*  int style = TTF_STYLE_NORMAL;
+  if (likely(this->data->fontTTF != NULL))
+    style = TTF_GetFontStyle(this->data->fontTTF);
+  PRINTF(0)("The font style is:");
+  if(style==TTF_STYLE_NORMAL)
+    PRINTF(0)(" normal");
+  else
+  {
+    if(style&TTF_STYLE_BOLD)
+      PRINTF(0)(" bold");
+    if(style&TTF_STYLE_ITALIC)
+      PRINTF(0)(" italic");
+    if(style&TTF_STYLE_UNDERLINE)
+      PRINTF(0)(" underline");*/
+//  }
+  PRINTF(0)("\n");
+}
Index: branches/heathaze/src/lib/graphics/text_engine/font.h
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/font.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/font.h	(revision 9940)
@@ -0,0 +1,68 @@
+/*!
+ * @file font.h
+ * brief Definition of the FONT-loading class
+ *
+ * !! IMPORTANT !! When using ttf fonts clear the license issues prior to
+ * adding them to orxonox. This is really important, because we do not want
+ * to offend anyone.
+ */
+
+#ifndef _FONT_H
+#define _FONT_H
+
+#include "material.h"
+
+#include "font_data.h"
+
+
+//! A class to handle a Font of a certain ttf-File/image-file, Size.
+class Font : public Material
+{
+  ObjectListDeclaration(Font);
+public:
+  typedef FontData::Glyph Glyph;
+public:
+  Font();
+  Font(const std::string& fontFile, unsigned int renderSize);
+  Font(const std::string& imageFile);
+  Font(char** xpmArray);
+  Font(const Font& font);
+  virtual ~Font();
+
+  Font& operator=(const Font& font);
+  /** @brief compare two fonts @param font the comparator, @returns true if they match */
+  bool operator==(const Font& font) const { return this->data == font.data; };
+
+  /// LOADING new Fonts
+  bool loadFontFromTTF(const std::string& fontFile, unsigned int renderSize);
+  bool loadFontFromSDL_Surface(SDL_Surface* surface);
+
+  void setStyle(const std::string& renderStyle);
+
+  /** @returns a Pointer to the Array of Glyphs */
+  inline const Glyph* const * const getGlyphArray() const { return this->data->getGlyphArray(); };
+
+  inline int getMaxHeight() const { return data->getMaxHeight(); };
+  inline int getMaxAscent() const { return data->getMaxAscent(); };
+  inline int getMaxDescent() const { return data->getMaxDescent(); };
+
+
+  static void createAsciiImage(const std::string& ttfFile, const std::string& fileName, unsigned int size);
+
+  void debug() const;
+
+  void acquireData(const FontData::Pointer& data) { this->data = data; };
+  const FontData::Pointer& dataPointer() const { return data; };
+private:
+  void init();
+  static void initDefaultFont();
+
+  void setTexture(const TextureData::Pointer& texDataPointer);
+
+private:
+  FontData::Pointer         data;                //!< A Data-Pointer to a Font.
+
+  static FontData::Pointer  defaultFontData;     //!< a default font, that is used, if other fonts were unable to be loaded.
+};
+
+#endif /* _FONT_H */
Index: branches/heathaze/src/lib/graphics/text_engine/font_data.cc
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/font_data.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/font_data.cc	(revision 9940)
@@ -0,0 +1,414 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "font_data.h"
+
+#include "debug.h"
+#include "compiler.h"
+
+#include "texture.h"
+
+
+/**
+ * @brief creates a new Font Data.
+ */
+FontData::FontData()
+    : texData(new TextureData)
+{
+  this->glyphArray = NULL;
+  this->renderStyle = TTF_STYLE_NORMAL;
+  this->renderSize = FONT_DEFAULT_RENDER_SIZE;
+
+  this->maxHeight = 0;
+  this->maxAscent = 0;
+  this->maxDescent = 0;
+}
+
+
+/**
+ * @brief Destructor of a Font
+ *
+ *  Frees Data, and deletes the fonts from GL
+ */
+FontData::~FontData()
+{
+  // deleting all Glyphs
+  if (this->glyphArray != NULL)
+  {
+    for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
+    {
+      if (this->glyphArray[i] != NULL)
+        delete this->glyphArray[i];
+    }
+    delete[] this->glyphArray;
+  }
+
+  //! @todo check if we really do not need to delete the fastTextureID here.
+  //   if (this->fastTextureID != 0)
+  //     if(glIsTexture(this->fastTextureID))
+  //       glDeleteTextures(1, &this->fastTextureID);
+}
+
+
+/**
+ * @brief sets The Font.
+ * @param fontFile The file containing the font.
+ * @returns true if loaded, false if something went wrong, or if a font was loaded before.
+ */
+bool FontData::loadFontFromTTF(const std::string& fontFile, unsigned int renderSize)
+{
+  TTF_Font* fontTTF;
+  //this->setName(fontFile);
+  fontTTF = TTF_OpenFont(fontFile.c_str(), renderSize);
+  this->renderSize = renderSize;
+
+  if(fontTTF != NULL)
+  {
+    this->maxHeight = TTF_FontHeight(fontTTF);
+    this->maxAscent = TTF_FontAscent(fontTTF);
+    this->maxDescent = TTF_FontDescent(fontTTF);
+
+    this->setStyle(fontTTF, "c");
+    if (this->createFastTexture(fontTTF))
+    {
+      TTF_CloseFont(fontTTF);
+      return true;
+    }
+
+    else
+    {
+      TTF_CloseFont(fontTTF);
+      PRINTF(1)("Unable to createa a Fast Texture fot %s\n", fontFile.c_str() );
+      return false;
+    }
+  }
+  else
+  {
+    PRINTF(1)("TTF_OpenFont: %s for %s\n", TTF_GetError(), fontFile.c_str());
+    return false;
+  }
+
+}
+
+
+
+/**
+ * @brief loads a font From an XPM-array.
+ * @param xpmArray the array of the XPM to load the font from.
+ */
+bool FontData::loadFontFromSDL_Surface(SDL_Surface* surface)
+{
+  if(surface == NULL)
+    return false;
+
+
+  bool hasAlpha;
+  SDL_Surface* newSurf = Texture::prepareSurface(surface, hasAlpha);
+  if (newSurf != NULL)
+  {
+    this->texData->setSurface(newSurf);
+    this->texData->setAlpha(hasAlpha);
+    this->texData->setTexture(Texture::loadTexToGL(newSurf));
+  }
+  else
+  {
+    return false;
+  }
+
+  // initializing the Glyphs.
+  if (this->glyphArray == NULL)
+  {
+    float cx,cy;
+    Glyph* tmpGlyph;
+    this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR];
+    for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
+    {
+      tmpGlyph = this->glyphArray[i] = new Glyph;
+      cx=(float)(i%16)/16.0f;                  // X Position Of Current Character
+      cy=(float)(i/16)/16.0f;                  // Y Position Of Current Character
+
+      tmpGlyph->texCoord[0] = cx;
+      tmpGlyph->texCoord[1] = cx+0.0625f;
+      tmpGlyph->texCoord[2] = cy;
+      tmpGlyph->texCoord[3] = cy+0.0625f;
+      tmpGlyph->minX = 0.0f;
+      tmpGlyph->maxX = 1.0f;
+      tmpGlyph->minY = 0.0f;
+      tmpGlyph->maxY = 1.0f;
+      tmpGlyph->width = 1.0f;
+      tmpGlyph->advance = 1.0f;
+      tmpGlyph->bearingX = 0.0f;
+      tmpGlyph->bearingY = 0.0f;
+      tmpGlyph->height = 1.0f;
+    }
+  }
+  return true;
+}
+
+/**
+ * @brief sets a specific data->renderStyle
+ * @param data->renderStyle the Style to render: a string (char-array) containing:
+ *   i: italic, b: bold, u, underline
+ */
+void FontData::setStyle(TTF_Font* font, const std::string& renderStyle)
+{
+  this->renderStyle = TTF_STYLE_NORMAL;
+
+  for (unsigned int i = 0; i < renderStyle.size(); i++)
+  {
+    if (renderStyle[i] == 'b')
+      this->renderStyle |= TTF_STYLE_BOLD;
+    else if (renderStyle[i] == 'i')
+      this->renderStyle |= TTF_STYLE_ITALIC;
+    else if (renderStyle[i] == 'u')
+      this->renderStyle |= TTF_STYLE_UNDERLINE;
+  }
+
+  /// !TODO REBUILD THE FONT
+
+  if (likely(font != NULL))
+      TTF_SetFontStyle(font, this->renderStyle);
+  //  else
+  //    PRINTF(2)("Font was not initialized, please do so before setting the Font-Style.\n");
+}
+
+
+
+/**
+ * @param glyph: The Glyph to set the Parameters to.
+ * @param character: The character to get info about.
+ * @returns a Glyph struct of a character. This Glyph is a pointer,
+ * and MUST be deleted by the user..
+ *
+ * This only works for horizontal fonts. see
+ * http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
+ * for more info about vertical Fonts
+ */
+bool FontData::getGlyphMetrics(TTF_Font* font, Glyph* glyph, Uint16 character)
+{
+  glyph->character = character;
+  if (likely (font != NULL))
+  {
+    int miX, maX, miY, maY, adv;
+    if (TTF_GlyphMetrics(font, glyph->character,
+                         &miX, &maX,
+                         &miY, &maY,
+                         &adv) == -1)
+      return false;
+    glyph->minX = (float)miX / (float)this->renderSize;
+    glyph->maxX = (float)maX / (float)this->renderSize;
+    glyph->minY = (float)miY / (float)this->renderSize;
+    glyph->maxY = (float)maY / (float)this->renderSize;
+    glyph->advance = (float)adv / (float)this->renderSize;
+
+    // Calculate the Rest.
+    glyph->height = glyph->maxY - glyph->minY;
+    glyph->width = glyph->maxX - glyph->minX;
+    glyph->bearingX = (glyph->advance - glyph->width) / 2;
+    glyph->bearingY = glyph->maxY;
+
+    //printf("%c:: %d %d %d %d %d\n", character, miX, maX, miY, maY, adv);
+
+    return true;
+  }
+  return false;
+}
+
+
+/**
+ * @brief creates a Fast-Texture of this Font
+ */
+bool FontData::createFastTexture(TTF_Font* fontTTF)
+{
+  /* interesting GLYPHS:
+  *  32: space
+  *  33-47: Special Characters.
+  *  48-57: 0-9
+  *  58-63: some more special chars (minor)
+  *  65-90: A-Z
+  *  97-122: a-z
+  */
+  int numberOfGlyphs = 91;
+
+  this->initGlyphs(fontTTF, 32, numberOfGlyphs);
+  //  this->glyphArray[32]->width = .5f; //!< @todo find out the real size of a Space
+
+  int rectSize = this->findOptimalFastTextureSize();
+
+  // setting default values. (maybe not needed afterwards)
+  SDL_Color tmpColor;  tmpColor.r = tmpColor.g = tmpColor.b = 0;
+  // Surface definition.
+  SDL_Rect tmpRect; // this represents a Rectangle for blitting.
+  SDL_Surface* tmpSurf =  SDL_CreateRGBSurface(SDL_HWSURFACE,
+                          rectSize, rectSize,
+                          32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
+                          0x000000FF,
+                          0x0000FF00,
+                          0x00FF0000,
+                          0xFF000000
+#else
+                          0xFF000000,
+                          0x00FF0000,
+                          0x0000FF00,
+                          0x000000FF
+#endif
+                                              );
+  tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;
+  SDL_SetClipRect(tmpSurf, &tmpRect);
+  int maxLineHeight = this->getMaxHeight();
+
+  // all the interessting Glyphs
+  for (int i = 0; i < 128; i++)
+  {
+    SDL_Surface* glyphSurf = NULL;
+    Glyph* tmpGlyph;
+
+    if ((tmpGlyph = this->glyphArray[i]) != NULL)
+    {
+      if (tmpGlyph->height*this->renderSize > maxLineHeight)
+        maxLineHeight = (int)(tmpGlyph->height*this->renderSize);
+
+      if (tmpRect.x+tmpGlyph->advance*this->renderSize > tmpSurf->w)
+      {
+        tmpRect.x = 0;
+        tmpRect.y = tmpRect.y + maxLineHeight;
+      }
+      if (tmpRect.y + maxLineHeight > tmpSurf->h)
+      {
+        PRINTF(1)("Protection, so font cannot write over the boundraries (!!this should not heappen!!)\n");
+        break;
+      }
+      // reading in the new Glyph
+      if (likely(fontTTF != NULL))
+      {
+        SDL_Color white = {255, 255, 255};
+        glyphSurf = TTF_RenderGlyph_Blended(fontTTF, i, white);
+      }
+      if( glyphSurf != NULL )
+      {
+        SDL_SetAlpha(glyphSurf, 0, 0);
+        int tmpY = tmpRect.y;
+        tmpRect.y += this->getMaxAscent()-(int)((float)tmpGlyph->bearingY*this->renderSize);
+        SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);
+        tmpRect.y = tmpY;
+
+        tmpGlyph->texCoord[0] = (float)((float)tmpRect.x )/(float)tmpSurf->w;
+        tmpGlyph->texCoord[1] = (float)((float)tmpRect.x + tmpGlyph->width*(float)this->renderSize)/(float)tmpSurf->w;
+        tmpGlyph->texCoord[2] = (float)(tmpRect.y)/(float)tmpSurf->w;
+        tmpGlyph->texCoord[3] = (float)((float)tmpRect.y+(float)this->getMaxHeight())/(float)tmpSurf->w;
+        SDL_FreeSurface(glyphSurf);
+        tmpRect.x += (int)(tmpGlyph->width * this->renderSize) + 1;
+      }
+    }
+  }
+  // outputting the GLYPH-table
+  //       char outName[1024];
+  //       sprintf( outName, "%s-glyphs.bmp", this->getName());
+  //       SDL_SaveBMP(tmpSurf, outName);
+  this->texData->setAlpha(true);
+  if (this->texData->setSurface(tmpSurf))
+    this->texData->setTexture(Texture::loadTexToGL(tmpSurf));
+  return true;
+}
+
+/**
+ * @brief stores Glyph Metrics in an Array.
+ * @param from The Glyph to start from.
+ * @param count The number of Glyphs to start From.
+ */
+void FontData::initGlyphs(TTF_Font* font, Uint16 from, Uint16 count)
+{
+  /* initialize the Array, and set all its entries to NULL
+  *  only if the Glyph-array has not been initialized
+  */
+  if (!this->glyphArray)
+  {
+    this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR];
+    for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
+      this->glyphArray[i] = NULL;
+  }
+
+  Uint16 lastGlyph = from + count;
+
+  for (int i = from; i <= lastGlyph; i++)
+  {
+    // setting up all the Glyphs we like.
+    Glyph* newGlyph = new Glyph;
+    if (getGlyphMetrics(font, newGlyph, i))
+      this->glyphArray[i] = newGlyph;
+    else
+    {
+      delete newGlyph;
+      this->glyphArray[i] = NULL;
+    }
+  }
+  return;
+}
+
+/**
+ * @returns the optimal size to use as the texture size
+ *
+ * @todo: this algorithm can be a lot faster, althought it does
+ * not really matter within the init-context, and 128 glyphs.
+ *
+ * This function searches for a 2^n sizes texture-size, this is for
+ * openGL-version < 1.2 compatibility ( and because it is realy easy like this :))
+ */
+int FontData::findOptimalFastTextureSize()
+{
+  if (this->glyphArray == NULL)
+    return 0;
+
+  unsigned int i;
+  unsigned int x,y; // the counters
+  int maxLineHeight = this->getMaxHeight();
+  unsigned int size = 32;  // starting Value, we have to start somewhere 32 seems reasonable. (take any small enough 2^i number)
+  bool sizeOK = false;
+  Glyph* tmpGlyph;
+
+  while (!sizeOK)
+  {
+    x = 0; y = 0;
+    for (i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
+    {
+      if((tmpGlyph = this->glyphArray[i]) != NULL)
+      {
+        // getting the height of the highest Glyph in the Line.
+        if (tmpGlyph->height*this->renderSize > maxLineHeight)
+          maxLineHeight = (int)(tmpGlyph->height*this->renderSize);
+
+        if (x + tmpGlyph->advance*this->renderSize > size)
+        {
+          x = 0;
+          y = y + maxLineHeight;
+          //maxLineHeight = 0;
+        }
+        if (y + maxLineHeight + 1 > size)
+          break;
+        x += (int)(tmpGlyph->advance*this->renderSize)+1;
+
+      }
+    }
+    if (i >= FONT_HIGHEST_KNOWN_CHAR-1 || size > 8192)
+      sizeOK = true;
+    else
+      size *= 2;
+  }
+  return size;
+}
+
Index: branches/heathaze/src/lib/graphics/text_engine/font_data.h
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/font_data.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/font_data.h	(revision 9940)
@@ -0,0 +1,100 @@
+/*!
+ * @file font_data.h
+ * @brief Contains the font-data class, that handles the reading of Images into Texutre-files.
+ */
+
+#ifndef _FONT_DATA_H
+#define _FONT_DATA_H
+
+#include "base_object.h"
+
+#include "glincl.h"
+#include "texture_data.h"
+
+#ifdef HAVE_SDL_TTF_H
+#include <SDL_ttf.h>
+#else
+#include <SDL/SDL_ttf.h>
+#endif
+
+
+
+/* some default values */
+#define FONT_NUM_COLORS              256           //!< number of colors.
+
+#define FONT_HIGHEST_KNOWN_CHAR      128           //!< The highest character known to the textEngine.
+#define FONT_DEFAULT_RENDER_SIZE     50            //!< At what Resolution to render fonts.
+
+class FontData
+{
+
+
+public:
+
+//! A struct for handling glyphs
+/**
+ * a Glyph is one letter of a certain font
+ */
+  struct Glyph
+  {
+  // Glyph-specific (size and so on)
+    Uint16   character;         //!< The character
+    float    minX;              //!< The minimum distance from the origin in X
+    float    maxX;              //!< The maximum distance from the origin in X
+    float    minY;              //!< The minimum distance from the origin in Y
+    float    maxY;              //!< The maximum distance from the origin in Y
+    float    width;             //!< The width of the Glyph
+    float    height;            //!< The height of the Glyph
+    float    bearingX;          //!< How much is right of the Origin
+    float    bearingY;          //!< How much is above the Origin
+    float    advance;           //!< How big a Glyph would be in monospace-mode
+
+    GLfloat texCoord[4];        //!< Texture coordinates: 0:left, 1:right, 2: top, 3: bottom.
+  };
+
+  typedef CountPointer<FontData> Pointer;
+public:
+  FontData();
+  ~FontData();
+
+  /// LOADING new Fonts
+  bool loadFontFromTTF(const std::string& fontFile, unsigned int renderSize);
+  bool loadFontFromSDL_Surface(SDL_Surface* surface);
+
+  void setStyle(TTF_Font* font, const std::string& renderStyle);
+
+  /** @returns a Pointer to the Array of Glyphs */
+  inline const Glyph* const * const getGlyphArray() const { return this->glyphArray; };
+
+  int getMaxHeight() const { return maxHeight; };
+  int getMaxAscent() const { return maxAscent; };
+  int getMaxDescent() const { return maxDescent; };
+
+  /** @returns the Texture-Data of this FontData */
+  const TextureData::Pointer& textureData() const { return texData; };
+
+  bool rebuild() { return texData->rebuild(); };
+
+private:
+  void initGlyphs(TTF_Font* font, Uint16 from, Uint16 count);
+  bool getGlyphMetrics(TTF_Font* font, Glyph* glyph, Uint16 character);
+
+  int findOptimalFastTextureSize();
+  bool createFastTexture(TTF_Font* font);
+
+
+private:
+  std::string   fontFile;            //!< The FileName the Font was loaded from.
+  int           renderStyle;         //!< The Renderstyle
+  unsigned int  renderSize;          //!< How big the Font should be rendered.
+
+  Glyph**       glyphArray;          //!< An Array of all the Glyphs stored in the Array of Glyphs.
+
+  int           maxHeight;           //!< Max Height of the Font.
+  int           maxAscent;           //!< Max Ascent of the Font.
+  int           maxDescent;          //!< Max Desent of the Font.
+
+  TextureData::Pointer   texData;
+};
+
+#endif /* _FONT_DATA_H */
Index: branches/heathaze/src/lib/graphics/text_engine/limited_width_text.cc
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/limited_width_text.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/limited_width_text.cc	(revision 9940)
@@ -0,0 +1,164 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "limited_width_text.h"
+#include "font.h"
+
+ObjectListDefinition(LimitedWidthText);
+/**
+ * @brief creates a new Text Element
+ * @param fontFile the Font to render this text in
+ * @param type The renderType to display this font in
+ */
+LimitedWidthText::LimitedWidthText(const std::string& fontFile, unsigned int textSize, float lineWidth, DotsPosition dotsPosition)
+    : Text(fontFile, textSize)
+{
+  this->registerObject(this, LimitedWidthText::_objectList);
+
+  this->_dotsPosition = End;
+  this->setLineWidth(lineWidth);
+}
+
+/**
+ * @brief sets the maximum Line width
+ * @param lineWidth the maximum lineWidth.
+ */
+void LimitedWidthText::setLineWidth(float lineWidth)
+{
+  this->_lineWidth = lineWidth;
+  this->setupTextWidth();
+}
+
+/**
+ * @brief sets the Dots Position
+ * @param dotsPosition the Position of the Dots
+ */
+void LimitedWidthText::setDotsPosition(DotsPosition dotsPosition)
+{
+  this->_dotsPosition = dotsPosition;
+  this->setupTextWidth();
+}
+
+
+/**
+ * @brief draws the Text
+ */
+void LimitedWidthText::draw() const
+{
+  if (unlikely(this->_dotedText.empty()))
+    return;
+  glPushMatrix();
+  glPushAttrib(GL_ENABLE_BIT);
+  // transform for alignment.
+  if (this->getAlignment() == TEXT_ALIGN_RIGHT)
+    glTranslatef(-this->getSizeX2D(), 0, 0);
+  else if (this->getAlignment() == TEXT_ALIGN_CENTER || this->getAlignment() == TEXT_ALIGN_SCREEN_CENTER)
+    glTranslatef(-this->getSizeX2D()/2, 0, 0);
+
+  // drawing this Text.
+  this->font().select();
+
+  glTranslatef(getAbsCoor2D().x, getAbsCoor2D().y, 0);
+  glRotatef(this->getAbsDir2D(), 0, 0, 1);
+
+  const Font::Glyph* tmpGlyph;
+  float posX = 0.0f;
+  glBegin(GL_QUADS);
+  for (unsigned int i = 0; i < this->_dotedText.size(); i++)
+  {
+    if(likely((tmpGlyph = this->font().getGlyphArray()[this->_dotedText[i]]) != NULL))
+    {
+      glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[2]);
+      glVertex2d(posX+tmpGlyph->maxX*this->size(), 0);
+
+      glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[3]);
+      glVertex2d(posX+tmpGlyph->maxX*this->size(), this->size());
+
+      glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[3]);
+      glVertex2d(posX+tmpGlyph->minX*this->size(), this->size());
+
+      glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[2]);
+      glVertex2d(posX+tmpGlyph->minX*this->size(), 0);
+
+      posX += tmpGlyph->advance * this->size();
+    }
+  }
+  glEnd();
+  glPopAttrib();
+  glPopMatrix();
+}
+
+
+/**
+ * @brief setting up the Text-Width if DYNAMIC
+ */
+void LimitedWidthText::setupTextWidth()
+{
+  float dotsSize = this->font().getGlyphArray()[46]->advance * 3.0;
+
+  float width = 0.0f;
+  float maxWidth = this->_lineWidth / this->size();
+
+  this->_dotedText = this->text();
+
+  switch (this->_dotsPosition)
+  {
+    case End:
+      for (unsigned int i = 0; i < this->text().size(); i++)
+      {
+        if (width + dotsSize > maxWidth )
+        {
+          this->_dotedText = this->text().substr(0, i) + "...";
+          if (i > 0)
+            width -= this->font().getGlyphArray()[this->text()[i-1]]->advance;
+          width += dotsSize;
+          break;
+        }
+        // Advance the Text.
+        if(this->font().getGlyphArray()[this->text()[i]] != NULL)
+          width += this->font().getGlyphArray()[this->text()[i]]->advance;
+      }
+      break;
+
+    case Begin:
+      int i = text().size() -1;
+      for (; i >= 0; --i)
+      {
+        if (width + dotsSize > maxWidth )
+        {
+          this->_dotedText = std::string("...") + this->text().substr(i);
+          if (i + 1 < (int)text().size() )
+            width -= this->font().getGlyphArray()[this->text()[i+1]]->advance;
+          width += dotsSize;
+          break;
+        }
+        // Advance the Text.
+        if(this->font().getGlyphArray()[this->text()[i]] != NULL)
+          width += this->font().getGlyphArray()[this->text()[i]]->advance;
+      }
+      break;
+  }
+  this->setSizeX2D(width * this->size());
+}
+
+/**
+ * @brief print out some nice debug output
+ */
+void LimitedWidthText::debug() const
+{
+  printf("Debug %s::%s \n", this->getClassCName(), this->getCName() );
+}
Index: branches/heathaze/src/lib/graphics/text_engine/limited_width_text.h
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/limited_width_text.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/limited_width_text.h	(revision 9940)
@@ -0,0 +1,52 @@
+/*!
+ * @file limited_width_text.h
+ * @brief Definition of a text Class, that is able to render text.
+ */
+
+#ifndef _LIMITED_WIDTH_TEXT_H
+#define _LIMITED_WIDTH_TEXT_H
+
+#include "text.h"
+
+#include <vector>
+
+//! Represents one textElement.
+class LimitedWidthText : public Text
+{
+  ObjectListDeclaration(LimitedWidthText);
+  public:
+    typedef enum {
+      Begin,
+      End,
+    } DotsPosition;
+
+
+  public:
+    LimitedWidthText(const std::string& fontFile = "", unsigned int fontSize = TEXT_DEFAULT_SIZE, float lineWidth = 100.0, DotsPosition dotsPosition = Begin);
+
+    // Setup:
+    void setLineWidth(float lineWidth);
+    void setDotsPosition(LimitedWidthText::DotsPosition dotsPosition);
+
+    // Retrieve:
+    /** @returns the LineWidth (maximum distance from the left to the right */
+    inline float lineWidth() const { return this->_lineWidth; };
+    /** @returns the dots position. */
+    inline float dotsPosition() const { return this->_dotsPosition; };
+
+    virtual void draw() const;
+
+    void debug() const;
+
+  protected:
+    virtual void setupTextWidth();
+
+  private:
+    std::string                _dotedText;
+
+    DotsPosition               _dotsPosition;
+    float                      _lineWidth;
+    unsigned int               _lineEnds;
+};
+
+#endif /* _LIMITED_WIDTH_TEXT_H */
Index: branches/heathaze/src/lib/graphics/text_engine/multi_line_text.cc
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/multi_line_text.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/multi_line_text.cc	(revision 9940)
@@ -0,0 +1,168 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "multi_line_text.h"
+#include "font.h"
+
+ObjectListDefinition(MultiLineText);
+
+/**
+ * @brief creates a new Text Element
+ * @param fontFile the Font to render this text in
+ * @param type The renderType to display this font in
+ */
+MultiLineText::MultiLineText(const std::string& fontFile, unsigned int textSize, float lineWidth)
+  : Text(fontFile, textSize)
+{
+  this->registerObject(this, MultiLineText::_objectList);
+
+  this->lineSpacing = 1.0;
+  this->lineCount = 0;
+  this->setLineWidth(lineWidth);
+}
+
+/**
+ * @brief sets the maximum Line width
+ * @param lineWidth the maximum lineWidth.
+ */
+void MultiLineText::setLineWidth(float lineWidth)
+{
+  this->lineWidth = lineWidth;
+  this->setSizeX2D(lineWidth);
+  this->setupTextWidth();
+}
+
+
+/**
+ * @param lineSpacing: the Spacing between the lines
+ */
+void MultiLineText::setLineSpacing(float lineSpacing)
+{
+   this->lineSpacing = lineSpacing;
+   this->setupTextWidth();
+}
+
+
+/**
+ * @brief draws the Text
+ */
+void MultiLineText::draw() const
+{
+  if (unlikely(this->text().empty()))
+    return;
+  glPushMatrix();
+  glPushAttrib(GL_ENABLE_BIT);
+  // transform for alignment.
+  // TODO make the Stuff with the alignment
+  if (this->getAlignment() == TEXT_ALIGN_RIGHT)
+    glTranslatef(-this->getSizeX2D(), 0, 0);
+  else if (this->getAlignment() == TEXT_ALIGN_CENTER || this->getAlignment() == TEXT_ALIGN_SCREEN_CENTER)
+    glTranslatef(-this->getSizeX2D()/2, 0, 0);
+
+  // drawing this Text.
+  this->font().select();
+
+  glTranslatef(this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
+  glRotatef(this->getAbsDir2D(), 0, 0, 1);
+
+  const Font::Glyph* tmpGlyph;
+  float posX = 0.0f;
+  float posY = 0.0f;
+  unsigned int lineNumber = 0;
+
+  glBegin(GL_QUADS);
+  for (unsigned int i = 0; i < this->text().size(); ++i)
+  {
+    if (unlikely(this->lineEnds.size() > lineNumber && i == this->lineEnds[lineNumber]))
+    {
+      // go to the next Line.
+      ++lineNumber;
+      posX = 0.0f;
+      posY += this->lineSpacing + this->size(); //this->font().getMaxHeight();
+    }
+
+    if(likely((tmpGlyph = this->font().getGlyphArray()[this->text()[i]]) != NULL))
+    {
+      glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[2]);
+      glVertex2d(posX+tmpGlyph->maxX*this->size(), posY);
+
+      glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[3]);
+      glVertex2d(posX+tmpGlyph->maxX*this->size(), posY + this->size());
+
+      glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[3]);
+      glVertex2d(posX+tmpGlyph->minX*this->size(), posY+ this->size());
+
+      glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[2]);
+      glVertex2d(posX+tmpGlyph->minX*this->size(), posY);
+
+      posX += tmpGlyph->advance * this->size();
+    }
+  }
+  glEnd();
+  glPopAttrib();
+  glPopMatrix();
+}
+
+
+/**
+ * @brief setting up the Text-Width if DYNAMIC
+ */
+void MultiLineText::setupTextWidth()
+{
+  this->lineEnds.clear();
+  float width = 0.0f;
+  float maxWidth = this->lineWidth / this->size();
+
+  for (unsigned int i = 0; i < this->text().size(); i++)
+  {
+    if (width > maxWidth || this->text()[i] == '\n')
+    {
+      if (likely(i > 0))
+      {
+        this->lineEnds.push_back( i -1 );
+        width = this->font().getGlyphArray()[this->text()[i-1]]->advance;
+      }
+      else
+        width = 0.0f;
+    }
+
+    // Advance the Text.
+    if(this->font().getGlyphArray()[this->text()[i]] != NULL)
+      width += this->font().getGlyphArray()[this->text()[i]]->advance;
+  }
+  this->lineCount = lineEnds.size() + 1;
+  this->setSizeY2D((this->lineEnds.size()+1) * (this->lineSpacing + this->font().getMaxHeight()));
+}
+
+/**
+ * @brief print out some nice debug output
+ */
+void MultiLineText::debug() const
+{
+ printf("Debug %s::%s: %d lines\n", this->getClassCName(), this->getCName(), this->getLineCount());
+
+ std::string tmpText = this->text();
+ std::vector<unsigned int> ends = this->lineEnds;
+ ends.push_back(tmpText.size());
+
+ unsigned int prev = 0;
+  for (unsigned int i = 0; i < ends.size(); i++)
+  {
+    printf("Line %d: %s\n", i, tmpText.substr(prev, ends[i] - prev).c_str());
+    prev = ends[i];
+  }
+}
Index: branches/heathaze/src/lib/graphics/text_engine/multi_line_text.h
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/multi_line_text.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/multi_line_text.h	(revision 9940)
@@ -0,0 +1,45 @@
+/*!
+ * @file multi_line_text.h
+ * @brief Definition of a text Class, that is able to render text.
+ */
+
+#ifndef _MULTI_LINE_TEXT_H
+#define _MULTI_LINE_TEXT_H
+
+#include "text.h"
+
+#include <vector>
+
+//! Represents one textElement.
+class MultiLineText : public Text
+{
+  ObjectListDeclaration(MultiLineText);
+  public:
+    MultiLineText(const std::string& fontFile = "", unsigned int fontSize = TEXT_DEFAULT_SIZE, float lineWidth = 100.0);
+
+    // Setup:
+    void setLineWidth(float lineWidth);
+    void setLineSpacing(float lineSpacing);
+
+    // Retrieve:
+    /** @returns the LineWidth (maximum distance from the left to the right */
+    inline float getLineWidth() const { return this->lineWidth; };
+    /** @returns the LineSpacing */
+    inline float getLineSpacing() const { return this->lineSpacing; };
+    inline unsigned int getLineCount() const { return this->lineCount; };
+
+    virtual void draw() const;
+
+    void debug() const;
+
+  protected:
+    virtual void setupTextWidth();
+
+  private:
+    float                      lineWidth;
+    float                      lineSpacing;
+    std::vector<unsigned int>  lineEnds;
+    unsigned int               lineCount;
+};
+
+#endif /* _MULTI_LINE_TEXT_H */
Index: branches/heathaze/src/lib/graphics/text_engine/resource_font.cc
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/resource_font.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/resource_font.cc	(revision 9940)
@@ -0,0 +1,54 @@
+
+#include "resource_font.h"
+#include "substring.h"
+#include "multi_type.h"
+#include "debug.h"
+
+
+ResourceFont::ResourceFont(const std::string& fontName, unsigned int renderSize, const Resources::KeepLevel& keepLevel)
+  : Font(), Resource(&ResourceFont::type)
+{
+  assert(!fontName.empty());
+  Resources::StorePointer* ptr = this->acquireResource(fontName + ',' + MultiType((int)renderSize).getString());
+
+  if (ptr)
+  {
+    PRINTF(5)("FOUND FONT: %s\n", fontName.c_str());
+    this->Font::acquireData(static_cast<ResourceFont::FontResourcePointer*>(ptr)->ptr());
+  }
+  else
+  {
+    PRINTF(5)("NOT FOUND FONT: %s\n", fontName.c_str());
+    std::string fileName = this->Resource::locateFile(fontName);
+
+    this->Font::loadFontFromTTF(fileName, renderSize);
+    this->Resource::addResource(new ResourceFont::FontResourcePointer(fontName + ',' + MultiType((int)renderSize).getString(), keepLevel, this->Font::dataPointer()));
+  }
+}
+
+ResourceFont ResourceFont::createFromString(const std::string& loadString, const Resources::KeepLevel& keepLevel)
+{
+  SubString loadValues(loadString, ',');
+  std::string fontName;
+  unsigned int renderSize = 20;
+  if (loadValues.size() > 0)
+    fontName = loadValues[0];
+  if (loadValues.size() > 1)
+    renderSize = (unsigned int)MultiType(loadValues[2]).getInt();
+
+  return ResourceFont(fontName, renderSize, keepLevel);
+}
+
+
+
+Resources::tType<ResourceFont> ResourceFont::type("Font");
+
+
+
+
+
+ResourceFont::FontResourcePointer::FontResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const FontData::Pointer& data)
+    : Resources::StorePointer(loadString, keepLevel) , pointer(data)
+{}
+
+
Index: branches/heathaze/src/lib/graphics/text_engine/resource_font.h
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/resource_font.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/resource_font.h	(revision 9940)
@@ -0,0 +1,36 @@
+/*!
+ * @file resource_font.h
+ * @brief Contains the ResourceFont class, that handles the Resource-specific loading part of the Font.
+ *
+ */
+
+#ifndef _RESOURCE_FONT_H
+#define _RESOURCE_FONT_H
+
+#include "util/loading/resource.h"
+#include "font.h"
+
+
+class ResourceFont : public Font, public Resources::Resource
+{
+public:
+  ResourceFont(const std::string& fontName, unsigned int renderSize, const Resources::KeepLevel& keepLevel = Resources::KeepLevel());
+  static ResourceFont createFromString(const std::string& loadString, const Resources::KeepLevel& keepLevel = Resources::KeepLevel());
+
+private:
+class FontResourcePointer : public Resources::StorePointer
+  {
+  public:
+    FontResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const FontData::Pointer& data);
+    inline const FontData::Pointer& ptr() const { return pointer; }
+    virtual bool last() const { return pointer.count() == 1; }
+  private:
+    FontData::Pointer pointer;
+  };
+
+private:
+  static Resources::tType<ResourceFont> type;
+};
+
+
+#endif /* _RESOURCE_FONT_H */
Index: branches/heathaze/src/lib/graphics/text_engine/text.cc
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/text.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/text.cc	(revision 9940)
@@ -0,0 +1,271 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "text.h"
+#include "resource_font.h"
+#include "font.h"
+#include "debug.h"
+
+ObjectListDefinition(Text);
+
+/**
+ * @brief creates a new Text Element
+ * @param fontFile the Font to render this text in
+ * @param type The renderType to display this font in
+ */
+Text::Text(const std::string& fontFile, unsigned int textSize)
+// : _font(fontFile, FONT_DEFAULT_RENDER_SIZE)
+{
+  this->registerObject(this, Text::_objectList);
+
+  // initialize this Text
+  if (!fontFile.empty())
+    this->setFont(fontFile, FONT_DEFAULT_RENDER_SIZE);
+  else
+    this->setFont("fonts/final_frontier.ttf", FONT_DEFAULT_RENDER_SIZE);
+  this->_size = textSize;
+  this->setSizeY2D(textSize);
+  this->setColor(TEXT_DEFAULT_COLOR);
+
+  this->setAlignment(TEXT_DEFAULT_ALIGNMENT);
+}
+
+Text::Text(const Text& text)
+    : _font()
+{
+  this->registerObject(this, Text::_objectList);
+
+  *this = text;
+}
+
+
+/**
+ * @brief deletes a Text out of memory
+ */
+Text::~Text()
+{
+  /*  if (this->_font != NULL && this->_font != Font::getDefaultFont())
+      ResourceManager::getInstance()->unload(this->_font);*/
+}
+
+/**
+ * @brief compare the Text with another Text.
+ * @param text the Text to compare.
+ * @returns true if all the properties Match.
+ */
+bool Text::operator==(const Text& text) const
+{
+  return (this->_text == text._text &&
+          this->_size == text._size &&
+          this->_font == text._font );
+}
+
+/**
+ * @brief compare this Text's internal String with the text.
+ * @param text the Comparator Text.
+ * @returns true on a match.
+ */
+bool Text::operator==(const std::string& text) const
+{
+  return (this->_text == text);
+}
+
+/**
+ * @brief Copies the properties of one text onto the other one.
+ * @param text: the Text to apply to this one.
+ * @returns This-reference.
+ */
+Text& Text::operator=(const Text& text)
+{
+  this->_size = text._size;
+  this->setAlignment(text.getAlignment());
+
+  this->_font = text._font;
+
+  this->_text = text._text;
+  return *this;
+}
+
+/**
+ * @brief Sets a new Text to the font
+ * @param text the new text to set
+ */
+void Text::setText(const std::string& text)
+{
+  this->_text = text;
+  this->setupTextWidth();
+}
+
+/**
+ * @brief append some text to the already existing Text.
+ * @param appendText The text to append to this Text.
+ */
+void Text::append(const std::string& appendText)
+{
+  this->_text += appendText;
+  this->setupTextWidth();
+}
+
+/**
+ * @brief appends one Character to the String.
+ */
+void Text::appendCharacter(char character)
+{
+  this->_text += character;
+  this->setupTextWidth();
+}
+
+
+/**
+ * @brief append some text to the already existing Text.
+ * @param appendText The text to append to this Text.
+ */
+const std::string& Text::operator <<(const std::string& appendText)
+{
+  this->append(appendText);
+  return this->_text;
+}
+
+/**
+ * @brief removes char characters from the Text.
+ *
+ * @note this function checks, if the count can be removed, and if so does it.
+ * Otherwise the maximum count of characters will be removed.
+ */
+void Text::removeCharacters(unsigned int chars)
+{
+  if (this->_text.size() > chars)
+    this->_text.resize(this->_text.size()-chars);
+  else if (!this->_text.empty())
+    this->_text.clear();
+  this->setupTextWidth();
+}
+
+
+/**
+ * @brief clears the Text Line (empies it).
+ */
+void Text::clear()
+{
+  this->_text.clear();
+  this->setupTextWidth();
+}
+
+/**
+ * @brief sets the Font of this Text to font from fontFile
+ * @param fontFile the File to load the Font from.
+ * @param fontSize the Size of the Font
+ */
+void Text::setFont(const std::string& fontFile, unsigned int fontSize)
+{
+  this->_font = ResourceFont(fontFile, fontSize);
+
+  this->setupTextWidth();
+}
+
+/**
+ * @brief set a new Font to this Text.
+ * @param font the Font to set.
+ */
+void Text::setFont(const Font& font)
+{
+  this->_font = font;
+  this->setupTextWidth();
+}
+
+/**
+ * @brief sets the Size of the Font
+ * @param size :the size of the Text
+ */
+void Text::setSize(float size)
+{
+  this->_size = size;
+  this->setSizeY2D(size);
+  this->setupTextWidth();
+}
+
+
+/**
+ * @brief draws the Text
+ */
+void Text::draw() const
+{
+  if (unlikely(this->_text.empty()))
+    return;
+  glPushMatrix();
+  glPushAttrib(GL_ENABLE_BIT);
+  // transform for alignment.
+  if (this->getAlignment() == TEXT_ALIGN_RIGHT)
+    glTranslatef(-this->getSizeX2D(), 0, 0);
+  else if (this->getAlignment() == TEXT_ALIGN_CENTER || this->getAlignment() == TEXT_ALIGN_SCREEN_CENTER)
+    glTranslatef(-this->getSizeX2D()/2, 0, 0);
+
+
+  this->font().select();
+  glTranslatef(getAbsCoor2D().x, getAbsCoor2D().y, 0);
+  glRotatef(this->getAbsDir2D(), 0, 0, 1);
+
+  const Font::Glyph* tmpGlyph;
+  float posX = 0.0f;
+  glBegin(GL_QUADS);
+  for (unsigned int i = 0; i < this->_text.size(); i++)
+  {
+    if(likely((tmpGlyph = this->font().getGlyphArray()[this->_text[i]]) != NULL))
+    {
+      glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[2]);
+      glVertex2d(posX+tmpGlyph->maxX*this->size(), 0);
+
+      glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[3]);
+      glVertex2d(posX+tmpGlyph->maxX*this->size(), this->size());
+
+      glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[3]);
+      glVertex2d(posX+tmpGlyph->minX*this->size(), this->size());
+
+      glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[2]);
+      glVertex2d(posX+tmpGlyph->minX*this->size(), 0);
+
+      posX += tmpGlyph->advance * this->size();
+    }
+  }
+  glEnd();
+  glPopAttrib();
+  glPopMatrix();
+}
+
+
+/**
+ * @brief setting up the Text-Width.
+ */
+void Text::setupTextWidth()
+{
+  float width = 0;
+  for (unsigned int i = 0; i < this->_text.size(); i++)
+    if(this->_font.getGlyphArray()[this->_text[i]] != NULL)
+      width += this->_font.getGlyphArray()[this->_text[i]]->advance;
+  this->setSizeX2D(width * this->size());
+}
+
+
+/**
+ * @brief prints out some nice debug information about this text
+ */
+void Text::debug() const
+{
+  PRINT(0)("=== TEXT: %s (with Font:'%s')  displaying %s ===\n", this->getCName(), this->_font.getCName(), this->_text.c_str());
+  //  PRINT(0)("Color: r=%0.2f g=%0.2f b=%0.2f a=%0.2f\n", this->_color.r(), this->_color.g(), this->_color.b(), this->_color.a());
+}
+
Index: branches/heathaze/src/lib/graphics/text_engine/text.h
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/text.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/text.h	(revision 9940)
@@ -0,0 +1,86 @@
+/*!
+ * @file text.h
+ * @brief Definition of a text Class, that is able to render text.
+ */
+
+#ifndef _TEXT_H
+#define _TEXT_H
+
+#include "element_2d.h"
+#include "color.h"
+#include "font.h"
+
+#define  TEXT_ALIGN_LEFT             E2D_ALIGN_LEFT
+#define  TEXT_ALIGN_RIGHT            E2D_ALIGN_RIGHT
+#define  TEXT_ALIGN_CENTER           E2D_ALIGN_CENTER
+#define  TEXT_ALIGN_SCREEN_CENTER    E2D_ALIGN_SCREEN_CENTER
+#define  TEXT_DEFAULT_COLOR          Color(1.0, 1.0, 1.0, 1.0f) //!< the default Color (white, fully visible)
+
+#define  TEXT_DEFAULT_ALIGNMENT      TEXT_ALIGN_LEFT            //!< default alignment
+#define  TEXT_DEFAULT_SIZE           20                         //!< default size of the Text
+
+// FORWARD DECLARATION
+struct SDL_Surface;
+
+//! Represents one textElement.
+class Text : public Element2D
+{
+  ObjectListDeclaration(Text);
+  public:
+    Text(const std::string& fontFile = "", unsigned int fontSize = TEXT_DEFAULT_SIZE);
+    Text(const Text& text);
+    virtual ~Text();
+    bool operator==(const Text& text) const;
+    bool operator==(const std::string& text) const;
+    Text& operator=(const Text& text);
+
+    /// Final Interfacing.
+    void setText(const std::string& text);
+    void append(const std::string& appendText);
+    void appendCharacter(char character);
+    const std::string& operator<<(const std::string& appendText);
+    void removeCharacters(unsigned int chars);
+    void clear();
+
+    /// SETUP
+    void setFont(const std::string& fontFile, unsigned int renderSize);
+    void setFont(const Font& font);
+    /** @param blending the blending intensity to set (between 0.0 and 1.0) */
+    inline void setBlending(float blending) { this->_font.setTransparency(blending); };
+    /** @param r red @param g green @param b blue @brief sets the Color of the Text to render (values in [0-1]) */
+    void setColor(float r, float g, float b) { this->_font.setDiffuseColor(Color(r, g, b, this->blending())); };
+    void setColor(float r, float g, float b, float a) { this->_font.setDiffuseColor(Color(r, g, b, a)); };
+    void setColor(const Color& color) { this->_font.setDiffuseColor(color); };
+    void setSize(float size);
+
+
+    /// RETRIEVE
+    /** @returns the String this Text displays */
+    inline const std::string& text() const { return this->_text; };
+
+    /** @returns the pointer to the stored Font (not changeable) */
+    inline const Font& font() const { return this->_font; };
+    /** @returns the Blending Value [0 invisible 1.0 full visible */
+    inline float blending() const { return this->_font.diffuseColor().a(); };
+    /** @returns: a Vector(r,g,b) @brief: retrieve a Vector holding the Color of the Text */
+    inline const Color& color() const { return this->_font.diffuseColor(); };
+    /** @returns the Size of the Text */
+    inline float size() const { return this->_size; };
+
+    virtual void draw() const;
+
+    void debug() const;
+
+  protected:
+    virtual void setupTextWidth();
+  private:
+    void init();
+
+  private:
+    Font              _font;           //!< Font of this text
+
+    std::string       _text;           //!< The text to display
+    float             _size;           //!< The size of the Text.
+};
+
+#endif /* _TEXT_H */
Index: branches/heathaze/src/lib/graphics/text_engine/text_engine.cc
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/text_engine.cc	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/text_engine.cc	(revision 9940)
@@ -0,0 +1,165 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   for some fonts and licenses visit: =http://www.dafont.com/en/font.php=
+
+   !! IMPORTANT !! When using ttf fonts clear the license issues prior to
+   adding them to orxonox. This is really important, because we do not
+   want to offend anyone.
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "text_engine.h"
+#include "text.h"
+#include "font.h"
+
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "graphics_engine.h"
+
+#include "debug.h"
+///////////////////
+/// TEXT-ENGINE ///
+///////////////////
+ObjectListDefinition(TextEngine);
+/**
+ *  standard constructor
+*/
+TextEngine::TextEngine ()
+{
+  this->registerObject(this, TextEngine::_objectList);
+  this->setName("TextEngine");
+  this->enableFonts();
+}
+
+/**
+ *  the singleton reference to this class
+*/
+TextEngine* TextEngine::singletonRef = NULL;
+
+/**
+ *  standard deconstructor
+
+*/
+TextEngine::~TextEngine ()
+{
+  // first remove all the remaining Texts (if any).
+  while (!Text::objectList().empty())
+    delete Text::objectList().front();
+  // delete all remaining fonts (There should not be Anything to do here)
+
+  //const std::list<BaseObject*>* fontList = ClassList::getList(CL_FONT);
+  //if (fontList != NULL)
+  {
+    ///FIXME
+    //    while (fontList->size() > 0)
+    {
+      //      Font* font = dynamic_cast<Font*>(fontList->back());
+      //if (likely(font != Font::getDefaultFont()))
+      //        ResourceManager::getInstance()->unload(font, RP_GAME);
+    }
+  }
+  this->disableFonts();
+
+  TextEngine::singletonRef = NULL;
+}
+
+/**
+ *  function to enable TTF_Fonts
+*/
+void TextEngine::enableFonts()
+{
+  if (!TTF_WasInit())
+  {
+    if(TTF_Init()==-1)
+      PRINTF(1)("TTF_Init: %s\n", TTF_GetError());
+
+    TextEngine::checkVersion();
+  }
+  else
+    PRINTF(4)("Fonts already initialized\n");
+}
+
+/**
+ *  function to disable TTF_fonts
+ */
+void TextEngine::disableFonts()
+{
+  if (TTF_WasInit())
+  {
+    //      Font::removeDefaultFont();
+    TTF_Quit();
+  }
+  else
+    PRINTF(4)("Fonts were not initialized.\n");
+}
+
+/**
+ *  outputs some nice Debug information
+ *
+ * @todo there should also be something outputted about Font
+ */
+void TextEngine::debug() const
+{
+  PRINT(0)("+-------------------------------+\n");
+  PRINT(0)("+ TEXT ENGINE DEBUG INFORMATION +\n");
+  PRINT(0)("+-------------------------------+\n");
+  PRINT(0)("Reference: %p; Text Counts: %d\n", this, Text::objectList().size());
+
+  for (ObjectList<Text>::const_iterator it = Text::objectList().begin();
+       it != Text::objectList().end();
+       ++it)
+  {
+      (*it)->debug();
+    PRINT(0)("+---------------------------TE--+\n");
+  }
+}
+
+
+/**
+ *  checks if the compiled version and the local version of SDL_ttf match.
+ * @returns true if match, false otherwise
+*/
+bool TextEngine::checkVersion()
+{
+  SDL_version compile_version;
+  SDL_version link_version;
+  TTF_VERSION(&compile_version);
+  link_version = *TTF_Linked_Version();
+
+  if (compile_version.major == link_version.major &&
+      compile_version.minor == link_version.minor &&
+      compile_version.patch == link_version.patch)
+  {
+    return true;
+  }
+  else
+  {
+    PRINTF(2)("compiled with SDL_ttf version: %d.%d.%d\n",
+              compile_version.major,
+              compile_version.minor,
+              compile_version.patch);
+
+    PRINTF(2)("running with SDL_ttf version: %d.%d.%d\n",
+              link_version.major,
+              link_version.minor,
+              link_version.patch);
+    return false;
+  }
+}
Index: branches/heathaze/src/lib/graphics/text_engine/text_engine.h
===================================================================
--- branches/heathaze/src/lib/graphics/text_engine/text_engine.h	(revision 9940)
+++ branches/heathaze/src/lib/graphics/text_engine/text_engine.h	(revision 9940)
@@ -0,0 +1,44 @@
+/*!
+ * @file text_engine.h
+ *  Definition of textEngine, the Font and the Text
+ *
+ * Text is the text outputed.
+ * Font is a class that loads a certain ttf-file with a specific height into memory
+ * TextEngine is used to manage the all the different Fonts that might be included
+ *
+ *   for more information see the specific classes.
+ *
+ *  !! IMPORTANT !! When using ttf fonts clear the license issues prior to
+ * adding them to orxonox. This is really important, because we do not want
+ * to offend anyone.
+ */
+
+#ifndef _TEXT_ENGINE_H
+#define _TEXT_ENGINE_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+//! A singleton Class that operates as a Handler initializing FONTS.
+class TextEngine : public BaseObject
+{
+  ObjectListDeclaration(TextEngine);
+  public:
+  virtual ~TextEngine();
+  /** @returns a Pointer to the only object of this Class */
+  inline static TextEngine* getInstance() { if (!singletonRef) singletonRef = new TextEngine();  return singletonRef; };
+
+  void debug() const;
+
+ private:
+  TextEngine();
+  static TextEngine* singletonRef;
+
+  // general
+  static void enableFonts();
+  static void disableFonts();
+  static bool checkVersion();
+};
+
+#endif /* _TEXT_ENGINE_H */
Index: branches/heathaze/src/lib/gui/Makefile.am
===================================================================
--- branches/heathaze/src/lib/gui/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/gui/Makefile.am	(revision 9940)
@@ -0,0 +1,28 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+AM_LDFLAGS =
+
+noinst_LIBRARIES = libORXbasegui.a
+
+
+libORXbasegui_a_SOURCES = \
+		gui_element.cc \
+		gui_saveable.cc \
+		gui.cc
+
+
+noinst_HEADERS= \
+		gui_element.h \
+		gui_saveable.h \
+		gui.h
+
+
+EXTRA_DIST =
+
+SUBDIRS = \
+	. \
+	gl \
+	qt
+
+#	gtk_gui
Index: branches/heathaze/src/lib/gui/gl/Makefile.am
===================================================================
--- branches/heathaze/src/lib/gui/gl/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/Makefile.am	(revision 9940)
@@ -0,0 +1,64 @@
+MAINSRCDIR=../../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+AM_LDFLAGS =
+
+noinst_LIBRARIES = libORXglgui.a
+
+libORXglgui_a_CPPFLAGS = -DBUILD_ORXONOX
+
+
+libORXglgui_a_SOURCES = \
+		glmenu/glmenu_imagescreen.cc \
+		\
+		glgui_handler.cc \
+		glgui_widget.cc \
+		glgui_mainwidget.cc \
+		glgui_button.cc \
+		glgui_pushbutton.cc \
+		glgui_checkbutton.cc \
+		glgui_slider.cc \
+		glgui_container.cc \
+		glgui_bar.cc \
+		glgui_box.cc \
+		glgui_fixedposition_box.cc \
+		glgui_frame.cc \
+		glgui_text.cc \
+		glgui_inputline.cc \
+		glgui_textfield.cc \
+		glgui_table.cc \
+		glgui_image.cc \
+		glgui_window.cc \
+		glgui_cursor.cc \
+		\
+		specials/glgui_notifier.cc
+
+
+noinst_HEADERS= \
+		glmenu/glmenu_imagescreen.h \
+		\
+		glgui.h \
+		glgui_defs.h \
+		glgui_handler.h \
+		glgui_widget.h \
+		glgui_mainwidget.h \
+		glgui_button.h \
+		glgui_pushbutton.h \
+		glgui_checkbutton.h \
+		glgui_slider.h \
+		glgui_container.h \
+		glgui_bar.h \
+		glgui_box.h \
+		glgui_fixedposition_box.h \
+		glgui_frame.h \
+		glgui_text.h \
+		glgui_inputline.h \
+		glgui_textfield.h \
+		glgui_table.h \
+		glgui_image.h \
+		glgui_window.h \
+		glgui_cursor.h \
+		\
+		specials/glgui_notifier.h
+
+EXTRA_DIST =
Index: branches/heathaze/src/lib/gui/gl/glgui.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui.h	(revision 9940)
@@ -0,0 +1,29 @@
+/*!
+ * @file glgui.h
+ * includes all the Files the GLGui knows.
+ */
+
+#ifndef _GLGUI_H
+#define _GLGUI_H
+
+#include "glgui_defs.h"
+#include "glgui_handler.h"
+
+#include "glgui_widget.h"
+
+#include "glgui_bar.h"
+#include "glgui_box.h"
+#include "glgui_fixedposition_box.h"
+#include "glgui_button.h"
+#include "glgui_checkbutton.h"
+#include "glgui_pushbutton.h"
+#include "glgui_slider.h"
+#include "glgui_cursor.h"
+#include "glgui_text.h"
+#include "glgui_inputline.h"
+#include "glgui_textfield.h"
+#include "glgui_table.h"
+#include "glgui_image.h"
+
+
+#endif /* _GLGUI_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_bar.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_bar.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_bar.cc	(revision 9940)
@@ -0,0 +1,120 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_bar.h"
+
+#include "debug.h"
+
+namespace OrxGui
+{
+
+  ObjectListDefinition(GLGuiBar);
+  /**
+   * @brief standard constructor
+  */
+  GLGuiBar::GLGuiBar ()
+  {
+    this->init();
+
+  }
+
+
+  /**
+   * @brief standard deconstructor
+   */
+  GLGuiBar::~GLGuiBar()
+  {}
+
+  /**
+   * @brief initializes the GUI-element
+   */
+  void GLGuiBar::init()
+  {
+    this->registerObject(this, GLGuiBar::_objectList);
+
+    this->setFrontColor(_changedValueColor, true);
+
+    this->setSize2D(50, 10);
+
+    this->_minimum = 0.0f;
+    this->_maximum = 1.0f;
+    this->setValue(0.5f);
+    this->resize();
+  }
+
+  void GLGuiBar::setValue(float value)
+  {
+    if (value > _maximum)
+    {
+      value = _maximum;
+      PRINTF(2)("Oversteped range, set Value to %f\n", _maximum);
+    }
+    if (value < _minimum)
+    {
+      value = _minimum;
+      PRINTF(2)("Oversteped range, set Value to %f\n", _minimum);
+    }
+
+    this->_value = value;
+    this->_frontRect.setSize((this->getSizeX2D() - borderLeft() - borderRight()) * (_value -_minimum)/ (_minimum + _maximum)
+        ,this->getSizeY2D() - borderTop() - borderBottom());
+  }
+  void GLGuiBar::setMinimum(float minimum)
+  {
+    this->_minimum = minimum;
+  }
+  void GLGuiBar::setMaximum(float maximum)
+  {
+    this->_maximum = maximum;
+  }
+  void GLGuiBar::setRange(float minimum, float maximum)
+  {
+    this->setMinimum(minimum);
+    this->setMaximum(maximum);
+  }
+
+  void GLGuiBar::setChangedValueColor(const Color& color)
+  {
+    this->_changedValueColor = color;
+  }
+
+
+  void GLGuiBar::resize()
+  {
+    GLGuiWidget::resize();
+
+    this->_frontRect.setTopLeft(borderLeft(), borderTop());
+    this->_frontRect.setSize((this->getSizeX2D() - borderLeft() - borderRight()) * (_value -_minimum)/ (_minimum + _maximum)
+                             ,this->getSizeY2D() - borderTop() - borderBottom());
+
+  }
+
+
+  /**
+   * @brief draws the GLGuiBar
+   */
+  void GLGuiBar::draw() const
+  {
+    this->beginDraw();
+    GLGuiWidget::draw();
+
+    this->foreground().select();
+    this->drawRect(this->_frontRect);
+
+    this->endDraw();
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_bar.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_bar.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_bar.h	(revision 9940)
@@ -0,0 +1,59 @@
+/*!
+ * @file glgui_bar.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_BAR_H
+#define _GLGUI_BAR_H
+
+#include "glgui_widget.h"
+
+
+namespace OrxGui
+{
+
+
+  //! This is Bar part of the openglGUI class
+  /**
+   * The Bar shows the part value.
+   */
+  class GLGuiBar : public GLGuiWidget
+  {
+    ObjectListDeclaration(GLGuiBar);
+  public:
+    GLGuiBar();
+    virtual ~GLGuiBar();
+
+    void setValue(float value);
+    void setMinimum(float minimum);
+    void setMaximum(float maximum);
+    void setRange(float minimum, float maximum);
+
+    void setChangedValueColor(const Color& color);
+
+    float value() const { return this->_value; };
+    float minimum() const { return this->_minimum; };
+    float maximum() const { return this->_maximum; };
+
+    virtual void update() { };
+    virtual void draw() const;
+
+  protected:
+    virtual void resize();
+
+  private:
+    void init();
+
+  private:
+    float         _value;
+
+    Rect2D        _frontRect;
+
+    float         _minimum;
+    float         _maximum;
+
+    Color         _changedValueColor;
+  };
+}
+#endif /* _GLGUI__H */
Index: branches/heathaze/src/lib/gui/gl/glgui_box.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_box.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_box.cc	(revision 9940)
@@ -0,0 +1,233 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_box.h"
+#include <cassert>
+#include "debug.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiBox);
+  /**
+   * standard constructor
+  */
+  GLGuiBox::GLGuiBox (OrxGui::Orientation orientation)
+  {
+    this->init();
+
+    this->setOrientation(orientation);
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGuiBox::~GLGuiBox()
+  {
+    // unpack all the widgets.
+    while(!this->_children.empty())
+    {
+      /// not deleting children here.
+      this->_children.front()->setParentWidget(NULL);
+      this->_children.pop_front();
+    }
+  }
+
+  /**
+   * initializes the GUI-element
+   */
+  void GLGuiBox::init()
+  {
+    this->registerObject(this, GLGuiBox::_objectList);
+  }
+
+  void GLGuiBox::pack(GLGuiWidget* widget)
+  {
+    assert (widget != NULL);
+    this->_children.push_back(widget);
+
+    this->packing(widget);
+  }
+
+
+  void GLGuiBox::pack(GLGuiWidget* widget, std::list<GLGuiWidget*>::iterator pos)
+  {
+    this->_children.insert(pos, widget);
+    this->packing(widget);
+  }
+
+  void GLGuiBox::pack(GLGuiWidget* widget, unsigned int position)
+  {
+    if (this->_children.empty())
+      this->pack(widget);
+
+    unsigned int pos = 0;
+    std::list<GLGuiWidget*>::iterator it = this->_children.begin();
+
+    for (; pos < position; ++pos)
+    {
+      if (this->_children.end() == ++it)
+      {
+        PRINTF(2)("Reached end of packing list, without getting to the designated position %d (i am at %d)\n", position, pos);
+        this->pack(widget);
+      }
+    }
+    this->_children.insert(it, widget);
+    this->packing(widget);
+  }
+
+  void GLGuiBox::pack(GLGuiWidget* widget, const GLGuiWidget* widgetPointer)
+  {
+    assert (widget != NULL && widgetPointer != NULL);
+
+    std::list<GLGuiWidget*>::iterator it = this->_children.begin();
+    for (; it != this->_children.end(); ++it)
+    {
+      if (widgetPointer == *it)
+      {
+        this->_children.insert(it, widget);
+        this->packing(widget);
+        return;
+      }
+    }
+    PRINTF(2)("WidgetPointer %p not found, inserting at the end\n", widgetPointer);
+    this->pack(widget);
+  }
+
+  void GLGuiBox::packFront(GLGuiWidget* widget)
+  {
+    this->_children.push_front(widget);
+    this->packing(widget);
+  }
+
+  void GLGuiBox::packBack(GLGuiWidget* widget)
+  {
+    this->pack(widget);
+  }
+
+  void GLGuiBox::packing(GLGuiWidget* widget)
+  {
+    widget->setParentWidget(this);
+    this->resize();
+  }
+
+  void GLGuiBox::unpack(GLGuiWidget* widget)
+  {
+    assert(widget != NULL);
+
+    std::list<GLGuiWidget*>::iterator delWidget = std::find(this->_children.begin(), this->_children.end(), widget);
+    if (delWidget != this->_children.end())
+    {
+      (*delWidget)->setParentWidget(NULL);
+      this->_children.erase(delWidget);
+    }
+    this->resize();
+  }
+
+  void GLGuiBox::clear()
+  {
+    this->_children.clear();
+    this->resize();
+  }
+
+  void GLGuiBox::showAll()
+  {
+    std::list<GLGuiWidget*>::iterator itC = this->_children.begin();
+    while (itC != this->_children.end())
+    {
+      if ((*itC)->isA(GLGuiContainer::staticClassID()))
+        static_cast<GLGuiContainer*>(*itC)->showAll();
+      else
+        (*itC)->show();
+      itC++;
+    }
+
+    this->show();
+  }
+
+  void GLGuiBox::hideAll()
+  {
+    std::list<GLGuiWidget*>::iterator itC = this->_children.begin();
+    while (itC != this->_children.end())
+    {
+      if ((*itC)->isA(GLGuiContainer::staticClassID()))
+        static_cast<GLGuiContainer*>(*itC)->hideAll();
+      else
+        (*itC)->hide();
+      itC++;
+    }
+
+    this->hide();
+  }
+
+  void GLGuiBox::resize()
+  {
+    if (orientation() == OrxGui::Vertical)
+    {
+      float height = borderTop();
+      float width = 0.0f;
+      std::list<GLGuiWidget*>::iterator widget;
+
+      // find out how big the Widgets are.
+      for (widget = this->_children.begin(); widget != this->_children.end(); ++widget)
+      {
+        (*widget)->setRelCoor2D(borderLeft(), height);
+        height += (*widget)->getSizeY2D();
+        width = fmax(width, (*widget)->getSizeX2D());
+      }
+
+      width += borderLeft() + borderRight();
+      height += borderBottom(); /* *2 done further up */
+
+      this->setSize2D(width, height);
+    }
+    else
+    {
+      float height = borderTop();
+      float width = borderLeft();
+      std::list<GLGuiWidget*>::iterator widget;
+
+      // find out how big the Widgets are.
+      for (widget = this->_children.begin(); widget != this->_children.end(); ++widget)
+      {
+        (*widget)->setRelCoor2D(width, borderTop());
+        height = fmax(height, (*widget)->getSizeY2D());
+        width += (*widget)->getSizeX2D();
+      }
+
+      width += borderRight() ;
+      height += borderBottom(); /* *2 done further up */
+
+      this->setSize2D(width, height);
+    }
+    GLGuiWidget::resize();
+
+    // resize everything.
+    //for (widget = this->_children.begin(); widget != this->_children.end(); ++widget)
+    //{}
+  }
+
+  /**
+   * @brief draws the GLGuiBox
+   */
+  void GLGuiBox::draw() const
+  {
+    this->beginDraw();
+    GLGuiWidget::draw();
+    this->endDraw();
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_box.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_box.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_box.h	(revision 9940)
@@ -0,0 +1,60 @@
+/*!
+ * @file glgui_box.h
+ * The gl_box widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_BOX_H
+#define _GLGUI_BOX_H
+
+#include "glgui_container.h"
+#include "glgui_defs.h"
+
+namespace OrxGui
+{
+  //! This is BOX part of the openglGUI class
+  /**
+   *
+   */
+  class GLGuiBox : public GLGuiContainer
+  {
+    ObjectListDeclaration(GLGuiBox);
+  public:
+    GLGuiBox(OrxGui::Orientation orientation = OrxGui::Vertical);
+    virtual ~GLGuiBox();
+
+    /** @returns the Orientation of the Box */
+    OrxGui::Orientation orientation() const { return this->_orientation; };
+    /** @param orientation the Orientation of the Box */
+    void setOrientation(OrxGui::Orientation orientation) { this->_orientation = orientation; };
+
+    virtual void pack(GLGuiWidget* widget);
+    void pack(GLGuiWidget* widget, unsigned int position);
+    void pack(GLGuiWidget* widget, const GLGuiWidget* widgetPointer);
+    void packFront(GLGuiWidget* widget);
+    void packBack(GLGuiWidget* widget);
+    virtual void unpack(GLGuiWidget* widget);
+
+    virtual void clear();
+
+    virtual void showAll();
+    virtual void hideAll();
+
+    virtual void draw() const;
+
+  protected:
+    virtual void resize();
+
+  private:
+    void init();
+    void packing(GLGuiWidget* widget); // the action executing when packing a widget.
+    void pack(GLGuiWidget* widget, std::list<GLGuiWidget*>::iterator pos);
+
+  private:
+
+
+    Orientation                _orientation;
+    std::list<GLGuiWidget*>    _children;
+  };
+}
+#endif /* _GLGUI__H */
Index: branches/heathaze/src/lib/gui/gl/glgui_button.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_button.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_button.cc	(revision 9940)
@@ -0,0 +1,122 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_button.h"
+
+#include "text.h"
+
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiButton);
+  /**
+   * standard constructor
+  */
+  GLGuiButton::GLGuiButton (const std::string& label)
+  {
+    this->init();
+
+    this->_label.setText( label );
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGuiButton::~GLGuiButton()
+  {
+    /* this does not have to be done, since the Label is a child,
+     * and will be deleted by Element2D's deletion Process
+     * delete this->label;
+    */
+  }
+
+  /**
+   * @brief initializes the GUI-element
+   */
+  void GLGuiButton::init()
+  {
+    this->registerObject(this, GLGuiButton::_objectList);
+
+    this->setSelectable(true);
+    this->setFocusable(true);
+    this->setClickable(true);
+
+    this->_label.setFont(this->font());
+    this->_label.setColor(this->foregroundColor() );
+
+    this->_label.setParent2D(this);
+    this->_label.setVisibility(false);
+  }
+
+
+  void GLGuiButton::setLabel(const std::string& label)
+  {
+    this->_label.setText(label);
+    this->resize();
+  }
+
+
+  void GLGuiButton::updateFrontColor()
+  {
+    this->_label.setColor(this->foregroundColor());
+  }
+
+  void GLGuiButton::clicking(const Vector2D& pos)
+  {
+    GLGuiWidget::clicking(pos);
+    clicked.emit();
+  }
+  void GLGuiButton::releasing(const Vector2D& pos, bool focused)
+  {
+    GLGuiWidget::releasing(pos, focused);
+    released.emit();
+  }
+
+  void GLGuiButton::hiding()
+  {
+    this->_label.setVisibility(false);
+  }
+
+  void GLGuiButton::showing()
+  {
+    this->_label.setVisibility(true);
+  }
+
+
+  bool GLGuiButton::processEvent(const Event& event)
+  {
+    if (event.type == SDLK_SPACE)
+    {
+      if (event.bPressed)
+        clicked.emit();
+      else
+        released.emit();
+      return true;
+    }
+    return false;
+  }
+
+
+  /**
+   * @brief draws the GLGuiButton
+   */
+  void GLGuiButton::draw() const
+  {
+    GLGuiWidget::draw();
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_button.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_button.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_button.h	(revision 9940)
@@ -0,0 +1,70 @@
+/*!
+ * @file glgui_button.h
+ * The gl_BUTTON widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_BUTTON_H
+#define _GLGUI_BUTTON_H
+
+#include "glgui_widget.h"
+
+#include "text.h"
+
+namespace OrxGui
+{
+  typedef enum
+  {
+    Button_Active,
+    Button_Inactive,
+    Button_Pressed,
+    Button_Released,
+    Button_Activating,
+    Button_Deactivating,
+
+  } ButtonState;
+
+  //! This is part of the openglGUI class
+  /**
+   * The Button is an Abstract class, that can be pushed to Toggle its state.
+   */
+  class GLGuiButton : public GLGuiWidget
+  {
+    ObjectListDeclaration(GLGuiButton);
+    public:
+      GLGuiButton(const std::string& label);
+      virtual ~GLGuiButton();
+
+      const std::string& label() const { return this->_label.text(); };
+      void setLabel(const std::string& label);
+
+      virtual void draw() const;
+      virtual bool processEvent(const Event& event);
+
+      sigslot::signal0<> clicked;
+      sigslot::signal0<> released;
+
+
+    protected:
+      virtual void updateFrontColor();
+
+      virtual void clicking(const Vector2D& pos);
+      virtual void releasing(const Vector2D& pos, bool focused);
+      virtual void hiding();
+      virtual void showing();
+
+      /** @returns the Text. (the physical Text) */
+      Text& labelText() { return this->_label; }
+      /** @returns the constant Text. (the physical Text) */
+      const Text& labelText() const { return this->_label; }
+
+    private:
+      void init();
+
+
+    private:
+      Text                 _label;
+      ButtonState          state;
+  };
+}
+#endif /* _GLGUI__H */
Index: branches/heathaze/src/lib/gui/gl/glgui_checkbutton.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_checkbutton.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_checkbutton.cc	(revision 9940)
@@ -0,0 +1,132 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_checkbutton.h"
+
+#include "text.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiCheckButton);
+
+  /**
+   * standard constructor
+  */
+  GLGuiCheckButton::GLGuiCheckButton (const std::string& label, bool active)
+  : GLGuiButton(label)
+  {
+    this->init();
+    this->bActive = active;
+
+    this->resize();
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGuiCheckButton::~GLGuiCheckButton()
+  {
+  }
+
+  /**
+   * initializes the GUI-element
+   */
+  void GLGuiCheckButton::init()
+  {
+    this->registerObject(this, GLGuiCheckButton::_objectList);
+  }
+
+  void GLGuiCheckButton::setActivity(bool bActive)
+  {
+    this->bActive = bActive;
+    this->toggled.emit(this->bActive);
+  }
+
+  void GLGuiCheckButton::toggleActiveState()
+  {
+    this->setActivity(!this->isActive());
+  }
+
+  void GLGuiCheckButton::resize()
+  {
+
+    this->labelText().setRelCoor2D( borderLeft() + 15.0, borderTop() + 5);
+    this->setSize2D(this->labelText().getSizeX2D() + 15.0 + borderLeft() + borderRight(), this->labelText().getSizeY2D() + 10 + borderTop()+borderBottom());
+    GLGuiWidget::resize();
+
+    this->_checkBox.setSize(10.0, 10.0);
+    this->_checkBox.setCenter( borderLeft() + _checkBox.height()/2.0, borderTop() + (this->getSizeY2D() - borderTop() - borderBottom()) / 2.0);
+
+/*    this->frontRect().setTopLeft(borderLeft(), borderTop());
+    this->frontRect().setSize(this->getSizeX2D() - (borderLeft() + borderRight()) , this->getSizeY2D() - (borderTop() + borderBottom()));*/
+  }
+
+
+  void GLGuiCheckButton::releasing(const Vector2D& pos, bool focused)
+  {
+    GLGuiButton::releasing(pos, focused);
+    if (focused)
+      this->toggleActiveState();
+  }
+
+
+
+  /**
+   * @brief draws the GLGuiPushButton
+   */
+  void GLGuiCheckButton::draw() const
+  {
+    this->beginDraw();
+    GLGuiButton::draw();
+
+//     this->frontMaterial().select();
+//     this->drawRect(this->frontRect());
+    if (this->bActive)
+    {
+      glColor3fv( &this->foregroundColor()[0]);
+      this->drawRect(this->_checkBox);
+
+
+      // DRAW a cross :)
+      Vector2D center = this->_checkBox.center();
+      glColor4f(1,1,1, 1.0);
+      glLineWidth(3.0);
+
+      glBegin(GL_LINE_LOOP);
+      glVertex2d(_checkBox.left(), _checkBox.top());
+      glVertex2d(center.x, center.y);
+
+      glVertex2d(_checkBox.right(), _checkBox.top());
+      glVertex2d(center.x, center.y);
+
+      glVertex2d(_checkBox.right(), _checkBox.bottom());
+      glVertex2d(center.x, center.y);
+
+      glVertex2d(_checkBox.left(), _checkBox.bottom());
+      glVertex2d(center.x, center.y);
+      glEnd();
+    }
+    else
+    {
+      glColor3fv( &this->foregroundColor()[0]);
+      this->drawRect(this->_checkBox);
+    }
+
+    this->endDraw();
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_checkbutton.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_checkbutton.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_checkbutton.h	(revision 9940)
@@ -0,0 +1,52 @@
+/*!
+ * @file glgui_checkbutton.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_CHECKBUTTON_H
+#define _GLGUI_CHECKBUTTON_H
+
+#include "glgui_button.h"
+
+namespace OrxGui
+{
+
+  // FORWARD DECLARATION
+
+  //! This is part of the openglGUI class
+  /**
+   *
+   */
+  class GLGuiCheckButton : public GLGuiButton
+  {
+    ObjectListDeclaration(GLGuiCheckButton);
+  public:
+    GLGuiCheckButton(const std::string& label = "", bool active = false);
+    virtual ~GLGuiCheckButton();
+
+
+    bool    isActive() { return this->bActive; };
+    void    setActivity(bool bActive);
+    void    toggleActiveState();
+
+    virtual void draw() const;
+    virtual void update() {};
+
+    sigslot::signal1<bool> toggled;
+
+  protected:
+    virtual void resize();
+    virtual void releasing(const Vector2D& pos, bool focused);
+
+  private:
+    void init();
+
+
+  private:
+    bool             bActive;
+    Rect2D           _checkBox;
+  };
+}
+
+#endif /* _GLGUI_CHECKBUTTON_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_colorselector.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_colorselector.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_colorselector.cc	(revision 9940)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_.h"
+
+namespace OrxGui
+{
+
+  /**
+   * standard constructor
+  */
+  GLGui::GLGui ()
+  {
+    this->init();
+
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGui::~GLGui()
+  {
+  }
+
+  /**
+   * initializes the GUI-element
+   */
+  GLGui::init()
+  {
+    this->setClassID(CL_GLGUI_, "GLGui");
+
+  }
+
+  /**
+   * draws the GLGui
+   */
+  void GLGui::draw()
+  {
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_colorselector.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_colorselector.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_colorselector.h	(revision 9940)
@@ -0,0 +1,36 @@
+/*!
+ * @file glgui_.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_COLORSELECTOR_H
+#define _GLGUI_COLORSELECTOR_H
+
+#include "glgui_widget.h"
+
+namespace OrxGui
+{
+
+  // FORWARD DECLARATION
+
+  //! This is part of the openglGUI class
+  /**
+   *
+   */
+  class GLGui : public GLGui
+  {
+    ObjectListDeclaration(GLGuiColorSelector);
+  public:
+    GLGui();
+    virtual ~GLGui();
+
+    void init();
+
+    virtual void draw();
+
+  private:
+
+  };
+}
+#endif /* _GLGUI__H */
Index: branches/heathaze/src/lib/gui/gl/glgui_container.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_container.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_container.cc	(revision 9940)
@@ -0,0 +1,62 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_container.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiContainer);
+  /**
+   * standard constructor
+  */
+  GLGuiContainer::GLGuiContainer ()
+  {
+    this->init();
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGuiContainer::~GLGuiContainer()
+  {}
+
+  /**
+   * initializes the GUI-element
+   */
+  void GLGuiContainer::init()
+  {
+    this->registerObject(this, GLGuiContainer::_objectList);
+
+    this->setBackgroundTexture("gui_container_background.png");
+
+  }
+
+
+  void GLGuiContainer::removeChildWidget(GLGuiWidget* widget)
+  {
+    this->unpack(widget);
+  }
+
+
+  /**
+   * draws the GLGuiContainer
+   */
+  void GLGuiContainer::draw()
+  {
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_container.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_container.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_container.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file glgui_container.h
+ * The gl_container widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_CONTAINER_H
+#define _GLGUI_CONTAINER_H
+
+#include "glgui_widget.h"
+
+namespace OrxGui
+{
+  // FORWARD DECLARATION
+
+  //! This is part of the openglGUI class
+  /**
+   *
+   */
+  class GLGuiContainer : public GLGuiWidget
+  {
+    ObjectListDeclaration(GLGuiContainer);
+  public:
+    GLGuiContainer();
+    virtual ~GLGuiContainer();
+
+    /** @brief packs a widget into this one. */
+    virtual void pack(GLGuiWidget* widget) = 0;
+    /** unpacks a Widget from this container. @param widget the GLGuiWidget to unpack, if NULL all subwidgets will be unpackt. */
+    virtual void unpack(GLGuiWidget* widget) = 0;
+    /** @brief clears all Widgets out. */
+    virtual void clear() = 0;
+
+    virtual void hideAll() = 0;
+    virtual void showAll() = 0;
+
+
+    virtual void draw();
+
+  protected:
+    virtual void removeChildWidget(GLGuiWidget* widget);
+
+  private:
+    void init();
+  };
+}
+#endif /* _GLGUI__H */
Index: branches/heathaze/src/lib/gui/gl/glgui_cursor.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_cursor.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_cursor.cc	(revision 9940)
@@ -0,0 +1,160 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_cursor.h"
+
+#include "glgui_handler.h"
+#include "color.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiCursor);
+  /**
+   * standard constructor
+  */
+  GLGuiCursor::GLGuiCursor ()
+  {
+    this->init();
+
+    this->subscribeEvent(ES_ALL,  EV_MOUSE_MOTION);
+    this->subscribeEvent(ES_ALL, EV_WINDOW_FOCUS);
+
+
+  }
+
+
+  /**
+   * @brief standard deconstructor
+   */
+  GLGuiCursor::~GLGuiCursor()
+  {
+    GLGuiHandler::getInstance()->deactivateCursor(false);
+  }
+
+  float GLGuiCursor::_mouseSensitivity = 1.0;
+
+
+
+  /**
+   * @brief initializes the GUI-element
+   */
+  void GLGuiCursor::init()
+  {
+    this->registerObject(this, GLGuiCursor::_objectList);
+
+    this->setBackgroundColor(Color(1.0, 1.0, 1.0, 1.0));
+    this->setBackgroundTexture("cursor.png");
+    this->setSize2D(50, 50);
+    this->setAbsCoor2D(100, 100);
+    this->setLayer(E2D_LAYER_ABOVE_ALL);
+    this->color = 0.0f;
+    this->frameNumber = 0.0f;
+
+    this->resize();
+  }
+
+  /**
+   * @brief Loads an Image-Series onto the Cursor.
+   * @param imageNameSubstitue The Prefix of the Image
+   * @param from From which image
+   * @param to To which image
+   * @return true on success.
+   *
+   * @see TextureSequence:: loadTextureSequence(const std::string& imageNameSubstitue, unsigned int from, unsigned int to)
+   */
+  bool GLGuiCursor::loadTextureSequence(const std::string& imageNameSubstitue, unsigned int from, unsigned int to)
+  {
+    //this->background().setDiffuse(1.0, 1.0, 1.0);
+    return this->seq.loadImageSeries(imageNameSubstitue, from, to);
+  }
+
+  void GLGuiCursor::tick(float dt)
+  {
+    if (!this->seq.empty())
+    {
+      this->frameNumber += 25.0*dt;
+      if (frameNumber >= this->seq.getFrameCount())
+        frameNumber = 0.0;
+    }
+    else
+    {
+      this->color += dt*10.0;
+      if (this->color > 360.0)
+        this->color -= 360.0;
+      Vector color =  Color::HSVtoRGB(Vector(this->color, 1.0, 1.0));
+      //this->setBackgroundColor(color.x, color.y, color.z);
+      /// FIXME
+
+    }
+    //if (this->movement != Vector2D())
+    {
+      newPos += movement;
+      // reposition the cursor.
+      if (newPos.x < 0.0f )
+        newPos.x = 0.0f;
+      if (newPos.x > this->_maxBorders.x)
+        newPos.x = this->_maxBorders.x;
+      if (newPos.y < 0.0f )
+        newPos.y = 0.0f;
+      if (newPos.y > this->_maxBorders.y)
+        newPos.y = this->_maxBorders.y;
+
+
+      movement = Vector2D();
+    }
+    this->setAbsCoor2D(newPos);
+  }
+
+  /**
+   * @brief draws the GLGuiCursor
+   */
+  void GLGuiCursor::draw() const
+  {
+    this->beginDraw();
+
+    this->background().select();
+    if (!this->seq.empty())
+      glBindTexture(GL_TEXTURE_2D, this->seq.getFrameTexture((int)frameNumber));
+    this->drawRect(this->backRect());
+
+    //GLGuiWidget::draw();
+    this->endDraw();
+  }
+
+  /**
+   * @brief processes Events from the EventHandler.
+   * @param event the Event to process.
+   */
+  void GLGuiCursor::process(const Event& event)
+  {
+    switch (event.type)
+    {
+      case EV_WINDOW_FOCUS:
+        if (event.bPressed)
+        {
+          int mouseX, mouseY;
+          SDL_GetMouseState(&mouseX, &mouseY);
+          newPos = Vector2D(mouseX, mouseY);
+        }
+        break;
+      case EV_MOUSE_MOTION:
+        movement += Vector2D((float)event.xRel * _mouseSensitivity, (float)event.yRel * _mouseSensitivity);
+        break;
+
+    }
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_cursor.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_cursor.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_cursor.h	(revision 9940)
@@ -0,0 +1,66 @@
+/*!
+ * @file glgui_cursor.h
+ * The gl_cursor widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_CURSOR_H
+#define _GLGUI_CURSOR_H
+
+#include "glgui_widget.h"
+#include "event_listener.h"
+#include "vector2D.h"
+
+#include "texture_sequence.h"
+
+class TextureSequence;
+
+namespace OrxGui
+{
+  // FORWARD DECLARATION
+
+  //! This is part of the openglGUI class
+  /**
+   *
+   */
+  class GLGuiCursor : public GLGuiWidget, public EventListener
+  {
+    ObjectListDeclaration(GLGuiCursor);
+  public:
+    GLGuiCursor();
+    virtual ~GLGuiCursor();
+
+
+    bool loadTextureSequence(const std::string& imagePrefix, unsigned int from, unsigned int to);
+
+
+    const Vector2D& position() const { return Element2D::getAbsCoor2D(); }
+
+    void setMaxBorders(const Vector2D& maxBorders) { this->_maxBorders = maxBorders; };
+    static void setMouseSensitivity(float mouseSensitivity);
+    static float mouseSensitivity() { return GLGuiCursor::_mouseSensitivity; };
+
+
+    virtual void tick(float dt);
+    virtual void draw() const;
+    virtual void process(const Event& event);
+
+  private:
+    void init();
+
+  private:
+
+    Vector2D      _maxBorders;
+
+    Vector2D      newPos;
+    Vector2D      movement;
+
+    float         color; // so f****ing temporary... ... ....
+
+    static float        _mouseSensitivity;
+    TextureSequence     seq;
+    float               frameNumber;
+
+  };
+}
+#endif /* _GLGUI_CURSOR_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_defs.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_defs.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_defs.h	(revision 9940)
@@ -0,0 +1,101 @@
+/*!
+ * @file glgui_defs.h
+ * Definitions for the GLGui.
+ */
+
+#ifndef _GLGUI_DEFS_H
+#define _GLGUI_DEFS_H
+
+#include <string>
+
+/// TODO MOVE TO ORXGUI_TYPES
+namespace OrxGui
+{
+  //! if the Element should be visible by default.
+#define GLGUI_WIDGET_DEFAULT_VISIBLE       false
+
+
+  //! An enumeration for the Orientation of an Element.
+  typedef enum {
+    Horizontal,       //!< Horizontal Orientation.
+    Vertical          //!< Vertical Orientation.
+  } Orientation;
+
+  //! Names of Orientations
+  const std::string OrientationString[] =
+    {
+      "Horizontal",
+      "Vertical"
+    };
+
+  //! An enumeration for the Positions of some Elements (FixedPositionBox as an example).
+  typedef enum {
+    Left,               //!< Left
+    Right,              //!< Right
+    Top,                //!< Top
+    Bottom,             //!< Bottom
+    TopLeft,            //!< TopLeft
+    TopRight,           //!< TopRight
+    BottomLeft,         //!< BottomLeft
+    BottomRight,        //!< BottomRight
+    Center,             //!< Centered
+  } Position;
+
+  //! Names of Positions
+  const std::string PositionString[] =
+    {
+      "Left",
+      "Right",
+      "Top",
+      "Bottom",
+      "TopLeft",
+      "TopRight",
+      "BottomLeft",
+      "BottomRight",
+      "Center"
+    };
+
+
+  //! An enumerator that defines the different states Widgets may be in.
+  typedef enum {
+    Normal,           //!< Normal state of the GUI's Widgets.
+    Focused,           //!< If the widget is Active.
+    Selected,         //!< If the Widget is Selected.
+    Insensitive       //!< If the Widget is insensitive.
+  } State;
+  //! The count of States a GUI-Element can be in.
+#define GLGUI_STATE_COUNT   4
+#define GLGUI_DEFAULT_STYLE OrxGui::Normal
+
+  //! names of the States.
+  const std::string StateString[] =
+    {
+      "Normal",
+      "Focused",
+      "Selected",
+      "Insensitive"
+    };
+
+  //! Where a Certain feature will be positioned at.
+  typedef enum {
+    FeatureLeft,          //!< On the Left side.
+    FeatureRight,         //!< On the Right side.
+    FeatureTop,           //!< On Top of the rest of the Widget.
+    FeatureBottom,        //!< At the Bottom of the rest of the Widget.
+  } FeaturePosition;
+
+  //! Names of Feature-Positions
+  const std::string FeaturePositionString[] =
+    {
+      "Left",
+      "Right",
+      "Top",
+      "Bottom"
+    };
+
+
+
+};
+
+
+#endif /* _GLGUI_DEFS_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_element.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_element.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_element.cc	(revision 9940)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_.h"
+
+namespace OrxGui
+{
+
+  /**
+  * standard constructor
+  */
+  GLGui::GLGui ()
+  {
+    this->init();
+
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGui::~GLGui()
+  {
+  }
+
+  /**
+   * initializes the GUI-element
+   */
+  GLGui::init()
+  {
+    this->setClassID(CL_GLGUI_, "GLGui");
+
+  }
+
+  /**
+   * draws the GLGui
+   */
+  void GLGui::draw()
+  {
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_element.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_element.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_element.h	(revision 9940)
@@ -0,0 +1,35 @@
+/*!
+ * @file glgui_.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI__H
+#define _GLGUI__H
+
+#include "base_object.h"
+
+namespace OrxGui
+{
+  // FORWARD DECLARATION
+
+  //! This is part of the openglGUI class
+  /**
+   *
+   */
+  class GLGui : public GLGui
+  {
+
+  public:
+    GLGui();
+    virtual ~GLGui();
+
+    void init();
+
+    virtual void draw();
+
+  private:
+
+  };
+}
+#endif /* _GLGUI__H */
Index: branches/heathaze/src/lib/gui/gl/glgui_fixedposition_box.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_fixedposition_box.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_fixedposition_box.cc	(revision 9940)
@@ -0,0 +1,73 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_fixedposition_box.h"
+#include "glgui_handler.h"
+
+#include <cassert>
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiFixedpositionBox);
+  /**
+   * standard constructor
+  */
+  GLGuiFixedpositionBox::GLGuiFixedpositionBox (OrxGui::Position position, OrxGui::Orientation orientation)
+      : GLGuiBox(orientation)
+  {
+    this->registerObject(this, GLGuiFixedpositionBox::_objectList);
+
+    this->subscribeEvent(ES_ALL, EV_VIDEO_RESIZE);
+    this->setPosition(position);
+  }
+
+
+  void GLGuiFixedpositionBox::setPosition(OrxGui::Position position)
+  {
+    this->_position = position;
+    this->resize();
+  }
+
+
+  void GLGuiFixedpositionBox::resize()
+  {
+    GLGuiBox::resize();
+
+    switch (this->_position)
+    {
+      case OrxGui::Center:
+        this->setAbsCoor2D((GLGuiHandler::getInstance()->resolution() - this->getSize2D()) / 2.0);
+        break;
+      default:
+        printf("not done mode yet!!\n");
+    }
+  }
+
+  void GLGuiFixedpositionBox::process(const Event& event)
+  {
+    switch(event.type)
+    {
+      case EV_VIDEO_RESIZE:
+        this->resize();
+        break;
+
+    }
+
+  }
+
+
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_fixedposition_box.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_fixedposition_box.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_fixedposition_box.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file glgui_fixedposition_box.h
+ * The gl_fixedposition_box widget of th openglGUi
+ */
+
+#ifndef _GLGUI_FIXEDPOSITION_BOX_H
+#define _GLGUI_FIXEDPOSITION_BOX_H
+
+#include "glgui_box.h"
+#include "event_listener.h"
+
+namespace OrxGui
+{
+  //! This is BOX part of the openglGUI class
+  /**
+   * The Box is always positioned at the designated position on the screen
+   *
+   * @note If you pack the box or move it with setRel/AbsCoor2D the
+   * behaviour of positioning is not predictable!
+   */
+  class GLGuiFixedpositionBox : public OrxGui::GLGuiBox, EventListener
+  {
+    ObjectListDeclaration(GLGuiFixedpositionBox);
+    public:
+      GLGuiFixedpositionBox(OrxGui::Position position = OrxGui::Center, OrxGui::Orientation orientation = OrxGui::Vertical);
+
+      inline OrxGui::Position position() const { return this->_position; };
+      void setPosition(OrxGui::Position position);
+
+    protected:
+      virtual void resize();
+      virtual void process(const Event& event); //!< from eventListener
+
+    private:
+      OrxGui::Position     _position;     //!< The Fixed position of the Widget.
+  };
+}
+#endif /* _GLGUI_FIXEDPOSITION_BOX_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_frame.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_frame.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_frame.cc	(revision 9940)
@@ -0,0 +1,100 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_frame.h"
+
+#include "debug.h"
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiFrame);
+  /**
+   * standard constructor
+  */
+  GLGuiFrame::GLGuiFrame ()
+  {
+    this->init();
+
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGuiFrame::~GLGuiFrame()
+  {
+  }
+
+  /**
+   * initializes the GUI-element
+   */
+  void GLGuiFrame::init()
+  {
+    this->registerObject(this, GLGuiFrame::_objectList);
+    this->child = NULL;
+  }
+
+  void GLGuiFrame::pack(GLGuiWidget* widget)
+  {
+    if (widget == NULL)
+      return;
+
+    if (this->child == NULL)
+      this->child = widget;
+    else
+    {
+      PRINTF(2)("Frame %s is already filled, not filling with %s\n", this->getCName(), widget->getCName());
+    }
+  }
+
+  void GLGuiFrame::unpack(GLGuiWidget* widget)
+  {
+    if (widget == NULL || widget == this->child)
+      this->child = NULL;
+  }
+
+  void GLGuiFrame::showAll()
+  {
+    if (this->child != NULL)
+    {
+      if (this->child->isA(GLGuiContainer::staticClassID()))
+        static_cast<GLGuiContainer*>(this->child)->showAll();
+      else
+        this->child->show();
+    }
+    this->show();
+  }
+
+  void GLGuiFrame::hideAll()
+  {
+    if (this->child != NULL)
+    {
+      if (this->child->isA(GLGuiContainer::staticClassID()))
+        static_cast<GLGuiContainer*>(this->child)->hideAll();
+      else
+        this->child->hide();
+    }
+    this->hide();
+  }
+
+
+  /**
+   * draws the GLGuiFrame
+   */
+  void GLGuiFrame::draw()
+  {
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_frame.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_frame.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_frame.h	(revision 9940)
@@ -0,0 +1,41 @@
+/*!
+ * @file glgui_frame.h
+ * The gl_frame widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_FRAME_H
+#define _GLGUI_FRAME_H
+
+#include "glgui_container.h"
+
+namespace OrxGui
+{
+  // FORWARD DECLARATION
+
+  //! This is Frame part of the openglGUI class
+  /**
+   *
+   */
+  class GLGuiFrame : public GLGuiContainer
+  {
+    ObjectListDeclaration(GLGuiFrame);
+  public:
+    GLGuiFrame();
+    virtual ~GLGuiFrame();
+
+    void init();
+
+    virtual void pack(GLGuiWidget* widget);
+    virtual void unpack(GLGuiWidget* widget);
+    virtual void showAll();
+    virtual void hideAll();
+
+    virtual void draw();
+
+  private:
+    GLGuiWidget*           child;
+
+  };
+}
+#endif /* _GLGUI__H */
Index: branches/heathaze/src/lib/gui/gl/glgui_handler.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_handler.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_handler.cc	(revision 9940)
@@ -0,0 +1,326 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_handler.h"
+#include "event_handler.h"
+#include "key_names.h"
+
+#include "glgui_mainwidget.h"
+#include "glgui_cursor.h"
+
+#include "loading/resource_manager.h"
+
+#include <cassert>
+
+#include "debug.h"
+
+
+/// TAKE THIS OUT OF HERE.
+#include "graphics_engine.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiHandler);
+  /**
+   * standard constructor
+   */
+  GLGuiHandler::GLGuiHandler ()
+  {
+    this->registerObject(this, GLGuiHandler::_objectList);
+    this->setName("GLGuiHandler");
+
+    this->_resolution = Vector2D(GraphicsEngine::getInstance()->getResolutionX(), GraphicsEngine::getInstance()->getResolutionY());
+
+    EventHandler::getInstance()->withUNICODE(ES_MENU, true );
+
+    this->_cursor = NULL;
+    for (unsigned int i = 0; i < EV_NUMBER; i++)
+    {
+      this->subscribeEvent(ES_GAME, i);
+      this->subscribeEvent(ES_GAME_MENU, i);
+      this->subscribeEvent(ES_MENU, i);
+    }
+  }
+
+  /**
+   *  the singleton reference to this class
+   */
+  GLGuiHandler* GLGuiHandler::singletonRef = NULL;
+
+  /**
+     @brief standard deconstructor
+   */
+  GLGuiHandler::~GLGuiHandler ()
+  {
+    GLGuiHandler::singletonRef = NULL;
+  }
+
+  void GLGuiHandler::activateCursor()
+  {
+    if (this->_cursor == NULL)
+      this->_cursor = new GLGuiCursor();
+    this->_cursor->show();
+    this->_cursor->setMaxBorders(Vector2D(GraphicsEngine::getInstance()->getResolutionX(), GraphicsEngine::getInstance()->getResolutionY()));
+
+    _cursor->loadTextureSequence(Resources::ResourceManager::getInstance()->mainGlobalPath().name() + "/" + "maps/reap_mouse/reap_mouse_##.png", 1, 49);
+
+  }
+
+  void GLGuiHandler::deactivateCursor(bool deleteCursor)
+  {
+    if (this->_cursor)
+    {
+      if (deleteCursor)
+        delete this->_cursor;
+      this->_cursor = NULL;
+    }
+  }
+
+  const Vector2D& GLGuiHandler::resolution()
+  {
+    if (this->_resolution == Vector2D::nullVector())
+      this->_resolution = Vector2D(GraphicsEngine::getInstance()->getResolutionX(), GraphicsEngine::getInstance()->getResolutionY());
+    return _resolution;
+  }
+
+
+  void GLGuiHandler::activate()
+  {
+    //EventHandler::getInstance()->pushState(ES_MENU);
+
+
+
+  }
+
+  void GLGuiHandler::deactivate()
+  {
+    //EventHandler::getInstance()->popState();
+
+
+  }
+
+  void GLGuiHandler::selectNext()
+  {
+    // retrieve Objects.
+    ObjectList<GLGuiWidget>::const_iterator it, currentIt;
+    currentIt = GLGuiWidget::objectList().end();
+
+    if (GLGuiWidget::selected() != NULL)
+    {
+      it = std::find(GLGuiWidget::objectList().begin(), GLGuiWidget::objectList().end(), GLGuiWidget::selected());
+      if (it != GLGuiWidget::objectList().end())
+      {
+        currentIt = it;
+        it++;
+      }
+    }
+    else
+    {
+      it = GLGuiWidget::objectList().begin();
+    }
+
+    bool cycledOnce = false;
+
+    for (; it != currentIt; ++it)
+    {
+      if (it == GLGuiWidget::objectList().end() && !cycledOnce)
+      {
+        it = GLGuiWidget::objectList().begin();
+        cycledOnce = true;
+      }
+
+      if ((*it)->selectable() && (*it)->isVisible())
+      {
+        (*it)->select();
+        return;
+      }
+    }
+
+  }
+
+  void GLGuiHandler::selectPrevious()
+  {
+    ObjectList<GLGuiWidget>::const_iterator it, currentIt;
+    currentIt = GLGuiWidget::objectList().begin();
+
+      if (GLGuiWidget::selected() != NULL)
+      {
+	it = std::find(GLGuiWidget::objectList().begin(), GLGuiWidget::objectList().end(), GLGuiWidget::selected());
+	if (it != GLGuiWidget::objectList().end())
+        {
+          currentIt = it;
+          it--;
+        }
+      }
+      else
+      {
+	it = GLGuiWidget::objectList().end();
+      }
+
+      bool cycledOnce = false;
+
+      for (; it != currentIt; --it)
+      {
+	if (it == GLGuiWidget::objectList().end() && !cycledOnce)
+        {
+          --it ;
+          cycledOnce = true;
+        }
+
+        if ((*it)->selectable() && (*it)->isVisible())
+        {
+          (*it)->select();
+          return;
+        }
+      }
+
+  }
+
+
+
+  void GLGuiHandler::process(const Event &event)
+  {
+    switch (event.type)
+    {
+      case EV_MOUSE_MOTION:
+      this->checkFocus();
+      break;
+
+      case  EV_MOUSE_BUTTON_LEFT:
+      if (GLGuiWidget::mouseFocused() != NULL && event.bPressed)
+      {
+        // if clickable select the Widget.
+        if (GLGuiWidget::mouseFocused()->clickable())
+        {
+          Vector2D cursorPos = (this->_cursor != NULL) ? this->_cursor->getAbsCoor2D() : Vector2D(event.x, event.y);
+          GLGuiWidget::mouseFocused()->select();
+          GLGuiWidget::mouseFocused()->click(cursorPos - GLGuiWidget::mouseFocused()->getAbsCoor2D());
+        }
+      }
+      else if (GLGuiWidget::selected() != NULL && !event.bPressed)
+      {
+        if (GLGuiWidget::selected()->clickable())
+        {
+          Vector2D cursorPos = (this->_cursor != NULL) ? this->_cursor->getAbsCoor2D() : Vector2D(event.x, event.y);
+          GLGuiWidget::selected()->release(cursorPos - GLGuiWidget::selected()->getAbsCoor2D());
+        }
+      }
+
+      break;
+      case EV_LEAVE_STATE:
+      if (GLGuiWidget::selected() != NULL)
+        GLGuiWidget::selected()->unselect();
+
+      if (GLGuiWidget::mouseFocused() != NULL)
+        GLGuiWidget::mouseFocused()->breakMouseFocus();
+      break;
+
+      case EV_VIDEO_RESIZE:
+      if (this->_cursor != NULL)
+        this->_cursor->setMaxBorders(Vector2D(event.resize.w, event.resize.h));
+      this->_resolution = Vector2D(event.resize.w, event.resize.h);
+      break;
+
+      case SDLK_TAB:
+      if (event.bPressed)
+      {
+        if (EventHandler::getInstance()->isPressed(SDLK_LSHIFT) || EventHandler::getInstance()->isPressed(SDLK_RSHIFT))
+          this->selectPrevious();
+        else
+          this->selectNext();
+      }
+      break;
+    }
+
+
+    // Send the Event to the Widget below.
+    if (GLGuiWidget::selected() != NULL)
+    {
+      GLGuiWidget::selected()->processEvent(event);
+    }
+
+
+
+  }
+
+
+  const Vector2D& GLGuiHandler::cursorPositionOverFocusedWidget() const
+  {
+    return (this->_cursor != NULL) ? this->_cursor->getAbsCoor2D() : Vector2D::nullVector();
+  }
+
+  const Vector2D& GLGuiHandler::cursorPositionAbs() const
+  {
+    if (this->_cursor)
+      return this->_cursor->getAbsCoor2D();
+    else
+      return Vector2D::nullVector();
+  }
+
+  Vector2D GLGuiHandler::cursorPositionRel(const GLGuiWidget* const widget) const
+  {
+    assert (widget != NULL);
+    if (this->_cursor)
+      return  this->_cursor->getAbsCoor2D() - widget->getAbsCoor2D();
+    else
+      return Vector2D::nullVector();
+  }
+
+
+  void GLGuiHandler::checkFocus()
+  {
+    // CHECK THE COLLISIONS.
+    if (this->_cursor != NULL)
+    {
+      for (ObjectList<GLGuiWidget>::const_iterator it = GLGuiWidget::objectList().begin();
+	   it != GLGuiWidget::objectList().end();
+	   it++)
+      {
+        GLGuiWidget* widget = (*it);
+
+        if (widget->isVisible() &&
+            widget->focusable() &&
+            widget->focusOverWidget(this->_cursor))
+        {
+          // receiving Focus
+          if (GLGuiWidget::mouseFocused() != widget)
+          {
+            widget->giveMouseFocus();
+          }
+          return ;
+        }
+      }
+      if (GLGuiWidget::mouseFocused() != NULL)
+        GLGuiWidget::mouseFocused()->breakMouseFocus();
+    }
+  }
+
+  void GLGuiHandler::draw()
+  {
+    //    GLGuiMainWidget::getInstance()->draw2D(E2D_LAYER_TOP);
+  }
+
+
+  void GLGuiHandler::tick(float dt)
+  {
+    // do not change if we already clicked into a Widget.
+    // if (GLGuiWidget::selected() != NULL && GLGuiWidget::selected()->pushed())
+    //      return ;
+
+    this->checkFocus();
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_handler.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_handler.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_handler.h	(revision 9940)
@@ -0,0 +1,63 @@
+/*!
+ * @file proto_singleton.h
+ * @brief Definition of the GLGuiHandler singleton Class
+*/
+
+#ifndef _GLGUI_HANDLER_H
+#define _GLGUI_HANDLER_H
+
+#include "event_listener.h"
+#include "glgui_widget.h"
+
+namespace OrxGui
+{
+ // FORWARD DECLARATION
+  class GLGuiCursor;
+
+
+  //! A singleton class for the GLGui-Handler
+  class GLGuiHandler : public EventListener
+  {
+    ObjectListDeclaration(GLGuiHandler);
+  public:
+    /** @returns a Pointer to the only object of this Class */
+    inline static GLGuiHandler* getInstance(void) { if (!GLGuiHandler::singletonRef) GLGuiHandler::singletonRef = new GLGuiHandler();  return GLGuiHandler::singletonRef; };
+    /** @brief deletes the instance if it exists */
+    inline static void deleteInstance() { if (GLGuiHandler::singletonRef) delete GLGuiHandler::singletonRef; };
+
+    void activateCursor();
+    void deactivateCursor(/** ignore param */ bool deleteCursor = true);
+    GLGuiCursor* cursor() const { return this->_cursor; }
+
+    const Vector2D& cursorPositionOverFocusedWidget() const;
+    const Vector2D& cursorPositionAbs() const;
+    Vector2D cursorPositionRel(const GLGuiWidget* const widget) const;
+
+    const Vector2D& resolution();
+
+    void selectNext();
+    void selectPrevious();
+
+    void activate();
+    void deactivate();
+
+    void checkFocus();
+
+    virtual void process(const Event &event);
+    void draw();
+    void tick(float dt);
+
+  private:
+    GLGuiHandler(void);
+    virtual ~GLGuiHandler(void);
+    static GLGuiHandler* singletonRef;
+
+
+    bool                 isActive;
+    GLGuiCursor*         _cursor;
+    Vector2D             _resolution;
+
+  };
+}
+
+#endif /* _GLGUI_HANDLER_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_image.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_image.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_image.cc	(revision 9940)
@@ -0,0 +1,102 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_image.h"
+
+#include "debug.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiImage);
+  /**
+   * standard constructor
+  */
+  GLGuiImage::GLGuiImage ()
+  {
+    this->init();
+
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGuiImage::~GLGuiImage()
+  {
+  }
+
+  /**
+   * initializes the GUI-element
+   */
+  void GLGuiImage::init()
+  {
+    this->registerObject(this, GLGuiImage::_objectList);
+
+    this->setForegroundColor(Color(1,1,1,1));
+    this->_imageMaterial.setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+    this->resize();
+  }
+
+
+  void GLGuiImage::loadImageFromTexture(const Texture& texture)
+  {
+    this->_imageMaterial.setDiffuseMap(texture);
+  }
+
+  void GLGuiImage::loadImageFromFile(const std::string& fileName)
+  {
+    this->_imageMaterial.setDiffuseMap(fileName);
+  }
+
+  void GLGuiImage::loadImageFromSDLSurface(SDL_Surface* surface)
+  {
+    this->_imageMaterial.setDiffuseMap(Texture(surface));
+  }
+
+  void GLGuiImage::loadImageFromDisplayList(GLuint texture)
+  {
+    PRINTF(2)("SORRY NOT IMPLEMENTED\n");
+//    this->_imageMaterial.setTexture(texture);
+  }
+
+  void GLGuiImage::updateFrontColor()
+  {
+    this->_imageMaterial.setDiffuseColor(foregroundColor());
+  }
+
+  void GLGuiImage::resize()
+  {
+    this->_imagePlane.setTopLeft(borderLeft(), borderTop());
+    this->_imagePlane.setSize(this->getSizeX2D() - (borderLeft() + borderRight()), this->getSizeY2D() - (borderTop() + borderBottom()) );
+    GLGuiWidget::resize();
+  }
+
+
+  /**
+   * @brief draws the GLGuiImage
+   */
+  void GLGuiImage::draw() const
+  {
+    this->beginDraw();
+    GLGuiWidget::draw();
+
+    this->_imageMaterial.select();
+    this->drawRect(this->_imagePlane);
+    this->endDraw();
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_image.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_image.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_image.h	(revision 9940)
@@ -0,0 +1,51 @@
+/*!
+ * @file glgui_image.h
+ * The gl_Image widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_IMAGE_H
+#define _GLGUI_IMAGE_H
+
+#include "glgui_widget.h"
+
+// FORWARD DECLARATION
+struct SDL_Surface;
+namespace OrxGui
+{
+
+  //! This is Image part of the openglGUI class
+  /**
+   *
+   */
+  class GLGuiImage : public GLGuiWidget
+  {
+    ObjectListDeclaration(GLGuiImage);
+  public:
+    GLGuiImage();
+    virtual ~GLGuiImage();
+
+    void loadImageFromTexture(const Texture& texture);
+
+    void loadImageFromFile(const std::string& fileName);
+    void loadImageFromSDLSurface(SDL_Surface* surface);
+    void loadImageFromDisplayList(GLuint texture);
+
+    virtual void draw() const;
+
+    sigslot::signal0<> imageChanged;
+
+  protected:
+    virtual void updateFrontColor();
+    virtual void resize();
+
+
+  private:
+    void init();
+
+  private:
+    Rect2D        _imagePlane;
+    Material      _imageMaterial;
+  };
+}
+#endif /* _GLGUI_IMAGE_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_inputline.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_inputline.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_inputline.cc	(revision 9940)
@@ -0,0 +1,270 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_inputline.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiInputLine);
+  /**
+   * @brief standard constructor
+   */
+  GLGuiInputLine::GLGuiInputLine ()
+  {
+    this->init();
+  }
+
+
+  /**
+   * @brief standard deconstructor
+   */
+  GLGuiInputLine::~GLGuiInputLine()
+  {}
+
+  float GLGuiInputLine::repeatDelay = 0.3f;
+  float GLGuiInputLine::repeatRate  = 0.01f;
+
+
+  /**
+   * @brief initializes the GUI-element
+   */
+  void GLGuiInputLine::init()
+  {
+    this->registerObject(this, GLGuiInputLine::_objectList);
+
+    this->setFocusable(true);
+    this->setClickable(true);
+    this->setSelectable(true);
+
+    this->_clearOnEnter = false;
+    this->_text.setParent2D(this);
+    this->_text.setRelCoor2D(4,4);
+    this->_text.setFont("fonts/final_frontier.ttf", 20);
+    this->_text.setLineWidth(400);
+    this->_text.setDotsPosition(LimitedWidthText::Begin);
+    this->_text.setColor(foregroundColor());
+    this->_text.setVisibility(false);
+    this->resize();
+
+    this->delayNext = 0.0;
+    this->pressedKey = SDLK_FIRST;
+    this->pressedKeyName = SDLK_FIRST;
+
+  }
+
+
+  /**
+   * @brief sets the Text of the InputLine
+   * @param text The new Text.
+   */
+  void GLGuiInputLine::setText(const std::string& text)
+  {
+    this->_text.setText(text);
+    this->changedText();
+  }
+
+  /**
+   * @brief appends text to the InputLine
+   * @param appendText the Text to append
+   */
+  void GLGuiInputLine::append(const std::string& appendText)
+  {
+    this->_text.append(appendText);
+    this->changedText();
+  }
+
+
+  /**
+   * @brief appends a Character to the InputLine
+   * @param character the Character to append.
+   */
+  void GLGuiInputLine::appendCharacter(char character)
+  {
+    this->_text.appendCharacter(character);
+    this->changedText();
+  }
+
+
+  /**
+   * @brief Removes Characters from the InputLine
+   * @param chars The count of characters to remove
+   */
+  void GLGuiInputLine::removeCharacters(unsigned int chars)
+  {
+    this->_text.removeCharacters(chars);
+    this->changedText();
+  }
+
+  void GLGuiInputLine::clear()
+  {
+    this->_text.clear();
+    this->changedText();
+  }
+
+  /**
+   * @brief If the Text has been changed this function is called.
+   *
+   * This Function also emits the Signal textChanged.
+   */
+  void GLGuiInputLine::changedText()
+  {
+    this->resize();
+    this->setFrontColor(Color(1,1,1,1), true);
+    this->textChanged.emit(this->_text.text());
+  }
+
+
+  /**
+   * removes the focus from this Widget.
+   */
+  void GLGuiInputLine::removedFocus()
+  {
+    GLGuiWidget::removedFocus();
+    this->pressedKey = 0;
+    this->pressedKeyName = 0;
+  }
+
+  /**
+   * @brief handles the EnterPush-Event.
+   *
+   * Emmits th EnterPushed Signal with the current Line,
+   * and if _clearOnEnter is pushed clears the Line.
+   */
+  void GLGuiInputLine::pushEnter()
+  {
+    this->enterPushed.emit(this->_text.text());
+    if (this->_clearOnEnter)
+      this->clear();
+  }
+
+
+  /**
+   * @brief Processes an Event.
+   * @param event The event to be processed
+   * @return true if the event was catched.
+   */
+  bool GLGuiInputLine::processEvent(const Event& event)
+  {
+    if (event.bPressed)
+    {
+      if (event.type == SDLK_BACKSPACE)
+      {
+        this->delayNext = GLGuiInputLine::repeatDelay;
+        this->pressedKey = SDLK_BACKSPACE;
+        this->pressedKeyName = SDLK_BACKSPACE;
+        this->removeCharacters(1);
+        return true;
+      }
+      else if(event.type == SDLK_RETURN || event.type == SDLK_KP_ENTER)
+      {
+        this->pushEnter();
+        return true;
+      }
+      // any other keyboard key
+      else if (likely(event.type < 127))
+      {
+        this->delayNext = GLGuiInputLine::repeatDelay;
+
+        this->appendCharacter(event.x);
+        this->pressedKey = event.type;
+        this->pressedKeyName = event.x;
+        return true;
+      }
+    }
+    else // if(!event.bPressed)
+    {
+      if (this->pressedKey == event.type)
+      {
+        this->pressedKeyName = 0;
+        this->pressedKey = 0;
+        this->delayNext = 0.0;
+        return true;
+      }
+    }
+    return false;
+  }
+
+
+  /**
+   * @brief Resizes the Widget to the new Size-constraints.
+   */
+  void GLGuiInputLine::resize()
+  {
+    this->_text.setRelCoor2D(borderLeft(), borderTop());
+    this->setSize2D( this->_text.getSize2D() + Vector2D(borderLeft() + borderRight(), borderTop() + borderBottom()));
+    GLGuiWidget::resize();
+    /*    this->frontRect().setTopLeft(borderLeft(), borderTop());
+        this->frontRect().setSize(this->getSize2D() - Vector2D(borderLeft() + borderRight(), borderTop() + borderBottom()));*/
+  }
+
+  void GLGuiInputLine::updateFrontColor()
+  {
+    this->_text.setColor(foregroundColor());
+  }
+
+  void GLGuiInputLine::hiding()
+  {
+    this->_text.setVisibility(false);
+  }
+
+  void GLGuiInputLine::showing()
+  {
+    this->_text.setVisibility(true);
+  }
+
+  /**
+   * @brief ticks the InputLine
+   * @param dt the time passed.
+   */
+  void GLGuiInputLine::tick(float dt)
+  {
+    GLGuiWidget::tick(dt);
+    if (this->delayNext > 0.0)
+      this->delayNext -= dt;
+    else if (this->pressedKey != SDLK_FIRST )
+    {
+      this->delayNext = GLGuiInputLine::repeatRate;
+      switch (this->pressedKey)
+      {
+        case SDLK_BACKSPACE:
+          this->removeCharacters(1);
+          break;
+        default:
+          {
+            if (likely(this->pressedKey < 127))
+              this->appendCharacter(this->pressedKeyName);
+          }
+      }
+    }
+
+
+  }
+
+  /**
+   * @brief draws the GLGuiInputLine
+   */
+  void GLGuiInputLine::draw() const
+  {
+    this->beginDraw();
+    GLGuiWidget::draw();
+
+    //     this->frontMaterial().select();
+    //     GLGuiWidget::drawRect(this->frontRect());
+
+    this->endDraw();
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_inputline.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_inputline.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_inputline.h	(revision 9940)
@@ -0,0 +1,81 @@
+/*!
+ * @file glgui_inputline.h
+ * The gl_INPUTLINE widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_INPUTLINE_H
+#define _GLGUI_INPUTLINE_H
+
+#include "glgui_widget.h"
+#include "limited_width_text.h"
+#include "event.h"
+
+// FORWARD DECLARATION
+namespace OrxGui
+{
+
+  //! This is InputLine part of the openglGUI class
+  /**
+   * The InputLine is a Widget, that displays a Line, that can be manipulated through
+   * Writing Text on it.
+   *
+   * Whenever the Text is changed the textChanged signal is emitted.
+   */
+  class GLGuiInputLine : public OrxGui::GLGuiWidget
+  {
+    ObjectListDeclaration(GLGuiInputLine);
+  public:
+    GLGuiInputLine();
+    virtual ~GLGuiInputLine();
+
+
+    /** @returns the text of the inputLine */
+    const std::string& _getText() const { return this->_text.text(); };
+
+    void setText(const std::string& text);
+    void append(const std::string& appendText);
+    void appendCharacter(char character);
+    void removeCharacters(unsigned int chars);
+    void clear();
+
+    void clearOnEnter(bool clear = true) { this->_clearOnEnter = clear; };
+
+    virtual void removedFocus();
+
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+    virtual bool processEvent(const Event& event);
+
+    sigslot::signal1<const std::string&> textChanged;
+    sigslot::signal1<const std::string&> enterPushed;
+
+  protected:
+    virtual void updateFrontColor();
+    virtual void hiding();
+    virtual void showing();
+    virtual void resize();
+
+
+  private:
+    void init();
+    void pushEnter();
+    void changedText();
+
+
+  private:
+    LimitedWidthText        _text;            //!< The Text to display inside of the InputLine.
+    bool                    _clearOnEnter;    //!< Clear on Enter
+
+    Uint16                  pressedKey;       //!< the pressed key that will be repeated.
+    Uint16                  pressedKeyName;   //!< The Name of the Key, that was pressed.
+
+    float                   delayNext;        //!< How much time must pass before next output.
+
+    static float            repeatDelay;      //!< Repead Delay.
+    static float            repeatRate;       //!< Repeat Rate.
+  };
+}
+
+#endif /* _GLGUI_INPUTLINE_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_mainwidget.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_mainwidget.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_mainwidget.cc	(revision 9940)
@@ -0,0 +1,45 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_mainwidget.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiMainWidget);
+
+  /**
+   * standard constructor
+   */
+  GLGuiMainWidget::GLGuiMainWidget()
+  {
+    this->registerObject(this, GLGuiMainWidget::_objectList);
+    this->setName("GLGuiMainWidget");
+  }
+
+  /**
+   *  the singleton reference to this class
+   */
+  GLGuiMainWidget* GLGuiMainWidget::singletonRef = NULL;
+
+  /**
+   * standard deconstructor
+   */
+  GLGuiMainWidget::~GLGuiMainWidget ()
+  {
+    GLGuiMainWidget::singletonRef = NULL;
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_mainwidget.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_mainwidget.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_mainwidget.h	(revision 9940)
@@ -0,0 +1,32 @@
+/*!
+ * @file glgui_mainwidget.h
+ * @brief Definition of the glGui singleton Class
+ */
+
+#ifndef _GLGUI_MAINWIDGET_H
+#define _GLGUI_MAINWIDGET_H
+
+#include "glgui_widget.h"
+
+namespace OrxGui
+{
+
+  //! A default singleton class.
+  class GLGuiMainWidget : public GLGuiWidget
+  {
+    ObjectListDeclaration(GLGuiMainWidget);
+  public:
+    virtual ~GLGuiMainWidget(void);
+    /** @returns a Pointer to the only object of this Class */
+    inline static GLGuiMainWidget* getInstance(void) { if (!GLGuiMainWidget::singletonRef) GLGuiMainWidget::singletonRef = new GLGuiMainWidget();  return GLGuiMainWidget::singletonRef; };
+
+  virtual void update() {};
+    virtual void draw() const {};
+
+  private:
+    GLGuiMainWidget(void);
+    static GLGuiMainWidget*       singletonRef;
+  };
+}
+
+#endif /* _GLGUI_MAINWIDGET_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_menu.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_menu.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_menu.cc	(revision 9940)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiMenu);
+  /**
+   * standard constructor
+  */
+  GLGuiMenu::GLGuiMenu ()
+  {
+    this->init();
+
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGuiMenu::~GLGuiMenu()
+  {
+  }
+
+  /**
+   * initializes the GUI-element
+   */
+  void GLGuiMenu::init()
+  {
+    this->setClassID(CL_GLGUI_MENU, "GLGuiMenu");
+
+  }
+
+  /**
+   * draws the GLGuiMenu
+   */
+  void GLGuiMenu::draw()
+  {
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_menu.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_menu.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_menu.h	(revision 9940)
@@ -0,0 +1,41 @@
+/*!
+ * @file glgui_menu.h
+ * The gl_Menu widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_MENU_H
+#define _GLGUI_MENU_H
+
+#include "base_object.h"
+namespace OrxGui
+{
+
+  // FORWARD DECLARATION
+  //! This is Menu part of the openglGUI class
+  /**
+   *
+   */
+  class GLGuiMenu : public GLGuiMenu
+  {
+    ObjectListDeclaration(GLGuiMenu);
+  public:
+    GLGuiMenu();
+    virtual ~GLGuiMenu();
+
+    void init();
+
+    void addItem(const std::string& itemName);
+    void removeItem(const std::string& itemName);
+    void removeItem(unsigned int itemNumber);
+    void selectItem(const std::string& itemName);
+    void selectItem(unsigned int itemNumber);
+
+    virtual void draw();
+
+  private:
+    std::list<std::string>         itemList;
+
+  };
+}
+#endif /* _GLGUI_MENU_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_pushbutton.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_pushbutton.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_pushbutton.cc	(revision 9940)
@@ -0,0 +1,106 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_pushbutton.h"
+
+#include "text.h"
+#include "material.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiPushButton);
+  /**
+   * @brief standard constructor
+   */
+  GLGuiPushButton::GLGuiPushButton (const std::string& label)
+  : GLGuiButton(label)
+  {
+    this->init();
+
+    this->resize();
+  }
+
+
+  /**
+   * @brief standard deconstructor
+  */
+  GLGuiPushButton::~GLGuiPushButton()
+  {
+  }
+
+  void GLGuiPushButton::resize()
+  {
+    this->labelText().setRelCoor2D(borderLeft(), borderTop());
+    this->setSize2D(this->labelText().getSizeX2D() + borderLeft() + borderRight(), this->labelText().getSizeY2D() + borderTop() + borderBottom() );
+
+    GLGuiWidget::resize();
+/*    this->frontRect().setTopLeft(borderLeft(), borderTop());
+    this->frontRect().setSize(this->getSizeX2D() - (borderLeft() + borderRight()), this->getSizeY2D() - (borderTop() + borderBottom()));*/
+  }
+
+  /**
+   * initializes the GUI-element
+   */
+  void GLGuiPushButton::init()
+  {
+    this->registerObject(this, GLGuiPushButton::_objectList);
+  }
+
+  void GLGuiPushButton::receivedFocus()
+  {
+    GLGuiWidget::receivedFocus();
+  }
+
+  void GLGuiPushButton::removedFocus()
+  {
+    GLGuiWidget::removedFocus();
+
+  }
+
+  void GLGuiPushButton::clicking(const Vector2D& pos)
+  {
+    GLGuiButton::clicking(pos);
+  }
+
+
+  void GLGuiPushButton::releasing(const Vector2D& pos, bool focused)
+  {
+    if (focused)
+      GLGuiButton::releasing(pos, focused);
+  }
+
+
+
+  /**
+   * @brief draws the GLGuiPushButton
+   */
+  void GLGuiPushButton::draw() const
+  {
+    this->beginDraw();
+    GLGuiButton::draw();
+
+    this->endDraw();
+  }
+
+  /**
+   * updates the GLGuiPushButton
+   */
+  void GLGuiPushButton::update()
+  {
+
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_pushbutton.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_pushbutton.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_pushbutton.h	(revision 9940)
@@ -0,0 +1,48 @@
+/*!
+ * @file glgui_pushbutton.h
+ * The gl_pushbutton widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_PUSHBUTTON_H
+#define _GLGUI_PUSHBUTTON_H
+
+#include "glgui_button.h"
+
+namespace OrxGui
+{
+
+  // FORWARD DECLARATION
+
+  //! This is part of the openglGUI class
+  /**
+   *
+   */
+  class GLGuiPushButton : public GLGuiButton
+  {
+    ObjectListDeclaration(GLGuiPushButton);
+  public:
+    GLGuiPushButton(const std::string& label = "");
+    virtual ~GLGuiPushButton();
+
+
+
+
+    virtual void draw() const;
+    virtual void update();
+
+  protected:
+    virtual void resize();
+    virtual void clicking(const Vector2D& pos);
+    virtual void releasing(const Vector2D& pos, bool focused);
+    virtual void receivedFocus();
+    virtual void removedFocus();
+
+
+
+  private:
+    void init();
+
+  };
+}
+#endif /* _GLGUI_PUSHBUTTON_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_slider.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_slider.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_slider.cc	(revision 9940)
@@ -0,0 +1,272 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_slider.h"
+#include "event_def.h"
+
+#include "glgui_handler.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiSlider);
+  /**
+   * @brief standard constructor
+   */
+  GLGuiSlider::GLGuiSlider ()
+  {
+    this->init();
+
+  }
+
+
+  /**
+   * @brief standard deconstructor
+   */
+  GLGuiSlider::~GLGuiSlider()
+  {}
+
+  /**
+   * @brief initializes the GUI-element
+   */
+  void GLGuiSlider::init()
+  {
+
+    this->registerObject(this, GLGuiSlider::_objectList);
+
+    this->setClickable(true);
+    this->setFocusable(true);
+    this->setSelectable(true);
+
+    this->_value = 0.0;
+    this->_minValue = 0.0;
+    this->_maxValue = 1.0;
+    this->_step = 0.1;
+    this->_sliderWidth = 5.0;
+    this->grabbed = false;
+
+    this->setSize2D(100, 30);
+    this->resize();
+  }
+
+  /**
+   * @param value the new Value.
+   * @note will automatically be set between max() and min()
+   */
+  void GLGuiSlider::setValue(float value)
+  {
+    if (value < this->min())
+      this->_value = min();
+    else if (value > max())
+      this->_value = max();
+    else
+      this->_value = value;
+    this->_handle.setCenter(this->sliderPosition(), borderTop() + (this->getSizeY2D() - borderTop() - borderBottom()) / 2.0);
+
+    valueChanged.emit(this->_value);
+  }
+
+  /**
+   * @param minimum the minumum of the range.
+   *
+   * @note will rearange value if necessary and will not be made bigger than max()
+   */
+  void GLGuiSlider::setMin(float minimum)
+  {
+    if (minimum <= max())
+    {
+      this->_minValue = minimum;
+      rangeChanged.emit(this->_minValue, this->_maxValue);
+    }
+    if (this->value() < this->min())
+      this->setValue(this->min());
+  }
+
+
+  /**
+   * @param maximum the maximum of the range.
+   *
+   * @note will rearange value if necessary and will not be made smaller than min()
+   */
+  void GLGuiSlider::setMax(float maximum)
+  {
+    if (maximum >= min())
+    {
+      this->_maxValue = maximum;
+      rangeChanged.emit(this->_minValue, this->_maxValue);
+    }
+    if (this->value() > this->max())
+      this->setValue(this->max());
+  }
+
+  /**
+   * @param minimum the minimum
+   * @param maximum the maximum
+   *
+   * @see setMax
+   * @see setMin
+   */
+  void GLGuiSlider::setRange(float minimum, float maximum)
+  {
+    if (minimum < maximum)
+    {
+      this->_minValue = minimum;
+      this->_maxValue = maximum;
+      rangeChanged.emit(this->_minValue, this->_maxValue);
+    }
+    if (this->value() < this->min())
+      this->setValue(this->min());
+    else if (this->value() > this->max())
+      this->setValue(this->max());
+  }
+
+  /**
+   * @brief sets the stepSize
+   */
+  void GLGuiSlider::setStep(float step)
+  {
+    this->_step = step;
+  }
+
+  /**
+   * @brief makes one step into the minus direction
+   */
+  void GLGuiSlider::stepMinus()
+  {
+    this->setValue(value() - step());
+  }
+
+  /**
+   * @brief makes one step into the minus direction
+   */
+  void GLGuiSlider::stepPlus()
+  {
+    this->setValue(value() + step());
+  }
+
+  /**
+   * @brief resizes the Slider, and through this Synchronizes the GUI-size.
+   */
+  void GLGuiSlider::resize()
+  {
+    GLGuiWidget::resize();
+//    this->frontRect().setTopLeft(this->borderLeft(), this->getSizeY2D()/2.0 - 2.0);
+//    this->frontRect().setSize(this->getSizeX2D() - borderLeft() - borderRight(), 4.0);
+    this->_slider.setTopLeft(borderLeft(), this->getSizeY2D() / 2.0 -2.0);
+    this->_slider.setSize(this->getSizeX2D() - borderLeft() - borderRight(), 4.0);
+    this->_handle.setSize(this->_sliderWidth, this->getSizeY2D() - borderTop() - borderBottom());
+  }
+
+  void GLGuiSlider::updateFrontColor()
+  {
+
+  }
+
+  /**
+   * @brief handle the clicked event.
+   * @param pos the position the Click occured (from the topleft corner out)
+   */
+  void GLGuiSlider::clicking(const Vector2D& pos)
+  {
+    GLGuiWidget::clicking(pos);
+
+    float sliderPosition = this->sliderPosition();
+    if (sliderPosition > pos.x + this->_sliderWidth)
+      this->setValue(this->value() - this->step());
+
+    else if (sliderPosition < pos.x - this->_sliderWidth)
+      this->setValue(this->value() + this->step());
+    else
+      this->grabbed = true;
+  }
+
+  void GLGuiSlider::releasing(const Vector2D& pos, bool focused)
+  {
+    GLGuiWidget::releasing(pos, focused);
+    this->grabbed = false;
+  }
+
+  void GLGuiSlider::removedFocus()
+  {
+    GLGuiWidget::removedFocus();
+  }
+
+  /**
+   * @returns the current SliderPosition calculated from the current value and the Silders' size.
+   */
+  float GLGuiSlider::sliderPosition() const
+  {
+    return (this->_value - this->_minValue)/( this->_maxValue - this->_minValue) *
+        (this->getSizeX2D() - (borderLeft() + borderRight() + 2.0*_sliderWidth)) +
+        (borderLeft() +_sliderWidth);
+  }
+
+  /**
+   * @param position the position relative from the left border.
+   * @returns the Value at the given position.
+   */
+  float GLGuiSlider::sliderValue(float position) const
+  {
+    return (position - (borderLeft()+_sliderWidth)) / (this->getSizeX2D() - (borderLeft() + borderRight() + 2.0*_sliderWidth))
+           *( this->_maxValue - this->_minValue) +
+           this->_minValue ;
+  }
+
+  void GLGuiSlider::tick(float dt)
+  {
+    GLGuiWidget::tick(dt);
+  }
+
+  /**
+   * @brief draws the GLGuiSlider
+   */
+  void GLGuiSlider::draw() const
+  {
+    this->beginDraw();
+    GLGuiWidget::draw();
+
+    glColor4fv(&this->foregroundColor()[0]);
+    this->drawRect(this->_slider);
+    this->drawRect(this->_handle);
+    //this->drawRect(Rect2D(this->sliderPosition()-_sliderWidth/2.0, 0*this->borderTop(), _sliderWidth, this->getSizeY2D() - (borderTop() + borderBottom()) ));
+
+    this->endDraw();
+  }
+
+
+  bool GLGuiSlider::processEvent( const Event& event )
+  {
+    if (this->grabbed && event.type == EV_MOUSE_MOTION)
+    {
+      this->setValue(sliderValue(GLGuiHandler::getInstance()->cursorPositionRel(this).x));
+      return true;
+    }
+    else if (event.bPressed)
+    {
+      if (event.type == SDLK_LEFT)
+      {
+        this->stepMinus();
+        return true;
+      }
+      else if (event.type == SDLK_RIGHT)
+      {
+        this->stepPlus();
+        return true;
+      }
+    }
+    return false;
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_slider.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_slider.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_slider.h	(revision 9940)
@@ -0,0 +1,87 @@
+/*!
+ * @file glgui_slider.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_SLIDER_H
+#define _GLGUI_SLIDER_H
+
+#include "glgui_widget.h"
+#include "glgui_defs.h"
+
+namespace OrxGui
+{
+  // FORWARD DECLARATION
+
+  //! This is part of the openglGUI class
+  /**
+   * The Slider is a Widget, with a Range and a Value.
+   */
+  class GLGuiSlider : public GLGuiWidget
+  {
+    ObjectListDeclaration(GLGuiSlider);
+  public:
+    GLGuiSlider();
+    virtual ~GLGuiSlider();
+
+    /** @returns the Value of the Slider. */
+    float value() const { return this->_value; }
+    /** @returns the minimum of the sliders range */
+    float min() const { return this->_minValue; };
+    /** @returns the maximum of the sliders range */
+    float max() const { return this->_maxValue; };
+    /** @returns the step size */
+    float step() const { return this->_step; };
+
+    void setValue(float value);
+
+    void setMin(float minimum);
+    void setMax(float maximum);
+    void setRange(float minimum, float maximum);
+
+    void setStep(float step);
+
+    void stepPlus();
+    void stepMinus();
+
+
+    virtual void tick(float dt);
+    virtual bool processEvent(const Event& event);
+    virtual void draw() const;
+
+    sigslot::signal1<float> valueChanged;
+    sigslot::signal2<float, float> rangeChanged;
+
+  protected:
+    virtual void resize();
+    virtual void updateFrontColor();
+
+    virtual void clicking(const Vector2D& pos);
+    virtual void releasing(const Vector2D& pos, bool focused);
+    virtual void removedFocus();
+
+  private:
+    void init();
+    float sliderPosition() const;
+    float sliderValue(float position) const;
+
+  private:
+    Orientation      orientation;
+
+    Rect2D           _slider;
+    Rect2D           _handle;
+
+    float            _maxValue;
+    float            _minValue;
+    float            _step;
+
+    float            _value;
+
+    float            _sliderWidth;
+
+    bool             grabbed;
+
+  };
+}
+#endif /* _GLGUI_SLIDER_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_table.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_table.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_table.cc	(revision 9940)
@@ -0,0 +1,372 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_table.h"
+#include "debug.h"
+
+#include "glgui_handler.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiTable);
+  /**
+   * @brief standard constructor
+   */
+  GLGuiTable::GLGuiTable (unsigned int rows, unsigned int columns)
+  : _selected(-1, -1), _focused(-1, -1)
+  {
+    this->init();
+
+    this->setRowCount(rows);
+    this->setColumnCount(columns);
+  }
+
+
+  /**
+   * @brief standard deconstructor
+   */
+  GLGuiTable::~GLGuiTable()
+  {}
+
+  /**
+   * @brief initializes the GUI-element
+   */
+  void GLGuiTable::init()
+  {
+    this->registerObject(this, GLGuiTable::_objectList);
+
+    this->setBorderTop(10);
+
+    this->setFocusable(true);
+    this->setClickable(true);
+
+  }
+
+
+  void GLGuiTable::setRowCount(unsigned int rowCount)
+  {
+
+    unsigned int currentRowCount = this->rowCount();
+
+    this->_rowHeights.resize(rowCount, 20);
+
+    this->_entries.resize(rowCount);
+    for (unsigned int i = currentRowCount; i < this->rowCount(); ++i)
+    {
+      this->_entries[i].resize(columnCount(), LimitedWidthText("fonts/final_frontier.ttf", 20));
+      for (unsigned int j = 0; j < columnCount(); ++j)
+        this->applyTextSettings(i, j, &this->_entries[i][j]);
+    }
+
+    assert(this->checkIntegrity());
+    this->repositionText(currentRowCount, 0);
+
+
+    this->resize();
+
+    if (!this->isVisible())
+      this->hiding();
+  }
+
+  void GLGuiTable::setColumnCount(unsigned int columnCount)
+  {
+    unsigned int i;
+    unsigned int currentColumnCount = this->columnCount();
+
+    this->_columnWidths.resize(columnCount, 100);
+
+    // setup Headers.
+    this->_headers.resize(columnCount, LimitedWidthText("fonts/final_frontier.ttf", 20));
+    for (i = currentColumnCount; i < columnCount; ++i)
+      this->applyTextSettings(0, i, &this->_headers[i]);
+
+    for (i = 0; i < rowCount(); i++)
+    {
+      this->_entries[i].resize(columnCount, LimitedWidthText("fonts/final_frontier.ttf", 20));
+      for (unsigned int j = currentColumnCount; j < columnCount; ++j)
+        this->applyTextSettings(i, j, &this->_entries[i][j]);
+
+    }
+    assert(this->checkIntegrity());
+
+    this->repositionText(0, currentColumnCount);
+
+    this->resize();
+    if (!this->isVisible())
+      this->hiding();
+  }
+
+
+
+
+  void GLGuiTable::setHeader(unsigned int number, const std::string& headerName)
+  {
+    if (number >= this->columnCount())
+      this->setColumnCount(number + 1);
+    this->_headers[number].setText(headerName);
+  }
+
+  void GLGuiTable::setHeader(const std::vector<std::string>& headerNames)
+  {
+    for (unsigned int i = 0; i < headerNames.size(); ++i)
+      this->setHeader(i, headerNames[i]);
+  }
+
+  void GLGuiTable::setEntry(unsigned int row, unsigned int column, const std::string& name)
+  {
+    if (column >= this->columnCount() )
+      this->setColumnCount(column + 1);
+    if (row >= this->rowCount() )
+      this->setRowCount(row + 1);
+    this->_entries[row][column].setText(name);
+  }
+
+  void GLGuiTable::setColumnWidth(unsigned int column, float size)
+  {
+    this->_headers[column].setLineWidth(size);
+    for (unsigned int i = 0; i < this->rowCount(); ++i)
+      this->_entries[i][column].setLineWidth(size);
+  }
+
+
+
+  /// TODO.
+  void GLGuiTable::setRowHeight(unsigned int row, unsigned int size)
+{}
+
+
+
+
+  /**
+   * removes the focus from this Widget.
+   */
+  void GLGuiTable::removedFocus()
+  {
+    GLGuiWidget::removedFocus();
+  }
+
+
+  /**
+   * @brief Processes an Event.
+   * @param event The event to be processed
+   * @return true if the event was catched.
+   */
+  bool GLGuiTable::processEvent(const Event& event)
+  {
+    if (event.type == EV_MOUSE_MOTION)
+    {
+      this->pixelPositionToElement((OrxGui::GLGuiHandler::getInstance()->cursorPositionRel(this)), &this->_focused.row, &this->_focused.column);
+      return true;
+    }
+
+    return false;
+  }
+
+
+  /**
+   * @brief Resizes the Widget to the new Size-constraints.
+   */
+  void GLGuiTable::resize()
+  {
+    Vector2D size;
+    unsigned int i;
+    for(i = 0; i < this->columnCount(); ++i)
+      size.x += this->_columnWidths[i];
+
+    for(i = 0; i < this->rowCount(); ++i)
+      size.y += this->_rowHeights[i];
+
+    this->setSize2D(size);
+    this->setSize2D( size + Vector2D(borderLeft() + borderRight(), borderTop() + borderBottom()));
+
+    GLGuiWidget::resize();
+  }
+
+  void GLGuiTable::updateFrontColor()
+  {
+    for (unsigned int i = 0; i < this->columnCount(); ++i)
+    {
+      this->_headers[i].setColor(this->foregroundColor());
+      for (unsigned int j = 0; j < this->rowCount(); ++j)
+        this->_entries[j][i].setColor(this->foregroundColor());
+    }
+
+  }
+
+  void GLGuiTable::hiding()
+  {
+    for (unsigned int i = 0; i < this->columnCount(); ++i)
+    {
+      this->_headers[i].setVisibility(false);
+      for (unsigned int j = 0; j < this->rowCount(); ++j)
+        this->_entries[j][i].setVisibility(false);
+    }
+  }
+
+  void GLGuiTable::showing()
+  {
+    for (unsigned int i = 0; i < this->columnCount(); ++i)
+    {
+      this->_headers[i].setVisibility(true);
+      for (unsigned int j = 0; j < this->rowCount(); ++j)
+        this->_entries[j][i].setVisibility(true);
+    }
+  }
+
+
+  /**
+   * @brief draws the GLGuiTable
+   */
+  void GLGuiTable::draw() const
+  {
+    this->beginDraw();
+    GLGuiWidget::draw();
+
+    float columnPos = this->borderLeft();
+    float rowPos = this->borderTop();
+
+    unsigned int i;
+    glColor4fv(&this->foregroundColor()[0]);
+    glLineWidth(1.5);
+    glBegin(GL_LINES);
+
+    glVertex2f(columnPos, this->borderTop());
+    glVertex2f(columnPos, this->getSizeY2D());
+    for (i = 0; i < this->columnCount(); ++i)
+    {
+      columnPos +=this->_columnWidths[i];
+      glVertex2f(columnPos, this->borderTop());
+      glVertex2f(columnPos, this->getSizeY2D());
+    }
+
+    glVertex2f(this->borderLeft(), rowPos);
+    glVertex2f(this->getSizeX2D(), rowPos);
+    for (i = 0; i < this->rowCount(); ++i)
+    {
+      rowPos +=this->_rowHeights[i];
+      glVertex2f(this->borderLeft(), rowPos);
+      glVertex2f(this->getSizeX2D(), rowPos);
+    }
+
+
+    glEnd();
+
+
+
+    this->endDraw();
+  }
+
+
+  void GLGuiTable::pixelPositionToElement(const Vector2D& pixelPosition, int* row, int* column)
+  {
+    *row = 0;
+    *column = 0;
+    float columnPos = this->borderLeft();
+    float rowPos = this->borderTop();
+
+    for (*row = 0; *row < (int)this->rowCount(); (*row)++)
+    {
+      if (pixelPosition.y > rowPos  && pixelPosition.y  < (rowPos += _rowHeights[*row]))
+        break;
+    }
+    for (*column = 0; *column < (int)this->columnCount(); (*column)++)
+    {
+      if (pixelPosition.x > columnPos && pixelPosition.x  < (columnPos += _columnWidths[*column]))
+        break;
+    }
+
+    PRINTF(3)("Mouse Over row:%d Column:%d\n", *row, *column);
+  }
+
+
+  void GLGuiTable::repositionText(unsigned int fromLeft, unsigned int fromTop)
+  {
+    float columnPos = this->borderLeft();
+    float rowPos = this->borderTop();
+    unsigned int i, j;
+    for (i = 0; i< fromLeft; ++i)
+      columnPos+=this->_columnWidths[i];
+    for (i = 0; i < fromTop; ++i)
+      rowPos += this->_rowHeights[i];
+
+    for (i = fromLeft; i < this->columnCount(); ++i)
+    {
+      this->_headers[i].setRelCoor2D(columnPos, rowPos);
+
+      // not required, but a good idea :)
+      this->_headers[i].setLineWidth(_columnWidths[i]);
+
+      float rowPosI = rowPos;
+      for (j = fromTop; j < this->rowCount(); ++j)
+      {
+        this->_entries[j][i].setRelCoor2D(columnPos, rowPosI);
+        this->_entries[j][i].setLineWidth(_columnWidths[i]);
+        rowPosI += _rowHeights[j];
+      }
+      columnPos+=this->_columnWidths[i];
+    }
+  }
+
+  /**
+   * @brief applies the GLGuiNotifiers Settings to a single Text of the GLGuiNotifier.
+   * @param text the Text to apply the settings to.
+   */
+  void GLGuiTable::applyTextSettings(unsigned int row, unsigned int column, LimitedWidthText* text)
+  {
+    text->setSize(this->textSize());
+    text->setLineWidth( this->_columnWidths[column] );
+    text->setFont("fonts/final_frontier.ttf", (int)this->textSize());
+    text->setColor(this->foregroundColor());
+
+    text->setColor(this->foregroundColor());
+    if (text->getParent2D() != this)
+      text->setParent2D(this);
+  }
+
+
+  void GLGuiTable::debug() const
+  {
+    PRINT(0)("Table: Size = %dx%d\n", this->rowCount(), this->columnCount());
+
+    for (unsigned int i = 0; i < this->rowCount(); ++i)
+      PRINT(0)("line %d: columns %d\n", i, this->_entries[i].size());
+  }
+
+
+  bool GLGuiTable::checkIntegrity() const
+  {
+    bool retVal = true;
+    if (rowCount() != this->_entries.size())
+    {
+      PRINTF(1)("ROW COUNT WRONG (is %d should be %d)\n", rowCount(), this->_entries.size());
+      retVal = false;
+    }
+    if (columnCount() != this->_headers.size())
+    {
+      PRINTF(1)("COLUMN COUNT WRONG (is %d should be %d)\n", columnCount(), this->_headers.size());
+      retVal = false;
+    }
+    for (unsigned int i = 0; i < this->rowCount(); ++i)
+      if (this->_entries[i].size() != this->columnCount())
+      {
+        PRINTF(1)("COLUMN-COUNT OF ROW %d WRONG (is %d should be %d)\n", i, this->_entries[i].size(), this->columnCount());
+        retVal = false;
+      }
+    return retVal;
+  }
+
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_table.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_table.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_table.h	(revision 9940)
@@ -0,0 +1,90 @@
+/*!
+ * @file glgui_table.h
+ * The gl_TABLE widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_TABLE_H
+#define _GLGUI_TABLE_H
+
+#include "glgui_widget.h"
+#include "limited_width_text.h"
+#include "event.h"
+
+// FORWARD DECLARATION
+namespace OrxGui
+{
+
+  //! This is Table part of the openglGUI class
+  /**
+   * The Table is a Widget, that displays a Line, that can be manipulated through
+   * Writing Text on it.
+   *
+   * Whenever the Text is changed the textChanged signal is emitted.
+   */
+  class GLGuiTable : public OrxGui::GLGuiWidget
+  {
+    ObjectListDeclaration(GLGuiTable);
+  public:
+    GLGuiTable(unsigned int rows, unsigned int columns);
+    virtual ~GLGuiTable();
+
+    unsigned int rowCount() const { return this->_entries.size(); };
+    unsigned int columnCount() const { return this->_headers.size(); };
+
+    void setRowCount(unsigned int rowCount);
+    void setColumnCount(unsigned int columnCount);
+
+    void setHeader(unsigned int number, const std::string& headerName);
+    void setHeader(const std::vector<std::string>& headerNames);
+
+    void setEntry(unsigned int row, unsigned int column, const std::string& name);
+
+    void setColumnWidth(unsigned int column, float size);
+    void setRowHeight(unsigned int row, unsigned int size);
+
+    virtual void draw() const;
+
+
+    void debug() const;
+
+  protected:
+    virtual void removedFocus();
+
+    virtual void updateFrontColor();
+    virtual void hiding();
+    virtual void showing();
+    virtual void resize();
+
+    virtual bool processEvent(const Event& event);
+
+  private:
+    void init();
+
+    void pixelPositionToElement(const Vector2D& pixelPosition, int* row, int* column);
+    void repositionText(unsigned int fromLeft, unsigned int fromTop);
+    void applyTextSettings(unsigned int row, unsigned int column, LimitedWidthText* text);
+    bool checkIntegrity() const;
+
+  private:
+    typedef struct Entry {
+      Entry(int row, int column) :row(row), column(column) {};
+      int  row;
+      int  column;
+    };
+
+    typedef std::vector<LimitedWidthText> TableTextList;
+    TableTextList                _headers;
+    std::vector<float>           _columnWidths;
+    std::vector<float>           _rowHeights;
+
+    std::vector<TableTextList>   _entries;     //!< inner is by column, outer is by row.
+
+    Entry                        _selected;
+    Entry                        _focused;
+
+
+  };
+}
+
+#endif /* _GLGUI_TABLE_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_text.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_text.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_text.cc	(revision 9940)
@@ -0,0 +1,180 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_text.h"
+
+#include "text.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiText);
+  /**
+   * standard constructor
+  */
+  GLGuiText::GLGuiText ()
+  {
+    this->init();
+
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGuiText::~GLGuiText()
+  {}
+
+  /**
+   * initializes the GUI-element
+   */
+  void GLGuiText::init()
+  {
+    this->registerObject(this, GLGuiText::_objectList);
+
+    this->_text.setParent2D(this);
+    this->_text.setRelCoor2D(4,4);
+    this->_text.setFont("fonts/final_frontier.ttf", 20);
+    this->_text.setLineWidth(400);
+    this->_text.setDotsPosition(LimitedWidthText::Begin);
+    this->_text.setColor(foregroundColor());
+    this->_text.setVisibility(false);
+    this->_changedTextColor = Color::white;
+    this->resize();
+  }
+
+  /**
+  * @brief sets the Text of the Text
+  * @param text The new Text.
+   */
+  void GLGuiText::setText(const std::string& text)
+  {
+    this->_text.setText(text);
+    this->changedText();
+  }
+
+  /**
+   * @brief appends text to the Text
+   * @param appendText the Text to append
+   */
+  void GLGuiText::append(const std::string& appendText)
+  {
+    this->_text.append(appendText);
+    this->changedText();
+  }
+
+
+  /**
+   * @brief appends a Character to the Text
+   * @param character the Character to append.
+   */
+  void GLGuiText::appendCharacter(char character)
+  {
+    this->_text.appendCharacter(character);
+    this->changedText();
+  }
+
+
+  /**
+   * @brief Removes Characters from the Text
+   * @param chars The count of characters to remove
+   */
+  void GLGuiText::removeCharacters(unsigned int chars)
+  {
+    this->_text.removeCharacters(chars);
+    this->changedText();
+  }
+
+  void GLGuiText::clear()
+  {
+    this->_text.clear();
+    this->resize();
+  }
+
+
+  /**
+  * @brief If the Text has been changed this function is called.
+  *
+  * This Function also emits the Signal textChanged.
+   */
+  void GLGuiText::changedText()
+  {
+    this->resize();
+    this->setFrontColor(_changedTextColor, true);
+    this->textChanged.emit(this->_text.text());
+  }
+
+  void GLGuiText::setTextSize(float size)
+  {
+    this->_text.setSize(size);
+    this->changedText();
+  }
+
+  void GLGuiText::setFont(const Font& font)
+  {
+    GLGuiWidget::setFont(font);
+    this->_text.setFont(font);
+  }
+
+  void GLGuiText::setChangedTextColor(const Color& color)
+  {
+    this->_changedTextColor = color;
+  }
+
+  /**
+   * @brief Resizes the Widget to the new Size-constraints.
+   */
+  void GLGuiText::resize()
+  {
+    this->_text.setRelCoor2D(borderLeft(), borderTop());
+    this->setSize2D( this->_text.getSize2D() + Vector2D(borderLeft() + borderRight(), borderTop() + borderBottom()));
+    //this->_text.setLineWidth(this->size2D);
+    GLGuiWidget::resize();
+    /*    this->frontRect().setTopLeft(borderLeft(), borderTop());
+    this->frontRect().setSize(this->getSize2D() - Vector2D(borderLeft() + borderRight(), borderTop() + borderBottom()));*/
+  }
+
+  void GLGuiText::updateFrontColor()
+  {
+    this->_text.setColor(foregroundColor());
+  }
+
+  void GLGuiText::hiding()
+  {
+    this->_text.setVisibility(false);
+  }
+
+  void GLGuiText::showing()
+  {
+    this->_text.setVisibility(true);
+  }
+
+
+
+  /**
+   * draws the GLGuiText
+   */
+  void GLGuiText::draw() const
+  {
+    this->beginDraw();
+    GLGuiWidget::draw();
+
+    //     this->frontMaterial().select();
+    //     GLGuiWidget::drawRect(this->frontRect());
+
+    this->endDraw();
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_text.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_text.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_text.h	(revision 9940)
@@ -0,0 +1,65 @@
+/*!
+ * @file glgui_text.h
+ * The gl_TEXT widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_TEXT_H
+#define _GLGUI_TEXT_H
+
+#include "glgui_widget.h"
+#include "limited_width_text.h"
+// FORWARD DECLARATION
+namespace OrxGui
+{
+
+  //! This is part of the openglGUI class
+  /**
+   *
+   */
+  class GLGuiText : public GLGuiWidget
+  {
+    ObjectListDeclaration(GLGuiText);
+  public:
+    GLGuiText();
+    virtual ~GLGuiText();
+
+    void setText(const std::string& text);
+    void append(const std::string& appendText);
+    void appendCharacter(char character);
+    void removeCharacters(unsigned int chars);
+    void clear();
+
+    void setTextSize(float size);
+    virtual void setFont(const Font& font);
+    void setChangedTextColor(const Color& color);
+
+    void setLineWidth(float lineWidth) { this->_text.setLineWidth(lineWidth); };
+    void setDotsPosition(LimitedWidthText::DotsPosition dotsPosition) { this->_text.setDotsPosition(dotsPosition); };
+
+    const std::string& text() const { return _text.text(); };
+
+
+    virtual void draw() const;
+
+    sigslot::signal1<const std::string&> textChanged;
+
+  protected:
+    virtual void updateFrontColor();
+    virtual void hiding();
+    virtual void showing();
+    virtual void resize();
+
+  private:
+    void init();
+    void changedText();
+
+
+  private:
+    LimitedWidthText    _text;
+
+    Color               _changedTextColor;
+  };
+}
+
+#endif /* _GLGUI_TEXT_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_textfield.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_textfield.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_textfield.cc	(revision 9940)
@@ -0,0 +1,166 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_textfield.h"
+
+#include "text.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiTextfield);
+  /**
+   * standard constructor
+  */
+  GLGuiTextfield::GLGuiTextfield ()
+  {
+    this->init();
+
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGuiTextfield::~GLGuiTextfield()
+  {}
+
+  /**
+   * initializes the GUI-element
+   */
+  void GLGuiTextfield::init()
+  {
+    this->registerObject(this, GLGuiTextfield::_objectList);
+
+    this->_text.setParent2D(this);
+    this->_text.setRelCoor2D(4,4);
+    this->_text.setFont("fonts/final_frontier.ttf", 20);
+    this->_text.setLineWidth(400);
+    this->_text.setColor(foregroundColor());
+    this->_text.setVisibility(false);
+    this->_changedTextColor = Color::white;
+    this->resize();
+  }
+
+  /**
+  * @brief sets the Text of the Text
+  * @param text The new Text.
+   */
+  void GLGuiTextfield::setText(const std::string& text)
+  {
+    this->_text.setText(text);
+    this->changedText();
+  }
+
+  /**
+   * @brief appends text to the Text
+   * @param appendText the Text to append
+   */
+  void GLGuiTextfield::append(const std::string& appendText)
+  {
+    this->_text.append(appendText);
+    this->changedText();
+  }
+
+
+  /**
+   * @brief appends a Character to the Text
+   * @param character the Character to append.
+   */
+  void GLGuiTextfield::appendCharacter(char character)
+  {
+    this->_text.appendCharacter(character);
+    this->changedText();
+  }
+
+
+  /**
+   * @brief Removes Characters from the Text
+   * @param chars The count of characters to remove
+   */
+  void GLGuiTextfield::removeCharacters(unsigned int chars)
+  {
+    this->_text.removeCharacters(chars);
+    this->changedText();
+  }
+
+  void GLGuiTextfield::clear()
+  {
+    this->_text.clear();
+    this->changedText();
+  }
+
+  /**
+  * @brief If the Text has been changed this function is called.
+  *
+  * This Function also emits the Signal textChanged.
+   */
+  void GLGuiTextfield::changedText()
+  {
+    this->resize();
+    this->setFrontColor(_changedTextColor, true);
+    this->textChanged.emit(this->_text.text());
+  }
+
+  void GLGuiTextfield::setChangedTextColor(const Color& color)
+  {
+    this->_changedTextColor = color;
+  }
+
+  /**
+   * @brief Resizes the Widget to the new Size-constraints.
+   */
+  void GLGuiTextfield::resize()
+  {
+    this->_text.setRelCoor2D(borderLeft(), borderTop());
+    this->setSize2D( this->_text.getSize2D() + Vector2D(borderLeft() + borderRight(), borderTop() + borderBottom()));
+    //this->_text.setLineWidth(this->size2D);
+    GLGuiWidget::resize();
+    /*    this->frontRect().setTopLeft(borderLeft(), borderTop());
+    this->frontRect().setSize(this->getSize2D() - Vector2D(borderLeft() + borderRight(), borderTop() + borderBottom()));*/
+  }
+
+  void GLGuiTextfield::updateFrontColor()
+  {
+    this->_text.setColor(foregroundColor());
+  }
+
+  void GLGuiTextfield::hiding()
+  {
+    this->_text.setVisibility(false);
+  }
+
+  void GLGuiTextfield::showing()
+  {
+    this->_text.setVisibility(true);
+  }
+
+
+
+  /**
+   * draws the GLGuiTextfield
+   */
+  void GLGuiTextfield::draw() const
+  {
+    this->beginDraw();
+    GLGuiWidget::draw();
+
+    //     this->frontMaterial().select();
+    //     GLGuiWidget::drawRect(this->frontRect());
+
+    this->endDraw();
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_textfield.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_textfield.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_textfield.h	(revision 9940)
@@ -0,0 +1,60 @@
+/*!
+ * @file glgui_textfield.h
+ * The gl_TEXTFIELD widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_TEXTFIELD_H
+#define _GLGUI_TEXTFIELD_H
+
+#include "glgui_widget.h"
+#include "multi_line_text.h"
+// FORWARD DECLARATION
+namespace OrxGui
+{
+
+  //! This is part of the openglGUI class
+  /**
+   *
+   */
+  class GLGuiTextfield : public GLGuiWidget
+  {
+    ObjectListDeclaration(GLGuiTextfield);
+  public:
+    GLGuiTextfield();
+    virtual ~GLGuiTextfield();
+
+    void setText(const std::string& text);
+    void append(const std::string& appendText);
+    void appendCharacter(char character);
+    void removeCharacters(unsigned int chars);
+    void clear();
+
+    void setChangedTextColor(const Color& color);
+
+    const std::string& text() const { return _text.text(); };
+
+
+    virtual void draw() const;
+
+    sigslot::signal1<const std::string&> textChanged;
+
+  protected:
+    virtual void updateFrontColor();
+    virtual void hiding();
+    virtual void showing();
+    virtual void resize();
+
+  private:
+    void init();
+    void changedText();
+
+
+  private:
+    MultiLineText      _text;
+
+    Color               _changedTextColor;
+  };
+}
+
+#endif /* _GLGUI_TEXTFIELD_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_widget.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_widget.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_widget.cc	(revision 9940)
@@ -0,0 +1,918 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_widget.h"
+
+#include "glgui_cursor.h"
+
+#include "material.h"
+
+#include "debug.h"
+
+#include "loading/load_param.h"
+#include "loading/resource_manager.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiWidget);
+  /**
+   * @brief standard constructor
+  */
+  GLGuiWidget::GLGuiWidget (GLGuiWidget* parent)
+  {
+    this->init();
+
+    this->setParentWidget(parent);
+  }
+
+
+  /**
+   * @brief loads Parameters for a Style from XML
+   * @param root the XML-Element to load from.
+   */
+  void GLGuiWidget::loadParams(const TiXmlElement* root)
+  {
+
+    /// STYLE
+    LoadParam(root, "border-left", this, GLGuiWidget, setBorderLeft);
+    LoadParam(root, "border-right", this, GLGuiWidget, setBorderRight);
+    LoadParam(root, "border-top", this, GLGuiWidget, setBorderTop);
+    LoadParam(root, "border-bottom", this, GLGuiWidget, setBorderBottom);
+
+    LoadParam(root, "text-size", this, GLGuiWidget, setTextSize);
+    LoadParam(root, "background-color", this, GLGuiWidget, setBackgroundColorS);
+    LoadParam(root, "foreground-color", this, GLGuiWidget, setForegroundColorS);
+
+    //    LoadParamXML(root, "backmat", this, GLGuiWidget, loadBackgroundMaterial);
+    //    LoadParamXML(root, "frontmat", this, GLGuiWidget, loadForegroundMaterial);
+
+    LoadParam(root, "feature-position", this, GLGuiWidget, setFeaturePositionS);
+    LoadParam(root, "Font", this, GLGuiWidget, setFont);
+
+    LoadParam(root, "animated-state-changes", this, GLGuiWidget, setAnimatedStateChanges);
+  }
+
+
+  /**
+   * @brief standard deconstructor
+   */
+  GLGuiWidget::~GLGuiWidget()
+  {
+    if (this == GLGuiWidget::_mouseFocused)
+      GLGuiWidget::_mouseFocused = NULL;
+    if (this == GLGuiWidget::selected())
+      this->unselect();
+
+    if (this->_parent != NULL)
+      this->_parent->removeChildWidget(this);
+  }
+
+  GLGuiWidget* GLGuiWidget::_selected = NULL;
+  GLGuiWidget* GLGuiWidget::_mouseFocused = NULL;
+  GLGuiWidget* GLGuiWidget::_inputGrabber = NULL;
+  Font* GLGuiWidget::_defaultFont = NULL;
+
+
+  /**
+   * initializes the GUI-element
+   */
+  void GLGuiWidget::init()
+  {
+    this->registerObject(this, GLGuiWidget::_objectList);
+
+    this->_focusable = false;
+    this->_clickable = false;
+    this->_selectable = false;
+    this->_pushed = false;
+    this->_state = OrxGui::Normal;
+
+    if(GLGuiWidget::_defaultFont == NULL)
+      GLGuiWidget::_defaultFont = new Font(Resources::ResourceManager::getInstance()->mainGlobalPath().name() + "/fonts/final_frontier.ttf", 20);
+
+    this->_font = *GLGuiWidget::_defaultFont;
+    this->resetStyle();
+
+    this->_animating = false;
+    this->_animationCycle = 0.0;
+    this->_animationDuration = 1.0;
+
+
+    this->setBackgroundColor(Color(.51, .3, .3, .5));
+    this->setBackgroundColor(Color(.3, .5, .3, 1), OrxGui::Selected);
+    this->_style[0]._background.setBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    this->_style[1]._background.setBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    this->_style[2]._background.setBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    this->_style[3]._background.setBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+    this->setForegroundColor(Color(.8, .8, 1, 1), OrxGui::Normal);
+    this->setForegroundColor(Color(0, .4, 1.0, 1), OrxGui::Selected);
+    this->setForegroundColor(Color(0, .0, 1.0, 1), OrxGui::Focused);
+    this->setForegroundColor(Color(.1, .1, .1, 1), OrxGui::Insensitive);
+
+    this->setVisibility(GLGUI_WIDGET_DEFAULT_VISIBLE);
+
+    this->setBorderLeft(15);
+    this->setBackgroundTexture("gui_element_background.png");
+
+    this->switchState(_state);
+    this->_currentStyle = this->_style[_state];
+  }
+
+
+  void GLGuiWidget::setParentWidget(GLGuiWidget* parent)
+  {
+    this->_parent = parent;
+
+    if (parent != NULL)
+      parent->addChild2D(this);
+  }
+
+
+  void GLGuiWidget::setFrontColor(const Color& frontColor, bool instantaniously)
+  {
+    this->_currentStyle._foreground.setDiffuseColor(frontColor);
+    this->animateBack();
+  };
+
+
+  bool GLGuiWidget::focusOverWidget(const Vector2D& position) const
+  {
+    return (this->getAbsCoor2D().x < position.x && this->getAbsCoor2D().x + this->getSizeX2D() > position.x &&
+        this->getAbsCoor2D().y < position.y && this->getAbsCoor2D().y + this->getSizeY2D() > position.y);
+  }
+
+  bool GLGuiWidget::focusOverWidget(const GLGuiCursor* const cursor) const
+  {
+    return this->focusOverWidget(cursor->getAbsCoor2D());
+  }
+
+
+
+  /** @brief gives focus to this widget */
+  void GLGuiWidget::giveMouseFocus()
+  {
+    if (this->_state == OrxGui::Insensitive)
+      return ;
+
+    if (GLGuiWidget::mouseFocused() != NULL)
+      GLGuiWidget::mouseFocused()->breakMouseFocus();
+    GLGuiWidget::_mouseFocused = this;
+
+    this->switchState(OrxGui::Focused);
+
+    this->receivedFocus();
+  };
+
+  void GLGuiWidget::breakMouseFocus()
+  {
+    if (GLGuiWidget::_mouseFocused == this)
+    {
+      GLGuiWidget::_mouseFocused = NULL;
+
+      if (GLGuiWidget::_selected != this)
+        this->switchState(OrxGui::Normal);
+      else
+        this->switchState(OrxGui::Selected);
+
+      this->removedFocus();
+    }
+  };
+
+  /**
+   * @brief selects the Widget, unselecting the old one (if existing)
+   */
+  void GLGuiWidget::select()
+  {
+    if (GLGuiWidget::_selected != NULL)
+      GLGuiWidget::selected()->unselect();
+    GLGuiWidget::_selected = this;
+
+    this->switchState(OrxGui::Selected);
+  }
+
+  /**
+   * @brief unselects the current Widget.
+   *
+   * if the current Widget is not selected, nothing is done here.
+   */
+  void GLGuiWidget::unselect()
+  {
+    if (GLGuiWidget::_selected != this)
+      return;
+
+    if (GLGuiWidget::_mouseFocused == this)
+      this->switchState(OrxGui::Focused);
+    else
+      this->switchState(OrxGui::Normal);
+
+    GLGuiWidget::_selected = NULL;
+  }
+
+
+  void GLGuiWidget::resize()
+  {
+    this->backRect().setSize(this->getSize2D());
+    if (this->parent() != NULL)
+      this->parent()->resize();
+  }
+
+
+  void GLGuiWidget::click(const Vector2D& pos)
+  {
+    assert (!this->_pushed);
+    this->_pushed = true;
+
+    this->clicking(pos);
+  }
+
+  void GLGuiWidget::release(const Vector2D& pos)
+  {
+    if (this->_pushed)
+    {
+      this->releasing(pos, GLGuiWidget::_mouseFocused == this);
+      this->_pushed = false;
+    }
+  }
+
+
+  void GLGuiWidget::clicking(const Vector2D& pos)
+  {}
+
+  void GLGuiWidget::releasing(const Vector2D& pos, bool focused)
+  {}
+
+  void GLGuiWidget::receivedFocus()
+  {
+  }
+
+  void GLGuiWidget::removedFocus()
+  {
+
+  }
+
+  void GLGuiWidget::selecting()
+  {
+  }
+
+  void GLGuiWidget::unselecting()
+  {
+  }
+
+
+  void GLGuiWidget::destroying()
+  {
+  }
+
+
+  void GLGuiWidget::setWidgetSize(const Vector2D& size)
+  {
+    this->setSize2D(size);
+    this->resize();
+
+  }
+
+
+  void GLGuiWidget::setWidgetSize(float x, float y)
+  {
+    this->setWidgetSize(Vector2D(x, y));
+  }
+
+  void GLGuiWidget::show()
+  {
+    this->setVisibility(true);
+    this->showing();
+  }
+
+
+
+  void GLGuiWidget::hide()
+  {
+    this->setVisibility(false);
+    this->hiding();
+  }
+
+
+  /**
+   * @brief resets the Style to the default Settings.
+   */
+  void GLGuiWidget::resetStyle()
+  {
+    this->setBorderLeft(1.0);
+    this->setBorderRight(1.0);
+    this->setBorderTop(1.0);
+    this->setBorderBottom(1.0);
+
+    this->setTextSize(20.0);
+    this->setBackgroundColor(1.0);
+    this->setForegroundColor(1.0);
+
+    this->setFeaturePosition(FeatureLeft);
+
+    this->setAnimatedStateChanges(true);
+  }
+
+
+  /**
+   * @brief sets the Width of the left border for all States
+   * @param value the borderWidth
+   */
+  void GLGuiWidget::setBorderLeft(float value)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      setBorderLeft(value, (OrxGui::State)i);
+  }
+
+  /**
+   * @brief sets the Width of the left border.
+   * @param value the borderWidth
+   * @param state the State to set the borderwidth to
+   */
+  void GLGuiWidget::setBorderLeft(float value, OrxGui::State state)
+  {
+    _style[state]._borderLeft = value;
+    if (state == _state)
+      _currentStyle._borderLeft = value;
+  }
+
+  /**
+   * @brief sets the Width of the left border.
+   * @param value the borderWidth
+   * @param stateName the State to set the borderwidth to
+   */
+  void GLGuiWidget::setBorderLeftS(float value, const std::string& stateName)
+  {
+    OrxGui::State state;
+    if (getState(stateName, &state))
+      this->setBorderLeft(value, state);
+    else
+      this->setBorderLeft(value);
+  }
+
+  /**
+   * @brief sets the Width of the right border for all states.
+   * @param value the borderWidth
+   */
+  void GLGuiWidget::setBorderRight(float value)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      setBorderRight(value, (OrxGui::State)i);
+  }
+
+  /**
+   * @brief sets the Width of the right border.
+   * @param value the borderWidth
+   * @param state the State to setup.
+   */
+  void GLGuiWidget::setBorderRight(float value, OrxGui::State state)
+  {
+    _style[state]._borderRight = value;
+    if (state == _state)
+      _currentStyle._borderRight = value;
+  }
+
+  /**
+   * @brief sets the Width of the right border.
+   * @param value the borderWidth
+   * @param stateName the State to setup.
+   */
+  void GLGuiWidget::setBorderRightS(float value, const std::string& stateName)
+  {
+    OrxGui::State state;
+    if (getState(stateName, &state))
+      this->setBorderRight(value, state);
+    else
+      this->setBorderRight(value);
+  }
+
+
+  /**
+   * @brief sets the Width of the top border for all states.
+   * @param value the borderWidth
+   */
+  void GLGuiWidget::setBorderTop(float value)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      setBorderTop(value, (OrxGui::State)i);
+  }
+
+  /**
+   * @brief sets the Width of the top border.
+   * @param value the borderWidth
+   * @param state the State to setup.
+   */
+  void GLGuiWidget::setBorderTop(float value, OrxGui::State state)
+  {
+    _style[state]._borderTop = value;
+    if (state == _state)
+      _currentStyle._borderTop = value;
+  }
+
+  /**
+   * @brief sets the Width of the top border.
+   * @param value the borderWidth
+   * @param stateName the State to setup.
+   */
+  void GLGuiWidget::setBorderTopS(float value, const std::string& stateName)
+  {
+    OrxGui::State state;
+    if (getState(stateName, &state))
+      this->setBorderTop(value, state);
+    else
+      this->setBorderTop(value);
+  }
+
+
+  /**
+   * @brief sets the Width of the bottom border for all states.
+   * @param value the borderWidth
+   */
+  void GLGuiWidget::setBorderBottom(float value)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      setBorderBottom(value, (OrxGui::State)i);
+  }
+
+  /**
+   * @brief sets the Width of the bottom border.
+   * @param value the borderWidth
+   * @param state the State to setup.
+   */
+  void GLGuiWidget::setBorderBottom(float value, OrxGui::State state)
+  {
+    _style[state]._borderBottom = value;
+    if (state == _state)
+      _currentStyle._borderBottom = value;
+
+  }
+
+  /**
+   * @brief sets the Width of the bottom border for all states.
+   * @param value the borderWidth
+   * @param stateName the State to setup.
+   */
+  void GLGuiWidget::setBorderBottomS(float value, const std::string& stateName)
+  {
+    OrxGui::State state;
+    if (getState(stateName, &state))
+      this->setBorderBottom(value, state);
+    else
+      this->setBorderBottom(value);
+  }
+
+
+  /**
+   * @brief sets the TextSize for all states.
+   * @param value the TextSize
+   */
+  void GLGuiWidget::setTextSize(float value)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      setTextSize(value, (OrxGui::State)i);
+  }
+
+  /**
+   * @brief sets the TextSize.
+   * @param value the TextSize.
+   * @param state: the State to setup
+   */
+  void GLGuiWidget::setTextSize(float value, OrxGui::State state)
+  {
+    _style[state]._textSize = value;
+    if (state == _state)
+      _currentStyle._textSize = value;
+  }
+
+  /**
+   * @brief sets the TextSize.
+   * @param value the TextSize.
+   * @param stateName: the State to setup
+   */
+  void GLGuiWidget::setTextSizeS(float value, const std::string& stateName)
+  {
+    OrxGui::State state;
+    if (getState(stateName, &state))
+      this->setTextSize(value, state);
+    else
+      this->setTextSize(value);
+  }
+
+
+  /**
+   * @brief sets the Background Color for all States.
+   * @param color the Color.
+   */
+  void GLGuiWidget::setBackgroundColor(const Color& color)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      setBackgroundColor(color, (OrxGui::State)i);
+  }
+
+  /**
+   * @brief sets the Background Color.
+   * @param color the Color.
+   * @param state: the State to setup
+   */
+  void GLGuiWidget::setBackgroundColor(const Color& color, OrxGui::State state)
+  {
+    _style[state]._background.setDiffuseColor(color);
+    if (state == _state)
+      _currentStyle._background.setDiffuseColor(color);
+
+  }
+
+  /**
+   * @brief sets the Background Color.
+   * @param r the Color's red part.
+   * @param g the Color's green part.
+   * @param b the Color's blue part.
+   * @param a the Color's alpha part.
+   * @param stateName: the State to setup
+   */
+  void GLGuiWidget::setBackgroundColorS(float r, float g, float b, float a, const std::string& stateName)
+  {
+    OrxGui::State state;
+    if (getState(stateName, &state))
+      this->setBackgroundColor(Color(r,g,b,a), state);
+    else
+      this->setBackgroundColor(Color(r,g,b,a));
+  }
+
+
+  /**
+   * @brief sets the Background Texture for all States.
+   * @param texture the Texture.
+   */
+  void GLGuiWidget::setBackgroundTexture(const Texture& texture)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      setBackgroundTexture(texture, (OrxGui::State)i);
+  }
+
+  /**
+  * @brief sets the Background Texture to all States.
+  * @param textureName the Texture's fileName.
+   */
+  void GLGuiWidget::setBackgroundTexture(const std::string& textureName)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      _style[i]._background.setDiffuseMap(textureName);
+    this->_currentStyle._background.setDiffuseMap(textureName);
+  }
+
+  /**
+   * @brief sets the Background Texture.
+   * @param texture the Texture.
+   * @param state the State to setup.
+   */
+  void GLGuiWidget::setBackgroundTexture(const Texture& texture, OrxGui::State state)
+  {
+    _style[state]._background.setDiffuseMap(texture);
+    if (state == _state)
+      _currentStyle._background.setDiffuseMap(texture);
+  }
+
+
+
+  /**
+   * @brief sets the Background Texture.
+   * @param texture the Texture.
+   * @param stateName the State to setup.
+   */
+  void GLGuiWidget::setBackgroundTexture(const std::string& textureName, const std::string& stateName)
+  {
+    OrxGui::State state;
+    if (getState(stateName, &state))
+      ; /// FIXME this->setBackgroundTexture(textureName, state);
+    else
+      ; ///    this->setBackgroundTexture(textureName);
+  }
+
+
+  /**
+   * @brief sets the Foreground Color for all States.
+   * @param color the Color.
+   */
+  void GLGuiWidget::setForegroundColor(const Color& color)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      setForegroundColor(color, (OrxGui::State)i);
+  }
+
+  /**
+   * @brief sets the Foreground Color.
+   * @param color the Color.
+   * @param state the State to setup
+   */
+  void GLGuiWidget::setForegroundColor(const Color& color, OrxGui::State state)
+  {
+    _style[state]._foreground.setDiffuseColor(color);
+    if (state == _state)
+      _currentStyle._foreground.setDiffuseColor(color);
+
+  }
+
+  /**
+   * @brief sets the Foreground Color.
+   * @param r the Color's red part.
+   * @param g the Color's green part.
+   * @param b the Color's blue part.
+   * @param a the Color's alpha part.
+   * @param stateName: the State to setup
+   */
+  void GLGuiWidget::setForegroundColorS(float r, float g, float b, float a, const std::string& stateName)
+  {
+    OrxGui::State state;
+    if (getState(stateName, &state))
+      this->setForegroundColor(Color(r,g,b,a), state);
+    else
+      this->setForegroundColor(Color(r,g,b,a));
+  }
+
+
+    /**
+   * @brief sets the Foreground Texture for all States.
+   * @param texture the Texture.
+     */
+  void GLGuiWidget::setForegroundTexture(const Texture& texture)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      setForegroundTexture(texture, (OrxGui::State)i);
+  }
+
+  /**
+   * @brief sets the Foreground Texture to all States.
+   * @param textureName the Texture's fileName.
+   */
+  void GLGuiWidget::setForegroundTexture(const std::string& textureName)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      _style[i]._foreground.setDiffuseMap(textureName);
+    this->_currentStyle._foreground.setDiffuseMap(textureName);
+  }
+
+  /**
+   * @brief sets the Foreground Texture.
+   * @param texture the Texture.
+   * @param state the State to setup.
+   */
+  void GLGuiWidget::setForegroundTexture(const Texture& texture, OrxGui::State state)
+  {
+    _style[state]._background.setDiffuseMap(texture);
+    if (state == _state)
+      _currentStyle._background.setDiffuseMap(texture);
+  }
+
+
+
+  /**
+   * @brief sets the Foreground Texture.
+   * @param texture the Texture.
+   * @param stateName the State to setup.
+   */
+  void GLGuiWidget::setForegroundTexture(const std::string& textureName, const std::string& stateName)
+  {
+    OrxGui::State state;
+    if (getState(stateName, &state))
+      ; /// FIXME this->setForegroundTexture(textureName, state);
+    else
+      ; ///    this->setForegroundTexture(textureName);
+  }
+
+
+  void GLGuiWidget::loadBackgroundMaterial(const Material& material)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      this->loadForegroundMaterial(material, (OrxGui::State)i);
+  }
+
+  void GLGuiWidget::loadBackgroundMaterial(const Material& material, OrxGui::State state)
+  {
+    this->_style[state]._background = material;
+    if (state == _state)
+      _currentStyle._background = material;
+
+  }
+
+  void GLGuiWidget::loadBackgroundMaterial(const TiXmlElement* element)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      this->loadBackgroundMaterial(element, (OrxGui::State)i);
+  }
+
+  void GLGuiWidget::loadBackgroundMaterial(const TiXmlElement* element, OrxGui::State state)
+  {
+    this->_style[state]._background.loadParams(element);
+    if (state == _state)
+      this->_currentStyle._background = _style[state]._background;
+  }
+
+  void GLGuiWidget::loadBackgroundMaterialS(const TiXmlElement* element, const std::string& stateName)
+  {
+    OrxGui::State state;
+    if (getState(stateName, &state))
+      this->loadBackgroundMaterial(element, state);
+    else
+      this->loadBackgroundMaterial(element);
+  }
+
+  void GLGuiWidget::loadForegroundMaterial(const Material& material)
+{}
+  void GLGuiWidget::loadForegroundMaterial(const Material& material, OrxGui::State state)
+  {}
+  void GLGuiWidget::loadForegroundMaterial(const TiXmlElement* element, OrxGui::State state)
+  {}
+  void GLGuiWidget::loadForegroundMaterialS(const TiXmlElement* element, const std::string& stateName)
+  {}
+
+
+  /**
+   * @brief sets the Feature-Position.
+   * @param featurePosition the Feature-Position.
+   */
+  void GLGuiWidget::setFeaturePosition(FeaturePosition featurePosition)
+  {
+    this->_featurePosition = featurePosition;
+  }
+
+  /**
+   * @brief sets the Feature-Position by converting from a String.
+   * @param featurePosition the Feature-Position.
+   */
+  void GLGuiWidget::setFeaturePositionS(const std::string& featurePosition)
+  {
+    for (unsigned int i = 0; i < 4; ++i)
+    {
+      if (featurePosition == FeaturePositionString[i])
+      {
+        this->setFeaturePosition((FeaturePosition)i);
+      }
+    }
+  }
+
+  /**
+   * @brief sets the Font.
+   * @param font the Font.
+   */
+  void GLGuiWidget::setFont(const Font& font)
+  {
+    this->_font = font;
+  }
+
+  /**
+   * @brief sets the font from a Font-Name.
+   * @param fontName the FileName of the Font.
+   */
+  void GLGuiWidget::setFont(const std::string& fontName, unsigned int renderSize)
+  {
+    this->setFont(Font(fontName, renderSize));
+  }
+
+  /**
+   * @brief sets the AnimatedState.
+   * @param animated: it states-changes should animate true, otherwise false.
+   */
+  void GLGuiWidget::setAnimatedStateChanges(bool animated)
+  {
+    this->_animatedStateChanges = animated;
+  }
+
+
+  void GLGuiWidget::switchState(OrxGui::State state)
+  {
+    //this->_currentStyle = this->_style[state];
+    this->_state = state;
+    PRINTF(4)("%s::%s Switches to state %s\n", this->getClassCName(), this->getCName(), OrxGui::StateString[state].c_str());
+
+    this->animateBack();
+  }
+
+
+  void GLGuiWidget::animateBack()
+  {
+    this->_animating = true;
+    this->_animationCycle = 0.0f;
+  }
+
+
+  void GLGuiWidget::tick(float dt)
+  {
+    if (this->_animating)
+    {
+      this->foregroundColor();
+
+      _animationCycle += dt / _animationDuration;
+      if (_animationCycle >= 1.0)
+      {
+        _currentStyle._foreground.diffuseColor() = this->foregroundColor(_state);
+        _currentStyle._background.diffuseColor() = this->backgroundColor(_state);
+        _animating = false;
+      }
+      else
+      {
+        _currentStyle._foreground.diffuseColor().slerp(this->foregroundColor(_state), _animationCycle);
+        _currentStyle._background.diffuseColor().slerp(this->backgroundColor(_state), _animationCycle);
+      }
+      this->updateFrontColor();
+    }
+  }
+
+
+  /**
+   * USE THIS FUNCTION ONLY FROM DERIVED CLASS
+   */
+  void GLGuiWidget::draw() const
+  {
+    this->background().select();
+    this->drawRect(this->backRect());
+    this->background().unselect();
+  }
+
+
+  /**
+   * @param stateName the Name of a State.
+   * @param state the found State is returned here if found.
+   * @returns true if String is found, false otherwise.
+   */
+  bool GLGuiWidget::getState(const std::string& stateName, OrxGui::State* state)
+  {
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+      if (stateName == OrxGui::StateString[i])
+      {
+        *state = (OrxGui::State)i;
+        return true;
+      }
+    return false;
+  }
+
+  /**
+   * @brief print out some nice debug output about the Widget.
+   */
+  void GLGuiWidget::debug(unsigned int level) const
+  {
+    PRINT(0)("Debug of %s::%s - WidgetPart ", this->getClassCName(), this->getCName());
+    if (_parent != NULL)
+      PRINT(0)("- Parent %s::%s ", _parent->getClassCName(), _parent->getCName());
+    PRINT(0)("- State: %s", StateString[_state].c_str());
+
+    if (_focusable)
+      PRINT(0)("- focusable ");
+    if (_clickable)
+      PRINT(0)("- Clickable ");
+    if (_pushed)
+      PRINT(0)("- Pushed ");
+    PRINT(0)("\n");
+
+
+    PRINT(0)("Minimum Size %0.2f %0.2f ", _minSize.x, _minSize.y);
+    PRINT(0)("Back Rect: ");
+    _backRect.debug();
+    PRINT(0)("Style:\n");
+
+    for (unsigned int i = 0; i < GLGUI_STATE_COUNT; ++i)
+    {
+      PRINT(0)("In State %s: \n", StateString[i].c_str());
+
+      PRINT(0)("  Borders: Left: %0.2f, Right: %0.2f, Top: %0.2f, Bottom %0.2f\n",
+               _style[i]._borderLeft, _style[i]._borderRight, _style[i]._borderTop, _style[i]._borderBottom);
+      PRINT(0)("  TextSize %0.2f\n", _style[i]._textSize);
+      PRINT(0)("  BackgroundColor: "); _style[i]._background.diffuseColor().debug();
+      PRINT(0)("  ForegroundColor: "); _style[i]._foreground.diffuseColor().debug();
+      PRINT(0)("\n");
+    }
+
+
+    PRINT(0)(" Feature at %s ", FeaturePositionString[_featurePosition].c_str());
+    /// TODO    PRINT(0)("");    Font*               _font;                 //!< The Font used in the current Widget.
+
+    if (_animatedStateChanges)
+      PRINT(0)("- AnimatedStateChanges");
+    PRINT(0)("\n");
+
+    /*
+    if (_animating)
+      PRINT(0)("- Animated ");
+
+    //
+    float               _animationCycle;
+    float               _animationDuration;
+    StatedStyle         _currentStyle;
+    OrxGui::State       _currentState;
+    */
+  }
+
+
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_widget.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_widget.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_widget.h	(revision 9940)
@@ -0,0 +1,340 @@
+/*!
+ * @file glgui_widget.h
+ * The gl_widget of the openglGUI
+ */
+
+#ifndef _GLGUI_WIDGET_H
+#define _GLGUI_WIDGET_H
+
+#include "element_2d.h"
+
+#include "glgui_defs.h"
+
+#include "material.h"
+#include "font.h"
+
+#include "rect2D.h"
+
+#include "event.h"
+#include "sigslot/signal.h"
+
+namespace OrxGui
+{
+  class GLGuiCursor;
+
+
+  //! This is widget part of the openglGUI class
+  /**
+   * A widget is the main class of all the elements of th GUI.
+   */
+  class GLGuiWidget : public Element2D
+  {
+    ObjectListDeclaration(GLGuiWidget);
+  public:
+    GLGuiWidget(GLGuiWidget* parent = NULL);
+    virtual ~GLGuiWidget();
+
+    void show();
+    void hide();
+
+    void setParentWidget(GLGuiWidget* parent);
+    GLGuiWidget* parent() const { return this->_parent; }
+
+    /// FOCUS
+    /** @brief gives mouse - focus to this widget */
+    void giveMouseFocus();
+    void breakMouseFocus();
+
+    /** @returns true if the widget is focusable */
+    bool focusable() const { return this->_focusable; };
+    /** @returns true if the position is inside of the Widget. @param position the position to check */
+    bool focusOverWidget(const Vector2D& position) const;
+    /** @brief overloaded function, that returns true if the cursor is on top of the Widget */
+    bool focusOverWidget(const OrxGui::GLGuiCursor* const cursor) const;
+
+    /** @returns the currently mouse - focused Widget (NULL if none is focused). */
+    static GLGuiWidget* mouseFocused() { return GLGuiWidget::_mouseFocused; };
+
+    /// SELECT
+    void select();
+    void unselect();
+    /** @returns true if the Widget is selectable */
+    bool selectable() const { return this->_selectable; }
+
+    /** @returns the currently Selected Widget (NULL if none is selected). */
+    static GLGuiWidget* selected() { return GLGuiWidget::_selected; };
+
+    /// CLICK
+    bool pushed() { return _pushed; };
+    void click(const Vector2D& pos);
+    void release(const Vector2D& pos);
+    bool clickable() const { return this->_clickable; };
+
+    OrxGui::State state() const { return this->_state; };
+
+    Rect2D& backRect() { return this->_backRect; };
+    const Rect2D& backRect() const { return this->_backRect; };
+
+    void setFrontColor(const Color& frontColor, bool instantaniously = false);
+
+    void setWidgetSize(const Vector2D& size);
+    void setWidgetSize(float x, float y);
+
+    void animateBack();
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    /// STYLE /////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////
+    /// Retrieve Current Values. ///
+    ////////////////////////////////
+    /** @returns current left borderWidth */
+    inline float borderLeft() const { return _currentStyle._borderLeft; }
+    /** @returns current right borderWidth */
+    inline float borderRight() const { return _currentStyle._borderRight; }
+    /** @returns current top borderWidth */
+    inline float borderTop() const { return _currentStyle._borderTop; }
+    /** @returns burrent bottom borderWidth */
+    inline float borderBottom() const { return _currentStyle._borderBottom; }
+
+
+    /** @returns current textSize */
+    inline float textSize() const { return _currentStyle._textSize; }
+    /** @returns the Background Color */
+    inline const Color& backgroundColor() const { return _currentStyle._background.diffuseColor(); }
+    /** @returns the current Background Material. */
+    inline const Material& background() const { return _currentStyle._background; }
+    /** @returns the current background Texture. */
+    inline const Texture& backgroundTexture() const { return _currentStyle._background.diffuseTexture(); }
+    /** @returns the current foreground Color */
+    inline const Color& foregroundColor() const { return _currentStyle._foreground.diffuseColor(); }
+    /** @returns the current ForeGroung Material. */
+    inline const Material& foreground() const { return _currentStyle._foreground; }
+
+
+    /** @returns FeaturePosition */
+    inline FeaturePosition featurePosition() const { return _featurePosition; }
+    /** @returns the constant font */
+    inline const Font& font() const { return _font; }
+    /** @returns the font */
+    inline Font& font() { return _font; }
+    /** @returns true if the Element is Animated */
+    inline bool animating() const { return _animating; }
+    /** @returns true if State-Changes are animated */
+    inline bool animatedStateChanges() const { return _animatedStateChanges; }
+
+
+    ///////////////////////////////////////////////////////////////
+    /// Retrieve Values for the Saved Values inside the States. ///
+    ///////////////////////////////////////////////////////////////
+    /** @returns left borderWidth @param state the State to retrieve from */
+    inline float borderLeft(OrxGui::State state) const { return _style[state]._borderLeft; }
+    /** @returns right borderWidth @param state the State to retrieve from */
+    inline float borderRight(OrxGui::State state) const { return _style[state]._borderRight; }
+    /** @returns top borderWidth @param state the State to retrieve from */
+    inline float borderTop(OrxGui::State state) const { return _style[state]._borderTop; }
+    /** @returns bottom borderWidth @param state the State to retrieve from */
+    inline float borderBottom(OrxGui::State state) const { return _style[state]._borderBottom; }
+
+    /** @returns textSize @param state the State to retrieve from */
+    inline float textSize(OrxGui::State state) const { return _style[state]._textSize; }
+    /** @returns the Background Color @param state the State to retrieve from */
+    inline const Color& backgroundColor(OrxGui::State state) const { return _style[state]._background.diffuseColor(); }
+    /** @returns the Background Material. @param state the state to retrieve from */
+    inline const Material& background(OrxGui::State state) const { return _style[state]._background; }
+    /** @returns background Texture. @param state the State to retrieve from */
+    inline const Texture& backgroundTexture(OrxGui::State state) const { return _style[state]._background.diffuseTexture(); }
+    /** @returns the foreground Color @param state the State to retrieve from */
+    inline const Color& foregroundColor(OrxGui::State state) const { return _style[state]._foreground.diffuseColor(); }
+    /** @returns the ForeGroung Material. @param state the state to retrieve from */
+    inline const Material& foreground(OrxGui::State state) const { return _style[state]._foreground; }
+
+
+    /// SETUP
+    void resetStyle();
+    void loadParams(const TiXmlElement* root);
+
+    void setBorderLeft(float value);
+    void setBorderLeft(float value, OrxGui::State state);
+    void setBorderLeftS(float value, const std::string& stateName);
+
+    void setBorderRight(float value);
+    void setBorderRight(float value, OrxGui::State state);
+    void setBorderRightS(float value, const std::string& stateName);
+
+    void setBorderTop(float value);
+    void setBorderTop(float value, OrxGui::State state);
+    void setBorderTopS(float value, const std::string& stateName);
+
+    void setBorderBottom(float value);
+    void setBorderBottom(float value, OrxGui::State state);
+    void setBorderBottomS(float value, const std::string& stateName);
+
+    void setTextSize(float value);
+    void setTextSize(float value, OrxGui::State state);
+    void setTextSizeS(float value, const std::string& stateName);
+
+    void setBackgroundColor(const Color& color);
+    void setBackgroundColor(const Color& color, OrxGui::State state);
+    void setBackgroundColorS(float r, float g, float b, float a, const std::string& stateName);
+
+    void setBackgroundTexture(const Texture& texture);
+    void setBackgroundTexture(const std::string& textureName);
+    void setBackgroundTexture(const Texture& texture, OrxGui::State state);
+    void setBackgroundTexture(const std::string& textureName, const std::string& stateName);
+
+    void setForegroundColor(const Color& color);
+    void setForegroundColor(const Color& color, OrxGui::State state);
+    void setForegroundColorS(float r, float g, float b, float a, const std::string& stateName);
+
+    void setForegroundTexture(const Texture& texture);
+    void setForegroundTexture(const std::string& textureName);
+    void setForegroundTexture(const Texture& texture, OrxGui::State state);
+    void setForegroundTexture(const std::string& textureName, const std::string& stateName);
+
+    void loadBackgroundMaterial(const Material& material);
+    void loadBackgroundMaterial(const Material& material, OrxGui::State state);
+    void loadBackgroundMaterial(const TiXmlElement* element);
+    void loadBackgroundMaterial(const TiXmlElement* element, OrxGui::State state);
+    void loadBackgroundMaterialS(const TiXmlElement* element, const std::string& stateName);
+
+    void loadForegroundMaterial(const Material& material);
+    void loadForegroundMaterial(const Material& material, OrxGui::State state);
+    void loadForegroundMaterial(const TiXmlElement* element, OrxGui::State state);
+    void loadForegroundMaterialS(const TiXmlElement* element, const std::string& stateName);
+
+    void setFeaturePosition(FeaturePosition featurePosition);
+    void setFeaturePositionS(const std::string& featurePosition);
+
+    virtual void setFont(const Font& font);
+    void setFont(const std::string& fontName, unsigned int renderSize = FONT_DEFAULT_RENDER_SIZE);
+
+    void setAnimatedStateChanges(bool animated);
+    void switchState(OrxGui::State state);
+    ///////////////////////////////////////////////////////////////////////////////////
+
+
+    inline void drawRect(const Rect2D& rect) const
+    {
+      glBegin(GL_QUADS);
+      glTexCoord2i(0,0); glVertex2d(rect.left(), rect.top());
+      glTexCoord2i(0,1); glVertex2d(rect.left(), rect.bottom());
+      glTexCoord2i(1,1); glVertex2d(rect.right(), rect.bottom());
+      glTexCoord2i(1,0); glVertex2d(rect.right(), rect.top());
+      glEnd();
+    }
+
+
+    virtual void update() {};
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+    /** @param the Event to process. @returns true if the Event has been consumed*/
+    virtual bool processEvent(const Event& event) { return false; };
+
+    bool getState(const std::string& stateName, OrxGui::State* state);
+
+  protected:
+    /** @param focusable sets if the Widget should be focusable */
+    void setFocusable(bool focusable = true) { this->_focusable = focusable; };
+    /** @param selectable true if the widget should be selectable */
+    void setSelectable(bool selectable) { this->_selectable = selectable; }
+    /** @param focusable true if the widget should be focusable */
+    void setClickable(bool clickable = true) { this->_clickable = clickable; };
+
+
+    /// RENDERING
+    inline void beginDraw() const { glPushMatrix(); glTranslatef(this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0); };
+    inline void endDraw() const { glPopMatrix(); };
+
+
+    /// LOOKS
+    virtual void resize();
+
+    virtual void hiding() {};
+    virtual void showing() {};
+
+    virtual void updateFrontColor() {};
+
+
+    /// EVENTS
+    // mouse clicking
+    virtual void clicking(const Vector2D& pos);
+    virtual void releasing(const Vector2D& pos, bool focused);
+    // mouse focusing
+    virtual void receivedFocus();
+    virtual void removedFocus();
+    // selecting either with the mouse by clicking, or by the keybord traversing to it.
+    virtual void selecting();
+    virtual void unselecting();
+    // destroying the Widget.
+    virtual void destroying();
+
+    // unparent the widget and from this widget seen as parent
+    virtual void removeChildWidget(GLGuiWidget* widget) {};
+
+
+    virtual void debug(unsigned int level) const;
+
+  private:
+    void init();
+
+  private:
+    static GLGuiWidget*            _selected;         //!< The currently selected Widget.
+    static GLGuiWidget*            _mouseFocused;     //!< The currently Focused Widget (mouse-focus).
+    static GLGuiWidget*            _inputGrabber;     //!< The Widget that grabs input (keyboard-focus).
+
+
+    /// WIDGET
+    GLGuiWidget*                   _parent;           //!< The parent of this Widget.
+
+    /// LOOKS
+    Rect2D                         _backRect;
+    Vector2D                       _minSize;
+
+
+    /// EVENTS
+    OrxGui::State                  _state;
+    bool                           _pushed;
+
+    bool                           _focusable;        //!< If this widget can receive focus.
+    bool                           _clickable;        //!< if this widget can be clicked upon.
+    bool                           _selectable;       //!< If this widget can be selected.
+
+
+
+
+    /// STYLE - Variables.
+    typedef struct
+    {
+      float                        _borderLeft;           //!< The Distance to the left Border of the widget, before any internal Element starts.
+      float                        _borderRight;          //!< The Distance to the right Border of the widget, before any internal Element starts.
+      float                        _borderTop;            //!< The Distance to the top Border of the widget, before any internal Element starts
+      float                        _borderBottom;         //!< The Distance to the bottom Border of the widget, before any internal Element starts
+
+      float                        _textSize;             //!< The TextSize of the Widget.
+
+      Material                     _background;           //!< The Background Material of the Widget.
+
+      Material                     _foreground;           //!< The foreground Material of the Widget.
+    }
+    StatedStyle;
+
+
+    StatedStyle                    _style[GLGUI_STATE_COUNT]; //!< Styles configured for different States
+
+    FeaturePosition                _featurePosition;      //!< The Position a Feature will be layed at (checkbox(box), slider(text),...)
+    Font                           _font;                 //!< The Font used in the current Widget.
+
+    static Font*                   _defaultFont;          //!< The default Font.
+
+    /// ANIMATION STUFF:
+    bool                           _animatedStateChanges; //!< If the Transitions between States are Animated automatically.
+
+    bool                           _animating;            //!< If the Widget is animated at the moment (Texture might be an AnimatedTexture.)
+    float                          _animationCycle;
+    float                          _animationDuration;
+    StatedStyle                    _currentStyle;
+
+  };
+}
+#endif /* _GLGUI_WIDGET_H */
Index: branches/heathaze/src/lib/gui/gl/glgui_window.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_window.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_window.cc	(revision 9940)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_window.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiWindow);
+  /**
+   * standard constructor
+  */
+  GLGuiWindow::GLGuiWindow ()
+  {
+    this->init();
+
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  GLGuiWindow::~GLGuiWindow()
+  {
+  }
+
+  /**
+   * initializes the GUI-element
+   */
+  void GLGuiWindow::init()
+  {
+    this->registerObject(this, GLGuiWindow::_objectList);
+
+  }
+
+  /**
+   * draws the GLGuiWindow
+   */
+  void GLGuiWindow::draw() const
+  {
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/glgui_window.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glgui_window.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glgui_window.h	(revision 9940)
@@ -0,0 +1,35 @@
+/*!
+ * @file glgui_window.h
+ * The gl_WINDOW widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_WINDOW_H
+#define _GLGUI_WINDOW_H
+
+#include "glgui_container.h"
+
+// FORWARD DECLARATION
+namespace OrxGui
+{
+
+  //! This is window part of the openglGUI class
+  /**
+   *
+   */
+  class GLGuiWindow : public GLGuiContainer
+  {
+    ObjectListDeclaration(GLGuiWindow);
+  public:
+    GLGuiWindow();
+    virtual ~GLGuiWindow();
+
+    void init();
+
+    virtual void draw() const;
+
+  private:
+
+  };
+}
+#endif /* _GLGUI__H */
Index: branches/heathaze/src/lib/gui/gl/glmenu/glmenu_imagescreen.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/glmenu/glmenu_imagescreen.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glmenu/glmenu_imagescreen.cc	(revision 9940)
@@ -0,0 +1,287 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin GRauer
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
+
+#include "glmenu_imagescreen.h"
+
+#include "graphics_engine.h"
+#include "material.h"
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(GLMenuImageScreen, CL_GLMENU_IMAGE_SCREEN);
+CREATE_FACTORY(GLMenuImageScreen);
+
+/**
+ * @param root The Element to load the GLMenu from
+ */
+GLMenuImageScreen::GLMenuImageScreen(const TiXmlElement* root)
+{
+  this->registerObject(this, GLMenuImageScreen::_objectList);
+  this->setName("GLMenuLoadScreen");
+  // Select Our VU Meter Background Texture
+  this->backMat = new Material("load_screen");
+  this->barMat = new Material("bar");
+  this->barMat->setDiffuse(1,1,1);
+  this->backMat->setDiffuse(1,1,1);
+  this->maxValue = 10;
+  this->currentValue = 0;
+  this->setPosition(0,0);
+  this->setScale(1,1);
+  this->setBarPosScale( .6, .75, .3, .1);
+  // End of Background image code.
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  Loads a GLMenu from an inputElement
+ * @param root The Element to load the GLMenu from
+*/
+void GLMenuImageScreen::loadParams(const TiXmlElement* root)
+{
+  LoadParam(root, "BackgroundImage", this, GLMenuImageScreen, setBackgroundImage)
+  .describe("sets the image to load onto the loadscreen");
+
+  LoadParam(root, "BackgroundPS", this, GLMenuImageScreen, setPosScale)
+  .describe("The Position and Scale of the Background Image in %(0-1.0). PosX, PosY, SizeX, SizeY");
+
+  LoadParam(root, "BarImage", this, GLMenuImageScreen, setBarImage)
+  .describe("sets the image of the LoadingBar");
+
+  LoadParam(root, "BarPS", this, GLMenuImageScreen, setBarPosScale)
+  .describe("The Position and Scale of the Loading Bar in %(0-1.0). PosX, PosY, SizeX, SizeY");
+
+  LoadParam(root, "ElementCount", this, GLMenuImageScreen, setMaximum)
+  .describe("The Count of elements to load into the bar (this is only a maximum value)");
+}
+
+/**
+ *  standard deconstructor
+   @todo this deconstructor is not jet implemented - do it
+*/
+GLMenuImageScreen::~GLMenuImageScreen()
+{
+  delete this->backMat;
+  delete this->barMat;
+}
+
+/**
+  * @brief sets the background image name
+  * @param backImageName name of the backgroun-image
+ */
+void GLMenuImageScreen::setBackgroundImage (const std::string& backImageName)
+{
+  this->backMat->setDiffuseMap(backImageName);
+}
+
+/**
+ * @brief sets position of the ImageScreen
+ * @param offsetX offset from the top left corner in percent(0-1) of the screensize
+ * @param offsetY offset from the top left corner in percent(0-1) of the screensize
+*/
+void GLMenuImageScreen::setPosition(float offsetX, float offsetY)
+{
+  this->offsetX = offsetX;
+  this->offsetY = offsetY;
+}
+
+/**
+ * @brief sets size of the ImageScreen
+ * @param scaleX the scaleing of the image into the x-direction (in percent (0-1))
+ * @param scaleY the scaleing of the image into the y-direction (in percent (0-1))
+*/
+void GLMenuImageScreen::setScale(float scaleX, float scaleY)
+{
+  this->scaleX = scaleX;
+  this->scaleY = scaleY;
+}
+
+/**
+ * @brief sets position and size of the ImageScreen
+ * @param offsetX offset from the top left corner in percent(0-1) of the screensize
+ * @param offsetY offset from the top left corner in percent(0-1) of the screensize
+ * @param scaleX the scaleing of the image into the x-direction (in percent (0-1))
+ * @param scaleY the scaleing of the image into the y-direction (in percent (0-1))
+*/
+void GLMenuImageScreen::setPosScale(float offsetX, float offsetY, float scaleX, float scaleY)
+{
+  this->setPosition(offsetX, offsetY);
+  this->setScale(scaleX, scaleY);
+}
+
+/**
+ * @param barImage An image for the Bar
+*/
+void GLMenuImageScreen::setBarImage(const std::string& barImage)
+{
+  this->barMat->setDiffuseMap(barImage);
+}
+
+/**
+ * @brief sets the Position and the Size of the bar
+ * @param barX The Position in the x-direction in percent of the screen (0-1)
+ * @param barY The Position in the y-direction in percent of the screen (0-1)
+ * @param barW The Size in the x-direction in percent of the screen (0-1)
+ * @param barH The Size in the y-direction in percent of the screen (0-1)
+*/
+void GLMenuImageScreen::setBarPosScale(float barX, float barY, float barW, float barH)
+{
+  this->barX = barX;
+  this->barY = barY;
+  this->barW = barW;
+  this->barH = barH;
+}
+
+
+/**
+ * @brief set the maximum of countable steps
+ * @param maxValue of steps
+*/
+void GLMenuImageScreen::setMaximum(int maxValue)
+{
+  this->maxValue = maxValue;
+}
+
+/**
+ * @brief set current value
+ * @param currentValue value to set
+*/
+void GLMenuImageScreen::setValue(int currentValue)
+{
+  this->currentValue = currentValue;
+  this->draw();
+}
+
+
+/**
+ * @brief get the current value
+ */
+int GLMenuImageScreen::getValue()
+{
+  return this->currentValue;
+}
+
+
+/**
+ * @brief call this to trigger a progress event
+ *
+ * this has to redraw the progress bar and the whole image
+ */
+void GLMenuImageScreen::step ()
+{
+  if (this->currentValue < this->maxValue)
+  {
+    this->currentValue++;
+    this->draw();
+  }
+  else
+    PRINTF(2)("ImageScreen-loadbar exceeds maximum value %d\n", this->maxValue);
+}
+
+
+
+/**
+ * @brief draws the ImageScreen to the screenbuffer
+*/
+void GLMenuImageScreen::draw ()
+{
+  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+  PRINTF(4)("GLMenuImagEscreen::draw() - drawing step %i/%i\n",
+            this->currentValue, this->maxValue);
+
+  /* screen size */
+  int screenWidth = GraphicsEngine::getInstance()->getResolutionX();
+  int screenHeight = GraphicsEngine::getInstance()->getResolutionY();
+
+  int imageWidth = (int)(screenWidth * this->scaleX);
+  int imageHeight = (int)(screenHeight * this->scaleY);
+
+  int offsetX = (int)(this->offsetX * screenWidth);
+  int offsetY = (int)(this->offsetY * screenHeight);
+
+  /* loadbar pos */
+  int barX = (int)(this->barX *screenWidth);
+  int barY = (int)(this->barY *screenHeight);
+  int barW = (int)(this->barW *screenWidth);
+  int barH = (int)(this->barH *screenHeight);
+
+  float val = (float)this->currentValue/(float)this->maxValue;
+
+  if( val > barW)
+    val = barW;
+
+  GraphicsEngine::enter2DMode();
+
+  /* draw the BackGround */
+  backMat->select();
+  glBegin(GL_TRIANGLE_STRIP);
+  glTexCoord2i(0, 1); glVertex2i(offsetX, offsetY + imageHeight);
+  glTexCoord2i(1, 1); glVertex2i(offsetX +imageWidth, offsetY + imageHeight);
+  glTexCoord2i(0, 0); glVertex2i(offsetX, offsetY);
+  glTexCoord2i(1, 0); glVertex2i(offsetX + imageWidth, offsetY);
+  glEnd();
+
+  /* draw white border */
+  glBegin(GL_LINE_LOOP);
+  glColor3f(1.0, 1.0, 1.0);
+  glVertex2i(barX - 2, barY - 2);
+  glVertex2i(barX + barW + 2, barY - 2);
+  glVertex2i(barX + barW + 2, barY + barH + 2);
+  glVertex2i(barX - 2, barY + barH + 2);
+  glColor3f(1.0, 1.0, 1.0);
+  glEnd();
+
+  /* draw the progress bar */
+  barMat->select();
+  glBegin(GL_TRIANGLE_STRIP);
+  glTexCoord2f(0,   1); glVertex2i(barX, barY + barH);
+  glTexCoord2f(val, 1); glVertex2i(barX + (int)(val * this->barW * (float)screenWidth), barY + barH);
+  glTexCoord2f(0,   0); glVertex2i(barX, barY);
+  glTexCoord2f(val, 0); glVertex2i(barX + (int)(val * this->barW * (float)screenWidth), barY);
+  glEnd();
+
+  /*
+    glBegin(GL_QUADS);
+    glColor3f(0.0, 0.0, 0.0);
+    glVertex2i(barX, barY);
+    glVertex2i(barX + barWidth, barY);
+    glVertex2i(barX + barWidth, barY + barHeight);
+    glVertex2i(barX, barY + barHeight);
+    glColor3f(1.0, 1.0, 1.0);
+    glEnd();
+
+    glBegin(GL_QUADS);
+    glColor3f(0.0, 0.0, 0.0);
+    glVertex2i(barX-1, barY-1);
+    glVertex2i(barX + barWidth +1, barY-1);
+    glVertex2i(barX + barWidth+1, barY + barHeight+1);
+    glVertex2i(barX - 1, barY + barHeight +1);
+    glColor3f(1.0, 1.0, 1.0);
+    glEnd();
+
+  */
+
+  GraphicsEngine::leave2DMode();
+
+  SDL_GL_SwapBuffers();
+}
Index: branches/heathaze/src/lib/gui/gl/glmenu/glmenu_imagescreen.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/glmenu/glmenu_imagescreen.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/glmenu/glmenu_imagescreen.h	(revision 9940)
@@ -0,0 +1,64 @@
+/*!
+ * @file glmenu_imagescreen.h
+ * class to display a LoadScreen
+ */
+
+#ifndef _GLMENU_IMAGESCREEN_H
+#define _GLMENU_IMAGESCREEN_H
+
+#include "base_object.h"
+
+class Material;
+class TiXmlElement;
+
+//! A class to display a loadScreen
+class GLMenuImageScreen : public BaseObject
+{
+  ObjectListDeclaration(GLMenuImageScreen);
+public:
+  GLMenuImageScreen (const TiXmlElement* root = NULL);
+  virtual void loadParams(const TiXmlElement* root);
+  virtual ~GLMenuImageScreen ();
+
+  void draw();
+
+  void setBackgroundImage(const std::string& backImageName);
+  void setPosition(float offsetX, float offsetY);
+  void setScale (float scaleX, float scaleY);
+  void setPosScale(float offsetX, float offsetY, float scaleX, float scaleY);
+
+  void setBarImage(const std::string& barImage);
+  void setBarPosScale(float barX, float barY, float barW, float barH);
+
+  void setMaximum (int maxValue);
+  /** @returns the maximum of countable steps*/
+  inline int getMaximum() const { return this->maxValue; };
+
+  void setValue (int currentValue);
+  int  getValue ();
+  void step ();
+
+
+private:
+  // background image
+  std::string         backImageName;       //!< the name of the file of the background image
+  float         offsetX;             //!< X-offset of the the image from the left
+  float         offsetY;             //!< Y-offset of the image from the top
+  float         scaleX;              //!< width of the image
+  float         scaleY;              //!< height of the image
+  Material*     backMat;             //!< Background Material.
+
+  // Load-Bar
+  float         barX;                //!< X-position of the Bar
+  float         barY;                //!< Y-position of the Bar
+  float         barW;                //!< Width of the Bat
+  float         barH;                //!< Height of the Bar.
+  Material*     barMat;              //!< A Material for the Loading-Bar
+
+  /* progress bar values */
+  int           currentValue;        //!< the current count of step() calls fired yet
+  int           maxValue;            //!< total count of steps
+
+};
+
+#endif /* _GLMENU_IMAGESCREEN_H */
Index: branches/heathaze/src/lib/gui/gl/specials/glgui_notifier.cc
===================================================================
--- branches/heathaze/src/lib/gui/gl/specials/glgui_notifier.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/specials/glgui_notifier.cc	(revision 9940)
@@ -0,0 +1,235 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
+
+#include "glgui_notifier.h"
+#include "multi_line_text.h"
+
+#include "debug.h"
+
+namespace OrxGui
+{
+  ObjectListDefinition(GLGuiNotifier);
+  /**
+   * @brief standard constructor
+   */
+  GLGuiNotifier::GLGuiNotifier ()
+  {
+    this->registerObject(this, GLGuiNotifier::_objectList);
+
+    // Element2D and generals
+    this->lineSpacing = 0;
+    this->linesProcessed = 0;
+    this->_fadeAge = 3.0;
+    this->setHideAge(4.0);
+
+    this->setDisplayLineCount(10);
+  }
+
+  /**
+   * @brief standard deconstructor
+   */
+  GLGuiNotifier::~GLGuiNotifier ()
+  {
+    // delete the displayable Buffers
+    /*    while (!this->displayLines.empty())
+        {
+          delete this->displayLines.front().text;
+          this->displayLines.pop_front();
+        }
+
+        while (!this->hiddenText.empty())
+        {
+          delete this->hiddenText.top();
+          this->hiddenText.pop();
+        }*/
+  }
+
+  /**
+   * @brief push a message onto the notifier.
+   * @param message the message to be pushed.
+   *
+   * @note it is not guaranteed, that the message is delivered instantaniously
+   * The possibility may arise, that the DisplayLines are all in use, then one
+   * has to wait until a line gets hidden, until a new one can be pushed to be
+   * displayed.
+   */
+  void GLGuiNotifier::pushNotifyMessage(const std::string& message)
+  {
+    if (!this->hiddenText.empty())
+    {
+      DisplayLine dl; // put everything in here, and then display it
+
+      // retrieve a Text.
+      dl.text = this->hiddenText.top();
+      this->hiddenText.pop();
+
+      // setup Text
+      dl.text->setBlending(1.0f);
+      dl.text->setText(message);
+      dl.text->setVisibility(true);
+      dl.text->setRelCoor2D(this->calculateLinePosition(0));
+
+      dl.age = 0.0f;
+      this->displayLines.push_front(dl);
+      this->repositionText();
+    }
+    else
+    {
+      // push it onto the List of messages we still need.
+      this->inputBuffer.push_front(message);
+    }
+  }
+
+
+  /**
+   * @brief sets the Dipsplay Line Count of the Notifier.
+   * @param coun the count of displayLines.
+   */
+  void GLGuiNotifier::setDisplayLineCount(unsigned int count)
+  {
+    unsigned int currentCount = displayLines.size() + hiddenText.size();
+
+    for (unsigned int i = currentCount; i < count; ++i)
+    {
+      MultiLineText* text = new MultiLineText();
+      this->applyTextSettings(text);
+      this->hiddenText.push(text);
+    }
+    bufferDisplaySize = count;
+  }
+
+  void GLGuiNotifier::setFadeAge(float fadeAge)
+  {
+    this->_fadeAge = fadeAge;
+    this->_transformAge = hideAge() - this->fadeAge();
+  }
+
+  void GLGuiNotifier::setHideAge(float hideAge)
+  {
+    this->_hideAge = hideAge;
+    this->_transformAge = this->hideAge() - fadeAge();
+  }
+
+
+  /**
+   * @brief repositiones all the Texts to their position.
+   */
+  void GLGuiNotifier::repositionText()
+  {
+    int linePos = -1;
+    std::list<DisplayLine>::iterator textIt;
+    for (textIt = this->displayLines.begin() ; textIt != this->displayLines.end(); ++textIt )
+    {
+      linePos += (*textIt).text->getLineCount();
+      (*textIt).text->setRelCoorSoft2D(this->calculateLinePosition(linePos), 8);
+      //      printf("%f %f\n", (*textIt).text->getAbsCoor2D().x, (*textIt).text->getAbsCoor2D().y);
+    }
+  }
+
+
+  /**
+   * @brief applies the GLGuiNotifiers Settings to a single Text of the GLGuiNotifier.
+   * @param text the Text to apply the settings to.
+   */
+  void GLGuiNotifier::applyTextSettings(MultiLineText* text)
+  {
+    text->setSize(this->textSize());
+    text->setLineWidth( 300 );
+    text->setFont("fonts/final_frontier.ttf", (int)this->textSize());
+
+    text->setColor(this->foregroundColor() );
+    if (text->getParent2D() != this)
+      text->setParent2D(this);
+  }
+
+
+  /**
+   * @brief ticks the entire Notifier.
+   * @param dt the time passed since the last Tick
+   */
+  void GLGuiNotifier::tick(float dt)
+  {
+    std::list<DisplayLine>::iterator line;
+    for (line = this->displayLines.begin() ; line != this->displayLines.end(); ++line )
+    {
+      (*line).age+=dt;
+      if ((*line).age > this->fadeAge())
+      {
+        (*line).text->setBlending((hideAge() - (*line).age)/_transformAge);
+        if ((*line).age > hideAge())
+        {
+          std::list<DisplayLine>::iterator tmp = line;
+          ++line;
+
+          (*tmp).text->setVisibility(false);
+          this->hiddenText.push((*tmp).text);
+          this->displayLines.erase(tmp);
+
+          if (!inputBuffer.empty())
+          {
+            this->pushNotifyMessage(inputBuffer.back());
+            inputBuffer.pop_back();
+          }
+        }
+      }
+    }
+  }
+
+
+  /**
+   * displays the GLGuiNotifier
+   */
+  void GLGuiNotifier::draw() const
+  {
+    // transform for alignment.
+    // setting the Blending effects
+    this->beginDraw();
+
+    this->background().select();
+    this->drawRect(this->backRect());
+    this->endDraw();
+  }
+
+  ///////////////////////
+  // HELPER FUNCTIONS  //
+  ///////////////////////
+
+  /**
+   * @brief calculates the position of a Buffer-Display Line
+   * @param lineNumber the lineNumber from the bottom to calculate the position from
+   * @returns the Position of the Line.
+   */
+  Vector2D GLGuiNotifier::calculateLinePosition(unsigned int lineNumber)
+  {
+    return Vector2D(0.0f, (float)(textSize() + this->lineSpacing)*(float)((int)this->bufferDisplaySize - (int)lineNumber - (int)1));
+  }
+
+
+  void GLGuiNotifier::resize()
+  {}
+
+  /**
+   * @brief displays some nice output from the GLGuiNotifier
+   */
+  void GLGuiNotifier::debug() const
+  {
+    PRINT(3)("Debugging output to console (not this shell)\n");
+
+    //   if (this->pressedKey != SDLK_FIRST)
+    //     printf("%s::%f %f\n", SDLKToKeyname(this->pressedKey), this->delayed, this->repeatDelay);
+  }
+}
Index: branches/heathaze/src/lib/gui/gl/specials/glgui_notifier.h
===================================================================
--- branches/heathaze/src/lib/gui/gl/specials/glgui_notifier.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gl/specials/glgui_notifier.h	(revision 9940)
@@ -0,0 +1,94 @@
+/*!
+ * @file shell.h
+ * Definition of a on-screen-shell
+ *
+ * @todo Buffer Display in different Colors for different debug mode.
+ * @todo choose color of the Font and the background.
+ */
+
+#ifndef _GLGUI_NOTIFIER_H
+#define _GLGUI_NOTIFIER_H
+
+#include "glgui_widget.h"
+#include "event_listener.h"
+
+#include <stack>
+
+// FORWARD DECLARATION
+class MultiLineText;
+class Text;
+
+//! Namespace of the GLGuiNotifier of ORXONOX.
+namespace OrxGui
+{
+  class GLGuiNotifier : public GLGuiWidget
+  {
+    ObjectListDeclaration(GLGuiNotifier);
+  public:
+    GLGuiNotifier();
+    virtual ~GLGuiNotifier();
+
+    void pushNotifyMessage(const std::string& message);
+
+    /// Setup
+    void setDisplayLineCount(unsigned int count);
+    void setFadeAge(float fadeAge);
+    void setHideAge(float hideAge);
+
+    /** @returns the beginning of the Hiding process */
+    inline float fadeAge() const { return _fadeAge; };
+    /** @returns at what age elements should be fully hidden */
+    inline float hideAge() const { return _hideAge; };
+
+    void clear();
+
+    // Element2D-functions
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+    void debug() const;
+
+  protected:
+    virtual void resize();
+
+  private:
+    void repositionText();
+    void applyTextSettings(MultiLineText* text);
+    void applySettings();
+    // helpers //
+    Vector2D calculateLinePosition(unsigned int lineNumber);
+
+
+
+  private:
+    //! structure that defines a Displayed line.
+    typedef struct
+    {
+      float             age;
+      MultiLineText*    text;
+
+    }
+    DisplayLine;
+
+
+    float                       _fadeAge;
+    float                       _hideAge;
+    float                       _transformAge;
+
+    unsigned int                lineSpacing;            //!< The Spacing between lines.
+
+    // BUFFER
+    unsigned int                bufferDisplaySize;      //!< The Size of the Display-buffer, in lines (not in characters).
+    std::list<DisplayLine>      displayLines;           //!< A list of stored bufferTexts for the display of the buffer.
+
+    std::stack<MultiLineText*>  hiddenText;             //!< Text that is not shown, and not used is thrown in here
+
+
+    unsigned long               linesProcessed;         //!< How many Lines have been processed so far.
+    std::list<std::string>      inputBuffer;            //!< The input buffer for lines that were not yet printet out, because there is too much input.
+
+  };
+
+}
+
+#endif /* _GLGUI_NOTIFIER_H */
Index: branches/heathaze/src/lib/gui/gui.cc
===================================================================
--- branches/heathaze/src/lib/gui/gui.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gui.cc	(revision 9940)
@@ -0,0 +1,96 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "gui.h"
+#include "gui_saveable.h"
+#include "parser/preferences/preferences.h"
+
+namespace OrxGui
+{
+
+
+  /**
+   * standard constructor
+  */
+  Gui::Gui ()
+  {
+    //this->setClassID(CL_PROTO_ID, "Gui");
+    this->state = Gui::Null;
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  Gui::~Gui ()
+  {
+    // delete what has to be deleted here
+  }
+
+
+  void Gui::loadAll()
+  {
+    std::vector<SaveableGroup*>::iterator loadElem;
+    for (loadElem = this->groups.begin(); loadElem != this->groups.end(); ++loadElem)
+    {
+      (*loadElem)->load();
+    }
+
+  }
+
+  void Gui::saveAll()
+  {
+    std::vector<SaveableGroup*>::iterator saveElem;
+    for (saveElem = this->groups.begin(); saveElem != this->groups.end(); ++saveElem)
+    {
+      (*saveElem)->save();
+    }
+
+    Preferences::getInstance()->save();
+  }
+
+  /**
+   * @brief adds a SaveableGroup
+   * @param saveableGroup the SaveableGroup to add to the SaveList.
+   */
+  void Gui::addSaveableGroup(SaveableGroup* saveableGroup)
+  {
+    if (std::find (this->groups.begin(), this->groups.end(), saveableGroup) == this->groups.end())
+      this->groups.push_back(saveableGroup);
+  }
+
+  /**
+   * @brief removes a SaveableGroup
+   * @param saveableGroup the SaveableGroup to remove from the SaveList.
+   */
+  void Gui::removeSaveableGroup(SaveableGroup* saveableGroup)
+  {
+    std::vector<SaveableGroup*>::iterator delElem = std::find (this->groups.begin(), this->groups.end(), saveableGroup);
+    if (delElem != this->groups.end())
+      this->groups.erase(delElem);
+  }
+
+  void Gui::quitEvent()
+  {
+    this->state |= Gui::Quitting;
+  }
+
+  void Gui::startEvent()
+  {
+    this->state |= Gui::Starting;
+  }
+}
Index: branches/heathaze/src/lib/gui/gui.h
===================================================================
--- branches/heathaze/src/lib/gui/gui.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gui.h	(revision 9940)
@@ -0,0 +1,59 @@
+/*!
+ * @file gui.h
+ * @brief Definition of ...
+*/
+
+#ifndef _GUI_H
+#define _GUI_H
+
+#include "base_object.h"
+#include <vector>
+
+// FORWARD DECLARATION
+
+namespace OrxGui
+{
+  class SaveableGroup;
+
+  //! A class for ...
+  class Gui : public BaseObject
+  {
+  public:
+    typedef enum {
+      Null          = 0,
+      Quitting      = 1,
+      Starting      = 2,
+      Saving        = 4,
+    } State;
+
+
+  public:
+    Gui();
+    virtual ~Gui();
+
+    //! Start the Gui
+    virtual void startGui() = 0;
+    //! Stop the gui
+    virtual void stopGui() = 0;
+    //! Suspend the Gui.
+    virtual void suspend() = 0;
+    //! Update the Gui.
+    virtual void update() = 0;
+
+    unsigned int getState() const { return this->state; };
+    void loadAll();
+    void saveAll();
+
+    void addSaveableGroup(SaveableGroup* saveableGroup);
+    void removeSaveableGroup(SaveableGroup* saveableGroup);
+
+  protected:
+    void quitEvent();
+    void startEvent();
+
+  private:
+    unsigned int                  state; //!< The State the Gui is in.
+    std::vector<SaveableGroup*>   groups;
+  };
+}
+#endif /* _GUI_H */
Index: branches/heathaze/src/lib/gui/gui_element.cc
===================================================================
--- branches/heathaze/src/lib/gui/gui_element.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gui_element.cc	(revision 9940)
@@ -0,0 +1,41 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "gui_element.h"
+
+namespace OrxGui
+{
+
+
+  /**
+   *  standard constructor
+   */
+  Element::Element (const std::string& name, OrxGui::Gui* gui)
+  : SaveableGroup(name, gui)
+  {
+  }
+
+
+  /**
+   *  standard deconstructor
+
+  */
+  Element::~Element()
+  {
+    // delete what has to be deleted here
+  }
+}
Index: branches/heathaze/src/lib/gui/gui_element.h
===================================================================
--- branches/heathaze/src/lib/gui/gui_element.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gui_element.h	(revision 9940)
@@ -0,0 +1,25 @@
+/*!
+ * @file gui_element.h
+ *  Definition of ...
+
+*/
+
+#ifndef _GUI_ELEMENT_H
+#define _GUI_ELEMENT_H
+
+#include "gui_saveable.h"
+
+namespace OrxGui
+{
+  class Widget;
+  class Gui;
+
+  //! A SuperClass for all the Different GuiElements
+  class Element : public SaveableGroup
+  {
+  public:
+    Element(const std::string& name, OrxGui::Gui* gui);
+    virtual ~Element();
+  };
+}
+#endif /* _GUI_ELEMENT_H */
Index: branches/heathaze/src/lib/gui/gui_saveable.cc
===================================================================
--- branches/heathaze/src/lib/gui/gui_saveable.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/gui_saveable.cc	(revision 9940)
@@ -0,0 +1,140 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "gui_saveable.h"
+#include "gui.h"
+#include "parser/preferences/preferences.h"
+
+#include "debug.h"
+
+namespace OrxGui
+{
+
+  /**
+   * standard constructor
+  */
+  Saveable::Saveable (const std::string& optionName, SaveableGroup* group, const MultiType& defaultValue)
+  : BaseObject(optionName)
+  {
+    this->bSaveable = false;
+    this->_defaultValue = defaultValue;
+
+    assert(group != NULL);
+    this->group = group;
+    this->group->addSaveable(this);
+
+  }
+
+
+  /**
+   * standard deconstructor
+  */
+  Saveable::~Saveable ()
+  {
+    this->group->removeSaveable(this);
+    // delete what has to be deleted here
+  }
+
+
+  void Saveable::makeSaveable()
+  {
+    this->bSaveable = true;
+
+  }
+
+
+  void Saveable::load()
+  {
+    this->value() = Preferences::getInstance()->getMultiType(this->group->getCName(), this->getCName(), this->_defaultValue);
+    PRINTF(4)("Loaded to '%s' of group '%s' value '%s'\n", this->getCName(), this->group->getCName(), this->value().getCString());
+  }
+
+  void Saveable::save()
+  {
+    Preferences::getInstance()->setMultiType(this->group->getCName(), this->getCName(), this->value() );
+    PRINTF(4)("Saved to '%s' of group '%s' value '%s'\n", this->getCName(), this->group->getCName(), this->value().getCString());
+  }
+
+
+
+
+  SaveableGroup::SaveableGroup(const std::string& groupName, OrxGui::Gui* gui)
+      : BaseObject(groupName)
+  {
+    assert (gui != NULL);
+    this->gui = gui;
+
+    this->gui->addSaveableGroup(this);
+    //this->mainWidget = NULL;
+  }
+
+
+
+  SaveableGroup::~SaveableGroup()
+  {
+    this->gui->removeSaveableGroup(this);
+  }
+
+
+  /**
+   * @brief Adds a Saveable to the List.
+   * @param saveable the saveable to add.
+   */
+  void SaveableGroup::addSaveable(Saveable* saveable)
+  {
+    if (std::find(this->saveables.begin(), this->saveables.end(), saveable) == this->saveables.end())
+      this->saveables.push_back(saveable);
+  }
+
+  /**
+   * @brief Removes a Saveable from the List.
+   * @param saveable the saveable to remove.
+   */
+  void SaveableGroup::removeSaveable(Saveable* saveable)
+  {
+    std::vector<Saveable*>::iterator delSav = std::find(this->saveables.begin(), this->saveables.end(), saveable);
+    if (delSav != this->saveables.end())
+      this->saveables.erase(delSav);
+  }
+
+
+  /**
+   * @brief load the value onto the Group.
+   * @param value the Value to load.
+   */
+  void SaveableGroup::load()
+  {
+    std::vector<Saveable*>::iterator elem;
+    for (elem = this->saveables.begin(); elem != this->saveables.end(); ++elem)
+      (*elem)->load();
+  }
+
+  /**
+   * @brief save the value from the Group
+   * @returns nothing.
+   */
+  void SaveableGroup::save()
+  {
+    std::vector<Saveable*>::iterator elem;
+    for (elem = this->saveables.begin(); elem != this->saveables.end(); ++elem)
+      (*elem)->save();
+  }
+
+
+
+
+}
Index: branches/heathaze/src/lib/gui/gui_saveable.h
===================================================================
--- branches/heathaze/src/lib/gui/gui_saveable.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/gui_saveable.h	(revision 9940)
@@ -0,0 +1,69 @@
+/*!
+ * @file gui_saveable.h
+ * @brief Definition of ...
+*/
+
+#ifndef _GUI_SAVEABLE_H
+#define _GUI_SAVEABLE_H
+
+#include "base_object.h"
+#include "lib/util/multi_type.h"
+#include <vector>
+
+// FORWARD DECLARATION
+namespace OrxGui
+{
+  class Gui;
+  class SaveableGroup;
+
+  //! A class for Elements in the Gui that are Saveable.
+  class Saveable : public BaseObject
+  {
+  public:
+    virtual ~Saveable();
+
+    void makeSaveable();
+
+    virtual void load();
+    virtual void save();
+
+    MultiType&       value() { return this->_value; };
+    const MultiType& value() const { return this->_value; };
+    MultiType&       defaultValue() { return this->_defaultValue; };
+    const MultiType& defaultValue() const { return this->_defaultValue; };
+    bool             isSaveable() const { return this->bSaveable; };
+
+  protected:
+    Saveable(const std::string& optionName, SaveableGroup* group, const MultiType& defaultValue);
+    virtual void makingElementSaveable() {};
+
+  private:
+    SaveableGroup*  group;
+    MultiType       _value;
+    MultiType       _defaultValue;
+    bool            bSaveable;
+  };
+
+
+
+  class SaveableGroup : public BaseObject
+  {
+  public:
+    virtual ~SaveableGroup();
+
+    void addSaveable(Saveable* saveable);
+    void removeSaveable(Saveable* saveable);
+
+    virtual void load();
+    virtual void save();
+
+  protected:
+    SaveableGroup(const std::string& name, OrxGui::Gui* gui);
+
+  private:
+    OrxGui::Gui*                        gui;
+    std::vector<Saveable*>              saveables;
+  };
+
+}
+#endif /* _GUI_SAVEABLE_H */
Index: branches/heathaze/src/lib/gui/qt/Makefile.am
===================================================================
--- branches/heathaze/src/lib/gui/qt/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/Makefile.am	(revision 9940)
@@ -0,0 +1,55 @@
+MAINSRCDIR=../../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+AM_LDFLAGS =
+
+noinst_LIBRARIES = libORXqtgui.a
+
+
+libORXqtgui_a_CPPFLAGS = \
+		@QT_CXXFLAGS@ \
+		-DBUILD_ORXONOX
+
+
+libORXqtgui_a_SOURCES = \
+		qt_gui.cc \
+		qt_gui_moc.cc \
+		qt_gui_elements.cc \
+		qt_gui_elements_moc.cc \
+		q_image_widget.cc \
+		q_image_widget_moc.cc \
+		\
+		gui_video.cc \
+		gui_audio.cc \
+		gui_general.cc \
+		gui_general_moc.cc \
+		gui_control.cc \
+		gui_control_moc.cc \
+		\
+		qt_gui_datadir_fallback.cc \
+		qt_gui_datadir_fallback_moc.cc
+
+
+
+noinst_HEADERS= \
+		qt_gui.h \
+		qt_gui_elements.h \
+		q_image_widget.h \
+		\
+		gui_video.h \
+		gui_audio.h \
+		gui_general.h \
+		gui_control.h \
+		\
+		qt_gui_datadir_fallback.cc
+
+
+EXTRA_DIST =
+
+
+
+%_moc.cc : %.h
+	@QT_MOC@ -o $@ $<
+
+clean-local:
+	rm -f *_moc.cc
Index: branches/heathaze/src/lib/gui/qt/banner.xpm
===================================================================
--- branches/heathaze/src/lib/gui/qt/banner.xpm	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/banner.xpm	(revision 9940)
@@ -0,0 +1,526 @@
+/* XPM */
+static char * banner_xpm[] = {
+"127 382 141 2",
+"  	c None",
+". 	c #183016",
+"+ 	c #183316",
+"@ 	c #183416",
+"# 	c #193816",
+"$ 	c #193916",
+"% 	c #193B16",
+"& 	c #1A3E17",
+"* 	c #1B3F17",
+"= 	c #1B4318",
+"- 	c #1B4418",
+"; 	c #1B4818",
+"> 	c #1C4F18",
+", 	c #1A3D17",
+"' 	c #172D15",
+") 	c #162A15",
+"! 	c #1C4B18",
+"~ 	c #193716",
+"{ 	c #36AC2D",
+"] 	c #42B837",
+"^ 	c #4DC042",
+"/ 	c #53C447",
+"( 	c #60CC53",
+"_ 	c #69D05D",
+": 	c #6ED261",
+"< 	c #74D669",
+"[ 	c #7BD86E",
+"} 	c #80D972",
+"| 	c #54C549",
+"1 	c #58C84D",
+"2 	c #45BC3C",
+"3 	c #1F641B",
+"4 	c #2FA326",
+"5 	c #32A829",
+"6 	c #25921E",
+"7 	c #2B9D23",
+"8 	c #24871D",
+"9 	c #2A9C21",
+"0 	c #31A628",
+"a 	c #183116",
+"b 	c #162314",
+"c 	c #162915",
+"d 	c #216F1B",
+"e 	c #141F14",
+"f 	c #206A1B",
+"g 	c #23791C",
+"h 	c #1D5018",
+"i 	c #1E5719",
+"j 	c #258F1E",
+"k 	c #1E5B1A",
+"l 	c #27991F",
+"m 	c #162514",
+"n 	c #23801D",
+"o 	c #22741B",
+"p 	c #2EA225",
+"q 	c #9CE391",
+"r 	c #89DC7B",
+"s 	c #BDEDB5",
+"t 	c #F8FDF7",
+"u 	c #9DE494",
+"v 	c #183216",
+"w 	c #1D5119",
+"x 	c #182F16",
+"y 	c #172A15",
+"z 	c #1B4217",
+"A 	c #30A527",
+"B 	c #85DB79",
+"C 	c #44BA39",
+"D 	c #1D5419",
+"E 	c #20691B",
+"F 	c #248E1E",
+"G 	c #26971E",
+"H 	c #216E1B",
+"I 	c #20661B",
+"J 	c #162614",
+"K 	c #182E16",
+"L 	c #EEFBEB",
+"M 	c #72D566",
+"N 	c #1A3C17",
+"O 	c #39B030",
+"P 	c #23851D",
+"Q 	c #152114",
+"R 	c #237D1C",
+"S 	c #61CD55",
+"T 	c #B5EBAD",
+"U 	c #D7F5D2",
+"V 	c #183516",
+"W 	c #1C4C18",
+"X 	c #48BD3D",
+"Y 	c #4FC244",
+"Z 	c #8EDF82",
+"` 	c #3DB433",
+" .	c #1E601A",
+"..	c #22771C",
+"+.	c #248A1E",
+"@.	c #1E5A19",
+"#.	c #C3EFBD",
+"$.	c #1F611A",
+"%.	c #E3F8DF",
+"&.	c #94E087",
+"*.	c #2C9F23",
+"=.	c #3FB735",
+"-.	c #21721B",
+";.	c #FCFEFC",
+">.	c #2DA024",
+",.	c #152314",
+"'.	c #ADE8A5",
+").	c #F3FCF2",
+"!.	c #D9F5D4",
+"~.	c #289A20",
+"{.	c #162414",
+"].	c #1B4518",
+"^.	c #DEF6D9",
+"/.	c #FEFFFE",
+"(.	c #172C15",
+"_.	c #162814",
+":.	c #26961E",
+"<.	c #FFFFFF",
+"[.	c #162714",
+"}.	c #D0F3CB",
+"|.	c #152214",
+"1.	c #38AF2F",
+"2.	c #6AD15E",
+"3.	c #1E5519",
+"4.	c #33A92A",
+"5.	c #1E5E1A",
+"6.	c #35AB2C",
+"7.	c #152014",
+"8.	c #37AD2E",
+"9.	c #3EB534",
+"0.	c #23821D",
+"a.	c #F6FDF5",
+"b.	c #A6E69C",
+"c.	c #BAECB3",
+"d.	c #FCFEFB",
+"e.	c #91DF85",
+"f.	c #F1FCEF",
+"g.	c #3CB332",
+"h.	c #43B938",
+"i.	c #172B15",
+"j.	c #C0EFBA",
+". . . . . + + + @ @ @ # # $ $ $ % % & * * * * * = = = - ; ; > > > > > , = = + . ' ' ' ' . . . ' ' ' . ' ' ' ) . ! > > ! , @ . . ~ ! { ] ] ^ / ( _ : < [ } [ < < _ | 1 ( 2 > 3 4 5 6 7 3 8 9 . > 0 a b } [ c d e f g ! h i j f k j l l m ) 9 n o p q : r s t u ",
+". . . + v . + + @ @ @ @ $ # % % % % % & & = & & = = - = ; > ; ; ! w ! & & * . v ' ' ) ' . . ' ' v x v x ' # v ) . . ' ) y z o p A p 1 / ^ ^ ^ ( : : [ } B [ < : ( | ( ( C D E F G H 6 6 F * I o J @ K L M $ N e z O d h h d 8 j d P n Q m p G R C S r _ u T U ",
+"K . . . . . . . @ @ @ @ V # # # % % & * & * N * = = = - - ; > > > > ! & = = . . ' ' ' ' ' . x ' + ' ' x ' ' . ' J @ W o 7 { C X Y X 1 S ( | ^ ( : [ B Z B [ : _ ( ( : _ `  .o ..H G 6 +.3 @.a i j c e #.[ Q z Q R ! ! f $.j f j p { j ) @ { p G Y [ B [ u %.&.",
+". . . . @ @ @ + @ @ V V $ $ $ $ % % % & * * & * = = - = ; > ; > ! > ; , = = v v ' ' ) ' . . ' ' ' ) ' + ' J ' - *.A O ] =.=.` O 2 ] A 2 _ : ( : [ [ } B B < : ( ( S < : 2 @.H R *.-.6 P F D l k @ $ K ;.O a @ e > X i i f $.j { >.n k ,.' d I o / '.[ } ).!.t ",
+"' ' . . . + + + @ + # @ V $ $ # % % & & & * % * = = = = ; > ; > > w - $ & * . . ' ' y ' ' . ' ' ' ' ' @ . ) > A =.=.` ` ` ` =.X 1 / l { ( _ ( : < [ } } } < : _ : ( S < ^ ; @.6 G 7 6 ~. .. ,.i j J {.T M e N e n R i $.].N y ) b Q Q e ) @ e Q h S k s ^./.T ",
+". . . . . . + + + @ @ V # # $ $ % % % * * = * & = = - - - - > ; > > > , = = v . ' ' ' ' . . x ' v x (.. _.. n ^ ` ` ` { O ` X / ^ | j { ( ( ( ( } } [ } [ < : : [ S _ : X ; D :.P 7 P F H ' j g @ @ @ <.=.b c Q k f Q e e c c e e e e e J y e Q 7 8 N 1 t r %.",
+". . . . . . . @ + + # # V # $ # % % % & & & N N = = = = ; ; > ; > > > , & * v . ' ) ' ' ' . ' ' ' ' . v [.$ 7 2 ` ` =.` =.Y / | Y S P p ( S : [ } [ [ < < < < < _ : _ | ` ; D +.7 -.+.P H * y k j Q e }.C e z b j c e e e a J e e e Q |.@ a e e ! C K T %.}.M ",
+". . . + @ @ + + @ @ @ V $ $ $ $ % % & * * = & & = = = - ; ; ; > > ! > * & = @ . ' ' ' x v . . ' x ' ' ) ) + { =.=.` ` =.2 Y | / / 1 l A _ _ : < B Z [ < [ } [ B < : 1 1 1.;  .F 6 +.o P H J 0 $.$ @ z L S b e e d k Q e b K c e e b e e c y e e { R $ M ).2.%.",
+"' . . . . + . a @ @ @ @ # # $ # % % & & * * * N = = = = ; > ; > > ; ; & N * a . x ' ' ' . v v x . ' . ' ' @ { ] =.=.2 Y Y Y / / Y 1 l 0 1 1 _ _ : } Z } < : : B : _ / 1 1.- @.F ..6 6 P :.j J h l e e ^.0 b e K { J e e e K Q e Q e e e v c e e i C y !.%.T | ",
+". . . . . . @ @ @ V V V # $ $ $ % % % * & = & & = = = ; - ; > ; > ; > = & = V ' ' ' ' . . . x x x x ' x x $ { O ` 2 2 Y / / / Y 1 1 7 A _ ( _ _ : B Z Z B < _ : : S | 1 1.; D 8 6 $.n F n y R N z y h }.{ e e Q 8 ! Q e e e e e e e e e e c e Q 0 f N M t Z !.",
+"K K . . . @ + + + @ # V # # $ # # % % * & * * N = = = ; - ; > > > ; ; & N * @ . ' ' ' . . . . x ' . ' ' ' + { =.=.Y ^ / | Y / Y | / *.A _ : < : : [ [ [ Z Z < : _ / / _ ` = D P n H 7 +.*. .v 8 8 e b ;.j Q e @ 0 c e e e Q e a ].N ].e z $.i N h R ; s #.!.1 ",
+". . . + + . + + @ @ @ # V $ % $ % % & & * * & & = = = = ; ; ; ; w ; > = & * @ ' ' ' ' ' . . x x (.' . ' ) + { 2 Y Y / / Y / / 1 1 1 *.7 ] 2 ( : } B < < Z Z : / S | | _ ` ; 3.+.G +.+.A j @.>.K $.b 0 '.b e e J j $ e a z $.l 1 S _ j J y O 0 O 2.C O 2.M 1 [ ",
+". . . . . . . + @ @ @ # # # % % $ % % & & * * & = = = = ; > ; ; w ; ; & * = @ . ' ' ' . v . . x ' x . ' ) + ` ^ / / / ^ Y / | 1 / | :.I 3 H F 4.| : [ } q Z : / S 1 1 _ 1.- 5.+.6 6 *.6.P = ' 0 k Q e %.k Q e e ! 0 ! d >.R j l j 0 0 e v 8 >.0 { X 1 }.).L 1 ",
+". . . . v @ + + @ V V # V $ % $ % % & * * * & * = = ; ; ; ; > > > ; > * & * @ . ' ' ' ' . v x x x ' x ' . , =.| ^ Y Y / / / 1 | _ _ { o 3 i o F +.6.C ^ : [ } [ S | S | 9 = 3 6 >.6 ~.A 5 * Y y n b { %.b e e e 0 d f f i o $.$.g 0 j 7.; Y >.>.| R 0 u %.t ).",
+"K K . . . + . a @ @ @ # V # # # # * % & & * % & = = = ; ; ; ; ; > ; > & & = . . ' ' ' ' . v . x + . x x ~ ; Y | / ^ X Y / 1 | | ^ ^ 4.P R o o R :.*.9 F >.1.C | S S | / F % H ~.>.0 8.6.F * $ 0 f e J U $ e Q b ! 8 d i i j j R f { { Q f 2.O 0 X | 1 !.M %.T ",
+". . . . . . @ + @ @ V V # $ % % N % % * * * * * = = = = ; ; > > > ; ; & % * @ . ) ' . . . ' x ' x ' ) ~ W = 2 1 ^ Y ^ / 1 | | / 1 : p 3 3 F +.n 9 *.~.A A G 8 P :.:.j H > - H A 0 8.0 4.3 V P K f b 0 S c a ].Q { d i o o $.o o o 0 d e f Z >.O j O Z !.#.L s ",
+". . . . . @ @ + @ @ @ # # $ $ $ % & % & & & * * = = = = ; ; ; > > ; ; & % & . . x (.) ' x x x . ) + , = ; = 2 ^ ^ / / ^ Y / | 1 1 _ A o  .E o P 9 ~.:.9 A G F 8 o 3 @.> ; > -.>.8.6 8.^ :.v > n d e c ;.a N c c $.k ; h o j j l 0 { o 7.N C >.O | | M s u #.Z ",
+". . . + + . + + V @ V V # # # % # % & % % * & * = = ; ; ; ; > ; w > ; & % * @ . ' ) ) ' + ' x x (.$ = - , ; 2 ^ ^ / | 1 ^ ^ S : _ | j R 3 w D 3 3 3 o G 9 A G :.8 o  .3.> 3.P 0 8.8.>.*.H & j ' n Q *.| k {.h e 0 $.i o o R l 0 j O d 7.h Y j >.| [ [ [ !.t &.",
+"K . . . . . . . @ @ @ V # % # & # & % & & * & * = = = - ; ; > ; > ; ; & % * . . ' ' ' . + ' (.x & , , @ $ W ^ 2 | 1 1 _ 1 1 1 _ S 2 7 =.1 1.9 8 o 3 3 H 3 o P 8 o o o H w > n 6.8.>.4.4.*.% > 0 $.e z ;.c k y {.R *.$.; f j *.X Y p f J f 1 >.>.C [ Z [ T ).%.",
+". . . . + @ @ @ V @ V # $ V % V * % & * & & * * = = = = ; ; ; > > > ; , & & @ . ) ) ' v x (.v @ ; , , , = W 2 | ^ | ( _ < _ ( Y | p j ^ [ < < : ^ 1.G E = = @.E  .E R H D > o >.8.*.9.6.A P I J l e d }.O Q z J =.R f n $.k j O { C o 7.>.Z j 0 1 T 1 T Z %.&.",
+"' ' . . . + + . @ @ @ @ % # % V # & % * * * * * = = ; ; ; ; ; > > ; ; & % * . . ) ' ) ' ' . , ; , $ , , - - ` _ ( 1 | 1 1 ^ { p P n O _ } : : : q q < C G o @.@.@.3.3. . .3 P >.>.8.*.6.*._.k O z e $ <.Q h c e f o i h o o j X _ 7 > 7.W { { 0 Y Z #.T U T }.",
+". . . . . . + + V @ # # # % V % * % % & % & * * = = = = ; > > ; > > ; % & & @ . ' ' ' ) ' ~ = = v @ $ $ , @ 9 ] | 2 ` { 4.9 n  .n P _ [ : : : B [ B Z } : / =.4.F o  .@.@.@.R A 4.*.O 4 4 G I K 0 e X %.j e {.v | $.; d o o ` r O z 7.7.y K R >.1 u T %.Y U r ",
+". . . . . . @ a @ @ V V # % # # # & & & & & & * = = = - ; ; > > > ; > % % * @ x ' x ' (.@ * , v @ @ @ @ - x D i :.0.o H o ..n o ; k _ : _ < < } B B : | _ : : [ < ( ` 8 D = 5.:.*.4.*.9.:.' I 0 $ e k t y @ y J v e y R *.k $ z $ Q e Q 7.a '.[ l C Z j ; ).<.",
+"' ' . . . . . v # @ @ @ # @ & # * # # * * * * & = = * 3., ! ! > > 3.; $ & = x (.K b _., - , $ + $ x @ = @ , - $ D D D ..3 5.H o I  ./ _ < < < [ } } : _ S [ B } < [ Z 1 @.# D P 6 *.0 *.- = g @ >.e Y t f e a a 1 b e n j v e Q |.e @ T N N }.a.} X O b e }.0 ",
+". ' . . . @ . x @ @ # @ # # # # * N & # & & & & * > & , > 3.* ; = > > * & = v ' _.v , = , @ v . v & @ $ W * @ = $ = i o D D k o 3 3 | ( : < } [ Z } : : : [ } [ [ [ } S n % W P ~.*.G 0 :.) f 7 N e l ).z ; b b j z y ! o @ e e e c { ;.}.e t t 1 2.j 7.f ).h ",
+"' x . x x . @ @ V # @ # # # # # & # & * & & = = * , ; ; * & * > 3.> ; # # $ x ' J , - , $ v + + v @ $ , = = , = , 5.0. .= k 5.$.i d _ _ ( < } B Z < S [ B } [ } Z : : _ p - W ..6 -.*.0 * + % $ 0 e e a k l ! Q z {.e $.j a e e Q e e ;.Z N 2.L 2.M { 7.b !.*.",
+"' ' . . x . . . @ # # # @ # # V N # * N * & & & ; & > & = 3.3.; > ; = & * , v ' - - @ a @ a v + # @ - - $ $ $ $ 5.R 0.i ; 3 5.- D d : : ( _ < B Z B [ } Z B [ } } : _ _ ` ! = -.$.+.7 ~.*.[.j l $ J e K j *.J e e e c j n Q e Q e Q b ; >.b >.0 C } >.b i ;.).",
+". x x . . x @ @ @ @ @ @ # # N # # & & & & * * = * , * > 3.& $ > > 3.> = & + a $ - , a * , ' . v v $ = @ $ $ $ D R H ; , - - D W i  ._ < : : < B B Z q Z Z Z Z } : : : _ =.W ; 3 G -.n O 4.@.N z { j b $ $.O z b e Q e k >.N e e b $ }./.T /.s S r Z { J Q r %.",
+"' ' . . . . . @ @ @ # # # # # # * V * & % & * = * > = ; @ ; @.& > > - D 3 D ; - a y y , ' v I n 3 ~ $ # v = 5.o W @ ; 7 0 D $ ; > > ^ ( < < < < B q b.Z Z B Z } _ : : : =.- W H ..-.6 +.8 _.{ N K 8 z y C l |.e e e Q ! k J e Q e $ Y Z M Z &.r 2.| f J Q e e ",
+". x x . . . @ . @ # @ # V # # & # & % & & * * * * _ [ } [ c.[ @.:.S c.c.| 3 , = a y ' a @ 5 L d.e.- x = @ w o D = ; _ f.a.^ * ; $ # O / _ [ } } Z e.q q Z B [ [ : _ < _ =.- > o ..6 P 5 g.j T s Q e y $ j >.N Q J y K J b b J z ; f 1 u 0 } C N ; h ; @ @ b b ",
+"' ' . . . @ . @ @ # @ # # # # # # & & % & * * * * S > * 3.* E }.S ~.* , i D , ' ' a @ ' (.^ /.d.d.o J @ W -.3 = W i '.d.a.| x % ) @ 1.2 | _ B B q Z Z q q } : : [ ( : : 2 = D o +.+.~.A  .y )./.; e e a | S c e e e Q e Q e $ %.T $ >.%.!.Z !.R f c j T S N c ",
+"x . @ . . ' @ @ @ @ @ # @ # # # * V & % % & N N * G > = = * D S 3.; = D R @ $ ' ' ' ' a ' : d.t t H [.W o W $ ; W , b.a.d.M |.b J . =.X | [ [ } B e.e.Z } < : : : : _ _ ] - > P F ~.:.A 8 # { T z e e e b N J e e e e e e e i %.!.; K >.R J { >.; c v u <.<.O ",
+"' ' x ' . . @ @ @ @ @ @ # # # @ # & & % & * & * > S / / S : / _ S : S : ^ W ' y ' y ' $ @ : a.d.d.I ' w D w w ; - , T d.a.: Q b b . ` X / < } B B Z B } < < : : : _ ( S h.; D F *.A 5 6.3.7.Q Q e b Q e e Q @ O b Q e e $ v z L t v ; #.).&.Y >.R e e @ i ! l ",
+"' ' ' . . @ . @ @ @ # @ @ # # # % # & % % & * * % 3.= = > ; - > = n H = V @ a a y a @ & + _ d.d.t o ' @ $ W i W , , c.d.t 1 e ,.b . ` X / M [ e.Z } [ < : : : : ( ( ( _ 2 ; 3.:.7 :.~.*.> # @ Q J $ $ e y e $.r d y l k K $ h T '.i i B L @.j 8 c R C e P {.h ",
+"@ . ' . @ @ @ . @ @ @ # # # # V * # & & % & * N * & = = ; ; > ; H 3 * $ x $ y a y , - $ ) _ d.d.t j ) ) v * - 3., $ c.;.t 1 e b b a ] X Y _ [ Z B [ : : : : : : ( _ ( _ ^ W 5.~.4.A 6.O n 6.1.A @ $ c e Q e $ { Q e l l >.i $ s ^.- = 1.%.b.E z $ 0 _ i 7.e i ",
+"# @ @ ' ' . @ @ @ @ @ # @ # # # # & # & % & & & = $ ; = & = > 3.o w V $ V $ ' ' ~ = , a b _ d.d.d.n J . $ $ $ W ; % '.;.;.2.e b J . =.X ^ 1 _ } [ < : _ : : _ _ 1 ( : _ ^ > 3 A 0 >.4.8.8 >.A g.0 e e c | z y N c e y h o d [ s '.4 @.8.^.A _ ! 0 Z 2 D - e 0 ",
+"% @ @ . @ ' @ @ @ @ @ @ # # # # # & # & % & & & & > & > * = o n > = ~ K * a a ' ! $ (.x ) _ a.;.d.d ) = = , , & D % u d.;.2.e Q J . ] X X / S < : : < : : : _ _ 1 S : : / w 3 4 6.8.4.0 F G 9 =.% e e c M }.M =.e e *.f k l 1 s c.5 F S a.b.o @.j t >.A 1 - n ",
+". @ @ . @ . @ @ @ @ @ @ # @ # # & # * N & & & & ; ^ 3., = -.S ~.* @ , W =.$ a = , ' _.a x : d.;./.H ) , & = = $ D , '.t ;.2.e b J . =.Y / 1 S [ < [ [ < < : _ : _ : < < | D H >.>.*.0 >.*.+.8.4.> e b e i ! C Z z b z f R h | < c.q 8.} /.1.; J | ^.^ { G J C ",
+") ' . @ . . . @ @ @ @ @ # # # # # # # * # & & , & S v 3.k H : 6 $ $ V ' ^ = * - _.y y v ' [ d.;.;.n {.' % ; & & > $ '.;.t 2.e b J . ` / 1 ( _ [ < [ } < : : _ : S : < < | D H A >.>.8.*.~.+.9.A g.. Q e e J j 8 b e M l ; d 1 }.c.g.>.C '.S H N P !.=.@.N g l ",
+"(.(.x x @ @ @ . @ @ @ @ @ @ # # V * * & N N & % - q A O C 9 < S :.A F :.b.o x a ' y a , = [ ;.;.d.$._.v $ $ - W , @ '.t ;.2.e ,.,.+ C / 1 ( < [ B [ < < < < } < [ : } B / w H A 0 >.>.>.~.6 >.8.5 O 5.V |.e i P y c l C $.$.C q %.^ -.* ,.C ^ & _ S X E ! *.| ",
+"i.i.K K v v @ x # @ # @ @ @ @ # $ N N % & * = , ! ^ } } S ^ [ 2 S ^ | | S - (.a y ' $ = # S t /./.f b # + @ D $ - + q ;./._ Q |.) $ 2 | / ( < [ B B [ [ < < } } [ M } B 1 w H A A *.4.>.~.~.>.8.8.9.0 6.3 Q ) i b Q [ 0 z l 1 T }.} +.~ Q P g.E >.q { 8 A M f ",
+"i.(.x x x x v @ v V @ # # # # # % % & & N $ , , , n n ! V ~ V % + V 3.k > i.a ' K V * , a : /.;.;.f ,.~ - @ $ ; % x '.<.d.: |.|.{.+ X 1 / : [ [ Z B B } } } [ } [ : [ B | D H A A >.>.0 6 6 0 0 8.9.9.9.{ R z ! e Q { r k k | Z ^.} ^ -.Q H 3 N A } [ o h | $.",
+"i.i.(.(.x x v v @ @ V V # % $ # $ $ * & & # $ , H -.; v $ V V $ V ! w $ a @ K y $ , , ~ @ B <.;./.$.b Q ) = % $ $ b q /.d.2.e m J . =.( Y : : < B B B B B B } r [ [ } } 1 w H A A >.>.4.~.6 0 8.9.8.6.>.~. .J N a |.1 | d d [ s s c.5 -.$.5 n @ P } S b 8 | N ",
+"x ' i.(.(.x v v v V @ @ V V # $ # % % , V , ; 3.-., @ ~ $ , ! , ! > - ~ ~ K i., * v ~ * $ : ;.;.;.k 7.' ,.' = % ) Q './.;.: e J c ~ C S Y ( [ B Z Z e.q e.Z Z } } [ } Z ^ D 3 A A *.4.>.6 6 *.8.8.6.9.4.A P ) ].b e j | i R 1 }.L ^ *.! i.| A N 6._ _  .j S y ",
+"i.(.i.i.(.(.x x x v @ @ # # # % % , $ $ , ! 5.3 K = V V @ V v > ..w , v @ @ $ @ K $ > * (._ /.;.t O e ,.' 7._.y e ! %./.;.} Q m J $ 0 : S 1 : B q Z q e.q Z Z Z } < } Z | 3.H A A >.>.4.~.6 0 8.8.8.9.4 ~.G ' ].y b 2 n ! 8 2.s }.< 5.J Q :.A > 7 B } N | O J ",
+"(.(.(.(.i.' (.' v x v V v V V V $ % $ ~ ! $.$.! @ =.> v $ , * P - , V a = V = x J V ! V ,.( <.;./.L $.e |.m e |.$.} <./.;.1 b b _.. d X _ _ < } Z q q b.q e.Z B } } B Z | w H A >.*.4.>.~.6 >.0 9.>.6.6.~.o ) $.b c d C f 8 [ }.^._ { ! ,.:.n * G }.=.' >.=.e ",
+"y y (.' (.' x (.' ' . v V V # $ # $ $ , k -.> i., j.=.| S ^ Z ^ ^ | | | ^ , . x v _.x $ ) Y ;./././.L C y e b j t <.;.;.<.0 e J ' {.x G ( : B Z q q q b.b.q Z Z } [ [ Z | 3.3 A A >.>.>.~.6 0 8.0 8.9.5 4 g.$ $ N Q 0 n ].j 1 T }.u ^ n = j @.' A Z 1 7.C ; b ",
+"(.(.(.' ' ' (.' ' x V V ' V , V , K ; n k ~ @ v v ^ $ v @ * H $ * @ $ , v @ $ (.' v _.V @ $ T /./.;./.<.}.=.r ;.;./.;.;.t N e _.) ' ) + D F C : } q b.b.q q q } Z : [ q ^ 3.$.A A *.4.4.6 6 >.6.0 9.0 4.A E {.I J b n { k j O u ^.#.1.K , C G = ` Z ` > 8 h e ",
+"' K y (.' ' x ' ' (.x . v V V V x = $.3 ! v v ~ $ :.# $ * - k * a * , @ $ i ; v ) ' J ' & b @ T ;.<.;.;.<.;./.<./.t <.).8 e _.b ) ' (.' @ = 5.+.^ : } q q q q Z } : Z Z C 5.-.4.>.*.>.4.6 6 0 6.6.9.9.>.7 g.h ].].Q $.8 i O O u ).'.n 7.Q 9 > = | c.Y = 1 K e ",
+"(.(.' ' ' x (.' ' a K v v v v v , $.k , K @ @ x v & x V V @ > 3.* = @ $ w $., $ V v K V b # _.b ; &.;.;.<.<./.;.;.%.R b e y Q ) ) (.' + $ = 3.R +.>.8.C ^ ^ S : } Z q [ A 3 n A 4.~.4.A 6 6 >.0 6.0 0 6.~.3.{.k y b 8 { R j C #.L #.g.v & n o > A f.o { h b e ",
+"(.' (.(.(.' x x i.x i.' @ ' v * w > ~ i.i.$ $ x & (.$ V x V , w 3.~ ~ k H w y a V = K a a a (.) l ^.<.<./.;.<.<.<.;.O v e b _.' ' (.(.v $ - 3.n n *.>.*.~.~.6 +.4.8.^ 4.n 3.n >.4.~.4.A 6 6 A 0 6.6.h.4.+.{ I ].; e h C f M f &.).s A (.K 1 > # ^ j.1.* R e e ",
+"(.(.(.' ' x ' ' ) K ' K ' v ~ 3., v v @ @ V # v v v $ V V = V V $.> 5.3.- v v ) _.a ! ~ a |.D u <./.t /.<.<././.;.t /.%.d e . ) . _._.v $ = 3.H ~.*.4.4.>.*.+.n  . .o -.w k n 4.4.*.>.4.+.6 A 4.4.C 0 *.>.$.7.! $ Q k R j R >.s #.!.^ x ; 6.G > =.L ; ` ! e Q ",
+"(.(.(.(.(.(.(.K y a @ a K ' $ ! * K i.@ v x @ # (.8 8 F F *.:.:.~.0 h.G -._.@ ' ' Q , - @ $ '.<./.<.<.<.U M T /.<./././.!.W Q ' + J J . % = 3. .n :.~.*.>.~.~.+.-. .H o $.H n >.>.*.>.A +.6 A 4.O 4.*.0 4 6 @ h N Q N | ; 2.v T ).!.{ Q {.^ @.E S =.] 0.b Q e ",
+"' ' (.' ' ' K ' a @ @ K i.v ~ , > * @ x v @ x . ; } *.*.F 8 P G 4 g.=.{ _ $ . ' N ) 7., D { d.<./.<.L [ z e @ X ;.<.<./.<.0 7.) ' ) # D 3.3.3.5. .H n n F ~.F o -. .H R $.H n *.4.~.>.A 6 6 7 4.~.^ 9.>.*. .Q $.k Q h 8 8 l $.#.%.!.=.b V E * D S j.> D {.e v ",
+"' (.' (.' x x ' (.y ' i.i.V , @ ~ ! , x v # v @ x S V $ , $ = ; 3 -.~ ' | $ + @ + x x b b e.<./.<.'.W |.|.) Q {.i 2.;.<.<._ Q _.J @ P 1 : ( ^ ^ g.4 F -.H o n H 3 3.H -.$.H n *.>.~.4.>.6 6 A A 4.6.A >.>.R ' i N Q ; 1 8 | K Z ).!.O ' > =.; o b.[ G I Q e e ",
+"x (.) x ' i.) (.(.x K ' ~ ! , K K @ 3.- v v ' $ $ c.S | ^ 9 4.] 9.:.6 ^ j.= $ & y ) v # Q : <.<.<.d Q ' . . @ @ c J }.<.<.M e J m @ X ( ( : [ Z b.q [ S =.j 5.> 3 W  .H  .5.n 4.>.*.>.4.6 6 >.4.A 4.8.>.~.-.' ; f Q h f | >.; r ).L : _.$ :.G 9 | #./ % e e y ",
+". (.(.x ' ' (.' ' x ' (.v , $ v K ~ v 3.> _.@ v v $.o :.F g.^ 5 6 *.:.6 3.$ - J _._.$ ; ,.S /.<.<.d Q ' . ~ % % @ c s <.<.[ Q b J a C 1 1 _ < Z Z b.'.c.q } ^ ] n  .i i 5.E o ~.>.*.0 0 6 6 *.4.A 4.8.A 7 n @ - $ Q h 1 f | Q !.).%.2._.b 6.3.3 ] ^./ @ Q |.Q ",
+"(.. (.(.' ' ' ' (.v x (.i.v V V V i.v ; 3.= K v @ K @ $ - H > = $ - - $ - @ V y ) V ; , e 1 <.<./.o {.' ' * ; z @ c T ;.<.} e b J + 2 1 ( : : } q q b.b.'.q q Z < 1 *.i D 5.o 4.*.~.*.0 6 6 >.>.6.4.8.>.~.6 D n o e f i Z R i Z ).%.&.b v 3.*.-.C U 1 |.b e a ",
+") x x ' (.x x ' x x K x x K v V V v V K = 5., $ v , v , H 3.~ @ $ , , V  .@ ,.(.v $ % . e 2.<.<.<.o |.' v - ; % b b s <.<.} Q {.J @ X 1 ( : < B q q q b.b.q q Z q q : p 5.> H 8.>.*.0 0 6 6 >.A 6.4.8.*.6 P = k ; e f X *.1 e %.L d.X _., ^ 3.=.B <.p Q D - e ",
+"J ' x ) ) (.x (.x ' K K K v K v @ > v (.@ & w , @ , > -.5.w ! @ $ - - - b # v a ; v ) . e S /.<.<.o |.+ # , # ) Q Q s <.<.M e m J . C 1 1 : : } q q b.b.b.b.q q < B Z : :.> 3 *.*.6 *.0 6 6 >.>.A 4.4.4.~.F w  .k Q K R &.n $ 2.).%.}.b > H ~.6.q ^.P e ]._.z ",
+"{._.(.(.(.(.' ' x ' ' x x v K K ~ ; = V K ' , - , 6 O 9.+.7 *.9.:.8 G R W ' % + $ . ) ' e 2./.<.<.I |.$ $ . _.Q b b s <.<.M e ,.J @ 2 1 1 : < B q q q q q q Z Z Z [ Z e.g.@.H *.0 *.*.0 6 6 *.>.A 4.A >.6 F  .o ! Q h =.C Y Q t }.t | m ) A 6 5 g.f.n {.|.e e ",
+") ) ) (.x (.' (.(.K x v v x v x V K w ! ~ v _.- H '.^ A F F ..4.C 7 4 :.B $ , % (.x ) J e [ <./.<.f ,.~ ' [.,.Q J e T <.<.[ e ,.{.. =.1 ( _ : } q q b.b.b.q q Z } _ < q ^ 3 5.~.*.6 0 *.+.6 >.>.A 8.4.>.+.R ; ; $.e K $.&.R J 2.t f.%.7.J 5.-.H / ^.o Q b e $ ",
+") J ) ' v x K x (.v v K (.K v v K K ~ 3 3.v v K $ [ $ v V $ & a $ , ' # ^ z $ J ' [.|.J e [ <.<.<.o {.. b Q ,._.,.e T <.<.[ e b J @ =./ ( : < B q q q q q q q Z Z B } q ^ 3.w 4.>.~.0 0 6 6 *.A A 4.4.>.6 G o n $.Q ! 0 2.Y J ).}.).r J > 5 +.F ^ a.D b ' |.Q ",
+") ) x $ @ ) ) V v x (.' v v v v K @ i.@ $.5.$ i.$ '.[ S ^ ] F :.F :.F ^ '.; J |.b |.b ) J 2./.<.<.n Q Q ,.Q |.b Q e '.<.<.M e |.b . ^ 1 1 _ : } q q b.b.q q Z Z [ < } Z ( D $.~.*.6 *.*.6 +.*.>.*.4.4.>.G o ! v k e c n '.$.e M t ).^.Q , 3.A 6.e.s ].Q m e b ",
+"(.V % v (.x V $ v v x K (.i.i.K v K v v * 3.3.@ K 5.P 5 9 +.~.F *.~.F F n ) |.m Q 7.,.) _.M <.<.<.g Q |.J Q Q Q Q b T <.<.[ Q {.b a X 1 1 _ < B q q q b.b.q q Z } < [ B | D $.*.*.*.*.*.6 +.~.>.A A *.~.*.F i + $.b y l T *.K %.L ).'.z $ o >.6.^ a.].J $ Q e ",
+"% N v ) (.$ $ v _.x $ $ v ' x v K v v K _.; H 5.@ i.$ * ! V - * ~ $ 3.= {.) ,.,.Q b ) ' _.2.<.<./.I e e Q Q |.Q Q e T <.<.: e |.J . 2 | | _ : } q q q b.q q Z Z B [ } B | w $.~.*.6 *.*.6 +.*.A A 4.8.*.n P ..D h e c n s z _.[ ).).}.7.v x 6.3 X %.d e @ e b ",
+"- v _.) x v x ' i.(.x v v v K x (.$ x (.V , = 3.$.* V K * - > 3.- , ! a |.' J |.) ' ' ) J _ <.<.<.d Q Q |.Q ,.b b e s <.<.[ e {.b a C 1 1 S : B q q q b.b.q q } [ < } B | D 5.~.*.*.*.*.6 +.~.>.A *.A *.6 F D Q j e Q l r R K %.!./.u @ J F C A 1./.i @ z c Q ",
+"' ) _.(.(._.(.V (.i.i.x v v (._.v v (.V w , i., A 3.@ @ v > 3.3.k w 3.v , J b {.) ) ) ' ) _ <./.<.$.Q Q ,.,.Q 7.b e #.;./.} e J {.. X / | _ : } q q b.q q q Z Z } < } Z | > $.6 *.6 *.*.6 +.~.*.~.A 8.~.n 6 :.d z K e o %.@ e Z ).).T J * F 1.~.B }.0 Q ) m J ",
+"_.) (.(.' K x x x (.i.' $ , $ V x i.v * & v @ - , R n ~.6 O 0 6 *.0 5 :.*.. b [.) [.) v ~ [ <.<.<.$.Q e Q b Q e e b s /./.} Q e b . 2 | 1 _ : B q q q q b.q Z Z [ < [ B | > $.~.*.6 *.6 +.+.6 >.>.>.>.*.~.+.; Q n e Q ` } ; a !.L L M 7.# =.C 7 =.t d c $ c e ",
+"K x ) ) (.x x ) $ V K ) ) V > 3 * K @ $ i.v ! 3.K 6 ~.F 9 5 [ | 6 7 0 5 F * ) ) ) (.+ ~ + Y <.<.<.k |.,.|.,.b Q Q J Z <.<.1 J Q {.. =.| | ( : } Z q q q q q Z B } : } B | w 5.6 6 6 *.*.6 n ~.>.>.A >.6 n F F o ! a Q 0 ^.c e T ).;.2.J i.6.A 5.=.%.>.J N y b ",
+") ) ) ) ) (.K v ) V , $ i._.v = $.& v v @ ; ! v V K $ = & V | ~.$ @ *  ., - x (.) x , + Q G a./.u J e Q Q Q Q b b e 0 ;.;.j e e b a C / 1 ( : B Z q q q q q Z Z [ : [ Z / w 5.~.*.6 6 6 6 n 6 *.~.A >.*.~.R = (.n Q Q Y u @ @ #.;.;.1 c ) F C F j L o c @ e e ",
+"x ) ) (.' i.(.' K ' , = @ K K i.= ! v K ! * i.V v ^ ^ S | S j.Z | | ^ ^ | W @ v # * ' b b {._.~ |.Q e e _.e Q ,.J b e @ @ b e J b . ] / 1 ( : } q q q q q q Z B } < } B | w 5.~.6 6 *.6 6 +.~.>.A 0 >.6 6 P o  .; $ J =.U e b #.).<.1 7.3 C A 8.^ L O Q c c e ",
+"i.(.x (.(.K ' _.(._.K , * a K @ ' ' i.@ > k * i.v *.:.F :.F >.+.6 :.:.:.F * , , = (.b |.|.Q e |.|.e J e e e b e e b e b e e Q {.m a =.| 1 ( : } Z q q q q q } B } : < B 1 w 3.6 ~.6 *.*.+.n 6 *.*.>.>.G 6 n ; J g Q e u &.J @ T t L 2._.F >.8.*.| a.>.K ; Q e ",
+") v v (.) (.(.(.' x i.' = * K y (.x ' @ ! 3.- $ K V @ & ; @ x & v $ $ $ (.' % = (.b |.|.J _.,.e e c 7 [ T }.T } R a e e b b b b b K 2 / 1 S : [ Z Z q q q Z Z B [ < } B | D  .G 6 6 6 6 6 +.~.~.G *.4.~.n P H - I z Q 2.u e e }.%.;.{ ,.= 9.~.A =.L C e J y |.",
+") ) x v x _._.K i.a a K , w , _.y V $ * 3.* ~ > $ i.a a , w $ v , @ x V y V V y a ) {.Q m e e b 7 }.<.<./.;.<.<.<.L 0 e e Q b c b K =.| | S : [ Z q q q q q Z B } : [ } / D 3.6 ~.6 6 6 6 n ~.~.A *.*.G n 6 o + f y e T =.b a &.;.L M 7.-.6 ^ -.A %.>.v z e e ",
+"J J (.V V x i.) i.y a $ , , - ! x v @ - k > ~ * * , v = 3.* ' $ $ @ v @ . J _.' # x J J [.e ~ 1 ;.<.<./.<.<././.<.;.<.e.@ e @ e b K =./ 1 ( _ B Z Z Z q q Z Z B [ < [ B | >  .F 6 6 6 *.n n G ~.*.*.>.G n n i ) j @ J Z }.e {.}.L <.G ,.H ^ +.^ ~.f.=.y N J J ",
+"' i.) ) v V v i.v v * $ y a ! w @.V v , ! k k * K ^ : : O , H ( ( | | g.g.x _.K ) v x ' ) _.S <.<.<.<.t %.%.U /./.<.<.<.'.c e y b K =.Y 1 S _ [ Z q q q q Z Z B < < < B 1 > 3.F 6 6 6 6 6 -.6 ~.G *.A *.n n  .$ h b c #.C Q a 2.t ).1 Q 6.>.9.6 S L =.b v |.e ",
+"x v ' i.i.v V V $ = , a ' $ , a -.= @ @ @ > $.k ~ : 3.' v $ ] A V @ , 3.< & y b |.@ # ' {.> L <.<.<.r h Q b ) ~ }.<./.<.;.I e Q b K =.| / _ _ } B Z Z Z q e.B } } : < } / w 3.G 6 +.6 6 n +.6 ~.*.*.~.G F R w ' l $ e Z u Q b %.t ;.p 7.! 8.*.*.=.).0 e @ e e ",
+"i.v , & v _.' , , a _.' - & (._.a V , - ~ K ~ -.k ^ ~ - $ x 1 :., # a ' ( J ) a ) J (.+ ' j <.;.<.L . e ,.e Q e b #.<.<.<.o ,.m b K =.| / ( _ } B Z q q q Z Z B [ : < } / D 3.F 6 6 6 6 n n +.~.~.A *.~.+.o 3.- $ c c !.j e c 2./.^.0 |.3.+.8.+.*.^.| J v Q e ",
+"v $ (.y * V b = , x ' ' V , a ' ) $ V v * ~ @ * -.j.j.c.j.^.j.> $ { ^ ( '.& J _._.J ) ' m : <.<.<.C Q e 7.e ,.e Q > <.<.<.O e Q J y 0 1 Y _ : } Z q q Z Z q B [ _ [ [ < | 3.5.+.+.+.6 6 +.n G ~.~.*.~.6 F n  .- 0 y e M [ e N %.L <.f {.~.9.0 8.+.L O v K b e ",
+"3.$ ' (.i.v i.(.- V a y ' V v a V $ ' y $ ~ @ * * -.> * ~ _.$ a @ = v ) - Q . x ) ) ) ) b : <.<./.l e e b e Q Q e @ )./.<.C e ,.e b *._ 1 S _ [ B Z q Z Z q Z B : [ } [ / > 3.+.+.+.6 6 n -.+.~.6 ~.~.6 +.o 3.; o e y T f Q e M ;.L =.e 6.~.0 9.^ L Y b N Q Q ",
+"$ v i.b a $ ' K V ' (.y ' V V $ + v ) J i.a ~ * @ > k > $ $ $ V $ v $ x @ ' V ,._.J ) (.m 2.<.<./.g e Q m Q e Q e b #./.<.S e b c e @ n 2 : < } } B q q Z Z B } < _ : [ ^ > 3.n 6 +.6 6 +.n +.G *.~.G n n n o I P c b M X Q a ^.L <.h e 3.^ *.>.=.d.>.$ J Q e ",
+"b i.K J V = V $ y y (.) i.' V $ ' ) ) ) ) ) a @ ~ @ * 3.k - @ $ $ v $ ' (.a y ) _._.) (.{._ <.<.<.o e Q e Q Q Q Q Q u <.<.M e e m e e x D F ^ [ q q b.q Z Z Z [ B _ : B / D 3.+.+.+.6 6 n n +.G 6 6 *.G n o 5.> @ e N M o e b [ <.).Y e = *.8.-.5 ^.u e @ e e ",
+"K _.@ $ @ ! - v J i.x v . (.(.' [.) ' ' ) ) ' (.w @ a * 3.- $ ,  .v $ v x v b a ) ) ) ) J : <.<.<.d Q b e |.,.b ,.Q '.<.<.} e e |.J b b [.. 3.F ^ S } q b.q } [ : _ < B ] 3.@.+.6 +.6 6 n n +.G ~.>.~.+.n R o H k $ e Z { e z T t <.~ ) >.9.0 ~.5.a.O @ e Q e ",
+"a ' ~ $ , ! V i.) ' V $ V (.' ) ) _._.c y y ' ) _., * ~ * > 3.@ ^ @ @ V y ' J ) _.) ) ) m _ <.<.<.f e y b e e Q e Q '.<./.M e e Q |.Q b ' V = w 3 F 4.^ S } Z q < < Z } p > @.F +.n 6 +.n -.+.~.n G ~.G n H D = {.e ; C $ e e r <.L j b h.*.0 8.^ %.&.e $ e Q ",
+"J y i.a - $ b y K V v V @ x x (.) ) c c y K y ) . $ ~ ~ @ * > > | a @ @ v v ' J ) ) y ' m : /.<.<.d Q a ' b Q e e Q T <.<.: e 7.Q |.{.J ' , ; 3 o n n n n ~.6.g.S _ [ ( 8 > $.n +.n 6 6 n n n G ~.~.~.n n o 3 i J { e &.>.b a #.t <.@ b 3.^ *.>.C d.| v b Q e ",
+"a _.K @ ' i.J K $ $ v v x ) ) J _.) y y y y y K ' ) V , , ~ ~ > _ $ $ ' x (.(.J J _.) (.m : <.<.<.n Q ' . @ ' Q Q Q T <.<.2.e Q J Q {.) ' V &  .H n :.F n o H  . . .n n ; ; H n 6 n 6 6 n n +.6 6 6 ~.n n o 3 D @ @ @ f K e |.s ;.U j e * *.C +.4.%.r c y e Q ",
+"_._.(.y J i.@ @ 3., v J ,.) ) ) ) ) ) ) y K K . a + v (.' , $ , : 3.$ y a ' ' J ) ) ) _.b M <.<./.n Q J @ , . ,.e Q T <.<.M e 7.b 7.m m v & >  .H n 8 F 8 o 3 5.D * D 3.> > $.6 +.n n 6 -.-.n 6 +.~.+.+.+.n i ; @ }.y C h e z &.<.).@ ,.P *.9.n o ^.Z c b e Q ",
+"V y J _._.K * k * -.@ _.' {._._.) ) _.) ) K . . a . . . @ # $ V - - - a a @ _.) ) ) ) ) ,.2.<.<.<.H |.. @ $ ' b Q Q T <.<.M 7.7._.e J ' N = ; > 3. .o R P R o 3 i = D 3.w > 3.n +.+.n 6 n -.+.6 +.~.~.+.n -.o n @ o k K N e e %.t L f @ ~.8.*.9.7 f.2.K b e Q ",
+", v J ,.) @ * * k ! $., J (.m ) _._.) ) ' . . + # @ % @ @ (.% % . = ; - ' y ,.' ) ) (._.b : <.<.<.H |.@ + + x ,.e Q T <.<.M e e e e H { ^ g.*.n  . . .5. . . .3 D w i 3.w > k n 6 -.+.+.-.n n 6 ~.6 n 6 6 o 3.D z /.b C v e $ S <.!.J 7.A 8.8.*.: L u Q c e e ",
+"K @ @ a $ $ ' J 3.* > k v b ' [._.) ) ' . v v v # . # x @ @ # # = , @ D v $ ' J _.) ) ) ,.: <.<.<.o {.' v ~ ' Q e Q T <.<.M e 7.m c 0 / S _ < [ S ^ A P 3 3.3.D W ; D D 3.3.k +.+.n n 6 -.-.n 6 6 ~.6 +.n H 5. .8 2.j J c e e ^.t %.f 7., 8.9.*.7 f.Y y e e Q ",
+"_._.v w 5.$ _.) ~ * * k 3.v [.) ) _.) ' x . @ @ V V % % E j P n R n $ v $ $ . ) ) ) ) _.{.: <.<.<.0.b ' @ $ ) e e 7.T <.<.M e e e c ` 1 / | : < Z Z q } ( 1.j o @.D ; = > 3.3.n +.n +.n -.-.+.+.+.6 6 +.n 3 w $ ; t e R c e c 1 /.}.Q J 6 *.^ n F ^.}.b b e e ",
+"K _.J $ 3.> a J i.K > > > 3.K ) ) ' ) ' v v V V x ^ q q ( ` j p ( | '.b.:.) ; ) ) y y _.,.: <.<.<.o Q . $ ' Q e e e T /.<.M e e Q ' X Y Y ( : < B B Z Z Z B [ < ^ A n D - w k n +.n +.+.-.-.n 6 6 +.6 +.n 3 & ,.j !.{ e J e J '.;.L k N 4.8.0 9.5.f.[ y e e _.",
+"@ i.J J @ w - _._.i.i.! > > k v y ) . v v v v V & ^ = v + % @ ' . . ' W < $ b ' J ) ) ) b : <.<.<.o |.. ' b e Q e Q T <.<.[ e e Q c X / ( S S < [ } Z Z q Z B B e.< / :.3.- 3.n n n n +.-.-.n +.+.+.G +.n 3 3.D o /.e N e Q e | ;.}.7.7.4.0 6 6 g.f.T b e e e ",
+"K a v K i.$ w > ' i.J _.* 3.! $.i.(.x . v v v V a b.0.G j j *.n 9 j P R q a v x _.) ) _.b : <.<.<.o J ) e e Q Q e e T <.<.M e Q b _.C X 1 ( ( [ B Z q Z q B [ [ S < q / o - 3.n +.n n +.-.-.n +.6 n 6 6 -.3 D > l t 0 Q e Q J }.).%.> 7.5.9.8.6 6 L [ K Q e Q ",
+"_.i.@ v _._.V w $ J i.i.@ k > > 3.* i.$ 3.- (.@ % P 7 F 9 9 j p j G ..o A H v ) (.(.y x ) B <.<.<.d e Q Q 7.Q e e Q T <.<.[ e e e K =./ / 1 _ [ B B Z q Z Z B [ : ( _ < 4.* 3.+.-.-.n n -.-.n +.+.n +.6 +.$.> m { %.e e e e e S /.T 7.' 4.*.9.H +.%.T b e Q Q ",
+"i.K K _._.i.K v R = b i.i.@ k > > 3.! $ x V & $ v * ' @ & @ , ' $ . = @ @ ) , V ' {.) = # e.<./.<.d e 7.Q e Q e e e u <.<.M e e e y =.Y / ( _ [ B B Z Z Z B B } : S < B =.- 3.n n -.+.n -.-.n +.*.+.n n 6 H ; {.*.<.j e e e K s ;.U $ z *.8.0 6 > j.T c e e e ",
+"~ ~ K _._.v ~ v @ $.w i._._.K ! k - $ K y @ = = $ # + * $ v & & v ; = v a ' (.$ ' ,.v > + : <.<.<.f e Q 7.e Q e e Q T /.<.[ e e e K =./ / S S [ B Z Z q Z Z } } < _ : B 2 > 3.n n -.n n -.-.n +.n 6 6 n n H H i *.t ; b e e e [ <.M 7._.^ 0 0 0 ] L u J e e e ",
+"~ K _._.' @ a ' b i.H 3.i.K K i.! ! @ _.@ , , = @ v = $ $ = @ , , ; ; W b (.a V x _.. % m ( /.<./.$.e e 7.e e e e Q T <.<.M e Q e K =.Y Y S _ < } B Z Z Z B } [ < _ : B ^ D 3.n n -.n n H -.n n n +.+.n o $.> {.` <.$.e Q e K r %.%.z Q ! 9.8.+.5 f.!.$ Q e e ",
+"~ @ v $ $ ' y ' i._.a $.- _.v i.K * - K ' $ @ ) ' ..F R j :.:.F *.:.*.~.o y a @ V . ) [.b [ <.<./.f e e Q e Q e e e T /.<.M e e e y =.Y / ( _ [ B B B q B B } [ : : : } C > 3.-.n -.n n -.$.n +.+.n +.n n H 3.7.=.;.=.e e e e u <.[ 7.) O 6 0 *.+.}.u J e e e ",
+"w * $ * $ _.i.v _.a {.a 5.$ ,.K K K * * @ $ , _., B *.:.p j r 1 *.0.:.P c.$ (.b y . ' y J } <././.$.e e 7.e Q e e e T <.<.M e e e K C | Y 1 _ < } B B Z Z B } [ : 2._ } ^ > w o -.-.n n -.H n n 6 n 6 -.3.5.3 [.X ;.v e e e K 2.;.s c = A 9.8.n ! }.^.N e e e ",
+"$ & * @ i._._.' @ {.(._.$ 3 @ b ~ y ~ > > > 3.* y : @ ' $ x _ A 3 V ' y : ' D , {.(.V # m _ <.<./.f e e Q 7.Q Q e Q T <.<.[ e Q e y =.Y | ( _ [ B B Z e.Z B } } _ : : } C w > n n -.n n H 3 n +.+.n n n n n o ) | t M Q e e b e./.1 7.@ C 6 *.9...#.#.v e Q e ",
+"m ~ - ~ @ @ K _.' % (.(.@ & w ! _._.y a * > w > a '.7 ~.R ~ 2 H $ ( ^ h.j.! v $ (.,.) + Q / <.<./.f e Q Q e Q e e e T <.<.M e Q e K =.Y Y 1 _ [ } B Z e.Z } [ [ _ : : B Y w > n o H n n -.H n n n -.-.-.$.! ; ' U ;.; e Q e J 1 /.u J 7.n 8.*.*.| d.%.v e e e ",
+"|.{.$ > * @ K i.) J @ & V _.' H * i.y a K ~ > > k k o :.-., v , , o *.:.5.a J ' - a J v b [ <.<./.o e e e e Q Q Q e T <.<.} e e e y C Y / S _ < B } B Z e.B B } 2._ : [ ^ w 3.o -.-.H n H $.n n +.6 n -.3.H  .) u <.M Q e e e u <.X 7.' H *.9.*.G ^.}.N e e |.",
+"[.Q {.$ = = V i.(.(.v v y J _.* P ! y i.@ @ ~ > ! ! , a ' x @ + # + W W ' b ) b = & J ) |.: <.<.<.$.e e Q e e e e b './.<.M e b e y =.Y Y 1 S [ B B B Z Z B [ < _ S : [ / > D R o H -.-.H 3 n n n -.n -.3 @.. ; t t j 7.Q Q y X <.M c > O >.0 -.$.T %.v e e Q ",
+") ,.{.) $ ; * K v ' v ) J K $ , W 3., J i.v @ ~ > 3.! x i.$ * $ $ & @ x (.y y x V ; J J |._ <.<.<.k e e b Q Q b e {.T /.<.S e e e c C Y | ( _ : } B Z Z Z B } } _ _ : [ ^ w 3.o -.H H n H H -.n +.H -.-.5.> ' k }./.S Q Q e e }.<.0 7.> 8.8.0 8.H %.}.; e e {.",
+"J _.) {._.V - $ V K K ) ) V , V b V ! $ i._.K K * ! $.3.& v @ $ , W $ ) ' x x & ' % . (.,._ <.<.<.k b e Q Q b e e e T /.<.[ e e e y O Y Y 1 _ < } } B Z B B [ [ _ S : [ / W w o n H -.-.H H -.n n n $.H 3.3.> ! <.).O J e Q J 0 ;.u 7.7.*.6 *.6 9.#.).c e e e ",
+"_.) J b {.(.$ ! ~ K K v v v v ' ) (.& ! , i.i.@ @ , ! 5.> V a $ & V V (._.$ - a b b $ + b : /.<.<.$.e e e e Q e Q e %.<.;.M e Q e y C Y / S _ [ } B Z Z Z B } [ _ ( _ < ^ w w o o H -.n H H -.n n -.$.H 5.3.; h u /.| e ,.e e T <.j 7.* 9 0 8.8.5 f.#.! e Q b ",
+"$ ' b _.) ,.J V - ~ v @ ' ) K @ @ x (.$ w * K K K K ~ ! w w = V V v v V , - V ,.) 7.J y c r <.<.<.j e Q Q e Q Q e K t <.;.Y e e e c C Y Y 1 S < } } B Z B } [ < 2.S : < ^ W w o o 3 H -.$.H -.n n $.-.$.3 = J j <.L 2.J e ,.e | /.| c  .C >.9.-.R '.%.c e Q Q ",
+"N v ) J _.b b _.- ! * ~ v _.' x ' . ) ) , w , i.K K v $ - w = v i.V v V = x Q b . ,.7.,.c S <.;./.} e e Q e Q Q e 0 ;.<.<.0 e Q e y C Y | ( _ < } } B B Z B [ < _ ( : < ^ w w -.-.H -.-.H $.-.n n H -.$.5.> J >.L ;.C e ,.e e } <.j 7.D =.0 9.8.= j.).i e e e ",
+",.# # J m _.) J i.* * ~ @ K (.) v (.' (._.$ w * K v v v V , $ x @ (.& > x ,.i.& ' # Q Q 7.{ /.<.<.t z Q e e e e N ^.<.<.<.R e e e c O Y | 1 S < } } B B B B } < _ S : < Y W w H -.3 -.-.H $.-.n n n 5.k 3. .> 8 /.;.u ) e e e 1 /.1 7.,.4.~.*.9.O }.}.y e e Q ",
+"b ' # . J J c J b K = ; , v K ) ) ' v v ) _.v - K v K @ @ V = ~ V v = v J $ ' J b v @ b e $ t <.<.<.#.0 ; c @ j t <./.<.;.$ e Q 7.J =.| | S _ [ } B Z Z Z B < : _ S _ [ ^ w D n o H H -.$.H -.n n -.H 3 w 3.7.=.L /.>.e e e c } t j 7.J n 0 0 *.8 f./.i e e e ",
+"J J ' @ a ) c J _.b i.$ = , $ v (.' (.v ' (.K $ > K i.i.v $ v v $ $ & (.J 3.= ,.) ,.. ' Q Q 2.<./.<.;.;.<./.t /.<.<.<.;.u J e e e c C | Y 1 _ : } } B B } } [ : _ _ _ [ / > w o o H -.n $.$.-.-.H -.H 5.3 _.b C t ;.}.e m J e 1 <.0 J ].8.8.0 n P j.}.v e Q e ",
+"i.b J v @ a y _._.{._.' $ , , v v x (.' x v x i.i.3 w _._.V V , , ; * K J i.$ ' J J . [.@ Q _.Y /.<.<.<.<././.<.<.<.t =.y e e e 7.y O Y C 1 : ( B B B B B B < < _ ( : < ^ > w -.-.3 H -.$.H -.n -.n $.3.3.3 ) | ).;.f e e e y S t i 7.o C 4.C 6 V }.t h e e e ",
+"_._.J _.) @ @ K J ) ) _.(.V , $ v x (.(.x x v x (.< : : 6.V :.B ^ S B : S i._.V a b (.x ' . e e g &.<.<./.;.<.<.<.r $.e e Q Q e Q y O 1 Y | : < < < B Z Z B < : 2.( : < ^ W D o -.3 H -.$.$.-.-.H n -.H 5.j J 1 /.).Y b ,.b e M <.{ 7.@ C 8.0 ^ 6 j.#.$ e e e ",
+"J i.) J _.' @ N J c _._.) a $ = V v K (.(.x x v x ^ > 3.= ) ( ~.$ a @ w } K _.v , y b (.m @ # Q e ) $.O : r S 0 $ e e Q J e e J 7.7.j _ S / S } } } B Z Z Z } < _ S _ [ ^ > w -.H 3 H -.$.$.-.-.H H k 3.5.(.# s <.t d e Q e y 2.t d 7.' -.4.9.*.~.L ).N e Q Q ",
+"b _.) ) _.J ) N @ y J ) y ) ) $ $ $ V K i.' v v _.: v . 3 $ ] n a , $ , [ , a J ' ! _.J x (.(.) e e e e e e e Q Q Q e e e e b e b 7.h C _ S S : Z B B B } [ < : S S _ < ^ > w o H $.$.H $.5.-.-.-.-.H $.w (.7.&.<.}.O e ) Q e u ;.j J W =.9.*.~.:.j.}.N e e e ",
+"{._.) i.i.J J ' # @ K y ' J {.' ~ $ ~ V K ' ' ' $ ( q U j.j.c.a $ 5 | ^ S ! $ ' y y , v y b y + ' $ k 8 n d d g d $.$.k $.J e Q e 7.J $.O 1 _ } < } Z e.B [ < < _ ( _ < ^ ; D H H 3 H -.5.k -.-.-.H k $.3.R + ^.t /.$ |.b {.c X t ! 7.o ^ 0 *.+.w s L ; e e e ",
+"{.) J b _.i._.{.' $ # c _._._._.v V V V V v x i.(.x V x x # @ v y , y ~ ' y , , ' b , ' $ b a Y %.t <.<.;./.<.<.<.<.<.<.<.0 e Q e b 7.b . W d 7 | _ B Z Z } < : S ( : < ^ ; w o 3 $.$.H $.5.-.-.H -.$.5.5.[._.#.<.}.o e @ Q e u ;.>.7.* C 4.9.9.= q L k b e e ",
+"_.) _.J _._._.) J ' @ # . ) _.) J (., $ V V V (.i.V v v V ' . $ a @ @ y m ' y * , m b ) ) Q q <.<.d.<.<.<.<.<.<./.<.<.;.<.1 Q e b 7.,.) . @ # ; D R *.] S } B < : / ( [ 4.> > H 3 $.H H $.k H -.$.5.$.> - (.! a.;.t @ e K Q b X %.].Q . *.4.0 >.h.^.t $ e e e ",
+"_.J _._._.) ) ) (.J ' # V ) {.(.' _.a , $ V v K ' i.x V (.v & (.V ' y a ' J b ' * $ a _.) k L <./.<.<./.<.<.<./.<.<.<.<.;.0 e Q Q Q Q ,.) v * D 3. . . .H ~.1.=./ _ B _ R = 3.H 3 $.H H $.$.H H -.5.3 5.E x ~ T <.u b b a e e &./.k 7.o >.4.4.*.7 U /.i e e e ",
+"J _._.J _.) _.) ) _.J x @ v (.) ' J ) @ $ $ V v ' x _.' V x x a ' @ y ) v b y b v * $ ' b { <.<.<.d.Y p 0 0 0 l j 0 l l n ) e e e {.b {.' v - 3.3.3 o 3 5.@.3.> D P 9 8 ; = 5.5.$.$.H H k $.H H $.5.5.5.o , n /.%.}.y e K J c 1 !.; 7.j 8.=.9.-.R '.a.v e e b ",
+"_.J _.) J ) ) ) J ) ) _.(.# @ ) ) ) ) ) a , & V ! =.| C ^ ^ ^ 2 ^ ^ | : b.(.J ) {.@ = = {.^ <./.<.< |.e e e Q |.e Q e Q Q e |.,.e Q Q ,.. @ & = 3.3 H 3 E @.> ; @ @ N = = ; 3 3 5.$.$.H k $.H H H 3 3 3.D |.i }.<.Y Q J K e e Z /.! 7.> ^ *.8.6.* '.d.j e Q e ",
+"J _.J _._.) _.) ) (.(.J _.V # . ' ' ) J ) v $ $ (.V V v ' @ & ' a a ' _.( ) y J b _.$ D (.S <.<.;.j e m m ) ) ) ) m ,.a ' Q Q e J e Q [.% & ; ; @.@.3 E 3 3.3.= * @ & D > ; 3.H $.5.H $.k k H 3 H 5.5.3. .@ { t !.#.e e N Q v M !.h 7._.9 =.9.>.O c.f.@ e e Q ",
+"J _.J ) _.) _.) (.) ) y ) (.. @ # . ) (.(.) (.$ , , a ' a y a V $ i.v D q . Q b J b ) $ ) r <./.<.I b . ) ) ' @ % # # % @ ~ . e e e > j O A F 3 D D 3.3.5.@.3.> N @ % = ; ; >  .$.5.H 3 5.5.H H $.5.H @.; b { ^.;.=.e y N e Q M ).; 7.3.>.C *.:.~.j.a.o e b e ",
+") [._._.) ) ) ) ) _.) ) ) _.) x # + (.) ' ) _.x $ ^ : | | | ^ | ^ S | 4.~.(.|.y J b b [.J } <.<.<.H ,.[.@ x . $ x , , ~ $ $.* e Q |.7 2 ( _ _ S =.A 8  .> > W > * $ * = W 3.3.3.5.$.3 H k 5.H 3 H 5.3 ; + e | %.).Z b e K J N 1 #.N b F =.: ^ ..6 q L ].e e e ",
+"_.[.[._._.) _.) J ) ' ) ) ) ) {.. # x ) (.' ) ) V $ a $ ~ y ' a @ a ) , |.(.b _.J J y [.b : ;.<.<.$.7.(.d = . v $ @ @ # = I @ e Q ) X | X | _ [ B B < | 6.o 3.* * * ! ; ; ; 3.3 5.5.3 3 5.5.H 3 $.3.H @.> ' S #.t *.e y @ ,.a } ).- Q 3 C 4.^ 6 ! b./.n e Q e ",
+") ) _.[.[.) ) ) ) ) ) ) ) ) ) (.) ' + + . (.(.' (.' @ $ @ $ a ' ' V x (.(.b [.J J ) ) [.Q S <.<.<.H Q = o R W x @ $ + $ D ; y e e c =.Y | 1 : : < < } B B : 2 1.f W N ; > @.= 5.5.5.5.5.3.5.3 $.H 3.3. .I {.| %.!.[ e e z % E #.#.$ ,.x 1.C C G :.q ^.f e e e ",
+") [.J ) [._.) ) _._.) ) ) ) ) ) ) (.. @ @ . (._.) v (.@ @ @ (.@ v a x ' [.) ) b J ) ) ) b : <.<.<.I _.= # ;  .; v @ ;  .k & _.Q e ) X Y | 1 _ < [ [ } } Z B < _ S Y 9  .* ; 3.H 5.3.3 3 3.5.H 3 3 H 3 ; = K Z #.t 8 e J b ) n 1 ;.@ 7.; A ^ : 4.g.^./.$.e e Q ",
+"b J _.) ) ) ) _.) ) _.) ) i.) i._.) (.. # V . ) ) + J , ' $ $ ' a x a ) x [._.) _.J _.) m M <.<.<.n J ' ) @ W D ; , ;  .* _.|.e e c =.Y / | : : < < < [ } B < < _ [ _ O  .> > 3 @.5.5.5.3.5.3 $.5.3 5.; _.e u #.#.2.e b % |.' Z '.N ' G =.: C -.P '.^.n e J e ",
+"b m J ) ) ) J ) ) ) _.i.) i.) ) (._._.) . V @ + # q ] 2 / ^ ] _ ^ ^ ( ] ^ . b J J _.) ) m M <.<.<.j ,.) + v v = i $ ' x [.e e e e c C Y Y 1 _ : < < < < < < _ S | | : _ G ; =  .5.3.5.3 3.5.3 $.-.3.3.H > ].#.s ).h b b . . i S ;.) 7.:.C S : n @.c.<.i e e c ",
+"m m m J [.[.) _.) ) ) ) ) ) i.i.i.) y y (.. @ # ) ] ' ) ) . $ x $ a ) # ( b b ' [.y (.) Q _ /.<.<.f ) z x ' a x = x Q e |.Q e e e c =.X / / : : : < B B } < : _ _ 1 S [ 1.> > 3 3.3.5.5.3.3.3 5.5.5.3 * |.v u s #.X e Q D D D ^.q ' 7.V 4.S S *.3 c.t O Q e e ",
+"b b {.J _.[.J _.) ) _.) ) ) ) ) _._.i.y ) (.. + . q l n P N [.* $ @ x > } ' b {.[.) ) ) e S <.<./.d ,.$ % # x v $ v b e Q e e e e c C X Y | _ : < < [ [ [ < < : 1 | 1 [ 2 @.3. . .3.5.$.5.3.3 5.H 3 5.* _.i T T ).y b e e $ F < L J 7.= A 8.[ 8.A }.<.f Q e {.",
+"b b b b J [.[.) ) _.) i._._.i.i.i.i.y (.y (.' . z 0 { X / X C 2 C 1 / g.p {.|.) _.) ) _.b 2.<.<.<.g e ) ! = x $ % , v b e e e e e J C X / | _ _ [ } < [ < < _ S 1 _ 1 [ 2 > ; 3.3.5.5.5.3.5.3 3 $.$.3.> b $ s #.T R Q |.~ x # j.q . N *.C ^ S 8 6 j.d.0 e e e ",
+"m b b b b [.[.) _.) _.i.i.) ) _.K y y y ) y ) ' . + z . ) . ) ' v v + $ |.) [.{.) ) [.) _.[ <.<.<.I e ' # = , V @ # * @ ,.e e e e J C Y Y | _ _ : < [ } } } : _ 1 1 | [ ^ ; ; H 3.3.3.3.3.3.5.3 $.$.3.n N f %.s s Q e _.$ $ = < %.e 7.A 6.S [ 3 o q a.o e e Q ",
+"m m m ,.,.b {.[.) _.) ) ) i._._.y y y ) y (.y (.. . , $ (.x . ) ) ' ' ' [.x [.) b J y . ) } <.<.<.d Q . . . $ ; @ ; $ @ & ) e Q 7.c O | | 1 S : : < [ [ [ < _ _ S | S [ Y > > @. .3.5.$.3.3.$.$.$.$.- @.e R u }.[ ! e e ' % > }._ @ 7.; 4.4.}.:.; e./.| e Q {.",
+"_.m m m ,.m {.{.) ) ) ) ) ) ) ) y _.y (.y (.(.y ) (.' @ # ' ' @ ' ' ) ) @ Q ) . ' (.y (.b : <.<.<.o e _.' # = ; @ + v = D x e Q e J O | | 1 S : < < [ [ [ [ _ _ S 1 1 _ X > > @.3.3.3.5.3.3.5.5.$.> H N 7.>.).u T e e (.. @ n #.U 7.@ @ A S C ~.A }.d.l e e e ",
+"J [.J m J b b b [._._.) ) ) (.y ) (.) y (.(.y (.) R :.F :.F 8 o P P o E P |.[.) a x (.) Q S /.<.<.o e _.+ = = % # v $ D  .. 7.e 7.c O | Y 1 S : < < [ [ [ < _ _ S Y _ : Y W > @. .> 3.5.3.3.$.$.$.3. .H J 0 }.!.C . |.W z J R L Y Q J E A C j.*.F U /.7 _.e e ",
+"J _.J J J J b {.J J _._.) ) ) ) ) y ) ) y (.(.(.+ ` ^ ] ^ ( : 2 ^ Y Y ` 4.@ [.b (.) ) ) |.: <.<.<.d Q ' ~ * % @ # % W i D # {.e 7.c O | | 1 S _ : < [ [ } < _ _ 1 | _ : 2 > > @. .3.3. .3.3.$.$.H 3.3.@.7.1 !.[ O e e a J b Q O T 7.J ` 1.4.G x o c.t { b Q b ",
+"m m J J [.m {.,.{.b J ) ) _.) _.y ) y y y (.(.(.b v ) ) . ' # . . ' _.) ,.Q |._.J ) ) ) b _ <.<.<.d Q + ~ $ v v & ; > ; - & @ _.Q c =.| Y 1 _ < < [ < [ [ [ _ _ 1 Y _ _ Y > > 3.3.> 3.3.3.3.5.5.5.w  .(.y 2.u h e Q e 7.c y { 7.i y Q * i _.A ~ > _ ;.| e c e ",
+"m [._._.[.J J b b ,.{.J ) _.) ) y ) (.(.) y y (.. ' J x v ) + # v @ y _.Q m e 7.J ) [.J |.: <.<.<.d ,.. . . . # = & , & - ; z N J y C Y X | S : : < [ [ < < _ _ 1 Y _ _ 2 > > 3.3.> 3.3.w 3.5.$.5.5.> ' ,.! @ K f e Q K 7.1 Y k Q Q v $ 7.` ] ^ j { u z c s 0 ",
+"m m m J J _.J J {.J J J J ) (.y ) y ) ) y (.(.(.) x v + . ' x (.% * ) Q m Q e |.b [._.b Q _ <.<.<.o Q ' ' . @ = * $ @ % ; W W > @ N | 1 | 1 _ [ : < < [ [ : _ _ 1 | S _ X W > @.3.w 3. .3.3. .3 3. .o P ' j ; Q J e Q K Q ; L ; J @ J 7.N _ }.|. .0 L [ { R y ",
+"b m m [.m _.[._.[.[.J {.J ) x a ) y y (.) (.(.(.) ) ) J x v ' . (.% . ) $.J 7.e e b [.[.b < <.<.<.n ,.) ' ~ % * v % $ # - W ! > h k M [ | 1 S : : < < < [ : _ _ 1 Y _ : 2 ; > 3.D > w 3.3.3. .3 n E N e f }.| v e b e b b { [ ; Q J ' N 7.P $.. ~ C t ).).h e ",
+"m m [.J J m [.[.J ) _.|._.= = v _._.) ) y y ) ) ) | / : ( b./ = H ] u #.` _.e e e e b m Q : <.<.<.f e ) . ~ $ @ $ @ # & = = = =  .g _ _ M _ S [ : < [ [ [ < _ _ S | S : Y D > 3.5.= D > D > 3.7 g h v c ! M u Q b e e j >.j T z b J v a e N l v N { %.L ).>.e ",
+"m m m J J m [._.' {.,.' V # x (.) ) i.) ) y (.) @ 1.V ) . b z j.` R @ J b e ,.e e e e |.e : <.<.<.d e ' v # # + @ @ $ # ~ - D $.@. .1 [ [ 2.S 1 : : [ [ < : _ S S Y 1 : ^ > > i - 5.>  .D ;  .D c Y M e h =.n v e b e h O S T ; Q ' J b Q K f i c O <.%.t N r ",
+"_.J m m J _.[._.) b J @ & ' J J ) y ) y y (.y (.) j ) ) $ ' . ^ # . {.b ) e Q e Q Q e e Q _ <.<.<.d Q ' . + @ @ + % % @ $ = D 3.D > 1 r [ M [ : : < [ [ } < 2._ 1 | ( : X D W D D ; i > D * @ ,.{ y Q $ k 2.O e b e e 7.7.> Y E c z N h h @ z N c | %./.s Y ; ",
+"J m m m [._.[.[.|.' ~ $ x ) _.y ) _.) ) ) (.y (.x ] ^ ^ g.^ 2 ^ ] Y / C l K e e e Q Q Q Q : <.<.<.o ,.. . . . @ # @ # % ; > ! = * 3.: B _ 1 S 2._ : < < [ : _ S S Y 1 : X > > D w 3.i 3.I Q D @ ; R Q Q =.1 0 b e e c y b 7.].7 g I $.d ].v k N a M <.t ).$ T ",
+"b m m _.m m m b {.@ & . J J ) ) _.) _.y y ) (.) b + J . . + ) {.' ) {.J c e e e e Q b J Q _ <.<.<.o Q y ' v v @ V . . , W W ; * V  .< _ 1 | 1 S : : : < : : 2._ 1 | ( : ^ W > D D - i & = # . K T v b Q j u 7 J Q 7.7.N z J % A n h f d @ @ 8 @ $.S }.#.^.Z 8 ",
+"b m _._.m b {.[.$ # x ) J _._._.y y ) ) y ) (.) ' ) {.v ' ) x @ _.) _.Q b e b Q e m _.) Q _ <.<.<.o |.' ' . + # @ @ % ; > , N * > o : Y Y 1 1 S _ M < < < : _ S 1 Y S _ Y W > D = 5.7.$ > $.N J i j Q { S $.+ @ j z 7.K b _.k A d W $.k K $ 0 ! o r '.T u R ].",
+"m J _.m b m ) ' % (.b [.(.) ) _.) ) ) y ) (.y y ) (.v ' J x + |.J _.) ,.Q e Q e ,.J ) _.,._ <.<.<.o Q y ' v v v + * W > - $ , = o o / ^ Y Y 1 S S _ : < : : _ S 1 | 1 : 2 W W D 3.= |.> G D Q c } b &.#.I $ ' ! h h b J K v D =.0.i o f @ N >.; *.&.^.U /.L &.",
+"J m _.J {.{.' # ' J b J y _.) (.) ) ) (.y (.(.) x 3 n H :.n 3 n 8 o n $.$ Q Q e _._.J b Q _ <.<.<.I Q ' . + + v # ; W & @ $ > $.; $ 4./ | X 1 S _ _ 2.< : 2._ S 1 Y 1 : ^ W W D w v v / a.! e e j { P X $.- I ! o N 7.y b a f O j ].i i v v j @ j u '.^.).;.%.",
+"J {.,.b _.+ + ' ) _.J ) J ) ) ) ) ) ) ) ) ) _.i.v H P P G R d o o d n P s e ,.[.[.{.J [.Q _ <.<.<.o Q ) . + v # w @ , % . > P & 7._.G < _ ^ 1 1 S S _ : [ : S S | 1 1 ( 2 - w w > > J > j a e c l y K D o g ! h k i Q z $ K o =.I > i f c N j $ n s '.%.d.^.s ",
+"J b |.) x a ' ) J _.J ) _._.) ) ) _._.) ) ) ) i.b $ ' b J b J ) {.' ,.e X m ) b J J _.) Q : <.<.<.d e _.' @ $ $ @ x v = D , . Q v x  .] : < < ( _ S _ _ 2.[ 2.S 1 1 ( : ^ - W w W # m Q e c e e =.0 ].0 j ! ! @ f ; b y c a h =.n i i d N N O z =.!.}.L t }.T ",
+"b |.J ' a x J J ) [._._._.) _._._.) ) ) ) (.) ) x H P o o o d d F I n 4.'.@ |.) _.J [.[.Q _ <.<./.o ,.' ' ' # = & $ @ % i . e Q ; - W H 9 4.g.C | : } [ [ 2.S | / 2 / : ^ w - ; w - . e z ~ e $ } [ =.P f $ k i f $.e @ K Q n { o ! i $.{.k *.z 0 U &.s ).}.u ",
+"b J (.. (._.{.J _.[.[.) ) ) ) ) ) ) ) ) ) (.) ) x 3 o o n H o o 3 n j D W b ) Q [.J _.) Q : <.<.<.f e m @ + + . $ % W = , [.7.,.; H o 3  .W W H F { / _ [ [ [ [ S / _ : g.W - ; W 3 I e j ).K Q [ u 0 j @ N h h f a y y c N ! Y f ].! ; @ @ Y z 0 T &.%.t !.#.",
+"b ) ' y J {._._.[._._.) J ) ) _.J ) ) (.' ) ) ) ,.) {.|.J J m m ) b a x ) e m (.J J J ) Q _ <.<.;.0 K @ % ; W > = -  .i > ' ) , - 3 3  .H  . .o = ;  .P A { ] Y / 1 : | :.= - 3.; > |.e &.u c $ 2.f j z z ].$ ! i k e $ y e k *.I ].> k Q ! *.! j #.u #.;.%.&.",
+"y y ) b J [.) J [.[.J ) ) _.) ) _.) ) ) (.) ) _.b c b _.) _._.) J v x {.m [.|.b J J J ) Q : <.<.<.t t ;.t t t t d.d./.d.L ` . , $.H D ; 5.H o R H 3.= = > = = * H I n ..D = ! w ; I - _.m n e Q 2.{ z f $ N h ; h c y c Q @ N X $.h i i z y { $ O #.#.%.%.#.'.",
+"' (.J b J _.) J _._._._._.) ) ) _._.) y ) ) [.J b y c J J ,.) . ' , ' b J ) b [.[.m ) J |._ <.<./.<.<.<.<.<.<.<.<.<.<.<.<.| ) ! W ; W w 3.3 H -.F o 3.> ; ; % @ . {.(.# , - W - W = _.7.].k b N | >.k $ $ N ! z ].].Q @ c _.f Y n k f d $ ].j ].*.}.#.!.;.}.} ",
+") J J J ) J J ) J [.[.[.) ) _.) ) ) ) ) _.J J b y @ c J J c . . V ' _._.m b b b J J [.[.Q : <.<.<.<.<.<.<.<./.<.<.<.<.<.<.S . ; = = W D w  .o R o o 3 3.* = & $ . {.v = = = ; > ; % $ e o T b e &.{ N v $ ! z ].].v K ~ c a h 1 o i ! > z @ j N O }.#.!.L #.[ ",
+"J J J J J J J J ) _._._._._.) _.) y ) [.[.J m J J Y b c _.' 1 j i.a y b J b ) J [.b y J Q S <.;.;././.;.<.;.;./.<.;.d.<./.l ) @ = = W k 3 H -.o R +.R 3 w = , # ' ) . & = ! > ; W % ,.Q O M y z X 8 K K $ ; ; z $.z b @ J K i C l i h h N N $.z j u s !.t %.'.",
+"b J J J J _.J J J [.[.[.[._.) _.) ) ) J m m J J Q X c b _.N ^ j _.i.y _.) 7.|.J b ' m ) |.~ ; h > z ! ; a y @ $ % $ ! $ . |.. . , = W D 5.3 -...R F F o  .> , V ) ) @ & = - w ; = $ y ,.7 %.Q e r 0 N $ ].N @ z y b J a y K $.| l h h i ].z i N j &.u #.L L !.",
+"J {.J J J J _.J J _._._._.) ) ) ) ) {.b {.J [.J . &.Y ^ / / c.[ ^ ^ ^ ^ 4 @ b ,.b y |.) ) J |.J b e {.~ ! f k K b e e e Q ' @ + , - ! D i 3 H o R P F F R 3 ; @ ) ) @ = = - > > D . 7.7.U M c z | 0 h @ N $.N b e e J N e v N O *.! ].i ! N ! $ n &.#.%./.%.u ",
+"J b J J J J _._.J J ) ) ) _.) ) [.[.{.m b ,.{.{.Q 8 o G G R j R P P P R I ) b m [.b J b _.~ x J ' =.%./.<.<.<./.s l . _.@ @ {.! z ; W 3.5.3 H o R P P F F ..i = ' _.. & = - > > & 8 E 7.| %.7.N }.8 J e b $ % $ Q e $ K c c N 0 { ! z h z a N N l r T !.;.%.u ",
+"J J J J J J J [.J _.J ) ) ) ) _.m m m {.b ,.,.,._.% V V x J _.' K a y m (.|.m [.m |.y m ) ' . H ^.;.<.<.<.<.<.<.<.<.}.o b = W $ , - D D 5.3 o o ....0.+.6 F o 3.@ ' ' # = > > = D @ 7._.C @ J j r ! ,.e Q z N J e e K N e @ K 0 { ].].i ! y @ N 8 } u %.;.).T ",
+"J {.J J J J J J J _._.) ) J _.[.b b b ,.b ,.,.J v # $ v i.) (.a _.a y b m b b e [.{.J _., _.H L <.<.<.<.<././.<./.;.<.L j ,.$ W - - W D i  .o o P P ..R F F 0.H ; # x $ = w > = = @.d 7.v N e $ #.z e e e v $ a e e z K b b ' j { ].].k i a a N l } u !.t %.T ",
+"J J J J J J J _.J [.) J J J b b Q b J J ,.{.) (.$ v J J (.' y _.y ' y b ) b ) m m y J x @ y _ <.d.<.<./.).U %.;.<./.<.<.'.$ @ ; - ; W D i 3 H ......P P 0.F 0.R E ; * & * ; ! = & * 7.' > b 7.8 S a b e Q N y e e Q v z e K y *.X h ].$.i @ @ N n M u !.;.).T ",
+"J {.{.J J J J J J [.) ) ) J b b ,.b b ,.,.J ' $ @ v _._.x ) ) a ' (._.b [.Q {.J |.y @ , y 5././.<./._ z {.e b > q <.<.<.;.d . $ ; W W D i 5.H o ..P +.0.0.F 0.R n @.; = & = > = = ,.,.Q ].f y v }.v e e v K e y e e c K e J _.o M I ].i i $ $ z *.r T L ;.L T ",
+"J {.J J J J J J [.J ) _.{.b ,.,.7.J J Q J V = $ i._._.K _.i.y ' y ' ' ) J J b b ' @ $ a e X <.<.<.e.J e Q |.[.Q Q C <.<.<.{ {.~ - ; W D i H o o ....R 0.0.0.0.R o o d 3 3.; ; ; = = 7.@.T K 7.o =.@ e b K K Q y N b K d @ e y d Y d z ! i z a K C u X X #.u &.",
+"J m {.J J J J J [.J [.[.b b |.b J ,.Q [.@ $ @ i._.i._.i.K _.(.) (.' ) _.b b J _.@ V v y e Y <.<.<.O e e [.x . ' |.o d.<./.C {.@ , ].W D 5.3 H H o ..0.P 8 P n o E R n n 3 > - = *  .' @ o 8 7.! }.7.Q @ v v z h D K $ l h J c i 1 n ].! i z N N { u u Z &.M 1 ",
+"{.J J J J J J J [.J m ,.b ,.b |.[.|.J @ = $ i.J i.K i.i.' _.' (.) ) y J ,.b _.' , x ) ,.Q 1 <./.<.I e [.x # . . _.~ %.<./.S |.. $ W D D 5. . .R ....P F 8 n n R H o F j 8 H > * W E _.@ / - Q R >.K Q ; ].].N $ k y y j D b b z | *.! ! ! N @ $ 1 2.} s %.^.}.",
+"b J J J J J J [.b b b ,.,.,.|.|.|._.V * V ' _.i._.J i._.' J y x y ' (.J b _.@ , V ) Q e e S <./.<.k Q ' x a ' . @ K }.<.<.M b ' $ W W D  .5.3 R ....R 8 8 8 8 R o d R j 9 F 3 ; N ,.= b { O 7.].u b y y $ $ N ; h y y *.g . Q $ { l z ].h N $ N 0 2.} T }.%.!.",
+"J b J _.J _.J m b b b Q ,.|.|.Q J @ N V (.J ) i._._.a ' ' ' m y x a i.J _.v V x J Q Q e e 1 <././.d |.' ' ' v @ ~ ~ #.<.<.} |.a $ = W W 3 H 3 o o R P P 8 P n o n o H 8 9 *.P H V ; ' # P J J $.X ; c ; v $ ].! j N y j d K Q @ =.{ h ! h z $ z 1 u T %.!.r } ",
+"J J J _.J {.J m Q b b |.Q ,.{.J # , @ ) b _.i.J J @ b b _.a ) (.(.) i.i.~ , V ) Q e e e e 1 <.<./.n Q [.. . # + . N s <.<.[ b K ~ z i i  .H o o o R 8 F 8 P 8 o H o R n :.9 G G E * ; ,.n i e R T b K v ; z ! ; h y Q 8 l ].b ' { O ! ].h ].z i 2.#.T u r T u ",
+"b b J J J m b Q b b b Q ,.|.) v = @ ) J ) ) ) _.y *.a ' ' a y a _.i.a * = V [.Q e e e e e | <./.<.g |.[.+ . v . . ~ T <./.} Q a $ ; i i ; i ..o ....P 8 8 n R P H o n F j :.~.9 ] H [.' ) J e j O ! y $ ; i z $ i K {.P *.D {.y 0 C z $ ; N @ z Y T T u u T | ",
+"b b J J J b b Q Q b b Q |.J v , , (.{.i.) J J v ) Z H R n o o ..-.R 7 4 H . 7.e 7.e e e e 1 <./.<.k Q _.+ v ' @ ~ @ s <./.e.Q a $ - ! $ ) , H o o ..P 8 8 8 R R H o 8 j ~.9 :.j 9 @ = 7.> y e *.[ e b N v $ ! z $ c c l { $.J c l O N z ! z @ z Y #.#.u #.!.0 ",
+"J J J b ,.m b Q Q m m 7.{.$ = V J _._._.) _.) ) (.[ R ....0.H +.R G 5 9 o |.e e e e e Q e 1 <.<.<.d Q (.x . + + + . j.<.<.[ Q K N W ~ {.m ) , o P n 8 F F P R R o o n j :.G 9 9 ] D _.. . J 7.0 =.y J v $ @ z ! ; Q y =.Y n ) Q n C f ! ! z K ; | s !.T }.2.$ ",
+"b [.[.,.e Q Q Q J Q Q b a , $ K _._._.) ) i.) _._.4.' m a a b y * 3.* b ,.Q Q e e Q 7.7.7.} <./.<.d e ) . v + @ @ v s <.<.} b a N N c Q b _.x = o R R o ..F 8 o o H o P :.9 :.G E (. .c N c b { M J 7.$ v $ i ! $.a J O j 0 N c n | n ! ! z @ z O }.s } T *.c ",
+"b b ,.Q Q e b ,.Q |._.V , $ K J _.J J _.) ) ) ) ) a b @ J J , ~ ! > x ,.e b e e 7.e 7.[.) [ <.<.<.d Q ) ' + v + ~ + s <.<.} b K y c Q e J ) (.. W o F P o 0.+.o H o R j :.9 9 G ` H _.' ) J e { Y ; c J $ @ $ h f b % n C 0 $.{.i O h N N $ @ N [ #.}.!.u i h ",
+") b Q Q m Q Q {.7._.& > , i._._._.) ) _.) y ) y ) J y y i.i., 3.! a |.,.e e e e 7.|.y $ ) _ ;.<.<.d Q (.' + + + @ @ #.<.<.} b y Q e e ,.m ) ' . x W R 6 0.o R R o o R j :.9 ~.:. .Q = Q C N b >.2.J e v v v j [ Y h b *.k C $ |.i 0 z @ N K @ z 0 #.}.#.r e u ",
+") _.J |.7.|.|.Q b $ w , i.J J _._._.J ) ) ) ) ) ) x v Q (.- w w v J |.,.e b Q e e ' , x Q S <.<.<.d Q ) x v v @ v @ s <.<.[ e Q e e b b J c ' x (.@ W R F 0.o 0.H o o 8 :.~.9 9 p > ) ! b.q 7.o { J e v k O S 1 %.y J b {.> o e ! 0 ! $ z v $ ! *.'.Z #.k y r ",
+",.x . b e Q b Q , - , i.b J ) J _.) _.) _.) ) ) ) J J ' - ! > _._.,.J e b e Q ,.' . x J 7.: <./.<.f 7.) ' v v @ . @ #.<.<.M e e e e Q Q J ) ' x # ' x W 0.F ....H o n P G 9 :.G d @ v @ L 0 e k | >.C X | X 1 u S h e J Q 0 @ b z =.o N z z ; ! 0 }./.%.u u <.",
+"b y V ' b Q b i.- $ i.b J ) ) J _._.) _.) ) ) ) _.( 2 | h.w O [ 2 ] Y ` 1 Q e Q $ (.,.b b _ <.<.<.d Q ) x v + + @ + #.<.<.[ e e e e e Q J ) . + $ v a $ w ..F R o o n F :.G 9 ~.*.@ ) E ^.r e r L Z &.Z } %.t }.M v K Q b l n {.i Y *.! i h h ].0 &.;.| >.}.T ",
+"J b ' & @ |.J = , i.J _.i.J J (._._.) ) ) ) ) y _.h.* w w a g.H ,.|.J _.X e m # ) ) J b Q : <./.<.d Q ) ' + v + @ ~ #.<.<.[ e e e b b b c ) . $ . & = a $ i R R o o n P :.9 G G p ; . $ } j 7.Z %.M M Z T Z { h g a e Q K 0 @ ) ! { n z $.k z $ O L u v $.).[ ",
+"J b b b a 3.D V J J J J J _.) _.) _.J J [._.y _.J } k w ' Q / I b (.|.|.^ v = [.J J [._.Q _ <.<.<.o Q ) (.. + @ $ . j.<.<.M e e e e Q ,.[.' + # , , , , @ x - 0.d E o j :.:.:.:.F . ; @ >.k b '.).1 Z } f >.X e e b . e . n h K N C *.z ! ; $ h 2.).u Q T ^.h ",
+"_.i.J y ' V > (.b b J ) i._.J _.) _.{.) (._._.i.> [ b.j.j.c.r y y p 2 p < # ) J J [._.) Q : <.<./.H Q ) ' . + ~ . ' s <.<.: e e e e Q ,._.' V # $ & & = , . + ; I P n o 9 *.:.*.9 d y N >.! b >.Z 2.Z 0 i [ %.! Q b J e c i $ b $ O *.h $.h $ ].M ;.{ n t S e ",
+"J @ , , b Q V , ) {.b _.) ) J J (.{.[.' y J y ~ > ! * J ) J b b b |.b . ; J |.b [.m [._.Q _ <.<.<.d Q ' ' . @ ~ _.,.T /.<.M e e e Q Q ,._.x @ & & * = = = + (.) z d P 8 :.9 :.9 G n . ! 8 f y >.Z 2.O ; N 2.}.].e e J Q {.@ z z ; 0 j z ; ; $ ! } Z Q ; %.8 h ",
+"y ' W @ J _.,.V v ) ,.b _.) ) J J _.) ) J _.~ w ! a b 7._._.b ) ' |.. ; ) ) J _.J J [.[.Q : <.<.<.H e ) ' + . . Q Q './.<.M e e e e Q ,.) . # N = = * * = $ x ) [.$ o *.:.F 9 ~.:.; y $.r N v { ; h N 7.v S r @ J e y h o 8 n f N >.8 ! ! ].z i | l e l j {.{ ",
+"_.' * y y a 7._.V v (.{.b ) (._._.) _.J y $ ! w ' Q [.) ,.Q y Q 7.@ , ' Q J Q b [.{.[.) Q _ <.<.<.d e ) . . ) m e e '.<.<.[ e e e e Q m ) @ # & * = - = * % # x ,.J W j ~.:.~.:.P @.* ; !.}.j $.C j R $ N j R N z b y 8 0 l j k @ j R z z N h R X N K 1 ! c 0 ",
+"$ D a y ' J J J ) ' v x _.b _._._._.J i.* 3.- x Q [.Q b b _.J _.% # x |.) b [.) _.J [.[.Q : <.<.<.H Q ' + ' |.e e Q T <.<.M e e e e Q J ) @ $ * N * = - * $ + ' _.m (.D :.9 :.*.G D 7.R %.C $.| f b z ! ; N N g f J y R j 8 8 $.K l l h ! N ! o { N M &.K i s ",
+"$.; b J (.i.(.b J _.x V x J b ) _.J i., D - v b J q | =.=.X O / _ ] / ` 2 {.J [.J {.[.[.Q _ <.<.<.f Q ' c m e e e e T <.<.M e e e Q |.J ) @ # & = $ = ; = $ @ (.) J {.v  .F 9 9 H > N _.}.2.N k k y ! ! z i k n f e c R >.j o ; ! O 0 i h h i j i e f =.k u }.",
+"= J |.J J y ) ) _.,.b V v _.b _._._.$ k w ' |.b Q C Q J {.,.V D + ' ) ) ^ b b ) J {._.[.Q : <.<.<.d Q m Q e e Q e e '.<.<.2.e e e Q ,._.) @ # & ; & * ; = & $ . {.J ' ' ' 5.*.:.p n J N S Z b C $ b ; i N N ; ! d c ! { { 0 j o K >.>.h k h ! f y b ].y j T [ ",
+"J ,.,.J _.J J _.J b v = $ J b (.|.' w D ' Q b m J &.g k j % ; v ) ) . ; Z ,.[.{.[.J J [.Q _ <./.<.I Q e e e e e e e T <./.r e e e Q ,.J ' @ % * = = = = = % @ + ) m ) $ $ v D *.*.= z b | %.f k =.y z ! ! z ! f z 7.$ l h >.f ! ! l j h ! ! z h K > ; i T T X ",
+"|.J b J (.(.J _.b x , @ ) i.) b ' 3.D (.b b b b J g 0 =.2 ^ ^ C ^ ^ { C 8 ,.|.J [.{.J [.Q : <.<.<.g Q e e e e e e Q T <./.M e e e e ,.J ) @ # * * = = = = & @ + ) _.y # $ V * i P D J 7.; [ { 1 f b a v z z $ ; h e $ R 1 Z { k $ l 8 ! ; ! i ! v O j | s T Y ",
+"J Q ) . i.) ) ,.= $ v i.b b ' a D D a |.|.J b b b b J . ' @ ' b |.' x J Q J b {.J J [.[.Q _ <.<./.o e e e e Q e e Q './.<.M e e e Q ,.J ' . $ * = = = - = % @ . _._.x @ = & $ V 8 G = ; 0 i ; C { b v ! ].N i $.@ y h { j %.C ; N >.o ; ; ! h K e K j | T } C ",
+"J b (.@ _.Q b (.3.V J J J J V 3.W (.Q b |.{.[.,.b J ) N (.,.J $ ' ) ) J ) [.|.) J J [.[.Q : <.<./.$.e Q e e 7.e e e T <.<.M Q e e e ,.J ' . # * * = = = = N @ . _._.' @ - ; , @ ) D c >.!.k b 2.h a $ a ].! ; ; k e >.>.{ O l h N 8 k $ N h i a Q N =.[ T [ } ",
+",.$ v b {.,._.5.(._.J _.@ , - ! y _.y b 7.,._.,.J J ~ ) 7.$ (.{.' ' Q ' 7._.) Q [.J [.) Q _ <.<.<.$.e b e e e e |.e }.<.<.M e e e Q ,.J ) @ % * = = = = = , ~ v ) ) x $ = - = = @. .k 8 L R b f 8 _.N k N @ ! i v 7.z O | %.j ; v k f ; $ ; h i ! o | T &.u M ",
+"# V ' ,.,.@ ; - Q J _.y , , a y _.@ ' b |.b ,.J ,.z _.{.) _._.. ) + (.b (.7.(.{.{.{.[.[.e _ <.<./.I e Q e e e e e e ^.<.<.1 e e e e ,._.' @ # * * * = = z , @ . _._.. & = = = D P # 7.| /.Z 7.o ! z ! ; z N $ z N b j ! 2.%.2.z v k $.N @ z ; k i ; X [ r u S ",
+"= J {.) ) ; D ,._.J J ' a y m y a a _.J ) b Q J % d.a.}.#.'.}.T '.c.U '.b.x Q ) b b [.[.e S <.<./.0 e e e e e e e z )./.<.X e Q e Q ,.J ) . % & = = = = = % ~ v ) ) ' % = ; i o j > J ; L ).; i f K v ; v y ; k h Q h >.>.Y $.; K f i $ $ z ].; @ n C Y u 2.M ",
+"{.J ,.(.> = ) J {._.J b J _.y , y y _.(.b b _.J {.G 1 c.u { ].y + ' _.) _.Q {.[.{.b [.[.e S <./.<.M b ,.J e e e Q >.<.<.<.0 e e e e ,.J ' . # * = = = = = % @ . _.) ' @ - 5.8 4 G - ,.7.M %.R l f z z h ! z h f ; y ! ! Z ).M $.b R f v @ $ ! z k 0 C } u &.S ",
+"J b $ > v ,.b [.J ) J b y $ ~ y _._._.) ' [.,.J b K J _.> { e.u 1 P ) J + 7.J _.|._.) |.b  .<.<.<.;.0 J J e e e C <.<.<.<.$.e e e Q ,.[.) @ % N * * * ; = # . . _.[.[.% H *.*.G A = 7.N 1 O $ }.0 c h $.! z h $ Q K v Q { u t Z @ $.h $ @ h h k k ! 0 &.u 2.2.",
+",._.V x J b _.) J J b b ' @ ' _.|.i.' y ) b ,.) c b c K _.J ) (.k ` } r ` @ m Q (.|.J ' ,.+ }.<.;.<.;.}.[ / [ #.<./.;.<.%.v e e e e ,._.(.+ $ * * = * * * N # . y ,..  .j G 9 G P @ K 2.t 2.; &.y c j ; b y N 7.Q e N c r Y o j c f ! @ $ ! i ! ].$.} %.%.&.Z ",
+"a - V |.|.y ) b J y b _.$ y Q y J ' a ' ) {.J ) _._.. m {.. y c $ 7 [ '.` ,.7.x ,._.J b b e 7 <.<.;.<.<.<.<./.<././.<.t 0 e Q e e Q |.J ) . % * % * = * * * @ . _.{.= G 9 :.G G ` $.b =.t Z @ #.j J K Q Q y $ Q e c b h #.L T z y h ].J N o z $ $ k X %.^.Z s ",
+"@ - , m |._.(.J J |.' = a J J b ' V a ) (.' ) ) . ) J _.a $.2 #.: 0 @ e _._.+ m |.(.) {.+ J ,.{ <./.<./.;.<.<.<.<.<.a.{ e e J e e e |._.' v $ & * * = = * * @ ' J @  .G j :.9 9 d y 2.^.s j R %.! 7.K K c 7.J e e Q z Q 0 [ %.=.J f ~ K N $ i ! i 0 u }.%.S #.",
+"m ) @ $ y |.b _.|.a $ a ' b b x @ + y J y . x (.) ; A u c.=.f c _.' {.Q b e c ) x Q ) b |.. e b n [ ^.t <./.d.a.#._ k Q e Q e Q e Q ,.m ) @ $ * & = * ; = @ @ . # D n j j G 9 G A > f }.L U y [ k c K b b y @ c Q e 7.O t [ f N v i ! a N N v i o 1 } !.#.Z '.",
+"Q e ) = , _.b b @ - a Q J ) a W y ) J b ) (.(.x (.d.d./ 1 2 O X X =.C Y 7 ) Q J x b ' J Q ' ' c 7.y ) _.% - , . J {.e e Q b e Q e Q ,.[.' @ $ * = = = ; * N * = E g n F 9 *.G G P Q R [ !.0 j O b 7.@ y Q e Q Q e e $ $ T %.u h N f ' $ h K ].; ; O &.#.%.| #.",
+"J Q Q ' , $ ' y w _.' i.e $ H @ b J J J _.J _.' ' V J (.' _.. ' c K J e e e Q Q [.x (.[.) b c J J Q b J e Q Q e m ) _.m b e Q Q Q e |.J ) @ $ & & ; * ; * = > E P o o j 9 G G G # J 0 !.U #.y &.z @ $ b e Q J e e J c j | O | Q @ ! $ . N K z i e C u %.}.[ }.",
+"Q J Q Q x $ $ - y _.b b $ D @ Q [._.) ) (.J b y a a x (.' ' ) _.c K c Q Q e e e b ) ' ) {., [ s *.) _.' |.) ) ' ' |. .u '.% e e Q Q |.[.) @ $ & $ = ; * * > o j H E n F 8 :.A j 9 J ; T }.8 h 0 $ Q ,.b J Q b J Q e k [ %.n J 7.! d @ ) a {.z N i O =.| M =.}.",
+"{.Q ,.,.Q x w $ b _.b y = v b y ) J {.) ) J J J i.$ $ x (.. ' _.' y c J e e e e e |.x . J ( /.<.d.k Q a y ' . ' ' + './.;._ e e e Q |.{.. x @ = = = & $ > o P o o o o 8 G 9 G G { $ j 0 8 n # t z Q ; $.y J a a K e k &.[ $ J _.! N K ; a K k ! o [ 1 X 0 j X ",
+"b |.,.|.e [.$ _.m b y $ @ (.) b ) J ) J b _.' i.J i.V V (.' ' ' ) y J Q e e e Q e Q _.) J _ <.<.;.f Q . ) ' . . . ~ j.<.<.[ e b e Q b ) ' V % = = & ; ; E 8 n o E o n 8 G 9 9 G o ' 0 %.L X =.j @ e $ ! m J $ ! ) b h s 0 @ e c ].$ y N @ z h b o X { | u Z | ",
+"{.b ,.Q Q Q b Q y , , ' y _.b _._.J J ) ' $ = = i.J y v @ v a ) . ' c Q e e e e e e Q |.m : <.<.<.d ,.' ' . v v @ + j.<.<.} m y b 7.Q _.) @ = & $ = 3.o 8 8 n o o o g P :.~.G G ] N z T ).=.Q }.a e $ ].y y $ ].y 7.l '.| K Q Q h ].' c Q @ ; b k Y C 2.r r 2.",
+"{.{.b b b |.|.|.' 3.- _._.J b y _.) b y , @ i., $ _.J _.' @ v J ) ) _.e e e e e e e e e Q 2.<.<.<.d 7.) ' v + @ @ @ j.<.<.B m ' @ {.Q _.' v $ & = 3.o 8 F n o o o o n P G 9 G G  .$ | u u z =.Y N b K v J J y $ K e R } f Q e K N z % @ J @ N e j 2.| 2.1 Y =.",
+",.,.b b J b |.b |.(., * y _.K J _._.' V $ ) b J = $ ' _._.$ , a ' x ) |.e Q Q e e e e e e S <.<.<.d 7.) ' a + @ v @ c.<.<.} b ' ; % ) {.(.v $ = 3.o :.F n P 8 n H H n j :.9 9 G { @ E !.;.| J }.J e a z K c Q b e Q 1 }.8 e e ) k N K c Q $ $ y O [ | 1 M | >.",
+"m ,.m b b {.|.{.Q Q ' = , _.J _.J _.= = ) _.a b v V x J J K $ $ a ' ) |.e e e Q e e Q e e 1 <.<./.d 7.) x v x @ @ @ j.<./.} ,.K N > * _._.x $ > R 8 F R o 8 R d o o o P G 9 G G E _.{ X =.; =.` c b $ z y b Q c b K Y q K e e ].h a y c J N @ K C r Y X X =.*.",
+"b |.m ,.|.m |.b Q m m ' - @ b i._.K $ ' |.J (.b J ' v @ K _.i.- & % V ' ,.e e e e e Q e e 1 <.<.<.d 7._.' . . @ @ @ }.<.<.} ,.. + W D # i.v ; 3...P R R 8 8 P o E o n j :.G 9 G D y 0 s %.1 a #.b Q N z c Q e b e b [ C $ e J K $ c y J b ; $ K >.1 { >.O O 0 ",
+"m |._.{.|.c J b b |.) a V ! - J ~ * ' b i.) J x ) ; o 0.3.i.v +.>.*.:.n - J e e e e Q e e 2.<./.<.o Q ) ' x . @ + + j.<./.} ,.. , z i  .= ,  .R -.o R P F R R R H o o P :.9 G G E b ; &.#.0 l k c Q $ N c b J K Q z [ | e Q Q ~ $ c ) b J i N y =.[ C 0 0 0 0 ",
+",.,.b ,.b b b b c J J J y K * -.v ' J J _.x x [.[.e.d o 3 _.| g.5 :.F F c.~ c e e e e e e | <.<.<.i y . J @ x a v @ j.<.<.} Q . # W W D o R H o o R ..R R n R o o E n G G G 9 j ' _.7 1 &.>.h }.e K N J Q e e Q Q K T h Q e _.$ @ a v c b N $ k 1 | O =.| Y C ",
+",.,.,.b J J b b c Q [.) J @ > , J b J v a J J x . X + _.) J | 9.$ _.7.J ] x . b e e e e e 1 <.<.<.n e N % J v @ ' . #.<.;.[ m ' ~ ; ; > H o H o o R R R 8 n n o f g n n 8 A G @.@ 7.j !.L X ; f a . $ J Q e Q y Q { &.! e b b . ) ' a J b ; ; f | Y 0 O C O O ",
+"b b {.m b b J J b ) J Q y * ~ i._._.' $ @ ) J ) # '.` ] ^ ^ j.$.b 3 H :.q ; e {.Q Q e e e | <.<./.f e ) - , . . ~ . c.<.<.} |.' ~ ; ; W 5.H 3 ..o o R P R R o o H o n j 9 9 H # $.y ! C r f $.&.J K ! ' Q m a ) e D | _.e e ) $ K y y b b k $ $ C X 0 O | C 0 ",
+",.,.,.,.m b b m J @ ) J = , _.b ,.v $ x _.y i.J J  .j n 3 0.H _.y i 8 ~.8 (.(.[.|.Q e e e 1 <.<./.$.e e ' D ~ . ~ $ T <.<.} Q . ~ ; W ; i 3 E R o o o n n n n o g E o A G  .N @ ,.y =.L s ! n r k J J b Q e y $ b M j Q e Q a v c c y Q y 8 ; @ >.O 0 X 1 C { ",
+"b b ,.{.b m J b J ,.. = V y J b ) & w $ J b _.y J J = $ ) _.J ) b v $ x J V W J _.[.Q e e 1 <.<.<.o e Q e (.- , . ~ j././.} {.. $ - W D i 3 H o R R R R n R n n o d o j H # (.@ f Q N &.!.! $.[ @ J c Q Q J c e h '.> ,.Q Q $ y b c c e e k @ v 0 C Y Z S 0 O ",
+",.b ,.b b b J J b J ' $ ' Q J $ W % $ > = i.J _.b ' b $ , [.v Q (.& J 7.b i.K , a (.,.e e 1 <.<.<.D e Q e Q ) z z K T <./.[ {.) $ - D D i 3 H H o R R R 8 R o o E n E = V x . @ J K =.T X c { U e.n y e Q Q 7.b 0 0 K e Q e % y b c c Q v j N z l 0 | }.u j j ",
+",.b ,.b b J b b {.) {.b ) _.y W $ J ,.' - - K _.K J b ) $ V b ' @ J y a b Q J V , @ J 7.e 1 <.<.<.o e e Q |.e (.].].U <.<.} |.' $ - W D  .3 H o o o R P n n n R f E = ' (.v V v Q b >.}.}.N $.u &.&./ - m e c N M S Q Q Q J ' Q b b Q e ! 0 $ $ *.O | !.u h y ",
+",.b b {.b m J b J Q ,.[.[.& w @ Q b |.,.' w - i.b +.^ h.h.*.& ) (.' J ,.J _.b J - $ _.7.e 1 <.<.<.M m e Q e Q e ' 0 <./.;.r |.. , - W > i 3 H o o o o R R R o n 8 ; J _.V V ' x . _.{ 2.R e >.'.&.&.C N J e e K #.i e e e b _.b b J b e ; j K $ l X 1 s [ $ Q ",
+"|.b ,.,.b b b J [._.{.Q x - # |.J m ,.Q b a * > b ! R R ..W ; y ) J (._.Q v Q b _.- = b Q Y <./.<.<.1 ) e e e _.S <.<.;.<.2 Q . $ = D 3.i  .H H R n P 8 n R n n ; J _.' @ x (.W % b l X v e $ o 1 s S h Q Q Q 0 }.j J e Q ) c e b J e e $ o y h =.C =.u &.c e ",
+",.b ,.{.m m b b |.,.{.|.b ) m Q |.b ,.b ,._.v * = ,._.i.i._.(.' _.J y _.J 7.K J ,.v = D |.i t <.;.<.<.%.7 e D T <.;.<.<.t l e ' ~ , W D D  .H o H R o R 8 j H D _.7.) . x v & 8 * ,.b ) 7.K v Q Q K N e ,.,.y 1 O a Q Q e c m Q Q a J e h R e ; R 0 Y } u $.e ",
+"b b {.,.b b m m ,.J [.J b |.|.|.|.|.b m b |.J x - * v J J ) x (.(.. {.Q _.Q _.J _.b ' $ + _.d #.<./.;.<.<.f.t <.;.<./.t C m ) ~ , - W D 5. .H o R o R n j o ; ) [.,._._.v D :./ ' ) _.J y N ) m b c e b y e $.r l ,.Q J b K b Q b b b Q $ h e z j O 1 u u | { ",
+"b ,.,.b b ,.,.b [.J _._.J b b [.,.|.|.,.b ,.|.,.& , $ @ ' _.b (.J . ' v ,._.Q _._.,.J J > = 7.' 0 L <././.<.<./.<.;.[ N e a ' ' $ z ; W 3. .3 o +.o R 8 o = ) ,.{.Q {.) w A C C D N b y f j @ ,.J e ) ,.e ) j }.8 J e Q ,._.e e c e e J ].z J n >.8 R 0 f l [ ",
+"b b b b b m J {.,.m b b m m m b b ,.,.,.b m ,.|.|.H : b.Z Z h.^ j.c.[ p i.b _.b b J J Q m > > e b } /.<.<.<.<.<./.#.; e e c > , = ; W D 3. .H o o o n 8 3.. J ) {.7.J > G ^ ] A ] p . k Y [ Y k m c Q c 1 { } 0 @ Q e b J e e Q Q b e b o z e R d y . ! $ b e ",
+"b {.,.m b b b J ,.J _.,.,.m m ,.|.J _.b |.J J m ) _ 8 > * ' (.y _.b v g.q ) Q b {.) (.' [.m ; *.^./.<.<.<.<././.<.<.%.>.Q e z $.- ; W D 3.3 H o o 8 n @.# (.) ' J Q % :.g.=.4.A j p ' n Y C S g b ! Q % =.u | 0 Q Q e c y e e J Q Q e J d N b z J e e c O r j ",
+"{.b b b ,.m J b {.[.c _.m {._.J |.b m J b J J J m | y V 3 x y ' x $ b J ^ b ) ,._.b |.b ) ) 7 <.<.<.<.<.<.;.<.<././.<./.M 7.7.$ W W W W i 3 H o o R 5.$ x (.) J 7.) H =.g.4 *.9 0 n + n Y X P ,.k n z ! r Y S ~ Q Q Q b m e e e b e Q z k @ z v Q e b v @ y z ",
+",.b b m ,.b m m J b ,.m m J J _._.,.,.J J c J J _.] ^ ^ ^ [ C ^ C C ^ ` 2 J b _.[.b {.+ e H d./.<.<.t U { @ n T <././.<.<.o 7.Q D > D D i 3 H o o > v ) ' x (.{.(.D A 1.9 *.1.5 ; ' @ N O s j [.y K b *.S M X Q Q e J Q e e e Q e e b h f b y _.e y =.{ ].e Q ",
+"b ,.,.b m b b b m m m m m J J J J J J J _.J m b # @ y _._.@ 3.- a _.y b _.7.) |._.J [.[.Q _ <.<.<.;.n e b Q e e o }.<./.<.S Q e e .  . .>  .H H # v (.v v ) _.# o 4.9 8 9 j 9 { n ' @ ] 1 H $ > a ) P O j } f c Q Q |.b Q e e Q e Q e v N ) N e $ k { D e e e ",
+",.,.,.,.m b m m m m m _.[.J J _.c J c c _.b ) @ + ) J K i._., k ~ v _._.|.{.b ,.[.m [.[.Q : <.<./.O {.,.Q e b e e $.%.<.<.r c m e 7.z H E H H D . . x v x ) , H A P j j j O X O Y _ 8 r T D ~ $ @ ; 1 =.[ C a e Q Q |.Q Q e e e Q e e z y ~ z e Q b 1 | y e e ",
+"{.b b m b m b ,.m m m m m J [.J _.J _.c m J . , ' _.b J y _.y ~ > ! i.J b [.,.J [.J ) ) Q _ <.<.<. .e $ * {.7.e Q b #.<.<.r ) $ [.7._.D I E > @ ' . x ' ) , o A A n 8 P 7 A p O ( 1 : q p ' $ , - j l g 2.*.J |.e ,.|.|.Q Q Q Q ,.e ,.@ c y *.Q e > O } j e e ",
+"b b ,.b m m m m m m m J m J J J m c _.m _.+ ~ v {.y v x ' y J _.* 3.V Q @.Q |.[.[.{.[.) Q : <.<.<.$.e @  .; J x ~ ) #.<.<.} 7.$ ; ' 7._.; > @ (.. @ x ) @ o A *.F o n j A l P 0 S ` : l @ ~ % i n S j =./ ].b Q Q Q Q |.Q e e Q e e z h e ! j N b ! 0 2.{ . e ",
+",.,.,.b ,.b m b m m m m J [.J J [.) _.,.(.@ + [.. {.m _.) y ' (._.= w @ '.|.J |.J J [.[.Q _ <.<.<. .Q [.+ o  .= + @ j.<.<.} e . > = _.7.' % @ ' v (.' # 3.*.5 8 d 3 n 7 n P 1.0 Y Y | P . N D ' p 0 *.r X Q b e Q Q Q Q Q Q Q e Q m @ K J @ p J e e n r l Q e ",
+",.b ,.m m m m m m m m J m [._.J _.{.{.) ' ' ) ) m x ' ) ) x @ (.J x & N ^.e b ) J J [.[.Q : <.<.<.H Q b a H 3 = + @ j.<./.[ ) ' N ; ; + |._.# ' (.' = o 9 p F o H H o 7 n = P Y O C Y ` j =.e.X 0 I 0 2.i b ,.b b |.Q Q Q Q Q Q Q e Q b Q g k K h 0 0 2.X ' e ",
+"b b b ,.,.,.b m m m m m J J m J ) J [.) ) {.J ) ) { ^ 2 2 h.( ^ ( ^ / ^ %.* ) Q J J _.) Q _ <.<./.n 7.J , - V @ (.x s <.<.} ) ) @ ;  .@.V ) v (.x = o A A F o n H n H G G # @ O ` Y S 1 } } / _ 0 =.[ Y J ) e ,.b Q e e Q Q Q e e Q J Q ,.e _.e e I 7 l | j e ",
+",.b ,.m m m b m m m m J m _._.J ) _.J J J J ) ) ) F o o G H ..:.A F  .3 :.* a (.J J J [.Q 2.<.<./.o e # = x x v # & }.<.<.} [.~ @ z ; I  .$ ' v $ R 5 { G o H n o H n j G @.# @.Y 4./ S 7 o { Y 0 O S h K Q J e b |.Q e e Q Q e Q ,.a N a c e Q e Q @ N c Q b ",
+",.,.m ,.,.b b m m m m m m m m J J J c _._.) _.[._.. ) ) (.) a |.J ,.|.,.Q . - ' |.J ) J Q : <.<.<.H b @ v ' (.@ W D U <.<.} b , > ; ; = o R % ' R *.5 j R n 8 o H o F 9 { n . $ 0 { 7 j j ` 0 P 0 | 0 @ b b ,.,.Q Q Q Q |.Q Q Q e c . ].~ e Q Q e e $ i y c ].",
+",.,.b m {.m b ,.b b b m m m [.J _.J _._.J c _.) b ) ' ) ) ) _.(.[.) b Q e 7.+ ; a J J ) e _ <.<.<.o J (.(.a V $ & ; }.<.<.[ Q @ > > D >  .R H H F :.:.8 P o R R H n j G 2 Y P D j l j *.{ { j n 0 1 O N b ,.Q ,.b ,.|.Q Q Q Q e Q Q ) h ! J Q b e Q y z . _.$ ",
+"m ,.b ,.,.m b m m b b m m _.m [.J J J J c _.) [.' ) (.x _.(.y v ' . ,.Q ,.e e ) - ' _.[.e : <./.<.n |.[.) V = & x # j.<.<.B b ~ ; -  .D ; 3 o :.7 8 n P R R o n o 3 P 9 A G G C j 0 0 O O 7 f P 0 Y 7 $ ,.Q b J Q Q Q Q Q Q e Q Q e v f $.v Q e Q e e y ! ! a ",
+",.,.m m b m m b m m m m m m J J _.J _._._._._.) ,.b @ :.F D y ) + [.' o 7 ) e |.v * v |.7.: <.<.<.d 7.[.+ = = # . @ #.<.<.} Q . > ;  .E 3. .H F ~.P o R R R o o H P 9 d E 7 { 0 p 1.O 4.p j o G Y O $.y b Q Q Q b ,.|.Q Q Q Q e Q e _.J e e e Q Q e e e ,.@ @ ",
+"m ,.,.,.b m m m m m b m m J m [._._.J _._._.) _.) } ^ o P : S 0./ q '.2 $.b e e Q $ , x |._ <.<.<.I e v & % @ v + @ #.<.<.r [.~ D - W  .H H 5.R +.6 F P R n 8 o 8 :.1.` 1.` =.0 =.1.0 0 7 G 0 O X R a Q ,.m Q Q Q Q Q |.Q Q Q Q e b v _.e e e e e e ,.e e _.].",
+"{.,.b b b ,.m b b m m m m m m m [._.J _._._._.) (.7 m _.' |.; q W + _._.c e e Q e ,.@ = ) _ /.<.<.I Q $ , . x + . + s <.<.&.K z - N = 3 8 R 5.H n 6 :.+.R R P o o 9 / ^ 0 { =.O 2 { A l o  .j =.n N b Q J m b m b |.Q Q |.Q Q Q Q J y Q e e e Q e e e e Q e b ",
+",.,.b b b m b m m b b m m J m m [._.[.[._.[.[.J ) 1 n o o o P } R R P o d c e e e e b # v [ /.<./.g [.@ v . . + ~ @ s <.<.r c @ ~ =  .o 8 :.F -.o n :.:.F P R R F R ` q B 1.7 =.{ 0 G h @ J * d ! y Q c c b b Q Q Q |.|.Q Q Q e Q _.J e e e e Q e e e e e e e ",
+"m ,.b b b b b b m b ,.{.m m m m [.[._._._.) _._.|.j I P d P I l j F n I o K Q e Q Q e Q @ b.<././.n J ) ) . @ + . + #.<.<.} J . ~ = 3 3 w H :.o R H R :.:.o o P :.F 7 *.G 0 ^ _ ` O o y _.J ' % @ J b _.[.b _.m ,.Q Q Q Q Q Q Q e a ) e Q e e e b e e e e Q ,.",
+"Q b b b {.{.b ,.|.J @ @ {.|.) ) J J J _._.c c _._.. {.J J ' b |.' , ' J ) [.' ' 7.7.Q 7.|.C <.;.t z Q ' ' a x @ @ ~ [ <./.` Q . = ..F D D H H F R ..o R F 6 0.o H H o P 9 C A C | 0 z J b N  .j D & y ) ' |.|.(.|.m |.Q Q Q e Q {.' b e e e e e e e e e e e e ",
+"b ,.b J J J m ,.b & W v J {.[.m J J J c J c c _.) |.' ) J _.J b Q . @ b Q {.) (.J |.|.7.e a | u n Q Q ) . v v ~ ' x H } : - Q ' i H 8 3 w 3.H R 8 R P R 8 0.R o E o ..4 ] *.# . y J y $ 8 p S F > W = i W y m Q Q ,.,.|.Q Q e e b c Q e e e e e e e e e e e Q ",
+"m Q b J J b ,.J v D > K J ) [.{._.c c J _.) ) ) ) [.) b . . J + ) ) + ~ 7.|.{.V x b 7.|.,.e e b b Q ' x a a a ' , , ; x {.) (.D w =  .o  .5.3 o F F P P R R 0.0.6  .+.{ H v b ,.b J b >.=.C *.! x ; - i 5.5.3 y Q b b |.e e Q e b J e e Q e e e e e e e e e Q ",
+"J Q Q b b Q b (.D - x J y x ) [.[.J [._.J c c c b > $.j k E j E o f $.n z _.Q b $ v b 7.7.Q z i ! J ) ) (.@ v v v d W ' |.. D $ - $ D 8 8 8 8 P o R 8 8 0.P F j F H :.*., |.) _._.b J k 1 O W x m # @ $ W F A ..' b Q ,.e e b Q J Q e e Q e e e e e e e e e e ",
+",.,.,.,.Q b y % ; (.,.J ) (.x ) ) ) _._.[.J c c a u d o P j d o j f f P _ ) Q b _.a @ b 7.p t /.j.- . @ ' (.' $ D D . ~ , $ D = , = i ..8 o o o H o P P ....+.6 3 *.F W $ ) b {.,.Q b m p _ - _.(.(.. (.$ ; D p ; ) Q |.Q e Q b _.Q e Q Q e e e e e e e e e e ",
+"|.,.b m J . # = ) b J J ,.J . (.(.y ) [._.J c c 7.1 K y ) . ' _.,.. . e | b @ b {.J @ ' J | <.;.<.D . = $ a @ W = (.@ ; D ; + , , D D  . .i 5.o o R P P P 0.+.F G R ; J m b b ) _._.c J z 1 $ ) ) ) x ) , W v i i . Q |.b e Q b J e e e e e e e e e e e e e e ",
+",.,.,.b . # $ . |.J _._.J {.) ) x ' (.) _._._.c a u Y C X 9 $.j j f R 0 '.c b @ J 7.) (.) _ <./.<.D b @ , $ a @ ' , , D - @ W $ D  .i D i @.o o o R R P +.P F 6 :.x b J x x ) [.J 7.) Q . D N . ' . . ) i p i v D $ J Q ,.Q Q b Q e Q e e e e e e e e e e e e ",
+"m ,.,.,.+ $ x Q J ) b J (.[.{.(.V v a (.(.) ) y J z o o g o o o R R $.o c e ,.) ) ,.J J ) : <.<.<.d e J - ! , y @ $ D W $ - , =  .i ; W 5. .o 3 o o R R +.6 ~.~.) [.# x = $ [.) b ' Q . m @ ) c ' . ) (. .A I ) ; , ' Q ,.Q Q b e e Q e e e e e e e e e e e e ",
+",.,.[.v . (.J b J J J J [.J [.) _.@ V ' ) ' c ,.m @ Q . . ' ' _._.K b b Q e e e $ . _.b Q : <.<.<.I Q _., 3 w ' = W - v $ , W i W - ; i i @.3 P R R P R -.4 6 @ ) @ $ , - ; = ; % b [.b ) (.' . ) @ ' J I p ; $ + . m ,.Q Q e e Q e J K Q e e e e e e e e e e ",
+"|.m ) x (._.J J J J J J [._.J J J _.v V v ' ) [.) |.a ,.) _.@ ' y ' y 7.e e Q e |.' + ) 7.2.<.<.<.$.Q v a ~ - 3 , $ , @ $ = W W ; - ; i  .E 3 H R -.o P 6 7 ..a b |.) v @ - D D i @ [.) W = @ ' ) ' ' K H 9 ~ ~ , . |.e e e b % $.$ d ! e Q e e e e e e e e e ",
+"|.[.(.) J J J _.J J J J J [.[._._._.) @ , # (.) ) J ) _._.' b J ' J y b e Q e e e |.) . J _ <.<.<.H b a y (.! ..= @ @ $ $ - ; $ , ; D i H R o 3 R H 0.>.5 5 P 5.' Q Q [._.~ = # D ; ) . I - ' ' v @ y + d G $ v ; ' ) J {.. ! d k $ j d e e e Q e e e e Q e e ",
+"b [.J b b _.J b J J J [._._.[.J J _._.y V = , ' ' I ' ) _.' y . K ) c Q Q e Q e Q e 7.' ' [ /.<.<.n Q m ' - D - W $ ~ ~ , = - $ = D i i 3 P 8 o H R 9 5 ~.+.....w ' ,.b J ' . J ; w @ i :.$ ' @ K @ y _.> P ~ J m e J ,.b > g k J b ! n @ e b y e e e e e e e ",
+"J [._.b b _._.b J J J [.[.) _._.) y J J ' $ , $ a h.Z } '.Y { d J @ c 7.b e e e Q e e 7.b } <./.<.d Q ) = 5.= ' = = $ $ z = $ = - D  .w i H F 8 R 7 5 :.0...o R  ., ) ,.J ) v $ W W , 0.{ = @ . v N K _.D j $ b b |.J e b ].$ Q e Q c i k J e Q e e e e e e e ",
+",.[.) _.b J _._.J J J J J _.[._.) J J _._._.a - $ $ @ b ) % d O Y _ X C 0 b e e Q e Q 7.7.2.<.<.<.I Q $ ; , x @ v $ + @ , , ~ ; - W i > > 3.o 8 9 A *.P o 0.R H i ; ~ ) [.c N 3 $ - - :.4.$ . y @ z v v E l z J m _.Q ,., ~ b Q K J b K k h e e e e Q e e e e ",
+"|.b ) i.i.J b J J J [.[.[._.J [.) m _.y _.b ' , $ = a @ ' d j X / Y Y Y 0 J e e e e e ,.e 1 ;.<.<.d b $ $ (.' ; @ + @ ~ z , = ; ; W W D 3.5.H 8 4 *.F o H o ..H D ; , @ y ' ; H @ i 3 *.4.= @ v K N ' ' i 7 - ,.|.b e z $.' e J J Q e e a ! c e e b J Q e e e ",
+",.,.J (.i.i.J b J J J [.[.) [.) J [.) _._._.i.i.> q j.S 2 *.n ) ' ) ' 7.Q e Q Q e 7.e e e M <.;./.j J ) ) x @ = ; ~ ~ ~ ~ $ ! D D W D H H 3 3 ..:.F :.:.8 F *.{ ; % - ! + @ > i @ o ..9 { D @ ' $ i N ' @.{ $._.m Q ' P g {.Q Q e J e e Q y N c e b y J Q e e ",
+"Q b b ,.) x i.J J J J J [.[.[.[.[.) [.[._._.J J _.5 h.| : ^ ( ^ A n c J e e e e e e Q e e 1 <.<.<.d Q (.$ ; $ a W W $ $ - W i - $ - W D o R 3 R 3 P F +.:.A 9 H % - > ; . . d W W P I H 4.j = ' ' g g y ' P j ~ m ,.].i ~ m e Q e e e e e b J b e Q a @ Q e Q ",
+"b b b b ,._.(.K b J _.y [.b b ) [.) ) ) ) _._._.' m - w $ @ $ J  .E s T T Q Q e e e Q e e S <.<.<.o Q x $ = @ ' @ ; H @ , H , @ - i 3.3.0.4 P H ....P 4 g.4 o W W $ W ' ,.%  .i - o 4.7 { 0 N ' @ 8 G = . D P o . . k h Q e b J Q e e e e Q Q e e Q v N c e e ",
+"b b b Q Q b ) v J J J ) _.J m ) ) [.J [._.) ) ) J y $ 7 ^ S '.^ < X O f b e e e Q e e e e S <.<.<.o Q ) @ , + v @ @ D H = ; 3 , = ; 3.H :.F 3 H H ..5 ^ 4.F H i > = ) . ' ) o - . j Y ` ^ A # @ @ h E ].) . i j - z h a e Q _.b b J Q e e e e e e Q @ ! a e e ",
+"Q Q b J b Q {.(.V ' b ,.J ) J J ) ) ) _._._._.J @ q | { h.w , V $ ) ,.m e J b e ,.e e e e _ <.<.<.o e _.. ~ @ $ ' , x D H = W o = ; 5.0.:.o 5.o o 4 ^ { R o R H W ' _.' . . > D ' p ` ] ^ o @ . x @ $ N ) J # D k D $ ,.,.b 7.b J J Q e e e e e e Q a i N b e ",
+"b Q b J J ,.,.,.% v y J b ) ) b _.) J _.[.[._._.Q ' a J y w w @ - _.x Q Q e e Q e e Q Q |.: <.<.<.d e m ' @ @ = @ a $ v W i $ D D 5.i  .H o o o *.5 *.0.o P 0.i . ,.J ' @ ) % * ' H p X A % ' # # @ . . K ) _.) N i ].v v ' m ,.Q e e e e e e e e e a k z Q Q ",
+"c Q Q Q b b ,.Q _.. $ V J b J _.J ) ) ) ) _._._.y y J y ' x & W $ $ v b Q Q e e e 7.[.) _.M <./.<.o Q ) x . . $ W ' $ , . W  ., i 5.w D w 5.P ~.4 :.o o F P i # # = . * = b % ) ) . p 1 G * . N # # @ ' y ) _.{._.N W W N ].! K b e e e e e e e e e y i N e Q ",
+"b b b Q b b b b ,.[.@ $ v b b ) _._.J _._.) ) _.) ) J V ) Q = w k - $ b |.e {.) e b (.) _._ <.<.<.o Q ' . x a $ , D a $ = ~ D D 5.i D 5. .3 :.{ R o o :.j i z D o > D D > @ ) # @ ) o 1.o * @ @ . @ @ ' ) _._._.' ' y v @ z f > K c b Q e e e e e e c ; @ e e ",
+"7.,.b Q b J b Q b e {.$ , i.J _.) ) ) ) _.J ) _._.J x b _.x ,.a ! w $ $ |.{.) b ,.) . ) ,.1 /.<.<.o e _.' ' v - $ = D , @ = $ - ; W = - i 0.*.6 o 0.0.F 3 @ ; 0 > ; W p A ~ ' ' # # ' W ].' N @ @ @ @ . ' ) _.J J y b K $ K N ! $ a K y J e e e e e {.z @ e Q ",
+",.b b J b b J J ,.,.,.J V = v Q _.J J ) _.) ) _.J x J ) x _.' ) ' ! k a b _.b {._.) J ,.Q 2./.<.<. .|.x (., W v , $ = W , $ = = ; ; W  .3 D 5.F ..H 0.F > (.+ H i D D  .E ; . ) . # * N V @ @ N # $ # @ # $ ' Q b J J J Q ,.c ' N z $ K y K J e e e b b Q e e ",
+",.{.b b b b b b J J ,.,.) V , v ,.J y i.J J ) _.b ) _.y (.[.y y i.@ w ! y m b J _.J J ) ) [ <.<.<.P e b ; W . v a , = - D ; $ = , - > i & [.+ o 0.o R :.o = ' _.d  .N y * @.; ) ' ) @ = ; N @ % @ # . . @ N , % J _.J J b Q Q Q Q a z N @ K c b e e Q e e e e ",
+",.,.,.b m b b m _.J ,.,.b ' V = K i.J J _._.J ) y b ) ) ) _.J y _.J @ w = V _.b J J {.' . r <.<./.j {.) ~ W , (.$ = $ = i D = , - ; , x {.b y , o R 0.0.8 o = J @ + . + W H $.= ' . @ N - = = N % # @ ' ' + N ! % a ) J Q Q 7.e e Q b c $ ].a e e e e e e e e ",
+",.,.b b {.m b b m J J J Q ,.) V > $ J b _.) J (.i.J _.y v x ) (._.$ a y , D , b J b b _.) [ <.<.<.$._.$ (.~ D , , , , = ; D i ; ! % c Q |.. ' _.= o :.0.0.:.8 D Q Q # E o  .@.E # + + @ % * ; ; = * # @ ' _.) @ z N @ a ) c ,.Q Q e e e b c b e e e e e e e e ",
+",.,.b b b m m m J ,.b J {.Q Q J = * v J J _._.) J v _.[.) _.(.J ' 3.! b . * W b J J J b Q M <.<.<.I Q $ , v v i v @ W - $ - i i % c e ,.) [.(.v _.= H P P F 8 ..% J ' k H k  .H # + + & N + # ; z # @ @ . ) ) ) _.a N ].z a c J e |.Q e e e e e e e e e e e e ",
+"b ,.b b b b m ,._.J J J _.{.,.{.b , - v J _.y _.) H y J J |.i W , ' $ , H ' , ) J ) (.{.e : <.<.<.o e ) = - + $ @ = = , = , v $ y Q e b _.[.' + (.y $ o :.+.o R o % J ' i P d = + - W $ + ~ N # * # @ @ @ ' ' ' ,.) a @ a . K a K c Q e e e e e e e e e e e e ",
+",.,.,.,.b m ,.J b b b J J b b J 7.i.- * ' _._.) x g.x ) . ) 2 1.$ Q _.& ^ v . ) b J ) _.Q M <.<.<.o |.) ' ; - (.= = $ $ = + |.e Q e e Q b ' . ) V (.' = o P +.P P E N . = d  .N @.o E * . N * @ = * N # @ ' ) ) _.J J b b J y . @ K J Q e e e e e e e e e e e ",
+"b ,.,.,.,.m b J ,.b J J J J b ,.J ,.@ 3.; (.J y J ^ ) J x J 1 4.) v ) 7.1 = a b J b {.m e _ <.<.<.d e ) ' v @ , , @ , = x b Q e Q e e J J J ' v + $ V ' & o +...H P H ; # @ > o 4.G o H > # @ * # % N % + ' c _._.[.J J b ,.7.e J Q e e Q e e e e e e e e e e ",
+",.,.b b b b {.b b b b b J J J J ,.{.|._.; D V J _.L ^.u j.j.%.%.c.j.}.j.^.' $ = b ,.b b e 2.<./.<.d Q ) (.(.. @ , = ~ ) Q e Q e e e Q m _.) . . # $ $ # v @ D P H H F G H & &  .p 9 1.1.H % % = & $ * = * . ) ) _.J J J m b b Q Q Q e Q Q Q e e e e e e e e e ",
+",.,.,.b m b J J J J J b J J J b J J ) J (.; D V b K b @ ' J . ) ' @ ' Q ' 7.V = _._.J (.' r <.<.<.H Q . . x x @ @ $ . |.e e Q e e e Q b J ) ' ' ' . ' ' ) [.(.+ % N * = ; % + + o 9 A j o P o * & $ & = = @ ) ) c _.J b b b b Q Q Q Q e e e e e e e e e e e Q ",
+",.,.,.b b J b b b b b J b J J J y m J {.,.x - 3.J i._.{.,.) _.K (.) ' x J ,.|.J > y |.' ~ } ;.<.<.o b v + x ' . @ ~ y e e e Q e e Q Q Q b J _.) ) _.) y ) [.,.b . @ $ # % ; $ [.(.- W , i A ] G i ; # @ . (.) ' [._._.J b Q Q Q Q Q e Q Q e e e e e e e e e e ",
+",.b ,.,.b m m J J J J J J J J J c [.Q ,.{.b (.D > J y x _.) ' c [.' . ) Q ' [.Q v & @ b Q } <./.<.d Q . + + . + @ v ) e e e Q e e Q |.,.b m _._.' ) ) ' ' ) {.|.b K $ % N z * @ J J J y N D n 7 7 8 k = ~ . ) ) J J J J m b b Q Q Q e e Q Q e e e e e e Q e e ",
+"b ,.b b b b b b b b b J b J J J ,.' ' J J ,.J K  .= ) {.. J ' _.(.(.x ) ' Q |.|.Q @ W + e _ <./.<. .e ) @ @ + . . c ,.e e Q e Q Q Q Q Q m _.c ) ' ' ' ) ) (._._.7.J a N z z z z @ _.J @ N @ # ! E $.$.I @.z K _._._._.m b ,.Q Q Q Q Q Q e e e e e e e Q e e e ",
+"b b b J m J J J J J b J J J J J {._.@ % (.b b b V S < =.: ^ } _ | g.] ] { ' Q |.J 7.(.* ' S /.<.<.$.e ) a ' _.|.|.e e e Q Q e Q e e b b m _.y ) ) ' . ' ) ) [.[.J ,.J v * z z N N K _.y a $ # a ) ' a N N # K ) J J J J b ,.,.,.Q Q e Q e e e e e e e Q e e c ",
+"b b b b b b b b b ,.J J b J J J ) ,.(.= V _.b b Q , H D ) x g.P _.x ' b J Q [.m b b b [.{.Z <./.<.d e y _.b e e e e e e e e Q Q Q Q Q Q m [.) y _.) ' ) ) ) J |.b Q Q _.v N N N ].* @ J ,.@ $ c c c _.J _.c c c c _.J b b b Q Q Q Q Q e Q e e e e e e e e J N ",
+",.b b b b J J J J ,.b {.J _.[.[.[.) {.) $ , J ,.i.@ w = ) . ] n _.) ) ) |._.|.Q e _.) |.Q < <.<.<.d e J Q e e Q 7.Q Q Q Q Q Q e Q Q b ,.m m J _.) ' . . + $ ~ @ ) ' ) _.) @ N $ $ N ].@ J ' # ) c c c c c J b ,.J c _.J b b Q ,.Q Q Q e Q e e e e e e e b $ i ",
+"b ,.,.b m b b b b J J J {.{.[._.J ) _.J i.V ~ ' - j.^.'.j.c.j.j.j.'.j.c.'.. Q ~ [.,.|.|.) < <.<./.j e K Q e Q e e e Q e e e 7.b ,.e e Q m ' $ W H H n j G G G j n o o o d E $.E = N % N @ _._.K J c c c b b J b J J J m m b b Q Q e e Q Q Q Q e e e e e y ! k ",
+"b b b b m m b {.J {.b {.J _._.) {._.) ) {.) V % -  ., ) ,.Q Q y (.a _.,.x Q J -  .7.b v _.1 <.<.<.2.c b b J Q e e e e e J b e Q Q m K z k P 9 p 0 A p p *.G G j P P j G 9 9 G 9 1.9 R i = # (.,._.c J c _.b J m b b b b b ,.Q Q e Q b Q e e e e e e e K ! k k ",
+"b b b b b b b b J ,.{.{.) _._.J J {.) ) b b x V ; (._._.b & (.7.J J (.- . ' b i n $ e ) |.H <.<.<./.}.u s T u T T T T T s O c @ ! i o P j 9 j n H 3  .D - & $ $ , , & D  .H F 9 p 2 2 A F o i % ' _.J _.c _.,.b b ,.,.b b Q b ,.e b Q e e e e e e Q a h i i h ",
+"b b b b b J J {.{.,.{._.) ) _._.) b {.) _._.) J V (.(._.Q 3 i J J b @ ; |.7.,.F n 9 [.7.m ) u <.<.<.<.;./.<.<./.<.<.<./.<.q z H d n 0.o D ; @ x |.b J ) y y ) J ,.Q Q ,.J J (.a = o *.A 5 5 4 j D $ [.,.{.J J _.,.,.b ,.b Q Q ,.Q Q e e Q Q e e b N i k h h i ",
+"b b ,.b J ,.{.J ,.J ) ) _.{._.) ) _._._._.(.) {.b # ,.) ,.E P i Q [.* ) e Q , o F o w 7.b Q i U ;.<.<.<.<.<.<./.<.<./.;.<.r @ W E W + J |.b (.@ W D  .o R ......H 3 5. .D = a (.|.J $ i R 9 A 4.0 o = . J ,.b J ,.,.Q Q Q Q Q Q b e e Q Q e e Q ].i k h h i i ",
+"b b b b b b b m J ) ) _.J b J ) ,.) ) b ,.b _.) . p v [.Q D j 0.; ' ) 7.{.Q i 8 :.o R . Q e e z S }.;.;./.;.;.;././.<.<.<.} + x J Q 7.J @ > o :.~.~.*.*.*.~.:.F R 0.F 9 *.9 F 8 D $ ' (.v , 3 *.1.A G E * ) |.7.b b ,.,.,.,.Q Q b e Q Q e e Q y k i i i k i i ",
+"b b b b b J b b ) _.) _.J J J J ) ) {.Q ,.Q b ' ) < n E E 1./ C : 0  .I 3 ) 3 F H F 0.D ,.J y e e c $ @ ; $ N $ k h D k  .$ e |.Q (.- o :.~.:.:.:.:.:.6 F F +.P F n 8 :.9 9 9 9 9 F n o W @ v # E 8 :.F o D # ) {.b ,.Q Q Q Q b Q Q e Q e e K ! h i i k i h h ",
+"b b b b ,.b b ,.. ) J J ) ) _.b , @ _._.V y ,.) ) } n E d 1./ : ^ ( :.o w @ F P ..o o  .b Q Q c |.e b y $ @ ! ; @ K ) {.e 7.|.a w H F F R R F ~.:.:.~.7 ~.:.6 8 R o n :.9 9 :.:.:.:.j :.j R  .W # ;  .o P F H ; J {.,.|.Q Q Q Q ,.Q Q e b K h o h k k h h k k ",
+"b m ,.,.Q J ) x ) J {.i.' b J > V b ,.b $.8 = ,.{.p ' e _.E :.G 0...P - ,.5.~.H R :.= J Q _.J e Q { !.;.;.<.<.;.}.C J e ' W W 3 R -.H ..+.F F F ~.~.~.:.~.:.F +.R 8 F j 9 ~.9 :.j F :.F R o F 9 G H % . w o o o o % ,.Q b Q e m ,.m e |.z I $.k k $.k i i i i ",
+",.m |.Q b x . ) _._.) ' ) ,._.> * i.b ,.> G n  .Q ) 7.[.,. .:.P ~...6 -.~ H :.0.j @ [.7.J _.e ].}.;.<.<./.;.<.<.<.;.U n 3 d H H o o o P +.8 F :.:.:.~.:.:.:.F F ..R +.F ~.~.~.~.:.:.:.:.F ..P :.p A 8 ; @ v ; H 3 o W [.7.,.m Q e e Q ) z $.I i k k k i i i i ",
+"m ,.Q ,.' @ x |.b _.(._._._.@ , ; v ) {.$ j n F 3 x 7.[.(.n :.:.R 6 +.R n R ..:.> Q c Q J 7.* }.<.<.;.<.<.<.<.<.<.<.<.L 0 o H H H -...P 0.+.6 :.~.~.:.~.~.:.F 8 R R 8 :.:.~.:.:.:.F :.~.F P ....j 4.1.:.i $ v $ R 0.E = (.7.e ,.Q 7.) @ ~ ! k k k i i k i h h ",
+"{.Q J . + ) b |.b _.) ,._.$ > = v x ' J ) o o 8 F H D . J 3.R 7 - 3 6 6 ..R -...) ,.Q J Q b : <.;.<.<.t L L U <.<.<.;.<.}.i j 0.o o o ..R 8 6 :.:.:.:.:.:.:.F 8 P P +.:.~.*.~.:.:.F :.~.:.P R ..R :.p 5 4.F - _.$ 3 0.d ; ) Q e b J . ~ . @ ! I k h h k $.i k ",
+"|.b (.+ ' |.Q y ) J ,.,._.$ * , J ) ) ,.b o 8 8 o P :.5.$ $.+...$ ' ..7 o ..R N |.) Q ) Q z t <.<.<.e.d . |.b D j.<./.<.<.F H 0.F P o o P 6 :.:.~.~.:.~.~.:.6 F ..R 8 :.~.~.:.:.:.6 F ~.:.F 8 P R R F 9 5 A 8  .b . i j n ~ b ' ' @ + a . . $ i $.k k k k i i ",
+"{.' . ) ,.b ) a J b b _.v i.,.,.{._.J ,.Q W n R F :.:.R P 6 G +.= ) $ 5.~.F = |.m _.J ) 7.*.<.<.<.#.@ e e m % ~ - r /.<.;.^ % o F +.....0.F :.F :.~.:.:.~.:.F P R P P F ~.7 ~.~.:.6 F ~.~.F F :.+.R P F ~.5 A *. .' b - i K J N . @ + . ~ @ K N k k $.k k i k ",
+". . (.|.,.) x (.J _.J K , $ _.,.J Q ,.,.,.+ 0.8 R ..F R G ..+.{ - ' e ) n  .m e ) J m e e S <.<.<.X e Q , D H D % R <.<.<.Y , $.F F :.P R F 6 :.~.:.:.~.:.6 F +.P ..F :.:.9 ~.:.:.F :.~.~.:.~.~.F +.P 0.8 9 5 9 A o . e |.a @ a @ @ . @ @ @ a a ! k $.k i i i ",
+"= . b b ' v ' J _.@ ) J ! P H ; ' {.,.{.{._.F *.3.J $.:.P +.0 4 ~ |.Q |._.) m Q e c y Q Q [ ;.<./.f Q % i 0.H R I $.L <.<.[ . D 8 :.~.:.P 0.6 :.~.~.:.~.:.:.F P R R F :.~.~.~.:.:.:.:.~.~.:.:.9 6 +.+...o 8 *.*.*.{ d . ,.) @ ~ . K ~ ~ ' ' @ @ $ h $.k i $.$.",
+") |.|.y . y J b v & = J ' o P ..P 3 , ' Q _.3 ~...J |., R g.4 P v ,.b ,.e e |.e e |._.Q c } <.<./.I ) I n R n j n o ^.<.<.r . D ..:.~.:.:.:.+.F ~.~.~.:.~.~.:.F R P P :.:.9 :.:.6 6 :.:.9 ~.~.~.~.6 F F ..H 0.9 { o - @ . @ @ K . D ~ . @ $ K a K N k $.i k $.",
+"J b ) V v b b ' > - v ,.J w :.F P ..o o D = 3 o 6 ' e ) , 3 F ~.' ,.,.b e e Q e b e e ' ! '.<.;.<.o + H n +.F :.0.o U <.<.e.. > o :.7 ~.*.~.6 :.:.6 ~.~.~.6 +.+...P P :.~.7 ~.:.F :.~.~.~.9 ~.~.*.~.6 F F n P j P ; @ % % . @ z n l > + K ~ . a a $ ! k $.$.$.",
+"Q _.v a J b y , $ v {.b 7.(.o R ..+.F ~.8 ..P 6 :.w J J . . = k ) Q ,.b e e Q e |.e |.> d '.<.<.<.P ~ o 0.0.F :.P o U <.<.r . > o :.9 *.4 *.~.~.F F :.*.*.:.8 F R ..+.:.~.~.~.:.:.6 :.:.~.~.~.~.~.7 *.F F :.0.H , ' . , ~ . @ $ G { n N ' @ a @ a @ $ h $.k i ",
+"J ' ' b ,.x = - [.J J y |.|.W P ..P 0.~.~.F P P P H + ' ' Q b ) m Q ,.Q e e Q e e ,.$ P d q <.<.<.j ~ 3 R 0.P 8 P R ^./.<.r . W H +.~.~.4 A *.4 :.~.*.5 4 ~.8 +.R R P F ~.~.~.:.F 6 ~.:.~.~.~.~.6 ~.~.F :.G  .+ |.+ N @ + > > ' > 7 { $.. . a @ v @ v N k $.k ",
+"a . J Q J $ $ . J b ) [.b Q ) 3 0.R 3 D H ..P 6 +.0.v ,.J e ,.Q ,.Q Q b e Q Q e e ~ I G W [ <.<./.j $  .o 0.P F F R U <.<.r K ! o F ~.9 4 5 5 5 *.*.4 { 5 *.F P P P F :.:.~.~.:.:.F :.~.~.~.~.~.*.:.6 9 :.3 + Q ' , - ' z 9 G - . d O o $ ~ @ K a v K @ h k k ",
+"x J Q {.' ) {.Q [.|.b |.J b Q = :.0.W m ' = 5.+.{ A $ Q Q |._.m b b Q 7.e e e e Q i *.:.v _ /.<.<.j $ 3 ..+.0.F F R ^.<.<.r K ! o F ~.:.*.4 5 { 5 { { g.5 5 ~.P ..R +.:.~.~.~.:.:.6 :.~.9 ~.~.~.4 :.9 A H . |.) - ~ + , o g.{ P + - P h . @ ~ a a @ v v z i $.",
+"J |.b (.) ,.|.(.b Q 7.7.{.Q e b 0.*.o x |.m m @ o .., |.|.|.b ,.Q b b Q Q e Q Q @ d 7 I |.S /.<.<.G #  .P P P 6 0...U <.<.r . W o F :.~.*.4 4 5 5 { { 5 { 5 *.F R P 8 :.~.~.~.:.F F :.:.~.~.~.~.~.*.*...$ |.J % , + , o p { { 4.$.@ ; ~ . ~ @ @ a ~ @ K @ ! $.",
+",.y V a J b $ I D W $ $ V v $ v - F :.= (._.b ' Q ) b Q b b ,.b b J b e e Q e Q H R H $ Q [ <.<.<.j +  .P P ..F 8 R ^.<.<.r . W H F ~.~.4 4 *.4 5 { { 5 { O 4 F ..P 0.F ~.~.~.~.:.:.~.~.9 ~.~.~.~.*.o + |.' % N @ z R { g.4.5 { p v ~ @ @ @ + @ v @ $ v v ; $.",
+"i.- ~ J y J ) W :.9 6 P P F :.....0.0.F = ) @ b |.|.,.,.,.b b b Q b J e b Q e ~ o n $ e ' q <.<.<.F $ H 8 8 F :.P R U <.<.e.x D o F :.7 4 5 4 5 4.5 5 5 4 A { g.6 ..R ~.*.9 :.:.~.0.F *.F :.*.F *...@ |.@ z ~ ~ k 4.] { 4.g.{ *.].% @ ~ $ ~ + . @ @ a $ @ $ k ",
+"~ , y b $ $ _._.H :.~.G 6 P R R R ..+.5 R v b |.|.|.,.,.,.,.b ,.,.b b e b e e ; n  .m |.- u <.<.<.F ~ H R R P F P R U /.<.Z x W -.F :.~.4 5 4 5 5 4.4.4.{ 4 4 4 *.F R F :.9 *.A 8 9 :.:.p G :.{ 0.% ) ~ ; N ~ ! p *.4.{ 4 { *.W @ K $ % ) a ! - @ @ a $ @ @ h ",
+"* a b b ' @ (.Q $ o 6 ~.7 +.P 7 6 +.+.*.9 * 7.|.,.,.,.b b b b b b J b Q e e ) $.P , e + I q <.<.<.j $ 3 R ..R +.P o ^.<.<.r x w H F ~.*.4 5 *.4 5 4.5 { 5 5 4 4 { A :.8 F ~.5 { 9 :.:.9 :.*.9 n % ) x ; z . ! F ] 4.*.4.] 9 > . @ @ z ~ . D P n + @ v v v @ ].",
+"y b J m m ) x ) |.= o G ~.H - - o 8 :.F :. .m b ,.b Q b b ,.b b b J Q b e e % P d {.Q D o q <.<.<.j ~  .d o o R 8 o ^./.<.Z ' W -.F :.*.4 5 *.4 A 4 5 { { { A *.{ 5 4 ~.~.A O O =.9 j G j p n @ [.@ - $ ' , 0.g.{ { 5 g.g.i ' ~ $ z @ ' > l p j @ a @ @ v K N ",
+"|.b _.(.|.{.) (.|._.- 0.~...$ Q |.y a _.. + b 7.Q b b b b b {.b m J Q b e b i j W e . o I e.<./.<.P @ k H H H n P R U <.<.B . w H F ~.~.*.*.*.4 5 5 A 5 { { { 5 4 5 5 A { =.g.{ ] 1.*.:.7 o z ) . z % @ W 0.{ g.{ 4 g.{ k ~ ~ $ N @ @ W j { A p , a @ @ @ @ @ ",
+"' [.{.{.b J _.m (.|.b , -.~.o * v J J 7.e ,.b J b b b b b b b b m J Q Q Q @ d o (.e D n D q <.<.<.F + i E H o P P R ^.<.<.e.x W H :.9 7 A A *.A A 5 A 5 { { g.{ *.A { { =.h.=.6.=.1.g.1.n N @ N z N N i *.9.O O h.g.9 i @ v N N $ K > p { { A 0 i @ ~ $ @ @ a ",
+". (.|.Q b ,.|.{.x J |.m - +.6 F $ J Q |.|.Q Q |.b b b b {.b {.m J ,.b 7.b h P $.e x d R i q <.<.<.n @ i 3 H o P F o U <.<.r a w H F 7 9 *.*.*.*.5 4 { 5 5 5 5 { 5 5 5 { =.h.h.g.=.4 ` A ; . z ].z N  .5 h.{ 5 9.{ A i . ~ % a $ @ ! P { 4.9 A A P @ @ @ v $ . ",
+"Q ) J ,.,.7.7.[._.$ , ~ w o o :.I $ m m m b b Q b b b b b b b b J ,.m e J d G D e W o H  .u <.<.<.n . i 3 H o 8 P o U <.<.r x D H F 7 *.*.*.*.4 4 4 { 5 5 5 A 4.g.5 4 5 6.=.h.h.{ =.p @., N - z N > 9 2 O 0 O O 5 D + $ % % ~ . z 7 g.p A { 4.4.0 ~ @ $ K $ . ",
+"b ,.) @ v = 3 3 o -.+.G +.....0.:.$.x e m J e b b b b b {.J J J ,.,.b 7.$ d P - b I ..H I Z <.<./.j @ D E o R F P ..U <.<.e.~ = 3 F ~.~.4 *.*.*.5 5 4 A 4.4.{ 5 A 5 { 5 5 { g.h.C :.> ~ N ; ; N - l ] g.5 g.g.4 - ~ @ % $ @ @ , 4.0 { 4.4.A A p 4.$.. $ @ v K ",
+"{._.# E j 9 :.....n R +.*.6 P P 9 n - _.b Q e J b b b b b b b b c _.m ,.! j P v J H 0.d 3 q <.<.<.l ~ D  .E R ~.F n U <.<.} v D o F ~.:.7 *.4 4 *.4 5 5 5 4 4 4 4 5 O O { { g.C *.5.& N - N N ; F ` h.{ O ^ 1.H ~ + % - $ v W :.4.A 4.A 5 4.4 p 4.o . @ @ @ a ",
+",.Q _.& E n 8 P H +.+.6 6 R $.W ; - ~ _.b Q e {.b b {.b J J {.m Q b b m > j H [., 0.0.o d q <.<.<.j @ D E H o 9 R o }.<.<.} x W 3 8 :.7 A 5 4 5 5 5 5 4 5 5 { { A 5 4.1.=.C g.9 > % # * - z i P ` ^ ` h.] 4.R , + - - @ + D 7 ` A A A 5 A 4 A 4.A :.% a $ $ $ ",
+"J b ,.{.v , 5.~.G +.n ! _.|.J {.|.|.|.Q m b Q b {.b b b b J b m Q _.J ,.a - , b E 0.o o H q <.<./.o . k o o H 8 :.n U <.<.r . D o 6 ~.7 4 4 7 *.5 5 5 4 5 { { 4 *.5 A A ] C 9 D + % * ~ % $.p ] g.{ 1.^ A D % ~ $ - $ ' ; *.] 4 4.4.5 5 5 5 4 4.A p ! @ $ . @ ",
+"b J b b {.{.v w 6 G ~.H a Q b ) J m Q ,.m _.b {.b b {.J J m m m J ) Q Q e e ,.b 3 0.0...I q <.<.<.l @ i $.@.3.H j 8 ^./.<.e.+ W o F ~.~.4 4 4 5 4 5 5 4 5 { 5 *.A 4 5 O g.p  .@ $ - z # > 9 ] 2 { g.{ A I ~ @ % - a . D ~.{ 5 A 5 4.4 5 5 5 4 A 4.{ D @ $ y a ",
+") _.{._.(.J ) a -.7 ~.o 3.' Q _.{.[.m m b b b {.J b b b m m m J J _.7.J b 7.7.Q $ H :.0. .q <./.<.P c ' J Q Q J * ; U <.<.r v ; 3 +.7 *.5 5 4 4 5 { 5 5 5 { { 4 4 5 1.g.G D % N z ~ @ - P g.] { g.^ *.D @ N ! % . v > *.g.5 9 4.4.4.4 4 7 0 4 A *.l ; ) $ @ @ ",
+". (.b |.,.J J ) ) ; H 8 G E @ _.,.,.b ,.,.b J J b {.{.m m m [.J b ) {.- D , [.Q b , o F 3 q <./.<.P Q Q e 7.7.Q Q _.#.<.<.r . ; o :.~.+...H D 5.~.5 g.5 4 5 5 5 4 4 5 j i # $ - N ~ - P g.] g.g.2 g.H ~ @ z h % + i 9 4.{ A 5 5 { { 5 5 5 7 4 *.F R ].Q ' $ $ ",
+". . ) J b {.) y _.) > R n G F ; # a ' J |.,.c y b b b m m m m J ,.[.|.> j P W ' Q m - 0...q <.<.<.d e Q ) V V v {.,.T <.<.B + D o R 3 = ' y y ' @ H 4 { 4.5 5 5 4 5 F ; @ * ].N N ].n ` 2 4.4.^ 1.n = , z ~ N % i ~.g.5 *.4 4.A { { 5 5 5 4 4 *.R R > e {.@ a ",
+") + v {.Q Q b v n 8 8 R R P F *.0.' Q m c ' _.,.m ,.,.,.m J J J _.Q {. .....0.3 b Q ) 3 I './.<.<.d e * 3 o H :.o [.u <.<.q ) W o o @ b @ w W , @ (.; A { { 5 4 { F ; @ N z N N @.A h.g.1.h.g.4.D - N N ! N . i ` 5 4 5 5 5 { { A { { 4 A 5 :.H d o  .Q e e Q ",
+"Q Q |.J ' , 3...F G :.F 8 P H w . e Q _._.m ,.|.b b ,.m [._.J b m ,.J  .R R 0.H ' J |.5.o Z <.<./.$.) E H R o R R  .#./.<.} @ W I ; J v o 4 4 9 - x $ n 4.5 5 4 P D + @ - % ~ ].p 1.1.{ C ^ ~.D , $ - ; N + ! *.{ 5 4 5 { 5 4.4.5 4.5 4.*.F ..H o o k Q Q Q b ",
+"7.{.$ i ..P +.R o ~.A n w @ _.|.Q Q ) ' _.m Q ,.b b _._._.m b m J ,.[.3 P o ..R & |.e W H e./.<.<.$.) E H ..o n l j %.<.<._ + W d + b D 4 4.{ O o @ v i { 4.{ 5 3.~ . , ].z > 8 ` =.{ { h.5  .@ $ z ].z N i *.` { 5 5 5 { 5 4 A 4.p A { p ..3 o H R  .Q e e Q ",
+") = ..:.6 ~.6 -.P H ; (.J _.J |.|.J ) m b b Q b m m _._.m b b m J J [.3 0.H o 8 w e |.= H q /.<./.l . d R H o 8 o P t <.<.| ) D  .) b  .5 *.*.{ p , v ; { 4 { 4 @ @ $ z z - n ^ 1.4.O ^ { H , , - ! z $ z d ` ` 5 5 6.5 5 5 A 4.5 A A 5 9 0.H H H o  .Q Q e b ",
+"|.' D o o ..6 6 n 5.$ i._.m b {._.J ) ,.|.m Q ,.J _._.m m m m m _.J J 5.0.o R P > Q |.; 3 Z <./.<.M @ - n o H o o S <.<.<.=.c D I + J 3 A 4.4.O :., + W g.4.5 4 $ ~ @ $ % N $.4.1.g.g.^ ] :.D = z ! N z z ].R g.5 O 5 5 5 4.A 5 4 4.4.A A 9 F H H R k Q e Q Q ",
+"x b |._.' @ 5.6 P +.F R D # b e ) b _.J b b Q Q _.J J m ,.m m J b b b i R R 0.o ' ,.7.D H =.<.<.<.t 0 $.3  .d F r t <.<.<.7 . k o , b $ ..*.A ~.W v = H g.{ { 4.o ; . ~ - , z  .4.g.g.O h.h.*.o $ z z z % . - d 5 O 5 5 5 4 +.0.:.A 4.A 4 A :.H H R  .Q e e b ",
+"@ ' m ,.|.Q Q _.H -.P 6 ~.P 3 w @ Q Q |.Q Q ,.J _.J b ,.b b m m m ,.{.i ..8 0.5.|.,.J H ....U <.;.<.d.#.q < q %.<.<.;.<.%.> $ k F H . m @ W W , @ @  .A g.5 { { { n - % - N % z I A ` 4.g.^ 2 g.$.! z N $ , ~ $ n 4.O 5 5 F H H ..:.*.4.A ~.+.o H o k Q Q Q Q ",
+"(.@ ' ,.Q ,.Q Q |.$ k -.-.8 :.:.d ' ,.b ,.b _.) m m ,.b J m b ,.J m _. ...8 o = |.Q ; R R W ^ /.<./.<.<.<.<.d.<.<./.<./.C {.- $.0.9 D ) b ) a ' a - 6 ^ g.5 5 5 ` A 3 ~ ~ z z z @ o { g.g.O O g.] i , z % , ~ $ , n 4.{ 7 +.o ..H ..~.{ 4.0.o o d R  .Q e e b ",
+"|.) . ' b Q Q |.J ' w R :.6 P H ) Q b Q Q ) c m m b m m ,.m m m _.,.|.> ~. .$ Q Q ) H +...3 i ^ <.<.<.<./.<.<.<./.<.;.{ c @ D H P 0.0.3 , _.y , H 7 g.{ 5 { 5 5 *.{ A $.@ @ ].].- % I { g.O h.^ g.4. .~ $ z % % @ $ o p 6 ..R H 0.o n 7 F H H o o n W e Q Q e ",
+"J J _.' [.Q Q [.& 3 6 P P F W 7.,.e ,.b b [.m ,.m m b m m b b m Q J b ' $ b b Q [.W F o o R W W { c.<.<.<./.<./.<.q P . _.W I P 9 9 *.9 R 3 o ~.*.{ g.5 4 5 5 5 5 4 { 4 H z N N N ].z I { g.5 g.O ] :.W ~ ~ ~ z ].+ @ D 0...-...o 3 H R ..d o o H n z e Q e Q ",
+"{.,.J _.J ,.(.= F ..P :.3 v ,.Q m Q m ) _.J m _.m m m m m m b m Q J ,.Q Q 7.|.Q  .8 F -.P F H i + D 9 ^ _ : S /  .' ) + W I H F F :.9 *.j n :.A g.O 5 4 4 4 4 4 5 7 5 ^ 4.H z $ ].N $ z I 5 h.O { ^ g.:. ., @ $ a y Q {.= o ..H o o o o H o R ..o R @ e Q e e ",
+"' J Q Q _.= H F P P ..; [.e e _.,.{.c _.m ,.,.,.,.m m ,.m m m b m [.|.|.v $ $ b  .n o o +.o ..0...; . v + ' ) ) ~ $ W D i o 0.~.F 6 :.9 :.o ..:.g.{ 5 7 { { { 5 5 7 4 =.] 1.n W z $ z - , I 4.h.g.] ] ] A H , ~ ' {.|.e |.= 0...o ....o H H H o o d _.e b e Q ",
+"' [.|.(.D P 0.-.o F H # {._._.Q e ,.,.,.,.,.,.,.m b ,.m b m ,.m J b Q J  .P E [.~ 0.0...-.o 0.H o ..H W = ; W > ; i ..H ..:.F F ~.:.9 *.:.0.R 8 7 5 0 5 5 O 5 4 5 5 5 5 { ^ g.P N z N $ ]., I g.` g.g.g.g.*. ., $ _.m J e |.W F H H d o o o o o R  .b e b e e ",
+"7.,.+  .F 6 0.o F o E H o I i i ! - ' ,.,.,._._.b m m b b m b m {.,.|.{.i j d ) @ 0.F ....-.+...R ....H H H  .5.H o F :.:.+.P 7 6 F :.9 j R R :.7 { 6.0 7 5 5 5 5 5 5 { 5 g.C g.$.% K z ! N z I { ] h.{ { g.5 o $ . _.m |.e J - 0.0.o o R ..o d n W Q e Q e e ",
+"Q J ~ D 5.i H F 8 :.8 n F F 0...A P % m ,.,.m m m {.m m m m m m b b m Q $ H o $ [.k 0.R P ....o +.n o P 0.o ..F 0...0.~.4 G P 6 ~.:.~.9 j n F ~.4 5 5 7 4 5 5 { 5 *.{ O 8.{ =.g.A D ].].N z ! $ R 4.g.{ 6.h.9.4 W , ' J J Q e e W H 0.R R R o o ..$ 7.Q e e e ",
+"Q Q ,.Q Q |.) ) ~ N N > 3 -.+.4 F k ) Q m ,.,.,.m ,.m b {.m m ,.b m [.7.. I 0.! Q i 8 o o R P R -.+.+.R P :.F o P :.F P 6 7 :.+.6 F :.~.F 0.:.5 5 0 5 6.5 5 5 { 4.*.5 O O 8.O 5 C { I $ $ z z ; N d 4.g.O O 8.O ~.W # @ _.e b b Q = o o d H o o o . e Q e Q Q ",
+",.m _.Q Q J |.Q 7.,.7.Q D :.6 +.W |.e [.|.Q Q [.,.m m m m b ,.m Q c b e b W n  .e + o 0.o R R ....n P P P P P +.+.+.+.+.6 6 7 7 +.F ~.*.*.~.*.5 4 5 7 5 5 5 4 4 5 5 5 { { O { { 5 { { j W @ $ z , $ 3 O h.{ 6.{ O 5 E ~ K y Q b e Q ~ d R o o o D ,.e Q e b e ",
+"Q ,.' ) {.b Q Q m e Q , 0.7 6 H (.Q ,._.b [.,.,.m b m b b m ,.,.b J ,.e e % n H m b  .F H o R ..R P ..n P +.P P P +.+.+.6 6 ~.~.~.:.~.9 *.*.*.4 4 5 5 5 4 4 4 4 5 5 0 { 6.{ { 1.{ g.] ` F ! $ - , ~ ; o *.g.h.4 5 g.4 I % y Q e Q Q b - n o H n % e e Q e Q e ",
+"Q Q . @ J Q e ,.,.e ~ 0.:.F 5.' |.b {.Q Q |.,.|.b b m b m ,.J J J ,.b Q e ' I n $ e , j o 8 8 o R ..R +.P P +.+.F +.P 8 +.F 6 ~.*.~.:.7 *.*.7 A 4 4 4 4 5 5 4 4 4 5 5 5 { { O { { g.O ] ` o , $ - ]., $  .5 g.5 5 { ] A $.~ ' J e Q e {.- ..R o ) e e Q e Q e ",
+"|.e _.) |.Q Q b e v o A 0.5.@ e Q b b |.) ) b ,.b ,.m m m b m m _.,.Q Q e ,.W P  .e {.3 8 R n R P P R P n P P +.P F +.8 +.F F 6 *.7 *.4 4 *.4 4 4 4 5 4 4 5 4 4 4 5 5 { { { { { A { { { ` 4.I $ $ ].; $ , 3 *.g.O *.5 g.p i @ . J |.b e ,.! R $.Q e Q Q e Q e ",
+"b e |.,.Q b Q Q )  .:.0.o D $ @ - W 3.H R > ' {.b b ,.,.b m J J b b ,.Q e Q v d n + Q % 8 R P P R P n P P P P P F +.+.+.+.F +.6 :.:.*.4 4 7 ~.*.4 5 4 5 5 4 4 4 4 4 5 5 { { { O { O O 4.O ] 5 H z % N , $ $  .{ { { *.{ g.F = + . Q Q ,.e b , ! e e b Q e e Q ",
+",.Q |.Q Q b Q J o 9 F ..F 0.H j F 0.0.:.0.$ |.Q b b m m J {.J b Q m ,.Q ,.e {.D 0.i |.{. .o R 8 P +.P R P n P P P +.+.P +.6 F F +.6 *.4 A 7 7 4 4 4 4 A 4 4 4 4 A 4 A 5 4.{ { O ` 4.g.g.4.` ] { P W ~ z z + ~ i A ] 1.4 1.{ +.3 % K J ,.Q e |._.e e b e e e e ",
+"Q Q ,.|.b |._.W A ~.0.R 0.P 0.F R 0.0.R > ) |.{.,.b m _.J b b ,.,.Q Q e Q e e + o n , Q @ H H ..P ..P P P P P P +.P 8 F F F 6 6 :.F ~.4 5 4 4 *.4 4 4 5 5 5 5 4 *.A 4.4.{ { { { { { { { { O g.h.` j ; # , ~ . ~ $.A { *.4 g.O 1. .; K ,.Q Q e e e Q Q Q e e e ",
+"e ,.b |.b b v :.3 D  .i = z % J ; H F .., |.Q b |.b m _._.{.Q Q J Q Q Q Q Q e ) d n H Q |.H H H P P P R P ..P R 8 +.+.F F F F F ~.F F 7 { { 5 *.A 4 4 4 4 A 4 4 *.*.A 4.{ { { O 4.{ O g.] ] g.g.2 { o ~ ~ - z $ @ I { g.4 *.5 4.0 W @ . Q e b Q Q e e Q Q e e ",
+"|.e ,.m e m $ (.m |.m |.Q b Q Q 5.P :.; J b Q |.Q ) _.,.b e e J Q Q b e Q Q Q e ; o j $ Q = n o -.0.6 +...+.P R P P 8 F F :.6 :.F F :.~.7 A 5 { 7 4 5 5 5 4 4 5 A 4.A 4.{ g.{ 4.{ O { 5 A g.h.O 5 2 4. .$ $ - $ % . i { { *.A 4.F % ~ ~ ' _.e Q e |.b Q e e e ",
+"Q ,.|.|.b J m Q b b m b b |.|.@ ..F ..v Q |.|._.z o ; Q e y y e Q b b Q Q Q Q Q ' I o 3 . _. .n H o ..P P R P F P +.+.+.+.F F 6 6 6 :.:.~.4 5 4.4 4 5 5 5 4.4 4 *.A 4.{ 4.{ { { g.{ A ~.~.4.] g.O g.g.4.H + ' , . N -  .p g.4.4.$ ~ D > @ y Q Q e e e Q Q e e ",
+"|.|.b (.x y J b |.J b b m Q (. .8 ..3.y J , W H :.P a ,.J Q ,.b b Q b Q e Q |.e e $ 3 l D Q . E ..H H 0.:.8 o +.8 8 8 F P F :.F :.:.6 ~.9 7 4 5 5 A 4 4 5 5 5 5 *.A 5 4.4.4.{ g.{ *.~.F 0.9 g.h.=.O =.^ 4.3 $ $ $ % $ @ D p A k .  .{ j z @ a c c e e e Q e e ",
+"J |.x = y |.J J m ) J J b |., 0.H R E 5.o P n P F H |.e ,.e Q e J Q Q Q Q Q |.e e ,.- R o @ 7.. ..R o o F :.n R R 0.0.+.8 F :.F F F :.~.~.~.4 5 5 5 4 5 4 A 4 A 7 A 5 4.{ { { { *.F F F :.*.{ g.g.h.O { g.g.0., % ~ ~ a @ k  .. D p ` g $ @ $ a a J Q e e e Q ",
+"J J @ a |.|.J b J y m m |.) 3 j +.F 0.R F :.:.:.n D |.Q [.e b ) J Q |.b Q Q |.Q Q e ) - F H {.Q = o R 3 H F ~.6 8 P 0.8 +.F F :.:.:.6 :.~.*.7 *.4 5 { 5 5 4 4 5 5 4 4 5 { O 5 A :.0.0.:.:.p g.g.O ^ ^ 4 A 2 { P x % ~ + ~ . . - 9 { *.! K v N @ $ @ ) Q e e b ",
+"_.$ x |.|.) J b b m J |.|.= F 0.R F F 8 H i H 0.P % 7.Q |.|.$ d y Q Q Q e Q |.e e Q e . H P D b 7.= P P H o F :.8 8 8 8 0.F F :.6 F ~.~.~.*.*.4 7 5 { { 5 4 4 4 5 5 5 5 { { A 6 0.R n F l A ` g.{ g.h.g.{ { 1.{ i % ' ~ z a v ! { O o % @ $ N @ v $ $ m e e b ",
+"$ $ y |.J ) b |.b b {.Q y 3 8 H F o D W x (. .o H # |.e [.; n P y b Q b e e Q e Q |.e |.~ H n = 7.J w R o o R ..:.F F 8 8 8 F F F :.:.~.*.7 4 4 *.4 5 { { 5 A 7 5 7 5 5 { 4 :.0.F 0.0.n :.4.] ` g.O g.h.g.4.4.] 4. .# ~ ~ $ z ~ o 0.- @ @ v @ v @ ].i z Q e Q ",
+", b Q J [.{.m m J J J Q # 0.R i - @ J ) |.J 3 8 H b Q @ i n 8 P . b Q ,.e e |.e |.e b e Q  .R R - b ' 3 ..H o o :.F F +.F F F 6 F 6 :.~.9 *.*.4 4 4 7 A 5 { 5 7 7 4 5 5 5 7 0...0.0.F 0.j { ] { g.g.g.g.g.g.{ { g.A i + ~ @ . ~ ' W @ a $ $ $ @ $ h g k _.e Q ",
+"b b ,.b b {.{.{.m |.|.J ' ' b b e J . |.e + R ..D $ i n n o o +.x ,.,.e $ > e e Q e Q e e J h j n D b |.D R 3 o H 6 9 F ..P :.:.6 :.6 ~.7 7 7 7 4 5 4 7 5 5 { 5 4 7 5 7 6 P 0.F R 0.R o F A { { 1.{ 1.g.g.g.{ { O P - @ . @ % @ ~ @ ~ $ $ @ @ @ h f d d k ' e ",
+"b b b {.b m J J m |.|.b m b |.b J a # b |.W 0.H ..3 0.F o n 0.+.$ Q Q . $.o @ e Q Q e Q b e c k n o ; Q 7.; 8 0.E 0.:.F +.F F +.6 G 6 ~.7 7 4 7 7 7 5 4 0 5 5 6.5 4 7 6 0.+.P P 0.F F 8 F 4 { { g.{ g.g.1.5 g.g.0.~ x 0.G % ' z % @ a @ $ @ $ N f d f d o ! c ",
+",.{.{.{.{.{.J {.{.|.Q b b b b ) W , ) e e 3 0...H ..G d ; H 0.0.a |.) $.g n  .) e b Q Q Q e e _. .0.H & b e + n ..F :.9 ~.:.:.F 6 :.~.~.~.4 7 4 4 7 5 5 7 7 4 O 5 7 F P +.8 F 0.8 8 0.0.0.9 { h.5 O g.g.5 ] g.7 + , I 0 { I ~ ' $ @ @ $ v a N h R g f f R o - ",
+"b b b {.b b b {.b b b b b b ) v $ (.|.Q _.o o ..F R i + |.> R 0.' ) > j o d n > e e Q b Q e b e _.k P H W {.7.' :.F F :.7 ~.:.F 6 6 6 ~.~.7 7 7 7 4 5 5 5 7 5 5 *.:.P R P 8 P R P R R 8 R F *.{ ` O 4 { h.] n $ = n { 2 A D @ @ ~ @ @ ~ a v ! d d d o d f o f ",
+"{.{.{.b {.{.{.b b b {.J J J (.+ _.J {.b . n d R H ; ) e Q  .F n & $ o P I o H I # e e b Q e e Q e ) D j n i @ |., i F *.9 6 F 6 :.:.~.~.~.*.*.4 4 4 4 5 5 { 4 7 P +.8 P P P 8 8 R 8 F j F F j ~.{ g.g.{ *.i , ; p ` { 7 $.@ . % @ $ @ v ~ ].k g $.f o d k $.g ",
+"{.b {.b b b b b b {.J [.J {.[.) _.J ,.Q ; G H W ) m Q |.J I 8 R E H j k N @.H n I , Q e Q Q e Q Q e J ! o P H i b (.; 3 P 6 :.6 6 :.:.~.~.7 *.7 4 4 4 7 4 5 ~.F H R 8 F 8 8 8 8 8 j F P P j G G *.1.~.D , , 3 A ` =.n - @ ~ % @ $ @ @ $ ! $.f d f $.f o f I d ",
+"b {.J {.b b b b J J b J J b m _._.,.,.J $.I - b |.,.,.,.7.h R P 8 P d ' Q , o 0...o z b e b Q Q e _.Q e , P j j H = b b % ..:.8 :.:.:.~.9 *.*.A *.4 *.4 *.~.F ..o o R 8 8 P 8 P n 8 P P j 9 G F n  .% + D 9 ` O *.I $ ~ @ . ~ ~ ~ @ @ ].$.d d $.g $.$.d o f f ",
+"J {.{.{.b b b b J b |.J _.J J J _.,._._.> J |.Q {.{.,.J ,.k R R P P - Q 7.$ 0.5.o ..H z e e Q Q ,.e e b {.+  .n A 9  .' Q y w ..F :.:.~.9 *.*.A *.*.*.A *.F ..o ..R o R 8 P F 8 n P j :.l 9 o 3.v |.# F { { { 0 i z . $ $ ~ % a a @ - $.g d f $.o d f f f f d ",
+"_.J b b {.{.b J b b J b b J b J b b ,.b ,.J |.|.J ) Q Q Q D n n *.W ,.Q Q b ..o ..E n k Q e m e Q e Q J m Q ) D p j F P D ) |.(.- H 9 *.~.:.~.9 *.A A *.j R R P o o o R n F 8 8 j F :.l n ; (.,._.= o 7 ` =.G W ~ % , % ~ ~ $ $ @ ].$.g d f f d f f f f f f f ",
+"b {.{.J J b {.J m b J m b J b J b b ,.b ,.J J J J b ,._.,.> P :.i + Q e 7.Q i o o R H N 7.e Q e e Q b {.b m ) . ; I :.9 G H = ' |.) ,  .0.9 A 4.A A A ~.:.0.R R H o n j :.j P P P d D $ _.,.' = o P l G P I D % + ~ ~ $ % ~ @ . ].i f d f f f d f f I f I f f ",
+"7.Q J [.[.J b b b b b b J J J J J {.{.,.J _.) x ,.J ) _.7.i 0.D ) {.Q e e e $ ..H n z Q Q 7.e Q e ,.m b m c _.Q |.@ > k o A 7 H  .= . x + $ W  .0...d H H H H H H o o o E  .D > ' _.J ' z  .P l p l d ! @ y K ~ ~ ~ % % ~ $ z ! f f d d f f d o f f f f f f f ",
+"7.Q ,.J _.[.[.b b b J b J J J J b b {.{.b [.) ' _.) J |.Q D D b |.b {.Q e e ) o R  .) 7.7.7.7.|.J Q ,._._.J _.m |.b J ) + i j p G :.F 0.H W , @ ) b |.Q |.b b ,.Q ,.,.,.,.b {.[.z @.n j j l l l k z . J |.Q _.@ N $ @ . @ ! I n n R g d f f f o I $.f $.$.f f ",
+"Q 7.Q |.J ) [.b m m b m b m J J b b J J J {._.(.@ ) |.,.[.. _.Q b J J e Q e Q $.o @ Q 7.e 7.|.,.[.|.m ) J b _._.) J ,.b {.c ~ W j G p 7 G ~.9 7 D W , $ # @ ' (.(.. # * >  .o j G j j j 9 P i ~ ' ) J J J J J J $ ~ K K - I P P P n o o o d f $.$.f $.f f I I ",
+",.7.e Q ,._._.{.{.J b b b b J J b b {.J [.{.b J ' a ' b |.|.|.b J J b e e Q Q ; i b e Q e e [.J |.[.' c m b m Q _.c _.c J {.J _.' , H :.A { *.:.F F P 8 0.8 8 n o R P j j G j j j l l f - a _.c J c ) c _.{.{.,.c @ z > $.o n o g o o f f o f $.f f I f $.$.f ",
+",.Q 7.Q Q ,.[.) ) J b b b b b b J J J m [.J J b J @ @ [.e b _.J [._.Q e e e e v . e e Q e ,.) b b . . [.,.J m Q b b J b _.y y _.J ) ' @ - i d o n n F P P 0.n n n P j j :.P o H > z . _._.c y J y y c J b Q b c Q ' h d g I I n g o f f f f f f $.$.$.$.f f $.",
+"Q b Q Q Q e b ) [.[.J b b b b J _.J J m [.) J m J b x . m b _.J ) _.Q Q e e e J e Q e e Q J J J (.+ x [.[._.J _._.m m J c c J _.) m _.(.) b b b + ~ ; W ! ; ! D ! ; ; ! - N . c m ,.b J c ) y c c c c c c b b J b J $ $.n d I d n g f $.$.$.f f f f f $.$.f f ",
+"Q Q Q Q Q ,.Q Q ) (.[.b b b m J J J J b m m [.J J b b ) ) _.J J [.[._.Q e Q |.Q e e Q ,.b ,._.' a y ) [.) ) ) [.m m {._.c y ) c c ) ) _.m b b {.|.,.,.|.|.,.|.Q 7.Q b b m J J _.J J c c ) c c _.y c c J J m J J J _.e {.i o $.$.$.d g f k $.$.$.$.k k $.$.$.I ",
+"Q Q Q Q Q Q Q Q [.) ) [.b b b J J b J J {.J [.[.b [._.b ) v x b ) J ,.{.,.e e ,.e ,.[.m {.[.' . ) J J J ) ) (.' ' ' ) J m J J ) y c J b b ,.b b b Q ,.b b b b ,.Q b m J ) c c _._._.c c c c c c c _._.c c c c c c ,.b b y ! g f f $.$.$.I $.$.d $.$.$.$.$.$.f ",
+"Q Q Q Q Q |.Q |.,.[.(.(.[.b b J b m J J J J m m b ) [.b m @ V y b J J |.|.b b m |.m _.{.J ) ' ' J J J ) (.' ' ' ' . . ' _._._._.y c b ,.|.b b m ,.b b b b b ,.b b b J y c ) c J c c J J J {.c c c ) y ' K y y c c Q J Q e K $.d I k i f k $ $ $.f $.$.$.$.$.$.",
+"Q Q Q Q Q ,.Q Q Q ,.J (.) ) {.b b b b J J {.{.b ) ) J J {._.x $ _.J _.|.7._.. ,.b |.|.|.J ' (.J J _._.) ) ) ) ' ' ' . . K ' K y c m Q 7.Q b J b b b m m m b b b Q b b c c J _.b J J J J c c c y K a a a . y c J J J b Q Q Q a i f f $.k $ e e ! $.$.$.$.$.$.$.",
+"Q Q Q Q Q Q Q Q Q Q |.J (.(.[.b b b b b J J m m ) b J ) m |._.@ % (.J b |.|.m [.{.|.Q J ) _.b b b [.(.y ) ) ) ) ' ) ) ' + ~ @ @ b b Q Q ,.m m m ,.b b J J J ,.|.b b {.{.J c J c b {.c c y K @ @ $ ~ v . ' y c J J J b ,.c e e a k I k $ Q e y i $.k k k k k $.",
+"Q Q Q Q Q Q |.Q |.Q Q |.) ' (.J J J m b b J J {.m m J _._.[.J J v # _.|.J {.b ) b b {.) ) J b J b J [.) ) ) ) (.. ' ' . @ ~ K _.e e Q Q b b J J m m J J J J b b b b c y y ' y ' K K a a @ @ $ $ @ ~ a K ' ) ) c c J b Q Q Q Q e K z $ e e a i $.$.k k k k k $.",
+"Q Q Q Q Q Q Q |.,.Q 7.Q |.[.) ' ) _.b b b b J J {.{.J J [._.b b b a @ b Q ) x ) b J y ) {.|.b ) b {.) ) ) ) ' ) ' ' . @ ~ K b e e e Q b b m J J J c c y ) c _.J Q {.c a @ v a K @ @ @ @ @ @ a a @ a a K y y c c _.J m b e Q b e e b b e e % $.i i k i i k k k "};
Index: branches/heathaze/src/lib/gui/qt/gui_audio.cc
===================================================================
--- branches/heathaze/src/lib/gui/qt/gui_audio.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/gui_audio.cc	(revision 9940)
@@ -0,0 +1,100 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+
+#include "gui_audio.h"
+
+#include <QtGui/QLayout>
+#include <QtGui/QLCDNumber>
+#include "debug.h"
+#include "globals.h"
+
+#include "qt_gui_elements.h"
+
+namespace OrxGui
+{
+  /**
+   *  Creates the Audio-Option-Frame
+  */
+  GuiAudio::GuiAudio(OrxGui::Gui* gui)
+      : Element(CONFIG_SECTION_AUDIO, gui), QGroupBox()
+  {
+    QGridLayout* layout = new QGridLayout(this);
+
+    {
+      QtGuiCheckBox* disableAudio = new QtGuiCheckBox(CONFIG_NAME_DISABLE_AUDIO, this, false);
+      layout->addWidget(disableAudio, 0, 0);
+
+
+      QLabel* soundCardLabel = new QLabel("Soundcard");
+      layout->addWidget(soundCardLabel, 1,0);
+      QtGuiComboBox* soundCard = new QtGuiComboBox(CONFIG_NAME_SOUNDCARD, this, "");
+      layout->addWidget(soundCard, 1, 1, 1, 2);
+      soundCard->addItem("Not supportet yet");
+
+
+      QtGuiSlider* channels = new QtGuiSlider(CONFIG_NAME_AUDIO_CHANNELS, this, 16, Qt::Vertical);
+      layout->addWidget(channels, 1, 3, 3, 1);
+      QLabel* channelsLabel = new QLabel("Channels");
+      layout->addWidget(channelsLabel, 5,3);
+      QLCDNumber* channelNumber = new QLCDNumber();
+      connect(channels, SIGNAL(valueChanged(int)), channelNumber, SLOT(display(int)));
+      layout->addWidget(channelNumber, 4, 3);
+
+
+      QLabel* musicLabel = new QLabel("Music Volume");
+      layout->addWidget(musicLabel, 2, 0);
+      QtGuiSlider* musicVolume = new QtGuiSlider(CONFIG_NAME_MUSIC_VOLUME, this, 80);
+      layout->addWidget(musicVolume, 3, 0, 1, 2);
+
+      QLCDNumber* musicNumber = new QLCDNumber();
+      connect(musicVolume, SIGNAL(valueChanged(int)), musicNumber, SLOT(display(int)));
+      layout->addWidget(musicNumber, 2, 1);
+
+
+      QLabel* effectsLabel = new QLabel("Effects Volume");
+      layout->addWidget(effectsLabel, 4, 0);
+      QtGuiSlider* effectVolume = new QtGuiSlider(CONFIG_NAME_EFFECTS_VOLUME, this, 80);
+      layout->addWidget(effectVolume, 5, 0, 1, 2);
+
+      QLCDNumber* effectsNumber = new QLCDNumber();
+      connect(effectVolume, SIGNAL(valueChanged(int)), effectsNumber, SLOT(display(int)));
+      layout->addWidget(effectsNumber, 4, 1);
+
+    }
+
+
+  }
+
+  /**
+   *  Destructs the Audio-stuff
+  */
+  GuiAudio::~GuiAudio()
+  {
+    // nothing to do here.
+  }
+
+
+}
Index: branches/heathaze/src/lib/gui/qt/gui_audio.h
===================================================================
--- branches/heathaze/src/lib/gui/qt/gui_audio.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/gui_audio.h	(revision 9940)
@@ -0,0 +1,25 @@
+/*!
+  \file gui_audio.h
+  \brief File that holds the class that creates the Audio-Options.
+*/
+#ifndef _GUI_AUDIO_H
+#define _GUI_AUDIO_H
+
+#include "../gui_element.h"
+#include <vector>
+#include <string>
+#include <QtGui/QGroupBox>
+
+namespace OrxGui
+{
+  //! Class that creates the Audio-Options.
+  class GuiAudio : public OrxGui::Element, public QGroupBox
+  {
+  public:
+    GuiAudio(OrxGui::Gui* gui);
+    virtual ~GuiAudio();
+
+  };
+}
+
+#endif /* _GUI_AUDIO_H */
Index: branches/heathaze/src/lib/gui/qt/gui_control.cc
===================================================================
--- branches/heathaze/src/lib/gui/qt/gui_control.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/gui_control.cc	(revision 9940)
@@ -0,0 +1,303 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+
+#include "gui_control.h"
+
+#include <QtGui/QLayout>
+#include <QtCore/QEvent>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMouseEvent>
+
+#include "sdlincl.h"
+#include "lib/event/key_names.h"
+
+#include "globals.h"
+#include "debug.h"
+#include "qt_gui_elements.h"
+
+#include "lib/event/key_mapper.h"
+#include "lib/event/key_names.h"
+
+namespace OrxGui
+{
+  /**
+   *  Creates the Control-Option-Frame
+  */
+  GuiControl::GuiControl(OrxGui::Gui* gui)
+      : Element(CONFIG_SECTION_CONTROL, gui), QGroupBox()
+  {
+    QGridLayout* layout = new QGridLayout(this);
+
+    {
+      //QLabel* keyLabel = new QLabel;
+
+      const KeyMapper::KeyMapping* map = KeyMapper::getKeyMapping();
+      unsigned int i = 0;
+      while(!map->pName.empty())
+      {
+        QLabel* label = new QLabel(QString().fromStdString(map->pName));
+        layout->addWidget(label, i, 0);
+
+        GuiControlInput* input = new GuiControlInput(map->pName, this, EVToKeyName(map->defaultValue));
+        layout->addWidget(input, i, 1);
+
+        ++map;
+        ++i;
+      }
+    }
+
+
+  }
+
+  /**
+   *  Destructs the Control-stuff
+  */
+  GuiControl::~GuiControl()
+  {
+    // nothing to do here.
+  }
+
+  GuiControlInput::GuiControlInput(const std::string& name, SaveableGroup* group, const std::string& defaultValue)
+      : QPushButton(QString().fromStdString(name)), Saveable(name, group, defaultValue)
+  {
+    this->bListening = false;
+
+    connect(this, SIGNAL(released()), this, SLOT(listen()));
+
+  }
+
+  void GuiControlInput::load()
+  {
+    Saveable::load();
+    this->setText(QString().fromStdString(this->value().getString()));
+  }
+
+  void GuiControlInput::save()
+  {
+    this->value() = this->text().toStdString();
+    Saveable::save();
+  }
+
+
+  bool GuiControlInput::event ( QEvent * e )
+  {
+    if (this->bListening && (e->type() == QEvent::KeyPress || e->type() == QEvent::MouseButtonPress))
+    {
+      this->bListening = false;
+      this->releaseKeyboard();
+      this->releaseMouse();
+      /// KEY IS PRESSED:
+      if (e->type() == QEvent::KeyPress)
+      {
+        QKeyEvent* event = dynamic_cast<QKeyEvent*>(e);
+
+        int ev = QtKToSDLK(event->key());
+        if (ev != -1)
+        {
+          this->setText(QString().fromStdString(SDLKToKeyname(ev)));
+        }
+        return true;
+      }
+      /// MOUSE BUTTON PRESSED:
+      if (e->type() == QEvent::MouseButtonPress)
+      {
+        QMouseEvent* event = dynamic_cast<QMouseEvent*>(e);
+        if (event->button() != Qt::NoButton)
+        {
+          this->setText(QString().fromStdString(QtKToString(event->button())));
+        }
+
+      }
+
+    }
+
+    return QPushButton::event(e);
+  }
+
+  void GuiControlInput::listen()
+  {
+    this->bListening = true;
+    this->grabKeyboard();
+    this->grabMouse();
+  }
+
+  int GuiControlInput::QtKToSDLK(int key)
+  {
+
+    switch(key)
+    {
+      case Qt::Key_Backspace: return SDLK_BACKSPACE;
+      case Qt::Key_Tab: return SDLK_TAB;
+      case Qt::Key_Clear: return SDLK_CLEAR;
+      case Qt::Key_Return: return SDLK_RETURN;
+      case Qt::Key_Escape: return SDLK_ESCAPE;
+      case Qt::Key_Space: return SDLK_SPACE;
+      case Qt::Key_exclamdown: return SDLK_EXCLAIM;
+      case Qt::Key_QuoteDbl: return SDLK_QUOTEDBL;
+        //case Qt::Key_Hash: return SDLK_HASH;
+      case Qt::Key_Pause: return SDLK_PAUSE;
+      case Qt::Key_Dollar: return SDLK_DOLLAR;
+      case Qt::Key_Ampersand: return SDLK_AMPERSAND;
+      case Qt::Key_QuoteLeft: return SDLK_QUOTE; /// TODO check if correct
+      case Qt::Key_ParenLeft: return SDLK_LEFTPAREN;
+      case Qt::Key_ParenRight: return SDLK_RIGHTPAREN;
+      case Qt::Key_Asterisk: return SDLK_ASTERISK;
+      case Qt::Key_Plus: return SDLK_PLUS;
+      case Qt::Key_Comma: return SDLK_COMMA;
+      case Qt::Key_Minus: return SDLK_MINUS;
+      case Qt::Key_Period: return SDLK_PERIOD;
+      case Qt::Key_Slash: return SDLK_SLASH;
+      case Qt::Key_0: return SDLK_0;
+      case Qt::Key_1: return SDLK_1;
+      case Qt::Key_2: return SDLK_2;
+      case Qt::Key_3: return SDLK_3;
+      case Qt::Key_4: return SDLK_4;
+      case Qt::Key_5: return SDLK_5;
+      case Qt::Key_6: return SDLK_6;
+      case Qt::Key_7: return SDLK_7;
+      case Qt::Key_8: return SDLK_8;
+      case Qt::Key_9: return SDLK_9;
+      case Qt::Key_Colon: return SDLK_COLON;
+      case Qt::Key_Semicolon: return SDLK_SEMICOLON;
+      case Qt::Key_Less: return SDLK_LESS;
+      case Qt::Key_Equal: return SDLK_EQUALS;
+      case Qt::Key_Greater: return SDLK_GREATER;
+      case Qt::Key_Question: return SDLK_QUESTION;
+      case Qt::Key_At: return SDLK_AT;
+      case Qt::Key_BracketLeft: return SDLK_LEFTBRACKET;
+      case Qt::Key_Backslash: return SDLK_BACKSLASH;
+      case Qt::Key_BracketRight: return SDLK_RIGHTBRACKET;
+        ///case Qt::Key_Caret: return SDLK_CARET;
+      case Qt::Key_Underscore: return SDLK_UNDERSCORE;
+        //case Qt::Key_Backquote: return SDLK_BACKQUOTE;
+      case Qt::Key_A: return SDLK_a;
+      case Qt::Key_B: return SDLK_b;
+      case Qt::Key_C: return SDLK_c;
+      case Qt::Key_D: return SDLK_d;
+      case Qt::Key_E: return SDLK_e;
+      case Qt::Key_F: return SDLK_f;
+      case Qt::Key_G: return SDLK_g;
+      case Qt::Key_H: return SDLK_h;
+      case Qt::Key_I: return SDLK_i;
+      case Qt::Key_J: return SDLK_j;
+      case Qt::Key_K: return SDLK_k;
+      case Qt::Key_L: return SDLK_l;
+      case Qt::Key_M: return SDLK_m;
+      case Qt::Key_N: return SDLK_n;
+      case Qt::Key_O: return SDLK_o;
+      case Qt::Key_P: return SDLK_p;
+      case Qt::Key_Q: return SDLK_q;
+      case Qt::Key_R: return SDLK_r;
+      case Qt::Key_S: return SDLK_s;
+      case Qt::Key_T: return SDLK_t;
+      case Qt::Key_U: return SDLK_u;
+      case Qt::Key_V: return SDLK_v;
+      case Qt::Key_W: return SDLK_w;
+      case Qt::Key_X: return SDLK_x;
+      case Qt::Key_Y: return SDLK_y;
+      case Qt::Key_Z: return SDLK_z;
+      case Qt::Key_Delete: return SDLK_DELETE;
+        /*      case Qt::Key_KP0: return SDLK_KP0;
+        case Qt::Key_KP1: return SDLK_KP1;
+        case Qt::Key_KP2: return SDLK_KP2;
+        case Qt::Key_KP3: return SDLK_KP3;
+        case Qt::Key_KP4: return SDLK_KP4;
+        case Qt::Key_KP5: return SDLK_KP5;
+        case Qt::Key_KP6: return SDLK_KP6;
+        case Qt::Key_KP7: return SDLK_KP7;
+        case Qt::Key_KP8: return SDLK_KP8;
+        case Qt::Key_KP9: return SDLK_KP9; */
+        /*      case Qt::Key_KP_Period: return SDLK_KP_PERIOD;
+              case Qt::Key_KP_Divide: return SDLK_KP_DIVIDE;
+              case Qt::Key_KP_Multiply: return SDLK_KP_MULTIPLY;
+              case Qt::Key_KP_Minus: return SDLK_KP_MINUS;
+              case Qt::Key_KP_PLUS: return SDLK_KP_PLUS;
+              case Qt::Key_KP_ENTER: return SDLK_KP_ENTER;
+              case Qt::Key_KP_EQUALS: return SDLK_KP_EQUALS;*/
+      case Qt::Key_Up: return SDLK_UP;
+      case Qt::Key_Down: return SDLK_DOWN;
+      case Qt::Key_Right: return SDLK_RIGHT;
+      case Qt::Key_Left: return SDLK_LEFT;
+      case Qt::Key_Insert: return SDLK_INSERT;
+      case Qt::Key_Home: return SDLK_HOME;
+      case Qt::Key_End: return SDLK_END;
+      case Qt::Key_PageUp: return SDLK_PAGEUP;
+      case Qt::Key_PageDown: return SDLK_PAGEDOWN;
+      case Qt::Key_F1: return SDLK_F1;
+      case Qt::Key_F2: return SDLK_F2;
+      case Qt::Key_F3: return SDLK_F3;
+      case Qt::Key_F4: return SDLK_F4;
+      case Qt::Key_F5: return SDLK_F5;
+      case Qt::Key_F6: return SDLK_F6;
+      case Qt::Key_F7: return SDLK_F7;
+      case Qt::Key_F8: return SDLK_F8;
+      case Qt::Key_F9: return SDLK_F9;
+      case Qt::Key_F10: return SDLK_F10;
+      case Qt::Key_F11: return SDLK_F11;
+      case Qt::Key_F12: return SDLK_F12;
+      case Qt::Key_F13: return SDLK_F13;
+      case Qt::Key_F14: return SDLK_F14;
+      case Qt::Key_F15: return SDLK_F15;
+      case Qt::Key_NumLock: return SDLK_NUMLOCK;
+      case Qt::Key_CapsLock: return SDLK_CAPSLOCK;
+      case Qt::Key_ScrollLock: return SDLK_SCROLLOCK;
+        ///case Qt::Key_RSHIFT: return SDLK_RSHIFT;
+      case Qt::Key_Shift: return SDLK_LSHIFT;
+        ///case Qt::Key_RCTRL: return SDLK_RCTRL;
+      case Qt::Key_Control: return SDLK_LCTRL;
+        ///case Qt::Key_RALT: return SDLK_RALT;
+      case Qt::Key_Alt: return SDLK_LALT;
+        //case Qt::Key_RMETA: return SDLK_RMETA;
+      case Qt::Key_Meta: return SDLK_LMETA;
+      case Qt::Key_Super_L: return SDLK_LSUPER;
+      case Qt::Key_Super_R: return SDLK_RSUPER;
+      case Qt::Key_Mode_switch: return SDLK_MODE;
+      case Qt::Key_Help: return SDLK_HELP;
+      case Qt::Key_Print: return SDLK_PRINT;
+      case Qt::Key_SysReq: return SDLK_SYSREQ;
+        ///case Qt::Key_Break: return SDLK_BREAK;
+        ///case Qt::Key_Menu: return SDLK_MENU;
+        ///case Qt::Key_Power: return SDLK_POWER;
+        ///case Qt::Key_Euro: return SDLK_EURO;
+      default:
+        return -1;
+    }
+
+    return 0;
+
+  }
+
+  std::string GuiControlInput::QtKToString(int button)
+  {
+    if( button == Qt::LeftButton) return "BUTTON_LEFT";
+    if( button == Qt::MidButton) return "BUTTON_MIDDLE";
+    if( button == Qt::RightButton) return "BUTTON_RIGHT";
+    //if( button == Qt::) return "BUTTON_WHEELUP";
+    //if( button == EV_MOUSE_BUTTON_WHEELDOWN) return "BUTTON_WHEELDOWN";
+    return "UNKNOWN";
+  }
+
+}
Index: branches/heathaze/src/lib/gui/qt/gui_control.h
===================================================================
--- branches/heathaze/src/lib/gui/qt/gui_control.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/gui_control.h	(revision 9940)
@@ -0,0 +1,55 @@
+/*!
+  \file gui_control.h
+  \brief File that holds the class that creates the Control-Options.
+*/
+#ifndef _GUI_CONTROL_H
+#define _GUI_CONTROL_H
+
+#include "../gui_element.h"
+#include <vector>
+#include <string>
+#include <QtGui/QGroupBox>
+#include <QtGui/QPushButton>
+#include "../gui_saveable.h"
+
+namespace OrxGui
+{
+  //! Class that creates the Control-Options.
+  class GuiControl : public OrxGui::Element, public QGroupBox
+  {
+  public:
+    GuiControl(OrxGui::Gui* gui);
+    virtual ~GuiControl();
+
+  private:
+  };
+
+  class GuiControlInput : public QPushButton, public OrxGui::Saveable
+  {
+    Q_OBJECT
+  public:
+    GuiControlInput(const std::string& name, SaveableGroup* group, const std::string& defaultValue);
+
+    virtual void load();
+    virtual void save();
+
+
+    virtual bool event(QEvent* e);
+
+    static int QtKToSDLK(int key);
+    static std::string QtKToString(int button);
+
+    public slots:
+    void listen();
+  signals:
+    //    void optionChanged();
+
+    private:
+      bool bListening;
+  };
+
+
+
+}
+
+#endif /* _GUI_CONTROL_H */
Index: branches/heathaze/src/lib/gui/qt/gui_general.cc
===================================================================
--- branches/heathaze/src/lib/gui/qt/gui_general.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/gui_general.cc	(revision 9940)
@@ -0,0 +1,106 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+
+#include "gui_general.h"
+
+#include <QtGui/QLayout>
+#include <QtGui/QFileDialog>
+
+#include "debug.h"
+#include "globals.h"
+
+#include "qt_gui_elements.h"
+
+namespace OrxGui
+{
+  /**
+   *  Creates the General-Option-Frame
+  */
+  GuiGeneral::GuiGeneral(OrxGui::Gui* gui)
+  : QGroupBox(), Element(CONFIG_SECTION_GENERAL, gui)
+  {
+    QGridLayout* layout = new QGridLayout(this);
+    {
+      QLabel* dataDirLabel = new QLabel("DataDirectory");
+      layout->addWidget(dataDirLabel, 0,0);
+      this->dataDir = new QtGuiInputLine(CONFIG_NAME_DATADIR, this, DEFAULT_DATA_DIR);
+      layout->addWidget(dataDir, 0, 1, 1, 2);
+      QPushButton* dataFileDialogButton = new QPushButton("browse");
+      layout->addWidget(dataFileDialogButton, 0, 3, 1, 1);
+      connect(dataFileDialogButton, SIGNAL(released()), this, SLOT(openDataFileDialog()));
+
+
+      QLabel* debugLabel = new QLabel("debug-mode");
+      layout->addWidget(debugLabel, 1,0);
+      QtGuiComboBox* debug = new QtGuiComboBox(CONFIG_NAME_DEBUG_LEVEL, this, "3 - information");
+      layout->addWidget(debug, 1, 1, 1, 2);
+
+      debug->addItem("0 - minimal");
+#if DEBUG_LEVEL >=1
+      debug->addItem("1 - errors");
+#endif
+#if DEBUG_LEVEL >=2
+      debug->addItem("2 - warnings");
+#endif
+#if DEBUG_LEVEL >=3
+      debug->addItem("3 - information");
+#endif
+#if DEBUG_LEVEL >=4
+      debug->addItem("4 - debug");
+#endif
+#if DEBUG_LEVEL >=5
+      debug->addItem("5 - extremely debug");
+#endif
+    }
+  }
+
+  /**
+   *  Destructs the General-stuff
+  */
+  GuiGeneral::~GuiGeneral()
+  {
+    // nothing to do here.
+  }
+
+  void GuiGeneral::openDataFileDialog()
+  {
+    QString browsePath = this->dataDir->text();
+    if (browsePath.isEmpty())
+      browsePath = ".";
+
+    QString s = QFileDialog::getOpenFileName(
+                  this,
+                  "Choose the ORXONOX DATA DIRECTORY",
+                  browsePath,
+                  "ORXONOX DATA INDEX (" DEFAULT_DATA_DIR_CHECKFILE ")" );
+
+    s.remove("data.oxd");
+    if (!s.isNull())
+      this->dataDir->setText(s);
+  }
+
+
+}
Index: branches/heathaze/src/lib/gui/qt/gui_general.h
===================================================================
--- branches/heathaze/src/lib/gui/qt/gui_general.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/gui_general.h	(revision 9940)
@@ -0,0 +1,35 @@
+/*!
+  \file gui_general.h
+  \brief File that holds the class that creates the General-Options.
+*/
+#ifndef _GUI_GENERAL_H
+#define _GUI_GENERAL_H
+
+#include "../gui_element.h"
+#include <vector>
+#include <string>
+#include <QtGui/QGroupBox>
+
+
+namespace OrxGui
+{
+  class QtGuiInputLine;
+
+  //! Class that creates the Audio-Options.
+  class GuiGeneral : public QGroupBox, public OrxGui::Element
+  {
+    Q_OBJECT
+
+  public:
+    GuiGeneral(OrxGui::Gui* gui);
+    virtual ~GuiGeneral();
+
+  public slots:
+    void openDataFileDialog();
+
+  private:
+    QtGuiInputLine* dataDir;
+  };
+}
+
+#endif /* _GUI_GENERAL_H */
Index: branches/heathaze/src/lib/gui/qt/gui_video.cc
===================================================================
--- branches/heathaze/src/lib/gui/qt/gui_video.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/gui_video.cc	(revision 9940)
@@ -0,0 +1,167 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+
+#include "gui_video.h"
+
+#include <QtGui/QLayout>
+#include "globals.h"
+#include "debug.h"
+
+#include "sdlincl.h"
+
+#include "qt_gui_elements.h"
+
+namespace OrxGui
+{
+  /**
+   *  Creates the Video-Option-Frame
+  */
+  GuiVideo::GuiVideo(OrxGui::Gui* gui)
+  : Element(CONFIG_SECTION_VIDEO, gui), QGroupBox()
+  {
+    QGridLayout* layout = new QGridLayout(this);
+
+    {
+      QtGuiCheckBox* fullscreen = new QtGuiCheckBox(CONFIG_NAME_FULLSCREEN, this, false);
+      //fullscreen->setName();
+      layout->addWidget(fullscreen, 0, 0);
+
+      QtGuiCheckBox* dedicated = new QtGuiCheckBox(CONFIG_NAME_NO_RENDER, this, false);
+      //fullscreen->setName();
+      layout->addWidget(dedicated, 1, 0);
+
+      QtGuiCheckBox* wireframe = new QtGuiCheckBox(CONFIG_NAME_WIREFRAME, this, false);
+      layout->addWidget(wireframe, 2, 0);
+
+      {
+        QComboBox* resolution = new QtGuiComboBox(CONFIG_NAME_RESOLUTION, this, "640x480");
+        resolution->setEditable(true);
+        layout->addWidget(resolution, 3, 0);
+        std::vector<QString> resolutions;
+        this->getResolutions(resolutions);
+        for (unsigned int i = 0; i < resolutions.size(); ++i)
+          resolution->addItem(resolutions[i]);
+      }
+
+
+      QGroupBox* advanced = new GuiAdvancedVideo(gui);
+
+
+      layout->addWidget(advanced, 0, 2, 4, 1);
+
+    }
+  }
+
+  /**
+   *  Destructs the Video-stuff
+  */
+  GuiVideo::~GuiVideo()
+  {
+    // nothing to do here.
+  }
+
+  /**
+   *  sets all resolutions to the menu
+   * @param menu the Menu to set The resolutions to.
+  */
+  void GuiVideo::getResolutions(std::vector<QString>& resolutionList)
+  {
+    SDL_Init(SDL_INIT_VIDEO);
+    SDL_Rect **modes;
+    int i;
+    int x = 0,y =0; // check for difference
+    char tmpChar[100];
+
+    /* Get available fullscreen/hardware modes */
+    modes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
+
+    /* Check is there are any modes available */
+    if(modes == (SDL_Rect **)0)
+    {
+      PRINTF(2)("No video-modes available!\n");
+      exit(-1);
+    }
+
+    /* Check if our resolution is restricted */
+    if(modes == (SDL_Rect **)-1)
+    {
+      PRINTF(2)("All resolutions available.\n");
+    }
+    else
+    {
+      /* Print valid modes */
+      PRINT(5)("Available Modes\n");
+      for(i = 0; modes[i] ;++i)
+      {
+        if (x != modes[i]->w || y != modes[i]->h)
+        {
+          PRINTF(5)("  %d x %d\n", modes[i]->w, modes[i]->h);
+          sprintf(tmpChar, "%dx%d", modes[i]->w, modes[i]->h);
+          resolutionList.push_back(QString(tmpChar));
+          x = modes[i]->w; y = modes[i]->h;
+        }
+      }
+    }
+    SDL_QuitSubSystem(SDL_INIT_VIDEO);
+    SDL_Quit();
+  }
+
+
+
+  GuiAdvancedVideo::GuiAdvancedVideo(OrxGui::Gui* gui)
+  : Element(CONFIG_SECTION_VIDEO_ADVANCED ,gui)
+  {
+    {
+      QGridLayout* advLayout = new QGridLayout(this);              //!< Advanced Layout
+      {
+        QtGuiCheckBox* shadows = new QtGuiCheckBox(CONFIG_NAME_SHADOWS, this, true);         //!< CheckBox for shadows
+        advLayout->addWidget(shadows, 0,0);
+        QtGuiCheckBox* fog = new QtGuiCheckBox(CONFIG_NAME_FOG, this, true);                 //!< CheckBox for fog.
+        advLayout->addWidget(fog, 1,0);
+        QtGuiCheckBox* reflections = new QtGuiCheckBox(CONFIG_NAME_REFLECTIONS, this, true);  //!< CheckBox for reflections
+        advLayout->addWidget(reflections, 2, 0);
+        QtGuiCheckBox* textures = new QtGuiCheckBox(CONFIG_NAME_TEXTURES, this, true);       //!< CheckBox for textures
+        advLayout->addWidget(textures, 3, 0);
+          /*
+        Menu* textureDetail;      //!< Menu for the Texture-Detail.
+        Label* modelDetailLabel;  //!< Label for model-detail.
+        Menu* modelDetail;        //!< model-detail.
+        CheckBox* particles;   //!< If the Particles should be enabled
+        Label* antiAliasingLabel; //!< Label for the anti-aliasing mode.
+        Menu* antiAliasing;       //!< Menu for the Antialiasing-mode.
+        Label* filterMethodLabel; //!< Label for filtering-Method.
+        Menu* filterMethod;       //!< Menu for filtering Method.
+        Button* closeButton;      //!< A Button to close the Advanced-settingsWindow.
+          */
+      }
+    }
+  }
+
+  GuiAdvancedVideo::~GuiAdvancedVideo()
+  {
+  }
+
+}
Index: branches/heathaze/src/lib/gui/qt/gui_video.h
===================================================================
--- branches/heathaze/src/lib/gui/qt/gui_video.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/gui_video.h	(revision 9940)
@@ -0,0 +1,34 @@
+/*!
+  \file gui_video.h
+  \brief File that holds the class that creates the Video-Options.
+*/
+#ifndef _GUI_VIDEO_H
+#define _GUI_VIDEO_H
+
+#include "../gui_element.h"
+#include <vector>
+#include <string>
+#include <QtGui/QGroupBox>
+
+namespace OrxGui
+{
+  //! Class that creates the Video-Options.
+  class GuiVideo : public OrxGui::Element, public QGroupBox
+  {
+  public:
+    GuiVideo(OrxGui::Gui* gui);
+    virtual ~GuiVideo();
+
+  private:
+    void getResolutions(std::vector<QString>& resolutionList);
+  };
+
+  class GuiAdvancedVideo : public OrxGui::Element, public QGroupBox
+  {
+    public:
+      GuiAdvancedVideo(OrxGui::Gui* gui);
+      virtual ~GuiAdvancedVideo();
+  };
+}
+
+#endif /* _GUI_VIDEO_H */
Index: branches/heathaze/src/lib/gui/qt/q_image_widget.cc
===================================================================
--- branches/heathaze/src/lib/gui/qt/q_image_widget.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/q_image_widget.cc	(revision 9940)
@@ -0,0 +1,67 @@
+/***************************************************************************
+                          QImageWidget.cpp  -  description
+                             -------------------
+    begin                : Fri Nov 17 2000
+    copyright            : (C) 2000 by Rainer Lehrig
+    email                : lehrig@t-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+#include "q_image_widget.h"
+#include <QtGui/QPainter>
+#include <QtGui/QPaintEvent>
+
+QImageWidget::QImageWidget( QWidget *parent)
+             : QWidget( parent)
+{
+  image = QImage(); // construct a null image
+  x = y = w = h = 0;
+}
+
+QImageWidget::~QImageWidget()
+{
+}
+
+void QImageWidget::setImage(const QImage& newimage)
+{
+  this->image = newimage.copy();
+  w = this->image.width();
+  h = this->image.height();
+  this->setMinimumSize(w, h);
+}
+
+void QImageWidget::paintEvent( QPaintEvent *e )
+{
+  if( !image.isNull() )
+  {
+    QPainter p;
+    p.begin(this);
+    p.setClipRect(e->rect());
+    p.drawLine(0,0,100,100);
+    p.drawImage(QPoint(0,0), this->image);
+    p.end();
+    /*
+    QPainter painter(this);
+    painter.setClipRect(e->rect());
+    painter.drawImage(QPoint(0,0), image);
+    */
+  }
+}
+
+void QImageWidget::setGeometry(int nx, int ny, int nw, int nh)
+{
+  x = nx;
+  y = ny;
+  w = nw;
+  h = nh;
+  move(x,y);
+  resize(w,h);
+  repaint(0,0,w,h);
+}
Index: branches/heathaze/src/lib/gui/qt/q_image_widget.h
===================================================================
--- branches/heathaze/src/lib/gui/qt/q_image_widget.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/q_image_widget.h	(revision 9940)
@@ -0,0 +1,42 @@
+/***************************************************************************
+                          QImageWidget.h  -  description
+                             -------------------
+    begin                : Fri Nov 17 2000
+    copyright            : (C) 2000 by Rainer Lehrig
+    email                : lehrig@t-online.de
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+#ifndef _QIMAGE_WIDGET_H_
+#define _QIMAGE_WIDGET_H_
+
+#include <QtGui/QWidget>
+#include <QtGui/QImage>
+
+class QImageWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    QImageWidget(QWidget *parent=0);
+    ~QImageWidget();
+    virtual void         setGeometry(int nx, int ny, int nw, int nh);
+    void	          setImage(const QImage& newimage);
+
+protected:
+    virtual void paintEvent( QPaintEvent * );
+
+private:
+    int		  conversion_flags;
+    int           x,y,w,h;
+    QImage	  image;			// the loaded image
+};
+
+
+#endif
Index: branches/heathaze/src/lib/gui/qt/qt_gui.cc
===================================================================
--- branches/heathaze/src/lib/gui/qt/qt_gui.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/qt_gui.cc	(revision 9940)
@@ -0,0 +1,117 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "qt_gui.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QToolBox>
+#include <QtGui/QGridLayout>
+
+#include "qt_gui_elements.h"
+#include "q_image_widget.h"
+
+#include "gui_general.h"
+#include "gui_video.h"
+#include "gui_audio.h"
+#include "gui_control.h"
+
+#include "banner.xpm"
+
+namespace OrxGui
+{
+  QtGui::QtGui(int argc, char** argv)
+  : QApplication(argc, argv)
+  {
+
+    this->mainWindow = new QMainWindow();
+    this->mainWindow->setMinimumSize(500, 200);
+
+    QGroupBox* groupBox = new QGroupBox(this->mainWindow);
+    QGridLayout* mainLayout = new QGridLayout(groupBox);
+    {
+      QImageWidget* bannerWidget = new QImageWidget();
+      QImage bannerImage(banner_xpm);
+      bannerImage.save("test.bmp", "bmp");
+      bannerWidget->setImage(bannerImage);
+      mainLayout->addWidget(bannerWidget, 0,0, 3, 1);
+
+
+      QToolBox* toolBox = new QToolBox(groupBox);
+      {
+        toolBox->addItem(new GuiGeneral(this), "General");
+        toolBox->addItem(new GuiVideo(this), "Video");
+        toolBox->addItem(new GuiAudio(this), "Audio");
+        toolBox->addItem(new GuiControl(this), "Control");
+      }
+      mainLayout->addWidget(toolBox,1,1, 1, 3);
+
+
+      QPushButton* start = new QPushButton("start");
+      connect(start, SIGNAL(released()), this, SLOT(startApp()));
+      mainLayout->addWidget(start, 2,2);
+
+      QPushButton* quit = new QPushButton("quit");
+      connect(quit, SIGNAL(released()), this, SLOT(quitApp()));
+      mainLayout->addWidget(quit, 2,3);
+
+    }
+
+    connect(this->mainWindow, SIGNAL(destroyed()), this, SLOT(quitApp()));
+    this->mainWindow->setCentralWidget(groupBox);
+    this->mainWindow->show();
+
+    this->loadAll();
+    this->exec();
+    this->saveAll();
+
+  }
+
+  QtGui::~QtGui()
+  {
+    delete this->mainWindow;
+  }
+
+  void QtGui::startGui()
+  {
+  }
+
+  void QtGui::stopGui()
+  {}
+
+  void QtGui::suspend()
+  {}
+
+    //! Update the Gui.
+  void QtGui::update()
+  {
+    this->processEvents();
+  }
+
+
+  void QtGui::quitApp()
+  {
+    Gui::quitEvent();
+    this->quit();
+  }
+
+  void QtGui::startApp()
+  {
+    Gui::startEvent();
+    this->quit();
+  }
+
+}
Index: branches/heathaze/src/lib/gui/qt/qt_gui.h
===================================================================
--- branches/heathaze/src/lib/gui/qt/qt_gui.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/qt_gui.h	(revision 9940)
@@ -0,0 +1,42 @@
+/*!
+ * @file qt_gui.h
+ * @brief Definition of ...
+*/
+
+#ifndef __QT_GUI_H
+#define __QT_GUI_H
+
+#include "../gui.h"
+#include "../gui_element.h"
+#include <QtGui/QApplication>
+#include <QtGui/QMainWindow>
+
+namespace OrxGui
+{
+  class QtGui : public QApplication, public OrxGui::Gui
+  {
+    Q_OBJECT
+    public:
+      QtGui(int argc, char** argv);
+      virtual ~QtGui();
+
+    //! Start the Gui
+      virtual void startGui();
+    //! Stop the gui
+      virtual void stopGui();
+    //! Suspend the Gui.
+      virtual void suspend();
+    //! Update the Gui.
+      virtual void update();
+
+    public slots:
+      void quitApp();
+      void startApp();
+
+    private:
+      QMainWindow*              mainWindow;
+      std::list<Element*>       elements;       //!< A List of Elements within the QTGui
+  };
+}
+
+#endif /* __QT_GUI_H */
Index: branches/heathaze/src/lib/gui/qt/qt_gui_datadir_fallback.cc
===================================================================
--- branches/heathaze/src/lib/gui/qt/qt_gui_datadir_fallback.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/qt_gui_datadir_fallback.cc	(revision 9940)
@@ -0,0 +1,113 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "qt_gui_datadir_fallback.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QToolBox>
+#include <QtGui/QGridLayout>
+
+#include "qt_gui_elements.h"
+#include "q_image_widget.h"
+
+#include "gui_general.h"
+#include "gui_video.h"
+#include "gui_audio.h"
+#include "gui_control.h"
+
+#include "banner.xpm"
+
+namespace OrxGui
+{
+  QtGuiDataDirFallback::QtGuiDataDirFallback(int argc, char** argv)
+  : QApplication(argc, argv)
+  {
+
+    this->mainWindow = new QMainWindow();
+    this->mainWindow->setMinimumSize(500, 200);
+
+    QGroupBox* groupBox = new QGroupBox(this->mainWindow);
+    QGridLayout* mainLayout = new QGridLayout(groupBox);
+    {
+      QImageWidget* bannerWidget = new QImageWidget();
+      QImage bannerImage(banner_xpm);
+      bannerImage.save("test.bmp", "bmp");
+      bannerWidget->setImage(bannerImage);
+      mainLayout->addWidget(bannerWidget, 0,0, 3, 1);
+
+      QLabel* label = new QLabel();
+      label->setText("ORXONOX needs its DataDirectory to be configured.\n Just Select the ORXONOX-dataDirectory with the browse-button, and start the Game\n");
+
+      mainLayout->addWidget(label, 0,1);
+
+      mainLayout->addWidget(new GuiGeneral(this), 1, 1, 1, 3);
+
+      QPushButton* start = new QPushButton("start");
+      connect(start, SIGNAL(released()), this, SLOT(startApp()));
+      mainLayout->addWidget(start, 2,2);
+
+      QPushButton* quit = new QPushButton("quit");
+      connect(quit, SIGNAL(released()), this, SLOT(quitApp()));
+      mainLayout->addWidget(quit, 2,3);
+
+    }
+
+    connect(this->mainWindow, SIGNAL(destroyed()), this, SLOT(quitApp()));
+    this->mainWindow->setCentralWidget(groupBox);
+    this->mainWindow->show();
+
+    this->loadAll();
+    this->exec();
+    this->saveAll();
+
+  }
+
+  QtGuiDataDirFallback::~QtGuiDataDirFallback()
+  {
+    delete this->mainWindow;
+  }
+
+  void QtGuiDataDirFallback::startGui()
+  {
+  }
+
+  void QtGuiDataDirFallback::stopGui()
+  {}
+
+  void QtGuiDataDirFallback::suspend()
+  {}
+
+    //! Update the Gui.
+  void QtGuiDataDirFallback::update()
+  {
+    this->processEvents();
+  }
+
+
+  void QtGuiDataDirFallback::quitApp()
+  {
+    Gui::quitEvent();
+    this->quit();
+  }
+
+  void QtGuiDataDirFallback::startApp()
+  {
+    Gui::startEvent();
+    this->quit();
+  }
+
+}
Index: branches/heathaze/src/lib/gui/qt/qt_gui_datadir_fallback.h
===================================================================
--- branches/heathaze/src/lib/gui/qt/qt_gui_datadir_fallback.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/qt_gui_datadir_fallback.h	(revision 9940)
@@ -0,0 +1,42 @@
+/*!
+ * @file qt_gui_datadir_fallback.h
+ * @brief Definition of ...
+*/
+
+#ifndef __QT_GUI_DATADIR_FALLBACK_H
+#define __QT_GUI_DATADIR_FALLBACK_H
+
+#include "../gui.h"
+#include "../gui_element.h"
+#include <QtGui/QApplication>
+#include <QtGui/QMainWindow>
+
+namespace OrxGui
+{
+  class QtGuiDataDirFallback : public QApplication, public OrxGui::Gui
+  {
+    Q_OBJECT
+    public:
+      QtGuiDataDirFallback(int argc, char** argv);
+      virtual ~QtGuiDataDirFallback();
+
+    //! Start the Gui
+      virtual void startGui();
+    //! Stop the gui
+      virtual void stopGui();
+    //! Suspend the Gui.
+      virtual void suspend();
+    //! Update the Gui.
+      virtual void update();
+
+    public slots:
+      void quitApp();
+      void startApp();
+
+    private:
+      QMainWindow*              mainWindow;
+      std::list<Element*>       elements;       //!< A List of Elements within the QTGui
+  };
+}
+
+#endif /* __QT_GUI_DATADIR_FALLBACK_H */
Index: branches/heathaze/src/lib/gui/qt/qt_gui_elements.cc
===================================================================
--- branches/heathaze/src/lib/gui/qt/qt_gui_elements.cc	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/qt_gui_elements.cc	(revision 9940)
@@ -0,0 +1,127 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "qt_gui_elements.h"
+
+namespace OrxGui
+{
+
+
+
+  QtGuiCheckBox::QtGuiCheckBox(const std::string& name, SaveableGroup* group, bool defaultValue)
+  : QCheckBox(QString().fromStdString(name)), Saveable(name, group, defaultValue)
+  {
+    //this->load(this->value());
+  }
+
+  void QtGuiCheckBox::load()
+  {
+    Saveable::load();
+    if (this->value().getBool())
+      this->setCheckState(Qt::Checked);
+    else
+      this->setCheckState(Qt::Unchecked);
+  }
+
+
+
+  void QtGuiCheckBox::save()
+  {
+    this->value() = this->checkState();
+    Saveable::save();
+  }
+
+
+
+
+
+  QtGuiSlider::QtGuiSlider(const std::string& name, SaveableGroup* group, int defaultValue, Qt::Orientation orientation)
+  : QSlider(orientation), Saveable(name, group, defaultValue)
+  {
+
+  }
+
+  QtGuiSlider::~QtGuiSlider()
+  {}
+
+  void QtGuiSlider::load()
+  {
+    Saveable::load();
+    this->setValue(this->Saveable::value().getInt());
+  }
+
+  void QtGuiSlider::save()
+  {
+    this->Saveable::value() = this->QSlider::value();
+    Saveable::save();
+  }
+
+
+
+
+
+
+
+  QtGuiComboBox::QtGuiComboBox(const std::string& name, SaveableGroup* group, const std::string& defaultValue)
+  : QComboBox(), Saveable(name, group, defaultValue)
+  {
+
+
+  }
+
+  void QtGuiComboBox::load()
+  {
+    Saveable::load();
+    int index = this->findText(QString().fromStdString(this->value().getString()));
+    if (index == -1)
+      index = 1;
+    this->setCurrentIndex(index);
+  }
+
+  void QtGuiComboBox::save()
+  {
+    this->value() = this->currentText().toStdString();
+    Saveable::save();
+  }
+
+
+  QtGuiInputLine::QtGuiInputLine(const std::string& name, SaveableGroup* group, const std::string& defaultValue)
+  : QLineEdit(), Saveable(name, group, defaultValue)
+  {
+
+
+  }
+
+
+  void QtGuiInputLine::load()
+  {
+    Saveable::load();
+    this->setText(QString().fromStdString(this->value().getString()));
+  }
+
+
+
+  void QtGuiInputLine::save()
+  {
+    this->value() = this->text().toStdString();
+    Saveable::save();
+  }
+
+
+
+
+}
Index: branches/heathaze/src/lib/gui/qt/qt_gui_elements.h
===================================================================
--- branches/heathaze/src/lib/gui/qt/qt_gui_elements.h	(revision 9940)
+++ branches/heathaze/src/lib/gui/qt/qt_gui_elements.h	(revision 9940)
@@ -0,0 +1,88 @@
+/*!
+ * @file qt_gui_elements.h
+ * @brief Definition of ...
+*/
+
+#ifndef __QT_GUI_ELEMENTS_H
+#define __QT_GUI_ELEMENTS_H
+
+#include "../gui_saveable.h"
+#include <list>
+
+// grouping
+#include <QtGui/QGroupBox>
+#include <QtGui/QProgressBar>
+#include <QtGui/QLabel>
+
+// events
+#include <QtGui/QPushButton>
+
+// options
+#include <QtGui/QCheckBox>
+#include <QtGui/QSlider>
+#include <QtGui/QLineEdit>
+#include <QtGui/QComboBox>
+
+namespace OrxGui
+{
+  class QtGuiCheckBox : public QCheckBox, public Saveable
+  {
+    Q_OBJECT
+  public:
+    QtGuiCheckBox(const std::string& name, SaveableGroup* group, bool defaultValue = false);
+    virtual ~QtGuiCheckBox() {};
+
+    virtual void load();
+    virtual void save();
+
+  public slots:
+    //    void setCheckValue(int);
+
+  signals:
+    //    void checkValueChanged();
+  };
+
+  class QtGuiSlider : public QSlider, public Saveable
+  {
+    Q_OBJECT
+
+  public:
+    QtGuiSlider(const std::string& name, SaveableGroup* group, int defaultValue = 0, Qt::Orientation orientation = Qt::Horizontal);
+    virtual ~QtGuiSlider();
+
+    virtual void load();
+    virtual void save();
+
+  public slots:
+    //   void setSliderValue(float);
+
+  signals:
+    //    void sliderValueChanged(float);
+  };
+
+
+  class QtGuiComboBox : public QComboBox, public OrxGui::Saveable
+  {
+    Q_OBJECT
+
+  public:
+    QtGuiComboBox(const std::string& name, SaveableGroup* group, const std::string& defaultValue);
+
+    virtual void load();
+    virtual void save();
+  };
+
+  class QtGuiInputLine : public QLineEdit, public OrxGui::Saveable
+  {
+    Q_OBJECT
+
+  public:
+    QtGuiInputLine(const std::string& name, SaveableGroup* group, const std::string& defaultValue);
+
+    virtual void load();
+    virtual void save();
+  };
+
+}
+
+#endif /* __QT_GUI_ELEMENTS_H */
Index: branches/heathaze/src/lib/lang/Makefile.am
===================================================================
--- branches/heathaze/src/lib/lang/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/lang/Makefile.am	(revision 9940)
@@ -0,0 +1,15 @@
+INCLUDES = -I../..
+INCLUDES +=-I..
+INCLUDES +=-I../util
+
+noinst_LIBRARIES = libORXlang.a
+
+libORXlang_a_SOURCES = \
+		base_object.cc \
+		class_id.cc \
+		object_list.cc
+
+noinst_HEADERS = \
+		base_object.h \
+		class_id.h \
+		object_list.h
Index: branches/heathaze/src/lib/lang/base_object.cc
===================================================================
--- branches/heathaze/src/lib/lang/base_object.cc	(revision 9940)
+++ branches/heathaze/src/lib/lang/base_object.cc	(revision 9940)
@@ -0,0 +1,158 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_BASE
+
+#include "base_object.h"
+
+#include "util/debug.h"
+#include "util/loading/load_param.h"
+
+ObjectListDefinition(BaseObject);
+
+/**
+ * @brief sets the name from a LoadXML-Element
+ * @param objectName: The name of the Object.
+ */
+BaseObject::BaseObject(const std::string& objectName)
+{
+  this->className = "BaseObject";
+
+  this->objectName = objectName;
+  this->xmlElem = NULL;
+  this->registerObject(this, BaseObject::_objectList);
+}
+
+/**
+ * @brief standard deconstructor
+*/
+BaseObject::~BaseObject ()
+{
+  /// Remove from the ObjectLists
+  ClassEntries::iterator it;
+  PRINTF(5)("Deleting Object of type %s::%s\n", this->getClassCName(), getCName());
+  for (it = this->_classes.begin(); it != this->_classes.end(); ++it)
+  {
+    if (ORX_DEBUG >= 5)
+      assert((*it)._objectList->checkIteratorInList((*it)._iterator) || (*it)._objectList->checkObjectInList(this));
+    (*it)._objectList->unregisterObject((*it)._iterator);
+    delete (*it)._iterator;
+  }
+
+  if (this->xmlElem != NULL)
+    delete this->xmlElem;
+}
+
+/**
+ * @brief loads parameters
+ * @param root the element to load from
+ */
+void BaseObject::loadParams(const TiXmlElement* root)
+{
+  // all loadParams should arrive here, and be tested for (root != NULL)
+  assert (root != NULL);
+
+  // copy the xml-element for to know how it was loaded.
+  if (this->xmlElem != NULL)
+    delete this->xmlElem;
+  this->xmlElem = root->Clone();
+
+  // name setup
+  LoadParam(root, "name", this, BaseObject, setName)
+      .describe("the Name of the Object.");
+}
+
+/**
+ * @brief set the name of the Object
+ * @param objectName The new name of the Object.
+ */
+void BaseObject::setName (const std::string& objectName)
+{
+  this->objectName = objectName;
+}
+
+
+/**
+ * @brief Seeks in the Inheritance if it matches objectList.
+ * @param objectList The ObjectList this should be a member of (by Pointer-comparison).
+ * @return True if found, false if not.
+ */
+bool BaseObject::isA(const ObjectListBase& objectList) const
+{
+  ClassEntries::const_iterator it;
+  for (it = this->_classes.begin(); it != this->_classes.end(); ++it)
+    if ((*it)._objectList == &objectList)
+      return true;
+  return false;
+}
+
+
+/**
+ * @brief Seeks in the Inheritance if it matches objectList.
+ * @param classID The ClassID this should be a member of (by Pointer-comparison).
+ * @return True if found, false if not.
+ */
+bool BaseObject::isA(const ClassID& classID) const
+{
+  ClassEntries::const_iterator it;
+  for (it = this->_classes.begin(); it != this->_classes.end(); ++it)
+    if (*(*it)._objectList == classID)
+      return true;
+  return false;
+}
+
+/**
+ * @brief Seeks in the Inheritance if it matches objectList.
+ * @param classID The ClassID of the class this should be a member of.
+ * @return True if found, false if not.
+ */
+bool BaseObject::isA(int classID) const
+{
+  ClassEntries::const_iterator it;
+  for (it = this->_classes.begin(); it != this->_classes.end(); ++it)
+    if (*(*it)._objectList == classID)
+
+      return true;
+  return false;
+}
+
+/**
+ * @brief Seeks in the Inheritance if it matches objectList.
+ * @param className The ClassName of the class this should be a member of.
+ * @return True if found, false if not.
+ */
+bool BaseObject::isA(const std::string& className) const
+{
+  ClassEntries::const_iterator it;
+  for (it = this->_classes.begin(); it != this->_classes.end(); ++it)
+    if (*(*it)._objectList == className)
+      return true;
+  return false;
+}
+
+
+/**
+ * @brief This is for debug purposes, to see the Inheritances of this Object and its classes.
+ *
+ * The Inheritance will be listed in a Linear fashion, diamand structures are resolved in a linear dependency.
+ */
+void BaseObject::listInheritance() const
+{
+  PRINT(0)("Listing inheritance diagram for %s::%s: ", getClassCName(), getCName());
+  ClassEntries::const_iterator it;
+  for (it = this->_classes.begin(); it != this->_classes.end(); ++it)
+    PRINT(0)(" -> %s(id:%d)", (*it)._objectList->name().c_str(), (*it)._objectList->id());
+  PRINT(0)("\n");
+
+}
Index: branches/heathaze/src/lib/lang/base_object.h
===================================================================
--- branches/heathaze/src/lib/lang/base_object.h	(revision 9940)
+++ branches/heathaze/src/lib/lang/base_object.h	(revision 9940)
@@ -0,0 +1,111 @@
+/*!
+ * @file base_object.h
+ * @brief Definition of the BaseObject class.
+ *
+ * This is a global handler for all classes Object and Class names
+ *
+ * BaseObject is the class, that handles object registration and
+ * is the only write-access member of ClassList, where the Objects
+ * References are stored.
+ */
+
+
+#ifndef __BASE_OBJECT_H_
+#define __BASE_OBJECT_H_
+
+#include "object_list.h"
+#include "util/sigslot/slot.h"
+
+#include <string>
+
+class TiXmlNode;
+class TiXmlElement;
+class ClassList;
+
+//! A class all other classes are derived from
+class BaseObject : public sigslot::has_slots<>
+{
+  //! Declare an ObjectList for this Class.
+  ObjectListDeclaration(BaseObject);
+public:
+  BaseObject (const std::string& objectName = "");
+
+  virtual ~BaseObject ();
+
+  virtual void loadParams(const TiXmlElement* root);
+  void setName (const std::string& newName);
+  /** returns the Name of this Object */
+  inline const std::string& getName() const { return this->objectName; };
+  /** returns the Name of this Object as a C-compliant string (const char*) */
+  inline const char* getCName() const { return this->objectName.c_str(); };
+  /** @returns the XML-Element with whicht this Object was loaded */
+  inline TiXmlNode* getXmlElem() const { return this->xmlElem; };
+
+  //  /** @returns the className of the corresponding Object */
+  //inline const std::string& getClassName() const { return this->className; }
+  /** @returns the className of the corresponding Object as a C-compliant string (const char*) */
+  inline const char* getClassCName() const { return _classes.front()._objectList->name().c_str(); };
+  /** @returns the ClassName of the Topmost Object of the ClassStack */
+  inline const std::string& getClassName() const { return _classes.front()._objectList->name(); };
+
+  /** @returns the ClassID of this Object */
+  inline const ClassID& getClassID() const { return _classes.front()._objectList->identity(); }
+  /** @returns the ID of the Topmost object of the ClassStack */
+  inline const int& getLeafClassID() const { return _classes.front()._objectList->identity().id(); }
+
+  bool isA(const ObjectListBase& objectList) const;
+  bool isA(const ClassID& classID) const;
+  bool isA(int classID) const;
+  bool isA(const std::string& className) const;
+
+  void listInheritance() const;
+
+  /** @param classID comparer for a ClassID @returns true on match, false otherwise */
+  bool operator==(int classID) const  { return this->isA(classID); };
+  /** @param objectName: the name to check. * @returns true on match, false otherwise. */
+  bool operator==(const std::string& objectName) const { return this->objectName == objectName;};
+
+protected:
+  template<class T> void registerObject(T* object, ObjectList<T>& list);
+
+protected:
+  std::string        objectName;       //!< The name of this object
+
+private:
+
+  TiXmlNode*         xmlElem;          //!< The XML Element with wich this Object was loaded(saved).
+
+  //////////////////////////////
+  //// Type Definition Part ////
+  //////////////////////////////
+  //! A ClassEntry so we can store Classes inside of Objects
+  struct ClassEntry
+  {
+    /** Simple Constuctor @param objectList the ObjectList, @param iterator the (intrusive) Iterator inside of the ObjectList */
+    inline ClassEntry (ObjectListBase* objectList, ObjectListBase::IteratorBase* iterator) : _objectList(objectList), _iterator(iterator) {}
+    ObjectListBase*                _objectList;  //!< An ObjectList this Object is part of
+    ObjectListBase::IteratorBase*  _iterator;    //!< An iterator pointing to the position of the Object inside of the List.
+  };
+  typedef std::list<ClassEntry>       ClassEntries;   //!< Type definition for the List.
+
+  std::string                         className;    //!< the name of the class
+  ClassEntries                        _classes;     //!< All Classes this object is part of.
+};
+
+
+/**
+ * @brief Registeres an Object of Type T to objectList
+ * @param object The Object to append to the objectList.
+ * @param objectList The ObjectList to append the Object to.
+ *
+ * This function is essential to integrate objects into their designated ObjectList.
+ * Remember if you do not want objects to be stored in Lists (less overhead),
+ * do not attempt to call this function.
+ */
+template<class T>
+inline void BaseObject::registerObject(T* object, ObjectList<T>& objectList)
+{
+  this->_classes.push_front(ClassEntry(&objectList, objectList.registerObject(object)));
+}
+
+#endif /* __BASE_OBJECT_H_ */
Index: branches/heathaze/src/lib/lang/class_id.cc
===================================================================
--- branches/heathaze/src/lib/lang/class_id.cc	(revision 9940)
+++ branches/heathaze/src/lib/lang/class_id.cc	(revision 9940)
@@ -0,0 +1,43 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "class_id.h"
+#include "object_list.h"
+
+/**
+ * @brief a Default Constructor.
+ * this Always points to the ID of the NullClass.
+ */
+ClassID::ClassID()
+{
+  NullClass::acquireID(this->_id, this->_name);
+};
+
+/**
+ * @brief Acquiring the ID of a objectList.
+ * @param objList The ObjectList to acquire the ID from.
+ */
+ClassID::ClassID(const ObjectListBase* const objList)
+{
+  objList->acquireID(this->_id, this->_name);
+}
+
+
+ClassID NullClass::_classID;
+
+int NullClass::_nullID;
+const std::string NullClass::_nullName = std::string("NullClass");
Index: branches/heathaze/src/lib/lang/class_id.h
===================================================================
--- branches/heathaze/src/lib/lang/class_id.h	(revision 9940)
+++ branches/heathaze/src/lib/lang/class_id.h	(revision 9940)
@@ -0,0 +1,78 @@
+/*!
+ * @file class_id.h
+ * @brief Definition of a dynamically allocating ClassID
+ *
+ */
+
+#ifndef _CLASS_ID_H
+#define _CLASS_ID_H
+
+#include <string>
+
+class ObjectListBase;
+
+//! A class to dynamically allocate ClassID's and to support a isA operator
+/**
+ * A ClassID can only be aquired over a ObjectList,
+ * thus enabling the developer to have permanent access to the correct ID and ClassName
+ *
+ * The Idea behind this concept is, that storing a ClassID that changes its internal state
+ * all ClassID's will be updated correctly.
+ *
+ * Since the Existance of any ObjectList is a requirement during the working process all
+ * ID's should reference a valid ID and ClassName
+ */
+class ClassID
+{
+public:
+  ClassID();
+  ClassID(const ObjectListBase* const id);
+  /// the copy constructor is also defined implicitely.
+
+  /** @returns A constant reference to the ID. */
+  const int& id() const { return *_id; };
+  /** @returns A constant reference to the Name. */
+  const std::string& name() const { return *_name; };
+
+  /** @param id the id to compare @returns true on match (match is same ID) @brief compares two id's */
+  bool operator==(const ClassID& id) const { return *_id == *id._id /* || _name == id._name */; };
+  /** @param id the id to compare @returns true on match (match is same ID) @brief compares two id's */
+  bool operator==(int id) const { return *_id == id; };
+  /** @param name the id to compare @returns true on match (match is same Name) @brief compares an ID with a ClassName */
+  bool operator==(const std::string& name) const { return *_name == name; };
+  /** @param id the id to compare @returns false on match (match is same ID) @brief compares two id's */
+  bool operator!=(const ClassID& id) const { return *_id != *id._id /* && _name != id._name*/;  };
+  /** @param id the id to compare @returns false on match (match is same ID) @brief compares two id's */
+  bool operator!=(int id) const { return *_id != id; };
+  /** @param name the id to compare @returns false on match (match is same Name) @brief compares an ID with a ClassName */
+  bool operator!=(const std::string& name) const { return *_name != name; };
+  /** @param classID: the Id to compare @returns true if this id is smaller than the classID's ID */
+  bool operator<(const ClassID& classID) const { return *this->_id < *classID._id; };
+
+private:
+  const int*                _id;           //!< A pointer to the ID of the ClassID.
+  const std::string*        _name;         //!< A pointer to the Name of the ClassID.
+};
+
+//! A NullClass. This is the Null of the ClassID.
+/**
+ * implemented as a Class id can be used to reference NullObjects.
+ */
+class NullClass
+{
+public:
+  /** @returns the NullClass' ID. */
+  static const ClassID& staticClassID() { return NullClass::_classID; }
+  /** @param id the ID to acquire @param name the name to acquire @brief acquires the ID of this Class */
+  static void acquireID(const int*& id, const std::string*& name) { id = &_nullID; name = &_nullName; };
+
+private:
+  NullClass() {}; //!< The Default Constructor is hidden from the User.
+
+private:
+  static ClassID            _classID;      //!< The NullClass' ID
+  static const std::string  _nullName;     //!< The NullClass' Name ("NullClass")
+  static int                _nullID;       //!< The NullClass' ID
+};
+
+#endif /* _CLASS_ID_H */
Index: branches/heathaze/src/lib/lang/object_list.cc
===================================================================
--- branches/heathaze/src/lib/lang/object_list.cc	(revision 9940)
+++ branches/heathaze/src/lib/lang/object_list.cc	(revision 9940)
@@ -0,0 +1,331 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "object_list.h"
+#include <cassert>
+
+/**
+ * @brief Constructor, that creates an ObjectList while checking (development mode) for uniqueness of all Keys (names and ID's)
+ * @param className The Name of the Class to create an ObjectList for.
+ * @param id The ID if you like, or -1 otherwise.
+ * @return a new NewObejctList
+ */
+ObjectListBase::ObjectListBase(const std::string& className, int id)
+    : _name(className)
+{
+  if (ObjectListBase::_classesByID == NULL)
+  {
+    ObjectListBase::_classesByID = new IDMap;
+    assert (ObjectListBase::_classesByName == NULL);
+    ObjectListBase::_classesByName = new NameMap;
+  }
+  assert(!ObjectListBase::classNameExists(className) && "Classes should only be included once, and no two classes should have the same name (key value)");
+
+  if (id == -1)
+  {
+    id = ObjectListBase::_classesByID->size();
+    // searching for a free ID
+    while (ObjectListBase::classIDExists(id)) ++id;
+  }
+  assert(!ObjectListBase::classIDExists(id) && "Classes should only be included once, and no two classes should have the same ID (key value)");
+
+  this->_id = id;
+  /// Some Output, that will fall out later
+  //  std::cout << "register new ObjectList " << className << " ID: " << this->_id << std::endl;
+
+  this->_identity = ClassID(this);
+  (*ObjectListBase::_classesByID)[this->_identity.id()] = this;
+  (*ObjectListBase::_classesByName)[this->_identity.name()] = this;
+}
+
+
+/**
+ * Destructor.
+ *
+ * This destructor deletes the ObjectList, and cleans up the ObjectList sorted Maps.
+ */
+ObjectListBase::~ObjectListBase()
+{
+  assert (ObjectListBase::_classesByName != NULL && ObjectListBase::_classesByID != NULL);
+  /*
+  std::cout << "Erasing: " << this->_name << " "<< this->_id  << std::endl;
+  std::cout << "SIZE OF _classByID: " << ObjectListBase::_classesByID->size() << std::endl;
+  std::cout << "SIZE OF _classByName: " << ObjectListBase::_classesByName->size() << std::endl;
+  */
+  ObjectListBase::_classesByID->erase(this->_identity.id());
+  ObjectListBase::_classesByName->erase(this->_identity.name());
+
+  if (ObjectListBase::_classesByID->empty())
+  {
+    delete ObjectListBase::_classesByID;
+    ObjectListBase::_classesByID = NULL;
+    assert(ObjectListBase::_classesByName != NULL);
+    delete ObjectListBase::_classesByName;
+    ObjectListBase::_classesByName = NULL;
+  }
+}
+
+ObjectListBase::IDMap* ObjectListBase::_classesByID = NULL;
+ObjectListBase::NameMap* ObjectListBase::_classesByName = NULL;
+std::list<std::string> ObjectListBase::_classNames;
+
+/**
+ * @returns the Registered Class Count.
+ */
+unsigned int ObjectListBase::classCount()
+{
+  assert (ObjectListBase::_classesByID != NULL);
+  return ObjectListBase::_classesByID->size();
+};
+
+/**
+ * @brief Checks if a Class with name already exists.
+ * @param id The id of the Class to check.
+ * @return true if such a class already exists.
+ */
+bool ObjectListBase::classIDExists(int id)
+{
+  return (ObjectListBase::_classesByID->find(id) != ObjectListBase::_classesByID->end());
+}
+
+/**
+ * @brief Checks if a Class with name already exists.
+ * @param name The Name of the Class to check.
+ * @return true if such a class already exists.
+ */
+bool ObjectListBase::classNameExists(const std::string& name)
+{
+  return (ObjectListBase::_classesByName->find(name) != ObjectListBase::_classesByName->end());
+}
+
+/**
+ * @brief searches for a ClassID in the list of all ObjectLists, and returns its Identity
+ * @param id: The Id to search for
+ * @returns the ClassID if found and NullClass' identity if not.
+ */
+const ClassID& ObjectListBase::retrieveIdentity(int id)
+{
+  const ObjectListBase* const base = ObjectListBase::getObjectList(id);
+
+  if (base != NULL)
+    return base->_identity;
+  else
+    return NullClass::staticClassID();
+}
+
+
+/**
+ * @brief searches for a ClassID in the list of all ObjectLists, and returns its Identity
+ * @param name: The Name to search for
+ * @returns the ClassID if found and NullClass' identity if not.
+ */
+const ClassID& ObjectListBase::retrieveIdentity(const std::string& name)
+{
+  const ObjectListBase* const base = ObjectListBase::getObjectList(name);
+
+  if (base != NULL)
+    return base->_identity;
+  else
+    return NullClass::staticClassID();
+}
+
+
+/**
+ * @brief Searches for a ObjectList with the ID classID
+ * @param classID the ID to search for.
+ * @return The ObjectList if found, NULL otherwise.
+ */
+const ObjectListBase* const ObjectListBase::getObjectList(int classID)
+{
+  assert (ObjectListBase::_classesByID != NULL);
+  ObjectListBase::IDMap::iterator it = ObjectListBase::_classesByID->find(classID);
+  if (it != ObjectListBase::_classesByID->end())
+    return (*it).second;
+  else
+    return NULL;
+}
+
+/**
+ * @brief Searches for a ObjectList with the Name className
+ * @param className the Name to search for.
+ * @return The ObjectList if found, NULL otherwise.
+ */
+const ObjectListBase* const ObjectListBase::getObjectList(const std::string& className)
+{
+  assert (ObjectListBase::_classesByName != NULL);
+  ObjectListBase::NameMap::iterator it = ObjectListBase::_classesByName->find(className);
+  if (it != ObjectListBase::_classesByName->end())
+    return (*it).second;
+  else
+    return NULL;
+}
+
+/**
+ * @brief Searches for a ObjectList with the ClassID classID
+ * @param classID the ID to search for.
+ * @return The ObjectList if found, NULL otherwise.
+ */
+const ObjectListBase* const ObjectListBase::getObjectList(const ClassID& classID)
+{
+  return ObjectListBase::getObjectList(classID.id());
+}
+
+/**
+ * @brief Retrieves the first BaseObject matching the name objectName from the List matching classID.
+ * @param classID the ID of the List.
+ * @param objectName the Name of the Object to search for
+ */
+BaseObject* ObjectListBase::getBaseObject(int classID, const std::string& objectName)
+{
+  const ObjectListBase* const base = ObjectListBase::getObjectList(classID);
+
+  if (base != NULL)
+    return base->getBaseObject(objectName);
+  else
+    return NULL;
+}
+
+/**
+ * @brief Retrieves the first BaseObject matching the name objectName from the List matching className.
+ * @param className the Name of the List.
+ * @param objectName the Name of the Object to search for
+ */
+BaseObject* ObjectListBase::getBaseObject(const std::string& className, const std::string& objectName)
+{
+  const ObjectListBase* const base = ObjectListBase::getObjectList(className);
+
+  if (base != NULL)
+    return base->getBaseObject(objectName);
+  else
+    return NULL;
+}
+
+/**
+ * @brief Retrieves the first BaseObject matching the name objectName from the List matching classID.
+ * @param classID The ClassID of the List.
+ * @param objectName the Name of the Object to search for
+ */
+BaseObject* ObjectListBase::getBaseObject(const ClassID& classID, const std::string& objectName)
+{
+  const ObjectListBase* const base = ObjectListBase::getObjectList(classID);
+
+  if (base != NULL)
+    return base->getBaseObject(objectName);
+  else
+    return NULL;
+}
+
+
+/**
+ * @returns An alphabetically sorted List of all stored ClassNames.
+ */
+const std::list<std::string>& ObjectListBase::getClassNames()
+{
+  if (ObjectListBase::classCount() != ObjectListBase::_classNames.size())
+  {
+    ObjectListBase::_classNames.clear();
+
+    for (NameMap::const_iterator it = ObjectListBase::_classesByName->begin();
+         it != ObjectListBase::_classesByName->end();
+         ++it)
+      ObjectListBase::_classNames.push_back((*it).second->name());
+  }
+  return ObjectListBase::_classNames;
+}
+
+
+#include "base_object.h"
+
+/**
+ * @brief Prints out some debugging information about a given List.
+ * @param level:
+ *  1: List ObjectListsand how many object.
+ *  2: 1+List ObjectLists entries, and information about Objects.
+ */
+void ObjectListBase::debug(unsigned int level) const
+{
+  base_list list;
+  this->getBaseObjectList(&list);
+
+  if (level > 1 || !list.empty())
+    printf(" ObjectList of class %s(id:%d) contains %d objects\n", this->name().c_str(), this->id(), list.size());
+
+  if (level >= 2)
+  {
+    printf("  - listing Instances: \n");
+    for (base_iterator it = list.begin();
+         it != list.end();
+         ++it)
+    {
+      printf("   + %s::%s (%p)\n", (*it)->getClassCName(), (*it)->getCName(), (*it));
+    }
+  }
+}
+
+
+/**
+ * @brief prints out debug output about all Lists
+ * @param level:
+ *  0: list number of ClassList and general info.
+ *  1: 0+List ObjectLists and how many object.
+ *  2: 1+List ObjectLists entries, and information about Objects.
+ */
+void ObjectListBase::debugAll(unsigned int level)
+{
+  printf("Listing all %d ObjectLists \n", ObjectListBase::_classesByID->size());
+
+  for (NameMap::const_iterator it = ObjectListBase::_classesByName->begin();
+       it != ObjectListBase::_classesByName->end();
+       ++it)
+    (*it).second->debug(level);
+}
+
+
+
+/**
+ * @brief Converts an ID into a ClassName String.
+ * @param classID The ID to convert.
+ * @return The ClassName or an empty string if the ID was not found.
+ */
+const std::string& ObjectListBase::IDToString(int classID)
+{
+  const ObjectListBase* const base = ObjectListBase::getObjectList(classID);
+
+  if (base != NULL)
+    return base->name();
+  else
+  {
+    static std::string empty;
+    return empty;
+  }
+}
+
+
+/**
+ * @brief Converts a String into an ID
+ * @param className the Name of the Class to search for
+ * @return The Classes ID if found, -1 otherwise.
+ */
+int ObjectListBase::StringToID(const std::string& className)
+{
+  const ObjectListBase* const base = ObjectListBase::getObjectList(className);
+
+  if (base != NULL)
+    return base->id();
+  else
+    return -1;
+}
Index: branches/heathaze/src/lib/lang/object_list.h
===================================================================
--- branches/heathaze/src/lib/lang/object_list.h	(revision 9940)
+++ branches/heathaze/src/lib/lang/object_list.h	(revision 9940)
@@ -0,0 +1,383 @@
+/*!
+ * @file object_list.h
+ * @brief Definition of a dynamically allocating ClassID
+ *
+ */
+
+#ifndef _OBJECT_LIST_H
+#define _OBJECT_LIST_H
+
+#include "class_id.h"
+#include <map>
+#include <list>
+#include <string>
+
+#include <cassert>
+#include <iostream>
+
+/**
+ * @brief Use this macro to easily declare a Class to store its own ObjectListDeclaration
+ * @param ClassName the Name of the Class.
+ * @note: Using this inside of a Class means, that you loose the member: _objectList, while defining
+ * two new functions objectList() and classID().
+ */
+#define ObjectListDeclaration(ClassName) \
+  public: \
+   static inline const ObjectList<ClassName>& objectList() { return ClassName::_objectList; }; \
+   static inline const ClassID& staticClassID() { return ClassName::_objectList.identity(); }; \
+  private: \
+   static ObjectList<ClassName> _objectList
+
+/**
+ * @brief Use this macro to easily define a Class to store its own ObjectListDefinition
+ * @param ClassName: the Name of the Class.
+ * @param ID: optional set a Fixed ID.
+ */
+#define ObjectListDefinitionID(ClassName, ID) \
+   ObjectList<ClassName> ClassName::_objectList(#ClassName, ID)
+
+/**
+ * @brief Use this macro to easily define a Class to store its own ObjectListDefinition
+ * @param ClassName: the Name of the Class.
+ */
+#define ObjectListDefinition(ClassName) \
+    ObjectListDefinitionID(ClassName, -1)
+
+class BaseObject;
+//! The superclass that all ObjectLists follow.
+/**
+ * @see template<class T> ObjectList<T>
+ */
+class ObjectListBase
+{
+public:
+  /** @brief A Typedefinition for the Base-List that can be retrieved with getBaseObjectList(base_list*) */
+  typedef std::list<BaseObject*>        base_list;
+  /** @brief An iterator for the base_list */
+  typedef base_list::iterator           base_iterator;
+  //! A fast iterator Base-Class, for iterator-casting and storing.
+  /** @note This Iterator is explicitely used only for storage purposes in the BaseObject */
+  class IteratorBase { };
+
+public:
+  /** @returns The Identity of the Class stored within. */
+  inline const ClassID&                 identity() const { return _identity; }
+  /** @returns the ID of the Identity of the ObjectList */
+  inline int                            id() const { return _id; };
+  /** @returns The Name of the Class stored in this ObjectList */
+  inline const std::string&             name() const { return _name; };
+  /** @param id The id to compare @returns true on match, false otherwise */
+  inline bool                           operator==(int id) const { return _id == id; };
+  /** @param id The id to compare @returns true on match, false otherwise */
+  inline bool                           operator==(const ClassID& id) const { return id == _id; };
+  /** @param name The name to compare @returns true on match, false otherwise */
+  inline bool                           operator==(const std::string& name) const { return _name == name; };
+  /** @param id The id to acquire @param name the Name to acquire @brief stores a Name and an ID in a pointer. */
+  inline void                           acquireID(const int*& id, const std::string*& name) const { id = &_id; name = &_name; };
+  /** @brief fills a list of Objects into a BaseObject*-List. @param list the list to fill */
+  virtual void                          getBaseObjectList(base_list* list) const = 0;
+
+  static const ClassID&                 retrieveIdentity(int id);
+  static const ClassID&                 retrieveIdentity(const std::string& name);
+
+  static const ObjectListBase* const    getObjectList(int classID);
+  static const ObjectListBase* const    getObjectList(const std::string& className);
+  static const ObjectListBase* const    getObjectList(const ClassID& classID);
+
+  static BaseObject*                    getBaseObject(int classID, const std::string& objectName);
+  static BaseObject*                    getBaseObject(const std::string& className, const std::string& objectName);
+  static BaseObject*                    getBaseObject(const ClassID& classID, const std::string& objectName);
+
+  /** @returns an Object with Name name out of this List @param name the name of the Object. */
+  virtual BaseObject*                   getBaseObject(const std::string& name) const = 0;
+
+  static const std::list<std::string>&  getClassNames();
+
+
+  static unsigned int                   classCount();
+  void                                  debug(unsigned int level) const;
+  static void                           debugAll(unsigned int level);
+
+  static const std::string&             IDToString(int classID);
+  static int                            StringToID(const std::string& className);
+
+  //! Only used to unsubscribe a BaseObject. (just try to make a valid iterator, stupid :))
+  virtual void                          unregisterObject(IteratorBase* _iterators) = 0;
+  //! Only for debug purposes
+  virtual bool                          checkIteratorInList(IteratorBase* _iterator) const = 0;
+  virtual bool                          checkObjectInList(BaseObject* obj) const = 0;
+
+protected:
+  ObjectListBase(const std::string& className, int id = -1);
+  virtual ~ObjectListBase();
+
+private:
+  /** @brief hidden copy constructor. */
+  ObjectListBase(const ObjectListBase&) {};
+
+  static bool                         classIDExists(int id);
+  static bool                         classNameExists(const std::string& className);
+
+
+protected:
+  typedef std::map<int, ObjectListBase*>         IDMap;   //!< The Generic Map.
+  typedef std::map<std::string, ObjectListBase*> NameMap; //!< The Generic Map.
+
+private:
+  int                           _id;                //!< The Unique ID of the Class.
+  const std::string             _name;              //!< The Name of the Class.
+  ClassID                       _identity;          //!< The Identity of the Class. (equal to _id and _name)
+
+private:
+  static IDMap*                 _classesByID;       //!< A Map of all the classes in existance.
+  static NameMap*               _classesByName;     //!< A Map of all the classes in existance.
+  static std::list<std::string> _classNames;        //!< A list of all the registered ClassNames.
+};
+
+
+/////////////////////////
+//// TEMPLATISATION /////
+/////////////////////////
+//! Defines a ObjectList handler for objects of type T.
+/**
+ * The ObjectList is a generic way to store every object created from a Class 'T'
+ *  in a List. The list can be retrieved, and used constantly over iterators,
+ *  as with normal std::list.
+ *
+ * Furthermore the linkage over the single Lists is given over the Superclass ObjectListBase.
+ *
+ * The approach of ObjectList is an intrusive one, meaning, that each Class that wants to
+ * support it must implement a Declaration and a Definition for the ObjectList, as mentioned
+ * in the next statement:
+ *
+ * To define a Class with a ObjectList, you have to:
+ *  1. Include 'ObjectListDeclaration(T);' in its Declaration (at the beginning)
+ *  2. Include 'ObjectListDefinition(T);' in some Definition file (cc-file)
+ *  3. In the constructor add 'registerObject(this, objectList);'
+ *
+ * @note The Class must define the compare with const std::string& operator for this to work.
+ *  The operator==(const std::string& name) should compare the object's name with name.
+ *
+ *
+ *
+ * Limitations:
+ *  ObjectList cannot be used with other Factory style Classes, if the class is also a BaseObject,
+ *   and not loaded before the ObjectList.
+ *
+ * example: Iterating: Iteration is made easy, and fast as follows:
+ *   for (ObjectList<PlayerStats>::const_iterator it = PlayerStats::objectList().begin();
+ *      it != PlayerStats::objectList().end();
+ *     ++it)
+ *   {
+ *    (*it)->dosomething
+ *   }
+ *
+ * example: Find an Object:
+ * Playable* playable = Playable::objectList("orxonox-super-rocket-fighter"); // searches an Object By its name.
+ *
+ */
+template<class T>
+class ObjectList : public ObjectListBase
+{
+public:
+  typedef std::list<T*>                  list;             //!< The list of Type T* (used for Objects in this ObjectList)
+  typedef typename list::iterator        iterator;         //!< The iterator for the List of type T (use with ObjectList<Type>::iterator)
+  typedef typename list::const_iterator  const_iterator;   //!< A constant iterator for the List of type T (use with ObjectList<Type>::const_iterator)
+
+
+  //! An iterator to store Objects in the BaseObject, and remove Objects fast.
+class Iterator : public ObjectListBase::IteratorBase
+  {
+  public:
+    /** @brief creates an Iterator fast. @param it the Iterator. */
+    inline Iterator(iterator it) { _it = it; }
+    /** @returns the Iterator */
+    inline iterator& it() { return _it; }
+  private:
+    typename ObjectList::iterator _it;  //!< Stored Iterator
+  };
+
+public:
+  ObjectList(const std::string& name, int id = -1);
+  ~ObjectList();
+
+  virtual BaseObject*                getBaseObject(const std::string& name) const;
+  T*                                 getObject(const std::string& name) const;
+  /** @returns A constant list of Objects of this Class. */
+  inline const list&                 objects() const { return _objects; };
+  bool                               exists(const T* const object) const;
+
+  /** @returns an Iterator to the beginning of the List. */
+  inline iterator                    begin() { return _objects.begin(); };
+  /** @returns a constant Iterator to the beginning of the List. */
+  inline const_iterator              begin() const { return _objects.begin(); };
+  /** @returns an Iterator to the end of the List. */
+  inline iterator                    end() { return _objects.end(); };
+  /** @returns a constant Iterator to the beginning of the List. */
+  inline const_iterator              end() const { return _objects.end(); };
+
+  /** @returns true if the List is empty. */
+  inline bool                        empty() const { return _objects.empty(); };
+  /** @returns the size of the List */
+  inline int                         size() const { return _objects.size(); };
+  /** @returns the frontmost Element of the list (normaly the last added Object). */
+  inline T*                          front() const { return _objects.front(); };
+  /** @returns the last added Object */
+  inline T*                          back() const { return _objects.back(); };
+
+
+  ObjectListBase::IteratorBase*      registerObject(T* object);
+  virtual void                       unregisterObject(IteratorBase* iterator);
+  bool                               checkIteratorInList(IteratorBase* iterator) const;
+  bool                               checkObjectInList(BaseObject* obj) const;
+protected:
+  virtual void                       getBaseObjectList(ObjectListBase::base_list* list) const;
+
+
+private:
+  //! the copy constructor will be hidden.
+  ObjectList(const ObjectList& definer) {};
+
+private:
+  list                _objects;     //!< The List of stored Objects of Type T.
+};
+
+
+
+
+
+/////////////////////////
+//// IMPLEMENTATION /////
+/////////////////////////
+/**
+ * @brief creates a new ObjectList
+ * @param name The name of the Class.
+ * @param id The ID of the class if desired, or -1 if an id should be assigned automatically.
+ */
+template <class T>
+ObjectList<T>::ObjectList(const std::string& name, int id)
+    : ObjectListBase(name, id)
+{}
+
+/**
+ * @brief deletes the ObjectList.
+ */
+template <class T>
+ObjectList<T>::~ObjectList()
+{
+  if (!_objects.empty())
+  {
+    // std::cout << "There are " << this->size() << " objects from class " << this->name() << "(id:" << this->id() << ") in existance\n";
+  }
+}
+
+/**
+ * @brief Retrieves a BaseObject matching the Name name in this List.
+ * @param name the Name of the Object.
+ * @returns a BaseObject pointing to the object if found, NULL otherwise.
+ */
+template <class T>
+BaseObject* ObjectList<T>::getBaseObject(const std::string& name) const
+{
+  return this->getObject(name);
+}
+
+
+
+/**
+ * @brief Retrieves an Object of type T matching the Name name in this List.
+ * @param name the Name of the Object.
+ * @returns an Object of type T pointing to the object if found, NULL otherwise.
+ */
+template <class T>
+T* ObjectList<T>::getObject(const std::string& name) const
+{
+  const_iterator it;
+  for (it = this->_objects.begin(); it != this->_objects.end(); ++it)
+    if ((*it)->getName() == name)
+      return (*it);
+  return NULL;
+}
+
+/**
+ * @brief checks if Object object exists in this ClassList.
+ * @param object the Object to check for
+ * @returns True if the object is found within the List, false otherwise
+ */
+template <class T>
+bool ObjectList<T>::exists(const T* const object) const
+{
+  return (std::find(_objects.begin(), _objects.end(), object) != _objects.end());
+}
+
+
+/**
+ * @brief retrieves a List of BaseObjects
+ * @param list the list to push the ObjectList into.
+ */
+template <class T>
+void ObjectList<T>::getBaseObjectList(ObjectListBase::base_list* list) const
+{
+  assert (list != NULL);
+  const_iterator it;
+  for (it = this->_objects.begin(); it != this->_objects.end(); ++it)
+    list->push_back(*it);
+}
+
+
+/**
+ * @brief registers an Object to the ObjectList.
+ * @param object The Object to register.
+ * @returns a pointer to the iterator inside of the list.
+ */
+template <class T>
+ObjectListBase::IteratorBase* ObjectList<T>::registerObject(T* object)
+{
+  this->_objects.push_back(object);
+  return new Iterator(--this->_objects.end());
+}
+
+/**
+ * @brief removes an Object from the ClassList.
+ * @param iterator the Position at which to remove the Object.
+ */
+template <class T>
+void ObjectList<T>::unregisterObject(IteratorBase* iterator)
+{
+  this->_objects.erase(static_cast<Iterator*>(iterator)->it());
+  //_objects.erase(std::find(_objects.begin(), _objects.end(), object));
+}
+
+template <class T>
+bool ObjectList<T>::checkIteratorInList(IteratorBase* iterator) const
+{
+  const_iterator it;
+  for (it = this->_objects.begin(); it != this->_objects.end(); ++it)
+    if (static_cast<Iterator*>(iterator)->it() == it)
+      return true;
+  printf("ObjectList:: checkIteratorInList:: ITERATOR NOT IN THE LIST '%s' (UN-SYNC SHOULD NOT HAPPEN!!)\n", this->name().c_str());
+  return false;
+}
+
+template <class T>
+bool ObjectList<T>::checkObjectInList(BaseObject* obj) const
+{
+  T* object = dynamic_cast<T*>(obj);
+  if (object != NULL)
+  {
+    printf("EXTREME BUG: Object does not exist anymore!! (or a bug in ObjectList)\n");
+    return false;;
+  }
+
+  const_iterator it;
+  for (it = this->_objects.begin(); it != this->_objects.end(); ++it)
+  {
+    if (*it == object)
+      return true;
+  }
+  printf("ObjectList:: checkObjectInList:: OBJECT NOT IN THE LIST '%s' (UN-SYNC SHOULD NOT HAPPEN!!)\n", this->name().c_str());
+  return false;
+}
+
+
+#endif /* _OBJECT_LIST_H */
Index: branches/heathaze/src/lib/lang/type_info.h
===================================================================
--- branches/heathaze/src/lib/lang/type_info.h	(revision 9940)
+++ branches/heathaze/src/lib/lang/type_info.h	(revision 9940)
@@ -0,0 +1,112 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
+//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any
+//     purpose is hereby granted without fee, provided that the above copyright
+//     notice appear in all copies and that both that copyright notice and this
+//     permission notice appear in supporting documentation.
+// The author or Addison-Wesley Longman make no representations about the
+//     suitability of this software for any purpose. It is provided "as is"
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+// Last update: June 20, 2001
+
+#ifndef __TYPE_INFO_H__
+#define __TYPE_INFO_H__
+
+#include <typeinfo>
+#include <cassert>
+////////////////////////////////////////////////////////////////////////////////
+// class TypeInfo
+// Purpose: offer a first-class, comparable wrapper over std::type_info
+////////////////////////////////////////////////////////////////////////////////
+
+class TypeInfo
+{
+public:
+  // Constructors
+  TypeInfo(); // needed for containers
+  TypeInfo(const std::type_info&); // non-explicit
+
+  bool operator==(const TypeInfo& typeInfo) const;
+  bool operator!=(const TypeInfo& typeInfo) const;
+  bool operator<(const TypeInfo& typeInfo) const;
+  bool operator>(const TypeInfo& typeInfo) const;
+  bool operator<=(const TypeInfo& typeInfo) const;
+  bool operator>=(const TypeInfo& typeInfo) const;
+
+  // Access for the wrapped std::type_info
+  const std::type_info& get() const;
+  // Compatibility functions
+  bool before(const TypeInfo& rhs) const;
+  const char* name() const;
+
+private:
+  const std::type_info* pInfo_;
+};
+
+// Implementation
+
+inline TypeInfo::TypeInfo()
+{
+  class Nil {};
+  pInfo_ = &typeid(Nil);
+  assert(pInfo_);
+}
+
+inline TypeInfo::TypeInfo(const std::type_info& ti)
+    : pInfo_(&ti)
+{
+  assert(pInfo_);
+}
+
+inline bool TypeInfo::before(const TypeInfo& rhs) const
+{
+  assert(pInfo_);
+  // type_info::before return type is int in some VC libraries
+  return pInfo_->before(*rhs.pInfo_) != 0;
+}
+
+inline const std::type_info& TypeInfo::get() const
+  {
+    assert(pInfo_);
+    return *pInfo_;
+  }
+
+inline const char* TypeInfo::name() const
+{
+  assert(pInfo_);
+  return pInfo_->name();
+}
+
+// Comparison operators
+
+inline bool TypeInfo::operator==(const TypeInfo& rhs) const
+// type_info::operator== return type is int in some VC libraries
+{ return (this->get() == rhs.get()) != 0; }
+
+inline bool TypeInfo::operator<(const TypeInfo& rhs) const
+{ return this->before(rhs); }
+
+inline bool TypeInfo::operator!=(const TypeInfo& rhs) const
+{ return !(*this == rhs); }
+
+inline bool TypeInfo::operator>(const TypeInfo& rhs) const
+{ return rhs < *this; }
+
+inline bool TypeInfo::operator<=(const TypeInfo& rhs) const
+{ return !(*this > rhs); }
+
+inline bool TypeInfo::operator>=(const TypeInfo& rhs) const
+{ return !(*this < rhs); }
+
+////////////////////////////////////////////////////////////////////////////////
+// Change log:
+// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
+////////////////////////////////////////////////////////////////////////////////
+
+#endif /* __TYPE_INFO_H__ */
Index: branches/heathaze/src/lib/math/Makefile.am
===================================================================
--- branches/heathaze/src/lib/math/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/math/Makefile.am	(revision 9940)
@@ -0,0 +1,27 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+
+noinst_LIBRARIES = libORXmath.a
+
+libORXmath_a_SOURCES = \
+		vector.cc \
+		vector2D.cc \
+		quaternion.cc \
+		matrix.cc \
+		curve.cc \
+		plane.cc \
+		line.cc \
+		rect2D.cc \
+		rotation_OBSOLETE.cc
+
+noinst_HEADERS = \
+		vector.h \
+		vector2D.h \
+		quaternion.h \
+		matrix.h \
+		curve.h \
+		plane.h \
+		line.h \
+		rect2D.h \
+		rotation_OBSOLETE.h
Index: branches/heathaze/src/lib/math/curve.cc
===================================================================
--- branches/heathaze/src/lib/math/curve.cc	(revision 9940)
+++ branches/heathaze/src/lib/math/curve.cc	(revision 9940)
@@ -0,0 +1,306 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+
+   ADD: Patrick Boenzli           B-Spline
+
+
+   TODO:
+     local-Time implementation
+     NURBS
+     !!tList implementation!!
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "curve.h"
+
+#include "debug.h"
+
+#include <cmath>
+#include <stdio.h>
+
+
+/**
+  *  default constructor for a Curve
+*/
+Curve::Curve()
+{
+  this->nodeCount = 0;
+  this->localTime = 0;
+  this->derivation = 0;
+  this->dirCurve = NULL;
+  this->firstNode = new PathNode();
+  this->currentNode = firstNode;
+
+  this->firstNode->position = Vector (.0, .0, .0);
+  this->firstNode->number = 0;
+  this->firstNode->next = 0; // not sure if this really points to NULL!!
+}
+
+
+Curve::~Curve()
+{
+  PathNode* pn = this->firstNode;
+  PathNode* unusedPN;
+  while( pn != NULL)
+  {
+    unusedPN = pn;
+    pn = pn->next;
+    delete unusedPN;
+  }
+
+  if (dirCurve)
+    delete dirCurve;
+}
+
+
+/**
+ *  adds a new Node to the bezier Curve
+ * @param newNode a Vector to the position of the new node
+*/
+void Curve::addNode(const Vector& newNode)
+{
+  if (nodeCount != 0 )
+    {
+      currentNode = currentNode->next = new PathNode;
+    }
+  currentNode->position = newNode;
+  currentNode->next = 0;
+  currentNode->number = (++nodeCount);
+  this->rebuild();
+  return;
+}
+
+/**
+ *  adds a new Node to the bezier Curve
+ * @param newNode a Vector to the position of the new node
+ * @param insertPosition after the n-th node the new node will be inserted
+*/
+void Curve::addNode(const Vector& newNode, unsigned int insertPosition)
+{
+  if (this->nodeCount == 0 || insertPosition > this->nodeCount)
+    return addNode(newNode);
+
+  if (insertPosition == 0)
+    insertPosition = 1;
+
+  PathNode* insNode = new PathNode;
+
+  // relinking
+  PathNode* tmpNode = this->firstNode;
+  if (insertPosition > 1)
+    {
+      while (tmpNode->next->number != insertPosition)
+        tmpNode= tmpNode->next;
+      insNode->next = tmpNode->next;
+      tmpNode->next = insNode;
+    }
+  else
+    {
+      insNode->next = this->firstNode;
+      this->firstNode = insNode;
+    }
+  // renumbering
+  insNode->number = insertPosition;
+  tmpNode = insNode->next;
+  while (tmpNode)
+    {
+      tmpNode->number++;
+      tmpNode = tmpNode->next;
+    }
+
+    // finished
+  insNode->position = newNode;
+  ++nodeCount;
+  this->rebuild();
+  return;
+}
+
+/**
+ *  Finds a Node by its Number, and returns its Position
+ * @param nodeToFind the n'th node in the List of nodes
+ * @returns A Vector to the Position of the Node.
+*/
+Vector Curve::getNode(unsigned int nodeToFind)
+{
+  if (nodeToFind > this->nodeCount || nodeToFind < 0)
+    return Vector(0,0,0);
+  PathNode* tmpNode = this->firstNode;
+  for (int i = 1; i < nodeToFind; i++)
+    tmpNode = tmpNode->next;
+  return tmpNode->position;
+}
+
+/**
+ *  Outputs information about the state of this Curve
+*/
+void Curve::debug()
+{
+  printf("<<-------------------------------\n");
+  printf("Curve Information:\n");
+  printf("NodeCount: %d\n", this->nodeCount);
+  PathNode* tmpNode = this->firstNode;
+  while (tmpNode)
+    {
+      printf("node #%d: %f, %f, %f\n", tmpNode->number, tmpNode->position.x, tmpNode->position.y, tmpNode->position.z);
+      tmpNode = tmpNode->next;
+    }
+  printf("------------------------------->>\n");
+}
+
+
+///////////////////////////////////
+/// Bezier Curve //////////////////
+///////////////////////////////////
+
+/**
+ *  Creates a new BezierCurve
+*/
+BezierCurve::BezierCurve ()
+{
+  this->derivation = 0;
+  dirCurve = new BezierCurve(1);
+}
+
+/**
+ *  Creates a new BezierCurve-Derivation-Curve
+*/
+BezierCurve::BezierCurve (int derivation)
+{
+  this->derivation = derivation;
+  dirCurve=NULL;
+}
+
+/**
+ *  Deletes a BezierCurve.
+
+   It does this by freeing all the space taken over from the nodes
+*/
+BezierCurve::~BezierCurve()
+{
+
+}
+
+/**
+ *  Rebuilds a Curve
+*/
+void BezierCurve::rebuild()
+{
+  PathNode* tmpNode = firstNode;
+
+  // rebuilding the Curve itself
+  float k = 0;
+  float n = nodeCount -1;
+  float binCoef = 1;
+  while( tmpNode)
+    {
+      tmpNode->factor = binCoef;
+      if( tmpNode = tmpNode->next)
+        {
+          binCoef *= (n-k) / (k+1);
+          ++k;
+        }
+    }
+
+  // rebuilding the Derivation curve
+  if( this->derivation <= 1)
+    {
+      tmpNode = firstNode;
+      delete dirCurve;
+      dirCurve = new BezierCurve(1);
+      while( tmpNode->next)
+        {
+          Vector tmpVector = (tmpNode->next->position) - (tmpNode->position);
+          tmpVector.x*=(float)nodeCount;
+          tmpVector.y*=(float)nodeCount;
+          tmpVector.z*=(float)nodeCount;
+          tmpVector.normalize();
+          this->dirCurve->addNode(tmpVector);
+          tmpNode = tmpNode->next;
+        }
+    }
+}
+
+/**
+ *  calculates the Position on the curve
+ * @param t The position on the Curve (0<=t<=1)
+ * @return the Position on the Path
+*/
+Vector BezierCurve::calcPos(float t)
+{
+  Vector ret = Vector(0.0,0.0,0.0);
+  if (this->nodeCount >= 3)
+    {
+      PathNode* tmpNode = this->firstNode;
+      double factor = pow(1.0-t,nodeCount-1);
+      while(tmpNode)
+        {
+          ret.x += tmpNode->factor * factor * tmpNode->position.x;
+          ret.y += tmpNode->factor * factor * tmpNode->position.y;
+          ret.z += tmpNode->factor * factor * tmpNode->position.z;
+          factor *= t/(1.0-t); // same as pow but much faster.
+
+          tmpNode = tmpNode->next;
+        }
+    }
+  else if (nodeCount == 2)
+    {
+      ret = this->firstNode->position *(1.0-t);
+      ret = ret + this->firstNode->next->position * t;
+    }
+  else if (nodeCount == 1)
+    ret = this->firstNode->position;
+  return ret;
+}
+
+/**
+ *  Calulates the direction of the Curve at time t.
+ * @param t The time at which to evaluate the curve.
+ * @returns The valuated Vector.
+*/
+Vector BezierCurve::calcDir (float t)
+{
+  return this->dirCurve->calcPos(t);
+}
+
+/**
+ *  Calulates the acceleration (second derivate) of the Curve at time t.
+ * @param t The time at which to evaluate the curve.
+ * @returns The valuated Vector.
+*/
+Vector BezierCurve::calcAcc (float t)
+{
+  return this->dirCurve->getDirCurve()->calcPos(t);
+}
+
+/**
+ *  Calculates the Quaternion needed for our rotations
+ * @param t The time at which to evaluate the cuve.
+ * @returns The evaluated Quaternion.
+*/
+Quaternion BezierCurve::calcQuat (float t)
+{
+  return Quaternion (calcDir(t), Vector(0,0,1));
+}
+
+
+/**
+  \brief returns the Position of the point calculated on the Curve
+  \return a Vector to the calculated position
+*/
+Vector BezierCurve::getPos() const
+{
+  return curvePoint;
+}
Index: branches/heathaze/src/lib/math/curve.h
===================================================================
--- branches/heathaze/src/lib/math/curve.h	(revision 9940)
+++ branches/heathaze/src/lib/math/curve.h	(revision 9940)
@@ -0,0 +1,116 @@
+
+/*!
+ * @file curve.h
+  *  A basic 3D curve framework
+
+    Contains classes to handle curves
+*/
+
+#ifndef _CURVE_H
+#define _CURVE_H
+
+#include "vector.h"
+#include "quaternion.h"
+
+template<class T> class tList;
+template<class T> class tIterator;
+
+//! An Enumerator that defines what sort of Curves are availible
+enum CurveType {
+  CURVE_BEZIER
+};
+
+
+//! An abstract class to handle curves. Needed for the Tracking system in orxonox.
+class Curve
+{
+ protected:
+  //! Handles the curve-points (dynamic List)
+  struct PathNode
+  {
+    int          number;       //!< The N-th node of this curve.
+    float        factor;       //!< Curve specific multiplier factor.
+    Vector       vFactor;      //!< A Vector-factor for multipliing.
+    Vector       position;     //!< Vector Pointung to this curve-point.
+    PathNode*    next;         //!< Pointer to the next Node.
+  };
+
+ public:
+  Curve();
+  virtual ~Curve();
+
+  void addNode(const Vector& newNode);
+  void addNode(const Vector& newNode, unsigned int insertPosition);
+  Vector getNode(unsigned int nodeToFind);
+  /** @returns the count of nodes in this curve */
+  inline int getNodeCount() const { return this->nodeCount; };
+  /** @returns the directional Curve */
+  Curve* getDirCurve() const { return this->dirCurve; };
+
+  /** @param t the value on the curve [0-1] @returns Vector to the position */
+  virtual Vector calcPos(float t) = 0;
+  /** @param t the value on the curve [0-1] @returns the direction */
+  virtual Vector calcDir(float t) = 0;
+  /** @param t the value on the curve [0-1] @returns the acceleration */
+  virtual Vector calcAcc(float t) = 0;
+  /** @param t the value on the curve [0-1] @returns quaternion of the rotation */
+  virtual Quaternion calcQuat(float t) = 0;
+
+  // DEBUG
+  void debug();
+
+ private:
+  /** \brief rebuilds the curve */
+  virtual void rebuild() = 0;
+
+ protected:
+  int                   nodeCount;       //!< The count of nodes the Curve has.
+  Vector                curvePoint;      //!< The point on the Cureve at a local Time.
+  float                 localTime;       //!< If the time of one point is asked more than once the programm will not calculate it again.
+  int                   derivation;      //!< Which derivation of a Curve is this.
+
+  Curve*                dirCurve;        //!< The derivation-curve of this Curve.
+
+  tList<PathNode>*      nodeList;        //!< A list of all the Nodes of a Curve.
+  tIterator<PathNode>*  nodeIterator;    //!< An iterator that should point to the current Node
+  PathNode*             firstNode;       //!< First node of the curve.
+  PathNode*             currentNode;     //!< The node we are working with (the Last node).
+
+};
+
+//!    Class to handle bezier curves in 3-dimesnsional space
+/**
+   This Curve is good, for Fast Interaction. If you want to change it during the game, go on.
+   !!be aware!! BezierCurves only flow through their first and last Node. Their Tangents at those Points a directed to the second and second-last Point.
+*/
+class BezierCurve : public Curve
+{
+ public:
+  BezierCurve();
+  BezierCurve(int derivation);
+  virtual ~BezierCurve();
+
+  virtual Vector calcPos(float t);
+  virtual Vector calcDir(float t);
+  virtual Vector calcAcc(float t);
+  virtual Quaternion calcQuat(float t);
+
+
+  Vector getPos() const;
+
+ private:
+  void rebuild();
+};
+
+
+//! B-Spline
+/**
+   class to handle b-spline in 3d space
+*/
+class BSplieCurve : public Curve
+{
+
+
+};
+
+#endif /* _CURVE_H */
Index: branches/heathaze/src/lib/math/line.cc
===================================================================
--- branches/heathaze/src/lib/math/line.cc	(revision 9940)
+++ branches/heathaze/src/lib/math/line.cc	(revision 9940)
@@ -0,0 +1,104 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Patrick Boenzli : Vector::scale()
+                                    Vector::abs()
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "line.h"
+#include "plane.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+
+
+/**
+ *  calculate the distance between two lines
+ * @param l: the other line
+ * @return the distance between the lines
+*/
+float Line::distance (const Line& l) const
+{
+  float q, d;
+  Vector n = a.cross(l.a);
+  q = n.dot(r-l.r);
+  d = n.len();
+  if( d == 0.0) return 0.0;
+  return q/d;
+}
+
+/**
+ *  calculate the distance between a line and a point
+ * @param v: the point
+ * @return the distance between the Line and the point
+*/
+float Line::distancePoint (const Vector& v) const
+{
+  Vector d = v-r;
+  Vector u = a * d.dot( a);
+  return (d - u).len();
+}
+
+/**
+ *  calculate the distance between a line and a point
+ * @param v: the point
+ * @return the distance between the Line and the point
+ */
+float Line::distancePoint (const sVec3D& v) const
+{
+  Vector s(v[0], v[1], v[2]);
+  Vector d = s - r;
+  Vector u = a * d.dot( a);
+  return (d - u).len();
+}
+
+/**
+ *  calculate the two points of minimal distance of two lines
+ * @param l: the other line
+ * @return a Vector[2] (!has to be deleted after use!) containing the two points of minimal distance
+*/
+Vector* Line::footpoints (const Line& l) const
+{
+  Vector* fp = new Vector[2];
+  Plane p = Plane (r + a.cross(l.a), r, r + a);
+  fp[1] = p.intersectLine (l);
+  p = Plane (fp[1], l.a);
+  fp[0] = p.intersectLine (*this);
+  return fp;
+}
+
+/**
+  \brief calculate the length of a line
+  \return the lenght of the line
+*/
+float Line::len() const
+{
+  return a.len();
+}
+
+/**
+ *  rotate the line by given rotation
+ * @param rot: a rotation
+*/
+void Line::rotate (const Rotation& rot)
+{
+  Vector t = a + r;
+  t = rotateVector( t, rot);
+  r = rotateVector( r, rot),
+  a = t - r;
+}
Index: branches/heathaze/src/lib/math/line.h
===================================================================
--- branches/heathaze/src/lib/math/line.h	(revision 9940)
+++ branches/heathaze/src/lib/math/line.h	(revision 9940)
@@ -0,0 +1,58 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+/*!
+ * @file line.h
+ * A basic 3D math line framework
+ *
+ * Contains class to handle lines
+*/
+
+#ifndef __LINE_H_
+#define __LINE_H_
+
+#include "compiler.h"
+#include "vector.h"
+#include "rotation_OBSOLETE.h"
+
+//! 3D line
+/**
+  Class to store Lines in 3-dimensional space
+
+  Supports line-to-line distance measurements and rotation
+*/
+class Line
+{
+  public:
+
+  Vector r;   //!< Offset
+  Vector a;   //!< Direction
+
+  Line ( Vector r, Vector a) : r(r), a(a) {}  //!< assignment constructor
+  Line () : r(Vector(0,0,0)), a(Vector (1,1,1)) {}
+  ~Line () {}
+
+  float distance (const Line& l) const;
+  float distancePoint (const Vector& v) const;
+  float distancePoint (const sVec3D& v) const;
+  Vector* footpoints (const Line& l) const;
+  float len () const;
+
+  void rotate(const Rotation& rot);
+};
+
+
+#endif /* __LINE_H_ */
+
Index: branches/heathaze/src/lib/math/matrix.cc
===================================================================
--- branches/heathaze/src/lib/math/matrix.cc	(revision 9940)
+++ branches/heathaze/src/lib/math/matrix.cc	(revision 9940)
@@ -0,0 +1,277 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+*/
+#include "matrix.h"
+#include <cmath>
+
+#ifdef DEBUG
+#include "debug.h"
+#else
+#include <stdio.h>
+#define PRINT(x) printf
+#endif
+
+/**
+ * constructs a Matrix from all Parameters in a Row
+ * @param m11 [0][0]
+ * @param m12 [0][1]
+ * @param m13 [0][2]
+ * @param m21 [1][0]
+ * @param m22 [1][1]
+ * @param m23 [1][2]
+ * @param m31 [2][0]
+ * @param m32 [2][1]
+ * @param m33 [2][2]
+ */
+Matrix::Matrix ( float m11, float m12, float m13,
+             float m21, float m22, float m23,
+             float m31, float m32, float m33 )
+{
+  this->m11 = m11; this->m12 = m12; this->m13 = m13;
+  this->m21 = m21; this->m22 = m22; this->m23 = m23;
+  this->m31 = m31; this->m32 = m32; this->m33 = m33;
+};
+
+/**
+ * creates a Matrix out of an Array of floats with size [3][3]
+ * @param m the Matrix stored in an Array
+ */
+Matrix::Matrix(const float m[3][3])
+{
+  this->m11 = m[0][0]; this->m12 = m[0][1]; this->m13 = m[0][2];
+  this->m21 = m[1][0]; this->m22 = m[1][1]; this->m23 = m[1][2];
+  this->m31 = m[2][0]; this->m32 = m[2][1]; this->m33 = m[2][2];
+};
+
+
+/**
+ * adds a Matrix to this one returning the result
+ * @param m the Matrix to add to this one
+ * @returns a copy of this Matrix added m
+ */
+Matrix Matrix::operator+ (const Matrix& m) const
+{
+  return Matrix (this->m11 + m.m11, this->m12 + m.m12, this->m13 + m.m13,
+                 this->m21 + m.m21, this->m22 + m.m22, this->m23 + m.m23,
+                 this->m31 + m.m31, this->m32 + m.m32, this->m33 + m.m33);
+}
+
+/**
+ * sustracts a Matrix from this one returning the result
+ * @param m the Matrix to substract from this one
+ * @returns a copy of this Matrix substracted m
+ */
+Matrix Matrix::operator- (const Matrix& m) const
+{
+  return Matrix (this->m11 - m.m11, this->m12 - m.m12, this->m13 - m.m13,
+                 this->m21 - m.m21, this->m22 - m.m22, this->m23 - m.m23,
+                 this->m31 - m.m31, this->m32 - m.m32, this->m33 - m.m33);
+}
+
+/**
+ * multiplies each value of a copu of this Matrix by k
+ * @param k the multiplication factor
+ * @returns a copy of this Matrix multiplied by k
+ */
+Matrix Matrix::operator* (float k) const
+{
+  return Matrix(this->m11 * k, this->m12 * k, this->m13 * k,
+                this->m21 * k, this->m22 * k, this->m23 * k,
+                this->m31 * k, this->m32 * k, this->m33 * k);
+}
+
+/**
+ * multiplies the Matrix by a Vector returning a Vector of the result
+ * @param v the Vector the matrix will be multiplied with
+ * @returns the result of the Multiplication
+ */
+Vector Matrix::operator* (const Vector& v) const
+{
+  return Vector (this->m11*v.x + this->m12*v.y + this->m13*v.z,
+                 this->m21*v.x + this->m22*v.y + this->m23*v.z,
+                 this->m31*v.x + this->m32*v.y + this->m33*v.z );
+}
+
+/**
+ * @returns a Transposed copy of this Matrix
+ */
+Matrix Matrix::getTransposed() const
+{
+  return Matrix( this->m11, this->m21, this->m31,
+                 this->m12, this->m22, this->m32,
+                 this->m13, this->m23, this->m33);
+}
+
+/**
+ * converts the Matrix into 3 Vector, and returns them in m1, m2 and m3
+ * @param m1 the first Column of the Matrix as a Vector
+ * @param m2 the second Column of the Matrix as a Vector
+ * @param m3 the third Column of the Matrix as a Vector
+ */
+void Matrix::toVectors(Vector& m1, Vector& m2, Vector& m3) const
+{
+  m1 = Vector(this->m11, this->m21, this->m31);
+  m2 = Vector(this->m12, this->m22, this->m32);
+  m3 = Vector(this->m13, this->m23, this->m33);
+}
+
+/**
+ * @returns the Determinant of this Matrix
+ */
+float Matrix::getDeterminant() const
+{
+  return this->m11*(this->m22*this->m33 - this->m23*this->m32) -
+      this->m12*(this->m21*this->m33 - this->m23*this->m31) +
+      this->m13*(this->m21*this->m32 - this->m22*this->m31);
+}
+
+/**
+ * calculates an returns the EingenValues of this Matrix.
+ * @param eigneValues the Values calculated in a Vector
+ * @returns the Count of found eigenValues
+ *
+ * This Function calculates the EigenValues of a 3x3-Matrix explicitly.
+ * the Returned value eigenValues has the Values stored in Vector form
+ * The Vector will be filled upside down, meaning if the count of found
+ * eingenValues is 1 the only value will be located in eigneValues.x
+ */
+int Matrix::getEigenValues(Vector& eigenValues) const
+{
+  int retVal = -1;
+  float a = 0;
+  float b = 0;
+
+  float c[3];
+
+  // c[0] is the determinante of mat
+  c[0] = this->m11 * this->m22 * this->m33 +
+      2* this->m12 * this->m13 * this->m23 -
+      this->m11 * this->m23 * this->m23 -
+      this->m22 * this->m13 * this->m13 -
+      this->m33 * this->m12 * this->m12;
+
+  // c[1] is the trace of a
+  c[1] = this->m11 * this->m22 -
+      this->m12 * this->m12 +
+      this->m11 * this->m33 -
+      this->m13 * this->m13 +
+      this->m22 * this->m33 -
+      this->m23 * this->m23;
+
+  // c[2] is the sum of the diagonal elements
+  c[2] = this->m11 +
+      this->m22 +
+      this->m33;
+
+
+  // Computing the roots:
+  a = (3.0*c[1] - c[2]*c[2]) / 3.0;
+  b = (-2.0*c[2]*c[2]*c[2] + 9.0*c[1]*c[2] - 27.0*c[0]) / 27.0;
+
+  float Q = b*b/4.0 + a*a*a/27.0;
+
+  // 3 distinct Roots
+  if (Q < 0)
+  {
+    float psi = atan2(sqrt(-Q), -b/2.0);
+    float p = sqrt((b/2.0)*(b/2.0) - Q);
+
+    eigenValues.x = c[2]/3.0 + 2 * pow(p, 1/3.0) * cos(psi/3.0);
+    eigenValues.y = c[2]/3.0 - pow(p, 1/3.0) * (cos(psi/3.0)
+        + sqrt(3.0) * sin(psi/3.0));
+    eigenValues.z = c[2]/3.0 - pow(p, 1/3.0) * (cos(psi/3.0)
+        - sqrt(3.0) * sin(psi/3.0));
+    retVal = 3;
+  }
+  // 2 Distinct Roots
+  else if (Q == 0)
+  {
+    eigenValues.x = eigenValues.y = c[2]/3.0 + pow(b/2.0, 1.0/3.0);
+    eigenValues.z = c[2]/3.0 + 2* pow(b/2.0, 1.0/3.0);
+    retVal = 2;
+  }
+  // 1 Root (not calculating anything.)
+  else if (Q > 0)
+  {
+    eigenValues.x = eigenValues.y = eigenValues.z = 1;
+    retVal = 1;
+  }
+  return retVal;
+}
+
+/**
+ * calculates and returns the EigenVectors of this function as Vectors.
+ * @param eigVc1 the first eigenVector will be stored here.
+ * @param eigVc2 the second eigenVector will be stored here.
+ * @param eigVc3 the third eigenVector will be stored here.
+ */
+void Matrix::getEigenVectors(Vector& eigVc1, Vector& eigVc2, Vector& eigVc3) const
+{
+  Vector eigenValues;
+  int eigenValuesCount = this->getEigenValues(eigenValues);
+
+  if (eigenValuesCount == 2 || eigenValuesCount == 3)
+  {
+    /* eigenvec creation */
+    eigVc1.x = -1/this->m13*(this->m33 - eigenValues.x) +
+        (this->m32*(-this->m31*this->m32 + this->m12*this->m33 - this->m12*eigenValues.x)) /
+        this->m13*(-this->m13*this->m22 - this->m12*this->m23 + this->m13*eigenValues.x);
+
+    eigVc1.y = -( -this->m13*this->m23 + this->m12*this->m33 - this->m12*eigenValues.x) /
+        (-this->m31*this->m22 + this->m12*this->m23 + this->m13*eigenValues.x);
+
+    eigVc1.z = 1.0f;
+
+    eigVc2.x = -1/this->m13*(this->m33 - eigenValues.y) +
+        (this->m32*(-this->m31*this->m32 + this->m12*this->m33 - this->m12*eigenValues.y)) /
+        this->m13*(-this->m13*this->m22 - this->m12*this->m23 + this->m13*eigenValues.y);
+
+    eigVc2.y = -( -this->m13*this->m23 + this->m12*this->m33 - this->m12*eigenValues.y) /
+        (-this->m31*this->m22 + this->m12*this->m23 + this->m13*eigenValues.y);
+
+    eigVc2.z = 1.0f;
+
+    eigVc3 = eigVc1.cross(eigVc2);
+
+    eigVc2 = eigVc3.cross(eigVc1);
+  }
+  else if (eigenValuesCount == 1)
+  {
+    eigVc1 = Vector(1,0,0);
+    eigVc2 = Vector(0,1,0);
+    eigVc3 = Vector(0,0,1);
+  }
+  eigVc1.normalize();
+  eigVc2.normalize();
+  eigVc3.normalize();
+
+  if (!(eigVc1.cross(eigVc3) == eigVc2))
+  {
+    eigVc3.cross(eigVc1);
+//     eigVc2.debug();
+  }
+/*  printf("ok\n")*/;
+}
+
+/**
+ * prints out some nice debug information
+ */
+void Matrix::debug() const
+{
+  printf("| %f | %f | %f |\n", this->m11, this->m12, this->m13 );
+  printf("| %f | %f | %f |\n", this->m21, this->m22, this->m23 );
+  printf("| %f | %f | %f |\n", this->m31, this->m32, this->m33 );
+
+}
+
Index: branches/heathaze/src/lib/math/matrix.h
===================================================================
--- branches/heathaze/src/lib/math/matrix.h	(revision 9940)
+++ branches/heathaze/src/lib/math/matrix.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file matrix.h
+ * @brief Definition of a 3x3 matrix.
+ */
+
+#include "vector.h"
+
+//! Matrix is a 3x3 Matrix class with most important functions
+class Matrix
+{
+  public:
+    Matrix() : m11(0), m12(0), m13(0), m21(0), m22(0), m23(0), m31(0), m32(0), m33(0) { };
+
+    Matrix ( float m11, float m12, float m13,
+             float m21, float m22, float m23,
+             float m31, float m32, float m33 );
+    Matrix(const float m[3][3]);
+
+    Matrix operator+ (const Matrix& m) const;
+    Matrix operator- (const Matrix& m) const;
+    Matrix operator* (float k) const;
+    Vector operator* (const Vector& v) const;
+
+    Matrix getTransposed() const;
+    void toVectors(Vector& m1, Vector& m2, Vector& m3) const;
+
+    float getDeterminant() const;
+
+    int getEigenValues(Vector& eigenVectors) const;
+    void getEigenVectors(Vector& a, Vector& b, Vector& c) const;
+
+    /** @returns the Identity-Matrix (diagonal 3x3 with 1's everywhere) */
+    static Matrix identity() { return Matrix(1,0,0, 0,1,0, 0,0,1); }
+
+    void debug() const;
+
+  public:
+    float m11;              //!< Matrix Entry [0][0]
+          float m12;        //!< Matrix Entry [0][1]
+                float m13;  //!< Matrix Entry [0][2]
+    float m21;              //!< Matrix Entry [1][0]
+          float m22;        //!< Matrix Entry [1][1]
+                float m23;  //!< Matrix Entry [1][2]
+    float m31;              //!< Matrix Entry [2][0]
+          float m32;        //!< Matrix Entry [2][1]
+                float m33;  //!< Matrix Entry [2][2]
+};
Index: branches/heathaze/src/lib/math/plane.cc
===================================================================
--- branches/heathaze/src/lib/math/plane.cc	(revision 9940)
+++ branches/heathaze/src/lib/math/plane.cc	(revision 9940)
@@ -0,0 +1,360 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "plane.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+
+
+/**
+ *  create a rotation from a vector
+ * @param v: a vector
+*/
+Rotation::Rotation (const Vector& v)
+{
+  Vector x = Vector( 1, 0, 0);
+  Vector axis = x.cross( v);
+  axis.normalize();
+  float angle = angleRad( x, v);
+  float ca = cos(angle);
+  float sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+ *  creates a rotation from an axis and an angle (radians!)
+ * @param axis: the rotational axis
+ * @param angle: the angle in radians
+*/
+Rotation::Rotation (const Vector& axis, float angle)
+{
+  float ca, sa;
+  ca = cos(angle);
+  sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+ *  creates a rotation from euler angles (pitch/yaw/roll)
+ * @param pitch: rotation around z (in radians)
+ * @param yaw: rotation around y (in radians)
+ * @param roll: rotation around x (in radians)
+*/
+Rotation::Rotation ( float pitch, float yaw, float roll)
+{
+  float cy, sy, cr, sr, cp, sp;
+  cy = cos(yaw);
+  sy = sin(yaw);
+  cr = cos(roll);
+  sr = sin(roll);
+  cp = cos(pitch);
+  sp = sin(pitch);
+  m[0] = cy*cr;
+  m[1] = -cy*sr;
+  m[2] = sy;
+  m[3] = cp*sr+sp*sy*cr;
+  m[4] = cp*cr-sp*sr*sy;
+  m[5] = -sp*cy;
+  m[6] = sp*sr-cp*sy*cr;
+  m[7] = sp*cr+cp*sy*sr;
+  m[8] = cp*cy;
+}
+
+/**
+ *  creates a nullrotation (an identity rotation)
+*/
+Rotation::Rotation ()
+{
+  m[0] = 1.0f;
+  m[1] = 0.0f;
+  m[2] = 0.0f;
+  m[3] = 0.0f;
+  m[4] = 1.0f;
+  m[5] = 0.0f;
+  m[6] = 0.0f;
+  m[7] = 0.0f;
+  m[8] = 1.0f;
+}
+
+/**
+ *  fills the specified buffer with a 4x4 glmatrix
+ * @param buffer: Pointer to an array of 16 floats
+
+   Use this to get the rotation in a gl-compatible format
+*/
+void Rotation::glmatrix (float* buffer)
+{
+        buffer[0] = m[0];
+        buffer[1] = m[3];
+        buffer[2] = m[6];
+        buffer[3] = m[0];
+        buffer[4] = m[1];
+        buffer[5] = m[4];
+        buffer[6] = m[7];
+        buffer[7] = m[0];
+        buffer[8] = m[2];
+        buffer[9] = m[5];
+        buffer[10] = m[8];
+        buffer[11] = m[0];
+        buffer[12] = m[0];
+        buffer[13] = m[0];
+        buffer[14] = m[0];
+        buffer[15] = m[1];
+}
+
+/**
+ *  multiplies two rotational matrices
+ * @param r: another Rotation
+ * @return the matrix product of the Rotations
+
+   Use this to rotate one rotation by another
+*/
+Rotation Rotation::operator* (const Rotation& r)
+{
+        Rotation p;
+
+        p.m[0] = m[0]*r.m[0] + m[1]*r.m[3] + m[2]*r.m[6];
+        p.m[1] = m[0]*r.m[1] + m[1]*r.m[4] + m[2]*r.m[7];
+        p.m[2] = m[0]*r.m[2] + m[1]*r.m[5] + m[2]*r.m[8];
+
+        p.m[3] = m[3]*r.m[0] + m[4]*r.m[3] + m[5]*r.m[6];
+        p.m[4] = m[3]*r.m[1] + m[4]*r.m[4] + m[5]*r.m[7];
+        p.m[5] = m[3]*r.m[2] + m[4]*r.m[5] + m[5]*r.m[8];
+
+        p.m[6] = m[6]*r.m[0] + m[7]*r.m[3] + m[8]*r.m[6];
+        p.m[7] = m[6]*r.m[1] + m[7]*r.m[4] + m[8]*r.m[7];
+        p.m[8] = m[6]*r.m[2] + m[7]*r.m[5] + m[8]*r.m[8];
+
+        return p;
+}
+
+
+/**
+ *  rotates the vector by the given rotation
+ * @param v: a vector
+ * @param r: a rotation
+ * @return the rotated vector
+*/
+Vector rotateVector( const Vector& v, const Rotation& r)
+{
+  Vector t;
+
+  t.x = v.x * r.m[0] + v.y * r.m[1] + v.z * r.m[2];
+  t.y = v.x * r.m[3] + v.y * r.m[4] + v.z * r.m[5];
+  t.z = v.x * r.m[6] + v.y * r.m[7] + v.z * r.m[8];
+
+  return t;
+}
+
+/**
+ *  calculate the distance between two lines
+ * @param l: the other line
+ * @return the distance between the lines
+*/
+float Line::distance (const Line& l) const
+{
+  float q, d;
+  Vector n = a.cross(l.a);
+  q = n.dot(r-l.r);
+  d = n.len();
+  if( d == 0.0) return 0.0;
+  return q/d;
+}
+
+/**
+ *  calculate the distance between a line and a point
+ * @param v: the point
+ * @return the distance between the Line and the point
+*/
+float Line::distancePoint (const Vector& v) const
+{
+  Vector d = v-r;
+  Vector u = a * d.dot( a);
+  return (d - u).len();
+}
+
+/**
+ *  calculate the distance between a line and a point
+ * @param v: the point
+ * @return the distance between the Line and the point
+ */
+float Line::distancePoint (const sVec3D& v) const
+{
+  Vector s(v[0], v[1], v[2]);
+  Vector d = s - r;
+  Vector u = a * d.dot( a);
+  return (d - u).len();
+}
+
+
+/**
+ *  calculate the two points of minimal distance of two lines
+ * @param l: the other line
+ * @return a Vector[2] (!has to be deleted after use!) containing the two points of minimal distance
+*/
+Vector* Line::footpoints (const Line& l) const
+{
+  Vector* fp = new Vector[2];
+  Plane p = Plane (r + a.cross(l.a), r, r + a);
+  fp[1] = p.intersectLine (l);
+  p = Plane (fp[1], l.a);
+  fp[0] = p.intersectLine (*this);
+  return fp;
+}
+
+/**
+  \brief calculate the length of a line
+  \return the lenght of the line
+*/
+float Line::len() const
+{
+  return a.len();
+}
+
+/**
+ *  rotate the line by given rotation
+ * @param rot: a rotation
+*/
+void Line::rotate (const Rotation& rot)
+{
+  Vector t = a + r;
+  t = rotateVector( t, rot);
+  r = rotateVector( r, rot),
+  a = t - r;
+}
+
+/**
+ *  create a plane from three points
+ * @param a: first point
+ * @param b: second point
+ * @param c: third point
+*/
+Plane::Plane (const Vector& a, const Vector& b, const Vector& c)
+{
+  n = (a-b).cross(c-b);
+  k = n.dot(a) / n.len();
+}
+
+/**
+ *  create a plane from anchor point and normal
+ * @param norm: normal vector
+ * @param p: anchor point
+*/
+Plane::Plane (const Vector& norm, const Vector& p)
+{
+  n = norm;
+  k = n.dot(p) / n.len();
+}
+
+
+/**
+  *  create a plane from anchor point and normal
+  * @param norm: normal vector
+  * @param p: anchor point
+*/
+Plane::Plane (const Vector& norm, const sVec3D& g)
+{
+  Vector p(g[0], g[1], g[2]);
+  n = norm;
+  k = n.dot(p) / n.len();
+}
+
+
+/**
+ *  returns the intersection point between the plane and a line
+ * @param l: a line
+*/
+Vector Plane::intersectLine (const Line& l) const
+{
+  if (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z == 0.0) return Vector(0,0,0);
+  float t = (n.x*l.r.x+n.y*l.r.y+n.z*l.r.z+k) / (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z);
+  return l.r + (l.a * t);
+}
+
+/**
+ *  returns the distance between the plane and a point
+ * @param p: a Point
+ * @return the distance between the plane and the point (can be negative)
+*/
+float Plane::distancePoint (const Vector& p) const
+{
+  float l = n.len();
+  if( l == 0.0) return 0.0;
+  return (n.dot(p) / n.len() - k);
+}
+
+
+/**
+ *  returns the distance between the plane and a point
+ * @param p: a Point
+ * @return the distance between the plane and the point (can be negative)
+ */
+// float Plane::distancePoint (const sVec3D& p) const
+// {
+//   Vector s(p[0], p[1], p[2]);
+//   float l = n.len();
+//   if( l == 0.0) return 0.0;
+//   return (n.dot(s) + k) / n.len();
+// }
+
+
+/**
+ *  returns the distance between the plane and a point
+ * @param p: a Point
+ * @return the distance between the plane and the point (can be negative)
+ */
+float Plane::distancePoint (const float* p) const
+{
+  Vector s(p[0], p[1], p[2]);
+
+  float l = n.len();
+  if( l == 0.0) return 0.0;
+  return (n.dot(s) / n.len() - k);
+}
+
+
+/**
+ *  returns the side a point is located relative to a Plane
+ * @param p: a Point
+ * @return 0 if the point is contained within the Plane, positive(negative) if the point is in the positive(negative) semi-space of the Plane
+*/
+float Plane::locatePoint (const Vector& p) const
+{
+  return (n.dot(p) + k);
+}
+
Index: branches/heathaze/src/lib/math/plane.h
===================================================================
--- branches/heathaze/src/lib/math/plane.h	(revision 9940)
+++ branches/heathaze/src/lib/math/plane.h	(revision 9940)
@@ -0,0 +1,89 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+/*!
+ * @file plane.h
+ * A basic 3D plane math framework
+ *
+ * Contains class to handle planes
+*/
+
+#ifndef __PLANE_H_
+#define __PLANE_H_
+
+#include "compiler.h"
+#include "vector.h"
+#include "line.h"
+
+//! 3D plane
+/**
+  Class to handle planes in 3-dimensional space
+
+  Critical for polygon-based collision detection
+*/
+class Plane
+{
+  public:
+
+  Vector n;   //!< Normal vector
+  float k;    //!< Offset constant
+
+  Plane (const Vector& a, const Vector& b, const Vector& c);
+  Plane (const Vector& norm, const Vector& p);
+  Plane (const Vector& norm, const sVec3D& p);
+  Plane (const Vector& n, float k) : n(n), k(k) {} //!< assignment constructor
+  Plane () : n(Vector(1,1,1)), k(0) {}
+  ~Plane () {}
+
+  Vector intersectLine (const Line& l) const;
+  float distancePoint (const Vector& p) const;
+//   float distancePoint (const sVec3D& p) const;
+  float distancePoint (const float* p) const;
+  float locatePoint (const Vector& p) const;
+};
+
+
+
+//! A class that represents a rectangle, this is needed for SpatialSeparation
+class Rectangle
+{
+
+  public:
+    Rectangle() { this->center = Vector(); }
+    Rectangle(const Vector &center, float len) { this->center = Vector(center.x, center.y, center.z); this->axis[0] = len; this->axis[1] = len; }
+    virtual ~Rectangle() {}
+
+    /** \brief sets the center of the rectangle to a defined vector @param center the new center */
+   inline void setCenter(const Vector &center) { this->center = center;}
+    /** \brief sets the center of the rectangle to a defined vector @param x coord of the center @param y coord of the center @param z coord of the center */
+   inline void setCenter(float x, float y, float z) { this->center.x = x; this->center.y = y; this->center.z = z; }
+   /** \brief returns the center of the rectangle to a defined vector @returns center the new center */
+   inline const Vector& getCenter() const { return this->center; }
+
+   /** \brief sets both axis of the rectangle to a defined vector @param unityLength the new center */
+   inline void setAxis(float unityLength) { this->axis[0] = unityLength; this->axis[1] = unityLength; }
+   /** \brief sets both axis of the rectangle to a defined vector @param v1 the length of the x axis @param v2 the length of the z axis*/
+   inline void setAxis(float v1, float v2) { this->axis[0] = v1; this->axis[1] = v2; }
+   /** \brief gets one axis length of the rectangle  @returns the length of the axis 0 */
+   inline float getAxis() { return this-> axis[0]; }
+
+  private:
+    Vector          center;
+    float           axis[2];
+};
+
+
+#endif /* __PLANE_H_ */
+
Index: branches/heathaze/src/lib/math/quaternion.cc
===================================================================
--- branches/heathaze/src/lib/math/quaternion.cc	(revision 9940)
+++ branches/heathaze/src/lib/math/quaternion.cc	(revision 9940)
@@ -0,0 +1,421 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Patrick Boenzli : Vector::scale()
+                                    Vector::abs()
+
+   Quaternion code borrowed from an Gamasutra article by Nick Bobick and Ken Shoemake
+
+   2005-06-02: Benjamin Grauer: speed up, and new Functionality to Vector (mostly inline now)
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "quaternion.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+/////////////////
+/* QUATERNIONS */
+/////////////////
+/**
+ * @brief calculates a lookAt rotation
+ * @param dir: the direction you want to look
+ * @param up: specify what direction up should be
+ *
+ * Mathematically this determines the rotation a (0,0,1)-Vector has to undergo to point
+ * the same way as dir. If you want to use this with cameras, you'll have to reverse the
+ * dir Vector (Vector(0,0,0) - your viewing direction) or you'll point the wrong way. You
+ * can use this for meshes as well (then you do not have to reverse the vector), but keep
+ * in mind that if you do that, the model's front has to point in +z direction, and left
+ * and right should be -x or +x respectively or the mesh wont rotate correctly.
+ *
+ * @TODO !!! OPTIMIZE THIS !!!
+ */
+Quaternion::Quaternion (const Vector& dir, const Vector& up)
+{
+  Vector z = dir.getNormalized();
+  Vector x = up.cross(z).getNormalized();
+  Vector y = z.cross(x);
+
+  float m[4][4];
+  m[0][0] = x.x;
+  m[0][1] = x.y;
+  m[0][2] = x.z;
+  m[0][3] = 0.0;
+  m[1][0] = y.x;
+  m[1][1] = y.y;
+  m[1][2] = y.z;
+  m[1][3] = 0.0;
+  m[2][0] = z.x;
+  m[2][1] = z.y;
+  m[2][2] = z.z;
+  m[2][3] = 0.0;
+  m[3][0] = 0.0;
+  m[3][1] = 0.0;
+  m[3][2] = 0.0;
+  m[3][3] = 1.0;
+
+  this->from4x4(m);
+}
+
+/**
+ * @brief calculates a rotation from euler angles
+ * @param roll: the roll in radians
+ * @param pitch: the pitch in radians
+ * @param yaw: the yaw in radians
+ */
+Quaternion::Quaternion (float roll, float pitch, float yaw)
+{
+  float cr, cp, cy, sr, sp, sy, cpcy, spsy;
+
+  // calculate trig identities
+  cr = cos(roll/2);
+  cp = cos(pitch/2);
+  cy = cos(yaw/2);
+
+  sr = sin(roll/2);
+  sp = sin(pitch/2);
+  sy = sin(yaw/2);
+
+  cpcy = cp * cy;
+  spsy = sp * sy;
+
+  w = cr * cpcy + sr * spsy;
+  v.x = sr * cpcy - cr * spsy;
+  v.y = cr * sp * cy + sr * cp * sy;
+  v.z = cr * cp * sy - sr * sp * cy;
+}
+
+/**
+ * @brief convert the Quaternion to a 4x4 rotational glMatrix
+ * @param m: a buffer to store the Matrix in
+ */
+void Quaternion::matrix (float m[4][4]) const
+{
+  float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
+
+  // calculate coefficients
+  x2 = v.x + v.x;
+  y2 = v.y + v.y;
+  z2 = v.z + v.z;
+  xx = v.x * x2; xy = v.x * y2; xz = v.x * z2;
+  yy = v.y * y2; yz = v.y * z2; zz = v.z * z2;
+  wx = w * x2; wy = w * y2; wz = w * z2;
+
+  m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz;
+  m[2][0] = xz + wy; m[3][0] = 0.0;
+
+  m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz);
+  m[2][1] = yz - wx; m[3][1] = 0.0;
+
+  m[0][2] = xz - wy; m[1][2] = yz + wx;
+  m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0;
+
+  m[0][3] = 0; m[1][3] = 0;
+  m[2][3] = 0; m[3][3] = 1;
+}
+
+
+
+/**
+ * @brief Slerps this QUaternion performs a smooth move.
+ * @param toQuat to this Quaternion
+ * @param t \% inth the the direction[0..1]
+ */
+void Quaternion::slerpTo(const Quaternion& toQuat, float t)
+{
+  float tol[4];
+  double omega, cosom, sinom, scale0, scale1;
+  //  float DELTA = 0.2;
+
+  cosom = this->v.x * toQuat.v.x + this->v.y * toQuat.v.y + this->v.z * toQuat.v.z + this->w * toQuat.w;
+
+  if( cosom < 0.0 )
+  {
+    cosom = -cosom;
+    tol[0] = -toQuat.v.x;
+    tol[1] = -toQuat.v.y;
+    tol[2] = -toQuat.v.z;
+    tol[3] = -toQuat.w;
+  }
+  else
+  {
+    tol[0] = toQuat.v.x;
+    tol[1] = toQuat.v.y;
+    tol[2] = toQuat.v.z;
+    tol[3] = toQuat.w;
+  }
+
+  omega = acos(cosom);
+  sinom = sin(omega);
+  scale0 = sin((1.0 - t) * omega) / sinom;
+  scale1 = sin(t * omega) / sinom;
+  this->v = Vector(scale0 * this->v.x + scale1 * tol[0],
+                   scale0 * this->v.y + scale1 * tol[1],
+                   scale0 * this->v.z + scale1 * tol[2]);
+  this->w = scale0 * this->w + scale1 * tol[3];
+}
+
+
+/**
+ * @brief performs a smooth move.
+ * @param from  where
+ * @param to where
+ * @param t the time this transformation should take value [0..1]
+ * @returns the Result of the smooth move
+ */
+Quaternion Quaternion::quatSlerp(const Quaternion& from, const Quaternion& to, float t)
+{
+  float tol[4];
+  double omega, cosom, sinom, scale0, scale1;
+  //  float DELTA = 0.2;
+
+  cosom = from.v.x * to.v.x + from.v.y * to.v.y + from.v.z * to.v.z + from.w * to.w;
+
+  if( cosom < 0.0 )
+  {
+    cosom = -cosom;
+    tol[0] = -to.v.x;
+    tol[1] = -to.v.y;
+    tol[2] = -to.v.z;
+    tol[3] = -to.w;
+  }
+  else
+  {
+    tol[0] = to.v.x;
+    tol[1] = to.v.y;
+    tol[2] = to.v.z;
+    tol[3] = to.w;
+  }
+
+  omega = acos(cosom);
+  sinom = sin(omega);
+  scale0 = sin((1.0 - t) * omega) / sinom;
+  scale1 = sin(t * omega) / sinom;
+  return Quaternion(Vector(scale0 * from.v.x + scale1 * tol[0],
+                           scale0 * from.v.y + scale1 * tol[1],
+                           scale0 * from.v.z + scale1 * tol[2]),
+                    scale0 * from.w + scale1 * tol[3]);
+}
+
+/**
+ * @returns the Heading
+ */
+float Quaternion::getHeading() const
+{
+  float pole = this->v.x*this->v.y + this->v.z*this->w;
+  if (fabsf(pole) != 0.5)
+    return atan2(2.0* (v.y*w - v.x*v.z), 1 - 2.0*(v.y*v.y - v.z*v.z));
+  else if (pole == .5) // North Pole
+    return 2.0 * atan2(v.x, w);
+  else // South Pole
+    return -2.0 * atan2(v.x, w);
+}
+
+/**
+ * @returns the Heading-Quaternion
+ */
+Quaternion Quaternion::getHeadingQuat() const
+{
+  return Quaternion(this->getHeading(), Vector(0,1,0));
+}
+
+/**
+ * @returns the Attitude
+ */
+float Quaternion::getAttitude() const
+{
+  return asin(2.0 * (v.x*v.y + v.z*w));
+}
+
+/**
+ * @returns the Attitude-Quaternion
+ */
+Quaternion Quaternion::getAttitudeQuat() const
+{
+  return Quaternion(this->getAttitude(), Vector(0,0,1));
+}
+
+
+/**
+ * @returns the Bank
+ */
+float Quaternion::getBank() const
+{
+  if (fabsf(this->v.x*this->v.y + this->v.z*this->w) != 0.5)
+    return atan2(2.0*(v.x*w-v.y*v.z) , 1 - 2.0*(v.x*v.x - v.z*v.z));
+  else
+    return 0.0f;
+}
+
+/**
+ * @returns the Bank-Quaternion
+ */
+Quaternion Quaternion::getBankQuat() const
+{
+  return Quaternion(this->getBank(), Vector(1,0,0));
+}
+
+
+
+/**
+ * @brief convert a rotational 4x4 glMatrix into a Quaternion
+ * @param m: a 4x4 matrix in glMatrix order
+ */
+void Quaternion::from4x4(float m[4][4])
+{
+
+  float  tr, s, q[4];
+  int    i, j, k;
+
+  static int nxt[3] = {1, 2, 0};
+
+  tr = m[0][0] + m[1][1] + m[2][2];
+
+  // check the diagonal
+  if (tr > 0.0)
+  {
+    s = sqrt (tr + 1.0);
+    w = s / 2.0;
+    s = 0.5 / s;
+    v.x = (m[1][2] - m[2][1]) * s;
+    v.y = (m[2][0] - m[0][2]) * s;
+    v.z = (m[0][1] - m[1][0]) * s;
+  }
+  else
+  {
+    // diagonal is negative
+    i = 0;
+    if (m[1][1] > m[0][0]) i = 1;
+    if (m[2][2] > m[i][i]) i = 2;
+    j = nxt[i];
+    k = nxt[j];
+
+    s = sqrt ((m[i][i] - (m[j][j] + m[k][k])) + 1.0);
+
+    q[i] = s * 0.5;
+
+    if (s != 0.0) s = 0.5 / s;
+
+    q[3] = (m[j][k] - m[k][j]) * s;
+    q[j] = (m[i][j] + m[j][i]) * s;
+    q[k] = (m[i][k] + m[k][i]) * s;
+
+    v.x = q[0];
+    v.y = q[1];
+    v.z = q[2];
+    w = q[3];
+  }
+}
+
+
+/**
+ * applies a quaternion from a 3x3 rotation matrix.
+ * @param mat The 3x3 source rotation matrix.
+ * @return The equivalent 4 float quaternion.
+ */
+void Quaternion::from3x3(float mat[3][3])
+{
+  int   NXT[] = {1, 2, 0};
+  float q[4];
+
+  // check the diagonal
+  float tr = mat[0][0] + mat[1][1] + mat[2][2];
+  if( tr > 0.0f)
+  {
+    float s = (float)sqrtf(tr + 1.0f);
+    this->w = s * 0.5f;
+    s = 0.5f / s;
+    this->v.x = (mat[1][2] - mat[2][1]) * s;
+    this->v.y = (mat[2][0] - mat[0][2]) * s;
+    this->v.z = (mat[0][1] - mat[1][0]) * s;
+  }
+  else
+  {
+    // diagonal is negative
+    // get biggest diagonal element
+    int i = 0;
+    if (mat[1][1] > mat[0][0]) i = 1;
+    if (mat[2][2] > mat[i][i]) i = 2;
+    //setup index sequence
+    int j = NXT[i];
+    int k = NXT[j];
+
+    float s = (float)sqrtf((mat[i][i] - (mat[j][j] + mat[k][k])) + 1.0f);
+
+    q[i] = s * 0.5f;
+
+    if (s != 0.0f) s = 0.5f / s;
+
+    q[j] = (mat[i][j] + mat[j][i]) * s;
+    q[k] = (mat[i][k] + mat[k][i]) * s;
+    q[3] = (mat[j][k] - mat[k][j]) * s;
+
+    this->v.x = q[0];
+    this->v.y = q[1];
+    this->v.z = q[2];
+    this->w   = q[3];
+  }
+}
+
+Quaternion Quaternion::lookAt(Vector from, Vector to, Vector up)
+{
+  Vector n = to - from;
+  n.normalize();
+  Vector v = n.cross(up);
+  v.normalize();
+  Vector u = v.cross(n);
+
+  float matrix[3][3];
+  matrix[0][0] = v.x;
+  matrix[0][1] = v.y;
+  matrix[0][2] = v.z;
+  matrix[1][0] = u.x;
+  matrix[1][1] = u.y;
+  matrix[1][2] = u.z;
+  matrix[2][0] = -n.x;
+  matrix[2][1] = -n.y;
+  matrix[2][2] = -n.z;
+
+  Quaternion quat;
+  quat.from3x3(matrix);
+  return quat;
+}
+
+
+/**
+ * @brief outputs some nice formated debug information about this quaternion
+*/
+void Quaternion::debug() const
+{
+  PRINT(0)("real a=%f; imag: x=%f y=%f z=%f\n", w, v.x, v.y, v.z);
+}
+
+/**
+ * @brief another better Quaternion Debug Function.
+ */
+void Quaternion::debug2() const
+{
+  Vector axis = this->getSpacialAxis();
+  PRINT(0)("angle = %f, axis: ax=%f, ay=%f, az=%f\n", this->getSpacialAxisAngle(), axis.x, axis.y, axis.z );
+}
+
+
+
+
+
+
Index: branches/heathaze/src/lib/math/quaternion.h
===================================================================
--- branches/heathaze/src/lib/math/quaternion.h	(revision 9940)
+++ branches/heathaze/src/lib/math/quaternion.h	(revision 9940)
@@ -0,0 +1,135 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+/*!
+ * @file quaternion.h
+ * A basic 3D quaternion math framework
+ *
+ * Contains classes to handle vectors, lines, rotations and planes
+*/
+
+#ifndef __QUATERNION_H_
+#define __QUATERNION_H_
+
+#include "compiler.h"
+#include "vector.h"
+
+//! Quaternion
+/**
+   Class to handle 3-dimensional rotation efficiently
+*/
+class Quaternion
+{
+  public:
+    /** creates a Default quaternion (multiplicational identity Quaternion)*/
+    inline Quaternion () { w = 1; v = Vector(0,0,0); }
+    /** Copy constructor @param q the Quaternion to copy. */
+    inline Quaternion (const Quaternion& q) { w = q.w; v = q.v; };
+    /** creates a Quaternion looking into the direction v @param v: the direction @param f: the value */
+    inline Quaternion (const Vector& v, float f) { this->w = f; this->v = v; }
+    /** turns a rotation along an axis into a Quaternion @param angle: the amount of radians to rotate @param axis: the axis to rotate around */
+    inline Quaternion (float angle, const Vector& axis) { w = cos(angle/2.0); v = axis * sin(angle/2.0); }
+    Quaternion (const Vector& dir, const Vector& up);
+    Quaternion (float roll, float pitch, float yaw);
+
+    void from3x3(float m[3][3]);
+    void from4x4(float m[4][4]);
+
+
+    /** @param q: the Quaternion to compare with this one. @returns true if the Quaternions are the same, false otherwise */
+  inline bool operator== (const Quaternion& q) const { return (unlikely(this->v==q.v&&this->w==q.w))?true:false; };
+    /** @param q: the Quaternion to compare with this one. @returns true if the Quaternions are the same, false otherwise */
+  inline bool operator!= (const Quaternion& q) const { return (unlikely(this->v!=q.v||this->w!=q.w))?true:false; };
+    /** @param f: a real value @return a Quaternion containing the quotient */
+    inline Quaternion operator/ (const float& f) const { return (unlikely(f==0.0)) ? Quaternion() : Quaternion(this->v/f, this->w/f); };
+    /** @param f: the value to divide by @returns the quaternion devided by f (this /= f) */
+    inline const Quaternion& operator/= (const float& f) {*this = *this / f; return *this;}
+    /** @param f: a real value @return a Quaternion containing the product */
+    inline Quaternion operator* (const float& f) const { return Quaternion(this->v*f, this->w*f); };
+    /** @param f: the value to multiply by @returns the quaternion multiplied by f (this *= f) */
+    inline const Quaternion& operator*= (const float& f) {*this = *this * f; return *this;}
+    /** @param q: another Quaternion to rotate this by @return a quaternion that represents the first one rotated by the second one (WARUNING: this operation is not commutative! e.g. (A*B) != (B*A)) */
+    Quaternion operator* (const Quaternion& q) const
+    {
+      return Quaternion(Vector(this->w*q.v.x + this->v.x*q.w + this->v.y*q.v.z - this->v.z*q.v.y,
+                               this->w*q.v.y + this->v.y*q.w + this->v.z*q.v.x - this->v.x*q.v.z,
+                               this->w*q.v.z + this->v.z*q.w + this->v.x*q.v.y - this->v.y*q.v.x),
+                        this->w*q.w - this->v.x*q.v.x - this->v.y*q.v.y - this->v.z*q.v.z);
+    };
+    /** @param q: the Quaternion to multiply by @returns the quaternion multiplied by q (this *= q) */
+    inline const Quaternion& operator*= (const Quaternion& q) {*this = *this * q; return *this; };
+    /** @param q the Quaternion by which to devide @returns the division from this by q (this / q) */
+    inline Quaternion operator/ (const Quaternion& q) const { return *this * q.inverse(); };
+    /** @param q the Quaternion by which to devide @returns the division from this by q (this /= q) */
+    inline const Quaternion& operator/= (const Quaternion& q) { *this = *this * q.inverse(); return *this; };
+    /** @param q the Quaternion to add to this @returns the quaternion added with q (this + q) */
+    inline Quaternion operator+ (const Quaternion& q) const { return Quaternion(q.v + v, q.w + w); };
+    /** @param q the Quaternion to add to this @returns the quaternion added with q (this += q) */
+    inline const Quaternion& operator+= (const Quaternion& q) { this->v += q.v; this->w += q.w; return *this; };
+    /** @param q the Quaternion to substrace from this @returns the quaternion substracted by q (this - q) */
+    inline Quaternion operator- (const Quaternion& q) const { return Quaternion(q.v - v, q.w - w); }
+    /** @param q the Quaternion to substrace from this @returns the quaternion substracted by q (this -= q) */
+    inline const Quaternion& operator-= (const Quaternion& q) { this->v -= q.v; this->w -= q.w; return *this; };
+    /** copy constructor @param q: the Quaternion to set this to. @returns the Quaternion q (or this) */
+    inline Quaternion operator= (const Quaternion& q) {this->v = q.v; this->w = q.w; return *this;}
+    /** conjugates this Quaternion @returns the conjugate */
+    inline Quaternion conjugate () const { return Quaternion(Vector(-v.x, -v.y, -v.z), this->w); };
+    /** @returns the norm of The Quaternion */
+    inline float norm () const { return sqrt(w*w + v.x*v.x + v.y*v.y + v.z*v.z); };
+    /** @returns the inverted Quaterntion of this */
+    inline Quaternion inverse () const { return conjugate() / (w*w + v.x*v.x + v.y*v.y + v.z*v.z); };
+    /** @returns the dot Product of a Quaternion */
+    inline float dot (const Quaternion& q) const { return v.x*q.v.x + v.y*q.v.y + v.z*q.v.z + w*q.w; };
+    /** @retuns the Distance between two Quaternions */
+    inline float distance(const Quaternion& q) const { return 2*acos(fabsf(this->dot(q))); };
+    /** @param v: the Vector  @return a new Vector representing v rotated by the Quaternion */
+    inline Vector apply (const Vector& v) const { return (*this * Quaternion(v, 0) * conjugate()).v; };
+    void matrix (float m[4][4]) const;
+    /** @returns the normalized Quaternion (|this|) */
+    inline Quaternion getNormalized() const { float n = this->norm(); return Quaternion(this->v/n, this->w/n); };
+    /** normalizes the current Quaternion */
+    inline void normalize() { float n = this->norm(); this->v /= n; this->w/=n; };
+
+    float getHeading() const;
+    Quaternion getHeadingQuat() const;
+    float getAttitude() const;
+    Quaternion getAttitudeQuat() const;
+    float getBank() const;
+    Quaternion getBankQuat() const;
+    /** @returns the rotational axis of this Quaternion */
+    inline Vector getSpacialAxis() const { return this->v / sin(acos(w));/*sqrt(v.x*v.x + v.y*v.y + v.z+v.z);*/ };
+    /** @returns the rotational angle of this Quaternion around getSpacialAxis()  !! IN DEGREE !! */
+    inline float getSpacialAxisAngle() const { return 360.0 / M_PI * acos( this->w ); };
+
+
+    inline void slerpTo(const Quaternion& toQuat, float t);
+    static Quaternion quatSlerp(const Quaternion& from, const Quaternion& to, float t);
+
+
+    static Quaternion lookAt(Vector from, Vector to, Vector up);
+
+    void debug() const;
+    void debug2() const;
+
+
+  public:
+    Vector    v;        //!< Imaginary Vector
+    float     w;        //!< Real part of the number
+};
+
+
+
+#endif /* __QUATERNION_H_ */
+
Index: branches/heathaze/src/lib/math/rect2D.cc
===================================================================
--- branches/heathaze/src/lib/math/rect2D.cc	(revision 9940)
+++ branches/heathaze/src/lib/math/rect2D.cc	(revision 9940)
@@ -0,0 +1,483 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli : Vector2D::scale()
+                                    Vector2D::abs()
+
+   Benjamin Grauer: port to Vector2D
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "rect2D.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+/**
+ * @brief creates a new Rectangle with
+ * @param x the left border
+ * @param y the top border
+ * @param width: the width
+ * @param height the height
+ */
+Rect2D::Rect2D(float x, float y, float width, float height)
+{
+  this->setLeft(x),
+  this->setTop(y);
+  this->setSize(width, height);
+}
+
+/**
+ * @brief creates a new Rectangle with
+ * @param topLeft the top-left corner
+ * @param bottomRight the lower-right corner
+ */
+Rect2D::Rect2D(const Vector2D& topLeft, const Vector2D& bottomRight )
+{
+  this->setTopLeft(topLeft);
+  this->setBottomRight(bottomRight);
+}
+
+/**
+ * @brief creates a new Rectangle with
+ * @param rect the rectangle to copy.
+ */
+Rect2D::Rect2D(const Rect2D& rect)
+{
+  *this = rect;
+}
+
+/**
+ * @brief copies the Values of rect to this rect
+ * @param rect copy the values from.
+ * @returns this reference.
+ */
+Rect2D& Rect2D::operator=(const Rect2D& rect)
+{
+  this->_topLeft = rect._topLeft;
+  this->_bottomRight = rect._bottomRight;
+  return *this;
+}
+
+/**
+ * @brief compares two rectanles.
+ * @param rect the rectangle to compare
+ * @returns true if the two rectangles are the same
+ */
+bool Rect2D::operator==(const Rect2D& rect) const
+{
+  return (this->_topLeft == rect._topLeft &&
+          this->_bottomRight == rect._bottomRight);
+}
+
+/**
+ * @brief negative compares two rectanles.
+ * @param rect the rectangle to compare
+ * @returns true if the two rectangles are different
+ */
+bool Rect2D::operator!=(const Rect2D& rect) const
+{
+  return (this->_topLeft != rect._topLeft ||
+          this->_bottomRight != rect._bottomRight);
+}
+
+/**
+ * @brief adds two rectangles together
+ * @param rect the rectagle to be added
+ * @returns a Rectangle, where both are added together.
+ *
+ * @note since adding rectangles does not make sense generally, here a description:
+ * adds toplefts and botomrights
+ */
+Rect2D Rect2D::operator+(const Rect2D& rect) const
+{
+  return Rect2D(this->_topLeft + rect._topLeft,
+                this->_bottomRight + rect._bottomRight);
+}
+
+
+/**
+ * @brief adds two rectangles together
+ * @param rect the rectagle to be added to this one
+ * @returns a Rectangle, where both are added together.
+ */
+Rect2D& Rect2D::operator+=(const Rect2D& rect)
+{
+  this->_topLeft += rect._topLeft;
+  this->_bottomRight += rect._bottomRight;
+  return *this;
+}
+
+
+/**
+ * @brief subracts two rectangles from each other
+ * @param rect the rectagle to be substracted from this one
+ * @returns a Rectangle, where both are substracted from one another.
+ */
+Rect2D Rect2D::operator-(const Rect2D& rect) const
+{
+  return Rect2D(this->_topLeft - rect._topLeft,
+                this->_bottomRight - rect._bottomRight);
+}
+
+/**
+ * @brief subracts two rectangles from each other
+ * @param rect the rectagle to be substracted from this one
+ * @returns a Rectangle, where both are substracted from one another.
+ */
+Rect2D& Rect2D::operator-=(const Rect2D& rect)
+{
+  this->_topLeft -= rect._topLeft;
+  this->_bottomRight -= rect._bottomRight;
+  return *this;
+}
+
+/**
+ * @brief intersects two Rectangles.
+ * @see intersection .
+ * @param rect the Rectangle to intersect with this one.
+ * @returns the intersection Region.
+ */
+Rect2D Rect2D::operator&(const Rect2D& rect) const
+{
+  return this->intersection(rect);
+}
+
+/**
+ * @brief intersects two Rectangles and assigns result to this one.
+ * @param rect the Rectangle to intersect with this one.
+ * @returns the intersection Region.
+ */
+Rect2D& Rect2D::operator&=(const Rect2D& rect)
+{
+  *this = this->intersection(rect);
+}
+
+/**
+ * TODO coment/implement
+ */
+Rect2D Rect2D::operator*(const Vector2D& scaling) const
+{
+#warning implements this...
+  //this->scale(scaling);
+}
+
+/**
+ * @brief sets the width of the Rectangle
+ * @param width the new width of the Rectangle
+ *
+ * the rectangle will be resized from the top left corner out.
+ */
+void Rect2D::setWidth(float width)
+{
+  this->_bottomRight.x = this->_topLeft.x + width;
+}
+
+
+/**
+ * @brief sets the height of the Rectangle
+ * @param height the new height of the Rectangle
+ *
+ * the rectangle will be resized from the top left corner out.
+ */
+void Rect2D::setHeight(float height)
+{
+  this->_bottomRight.y = this->_topLeft.y + height;
+}
+
+/**
+ * @brief sets the size of the Rectangle
+ * @param width the new width of the Rectangle.
+ * @param height the new height of the Rectangle.
+ * the rectangle will be resized from the top left corner out.
+ */
+void Rect2D::setSize(float width, float height)
+{
+  this->_bottomRight = this->_topLeft + Vector2D(width, height);
+}
+
+
+/**
+ * @brief sets the size of the Rectangle
+ * @param size the new size of the Rectangle.
+ * the rectangle will be resized from the top left corner out.
+ */
+void Rect2D::setSize(const Vector2D& size)
+{
+  this->_bottomRight = this->_topLeft + size;
+}
+
+/**
+ * @brief sets the new Center
+ * @param center the center to move the Rectangle to.
+ * moves the Rectangle from its current center to the new Center
+ */
+void Rect2D::setCenter(const Vector2D& center)
+{
+  this->move(center - this->center());
+}
+
+/**
+ * @brief sets the new Center
+ * @param x the center's X to move the Rectangle to.
+ * @param y the center's Y to move the Rectangle to.
+ * moves the Rectangle from its current center to the new Center
+ */
+void Rect2D::setCenter(float x, float y)
+{
+  this->setCenter(Vector2D(x, y));
+}
+
+/**
+ * @brief sets the new Center
+ * @param center the center to move the Rectangle to.
+ * moves the Rectangle from its current center to the new Center
+ */
+void Rect2D::setCenterX(float x)
+{
+#warning implement this
+}
+
+/**
+ * @brief sets the new Center
+ * @param center the center to move the Rectangle to.
+ * moves the Rectangle from its current center to the new Center
+ */
+void Rect2D::setCenterY(float y)
+{
+#warning implement this
+}
+
+/**
+ * @brief scales the Rectangle from topLeft out.
+ * @param x: the scale factor in x direction
+ */
+void Rect2D::scaleX(float x)
+{
+  this->_bottomRight.x = this->_topLeft.x + this->width() * x;
+}
+
+/**
+ * @brief scales the Rectangle from topLeft out.
+ * @param y: the scale factor in y direction
+ */
+void Rect2D::scaleY(float y)
+{
+  this->_bottomRight.y = this->_topLeft.y + this->height() * y;
+}
+
+/**
+ * @brief scales the Rectangle from topLeft out.
+ * @param x: the scale factor in x direction
+ * @param y: the scale factor in y direction
+ */
+void Rect2D::scale(float x, float y)
+{
+  this->scale(Vector2D(x,y));
+}
+
+/**
+ * @brief scales the Rectangle from topLeft out.
+ * @param v: the scale factors.
+ */
+void Rect2D::scale(const Vector2D& v)
+{
+  this->_bottomRight = this->_topLeft + this->size().internalMultipy(v);
+
+}
+
+/**
+ * @brief scales the Rectangle from the Center out.
+ * @param x: the scale factor in x-direction.
+ * @param y: the scale factor in y-direction.
+ */
+void Rect2D::scaleCentered(float x, float y)
+{
+  this->scaleCentered(Vector2D(x, y));
+}
+
+
+/**
+ * @brief scales the Rectangle from the Center out.
+ * @param v: the scale factors.
+ */
+void Rect2D::scaleCentered(const Vector2D& v)
+{
+#warning implement this
+}
+
+/**
+ * @brief moves the Rectangle
+ * @param x the amount to move in x.
+ */
+void Rect2D::moveX(float x)
+{
+  this->_topLeft.x += x;
+  this->_bottomRight.x += x;
+}
+
+/**
+ * @brief moves the Rectangle
+ * @param y the amount to move in y.
+ */
+void Rect2D::moveY(float y)
+{
+  this->_topLeft.y += y;
+  this->_bottomRight.y += y;
+}
+
+/**
+ * @brief moves the Rectangle
+ * @param x the amount to move in x.
+ * @param y the amount to move in y.
+ */
+void Rect2D::move(float x, float y)
+{
+  this->move(Vector2D(x, y));
+}
+
+/**
+ * @brief moves the Rectangle
+ * @param v the amount to move.
+ */
+void Rect2D::move(const Vector2D& v)
+{
+  this->_topLeft += v;
+  this->_bottomRight += v;
+}
+
+/**
+ * @brief swaps top and bottom.
+ */
+void Rect2D::swapTopBottom()
+{
+  float tmp = this->top();
+  this->setTop(this->bottom());
+  this->setBottom(tmp);
+}
+
+/**
+ * @brief swaps left and right.
+ */
+void Rect2D::swapLeftRight()
+{
+  float tmp = this->left();
+  this->setLeft(this->right());
+  this->setRight(tmp);
+}
+
+/**
+ * @brief normalizes the Rectangle.
+ *
+ * Normalizing a Rectangle means, that the top is above bottom, and left is left of right afterwards :)
+ */
+void Rect2D::normalize()
+{
+  if (this->top() > this->bottom())
+    this->swapTopBottom();
+  if (this->left() > this->right())
+    this->swapLeftRight();
+}
+
+/**
+ * @brief normalizes the Rectangle.
+ * @returns the normalized version of this rectangle.
+ *
+ * Normalizing a Rectangle means, that the top is above bottom, and left is left of right afterwards :)
+ */
+Rect2D Rect2D::normalized() const
+{
+  Rect2D norm(*this);
+  norm.normalize();
+  return norm;
+}
+
+/**
+ * @brief The intersection of two Rectangles is calculated and returned.
+ * @param intersector the Rectangle to intersect with this one.
+ * @return the intersection region.
+ */
+Rect2D Rect2D::intersection(const Rect2D& intersector) const
+{
+#warning implement
+}
+
+/**
+ * @brief checks if the intersection of two Rectangles is not empty.
+ */
+bool Rect2D::intersects(const Rect2D& intersector) const
+{
+#warning implement
+
+}
+
+/**
+ * @brief make an Extensive join of two rectangles.
+ * @param rect the rectangle to unite with this one.
+ * @returns the united rectangle
+ */
+Rect2D Rect2D::unite(const Rect2D& rect)
+{
+#warning implement
+
+}
+
+/**
+ * @brief checks if rect is inside of this Rectangle.
+ * @param rect The Rectangle that should be inside of this one.
+ * @returns tru if it is.
+ */
+bool Rect2D::contains(const Rect2D& rect) const
+{
+  return (this->top() <= rect.top() &&
+          this->bottom() >= rect.bottom() &&
+          this->left() <= rect.left() &&
+          this->right() >= rect.right());
+}
+
+/**
+ * @param point the point to check if it is inside.
+ * @returns true if the point is inside of this Rectangle.
+ */
+bool Rect2D::contains(const Vector2D& point) const
+{
+  return (this->top() <= point.y &&
+          this->bottom() >= point.y &&
+          this->left() <= point.x &&
+          this->right() >= point.x);
+}
+
+/**
+ * @brief slerps this Rectangle to rect.
+ * @param rect the rectangle to slerp to.
+ * @param value how much to slerp to [0:stay, 1:go there]
+ * @returns reference to this.
+ */
+const Rect2D& Rect2D::slerp(const Rect2D& rect, float value)
+{
+  this->_topLeft.slerp(rect._topLeft, value);
+  this->_bottomRight.slerp(rect._bottomRight, value);
+
+  return *this;
+}
+
+/**
+ * @brief print debug output for the Rect
+ */
+void Rect2D::debug() const
+{
+  PRINT(0)("Top: %0.2f Left: %0.2f; Bottom %0.2f Right:%0.2f; Size: %0.2fx%0.2f\n", top(), left(), bottom(), right(), size().x, size().y);
+}
Index: branches/heathaze/src/lib/math/rect2D.h
===================================================================
--- branches/heathaze/src/lib/math/rect2D.h	(revision 9940)
+++ branches/heathaze/src/lib/math/rect2D.h	(revision 9940)
@@ -0,0 +1,138 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file vector2D.h
+ * A basic 2D Vector math framework
+ *
+ * Contains classes to handle vectors, lines, rotations and planes
+*/
+
+#ifndef __RECT2D_H_
+#define __RECT2D_H_
+
+#include "vector2D.h"
+
+//! 2D Rectangle 2D
+/**
+ *       Class to handle 2-Dimensional Rectangles.
+ */
+class Rect2D
+{
+public:
+  Rect2D() { };
+  Rect2D(float x, float y, float width, float height);
+  Rect2D(const Vector2D& topLeft, const Vector2D& bottomRight );
+  Rect2D(const Rect2D& rect);
+
+  Rect2D& operator=(const Rect2D& rect);
+  bool operator==(const Rect2D& rect) const;
+  bool operator!=(const Rect2D& rect) const;
+
+  Rect2D operator+(const Rect2D& rect) const;
+  Rect2D& operator+=(const Rect2D& rect);
+
+  Rect2D operator-(const Rect2D& rect) const;
+  Rect2D& operator-=(const Rect2D& rect);
+
+  Rect2D operator&(const Rect2D& rect) const;
+  Rect2D& operator&=(const Rect2D& rect);
+
+  Rect2D operator*(const Vector2D& scaling) const;
+
+
+
+  /** @returns the top of the Rectangle */
+  inline float top() const { return _topLeft.y; };
+  /** @returns the bottom of the Rectangle */
+  inline float bottom() const { return _bottomRight.y; };
+  /** @returns the left border of the Rectangle */
+  inline float left() const { return _topLeft.x; };
+  /** @returns the right border of the rectangle */
+  inline float right() const { return _bottomRight.x; };
+  /** @returns the Center of the Rectangle */
+  inline Vector2D center() const { return (_topLeft+_bottomRight)/ 2.0; }
+  /** @returns the width of the Rectangle */
+  inline float width() const { return (right() - left()); };
+  /** @returns the height of the rectangle */
+  inline float height() const { return (bottom() - top()); };
+  /** @returns the Size of the Rectangle */
+  inline Vector2D size() const { return Vector2D(width(), height()); }
+  /** @returns the area of the Rectangle */
+  float area() const { return width()*height(); }
+
+  /** @param top sets the top border of the Rectangle */
+  inline void setTop(float top) { _topLeft.y = top; };
+  /** @param bottom the bottom border of the Rectangle */
+  inline void setBottom(float bottom) { _bottomRight.y = bottom; };
+  /** @param left the left border of the Rectangle */
+  inline void setLeft(float left) { _topLeft.x = left; };
+  /** @param right the right border of the Rectangle */
+  inline void setRight(float right) { _bottomRight.x = right; };
+  /** @param topLeft the top left corner of the Rectangle */
+  inline void setTopLeft(const Vector2D& topLeft) { _topLeft = topLeft; };
+  /** @param x the left border of the Rectangle @param y the top border */
+  inline void setTopLeft(float x, float y) { this->setTopLeft(Vector2D(x,y)); };
+  /** @param bottomRight the lower right corner of the Rectangle */
+  inline void setBottomRight(const Vector2D& bottomRight) { _bottomRight = bottomRight; };
+  /** @param x the right border of the Rectangle @param y the bottom border */
+  inline void setBottomRight(float x, float y) { this->setBottomRight(Vector2D(x,y)); };
+
+  void setWidth(float width);
+  void setHeight(float height);
+  void setSize(float width, float height);
+  void setSize(const Vector2D& size);
+  void setCenter(const Vector2D& center);
+  void setCenter(float x, float y);
+  void setCenterX(float x);
+  void setCenterY(float y);
+
+
+  void scaleX(float x);
+  void scaleY(float y);
+  void scale(float x, float y);
+  void scale(const Vector2D& v);
+  void scaleCentered(float x, float y);
+  void scaleCentered(const Vector2D& v);
+
+  void moveX(float x);
+  void moveY(float y);
+  void move(float x, float y);
+  void move(const Vector2D& v);
+
+  void swapTopBottom();
+  void swapLeftRight();
+  void normalize();
+  Rect2D normalized() const;
+
+
+  Rect2D intersection(const Rect2D& intersector) const;
+  bool intersects(const Rect2D& intersector) const;
+  Rect2D unite(const Rect2D& rect);
+  bool contains(const Rect2D& rect) const;
+  bool contains(const Vector2D& point) const;
+
+  const Rect2D& slerp(const Rect2D& rect, float value);
+
+  void debug() const;
+
+private:
+  Vector2D _topLeft;
+  Vector2D _bottomRight;
+};
+
+
+#endif /* __RECT2D_H_ */
+
Index: branches/heathaze/src/lib/math/rotation_OBSOLETE.cc
===================================================================
--- branches/heathaze/src/lib/math/rotation_OBSOLETE.cc	(revision 9940)
+++ branches/heathaze/src/lib/math/rotation_OBSOLETE.cc	(revision 9940)
@@ -0,0 +1,182 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "rotation_OBSOLETE.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+
+
+/**
+ *  create a rotation from a vector
+ * @param v: a vector
+*/
+Rotation::Rotation (const Vector& v)
+{
+  Vector x = Vector( 1, 0, 0);
+  Vector axis = x.cross( v);
+  axis.normalize();
+  float angle = angleRad( x, v);
+  float ca = cos(angle);
+  float sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+ *  creates a rotation from an axis and an angle (radians!)
+ * @param axis: the rotational axis
+ * @param angle: the angle in radians
+*/
+Rotation::Rotation (const Vector& axis, float angle)
+{
+  float ca, sa;
+  ca = cos(angle);
+  sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+ *  creates a rotation from euler angles (pitch/yaw/roll)
+ * @param pitch: rotation around z (in radians)
+ * @param yaw: rotation around y (in radians)
+ * @param roll: rotation around x (in radians)
+*/
+Rotation::Rotation ( float pitch, float yaw, float roll)
+{
+  float cy, sy, cr, sr, cp, sp;
+  cy = cos(yaw);
+  sy = sin(yaw);
+  cr = cos(roll);
+  sr = sin(roll);
+  cp = cos(pitch);
+  sp = sin(pitch);
+  m[0] = cy*cr;
+  m[1] = -cy*sr;
+  m[2] = sy;
+  m[3] = cp*sr+sp*sy*cr;
+  m[4] = cp*cr-sp*sr*sy;
+  m[5] = -sp*cy;
+  m[6] = sp*sr-cp*sy*cr;
+  m[7] = sp*cr+cp*sy*sr;
+  m[8] = cp*cy;
+}
+
+/**
+ *  creates a nullrotation (an identity rotation)
+*/
+Rotation::Rotation ()
+{
+  m[0] = 1.0f;
+  m[1] = 0.0f;
+  m[2] = 0.0f;
+  m[3] = 0.0f;
+  m[4] = 1.0f;
+  m[5] = 0.0f;
+  m[6] = 0.0f;
+  m[7] = 0.0f;
+  m[8] = 1.0f;
+}
+
+/**
+ *  fills the specified buffer with a 4x4 glmatrix
+ * @param buffer: Pointer to an array of 16 floats
+
+   Use this to get the rotation in a gl-compatible format
+*/
+void Rotation::glmatrix (float* buffer)
+{
+        buffer[0] = m[0];
+        buffer[1] = m[3];
+        buffer[2] = m[6];
+        buffer[3] = m[0];
+        buffer[4] = m[1];
+        buffer[5] = m[4];
+        buffer[6] = m[7];
+        buffer[7] = m[0];
+        buffer[8] = m[2];
+        buffer[9] = m[5];
+        buffer[10] = m[8];
+        buffer[11] = m[0];
+        buffer[12] = m[0];
+        buffer[13] = m[0];
+        buffer[14] = m[0];
+        buffer[15] = m[1];
+}
+
+/**
+ *  multiplies two rotational matrices
+ * @param r: another Rotation
+ * @return the matrix product of the Rotations
+
+   Use this to rotate one rotation by another
+*/
+Rotation Rotation::operator* (const Rotation& r)
+{
+        Rotation p;
+
+        p.m[0] = m[0]*r.m[0] + m[1]*r.m[3] + m[2]*r.m[6];
+        p.m[1] = m[0]*r.m[1] + m[1]*r.m[4] + m[2]*r.m[7];
+        p.m[2] = m[0]*r.m[2] + m[1]*r.m[5] + m[2]*r.m[8];
+
+        p.m[3] = m[3]*r.m[0] + m[4]*r.m[3] + m[5]*r.m[6];
+        p.m[4] = m[3]*r.m[1] + m[4]*r.m[4] + m[5]*r.m[7];
+        p.m[5] = m[3]*r.m[2] + m[4]*r.m[5] + m[5]*r.m[8];
+
+        p.m[6] = m[6]*r.m[0] + m[7]*r.m[3] + m[8]*r.m[6];
+        p.m[7] = m[6]*r.m[1] + m[7]*r.m[4] + m[8]*r.m[7];
+        p.m[8] = m[6]*r.m[2] + m[7]*r.m[5] + m[8]*r.m[8];
+
+        return p;
+}
+
+
+/**
+ *  rotates the vector by the given rotation
+ * @param v: a vector
+ * @param r: a rotation
+ * @return the rotated vector
+*/
+Vector rotateVector( const Vector& v, const Rotation& r)
+{
+  Vector t;
+
+  t.x = v.x * r.m[0] + v.y * r.m[1] + v.z * r.m[2];
+  t.y = v.x * r.m[3] + v.y * r.m[4] + v.z * r.m[5];
+  t.z = v.x * r.m[6] + v.y * r.m[7] + v.z * r.m[8];
+
+  return t;
+}
Index: branches/heathaze/src/lib/math/rotation_OBSOLETE.h
===================================================================
--- branches/heathaze/src/lib/math/rotation_OBSOLETE.h	(revision 9940)
+++ branches/heathaze/src/lib/math/rotation_OBSOLETE.h	(revision 9940)
@@ -0,0 +1,57 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+/*!
+ * @file rotation_OBSOLETE.h
+ * A basic 3D rotation framework
+ *
+ * THIS IS AN OBSOLETE FRAMEWORK, AND WILL BE DELETED SOON
+ *
+ *
+ * Contains classes to handle vectors, lines, rotations and planes
+*/
+
+#ifndef __ROTATION_H_
+#define __ROTATION_H_
+
+#include "vector.h"
+
+//! 3D rotation (OBSOLETE)
+/**
+  Class to handle 3-dimensional rotations.
+  Can create a rotation from several inputs, currently stores rotation using a 3x3 Matrix
+*/
+class Rotation {
+  public:
+
+  float m[9]; //!< 3x3 Rotation Matrix
+
+  Rotation ( const Vector& v);
+  Rotation ( const Vector& axis, float angle);
+  Rotation ( float pitch, float yaw, float roll);
+  Rotation ();
+  ~Rotation () {}
+
+  Rotation operator* (const Rotation& r);
+
+  void glmatrix (float* buffer);
+};
+
+//!< Apply a rotation to a vector
+Vector rotateVector( const Vector& v, const Rotation& r);
+
+
+#endif /* __ROTATION_H_ */
+
Index: branches/heathaze/src/lib/math/vector.cc
===================================================================
--- branches/heathaze/src/lib/math/vector.cc	(revision 9940)
+++ branches/heathaze/src/lib/math/vector.cc	(revision 9940)
@@ -0,0 +1,67 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Patrick Boenzli : Vector::scale()
+                                    Vector::abs()
+
+   Quaternion code borrowed from an Gamasutra article by Nick Bobick and Ken Shoemake
+
+   2005-06-02: Benjamin Grauer: speed up, and new Functionality to Vector (mostly inline now)
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "vector.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+
+/////////////
+/* VECTORS */
+/////////////
+/**
+ *  returns the this-vector normalized to length 1.0
+ * @todo there is some error in this function, that i could not resolve. it just does not, what it is supposed to do.
+ */
+Vector Vector::getNormalized() const
+{
+  float length = this->len();
+  if (unlikely(length == 0.0))
+    return *this;
+  else
+    return (*this / length);
+}
+
+/**
+ *  Vector is looking in the positive direction on all axes after this
+*/
+Vector Vector::abs()
+{
+  Vector v(fabs(x), fabs(y), fabs(z));
+  return v;
+}
+
+
+
+/**
+ *  Outputs the values of the Vector
+ */
+void Vector::debug() const
+{
+  PRINT(0)("x: %f; y: %f; z: %f", x, y, z);
+  PRINT(0)(" lenght: %f", len());
+  PRINT(0)("\n");
+}
Index: branches/heathaze/src/lib/math/vector.h
===================================================================
--- branches/heathaze/src/lib/math/vector.h	(revision 9940)
+++ branches/heathaze/src/lib/math/vector.h	(revision 9940)
@@ -0,0 +1,129 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+/*!
+ * @file vector.h
+ * A basic 3D math framework
+ *
+ * Contains classes to handle vectors, lines, rotations and planes
+*/
+
+#ifndef __VECTOR_H_
+#define __VECTOR_H_
+
+#include <cmath>
+#include "compiler.h"
+//! PI the circle-constant
+#define PI 3.14159265359f
+
+
+//! this is a small and performant 3D vector
+typedef float sVec3D[3];
+
+
+//! 3D Vector
+/**
+        Class to handle 3D Vectors
+*/
+class Vector {
+ public:
+  Vector (float x, float y, float z) : x(x), y(y), z(z) {}  //!< assignment constructor
+  Vector () : x(0), y(0), z(0) {}
+
+  /** @param v: the Vecor to compare with this one @returns true, if the Vecors are the same, false otherwise */
+  inline bool operator== (const Vector& v) const { return (this->x==v.x&&this->y==v.y&&this->z==v.z)?true:false; };
+  /** @param v: the Vecor to compare with this one @returns true, if the Vecors are different, false otherwise */
+  inline bool operator!= (const Vector& v) const { return (this->x!=v.x||this->y!=v.y||this->z!=v.z)?true:false; };
+  /** @param index The index of the "array" @returns the x/y/z coordinate */
+  inline float operator[] (float index) const {if( index == 0) return this->x; if( index == 1) return this->y; if( index == 2) return this->z; }
+  /** @param v The vector to add @returns the addition between two vectors (this + v) */
+  inline Vector operator+ (const Vector& v) const { return Vector(x + v.x, y + v.y, z + v.z); };
+  /** @param v The vector to add @returns the addition between two vectors (this + v) */
+  inline Vector operator+ (const sVec3D& v) const { return Vector(x + v[0], y + v[1], z + v[2]); };
+  /** @param v The vector to add  @returns the addition between two vectors (this += v) */
+  inline const Vector& operator+= (const Vector& v) { this->x += v.x; this->y += v.y; this->z += v.z; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline const Vector& operator+= (const sVec3D& v) { this->x += v[0]; this->y += v[1]; this->z += v[2]; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline Vector operator- (const Vector& v) const { return Vector(x - v.x, y - v.y, z - v.z); }
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline Vector operator- (const sVec3D& v) const { return Vector(x - v[0], y - v[1], z - v[2]); }
+  /** @param v The vector to substract  @returns the substraction between two vectors (this -= v) */
+  inline const Vector& operator-= (const Vector& v) { this->x -= v.x; this->y -= v.y; this->z -= v.z; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this -= v) */
+  inline const Vector& operator-= (const sVec3D& v) { this->x -= v[0]; this->y -= v[1]; this->z -= v[2]; return *this; };
+  /** @param v the second vector  @returns The dotProduct between two vector (this (dot) v) */
+  inline float operator* (const Vector& v) const { return x * v.x + y * v.y + z * v.z; };
+  /** @todo strange */
+  inline const Vector& operator*= (const Vector& v) { this->x *= v.x; this->y *= v.y; this->z *= v.z; return *this; };
+  /** @param f a factor to multiply the vector with @returns the vector multiplied by f (this * f) */
+  inline Vector operator* (float f) const { return Vector(x * f, y * f, z * f); };
+  /** @param f a factor to multiply the vector with @returns the vector multiplied by f (this *= f) */
+  inline const Vector& operator*= (float f) { this->x *= f; this->y *= f; this->z *= f; return *this; };
+  /** @param f a factor to divide the vector with @returns the vector divided by f (this / f) */
+  inline Vector operator/ (float f) const { return (unlikely(f == 0.0))?Vector(0,0,0):Vector(this->x / f, this->y / f, this->z / f); };
+  /** @param f a factor to divide the vector with @returns the vector divided by f (this /= f) */
+  inline const Vector& operator/= (float f) {if (unlikely(f == 0.0)) {this->x=0;this->y=0;this->z=0;} else {this->x /= f; this->y /= f; this->z /= f;} return *this; };
+  /**  copy constructor @todo (i do not know it this is faster) @param v the vector to assign to this vector. @returns the vector v */
+  inline const Vector& operator= (const Vector& v) { this->x = v.x; this->y = v.y; this->z = v.z; return *this; };
+  /** copy constructor* @param v the sVec3D to assign to this vector. @returns the vector v */
+  inline const Vector& operator= (const sVec3D& v) { this->x = v[0]; this->y = v[1]; this->z = v[2]; return *this; }
+  inline const Vector& operator= (const float* v) { this->x = v[0]; this->y = v[1]; this->z = v[2]; return *this; }
+  /** @param v: the other vector \return the dot product of the vectors */
+  float dot (const Vector& v) const { return x*v.x+y*v.y+z*v.z; };
+  /** @param v: the corss-product partner @returns the cross-product between this and v (this (x) v) */
+  inline Vector cross (const Vector& v) const { return Vector(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); }
+  /** scales the this vector with v* @param v the vector to scale this with */
+  void scale(const Vector& v) {   x *= v.x;  y *= v.y; z *= v.z; };
+  /** @returns the length of the vector */
+  inline float len() const { return sqrt (x*x + y*y + z*z); }
+  /** normalizes the vector */
+  inline void normalize() { float l = len(); if( unlikely(l == 0.0))return; this->x=this->x/l; this->y=this->y/l; this->z=this->z/l; };
+  Vector getNormalized() const;
+  Vector abs();
+
+  /** @param toVec nears this Vector to... @param t how much to advance (0.0: not at all; 1.0: fully) */
+  inline void slerpTo(const Vector& toVec, float t) { *this + (toVec - *this) * t; };
+
+  /** @returns a Null Vector */
+  inline static const Vector& nullVector() { static Vector nullVector; return nullVector; }
+  void debug() const;
+
+ public:
+  float    x;     //!< The x Coordinate of the Vector.
+  float    y;     //!< The y Coordinate of the Vector.
+  float    z;     //!< The z Coordinate of the Vector.
+};
+
+/**
+ *  calculate the angle between two vectors in radiances
+ * @param v1: a vector
+ * @param v2: another vector
+ * @return the angle between the vectors in radians
+*/
+inline float angleDeg (const Vector& v1, const Vector& v2) { return acos( v1 * v2 / (v1.len() * v2.len())); };
+/**
+ *  calculate the angle between two vectors in degrees
+ * @param v1: a vector
+ * @param v2: another vector
+ * @return the angle between the vectors in degrees
+*/
+inline float angleRad (const Vector& v1, const Vector& v2) { return acos( v1 * v2 / (v1.len() * v2.len())) * 180/M_PI; };
+
+/** an easy way to create a Random Vector @param sideLength the length of the Vector (x not sqrt(x^2...)) */
+#define VECTOR_RAND(sideLength)  (Vector((float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5) * sideLength)
+
+#endif /* __VECTOR_H_ */
+
Index: branches/heathaze/src/lib/math/vector2D.cc
===================================================================
--- branches/heathaze/src/lib/math/vector2D.cc	(revision 9940)
+++ branches/heathaze/src/lib/math/vector2D.cc	(revision 9940)
@@ -0,0 +1,66 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli : Vector2D::scale()
+                                    Vector2D::abs()
+
+   Benjamin Grauer: port to Vector2D
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "vector2D.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+
+
+/////////////
+/* VECTORS */
+/////////////
+/**
+ *  returns the this-vector normalized to length 1.0
+ * @todo there is some error in this function, that i could not resolve. it just does not, what it is supposed to do.
+ */
+Vector2D Vector2D::getNormalized() const
+{
+  float l = this->len();
+  if(unlikely(l == 1.0 || l == 0.0))
+    return *this;
+  else
+    return (*this / l);
+}
+
+/**
+ *  Vector2D is looking in the positive direction on all axes after this
+*/
+Vector2D Vector2D::abs()
+{
+  Vector2D v(fabs(x), fabs(y));
+  return v;
+}
+
+
+
+/**
+ *  Outputs the values of the Vector2D
+ */
+void Vector2D::debug() const
+{
+  PRINT(0)("x: %f; y: %f", x, y);
+  PRINT(0)(" lenght: %f", len());
+  PRINT(0)("\n");
+}
Index: branches/heathaze/src/lib/math/vector2D.h
===================================================================
--- branches/heathaze/src/lib/math/vector2D.h	(revision 9940)
+++ branches/heathaze/src/lib/math/vector2D.h	(revision 9940)
@@ -0,0 +1,111 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file vector2D.h
+ * A basic 2D Vector math framework
+ *
+ * Contains classes to handle vectors, lines, rotations and planes
+*/
+
+#ifndef __VECTOR2D_H_
+#define __VECTOR2D_H_
+
+#include <cmath>
+#include "compiler.h"
+
+//! small and performant 2D vector
+typedef float sVec2D[2];
+
+//! 2D Vector2D
+/**
+ *       Class to handle 2D Vector2Ds
+ */
+class Vector2D {
+ public:
+  Vector2D (float x, float y) : x(x), y(y) {}  //!< assignment constructor
+  Vector2D () : x(0), y(0) {}
+
+  /** @param v: the Vecor to compare with this one @returns true, if the Vecors are the same, false otherwise */
+  inline bool operator== (const Vector2D& v) const { return (this->x==v.x && this->y==v.y); };
+  /** @param v: the Vector to negative-compare with this one @returns true if the two vectors are different */
+  inline bool operator!= (const Vector2D& v) const { return (this->x!=v.x && this->y!=v.y); };
+  /** @param index The index of the "array" @returns the x/y coordinate */
+  inline float operator[] (float index) const { return ( index == 0)? this->x : this->y; }
+  /** @param v The vector to add @returns the addition between two vectors (this + v) */
+  inline Vector2D operator+ (const Vector2D& v) const { return Vector2D(x + v.x, y + v.y); };
+  /** @param v The vector to add @returns the addition between two vectors (this + v) */
+  inline Vector2D operator+ (const sVec2D& v) const { return Vector2D(x + v[0], y + v[1]); };
+  /** @param v The vector to add  @returns the addition between two vectors (this += v) */
+  inline const Vector2D& operator+= (const Vector2D& v) { this->x += v.x; this->y += v.y; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline const Vector2D& operator+= (const sVec2D& v) { this->x += v[0]; this->y += v[1]; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline Vector2D operator- (const Vector2D& v) const { return Vector2D(x - v.x, y - v.y); }
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline Vector2D operator- (const sVec2D& v) const { return Vector2D(x - v[0], y - v[1]); }
+  /** @param v The vector to substract  @returns the substraction between two vectors (this -= v) */
+  inline const Vector2D& operator-= (const Vector2D& v) { this->x -= v.x; this->y -= v.y; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this -= v) */
+  inline const Vector2D& operator-= (const sVec2D& v) { this->x -= v[0]; this->y -= v[1]; return *this; };
+  /** @param v the second vector  @returns The dotProduct between two vector (this (dot) v) */
+  inline float operator* (const Vector2D& v) const { return x * v.x + y * v.y; };
+  /** @todo strange */
+  inline const Vector2D& operator*= (const Vector2D& v) { this->x *= v.x; this->y *= v.y; return *this; };
+  /** @param f a factor to multiply the vector with @returns the vector multiplied by f (this * f) */
+  inline Vector2D operator* (float f) const { return Vector2D(x * f, y * f); };
+  /** @param f a factor to multiply the vector with @returns the vector multiplied by f (this *= f) */
+  inline const Vector2D& operator*= (float f) { this->x *= f; this->y *= f; return *this; };
+  /** @param f a factor to divide the vector with @returns the vector divided by f (this / f) */
+  inline Vector2D operator/ (float f) const { return (unlikely(f == 0.0)) ? Vector2D(0,0):Vector2D(this->x / f, this->y / f); };
+  /** @param f a factor to divide the vector with @returns the vector divided by f (this /= f) */
+  inline const Vector2D& operator/= (float f) {if (unlikely(f == 0.0)) {this->x=0;this->y=0;} else {this->x /= f; this->y /= f;} return *this; };
+  /**  copy constructor @todo (i do not know it this is faster) @param v the vector to assign to this vector. @returns the vector v */
+  inline const Vector2D& operator= (const Vector2D& v) { this->x = v.x; this->y = v.y; return *this; };
+  /** copy constructor* @param v the sVec3D to assign to this vector. @returns the vector v */
+  inline const Vector2D& operator= (const sVec2D& v) { this->x = v[0]; this->y = v[1]; return *this; }
+  /** @param v: the other vector \return the dot product of the vectors */
+  float dot (const Vector2D& v) const { return x*v.x+y*v.y; };
+  /** @param v multipy each entry with each other @returns this reference */
+  const Vector2D& internalMultipy(const Vector2D& v) { this->x *= v.x; this->y *= y; return *this; };
+  /** scales the this vector with v* @param v the vector to scale this with */
+  void scale(const Vector2D& v) {   x *= v.x;  y *= v.y; };
+  /** @returns the length of the vector */
+  inline float len() const { return sqrt (x*x+y*y); }
+  /** normalizes the vector */
+  inline void normalize() { float l = len(); if( unlikely(l == 0.0))return; this->x=this->x/l; this->y=this->y/l; };
+  Vector2D getNormalized() const;
+  Vector2D abs();
+
+  /** @param v the Vector to slerp to @param val 0 = stay 1 = at v */
+  void slerp(const Vector2D& v, float val) { *this += (*this - v) * val; }
+
+  /** @returns a Vector of (0,0) */
+  static const Vector2D& nullVector() { static Vector2D nullVector; return nullVector; };
+
+  void debug() const;
+
+ public:
+  float    x;     //!< The x Coordinate of the Vector2D.
+  float    y;     //!< The y Coordinate of the Vector2D.
+};
+
+
+/** an easy way to create a Random Vector2D @param sideLength the length of the Vector2D (x not sqrt(x^2...)) */
+#define VECTOR2D_RAND(sideLength)  (Vector2D((float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5) * sideLength)
+
+
+#endif /* __VECTOR2D_H_ */
+
Index: branches/heathaze/src/lib/network/Makefile.am
===================================================================
--- branches/heathaze/src/lib/network/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/network/Makefile.am	(revision 9940)
@@ -0,0 +1,97 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXnet.a
+
+libORXnet_a_SOURCES = synchronizeable.cc \
+		      network_manager.cc \
+		      shared_network_data.cc \
+		      network_socket.cc \
+		      network_stream.cc \
+                      data_stream.cc \
+                      network_protocol.cc \
+		      server_socket.cc \
+		      tcp_server_socket.cc \
+		      tcp_socket.cc \
+		      udp_server_socket.cc \
+		      udp_socket.cc \
+		      handshake.cc \
+		      network_game_manager.cc \
+		      converter.cc \
+		      peer_info.cc \
+		      message_manager.cc \
+		      network_log.cc \
+		      zip.cc \
+		      player_stats.cc \
+		      udp_broadcast.cc \
+		      \
+		      proxy/network_settings.cc \
+		      proxy/proxy_control.cc \
+		      \
+		      monitor/connection_monitor.cc \
+		      monitor/network_monitor.cc \
+		      monitor/network_node.cc \
+		      monitor/network_stats_widget.cc \
+		      \
+		      synchronizeable_var/synchronizeable_var.cc \
+		      synchronizeable_var/synchronizeable_vector.cc \
+		      synchronizeable_var/synchronizeable_int.cc \
+		      synchronizeable_var/synchronizeable_quaternion.cc \
+		      synchronizeable_var/synchronizeable_string.cc \
+		      synchronizeable_var/synchronizeable_float.cc \
+		      synchronizeable_var/synchronizeable_bool.cc \
+		      synchronizeable_var/synchronizeable_uint.cc \
+		      synchronizeable_var/synchronizeable_ip.cc \
+		      \
+		      ip.cc
+
+
+
+
+noinst_HEADERS = \
+		netdefs.h \
+		nettypes.h \
+		netincl.h \
+		\
+		synchronizeable.h \
+                network_manager.h \
+                shared_network_data.h \
+                network_socket.h \
+		network_stream.h \
+                data_stream.h \
+                network_protocol.h \
+		server_socket.h \
+		tcp_server_socket.h \
+		tcp_socket.h \
+		udp_server_socket.h \
+		udp_socket.h \
+		handshake.h \
+		network_game_manager.h \
+		converter.h \
+		peer_info.h \
+		netdefs.h \
+		message_manager.h \
+		network_log.h \
+		zip.h \
+		player_stats.h \
+		udp_broadcast.h \
+		\
+		proxy/network_settings.h \
+		proxy/proxy_control.h \
+		\
+		monitor/connection_monitor.h \
+		monitor/network_monitor.h \
+		monitor/network_node.h \
+		monitor/network_stats_widget.h \
+		\
+		synchronizeable_var/synchronizeable_var.h \
+		synchronizeable_var/synchronizeable_vector.h \
+		synchronizeable_var/synchronizeable_int.h \
+		synchronizeable_var/synchronizeable_quaternion.h \
+		synchronizeable_var/synchronizeable_string.h \
+		synchronizeable_var/synchronizeable_float.h \
+		synchronizeable_var/synchronizeable_bool.h \
+		synchronizeable_var/synchronizeable_uint.h \
+		synchronizeable_var/synchronizeable_ip.h \
+		\
+		ip.h
Index: branches/heathaze/src/lib/network/README.NETWORK
===================================================================
--- branches/heathaze/src/lib/network/README.NETWORK	(revision 9940)
+++ branches/heathaze/src/lib/network/README.NETWORK	(revision 9940)
@@ -0,0 +1,96 @@
+
+
+
+
+WORD OF WARNING:
+================
+ - Allways keep the network_settings.conf file from the data repos up-to-date!! Its very important, that the user numbers are synchronized!
+
+
+WORKING_STACK:
+==============
+ - removed compiler warnings in some modules
+ - totaly rework of the permission system
+ - introduced a new PERMISSION layer: PERMISSION_SERVER which gives the nearest server the authority to handle
+
+
+UNSOLVED:
+=========
+ - the clients cant get its ip in the handleHandshakes without throwing sigseg
+ - MessageManager: proxy/server forward the messages always. Perhaps there is a case, where messages get forwarded forever if there is a loop in the network. think about it again.
+ - Permissions: Proxy Servers shouldn't be able to create new eneitites on the server
+ - the nick name must be handled new
+
+
+
+This readme just gives some hints for the general network programming:
+
+ARCHITECTURE:
+The NetworkStream is in the center of this structure.
+
+
+UserId:
+=======
+containing the id of a user (==client). This id must be unique within a orxonox network its used especialy in the NetworkStream for node identification and also in the Synchronizeable base class for permissions checking (PERMISSION_OWNER)
+
+the connections belonging tu toe userId's are stored in the NetworkStream::peers std::map. As a keyvalue the userId's are used. Therefore the usage of this peers map is very delicate. Don't ever try to add anything you are not sure about the id stuff.
+
+There are some reserved id's, don't mess with them:
+0 :                  Master Server
+1 :                  First Proxy Server
+2 :                  Second Proxy Server
+3 :                  Third Proxy Server
+4 :                  Fourth Proxy Server
+.
+.
+.
+NET_MAX_PROXY        The maximal number of proxy servers
+NET_MAX... + 1       First Client
+NET_MAX... + 2       Second Client
+.
+.
+.
+NET_MAX_CONNECTION   Last client
+
+The proxy server ids are assigned as stated in the data/trunk/config/network_settings.conf, the first proxy server in the list gets the id NET_ID_PROXY_01 and so on.
+
+
+The ids are created by the master/proxy servers. Each server receives an address space of 1000 nodes where it is able to assign nodes to. This address space could be extended quite easely, since we got plenty of numbers in 4bytes (integer)
+
+The handshake sync has always the uniqueId == userId. This is why there are some reserved uniqueIds
+
+
+uniqueId:
+=========
+uniqueId is an id (unique :D) for each synchronizeable to be identified in a network. the number space for uniqueIds goes from 0 to maxplayers - 1
+
+The handshake sync has always the uniqueId == userId. This is why there are some reserved uniqueIds
+
+
+permissions:
+============
+Each synchronizeable variable has some write permissions. this permission systems allows to manage which network nodes are able to write the variables.
+PERMISSION_MASTER_SERVER       : only the master server can write this variable
+PERMISSION_PROXY_SERVER        : only the proxy server can write this variable
+PERMISSION_OWNER               : only the owner can write this variable
+PERMISSION_ALL                 : all clients can write this variable
+
+Only the master server should have the permission to create new WorldEntities and to add them to the game
+
+
+
+
+NetworkStream PeerInfo list: (peers)
+=====================================
+The network node with the offset 0 is always the server to which the client must connect to (in case there are connections to other hosts at the same time).
+
+
+
+MessageManager:
+===============
+The message manager has special handling if its a master/proxy: the messages will simply be forwarded to the other server
+
+
+Proxy Control:
+==============
+The ProxyControl class manages the state of the network by exchanging state messages.
Index: branches/heathaze/src/lib/network/converter.cc
===================================================================
--- branches/heathaze/src/lib/network/converter.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/converter.cc	(revision 9940)
@@ -0,0 +1,606 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Wuest (bwuest@ee.ethz.ch)
+   co-programmer: Christoph Renner (rennerc@ee.ethz.ch)
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+/* include your own header */
+#include "converter.h"
+#include "shell_command.h"
+#include "debug.h"
+#include <limits>
+
+SHELL_COMMAND_STATIC(debug, Converter, Converter::debug);
+
+ObjectListDefinition(Converter);
+/* using namespace std is default, this needs to be here */
+
+
+/*!
+ * Standard constructor
+ */
+Converter::Converter()
+{
+  /* set the class id for the base object */
+}
+
+/*!
+ * Standard destructor
+ */
+Converter::~Converter()
+{
+}
+
+const int sgnadd = 128; // = 2^7
+
+/*!
+ * Converts an int into a byte-array
+ * @remarks: The int is stored in big-endian
+ * @param x: The int which is to convert
+ * @return: A byte-array that accords the given int value
+ */
+byte* Converter::intToByteArray(int x)
+{
+  const int mod = 256; // = 2^8
+
+
+  byte* result = new byte[INTSIZE];
+  int sgn;
+  if (x >= 0)
+    sgn = 1;
+  else
+  {
+    sgn = -1;
+    x = -x;
+  }
+
+  for (int i = 0; i < INTSIZE; i++)
+  {
+    result[i] = x % mod;
+    x /= mod;
+  }
+
+  if (sgn == -1)
+    result[INTSIZE - 1] += sgnadd;
+
+
+  return result;
+}
+
+/*!
+ * Converts an int into a byte-array and stores the result into a given byte-array
+ * @remarks: The int is stored in big-endian
+ * @param x: The int which is to convert
+ * @return: The number of written bytes
+ */
+int Converter::_intToByteArray(int x, byte* a, int length)
+{
+  if (length < INTSIZE)
+  {
+    PRINTF(1)("byte buffer to short to store an int. Needed length %i. Avaiable length %i", INTSIZE, length);
+    return -1;
+  }
+
+  const int mod = 256; // = 2^8
+
+  int sgn;
+  if (x >= 0)
+    sgn = 1;
+  else
+  {
+    sgn = -1;
+    x = -x;
+  }
+
+  for (int i = 0; i < INTSIZE; i++)
+  {
+    a[i] = x % mod;
+    x /= mod;
+  }
+
+  if (sgn == -1)
+    a[INTSIZE - 1] += sgnadd;
+
+  return INTSIZE;
+}
+
+/*!
+ * Converts a byte-array into an int
+ * @param a: The byte-array which is to convert
+ * @param x: The place where the result is stored
+ * @return: The number of read bytes
+ */
+int Converter::_byteArrayToInt(const byte* a, int* x)
+{
+  int mult = 1;
+  const int step = 256; // = 2 ^ 8
+  *x = 0;
+  for (int i = 0; i < INTSIZE - 1; i++)
+  {
+    *x += a[i] * mult;
+    mult *= step;
+  }
+
+  if (a[INTSIZE - 1] >= sgnadd)
+  {
+    *x += (a[INTSIZE - 1] - sgnadd) * mult;
+    *x *= -1;
+  }
+  else
+    *x += a[INTSIZE - 1] * mult;
+
+  return INTSIZE;
+}
+
+int Converter::byteArrayToInt(const byte* a, int* x)
+{
+  memcpy( x, a, INTSIZE );
+  return INTSIZE;
+}
+
+int Converter::intToByteArray(int x, byte* a, int length)
+{
+  if ( length< INTSIZE )
+  {
+    PRINTF(1)("Byte Array to small : %d\n", length);
+    return 0;
+  }
+  memcpy(a, &x, INTSIZE);
+  return INTSIZE;
+}
+
+/*!
+ * Converts a float into a string containing its binary representation
+ * @param x: The float which is to convert
+ * @return: A string containing the float's binary representation
+ */
+char* Converter::floatToBinString(float x)
+{
+  char* result = new char[200];
+  int pos = 0;
+
+  if (x < 0)
+  {
+    result[pos++] = '-';
+    x = -x;
+  }
+
+  float sub = 1;
+  while (sub < x)
+    sub *= 2;
+
+  while ((x > 0 || sub >= 1) && pos < 200)
+  {
+    if (x >= sub)
+    {
+      result[pos] = '1';
+      x -= sub;
+    }
+    else
+      result[pos] = '0';
+    pos++;
+    sub /= 2;
+
+    if (sub == 0.5f)
+      result[pos++] = '.';
+  }
+
+  return result;
+}
+
+const int expmult = 8388608; //2^23
+
+float Converter::getDenormConst()
+{
+  const int exp = 126;
+  float result = 1.0f;
+  for (int i = 0; i < exp; i++)
+    result /= 2.0f;
+  return result;
+}
+
+/*!
+ * Converts a float value into a byte-array and stores the result into a given byte-array
+ * @param x: The float which is to convert
+ * @param a: The byte array where the result is to store
+ * @param length: The length of the array a
+ * @return: The number of written bytes
+ */
+int Converter::_floatToByteArray(float x, byte* a, int length)
+{
+  if (length < FLOATSIZE)
+  {
+    PRINTF(1)("byte buffer to short to store a float. Needed length %i. Avaiable length %i", FLOATSIZE, length);
+    return -1;
+  }
+
+  //handle 0 else function will loop for ever
+  /*if ( x == 0 )
+  {
+    for ( int i = 0; i<FLOATSIZE; i++)
+      a[i] = 0;
+    return FLOATSIZE;
+}*/
+
+  int mantisse = 0;
+  int exponent = 128;
+
+  int sgn;
+  if (x < 0)
+  {
+    x = -x;
+    sgn = -1;
+  }
+  else
+    sgn = 1;
+
+  if (x == 0)
+  {
+    exponent = 255;
+    mantisse = 0;
+  }
+  else
+  {
+    //if (x < getDenormConst())
+    //  printf("Denormalisiert!\n");
+    //printf("DenormConst = %e", getDenormConst());
+
+    float sub = 1;
+    while (sub < x)
+    {
+      sub *= 2;
+      exponent++;
+    }
+
+    while (x > 0)
+    {
+      if (x >= sub)
+      {
+        mantisse += 1;
+        x -= sub;
+      }
+
+      mantisse *= 2;
+      exponent--;
+      sub /= 2;
+    }
+    exponent++;
+    mantisse /= 2;
+
+
+///    printf("Conv:        mantisse = %i exponent = %i \n", mantisse, exponent);
+
+
+    //if (mantisse != 0)
+    //{
+      while (mantisse < expmult)
+      {
+        mantisse *= 2;
+        exponent--;
+      }
+
+      if (exponent >= 0)
+        mantisse -= expmult;
+      else
+      {
+        //Denormalized
+        while (exponent < 0)
+        {
+          mantisse /= 2;
+          exponent++;
+        }
+        printf("Conv: Denorm");
+      }
+    //}
+  }
+
+///  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
+
+
+  int hx = mantisse + expmult * exponent;
+  //int result = intToByteArray(hx, a, length);
+  intToByteArray(hx, a, length);
+  if (sgn == -1)
+    a[3] += sgnadd;
+
+
+//  int hx = mantisse + expmult * exponent;
+//  byte* result = intToByteArray(hx);
+//  if (sgn == -1)
+//    result[3] += sgnadd;
+
+  //return result;
+  return FLOATSIZE;
+}
+
+
+/*!
+ * Converts a byte-array into a float value
+ * @param a: The byte-array which is to convert
+ * @param x: The place where the result is to store
+ * @return: The number of read bytes
+ */
+int Converter::_byteArrayToFloat(const byte* a, float* x)
+{
+    //handle 0
+  /*for (int i = 0; i<FLOATSIZE; i++)
+  {
+    if (a[i]!=0)
+      break;
+    if ( i==FLOATSIZE-1 )
+    {
+      *x = 0.0f;
+      return FLOATSIZE;
+    }
+}*/
+
+  int hexp = a[2] + a[3] * 256;
+  int exponent = (hexp / 128) % 256;
+
+  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
+  int mantisse = hmant % expmult;
+
+  //handle 0
+  if (mantisse == 0 && exponent == 255)
+  {
+    *x = 0;
+    return FLOATSIZE;
+  }
+  else if (exponent == 0 && mantisse != 0)
+  {
+    exponent = -126;
+    printf("ReConv: Denorm");
+  }
+  else
+  {
+    mantisse += expmult;
+    exponent -= 128;
+  }
+
+  int sgn;
+  if (a[3] >= sgnadd)
+    sgn = -1;
+  else
+    sgn = 1;
+
+///  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
+
+  float emult = 1;
+  if (exponent > 0)
+    for (int i = 0; i < exponent; i++)
+      emult *= 2;
+  else if (exponent < 0)
+    for (int i = 0; i > exponent; i--)
+      emult /= 2;
+
+  /*
+  float result = mantisse * emult;
+  if (sgn == -1)
+    result = -result;
+
+  return result;
+  */
+
+  *x = mantisse * emult;
+  if (sgn == -1)
+    *x = -  *x;
+
+  return FLOATSIZE;
+}
+
+/*!
+ * Converts a float value into a byte-array
+ * @param x: The float which is to convert
+ * @param a: The array where the result is to store
+ * @param length: The length of the array a
+ * @return: The number of written bytes
+ */
+int Converter::floatToByteArray(float x, byte* a, int length)
+{
+  if ( length< FLOATSIZE )
+  {
+    PRINTF(1)("Byte Array to small\n");
+    return 0;
+  }
+  byte* p = (byte*)&x;
+
+  for (int i = 0; i < 4; i++)
+    a[i] = p[i];
+
+  return FLOATSIZE;
+}
+
+
+/*!
+ * Converts a byte-array into a float value
+ * @param a: The byte-array which is to convert
+ * @param x: The place where the result is to store
+ * @return: The number of read bytes
+ */
+int Converter::byteArrayToFloat(const byte* a, float* x)
+{
+  *x = *((float*)a);
+
+  return FLOATSIZE;
+}
+
+
+
+
+
+
+
+
+
+
+/**
+ * copies a strint to a byte array
+ * @param s: string to copy
+ * @param a: byte array
+ * @param length: string length
+ * @return: the used number of bytes in byte array
+ */
+int Converter::stringToByteArray( const std::string & s, byte * a, int maxLength )
+{
+  if ( s.length()+INTSIZE > maxLength )
+  {
+    PRINTF(1)("Byte array is too small (%d) to store %d bytes\n", maxLength, s.length()+INTSIZE);
+    return -1;
+  }
+
+  int n = Converter::intToByteArray( s.length(), a, maxLength );
+
+  memcpy( a+INTSIZE, s.c_str(), s.length() );
+
+  return s.length() + INTSIZE;
+}
+
+/**
+ * reads a string out of a byte array
+ * @param a: byte array
+ * @param s: string
+ * @param maxLength: max bytes to copy
+ * @return: the number of read bytes in byte array
+ */
+int Converter::byteArrayToString( const byte * a, std::string&s, int maxLength )
+{
+  int length;
+
+  int n = Converter::byteArrayToInt( a, &length );
+
+
+  if ( length+1 > maxLength )
+  {
+    PRINTF(1)("something went wrong length > remaining bytes in buffer\n" );
+
+    //TODO remove this
+    for ( int i = -1000; i < 1001; i++ )
+    {
+      if ( ( a[i] > 'a' && a[i] < 'z' ) || ( a[i] > 'A' && a[i] < 'Z' ) )
+        printf("%c", a[i]);
+      else
+        printf(".");
+    }
+    printf("\n");
+
+    s = "";
+    return -1;
+  }
+
+  s = "";
+  s.append( (char*)a+n, length );
+
+  return n+length;
+}
+
+#if 0
+/**
+ * reads a string out of a byte array and allocates memory for string
+ * @param a: byte array
+ * @param s: string
+ * @param maxLength: max bytes to copy
+ * @return: the number of read bytes in byte array
+ */
+int Converter::byteArrayToStringM( const byte * a, char*& s )
+{
+  int length;
+
+  int n = Converter::byteArrayToInt( a, &length );
+
+  s = new char[length+1];
+
+  if ( !s )
+  {
+    PRINTF(1)("Could not allocate memory!\n" );
+    return -1;
+  }
+
+  memcpy( s, a+n, length );
+  s[length] = '\0';
+
+  return n+length;
+}
+#endif
+
+
+
+void Converter::floatTest(float x)
+{
+  //float x = 8.0f;
+  //float x = numeric_limits<float>::infinity();
+
+  printf("To Convert: %e\n", x);
+
+//  byte* res = floatToByteArray(x);
+//   for (int i = 0; i < 4; i++)
+//     printf("%i ", res[i]);
+//   printf("\n");
+
+//  float y = byteArrayToFloat(res);
+//   printf("ReConvert: %e\n", y);
+
+//   if (x == y)
+//     printf("equal\n");
+//   else
+//     printf("different\n");
+}
+
+void Converter::ArrayfloatTest(float x)
+{
+  //float x = 8.0f;
+  //float x = numeric_limits<float>::infinity();
+
+  printf("To Convert: %e\n", x);
+  byte* res = new byte[4];
+
+  int wr = floatToByteArray(x, res, 4);
+  for (int i = 0; i < 4; i++)
+    printf("%i ", res[i]);
+  printf("  written bytes: %i \n", wr);
+
+  float y;
+  int rd = byteArrayToFloat(res, &y);
+  printf("ReConvert: %e\n", y);
+  printf("Read bytes: %i   ->  ", rd);
+
+  if (x == y)
+    printf("equal\n");
+  else
+    printf("different\n");
+}
+
+void Converter::debug()
+{
+  printf("We rulez\n");
+
+  ArrayfloatTest(0.125f);
+  ArrayfloatTest(64.0f);
+  ArrayfloatTest(0.0f);
+  ArrayfloatTest(5.00091e-29f);
+
+  //floatTest(-18.0098f);
+  //floatTest(-24.07e23f);
+  //floatTest(-0.0f);
+  //floatTest(-5.67e-29f);
+
+
+  //floatTest(-45.7e-32f);
+  //floatTest(45.7e-33f);
+  //floatTest(-45.7e-34f);
+  //floatTest(45.7e-35f);
+}
Index: branches/heathaze/src/lib/network/converter.h
===================================================================
--- branches/heathaze/src/lib/network/converter.h	(revision 9940)
+++ branches/heathaze/src/lib/network/converter.h	(revision 9940)
@@ -0,0 +1,68 @@
+/*!
+ * @file converter.h
+ *  Is able to convert int to byte-array and vice versa
+ */
+
+#ifndef _CONVERTER
+#define _CONVERTER
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+
+/* The size of an int in byte */
+#define INTSIZE 4
+/* The size of a float in byte */
+#define FLOATSIZE 4
+
+/*!
+ * a class that can convert int to byte-array and vice versa
+ */
+class Converter : public BaseObject
+{
+  ObjectListDeclaration(Converter);
+  public:
+    static byte* intToByteArray(int x);
+    static int byteArrayToInt(const byte* a);
+
+    static int intToByteArray(int x, byte* a, int length);
+    static int byteArrayToInt(const byte* a, int* x);
+
+    static int _intToByteArray(int x, byte* a, int length);
+    static int _byteArrayToInt(const byte* a, int* x);
+
+    static int stringToByteArray(const std::string & s, byte* a, int maxLength);
+    static int byteArrayToString(const byte* a, std::string&s, int maxLength);
+//    static int byteArrayToStringM(const byte* a, char*& s );
+
+    //Test
+    static char* floatToBinString(float x);
+
+//     static byte* floatToByteArray(float x);
+//     static float byteArrayToFloat(byte* a);
+
+    static int floatToByteArray(float x, byte* a, int length);
+    static int byteArrayToFloat(const byte* a, float* x);
+
+    static int _floatToByteArray(float x, byte* a, int length);
+    static int _byteArrayToFloat(const byte* a, float* x);
+
+
+
+    static void debug();
+    static void floatTest(float x);
+    static void ArrayfloatTest(float x);
+    static float getDenormConst();
+
+
+  private:
+    Converter();
+    virtual ~Converter();
+};
+
+#undef byte
+
+#endif /*_CONVERTER*/
Index: branches/heathaze/src/lib/network/data_stream.cc
===================================================================
--- branches/heathaze/src/lib/network/data_stream.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/data_stream.cc	(revision 9940)
@@ -0,0 +1,124 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Knecht
+   co-programmer: ...
+*/
+
+/* include Data_stream Header */
+#include "data_stream.h"
+
+
+/* using namespace std is default, this needs to be here */
+
+ObjectListDefinition(DataStream);
+
+/**
+ * This is the empty constructor
+ */
+DataStream::DataStream()
+{
+  this->upBuffer = new byte[DATA_STREAM_BUFFER_SIZE];
+  this->downBuffer = new byte[DATA_STREAM_BUFFER_SIZE];
+}
+
+/**
+ * This constructor creates a new DataStream and connects it to both streams (upStream, downStream)
+ */
+DataStream::DataStream(DataStream& inStream, DataStream& outStream)
+{
+  this->registerObject(this, DataStream::_objectList);
+    this->downStream = &outStream;
+    this->upStream = &inStream;
+
+    if( this->upBuffer)
+      delete[] this->upBuffer;
+    if( this->downBuffer)
+      delete[] this->downBuffer;
+}
+
+/**
+ *  standart deconstructor
+ */
+DataStream::~DataStream()
+{
+  delete [] this->upBuffer;
+  this->upBuffer = NULL;
+  delete [] this->downBuffer;
+  this->downBuffer = NULL;
+}
+
+
+/**
+ * This function connects this stream to another stream. The connected DataStream is an up-stream, meaning
+ * that the stream is "further away" from the NetworkSocket. The local reference upStream will be set to this
+ * Stream
+ */
+void DataStream::connectUpStream(DataStream& upStream)
+{
+
+}
+
+/**
+ * This function connects this stream to another stream. The connected DataStream is an down-stream, meaning
+ * that the stream is "closer" to the NetworkSocket.
+ */
+void DataStream::connectDownStream(DataStream& upStream)
+{
+
+}
+
+/**
+ * This function disconnects the upStream and sets it to NULL
+ */
+void DataStream::disconnectUpStream()
+{
+
+}
+
+/**
+ * This function disconnects the downStream and sets it to NULL
+ */
+void DataStream::disconnectDownStream()
+{
+
+}
+
+
+/**
+ * Following functions are protected and only visible inside the object and from derived classes
+ */
+
+/**
+ * This function writes the binary data to the local data. You will have to copy each byte and not only dublicate
+ * it.
+ *
+ * @param data: the binary array
+ * @param length: the length of the array
+ */
+void passDown(byte* data, int length)
+{
+
+}
+
+
+/**
+ * This function returns a reference to the local upData data array. So it can be read by an upper Stream
+ * The reading function will have to copy the whole data and musn't just reference it!
+ * This function is only called from other connected DataStreams to read the data.
+ *
+ * @param data: the binary array
+ * @return: the length of the data
+ */
+int passUp(byte* data)
+{
+  return 0;
+}
Index: branches/heathaze/src/lib/network/data_stream.h
===================================================================
--- branches/heathaze/src/lib/network/data_stream.h	(revision 9940)
+++ branches/heathaze/src/lib/network/data_stream.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file data_stream.h
+  *  Main class for a data stream, used for our network stream
+  *  network stream will get data, and will send it with a network socket
+  *  to another network stream
+
+*/
+
+#ifndef _DATA_STREAM_H
+#define _DATA_STREAM_H
+
+#include "base_object.h"
+#include "netdefs.h"
+
+#define DATA_STREAM_BUFFER_SIZE 10240
+
+class DataStream : public BaseObject
+{
+  ObjectListDeclaration(DataStream);
+  public:
+      DataStream();
+      DataStream(DataStream& inStream, DataStream& outStream);
+      virtual ~DataStream();
+
+
+      void connectUpStream(DataStream& upStream);
+
+      void disconnectUpStream();
+
+      void connectDownStream(DataStream& downStream);
+
+      void disconnectDownStream();
+
+      virtual void processData() = 0;
+
+      protected:
+      void passDown(byte* data, int length);
+
+      int passUp(byte* data);
+
+      byte* upBuffer;
+      byte* downBuffer;
+      unsigned int bufferSize;
+      DataStream* upStream;
+      DataStream* downStream;
+
+};
+
+#endif /* _DATA_STREAM_ */
Index: branches/heathaze/src/lib/network/handshake.cc
===================================================================
--- branches/heathaze/src/lib/network/handshake.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/handshake.cc	(revision 9940)
@@ -0,0 +1,156 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner (rennerc@ee.ethz.ch)
+   co-programmer: Patirck Boenzli (boenzlip@orxonox.ethz.ch)
+*/
+
+
+#define DEBUG_MODULE_NETWORK
+
+#include "handshake.h"
+
+#include <cassert>
+#include "debug.h"
+
+
+ObjectListDefinition(Handshake);
+
+
+ Handshake::Handshake( int nodeType, int clientId, int networkGameManagerId, int messageManagerId )
+  : Synchronizeable()
+{
+  /* set the class id for the base object */
+  this->registerObject(this, Handshake::_objectList);
+
+
+  // register all variable handlers
+  orxId_handler = registerVarId( new SynchronizeableInt( &localState.orxId, &remoteState.orxId, "orxonoxId", PERMISSION_ALL ) );
+  version_handler = registerVarId( new SynchronizeableInt( &localState.version, &remoteState.version, "version", PERMISSION_ALL ) );
+  netManId_handler = registerVarId( new SynchronizeableInt( &localState.networkManagerId, &remoteState.networkManagerId, "networkManagerId", PERMISSION_ALL ) );
+  msgManId_handler = registerVarId( new SynchronizeableInt( &localState.messageManagerId, &remoteState.messageManagerId, "messageManagerId", PERMISSION_ALL ) );
+  hostId_handler = registerVarId( new SynchronizeableInt( &localState.hostId, &remoteState.hostId, "hostId", PERMISSION_ALL ) );
+  completed_handler = registerVarId( new SynchronizeableInt( &localState.completed, &remoteState.completed, "completed", PERMISSION_ALL ) );
+  error_handler = registerVarId( new SynchronizeableInt( &localState.error, &remoteState.error, "error", PERMISSION_ALL ) );
+  errorString_handler = registerVarId( new SynchronizeableString( &localState.errorString, &remoteState.errorString, "errorString", PERMISSION_ALL ) );
+
+  this->nodeTypeHandler = registerVarId( new SynchronizeableInt( &localState.nodeType, &remoteState.nodeType, "nodeType", PERMISSION_ALL ) );
+
+  candel_id = registerVarId( new SynchronizeableInt( &localState.canDel, &remoteState.canDel, "canDel", PERMISSION_ALL ) );
+
+  registerVar( new SynchronizeableString( &localState.preferedNickName, &remoteState.preferedNickName, "preferedNickName", PERMISSION_ALL ) );
+  // now synchronize only two of the available proxy server addresses
+  registerVar( new SynchronizeableIP( &this->proxy1, &this->proxy1, "proxy server 1", PERMISSION_MASTER_SERVER ) );
+  registerVar( new SynchronizeableIP( &this->proxy2, &this->proxy2, "proxy server 2", PERMISSION_MASTER_SERVER ) );
+  registerVar( new SynchronizeableInt( &this->redirectProxy, &this->redirectProxy, "proxy server redirection flag", PERMISSION_MASTER_SERVER ) );
+
+
+  // init the local state
+  localState.completed = 0;
+  localState.error = 0;
+  localState.errorString = "";
+  localState.hostId = clientId;
+  localState.networkManagerId = networkGameManagerId;
+  this->localState.messageManagerId = messageManagerId;
+  localState.orxId = _ORXONOX_ID;
+  localState.version = _ORXONOX_VERSION;
+  localState.nodeType = nodeType;
+  localState.canDel = 0;
+
+
+  // init the remote state
+  remoteState.completed = 0;
+  remoteState.error = 0;
+  remoteState.errorString = "";
+  remoteState.hostId = NET_ID_UNASSIGNED;
+  remoteState.networkManagerId = -1;
+  remoteState.messageManagerId = -1;
+  remoteState.orxId = 0;
+  remoteState.version = 0;
+  remoteState.nodeType = NET_UNASSIGNED;
+  remoteState.canDel = 0;
+
+
+  this->proxy1 = IP(0, 0);
+  this->proxy2 = IP(0, 0);
+  this->redirectProxy = 0;
+
+
+  // activate the synchronization process
+  this->setSynchronized(true);
+  PRINTF(0)("Handshake created clientId = %d\n", clientId);
+}
+
+
+/**
+ * handler for changes in synced vars
+ * @param id id's which have changed
+ */
+void Handshake::varChangeHandler( std::list< int > & id )
+{
+  for ( std::list<int>::iterator it = id.begin(); it != id.end(); it++ )
+  {
+    // orxonox id handler
+    if ( *it == this->orxId_handler )
+    {
+      if ( remoteState.orxId != _ORXONOX_ID )
+      {
+        localState.error = 1;
+        localState.completed = 1;
+        localState.errorString = "Seems not to be orxonox!";
+        continue;
+      }
+    }
+
+    // orxonox version handler
+    if ( *it == this->version_handler )
+    {
+      if ( remoteState.version != _ORXONOX_VERSION )
+      {
+        localState.error = 2;
+        localState.completed = 1;
+        localState.errorString = "Versions of server and client do not match!";
+        continue;
+      }
+    }
+
+    // node type handler: for each node type there is a specific action to be taken
+    if ( *it == this->nodeTypeHandler)
+    {
+      if ( remoteState.nodeType == NET_MASTER_SERVER )
+      {
+        continue;
+      }
+      else if( remoteState.nodeType == NET_PROXY_SERVER_ACTIVE)
+      {
+        continue;
+      }
+      else if( remoteState.nodeType == NET_CLIENT)
+      {
+        continue;
+      }
+    }
+
+    // cancel
+    if ( *it == candel_id )
+    {
+      PRINTF(0)("handshake finished candel changed\n");
+    }
+  }
+
+  // handshake completed
+  if ( remoteState.orxId == _ORXONOX_ID &&
+       remoteState.version == _ORXONOX_VERSION )
+  {
+    localState.completed = 1;
+  }
+}
+
Index: branches/heathaze/src/lib/network/handshake.h
===================================================================
--- branches/heathaze/src/lib/network/handshake.h	(revision 9940)
+++ branches/heathaze/src/lib/network/handshake.h	(revision 9940)
@@ -0,0 +1,123 @@
+/*!
+ * @file network_stream.h
+ *  implementation of a network pipe. This node handles the handshake of two network nodes and exchanges informationas
+ * vial to the connection setup.
+ *
+ * the local node only writes in the localState variable. the remoteState variable will be written from the remote network node
+ * so don't write into it!
+ */
+
+#ifndef _HANDSHAKE
+#define _HANDSHAKE
+
+#include "base_object.h"
+#include "ip.h"
+#include "synchronizeable.h"
+#include "shared_network_data.h"
+
+//!< a struct to save the handshakes to
+struct HandshakeState
+{
+  int           orxId;                         //!< orxonox id
+  int           version;                       //!< network protocol version
+
+  int           networkManagerId;              //!< unique id of the network manager
+  int           messageManagerId;              //!< unique id of the message manager
+  int           hostId;                        //!< host id
+  int           nodeType;                      //!< type of the network node
+
+  int           completed;                     //!< true if completed
+  int           canDel;                        //!< true if marked for deletion
+
+  int           error;                         //!< error number
+
+  std::string   errorString;                   //!< error string
+
+  //additional data
+  std::string   preferedNickName;              //!< prefered nick name
+};
+
+
+//!< the handshake itself with some interface functions
+class Handshake : public Synchronizeable
+{
+  ObjectListDeclaration(Handshake);
+  public:
+    Handshake( int nodeType, int clientId = 0, int networkGameManagerId = 0, int messageManagerId = 0 );
+
+
+    /* functions indicating states of the handshake */
+    /** @returns true if the handshake is completed */
+    inline bool completed() const { return localState.completed != 0 && remoteState.completed != 0; }
+    /** @returns true if no error has occured until now */
+    inline bool ok() const { return localState.error == 0 && remoteState.error == 0; }
+    /** stops the handshake and reject the other side with @param reason: string describing the reason */
+    inline void doReject( std::string reason ){ localState.error = 1; localState.errorString = "the server rejected your connection ["+ reason +"]"; }
+    /** @returns true if the handshake is finished and the instances can be deleted */
+    inline bool canDel() const { return localState.canDel == 1 && remoteState.canDel == 1; }
+    /** @returns true if the local state can be removed*/
+    inline bool allowDel() const { return localState.canDel == 1; }
+    /** marks the handshake to be deleted */
+    inline void del() { localState.canDel = 1; }
+
+
+    /* the actual informations exchanged in the handshake */
+    /** @returns the host id of the remote host */
+    inline int  getHostId() const { return remoteState.hostId; }
+    /** @returns the unique id of the network game manager*/
+    inline int  getNetworkGameManagerId() const { return remoteState.networkManagerId; }
+    /** @returns the unique id of the message manager */
+    inline int  getMessageManagerId() const { return remoteState.messageManagerId; }
+    /** @returns the node type of the remote host */
+    inline int getRemoteNodeType() const { return this->remoteState.nodeType; }
+
+    /** sets @param nick the prefereded nick name */
+    inline void setPreferedNickName( const std::string & nick ){ localState.preferedNickName = nick; }
+    /** @returns the prefered nick name */
+    inline const std::string& getPreferedNickName() const { return remoteState.preferedNickName; }
+
+    /** @returns if true the local client should reconnect to a proxy server from the proxy server list */
+    inline bool redirect() const  { return this->redirectProxy; }
+    /** @param flag: indicating if the client should be redirected */
+    inline void setRedirect(bool flag) { if( SharedNetworkData::getInstance()->isClient()) return; this->redirectProxy = (int)flag; }
+
+    /** @param address: the address of the proxy server 1 if any */
+    inline void setProxy1Address(IP address) { if( SharedNetworkData::getInstance()->isClient()) return; this->proxy1 = address; }
+    /** @returns the address of the proxy server 1 if any */
+    inline IP getProxy1Address() const { return this->proxy1; }
+    /** @param address: the address of the proxy server 2 if any */
+    inline void setProxy2Address(IP address) { if( SharedNetworkData::getInstance()->isClient()) return; this->proxy2 = address; }
+    /** @returns the address of the proxy server 2 if any */
+    inline IP getProxy2Address() const { return this->proxy2; }
+
+
+    /* variable handler function */
+    virtual void varChangeHandler( std::list<int> & id );
+
+
+  private:
+    HandshakeState     localState;                            //!< the local handshake state
+    HandshakeState     remoteState;                           //!< the remote handshake state
+
+    int                orxId_handler;                         //!< orxonox id handler
+    int                version_handler;                       //!< orxonox version id handler
+    int                netManId_handler;                      //!< network manager handler
+    int                msgManId_handler;                      //!< message manager handler
+    int                hostId_handler;                        //!< host id handler
+    int                nodeTypeHandler;                       //!< node type handler
+    int                proxy1Handler;                         //!< handler for the proxy
+    int                proxy2Handler;                         //!< handler for the proxy
+
+    int                completed_handler;                     //!< handshake completion handler
+    int                error_handler;                         //!< handshake error handler
+    int                errorString_handler;                   //!< handshake error string handler
+    int                candel_id;                             //!< handshake deletion handler
+    int                nodeType;                              //!, the type of the network node
+
+    int                redirectProxy;                         //!< true if the client should reconnect to a proxy server
+    IP                 proxy1;                               //!< ip address of the first proxy (0.0.0.0 of not available)
+    IP                 proxy2;                               //!< ip address of the second proxy (0.0.0.0 of not available)
+};
+
+
+#endif
Index: branches/heathaze/src/lib/network/ip.cc
===================================================================
--- branches/heathaze/src/lib/network/ip.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/ip.cc	(revision 9940)
@@ -0,0 +1,294 @@
+/**
+ * @file ip.cc
+ * @brief A IP class, that handles IP names and resolution.
+ *
+ * code taken from audiere.
+ *
+ *
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+ * co-programmer: Patrick Boenzli
+ */
+
+#include "ip.h"
+
+#include <iostream>
+
+#include "multi_type.h"
+#include "substring.h"
+
+/**
+ * @brief default constructor
+ */
+IP::IP()
+{
+  this->_host = 0;
+  this->_port = IP::_defaultPort;
+}
+
+
+/**
+ * @brief constructor from ip and port
+ * @param ip the IP
+ * @param port the Port
+ * @return self
+ */
+IP::IP(int ip, int port)
+{
+  this->_host = ip;
+  if (port != -1)
+    this->_port = port;
+  else
+    this->_port = IP::_defaultPort;
+}
+
+
+/**
+ * @brief constructor from a String
+ * @param ip the IP as a String.
+ * @param resolve if true, the IP is resolved via DNS,
+ * @return self
+ */
+IP::IP(const std::string& ip, bool resolve)
+{
+  *this = IP::stringToIP(ip, IP::_defaultPort, resolve);
+}
+
+/**
+ * @brief constructor from a String
+ * @param ip the IP as a String.
+ * @param port The port to be resolved.
+ * @param resolve if true, the IP is resolved via DNS,
+ * @return self
+ */
+IP::IP(const std::string& ip, int port, bool resolve)
+{
+  *this = IP::stringToIP(ip, port, resolve);
+}
+
+
+/**
+ * @brief constructor from an SDL net structure IPaddress
+ * @param ip the ip.
+ * @return self
+ */
+IP::IP(const IPaddress& ip)
+{
+  this->_host = ip.host;
+  this->_port = ip.port;
+}
+
+
+/**
+ * @brief copy constructor.
+ * @param ip the IP to copy.
+ * @return self
+ */
+IP::IP(const IP& ip)
+{
+  *this = ip;
+}
+
+
+/**
+ * @brief constructs an IP out of the four pairs and a Port.
+ * @param first The first octal.
+ * @param second The second octal.
+ * @param third The third octal.
+ * @param fourth The fourth octal.
+ * @param port The Port.
+ * @return self.
+ */
+IP::IP(unsigned int first, unsigned int second, unsigned int third, unsigned int fourth, int port)
+{
+  this->_host = (fourth << 24) +
+                (third << 16) +
+                (second <<  8) +
+                (first);
+  this->_port = port;
+}
+
+
+/**
+ * @brief copy operator
+ * @param ip the IP to copy.
+ * @return self.
+ */
+const IP& IP::operator=(const IP& ip)
+{
+  this->_host = ip.host();
+  this->_port = ip.port();
+  return *this;
+}
+
+
+/**
+ * @brief copy operator
+ * @param ip the IP to copy.
+ * @return self.
+ */
+const IP& IP::operator=(const IPaddress& ip)
+{
+  this->_host = ip.host;
+  this->_port = ip.port;
+  return *this;
+}
+
+
+/**
+ * @brief comparison operator
+ * @param ip the IP to compare
+ * @return true if ip _and_ port match.
+ */
+bool IP::operator==(const IP& ip) const
+{
+  return (this->_host == ip.host() &&
+          this->_port == ip.port());
+}
+
+
+/**
+ * @brief comparison operator
+ * @param ip the IP to compare
+ * @return true if ip _or_ port do not match.
+ */
+bool IP::operator!=(const IP& ip) const
+{
+  return (this->_host != ip.host() ||
+          this->_port != ip.port());
+}
+
+
+/**
+ * @brief converts a String into an IP Object.
+ * @param ip The string holding an IP.
+ * @param port The port to be resolved.
+ * @param resolve if true, the IP is resolved via DNS,
+ * otherwise (resolve == false) the IP is being transformed
+ * from a String (xxx.xxx.xxx.xxx) to an integer.
+ *
+ * @return A newly constructed IP.
+ */
+IP IP::stringToIP(const std::string& ip, int port, bool resolve)
+{
+  if (resolve)
+  {
+    IPaddress ipaddr;
+
+    SDLNet_ResolveHost(&ipaddr, ip.c_str(), port);
+
+    return IP(ipaddr);
+  }
+  else
+  {
+    SubString ipaddr(ip, '.');
+    if(ip.size() != 4 )
+      return IP();
+
+    MultiType part0(ipaddr[0]);
+    MultiType part1(ipaddr[1]);
+    MultiType part2(ipaddr[2]);
+    MultiType part3(ipaddr[3]);
+
+    int addr = (part0.getInt() << 24) +
+               (part1.getInt() << 16) +
+               (part2.getInt() <<  8) +
+               part3.getInt();
+    return IP(addr, port);
+  }
+}
+
+
+/**
+ * @brief if you want to have a specific part of an IP
+ * @param part the n'th part of the IP addr (splitted by '.').
+ * @return the amount held in the designated part.
+ */
+int IP::ipPart(unsigned int part) const
+{
+  switch (part)
+  {
+    case 0:
+      return  (_host & 0xFF000000) >> 24;
+    case 1:
+      return  (_host & 0x00FF0000) >> 16;
+    case 2:
+      return  (_host & 0x0000FF00) >> 8;
+    case 3:
+      return  (_host & 0x000000FF);
+    default:
+      return -1;
+  }
+}
+
+
+/**
+ * @return the Ip as a string.
+ */
+std::string IP::ipString() const
+{
+  return IP::ipToString(this->_host, this->_port);
+}
+
+
+/**
+ * @brief converts an IPaddress struct into a String.
+ * @param ipaddr the IP address as a SDL_net struct.
+ * @return the string retrieved from the IP.
+ */
+std::string IP::ipToString(const IPaddress& ipaddr)
+{
+  int ip = SDLNet_Read32 (ipaddr.host);
+  return IP::ipToString(ip, ipaddr.port);
+}
+
+
+/**
+ * @brief converts a IP into a String (without port).
+ * @param host the IP to put into the string.
+ * @param port -1 if not wanted
+ * @return the string of the ip.
+ */
+std::string IP::ipToString(int host, int port)
+{
+  MultiType part0((int) ((host & 0xFF000000) >> 24));
+  MultiType part1((int) ((host & 0x00FF0000) >> 16));
+  MultiType part2((int) ((host & 0x0000FF00) >>  8));
+  MultiType part3((int) ((host & 0x000000FF) ));
+
+  std::string addr = part3.getString() + "." + part2.getString() + "." +
+                     part1.getString() + "." + part0.getString();
+
+  return addr;
+}
+
+
+/// default port definition.
+int IP::_defaultPort = 9999;
+
+/**
+ * @brief if no IP is supplied this port is used, so that IP can be resolved usefully.
+ * @param defaultPort The default port.
+ */
+void IP::setDefaultPort(int defaultPort)
+{
+  IP::_defaultPort = defaultPort;
+}
+
+
+/**
+ * @brief print out the IP in a nice fashion
+ */
+void IP::debug() const
+{
+  std::cout << "IP is " << this->ipString() << std::endl;
+}
Index: branches/heathaze/src/lib/network/ip.h
===================================================================
--- branches/heathaze/src/lib/network/ip.h	(revision 9940)
+++ branches/heathaze/src/lib/network/ip.h	(revision 9940)
@@ -0,0 +1,68 @@
+
+/*!
+ * @file ip.h
+ *
+ * @brief the ip class is used to transform strings to ip's and backwards
+ * it can also be used to
+ */
+
+#ifndef __IP_H__
+#define __IP_H__
+
+#include "netincl.h"
+#include <string>
+
+
+
+//! A class to handle time itself
+class IP
+{
+  public:
+    /// CONSTRUCTORS
+    IP();
+    IP(int ip, int port);
+    IP(const std::string& ip, bool resolve = true);
+    IP(const std::string& ip, int port = -1, bool resolve = true);
+    IP(const IPaddress& ip);
+    IP(const IP& ip);
+    IP(unsigned int first, unsigned int second, unsigned int third, unsigned int fourth, int port = IP::_defaultPort);
+
+    /// OPERATORS
+    const IP& operator=(const IP& ip);
+    const IP& operator=(const IPaddress& ip);
+    bool operator==(const IP& ip) const;
+    bool operator!=(const IP& up) const;
+
+    /// RETRIVEAL
+    /** @returns the IP */
+    int host() const { return this->_host; };
+    int* hostRef()  { return &this->_host; }
+    /** @returns the Port */
+    int port() const { return this->_port; };
+    int* portRef() { return &this->_port; };
+
+    inline IPaddress getSDLNotation() { IPaddress sdlIP; sdlIP.host = this->_host; sdlIP.port = this->_port; return sdlIP; }
+
+    int ipPart(unsigned int part) const;
+    std::string ipString() const;
+
+    void debug() const;
+
+  public:
+    /// SETUP
+    static IP stringToIP(const std::string& ip, int port = -1, bool resolve = true);
+
+    static std::string ipToString(const IPaddress& ipaddr);
+    static std::string ipToString(int host, int port = -1);
+
+    static void setDefaultPort(int defaultPort);
+    static int defaultPort(int defaultPort) { return IP::_defaultPort; };
+
+  private:
+    int           _host;           //!< The IP in int form.
+    int           _port;         //!< The Port number of the IP
+
+    static int    _defaultPort;  //!< Default Port
+};
+
+#endif /* __IP_H__ */
Index: branches/heathaze/src/lib/network/message_manager.cc
===================================================================
--- branches/heathaze/src/lib/network/message_manager.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/message_manager.cc	(revision 9940)
@@ -0,0 +1,515 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: Patrick Boenzli (patrick@orxonox.ethz.ch)
+
+     June 2006: finishing work on the network stream for pps presentation (rennerc@ee.ethz.ch)
+     July 2006: some code rearangement and integration of the proxy server mechanism (boenzlip@ee.ethz.ch)
+     July 2006: message forwarding algorithms
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "message_manager.h"
+
+#include "network_stream.h"
+#include "shared_network_data.h"
+#include "converter.h"
+#include <cassert>
+
+
+ObjectListDefinition(MessageManager);
+MessageManager* MessageManager::singletonRef = NULL;
+
+
+/**
+ * standard constructor
+*/
+MessageManager::MessageManager ()
+{
+  this->registerObject(this, MessageManager::_objectList);
+  newNumber = 1;
+  setSynchronized( true );
+}
+
+
+/**
+ * standard deconstructor
+*/
+MessageManager::~MessageManager ()
+{
+  for ( MessageQueue::iterator it = outgoingMessageQueue.begin(); it != outgoingMessageQueue.end(); it++ )
+  {
+    for ( std::list<NetworkMessage>::iterator it2 = it->second.messages.begin(); it2 != it->second.messages.end(); it2++ )
+    {
+      if ( it2->data )
+      {
+        delete [] it2->data;
+        it2->data = NULL;
+      }
+    }
+
+    it->second.messages.clear();
+    it->second.toAck.clear();
+  }
+
+  outgoingMessageQueue.clear();
+
+  this->messageHandlerMap.clear();
+
+  MessageManager::singletonRef = NULL;
+}
+
+/**
+ * get the diff to last acked state of userId
+ *
+ * this class does not use the normal SynchronizeableVars for zynchronisation. instead
+ * it defines its own protocol
+ *
+ * @param userId user to create diff for
+ * @param data buffer to copy diff in
+ * @param maxLength max bytes to copy into data
+ * @param stateId id of current state
+ * @param fromStateId the reference state for the delta state
+ * @param priorityTH tells getStateDiff to not send element with priority \< priorityTH
+ * @return n bytes copied into data
+ */
+int MessageManager::getStateDiff( int userId, byte * data, int maxLength, int stateId, int fromStateId, int priorityTH )
+{
+  int i = 0;
+  int n;
+
+  n = Converter::intToByteArray( outgoingMessageQueue[userId].toAck.size(), data + i, maxLength );
+  i += n;
+  assert( n == INTSIZE );
+
+  for ( std::list<int>::iterator it = outgoingMessageQueue[userId].toAck.begin(); it != outgoingMessageQueue[userId].toAck.end(); it++)
+  {
+    n = Converter::intToByteArray( *it, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+  }
+
+  outgoingMessageQueue[userId].toAck.clear();
+
+  n = Converter::intToByteArray( outgoingMessageQueue[userId].messages.size(), data + i, maxLength );
+  i += n;
+  assert( n == INTSIZE );
+
+  // write the message down, a message has this structure:
+  //   | data_length | serial_number | message_type | source_id | dest_id | ...data... |
+  //      4byte        4byte            4byte         4byte      4byte     data_length
+  for ( std::list<NetworkMessage>::iterator it = outgoingMessageQueue[userId].messages.begin(); it != outgoingMessageQueue[userId].messages.end(); it++ )
+  {
+    // send data length
+    n = Converter::intToByteArray( it->length, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+
+    // send serial number
+    n = Converter::intToByteArray( it->number, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+
+    // send message type
+    n = Converter::intToByteArray( it->messageType, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+
+    // send sender id
+    n = Converter::intToByteArray( it->senderId, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+
+    // send destination id
+    n = Converter::intToByteArray( it->destinationId, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+
+    // send receiver type
+    n = Converter::intToByteArray( it->recieverType, data + i, maxLength );
+    i += n;
+    assert( n == INTSIZE );
+
+    // and copy the data
+    assert( i + it->length <= maxLength );
+    memcpy( data + i, it->data, it->length );
+    i += it->length;
+  }
+
+  return i;
+}
+
+/**
+ * sets a new state out of a diff created on another host
+ * @param userId hostId of user who send me that diff
+ * @param data pointer to diff
+ * @param length length of diff
+ * @param stateId id of current state
+ * @param fromStateId id of the base state id
+ * @return number bytes read
+ * @todo check for permissions
+ */
+int MessageManager::setStateDiff( int userId, byte * data, int length, int stateId, int fromStateId )
+{
+  int i = 0;
+  int n;
+
+  int nAcks;
+
+
+  assert( i + INTSIZE <= length );
+  n = Converter::byteArrayToInt( data + i, &nAcks );
+  assert( n == INTSIZE );
+  i += n;
+
+  std::list<int> acks;
+
+  int number;
+
+  for ( int j = 0; j < nAcks; j++ )
+  {
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &number );
+    assert( n == INTSIZE );
+    i += n;
+
+    acks.push_back( number );
+  }
+
+  int nMessages;
+
+  assert( i + INTSIZE <= length );
+  n = Converter::byteArrayToInt( data + i, &nMessages );
+  assert( n == INTSIZE );
+  i += n;
+
+  int messageLength, messageType;
+  int senderId, destinationId, recieverType;
+
+  // now go through all newly received messages and assemble them
+  for ( int j = 0; j < nMessages; j++ )
+  {
+    // read the length
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &messageLength );
+    assert( n == INTSIZE );
+    i += n;
+
+    // read the serial number
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &number );
+    assert( n == INTSIZE );
+    i += n;
+
+    // read the message type
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &messageType );
+    assert( n == INTSIZE );
+    i += n;
+
+    // read the sender id
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &senderId );
+    assert( n == INTSIZE );
+    i += n;
+
+    //read the destination id
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &destinationId);
+    assert( n == INTSIZE );
+    i += n;
+
+    // read the receiver type
+    assert( i + INTSIZE <= length );
+    n = Converter::byteArrayToInt( data + i, &recieverType);
+    assert( n == INTSIZE );
+    i += n;
+
+    if ( number > 0 )
+      outgoingMessageQueue[userId].toAck.push_back( number );
+
+//     PRINTF(0)("got message with type: %i\n", messageType);
+    assert( i + messageLength <= length );
+    // make sure there is a message handler for this message type
+    assert( messageHandlerMap.find( (MessageType)messageType ) != messageHandlerMap.end());
+
+
+    if ( std::find( outgoingMessageQueue[userId].recievedMessages.begin(), outgoingMessageQueue[userId].recievedMessages.end(), number ) ==
+         outgoingMessageQueue[userId].recievedMessages.end() )
+    {
+
+      // find out if this message is addressed for this client too
+      if( recieverType == RT_ALL_BUT_ME  && SharedNetworkData::getInstance()->getHostID() != senderId ||
+          recieverType == RT_ALL_ME ||
+          recieverType == RT_NOT_USER && SharedNetworkData::getInstance()->getHostID() != destinationId ||
+          recieverType == RT_USER  && SharedNetworkData::getInstance()->getHostID() == destinationId ||
+          recieverType == RT_SERVER && SharedNetworkData::getInstance()->isMasterServer() ||
+          recieverType == RT_SERVER && SharedNetworkData::getInstance()->isProxyServerActive())
+      {
+
+        PRINTF(0)("<<< MessageManager: got msg with type: %i, from sender %i, to rec: %i\n", messageType, senderId, destinationId);
+      // call the handler function and handle errors
+        if ( !(*(messageHandlerMap[(MessageType)messageType].cb))( (MessageType)messageType, data + i, messageLength,
+                 messageHandlerMap[(MessageType)messageType].someData, senderId, destinationId ) )
+        {
+        // if the message is not handled correctly, bush it back to the incoming packets therefore trying it later
+          NetworkMessage msg;
+
+          msg.data = new byte[messageLength];
+          memcpy( msg.data, data + i, messageLength );
+          msg.length = messageLength;
+          msg.messageType = (MessageType)messageType;
+          msg.number = userId;
+          msg.senderId = senderId;
+          msg.recieverType = (RecieverType)recieverType;
+          msg.destinationId = destinationId;
+
+          incomingMessageQueue.push_back( msg );
+        }
+      }
+
+
+      // check if the message needs to be forwarded
+      if( recieverType == RT_ALL_BUT_ME ||
+          recieverType == RT_ALL_ME ||
+          recieverType == RT_NOT_USER ||
+          recieverType == RT_USER  && SharedNetworkData::getInstance()->getHostID() != destinationId ||
+          recieverType == RT_SERVER && SharedNetworkData::getInstance()->isProxyServerActive() )
+      {
+        // forwarding the messages but only if its a proxy
+        if( SharedNetworkData::getInstance()->isProxyServerActive())
+        {
+          PRINTF(0)("===========>> Forwarding Message msg with type: %i, from sender %i, to rec: %i\n", messageType, senderId, destinationId);
+          NetworkMessage msg;
+
+          msg.data = new byte[messageLength];
+          memcpy( msg.data, data + i, messageLength );
+          msg.length = messageLength;
+          msg.messageType = (MessageType)messageType;
+          msg.number = userId;
+          msg.senderId = senderId;
+          msg.destinationId = destinationId;
+          msg.recieverType = (RecieverType)recieverType;
+
+          this->sendMessage(msg.messageType, msg.data, msg.length, msg.recieverType, msg.senderId = senderId, msg.destinationId, MP_HIGHBANDWIDTH);
+        }
+      }
+
+      // save the serial number for ack signaling
+      outgoingMessageQueue[userId].recievedMessages.push_back( number );
+    }
+
+    i += messageLength;
+  }
+
+
+  //walk throu message queue and remove acked messages
+  for ( std::list<NetworkMessage>::iterator it = outgoingMessageQueue[userId].messages.begin(); it != outgoingMessageQueue[userId].messages.end();  )
+  {
+    if ( std::find( acks.begin(), acks.end(), it->number) != acks.end() )
+    {
+      std::list<NetworkMessage>::iterator delIt = it;
+      it++;
+      outgoingMessageQueue[userId].messages.erase( delIt );
+      continue;
+    }
+    it++;
+  }
+
+  //TODO find bether way. maybe with timestamp
+  if ( outgoingMessageQueue[userId].recievedMessages.size() > 1000 )
+  {
+    for ( int j = 0; j < (int)outgoingMessageQueue[userId].recievedMessages.size() - 1000; j++ )
+      outgoingMessageQueue[userId].recievedMessages.erase( outgoingMessageQueue[userId].recievedMessages.begin() );
+  }
+
+  return i;
+}
+
+
+
+
+/**
+ * processes the message manager data, specialy check for localy generated messages
+ */
+void MessageManager::processData()
+{
+  // now call the message handlers with the new message
+  for ( std::list<NetworkMessage>::iterator it = incomingMessageQueue.begin(); it != incomingMessageQueue.end();  )
+  {
+    PRINTF(0)("<<< MessageManager: got local msg with type: %i, from sender %i, to rec: %i\n", (*it).messageType, (*it).senderId, (*it).destinationId);
+
+    if ( (*(messageHandlerMap[it->messageType].cb))( it->messageType, it->data, it->length, messageHandlerMap[it->messageType].someData,
+                                                     /*it->number, */it->senderId, it->destinationId ) )
+    {
+      std::list<NetworkMessage>::iterator delIt = it;
+      if ( it->data )
+        delete it->data;
+      it++;
+      incomingMessageQueue.erase( delIt );
+      continue;
+    }
+    it++;
+  }
+
+}
+
+
+
+
+/**
+ * clean up memory reserved for user
+ * @param userId userid
+ */
+void MessageManager::cleanUpUser( int userId )
+{
+  if ( outgoingMessageQueue.find( userId ) == outgoingMessageQueue.end() )
+    return;
+
+  for ( std::list<NetworkMessage>::iterator it = outgoingMessageQueue[userId].messages.begin(); it != outgoingMessageQueue[userId].messages.end(); it++ )
+  {
+    if ( it->data )
+      delete it->data;
+    it->data = NULL;
+  }
+
+  outgoingMessageQueue[userId].toAck.clear();
+
+  outgoingMessageQueue.erase( userId );
+}
+
+/**
+ * registers function to handle messages with id messageType. someData is passed to callbackfuntion
+ * @param messageType message id to handle
+ * @param cb function pointer to callback function
+ * @param someData this pointer is passed to callback function without modification
+ * @return true on success
+ */
+bool MessageManager::registerMessageHandler( MessageType messageType, MessageCallback cb, void * someData )
+{
+  MessageHandler messageHandler;
+
+  messageHandler.cb = cb;
+  messageHandler.messageType = messageType;
+  messageHandler.someData = someData;
+
+  messageHandlerMap[messageType] = messageHandler;
+
+  return true;
+}
+
+/**
+ * initializes buffers for user
+ * @param userId userId
+ */
+void MessageManager::initUser( int userId )
+{
+  // just do something so map creates a new entry
+  outgoingMessageQueue[userId].toAck.clear();
+  //assert( outgoingMessageQueue[userId].messages.size() == 0 );
+}
+
+
+
+/**
+ * send a message to one or more clients
+ * recieverType:
+ *               RT_ALL send to all users. reciever is ignored
+ *               RT_USER send only to reciever
+ *               RT_NOT_USER send to all but reciever
+ *
+ * @param messageType message id
+ * @param data pointer to data
+ * @param dataLength length of data
+ * @param recieverType type of the receiver
+ * @param reciever the userId of the receiver if needed (depends on the ReceiverType)
+ */
+void MessageManager::sendMessage( MessageType messageType, byte * data, int dataLength, RecieverType recieverType, int reciever, MessagePriority messagePriority )
+{
+  this->sendMessage(messageType, data, dataLength, recieverType, SharedNetworkData::getInstance()->getHostID(), reciever, messagePriority);
+}
+
+
+/**
+ * send a message to one or more clients as a special client
+ * recieverType:
+ *               RT_ALL send to all users. reciever is ignored
+ *               RT_USER send only to reciever
+ *               RT_NOT_USER send to all but reciever
+ *
+ * @param messageType message id
+ * @param data pointer to data
+ * @param dataLength length of data
+ * @param recieverType type of the receiver
+ * @param sender the userId of the sender if there is need for shadowing it (eg. for msg forwarding)
+ * @param reciever the userId of the receiver if needed (depends on the ReceiverType)
+ */
+    void MessageManager::sendMessage( MessageType messageType, byte * data, int dataLength, RecieverType recieverType, int sender, int reciever, MessagePriority messagePriority )
+{
+  PRINTF(0)(" >>> MessageManager: sending msg with type: %i, recieverType: %i, reciever %i\n", messageType, recieverType, reciever);
+
+  // go through all outgoing message queues and add the message if its appropriate
+  for ( MessageQueue::iterator it = this->outgoingMessageQueue.begin(); it != this->outgoingMessageQueue.end(); it++ )
+  {
+
+    if (
+         recieverType == RT_ALL_ME      ||
+         recieverType == RT_ALL_BUT_ME  ||
+         recieverType == RT_USER        && it->first == reciever ||
+         recieverType == RT_USER        && reciever == NET_ID_MASTER_SERVER && !getNetworkStream()->isUserMasterServer( it->first ) ||  //(*)
+         recieverType == RT_NOT_USER    && it->first != reciever ||
+         recieverType == RT_SERVER      && getNetworkStream()->isUserMasterServer( it->first ) ||
+         recieverType == RT_SERVER      && getNetworkStream()->isUserProxyServerActive( it->first )
+       )// (*) special case: forward
+    {
+      NetworkMessage msg;
+
+      msg.data = new byte[dataLength];
+      memcpy( msg.data, data, dataLength );
+      msg.length = dataLength;
+      msg.messageType = messageType;
+      msg.number = this->newNumber++;
+      msg.senderId = sender;
+      msg.destinationId = reciever;
+      msg.recieverType = recieverType;
+      msg.priority = messagePriority;
+
+      it->second.messages.push_back( msg );
+    }
+
+
+  }
+
+
+  // if the message is also for myself, handle it here
+  if ( recieverType == RT_ALL_ME ||
+       recieverType == RT_USER   && reciever == SharedNetworkData::getInstance()->getHostID()
+     )
+  {
+    NetworkMessage msg;
+
+    msg.data = new byte[dataLength];
+    memcpy( msg.data, data, dataLength );
+    msg.length = dataLength;
+    msg.messageType = messageType;
+    msg.number = SharedNetworkData::getInstance()->getHostID();
+    msg.senderId = sender;
+    msg.destinationId = reciever;
+    msg.recieverType = recieverType;
+    msg.priority = messagePriority;
+
+    this->incomingMessageQueue.push_back( msg );
+  }
+}
+
+
Index: branches/heathaze/src/lib/network/message_manager.h
===================================================================
--- branches/heathaze/src/lib/network/message_manager.h	(revision 9940)
+++ branches/heathaze/src/lib/network/message_manager.h	(revision 9940)
@@ -0,0 +1,138 @@
+/*!
+ * @file message_manager.h
+ * @brief Definition of MessageManager
+*/
+
+#ifndef _MESSAGE_MANAGER_H
+#define _MESSAGE_MANAGER_H
+
+#include "synchronizeable.h"
+
+#include <map>
+#include <list>
+
+/*
+  Protocol:
+    int nacks
+    int acks[1..nacks]
+    int nmsg
+    (
+      int length
+      int number
+      int MessageType
+      byte * data
+    )[1..nmsg]
+*/
+
+
+//!< different message ids
+enum MessageType
+{
+  TESTMESSAGEID                  = 1,         //!< for testing purposes
+  MSGID_DELETESYNCHRONIZEABLE,                //!< message for sync deletion
+  MSGID_PREFEREDTEAM,                         //!< change prefered team
+  MSGID_CHANGENICKNAME,                       //!< change nicknames
+  MSGID_CHATMESSAGE,                          //!< chat message
+  MSGID_RESPAWN,                              //!< respawn message
+
+  MSGID_PROXY_NEWCLIENT,                       //!< informs the master server about a new client
+  MSGID_PROXY_LEAVECLIENT,                     //!< informs the master and other proxy servers about a leaving client
+  MSGID_PROXY_COMMAND,                         //!< command handler: delivers commands from and to proxies/clients
+};
+
+
+typedef bool (*MessageCallback)( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId );
+
+typedef enum RecieverType
+{
+  RT_ALL_BUT_ME = 1,   //!< message is sent to all users but myself
+  RT_ALL_ME,           //!< message is sent to all users
+  RT_USER,             //!< message is only sent to reciever
+  RT_NOT_USER,         //!< message is sent to all but reciever
+  RT_SERVER            //!< message is sent to server only
+};
+
+//TODO implement priority handling
+enum MessagePriority
+{
+  MP_HIGHBANDWIDTH = 1,  //!< fast and reliable but uses a lot of bandwidth
+  MP_LOWBANDWIDTH,       //!< may take a long time to arrive. reliable
+  MP_UNRELIABLE          //!< unreliable. low bandwidth
+};
+
+struct NetworkMessage
+{
+  MessageType      messageType;                         //!< type of the message
+  byte *           data;                                //!< data
+  int              length;                              //!< length of the data
+  int              number;                              //!< serial number
+  int              senderId;                            //!< userId of the sender
+  int              destinationId;                       //!< userId of the destination
+  RecieverType     recieverType;                        //!< type of the receiver
+  MessagePriority  priority;                            //!< priority of the messages
+};
+
+struct MessageUserQueue
+{
+  std::list<NetworkMessage> messages;
+  std::list<int>            toAck;
+  std::list<int>            recievedMessages;
+};
+
+typedef std::map<int,MessageUserQueue> MessageQueue;
+
+
+
+struct MessageHandler
+{
+  MessageCallback   cb;
+  MessageType       messageType;
+  void *            someData;
+};
+
+typedef std::map<MessageType,MessageHandler> MessageHandlerMap;
+
+//! A class for sending messages over network
+class MessageManager : public Synchronizeable {
+
+  ObjectListDeclaration(MessageManager);
+ public:
+   inline static MessageManager * getInstance(){ if (!singletonRef) singletonRef = new MessageManager();  return singletonRef; }
+
+   virtual ~MessageManager();
+
+   bool registerMessageHandler( MessageType messageType, MessageCallback cb, void * someData );
+
+   void sendMessage( MessageType messageType, byte * data, int dataLength, RecieverType recieverType, int reciever, MessagePriority messagePriority );
+   void sendMessage( MessageType messageType, byte * data, int dataLength, RecieverType recieverType, int sender, int reciever, MessagePriority messagePriority );
+
+   void initUser( int userId );
+
+   void processData();
+
+
+  protected:
+    MessageManager();
+
+
+  private:
+   virtual int getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH );
+   virtual int setStateDiff( int userId, byte* data, int length, int stateId, int fromStateId );
+   virtual void cleanUpUser( int userId );
+   virtual void handleSentState( int userId, int stateId, int fromStateId ){}
+   virtual void handleRecvState( int userId, int stateId, int fromStateId ){}
+
+
+ private:
+   static MessageManager *   singletonRef;           //!< the singleton reference
+
+   std::list<NetworkMessage> incomingMessageQueue;   //!< the incoming message buffer
+   MessageQueue              outgoingMessageQueue;   //!< stores messages to send
+   MessageHandlerMap         messageHandlerMap;      //!< contains handlers for messages
+
+   int                       newNumber;              //!< used to create unique message numbers
+
+
+};
+
+#endif /* _MESSAGE_MANAGER_H */
Index: branches/heathaze/src/lib/network/monitor/connection_monitor.cc
===================================================================
--- branches/heathaze/src/lib/network/monitor/connection_monitor.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/monitor/connection_monitor.cc	(revision 9940)
@@ -0,0 +1,257 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+#include "connection_monitor.h"
+#include "network_log.h"
+
+#include <debug.h>
+#include <SDL/SDL.h>
+#include <string.h>
+
+/* using namespace std is default, this needs to be here */
+
+ObjectListDefinition(ConnectionMonitor);
+/**
+ * constructor
+ * @param userId user's id
+ */
+ConnectionMonitor::ConnectionMonitor( int userId )
+{
+  /* set the class id for the base object and add ist to class list*/
+  this->registerObject(this, ConnectionMonitor::_objectList);
+
+  this->userId = userId;
+  this->ping = 0;
+  this->incomingUnzippedBandWidth = 0;
+  this->outgoingUnzippedBandWidth = 0;
+  this->incomingZippedBandWidth = 0;
+  this->outgoingZippedBandWidth = 0;
+  this->nIncomingPackets = 0;
+  this->nOutgoingPackets = 0;
+  this->nZIncomingPackets = 0;
+  this->nZOutgoingPackets = 0;
+
+  this->lastPacketTick = 0;
+  this->lastPrintTick = 0;
+}
+
+/**
+ * deconstructor
+ */
+ConnectionMonitor::~ConnectionMonitor( )
+{
+}
+
+/**
+ * process unzipped outgoing packet
+ * @param data pointer to packet data
+ * @param length length of packet
+ * @param stateId packet's state id
+ */
+void ConnectionMonitor::processUnzippedOutgoingPacket( int tick, byte * data, int length, int stateId )
+{
+  nOutgoingPackets++;
+
+  // for ping calculation
+  sentStateTicks[stateId] = tick;
+
+  // calculate bandwidth
+  outgoingUnzippedPacketHistory[tick] = length;
+  outgoingUnzippedBandWidth = calculateBandWidth( outgoingUnzippedPacketHistory, tick );
+
+  //NETPRINTF(n)("UNZIPPED UPSTREAM: user: %d bandwidth %f\n", userId, outgoingUnzippedBandWidth );
+
+  // count zero bytes
+  //int nZeroBytes = 0;
+
+  //for ( int i = 0; i < length; i++ )
+  //  if ( data[i] == '\0' )
+  //    nZeroBytes++;
+
+  //NETPRINTF(n)( "ZEROBYTES: %d (%f%%)\n", nZeroBytes, ((float)100)*nZeroBytes/length );
+}
+
+/**
+ * process unzipped incoming packet
+ * @param data pointer to packet data
+ * @param length length of packet
+ * @param stateId packet's state id
+ * @param ackedState state which was acked by this packet
+ */
+void ConnectionMonitor::processUnzippedIncomingPacket( int tick, byte * data, int length, int stateId, int ackedState )
+{
+  nIncomingPackets++;
+
+  lastPacketTick = tick;
+
+  // calculate ping
+  if ( sentStateTicks.find( ackedState ) != sentStateTicks.end() )
+  {
+    ackDelay.push_back( tick - sentStateTicks[ackedState] );
+  }
+
+  while ( sentStateTicks.begin() != sentStateTicks.end() && sentStateTicks.begin()->first <= ackedState )
+    sentStateTicks.erase( sentStateTicks.begin() );
+
+  while ( ackDelay.size() > N_PACKETS_FOR_PING )
+    ackDelay.erase( ackDelay.begin() );
+
+  ping = 0;
+
+  for ( std::list<int>::iterator it = ackDelay.begin(); it != ackDelay.end(); it++ )
+    ping += *it;
+
+  if ( ackDelay.size() == 0 )
+    ping = -1;
+  else
+    ping /= ackDelay.size();
+
+  //NETPRINTF(n)("PING: user: %d ping: %d\n", userId, ping );
+
+  // calculate bandwidth
+  incomingUnzippedPacketHistory[tick] = length;
+  incomingUnzippedBandWidth = calculateBandWidth( incomingUnzippedPacketHistory, tick );
+
+  //NETPRINTF(n)("UNZIPPED DOWNSTREAM: user: %d bandwidth %f\n", userId, incomingUnzippedBandWidth );
+
+}
+
+/**
+ * remove old packets
+ * @param packetHistory
+ * @param tick
+ */
+void ConnectionMonitor::removeOldPackets( std::map< int, int > & packetHistory, int tick )
+{
+  while ( packetHistory.begin()->first < tick - MSECS_TO_CALC_BWIDTH )
+    packetHistory.erase( packetHistory.begin() );
+}
+
+/**
+ * calculate bandwidth out of packethistory
+ * @param packetHistory packet history
+ * @param tick current tick from SDL_GetTicks
+ * @return bandwidth in bytes/sec
+ */
+float ConnectionMonitor::calculateBandWidth( std::map< int, int > & packetHistory, int tick )
+{
+  removeOldPackets( packetHistory, tick );
+
+  float res = 0.0f;
+#if 0
+  for ( std::map<int,int>::iterator it = packetHistory.begin(); it != packetHistory.end(); it++ )
+  {
+    if ( it != packetHistory.begin() )
+      res += it->second;
+  }
+
+  if ( packetHistory.size() <= 1 || tick - packetHistory.begin()->first == 0 )
+    res = 0.0f;
+  else
+    res /= (float)(tick - packetHistory.begin()->first);
+
+  res *= 1000.0f;
+#endif
+
+  for ( std::map<int,int>::const_iterator it = packetHistory.begin(); it != packetHistory.end(); it++ )
+  {
+    res += it->second;
+  }
+
+  if ( packetHistory.size() <= 1 )
+    res = 0.0f;
+  else
+    res /= (float)(tick - packetHistory.begin()->first);
+
+  res *= 1000.0f;
+
+  return res;
+}
+
+
+/**
+ * process zipped outgoing packet
+ * @param data pointer to packet data
+ * @param length length of packet
+ * @param stateId packet's state id
+ */
+void ConnectionMonitor::processZippedOutgoingPacket( int tick, byte * data, int length, int stateId )
+{
+  nZOutgoingPackets++;
+
+  // calculate bandwidth
+  outgoingZippedPacketHistory[tick] = length;
+  outgoingZippedBandWidth = calculateBandWidth( outgoingZippedPacketHistory, tick );
+
+  //NETPRINTF(n)("UPSTREAM: user: %d bandwidth %f nOutgoingPackets %d\n", userId, outgoingZippedBandWidth, nOutgoingPackets );
+
+  if ( lastPrintTick < tick-1000 )
+  {
+    printStatis();
+    lastPrintTick = tick;
+  }
+}
+
+
+/**
+ * process zipped incoming packet
+ * @param data pointer to packet data
+ * @param length length of packet
+ * @param stateId packet's state id
+ * @param ackedState state which was acked by this packet
+ */
+void ConnectionMonitor::processZippedIncomingPacket( int tick, byte * data, int length )
+{
+  nZIncomingPackets++;
+
+  // calculate bandwidth
+  incomingZippedPacketHistory[tick] = length;
+  incomingZippedBandWidth = calculateBandWidth( incomingZippedPacketHistory, tick );
+
+  //NETPRINTF(n)("DOWNSTREAM: user: %d bandwidth %f nIncomingPackets %d\n", userId, incomingZippedBandWidth, nIncomingPackets );
+
+}
+
+
+/**
+ * check if client sent no packets for SECS_TO_TIMEOUT
+ * @return true if last packet recieved \< NOW() - SECS_TO_TIMEOUT
+ */
+bool ConnectionMonitor::hasTimedOut( ) const
+{
+  if ( lastPacketTick + SECS_TO_TIMEOUT*1000 < SDL_GetTicks() && nIncomingPackets > 0 )
+    return true;
+
+  if ( nIncomingPackets == 0 && nOutgoingPackets >= NETWORK_FREQUENCY*SECS_TO_TIMEOUT )
+    return true;
+
+  return false;
+}
+
+
+
+/**
+ * prints bandwith usage, ping and other important things to telnet-console
+ */
+void ConnectionMonitor::printStatis( ) const
+{
+  NETPRINT(n)("============NETWORKSTATS FOR USER %d============\n", userId);
+  NETPRINT(n)("PING = %d\n", ping );
+  NETPRINT(n)("BANDWIDTH: UP: %f (%f) DOWN %f (%f)\n", outgoingZippedBandWidth, outgoingUnzippedBandWidth, incomingZippedBandWidth, incomingUnzippedBandWidth);
+  NETPRINT(n)("PACKETS: RECIEVED %d; SENT %d\n", nIncomingPackets, nOutgoingPackets );
+  NETPRINT(n)("================================================\n");
+}
+
+
Index: branches/heathaze/src/lib/network/monitor/connection_monitor.h
===================================================================
--- branches/heathaze/src/lib/network/monitor/connection_monitor.h	(revision 9940)
+++ branches/heathaze/src/lib/network/monitor/connection_monitor.h	(revision 9940)
@@ -0,0 +1,76 @@
+/*!
+ * @file connection_monitor.h
+    \brief provides information about the quality of a connection.
+ */
+
+#ifndef _CONNECTION_MONITOR_H
+#define _CONNECTION_MONITOR_H
+
+#include "base_object.h"
+#include "netdefs.h"
+
+#include <map>
+#include <list>
+
+#define N_PACKETS_FOR_PING 20
+#define MSECS_TO_CALC_BWIDTH 1000
+#define SECS_TO_TIMEOUT 30
+
+class ConnectionMonitor : virtual public BaseObject
+{
+  ObjectListDeclaration(ConnectionMonitor);
+  public:
+    ConnectionMonitor( int userId );
+    virtual ~ConnectionMonitor();
+
+    void processUnzippedOutgoingPacket( int tick, byte * data, int length, int stateId );
+    void processUnzippedIncomingPacket( int tick, byte * data, int length, int stateId, int ackedState );
+
+    void processZippedOutgoingPacket( int tick, byte * data, int length, int stateId );
+    void processZippedIncomingPacket( int tick, byte * data, int length );
+
+    void calculatePing();
+
+    bool hasTimedOut() const;
+
+    void printStatis() const;
+    float getIncomingUnzippedBandWidth() const { return incomingUnzippedBandWidth; }
+    float getOutgoingUnzippedBandWidth() const { return outgoingUnzippedBandWidth; }
+    float getIncomingZippedBandWidth() const { return incomingZippedBandWidth; }
+    float getOutgoingZippedBandWidth() const { return outgoingZippedBandWidth; }
+
+  private:
+    float calculateBandWidth( std::map<int,int> & packetHistory, int tick );
+    void removeOldPackets( std::map<int,int> & packetHistory, int tick );
+
+    int userId;       //!< user's id
+
+    std::map<int,int>   sentStateTicks;
+
+    std::map<int,int>   incomingUnzippedPacketHistory;
+    std::map<int,int>   outgoingUnzippedPacketHistory;
+
+    std::map<int,int>   incomingZippedPacketHistory;
+    std::map<int,int>   outgoingZippedPacketHistory;
+
+    std::list<int>      ackDelay;
+    int                 ping;
+
+    float               incomingUnzippedBandWidth;
+    float               outgoingUnzippedBandWidth;
+
+    float               incomingZippedBandWidth;
+    float               outgoingZippedBandWidth;
+
+    int                 nIncomingPackets;
+    int                 nOutgoingPackets;
+
+    int                 nZIncomingPackets;
+    int                 nZOutgoingPackets;
+
+    int                 lastPacketTick;
+
+    int                 lastPrintTick;
+  };
+
+#endif
Index: branches/heathaze/src/lib/network/monitor/network_monitor.cc
===================================================================
--- branches/heathaze/src/lib/network/monitor/network_monitor.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/monitor/network_monitor.cc	(revision 9940)
@@ -0,0 +1,321 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli (patrick@orxonox.ethz.ch)
+*/
+
+#include "glgui.h"
+#include "shell_command.h"
+
+#include "network_stream.h"
+#include "debug.h"
+
+#include "proxy/network_settings.h"
+#include "shared_network_data.h"
+
+#include "network_monitor.h"
+#include "network_node.h"
+#include "peer_info.h"
+#include "network_stream.h"
+#include "netdefs.h"
+
+#include <vector>
+
+
+#include "network_stats_widget.h"
+
+SHELL_COMMAND(gui, NetworkMonitor, toggleGUI)
+ ->setAlias("ProxyGui");
+SHELL_COMMAND(debug, NetworkMonitor, debug);
+
+ObjectListDefinition(NetworkMonitor);
+
+
+/**
+ * starts a network monitor
+ */
+NetworkMonitor::NetworkMonitor(NetworkStream* networkStream)
+  : Synchronizeable()
+{
+  this->registerObject(this, NetworkMonitor::_objectList);
+
+  this->networkStream = networkStream;
+  this->playerNumber = 0;
+  this->connectionNumber = 0;
+  // create the localnode, init it and add it to the nodes list
+  this->localNode = new NetworkNode( this->networkStream->getPeerInfo());
+  this->addNode(this->localNode);
+
+  this->setSynchronized(false);
+
+  // read in the proxy server list, this is only the case for the master server
+  if( SharedNetworkData::getInstance()->isMasterServer())
+  {
+    // assuming that the config files are already read we get the proxy servers
+    std::vector<IP>* proxyList = NetworkSettings::getInstance()->getProxyList();
+    std::vector<IP>::iterator it = proxyList->begin();
+    // create a peer info class and a network node class for each new proxy and add them to the passive list
+    for(; it < proxyList->end(); it++)
+    {
+      PeerInfo* peer = new PeerInfo();
+      peer->ip = (*it);
+      peer->nodeType = NET_PROXY_SERVER_PASSIVE;
+      peer->userId = -1;
+
+      this->addActiveProxyServer( this->localNode, peer);
+    }
+  }
+  this->box = NULL;
+}
+
+
+/**
+ * deconstructor
+ */
+NetworkMonitor::~NetworkMonitor()
+{
+  if( this->localNode)
+    delete this->localNode;
+}
+
+
+/**
+ * add the network node
+ * @param node to add
+ */
+void NetworkMonitor::addNetworkNode(NetworkNode* node)
+{
+  this->nodeList.push_back(node);
+}
+
+
+/**
+ * add the network node
+ * @param node to add
+ */
+void NetworkMonitor::removeNetworkNode(NetworkNode* node)
+{
+  std::list<NetworkNode*>::iterator it = this->nodeList.begin();
+  for(; it != this->nodeList.end(); it++)
+  {
+    if( *it == node)
+    {
+      if( node->getNodeType() == NET_CLIENT)
+        this->playerNumber--;
+
+      this->nodeList.erase(it);
+      return;
+    }
+  }
+}
+
+/**
+ * tihs adds the new network node
+ * @param ip ip of the new node
+ */
+void NetworkMonitor::addNode(const IP& ip, int nodeType)
+{
+  PeerInfo* pInfo = new PeerInfo();
+  pInfo->nodeType = nodeType;
+  pInfo->ip = ip;
+
+  this->addNode( pInfo);
+}
+
+
+/**
+ * adds a network node to the local node
+ *  @param pInfo node information
+ */
+void NetworkMonitor::addNode(PeerInfo* pInfo)
+{
+  if( this->localNode == NULL)
+    return;
+
+  PRINTF(0)("^^^^^^^^^^^^^^^^^^^^^^^^^^ adding node: %i with type: %s\n\n", pInfo->userId, pInfo->getNodeTypeString().c_str());
+
+  if( pInfo->isClient())
+  {
+    this->localNode->addClient(new NetworkNode(pInfo));
+  }
+  else if( pInfo->isProxyServerActive())
+  {
+    this->localNode->addActiveProxyServer(new NetworkNode(pInfo));
+  }
+  else if( pInfo->isProxyServerActivePassive())
+  {
+    this->localNode->addPassiveProxyServer(new NetworkNode(pInfo));
+  }
+  else if( pInfo->isMasterServer())
+  {
+    this->localNode->addMasterServer(new NetworkNode(pInfo));
+  }
+  else
+    assert(false);
+}
+
+
+/**
+ * adds a network node to the local node
+ *  @param node node to add to
+ *  @param pInfo node information
+ */
+void NetworkMonitor::addNode(NetworkNode* node, PeerInfo* pInfo)
+{
+  if( node == NULL)
+    return;
+
+  if( pInfo->isClient())
+    node->addClient(new NetworkNode(pInfo));
+  else if( pInfo->isProxyServerActive())
+    node->addActiveProxyServer(new NetworkNode(pInfo));
+  else if( pInfo->isMasterServer())
+    node->addMasterServer(new NetworkNode(pInfo));
+}
+
+
+
+/**
+ * removes a node from the network monitor
+ * @param pInfo the node to remove
+ */
+void NetworkMonitor::removeNode(PeerInfo* pInfo)
+{
+  this->removeNode(this->localNode, pInfo);
+}
+
+
+/**
+ * removes the network node
+ * @param node the network node where the PeerInfo node is connected to
+ * @param pInfo the PeerInfo to remove
+ */
+void NetworkMonitor::removeNode(NetworkNode* node, PeerInfo* pInfo)
+{
+  if( node == NULL || pInfo == NULL)
+    return;
+
+  if( pInfo->isClient())
+    node->removeClient(pInfo->userId);
+  else if( pInfo->isProxyServerActive())
+    node->removeActiveProxyServer(pInfo->userId);
+  else if( pInfo->isMasterServer())
+    node->removeMasterServer(pInfo->userId);
+}
+
+
+/**
+ * @returns the proxy server of the first choice
+ */
+PeerInfo* NetworkMonitor::getFirstChoiceProxy() const
+{
+  // return the fist proxy in the list
+  return this->localNode->getActiveProxyServer(0);
+}
+
+
+/**
+ * @returns the proxy server of second choice
+ */
+PeerInfo* NetworkMonitor::getSecondChoiceProxy() const
+{
+  // return the second server in the list
+  return this->localNode->getActiveProxyServer(1);
+}
+
+
+/**
+ * @param userId of the searched node
+ * @returns the PeerInfo of the userId peer
+ */
+PeerInfo* NetworkMonitor::getPeerByUserId( int userId)
+{
+  NetworkNode* node = this->getNodeByUserId(userId);
+  if( node != NULL)
+    return node->getPeerInfo();
+
+  return NULL;
+}
+
+/**
+ * searches for a given NetworkNode
+ * @param userId of the searched node
+ * @returns the PeerInfo of the userId peer
+ */
+NetworkNode* NetworkMonitor::getNodeByUserId( int userId)
+{
+  std::list<NetworkNode*>::iterator it = this->nodeList.begin();
+  NetworkNode* node = NULL;
+  for(; it != this->nodeList.end(); it++)
+  {
+    node = (*it)->getNodeByUserId(userId);
+    if( node != NULL)
+      return node;
+  }
+
+  return NULL;
+}
+
+
+/**
+ * this displays the network monitor gui
+ */
+void NetworkMonitor::toggleGUI()
+{
+  if (this->box == NULL)
+  {
+    this->box = new NetworkStatsWidget(this);
+    this->box->showAll();
+  }
+  else
+  {
+    delete this->box;
+    this->box = NULL;
+  }
+}
+
+/**
+ * processes the network monitor data
+ */
+void NetworkMonitor::process()
+{
+  this->playerNumber = 0;
+  std::list<NetworkNode*>::iterator it = this->nodeList.begin();
+  for(; it != this->nodeList.end(); it++)
+  {
+    this->playerNumber += (*it)->getPlayerNumber();
+  }
+
+  // check if a proxy server has to activated
+
+//   this->debug();
+}
+
+/**
+ * prints out the debug informations
+ */
+void NetworkMonitor::debug() const
+{
+  PRINT(0)("================================= Network Monitor::debug() =====\n");
+  PRINT(0)(" I am: %s\n", this->localNode->getPeerInfo()->getNodeTypeString().c_str());
+  PRINT(0)(" Total count of network connections: %i\n", this->connectionNumber);
+  PRINT(0)(" Total count of players: %i\n", this->playerNumber);
+  PRINT(0)(" Max players on this server: %i\n", SharedNetworkData::getInstance()->getMaxPlayer());
+
+  std::list<NetworkNode*>::const_iterator it = this->nodeList.begin();
+  for(; it != this->nodeList.end(); it++)
+  {
+    (*it)->debug(1);
+  }
+
+  PRINT(0)("================================================================\n");
+}
+
Index: branches/heathaze/src/lib/network/monitor/network_monitor.h
===================================================================
--- branches/heathaze/src/lib/network/monitor/network_monitor.h	(revision 9940)
+++ branches/heathaze/src/lib/network/monitor/network_monitor.h	(revision 9940)
@@ -0,0 +1,111 @@
+/*!
+ * @file network_monitor.h
+ *  a class to monitor the network: throughput, network nodes
+ */
+
+#ifndef _NETWORK_MONITOR_H
+#define _NETWORK_MONITOR_H
+
+#include "base_object.h"
+#include "synchronizeable.h"
+#include "shared_network_data.h"
+#include "ip.h"
+
+#include "network_node.h"
+
+#include <list>
+
+class NetworkStream;
+class PeerInfo;
+
+
+namespace OrxGui { class GLGuiBox; };
+
+
+
+//!< a class that monitors the whole network. it tries to gather all informations its able to from the network
+class NetworkMonitor : public Synchronizeable
+{
+  ObjectListDeclaration(NetworkMonitor);
+  public:
+    NetworkMonitor(NetworkStream* networkStream);
+    virtual ~NetworkMonitor();
+
+    /* client/masterserver/proxyserver addition/removal interface */
+    void addNetworkNode(NetworkNode* node);
+    void removeNetworkNode(NetworkNode* node);
+
+    void addNode(PeerInfo* pInfo);
+    void addNode(const IP& ip, int nodeType);
+    void addNode(NetworkNode* node) { this->nodeList.push_back(node); }
+    void addNode(NetworkNode* node, PeerInfo* pInfo);
+
+    /** adds to @param node a network node @param pInfo a new client */
+    inline void addClient(NetworkNode* node, PeerInfo* pInfo) { node->addClient(new NetworkNode(pInfo)); }
+    /** adds to @param node a network node @param pInfo a new proxy server */
+    inline void addActiveProxyServer(NetworkNode* node, PeerInfo* pInfo) { node->addActiveProxyServer(new NetworkNode(pInfo)); }
+    /** adds to @param node a network node @param pInfo a new proxy server */
+    inline void addPassiveProxyServer(NetworkNode* node, PeerInfo* pInfo) { node->addPassiveProxyServer(new NetworkNode(pInfo)); }
+    /** adds to @param node a network node @param pInfo a new master server*/
+    inline void addMasterServer(NetworkNode* node, PeerInfo* pInfo) { node->addMasterServer(new NetworkNode(pInfo)); }
+
+    void removeNode(PeerInfo* pInfo);
+    void removeNode(NetworkNode* node, PeerInfo* pInfo);
+
+    inline void removeClient(NetworkNode* node, int userId) { node->removeClient(userId); }
+    inline void removeActiveProxyServer(NetworkNode* node, int userId) { node->removeActiveProxyServer(userId); }
+    inline void removePassiveProxyServer(NetworkNode* node, int userId) { node->removePassiveProxyServer(userId); }
+    inline void removeMasterServer(NetworkNode* node, int userId) { node->removeMasterServer(userId); }
+
+    PeerInfo* getFirstChoiceProxy() const;
+    PeerInfo* getSecondChoiceProxy() const;
+    /** @returns the local node */
+    inline NetworkNode* getLocalNode() const { return this->localNode; };
+
+    /** @returns the active proxy server list of the localnode */
+    inline std::list<NetworkNode*> getActiveProxyServers() const { return this->localNode->getActiveProxyServers(); }
+
+    /* slots admin and info interface */
+    /** @returns the total number of players in this game (including all proxy servers etc)*/
+    inline int getPlayerNumber() const { return this->playerNumber; }
+
+    /** @returns true if there are still free network slots available at the local node*/
+    inline bool gotFreeSlots() const { return (this->localNode->getPlayerNumber() < SharedNetworkData::getInstance()->getMaxPlayer()); }
+    /** @param node node to be checked for slots @returns true if there are still free network slots available at this node */
+    inline bool gotFreeSlots(NetworkNode* node) const { return (node->getPlayerNumber() < SharedNetworkData::getInstance()->getMaxPlayer()); }
+
+    /** @returns true if the next client should be reconnected to some other proxy server with more connections */
+    inline bool isReconnectNextClient() const { return (this->localNode->getPlayerNumber() >= SharedNetworkData::getInstance()->getMaxPlayer()); }
+
+    inline const std::list<NetworkNode*>& getNodeList() const { return this->nodeList; };
+    PeerInfo* getPeerByUserId( int userId);
+    NetworkNode* getNodeByUserId( int userId);
+
+    /* forced reconnection interface */
+    inline void setForcedReconnection(IP address) { this->bForcedRecon = true; this->forcedReconnection = address;}
+    inline bool isForcedReconnection() const { return this->bForcedRecon; }
+    inline IP getForcedReconnectionIP() { this->bForcedRecon = false; return this->forcedReconnection; }
+
+
+    void toggleGUI();
+
+    void process();
+    void debug() const;
+
+
+  private:
+    NetworkStream*               networkStream;              //!< reference to the one networkstream of the network
+    NetworkNode*                 localNode;                  //!< reference to the local node
+    std::list<NetworkNode*>      nodeList;                   //!< list of all network nodes
+
+    OrxGui::GLGuiBox*            box;
+
+    int                          playerNumber;                 //!< total number of players in the game
+    int                          connectionNumber;             //!< total number of connections at this localhost
+
+    IP                           forcedReconnection;           //!< ip of a forced reconnection
+    bool                         bForcedRecon;                 //!< true if there is a forced recon
+};
+
+
+#endif
Index: branches/heathaze/src/lib/network/monitor/network_node.cc
===================================================================
--- branches/heathaze/src/lib/network/monitor/network_node.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/monitor/network_node.cc	(revision 9940)
@@ -0,0 +1,459 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+
+#include "network_node.h"
+
+#include "debug.h"
+
+/**
+ * constructor
+ */
+NetworkNode::NetworkNode(PeerInfo* pInfo)
+{
+  this->playerNumber = 0;
+  this->peerInfo = pInfo;
+}
+
+
+/**
+ * deconstructor
+ */
+NetworkNode::~NetworkNode()
+{}
+
+
+/**
+ * adds a client
+ */
+void NetworkNode::addClient(NetworkNode* node)
+{
+  this->clientList.push_back(node);
+  this->playerNumber++;
+  this->connectionNumber++;
+}
+
+/**
+ * adds a proxy server
+ */
+void NetworkNode::addActiveProxyServer(NetworkNode* node)
+{
+  this->activeProxyServerList.push_back(node);
+  this->connectionNumber++;
+}
+
+/**
+ * adds a proxy server
+ */
+void NetworkNode::addPassiveProxyServer(NetworkNode* node)
+{
+  this->passiveProxyServerList.push_back(node);
+}
+
+/**
+ * adds a master server
+ */
+void NetworkNode::addMasterServer(NetworkNode* node)
+{
+  this->masterServerList.push_back(node);
+  this->playerNumber++;
+}
+
+/**
+ * removes a client
+ */
+void NetworkNode::removeClient(NetworkNode* node)
+{
+  std::list<NetworkNode*>::iterator it = this->clientList.begin();
+  for(; it != this->clientList.end(); it++)
+  {
+    if( *it == node)
+    {
+      this->clientList.erase(it);
+      this->playerNumber--;
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove client from the list, very strange...");
+}
+
+/**
+ * removes a proxy server
+ */
+void NetworkNode::removeActiveProxyServer(NetworkNode* node)
+{
+  std::list<NetworkNode*>::iterator it = this->activeProxyServerList.begin();
+  for(; it != this->activeProxyServerList.end(); it++)
+  {
+    if( *it == node)
+    {
+      this->activeProxyServerList.erase(it);
+      this->playerNumber--;
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove proxy server from the list, very strange...");
+}
+
+/**
+ * removes a proxy server
+ */
+void NetworkNode::removePassiveProxyServer(NetworkNode* node)
+{
+  std::list<NetworkNode*>::iterator it = this->passiveProxyServerList.begin();
+  for(; it != this->passiveProxyServerList.end(); it++)
+  {
+    if( *it == node)
+    {
+      this->passiveProxyServerList.erase(it);
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove proxy server from the list, very strange...");
+}
+
+/**
+ * removes a master server
+ */
+void NetworkNode::removeMasterServer(NetworkNode* node)
+{
+  std::list<NetworkNode*>::iterator it = this->masterServerList.begin();
+  for(; it != this->masterServerList.end(); it++)
+  {
+    if( *it == node)
+    {
+      this->masterServerList.erase(it);
+      this->playerNumber--;
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove client from the list, very strange...");
+}
+
+
+
+
+/**
+ * removes a client
+ */
+void NetworkNode::removeClient(int userId)
+{
+  std::list<NetworkNode*>::iterator it = this->clientList.begin();
+  for(; it != this->clientList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+    {
+      this->clientList.erase(it);
+      this->playerNumber--;
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove client from the list, very strange...");
+}
+
+/**
+ * removes a proxy server
+ */
+void NetworkNode::removeActiveProxyServer(int userId)
+{
+  std::list<NetworkNode*>::iterator it = this->activeProxyServerList.begin();
+  for(; it != this->activeProxyServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+    {
+      this->activeProxyServerList.erase(it);
+      this->playerNumber--;
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove proxy server from the list, very strange...");
+}
+
+/**
+ * removes a proxy server
+ */
+void NetworkNode::removePassiveProxyServer(int userId)
+{
+  std::list<NetworkNode*>::iterator it = this->passiveProxyServerList.begin();
+  for(; it != this->passiveProxyServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+    {
+      this->passiveProxyServerList.erase(it);
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove proxy server from the list, very strange...");
+}
+
+/**
+ * removes a master server
+ */
+void NetworkNode::removeMasterServer(int userId)
+{
+  std::list<NetworkNode*>::iterator it = this->masterServerList.begin();
+  for(; it != this->masterServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+    {
+      this->masterServerList.erase(it);
+      this->playerNumber--;
+      return;
+    }
+  }
+
+  PRINTF(2)("Could not remove client from the list, very strange...");
+}
+
+
+
+
+
+/**
+ *  gets the peer info by user id
+ * @param userId  the user id of the node to look up
+ * @return the peer info of this node NULL if nothing found
+ */
+PeerInfo* NetworkNode::getPeerByUserId( int userId)
+{
+  // look through the master server lists
+  std::list<NetworkNode*>::const_iterator it = this->masterServerList.begin();
+  for( ;it != this->masterServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+      return (*it)->getPeerInfo();
+  }
+
+  // look through the active proxy server list
+  it = this->activeProxyServerList.begin();
+  for( ; it != this->activeProxyServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+      return (*it)->getPeerInfo();
+  }
+
+  // look through the passive server list
+  it = this->passiveProxyServerList.begin();
+  for( ; it != this->passiveProxyServerList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+      return (*it)->getPeerInfo();
+  }
+
+  // look through the client list
+  it = this->clientList.begin();
+  for( ; it != this->clientList.end(); it++)
+  {
+    if( (*it)->getPeerInfo()->userId == userId)
+      return (*it)->getPeerInfo();
+  }
+
+  return NULL;
+}
+
+
+/**
+ * @param index index to the client
+ * @return the client in the list or NULL if none
+ */
+PeerInfo* NetworkNode::getClient(int index) const
+{
+  if( (int)this->clientList.size() < index)
+    return NULL;
+
+  std::list<NetworkNode*>::const_iterator it = this->clientList.begin();
+  for(int i = 0; it != this->clientList.end(); it++, i++)
+  {
+  if( i == index)
+    return (*it)->getPeerInfo();
+  }
+
+  return NULL;
+}
+
+
+/**
+ * @param index index to the client
+ * @return the active proxy server in the list or NULL if none
+ */
+PeerInfo* NetworkNode::getActiveProxyServer(int index) const
+{
+  if( (int)this->activeProxyServerList.size() < index)
+    return NULL;
+
+  std::list<NetworkNode*>::const_iterator it = this->activeProxyServerList.begin();
+  for(int i = 0; it != this->activeProxyServerList.end(); it++, i++)
+  {
+    if( i == index)
+      return (*it)->getPeerInfo();
+  }
+
+  return NULL;
+}
+
+
+/**
+ * @param index index to the client
+ * @return the passive proxy server in the list or NULL if none
+ */
+PeerInfo* NetworkNode::getPassiveProxyServer(int index) const
+{
+  if( (int)this->passiveProxyServerList.size() < index)
+    return NULL;
+
+  std::list<NetworkNode*>::const_iterator it = this->passiveProxyServerList.begin();
+  for(int i = 0; it != this->passiveProxyServerList.end(); it++, i++)
+  {
+    if( i == index)
+      return (*it)->getPeerInfo();
+  }
+
+  return NULL;
+}
+
+
+/**
+ * @param index index to the client
+ * @return the master server in the list or NULL if none
+ */
+PeerInfo* NetworkNode::getMasterServer(int index) const
+{
+  if( (int)this->masterServerList.size() < index)
+    return NULL;
+
+  std::list<NetworkNode*>::const_iterator it = this->masterServerList.begin();
+  for(int i = 0; it != this->masterServerList.end(); it++, i++)
+  {
+    if( i == index)
+      return (*it)->getPeerInfo();
+  }
+
+  return NULL;
+}
+
+
+
+/**
+ * searches for a given NetworkNode
+ * @param userId of the searched node
+ * @returns the PeerInfo of the userId peer
+ */
+NetworkNode* NetworkNode::getNodeByUserId( int userId)
+{
+  if( this->peerInfo->userId == userId)
+    return this;
+
+
+  NetworkNode* node = NULL;
+  std::list<NetworkNode*>::const_iterator it = this->masterServerList.begin();
+
+  for(; it != this->masterServerList.end(); it++)
+  {
+    node = (*it)->getNodeByUserId(userId);
+    if( node != NULL)
+      return node;
+  }
+
+  it = this->activeProxyServerList.begin();
+  for(; it != this->activeProxyServerList.end(); it++)
+  {
+    node = (*it)->getNodeByUserId(userId);
+    if( node != NULL)
+      return node;
+  }
+
+  it = this->passiveProxyServerList.begin();
+  for(; it != this->passiveProxyServerList.end(); it++)
+  {
+    node = (*it)->getNodeByUserId(userId);
+    if( node != NULL)
+      return node;
+  }
+
+  it = this->clientList.begin();
+  for(; it != this->clientList.end(); it++)
+  {
+    node = (*it)->getNodeByUserId(userId);
+    if( node != NULL)
+      return node;
+  }
+
+  return NULL;
+}
+
+
+/**
+ * debug function
+ * @param depth: depth in the tree
+ */
+void NetworkNode::debug(int depth) const
+{
+  char indent[depth +1];
+  for( int i = 0; i < depth; i++) {     indent[i] = ' ';  }
+  indent[depth] = '\0';
+
+  PRINT(0)("%s + %s, with id %i and ip: %s\n", indent, this->peerInfo->getNodeTypeString().c_str(), this->peerInfo->userId, this->peerInfo->ip.ipString().c_str());
+
+
+
+  std::list<NetworkNode*>::const_iterator it;
+  if( !this->masterServerList.empty())
+  {
+    it = this->masterServerList.begin();
+
+    for(; it != this->masterServerList.end(); it++)
+    {
+      (*it)->debug(depth+1);
+    }
+  }
+
+  if( !this->activeProxyServerList.empty())
+  {
+    it = this->activeProxyServerList.begin();
+
+    for(; it != this->activeProxyServerList.end(); it++)
+    {
+      (*it)->debug(depth+1);
+    }
+  }
+
+
+  if( !this->passiveProxyServerList.empty())
+  {
+    it = this->passiveProxyServerList.begin();
+
+    for(; it != this->passiveProxyServerList.end(); it++)
+    {
+      (*it)->debug(depth+1);
+    }
+  }
+
+  if( !this->clientList.empty())
+  {
+    it = this->clientList.begin();
+
+    for(; it != this->clientList.end(); it++)
+    {
+      (*it)->debug(depth+1);
+    }
+  }
+}
+
Index: branches/heathaze/src/lib/network/monitor/network_node.h
===================================================================
--- branches/heathaze/src/lib/network/monitor/network_node.h	(revision 9940)
+++ branches/heathaze/src/lib/network/monitor/network_node.h	(revision 9940)
@@ -0,0 +1,80 @@
+/*!
+ * @file network_node.h
+ *  a class representing a node in the network (this can be a MASTER_SERVER, PROXY_SERVER or a CLIENT
+ */
+
+#ifndef _NETWORK_NODE_H
+#define _NETWORK_NODE_H
+
+#include "base_object.h"
+#include "synchronizeable.h"
+#include "peer_info.h"
+
+#include <list>
+
+//!< a class representing a node in the network (this can be a MASTER_SERVER, PROXY_SERVER or a CLIENT
+class NetworkNode
+{
+  public:
+    NetworkNode(PeerInfo* pInfo);
+    ~NetworkNode();
+
+
+    void addClient(NetworkNode* node);
+    void addActiveProxyServer(NetworkNode* node);
+    void addPassiveProxyServer(NetworkNode* node);
+    void addMasterServer(NetworkNode* node);
+
+    void removeClient(NetworkNode* node);
+    void removeActiveProxyServer(NetworkNode* node);
+    void removePassiveProxyServer(NetworkNode* node);
+    void removeMasterServer(NetworkNode* node);
+
+    void removeClient(int userId);
+    void removeActiveProxyServer(int userId);
+    void removePassiveProxyServer(int userId);
+    void removeMasterServer(int userId);
+
+
+    PeerInfo* getClient(int index) const;
+    PeerInfo* getActiveProxyServer(int index) const;
+    PeerInfo* getPassiveProxyServer(int index) const;
+    PeerInfo* getMasterServer(int index) const;
+
+    /** @returns the master server list */
+    inline std::list<NetworkNode*> getMasterServers() const { return this->masterServerList; }
+    /** @returns the active proxy server list */
+    inline std::list<NetworkNode*> getActiveProxyServers() const { return this->activeProxyServerList; }
+    /** @returns the passive proxy server list */
+    inline std::list<NetworkNode*> getPassiveProxyServers() const { return this->passiveProxyServerList; }
+    /** @returns the client list */
+    inline std::list<NetworkNode*> getClients() const { return this->clientList; }
+
+    PeerInfo* getPeerByUserId( int userId);
+
+    /** @returns the number of players */
+    inline int getPlayerNumber() const { return this->playerNumber; }
+    /** @returns the node type of this node */
+    inline int getNodeType() const { return this->peerInfo->nodeType; }
+    /** @returns the peer info of this node */
+    inline PeerInfo* getPeerInfo() const { return this->peerInfo; }
+
+    NetworkNode* getNodeByUserId( int userId);
+
+    void debug(int depth) const;
+
+
+  private:
+    int                          playerNumber;                 //!< localy direct connected player number
+    int                          connectionNumber;             //!< number of connections ( can but musn't be equal players)
+    PeerInfo*                    peerInfo;                     //!< the peer information about this node
+
+    /* network nodes directly connected to this node */
+    std::list<NetworkNode*>         clientList;                   //!< list of all clients in the network
+    std::list<NetworkNode*>         activeProxyServerList;        //!< list of all proxy servers in the network
+    std::list<NetworkNode*>         passiveProxyServerList;       //!< list of all proxy servers in the network
+    std::list<NetworkNode*>         masterServerList;             //!< list of all master servers in the network (should be 1!! :D)
+
+};
+
+#endif /* _NETWORK_NODE_H */
Index: branches/heathaze/src/lib/network/monitor/network_stats_widget.cc
===================================================================
--- branches/heathaze/src/lib/network/monitor/network_stats_widget.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/monitor/network_stats_widget.cc	(revision 9940)
@@ -0,0 +1,372 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "network_stats_widget.h"
+#include "network_monitor.h"
+#include "peer_info.h"
+
+#include "loading/resource_manager.h"
+
+#include "multi_type.h"
+
+#include "shell_command.h"
+
+// this fcuk does not work!
+// SHELL_COMMAND(gui, NetworkStatsWidget, toggleGUI)
+// ->setAlias("ProxyGui");
+
+HostWidget::HostWidget(const std::string& name, const IP& ip)
+    : GLGuiBox(OrxGui::Horizontal)
+{
+  this->init();
+
+  this->setName(name);
+  this->setIP(ip);
+
+}
+
+HostWidget::HostWidget(const PeerInfo* peerInfo)
+    : GLGuiBox(OrxGui::Horizontal)
+{
+  this->init();
+  if (peerInfo == NULL)
+  {
+    this->setName("INVALID");
+    return;
+  }
+  this->setName(peerInfo->getNodeTypeString() + "ID: " + MultiType(peerInfo->userId).getString());
+  this->setIP(peerInfo->ip);
+}
+
+void HostWidget::init()
+{
+  if(_font == NULL)
+    _font = new Font(Resources::ResourceManager::getInstance()->mainGlobalPath().name() + "/fonts/arial.ttf", 20);
+
+  //this->_name.setFont(*_font);
+  this->_name.setTextSize(15);
+  //this->_ip.setFont(*_font);
+  this->_ip.setTextSize(15);
+
+  this->pack(&this->_name);
+  this->pack(&this->_ip);
+}
+
+void HostWidget::showing()
+{
+  this->_name.show();
+  this->_ip.show();
+}
+
+void HostWidget::hiding()
+{
+  this->_name.hide();
+  this->_ip.hide();
+}
+
+Font* HostWidget::_font = NULL;
+
+
+
+
+//======================================================//
+
+
+NodeWidget::NodeWidget(const std::string& proxyName, const IP& ip)
+    : _proxyWidget(proxyName, ip)
+{
+  this->_nodeNameWidth = 100.0f;
+  this->pack(&_proxyWidget);
+}
+
+NodeWidget::NodeWidget(const NetworkNode* node)
+    : _proxyWidget(node->getPeerInfo())// "node", node->getPeerInfo()->ip)
+{
+  this->_nodeNameWidth = 100.0f;
+  this->pack(&_proxyWidget);
+
+  std::list<NetworkNode*> list = node->getMasterServers();
+  std::list<NetworkNode*>::const_iterator it;
+
+  for(it = list.begin(); it != list.end(); it++)
+    this->addNode(*it);
+
+  list = node->getActiveProxyServers();
+  for(it = list.begin(); it != list.end(); it++)
+    this->addNode(*it);
+
+  list = node->getPassiveProxyServers();
+  for(it = list.begin(); it != list.end(); it++)
+    this->addNode(*it);
+
+  list = node->getClients();
+  for(it = list.begin(); it != list.end(); it++)
+    this->addNode(*it);
+}
+
+
+void NodeWidget::addNode(const NetworkNode* node)
+{
+  this->_nodes.push_back(new NodeWidget(node));
+  this->pack(this->_nodes.back());
+  this->_nodes.back()->show();
+}
+
+
+void NodeWidget::addNode(const std::string& name, const IP& ip)
+{
+  HostWidget* newClient = new HostWidget(name, ip);
+  newClient->setNameWidth(this->_nodeNameWidth);
+
+  this->pack(newClient);
+
+  if (this->isVisible())
+    newClient->show();
+}
+
+bool NodeWidget::removeNode(const IP& ip)
+{
+//   std::vector<HostWidget*>::iterator rmIt;
+//   for(rmIt = this->_nodes.begin(); rmIt != this->_nodes.end(); ++rmIt)
+//   {
+//     if (*(*rmIt) == ip)
+//     {
+//       delete (*rmIt);
+//       this->_nodes.erase(rmIt);
+//       return true;
+//     }
+//   }
+//   return false;
+}
+
+bool NodeWidget::removeNode(const std::string& name)
+{
+//   std::vector<HostWidget*>::iterator rmIt;
+//   for(rmIt = this->_nodes.begin(); rmIt != this->_nodes.end(); ++rmIt)
+//   {
+//     if (*(*rmIt) == name)
+//     {
+//       delete (*rmIt);
+//       this->_nodes.erase(rmIt);
+//       return true;
+//     }
+//   }
+//   return false;
+
+}
+
+bool NodeWidget::removeNode(const std::string& name, const IP& ip)
+{
+//   std::vector<HostWidget*>::iterator rmIt;
+//   for(rmIt = this->_nodes.begin(); rmIt != this->_nodes.end(); ++rmIt)
+//   {
+//     if (*(*rmIt) == ip && *(*rmIt) == name)
+//     {
+//       delete (*rmIt);
+//       this->_nodes.erase(rmIt);
+//       return true;
+//     }
+//   }
+//   return false;
+}
+
+
+void NodeWidget::setNodeNameWidths(float width)
+{
+/*  this->_nodeNameWidth = width;
+  for (unsigned int i = 0; i < this->_nodes.size(); ++i)
+    this->_nodes[i]->setNameWidth(width);*/
+}
+
+void NodeWidget::hiding()
+{
+  this->_proxyWidget.hide();
+  for (unsigned int i = 0; i < this->_nodes.size(); ++i)
+    this->_nodes[i]->hide();
+}
+
+void NodeWidget::showing()
+{
+  this->_proxyWidget.show();
+  for (unsigned int i = 0; i < this->_nodes.size(); ++i)
+    this->_nodes[i]->show();
+}
+
+
+//======================================================//
+
+
+ObjectListDefinition(NetworkStatsWidget);
+/**
+ * @brief standard constructor
+ */
+NetworkStatsWidget::NetworkStatsWidget(const NetworkMonitor* monitor)
+    : OrxGui::GLGuiFixedpositionBox(OrxGui::Center, OrxGui::Vertical), _thisHost("myName", IP(127, 0, 0 , 1))
+{
+  this->_monitor = monitor;
+  this->_passedTime = 0.0f;
+
+  /*
+  this->_bar.setSize2D(100, 30);
+  this->pack(&this->_valueText);
+  this->_bar.setParent2D(&this->_valueText);
+
+  this->_valueText.setChangedTextColor(Color::white);
+
+  //this->setBackgroundTexture("maps/gui_element_background_2.png");
+  this->setBackgroundColor(Color(.5,.5,.5,1));
+
+  //this->_name.setBackgroundTexture(Texture());
+  //this->_valueText.setBackgroundTexture("maps/gui_element_background_2.png");
+  this->_bar.setBackgroundTexture(Texture());
+  this->_bar.setBackgroundColor(Color(0,0,0,0));
+  this->_bar.setForegroundTexture("maps/gui_element_background_faded.png");
+  this->_bar.setForegroundColor(Color(.5, .5, .5, 1));
+  this->_bar.setChangedValueColor(Color::black);
+  */
+  this->_thisHostIs.setText(std::string("I am ") + _monitor->getLocalNode()->getPeerInfo()->getNodeTypeString());
+
+  this->pack(&this->_thisHostIs);
+
+  this->pack(&this->_thisHost);
+
+  this->pack(&this->_serverBox);
+
+  this->pack(&this->_upstreamText);
+  this->pack(&this->_downstreamText);
+
+
+  this->rebuild();
+}
+
+
+/**
+ * @brief standard deconstructor
+ */
+NetworkStatsWidget::~NetworkStatsWidget ()
+{}
+
+
+void NetworkStatsWidget::addNode(const NetworkNode* node)
+{
+  this->_proxies.push_back(new NodeWidget(node));
+  this->_serverBox.pack(this->_proxies.back());
+  this->_proxies.back()->show();
+}
+
+
+
+
+NetworkStatsWidget* NetworkStatsWidget::_statsWidget = NULL;
+
+void NetworkStatsWidget::toggleGUI()
+{
+  NetworkMonitor* monitor;
+  if (!NetworkMonitor::objectList().empty())
+    monitor = NetworkMonitor::objectList().front();
+
+  if (monitor != NULL && NetworkStatsWidget::_statsWidget == NULL)
+  {
+    NetworkStatsWidget::_statsWidget = new NetworkStatsWidget(monitor);
+    NetworkStatsWidget::_statsWidget->showAll();
+  }
+  else
+  {
+    delete NetworkStatsWidget::_statsWidget;
+    NetworkStatsWidget::_statsWidget = NULL;
+  }
+}
+
+
+void NetworkStatsWidget::setMaximum(float max)
+{
+  // this->_bar.setMaximum(max);
+}
+
+void NetworkStatsWidget::setValue(float value)
+{
+  MultiType val(value);
+  val.setType(MT_INT);
+  /*
+
+  this->_bar.setValue(value);
+  this->_bar.setForegroundColor(Color::slerpHSVColor(Color::red, Color::green, value/this->_bar.maximum()));
+  this->_bar.setFrontColor(Color(1,1,1,1), true);
+  this->_valueText.setText(val.getString());
+  */
+}
+
+
+void NetworkStatsWidget::addProxy(const std::string& name, const IP& proxy)
+{}
+
+void NetworkStatsWidget::clearProxies()
+{}
+
+
+void NetworkStatsWidget::rebuild()
+{
+  while (!this->_proxies.empty())
+  {
+    delete this->_proxies.back();
+    this->_proxies.pop_back();
+  }
+
+  const NetworkNode* node = this->_monitor->getLocalNode();
+  if (node == NULL)
+  {
+    printf("NO NODE\n");
+    return;
+  }
+
+  this->addNode(node);
+}
+
+
+
+void NetworkStatsWidget::tick(float dt)
+{
+
+  if ((_passedTime+= dt) > 1.0f)
+  {
+    this->_passedTime = 0.0f;
+    this->rebuild();
+  }
+
+  assert (this->_monitor->getLocalNode() != NULL);
+  assert(this->_monitor->getLocalNode()->getPeerInfo() != NULL);
+
+  if(this->_monitor->getLocalNode()->getPeerInfo()->connectionMonitor != NULL)
+  {
+    ConnectionMonitor* mon = this->_monitor->getLocalNode()->getPeerInfo()->connectionMonitor;
+
+    this->_upstreamText.setText(MultiType(mon->getOutgoingZippedBandWidth()).getString());
+    this->_downstreamText.setText(MultiType(mon->getIncomingZippedBandWidth()).getString());
+  }
+}
+
+void NetworkStatsWidget::resize()
+{
+  GLGuiFixedpositionBox::resize();
+}
+
+
+void NetworkStatsWidget::showing()
+{}
+
+void NetworkStatsWidget::hiding()
+{}
Index: branches/heathaze/src/lib/network/monitor/network_stats_widget.h
===================================================================
--- branches/heathaze/src/lib/network/monitor/network_stats_widget.h	(revision 9940)
+++ branches/heathaze/src/lib/network/monitor/network_stats_widget.h	(revision 9940)
@@ -0,0 +1,137 @@
+/*!
+ * @file network_stats_widget.h
+ * @brief Definition of an EnergyWidget, that displays a bar and a Text
+ */
+
+#ifndef _NETWORK_STATS_WIDGET_H
+#define _NETWORK_STATS_WIDGET_H
+
+#include "glgui_fixedposition_box.h"
+#include "glgui_bar.h"
+#include "glgui_text.h"
+#include "glgui_pushbutton.h"
+
+#include "network/ip.h"
+
+class NetworkMonitor;
+class NetworkNode;
+class PeerInfo;
+
+class HostWidget : public OrxGui::GLGuiBox
+{
+  public:
+    HostWidget(const std::string& name, const IP& ip);
+    HostWidget(const PeerInfo* peerInfo);
+
+    void setName(const std::string& name) { this->_name.setText(name); };
+    void setIP(const IP& ip) { this->_ip.setText(std::string("at ") + ip.ipString()); this->_storedIP = ip; };
+
+    void setNameWidth(float width) { this->_name.setLineWidth(width); };
+
+    bool operator==(const IP& ip) const { return (this->_storedIP == ip); };
+    bool operator==(const std::string& name) const { return (this->_name == name); };
+
+  protected:
+    virtual void showing();
+    virtual void hiding();
+
+  private:
+    void init();
+  private:
+    OrxGui::GLGuiText _name;           //!< The Name of the Proxy server to be displayed.
+    OrxGui::GLGuiText _ip;             //!< The IP of the proxy server.
+    IP                _storedIP;       //!< The ip to compare.
+
+    static Font*      _font;
+};
+
+
+class NodeWidget : public OrxGui::GLGuiBox
+{
+  public:
+    NodeWidget(const std::string& proxyName, const IP& ip);
+    NodeWidget(const NetworkNode* node);
+
+    void addNode(const NetworkNode* node);
+    void addNode(const std::string& name, const IP& ip);
+
+    bool removeNode(const IP& ip);
+    bool removeNode(const std::string& name);
+    bool removeNode(const std::string& name, const IP& ip);
+
+    void setNodeNameWidths(float width);
+
+
+  protected:
+    virtual void hiding();
+    virtual void showing();
+
+
+  private:
+    HostWidget                _proxyWidget;
+
+    std::vector<NodeWidget*>  _nodes;
+    float                     _nodeNameWidth;
+};
+
+
+
+
+//! A class to display network Statistics.
+class NetworkStatsWidget : public OrxGui::GLGuiFixedpositionBox
+{
+  ObjectListDeclaration(NetworkStatsWidget);
+  public:
+    static void toggleGUI();
+
+    NetworkStatsWidget(const NetworkMonitor* monitor);
+    virtual ~NetworkStatsWidget();
+
+    void setUpstream(unsigned int upstream);
+    void setDownstream(unsigned int upstream);
+    void setIP(const IP& ip);
+
+
+
+    void addProxy(const std::string& name, const IP& proxy);
+    void addNode(const NetworkNode* node);
+
+    void clearProxies();
+
+    void rebuild();
+
+    //void rebuildConnectedHosts(std::vector<hosts> hosts);
+
+    void setMaximum(float max);
+    void setValue(float value);
+
+    virtual void tick(float dt);
+
+  protected:
+    virtual void resize();
+    virtual void showing();
+    virtual void hiding();
+
+  private:
+    const NetworkMonitor*  _monitor;
+
+    OrxGui::GLGuiText      _thisHostIs;
+    HostWidget             _thisHost;
+
+    OrxGui::GLGuiText      _upstreamText;
+    OrxGui::GLGuiText      _downstreamText;
+
+    OrxGui::GLGuiBox       _serverBox;
+
+    std::vector<NodeWidget*> _proxies;
+
+
+    static NetworkStatsWidget*    _statsWidget;
+
+
+    float                   _passedTime;
+    //OrxGui::GLGuiText       _valueText;
+    //OrxGui::GLGuiBar        _bar;
+};
+
+#endif /* _NETWORK_STATS_WIDGET_H */
Index: branches/heathaze/src/lib/network/netdefs.h
===================================================================
--- branches/heathaze/src/lib/network/netdefs.h	(revision 9940)
+++ branches/heathaze/src/lib/network/netdefs.h	(revision 9940)
@@ -0,0 +1,139 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner rennerc@ee.ethz.ch
+   co-programmer:   Patrick Boenzli  boenzlip@orxonox.ethz.ch
+
+     June 2006: finishing work on the network stream for pps presentation (rennerc@ee.ethz.ch)
+     July 2006: some code rearangement and integration of the proxy server mechanism (boenzlip@ee.ethz.ch)
+*/
+
+/*!
+ * @file network_manager.h
+ *  Main interface for the network module. Manages all the modules
+ */
+
+#ifndef _NETDEFS_H
+#define _NETDEFS_H
+
+#include "nettypes.h"
+#include "netincl.h"
+
+
+
+//!< the amount of slots used before a proxy server is activated
+#define NET_CONNECTION_SATURATION 0.75
+
+//!< network polling frequency
+#define NETWORK_FREQUENCY 66
+
+
+//!< orxonox protocol id
+#define _ORXONOX_ID        0xF91337A0
+//!< orxonox network version identifier
+#define _ORXONOX_VERSION   1
+
+
+
+
+//!< enum indicating the type of the node
+typedef enum {
+  NET_UNASSIGNED              = -1,
+
+  NET_MASTER_SERVER           =  0,
+  NET_PROXY_SERVER_ACTIVE,
+  NET_PROXY_SERVER_PASSIVE,
+  NET_CLIENT,
+
+  NET_NR_TYPES
+
+} NodeType;
+
+
+//!< enum indicating the type of the network connection (2 protocols supported)
+typedef enum ConnectionType {
+  NET_UDP = 0,
+  NET_TCP
+};
+
+
+//!< the type of the unique id (special number never used elsewhere)
+typedef enum {
+  NET_UID_UNASSIGNED = -1,
+
+  NET_UID_HANDSHAKE  =  0,
+
+
+  NET_UID_NUMBER
+} UidType;
+
+
+//!< the network id list
+typedef enum nodeId {
+  NET_ID_UNASSIGNED       =-1,
+
+  NET_ID_MASTER_SERVER    = 0,
+
+  NET_ID_PROXY_SERVER_01  = 1,
+  NET_ID_PROXY_SERVER_02,
+  NET_ID_PROXY_SERVER_03,
+  NET_ID_PROXY_SERVER_04,
+  NET_ID_PROXY_SERVER_05,
+  NET_ID_PROXY_SERVER_06,
+  NET_ID_PROXY_SERVER_07,
+  NET_ID_PROXY_SERVER_08  = 8,
+
+  NET_ID_PROXY_MAX        = 8,
+
+  NET_ID_CLIENT_01        = 9,
+  NET_ID_CLIENT_02,
+  NET_ID_CLIENT_03,
+  NET_ID_CLIENT_04,
+  NET_ID_CLIENT_05,
+  NET_ID_CLIENT_06,
+  NET_ID_CLIENT_07,
+  NET_ID_CLIENT_08,
+  NET_ID_CLIENT_09,
+  NET_ID_CLIENT_10,
+  NET_ID_CLIENT_11,
+  NET_ID_CLIENT_12,
+  NET_ID_CLIENT_13,
+  NET_ID_CLIENT_14,
+  NET_ID_CLIENT_15,
+  NET_ID_CLIENT_16,
+  NET_ID_CLIENT_17,
+  NET_ID_CLIENT_18,
+  NET_ID_CLIENT_19,
+  NET_ID_CLIENT_20,
+  NET_ID_CLIENT_21,
+  NET_ID_CLIENT_22,
+  NET_ID_CLIENT_23,
+  NET_ID_CLIENT_24,
+  NET_ID_CLIENT_25,
+  NET_ID_CLIENT_26,
+  NET_ID_CLIENT_27,
+  NET_ID_CLIENT_28,
+  NET_ID_CLIENT_29,
+  NET_ID_CLIENT_30,
+  NET_ID_CLIENT_31,
+  NET_ID_CLIENT_32,
+  NET_ID_CLIENT_33,
+  NET_ID_CLIENT_34,
+  NET_ID_CLIENT_35,
+  NET_ID_CLIENT_36,
+  NET_ID_CLIENT_37,
+  NET_ID_CLIENT_38,
+  NET_ID_CLIENT_39,
+  NET_ID_CLIENT_40,
+
+  NET_ID_CLIENT_MAX        = 40
+};
+#endif /* _NETDEFS_H */
Index: branches/heathaze/src/lib/network/netincl.h
===================================================================
--- branches/heathaze/src/lib/network/netincl.h	(revision 9940)
+++ branches/heathaze/src/lib/network/netincl.h	(revision 9940)
@@ -0,0 +1,12 @@
+
+#ifndef _NETINCL_H
+#define _NETINCL_H
+
+#ifdef HAVE_SDL_NET_H
+#include <SDL_net.h>
+#else
+#include <SDL/SDL_net.h>
+#endif
+
+
+#endif /* _NETINCL_H */
Index: branches/heathaze/src/lib/network/nettypes.h
===================================================================
--- branches/heathaze/src/lib/network/nettypes.h	(revision 9940)
+++ branches/heathaze/src/lib/network/nettypes.h	(revision 9940)
@@ -0,0 +1,18 @@
+
+#ifndef __NET_TYPES_H_
+#define __NET_TYPES_H_
+
+typedef unsigned char byte;
+
+
+//!< this are the network write variable permissions
+typedef enum netPermissions {
+  PERMISSION_MASTER_SERVER = 1,
+  PERMISSION_PROXY_SERVER  = 2,
+  PERMISSION_SERVER        = 4,
+  PERMISSION_OWNER         = 8,
+  PERMISSION_ALL           = 16
+};
+
+
+#endif /* __NET_TYPES_H */
Index: branches/heathaze/src/lib/network/network_game_manager.cc
===================================================================
--- branches/heathaze/src/lib/network/network_game_manager.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/network_game_manager.cc	(revision 9940)
@@ -0,0 +1,369 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner rennerc@ee.ethz.ch
+   co-programmer:   Patrick Boenzli  boenzlip@orxonox.ethz.ch
+
+     June 2006: finishing work on the network stream for pps presentation (rennerc@ee.ethz.ch)
+     July 2006: some code rearangement and integration of the proxy server mechanism (boenzlip@ee.ethz.ch)
+*/
+
+
+
+#define DEBUG_MODULE_NETWORK
+
+#include "util/loading/factory.h"
+#include "state.h"
+#include "debug.h"
+
+#include "network_stream.h"
+#include "shared_network_data.h"
+#include "converter.h"
+#include "message_manager.h"
+
+#include "playable.h"
+#include "player.h"
+
+#include "game_world.h"
+
+#include "game_rules.h"
+#include "network_game_rules.h"
+
+#include "network_game_manager.h"
+
+#include "multiplayer_team_deathmatch.h"
+
+#include "parser/preferences/preferences.h"
+
+
+
+ObjectListDefinition(NetworkGameManager);
+NetworkGameManager* NetworkGameManager::singletonRef = NULL;
+
+/*!
+ * Standard constructor
+ */
+NetworkGameManager::NetworkGameManager()
+  : Synchronizeable()
+{
+  PRINTF(0)("START\n");
+
+  /* set the class id for the base object */
+  this->registerObject(this, NetworkGameManager::_objectList);
+
+  this->setSynchronized(true);
+
+  MessageManager::getInstance()->registerMessageHandler( MSGID_DELETESYNCHRONIZEABLE, delSynchronizeableHandler, NULL );
+  MessageManager::getInstance()->registerMessageHandler( MSGID_PREFEREDTEAM, preferedTeamHandler, NULL );
+  MessageManager::getInstance()->registerMessageHandler( MSGID_CHATMESSAGE, chatMessageHandler, NULL );
+
+  this->gameState = 0;
+  registerVar( new SynchronizeableInt( &gameState, &gameState, "gameState", PERMISSION_MASTER_SERVER ) );
+}
+
+/*!
+ * Standard destructor
+ */
+NetworkGameManager::~NetworkGameManager()
+{
+  delete MessageManager::getInstance();
+
+  PlayerStats::deleteAllPlayerStats();
+
+  NetworkGameManager::singletonRef = NULL;
+}
+
+
+/**
+ * insert new player into game
+ * @param userId
+ * @return
+ */
+bool NetworkGameManager::signalNewPlayer( int userId )
+{
+  assert( SharedNetworkData::getInstance()->isMasterServer());
+  assert( State::getGameRules() );
+  assert( State::getGameRules()->isA( NetworkGameRules::staticClassID()) );
+
+  NetworkGameRules & rules = *(dynamic_cast<NetworkGameRules*>(State::getGameRules()));
+
+  int          team = rules.getTeamForNewUser();
+  ClassID   playableClassId = rules.getPlayableClassId( userId, team );
+  std::string  playableModel = rules.getPlayableModelFileName( userId, team, playableClassId );
+  std::string  playableTexture = rules.getPlayableModelFileName( userId, team, playableClassId );
+  float        playableScale = rules.getPlayableScale( userId, team, playableClassId );
+
+  BaseObject * bo = Factory::fabricate( playableClassId );
+
+  assert( bo != NULL );
+  assert( bo->isA( Playable::staticClassID()) );
+
+  Playable & playable = *(dynamic_cast<Playable*>(bo));
+
+  playable.loadMD2Texture( playableTexture );
+  playable.setTeam(team);
+  playable.loadModel( playableModel, 100.0f );
+  playable.setOwner( userId );
+  playable.setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
+  playable.setSynchronized( true );
+
+  PlayerStats * stats = rules.getNewPlayerStats( userId );
+
+  stats->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
+  stats->setSynchronized( true );
+  stats->setOwner( SharedNetworkData::getInstance()->getHostID() );
+
+  stats->setTeamId( team );
+  stats->setPlayableClassId( playableClassId );
+  stats->setPlayableUniqueId( playable.getUniqueID() );
+  stats->setModelFileName( playableModel );
+
+  if ( userId == 0 )
+    stats->setNickName( Preferences::getInstance()->getString( "multiplayer", "nickname", "Server" ) );
+
+  if ( rules.isA( MultiplayerTeamDeathmatch::staticClassID()) )
+    dynamic_cast<MultiplayerTeamDeathmatch*>(&rules)->respawnPlayable( &playable, team, 0.0f );
+
+  return true;
+}
+
+
+/**
+ * remove player from game
+ * @param userID
+ * @return
+ */
+bool NetworkGameManager::signalLeftPlayer(int userID)
+{
+  if ( PlayerStats::getStats( userID ) )
+  {
+    if ( PlayerStats::getStats( userID )->getPlayable() )
+      delete PlayerStats::getStats( userID )->getPlayable();
+    delete PlayerStats::getStats( userID );
+  }
+
+  return true;
+}
+
+
+
+/**
+ * handler for remove synchronizeable messages
+ * @param messageType
+ * @param data
+ * @param dataLength
+ * @param someData
+ * @param userId
+ * @return true on successfull handling else handler will be called again
+ */
+bool NetworkGameManager::delSynchronizeableHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+
+  PRINTF(0)(" del synchronizeable\n");
+
+  if ( SharedNetworkData::getInstance()->isMasterServer() ||
+       SharedNetworkData::getInstance()->isProxyServerActive() && SharedNetworkData::getInstance()->isUserClient(senderId))
+  {
+    PRINTF(0)("Recieved DeleteSynchronizeable message from client %d!\n", senderId);
+    return true;
+  }
+
+  int uniqueId = 0;
+  int len = Converter::byteArrayToInt( data, &uniqueId );
+
+  if ( len != dataLength )
+  {
+    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, senderId);
+    return true;
+  }
+
+  for (ObjectList<Synchronizeable>::const_iterator it = Synchronizeable::objectList().begin();
+       it != Synchronizeable::objectList().end();
+      ++it)
+  {
+    if ( (*it)->getUniqueID() == uniqueId )
+    {
+      if ( (*it)->isA(Playable::staticClassID()) )
+      {
+        getInstance()->playablesToDelete.push_back( dynamic_cast<Playable*>(*it) );
+        return true;
+      }
+
+      delete (*it);
+      return true;
+    }
+  }
+
+  return true;
+}
+
+/**
+ * removes synchronizeable (also on clients)
+ * @param uniqueId uniqueid to delete
+ */
+void NetworkGameManager::removeSynchronizeable( int uniqueId )
+{
+  byte buf[INTSIZE];
+
+  assert( Converter::intToByteArray( uniqueId, buf, INTSIZE ) == INTSIZE );
+
+  MessageManager::getInstance()->sendMessage( MSGID_DELETESYNCHRONIZEABLE, buf, INTSIZE, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
+}
+
+
+
+/**
+ * handler for MSGID_PREFEREDTEAM message
+ * @param messageType
+ * @param data
+ * @param dataLength
+ * @param someData
+ * @param userId
+ * @return
+ */
+bool NetworkGameManager::preferedTeamHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  assert( SharedNetworkData::getInstance()->isMasterServer() );
+
+  int teamId = 0;
+  int len = Converter::byteArrayToInt( data, &teamId );
+
+  if ( len != dataLength )
+  {
+    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, senderId);
+    return true;
+  }
+
+  PRINTF(0)("Client %i wishes to play in team %i\n", senderId, teamId);
+  NetworkGameManager::getInstance()->setPreferedTeam( senderId, teamId );
+
+  return true;
+}
+
+
+/**
+ * this actualy sets the new prefered team id
+ * @param userId: the user that changes team
+ * @param teamId: the new team id for the user
+ */
+void NetworkGameManager::setPreferedTeam( int userId, int teamId )
+{
+  if ( !PlayerStats::getStats( userId ) )
+    return;
+
+  PlayerStats & stats = *(PlayerStats::getStats( userId ));
+
+  stats.setPreferedTeamId( teamId );
+}
+
+
+/**
+ * set prefered team for this host
+ * @param teamId
+ */
+void NetworkGameManager::prefereTeam( int teamId )
+{
+  if ( SharedNetworkData::getInstance()->isMasterServer() )
+    this->setPreferedTeam( SharedNetworkData::getInstance()->getHostID(), teamId );
+  else
+  {
+    byte buf[INTSIZE];
+
+    assert( Converter::intToByteArray( teamId, buf, INTSIZE) == INTSIZE );
+
+    // send this message to the master server
+    MessageManager::getInstance()->sendMessage( MSGID_PREFEREDTEAM, buf, INTSIZE, RT_USER, NET_ID_MASTER_SERVER, MP_HIGHBANDWIDTH );
+  }
+}
+
+/**
+ * this function will be called periodically by networkManager
+ * @param ds time elapsed since last call of tick
+ */
+void NetworkGameManager::tick( float ds )
+{
+  //delete playables if they are not assigned to local player anymore
+  for ( std::list<Playable*>::iterator it = playablesToDelete.begin(); it != playablesToDelete.end();  )
+  {
+    if ( State::getPlayer()->getPlayable() != *it )
+    {
+      if ( std::find( Playable::objectList().begin(), Playable::objectList().end(), *it ) != Playable::objectList().end() )
+      {
+        PRINTF(0)("Delete unused playable: %s owner: %d\n", (*it)->getClassCName(), (*it)->getOwner() );
+        std::list<Playable*>::iterator delit = it;
+        it++;
+        delete *delit;
+        playablesToDelete.erase( delit );
+        continue;
+      }
+    }
+    it++;
+  }
+}
+
+
+
+bool NetworkGameManager::chatMessageHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  PRINTF(0)("NetworkGameManager::chatMessageHandler %d %d\n", senderId, SharedNetworkData::getInstance()->getHostID() );
+  if ( (SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/) && senderId !=  SharedNetworkData::getInstance()->getHostID() )
+  {
+    MessageManager::getInstance()->sendMessage( messageType, data, dataLength, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
+  }
+
+  assert( State::getGameRules() );
+  assert( State::getGameRules()->isA( NetworkGameRules::staticClassID()) );
+
+  NetworkGameRules & rules = *(dynamic_cast<NetworkGameRules*>(State::getGameRules()));
+
+  if ( dataLength < 3*INTSIZE )
+  {
+    PRINTF(2)("got too small chatmessage from client %d\n", senderId);
+
+    return true;
+  }
+
+  int chatType = 0;
+  Converter::byteArrayToInt( data, &chatType);
+  int senderUserId = 0;
+  Converter::byteArrayToInt( data+INTSIZE, &senderUserId );
+  std::string message;
+  Converter::byteArrayToString( data+2*INTSIZE, message, dataLength-2*INTSIZE );
+
+  rules.handleChatMessage( senderUserId, message, chatType);
+
+  return true;
+}
+
+/**
+ * send chat message
+ * @param message message text
+ * @param messageType some int
+ */
+void NetworkGameManager::sendChatMessage( const std::string & message, int messageType )
+{
+  byte * buf = new byte[message.length()+3*INTSIZE];
+
+  assert( Converter::intToByteArray( messageType, buf, INTSIZE ) == INTSIZE );
+  assert( Converter::intToByteArray( SharedNetworkData::getInstance()->getHostID(), buf+INTSIZE, INTSIZE ) == INTSIZE );
+  assert( Converter::stringToByteArray(message, buf+2*INTSIZE, message.length()+INTSIZE) == message.length()+INTSIZE );
+
+  if ( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
+    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
+  else
+    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
+
+
+  delete [] buf;
+}
+
+
+
Index: branches/heathaze/src/lib/network/network_game_manager.h
===================================================================
--- branches/heathaze/src/lib/network/network_game_manager.h	(revision 9940)
+++ branches/heathaze/src/lib/network/network_game_manager.h	(revision 9940)
@@ -0,0 +1,76 @@
+/*!
+ * @file entity_manager.h
+ *  Manages creation and destruction of entities
+ */
+
+#ifndef _NETWORK_GAME_MANGER
+#define _NETWORK_GAME_MANAGER
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+/* include base_object.h since all classes are derived from this one */
+#include "synchronizeable.h"
+#include "playable.h"
+#include "message_manager.h"
+
+
+class TiXmlElement;
+class PNode;
+
+
+
+struct clientBuffer
+{
+  int length;
+  int maxLength;
+  byte * buffer;
+};
+
+/*!
+ * a class that can create and remove entities over the network
+ */
+class NetworkGameManager: public Synchronizeable
+{
+  ObjectListDeclaration(NetworkGameManager);
+  public:
+    virtual ~NetworkGameManager();
+
+    static NetworkGameManager* getInstance()
+    { if (!NetworkGameManager::singletonRef) NetworkGameManager::singletonRef = new NetworkGameManager(); return NetworkGameManager::singletonRef; }
+
+
+    bool signalNewPlayer( int userId );
+    bool signalLeftPlayer( int userID );
+
+    void prefereTeam( int teamId );
+
+
+    inline void setGameState( int gameState ){ this->gameState = gameState; }
+    inline int getGameState(){ return this->gameState; }
+
+    void tick( float ds );
+
+    void removeSynchronizeable( int uniqueId );
+    void sendChatMessage( const std::string & message, int messageType );
+
+
+  private:
+    NetworkGameManager();
+
+    static bool delSynchronizeableHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+    static bool preferedTeamHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+    static bool chatMessageHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+
+    void setPreferedTeam( int userId, int teamId );
+
+
+  private:
+    static NetworkGameManager*    singletonRef;
+
+    int                           gameState;
+
+    std::list<Playable*>          playablesToDelete;
+};
+
+#endif /*_ENTITY_MANGER*/
Index: branches/heathaze/src/lib/network/network_log.cc
===================================================================
--- branches/heathaze/src/lib/network/network_log.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/network_log.cc	(revision 9940)
@@ -0,0 +1,219 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+#include "network_log.h"
+#include <cassert>
+#include <stdarg.h>
+/**
+ *  the singleton reference to this class
+ */
+NetworkLog* NetworkLog::singletonRef = NULL;
+
+
+/**
+ * standard constructor
+ */
+NetworkLog::NetworkLog ()
+{
+  listensock = NULL;
+}
+
+
+/**
+   @brief standard deconstructor
+ */
+NetworkLog::~NetworkLog ()
+{
+  NetworkLog::singletonRef = NULL;
+}
+
+/**
+ * listens on port for connections
+ * @param port port number
+ * @return true on success
+ */
+bool NetworkLog::listen( int port )
+{
+  IPaddress ip;
+
+  if ( SDLNet_ResolveHost( &ip, NULL, port ) == -1 ) {
+    PRINT(1)( "SDLNet_ResolveHost: %s\n", SDLNet_GetError() );
+    listensock = NULL;
+    return false;
+  }
+
+  listensock = SDLNet_TCP_Open( &ip );
+
+  if( !listensock ) {
+    PRINT(1)( "SDLNet_TCP_Open: %s\n", SDLNet_GetError() );
+    return false;
+  }
+
+  return true;
+}
+
+/**
+ * prints string to all connected sockets
+ */
+void NetworkLog::printfn( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+
+  va_end( ap );
+
+  printfnet();
+}
+
+/**
+ * accepts new connections
+ */
+void NetworkLog::acceptNewConnections( )
+{
+  TCPsocket newSock = SDLNet_TCP_Accept( listensock );
+
+  if ( newSock )
+    sockets.push_back( newSock );
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(0)
+ */
+void NetworkLog::printf0( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+
+  va_end( ap );
+
+  PRINT(0)( buf );
+  printfnet();
+
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(1)
+ */
+void NetworkLog::printf1( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+
+  va_end( ap );
+
+  PRINT(1)( buf );
+  printfnet();
+
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(2)
+ */
+void NetworkLog::printf2( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+
+  va_end( ap );
+
+  PRINT(2)( buf );
+  printfnet();
+
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(3)
+ */
+void NetworkLog::printf3( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+
+  va_end( ap );
+
+  PRINT(3)( buf );
+  printfnet();
+
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(4)
+ */
+void NetworkLog::printf4( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+
+  va_end( ap );
+
+  PRINT(4)( buf );
+  printfnet();
+
+}
+
+/**
+ * prints to all connected sockets and to PRINTF(5)
+ */
+void NetworkLog::printf5( char * format, ... )
+{
+  va_list ap;
+  va_start( ap, format );
+
+  assert( vsnprintf( buf, NETWORK_LOG_BUFLEN, format, ap ) < NETWORK_LOG_BUFLEN );
+
+  va_end( ap );
+
+  PRINT(5)( buf );
+  printfnet();
+
+}
+
+
+/**
+ * prints buf to network sockets
+ */
+void NetworkLog::printfnet()
+{
+  if ( !listensock )
+    return;
+
+  acceptNewConnections();
+
+  for ( std::list<TCPsocket>::iterator it = sockets.begin(); it != sockets.end(); )
+  {
+    if ( SDLNet_TCP_Send( *it, buf, strlen( buf) ) < strlen( buf ) )
+    {
+      SDLNet_TCP_Close( *it );
+      std::list<TCPsocket>::iterator delIt = it;
+      it++;
+      sockets.erase( delIt );
+      continue;
+    }
+
+    it++;
+  }
+}
Index: branches/heathaze/src/lib/network/network_log.h
===================================================================
--- branches/heathaze/src/lib/network/network_log.h	(revision 9940)
+++ branches/heathaze/src/lib/network/network_log.h	(revision 9940)
@@ -0,0 +1,70 @@
+/*!
+ * @file network_log.h
+ * @brief Definition of the NetworkLog singleton Class
+ */
+
+#ifndef _NETWORK_LOG_H
+#define _NETWORK_LOG_H
+
+#include "netdefs.h"
+#include "debug.h"
+
+#include <string>
+#include <list>
+
+#define NETWORK_LOG_BUFLEN 1024
+
+/* macro definitions */
+#define NETPRINTF(x) NETPRINTF ## x
+#define NETPRINT(x) NETPRINT ## x
+
+#define NETPRINTFn NetworkLog::getInstance()->printfn("%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printfn
+#define NETPRINTF0 NetworkLog::getInstance()->printf0("%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf0
+#define NETPRINTF1 NetworkLog::getInstance()->printf1("(EE)::%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf1
+#define NETPRINTF2 NetworkLog::getInstance()->printf2("(WW)::%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf2
+#define NETPRINTF3 NetworkLog::getInstance()->printf3("(II)::%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf3
+#define NETPRINTF4 NetworkLog::getInstance()->printf4("(DD)::%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf4
+#define NETPRINTF5 NetworkLog::getInstance()->printf5("(VD)::%s:%d:", __FILE__, __LINE__); NetworkLog::getInstance()->printf5
+
+#define NETPRINTn NetworkLog::getInstance()->printfn
+#define NETPRINT0 NetworkLog::getInstance()->printf0
+#define NETPRINT1 NetworkLog::getInstance()->printf1
+#define NETPRINT2 NetworkLog::getInstance()->printf2
+#define NETPRINT3 NetworkLog::getInstance()->printf3
+#define NETPRINT4 NetworkLog::getInstance()->printf4
+#define NETPRINT5 NetworkLog::getInstance()->printf5
+
+//! A default singleton class.
+class NetworkLog
+{
+  public:
+    virtual ~NetworkLog(void);
+    /** @returns a Pointer to the only object of this Class */
+    inline static NetworkLog* getInstance(void) { if (!singletonRef) singletonRef = new NetworkLog();  return singletonRef; };
+
+    bool listen( int port );
+
+    void printfnet( );
+
+    void printfn( char * format, ... );
+    void printf0( char * format, ... );
+    void printf1( char * format, ... );
+    void printf2( char * format, ... );
+    void printf3( char * format, ... );
+    void printf4( char * format, ... );
+    void printf5( char * format, ... );
+
+  private:
+    NetworkLog();
+
+    void acceptNewConnections();
+
+    static NetworkLog* singletonRef;
+
+    TCPsocket listensock;
+    std::list<TCPsocket> sockets;
+
+    char buf[NETWORK_LOG_BUFLEN];
+};
+
+#endif /* _NETWORK_LOG_H */
Index: branches/heathaze/src/lib/network/network_manager.cc
===================================================================
--- branches/heathaze/src/lib/network/network_manager.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/network_manager.cc	(revision 9940)
@@ -0,0 +1,241 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli (patrick@orxonox.ethz.ch)
+   co-programmer: Christoph Renner (rennerc@ee.ethz.ch)
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "debug.h"
+#include "shell_command.h"
+
+/* include your own header */
+#include "network_manager.h"
+#include "shared_network_data.h"
+#include "network_stream.h"
+#include "parser/preferences/preferences.h"
+#include "network_log.h"
+#include "network_game_manager.h"
+#include "proxy/proxy_control.h"
+
+
+/* using namespace std is default, this needs to be here */
+
+
+SHELL_COMMAND(debug, NetworkManager, debug);
+SHELL_COMMAND(redirTest, NetworkManager, setRedirectionTest);
+
+
+ObjectListDefinition(NetworkManager);
+NetworkManager* NetworkManager::singletonRef = NULL;
+
+/**
+ *  standard constructor
+ */
+NetworkManager::NetworkManager()
+{
+  /* set the class id for the base object */
+  this->registerObject(this, NetworkManager::_objectList);
+  PRINTF(0)("START\n");
+
+  /* initialize the references */
+  this->networkStream = NULL;
+  this->elapsedTime = 0.0f;
+
+
+  int port = Preferences::getInstance()->getInt( "network", "telnetport", 0 );
+
+  if ( port > 0 )
+    NetworkLog::getInstance()->listen( port );
+
+  PRINTF(0)("NetworkManager created\n");
+}
+
+
+/**
+ *  standard deconstructor
+ */
+NetworkManager::~NetworkManager()
+{
+  PRINTF(0)("NetworkManager destructor\n");
+  if ( this->networkStream )
+  {
+    delete this->networkStream;
+    this->networkStream = NULL;
+  }
+
+  NetworkManager::singletonRef = NULL;
+}
+
+
+/**
+ *  initializes the network manager
+ */
+void NetworkManager::initialize()
+{
+  PRINTF(0)("NetworkManager initzalized\n");
+}
+
+
+/**
+ *  shutsdown the network manager
+ */
+void NetworkManager::shutdown()
+{
+
+}
+
+
+
+/**
+ *  creates a new NetworkStream of server type
+ * @param clientPort: number of the TCP/UDP port for client connections
+ * @param proxyPort: number of the TCP/UDP port for proxy connections
+ */
+int NetworkManager::createMasterServer(unsigned int port)
+{
+  // load the network settings
+  NetworkSettings::getInstance()->loadData();
+
+  // create the network stream
+  this->networkStream = new NetworkStream(NET_MASTER_SERVER);
+  this->networkStream->createServer( port, port + 1, port + 2);
+
+  // start the network game manager
+  this->networkStream->createNetworkGameManager();
+
+  // init the proxy control center
+  ProxyControl::getInstance();
+
+  PRINTF(0)("Created Network Master Server\n");
+  SDL_Delay(20);
+  return 1;
+}
+
+/**
+ *  creates a new network stream of proxy server type
+ * @param port: number of the TCP port
+ */
+int NetworkManager::createProxyServer(unsigned int port)
+{
+  // load the network settings
+  NetworkSettings::getInstance()->loadData();
+
+  // create the network stream af
+  this->networkStream = new NetworkStream(NET_PROXY_SERVER_ACTIVE );
+  // first connect to the master server for synchronization
+  this->networkStream->connectToMasterServer(NetworkSettings::getInstance()->getMasterAddr().ipString(), 10000);
+  // start the handshake with the master server
+  this->networkStream->startHandshake(NET_ID_MASTER_SERVER);
+
+  // then start the server
+  this->networkStream->createServer( port, port + 1, port + 2);
+
+  // and to the other proxy servers also, this would be very nice if its works
+  /* put it here....*/
+
+  // init the proxy control center
+  ProxyControl::getInstance();
+
+  PRINTF(0)("Created Network Proxy Server\n");
+  SDL_Delay(20);
+  return 1;
+}
+
+
+/**
+ *  creates a connection from one object to a host
+ * @param hostName: the name of the destination host
+ */
+int NetworkManager::createClient(const std::string & name, unsigned int port)
+{
+  // load the network settings
+  NetworkSettings::getInstance()->loadData();
+
+  // create the network stream
+  this->networkStream = new NetworkStream(NET_CLIENT);
+  // connect to the master server, if a redirection should occure, this is handled in the NetworkStream itself
+  this->networkStream->connectToMasterServer( name, port);
+
+
+  // and start the handshake
+  this->networkStream->startHandshake();
+  // create the proxy control
+  ProxyControl::getInstance();
+
+  PRINTF(0)("Created Network Client\n");
+  return 1;
+}
+
+
+/**
+ * reconnects this client to another server
+ * @param address new server address
+ */
+void NetworkManager::reconnectToServer(IP address)
+{
+  PRINTF(0)("Rec. reconnection command\n");
+  this->networkStream->reconnectToServer(address);
+}
+
+
+/**
+ * connects a synchronizeable to the network stream
+ * @param sync: synchronizeable to connect
+ */
+void NetworkManager::connectSynchronizeable(Synchronizeable& sync)
+{
+  if( this->networkStream)
+    this->networkStream->connectSynchronizeable(sync);
+}
+
+
+/**
+ *  sync the network
+ *  @param dtS: the seceonds elapsed since the last synchronize call
+ */
+void NetworkManager::synchronize( float dtS)
+{
+  this->elapsedTime += dtS;
+  if( likely(this->elapsedTime < 1.0f / NETWORK_FREQUENCY))
+    return;
+
+  this->elapsedTime = 0.0f;
+
+  if ( this->networkStream )
+    networkStream->processData();
+
+  NetworkGameManager::getInstance()->tick( this->elapsedTime );
+}
+
+
+
+/**
+ * debug output
+ */
+ void NetworkManager::debug()
+{
+  PRINT(0)("=================Network::debug()=========\n");
+  this->networkStream->debug();
+  PRINT(0)("===========================================\n");
+}
+
+
+void NetworkManager::setRedirectionTest()
+{
+  this->networkStream->setRedirectionTest();
+}
+
Index: branches/heathaze/src/lib/network/network_manager.h
===================================================================
--- branches/heathaze/src/lib/network/network_manager.h	(revision 9940)
+++ branches/heathaze/src/lib/network/network_manager.h	(revision 9940)
@@ -0,0 +1,65 @@
+/*!
+ * @file network_manager.h
+  *  Main interface for the network module. Manages all the modules
+*/
+
+/* you will want to add such a a line at your header file also, since it will
+   prevent c++ from including your code twice*/
+#ifndef _NETWORK_MANAGER
+#define _NETWORK_MANAGER
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+#include "shared_network_data.h"
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+
+
+
+class NetworkStream;
+class Synchronizeable;
+
+
+/* and here is the class itsself*/
+class NetworkManager : public BaseObject
+{
+  ObjectListDeclaration(NetworkManager);
+  public:
+
+    inline static NetworkManager* getInstance() { if (!NetworkManager::singletonRef) NetworkManager::singletonRef = new NetworkManager();
+      return NetworkManager::singletonRef; }
+    virtual ~NetworkManager();
+
+    void initialize();
+    void shutdown();
+
+    int createClient( const std::string & name, unsigned int port);
+    int createMasterServer( unsigned int port);
+    int createProxyServer( unsigned int port);
+
+    void reconnectToServer(IP address);
+
+    void connectSynchronizeable(Synchronizeable& sync);
+    void synchronize(float dtS);
+
+    void debug();
+
+    void setRedirectionTest();
+
+
+
+  private:
+    NetworkManager();
+
+
+  private:
+    static NetworkManager*           singletonRef;            //!< Pointer to the only instance of this Class
+    NetworkStream*                   networkStream;           //!< pointer to network stream
+
+    float                            elapsedTime;             //!< elapsed time since the last network update
+};
+
+
+
+#endif /* _NETWORK_MANAGER */
Index: branches/heathaze/src/lib/network/network_protocol.cc
===================================================================
--- branches/heathaze/src/lib/network/network_protocol.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/network_protocol.cc	(revision 9940)
@@ -0,0 +1,120 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Wuest
+   co-programmer: ...
+*/
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+//#include ...
+
+/* include my own header */
+#include "network_protocol.h"
+
+/* include the synchronizeable object */
+#include "synchronizeable.h"
+
+/* include this file for debugging */
+#include "debug.h"
+
+#include "converter.h"
+
+/* using namespace std is default, this needs to be here */
+
+
+ObjectListDefinition(NetworkProtocol);
+/**
+  standard constructor
+*/
+NetworkProtocol::NetworkProtocol()
+{
+  /* set the class id for the base object */
+  this->registerObject(this, NetworkProtocol::_objectList);
+  this->headerLength = INTSIZE+FLOATSIZE;
+}
+
+/**
+  standard destructor
+*/
+NetworkProtocol::~NetworkProtocol()
+{}
+
+/**
+    * creates a new packet header from the function arguments
+    *
+    * @arg data: the binary data without header -> return the data in this binary array
+    * @arg length: the data length without header
+    * @arg bufferLength: the length of the internal buffer
+    * @arg source: reference to the source Synchronizeable object
+    * @return: the new data length with header (the header data is included into byte* data)
+    *          -1 if there isn't enough space in the buffer for the header
+*/
+int NetworkProtocol::createHeader(byte* data, int length, int bufferLength, const Synchronizeable& source)
+{
+  PRINTF(5)("create header length = %i, bufferLength = %i\n", length, bufferLength);
+  //If there isn't enough space for the header return -1
+  if (length + 2*INTSIZE > bufferLength)
+    return -1;
+
+
+  // FIXME: without move Create space for the header
+  for( int i = length - 1; i >= 0; i--)
+    data[i + INTSIZE+INTSIZE] = data[i];
+
+  //Now create the header
+  /* sender ID: FIXME: there will be a better ID (for example unique:D)*/
+  //data[0] = (byte)(source.getUniqueID());
+  int res = Converter::intToByteArray( source.getUniqueID(), data, bufferLength );
+
+  /* data length*/
+  //data[1] = length;
+  res += Converter::intToByteArray( length, data+res, bufferLength-res );
+
+
+  return length + res;
+}
+
+/**
+    * extracts the header from the binary data stream
+    * @arg data: the binary data with the header
+    * @arg length: the length of the binary data (including header)
+    * @return: a Header struct with the header information and the binary data
+*/
+Header NetworkProtocol::extractHeader(byte* data, int length)
+{
+  PRINTF(5)("extract Header\n");
+  //Test if received data can contain a header
+  if (length < 2*INTSIZE)
+  {
+    PRINTF(1)("Received data is to short; it can't contain a header!\n");
+    Header h;
+    h.length = 0;
+    return h;
+  }
+
+  //Extract header
+  Header h;
+  //&h = data;
+
+  /* unique ID */
+  //h.synchronizeableID = data[0];
+  int res = Converter::byteArrayToInt( data, &(h.synchronizeableID) );
+  /* data length*/
+  //h.length = data[1];
+  Converter::byteArrayToInt( data+res, &(h.length) );
+
+
+  return h;
+}
Index: branches/heathaze/src/lib/network/network_protocol.h
===================================================================
--- branches/heathaze/src/lib/network/network_protocol.h	(revision 9940)
+++ branches/heathaze/src/lib/network/network_protocol.h	(revision 9940)
@@ -0,0 +1,39 @@
+/*!
+
+*/
+
+#ifndef _NETWORK_PROTOCOL_H
+#define _NETWORK_PROTOCOL_H
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+typedef struct Header
+{
+  int synchronizeableID;
+  int length;
+};
+
+class Synchronizeable;
+
+/*!
+
+*/
+class NetworkProtocol : virtual public BaseObject
+{
+  ObjectListDeclaration(NetworkProtocol);
+  public:
+    NetworkProtocol();
+    virtual ~NetworkProtocol();
+
+    int createHeader(byte* data, int length, int bufferLength, const Synchronizeable& source);
+    Header extractHeader(byte* data, int length);
+
+  private:
+    unsigned int headerLength; //The Length of the Header in bytes
+};
+
+#endif //_NETWORK_PROTOCOL_H
Index: branches/heathaze/src/lib/network/network_socket.cc
===================================================================
--- branches/heathaze/src/lib/network/network_socket.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/network_socket.cc	(revision 9940)
@@ -0,0 +1,42 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner, David Hasenfratz
+   co-programmer:
+*/
+
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+/* include your own header */
+#include "network_socket.h"
+
+ObjectListDefinition(NetworkSocket);
+/**
+ * Default constructor
+ */
+NetworkSocket::NetworkSocket()
+{
+  bOk = true;
+  this->ip.host = 0;
+  this->ip.port = 0;
+}
+
+NetworkSocket::~ NetworkSocket( )
+{
+}
+
+
+
Index: branches/heathaze/src/lib/network/network_socket.h
===================================================================
--- branches/heathaze/src/lib/network/network_socket.h	(revision 9940)
+++ branches/heathaze/src/lib/network/network_socket.h	(revision 9940)
@@ -0,0 +1,80 @@
+/*!
+ * @file network_socket.h
+  *  Main interface for the network module. Manages all the modules
+
+*/
+
+#ifndef _NETWORK_SOCKET
+#define _NETWORK_SOCKET
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+
+class NetworkSocket : public BaseObject
+{
+  ObjectListDeclaration(NetworkSocket);
+  public:
+    NetworkSocket();
+    virtual ~NetworkSocket();
+
+    /**
+     * connect to server on host with port port
+     * @param host hostname might be xxx.xxx.xxx.xxx or localhost ...
+     * @param port port to connect to
+     */
+    virtual void connectToServer( std::string host, int port ) = 0;
+
+    /**
+     * disconnect from server
+     */
+    virtual void disconnectServer() = 0;
+
+    /**
+     * reconnecting to another server by terminating old connection and init a new connection
+     */
+    virtual void reconnectToServer( std::string host, int port) = 0;
+
+    /**
+     * reconnecting to anoter server softly
+     */
+    virtual void reconnectToServerSoft( std::string host, int port) = 0;
+
+    /**
+     * send packet to connected socket. will be recieved as whole packet
+     * @param data pointer to data to send
+     * @param length lengt of packet to send
+     * @return true on success
+     */
+    virtual bool writePacket(byte * data, int length) = 0;
+
+    /**
+     * read a packet sent by another NetworkSocket
+     * @param data data will be copied here
+     * @param maxLength readPacket will not read more than maxLength
+     * @return bytes read. on error less than zero
+     */
+    virtual int readPacket(byte * data, int maxLength) = 0;
+
+    /**
+     * check if socket is ok
+     * @return true if socket is ok
+     */
+    inline bool isOk() { return this->bOk; }
+
+    /** @returns the ip adderess of the destination socket */
+    IPaddress getRemoteAddress() { return ip; }
+
+
+  protected:
+    bool              bOk;            //!< check for socket status
+
+    IPaddress         ip;             //!< host,port
+};
+
+
+
+#endif /* _NETWORK_SOCKET */
Index: branches/heathaze/src/lib/network/network_stream.cc
===================================================================
--- branches/heathaze/src/lib/network/network_stream.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/network_stream.cc	(revision 9940)
@@ -0,0 +1,1334 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner rennerc@ee.ethz.ch
+   co-programmer:   Patrick Boenzli  patrick@orxonox.ethz.ch
+
+     June 2006: finishing work on the network stream for pps presentation (rennerc@ee.ethz.ch)
+     July 2006: some code rearangement and integration of the proxy server mechanism (patrick@orxonox.ethz.ch)
+*/
+
+
+#define DEBUG_MODULE_NETWORK
+
+#include "proxy/proxy_control.h"
+
+#include "base_object.h"
+#include "network_protocol.h"
+#include "udp_socket.h"
+#include "udp_server_socket.h"
+#include "monitor/connection_monitor.h"
+#include "monitor/network_monitor.h"
+#include "synchronizeable.h"
+#include "ip.h"
+#include "network_game_manager.h"
+#include "shared_network_data.h"
+#include "message_manager.h"
+#include "parser/preferences/preferences.h"
+#include "zip.h"
+
+#include "network_log.h"
+
+#include "player_stats.h"
+
+#include "loading/factory.h"
+#include "loading/resource_manager.h"
+
+#include "debug.h"
+
+#include "network_stream.h"
+
+
+#include "converter.h"
+
+
+#define PACKAGE_SIZE  256
+
+ObjectListDefinition(NetworkStream);
+/**
+ * empty constructor
+ */
+NetworkStream::NetworkStream()
+    : DataStream()
+{
+  this->init();
+  /* initialize the references */
+  this->pInfo->nodeType = NET_UNASSIGNED;
+}
+
+
+NetworkStream::NetworkStream( int nodeType)
+{
+  this->init();
+
+  this->pInfo->nodeType = nodeType;
+
+  switch( nodeType)
+  {
+    case NET_MASTER_SERVER:
+      // init the shared network data
+      SharedNetworkData::getInstance()->setHostID(NET_ID_MASTER_SERVER);
+      this->pInfo->userId = NET_ID_MASTER_SERVER;
+      this->pInfo->nodeType = NET_MASTER_SERVER;
+
+      break;
+    case NET_PROXY_SERVER_ACTIVE:
+      // init the shared network data
+      SharedNetworkData::getInstance()->setHostID(NET_ID_PROXY_SERVER_01);
+      this->pInfo->nodeType = NET_PROXY_SERVER_ACTIVE;
+
+      break;
+    case NET_PROXY_SERVER_PASSIVE:
+      // init the shared network data
+      SharedNetworkData::getInstance()->setHostID(NET_ID_PROXY_SERVER_01);
+      this->pInfo->nodeType = NET_PROXY_SERVER_PASSIVE;
+
+      break;
+    case NET_CLIENT:
+      SharedNetworkData::getInstance()->setHostID(NET_ID_UNASSIGNED);
+      this->pInfo->nodeType = NET_CLIENT;
+      break;
+  }
+
+  SharedNetworkData::getInstance()->setDefaultSyncStream(this);
+
+  // get the local ip address
+  IP ip("localhost", 0);
+  this->pInfo->ip = ip;
+}
+
+
+
+/**
+ * generic init functions
+ */
+void NetworkStream::init()
+{
+  /* set the class id for the base object */
+  this->registerObject(this, NetworkStream::_objectList);
+  this->clientSocket = NULL;
+  this->clientSoftSocket = NULL;
+  this->proxySocket = NULL;
+  this->networkGameManager = NULL;
+  this->networkMonitor = NULL;
+
+  this->pInfo = new PeerInfo();
+  this->pInfo->userId = NET_UID_UNASSIGNED;
+  this->pInfo->lastAckedState = 0;
+  this->pInfo->lastRecvedState = 0;
+  this->pInfo->bLocal = true;
+
+  this->bRedirect = false;
+
+  this->currentState = 0;
+  this->redirectionUID = NET_ID_MASTER_SERVER;
+
+  remainingBytesToWriteToDict = Preferences::getInstance()->getInt( "compression", "writedict", 0 );
+
+  assert( Zip::getInstance()->loadDictionary( "testdict" ) >= 0 );
+  this->dictClient = Zip::getInstance()->loadDictionary( "dict2pl_client" );
+  assert( this->dictClient >= 0 );
+  this->dictServer = Zip::getInstance()->loadDictionary( "dict2p_server" );
+  assert( this->dictServer >= 0 );
+}
+
+
+/**
+ * deconstructor
+ */
+NetworkStream::~NetworkStream()
+{
+  if ( this->clientSocket )
+  {
+    this->clientSocket->close();
+    delete this->clientSocket;
+    this->clientSocket = NULL;
+  }
+  if ( this->clientSoftSocket )
+  {
+    this->clientSoftSocket->close();
+    delete this->clientSoftSocket;
+    this->clientSoftSocket = NULL;
+  }
+  if ( this->proxySocket)
+  {
+    proxySocket->close();
+    delete proxySocket;
+    proxySocket = NULL;
+  }
+  for ( PeerList::iterator i = peers.begin(); i!=peers.end(); i++)
+  {
+    if ( i->second.socket )
+    {
+      i->second.socket->disconnectServer();
+      delete i->second.socket;
+      i->second.socket = NULL;
+    }
+
+    if ( i->second.handshake )
+    {
+      delete i->second.handshake;
+      i->second.handshake = NULL;
+    }
+
+    if ( i->second.connectionMonitor )
+    {
+      delete i->second.connectionMonitor;
+      i->second.connectionMonitor = NULL;
+    }
+  }
+  for ( SynchronizeableList::const_iterator it = getSyncBegin(); it != getSyncEnd(); it ++ )
+    (*it)->setNetworkStream( NULL );
+
+  if( this->pInfo)
+    delete this->pInfo;
+
+  if( this->networkMonitor)
+    delete this->networkMonitor;
+}
+
+
+/**
+ * establish a connection to a remote master server
+ * @param host: host name
+ * @param port: the port number
+ */
+void NetworkStream::connectToMasterServer(std::string host, int port)
+{
+  int node = NET_ID_MASTER_SERVER;
+  // this create the new node in the peers map
+  this->peers[node].socket = new UdpSocket( host, port );
+  this->peers[node].userId = NET_ID_MASTER_SERVER;
+
+  this->peers[node].nodeType = NET_MASTER_SERVER;
+  this->peers[node].connectionMonitor = new ConnectionMonitor( NET_ID_MASTER_SERVER );
+  this->peers[node].ip = this->peers[node].socket->getRemoteAddress();
+  this->peers[node].bLocal = true;
+}
+
+
+/**
+ * establish a connection to a remote proxy server
+ * @param host: host name
+ * @param port: the port number
+ */
+void NetworkStream::connectToProxyServer(int proxyId, std::string host, int port)
+{
+  PRINTF(0)("connect to proxy %s, this is proxyId %i\n", host.c_str(), proxyId);
+
+  // this creates the new proxyId in the peers map
+  this->peers[proxyId].socket = new UdpSocket( host, port );
+  this->peers[proxyId].userId = proxyId;
+
+  this->peers[proxyId].nodeType = NET_PROXY_SERVER_ACTIVE;
+  this->peers[proxyId].connectionMonitor = new ConnectionMonitor( proxyId );
+  this->peers[proxyId].ip = this->peers[proxyId].socket->getRemoteAddress();
+  this->peers[proxyId].bLocal = true;
+}
+
+
+/**
+ * create a server
+ * @param port: interface port for all clients
+ */
+void NetworkStream::createServer(int clientPort, int proxyPort, int clientSoftPort)
+{
+  PRINTF(0)(" Creating new Server: listening for clients on port %i and for proxies on port %i", clientPort, proxyPort);
+  this->clientSocket= new UdpServerSocket(clientPort);
+  this->clientSoftSocket= new UdpServerSocket(clientSoftPort);
+  this->proxySocket = new UdpServerSocket(proxyPort);
+}
+
+
+/**
+ * creates a new instance of the network game manager
+ */
+void NetworkStream::createNetworkGameManager()
+{
+  this->networkGameManager = NetworkGameManager::getInstance();
+
+  this->networkGameManager->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
+  MessageManager::getInstance()->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
+}
+
+
+/**
+ * starts the network handshake
+ * handsakes are always initialized from the client side first. this starts the handshake and therefore is only
+ * executed as client
+ * @param userId: start handshake for this user id (optional, default == 0)
+ */
+void NetworkStream::startHandshake(int userId)
+{
+  Handshake* hs = new Handshake(this->pInfo->nodeType);
+  // fake the unique id
+  hs->setUniqueID( userId);
+  assert( this->peers[userId].handshake == NULL );
+  this->peers[userId].handshake = hs;
+  this->peers[userId].bLocal = true;
+
+  // set the preferred nick name
+  hs->setPreferedNickName( Preferences::getInstance()->getString( "multiplayer", "nickname", "Player" ) );
+
+  PRINTF(0)("NetworkStream: Handshake created: %s\n", hs->getCName());
+}
+
+
+/**
+ * this functions connects a synchronizeable to the networkstream, therefore synchronizeing
+ * it all over the network and creating it on the other platforms (if and only if it is a
+ * server
+ * @param sync: the synchronizeable to add
+ */
+void NetworkStream::connectSynchronizeable(Synchronizeable& sync)
+{
+  this->synchronizeables.push_back(&sync);
+  sync.setNetworkStream( this );
+}
+
+
+/**
+ * removes the synchronizeable from the list of synchronized entities
+ * @param sync: the syncronizeable to remove
+ */
+void NetworkStream::disconnectSynchronizeable(Synchronizeable& sync)
+{
+  // removing the Synchronizeable from the List.
+  std::list<Synchronizeable*>::iterator disconnectSynchro = std::find(this->synchronizeables.begin(), this->synchronizeables.end(), &sync);
+  if (disconnectSynchro != this->synchronizeables.end())
+    this->synchronizeables.erase(disconnectSynchro);
+
+  oldSynchronizeables[sync.getUniqueID()] = SDL_GetTicks();
+}
+
+
+/**
+ * this is called to process data from the network socket to the synchronizeable and vice versa
+ */
+void NetworkStream::processData()
+{
+  // create the network monitor after all the init work and before there is any connection handlings
+  if( this->networkMonitor == NULL)
+  {
+    this->networkMonitor = new NetworkMonitor(this);
+    SharedNetworkData::getInstance()->setNetworkMonitor( this->networkMonitor);
+  }
+
+
+  int tick = SDL_GetTicks();
+
+  this->currentState++;
+  // there was a wrap around
+  if( this->currentState < 0)
+  {
+    PRINTF(1)("A wrap around in the state variable as occured. The server was running so long? Pls restart server or write a mail to the supporters!\n");
+  }
+
+  if ( SharedNetworkData::getInstance()->isMasterServer())
+  {
+    // execute everytthing the master server shoudl do
+    if ( this->clientSocket )
+      this->clientSocket->update();
+    if ( this->clientSoftSocket)
+      this->clientSoftSocket->update();
+    if( this->proxySocket)
+      this->proxySocket->update();
+
+    this->updateConnectionList();
+  }
+  else if( SharedNetworkData::getInstance()->isProxyServerActive())
+  {
+    //execute everything the proxy server should do
+    if ( this->clientSocket )
+      this->clientSocket->update();
+    if ( this->clientSoftSocket)
+      this->clientSoftSocket->update();
+    if( this->proxySocket)
+      this->proxySocket->update();
+
+    this->updateConnectionList();
+  }
+
+#warning make this more modular: every proxy/master server connection should be watched for termination
+  if( !SharedNetworkData::getInstance()->isMasterServer())
+  {
+    // check if the connection is ok else terminate and remove
+    if ( !peers.empty() && peers[NET_ID_MASTER_SERVER].socket &&
+          ( !peers[NET_ID_MASTER_SERVER].socket->isOk() ||
+          peers[NET_ID_MASTER_SERVER].connectionMonitor->hasTimedOut() ) )
+    {
+      this->handleDisconnect( NET_ID_MASTER_SERVER);
+      PRINTF(1)("lost connection to server\n");
+    }
+    // check if there is a redirection command
+    if( this->bRedirect)
+    {
+      this->handleReconnect( this->redirectionUID);
+    }
+  }
+
+  this->cleanUpOldSyncList();
+  this->handleHandshakes();
+
+  // update the network monitor
+  this->networkMonitor->process();
+
+  // order of up/downstream is important!!!!
+  // don't change it
+  this->handleDownstream( tick );
+  this->handleUpstream( tick );
+
+  // process the local data of the message manager
+  MessageManager::getInstance()->processData();
+
+  if( this->bSoftRedirect)
+    this->softReconnectToServer(0, IP("localhost", 10001));
+}
+
+
+/**
+ * @brief handles incoming connections
+ *
+ * if we are a NET_MASTER_SERVER or NET_PROXY_SERVER_ACTIVE update the connection list to accept new connections (clients)
+ * start and initialize the handsake for the new clients
+ */
+void NetworkStream::updateConnectionList( )
+{
+  //check for new connections
+
+  NetworkSocket* tempNetworkSocket = NULL;
+  int userId;
+
+  if( this->clientSocket != NULL)
+  {
+    tempNetworkSocket = this->clientSocket->getNewSocket();
+
+    // we got new NET_CLIENT connecting
+    if ( tempNetworkSocket )
+    {
+      // get a userId
+//       if ( freeSocketSlots.size() > 0 )
+//       {
+//         // this should never be called
+//         userId = freeSocketSlots.back();
+//         freeSocketSlots.pop_back();
+//       }
+//       else
+      {
+        // each server (proxy and master) have an address space for new network nodes of 1000 nodes
+        // the first NET_ID_PROXY_MAX are always reserved for proxy servers
+        userId = SharedNetworkData::getInstance()->getHostID() * 1000 + NET_ID_PROXY_MAX + 1;
+
+        for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
+          if ( it->first >= userId )
+            userId = it->first + 1;
+
+        // make sure that this server only uses an address space of 1000
+        assert( userId < (SharedNetworkData::getInstance()->getHostID() + 1) * 1000);
+      }
+      // this creates a new entry in the peers list
+      peers[userId].socket = tempNetworkSocket;
+      peers[userId].nodeType = NET_CLIENT;
+
+      // handle the newly connected client
+      this->handleConnect(userId);
+
+      PRINTF(0)("New Client: %d\n", userId);
+    }
+  }
+
+  if( this->clientSoftSocket != NULL)
+  {
+    tempNetworkSocket = this->clientSoftSocket->getNewSocket();
+
+    // we got new NET_CLIENT connecting
+    if ( tempNetworkSocket )
+    {
+
+      // this creates a new entry in the peers list
+      peers[userId].socket = tempNetworkSocket;
+      peers[userId].nodeType = NET_CLIENT;
+
+      // handle the newly connected client
+      this->handleSoftConnect(userId);
+
+      PRINTF(0)("New Client softly connected: %d :D\n", userId);
+    }
+  }
+
+
+  if( this->proxySocket != NULL)
+  {
+    tempNetworkSocket = this->proxySocket->getNewSocket();
+
+    // we got new NET_PROXY_SERVER_ACTIVE connecting
+    if ( tempNetworkSocket )
+    {
+      // determine the network node id
+//       if ( freeSocketSlots.size() > 0 )
+//       {
+//         userId = freeSocketSlots.back();
+//         freeSocketSlots.pop_back();
+//       }
+//       else
+      {
+        userId = 1;
+
+        // find an empty slot within the range
+        for( int i = 0; i < NET_ID_PROXY_MAX; i++)
+        {
+          if( this->peers.find( i) == this->peers.end())
+          {
+            userId = i;
+            break;
+          }
+        }
+
+//         for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
+//           if ( it->first >= userId )
+//             userId = it->first + 1;
+      }
+
+      // this creates a new entry in the peers list
+      peers[userId].socket = tempNetworkSocket;
+      peers[userId].nodeType = NET_PROXY_SERVER_ACTIVE;
+
+      // handle the newly connected proxy server
+      this->handleConnect(userId);
+
+      PRINTF(0)("New proxy connected: %d\n", userId);
+    }
+  }
+
+
+
+  //check if connections are ok else remove them
+  for ( PeerList::iterator it = peers.begin(); it != peers.end(); )
+  {
+    if (
+          it->second.socket &&
+          (
+            !it->second.socket->isOk()  ||
+            it->second.connectionMonitor->hasTimedOut()
+          )
+       )
+    {
+      std::string reason = "disconnected";
+      if ( it->second.connectionMonitor->hasTimedOut() )
+        reason = "timeout";
+      PRINTF(0)("Client is gone: %d (%s)\n", it->second.userId, reason.c_str());
+
+
+      this->handleDisconnect( it->second.userId);
+
+      if( SharedNetworkData::getInstance()->isProxyServerActive())
+        ProxyControl::getInstance()->signalLeaveClient(it->second.userId);
+
+      it++;
+      continue;
+    }
+
+    it++;
+  }
+}
+
+
+/**
+ * this handles new connections
+ * @param userId: the id of the new user node
+ */
+void NetworkStream::handleConnect( int userId)
+{
+  // create new handshake and init its variables
+  this->peers[userId].handshake = new Handshake(this->pInfo->nodeType, userId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID());
+  this->peers[userId].handshake->setUniqueID(userId);
+
+  this->peers[userId].connectionMonitor = new ConnectionMonitor( userId );
+  this->peers[userId].userId = userId;
+  this->peers[userId].bLocal = true;
+
+  PRINTF(0)("num sync: %d\n", synchronizeables.size());
+
+  // get the proxy server informations and write them to the handshake, if any (proxy)
+  assert( this->networkMonitor != NULL);
+  PeerInfo* pi = this->networkMonitor->getFirstChoiceProxy();
+  if( pi != NULL)
+  {
+    this->peers[userId].handshake->setProxy1Address( pi->ip);
+  }
+  pi = this->networkMonitor->getSecondChoiceProxy();
+  if( pi != NULL)
+    this->peers[userId].handshake->setProxy2Address( pi->ip);
+
+  // check if the connecting client should reconnect to a proxy server
+  if( SharedNetworkData::getInstance()->isMasterServer())
+  {
+    if( this->networkMonitor->isReconnectNextClient())
+    {
+      this->peers[userId].handshake->setRedirect(true);
+      PRINTF(0)("forwarding client to proxy server because this server is saturated\n");
+    }
+  }
+
+  // the connecting node of course is a client
+  this->peers[userId].ip = this->peers[userId].socket->getRemoteAddress();
+}
+
+
+/**
+ * this handles new soft connections
+ * @param userId: the id of the new user node
+ *
+ * soft connections are connections from clients that are already in the network and don't need a new handshake etc.
+ * the state of all entitites owned by userId are not deleted and stay
+ * soft connections can not be redirected therefore they are negotiated between the to parties
+ */
+void NetworkStream::handleSoftConnect( int userId)
+{
+  // create new handshake and init its variables
+  this->peers[userId].handshake = NULL;
+  this->peers[userId].handshake->setUniqueID(userId);
+
+  this->peers[userId].connectionMonitor = new ConnectionMonitor( userId );
+  this->peers[userId].userId = userId;
+  this->peers[userId].bLocal = true;
+
+  PRINTF(0)("num sync: %d\n", synchronizeables.size());
+
+  // the connecting node of course is a client
+  this->peers[userId].ip = this->peers[userId].socket->getRemoteAddress();
+}
+
+
+
+
+/**
+ * some debug output
+ */
+void NetworkStream::debug()
+{
+  if( SharedNetworkData::getInstance()->isMasterServer()) {
+    PRINT(0)(" Host ist Master Server with ID: %i\n", this->pInfo->userId);
+  }
+  else if( SharedNetworkData::getInstance()->isProxyServerActive()) {
+    PRINT(0)(" Host ist Proxy Server with ID: %i\n", this->pInfo->userId);
+  }
+  else {
+    PRINT(0)(" Host ist Client with ID: %i\n", this->pInfo->userId);
+  }
+
+  PRINT(0)(" Current number of connections is: %i\n", this->peers.size());
+  for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
+  {
+    PRINT(0)("  peers[%i] with uniqueId %i and address: %s\n", it->first, it->second.userId, it->second.ip.ipString().c_str());
+  }
+  PRINT(0)("\n\n");
+
+
+  PRINT(0)(" Got %i connected Synchronizeables, showing active Syncs:\n", this->synchronizeables.size());
+  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
+  {
+    if( (*it)->beSynchronized() == true)
+      PRINT(0)("  Synchronizeable of class: %s::%s, with unique ID: %i, Synchronize: %i\n", (*it)->getClassCName(), (*it)->getCName(),
+               (*it)->getUniqueID(), (*it)->beSynchronized());
+  }
+  PRINT(0)(" Maximal Connections: %i\n", SharedNetworkData::getInstance()->getMaxPlayer() );
+
+}
+
+
+/**
+ * @returns the number of synchronizeables registered to this stream
+ */
+int NetworkStream::getSyncCount()
+{
+  int n = 0;
+  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
+    if( (*it)->beSynchronized() == true)
+      ++n;
+
+  //return synchronizeables.size();
+  return n;
+}
+
+
+/**
+ * check if handshakes completed. if so create the network game manager else remove it again
+ */
+void NetworkStream::handleHandshakes( )
+{
+  for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
+  {
+    if ( it->second.handshake )
+    {
+      // handshake finished
+      if ( it->second.handshake->completed() )
+      {
+        //handshake is correct
+        if ( it->second.handshake->ok() )
+        {
+          // write the first informations into the node so they can be read from there for case differentiation
+          it->second.nodeType = it->second.handshake->getRemoteNodeType();
+
+          // the counter part didn't mark it free for deletion yet
+          if ( !it->second.handshake->allowDel() )
+          {
+            // make sure this is a connection:
+            // - client       <==> master server
+            // - proxy server <==> master server
+            if(  SharedNetworkData::getInstance()->isClient() ||
+                 SharedNetworkData::getInstance()->isProxyServerActive() &&
+                 SharedNetworkData::getInstance()->isUserMasterServer(it->second.userId))
+            {
+              PRINTF(4)("Handshake: i am in client role\n");
+
+              SharedNetworkData::getInstance()->setHostID( it->second.handshake->getHostId() );
+              this->pInfo->userId = SharedNetworkData::getInstance()->getHostID();
+
+//               it->second.ip = it->second.socket->getRemoteAddress();
+
+              it->second.nodeType = it->second.handshake->getRemoteNodeType();
+              // it->second.ip = it->second.socket->getRemoteAddress();
+              // add the new server to the nodes list (it can be a NET_MASTER_SERVER or NET_PROXY_SERVER)
+              this->networkMonitor->addNode(&it->second);
+              // get proxy 1 address and add it
+              this->networkMonitor->addNode(it->second.handshake->getProxy1Address(), NET_PROXY_SERVER_ACTIVE);
+              // get proxy 2 address and add it
+              this->networkMonitor->addNode(it->second.handshake->getProxy2Address(), NET_PROXY_SERVER_ACTIVE);
+
+              // now check if the server accepted the connection
+              if( SharedNetworkData::getInstance()->isClient() && it->second.handshake->redirect() )
+              {
+                this->bRedirect = true;
+              }
+
+              // create the new network game manager and init it
+              this->networkGameManager = NetworkGameManager::getInstance();
+              this->networkGameManager->setUniqueID( it->second.handshake->getNetworkGameManagerId() );
+              // init the new message manager
+              MessageManager::getInstance()->setUniqueID( it->second.handshake->getMessageManagerId() );
+            }
+
+            PRINT(0)("handshake finished id=%d\n", it->second.handshake->getNetworkGameManagerId());
+            it->second.handshake->del();
+
+          }
+          else
+          {
+            // handshake finished registring new player
+            if ( it->second.handshake->canDel() )
+            {
+
+              if (  SharedNetworkData::getInstance()->isMasterServer() )
+              {
+                it->second.ip = it->second.socket->getRemoteAddress();
+
+                this->networkMonitor->addNode(&it->second);
+
+                this->handleNewClient( it->second.userId );
+
+                if ( PlayerStats::getStats( it->second.userId ) && it->second.handshake->getPreferedNickName() != "" )
+                {
+                  PlayerStats::getStats( it->second.userId )->setNickName( it->second.handshake->getPreferedNickName() );
+                }
+              }
+              else if ( SharedNetworkData::getInstance()->isProxyServerActive() && it->second.isClient() )
+              {
+                PRINTF(4)("Handshake: Proxy in server role: connecting %i\n", it->second.userId);
+
+                it->second.ip = it->second.socket->getRemoteAddress();
+
+                this->networkMonitor->addNode(&it->second);
+
+                // work with the ProxyControl to init the new client
+                ProxyControl::getInstance()->signalNewClient( it->second.userId);
+
+                if ( PlayerStats::getStats( it->second.userId ) && it->second.handshake->getPreferedNickName() != "" )
+                {
+                  PlayerStats::getStats( it->second.userId )->setNickName( it->second.handshake->getPreferedNickName() );
+                }
+              }
+
+              PRINT(0)("handshake finished delete it\n");
+              delete it->second.handshake;
+              it->second.handshake = NULL;
+            }
+          }
+
+        }
+        else
+        {
+          PRINT(1)("handshake failed!\n");
+          it->second.socket->disconnectServer();
+        }
+      }
+    }
+  }
+}
+
+
+/**
+ * this functions handles a reconnect event received from the a NET_MASTER_SERVER or NET_PROXY_SERVER
+ * @param userId
+ */
+void NetworkStream::handleReconnect(int userId)
+{
+  this->bRedirect = false;
+#warning this peer will be created if it does not yet exist: dangerous
+  PeerInfo* pInfo = &this->peers[userId];
+
+  IP proxyIP;
+  if( this->networkMonitor->isForcedReconnection())
+    proxyIP = this->networkMonitor->getForcedReconnectionIP();
+  else
+    proxyIP = pInfo->handshake->getProxy1Address();
+
+  PRINTF(0)("===============================================\n");
+  PRINTF(0)("Client is redirected to the other proxy servers\n");
+  PRINTF(0)("  user id: %i\n", userId);
+  PRINTF(0)("  connecting to: %s\n", proxyIP.ipString().c_str());
+  PRINTF(0)("===============================================\n");
+
+  // flush the old synchronization states, since the numbering could be completely different
+  pInfo->lastAckedState = 0;
+  pInfo->lastRecvedState = 0;
+
+  // disconnect from the current server and reconnect to proxy server
+  this->handleDisconnect( userId);
+  this->connectToProxyServer(NET_ID_PROXY_SERVER_01, proxyIP.ipString(), 9999);
+//   this->connectToMasterServer(proxyIP.ipString(), 9999);
+  #warning the ports are not yet integrated correctly in the ip class
+
+  // and restart the handshake
+  this->startHandshake( userId);
+}
+
+
+
+/**
+ * reconnects to another server, with full handshake
+ * @param address of the new server
+ */
+void NetworkStream::reconnectToServer(IP address)
+{
+  ///TODO make a redirection struct and push it to the network monitor
+  this->networkMonitor->setForcedReconnection(address);
+
+  // reconnect (depending on how we are connected at the moment)
+  if ( peers.find( NET_ID_MASTER_SERVER) != peers.end() )
+    this->redirectionUID = NET_ID_MASTER_SERVER;
+  else if( peers.find( NET_ID_PROXY_SERVER_01) != peers.end() )
+    this->redirectionUID = NET_ID_PROXY_SERVER_01;
+
+  this->bRedirect = true;
+}
+
+
+
+/**
+ * softly reconnecting to another server
+ * @param serverUserId the id of the client
+ * @param address  of the new server
+ */
+void NetworkStream::softReconnectToServer(int serverUserId, IP address)
+{
+//   this->networkMonitor->setForcedReconnection(address);
+//   this->handleReconnect( NET_ID_MASTER_SERVER);
+
+  // create the new udp socket and open the connection to the soft connection port
+  NetworkSocket* newSocket = new UdpSocket(address.ipString(), 10001);
+
+  // delete the synchronization state of this client for all syncs
+  for ( SynchronizeableList::iterator it2 = synchronizeables.begin(); it2 != synchronizeables.end(); it2++ )  {
+    (*it2)->cleanUpUser( serverUserId );
+  }
+
+  // temp save the old socket
+  NetworkSocket* oldSocket = this->peers[serverUserId].socket;
+
+  // now integrate the new socket
+  this->peers[serverUserId].socket = newSocket;
+
+  this->bSoftRedirect = false;
+  return;
+
+  // now remove the old socket
+  oldSocket->disconnectServer();
+  delete oldSocket;
+
+  // replace the old connection monitor
+  if ( this->peers[serverUserId].connectionMonitor )
+    delete this->peers[serverUserId].connectionMonitor;
+  this->peers[serverUserId].connectionMonitor = new ConnectionMonitor(serverUserId);
+
+  // remove old node from the network monitor
+  this->networkMonitor->removeNode(&this->peers[serverUserId]);
+
+}
+
+
+
+/**
+ * prepares a soft connection for a client to connect to
+ * @param userId that will connect to this server
+ */
+void NetworkStream::prepareSoftConnection(int userId)
+{
+  PRINTF(0)("prepare soft connection for userId %i\n");
+}
+
+
+
+/**
+ * handles the disconnect event
+ * @param userId id of the user to remove
+ */
+void NetworkStream::handleDisconnect( int userId )
+{
+  this->peers[userId].socket->disconnectServer();
+  delete this->peers[userId].socket;
+  this->peers[userId].socket = NULL;
+
+  if ( this->peers[userId].handshake )
+    delete this->peers[userId].handshake;
+  this->peers[userId].handshake = NULL;
+
+  if ( this->peers[userId].connectionMonitor )
+    delete this->peers[userId].connectionMonitor;
+  this->peers[userId].connectionMonitor = NULL;
+
+  // delete the synchronization state of this client for all syncs
+  for ( SynchronizeableList::iterator it2 = synchronizeables.begin(); it2 != synchronizeables.end(); it2++ )  {
+    (*it2)->cleanUpUser( userId );
+  }
+
+  if( SharedNetworkData::getInstance()->isMasterServer())
+    NetworkGameManager::getInstance()->signalLeftPlayer(userId);
+
+  this->freeSocketSlots.push_back( userId );
+
+  this->networkMonitor->removeNode(&this->peers[userId]);
+  this->peers.erase( userId);
+}
+
+
+/**
+ * handle upstream network traffic
+ * @param tick: seconds elapsed since last update
+ */
+void NetworkStream::handleUpstream( int tick )
+{
+  int offset;
+  int n;
+
+  for ( PeerList::reverse_iterator peer = peers.rbegin(); peer != peers.rend(); peer++ )
+  {
+    offset = INTSIZE; // reserve enough space for the packet length
+
+    // continue with the next peer if this peer has no socket assigned (therefore no network)
+    if ( !peer->second.socket )
+      continue;
+
+    // header informations: current state
+    n = Converter::intToByteArray( currentState, buf + offset, UDP_PACKET_SIZE - offset );
+    assert( n == INTSIZE );
+    offset += n;
+
+    // header informations: last acked state
+    n = Converter::intToByteArray( peer->second.lastAckedState, buf + offset, UDP_PACKET_SIZE - offset );
+    assert( n == INTSIZE );
+    offset += n;
+
+    // header informations: last recved state
+    n = Converter::intToByteArray( peer->second.lastRecvedState, buf + offset, UDP_PACKET_SIZE - offset );
+    assert( n == INTSIZE );
+    offset += n;
+
+    // now write all synchronizeables in the packet
+    for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
+    {
+
+      int oldOffset = offset;
+      Synchronizeable & sync = **it;
+
+
+      // do not include synchronizeables with uninit id and syncs that don't want to be synchronized
+      if ( !sync.beSynchronized() || sync.getUniqueID() <= NET_UID_UNASSIGNED )
+        continue;
+
+      // if handshake not finished only sync handshake
+      if ( peer->second.handshake && Handshake::staticClassID() != sync.getLeafClassID())
+        continue;
+
+      // if we are a server (both master and proxy servers) and this is not our handshake
+      if ( ( SharedNetworkData::getInstance()->isMasterServer() ||
+             SharedNetworkData::getInstance()->isProxyServerActive() &&  peer->second.isClient())
+	     && Handshake::staticClassID() == sync.getLeafClassID() && sync.getUniqueID() != peer->second.userId )
+        continue;
+
+      /* list of synchronizeables that will never be synchronized over the network: */
+      // do not sync null parent
+      if ( NullParent::staticClassID() == sync.getLeafClassID())
+        continue;
+
+
+      assert( sync.getLeafClassID() != 0);
+
+      assert( offset + INTSIZE <= UDP_PACKET_SIZE );
+
+      // server fakes uniqueid == 0 for handshake synchronizeable
+      if ( ( SharedNetworkData::getInstance()->isMasterServer() ||
+             SharedNetworkData::getInstance()->isProxyServerActive() &&  peer->second.isClient() ) &&
+             ( sync.getUniqueID() >= 1000 || sync.getUniqueID() <= SharedNetworkData::getInstance()->getMaxPlayer() + 1 + NET_ID_PROXY_MAX))
+        n = Converter::intToByteArray( 0, buf + offset, UDP_PACKET_SIZE - offset );
+      else
+        n = Converter::intToByteArray( sync.getUniqueID(), buf + offset, UDP_PACKET_SIZE - offset );
+
+
+      assert( n == INTSIZE );
+      offset += n;
+
+      // make space for packet size
+      offset += INTSIZE;
+
+      n = sync.getStateDiff( peer->second.userId, buf + offset, UDP_PACKET_SIZE-offset, currentState, peer->second.lastAckedState, -1000 );
+      offset += n;
+
+      assert( Converter::intToByteArray( n, buf + offset - n - INTSIZE, INTSIZE ) == INTSIZE );
+
+      // check if all data bytes == 0 -> remove data and the synchronizeable from the sync process since there is no update
+      // TODO not all synchronizeables like this maybe add Synchronizeable::canRemoveZeroDiff()
+      bool allZero = true;
+      for ( int i = 0; i < n; i++ )
+      {
+         if ( buf[i+oldOffset+2*INTSIZE] != 0 )
+           allZero = false;
+      }
+      // if there is no new data in this synchronizeable reset the data offset to the last state -> dont synchronizes
+      // data that hast not changed
+      if ( allZero )
+      {
+        offset = oldOffset;
+      }
+    } // all synchronizeables written
+
+
+
+    for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
+    {
+      Synchronizeable & sync = **it;
+
+      // again exclude all unwanted syncs
+      if ( !sync.beSynchronized() || sync.getUniqueID() <= NET_UID_UNASSIGNED)
+        continue;
+
+      sync.handleSentState( peer->second.userId, currentState, peer->second.lastAckedState );
+    }
+
+
+    assert( Converter::intToByteArray( offset, buf, INTSIZE ) == INTSIZE );
+
+    // now compress the data with the zip library
+    int compLength = 0;
+    if ( SharedNetworkData::getInstance()->isMasterServer() ||
+         SharedNetworkData::getInstance()->isProxyServerActive())
+      compLength = Zip::getInstance()->zip( buf, offset, compBuf, UDP_PACKET_SIZE, dictServer );
+    else
+      compLength = Zip::getInstance()->zip( buf, offset, compBuf, UDP_PACKET_SIZE, dictClient );
+
+    if ( compLength <= 0 )
+    {
+      PRINTF(1)("compression failed!\n");
+      continue;
+    }
+
+    assert( peer->second.socket->writePacket( compBuf, compLength ) );
+
+    if ( this->remainingBytesToWriteToDict > 0 )
+      writeToNewDict( buf, offset, true );
+
+    peer->second.connectionMonitor->processUnzippedOutgoingPacket( tick, buf, offset, currentState );
+    peer->second.connectionMonitor->processZippedOutgoingPacket( tick, compBuf, compLength, currentState );
+
+  }
+}
+
+/**
+ * handle downstream network traffic
+ */
+void NetworkStream::handleDownstream( int tick )
+{
+  int offset = 0;
+
+  int length = 0;
+  int packetLength = 0;
+  int compLength = 0;
+  int uniqueId = 0;
+  int state = 0;
+  int ackedState = 0;
+  int fromState = 0;
+  int syncDataLength = 0;
+
+  for ( PeerList::iterator peer = peers.begin(); peer != peers.end(); peer++ )
+  {
+
+    if ( !peer->second.socket )
+      continue;
+
+    while ( 0 < (compLength = peer->second.socket->readPacket( compBuf, UDP_PACKET_SIZE )) )
+    {
+      peer->second.connectionMonitor->processZippedIncomingPacket( tick, compBuf, compLength );
+
+      packetLength = Zip::getInstance()->unZip( compBuf, compLength, buf, UDP_PACKET_SIZE );
+
+      if ( packetLength < 4*INTSIZE )
+      {
+        if ( packetLength != 0 )
+          PRINTF(1)("got too small packet: %d\n", packetLength);
+        continue;
+      }
+
+      if ( this->remainingBytesToWriteToDict > 0 )
+        writeToNewDict( buf, packetLength, false );
+
+      assert( Converter::byteArrayToInt( buf, &length ) == INTSIZE );
+      assert( Converter::byteArrayToInt( buf + INTSIZE, &state ) == INTSIZE );
+      assert( Converter::byteArrayToInt( buf + 2*INTSIZE, &fromState ) == INTSIZE );
+      assert( Converter::byteArrayToInt( buf + 3*INTSIZE, &ackedState ) == INTSIZE );
+      offset = 4*INTSIZE;
+
+      peer->second.connectionMonitor->processUnzippedIncomingPacket( tick, buf, packetLength, state, ackedState );
+
+
+      //if this is an old state drop it
+      if ( state <= peer->second.lastRecvedState )
+        continue;
+
+      if ( packetLength != length )
+      {
+        PRINTF(1)("real packet length (%d) and transmitted packet length (%d) do not match!\n", packetLength, length);
+        peer->second.socket->disconnectServer();
+        continue;
+      }
+
+      while ( offset + 2 * INTSIZE < length )
+      {
+        // read the unique id of the sync
+        assert( offset > 0 );
+        assert( Converter::byteArrayToInt( buf + offset, &uniqueId ) == INTSIZE );
+        offset += INTSIZE;
+
+        // read the data length
+        assert( Converter::byteArrayToInt( buf + offset, &syncDataLength ) == INTSIZE );
+        offset += INTSIZE;
+
+        assert( syncDataLength > 0 );
+        assert( syncDataLength < 10000 );
+
+        Synchronizeable * sync = NULL;
+
+        // look for the synchronizeable in question
+        for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
+        {
+          // client thinks his handshake has a special id: hostId * 1000 (host id of this server)
+          if ( (*it)->getUniqueID() == uniqueId ||                                          // so this client exists already go to sync work
+                 ( uniqueId == 0  && (*it)->getUniqueID() == peer->second.userId ) )        // so this is a Handshake!
+          {
+            sync = *it;
+            break;
+          }
+        }
+
+        // this synchronizeable does not yet exist! create it
+        if ( sync == NULL )
+        {
+          PRINTF(0)("could not find sync with id %d. try to create it\n", uniqueId);
+
+          // if it is an old synchronizeable already removed, ignore it
+          if ( oldSynchronizeables.find( uniqueId ) != oldSynchronizeables.end() )
+          {
+            offset += syncDataLength;
+            continue;
+          }
+
+          // if the node we got this unknown sync we ignore it if:
+          //  - the remote host is a client
+          //  - the remote host is a proxy server and we are master server
+          // (since it has no rights to create a new sync)
+          if ( peers[peer->second.userId].isClient() ||
+               (peers[peer->second.userId].isProxyServerActive() && SharedNetworkData::getInstance()->isMasterServer()))
+          {
+            offset += syncDataLength;
+            continue;
+          }
+
+          int leafClassId;
+          if ( INTSIZE > length - offset )
+          {
+            offset += syncDataLength;
+            continue;
+          }
+
+          Converter::byteArrayToInt( buf + offset, &leafClassId );
+
+          assert( leafClassId != 0 );
+
+
+          BaseObject * b = NULL;
+          /* These are some small exeptions in creation: Not all objects can/should be created via Factory */
+          /* Exception 1: NullParent */
+	  if( NullParent::staticClassID() == leafClassId || Synchronizeable::staticClassID() == leafClassId || NetworkGameManager::staticClassID() == leafClassId)
+          {
+            PRINTF(1)("Don't create Object with ID %x, ignored!\n", (int)leafClassId);
+            offset += syncDataLength;
+            continue;
+          }
+          else
+	    ; /// FIXME CLASS_ID :: b = Factory::fabricate( leafClassId );
+
+          if ( !b )
+          {
+            PRINTF(1)("Could not fabricate Object with classID %x\n", leafClassId);
+            offset += syncDataLength;
+            continue;
+          }
+
+	  if ( b->isA(Synchronizeable::staticClassID()) )
+          {
+            sync = dynamic_cast<Synchronizeable*>(b);
+            sync->setUniqueID( uniqueId );
+            sync->setSynchronized(true);
+
+            PRINTF(0)("Fabricated %s with id %d\n", sync->getClassCName(), sync->getUniqueID());
+          }
+          else
+          {
+            PRINTF(1)("Class with ID %x is not a synchronizeable!\n", (int)leafClassId);
+            delete b;
+            offset += syncDataLength;
+            continue;
+          }
+        }
+
+
+        int n = sync->setStateDiff( peer->second.userId, buf+offset, syncDataLength, state, fromState );
+        offset += n;
+
+      }
+
+      if ( offset != length )
+      {
+        PRINTF(0)("offset (%d) != length (%d)\n", offset, length);
+        peer->second.socket->disconnectServer();
+      }
+
+
+      for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
+      {
+        Synchronizeable & sync = **it;
+
+        if ( !sync.beSynchronized() || sync.getUniqueID() <= NET_UID_UNASSIGNED )
+          continue;
+
+        sync.handleRecvState( peer->second.userId, state, fromState );
+      }
+
+      assert( peer->second.lastAckedState <= ackedState );
+      peer->second.lastAckedState = ackedState;
+
+      assert( peer->second.lastRecvedState < state );
+      peer->second.lastRecvedState = state;
+
+    }
+
+  }
+
+}
+
+/**
+ * is executed when a handshake has finished
+ */
+void NetworkStream::handleNewClient( int userId )
+{
+  // init and assign the message manager
+  MessageManager::getInstance()->initUser( userId );
+  // do all game relevant stuff here
+  networkGameManager->signalNewPlayer( userId );
+}
+
+
+/**
+ * removes old items from oldSynchronizeables
+ */
+void NetworkStream::cleanUpOldSyncList( )
+{
+  int now = SDL_GetTicks();
+
+  for ( std::map<int,int>::iterator it = oldSynchronizeables.begin(); it != oldSynchronizeables.end();  )
+  {
+    if ( it->second < now - 10*1000 )
+    {
+      std::map<int,int>::iterator delIt = it;
+      it++;
+      oldSynchronizeables.erase( delIt );
+      continue;
+    }
+    it++;
+  }
+}
+
+/**
+ * writes data to DATA/dicts/newdict
+ * @param data pointer to data
+ * @param length length
+ */
+void NetworkStream::writeToNewDict( byte * data, int length, bool upstream )
+{
+  if ( remainingBytesToWriteToDict <= 0 )
+    return;
+
+  if ( length > remainingBytesToWriteToDict )
+    length = remainingBytesToWriteToDict;
+
+  std::string fileName = Resources::ResourceManager::getInstance()->mainGlobalPath().name();
+  fileName += "/dicts/newdict";
+
+  if ( upstream )
+    fileName += "_upstream";
+  else
+    fileName += "_downstream";
+
+  FILE * f = fopen( fileName.c_str(), "a" );
+
+  if ( !f )
+  {
+    PRINTF(2)("could not open %s\n", fileName.c_str());
+    remainingBytesToWriteToDict = 0;
+    return;
+  }
+
+  if ( fwrite( data, 1, length, f ) != length )
+  {
+    PRINTF(2)("could not write to file\n");
+    fclose( f );
+    return;
+  }
+
+  fclose( f );
+
+  remainingBytesToWriteToDict -= length;
+}
+
+
+
+
+
+
Index: branches/heathaze/src/lib/network/network_stream.h
===================================================================
--- branches/heathaze/src/lib/network/network_stream.h	(revision 9940)
+++ branches/heathaze/src/lib/network/network_stream.h	(revision 9940)
@@ -0,0 +1,142 @@
+/*!
+ * @file network_stream.h
+ *  implementation of a network pipe
+ */
+
+#ifndef _NETWORK_STREAM
+#define _NETWORK_STREAM
+
+#include <vector>
+#include <list>
+#include <map>
+
+#include "data_stream.h"
+#include "server_socket.h"
+#include "handshake.h"
+#include "monitor/connection_monitor.h"
+#include "udp_server_socket.h"
+#include "peer_info.h"
+
+#include "shared_network_data.h"
+
+class Synchronizeable;
+class NetworkSocket;
+class ServerSocket;
+class NetworkGameManager;
+class NetworkMonitor;
+
+
+typedef std::list<Synchronizeable*>  SynchronizeableList;
+typedef std::map<int,PeerInfo>       PeerList;
+
+
+class NetworkStream : public DataStream
+{
+  ObjectListDeclaration(NetworkStream);
+  public:
+    NetworkStream();
+    NetworkStream(int nodeType);
+    virtual ~NetworkStream();
+
+    void init();
+
+    /* network interface controls */
+    void connectToMasterServer(std::string host, int port);
+    void connectToProxyServer(int proxyId, std::string host, int port);
+    void createServer(int clientPort, int proxyPort, int clientSoftPort);
+
+    void createNetworkGameManager();
+    void startHandshake(int userId = NET_ID_MASTER_SERVER);
+
+    void reconnectToServer(IP address);
+    void softReconnectToServer(int serverUserId, IP address);
+    void prepareSoftConnection(int userId);
+
+
+    /* synchronizeable interface */
+    void connectSynchronizeable(Synchronizeable& sync);
+    void disconnectSynchronizeable(Synchronizeable& sync);
+
+    inline int getMaxConnections(){ return SharedNetworkData::getInstance()->getMaxPlayer(); }
+
+    /* functions for the peerInfo information retreival */
+    /** @returns true if this userId is activated at this client false if not*/
+    inline bool isUserIdActive( int userID ) { return (peers.find(userID) != peers.end()); }
+    /** @returns true if this userId is a local client */
+    inline bool isUserLocal( int userID) { return this->isUserIdActive(userID); }
+    /** @returns true if this user is a master server */
+    inline bool isUserMasterServer( int userID ){ if ( !isUserIdActive(userID) ) return false; return peers[userID].isMasterServer(); }
+    /** @returns true if this user is a proxy server */
+    inline bool isUserProxyServerActive( int userID ){ if ( !isUserIdActive(userID) ) return false; return peers[userID].isProxyServerActive(); }
+    /** @returns true if this user is a client */
+    inline bool isUserClient( int userID ){ if ( !isUserIdActive(userID) ) return false; return peers[userID].isClient(); }
+
+    /* peering interface */
+    inline PeerInfo & getPeerInfo( int userId ) { return peers[userId]; }
+    inline PeerInfo* getPeerInfo() { return this->pInfo; }
+    inline PeerList getPeerInfoList() { return this->peers; }
+
+    inline void setRedirectionTest() { this->bSoftRedirect = true; }
+
+    /* data processing*/
+    virtual void processData();
+
+    /* debugging */
+    void debug();
+
+
+  private:
+
+    inline SynchronizeableList::const_iterator getSyncBegin(){ return synchronizeables.begin(); }
+    inline SynchronizeableList::const_iterator getSyncEnd(){ return synchronizeables.end(); }
+    void cleanUpOldSyncList();
+    int getSyncCount();
+
+    void updateConnectionList();
+
+    /* handle processes */
+    void handleHandshakes();
+    void handleUpstream( int tick );
+    void handleDownstream(int tick );
+
+    /* handle events*/
+    void handleNewClient( int userId );
+
+    void handleConnect( int userId);
+    void handleSoftConnect( int userId);
+    void handleReconnect( int userId );
+    void handleDisconnect( int userId );
+    void handleSoftDisconnect( int userId);
+
+    void writeToNewDict( byte * data, int length, bool upstream );
+
+
+  private:
+    PeerList                   peers;                       //!< list of the network node informations
+
+    PeerInfo*                  pInfo;                       //!< the info about the local peer node (not in the PeerList)
+
+    std::list<int>             freeSocketSlots;             //!< list of free sockets (to ensure not to resycle sockets)
+    int                        currentState;                //!< current state id
+
+    NetworkMonitor*            networkMonitor;              //!< the network monitor
+    NetworkGameManager*        networkGameManager;          //!< reference to the network game manager
+    ServerSocket*              clientSocket;                //!< the listening socket for clients of the server
+    ServerSocket*              clientSoftSocket;            //!< the listening socket for soft connections to the server
+    ServerSocket*              proxySocket;                 //!< socket for proxy connections
+
+    std::map<int,int>          oldSynchronizeables;         //!< used to save recently deleted sync ids to not recreate them
+    SynchronizeableList        synchronizeables;            //!< list of the synchronizeables
+
+    byte                       buf[UDP_PACKET_SIZE];        //!< used by handleUp/Downstream
+    byte                       compBuf[UDP_PACKET_SIZE];    //!< used by handleUp/Downstream
+    int                        remainingBytesToWriteToDict; //!< if > 0 NetworkStream will write packets to DATA/dicts/newdict
+
+    int                        dictServer;                  //!< the zip dict for the server
+    int                        dictClient;                  //!< the zip dict for the client
+
+    bool                       bRedirect;                   //!< true if the master server sent a redirect command
+    int                        redirectionUID;              //!< uid of the redir host
+    bool                       bSoftRedirect;               //!< tsting
+};
+#endif /* _NETWORK_STREAM */
Index: branches/heathaze/src/lib/network/peer_info.cc
===================================================================
--- branches/heathaze/src/lib/network/peer_info.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/peer_info.cc	(revision 9940)
@@ -0,0 +1,76 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner rennerc@ee.ethz.ch
+   co-programmer:   Patrick Boenzli  boenzlip@orxonox.ethz.ch
+
+     June 2006: finishing work on the network stream for pps presentation (rennerc@ee.ethz.ch)
+     July 2006: some code rearangement and integration of the proxy server mechanism (boenzlip@ee.ethz.ch)
+*/
+
+
+#define DEBUG_MODULE_NETWORK
+
+
+#include "peer_info.h"
+
+
+
+
+
+
+/**
+ * constructor
+ */
+PeerInfo::PeerInfo()
+{
+  this->clear();
+}
+
+
+/**
+ * clearint and initializing the peer info
+ */
+void PeerInfo::clear()
+{
+  this->userId = NET_ID_UNASSIGNED;
+  this->nodeType = NET_UNASSIGNED;
+  this->socket = NULL;
+  this->handshake = NULL;
+  this->lastAckedState = 0;
+  this->lastRecvedState = 0;
+  this->connectionMonitor = NULL;
+  this->bLocal = false;
+
+  this->ip = IP(0,0);
+}
+
+
+const std::string& PeerInfo::getNodeTypeString() const
+{
+  return PeerInfo::nodeTypeToString( this->nodeType );
+  // the above does the same, and is faster in it. (there is no case where node is uninit i hope!)
+}
+
+const std::string& PeerInfo::nodeTypeToString(unsigned int type)
+{
+  return PeerInfo::nodeNames[type];
+}
+
+
+const std::string PeerInfo::nodeNames[] =
+{
+  "master server",
+  "proxy server active",
+  "proxy server passive",
+  "client",
+  "node is not initialized"
+};
Index: branches/heathaze/src/lib/network/peer_info.h
===================================================================
--- branches/heathaze/src/lib/network/peer_info.h	(revision 9940)
+++ branches/heathaze/src/lib/network/peer_info.h	(revision 9940)
@@ -0,0 +1,55 @@
+/*!
+ * @file peer_info.h
+ *  implementation a peer info
+ */
+
+#ifndef _PEER_INFO_H
+#define _PEER_INFO_H
+
+#include "server_socket.h"
+#include "handshake.h"
+#include "monitor/connection_monitor.h"
+
+#include <string>
+
+//!< this structure contains informations about the network node
+class PeerInfo
+{
+  public:
+    PeerInfo();
+
+    void clear();
+
+
+    inline bool isMasterServer() const { return this->nodeType == NET_MASTER_SERVER; }
+    inline bool isProxyServerActive() const { return this->nodeType == NET_PROXY_SERVER_ACTIVE; }
+    inline bool isProxyServerActivePassive() const { return this->nodeType == NET_PROXY_SERVER_PASSIVE; }
+    inline bool isClient() const { return this->nodeType == NET_CLIENT; }
+
+    const std::string& getNodeTypeString() const;
+    static const std::string& nodeTypeToString(unsigned int type);
+
+    inline bool isLocal() { return this->bLocal; }
+
+
+  public:
+    int                 userId;                  //!< id of this network node
+    int                 nodeType;                //!< type of this network node
+    IP                  ip;                      //!> the ip address of this network node
+
+    NetworkSocket *     socket;                  //!< socket connecting to this node
+    Handshake *         handshake;               //!< the handshake object, active on connection setup
+    ConnectionMonitor * connectionMonitor;       //!< ConnectionMonitor monitoring the current network traffic
+
+    int                 lastAckedState;          //!< last acked state synchronized state
+    int                 lastRecvedState;         //!< last received state
+
+    bool                bLocal;                  //!< true if this node is localy connected to this node
+
+    static const std::string nodeNames[];
+
+};
+
+
+
+#endif /* _PEER_INFO_H */
Index: branches/heathaze/src/lib/network/player_stats.cc
===================================================================
--- branches/heathaze/src/lib/network/player_stats.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/player_stats.cc	(revision 9940)
@@ -0,0 +1,289 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+#include "player_stats.h"
+
+#include "src/lib/util/loading/factory.h"
+
+#include "player.h"
+#include "playable.h"
+#include "state.h"
+#include "shared_network_data.h"
+
+#include "converter.h"
+
+#include "parser/preferences/preferences.h"
+
+#include "debug.h"
+#include "shell_command.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(PlayerStats, CL_PLAYER_STATS);
+CREATE_FACTORY(PlayerStats);
+
+/**
+ * constructor
+ */
+PlayerStats::PlayerStats( int userId )
+{
+  init();
+
+  this->assignedUserId = userId;
+}
+
+/**
+ * constructor
+ */
+PlayerStats::PlayerStats( const TiXmlElement* root )
+{
+  init();
+}
+
+void PlayerStats::init( )
+{
+  this->registerObject(this, PlayerStats::_objectList);
+
+  this->assignedUserId = 0;
+  this->teamId = TEAM_NOTEAM;
+  this->preferedTeamId = TEAM_NOTEAM;
+  this->score = 0;
+  this->playableClassId = 0;
+  this->modelFileName = "";
+  this->nickName = "Player";
+  this->oldNickName = "Player";
+
+  userId_handle = registerVarId( new SynchronizeableInt( &assignedUserId, &assignedUserId, "userId", PERMISSION_MASTER_SERVER ) );
+  teamId_handle = registerVarId( new SynchronizeableInt( &teamId, &teamId, "teamId", PERMISSION_MASTER_SERVER ) );
+  preferedTeamId_handle = registerVarId( new SynchronizeableInt( &preferedTeamId, &preferedTeamId, "preferedUserId", PERMISSION_MASTER_SERVER ) );
+  score_handle = registerVarId( new SynchronizeableInt( &score, &score, "score", PERMISSION_MASTER_SERVER ) );
+  playableClassId_handle = registerVarId( new SynchronizeableInt( &playableClassId, &playableClassId, "playableClassId", PERMISSION_MASTER_SERVER) );
+  playableUniqueId_handle = registerVarId( new SynchronizeableInt( &playableUniqueId, &playableUniqueId, "playableUniqueId", PERMISSION_MASTER_SERVER ) );
+  modelFileName_handle = registerVarId( new SynchronizeableString( &modelFileName, &modelFileName, "modelFileName", PERMISSION_MASTER_SERVER ) );
+  nickName_handler = registerVarId( new SynchronizeableString( &nickName, &nickName, "nickName", PERMISSION_MASTER_SERVER ) );
+
+  MessageManager::getInstance()->registerMessageHandler( MSGID_CHANGENICKNAME, changeNickHandler, NULL );
+
+  PRINTF(5)("PlayerStats created\n");
+}
+
+
+/**
+ * standard deconstructor
+ */
+PlayerStats::~PlayerStats()
+{}
+
+
+/**
+* override this function to be notified on change
+* of your registred variables.
+* @param id id's which have changed
+ */
+void PlayerStats::varChangeHandler( std::list< int > & id )
+{
+  if ( std::find( id.begin(), id.end(), playableUniqueId_handle ) != id.end() )
+  {
+    this->setPlayableUniqueId( this->playableUniqueId );
+
+    PRINTF(4)("uniqueID changed %d %d %d\n", assignedUserId, SharedNetworkData::getInstance()->getHostID(), getUniqueID());
+  }
+
+  if ( std::find( id.begin(), id.end(), nickName_handler ) != id.end() )
+  {
+    PRINTF(0)("user %s is now known as %s\n", oldNickName.c_str(), nickName.c_str());
+    this->oldNickName = nickName;
+  }
+
+  if ( std::find( id.begin(), id.end(), preferedTeamId_handle) != id.end() )
+  {
+    PRINTF(0)("user %s has changed team to %i\n", nickName.c_str(), this->teamId);
+  }
+}
+
+
+
+/**
+ * get stats for user userId
+ * @param userId user's id
+ * @return stats assigned to user
+ */
+PlayerStats * PlayerStats::getStats( int userId )
+{
+  for (ObjectList<PlayerStats>::const_iterator it = PlayerStats::objectList().begin();
+       it != PlayerStats::objectList().end();
+       ++it)
+  {
+    if ( (*it)->getAssignedUserId() == userId )
+    {
+      return (*it);
+    }
+  }
+
+  return NULL;
+}
+
+/**
+ * set playable class id and set playable
+ */
+void PlayerStats::setPlayableUniqueId( int uniqueId )
+{
+  this->playable = NULL;
+  for (ObjectList<Playable>::const_iterator it = Playable::objectList().begin();
+       it != Playable::objectList().end();
+       ++it)
+  {
+    if ( (*it)->getUniqueID() == uniqueId )
+    {
+      this->playable = (*it);
+      //TODO when OM_PLAYERS is ticked add line:
+      //this->playable->toList( OM_PLAYERS );
+      break;
+    }
+  }
+
+  if ( this->playable && this->assignedUserId == SharedNetworkData::getInstance()->getHostID() )
+  {
+    State::getPlayer()->setPlayable( this->playable );
+    // also set the team id
+  }
+
+  this->playableUniqueId = uniqueId;
+}
+
+/**
+ * get playable associated to player
+ * @return playable associated to player
+ */
+Playable * PlayerStats::getPlayable()
+{
+  if ( playable )
+    return playable;
+
+  assert( playableUniqueId > 0 );
+
+  setPlayableUniqueId( playableUniqueId );
+
+  assert( playable );
+
+  return playable;
+}
+
+/**
+ * client sends server a message to change nick and server changes nick directly
+ * @param nick new nickname
+ */
+void PlayerStats::setNickName( std::string nick )
+{
+  if ( SharedNetworkData::getInstance()->isMasterServer())
+  {
+    this->nickName = nick;
+    PRINTF(0)("user %s is now known as %s\n", oldNickName.c_str(), nickName.c_str());
+    oldNickName = nickName;
+    return;
+  }
+  else
+  {
+    byte * data = new byte[nick.length()+INTSIZE];
+
+    assert( Converter::stringToByteArray( nick, data, nick.length()+INTSIZE) == nick.length()+INTSIZE );
+
+    MessageManager::getInstance()->sendMessage( MSGID_CHANGENICKNAME, data, nick.length()+INTSIZE, RT_SERVER, NET_MASTER_SERVER, MP_HIGHBANDWIDTH );
+    return;
+  }
+}
+
+/**
+ * handler for the nick name
+ * @param messageType type of the message
+ * @param data  data of the message
+ * @param dataLength length of the data
+ * @param someData some additional data
+ * @param senderId userId of the sender
+ * @param destinationId userId of the rec
+ * @return true if handled correctly
+ */
+bool PlayerStats::changeNickHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  std::string newNick;
+  int res = Converter::byteArrayToString( data, newNick, dataLength );
+
+  if ( res != dataLength )
+  {
+    PRINTF(2)("invalid message size from user %d\n", senderId);
+    newNick = "invalid";
+  }
+
+  if ( PlayerStats::getStats( senderId) )
+    PlayerStats::getStats( senderId )->setNickName( newNick );
+
+  return true;
+}
+
+/**
+ * sets the nick name from the shell
+ * @param newNick new prefered nick name
+ */
+void PlayerStats::shellNick( const std::string& newNick )
+{
+  if ( getStats( SharedNetworkData::getInstance()->getHostID() ) )
+    getStats( SharedNetworkData::getInstance()->getHostID() )->setNickName( newNick );
+
+  Preferences::getInstance()->setString( "multiplayer", "nickname", newNick );
+}
+
+
+
+/**
+ * removes and delets all player stats
+ */
+void PlayerStats::deleteAllPlayerStats( )
+{
+
+  while(!PlayerStats::objectList().empty())
+    delete PlayerStats::objectList().front();
+}
+
+
+
+/**
+ * @return the score list of this player stat
+ */
+ScoreList PlayerStats::getScoreList( )
+{
+  ScoreList result;
+
+  for (ObjectList<PlayerStats>::const_iterator it = PlayerStats::objectList().begin();
+       it != PlayerStats::objectList().end();
+       ++it)
+  {
+    PlayerStats& stats = *(*it);
+
+    TeamScoreList::iterator it = result[stats.getTeamId()].begin();
+
+    while (  it != result[stats.getTeamId()].end() && stats.score > it->score )
+    {
+      it++;
+    }
+
+    PlayerScore score;
+    score.name = stats.getNickName();
+    score.score = stats.getScore();
+
+    result[stats.getTeamId()].insert(it, score);
+  }
+
+  return result;
+}
Index: branches/heathaze/src/lib/network/player_stats.h
===================================================================
--- branches/heathaze/src/lib/network/player_stats.h	(revision 9940)
+++ branches/heathaze/src/lib/network/player_stats.h	(revision 9940)
@@ -0,0 +1,110 @@
+/*!
+ * @file player_stats.h
+ * @brief Definition of PlayerStats
+ */
+
+#ifndef _PLAYER_STATS_H
+#define _PLAYER_STATS_H
+
+#include "synchronizeable.h"
+#include "playable.h"
+#include "message_manager.h"
+
+#include <string>
+#include <list>
+
+enum
+{
+  TEAM_NOTEAM       = -3,
+  TEAM_RANDOM       = -2,
+  TEAM_SPECTATOR    = -1
+};
+
+
+struct PlayerScore
+{
+  std::string name;
+  int score;
+};
+
+
+typedef std::list<PlayerScore> TeamScoreList;
+typedef std::map<int,TeamScoreList> ScoreList;
+
+
+//! A class for storing player information
+class PlayerStats : public Synchronizeable
+{
+  ObjectListDeclaration(PlayerStats);
+  public:
+    PlayerStats( const TiXmlElement* root = NULL );
+    PlayerStats( int userId );
+    virtual ~PlayerStats();
+
+    virtual void varChangeHandler( std::list<int> & id );
+
+    static PlayerStats * getStats( int userId );
+    inline int getAssignedUserId(){ return this->assignedUserId; }
+
+
+    inline int getTeamId(){ return teamId; }
+    inline void setTeamId( int teamId ){ this->teamId = teamId; }
+
+    inline int getPreferedTeamId(){ return preferedTeamId; }
+    inline void setPreferedTeamId( int preferedTeamId ) { this->preferedTeamId = preferedTeamId; }
+
+    inline int getScore(){ return score; }
+    inline void setScore( int score ){ this->score = score; }
+
+    inline int getPlayableClassId(){ return playableClassId; }
+    void setPlayableClassId( const ClassID& classId ){ this->playableClassId = classId.id(); };
+
+    inline int getPlayableUniqueId(){ return playableUniqueId; }
+    void setPlayableUniqueId( int uniqueId );
+
+    inline std::string getModelFileName(){ return modelFileName; }
+    inline void setModelFileName( std::string filename ){ modelFileName = filename; }
+
+    Playable * getPlayable();
+
+    inline std::string getNickName(){ return this->nickName; }
+    void setNickName( std::string nick );
+    static bool changeNickHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+    void shellNick( const std::string&  newNick );
+
+    static void deleteAllPlayerStats();
+
+    static ScoreList getScoreList();
+
+
+  private:
+    void init();
+
+
+  private:
+    // handles for SynchronizeableVars
+    int              userId_handle;
+    int              teamId_handle;
+    int              preferedTeamId_handle;
+    int              score_handle;
+    int              playableClassId_handle;
+    int              playableUniqueId_handle;
+    int              modelFileName_handle;
+    int              nickName_handler;
+
+    int              assignedUserId;            //!< userId
+    int              teamId;                    //!< teamId
+    int              preferedTeamId;            //!< preferedTeamId
+
+    std::string      nickName;                  //!< players nickname
+    std::string      oldNickName;               //!< nickname player had before
+
+    int              score;                     //!< users score points
+    int              playableClassId;           //!< players playable class id
+    int              playableUniqueId;          //!< playable's uniqueId
+    std::string      modelFileName;             //!< model filename
+
+    Playable *       playable;                  //!< pointer to players playable
+};
+
+#endif /* _PLAYER_STATS_H */
Index: branches/heathaze/src/lib/network/proxy/network_settings.cc
===================================================================
--- branches/heathaze/src/lib/network/proxy/network_settings.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/proxy/network_settings.cc	(revision 9940)
@@ -0,0 +1,149 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+
+#define DEBUG_MODULE_NETWORK
+
+#include "network_settings.h"
+
+#include "netdefs.h"
+#include "shared_network_data.h"
+
+#include "loading/load_param.h"
+#include "loading/resource_manager.h"
+#include "debug.h"
+
+
+ObjectListDefinition(NetworkSettings);
+
+NetworkSettings* NetworkSettings::singletonRef = NULL;
+
+/**
+ * Standard constructor
+ */
+NetworkSettings::NetworkSettings()
+{
+  /* set the class id for the base object */
+  this->registerObject(this, NetworkSettings::_objectList);
+
+  // suggest a good standard max players value
+  this->maxPlayer = 10;
+}
+
+
+/**
+ * Standard destructor
+ */
+NetworkSettings::~NetworkSettings()
+{
+  NetworkSettings::singletonRef = NULL;
+
+  // remove all unused proxy data again
+  for(unsigned int i = 0; i < this->proxies.size(); i++)
+  {
+    IP ip = this->proxies.back();
+    this->proxies.pop_back();
+  }
+}
+
+
+/**
+ *  this loads the proxy settings from a configuration file
+ */
+void NetworkSettings::loadData()
+{
+  std::string fileName = Resources::ResourceManager::getInstance()->mainGlobalPath().name();
+  fileName += "configs/network_settings.conf";
+
+  TiXmlDocument doc(fileName);
+  if( !doc.LoadFile(fileName))
+  {
+    PRINTF(1)("Loading file %s failed for Network Settings.\n", fileName.c_str());
+    return;
+  }
+  const TiXmlElement* root = doc.RootElement();
+
+  if( strcmp( root->Value(), "NetworkSettings"))
+  {
+    // report an error
+    PRINTF(1)("Specified XML File is not an orxonox Network Settings file (NetworkSettings element missing)\n");
+    return;
+  }
+
+  this->loadNetworkSettings( root);
+
+  // set the new unique id offset
+  // setUniqueID( maxCon+2 ) because we need one id for every handshake
+  // and one for handshake to reject client maxCon+1
+  // NEW: at most there will be
+  SharedNetworkData::getInstance()->setNewUniqueID( this->maxPlayer + NET_ID_PROXY_MAX + 2);
+}
+
+
+
+/**
+ * load the proxy settings
+ * @param root: the root element of the xml elemnts
+ */
+void NetworkSettings::loadNetworkSettings(const TiXmlElement* root)
+{
+  LoadParam(root, "master-addr", this, NetworkSettings, setMasterAddr);
+
+  LoadParam(root, "max-player", this, NetworkSettings, setMaxPlayer);
+  LoadParam(root, "max-player-saturation", this, NetworkSettings, setMaxPlayerSaturation);
+
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    element->ToText();
+    LoadParam_CYCLE(element, "proxy-addr", this, NetworkSettings, setProxyAddr);
+  }
+  LOAD_PARAM_END_CYCLE(element);
+
+}
+
+
+/**
+ * sets the master server address
+ * @param masterAddr: the address of the master server
+ */
+void NetworkSettings::setMasterAddr(const std::string& masterAddr)
+{
+  IPaddress *ip = new IPaddress;
+
+  SDLNet_ResolveHost( ip, masterAddr.c_str(), 9999 );
+
+  this->masterServer = *ip;
+}
+
+
+/**
+ * sets the proxy address to
+ *  @param proxyAddr: the proxy address
+ */
+void NetworkSettings::setProxyAddr(const std::string& proxyAddr)
+{
+
+  if( !SharedNetworkData::getInstance()->isMasterServer())
+    return;
+
+  this->proxies.push_back(IP(proxyAddr, 9999));
+}
+
+
+
+
+
+
+
Index: branches/heathaze/src/lib/network/proxy/network_settings.h
===================================================================
--- branches/heathaze/src/lib/network/proxy/network_settings.h	(revision 9940)
+++ branches/heathaze/src/lib/network/proxy/network_settings.h	(revision 9940)
@@ -0,0 +1,70 @@
+/*!
+ * @file proxy_settings.h
+ *  some shared data from the proxy settings
+ */
+
+#ifndef _NETWORK_SETTINGS_H
+#define _NETWORK_SETTINGS_H
+
+#include "base_object.h"
+#include "netdefs.h"
+
+#include "debug.h"
+#include "ip.h"
+
+#include <vector>
+
+
+class NetworkStream;
+class Synchronizeable;
+class TiXmlElement;
+
+
+/* and here is the class itsself*/
+class NetworkSettings : public BaseObject
+{
+  ObjectListDeclaration(NetworkSettings);
+  public:
+    inline static NetworkSettings* getInstance() { if (!NetworkSettings::singletonRef) NetworkSettings::singletonRef = new NetworkSettings();
+      return NetworkSettings::singletonRef; }
+    virtual ~NetworkSettings();
+
+    void loadData();
+
+    void loadNetworkSettings(const TiXmlElement* root);
+
+    /** @param number: sets the max number of players */
+    inline void setMaxPlayer(int number) { this->maxPlayer = number; }
+    /** @returns teh max number of players */
+    int getMaxPlayer() const { return this->maxPlayer; }
+    /** sets the @param saturation: a threshold in percente when the proxy servers should be activated to be able to redirect the clients */
+    inline void setMaxPlayerSaturation(float saturation) { this->maxPlayerSaturation = saturation; }
+
+
+    void setMasterAddr(const std::string& masterAddr);
+    /** @returns the address of the master server read from the network config file */
+    inline const IP& getMasterAddr() const { return this->masterServer; }
+
+    void setProxyAddr(const std::string& proxyAddr);
+    /** @returns the list of proxy servers from the init file */
+    inline std::vector<IP>* getProxyList() { return &this->proxies; }
+
+
+  private:
+    NetworkSettings();
+
+
+  private:
+    static NetworkSettings*      singletonRef;            //!< Pointer to the only instance of this Class
+
+    int                          maxPlayer;               //!< maximal number of players
+    float                        maxPlayerSaturation;     //!< the saturation level from where on the proxy server should be activated
+
+    std::vector<IP>              proxies;                 //!< all registered proxies
+    IP                           masterServer;            //!< master server ip address
+
+};
+
+
+
+#endif /* _NETWORK_SETTINGS_H */
Index: branches/heathaze/src/lib/network/proxy/proxy_control.cc
===================================================================
--- branches/heathaze/src/lib/network/proxy/proxy_control.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/proxy/proxy_control.cc	(revision 9940)
@@ -0,0 +1,387 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli (patrick@orxonox.ethz.ch)
+*/
+
+#include "proxy_control.h"
+
+#include "shell_command.h"
+
+#include "state.h"
+#include "shared_network_data.h"
+#include "network_manager.h"
+#include "network_game_manager.h"
+#include "ip.h"
+#include "peer_info.h"
+#include "network_stream.h"
+
+#include "converter.h"
+
+#include "parser/preferences/preferences.h"
+
+#include "debug.h"
+
+#include "monitor/network_monitor.h"
+
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_NETWORK
+
+ProxyControl* ProxyControl::singletonRef = NULL;
+
+
+SHELL_COMMAND(forceReconnect, ProxyControl, forceReconnectionShell);
+ObjectListDefinition(ProxyControl);
+
+/**
+ * constructor
+ */
+ProxyControl::ProxyControl()
+{
+  this->registerObject(this, ProxyControl::_objectList);
+
+  this->setSynchronized(false);
+
+  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_NEWCLIENT, messageHandlerNewClient, NULL );
+  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_LEAVECLIENT, messageHandlerLeaveClient, NULL );
+  MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_COMMAND, messageHandlerCommand, NULL );
+
+
+  PRINTF(0)("ProxyControl created\n");
+}
+
+
+/**
+ * standard deconstructor
+ */
+ProxyControl::~ProxyControl()
+{
+  ProxyControl::singletonRef = NULL;
+}
+
+
+ /**
+ * override this function to be notified on change
+ * of your registred variables.
+ * @param id id's which have changed
+  */
+void ProxyControl::varChangeHandler( std::list< int > & id )
+{
+//   if ( std::find( id.begin(), id.end(), playableUniqueId_handle ) != id.end() )
+//   {
+//     this->setPlayableUniqueId( this->playableUniqueId );
+//
+//     PRINTF(0)("uniqueID changed %d %d %d\n", userId, SharedNetworkData::getInstance()->getHostID(), getUniqueID());
+//   }
+}
+
+
+/**
+ *  signals new client connected to this local proxy
+ *
+ *  byte 0 - 3     :      userId
+ *  byte 4 - 7     :      ip address (IPaddress.host)
+ *
+ * @param userId userId of the new client
+ */
+void ProxyControl::signalNewClient(int userId)
+{
+  PRINTF(0)("Signaling new Client: %i\n", userId);
+  // make sure we are a proxy server
+  assert(SharedNetworkData::getInstance()->isProxyServerActive());
+
+  byte data[2 * INTSIZE];
+  // write the userId in the message
+  assert( Converter::intToByteArray( userId, data, INTSIZE ) == INTSIZE );
+  // and the ip as an int
+  PeerInfo* pInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(userId);
+  assert(pInfo != NULL);
+  assert( Converter::intToByteArray( pInfo->ip.host(), data + INTSIZE, INTSIZE ) == INTSIZE );
+
+  MessageManager::getInstance()->sendMessage( MSGID_PROXY_NEWCLIENT, data, 2*INTSIZE, RT_SERVER, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
+}
+
+
+/**
+ * this is the handler for proxy signals: new clients
+ *
+ * @param messageType the type of the message
+ * @param data message data
+ * @param dataLength length of the message data
+ * @param someData some other atteched data
+ * @param senderId id of the sender client
+ * @param destinationId id of the destination client
+ * @return true if succeeded
+ */
+bool ProxyControl::messageHandlerNewClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  // body data length correct?
+  if ( dataLength != 2 * INTSIZE )
+  {
+    PRINTF(2)("new client message has wrong size: %d\n", dataLength );
+    return true;
+  }
+  // read the userId fromt he message body
+  int newClientId = 0;
+  assert( Converter::byteArrayToInt( data, &newClientId) == INTSIZE );
+  // now read the ip address
+  int ipHost = 0;
+  assert( Converter::byteArrayToInt( data + INTSIZE, &ipHost) == INTSIZE );
+
+  // register the new node at the network monitor
+  NetworkMonitor* netMon = SharedNetworkData::getInstance()->getNetworkMonitor();
+  NetworkNode* nNode = netMon->getNodeByUserId(senderId); // this gets the proxy server who sent the msg
+  if( nNode == NULL)
+    PRINTF(0)("Couldn't find node %i! Error\n", senderId);
+  PeerInfo* pInfo = new PeerInfo();
+  pInfo->bLocal = false;
+  pInfo->ip = IP(ipHost, 9999);
+  pInfo->nodeType = NET_CLIENT;
+  pInfo->userId = newClientId;
+  netMon->addNode(nNode, pInfo);
+
+  PRINTF(0)("Got Signal: from %i new player arrived with userId: %i and ip: %s on %i\n", senderId, newClientId, pInfo->ip.ipString().c_str(), senderId);
+  // part for the master server
+  if( SharedNetworkData::getInstance()->isMasterServer())
+  {
+    // we now create the new player ship and stuff...
+    NetworkGameManager::getInstance()->signalNewPlayer(newClientId);
+  }
+
+  return true;
+}
+
+
+
+/**
+ *  signals client disconnect
+ * @param userId userId of the old client
+ */
+void ProxyControl::signalLeaveClient(int userId)
+{
+  PRINTF(0)("Signaling new Client: %i\n", userId);
+  // make sure we are a proxy server
+  assert(SharedNetworkData::getInstance()->isProxyServerActive());
+
+  byte data[INTSIZE];
+
+  assert( Converter::intToByteArray( userId, data, INTSIZE ) == INTSIZE );
+
+  MessageManager::getInstance()->sendMessage( MSGID_PROXY_LEAVECLIENT, data, INTSIZE, RT_SERVER, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
+}
+
+
+/**
+ * this is the handler for proxy signals: removing clients
+ *
+ * @param messageType the type of the message
+ * @param data message data
+ * @param dataLength length of the message data
+ * @param someData some other atteched data
+ * @param senderId id of the sender client
+ * @param destinationId id of the destination client
+ * @return true if succeeded
+ */
+bool ProxyControl::messageHandlerLeaveClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  // body data length correct?
+  if ( dataLength != INTSIZE )
+  {
+    PRINTF(2)("leave client message has wrong size: %d\n", dataLength );
+    return true;
+  }
+  // read the userId fromt he message body
+  int leaveClientId = 0;
+  assert( Converter::byteArrayToInt( data, &leaveClientId) == INTSIZE );
+
+  // remove the node from the network monitor
+  NetworkMonitor* netMon = SharedNetworkData::getInstance()->getNetworkMonitor();
+  NetworkNode* nNode = netMon->getNodeByUserId(senderId); // this gets the proxy server who sent the msg
+  netMon->removeNode(nNode, netMon->getPeerByUserId(leaveClientId));
+
+  PRINTF(0)("Got Signal: from %i player left with userId: %i\n", senderId, leaveClientId);
+  // part for the master server
+  if( SharedNetworkData::getInstance()->isMasterServer())
+  {
+    // we now create the new player ship and stuff...
+    NetworkGameManager::getInstance()->signalLeftPlayer(leaveClientId);
+  }
+  else if(SharedNetworkData::getInstance()->isProxyServerActive())
+  {
+
+  }
+
+  return true;
+}
+
+
+
+/**
+ * forces a client to reconnect to another server
+ * @param userId the userId of the client/user :D
+ * @param newAddress the addresss the client should connect to (fully quali dns)
+ */
+void ProxyControl::forceReconnection(int userId, const std::string& newAddress)
+{
+  IP ipAddr = IP(newAddress, 9999);
+  this->forceReconnection(userId, newAddress);
+}
+
+
+
+/**
+ * thumb command: staticly reconnect node 10 to node 0
+ */
+void ProxyControl::forceReconnectionShellThumb()
+{
+  this->forceReconnectionShell(10, 0);
+}
+
+/**
+ * a shell command wrapper
+ * @param userId the userId of the client/user :D
+ * @param serverId the userId of the server to connect to
+ */
+void ProxyControl::forceReconnectionShell(int userId, int serverId)
+{
+  PRINTF(0)("shell reconnectoin command: %i to %i\n", userId, serverId);
+
+  this->forceReconnection(userId, serverId);
+}
+
+
+/**
+ * forces a client to reconnect to another server
+ * @param userId the userId of the client/user :D
+ * @param serverId the userId of the server to connect to
+ */
+void ProxyControl::forceReconnection(int userId, int serverId)
+{
+  PeerInfo* serverInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(serverId);
+  if( serverInfo == NULL)
+  {
+    PRINTF(0)("There is no server with userId %i registered in this network. Check the uid again\n", serverId);
+    return;
+  }
+  else if( serverInfo->isClient())
+  {
+    PRINTF(0)("You can't connec to to a client (userId %i)\n", serverId);
+    return;
+  }
+
+
+  this->forceReconnection(userId, serverId, serverInfo->ip);
+}
+
+
+/**
+ * forces a client to reconnect to another server
+ * @param userId the userId of the client/user :D
+ * @param newAddress the addresss the client should connect to
+ */
+void ProxyControl::forceReconnection(int userId, int serverId, IP newAddress)
+{
+  PRINTF(0)("forcing reconnection: userId %i to %s\n", userId, newAddress.ipString().c_str());
+  // make sure we are a proxy server
+
+  if( SharedNetworkData::getInstance()->isClient())
+  {
+    PRINTF(0)("I am client, got no right to force reconnection\n");
+    return;
+  }
+
+
+  byte data[3 * INTSIZE];
+
+  // write type of message
+  int type = PXY_RECONNECT;
+  assert( Converter::intToByteArray( type, data, INTSIZE ) == INTSIZE );
+  // write the userId in the message
+  assert( Converter::intToByteArray( userId, data + INTSIZE, INTSIZE ) == INTSIZE );
+  // and the ip as an int
+  PeerInfo* pInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(userId);
+  if( pInfo == NULL)
+  {
+    PRINTF(0)("There is no client with userId %i registered in this network. Check the uid again\n", userId);
+    return;
+  }
+  else if( pInfo->isMasterServer() || pInfo->isProxyServerActive())
+  {
+    PRINTF(0)("You cannont reconnect a %s, abording\n", pInfo->getNodeTypeString().c_str());
+    return;
+  }
+  assert( Converter::intToByteArray( newAddress.host(), data + 2 * INTSIZE, INTSIZE ) == INTSIZE );
+
+  PRINTF(0)("Sending reconnection command to: %i\n", userId);
+  // send the reconnection signal to the client who must reconnect
+  MessageManager::getInstance()->sendMessage( MSGID_PROXY_COMMAND, data, 3*INTSIZE, RT_USER, userId, MP_HIGHBANDWIDTH );
+  // and to the server who needs to accept the new client
+  MessageManager::getInstance()->sendMessage( MSGID_PROXY_COMMAND, data, 3*INTSIZE, RT_USER, serverId, MP_HIGHBANDWIDTH );
+}
+
+
+/**
+ * this is the handler for proxy commands
+ *
+ * @param messageType the type of the message
+ * @param data message data
+ * @param dataLength length of the message data
+ * @param someData some other atteched data
+ * @param senderId id of the sender client
+ * @param destinationId id of the destination client
+ * @return true if succeeded
+ */
+bool ProxyControl::messageHandlerCommand( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  // body data length correct?
+  if ( dataLength != 3 * INTSIZE )
+  {
+    PRINTF(1)("leave client message has wrong size: %d\n", dataLength );
+    return true;
+  }
+
+  // read the command type
+  int type = 0;
+  assert( Converter::byteArrayToInt( data, &type) == INTSIZE );
+  PRINTF(0)("got command from %i with code %i\n", senderId, type);
+
+  // now distingush all different sorts of commands
+  switch( type)
+  {
+    case PXY_RECONNECT:
+    {
+      // now read the user id
+      int userId;
+      assert( Converter::byteArrayToInt( data + INTSIZE, &userId) == INTSIZE );
+      // and read the dest address
+      int ipHost = 0;
+      assert( Converter::byteArrayToInt( data + INTSIZE, &ipHost) == INTSIZE );
+
+      PRINTF(0)("Got reconnection command from %i: reconnect!\n", senderId);
+      // handle it
+      if( SharedNetworkData::getInstance()->getHostID() == userId)
+      {
+        if( SharedNetworkData::getInstance()->isClient())
+          SharedNetworkData::getInstance()->getDefaultSyncStream()->softReconnectToServer(userId, IP(ipHost, 9999));
+        else
+          SharedNetworkData::getInstance()->getDefaultSyncStream()->prepareSoftConnection(userId);
+      }
+      break;
+    }
+    default:
+      PRINTF(0)("Command not known with id %i\n", type);
+  }
+
+
+
+  return true;
+}
+
Index: branches/heathaze/src/lib/network/proxy/proxy_control.h
===================================================================
--- branches/heathaze/src/lib/network/proxy/proxy_control.h	(revision 9940)
+++ branches/heathaze/src/lib/network/proxy/proxy_control.h	(revision 9940)
@@ -0,0 +1,65 @@
+/*!
+ * @file player_stats.h
+ * @brief Definition of ProxyControl
+ *
+ * manages the clients on the proxies (connect/disconnect)
+ */
+
+#ifndef _PROXY_SETTINGS_H
+#define _PROXY_SETTINGS_H
+
+#include "synchronizeable.h"
+#include "message_manager.h"
+
+#include <string>
+#include <list>
+
+
+typedef enum proxyCommand {
+  PXY_RECONNECT              = 0,              //!< forces a reconnection of the node
+
+  PXY_WEAKUP,                                  //!< signal to weakup a sleeping proxy server (not impl. yet)
+  PXY_SLEEP,                                   //!< signal to sleep and disconnect clients
+
+  PXY_NUMBER
+};
+
+
+
+//! A class for storing player information
+class ProxyControl : public Synchronizeable
+{
+  ObjectListDeclaration(ProxyControl);
+  public:
+    inline static ProxyControl* getInstance() { if (!ProxyControl::singletonRef) ProxyControl::singletonRef = new ProxyControl();
+      return ProxyControl::singletonRef; }
+    virtual ~ProxyControl();
+
+    virtual void varChangeHandler( std::list<int> & id );
+
+    /* connection signal handling */
+    void signalNewClient(int userId);
+    static bool messageHandlerNewClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+
+    void signalLeaveClient(int userId);
+    static bool messageHandlerLeaveClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+
+    /* proxy server network control */
+    void forceReconnectionShellThumb();
+    void forceReconnectionShell(int userId, int serverId);
+    void forceReconnection(int userId, int serverId);
+    void forceReconnection(int userId, int serverId, IP newAddress);
+    void forceReconnection(int userId, const std::string& newAddress);
+    static bool messageHandlerCommand( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+
+  private:
+    ProxyControl();
+
+
+  private:
+    static ProxyControl*      singletonRef;            //!< Pointer to the only instance of this Class
+
+
+};
+
+#endif /* _PROXY_SETTINGS_H */
Index: branches/heathaze/src/lib/network/server_socket.cc
===================================================================
--- branches/heathaze/src/lib/network/server_socket.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/server_socket.cc	(revision 9940)
@@ -0,0 +1,37 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer:
+*/
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+
+/* include your own header */
+#include "server_socket.h"
+
+ObjectListDefinition(ServerSocket);
+/**
+ * constructor
+ * @param port port to assign to socket
+ */
+ServerSocket::ServerSocket( int port )
+{
+  bOk = true;
+}
+
+ServerSocket::~ ServerSocket( )
+{
+}
Index: branches/heathaze/src/lib/network/server_socket.h
===================================================================
--- branches/heathaze/src/lib/network/server_socket.h	(revision 9940)
+++ branches/heathaze/src/lib/network/server_socket.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file server_socket.h
+ * waits for incoming connections and handles them.
+ *
+ */
+
+#ifndef _SERVER_SOCKET
+#define _SERVER_SOCKET
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+#include "network_socket.h"
+
+
+class ServerSocket : public BaseObject
+{
+  ObjectListDeclaration(ServerSocket);
+  public:
+    ServerSocket( int port);
+
+    virtual ~ServerSocket();
+
+    virtual bool listen( unsigned int port ) = 0;
+    virtual NetworkSocket* getNewSocket( void ) = 0;
+    virtual void close() = 0;
+    virtual void update() = 0;
+    virtual bool isOk() { return this->bOk; };
+
+  protected:
+    bool bOk;
+
+};
+
+#endif
Index: branches/heathaze/src/lib/network/shared_network_data.cc
===================================================================
--- branches/heathaze/src/lib/network/shared_network_data.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/shared_network_data.cc	(revision 9940)
@@ -0,0 +1,83 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+
+#define DEBUG_MODULE_NETWORK
+
+#include "shared_network_data.h"
+#include "netdefs.h"
+#include "state.h"
+
+#include "network_stream.h"
+
+#include "debug.h"
+
+
+ObjectListDefinition(SharedNetworkData);
+SharedNetworkData* SharedNetworkData::singletonRef = NULL;
+
+/**
+ * Standard constructor
+ */
+SharedNetworkData::SharedNetworkData()
+{
+  /* set the class id for the base object */
+  this->registerObject(this, SharedNetworkData::_objectList);
+
+  this->nodeType = NET_MASTER_SERVER;
+  this->hostID = -1;
+  this->defaultSyncStream = NULL;
+
+  // setUniqueID( maxCon+2 ) because we need one id for every handshake
+  // and one for handshake to reject client maxCon+1
+  this->newUniqueID = 2;
+}
+
+
+/**
+ * Standard destructor
+ */
+SharedNetworkData::~SharedNetworkData()
+{
+  SharedNetworkData::singletonRef = NULL;
+}
+
+
+
+/** @return true if this user is connected to the local host */
+bool SharedNetworkData::isUserLocal( int userID)
+{
+  return this->defaultSyncStream->isUserLocal(userID);
+}
+
+
+/** @returns true if this user is a master server */
+bool SharedNetworkData::isUserMasterServer( int userID )
+{
+  return this->defaultSyncStream->isUserMasterServer(userID);
+}
+
+
+/** @returns true if this user is a proxy server */
+bool SharedNetworkData::isUserProxyServerActive( int userID )
+{
+   return this->defaultSyncStream->isUserProxyServerActive(userID);
+}
+
+
+/** @returns true if this user is a client */
+bool SharedNetworkData::isUserClient( int userID )
+{
+  return this->defaultSyncStream->isUserClient(userID);
+}
Index: branches/heathaze/src/lib/network/shared_network_data.h
===================================================================
--- branches/heathaze/src/lib/network/shared_network_data.h	(revision 9940)
+++ branches/heathaze/src/lib/network/shared_network_data.h	(revision 9940)
@@ -0,0 +1,91 @@
+/*!
+ * @file shared_network_data.h
+ *  some shared data from the NetworkManager
+ */
+
+#ifndef _SHARED_NETWORK_DATA
+#define _SHARED_NETWORK_DATA
+
+#include "base_object.h"
+#include "netdefs.h"
+#include "proxy/network_settings.h"
+
+//!< maximal connectinons for the server
+#define NET_MAX_CONNECTIONS 2
+
+
+class Synchronizeable;
+class NetworkMonitor;
+
+
+/* and here is the class itsself*/
+class SharedNetworkData : public BaseObject
+{
+  ObjectListDeclaration(SharedNetworkData);
+  public:
+    inline static SharedNetworkData* getInstance() { if (!SharedNetworkData::singletonRef) SharedNetworkData::singletonRef = new SharedNetworkData();
+      return SharedNetworkData::singletonRef; }
+    virtual ~SharedNetworkData();
+
+    /** @returns the next uniqueID free for an object */
+    inline int getNewUniqueID() { return ( isMasterServer())?this->newUniqueID++:-1; }
+    /** sets the @param newUniqueID: the new offset for the next unique id */
+    inline void setNewUniqueID(int newUniqueID) { this->newUniqueID = newUniqueID; }
+
+    /** sets the game server flag @param bGameServer true if it is a game server */
+    inline void setNodeType(int nodeType) { this->nodeType = nodeType; }
+    /** @returns true is this node is a master server */
+    inline bool isMasterServer() { return this->nodeType == NET_MASTER_SERVER; }
+    /** @returns true is this node is a proxy server */
+    inline bool isProxyServerActive() { return this->nodeType == NET_PROXY_SERVER_ACTIVE; }
+    /** @returns true is this node is a client*/
+    inline bool isClient() { return this->nodeType == NET_CLIENT; }
+
+    /** @return true if this user is connected to the local host */
+    bool isUserLocal( int userID);
+    /** @returns true if this user is a master server */
+    bool isUserMasterServer( int userID );
+    /** @returns true if this user is a proxy server */
+    bool isUserProxyServerActive( int userID );
+    /** @returns true if this user is a client */
+    bool isUserClient( int userID );
+
+
+    /** @returns the maximum number of players for this server */
+    inline int getMaxPlayer() { return NetworkSettings::getInstance()->getMaxPlayer(); }
+
+    /** @returns the hostID of the node */
+    inline int getHostID() { return this->hostID; }
+    /** sets the hostID of this node @param hostID of the node */
+    inline void setHostID(int hostID) { this->hostID = hostID; }
+
+    /** @returns the default synchronize stream */
+    inline NetworkStream* getDefaultSyncStream() { return this->defaultSyncStream; }
+    /** sets the default sync stream @param defaultSyncStream the default sync stream */
+    inline void setDefaultSyncStream(NetworkStream* defaultSyncStream) { this->defaultSyncStream = defaultSyncStream; }
+
+    /** @returns the network monitor reference */
+    inline NetworkMonitor* getNetworkMonitor() { return this->networkMonitor; }
+    /** @param networkMonitor sets the NetworkMonitor reference */
+    inline void setNetworkMonitor( NetworkMonitor* networkMonitor) { this->networkMonitor = networkMonitor; }
+
+
+  private:
+    SharedNetworkData();
+
+
+  private:
+    int                             newUniqueID;             //!< next uniqueID
+    int                             nodeType;                //!< saves the node type here
+
+    int                             hostID;                  //!< The Host-ID of the Manager
+    NetworkStream*                  defaultSyncStream;       //!< default synchronize NetworkStream
+    NetworkMonitor*                 networkMonitor;          //!< reference to the NetworkMonitor
+
+    static SharedNetworkData*       singletonRef;            //!< Pointer to the only instance of this Class
+
+};
+
+
+
+#endif /* _SHARED_NETWORK_DATA */
Index: branches/heathaze/src/lib/network/synchronizeable.cc
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable.cc	(revision 9940)
@@ -0,0 +1,723 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+
+### File Specific:
+   main-programmer: Christoph Renner (rennerc@ee.ethz.ch)
+   co-programmer: Patrick Boenzli (patrick@orxonox.ethz.ch)
+*/
+
+#define DEBUG_MODULE_NETWORK
+
+#include "shared_network_data.h"
+#include "network_stream.h"
+#include "netdefs.h"
+#include "network_log.h"
+#include "network_game_manager.h"
+
+#include "state.h"
+
+#include <cassert>
+
+#include "synchronizeable.h"
+
+#include "converter.h"
+
+
+ObjectListDefinition(Synchronizeable);
+
+/**
+ *  default constructor
+ */
+Synchronizeable::Synchronizeable()
+{
+  this->registerObject(this, Synchronizeable::_objectList);
+  this->owner = 0;
+//   this->setIsServer(SharedNetworkData::getInstance()->getHostID() == 0);
+  this->uniqueID = NET_UID_UNASSIGNED;
+  this->networkStream = NULL;
+  this->bSynchronize = false;
+
+  if( State::isOnline())
+  {
+    NetworkStream* nd = SharedNetworkData::getInstance()->getDefaultSyncStream();
+    assert(nd != NULL);
+    nd->connectSynchronizeable(*this);
+    this->setUniqueID(SharedNetworkData::getInstance()->getNewUniqueID());
+  }
+
+  /* make sure loadClassId is first synced var because this is read by networkStream */
+  assert( syncVarList.size() == 0 );
+  mLeafClassId = this->registerVarId( new SynchronizeableInt( (int*)&this->getLeafClassID(), (int*)&this->getLeafClassID(), "leafClassId", PERMISSION_MASTER_SERVER) );
+
+  this->registerVar( new SynchronizeableInt( &this->owner, &this->owner, "owner", PERMISSION_MASTER_SERVER ) );
+  this->registerVar( new SynchronizeableString( &this->objectName, &this->objectName, "objectName", PERMISSION_MASTER_SERVER ) );
+}
+
+
+
+/**
+ *  default destructor deletes all unneded stuff
+ */
+Synchronizeable::~Synchronizeable()
+{
+  if ( this->networkStream )
+  {
+    this->networkStream->disconnectSynchronizeable(*this);
+
+    // remove the message manager only by the server
+    if ( (SharedNetworkData::getInstance()->isMasterServer() )
+	  && this->beSynchronized() && this->getUniqueID() > 0 && !this->isA( MessageManager::staticClassID() ) )
+      NetworkGameManager::getInstance()->removeSynchronizeable( this->getUniqueID() );
+  }
+
+  for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
+  {
+    delete *it;
+  }
+  syncVarList.clear();
+
+  for ( UserStateHistory::iterator it = recvStates.begin(); it != recvStates.end(); it++ )
+  {
+    for ( StateHistory::iterator it2 = it->begin(); it2 != it->end(); it2++ )
+    {
+      if ( (*it2)->data )
+      {
+        delete [] (*it2)->data;
+        (*it2)->data = NULL;
+      }
+      delete *it2;
+    }
+
+  }
+
+  for ( UserStateHistory::iterator it = sentStates.begin(); it != sentStates.end(); it++ )
+  {
+    for ( StateHistory::iterator it2 = it->begin(); it2 != it->end(); it2++ )
+    {
+      if ( (*it2)->data )
+      {
+        delete [] (*it2)->data;
+        (*it2)->data = NULL;
+      }
+      delete *it2;
+    }
+  }
+}
+
+
+
+/**
+ * creates a diff image from two states
+ * @param userId: the userid of the user where the image will be sent to
+ * @param data: the binary data array to write to
+ * @param maxLength: maximal length of the data written (length of available space in the array)
+ * @param stateId: the state id that this diff will represent
+ * @param priorityTH: the priority threshold: all syncs below this threshold won't be synchronized
+ *
+ * @todo check for permissions
+ */
+int Synchronizeable::getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH )
+{
+  // make sure this user has his history or resize for new clients
+  if ( (int)sentStates.size() <= userId )
+    sentStates.resize( userId+1 );
+
+  //calculate needed memory
+  int neededSize = 0;
+
+  // calculate the needed space for network packet by summing up
+  for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
+  {
+    //PRINTF(0)("SIZE = %d %s\n", (*it)->getSize(), (*it)->getName().c_str());
+    neededSize += (*it)->getSize();
+  }
+
+  if ( !( neededSize <= maxLength ) )
+  {
+    PRINTF(0)( "%d > %d\n", neededSize, maxLength );
+    assert(false);
+  }
+
+  //remove older states from history than fromStateId
+  StateHistory::iterator it = sentStates[userId].begin();
+
+  while ( it != sentStates[userId].end() && (*it)->stateId < fromStateId )
+    it++;
+
+  if ( it != sentStates[userId].begin() )
+  {
+    for ( StateHistory::iterator it2 = sentStates[userId].begin(); it2 != it; it2++ )
+    {
+      if ( (*it2)->data != NULL )
+      {
+        delete [] (*it2)->data;
+        (*it2)->data = NULL;
+      }
+
+      delete *it2;
+    }
+    sentStates[userId].erase( sentStates[userId].begin(), it );
+  }
+
+  //find state to create diff from
+  StateHistoryEntry * stateFrom = NULL;
+
+  it = sentStates[userId].begin();
+  while ( it != sentStates[userId].end() && (*it)->stateId != fromStateId )
+    it++;
+
+  if ( it == sentStates[userId].end() )
+  {
+    StateHistoryEntry * initialEntry = new StateHistoryEntry();
+
+    initialEntry->stateId = fromStateId;
+    initialEntry->dataLength = 0;
+    initialEntry->data = NULL;
+
+    stateFrom = initialEntry;
+
+    sentStates[userId].push_back( stateFrom );
+  }
+  else
+    stateFrom = (*it);
+
+  StateHistoryEntry * stateTo = new StateHistoryEntry;
+
+  sentStates[userId].push_back( stateTo );
+
+  stateTo->stateId = stateId;
+  stateTo->dataLength = neededSize;
+  stateTo->data = new byte[ neededSize ];
+
+  std::list<int>::iterator sizeIter = stateFrom->sizeList.begin();
+
+  int i = 0;
+  int n;
+
+  bool sizeChanged = false;
+
+  // now do the actual synchronization: kick all variables to write into a common buffer
+  for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
+  {
+
+    ////////////////////////////////
+    // Data SENDING Permissions
+    ////////////////////////////////
+    bool hasPermission = false;
+    bool b1, b2, b3, b4, b5, b6, b7, b8, b9;
+    b1 = b2 = b3 = b4 = b5 = b6 = b7 = b8 = b9 = false;
+
+
+    // Permission   OWNER accept if:
+    // I am the owner
+    if(       (*it)->checkPermission( PERMISSION_OWNER ) && this->owner == SharedNetworkData::getInstance()->getHostID()) {
+      hasPermission = true; b1 = true; }
+    // reciever != owner && owner is local
+    else if(  (*it)->checkPermission( PERMISSION_OWNER ) && userId != this->owner &&
+                (SharedNetworkData::getInstance()->isUserLocal(this->owner) || this->owner == SharedNetworkData::getInstance()->getHostID())) {
+      hasPermission = true; b2 = true; }
+
+
+    // Permission   MASTER_SERVER accept if:
+    // im MASTER_SERVER
+    else if( (*it)->checkPermission( PERMISSION_MASTER_SERVER ) && SharedNetworkData::getInstance()->isMasterServer()) {
+      hasPermission = true; b3 = true; }
+    // im PROXY_SERVER && reciever == CLIENT
+    else if( (*it)->checkPermission( PERMISSION_MASTER_SERVER ) && SharedNetworkData::getInstance()->isProxyServerActive() &&
+               SharedNetworkData::getInstance()->isUserClient( userId)) {
+      hasPermission = true;  b4 = true; }
+
+
+    // Pemission    SERVER accept if:
+    // i am server && reciever == CLIENT
+    else if( (*it)->checkPermission( PERMISSION_SERVER ) && !SharedNetworkData::getInstance()->isClient() &&
+               SharedNetworkData::getInstance()->isUserClient( userId)) {
+      hasPermission = true; b5 = true; }
+    // i am SERVER && reciever == SERVER && reciever != owner && ( owner is local || i am owner)
+    else if( (*it)->checkPermission( PERMISSION_SERVER ) && !SharedNetworkData::getInstance()->isClient() &&
+               userId != this->owner &&
+               ( SharedNetworkData::getInstance()->isUserLocal( this->owner) || this->owner ==  SharedNetworkData::getInstance()->getHostID())) {
+      hasPermission = true; b6 = true; }
+
+
+    // Permission   ALL accept if:
+    else if( (*it)->checkPermission( PERMISSION_ALL )) {
+      hasPermission = true; b7 = true; }
+    // or else refuse sending data
+    else
+      hasPermission = false;
+
+
+
+    if ( sizeIter == stateFrom->sizeList.end() || *sizeIter != (*it)->getSize() )
+      sizeChanged = true;
+
+    if ( ( hasPermission && (*it)->getPriority() >= priorityTH ) || sizeChanged )
+    {
+      n = (*it)->writeToBuf( stateTo->data+i, stateTo->dataLength - i );
+      //NETPRINTF(0)("getvar %s %d\n", (*it)->getName().c_str(), n);
+//       PRINTF(0)("sending %s %d\n", (*it)->getName().c_str(), n);
+
+//       if( this->isA(CL_PLAYABLE))
+//       {
+//         PRINTF(0)("ms: %i, ps: %i, c: %i, sender: %i, reciever: %i, owner: %i, perm: (ow %i, ms %i, s %i, a %i)\n",
+//         SharedNetworkData::getInstance()->isMasterServer(), SharedNetworkData::getInstance()->isProxyServerActive(), SharedNetworkData::getInstance()->isClient(),
+//         SharedNetworkData::getInstance()->getHostID(), userId, this->owner,
+//         (*it)->checkPermission( PERMISSION_OWNER ), (*it)->checkPermission( PERMISSION_MASTER_SERVER ),
+//         (*it)->checkPermission( PERMISSION_SERVER ), (*it)->checkPermission( PERMISSION_ALL ));
+//         PRINTF(0)("hasPermission: %i, sizeChanged: %i, eval: %i, %i, %i, %i, %i, %i, %i\n", hasPermission, sizeChanged, b1, b2, b3, b4, b5, b6, b7);
+//         PRINTF(0)("sending %s %s %d\n", this->getClassCName(), (*it)->getName().c_str(), n);
+//       }
+
+
+      stateTo->sizeList.push_back( n );
+      // this is only for very hardcore debug sessions
+      // (*it)->debug();
+      i += n;
+    }
+    else
+    {
+      for ( int j = 0; j<(*sizeIter); j++ )
+      {
+        assert( i < stateFrom->dataLength );
+        stateTo->data[i] = stateFrom->data[i];
+        i++;
+      }
+      //NETPRINTF(0)("getvar %s %d\n", (*it)->getName().c_str(), *sizeIter);
+      stateTo->sizeList.push_back( (*sizeIter) );
+    }
+
+    if ( sizeIter != stateFrom->sizeList.end() )
+      sizeIter++;
+  }
+
+  if ( i != neededSize )
+  {
+    PRINTF(0)("strange error: (%s) %d != %d\n", this->getClassCName(), i, neededSize);
+    assert(false);
+  }
+
+  //write diff to data
+  for ( i = 0; i<neededSize; i++ )
+  {
+    if ( i < stateFrom->dataLength )
+      data[i] = stateTo->data[i] - stateFrom->data[i];
+    else
+      data[i] = stateTo->data[i];
+  }
+
+  return neededSize;
+}
+
+/**
+ * sets a new state out of a diff created on another host (recieving data)
+ * @param userId hostId of user who send me that diff
+ * @param data pointer to diff
+ * @param length length of diff
+ * @param stateId id of current state
+ * @param fromStateId id of the base state id
+ * @return number bytes read
+ *
+ * @todo check for permissions
+ */
+int Synchronizeable::setStateDiff( int userId, byte* data, int length, int stateId, int fromStateId )
+{
+  //make sure this user has his history
+  if ( (int)recvStates.size() <= userId )
+    recvStates.resize( userId+1 );
+
+  //create new state
+  StateHistoryEntry * stateTo = new StateHistoryEntry();
+  stateTo->stateId = stateId;
+  stateTo->dataLength = length;
+  stateTo->data = new byte[ length ];
+
+
+  //find state to apply diff to
+  StateHistoryEntry * stateFrom = NULL;
+
+  // search the state from wich the diff is made of
+  StateHistory::iterator it = recvStates[userId].begin();
+  while ( it != recvStates[userId].end() && (*it)->stateId != fromStateId )
+    it++;
+
+  // if this is the first state to receive
+  if ( it == recvStates[userId].end() )
+  {
+    StateHistoryEntry * initialEntry = new StateHistoryEntry();
+
+    initialEntry->stateId = fromStateId;
+    initialEntry->dataLength = 0;
+    initialEntry->data = NULL;
+
+    stateFrom = initialEntry;
+
+    recvStates[userId].push_back( stateFrom );
+  }
+  else
+    stateFrom = (*it);
+
+
+  // apply diff
+  for ( int i = 0; i<length; i++ )
+  {
+    if ( i < stateFrom->dataLength )
+      stateTo->data[i] = stateFrom->data[i] + data[i];
+    else
+      stateTo->data[i] = data[i];
+  }
+
+  //add state to state history
+  recvStates[userId].push_back( stateTo );
+
+  int i = 0;
+  int n = 0;
+  std::list<int> changes;
+
+  // extract the new state for every client
+  for ( SyncVarList::iterator it = syncVarList.begin(); it != syncVarList.end(); it++ )
+  {
+    // DATA PERMISSIONS
+    // check if this synchronizeable has the permissions to write the data
+
+    bool hasPermission = false;
+    bool b1, b2, b3, b4, b5, b6, b7, b8, b9;
+    b1 = b2 = b3 = b4 = b5 = b6 = b7 = b8 = b9 = false;
+
+    ////////////////////////////////
+    // Data RECIEVING Permissions
+    ////////////////////////////////
+
+    // i should never ever receive a state update from a synchronizeable, that belongs to me! If it does somethings wrong with the send rules
+//     assert(   !((*it)->checkPermission( PERMISSION_OWNER ) && this->owner == SharedNetworkData::getInstance()->getHostID()));
+
+
+    // Permission   OWNER accept if:
+    // sender == owner
+    if(      (*it)->checkPermission( PERMISSION_OWNER ) && this->owner == userId) {
+      hasPermission = true; b1 = true; }
+    // sender == MASTER_SERVER
+    else if( (*it)->checkPermission( PERMISSION_OWNER ) && SharedNetworkData::getInstance()->isUserMasterServer( userId)
+               && this->owner != SharedNetworkData::getInstance()->getHostID()) {
+      hasPermission = true; b2 = true; }
+    // sender == PROXY_SERVER
+      else if( (*it)->checkPermission( PERMISSION_OWNER ) && SharedNetworkData::getInstance()->isUserProxyServerActive( userId) &&
+                 this->owner != SharedNetworkData::getInstance()->getHostID()) {
+        hasPermission = true; b3 = true; }
+
+
+
+    // Permission   MASTER_SERVER accept if:
+    // sender == MASTER_SERVER
+    else if( (*it)->checkPermission( PERMISSION_MASTER_SERVER) && SharedNetworkData::getInstance()->isUserMasterServer( userId)) {
+      hasPermission = true; b4 = true; }
+    // sender == PROXY_SERVER && im not MASTER_SERVER && im not PROXY_SERVER
+    else if( (*it)->checkPermission( PERMISSION_MASTER_SERVER) && SharedNetworkData::getInstance()->isClient() &&
+               SharedNetworkData::getInstance()->isUserProxyServerActive( userId)) {
+      hasPermission = true; b5 = true; }
+
+    // Permission   SERVER accept if:
+    // sender == SERVER
+    else if( (*it)->checkPermission( PERMISSION_SERVER ) && !SharedNetworkData::getInstance()->isUserClient( userId) /*&&
+               SharedNetworkData::getInstance()->isClient()*/) {
+      hasPermission = true; b6 = true; }
+
+
+
+    // Pemission    ALL accept if:
+    else if(  (*it)->checkPermission( PERMISSION_ALL )) {
+      hasPermission = true; b8 = true; }
+
+
+   // no rights to over-write local data
+    else
+      hasPermission = false;
+
+
+
+    // if it has the permission to write do it
+    if( hasPermission)
+    {
+      n = (*it)->readFromBuf( stateTo->data + i, stateTo->dataLength - i );
+      i += n;
+      //NETPRINTF(0)("%s::setvar %s %d\n", getClassCName(), (*it)->getName().c_str(), n);
+//       PRINTF(0)("recieving: %s %d\n",  (*it)->getName().c_str(), n);
+      //(*it)->debug();
+
+//       if( this->isA(CL_PLAYABLE))
+//       {
+//         PRINTF(0)("ms: %i, ps: %i, c: %i, sender: %i, reciever: %i, owner: %i, perm: (ow %i, ms %i, s %i, a %i)\n",
+//         SharedNetworkData::getInstance()->isMasterServer(), SharedNetworkData::getInstance()->isProxyServerActive(), SharedNetworkData::getInstance()->isClient(),
+//         userId, SharedNetworkData::getInstance()->getHostID(), this->owner,
+//         (*it)->checkPermission( PERMISSION_OWNER ), (*it)->checkPermission( PERMISSION_MASTER_SERVER ),
+//         (*it)->checkPermission( PERMISSION_SERVER ), (*it)->checkPermission( PERMISSION_ALL ));
+//         PRINTF(0)("hasPermission: %i, eval: %i, %i, %i, %i, %i, %i, %i, %i\n", hasPermission, b1, b2, b3, b4, b5, b6, b7, b8);
+//         PRINTF(0)("rec %s %s %d\n", this->getClassCName(), (*it)->getName().c_str(), n);
+//       }
+
+
+      if ( (*it)->getHasChanged() )
+      {
+        changes.push_back( (*it)->getVarId() );
+      }
+    }
+    else
+    {
+//       PRINTF(0)("DONT SET VAR BECAUSE OF PERMISSION: %s perm: %d %d %d - %d %d %d\n", (*it)->getName().c_str(), (*it)->checkPermission( PERMISSION_MASTER_SERVER ), (*it)->checkPermission( PERMISSION_OWNER ), (*it)->checkPermission( PERMISSION_ALL ), networkStream->isUserMasterServer( userId ), this->owner, userId );
+      n = (*it)->getSizeFromBuf( stateTo->data + i, stateTo->dataLength - i );
+      //NETPRINTF(0)("%s::setvar %s %d\n", getClassCName(), (*it)->getName().c_str(), n);
+      //(*it)->debug();
+      i += n;
+    }
+  }
+
+  this->varChangeHandler( changes );
+
+  return i;
+}
+
+ /**
+ * override this function to be notified on change
+ * of your registred variables.
+ * @param id id's which have changed
+ */
+void Synchronizeable::varChangeHandler( std::list<int> & id )
+{
+}
+
+/**
+ * registers a varable to be synchronized over network
+ * @param var see src/lib/network/synchronizeable_var/ for available classes
+ */
+void Synchronizeable::registerVar( SynchronizeableVar * var )
+{
+  syncVarList.push_back( var );
+}
+
+/**
+ * registers a varable to be synchronized over network
+ * return value is passed to varChangeHandler on change
+ * @param var see src/lib/network/synchronizeable_var/ for available classes
+ * @return handle passed to varChangeHandler on changes
+ */
+int Synchronizeable::registerVarId( SynchronizeableVar * var )
+{
+  syncVarList.push_back( var );
+  var->setWatched( true );
+  var->setVarId( syncVarList.size()-1 );
+  return syncVarList.size()-1;
+}
+
+/**
+ * removed user's states from memory
+ * @param userId user to clean
+ */
+void Synchronizeable::cleanUpUser( int userId )
+{
+  if ( (int)recvStates.size() > userId )
+  {
+    for ( std::list<StateHistoryEntry*>::iterator it = recvStates[userId].begin(); it != recvStates[userId].end(); it++ )
+    {
+      if ( (*it)->data )
+      {
+        delete [] (*it)->data;
+        (*it)->data = NULL;
+      }
+
+      delete *it;
+    }
+    recvStates[userId].clear();
+  }
+
+  if ( (int)sentStates.size() > userId )
+  {
+
+    for ( std::list<StateHistoryEntry*>::iterator it = sentStates[userId].begin(); it != sentStates[userId].end(); it++ )
+    {
+      if ( (*it)->data )
+      {
+        delete [] (*it)->data;
+        (*it)->data = NULL;
+      }
+
+      delete *it;
+    }
+    sentStates[userId].clear();
+  }
+}
+
+/**
+ * this function is called after recieving a state.
+ * @param userId
+ * @param stateId
+ * @param fromStateId
+ */
+void Synchronizeable::handleRecvState( int userId, int stateId, int fromStateId )
+{
+   //make sure this user has his history
+  if ( (int)recvStates.size() <= userId )
+    recvStates.resize( userId+1 );
+
+  //remove old states
+  StateHistory::iterator it = recvStates[userId].begin();
+
+#if 0
+  while ( it != recvStates[userId].end() && (*it)->stateId < fromStateId )
+    it++;
+
+  if ( it != recvStates[userId].begin() )
+  {
+    for ( StateHistory::iterator it2 = recvStates[userId].begin(); it2 != it; it2++ )
+    {
+      if ( (*it2)->data != NULL )
+      {
+        delete [] (*it2)->data;
+        (*it2)->data = NULL;
+      }
+    }
+    recvStates[userId].erase( recvStates[userId].begin(), it );
+  }
+#endif
+
+  for ( it = recvStates[userId].begin(); it != recvStates[userId].end();  )
+  {
+    if ( (*it)->stateId < fromStateId )
+    {
+      StateHistory::iterator delIt = it;
+      it ++;
+
+      if ( (*delIt)->data )
+      {
+        delete [] (*delIt)->data;
+        (*delIt)->data = NULL;
+      }
+      delete *delIt;
+      recvStates[userId].erase( delIt );
+
+      continue;
+    }
+    it++;
+  }
+
+  StateHistory::iterator fromState = recvStates[userId].end();
+  StateHistory::iterator toState = recvStates[userId].end();
+
+  for ( it = recvStates[userId].begin(); it != recvStates[userId].end(); it++ )
+  {
+    if ( (*it)->stateId == stateId )
+      toState = it;
+    if ( (*it)->stateId == fromStateId )
+      fromState = it;
+
+    if ( fromState != recvStates[userId].end() && toState != recvStates[userId].end() )
+      break;
+  }
+
+  // setStateDiff was not called and i know fromStateId
+  if ( fromState != recvStates[userId].end() && toState == recvStates[userId].end() )
+  {
+    StateHistoryEntry * entry = new StateHistoryEntry;
+
+    entry->dataLength = (*fromState)->dataLength;
+    if ( entry->dataLength > 0 )
+    {
+      entry->data = new byte[entry->dataLength];
+
+      assert( (*fromState)->data );
+      memcpy( entry->data, (*fromState)->data, entry->dataLength );
+    }
+    else
+      entry->data = NULL;
+
+    entry->sizeList = (*fromState)->sizeList;
+    entry->stateId = stateId;
+
+    recvStates[userId].push_back(entry);
+  }
+}
+
+/**
+ * this function is called after sending a state
+ * @param userId
+ * @param stateId
+ * @param fromStateId
+ */
+void Synchronizeable::handleSentState( int userId, int stateId, int fromStateId )
+{
+   //make sure this user has his history
+  if ( (int)sentStates.size() <= userId )
+    sentStates.resize( userId+1 );
+
+   //remove old states
+  StateHistory::iterator it = sentStates[userId].begin();
+
+  for ( it = sentStates[userId].begin(); it != sentStates[userId].end();  )
+  {
+    if ( (*it)->stateId < fromStateId )
+    {
+      StateHistory::iterator delIt = it;
+      it ++;
+
+      if ( (*delIt)->data )
+      {
+        delete [] (*delIt)->data;
+        (*delIt)->data = NULL;
+      }
+      delete *delIt;
+      sentStates[userId].erase( delIt );
+
+      continue;
+    }
+    it++;
+  }
+
+
+  StateHistory::iterator fromState = sentStates[userId].end();
+  StateHistory::iterator toState = sentStates[userId].end();
+
+  for ( it = sentStates[userId].begin(); it != sentStates[userId].end(); it++ )
+  {
+    if ( (*it)->stateId == stateId )
+      toState = it;
+    if ( (*it)->stateId == fromStateId )
+      fromState = it;
+
+    if ( fromState != sentStates[userId].end() && toState != sentStates[userId].end() )
+      break;
+  }
+
+
+  // getStateDiff was not called and i know fromStateId
+  if ( fromState != sentStates[userId].end() && toState == sentStates[userId].end() )
+  {
+    StateHistoryEntry * entry = new StateHistoryEntry;
+
+    entry->dataLength = (*fromState)->dataLength;
+    if ( entry->dataLength > 0 )
+    {
+      entry->data = new byte[entry->dataLength];
+
+      assert( (*fromState)->data );
+      memcpy( entry->data, (*fromState)->data, entry->dataLength );
+    }
+    else
+      entry->data = NULL;
+
+    entry->sizeList = (*fromState)->sizeList;
+    entry->stateId = stateId;
+
+    sentStates[userId].push_back(entry);
+  }
+
+}
+
+
+
Index: branches/heathaze/src/lib/network/synchronizeable.h
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable.h	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable.h	(revision 9940)
@@ -0,0 +1,91 @@
+/*!
+ * @file synchronizeable.h
+ * @brief interface for all classes that have to be synchronized
+ */
+
+#ifndef _SYNCHRONIZEABLE_H
+#define _SYNCHRONIZEABLE_H
+
+#include "base_object.h"
+
+#include "synchronizeable_var/synchronizeable_var.h"
+#include "synchronizeable_var/synchronizeable_vector.h"
+#include "synchronizeable_var/synchronizeable_quaternion.h"
+#include "synchronizeable_var/synchronizeable_string.h"
+#include "synchronizeable_var/synchronizeable_int.h"
+#include "synchronizeable_var/synchronizeable_float.h"
+#include "synchronizeable_var/synchronizeable_bool.h"
+#include "synchronizeable_var/synchronizeable_uint.h"
+#include "synchronizeable_var/synchronizeable_ip.h"
+
+#include <vector>
+#include <list>
+
+
+struct StateHistoryEntry
+{
+  int             stateId;
+  byte *          data;
+  int             dataLength;
+  std::list<int>  sizeList;
+};
+
+typedef std::list<StateHistoryEntry*> StateHistory;
+
+typedef std::vector<StateHistory> UserStateHistory;
+
+typedef std::vector<SynchronizeableVar*> SyncVarList;
+
+class NetworkStream;
+
+class Synchronizeable : virtual public BaseObject
+{
+  ObjectListDeclaration(Synchronizeable);
+
+  public:
+    Synchronizeable();
+    virtual ~Synchronizeable();
+
+    virtual void varChangeHandler( std::list<int> & id );
+
+    virtual int getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH );
+    virtual int setStateDiff( int userId, byte* data, int length, int stateId, int fromStateId );
+    virtual void cleanUpUser( int userId );
+    virtual void handleSentState( int userId, int stateId, int fromStateId );
+    virtual void handleRecvState( int userId, int stateId, int fromStateId );
+
+    void registerVar( SynchronizeableVar * var );
+    int registerVarId( SynchronizeableVar * var );
+
+    inline void setUniqueID( int id ){ uniqueID = id; }
+    inline int  getUniqueID() const { return uniqueID; }
+
+    inline int getOwner(){ return owner; }
+    inline void setOwner(int owner){ this->owner = owner; }
+
+    /** @returns true if this Synchronizeable wants to be synchronized over network */
+    inline bool beSynchronized() { return this->bSynchronize; }
+    /** @param bSynchronize sets the Synchronizeable to be sunchronized or not */
+    inline void setSynchronized(bool bSynchronize) { this->bSynchronize = bSynchronize; }
+
+    inline void setNetworkStream(NetworkStream* stream) { this->networkStream = stream; }
+    inline NetworkStream* getNetworkStream() { return this->networkStream; }
+
+
+  protected:
+    NetworkStream*    networkStream;  //!< reference network stream we are connected to
+
+
+  private:
+    int               uniqueID;       //!< unique id assigned to synchronizeable
+    int               mLeafClassId;   //!< store leafClassId to send via states
+    int               owner;          //!< hostId of owner ( 0 if none / server )
+    bool              bSynchronize;   //!< do we need beeing synchronized?
+
+    SyncVarList       syncVarList;    //!< list containing variables to synchronize
+
+    UserStateHistory  sentStates;     //!< store already sent states to create diffs from, offset corresponds to the user id
+    UserStateHistory  recvStates;     //!< store recieved states to apply diffs, offset corresponds to the user id
+
+};
+#endif /* _SYNCHRONIZEABLE_H */
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_bool.cc
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_bool.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_bool.cc	(revision 9940)
@@ -0,0 +1,80 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_bool.h"
+#include <cassert>
+
+
+/**
+ * standard constructor
+ */
+SynchronizeableBool::SynchronizeableBool( bool * ptrIn, bool * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, 1, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableBool::~SynchronizeableBool ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableBool::writeToBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= 1 );
+
+  buf[0] = ( *vPtrIn ) ? 1 : 0;
+
+  return 1;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableBool::readFromBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= 1 );
+
+  bool oldVal = *vPtrOut;
+
+  *vPtrOut = buf[0] != 0;
+
+  setHasChanged( oldVal != *vPtrOut );
+
+  return 1;
+}
+
+/**
+ * print out variable value
+ */
+void SynchronizeableBool::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: %d OUT: %d\n", name.c_str(), (int)*vPtrIn, (int)*vPtrOut );
+}
+
+
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_bool.h
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_bool.h	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_bool.h	(revision 9940)
@@ -0,0 +1,34 @@
+/*!
+ * @file synchronizeable_int.h
+ * @brief Definition of SynchronizeableInt
+ */
+
+#ifndef _SYNCHRONIZEABLE_BOOL_H
+#define _SYNCHRONIZEABLE_BOOL_H
+
+#include "synchronizeable_var.h"
+
+class SynchronizeableBool : public SynchronizeableVar {
+
+  public:
+    SynchronizeableBool( bool * ptrIn, bool * ptrOut, std::string name, int permission, int priority = 0 );
+    virtual ~SynchronizeableBool();
+
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return true; };
+
+    virtual void debug();
+
+  private:
+    bool * vPtrIn;       //!< pointer to data (read)
+    bool * vPtrOut;      //!< pointer to data (write)
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_float.cc
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_float.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_float.cc	(revision 9940)
@@ -0,0 +1,84 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_float.h"
+#include "converter.h"
+#include <cassert>
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+SynchronizeableFloat::SynchronizeableFloat( float * ptrIn, float * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, FLOATSIZE, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableFloat::~SynchronizeableFloat ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableFloat::writeToBuf( byte * buf, int maxLength )
+{
+  int res = Converter::floatToByteArray( *vPtrIn, buf, maxLength );
+
+  assert( res == FLOATSIZE );
+
+  return res;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableFloat::readFromBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= FLOATSIZE );
+
+  float oldVal = *vPtrOut;
+
+  int res = Converter::byteArrayToFloat( buf, vPtrOut );
+
+  setHasChanged( oldVal != *vPtrOut );
+
+  assert( res == FLOATSIZE );
+
+  return res;
+}
+
+
+/**
+ * print out variable value
+ */
+void SynchronizeableFloat::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: %f OUT: %f\n", name.c_str(), *vPtrIn, *vPtrOut );
+}
+
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_float.h
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_float.h	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_float.h	(revision 9940)
@@ -0,0 +1,35 @@
+/*!
+ * @file synchronizeable_float.h
+ * @brief Definition of SynchronizeableFloat
+ */
+
+
+#ifndef _SYNCHRONIZEABLE_FLOAT_H
+#define _SYNCHRONIZEABLE_FLOAT_H
+
+#include "synchronizeable_var.h"
+
+class SynchronizeableFloat : public SynchronizeableVar {
+
+  public:
+    SynchronizeableFloat( float * ptrIn, float * ptrOut, std::string name, int permission, int priority = 0 );
+    virtual ~SynchronizeableFloat();
+
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return true; };
+
+    virtual void debug();
+
+  private:
+    float * vPtrIn;       //!< pointer to data (read)
+    float * vPtrOut;      //!< pointer to data (write)
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_int.cc
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_int.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_int.cc	(revision 9940)
@@ -0,0 +1,84 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_int.h"
+#include "converter.h"
+
+#include <cassert>
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+SynchronizeableInt::SynchronizeableInt( int * ptrIn, int * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, INTSIZE, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableInt::~SynchronizeableInt ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableInt::writeToBuf( byte * buf, int maxLength )
+{
+  int res = Converter::intToByteArray( *vPtrIn, buf, maxLength );
+
+  assert( res == INTSIZE );
+
+  return res;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableInt::readFromBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= INTSIZE );
+
+  int oldVal = *vPtrOut;
+
+  int res = Converter::byteArrayToInt( buf, vPtrOut );
+
+  setHasChanged( oldVal != *vPtrOut );
+
+  assert( res == INTSIZE );
+
+  return res;
+}
+
+
+/**
+ * print out variable value
+ */
+void SynchronizeableInt::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: %d OUT: %d\n", name.c_str(), *vPtrIn, *vPtrOut );
+}
+
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_int.h
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_int.h	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_int.h	(revision 9940)
@@ -0,0 +1,36 @@
+/*!
+ * @file synchronizeable_int.h
+ * @brief Definition of SynchronizeableInt
+*/
+
+
+#ifndef _SYNCHRONIZEABLE_INT_H
+#define _SYNCHRONIZEABLE_INT_H
+
+#include "synchronizeable_var.h"
+
+class SynchronizeableInt : public SynchronizeableVar {
+
+  public:
+    SynchronizeableInt( int * ptrIn, int * ptrOut, std::string name, int permission, int priority = 0 );
+    virtual ~SynchronizeableInt();
+
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return true; };
+
+    virtual void debug();
+
+  protected:
+    int * vPtrIn;       //!< pointer to data (read)
+    int * vPtrOut;      //!< pointer to data (write)
+
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_ip.cc
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_ip.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_ip.cc	(revision 9940)
@@ -0,0 +1,108 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+
+#include "synchronizeable_ip.h"
+#include "converter.h"
+#include "netdefs.h"
+#include "ip.h"
+#include <cassert>
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+SynchronizeableIP::SynchronizeableIP( IP * ptrIn, IP * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, 2*INTSIZE, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableIP::~SynchronizeableIP ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableIP::writeToBuf( byte * buf, int maxLength )
+{
+  int n = 0;
+  int res;
+
+  res = Converter::intToByteArray( (int)vPtrIn->host(), buf, maxLength );
+  assert(res > 0);
+  n += res;
+
+
+  res = Converter::intToByteArray( (int)vPtrIn->port(), buf + n, maxLength);
+  assert(res > 0);
+  n += res;
+
+  assert( 2 * INTSIZE == n);
+
+  return n;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableIP::readFromBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= 2 * INTSIZE);
+
+  int host, port;
+
+  int res;
+  int n = 0;
+
+  IP oldVal = *vPtrOut;
+
+  res = Converter::byteArrayToInt( buf + n, &host);
+  assert( res > 0);
+  n += res;
+
+
+  res = Converter::byteArrayToInt( buf + n, &port);
+  assert( res > 0);
+  n += res;
+
+  *this->vPtrOut = IP(host, port);
+
+  this->setHasChanged( *this->vPtrOut != oldVal);
+
+  assert( n == 2 * INTSIZE);
+
+  return n;
+}
+
+
+/**
+ * print out variable value
+ */
+void SynchronizeableIP::SynchronizeableIP::debug( )
+{
+  printf("SYNCHRONIZEABLE_VAR: %s IN: %i, %i OUT: %i, %i\n", name.c_str(), vPtrIn->host(), vPtrIn->port(), vPtrOut->host(), vPtrOut->port());
+}
+
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_ip.h
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_ip.h	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_ip.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file synchronizeable_ip.h
+ * @brief Definition of SynchronizeableIP
+*/
+
+
+#ifndef _SYNCHRONIZEABLE_IP_H
+#define _SYNCHRONIZEABLE_IP_H
+
+#include "synchronizeable_var.h"
+
+class IP;
+
+class SynchronizeableIP : public SynchronizeableVar {
+
+  public:
+    SynchronizeableIP( IP *ptrIn, IP * ptrOut, std::string name, int permission, int priority = 0 );
+    virtual ~SynchronizeableIP();
+
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return true; }
+
+    virtual void debug();
+
+
+  private:
+    IP * vPtrIn;       //!< pointer to data (read)
+    IP * vPtrOut;      //!< pointer to data (write)
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_quaternion.cc
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_quaternion.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_quaternion.cc	(revision 9940)
@@ -0,0 +1,120 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_quaternion.h"
+#include "converter.h"
+#include <cassert>
+
+
+/**
+ * standard constructor
+ */
+SynchronizeableQuaternion::SynchronizeableQuaternion( Quaternion * ptrIn, Quaternion * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, 4*INTSIZE, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+ */
+SynchronizeableQuaternion::~SynchronizeableQuaternion ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableQuaternion::writeToBuf( byte * buf, int maxLength )
+{
+  int n = 0;
+  int res;
+
+  res = Converter::floatToByteArray( vPtrIn->v.x, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::floatToByteArray( vPtrIn->v.y, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::floatToByteArray( vPtrIn->v.z, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::floatToByteArray( vPtrIn->w, buf +  n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  assert( 4*FLOATSIZE == n );
+
+  return n;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableQuaternion::readFromBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= 4*FLOATSIZE );
+
+  float x,y,z,w;
+
+  int res;
+  int n = 0;
+
+  res = Converter::byteArrayToFloat( buf + n, &x );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::byteArrayToFloat( buf + n, &y );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::byteArrayToFloat( buf + n, &z );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::byteArrayToFloat( buf + n, &w );
+  assert( res > 0 );
+  n += res;
+
+  Quaternion oldVal = *vPtrOut;
+
+  *vPtrOut = Quaternion( Vector(x, y, z), w );
+
+  setHasChanged( ! ( oldVal == *vPtrOut ) );
+
+  assert( n == 4*FLOATSIZE );
+  return n;
+}
+
+
+/**
+ * print out variable value
+ */
+void SynchronizeableQuaternion::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: ((%f, %f, %f), %f) OUT: ((%f %f %f), %f)\n", name.c_str(), vPtrIn->v.x, vPtrIn->v.y, vPtrIn->v.z, vPtrIn->w, vPtrOut->v.x, vPtrOut->v.y, vPtrOut->v.z, vPtrOut->w );
+}
+
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_quaternion.h
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_quaternion.h	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_quaternion.h	(revision 9940)
@@ -0,0 +1,36 @@
+/*!
+ * @file synchronizeable_quaternion.h
+ * @brief Definition of SynchronizeableQuaternion
+*/
+
+#ifndef _SYNCHRONIZEABLE_QUATERNION_H
+#define _SYNCHRONIZEABLE_QUATERNION_H
+
+#include "synchronizeable_var.h"
+
+#include "quaternion.h"
+
+class SynchronizeableQuaternion : public SynchronizeableVar {
+
+  public:
+    SynchronizeableQuaternion( Quaternion * ptrIn, Quaternion * ptrOut, std::string name, int permission, int priority = 0 );
+    virtual ~SynchronizeableQuaternion();
+
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return true; };
+
+    virtual void debug();
+
+  private:
+    Quaternion * vPtrIn;       //!< pointer to data (read)
+    Quaternion * vPtrOut;      //!< pointer to data (write)
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_string.cc
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_string.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_string.cc	(revision 9940)
@@ -0,0 +1,110 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_string.h"
+#include "converter.h"
+#include <cassert>
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+SynchronizeableString::SynchronizeableString( std::string * ptrIn, std::string * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, 0, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableString::~SynchronizeableString ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableString::writeToBuf( byte * buf, int maxLength )
+{
+  int res = Converter::stringToByteArray( *vPtrIn, buf, maxLength );
+
+  assert( res > 0 );
+  assert( res == vPtrIn->length()+INTSIZE );
+
+  return res;
+}
+
+int SynchronizeableString::getSize()
+{
+   return vPtrIn->length()+INTSIZE;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableString::readFromBuf( byte * buf, int maxLength )
+{
+  std::string oldVal = *vPtrOut;
+
+  int res = Converter::byteArrayToString( buf, *vPtrOut, maxLength );
+
+  setHasChanged( oldVal != *vPtrOut );
+
+  if ( res < 0 )
+  {
+    printf("%s | res (%d) < 0\n", this->getName().c_str(), res);
+  }
+  assert( res > 0 );
+
+  return res;
+}
+
+/**
+ * print out variable value
+ */
+void SynchronizeableString::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: '%s' OUT: '%s'\n", name.c_str(), vPtrIn->c_str(), vPtrOut->c_str() );
+}
+
+
+/**
+ * reads actual size from buffer. this is used when size is not constant
+ * @param buf pointer to data
+ * @param maxLength maximal size of data
+ * @return same as readFromBuf would return
+ */
+int SynchronizeableString::getSizeFromBuf( byte * buf, int maxLength )
+{
+  std::string t;
+
+  int res = Converter::byteArrayToString( buf, t, maxLength );
+
+  assert( res > 0 );
+
+  return res;
+}
+
+
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_string.h
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_string.h	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_string.h	(revision 9940)
@@ -0,0 +1,41 @@
+/*!
+ * @file synchronizeable_string.h
+ * @brief Definition of SynchronizeableString
+*/
+
+#ifndef _SYNCHRONIZEABLE_STRING_H
+#define _SYNCHRONIZEABLE_STRING_H
+
+#include "synchronizeable_var.h"
+
+#include <string>
+
+class SynchronizeableString : public SynchronizeableVar {
+
+  public:
+    SynchronizeableString( std::string * ptrIn, std::string * ptrOut, std::string name, int permission, int priority = 0 );
+    virtual ~SynchronizeableString();
+
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+
+
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return false; };
+
+    virtual int getSize();
+
+    virtual int getSizeFromBuf( byte * buf, int maxLength );
+
+    virtual void debug();
+
+  private:
+    std::string * vPtrIn;       //!< pointer to data (read)
+    std::string * vPtrOut;      //!< pointer to data (write)
+
+};
+
+#endif /* _SYNCHRONIZEABLE_STRING_H */
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_uint.cc
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_uint.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_uint.cc	(revision 9940)
@@ -0,0 +1,43 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_uint.h"
+
+
+/**
+ * standard constructor
+*/
+SynchronizeableUInt::SynchronizeableUInt( unsigned int * ptrIn, unsigned int * ptrOut, std::string name, int permission, int priority) : SynchronizeableInt( (int*)ptrIn, (int*)ptrOut, name, permission, priority )
+{
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableUInt::~SynchronizeableUInt ()
+{
+}
+
+
+/**
+ * print out variable value
+ */
+void SynchronizeableUInt::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: %u OUT: %u\n", name.c_str(), *vPtrIn, *vPtrOut );
+}
+
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_uint.h
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_uint.h	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_uint.h	(revision 9940)
@@ -0,0 +1,22 @@
+/*!
+ * @file synchronizeable_uint.h
+ * @brief Definition of SynchronizeableInt
+*/
+
+
+#ifndef _SYNCHRONIZEABLE_UINT_H
+#define _SYNCHRONIZEABLE_UINT_H
+
+#include "synchronizeable_int.h"
+
+class SynchronizeableUInt : public SynchronizeableInt {
+
+  public:
+    SynchronizeableUInt( unsigned int * ptrIn, unsigned int * ptrOut, std::string name, int permission, int priority = 0 );
+    virtual ~SynchronizeableUInt();
+
+    virtual void debug();
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_var.cc
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_var.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_var.cc	(revision 9940)
@@ -0,0 +1,49 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_var.h"
+#include "netdefs.h"
+#include <cassert>
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+SynchronizeableVar::SynchronizeableVar ( void * ptrIn, void * ptrOut, std::string name, int length, int permission, int priority)
+{
+  assert( ptrIn );
+  assert( ptrOut );
+
+  this->ptrIn = ptrIn;
+  this->ptrOut = ptrOut;
+  this->length = length;
+  this->permission = permission;
+  this->priority = priority;
+  this->realPriority = priority;
+  this->name = name;
+  this->bWatched = false;
+  this->changed = false;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableVar::~SynchronizeableVar ()
+{
+}
+
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_var.h
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_var.h	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_var.h	(revision 9940)
@@ -0,0 +1,152 @@
+/*!
+ * @file synchronizeable_var.h
+ * @brief Definition of SynchronizeableVar
+*/
+
+#ifndef _SYNCHRONIZEABLE_VAR_H
+#define _SYNCHRONIZEABLE_VAR_H
+
+#include "nettypes.h"
+#include <string>
+
+
+
+class SynchronizeableVar {
+
+  public:
+    SynchronizeableVar( void * ptrIn, void * ptrOut, std::string name, int length, int permission, int priority = 0 );
+    virtual ~SynchronizeableVar();
+
+    /**
+     * check if synchronizeable wants to be informed on changes
+     * @return true if synchronizeable wants to be informed on changes
+     */
+    inline bool beWatched(){ return this->bWatched; }
+
+    /**
+     * set flag if synchronizeable wants to be informed on changes
+     */
+    inline void setWatched( bool watched ){ this->bWatched = watched; }
+
+    /**
+     * write var data to byte buffer
+     * @param buf pointer to write to
+     * @param maxLength writeToBuf will not write more than maxLength bytes
+     * @return number bytes written
+     */
+    virtual int writeToBuf( byte * buf, int maxLength ) = 0;
+
+    /**
+     * read var data from byte buffer
+     * @param buf pointer to read from
+     * @param maxLength readFromBuf will not read more than maxLength bytes
+     * @return number bytes read
+     */
+    virtual int readFromBuf( byte * buf, int maxLength ) = 0;
+
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize() = 0;
+
+    /**
+     * get size writeToBuf needs
+     * @return size in bytes
+     */
+    virtual int getSize(){ return length; }
+
+    /**
+     * check for permission to write
+     * @return true if you can write
+     */
+    inline bool checkPermission( int permission ){ return (permission & this->permission) != 0; }
+
+    /**
+     * get variable name
+     * @return name
+     */
+    inline std::string getName(){ return name; }
+
+    /**
+     * set variable name
+     * @param name new name
+     */
+    inline void setName( std::string name ) { this->name = name; }
+
+    /**
+     * get priority
+     * @return priority
+     */
+    inline int getPriority() { return this->priority; }
+
+    /**
+     * set priority
+     * @param p priority
+     */
+    inline void setPriority( int p ) { this->priority = p; }
+
+    /**
+     * reset priority to variable specific default value
+     */
+    inline void resetPriority() { this->priority = this->realPriority; }
+
+    /**
+     * reads actual size from buffer. this is used when size is not constant
+     * @param buf pointer to data
+     * @param maxLength maximal size of data
+     * @return same as readFromBuf would return
+     */
+    virtual inline int getSizeFromBuf( byte * buf, int maxLength ){ return this->getSize(); }
+
+    /**
+     * set variable id
+     * @param id
+     */
+    inline void setVarId( int id ){ this->varId = id; }
+
+    /**
+     * get variable id
+     * @return variable id
+     */
+    inline int getVarId(){ return varId; }
+
+    /**
+     * set hasChanged
+     * @param changed
+     */
+    inline void setHasChanged( bool changed ){ this->changed = changed; }
+
+    /**
+     * get hasChanged
+     * @return variable id
+     */
+    inline bool getHasChanged(){ return changed; }
+
+    /**
+     * print out variable value
+     */
+    virtual void debug() = 0;
+
+
+  private:
+    bool bWatched;      //!< true if synchronizeable wants to be informed on changes
+
+    int permission;     //!< who is allowed to change this var
+    int priority;       //!< priority assigned to var
+    int realPriority;   //!< priority assigned to var, increased every time not sent
+    int varId;          //!< id to identify varables
+
+    bool changed;       //!< true if last readFromBuf changed anything
+
+  protected:
+    void * ptrIn;       //!< pointer to data (read)
+    void * ptrOut;      //!< pointer to data (write)
+    int length;         //!< data length
+
+
+    std::string name;    //!< variable name (for debugging)
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_vector.cc
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_vector.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_vector.cc	(revision 9940)
@@ -0,0 +1,113 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+
+#include "synchronizeable_vector.h"
+#include "converter.h"
+#include <cassert>
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+SynchronizeableVector::SynchronizeableVector( Vector * ptrIn, Vector * ptrOut, std::string name, int permission, int priority) : SynchronizeableVar( ptrIn, ptrOut, name, 3*FLOATSIZE, permission, priority )
+{
+  this->vPtrIn = ptrIn;
+  this->vPtrOut = ptrOut;
+}
+
+
+/**
+ * standard deconstructor
+*/
+SynchronizeableVector::~SynchronizeableVector ()
+{
+}
+
+/**
+ * write var data to byte buffer
+ * @param buf pointer to write to
+ * @param maxLength writeToBuf will not write more than maxLength bytes
+ * @return number bytes written
+ */
+int SynchronizeableVector::writeToBuf( byte * buf, int maxLength )
+{
+  int n = 0;
+  int res;
+
+  res = Converter::floatToByteArray( vPtrIn->x, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::floatToByteArray( vPtrIn->y, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::floatToByteArray( vPtrIn->z, buf + n, maxLength - n );
+  assert( res > 0 );
+  n += res;
+
+  assert( 3*FLOATSIZE == n );
+
+  return n;
+}
+
+/**
+ * read var data from byte buffer
+ * @param buf pointer to read from
+ * @param maxLength readFromBuf will not read more than maxLength bytes
+ * @return number bytes read
+ */
+int SynchronizeableVector::readFromBuf( byte * buf, int maxLength )
+{
+  assert( maxLength >= 3*FLOATSIZE );
+
+  float x,y,z;
+
+  int res;
+  int n = 0;
+
+  Vector oldVec = *vPtrOut;
+
+  res = Converter::byteArrayToFloat( buf + n, &x );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::byteArrayToFloat( buf + n, &y );
+  assert( res > 0 );
+  n += res;
+
+  res = Converter::byteArrayToFloat( buf + n, &z );
+  assert( res > 0 );
+  n += res;
+
+  *vPtrOut = Vector( x, y, z );
+
+  setHasChanged( !(*vPtrOut == oldVec) );
+
+  assert( n == 3*FLOATSIZE );
+  return n;
+}
+
+
+/**
+ * print out variable value
+ */
+void SynchronizeableVector::SynchronizeableVector::debug( )
+{
+  printf( "SYNCHRONIZEABLE_VAR: %s IN: (%f, %f, %f) OUT: (%f %f %f)\n", name.c_str(), vPtrIn->x, vPtrIn->y, vPtrIn->z, vPtrOut->x, vPtrOut->y, vPtrOut->z );
+}
+
Index: branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_vector.h
===================================================================
--- branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_vector.h	(revision 9940)
+++ branches/heathaze/src/lib/network/synchronizeable_var/synchronizeable_vector.h	(revision 9940)
@@ -0,0 +1,36 @@
+/*!
+ * @file synchronizeable_vector.h
+ * @brief Definition of SynchronizeableVector
+*/
+
+#ifndef _SYNCHRONIZEABLE_VECTOR_H
+#define _SYNCHRONIZEABLE_VECTOR_H
+
+#include "synchronizeable_var.h"
+
+#include "vector.h"
+
+class SynchronizeableVector : public SynchronizeableVar {
+
+  public:
+    SynchronizeableVector( Vector * ptrIn, Vector * ptrOut, std::string name, int permission, int priority = 0 );
+    virtual ~SynchronizeableVector();
+
+    virtual int writeToBuf( byte * buf, int maxLength );
+    virtual int readFromBuf( byte * buf, int maxLength );
+
+    /**
+     * check if writeToBuf will return the same size every time
+     * @return true if same size every time
+     */
+    virtual bool hasStaticSize(){ return true; }
+
+    virtual void debug();
+
+  private:
+    Vector * vPtrIn;       //!< pointer to data (read)
+    Vector * vPtrOut;      //!< pointer to data (write)
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: branches/heathaze/src/lib/network/tcp_server_socket.cc
===================================================================
--- branches/heathaze/src/lib/network/tcp_server_socket.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/tcp_server_socket.cc	(revision 9940)
@@ -0,0 +1,141 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer:
+*/
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "tcp_server_socket.h"
+#include "tcp_socket.h"
+
+
+/* header for debug output */
+#include "debug.h"
+
+ObjectListDefinition(TcpServerSocket);
+TcpServerSocket::TcpServerSocket( int port ) : ServerSocket( port )
+{
+  init();
+  listen(port);
+}
+
+/**
+ * Default destructor
+ */
+TcpServerSocket::~TcpServerSocket( )
+{
+  /* Quit SDL_net */
+  // NOTE: what if other instances of NetworkSocket running?
+  SDLNet_Quit();
+  PRINTF(5)("SDL_net shutdown\n");
+
+  _isListening = false;
+}
+
+void TcpServerSocket::init( )
+{
+  /* set the class id for the base object */
+  this->registerObject(this, TcpServerSocket::_objectList);
+
+  terminateThread = false;
+  listenSocket = NULL;
+  _isListening = false;
+
+  if(SDLNet_Init()==-1)
+  {
+    PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
+    return;
+  }
+  else
+    PRINTF(5)("SDL_net initialized\n");
+
+  PRINTF(0)("TcpServerSocket created\n");
+}
+
+
+/**
+ * Tells the NetworkSocket to listen on a specific port for incoming connections.
+ * NetworkSocket::writeBytes(...) will have no effect until there is a valuable connection.
+ * @param port
+ */
+bool TcpServerSocket::listen(unsigned int port)
+{
+  PRINTF(0)("TcpServerSocket::listen()\n");
+  _isListening = true;
+  //check if not already connected or listening
+  if (listenSocket)
+  {
+    PRINTF(1)("TcpServerSocket::listen: tcpSocket!=NULL! maybe you already called listen or did not call close()!\n");
+    _isListening = false;
+    return false;
+  }
+
+  IPaddress ip;
+
+  if (SDLNet_ResolveHost(&ip, NULL, port)==-1)
+  {
+    PRINTF(1)("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
+    _isListening = false;
+    return false;
+  }
+
+  listenSocket = SDLNet_TCP_Open(&ip);
+
+  if (!listenSocket)
+  {
+    PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
+    _isListening = false;
+    return false;
+  }
+
+  return true;
+}
+
+
+NetworkSocket* TcpServerSocket::getNewSocket( )
+{
+  if ( !listenSocket )
+  {
+    PRINTF(1)("listenSocket == NULL! Maybe you forgot to call listen()\n");
+    close();
+    return NULL;
+  }
+
+  TCPsocket sock = SDLNet_TCP_Accept(listenSocket);
+
+  if ( !sock )
+  {
+    return NULL;
+  }
+  else
+  {
+    return new TcpSocket(sock);
+  }
+}
+
+
+
+void TcpServerSocket::close( )
+{
+  if ( listenSocket )
+  {
+    SDLNet_TCP_Close( listenSocket );
+    listenSocket = NULL;
+  }
+
+  _isListening = false;
+}
+
Index: branches/heathaze/src/lib/network/tcp_server_socket.h
===================================================================
--- branches/heathaze/src/lib/network/tcp_server_socket.h	(revision 9940)
+++ branches/heathaze/src/lib/network/tcp_server_socket.h	(revision 9940)
@@ -0,0 +1,42 @@
+/*!
+ * @file server_socket.h
+ *  waits for incoming connections
+
+ */
+
+#ifndef _TCP_SERVER_SOCKET
+#define _TCP_SERVER_SOCKET
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+#include "server_socket.h"
+
+
+class TcpServerSocket : public ServerSocket
+{
+  ObjectListDeclaration(TcpServerSocket);
+  public:
+    TcpServerSocket( int port );
+
+    virtual ~TcpServerSocket();
+
+    virtual bool listen( unsigned int port );
+    virtual NetworkSocket* getNewSocket( void );
+    virtual void close();
+    virtual void update() {};
+
+  private:
+    TCPsocket listenSocket;
+    bool terminateThread;
+
+    bool _isListening;
+
+    void init();
+
+};
+
+#endif
Index: branches/heathaze/src/lib/network/tcp_socket.cc
===================================================================
--- branches/heathaze/src/lib/network/tcp_socket.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/tcp_socket.cc	(revision 9940)
@@ -0,0 +1,480 @@
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner, David Hasenfratz
+   co-programmer:
+*/
+
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "converter.h"
+
+/* include your own header */
+#include "tcp_socket.h"
+
+/* header for debug output */
+#include "debug.h"
+
+ObjectListDefinition(TcpSocket);
+/**
+ * Default constructor
+ */
+TcpSocket::TcpSocket()
+{
+  this->init();
+}
+
+/**
+ * Constructor to connect directly
+ */
+TcpSocket::TcpSocket( std::string host, int port )
+{
+  this->init();
+  connectToServer( host, port);
+}
+
+
+TcpSocket::TcpSocket( TCPsocket sock )
+{
+  this->init();
+  this->tcpSocket = sock;
+
+  readThread = SDL_CreateThread(thread_read, (void*)this);
+  writeThread = SDL_CreateThread(thread_write, (void*)this);
+}
+
+void TcpSocket::init()
+{
+  /* set the class id for the base object */
+  this->registerObject(this, TcpSocket::_objectList);
+
+  tcpSocket = NULL;
+  incomingBufferLength = 0;
+  outgoingBufferLength = 0;
+
+  readThread = NULL;
+  writeThread = NULL;
+
+
+  thread_write_running = false;
+  thread_read_running = false;
+
+  incomingBufferMutex = SDL_CreateMutex();
+  outgoingBufferMutex = SDL_CreateMutex();
+
+
+  socketMutex = SDL_CreateMutex();
+  terminateThread = false;
+
+  /* Init SDL_net */
+  //NOTE: do we need to call SDLNet_Init for all instances?
+  if(SDLNet_Init()==-1)
+  {
+    PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
+    return;
+  }
+  else
+    PRINTF(5)("SDL_net initialized\n");
+
+  PRINTF(0)("TcpSocket created\n");
+
+}
+
+
+
+/**
+ * Default destructor
+ * dont use this from outside: use destroy() instead!!
+ */
+TcpSocket::~TcpSocket( )
+{
+  this->terminateThread = true;
+  /* Quit SDL_net */
+  // NOTE: what if other instances of TcpSocket running?
+  SDLNet_Quit();
+  PRINTF(5)("SDL_net shutdown\n");
+
+  SDL_DestroyMutex(incomingBufferMutex);
+  SDL_DestroyMutex(outgoingBufferMutex);
+  SDL_DestroyMutex(socketMutex);
+  SDL_DestroyMutex(threadTerminationMutex);
+}
+
+/**
+ * This function establishes a TCP/UDP connection to a given server (function argument).
+ * It is called by the NetworkStream. It creates a TCP/UDP socket for the connection.
+ * @param ip
+ */
+void TcpSocket::connectToServer( std::string host, int port)
+{
+  IPaddress ip;
+
+  bOk = true;
+
+  if ( SDLNet_ResolveHost( &ip, host.c_str(), port ) != 0 )
+  {
+    PRINTF(1)("could not resolve host %s\n", host.c_str() );
+    bOk = false;
+    return;
+  }
+
+  //check if not already connected or listening
+  if (tcpSocket)
+  {
+    PRINTF(1)("TcpSocket::listen: tcpSocket!=NULL! maybe you already called listen or connectToServer or did not call disconnectServer()!");
+  }
+
+  /* Connect to the host and port contained in ip using a TCP connection. */
+  tcpSocket = SDLNet_TCP_Open(&ip);
+  if(!tcpSocket)
+  {
+    PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
+    return;
+  }
+
+  readThread = SDL_CreateThread(thread_read, (void*)this);
+  writeThread = SDL_CreateThread(thread_write, (void*)this);
+}
+
+
+/**
+ * DTears down a TCP/UDP connection.
+ */
+void TcpSocket::disconnectServer( )
+{
+  terminateThread = true;
+  /* Close the connection */
+
+  SDL_mutexP(socketMutex);
+  SDLNet_TCP_Close(tcpSocket);
+  tcpSocket = NULL;
+  SDL_mutexV(socketMutex);
+}
+
+
+/**
+ * This function writes some bytes (data) to the network connection (if the connection is already
+ * estabilhed) otherwise it just does nothing (silently discarding the data). And writes some
+ * warnings
+ * @param data: pointer to the data to send
+ * @param length: n bytes to send
+ * @return the number successfully written bytes
+ */
+int TcpSocket::writeBytes(byte * data, int length)
+{
+  PRINTF(5)("TcpSocket::writeBytes()\n");
+#ifdef _USE_OUTGOING_BUFFER
+
+#define min(a,b) (a<b)?a:b
+  int nbytes = min(_OUTGOING_BUFFER_SIZE - outgoingBufferLength, length);
+#undef min
+
+  if (!tcpSocket || data==NULL || nbytes<=0)
+{
+  assert(_OUTGOING_BUFFER_SIZE - outgoingBufferLength > 0);
+  return 0;
+}
+
+  SDL_mutexP(outgoingBufferMutex);
+
+  memcpy(outgoingBuffer + outgoingBufferLength, data, nbytes);
+  outgoingBufferLength += nbytes;
+
+  SDL_mutexV(outgoingBufferMutex);
+
+
+  return nbytes;
+#else
+  SDL_mutexP(socketMutex);
+
+  if (!tcpSocket || data==NULL)
+    return 0;
+
+  int res = SDLNet_TCP_Send(tcpSocket, data, length);
+
+  SDL_mutexV(socketMutex);
+
+  if (res<length)
+    PRINTF(1)("SDLNet_TCP_Send: %s\n", SDLNet_GetError());
+
+  return res;
+#endif
+}
+
+/**
+ * Reads in the bytes from the network interface and passes it to the NetworkStream.
+ * This function must internaly be implemented/connected as a thread, since the read
+ * functions of many network libraries are blocking an would therefore block the whole
+ * program.
+ * From outside, the thread shouldn't be accessible at all.
+ * @param data: pointer to memory, big enough to store length bytes
+ * @param length: n bytes to read
+ * @return the number successfully read bytes. -1 on error. may be less than length!
+ */
+int TcpSocket::readBytes(byte * data, int length)
+{
+  PRINTF(5)("TcpSocket::readBytes()\n");
+  if (data==NULL)
+    return 0;
+
+  int nbytes = (length<incomingBufferLength) ? length : incomingBufferLength;
+
+
+  //printf("readBytes: nbytes = %d; length=%d; incomingBufferLength=%d\n", nbytes, length, incomingBufferLength);
+
+  // just in case ...
+  if (nbytes<0)
+    return -1;
+
+  if (nbytes==0)
+    return 0;
+
+  SDL_mutexP(incomingBufferMutex);
+
+  memcpy(data, incomingBuffer, nbytes);
+
+  //important: use memmove because the memory areas may overlap
+  memmove(incomingBuffer, incomingBuffer+nbytes, incomingBufferLength-nbytes);
+  incomingBufferLength -= nbytes;
+
+  SDL_mutexV(incomingBufferMutex);
+
+  return nbytes;
+}
+
+/**
+ * Reads in the bytes form the network interface and passes it to the NetworkStream.
+ * It only reads the bytes if there are enough bytes in our buffer.
+ * @param data: pointer to memory, big enough to store length bytes
+ * @param length: n bytes to read
+ * @return the number successfully read bytes. -1 on error. 0 if there are not enough bytes in our buffer.
+ */
+int TcpSocket::readBlock(byte * data, int length)
+{
+  printf("TcpSocket: got %i bytes, NetworkStream requested %i bytes\n", this->incomingBufferLength, length);
+  if (incomingBufferLength >= length)
+    return readBytes(data, length);
+  else return 0;
+}
+
+
+/**
+ * used to create a thread to read from socket
+ * @param data: pointer to TcpSocket
+ */
+int TcpSocket::thread_read( void * data )
+{
+  int nbytesread = 0;
+  int nbytestoread = 0;
+  char buffer[_LOCAL_BUFFER_SIZE];
+  TcpSocket * self = (TcpSocket*)data;
+
+  self->thread_read_running = true;
+
+  while (!self->terminateThread)
+  {
+#define min(a,b) (a<b)?a:b
+    nbytestoread = min(_INCOMING_BUFFER_SIZE - self->incomingBufferLength, _LOCAL_BUFFER_SIZE);
+#undef min
+
+    //if buffer is full
+    if (nbytestoread<=0 || !self->tcpSocket)
+{
+  SDL_Delay(_MSECONDS_SLEEP_FULL_BUFFER);
+  continue;
+}
+
+    nbytesread = SDLNet_TCP_Recv(self->tcpSocket, buffer, nbytestoread);
+
+    SDL_mutexP(self->incomingBufferMutex);
+
+    if (nbytesread<=0)
+{
+  if (nbytesread<0)
+    printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
+
+  SDL_mutexP(self->socketMutex);
+
+  SDLNet_TCP_Close(self->tcpSocket);
+  self->tcpSocket = NULL;
+
+  SDL_mutexV(self->socketMutex);
+  SDL_mutexV(self->incomingBufferMutex);
+  continue;
+}
+
+    //printf("thread_read: nbytesread=%d\n", nbytesread);
+
+    memcpy(self->incomingBuffer+self->incomingBufferLength, buffer, nbytesread);
+    self->incomingBufferLength += nbytesread;
+
+    SDL_mutexV(self->incomingBufferMutex);
+  }
+
+  SDL_mutexP(self->threadTerminationMutex);
+  self->thread_read_running = false;
+
+  if ( !self->thread_write_running )
+{
+    //delete self;
+  SDL_mutexV(self->threadTerminationMutex);
+}
+  else
+{
+  SDL_mutexV(self->threadTerminationMutex);
+}
+
+
+#ifdef DONTEXITTHREADS
+  while ( true )
+{
+  SDL_Delay(1000);
+}
+#endif
+
+  PRINTF(0)("QUIT READ THREAD\n");
+
+  return 0;
+}
+
+int TcpSocket::thread_write( void * data )
+{
+  int nbyteswrite = 0;
+  int nbytestowrite = 0;
+  char buffer[_LOCAL_BUFFER_SIZE];
+  TcpSocket * self = (TcpSocket*)data;
+
+  self->thread_write_running = true;
+
+  while (!self->terminateThread)
+  {
+#define min(a,b) (a<b)?a:b
+    nbytestowrite = min(self->outgoingBufferLength, _LOCAL_BUFFER_SIZE);
+#undef min
+
+//     printf("thread_write nbytes=%d listening=%d\n", nbytestowrite, (int)self->_isListening);
+
+    //if buffer is full
+    if (nbytestowrite<=0 || !self->tcpSocket)
+{
+  SDL_Delay(_MSECONDS_SLEEP_EMPTY_BUFFER);
+  continue;
+}
+
+    SDL_mutexP(self->outgoingBufferMutex);
+
+    //printf("a\n");
+
+    memcpy(buffer, self->outgoingBuffer, nbytestowrite);
+    self->outgoingBufferLength -= nbytestowrite;
+    memmove(self->outgoingBuffer, self->outgoingBuffer+nbytestowrite, self->outgoingBufferLength);
+
+    SDL_mutexV(self->outgoingBufferMutex);
+
+    nbyteswrite = SDLNet_TCP_Send(self->tcpSocket, buffer, nbytestowrite);
+
+    if (nbyteswrite<=0)
+{
+  printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
+
+  SDL_mutexP(self->socketMutex);
+
+  SDLNet_TCP_Close(self->tcpSocket);
+  self->tcpSocket = NULL;
+
+  SDL_mutexV(self->socketMutex);
+  continue;
+}
+
+  }
+
+  SDL_mutexP(self->threadTerminationMutex);
+  self->thread_write_running = false;
+
+  if ( !self->thread_read_running )
+{
+    //delete self;
+  SDL_mutexV(self->threadTerminationMutex);
+}
+  else
+{
+  SDL_mutexV(self->threadTerminationMutex);
+}
+
+#ifdef DONTEXITTHREADS
+  while ( true )
+{
+  SDL_Delay(1000);
+}
+#endif
+
+  PRINTF(0)("QUIT WRITE THREAD\n");
+
+  return 0;
+
+}
+
+bool TcpSocket::writePacket( byte * data, int length )
+{
+  PRINTF(5)("TcpSocket::writePacket() size=%d\n", length);
+
+  if ( length > 1024 )
+    PRINTF(2)("WARNING SENDING BIG PACKET SIZE = %d\n", length);
+
+  byte blen[INTSIZE];
+
+  Converter::intToByteArray( length, blen, INTSIZE );
+
+  writeBytes(blen, INTSIZE);
+  writeBytes(data, length);
+}
+
+int TcpSocket::readPacket( byte * data, int maxLength )
+{
+  PRINTF(5)("TcpSocket::readPacket()\n");
+  if (incomingBufferLength<INTSIZE)
+  {
+    return 0;
+  }
+
+  int blen;
+  Converter::byteArrayToInt( incomingBuffer, &blen );
+
+  if (blen>maxLength)
+  {
+    PRINTF(1)("Buffersize is too small (%d) for packet (%d).\n", maxLength, blen);
+    assert(false);
+    return 0;
+  }
+
+  if (blen>incomingBufferLength)
+  {
+    return 0;
+  }
+
+  byte t[INTSIZE];
+  readBytes(t, INTSIZE);
+  int res = readBytes(data, blen);
+
+  if (res!=blen)
+    return -1;
+  else
+    return blen;
+
+}
+
+
Index: branches/heathaze/src/lib/network/tcp_socket.h
===================================================================
--- branches/heathaze/src/lib/network/tcp_socket.h	(revision 9940)
+++ branches/heathaze/src/lib/network/tcp_socket.h	(revision 9940)
@@ -0,0 +1,100 @@
+/*!
+ * @file tcp_socket.h
+  *  tcp socket network interface
+
+*/
+
+#ifndef _TCP_SOCKET
+#define _TCP_SOCKET
+
+//TODO HACK else gdb will not work on server
+#define DONTEXITTHREADS
+
+//if you want to use outgoing buffer define _USE_OUTGOING_BUFFER
+#define _USE_OUTGOING_BUFFER
+
+#define _INCOMING_BUFFER_SIZE 2024000
+#define _OUTGOING_BUFFER_SIZE 2024000
+#define _LOCAL_BUFFER_SIZE 2048
+//sleep if incoming buffer is full
+#define _MSECONDS_SLEEP_FULL_BUFFER 10
+//sleep if outgoing buffer is empty
+#define _MSECONDS_SLEEP_EMPTY_BUFFER 10
+
+
+/* contains memmove and memcpy */
+#include <string.h>
+
+#ifdef HAVE_SDL_H
+#include <SDL_thread.h>
+#else
+#include <SDL/SDL_thread.h>
+#endif
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include network_socket.h since all classes are derived from this one */
+#include "network_socket.h"
+
+class TcpSocket : public NetworkSocket
+{
+  ObjectListDeclaration(TcpSocket);
+  public:
+    TcpSocket();
+    TcpSocket( std::string host, int port );
+    TcpSocket(TCPsocket sock);
+    virtual ~TcpSocket();
+
+    virtual void connectToServer( std::string host, int port );
+
+    virtual void disconnectServer();
+    virtual void reconnectToServer( std::string host, int port);
+    virtual void reconnectToServerSoft( std::string host, int port);
+
+    virtual bool writePacket(byte * data, int length);
+
+    virtual int readPacket(byte * data, int maxLength);
+
+  private:
+    TCPsocket tcpSocket;
+
+    byte incomingBuffer[_INCOMING_BUFFER_SIZE];
+#ifdef _USE_OUTGOING_BUFFER
+  byte outgoingBuffer[_OUTGOING_BUFFER_SIZE];
+#endif
+  int incomingBufferLength;
+#ifdef _USE_OUTGOING_BUFFER
+  int outgoingBufferLength;
+#endif
+
+  SDL_mutex * incomingBufferMutex;
+#ifdef _USE_OUTGOING_BUFFER
+  SDL_mutex * outgoingBufferMutex;
+#endif
+  SDL_mutex * socketMutex;
+  bool terminateThread;
+
+  SDL_mutex* threadTerminationMutex;
+  static int thread_read(void * data);
+  bool thread_read_running;
+  bool thread_write_running;
+
+  SDL_Thread*            readThread;
+  SDL_Thread*            writeThread;
+
+#ifdef _USE_OUTGOING_BUFFER
+  static int thread_write(void * data);
+#endif
+
+  int writeBytes(byte * data, int length);
+  int readBytes(byte * data, int length);
+  int readBlock(byte * data, int length);
+
+  void init();
+
+};
+
+
+
+#endif /* _NETWORK_SOCKET */
Index: branches/heathaze/src/lib/network/udp_broadcast.cc
===================================================================
--- branches/heathaze/src/lib/network/udp_broadcast.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/udp_broadcast.cc	(revision 9940)
@@ -0,0 +1,104 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "udp_broadcast.h"
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+ */
+UdpBroadcast::UdpBroadcast ()
+{
+  this->port = 0;
+  packet = SDLNet_AllocPacket( BROADCAST_PACKET_SIZE );
+
+  if ( !packet )
+  {
+    printf( "SDLNet_AllocPacket: %s\n", SDLNet_GetError() );
+    assert( packet );
+  }
+
+  this->socket = NULL;
+}
+
+
+/**
+ * standard deconstructor
+ */
+UdpBroadcast::~UdpBroadcast ()
+{
+  if ( this->packet )
+  {
+    SDLNet_FreePacket( this->packet );
+    this->packet = NULL;
+  }
+
+  if ( this->socket )
+  {
+    SDLNet_UDP_Close( this->socket );
+    this->socket = NULL;
+  }
+
+}
+
+/**
+ * listen for incoming broadcast packets
+ * @param port port to listen on
+ * @return true on success
+ */
+bool UdpBroadcast::listen( int port )
+{
+  return true;
+}
+
+/**
+ * prepare for sending broadcast packets to port
+ * @param port port to send to
+ * @return true on success
+ */
+bool UdpBroadcast::open( int port )
+{
+  this->port = port;
+
+  return true;
+}
+
+/**
+ * send packet
+ * @param data data to send
+ * @param length length of data
+ * @param ip if ip == NULL broadcast is used
+ * @return number of bytes sent
+ */
+int UdpBroadcast::send( byte * data, int length, IPaddress * ip )
+{
+  return 0;
+}
+
+/**
+ * recieve packets
+ * @param data pointer to buffer to copy data to
+ * @param maxLength maxmal number of bytes to copy to data
+ * @param ip if != 0 ip contains data about sender
+ * @return number of bytes recieved
+ */
+int UdpBroadcast::recv( byte * data, int maxLength, IPaddress * ip )
+{
+  return 0;
+}
+
+
Index: branches/heathaze/src/lib/network/udp_broadcast.h
===================================================================
--- branches/heathaze/src/lib/network/udp_broadcast.h	(revision 9940)
+++ branches/heathaze/src/lib/network/udp_broadcast.h	(revision 9940)
@@ -0,0 +1,33 @@
+/*!
+ * @file proto_class.h
+ * @brief Definition of ...
+ */
+
+#ifndef _UDP_BROADCAST_H
+#define _UDP_BROADCAST_H
+
+#include "netdefs.h"
+#include <cassert>
+
+#define BROADCAST_PACKET_SIZE 1024
+
+//! A class for sending/recieving brotcast packets for lan
+class UdpBroadcast
+{
+  public:
+    UdpBroadcast();
+    virtual ~UdpBroadcast();
+
+    bool listen( int port );
+    bool open( int port );
+    int send( byte * data, int length, IPaddress * ip = NULL );
+    int recv( byte * data, int maxLength, IPaddress * ip = NULL );
+
+  private:
+    int port;
+    UDPpacket * packet;
+    UDPsocket socket;
+
+};
+
+#endif /* _UDP_BROADCAST_H */
Index: branches/heathaze/src/lib/network/udp_server_socket.cc
===================================================================
--- branches/heathaze/src/lib/network/udp_server_socket.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/udp_server_socket.cc	(revision 9940)
@@ -0,0 +1,305 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer:
+*/
+
+#include "udp_server_socket.h"
+#include "debug.h"
+
+
+ObjectListDefinition(UdpServerSocket);
+/**
+ * constructor
+ * @param port port to listen on
+ */
+UdpServerSocket::UdpServerSocket( int port ) : ServerSocket( port )
+{
+  packet = SDLNet_AllocPacket( UDP_PACKET_SIZE );
+
+  if ( !packet )
+  {
+    PRINTF(1)("SDLNet_AllocPacket: %s\n", SDLNet_GetError());
+
+    assert( false );
+    bOk = false;
+  }
+
+  memset( packet->data, 0, UDP_PACKET_SIZE );
+
+  listen( port );
+}
+
+/**
+ * default destructor
+ */
+UdpServerSocket::~UdpServerSocket( )
+{
+  for ( int i = 0; i < (int)packetBuffer.size(); i++ )
+    removeUserPackets( i );
+
+  if ( packet )
+    SDLNet_FreePacket( packet );
+
+  if ( socket )
+    SDLNet_UDP_Close( socket );
+}
+
+/**
+ * tell udpServerSocket to recieve packets on port
+ * @param port port
+ * @return true on success
+ */
+bool UdpServerSocket::listen( unsigned int port )
+{
+  socket = SDLNet_UDP_Open( port );
+
+  PRINTF(0)("listening on port: %d\n", port);
+
+  if ( !socket )
+  {
+
+    bOk = false;
+    return false;
+  }
+
+  return true;
+}
+
+/**
+ * get newly connected socket. note
+ * @return new socket or NULL if no new socket exists
+ */
+NetworkSocket * UdpServerSocket::getNewSocket( void )
+{
+  NetworkSocket * result = NULL;
+
+  if ( newSocketList.size() > 0 )
+  {
+    result = newSocketList.front();
+
+    newSocketList.pop_front();
+  }
+
+  return result;
+}
+
+
+/**
+ * stop listening on server
+ */
+void UdpServerSocket::close( )
+{
+
+  for ( int i = 0; i < (int)packetBuffer.size(); i++ )
+    removeUserPackets( i );
+
+  packetBuffer.clear();
+  userList.clear();
+
+  SDLNet_UDP_Close( socket );
+  socket = NULL;
+}
+
+/**
+ * clean up users buffer
+ * @param userId users userid
+ */
+void UdpServerSocket::removeUserPackets( int userId )
+{
+  if ( userId >= (int)packetBuffer.size() )
+    return;
+
+  for ( NetworkPacketList::iterator it = packetBuffer[userId].begin(); it!=packetBuffer[userId].end(); it++ )
+  {
+    if ( it->data )
+    {
+      free( it->data );
+      it->data = NULL;
+    }
+  }
+
+  packetBuffer[userId].clear();
+}
+
+/**
+ * get next packet for user
+ * @param userId user id
+ * @return recieved packet or packet with length 0 if no packet available
+ */
+NetworkPacket UdpServerSocket::getPacket( int userId )
+{
+  NetworkPacket res;
+  res.data = NULL;
+  res.length = 0;
+
+  if ( (int)packetBuffer.size() > userId && (int)packetBuffer[userId].size() > 0 )
+  {
+    res.data = packetBuffer[userId].front().data;
+    res.length = packetBuffer[userId].front().length;
+    packetBuffer[userId].pop_front();
+  }
+
+  return res;
+}
+
+/**
+ * get number of packets recieved for user
+ * @param userId user id
+ * @return number of packets in buffer
+ */
+int UdpServerSocket::getPacketCount( int userId )
+{
+  if ( userId >= (int)packetBuffer.size() )
+    return -1;
+
+  return packetBuffer[userId].size();
+}
+
+/**
+ * will set user state
+ * @param userId users id
+ * @param ip users host / port
+ */
+void UdpServerSocket::initUser( int userId, IPaddress ip, byte randomByte )
+{
+  int channel = SDLNet_UDP_Bind( socket, userId, &ip );
+  if( channel != userId )
+  {
+    PRINTF(1)("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
+    assert(false);
+    return;
+  }
+
+  if ( userId < (int)packetBuffer.size() )
+    removeUserPackets( userId );
+
+  if ( (int)packetBuffer.size() <= userId )
+    packetBuffer.resize( userId + 1 );
+
+  if ( (int)userList.size() <= userId )
+    userList.resize( userId + 1 );
+
+  userList[ userId ].addr = ip;
+  userList[ userId ].randomByte = randomByte;
+}
+
+/**
+ * remove user from list
+ * @param userId user id
+ */
+void UdpServerSocket::removeUser( int userId )
+{
+  removeUserPackets( userId );
+
+  if ( userId >= (int)userList.size() )
+    return;
+
+  userList[userId].addr.host = 0;
+  userList[userId].addr.port = 0;
+
+  SDLNet_UDP_Unbind( socket, userId );
+}
+
+/**
+ * send one packet to client associated to userId
+ * @param networkPacket packet to send
+ * @param userId users id
+ * @return true on success
+ */
+bool UdpServerSocket::sendPacket( NetworkPacket networkPacket , int userId )
+{
+  if ( !socket )
+    return false;
+
+  assert( networkPacket.length <= UDP_PACKET_SIZE );
+
+  memcpy( packet->data, networkPacket.data, networkPacket.length );
+  packet->len = networkPacket.length;
+  packet->channel = -1;
+
+  if ( SDLNet_UDP_Send( socket, userId, packet ) == 0 )
+  {
+    PRINTF(1)("SDLNet_UDP_Send: %s\n", SDLNet_GetError());
+    return false;
+  }
+
+  return true;
+}
+
+/**
+ * do periodically things
+ */
+void UdpServerSocket::update( )
+{
+  int res;
+  int newConn = 0;
+
+  // iterate through all newly received packets and assign them to the users packet buffer
+  for ( res = SDLNet_UDP_Recv( socket, packet ); res == 1; res = SDLNet_UDP_Recv( socket, packet ) )
+  {
+    int userId;
+    bool isNewConnection = false;
+
+    if ( packet->len <= 0 )
+      continue;
+
+    // search the user id this backet belongs to
+    for ( userId = 0; userId < (int)userList.size(); userId++ )
+    {
+      if ( userList[userId].addr.host == packet->address.host &&
+           userList[userId].addr.port == packet->address.port &&
+           userList[userId].randomByte == ( packet->data[0] & 0xFC ) )
+        break;
+    }
+
+    // is it a new packet initializing a new connecion?
+    if ( userId >= (int)userList.size() )
+    {
+      newConn++;
+      isNewConnection = true;
+
+      if ( newConn > MAX_NEW_CONNECTIONS )
+      {
+        PRINTF(2)("Too many new connections. Dropping packet\n");
+        continue;
+      }
+
+      for ( userId =0; userId < (int)userList.size(); userId++ )
+        if ( userList[userId].addr.host == 0 && userList[userId].addr.port == 0 )
+          break;
+
+      this->initUser( userId, packet->address, packet->data[0] & 0xFC );
+      UdpSocket * sock = new UdpSocket( this, packet->address, userId, packet->data[0] & 0xFC );
+      newSocketList.push_back( sock );
+      PRINTF(0)("NEW CONNECTION %x\n", packet->address.host );
+    }
+
+
+    // add new packet to packetbuffer
+    NetworkPacket networkPacket;
+    networkPacket.length = packet->len;
+    if ( packet->len != 0 )
+    {
+      networkPacket.data = (byte*)malloc( packet->len );
+      assert( networkPacket.data );
+    }
+    else
+    {
+      networkPacket.data = NULL;
+    }
+    memcpy( networkPacket.data, packet->data, packet->len );
+    packetBuffer[userId].push_back( networkPacket );
+  }
+
+  assert( res == 0 );
+}
Index: branches/heathaze/src/lib/network/udp_server_socket.h
===================================================================
--- branches/heathaze/src/lib/network/udp_server_socket.h	(revision 9940)
+++ branches/heathaze/src/lib/network/udp_server_socket.h	(revision 9940)
@@ -0,0 +1,85 @@
+/*!
+ * @file udp_server_socket.h
+ *  waits for incoming connections
+
+ */
+
+#ifndef _UDP_SERVER_SOCKET
+#define _UDP_SERVER_SOCKET
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+#include "server_socket.h"
+#include "udp_socket.h"
+
+#include <list>
+#include <vector>
+
+#define UDP_PACKET_SIZE 10240
+#define MAX_NEW_CONNECTIONS 8
+
+struct NetworkPacket
+{
+  int length;
+  byte * data;
+};
+
+typedef std::list<NetworkPacket> NetworkPacketList;
+
+typedef std::vector<NetworkPacketList> PacketBuffer;
+
+
+//!< informations struct for each user
+struct UserInfo
+{
+  IPaddress     addr;            //!< ip address of this user
+  byte          randomByte;      //!< random byte of this user
+};
+
+
+typedef std::vector<UserInfo> UserList;
+
+typedef std::list<UdpSocket*> UdpSocketList;
+
+
+//!< the upd server socket listening for incoming connections
+class UdpServerSocket : public ServerSocket
+{
+  ObjectListDeclaration(UdpServerSocket);
+  public:
+    UdpServerSocket( int port);
+    virtual ~UdpServerSocket();
+
+    /* server socket manipulations */
+    virtual bool listen( unsigned int port );
+    virtual NetworkSocket* getNewSocket( void );
+    virtual void close();
+
+    virtual void update();
+
+    /* network traffic interface */
+    NetworkPacket getPacket( int userId );
+    void removeUser( int userId );
+    bool sendPacket( NetworkPacket networkPacket, int userId );
+
+
+  private:
+    void removeUserPackets( int userId );
+    int getPacketCount( int childId );
+    void initUser( int childId, IPaddress ip, byte randomByte );
+
+
+  private:
+    UDPsocket          socket;           //!< will be used to send/recieve data to/from clients
+    UDPpacket *        packet;           //!< packet structure to recieve packet
+    PacketBuffer       packetBuffer;     //!< will store recieved packets for UdpSockets
+    UserList           userList;         //!< contains information about clients
+    UdpSocketList      newSocketList;    //!< contains new socket
+
+};
+
+#endif
Index: branches/heathaze/src/lib/network/udp_socket.cc
===================================================================
--- branches/heathaze/src/lib/network/udp_socket.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/udp_socket.cc	(revision 9940)
@@ -0,0 +1,354 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer:
+*/
+
+#include "udp_socket.h"
+#include "udp_server_socket.h"
+#include "debug.h"
+
+ObjectListDefinition(UdpSocket);
+
+void UdpSocket::init( )
+{
+  //TODO setClassId
+  this->serverSocket = NULL;
+  this->socket = NULL;
+  this->packet = NULL;
+  this->randomByte = 0;
+}
+
+
+/**
+ * constructor - connects to give host
+ * @param host host
+ * @param port port
+ */
+UdpSocket::UdpSocket( std::string host, int port )
+{
+  init();
+  this->packet = SDLNet_AllocPacket( UDP_PACKET_SIZE );
+
+  assert( this->packet );
+
+  memset( packet->data, 0, UDP_PACKET_SIZE );
+  PRINTF(0)("PACKET DATA: %x\n", packet->data);
+
+  this->connectToServer( host, port );
+}
+
+/**
+ * default constructor. use this one if you want to call connecttoServer
+ */
+UdpSocket::UdpSocket( )
+{
+  this->init();
+  this->packet = SDLNet_AllocPacket( UDP_PACKET_SIZE );
+
+  if ( !packet )
+  {
+    PRINTF(1)("SDLNet_AllocPacket: %s\n", SDLNet_GetError());
+
+    assert( false );
+    bOk = false;
+  }
+
+}
+
+/**
+ * constructor. used by UdpServerSocket
+ * @param serverSocket pointer to serverSocket
+ * @param ip client's ip address
+ * @param userId userid used by serverSocket
+ */
+UdpSocket::UdpSocket( UdpServerSocket * serverSocket, IPaddress ip, int userId, byte randomByte )
+{
+  this->init();
+  this->ip = ip;
+  this->serverSocket = serverSocket;
+  this->userId = userId;
+  this->randomByte = randomByte;
+}
+
+/**
+ * destructor
+ */
+UdpSocket::~UdpSocket( )
+{
+  this->disconnectServer();
+
+  if ( serverSocket )
+    serverSocket->removeUser( userId );
+
+  if ( this->packet )
+    SDLNet_FreePacket( this->packet );
+
+  if ( socket )
+    SDLNet_UDP_Close( socket );
+}
+
+/**
+ * connect to server
+ * @param host host name
+ * @param port port number
+ */
+void UdpSocket::connectToServer( std::string host, int port )
+{
+  assert( serverSocket == NULL );
+
+  this->randomByte = generateNewRandomByte();
+
+  PRINTF(0)("connect to server %s on port %d\n", host.c_str(), port);
+
+  if ( SDLNet_ResolveHost( &this->ip, host.c_str(), port ) != 0 )
+  {
+    PRINTF(1)("SDLNet_ResolveHost: %s\n", SDLNet_GetError() );
+    bOk = false;
+    return;
+  }
+
+  socket = SDLNet_UDP_Open(0);
+  if ( !socket )
+  {
+    PRINTF(1)("SDLNet_UDP_Open: %s\n", SDLNet_GetError() );
+    bOk = false;
+    return;
+  }
+
+  int channel = SDLNet_UDP_Bind(socket, 1, &this->ip);
+  if ( channel == -1 )
+  {
+    PRINTF(1)("SDLNet_UDP_Bind: %s\n", SDLNet_GetError());
+    bOk = false;
+    return;
+  }
+}
+
+/**
+ * disconnect from server
+ */
+void UdpSocket::disconnectServer( )
+{
+  PRINTF(0)("disconnect\n");
+  byte cmd = this->randomByte | UDPCMD_DISCONNECT;
+  writeRawPacket( &cmd, 1 );
+  SDLNet_UDP_Unbind( socket, -1 );
+  SDLNet_UDP_Close( socket );
+  bOk = false;
+  socket = NULL;
+
+  this->ip.host = 0;
+  this->ip.port = 0;
+}
+
+
+/**
+ * reconnects to
+ * @param host new server address
+ * @param port new port number
+ *
+ * this terminates the current connection and starts a new connection to the new server
+ */
+void UdpSocket::reconnectToServer( std::string host, int port)
+{
+  // first disconnect the old server
+  this->disconnectServer();
+
+  // now connect to the new
+  this->connectToServer( host, port);
+}
+
+
+/**
+ * reconnects to
+ * @param host new server address
+ * @param port new port number
+ *
+ * this terminates the current connection and starts a new connection to the new server
+ */
+void UdpSocket::reconnectToServerSoft( std::string host, int port)
+{}
+
+
+/**
+ * send one packet to other host
+ * @param data pointer to data which will be sent
+ * @param length length of data
+ * @return true on success
+ */
+bool UdpSocket::writePacket( byte * data, int length )
+{
+  byte * buf = new byte[length+1];
+  if ( length > 0 )
+    memcpy( buf+1, data, length );
+  buf[0] = this->randomByte;
+  return writeRawPacket( buf, length+1 );
+}
+
+/**
+ * recieve one packet from another host
+ * @param data pointer to buffer to copy data into
+ * @param maxLength maximal length of buffer
+ * @return less than 0 on error, number bytes read else
+ */
+int UdpSocket::readPacket( byte * data, int maxLength )
+{
+  assert( maxLength <= UDP_PACKET_SIZE );
+
+  if ( serverSocket )
+  {
+    NetworkPacket networkPacket = serverSocket->getPacket( this->userId );
+
+    byte udpCmd = 0;
+
+    if ( networkPacket.length > 0 )
+    {
+      assert( maxLength > networkPacket.length );
+
+      memcpy( data, networkPacket.data+1, networkPacket.length-1 );
+      udpCmd = networkPacket.data[0];
+    }
+    else
+      return 0;
+
+    if ( !checkRandomByte( networkPacket.data[0] ) )
+      return 0;
+
+    if ( networkPacket.data )
+    {
+      free( networkPacket.data );
+      networkPacket.data = NULL;
+    }
+
+    if ( !checkUdpCmd( udpCmd ) )
+      return 0;
+
+    return networkPacket.length-1;
+  }
+  else
+  {
+    int numrecv = SDLNet_UDP_Recv( socket, packet);
+
+    byte udpCmd = 0;
+
+    if ( numrecv > 0)
+    {
+      assert( packet->len <= maxLength );
+
+      if ( packet->len > 0 )
+        memcpy( data, packet->data+1, packet->len-1 );
+      else
+        return 0;
+
+      if ( !checkRandomByte( packet->data[0] ) )
+        return 0;
+
+      if ( !checkUdpCmd( udpCmd ) )
+        return 0;
+
+      return packet->len-1;
+    }
+    else if ( numrecv < 0 )
+    {
+      PRINTF(1)("SDLNet_UDP_Recv: %s\n", SDLNet_GetError());
+      bOk = false;
+      return -1;
+    }
+    else
+    {
+      return 0;
+    }
+  }
+
+  return 0;
+}
+
+bool UdpSocket::writeRawPacket( byte * data, int length )
+{
+  if ( serverSocket )
+  {
+    NetworkPacket networkPacket;
+    networkPacket.length = length;
+    networkPacket.data = data;
+    if ( !serverSocket->sendPacket( networkPacket, this->userId ) )
+    {
+      bOk = false;
+      return false;
+    }
+    else
+      return true;
+  }
+  else
+  {
+    assert( length <= packet->maxlen );
+
+    memcpy( packet->data, data, length );
+    packet->len = length;
+
+    if ( socket && SDLNet_UDP_Send( socket, 1, packet) == 0 )
+    {
+      PRINTF(1)("SDLNet_UDP_Send: %s\n", SDLNet_GetError());
+      bOk = false;
+      return false;
+    }
+
+    return true;
+  }
+}
+
+bool UdpSocket::checkUdpCmd( byte udpCmd )
+{
+  if ( udpCmd & UDPCMD_DISCONNECT )
+  {
+    this->disconnectServer();
+    PRINTF(0)("received disconnect byte\n");
+    return false;
+  }
+
+  if ( !this->serverSocket && ( udpCmd & UDPCMD_INVALIDRNDBYTE ) )
+  {
+    PRINTF(0)("received invlid random number byte\n");
+    byte cmd = this->randomByte | UDPCMD_DISCONNECT;
+    writeRawPacket( &cmd, 1 );
+    this->randomByte = generateNewRandomByte();
+    return false;
+  }
+
+  return true;
+}
+
+byte UdpSocket::generateNewRandomByte( )
+{
+  srand( SDL_GetTicks() );
+  byte res = ( rand() & 0xFC );
+
+  PRINTF(0)("generated random byte: %x\n", res);
+
+  return res;
+}
+
+bool UdpSocket::checkRandomByte( byte rndByte )
+{
+  if ( ( rndByte & 0xFC ) == this->randomByte )
+  {
+    return true;
+  }
+  else
+  {
+    PRINTF(2)("wrong random byte: %x\n", ( rndByte & 0xFC ));
+    return false;
+  }
+}
+
+
+
Index: branches/heathaze/src/lib/network/udp_socket.h
===================================================================
--- branches/heathaze/src/lib/network/udp_socket.h	(revision 9940)
+++ branches/heathaze/src/lib/network/udp_socket.h	(revision 9940)
@@ -0,0 +1,63 @@
+/*!
+ * @file upd_socket.h
+ *  class to connect to other clients via udp
+ */
+
+#ifndef _UDP_SOCKET
+#define _UDP_SOCKET
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "network_socket.h"
+
+class UdpServerSocket;
+
+enum
+{
+  UDPCMD_DISCONNECT = 1,
+  UDPCMD_INVALIDRNDBYTE = 2
+};
+
+class UdpSocket : public NetworkSocket
+{
+  ObjectListDeclaration(UdpSocket);
+  public:
+    UdpSocket();
+    UdpSocket( UdpServerSocket * serverSocket, IPaddress ip, int userId, byte randomByte );
+    UdpSocket( std::string host, int port );
+    virtual ~UdpSocket();
+
+    virtual void connectToServer( std::string host, int port );
+    virtual void disconnectServer();
+
+    virtual void reconnectToServer( std::string host, int port);
+    virtual void reconnectToServerSoft( std::string host, int port);
+
+    virtual bool writePacket(byte * data, int length );
+    virtual int readPacket(byte * data, int maxLength);
+
+
+  private:
+    void init();
+
+    bool writeRawPacket( byte * data, int length );
+    bool checkUdpCmd( byte udpCmd );
+    bool checkRandomByte( byte rndByte );
+    byte generateNewRandomByte();
+
+
+  private:
+    UdpServerSocket * serverSocket;   //!< will get packets here
+    int               userId;         //!< user id used by serverSocket
+    UDPsocket         socket;         //!< socket used to send/recieve
+    UDPpacket *       packet;
+
+    byte              randomByte;     //!< contains random bytes & 0xFC
+};
+
+
+
+#endif /* _NETWORK_SOCKET */
Index: branches/heathaze/src/lib/network/zip.cc
===================================================================
--- branches/heathaze/src/lib/network/zip.cc	(revision 9940)
+++ branches/heathaze/src/lib/network/zip.cc	(revision 9940)
@@ -0,0 +1,253 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+#include "zip.h"
+#include "loading/resource_manager.h"
+#include "debug.h"
+
+/**
+ *  the singleton reference to this class
+ */
+Zip* Zip::singletonRef = NULL;
+
+
+/**
+ * standard constructor
+ */
+Zip::Zip()
+{
+
+}
+
+
+/**
+ * @brief standard deconstructor
+ */
+Zip::~Zip()
+{
+  Zip::singletonRef = NULL;
+}
+
+/**
+ * load a dictionary to unzip. you can load more than one dictionary
+ * if you call unzip with data from zip without loading the same dictionary
+ * used with zip unzip will fail
+ * @param name name of dictionary
+ * @return true on success
+ */
+int Zip::loadDictionary( std::string name )
+{
+  std::string fileName = Resources::ResourceManager::getInstance()->mainGlobalPath().name();
+  //PRINTF(0)("datadir: %s\n", fileName.c_str());
+  fileName = fileName + "/dicts/" + name;
+  //PRINTF(0)("filename: %s\n", fileName.c_str());
+
+  FILE * f = fopen( fileName.c_str(), "r" );
+
+  if ( !f )
+  {
+    PRINTF(1)("Could not open %d\n", fileName.c_str());
+    return -1;
+  }
+
+  byte buf[1024];
+
+  int nBytesRead = 0;
+
+  while ( !feof( f ) )
+  {
+    nBytesRead += fread( buf, 1, sizeof(buf), f );
+  }
+
+  DictionaryEntry entry;
+
+  entry.dictLen = nBytesRead;
+  entry.dict = new Byte[nBytesRead];
+
+  fseek( f, 0, SEEK_SET );
+
+  assert( fread( entry.dict, 1, nBytesRead, f ) == nBytesRead );
+
+  entry.adler = adler32( adler32( 0L, Z_NULL, 0 ), entry.dict, nBytesRead );
+
+  dicts.push_back( entry );
+
+  PRINTF(3)("Loaded dictionary '%s' with adler = %d\n", name.c_str(), entry.adler );
+
+  return dicts.size()-1;
+}
+
+/**
+ * zip data. you must call loadDictionary before
+ * @param from data to compress
+ * @param fromLength length of data to compress
+ * @param to pointer to compressed data
+ * @param maxLength max bytes to compress
+ * @param dict dictionary to use. default is 0
+ * @return num bytes writen to to
+ */
+int Zip::zip( byte * from, int fromLength, byte * to, int maxLength, int dict )
+{
+  if ( dicts.size() < dict+1 )
+  {
+    PRINTF(1)("you cannot use dict nr %d. num dicts: %d\n", dict, dicts.size() );
+    return -1;
+  }
+
+  int res;
+
+  z_stream strm;
+
+  strm.zalloc = Z_NULL;
+  strm.zfree = Z_NULL;
+  strm.opaque = Z_NULL;
+
+  res = deflateInit( &strm, 9 );
+
+  if ( res != Z_OK )
+  {
+    PRINTF(1)("deflateInit error: %s\n", strm.msg);
+    return -1;
+  }
+
+  res = deflateSetDictionary( &strm, (Bytef*)(dicts[dict].dict), dicts[dict].dictLen );
+
+  if ( res != Z_OK )
+  {
+    PRINTF(1)("deflateSetDictionary error: %s\n", strm.msg);
+    return -1;
+  }
+
+  strm.next_out = (Bytef*)to;
+  strm.avail_out = maxLength;
+  assert( strm.total_out == 0 );
+  strm.next_in = (Bytef*)from;
+  strm.avail_in = fromLength;
+  assert( strm.total_in == 0 );
+
+  res = deflate( &strm, Z_FINISH );
+
+  if ( res != Z_STREAM_END )
+  {
+    PRINTF(1)("buffer to small or deflate error: %s\n", strm.msg);
+    return -1;
+  }
+
+  assert( strm.avail_out != 0 );
+  assert( strm.avail_in == 0 );
+
+  int zippedlen = strm.total_out;
+
+  res = deflateEnd( &strm );
+
+  if ( res != Z_OK )
+  {
+    if ( res == Z_STREAM_ERROR )
+      PRINTF(1)("deflateEnd error: Z_STREAM_ERROR\n");
+    else if ( res == Z_DATA_ERROR )
+      PRINTF(1)("deflateEnd error: Z_DATA_ERROR %s\n", strm.msg);
+    else
+      PRINTF(1)("deflateEnd error: dont know\n");
+
+    return -1;
+  }
+
+  return zippedlen;
+
+}
+
+/**
+ * uncompress data. same dict as used in zip must be loaded
+ * @param from compressed data
+ * @param fromLength length of compressed data
+ * @param to buffer to copy uncompressed data to
+ * @param maxLength max bytes to copy to to
+ * @return num bytes writen to to
+ */
+int Zip::unZip( byte * from, int fromLength, byte * to, int maxLength )
+{
+  z_stream strm;
+  int res = 0;
+
+  strm.zalloc = Z_NULL;
+  strm.zfree = Z_NULL;
+  strm.opaque = Z_NULL;
+
+  res = inflateInit( &strm );
+
+  if ( res != Z_OK )
+  {
+    PRINTF(1)("inflateInit error: %s\n", strm.msg);
+    return -1;
+  }
+
+  strm.next_out = (Bytef*)to;
+  strm.avail_out = maxLength;
+  assert( strm.total_out == 0 );
+  strm.next_in = (Bytef*)from;
+  strm.avail_in = fromLength;
+  assert( strm.total_in == 0 );
+
+  assert( inflate( &strm, Z_NO_FLUSH ) == Z_NEED_DICT );
+
+  int dictId = -1;
+
+  for ( int i = 0; i < dicts.size(); i++ )
+  {
+    if ( dicts[i].adler == strm.adler )
+    {
+      dictId = i;
+      break;
+    }
+  }
+
+  if ( dictId == -1 )
+  {
+    PRINTF(1)("Could not find dict used to compress this packet! ( adler = %d )\n", strm.adler);
+    return -1;
+  }
+
+  res = inflateSetDictionary( &strm, (Bytef*)dicts[dictId].dict, dicts[dictId].dictLen );
+
+  if ( res != Z_OK )
+  {
+    PRINTF(1)("inflateSetDictionary error: %s\n", strm.msg);
+    return -1;
+  }
+
+
+  res = inflate( &strm, Z_FINISH );
+
+  if ( res != Z_STREAM_END )
+  {
+    PRINTF(1)("inflate error: %s\n", strm.msg);
+    return -1;
+  }
+
+  assert( strm.avail_out != 0 );
+  assert( strm.avail_in == 0 );
+
+  int unzippedlen = strm.total_out;
+
+  res = inflateEnd( &strm );
+
+  if ( res != Z_OK )
+  {
+    PRINTF(1)("inflateEnd error: %s\n", strm.msg);
+    return -1;
+  }
+
+  return unzippedlen;
+}
Index: branches/heathaze/src/lib/network/zip.h
===================================================================
--- branches/heathaze/src/lib/network/zip.h	(revision 9940)
+++ branches/heathaze/src/lib/network/zip.h	(revision 9940)
@@ -0,0 +1,43 @@
+/*!
+ * @file zip.h
+ * @brief Definition of the Zip singleton Class
+ */
+
+#ifndef _ZIP_H
+#define _ZIP_H
+
+#include <zlib.h>
+#include <string>
+#include <vector>
+
+#include "netdefs.h"
+
+struct DictionaryEntry
+{
+  byte * dict;
+  int    dictLen;
+  uLong  adler;
+};
+
+//! A class for compressing/uncompressing packes.
+class Zip
+{
+  public:
+    virtual ~Zip(void);
+    /** @returns a Pointer to the only object of this Class */
+    inline static Zip* getInstance(void) { if (!singletonRef) singletonRef = new Zip();  return singletonRef; };
+
+    int loadDictionary( std::string name );
+    int zip( byte * from, int fromLength, byte * to, int maxLength, int dict = 0 );
+    int unZip( byte * from, int fromLength, byte * to, int maxLength );
+
+    int getDictCount(){ return dicts.size(); }
+
+  private:
+    Zip();
+    static Zip* singletonRef;
+
+    std::vector<DictionaryEntry> dicts;
+};
+
+#endif /* _ZIP_H */
Index: branches/heathaze/src/lib/parser/Makefile.am
===================================================================
--- branches/heathaze/src/lib/parser/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/parser/Makefile.am	(revision 9940)
@@ -0,0 +1,7 @@
+SUBDIRS = \
+          tinyxml \
+	  ini_parser \
+	  cmdline_parser \
+	  preferences
+
+
Index: branches/heathaze/src/lib/parser/cmdline_parser/Makefile.am
===================================================================
--- branches/heathaze/src/lib/parser/cmdline_parser/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/parser/cmdline_parser/Makefile.am	(revision 9940)
@@ -0,0 +1,12 @@
+
+INCLUDES = -I../../..
+
+noinst_LIBRARIES = libCmdLineParser.a
+
+libCmdLineParser_a_SOURCES = cmdline_parser.cc
+
+libCmdLineParser_a_CPPFLAGS = "-DNO_SHELL"
+
+noinst_HEADERS = cmdline_parser.h
+
+
Index: branches/heathaze/src/lib/parser/cmdline_parser/cmdline_parser.cc
===================================================================
--- branches/heathaze/src/lib/parser/cmdline_parser/cmdline_parser.cc	(revision 9940)
+++ branches/heathaze/src/lib/parser/cmdline_parser/cmdline_parser.cc	(revision 9940)
@@ -0,0 +1,285 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer:
+*/
+
+#include "cmdline_parser.h"
+
+#include <cassert>
+#include "src/lib/util/substring.h"
+
+
+
+
+/**
+ * standard constructor
+ */
+CmdLineParser::CmdLineParser ()
+{
+}
+
+
+/**
+ * standard deconstructor
+ */
+CmdLineParser::~CmdLineParser ()
+{
+}
+
+
+bool CmdLineParser::add( int id, const std::string & longOption, char shortOption, int numArgs, const std::string & argNames, const std::string& help, bool back )
+{
+  ArgTableEntry entry;
+
+  entry.id = id;
+  entry.longOption = longOption;
+  entry.shortOption = shortOption;
+  entry.numArgs = numArgs;
+  entry.argNames = argNames;
+  entry.help = help;
+
+  if ( back )
+    argTable.push_back( entry );
+  else
+    argTable.push_front( entry );
+  return true;
+}
+
+
+bool CmdLineParser::parse( ArgParserCallback cb, void * data, int argc, char ** argv )
+{
+  this->exeName = argv[0];
+
+  //put all args in vector
+  std::vector<std::string> args;
+
+  for ( int i = 1; i<argc; i++ )
+  {
+    std::string s = argv[i];
+
+    if ( s.find( "=" ) == std::string::npos )
+    {
+      if ( s.length() > 2 && s[0] == '-' && s[1] != '-' )
+      {
+        for (unsigned int j = 1; j < s.length(); j++ )
+        {
+          std::string t = "-";
+          t += s[j];
+          args.push_back( t );
+        }
+      }
+      else
+      {
+        args.push_back(s);
+      }
+    }
+    else
+    {
+      std::string op = s;
+      std::string ar = s;
+      op.erase( op.find("=") );
+      ar.erase( 0, ar.find("=")+1);
+
+      //PRINTF(0)("'%s' '%s'\n", op.c_str(), ar.c_str());
+      args.push_back( op );
+      args.push_back( ar );
+    }
+  }
+
+  unsigned int i = 0;
+
+  ArgTable::iterator it;
+  bool finish;
+  bool found;
+
+  while ( i < args.size() )
+  {
+    found = false;
+    for ( it = argTable.begin(); it != argTable.end(); it++ )
+    {
+      if ( matches( *it, args[i], finish ) )
+      {
+        found = true;
+
+        unsigned int posArgs = 1;
+
+        while ( i + posArgs < args.size() )
+        {
+          if ( args[ i + posArgs ].length() > 0 && args[ i + posArgs ][0] == '-' )
+            break;
+          else
+            posArgs++;
+        }
+
+        posArgs--;
+
+        if ( it->numArgs > posArgs )
+        {
+          PRINTF(1)( "%s needs %d arguments!\n", args[i].c_str(), it->numArgs );
+          return false;
+        }
+
+        std::vector<MultiType> argArgs;
+
+        for (unsigned int j = 1; j <= it->numArgs; j++ )
+          argArgs.push_back( args[i+j] );
+
+        if ( !cb( *it, data, args[i], argArgs ) )
+          return false;
+
+        i += it->numArgs;
+
+        if ( finish )
+        {
+          i++;
+          break;
+        }
+        else
+        {
+          assert( it->numArgs == 0 );
+        }
+      }
+    }
+
+    if ( !found )
+    {
+      PRINTF(1)("%s: illegal option\n", args[i].c_str());
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool CmdLineParser::matches( ArgTableEntry entry, std::string arg, bool & finish )
+{
+  finish = true;
+
+  if ( arg.length() < 2 )
+    return false;
+
+  if ( arg[0] == '-' )
+  {
+    if ( arg[1] == '-' )
+    {
+      arg.erase( 0, 2 );
+
+      if ( entry.longOption.find('%') != std::string::npos )
+      {
+        //TODO implement bether match algo
+        assert( entry.longOption.find('%') == entry.longOption.length()-1 );
+        std::string lo = entry.longOption;
+        lo.erase( lo.length()-1, 1 );
+        //PRINTF(0)("%s %s\n", arg.c_str(), lo.c_str());
+        return arg.find( lo ) == 0;
+      }
+      else
+      {
+        return arg.find( entry.longOption ) != std::string::npos;
+      }
+    }
+    else
+    {
+      if ( arg.find(entry.shortOption) != std::string::npos && arg.length() != 2 && entry.numArgs != 0 )
+      {
+        PRINTF(1)("using multiple flags together is only alowed if none needs an arugument. %c needs %d arguments\n", entry.shortOption, entry.numArgs);
+        //FIXME find beter solution
+        exit(1);
+        return false;
+      }
+      finish = arg.length()==2;
+      return arg.find(entry.shortOption) != std::string::npos;
+    }
+  }
+  else
+    return false;
+}
+
+void CmdLineParser::showHelp()
+{
+  printf("Usage: %s [options]\n", exeName.c_str());
+  printf("\n");
+
+  std::list<std::vector<std::string> > output;
+
+  for ( ArgTable::iterator it = argTable.begin(); it != argTable.end(); it++ )
+  {
+    output.push_back( std::vector<std::string>() );
+
+    SubString substr( it->argNames );
+    std::string args;
+    assert( it->numArgs == substr.size() );
+
+    for (unsigned int i = 0; i<it->numArgs; i++ )
+    {
+      args += " [" + substr[i] + "]";
+    }
+
+    if ( it->shortOption != '\0' )
+    {
+      output.back().push_back( " -" + std::string((char*)&it->shortOption, 1) );
+      output.back().back() += args;
+    }
+    else
+      output.back().push_back( "" );
+
+    if ( it->longOption != "" )
+    {
+      output.back().push_back( "--" + it->longOption );
+
+      output.back().back() += args;
+    }
+    else
+      output.back().push_back( "" );
+
+    output.back().push_back( it->help );
+  }
+
+  output.push_back( std::vector<std::string>() );
+  output.back().push_back( "Option" );
+  output.back().push_back( "Long option" );
+  output.back().push_back( "Description" );
+
+  output.reverse();
+
+  unsigned int maxShort = 0;
+  unsigned int maxLong = 0;
+
+  std::list<std::vector<std::string> >::const_iterator it;
+
+  for ( it = output.begin(); it != output.end(); it++ )
+  {
+    if ( (*it)[0].length() > maxShort )
+      maxShort = (*it)[0].length();
+
+    if ( (*it)[1].length() > maxLong )
+      maxLong = (*it)[1].length();
+  }
+
+  for ( it = output.begin(); it != output.end(); it++ )
+  {
+    printf("%s ", (*it)[0].c_str());
+
+    for (unsigned  int i = 0; i<maxShort-(*it)[0].length(); i++ )
+      printf(" ");
+
+    printf("%s ", (*it)[1].c_str());
+
+    for (unsigned int i = 0; i<maxLong-(*it)[1].length(); i++ )
+      printf(" ");
+
+    printf("%s\n", (*it)[2].c_str());
+  }
+
+  exit(0);
+}
Index: branches/heathaze/src/lib/parser/cmdline_parser/cmdline_parser.h
===================================================================
--- branches/heathaze/src/lib/parser/cmdline_parser/cmdline_parser.h	(revision 9940)
+++ branches/heathaze/src/lib/parser/cmdline_parser/cmdline_parser.h	(revision 9940)
@@ -0,0 +1,53 @@
+/*!
+ * @file cmdline_parser.h
+ * @brief Definition of ...
+ */
+
+#ifndef _CMD_LINE_PARSER_H
+#define _CMD_LINE_PARSER_H
+
+#include <list>
+#include <string>
+#include <vector>
+
+#include "lib/util/debug.h"
+#include "lib/util/multi_type.h"
+
+
+struct ArgTableEntry
+{
+  unsigned int    id;
+  std::string     longOption;
+  char            shortOption;
+  unsigned int    numArgs;
+  std::string     argNames;
+  std::string     help;
+};
+
+typedef std::list<ArgTableEntry> ArgTable;
+
+typedef bool (*ArgParserCallback)( ArgTableEntry, void*, const std::string &, const std::vector<MultiType> & );
+
+
+//! A class for parsing command line arguments
+class CmdLineParser {
+
+  public:
+    CmdLineParser();
+    virtual ~CmdLineParser();
+
+    bool add( int id, const std::string& longOption, char shortOption, int numArgs, const std::string & argNames, const std::string& help, bool back=false );
+
+    bool parse( ArgParserCallback cb, void* data, int argc, char** argv );
+
+    void showHelp();
+
+  private:
+    ArgTable argTable;
+    std::string exeName;
+
+    inline bool matches( ArgTableEntry entry, std::string arg, bool & finish );
+
+};
+
+#endif /* _CMD_LINE_PARSER_H */
Index: branches/heathaze/src/lib/parser/ini_parser/Makefile.am
===================================================================
--- branches/heathaze/src/lib/parser/ini_parser/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/parser/ini_parser/Makefile.am	(revision 9940)
@@ -0,0 +1,12 @@
+INCLUDES = -I../../..
+
+
+noinst_LIBRARIES = libIniParser.a
+
+libIniParser_a_SOURCES = ini_parser.cc
+
+libIniParser_a_CPPFLAGS = "-DNO_SHELL"
+
+noinst_HEADERS = ini_parser.h
+
+
Index: branches/heathaze/src/lib/parser/ini_parser/ini_parser.cc
===================================================================
--- branches/heathaze/src/lib/parser/ini_parser/ini_parser.cc	(revision 9940)
+++ branches/heathaze/src/lib/parser/ini_parser/ini_parser.cc	(revision 9940)
@@ -0,0 +1,673 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Christian Meyer
+
+   2005-08-14: complete reimplementation:
+               now the File is parsed at the initialisation,
+               and informations is gathered there.
+   2006-10-10: Complete reimplementation again :)
+               New STL-like style. The Parser has no state itself
+               Elements as Nodes
+*/
+/*!
+ * @file ini_parser.cc
+ */
+
+#include "ini_parser.h"
+
+#include <cassert>
+#include <algorithm>
+
+#define PARSELINELENGHT     1024       //!< how many chars to read at once
+
+
+/// /// /// /// /// ///
+/// INI-PARSER NODE ///
+/// /// /// /// /// ///
+/**
+ * @brief Constructs a Node
+ * @param name The name of the Node
+ * @param comment The comment of the Node.
+ */
+IniParser::Node::Node(const std::string& name, const std::string& comment)
+{
+  this->_name = name;
+  this->_comment = comment;
+}
+
+/// /// /// /// /// ////
+/// INI-PARSER ENTRY ///
+/// /// /// /// /// ////
+/**
+ * @brief Constructs a new Entry
+ * @param name the Name of the Entry
+ * @param value The name of the Value
+ * @param comment The Comment used for the Entry
+ */
+IniParser::Entry::Entry(const std::string& name, const std::string& value, const std::string& comment)
+    : IniParser::Node(name, comment), _value(value)
+{}
+
+/**
+ * @brief Displays some nice debug info.
+ */
+void IniParser::Entry::debug() const
+{
+  printf("   %s = %s\n", this->name().c_str(), this->_value.c_str());
+}
+
+
+/// /// /// /// /// /// ///
+/// INI-PARSER SECTION  ///
+/// /// /// /// /// /// ///
+/**
+ * @brief constructs a new Section
+ * @param sectionName The name of the Section
+ * @param comment The Comment for this section
+ */
+IniParser::Section::Section(const std::string& sectionName, const std::string& comment)
+    : IniParser::Node(sectionName, comment)
+{}
+
+/**
+ * @brief Adds a new Entry to this Section
+ * @param entryName The name of the Entry
+ * @param value The Value of the Section
+ * @param comment The Comment
+ * @returns Reference to the Entry added.
+ * @see IniParser::Entry::Entry
+ */
+IniParser::Entry& IniParser::Section::addEntry(const std::string& entryName, const std::string& value, const std::string& comment)
+{
+  Entry::iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
+  if (entry == this->_entries.end())
+  {
+    this->_entries.push_back(Entry(entryName, value, comment));
+    entry = --this->_entries.end();
+  }
+  return *entry;
+}
+
+/**
+ * @brief edits an Entry's Value
+ * @param entryName The Entry to edit
+ * @param value The Value to change
+ * @param createMissing If the Entry is missing it is created if true.
+ * @return true on success.
+ */
+bool IniParser::Section::editEntry(const std::string& entryName, const std::string& value, bool createMissing)
+{
+  Entry::iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
+  if (entry == this->_entries.end())
+  {
+    if (createMissing)
+    {
+      this->addEntry(entryName, value);
+      return true;
+    }
+    else
+      return false;
+  }
+  (*entry).setValue(value);
+  return true;
+}
+
+/**
+ * @param entryName The name of the entry to search for
+ * @param defaultValue The returned value, if the entry is not found
+ * @return The Value of the Entry, or defaultValue, if not found.
+ */
+const std::string& IniParser::Section::getValue(const std::string& entryName, const std::string& defaultValue) const
+{
+  Entry::const_iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
+  if (entry != this->_entries.end())
+    return (*entry).value();
+  else
+    return defaultValue;
+}
+
+/**
+ * @brief sets a Comment to an Entry
+ * @param entryName The Name of the Entry to set the comment to.
+ * @param comment the Comment.
+ * @return true on success (entry found and setup).
+ */
+bool IniParser::Section::setEntryComment(const std::string& entryName, const std::string& comment)
+{
+  Entry::iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
+  if (entry != this->_entries.end())
+  {
+    (*entry).setComment(comment);
+    return true;
+  }
+  return false;
+}
+
+/**
+ * @brief retrieves a Comment of an Entry
+ * @param entryName The Entry to get the comment of.
+ * @return The Comment, or "" if the Entry was not found.
+ */
+const std::string& IniParser::Section::getEntryComment(const std::string& entryName) const
+{
+  Entry::const_iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
+  if (entry != this->_entries.end())
+  {
+    return (*entry).comment();
+  }
+  return IniParser::_emptyString;
+}
+
+
+/**
+ * @brief retrieves a pointer to an Entry
+ * @param entryName The Name of the Entry.
+ * @return the located Entry or NULL!
+ * @note beware of NULL!
+ */
+IniParser::Entry* IniParser::Section::getEntry(const std::string& entryName)
+{
+  Entry::iterator entry = std::find(this->_entries.begin(), this->_entries.end(), entryName);
+  if (entry != this->_entries.end())
+    return &(*entry);
+  else
+    return NULL;
+}
+
+/**
+ * @brief retrieves an Iterator to an Entry called entryName within this section
+ * @param entryName the name of the Entry
+ * @return The iterator to the position, or end();
+ * @see Section::end();
+ */
+IniParser::Entry::const_iterator IniParser::Section::getEntryIt(const std::string& entryName) const
+{
+  return std::find(this->_entries.begin(), this->_entries.end(), entryName);
+}
+
+/**
+ * @brief clears the Section's entries (flushes them)
+ */
+void IniParser::Section::clear()
+{
+  this->_entries.clear();
+}
+
+/**
+ * @brief print out some debug info
+ */
+void IniParser::Section::debug() const
+{
+  printf(" [%s]\n", this->name().c_str());
+  for(Entry::const_iterator entry = this->_entries.begin(); entry != this->_entries.end(); ++entry)
+    (*entry).debug();
+}
+
+
+
+/// /// /// /// /// /// ///
+/// INI-PARSER DOCUMENT ///
+/// /// /// /// /// /// ///
+/**
+ * @brief Constructs a new Document
+ * @param fileName The Name of the Document.
+ * @param comment Some Comment
+ */
+IniParser::Document::Document(const std::string& fileName, const std::string& comment)
+    : IniParser::Node(fileName, comment)
+{}
+
+/**
+ * @brief Adds a new Section to the Document
+ * @param sectionName The Name of the Section to add
+ * @param comment A comment for the section.
+ * @return A Reference to the newly added section.
+ */
+IniParser::Section& IniParser::Document::addSection(const std::string& sectionName, const std::string& comment)
+{
+  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
+  if (section == this->_sections.end())
+  {
+    this->_sections.push_back(Section(sectionName, comment));
+    return *(--_sections.end());
+  }
+  else
+    return *section;
+}
+
+/**
+ * @brief removes a Section from the Document.
+ * @param sectionName The section to remove
+ * @return true on success (section was found).
+ */
+bool IniParser::Document::removeSection(const std::string& sectionName)
+{
+  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
+  if (section != this->_sections.end())
+  {
+    this->_sections.erase(section);
+    return true;
+  }
+  else
+    return false;
+}
+
+/**
+ * @brief Sets a comment to a section
+ * @param sectionName The name of the section
+ * @param comment The Comment.
+ * @return True on success (section was found).
+ */
+bool IniParser::Document::setSectionsComment(const std::string& sectionName, const std::string& comment)
+{
+  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
+  if (section != this->_sections.end())
+  {
+    (*section).setComment(comment);
+    return true;
+  }
+  else
+    return false;
+}
+
+/**
+ * @brief Retrieves the comment for a specified section
+ * @param sectionName The name of the section
+ * @returns The Comment of the section.
+ */
+const std::string& IniParser::Document::getSectionsComment(const std::string& sectionName) const
+{
+  Section::const_iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
+  if (section != this->_sections.end())
+  {
+    return (*section).comment();
+  }
+  else
+    return IniParser::_emptyString;
+}
+
+/**
+ * @brief Queries for a Section within the document returning a Pointer to it
+ * @param sectionName The Section to search for.
+ * @return A pointer to the section, of NULL if not found.
+ * @brief beware of the NULL-pointer!
+ */
+IniParser::Section* IniParser::Document::getSection(const std::string& sectionName)
+{
+  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
+  if (section != this->_sections.end())
+  {
+    return &(*section);
+  }
+  else
+    return NULL;
+}
+
+/**
+ * @brief Queries for a Section within the document returning a Pointer to it
+ * @param sectionName The Section to search for.
+ * @return An iterator to the Section, or end()
+ * @see Section::end().
+ */
+IniParser::Section::const_iterator IniParser::Document::getSectionIt(const std::string& sectionName) const
+{
+  Section::const_iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
+  return section;
+}
+
+/**
+ * @brief adds a new Entry to a designated section.
+ * @param sectionName The name of the Section
+ * @param entryName The Name of the Entry to add
+ * @param value The Value to set for the entry
+ * @param comment optionally a comment.
+ * @return true on success (always true)
+ *
+ * @note the section will also be created on the go, if it did not exists so far!
+ */
+bool IniParser::Document::addEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, const std::string& comment)
+{
+  // locating section
+  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
+  if (section == this->_sections.end())
+  {
+    // creating section if not found!!
+    this->_sections.push_back(Section(sectionName));
+    section = --_sections.end();
+  }
+
+  (*section).addEntry(entryName, value, comment);
+  return true;
+}
+
+/**
+ * @brief edits an Entry, and possibly creating it.
+ * @param sectionName The Section's name to edit the entry in.
+ * @param entryName The Name of the Entry to edit the value from
+ * @param value The new value for the Entry.
+ * @param createMissing if true, the Entry, (and the section) will be created.
+ * @return true on success, false otherwise.
+ */
+bool IniParser::Document::editEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, bool createMissing)
+{
+  // locating section
+  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
+  if (section == this->_sections.end())
+  {
+    // creating section if not found!!
+    if (createMissing)
+    {
+      this->_sections.push_back(Section(sectionName));
+      section = --_sections.end();
+    }
+    else
+      return false;
+  }
+
+  return (*section).editEntry(entryName, value, createMissing);
+}
+
+/**
+ * @brief Retrieve a value from an Entry.
+ * @param sectionName The Name of the Section the enrty is in
+ * @param entryName The Name of the entry
+ * @param defaultValue A default value, if the entry is not found
+ * @return A string containing the value, or defaultValue, if the Section->Entry was not found.
+ */
+const std::string& IniParser::Document::getValue(const std::string& sectionName, const std::string& entryName, const std::string& defaultValue) const
+{
+  // locating section
+  Section::const_iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
+  if (section != this->_sections.end())
+    return (*section).getValue(entryName, defaultValue);
+  return defaultValue;
+}
+
+/**
+ * @brief Sets a Comment to an Entry.
+ * @param sectionName The name of the Section.
+ * @param entryName The name of the Entry.
+ * @param comment The comment to set to this Entry
+ * @return true on success (Section->Entry found).
+ */
+bool IniParser::Document::setEntryComment(const std::string& sectionName, const std::string& entryName, const std::string& comment)
+{
+  // locating section
+  Section::iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
+  if (section != this->_sections.end())
+    return (*section).setEntryComment(entryName, comment);
+  else
+    return false;
+}
+
+/**
+ * @brief retrieved the comment of an Entry.
+ * @param sectionName The section.
+ * @param entryName The Entry to get the comment from
+ * @return the Comment of the Entry.
+ */
+const std::string& IniParser::Document::getEntryComment(const std::string& sectionName, const std::string& entryName) const
+{
+  Section::const_iterator section = std::find(this->_sections.begin(), this->_sections.end(), sectionName);
+  if (section != this->_sections.end())
+    return (*section).getEntryComment(entryName);
+  else
+    return IniParser::_emptyString;
+}
+
+/**
+ * @brief clears all sections.
+ */
+void IniParser::Document::clear()
+{
+  this->_sections.clear();
+}
+
+/**
+ * @brief Print some nice debug output.
+ */
+void IniParser::Document::debug() const
+{
+  for(Section::const_iterator section = this->_sections.begin(); section != this->_sections.end(); ++section)
+    (*section).debug();
+}
+
+
+
+
+/// /// /// /// /// /// //
+/// INI-PARSER ITSELF ////
+/// /// /// /// /// /// //
+const std::string IniParser::_emptyString = "";
+/**
+ * @brief constructs an IniParser using a file
+ * @param fileName: the path and name of the file to parse
+ */
+IniParser::IniParser (const std::string& fileName)
+    : _document(fileName)
+{
+  this->_fileName = fileName;
+  if (!fileName.empty())
+    this->readFile(fileName);
+}
+
+
+/**
+ * @brief removes the IniParser from memory
+ */
+IniParser::~IniParser ()
+{}
+
+/**
+ * @brief opens a file to parse
+ * @param fileName: path and name of the new file to parse
+ * @param keepSettings if the Settings (if already some are set) should be kept (false by default)
+ * @return true on success false otherwise;
+ *
+ * If there was already an opened file, the file will be closed,
+ * and the new one will be opened.
+ */
+bool IniParser::readFile(const std::string& fileName, bool keepSettings)
+{
+  FILE*    stream;           //< The stream we use to read the file.
+  int      lineCount = 0;    //< The Count of lines read.
+  std::list<std::string>  commentList;     //< A list of Comments.
+  Section* currentSection = NULL;
+
+  if (!keepSettings)
+    this->_document.clear();
+
+  if( (stream = fopen (fileName.c_str(), "r")) == NULL)
+  {
+    printf("ERROR:: IniParser could not open %s for reading\n", fileName.c_str());
+    return false;
+  }
+  else
+  {
+    this->_fileName = fileName;
+
+    /////////////////////////////
+    // READING IN THE INI-FILE //
+    /////////////////////////////
+    char lineBuffer[PARSELINELENGHT+1];
+    char buffer[PARSELINELENGHT+1];
+    const char* lineBegin;
+    char* ptr;
+
+    while( fgets (lineBuffer, PARSELINELENGHT, stream))
+    {
+      lineBegin = lineBuffer;
+      // remove newline char, and \0-terminate
+      if( (ptr = strchr( lineBuffer, '\n')) != NULL)
+        *ptr = 0;
+      else
+        lineBuffer[PARSELINELENGHT] = 0;
+      // cut up to the beginning of the line.
+      while((*lineBegin == ' ' || *lineBegin == '\t') && lineBegin < lineBuffer + strlen(lineBuffer))
+        ++lineBegin;
+
+      if ( !strcmp( lineBegin, "" ) )
+        continue;
+
+      // check if we have a FileComment
+      if ( (*lineBegin == '#' || *lineBegin == ';'))
+      {
+        std::string newCommenLine = lineBegin;
+        commentList.push_back(newCommenLine);
+        continue;
+      }
+      if (lineCount == 0 && !commentList.empty())
+      {
+        this->setNodeComment(&this->_document, &commentList);
+        lineCount++;
+      }
+
+      // check for section identifyer
+      else if( sscanf (lineBegin, "[%s", buffer) == 1)
+      {
+        if( (ptr = strchr( buffer, ']')) != NULL)
+        {
+          *ptr = 0;
+          Section& node = this->_document.addSection(buffer);
+          setNodeComment(&node, &commentList);
+          currentSection = &node;
+        }
+      }
+      // check for Entry identifier (Entry = Value)
+      else if( (ptr = strchr( lineBegin, '=')) != NULL)
+      {
+        if (currentSection == NULL)
+        {
+	  printf("WARNING:: Not in a Section yet for %s\n", lineBegin);
+          lineCount++;
+          continue;
+        }
+        if( ptr == lineBegin)
+        {
+          lineCount++;
+          continue;
+        }
+        char* valueBegin = ptr+1;
+        while ((*valueBegin == ' ' || *valueBegin == '\t') && valueBegin <= lineBegin + strlen(lineBegin))
+          ++valueBegin;
+        char* valueEnd = valueBegin + strlen(valueBegin)-1;
+        while ((*valueEnd == ' ' || *valueEnd == '\t') && valueEnd >= valueBegin)
+          --valueEnd;
+        valueEnd[1] = '\0';
+        char* nameEnd = ptr-1;
+        while ((*nameEnd == ' ' || *nameEnd == '\t' ) && nameEnd >= lineBegin)
+          --nameEnd;
+        nameEnd[1] = '\0';
+
+        Entry& node = currentSection->addEntry(lineBegin, valueBegin);
+        this->setNodeComment(&node, &commentList);
+
+        lineCount++;
+      }
+    }
+  }
+  fclose(stream);
+  return true;
+}
+
+
+/**
+ * @brief opens a file and writes to it.
+ * @param fileName: path and name of the new file to write to. If empty the internal value is used.
+ * @return true on success false otherwise
+ */
+bool IniParser::writeFile(const std::string& fileName) const
+{
+  std::string parseFile;
+  FILE*    stream;           //!< The stream we use to read the file.
+  if( fileName.empty())
+    parseFile = _fileName;
+  else
+    parseFile = fileName;
+
+  if( (stream = fopen (parseFile.c_str(), "w")) == NULL)
+  {
+    printf("ERROR:: IniParser could not open %s for writing\n", parseFile.c_str());
+    return false;
+  }
+  else
+  {
+    if (!this->_document.comment().empty())
+      fprintf(stream, "%s\n\n", this->_document.comment().c_str());
+
+    Section::const_iterator section;
+    for (section = this->_document.sections().begin(); section != this->_document.sections().end(); ++section)
+    {
+      if (!(*section).comment().empty())
+        fprintf(stream, "%s", (*section).comment().c_str());
+      fprintf(stream, "\n [%s]\n", (*section).name().c_str());
+
+      Entry::const_iterator entry;
+      for (entry = (*section).entries().begin(); entry != (*section).entries().end(); ++entry)
+      {
+        if (!(*entry).comment().empty())
+          fprintf(stream, "%s", (*entry).comment().c_str());
+        fprintf(stream, "   %s = %s\n", (*entry).name().c_str(), (*entry).value().c_str());
+      }
+    }
+  }
+  fclose(stream);
+  return true;
+}
+
+
+/**
+ * @brief output the whole tree in a nice and easy way.
+ */
+void IniParser::debug() const
+{
+  printf("Iniparser '%s' - debug\n", this->_fileName.c_str());
+  if (!this->_document.comment().empty())
+    printf("FileComment:\n '%s'\n\n", this->_document.comment().c_str());
+
+  if (!this->_document.sections().empty())
+    this->_document.debug();
+  else
+    printf("no Sections Defined in this ini-file (%s).\n", _fileName.c_str());
+}
+
+
+/**
+ * @brief takes lines together to form one NodeComment, ereasing the commentList
+ * @param node the Node to apply the Comment to.
+ * @param comments the CommentList to append.
+ */
+void IniParser::setNodeComment(Node* node, std::list<std::string>* comments)
+{
+  assert(node != NULL);
+  assert(comments != NULL);
+
+  std::string comment;
+  if (comments->empty())
+  {
+    comment = "";
+  }
+  else
+  {
+    while (!comments->empty())
+    {
+      if (!comment.empty())
+        comment += "\n";
+      comment += comments->front();
+      comments->pop_front();
+    }
+  }
+  node->setComment(comment);
+}
+
+
Index: branches/heathaze/src/lib/parser/ini_parser/ini_parser.h
===================================================================
--- branches/heathaze/src/lib/parser/ini_parser/ini_parser.h	(revision 9940)
+++ branches/heathaze/src/lib/parser/ini_parser/ini_parser.h	(revision 9940)
@@ -0,0 +1,217 @@
+/*!
+ * @file ini_parser.h
+ * A small ini file parser
+ *
+ * Can be used to find a defined [Section] in an ini file and get the VarName = Value entries
+ */
+#ifndef _INI_PARSER_H
+#define _INI_PARSER_H
+
+#include <string>
+#include <list>
+
+//! ini-file parser
+/**
+ * This class can be used to load an initializer file and parse it's contents for variablename=value pairs.
+ */
+class IniParser
+{
+public:
+  ////////////////////////////////////
+  /// A class for a Ini-Node. The base of all INI-elements.
+  class Node
+  {
+  public:
+    Node(const std::string& name, const std::string& comment = "");
+    //! Simple destructor
+    virtual ~Node() {};
+    /** @returns the name of the Node */
+    const std::string& name() const  { return _name; };
+    /** @returns the Comment of the Node */
+    const std::string& comment() const  { return _comment; };
+    /** @param name the name to set for this node */
+    void setName(const std::string& name) { this->_name = name; };
+    /** @param comment the Comment to set for this node */
+    void setComment(const std::string& comment) { this->_comment = comment; };
+
+    /** @param name the name to compare against this nodes name @returns true on match */
+    bool operator==(const std::string& name) const { return _name == name; };
+
+    /** @brief displays some debug information about the node */
+    virtual void debug() const = 0;
+
+  private:
+    std::string         _comment;  //!< A Comment that is appendet to the Top of this Node
+    std::string         _name;     //!< name of a given Node
+  };
+
+  //! a class for Entries in the Parser's File's Sections
+class Entry : public Node
+  {
+  public:
+    Entry(const std::string& name, const std::string& value = "", const std::string& comment = "");
+    /** @returns the Value of the Entry */
+    const std::string& value() const { return _value; };
+    /** @param value sets the value of the Entry */
+    void setValue (const std::string& value) { _value = value; };
+
+    virtual void debug() const;
+
+  public:
+    typedef std::list<Entry>       list;           //!< A Type definition for lists of Entries.
+    typedef list::iterator         iterator;       //!< A Type definition for iterators of Entries.
+    typedef list::const_iterator   const_iterator; //!< A Type definition for constant iterators of Entries.
+
+  private:
+    std::string                    _value;         //!< value of a given Entry
+  };
+
+  //! a clas for Sections in the Parser's file
+class Section : public Node
+  {
+  public:
+    Section(const std::string& sectionName, const std::string& comment = "");
+
+    Entry& addEntry(const std::string& entryName, const std::string& value = "", const std::string& comment = "");
+    bool editEntry(const std::string& entryName, const std::string& value, bool createMissing = true);
+    const std::string& getValue(const std::string& entryName, const std::string& defaultValue = "") const;
+
+    bool setEntryComment(const std::string& entryName, const std::string& comment);
+    const std::string& getEntryComment(const std::string& entryName) const;
+
+    /** @returns the List of Entries */
+    const Entry::list& entries() const { return _entries; }
+    Entry* getEntry(const std::string& entryName);
+
+    Entry::const_iterator getEntryIt(const std::string& entryName) const;
+    /** @returns an Iterator pointing to the beginning of the entries. */
+    Entry::iterator begin() { return _entries.begin(); };
+    /** @returns a constant Iterator pointing to the beginning of the entries */
+    Entry::const_iterator begin() const { return _entries.begin(); };
+    /** @returns an Iterator pointing to the end of the entries */
+    Entry::iterator end() { return _entries.end(); };
+    /** @returns a constant Iterator pointing to the end of the entries */
+    Entry::const_iterator end() const { return _entries.end(); };
+
+    void clear();
+
+    virtual void debug() const;
+
+  public:
+    typedef std::list<Section>      list;            //!< A Type definition for lists of Sections
+    typedef list::iterator          iterator;        //!< A Type definition for iterators of Sectionlists.
+    typedef list::const_iterator    const_iterator;  //!< A Type definition for constant iterators of Sectionlists.
+
+  private:
+    Entry::list                     _entries;        //!< a list of entries for this section
+  };
+
+  //! A class for a INI-file.
+class Document : public Node
+  {
+  public:
+    Document(const std::string& fileName, const std::string& comment = "");
+
+    Section& addSection(const std::string& sectionName, const std::string& comment = "");
+    bool removeSection(const std::string& sectionName);
+    bool setSectionsComment(const std::string& sectionName, const std::string& comment);
+    const std::string& getSectionsComment(const std::string& sectionName) const;
+
+    /** @returns list of all sections */
+    const Section::list& sections() const { return _sections; }
+    Section* getSection(const std::string& sectionName);
+
+    Section::const_iterator getSectionIt(const std::string& sectionName) const;
+    /** @returns an Iterator poining to the beginning of the Sections List */
+    Section::iterator begin() { return _sections.begin(); };
+    /** @returns a constant Iterator poining to the beginning of the Sections List */
+    Section::const_iterator begin() const { return _sections.begin(); };
+    /** @returns an Iterator poining to the end of the Sections List */
+    Section::iterator end() { return _sections.end(); };
+    /** @returns a constant Iterator poining to the end of the Sections List */
+    Section::const_iterator end() const { return _sections.end(); };
+
+    bool addEntry(const std::string& sectionName, const std::string& entryName, const std::string& value = "", const std::string& comment = "");
+    bool editEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, bool createMissing = true);
+    const std::string& getValue(const std::string& sectionName, const std::string& entryName, const std::string& defaultValue = "") const;
+
+    bool setEntryComment(const std::string& sectionName, const std::string& entryName, const std::string& comment);
+    const std::string& getEntryComment(const std::string& sectionName, const std::string& entryName) const;
+
+    void clear();
+
+    virtual void debug() const;
+
+  private:
+    Section::list       _sections;        //!< a list of all stored Sections of the Parser.
+  };
+
+public:
+  IniParser (const std::string& filename = "");
+  virtual ~IniParser ();
+
+  /** @returns true if the file is opened, false otherwise */
+  bool isOpen() const { return !this->_document.sections().empty(); };
+  /** @returns the fileName we have opened. */
+  const std::string& getFileName() const { return this->_document.name(); };
+
+  /// Read and Write the File
+  bool readFile(const std::string& fileName, bool keepSettings = false);
+  bool writeFile(const std::string& fileName = "") const;
+
+  //! @param fileComment the comment of the Document */
+  void setFileComment(const std::string& fileComment) { this->_document.setComment(fileComment); };
+  /** @returns comments for the File. */
+  const std::string& getFileComment() const { return this->_document.comment(); };
+
+  /// Working with Sections.
+  Section& addSection(const std::string& sectionName);
+  // iterate through sections with these Functions
+  //! @see Section::getSection()
+  Section* getSection(const std::string& sectionName) { return this->_document.getSection(sectionName); };
+  //! @see Document::getSectionIt()
+  Section::const_iterator getSectionIt(const std::string& sectionName) const { return this->_document.getSectionIt(sectionName); };
+
+  //! @see Document::begin()
+  Section::iterator begin() { return this->_document.begin(); };
+  //! @see Document::begin()
+  Section::const_iterator begin() const { return this->_document.begin(); };
+  //! @see Document::end()
+  Section::iterator end() { return this->_document.end(); };
+  //! @see Document::end()
+  Section::const_iterator end() const { return this->_document.end(); };
+  //! @see Document::setSectionComment()
+  void setSectionsComment(const std::string& sectionName, const std::string& comment) { this->_document.setSectionsComment(sectionName, comment); };
+  //! @see Document::getSectionsComment()
+  const std::string& getSectionsComment(const std::string& sectionName) const { return this->_document.getSectionsComment(sectionName); };
+
+  /// Working on Entries. (globally)
+  //! @see Document::addEntry()
+  bool addEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, const std::string& comment)
+  { return this->_document.addEntry(sectionName, entryName, value, comment); };
+  //! @see Document::getValue()
+  const std::string& getValue(const std::string& sectionName, const std::string& entryName, const std::string& defaultValue = "") const
+  { return this->_document.getValue(sectionName, entryName, defaultValue); };
+  //! @see Document::editEntry()
+  bool editEntry(const std::string& sectionName, const std::string& entryName, const std::string& value, bool createMissing = true)
+  { return this->_document.editEntry(sectionName, entryName, value, createMissing); };
+  //! @see Document::setEntryComment()
+  void setEntryComment(const std::string& sectionName, const std::string& entryName, const std::string& comment)
+  { this->_document.setEntryComment(sectionName, entryName, comment); };
+  //! @see Document::getEntryComment()
+  const std::string& getEntryComment(const std::string& sectionName, const std::string& entryName) const
+  { return this->_document.getEntryComment(sectionName, entryName); };
+
+  // maintenance.
+  void debug() const;
+
+private:
+  void setNodeComment(Node* node, std::list<std::string>* comments);
+private:
+  std::string                      _fileName;        //!< The name of the File that is parsed here.
+  Document                         _document;        //!< The Document inside of the file.
+
+  static const std::string         _emptyString;     //!< Just an Empty String that will be returned if nothing else is found.
+};
+
+#endif /* _INI_PARSER_H */
Index: branches/heathaze/src/lib/parser/preferences/Makefile.am
===================================================================
--- branches/heathaze/src/lib/parser/preferences/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/parser/preferences/Makefile.am	(revision 9940)
@@ -0,0 +1,15 @@
+MAINSRCDIR=../../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libPrefsParser.a
+
+libPrefsParser_a_SOURCES = \
+		cmd_line_prefs_reader.cc \
+		ini_file_prefs_reader.cc \
+		preferences.cc
+
+
+noinst_HEADERS = \
+		cmd_line_prefs_reader.h \
+		ini_file_prefs_reader.h \
+		preferences.h
Index: branches/heathaze/src/lib/parser/preferences/cmd_line_prefs_reader.cc
===================================================================
--- branches/heathaze/src/lib/parser/preferences/cmd_line_prefs_reader.cc	(revision 9940)
+++ branches/heathaze/src/lib/parser/preferences/cmd_line_prefs_reader.cc	(revision 9940)
@@ -0,0 +1,165 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "cmd_line_prefs_reader.h"
+
+#include "preferences.h"
+
+
+
+RegistredArgs CmdLinePrefsReader::regArgs;
+
+/**
+ * standard constructor
+*/
+CmdLinePrefsReader::CmdLinePrefsReader( )
+{
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+CmdLinePrefsReader::~CmdLinePrefsReader ()
+{
+}
+
+bool CmdLinePrefsReader::callBack( ArgTableEntry entry, void * data, const std::string & arg, const std::vector<MultiType> & argArgs )
+{
+  CallbackData * cbd = (CallbackData *)data;
+
+  switch ( entry.id )
+  {
+    case ID_SET_INI:
+    {
+      std::string section = arg;
+      section.erase( 0, entry.longOption.length()+1 );
+      std::string key = section;
+      section.erase( section.find(".") );
+      key.erase( 0, key.find(".")+1 );
+      //PRINTF(0)("SECTION '%s', KEY '%s'\n", section.c_str(), key.c_str());
+
+      if ( key == "" || section == "" || argArgs.size() != 1 )
+      {
+        PRINTF(1)("usage: --set-section.key=value\n");
+        return false;
+      }
+
+      //Preferences::getInstance()->setMultiType( section, key, argArgs[0], true );
+      cbd->iniEntries.push_back( IniEntry() );
+      cbd->iniEntries.back().section = section;
+      cbd->iniEntries.back().key = key;
+      cbd->iniEntries.back().value = argArgs[0].getString();
+      return true;
+    }
+    case ID_HELP:
+      cbd->parser->showHelp();
+      return true;
+  }
+
+  if ( entry.id >= ID_PREFS && entry.id  < regArgs.size() + ID_PREFS)
+  {
+    if ( regArgs[entry.id - ID_PREFS].value == "%arg%" )
+    {
+      assert( argArgs.size() == 1 );
+
+      cbd->iniEntries.push_back( IniEntry() );
+      cbd->iniEntries.back().section = regArgs[entry.id - ID_PREFS].section;
+      cbd->iniEntries.back().key = regArgs[entry.id - ID_PREFS].key;
+      cbd->iniEntries.back().value = argArgs[0].getString();
+    }
+    else
+    {
+      cbd->iniEntries.push_back( IniEntry() );
+      cbd->iniEntries.back().section = regArgs[entry.id - ID_PREFS].section;
+      cbd->iniEntries.back().key = regArgs[entry.id - ID_PREFS].key;
+      cbd->iniEntries.back().value = regArgs[entry.id - ID_PREFS].value;
+    }
+  }
+  else
+  {
+    assert(false);
+  }
+
+  return true;
+}
+
+
+bool CmdLinePrefsReader::parse( int argc, char ** argv )
+{
+  CmdLineParser parser;
+
+  parser.add( ID_HELP, "help", 'h', 0, "", "Shows this help and exits");
+
+  for (unsigned int i = 0; i<regArgs.size(); i++ )
+  {
+    if ( regArgs[i].value == "%arg%" )
+    {
+      parser.add( ID_PREFS + i, regArgs[i].longOption, regArgs[i].shortOption, 1, regArgs[i].argName, regArgs[i].help );
+    }
+    else
+    {
+      parser.add( ID_PREFS + i, regArgs[i].longOption, regArgs[i].shortOption, 0, "", regArgs[i].help );
+    }
+  }
+
+  parser.add( ID_SET_INI, "set-%", '\0', 1, "value", "Override a configuration element." );
+
+  CallbackData cbd;
+
+  cbd.parser = &parser;
+
+  if ( parser.parse( &callBack, &cbd, argc, argv ) )
+  {
+    std::list<IniEntry>::const_iterator it;
+    for ( it = cbd.iniEntries.begin(); it != cbd.iniEntries.end(); it++ )
+    {
+      Preferences::getInstance()->setString( it->section, it->key, it->value, true);
+    }
+  }
+  else
+  {
+    exit(EXIT_FAILURE);
+  }
+
+  return true;
+}
+
+bool CmdLinePrefsReader::registerArgument( const char shortOption, const std::string & longOption, const std::string & section, const std::string & key, const std::string & help, const std::string & argName, const std::string & value )
+{
+  RegistredArgument arg;
+
+  arg.longOption = longOption;
+  while ( arg.longOption.find("_") != std::string::npos )
+  {
+    arg.longOption.replace( arg.longOption.find("_"), 1, "-" );
+  }
+  arg.shortOption = shortOption;
+  if ( arg.shortOption == '_' )
+    arg.shortOption = '\0';
+  arg.value = value;
+  arg.help = help;
+  arg.argName = argName;
+  arg.section = section;
+  arg.key = key;
+
+  regArgs.push_back( arg );
+  return true;
+}
+
+
Index: branches/heathaze/src/lib/parser/preferences/cmd_line_prefs_reader.h
===================================================================
--- branches/heathaze/src/lib/parser/preferences/cmd_line_prefs_reader.h	(revision 9940)
+++ branches/heathaze/src/lib/parser/preferences/cmd_line_prefs_reader.h	(revision 9940)
@@ -0,0 +1,71 @@
+/*!
+ * @file proto_class.h
+ * @brief Definition of CmdLinePrefsReader
+*/
+
+#ifndef _CMD_LINE_PREFS_READER_H
+#define _CMD_LINE_PREFS_READER_H
+
+#include "debug.h"
+
+#include "src/lib/parser/cmdline_parser/cmdline_parser.h"
+
+struct IniEntry
+{
+  std::string section;
+  std::string key;
+  std::string value;
+};
+
+struct CallbackData
+{
+  std::list<IniEntry> iniEntries;
+  CmdLineParser * parser;
+};
+
+struct RegistredArgument
+{
+  char shortOption;
+  std::string longOption;
+  std::string value;
+  std::string help;
+  std::string argName;
+  std::string section;
+  std::string key;
+};
+
+typedef std::vector<RegistredArgument> RegistredArgs;
+
+enum
+{
+  ID_SET_INI = 1,
+  ID_HELP,
+  ID_PREFS
+};
+
+#define REGISTER_ARG_FLAG(shortOption,longOption,section,key,description,value) bool _ARGVAR_##shortOption##_##longOption = CmdLinePrefsReader::registerArgument(#shortOption[0],#longOption,section,key,description,"",value)
+
+#define REGISTER_ARG_ARG(shortOption,longOption,section,key,description,argname) bool _ARGVAR_##shortOption##_##longOption = CmdLinePrefsReader::registerArgument(#shortOption[0],#longOption,section,key,description,argname)
+
+//! A class for reading commandline arguments into Preferences
+class CmdLinePrefsReader
+{
+
+ public:
+   CmdLinePrefsReader();
+   virtual ~CmdLinePrefsReader();
+
+    bool parse(int argc, char** argv);
+
+    static bool registerArgument( const char shortOption, const std::string & longOption, const std::string & section, const std::string & key, const std::string & help,  const std::string & argName = "", const std::string & value = "%arg%" );
+
+    static bool asdf;
+
+  private:
+    static bool callBack( ArgTableEntry entry, void* data, const std::string & arg, const std::vector<MultiType> & argArgs );
+
+    static RegistredArgs regArgs;
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: branches/heathaze/src/lib/parser/preferences/ini_file_prefs_reader.cc
===================================================================
--- branches/heathaze/src/lib/parser/preferences/ini_file_prefs_reader.cc	(revision 9940)
+++ branches/heathaze/src/lib/parser/preferences/ini_file_prefs_reader.cc	(revision 9940)
@@ -0,0 +1,63 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "ini_file_prefs_reader.h"
+
+
+
+
+/**
+ * standard constructor
+*/
+IniFilePrefsReader::IniFilePrefsReader ( const std::string& fileName )
+{
+  IniParser iniParser;
+
+
+  Preferences* prefs = Preferences::getInstance();
+
+  prefs->setUserIni( fileName );
+
+  if ( !iniParser.readFile( fileName ) )
+    return;
+
+  for(IniParser::Section::iterator section = iniParser.begin();
+      section != iniParser.end();
+      ++section)
+    for (IniParser::Entry::iterator entry = (*section).begin();
+         entry != (*section).end();
+         ++entry)
+      prefs->setString( (*section).name(), (*entry).name(), (*entry).value(), true );
+
+  /*iniParser.firstVar();
+
+  Preferences* prefs = Preferences::getInstance();
+
+  while ( iniParser.nextVar() )
+  {
+    prefs->setString( iniParser.getCurrentSection(), iniParser.getCurrentName(), iniParser.getCurrentValue(), true );
+  }*/
+}
+
+
+/**
+ * standard deconstructor
+*/
+IniFilePrefsReader::~IniFilePrefsReader ()
+{}
+
+
Index: branches/heathaze/src/lib/parser/preferences/ini_file_prefs_reader.h
===================================================================
--- branches/heathaze/src/lib/parser/preferences/ini_file_prefs_reader.h	(revision 9940)
+++ branches/heathaze/src/lib/parser/preferences/ini_file_prefs_reader.h	(revision 9940)
@@ -0,0 +1,23 @@
+/*!
+ * @file ini_file_prefs_reader.h
+ * @brief Definition of IniFilePrefsReader
+*/
+
+#ifndef _INI_FILE_PREFS_READER_H
+#define _INI_FILE_PREFS_READER_H
+
+#include "lib/parser/ini_parser/ini_parser.h"
+#include "preferences.h"
+
+
+//! A class for reading inifiles into Preferences
+class IniFilePrefsReader {
+
+ public:
+   IniFilePrefsReader(const std::string& fileName);
+   virtual ~IniFilePrefsReader();
+
+
+};
+
+#endif /* _INI_FILE_PREFS_READER_H */
Index: branches/heathaze/src/lib/parser/preferences/preferences.cc
===================================================================
--- branches/heathaze/src/lib/parser/preferences/preferences.cc	(revision 9940)
+++ branches/heathaze/src/lib/parser/preferences/preferences.cc	(revision 9940)
@@ -0,0 +1,335 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "preferences.h"
+#include "lib/parser/ini_parser/ini_parser.h"
+#include "debug.h"
+
+ObjectListDefinition(Preferences);
+
+/**
+ * standard constructor
+ */
+Preferences::Preferences ()
+{
+  this->registerObject(this, Preferences::_objectList);
+   this->setName("Preferences");
+   this->fileName = "";
+}
+
+/**
+ *  the singleton reference to this class
+ */
+Preferences* Preferences::singletonRef = NULL;
+
+/**
+   @brief standard deconstructor
+ */
+Preferences::~Preferences ()
+{
+  Preferences::singletonRef = NULL;
+}
+
+/**
+ * Check if this item exists
+ * @param section name of the section
+ * @param name name of the item to check
+ * @return true if the item exists
+ */
+bool Preferences::exists( const std::string& section, const std::string& name)
+{
+  std::list<prefSection>::const_iterator it = data.begin();
+
+  for ( ; it!=data.end(); it++)
+  {
+    if ( it->sectionName == section )
+    {
+      std::list<prefItem>::const_iterator it2 = it->items.begin();
+
+      for ( ; it2!=it->items.end(); it2++)
+      {
+        if ( it2->name == name )
+          return true;
+      }
+
+      break;
+    }
+  }
+
+  return false;
+}
+
+/**
+ * Check if this section exists
+ * @param section name of the section
+ * @param name name of the item to check
+ * @return true if the item exists
+ */
+bool Preferences::sectionExists( const std::string& section )
+{
+  std::list<prefSection>::const_iterator it = data.begin();
+
+  for ( ; it!=data.end(); it++)
+  {
+    if ( it->sectionName == section )
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+/**
+ * Sets the value of an item. Creates it if doesn't exits.
+ * @param section name of the section
+ * @param name name of the item
+ * @param value value
+ */
+void Preferences::setString(const std::string& section, const std::string& name, const std::string& value, bool dontSetModified)
+{
+  MultiType t(value);
+  setMultiType(section, name, t, dontSetModified);
+}
+
+/**
+ * Sets the value of an item. Creates it if doesn't exits.
+ * @param section name of the section
+ * @param name name of the item
+ * @param value value
+ */
+void Preferences::setInt(const std::string& section, const std::string& name, int value, bool dontSetModified)
+{
+  MultiType t(value);
+  setMultiType(section, name, t, dontSetModified);
+}
+
+/**
+ * Sets the value of an item. Creates it if doesn't exits.
+ * @param section name of the section
+ * @param name name of the item
+ * @param value value
+ */
+void Preferences::setFloat(const std::string& section, const std::string& name, float value, bool dontSetModified)
+{
+  MultiType t(value);
+  setMultiType(section, name, t, dontSetModified);
+}
+
+/**
+ * Get the value of an item
+ * @param section name of the section
+ * @param name name of the item to check
+ * @param defaultValue value to return if item doesn't exist
+ * @return value of the item if found. defaultValue else
+ */
+std::string Preferences::getString(const std::string& section, const std::string& name, const std::string& defaultValue)
+{
+  return getMultiType(section, name, MultiType(defaultValue)).getString();
+}
+
+/**
+ * Get the value of an item
+ * @param section name of the section
+ * @param name name of the item to check
+ * @param defaultValue value to return if item doesn't exist
+ * @return value of the item if found. defaultValue else
+ */
+int Preferences::getInt(const std::string& section, const std::string& name, int defaultValue)
+{
+  return getMultiType(section, name, MultiType(defaultValue)).getInt();
+}
+
+/**
+ * Get the value of an item
+ * @param section name of the section
+ * @param name name of the item to check
+ * @param defaultValue value to return if item doesn't exist
+ * @return value of the item if found. defaultValue else
+ */
+float Preferences::getFloat(const std::string& section, const std::string& name, float defaultValue)
+{
+  return getMultiType(section, name, MultiType(defaultValue)).getFloat();
+}
+
+/**
+ * Sets the value of an item. Creates it if doesn't exits.
+ * @param section name of the section
+ * @param name name of the item
+ * @param value value
+ */
+void Preferences::setMultiType(const std::string& section, const std::string& name, const MultiType& value, bool dontSetModified)
+{
+  std::list<prefSection>::iterator it = data.begin();
+
+  for ( ; it!=data.end(); it++)
+  {
+    if ( it->sectionName == section )
+    {
+      std::list<prefItem>::iterator it2 = it->items.begin();
+
+      for ( ; it2!=it->items.end(); it2++)
+      {
+        if ( it2->name == name )
+        {
+          if (!dontSetModified)
+            it2->modified = value.getString() != it2->value.getString();
+
+          it2->value = value;
+
+          return;
+        }
+      }
+      prefItem item;
+      item.value = value;
+      item.modified = !dontSetModified;
+      item.name = name;
+      it->items.push_back(item);
+      return;
+    }
+  }
+
+  prefItem item;
+  item.value = value;
+  item.modified = !dontSetModified;
+  item.name = name;
+
+  prefSection sec;
+  sec.items.push_back(item);
+  sec.sectionName = section;
+  data.push_back( sec );
+}
+
+/**
+ * Get the value of an item
+ * @param section name of the section
+ * @param name name of the item to check
+ * @param defaultValue value to return if item doesn't exist
+ * @return value of the item if found. defaultValue else
+ */
+MultiType Preferences::getMultiType(const std::string& section, const std::string& name,const MultiType& defaultValue)
+{
+  std::list<prefSection>::const_iterator it = data.begin();
+
+  for ( ; it!=data.end(); it++)
+  {
+    if ( it->sectionName == section )
+    {
+      std::list<prefItem>::const_iterator it2 = it->items.begin();
+
+      for ( ; it2!=it->items.end(); it2++)
+      {
+        if ( it2->name == name )
+        {
+          return it2->value;
+        }
+      }
+
+      break;
+    }
+  }
+
+  return defaultValue;
+}
+
+void Preferences::setUserIni(const std::string& fileName)
+{
+  this->fileName = fileName;
+}
+
+bool Preferences::save()
+{
+  if ( this->fileName == "" )
+  {
+    PRINTF(1)("You must call setUserIni before you can call save()\n");
+    return false;
+  }
+  IniParser iniParser(this->fileName);
+
+  std::list<prefSection>::iterator it = data.begin();
+  bool didChanges = false;
+  for ( ; it!=data.end(); it++)
+  {
+    std::list<prefItem>::iterator it2 = it->items.begin();
+
+    for ( ; it2!=it->items.end(); it2++)
+    {
+      if ( it2->modified )
+      {
+	iniParser.editEntry(it->sectionName, it2->name, it2->value.getString());
+        didChanges = true;
+      }
+    }
+  }
+  /// HACK DO WE HAVE TO CHECK THIS??
+  //if ( didChanges )
+  {
+    iniParser.writeFile( this->fileName );
+  }
+
+  return true;
+}
+
+/**
+ * prints out all section with its items and values
+ */
+void Preferences::debug()
+{
+  std::list<prefSection>::iterator it = data.begin();
+
+  for ( ; it!=data.end(); it++)
+  {
+    PRINTF(0)("%s\n", it->sectionName.c_str());
+    std::list<prefItem>::iterator it2 = it->items.begin();
+
+    for ( ; it2!=it->items.end(); it2++)
+    {
+      PRINTF(0)("--> %s = '%s'%s\n", it2->name.c_str(), it2->value.getString().c_str(), ((!it2->modified)?"":" <modified>"));
+    }
+  }
+}
+
+/**
+ * list all keys in section
+ * @param section section
+ * @return list of keys
+ */
+std::list< std::string > Preferences::listKeys( const std::string section )
+{
+  std::list<std::string> lst;
+
+  std::list<prefSection>::const_iterator it = data.begin();
+
+  for ( ; it!=data.end(); it++)
+  {
+    if ( it->sectionName == section )
+    {
+      std::list<prefItem>::const_iterator it2 = it->items.begin();
+
+      for ( ; it2!=it->items.end(); it2++)
+      {
+        lst.push_back( it2->name );
+      }
+
+      break;
+    }
+  }
+
+  return lst;
+}
+
+
Index: branches/heathaze/src/lib/parser/preferences/preferences.h
===================================================================
--- branches/heathaze/src/lib/parser/preferences/preferences.h	(revision 9940)
+++ branches/heathaze/src/lib/parser/preferences/preferences.h	(revision 9940)
@@ -0,0 +1,79 @@
+/*!
+ * @file proto_singleton.h
+ * @brief Definition of the ... singleton Class
+*/
+
+#ifndef _PREFERENCES_H
+#define _PREFERENCES_H
+
+#include "base_object.h"
+#include "multi_type.h"
+#include <list>
+
+// FORWARD DECLARATION
+
+class IniFilePrefsReader;
+
+//! A default singleton class.
+class Preferences : public BaseObject
+{
+  ObjectListDeclaration(Preferences);
+public:
+  virtual ~Preferences(void);
+  /** @returns a Pointer to the only object of this Class */
+  inline static Preferences* getInstance(void) { if (!singletonRef) singletonRef = new Preferences();  return singletonRef; };
+
+  //check if this entry exists
+  bool sectionExists(const std::string& section );
+  bool exists(const std::string& section, const std::string& name);
+
+  void setString(const std::string& section, const std::string& name, const std::string& value, bool dontSetModified = false);
+  void setInt(const std::string& section, const std::string& name, int value, bool dontSetModified = false);
+  void setFloat(const std::string& section, const std::string& name, float value, bool dontSetModified = false);
+  void setMultiType(const std::string& section, const std::string& name, const MultiType& value, bool dontSetModified = false);
+
+  std::string getString(const std::string& section, const std::string& name, const std::string& defaultValue);
+  int getInt(const std::string& section, const std::string& name, int defaultValue);
+  float getFloat(const std::string& section, const std::string& name, float defaultValue);
+  MultiType getMultiType(const std::string& section, const std::string& name, const MultiType& defaultValue);
+
+  void setUserIni(const std::string& fileName);
+
+  bool save();
+
+  void debug();
+
+  std::list<std::string> listKeys( const std::string section );
+
+private:
+  typedef struct
+  {
+    std::string name;
+    MultiType value;
+    bool modified;
+  }
+  prefItem;
+
+  typedef struct
+  {
+    std::string sectionName;
+    std::list<prefItem> items;
+  }
+  prefSection ;
+
+
+private:
+  Preferences(void);
+
+private:
+  static Preferences* singletonRef;
+
+  std::list<prefSection> data;
+
+  std::list<IniFilePrefsReader*> iniFilePrefsReaders;
+
+  std::string fileName;
+
+};
+
+#endif /* _PREFERENCES_H */
Index: branches/heathaze/src/lib/parser/tinyxml/Makefile.am
===================================================================
--- branches/heathaze/src/lib/parser/tinyxml/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/parser/tinyxml/Makefile.am	(revision 9940)
@@ -0,0 +1,10 @@
+
+noinst_LIBRARIES = libtinyxml.a 
+
+libtinyxml_a_SOURCES = tinyxml.cc \
+		       tinystr.cc \
+		       tinyxmlerror.cc \
+		       tinyxmlparser.cc
+
+noinst_HEADERS= tinyxml.h \
+		tinystr.h
Index: branches/heathaze/src/lib/parser/tinyxml/tinystr.cc
===================================================================
--- branches/heathaze/src/lib/parser/tinyxml/tinystr.cc	(revision 9940)
+++ branches/heathaze/src/lib/parser/tinyxml/tinystr.cc	(revision 9940)
@@ -0,0 +1,115 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005.
+ */
+
+
+#ifndef TIXML_USE_STL
+
+#include "tinystr.h"
+
+// Error value for find primitive
+const TiXmlString::size_type TiXmlString::npos = static_cast< size_type >(-1);
+
+// Null rep.
+TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, '\0' };
+
+
+void TiXmlString::reserve (size_type cap)
+{
+	if (cap > capacity())
+	{
+		TiXmlString tmp;
+		tmp.init(length(), cap);
+		memcpy(tmp.start(), data(), length());
+		swap(tmp);
+	}
+}
+
+
+TiXmlString& TiXmlString::assign(const char* str, size_type len)
+{
+	size_type cap = capacity();
+	if (len > cap || cap > 3*(len + 8))
+	{
+		TiXmlString tmp;
+		tmp.init(len);
+		memcpy(tmp.start(), str, len);
+		swap(tmp);
+	}
+	else
+	{
+		memmove(start(), str, len);
+		set_size(len);
+	}
+	return *this;
+}
+
+
+TiXmlString& TiXmlString::append(const char* str, size_type len)
+{
+	size_type newsize = length() + len;
+	if (newsize > capacity())
+	{
+		reserve (newsize + capacity());
+	}
+	memmove(finish(), str, len);
+	set_size(newsize);
+	return *this;
+}
+
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	tmp.reserve(a.length() + b.length());
+	tmp += a;
+	tmp += b;
+	return tmp;
+}
+
+TiXmlString operator + (const TiXmlString & a, const char* b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
+	tmp.reserve(a.length() + b_len);
+	tmp += a;
+	tmp.append(b, b_len);
+	return tmp;
+}
+
+TiXmlString operator + (const char* a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
+	tmp.reserve(a_len + b.length());
+	tmp.append(a, a_len);
+	tmp += b;
+	return tmp;
+}
+
+
+#endif	// TIXML_USE_STL
Index: branches/heathaze/src/lib/parser/tinyxml/tinystr.h
===================================================================
--- branches/heathaze/src/lib/parser/tinyxml/tinystr.h	(revision 9940)
+++ branches/heathaze/src/lib/parser/tinyxml/tinystr.h	(revision 9940)
@@ -0,0 +1,304 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
+ *
+ * - completely rewritten. compact, clean, and fast implementation.
+ * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
+ * - fixed reserve() to work as per specification.
+ * - fixed buggy compares operator==(), operator<(), and operator>()
+ * - fixed operator+=() to take a const ref argument, following spec.
+ * - added "copy" constructor with length, and most compare operators.
+ * - added swap(), clear(), size(), capacity(), operator+().
+ */
+
+#ifndef TIXML_USE_STL
+
+#ifndef TIXML_STRING_INCLUDED
+#define TIXML_STRING_INCLUDED
+
+#include <assert.h>
+#include <string.h>
+
+/*
+   TiXmlString is an emulation of a subset of the std::string template.
+   Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
+   Only the member functions relevant to the TinyXML project have been implemented.
+   The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
+   a string and there's no more room, we allocate a buffer twice as big as we need.
+*/
+class TiXmlString
+{
+  public :
+	// The size type used
+  	typedef unsigned int size_type;
+
+	// Error value for find primitive
+	static const size_type npos; // = -1;
+
+
+	// TiXmlString empty constructor
+	TiXmlString () : rep_(&nullrep_)
+	{
+	}
+
+	// TiXmlString copy constructor
+	TiXmlString (const TiXmlString & copy)
+	{
+		init(copy.length());
+		memcpy(start(), copy.data(), length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TiXmlString (const char * copy)
+	{
+		init( static_cast<size_type>( strlen(copy) ));
+		memcpy(start(), copy, length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TiXmlString (const char * str, size_type len)
+	{
+		init(len);
+		memcpy(start(), str, len);
+	}
+
+	// TiXmlString destructor
+	~TiXmlString ()
+	{
+		quit();
+	}
+
+	// = operator
+	TiXmlString& operator = (const char * copy)
+	{
+		return assign( copy, (size_type)strlen(copy));
+	}
+
+	// = operator
+	TiXmlString& operator = (const TiXmlString & copy)
+	{
+		return assign(copy.start(), copy.length());
+	}
+
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const char * suffix)
+	{
+		return append(suffix, static_cast<size_type>( strlen(suffix) ));
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (char single)
+	{
+		return append(&single, 1);
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const TiXmlString & suffix)
+	{
+		return append(suffix.data(), suffix.length());
+	}
+
+
+	// Convert a TiXmlString into a null-terminated char *
+	const char * c_str () const { return rep_->str; }
+
+	// Convert a TiXmlString into a char * (need not be null terminated).
+	const char * data () const { return rep_->str; }
+
+	// Return the length of a TiXmlString
+	size_type length () const { return rep_->size; }
+
+	// Alias for length()
+	size_type size () const { return rep_->size; }
+
+	// Checks if a TiXmlString is empty
+	bool empty () const { return rep_->size == 0; }
+
+	// Return capacity of string
+	size_type capacity () const { return rep_->capacity; }
+
+
+	// single char extraction
+	const char& at (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// [] operator
+	char& operator [] (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// find a char in a string. Return TiXmlString::npos if not found
+	size_type find (char lookup) const
+	{
+		return find(lookup, 0);
+	}
+
+	// find a char in a string from an offset. Return TiXmlString::npos if not found
+	size_type find (char tofind, size_type offset) const
+	{
+		if (offset >= length()) return npos;
+
+		for (const char* p = c_str() + offset; *p != '\0'; ++p)
+		{
+		   if (*p == tofind) return static_cast< size_type >( p - c_str() );
+		}
+		return npos;
+	}
+
+	void clear ()
+	{
+		//Lee:
+		//The original was just too strange, though correct:
+		//	TiXmlString().swap(*this);
+		//Instead use the quit & re-init:
+		quit();
+		init(0,0);
+	}
+
+	/*	Function to reserve a big amount of data when we know we'll need it. Be aware that this
+		function DOES NOT clear the content of the TiXmlString if any exists.
+	*/
+	void reserve (size_type cap);
+
+	TiXmlString& assign (const char* str, size_type len);
+
+	TiXmlString& append (const char* str, size_type len);
+
+	void swap (TiXmlString& other)
+	{
+		Rep* r = rep_;
+		rep_ = other.rep_;
+		other.rep_ = r;
+	}
+
+  private:
+
+	void init(size_type sz) { init(sz, sz); }
+	void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
+	char* start() const { return rep_->str; }
+	char* finish() const { return rep_->str + rep_->size; }
+
+	struct Rep
+	{
+		size_type size, capacity;
+		char str[1];
+	};
+
+	void init(size_type sz, size_type cap)
+	{
+		if (cap)
+		{
+			// Lee: the original form:
+			//	rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
+			// doesn't work in some cases of new being overloaded. Switching
+			// to the normal allocation, although use an 'int' for systems
+			// that are overly picky about structure alignment.
+			const size_type bytesNeeded = sizeof(Rep) + cap;
+			const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); 
+			rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
+
+			rep_->str[ rep_->size = sz ] = '\0';
+			rep_->capacity = cap;
+		}
+		else
+		{
+			rep_ = &nullrep_;
+		}
+	}
+
+	void quit()
+	{
+		if (rep_ != &nullrep_)
+		{
+			// The rep_ is really an array of ints. (see the allocator, above).
+			// Cast it back before delete, so the compiler won't incorrectly call destructors.
+			delete [] ( reinterpret_cast<int*>( rep_ ) );
+		}
+	}
+
+	Rep * rep_;
+	static Rep nullrep_;
+
+} ;
+
+
+inline bool operator == (const TiXmlString & a, const TiXmlString & b)
+{
+	return    ( a.length() == b.length() )				// optimization on some platforms
+	       && ( strcmp(a.c_str(), b.c_str()) == 0 );	// actual compare
+}
+inline bool operator < (const TiXmlString & a, const TiXmlString & b)
+{
+	return strcmp(a.c_str(), b.c_str()) < 0;
+}
+
+inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
+inline bool operator >  (const TiXmlString & a, const TiXmlString & b) { return b < a; }
+inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
+inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
+
+inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
+inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
+inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
+inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
+TiXmlString operator + (const TiXmlString & a, const char* b);
+TiXmlString operator + (const char* a, const TiXmlString & b);
+
+
+/*
+   TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
+   Only the operators that we need for TinyXML have been developped.
+*/
+class TiXmlOutStream : public TiXmlString
+{
+public :
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const TiXmlString & in)
+	{
+		*this += in;
+		return *this;
+	}
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const char * in)
+	{
+		*this += in;
+		return *this;
+	}
+
+} ;
+
+#endif	// TIXML_STRING_INCLUDED
+#endif	// TIXML_USE_STL
Index: branches/heathaze/src/lib/parser/tinyxml/tinyxml.cc
===================================================================
--- branches/heathaze/src/lib/parser/tinyxml/tinyxml.cc	(revision 9940)
+++ branches/heathaze/src/lib/parser/tinyxml/tinyxml.cc	(revision 9940)
@@ -0,0 +1,1732 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include <ctype.h>
+#include "tinyxml.h"
+
+#ifdef TIXML_USE_STL
+#include <sstream>
+#endif
+
+
+bool TiXmlBase::condenseWhiteSpace = true;
+
+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream )
+{
+	TIXML_STRING buffer;
+	PutString( str, &buffer );
+	(*stream) << buffer;
+}
+
+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
+{
+	int i=0;
+
+	while( i<(int)str.length() )
+	{
+		unsigned char c = (unsigned char) str[i];
+
+		if (    c == '&' 
+		     && i < ( (int)str.length() - 2 )
+			 && str[i+1] == '#'
+			 && str[i+2] == 'x' )
+		{
+			// Hexadecimal character reference.
+			// Pass through unchanged.
+			// &#xA9;	-- copyright symbol, for example.
+			//
+			// The -1 is a bug fix from Rob Laveaux. It keeps
+			// an overflow from happening if there is no ';'.
+			// There are actually 2 ways to exit this loop -
+			// while fails (error case) and break (semicolon found).
+			// However, there is no mechanism (currently) for
+			// this function to return an error.
+			while ( i<(int)str.length()-1 )
+			{
+				outString->append( str.c_str() + i, 1 );
+				++i;
+				if ( str[i] == ';' )
+					break;
+			}
+		}
+		else if ( c == '&' )
+		{
+			outString->append( entity[0].str, entity[0].strLength );
+			++i;
+		}
+		else if ( c == '<' )
+		{
+			outString->append( entity[1].str, entity[1].strLength );
+			++i;
+		}
+		else if ( c == '>' )
+		{
+			outString->append( entity[2].str, entity[2].strLength );
+			++i;
+		}
+		else if ( c == '\"' )
+		{
+			outString->append( entity[3].str, entity[3].strLength );
+			++i;
+		}
+		else if ( c == '\'' )
+		{
+			outString->append( entity[4].str, entity[4].strLength );
+			++i;
+		}
+		else if ( c < 32 )
+		{
+			// Easy pass at non-alpha/numeric/symbol
+			// Below 32 is symbolic.
+			char buf[ 32 ];
+			
+			#if defined(TIXML_SNPRINTF)		
+				TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#else
+				sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#endif		
+
+			//*ME:	warning C4267: convert 'size_t' to 'int'
+			//*ME:	Int-Cast to make compiler happy ...
+			outString->append( buf, (int)strlen( buf ) );
+			++i;
+		}
+		else
+		{
+			//char realc = (char) c;
+			//outString->append( &realc, 1 );
+			*outString += (char) c;	// somewhat more efficient function call.
+			++i;
+		}
+	}
+}
+
+
+// <-- Strange class for a bug fix. Search for STL_STRING_BUG
+TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str )
+{
+	buffer = new char[ str.length()+1 ];
+	if ( buffer )
+	{
+		strcpy( buffer, str.c_str() );
+	}
+}
+
+
+TiXmlBase::StringToBuffer::~StringToBuffer()
+{
+	delete [] buffer;
+}
+// End strange bug fix. -->
+
+
+TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
+{
+	parent = 0;
+	type = _type;
+	firstChild = 0;
+	lastChild = 0;
+	prev = 0;
+	next = 0;
+}
+
+
+TiXmlNode::~TiXmlNode()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+}
+
+
+void TiXmlNode::CopyTo( TiXmlNode* target ) const
+{
+	target->SetValue (value.c_str() );
+	target->userData = userData; 
+}
+
+
+void TiXmlNode::Clear()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+
+	firstChild = 0;
+	lastChild = 0;
+}
+
+
+TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
+{
+	node->parent = this;
+
+	node->prev = lastChild;
+	node->next = 0;
+
+	if ( lastChild )
+		lastChild->next = node;
+	else
+		firstChild = node;			// it was an empty list.
+
+	lastChild = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
+{
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+
+	return LinkEndChild( node );
+}
+
+
+TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
+{	
+	if ( !beforeThis || beforeThis->parent != this )
+		return 0;
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->next = beforeThis;
+	node->prev = beforeThis->prev;
+	if ( beforeThis->prev )
+	{
+		beforeThis->prev->next = node;
+	}
+	else
+	{
+		assert( firstChild == beforeThis );
+		firstChild = node;
+	}
+	beforeThis->prev = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
+{
+	if ( !afterThis || afterThis->parent != this )
+		return 0;
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->prev = afterThis;
+	node->next = afterThis->next;
+	if ( afterThis->next )
+	{
+		afterThis->next->prev = node;
+	}
+	else
+	{
+		assert( lastChild == afterThis );
+		lastChild = node;
+	}
+	afterThis->next = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
+{
+	if ( replaceThis->parent != this )
+		return 0;
+
+	TiXmlNode* node = withThis.Clone();
+	if ( !node )
+		return 0;
+
+	node->next = replaceThis->next;
+	node->prev = replaceThis->prev;
+
+	if ( replaceThis->next )
+		replaceThis->next->prev = node;
+	else
+		lastChild = node;
+
+	if ( replaceThis->prev )
+		replaceThis->prev->next = node;
+	else
+		firstChild = node;
+
+	delete replaceThis;
+	node->parent = this;
+	return node;
+}
+
+
+bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
+{
+	if ( removeThis->parent != this )
+	{	
+		assert( 0 );
+		return false;
+	}
+
+	if ( removeThis->next )
+		removeThis->next->prev = removeThis->prev;
+	else
+		lastChild = removeThis->prev;
+
+	if ( removeThis->prev )
+		removeThis->prev->next = removeThis->next;
+	else
+		firstChild = removeThis->next;
+
+	delete removeThis;
+	return true;
+}
+
+const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = firstChild; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+TiXmlNode* TiXmlNode::FirstChild( const char * _value )
+{
+	TiXmlNode* node;
+	for ( node = firstChild; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = lastChild; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlNode* TiXmlNode::LastChild( const char * _value )
+{
+	TiXmlNode* node;
+	for ( node = lastChild; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild();
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling();
+	}
+}
+
+TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous )
+{
+	if ( !previous )
+	{
+		return FirstChild();
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling();
+	}
+}
+
+const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild( val );
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling( val );
+	}
+}
+
+TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous )
+{
+	if ( !previous )
+	{
+		return FirstChild( val );
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling( val );
+	}
+}
+
+const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const 
+{
+	const TiXmlNode* node;
+	for ( node = next; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlNode* TiXmlNode::NextSibling( const char * _value )
+{
+	TiXmlNode* node;
+	for ( node = next; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = prev; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlNode* TiXmlNode::PreviousSibling( const char * _value )
+{
+	TiXmlNode* node;
+	for ( node = prev; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+void TiXmlElement::RemoveAttribute( const char * name )
+{
+	TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+	{
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+const TiXmlElement* TiXmlNode::FirstChildElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+TiXmlElement* TiXmlNode::FirstChildElement()
+{
+	TiXmlNode* node;
+
+	for (	node = FirstChild();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+TiXmlElement* TiXmlNode::FirstChildElement( const char * _value )
+{
+	TiXmlNode* node;
+
+	for (	node = FirstChild( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+const TiXmlElement* TiXmlNode::NextSiblingElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling();
+	node;
+	node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+TiXmlElement* TiXmlNode::NextSiblingElement()
+{
+	TiXmlNode* node;
+
+	for (	node = NextSibling();
+	node;
+	node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling( _value );
+	node;
+	node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value )
+{
+	TiXmlNode* node;
+
+	for (	node = NextSibling( _value );
+	node;
+	node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlDocument* TiXmlNode::GetDocument() const
+{
+	const TiXmlNode* node;
+
+	for( node = this; node; node = node->parent )
+	{
+		if ( node->ToDocument() )
+			return node->ToDocument();
+	}
+	return 0;
+}
+
+TiXmlDocument* TiXmlNode::GetDocument()
+{
+	TiXmlNode* node;
+
+	for( node = this; node; node = node->parent )
+	{
+		if ( node->ToDocument() )
+			return node->ToDocument();
+	}
+	return 0;
+}
+
+TiXmlElement::TiXmlElement (const char * _value)
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlElement::TiXmlElement( const std::string& _value ) 
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+#endif
+
+
+TiXmlElement::TiXmlElement( const TiXmlElement& copy)
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	copy.CopyTo( this );	
+}
+
+
+void TiXmlElement::operator=( const TiXmlElement& base )
+{
+	ClearThis();
+	base.CopyTo( this );
+}
+
+
+TiXmlElement::~TiXmlElement()
+{
+	ClearThis();
+}
+
+
+void TiXmlElement::ClearThis()
+{
+	Clear();
+	while( attributeSet.First() )
+	{
+		TiXmlAttribute* node = attributeSet.First();
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+
+const char * TiXmlElement::Attribute( const char * name ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+
+	if ( node )
+		return node->Value();
+
+	return 0;
+}
+
+
+const char * TiXmlElement::Attribute( const char * name, int* i ) const
+{
+	const char * s = Attribute( name );
+	if ( i )
+	{
+		if ( s )
+			*i = atoi( s );
+		else
+			*i = 0;
+	}
+	return s;
+}
+
+
+const char * TiXmlElement::Attribute( const char * name, double* d ) const
+{
+	const char * s = Attribute( name );
+	if ( d )
+	{
+		if ( s )
+			*d = atof( s );
+		else
+			*d = 0;
+	}
+	return s;
+}
+
+
+int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+
+	return node->QueryIntValue( ival );
+}
+
+
+int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+
+	return node->QueryDoubleValue( dval );
+}
+
+
+void TiXmlElement::SetAttribute( const char * name, int val )
+{	
+	char buf[64];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%d", val );
+	#else
+		sprintf( buf, "%d", val );
+	#endif
+	SetAttribute( name, buf );
+}
+
+
+void TiXmlElement::SetDoubleAttribute( const char * name, double val )
+{	
+	char buf[256];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%f", val );
+	#else
+		sprintf( buf, "%f", val );
+	#endif
+	SetAttribute( name, buf );
+}
+
+
+void TiXmlElement::SetAttribute( const char * name, const char * _value )
+{
+	TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+	{
+		node->SetValue( _value );
+		return;
+	}
+
+	TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
+	if ( attrib )
+	{
+		attributeSet.Add( attrib );
+	}
+	else
+	{
+		TiXmlDocument* document = GetDocument();
+		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+}
+
+void TiXmlElement::Print( FILE* cfile, int depth ) const
+{
+	int i;
+	for ( i=0; i<depth; i++ )
+	{
+		fprintf( cfile, "    " );
+	}
+
+	fprintf( cfile, "<%s", value.c_str() );
+
+	const TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{
+		fprintf( cfile, " " );
+		attrib->Print( cfile, depth );
+	}
+
+	// There are 3 different formatting approaches:
+	// 1) An element without children is printed as a <foo /> node
+	// 2) An element with only a text child is printed as <foo> text </foo>
+	// 3) An element with children is printed on multiple lines.
+	TiXmlNode* node;
+	if ( !firstChild )
+	{
+		fprintf( cfile, " />" );
+	}
+	else if ( firstChild == lastChild && firstChild->ToText() )
+	{
+		fprintf( cfile, ">" );
+		firstChild->Print( cfile, depth + 1 );
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+	else
+	{
+		fprintf( cfile, ">" );
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			if ( !node->ToText() )
+			{
+				fprintf( cfile, "\n" );
+			}
+			node->Print( cfile, depth+1 );
+		}
+		fprintf( cfile, "\n" );
+		for( i=0; i<depth; ++i )
+		fprintf( cfile, "    " );
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+}
+
+void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<" << value;
+
+	const TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{	
+		(*stream) << " ";
+		attrib->StreamOut( stream );
+	}
+
+	// If this node has children, give it a closing tag. Else
+	// make it an empty tag.
+	TiXmlNode* node;
+	if ( firstChild )
+	{ 		
+		(*stream) << ">";
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			node->StreamOut( stream );
+		}
+		(*stream) << "</" << value << ">";
+	}
+	else
+	{
+		(*stream) << " />";
+	}
+}
+
+
+void TiXmlElement::CopyTo( TiXmlElement* target ) const
+{
+	// superclass:
+	TiXmlNode::CopyTo( target );
+
+	// Element class: 
+	// Clone the attributes, then clone the children.
+	const TiXmlAttribute* attribute = 0;
+	for(	attribute = attributeSet.First();
+	attribute;
+	attribute = attribute->Next() )
+	{
+		target->SetAttribute( attribute->Name(), attribute->Value() );
+	}
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}
+}
+
+
+TiXmlNode* TiXmlElement::Clone() const
+{
+	TiXmlElement* clone = new TiXmlElement( Value() );
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+const char* TiXmlElement::GetText() const
+{
+	const TiXmlNode* child = this->FirstChild();
+	if ( child ) {
+		const TiXmlText* childText = child->ToText();
+		if ( childText ) {
+			return childText->Value();
+		}
+	}
+	return 0;
+}
+
+
+TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	ClearError();
+}
+
+TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	value = documentName;
+	ClearError();
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+    value = documentName;
+	ClearError();
+}
+#endif
+
+
+TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDocument::operator=( const TiXmlDocument& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
+{
+	// See STL_STRING_BUG below.
+	StringToBuffer buf( value );
+
+	if ( buf.buffer && LoadFile( buf.buffer, encoding ) )
+		return true;
+
+	return false;
+}
+
+
+bool TiXmlDocument::SaveFile() const
+{
+	// See STL_STRING_BUG below.
+	StringToBuffer buf( value );
+
+	if ( buf.buffer && SaveFile( buf.buffer ) )
+		return true;
+
+	return false;
+}
+
+bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding )
+{
+	// Delete the existing data:
+	Clear();
+	location.Clear();
+
+	// There was a really terrifying little bug here. The code:
+	//		value = filename
+	// in the STL case, cause the assignment method of the std::string to
+	// be called. What is strange, is that the std::string had the same
+	// address as it's c_str() method, and so bad things happen. Looks
+	// like a bug in the Microsoft STL implementation.
+	// See STL_STRING_BUG above.
+	// Fixed with the StringToBuffer class.
+	value = filename;
+
+	// reading in binary mode so that tinyxml can normalize the EOL
+	FILE* file = fopen( value.c_str (), "rb" );	
+
+	if ( file )
+	{
+		// Get the file size, so we can pre-allocate the string. HUGE speed impact.
+		long length = 0;
+		fseek( file, 0, SEEK_END );
+		length = ftell( file );
+		fseek( file, 0, SEEK_SET );
+
+		// Strange case, but good to handle up front.
+		if ( length == 0 )
+		{
+			fclose( file );
+			return false;
+		}
+
+		// If we have a file, assume it is all one big XML file, and read it in.
+		// The document parser may decide the document ends sooner than the entire file, however.
+		TIXML_STRING data;
+		data.reserve( length );
+
+		// Subtle bug here. TinyXml did use fgets. But from the XML spec:
+		// 2.11 End-of-Line Handling
+		// <snip>
+		// <quote>
+		// ...the XML processor MUST behave as if it normalized all line breaks in external 
+		// parsed entities (including the document entity) on input, before parsing, by translating 
+		// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
+		// a single #xA character.
+		// </quote>
+		//
+		// It is not clear fgets does that, and certainly isn't clear it works cross platform. 
+		// Generally, you expect fgets to translate from the convention of the OS to the c/unix
+		// convention, and not work generally.
+
+		/*
+		while( fgets( buf, sizeof(buf), file ) )
+		{
+			data += buf;
+		}
+		*/
+
+		char* buf = new char[ length+1 ];
+		buf[0] = 0;
+
+		if ( fread( buf, length, 1, file ) != 1 ) {
+		//if ( fread( buf, 1, length, file ) != (size_t)length ) {
+			SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+			fclose( file );
+			return false;
+		}
+		fclose( file );
+
+		const char* lastPos = buf;
+		const char* p = buf;
+
+		buf[length] = 0;
+		while( *p ) {
+			assert( p < (buf+length) );
+			if ( *p == 0xa ) {
+				// Newline character. No special rules for this. Append all the characters
+				// since the last string, and include the newline.
+				data.append( lastPos, p-lastPos+1 );	// append, include the newline
+				++p;									// move past the newline
+				lastPos = p;							// and point to the new buffer (may be 0)
+				assert( p <= (buf+length) );
+			}
+			else if ( *p == 0xd ) {
+				// Carriage return. Append what we have so far, then
+				// handle moving forward in the buffer.
+				if ( (p-lastPos) > 0 ) {
+					data.append( lastPos, p-lastPos );	// do not add the CR
+				}
+				data += (char)0xa;						// a proper newline
+
+				if ( *(p+1) == 0xa ) {
+					// Carriage return - new line sequence
+					p += 2;
+					lastPos = p;
+					assert( p <= (buf+length) );
+				}
+				else {
+					// it was followed by something else...that is presumably characters again.
+					++p;
+					lastPos = p;
+					assert( p <= (buf+length) );
+				}
+			}
+			else {
+				++p;
+			}
+		}
+		// Handle any left over characters.
+		if ( p-lastPos ) {
+			data.append( lastPos, p-lastPos );
+		}		
+		delete [] buf;
+		buf = 0;
+
+		Parse( data.c_str(), 0, encoding );
+
+		if (  Error() )
+            return false;
+        else
+			return true;
+	}
+	SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+	return false;
+}
+
+bool TiXmlDocument::SaveFile( const char * filename ) const
+{
+	// The old c stuff lives on...
+	FILE* fp = fopen( filename, "w" );
+	if ( fp )
+	{
+		if ( useMicrosoftBOM ) 
+		{
+			const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+			const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+			const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+			fputc( TIXML_UTF_LEAD_0, fp );
+			fputc( TIXML_UTF_LEAD_1, fp );
+			fputc( TIXML_UTF_LEAD_2, fp );
+		}
+		Print( fp, 0 );
+		fclose( fp );
+		return true;
+	}
+	return false;
+}
+
+
+void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->error = error;
+	target->errorDesc = errorDesc.c_str ();
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}	
+}
+
+
+TiXmlNode* TiXmlDocument::Clone() const
+{
+	TiXmlDocument* clone = new TiXmlDocument();
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlDocument::Print( FILE* cfile, int depth ) const
+{
+	const TiXmlNode* node;
+	for ( node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->Print( cfile, depth );
+		fprintf( cfile, "\n" );
+	}
+}
+
+void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const
+{
+	const TiXmlNode* node;
+	for ( node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->StreamOut( out );
+
+		// Special rule for streams: stop after the root element.
+		// The stream in code will only read one element, so don't
+		// write more than one.
+		if ( node->ToElement() )
+			break;
+	}
+}
+
+
+const TiXmlAttribute* TiXmlAttribute::Next() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+
+TiXmlAttribute* TiXmlAttribute::Next()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+
+const TiXmlAttribute* TiXmlAttribute::Previous() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+
+TiXmlAttribute* TiXmlAttribute::Previous()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+
+void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const
+{
+	TIXML_STRING n, v;
+
+	PutString( name, &n );
+	PutString( value, &v );
+
+	if (value.find ('\"') == TIXML_STRING::npos)
+		fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
+	else
+		fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
+}
+
+
+void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	if (value.find( '\"' ) != TIXML_STRING::npos)
+	{
+		PutString( name, stream );
+		(*stream) << "=" << "'";
+		PutString( value, stream );
+		(*stream) << "'";
+	}
+	else
+	{
+		PutString( name, stream );
+		(*stream) << "=" << "\"";
+		PutString( value, stream );
+		(*stream) << "\"";
+	}
+}
+
+int TiXmlAttribute::QueryIntValue( int* ival ) const
+{
+	if ( sscanf( value.c_str(), "%d", ival ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+int TiXmlAttribute::QueryDoubleValue( double* dval ) const
+{
+	if ( sscanf( value.c_str(), "%lf", dval ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+void TiXmlAttribute::SetIntValue( int _value )
+{
+	char buf [64];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
+	#else
+		sprintf (buf, "%d", _value);
+	#endif
+	SetValue (buf);
+}
+
+void TiXmlAttribute::SetDoubleValue( double _value )
+{
+	char buf [256];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value);
+	#else
+		sprintf (buf, "%lf", _value);
+	#endif
+	SetValue (buf);
+}
+
+int TiXmlAttribute::IntValue() const
+{
+	return atoi (value.c_str ());
+}
+
+double  TiXmlAttribute::DoubleValue() const
+{
+	return atof (value.c_str ());
+}
+
+
+TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlComment::operator=( const TiXmlComment& base )
+{
+	Clear();
+	base.CopyTo( this );
+}
+
+
+void TiXmlComment::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+	{
+		fputs( "    ", cfile );
+	}
+	fprintf( cfile, "<!--%s-->", value.c_str() );
+}
+
+void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<!--";
+	//PutString( value, stream );
+	(*stream) << value;
+	(*stream) << "-->";
+}
+
+
+void TiXmlComment::CopyTo( TiXmlComment* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+TiXmlNode* TiXmlComment::Clone() const
+{
+	TiXmlComment* clone = new TiXmlComment();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlText::Print( FILE* cfile, int depth ) const
+{
+	if ( cdata )
+	{
+		int i;
+		fprintf( cfile, "\n" );
+		for ( i=0; i<depth; i++ ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "<![CDATA[" );
+		fprintf( cfile, "%s", value.c_str() );	// unformatted output
+		fprintf( cfile, "]]>\n" );
+	}
+	else
+	{
+		TIXML_STRING buffer;
+		PutString( value, &buffer );
+		fprintf( cfile, "%s", buffer.c_str() );
+	}
+}
+
+
+void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	if ( cdata )
+	{
+		(*stream) << "<![CDATA[" << value << "]]>";
+	}
+	else
+	{
+		PutString( value, stream );
+	}
+}
+
+
+void TiXmlText::CopyTo( TiXmlText* target ) const
+{
+	TiXmlNode::CopyTo( target );
+	target->cdata = cdata;
+}
+
+
+TiXmlNode* TiXmlText::Clone() const
+{	
+	TiXmlText* clone = 0;
+	clone = new TiXmlText( "" );
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlDeclaration::TiXmlDeclaration( const char * _version,
+									const char * _encoding,
+									const char * _standalone )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDeclaration::TiXmlDeclaration(	const std::string& _version,
+									const std::string& _encoding,
+									const std::string& _standalone )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+#endif
+
+
+TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	copy.CopyTo( this );	
+}
+
+
+void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const
+{
+	fprintf (cfile, "<?xml ");
+
+	if ( !version.empty() )
+		fprintf (cfile, "version=\"%s\" ", version.c_str ());
+	if ( !encoding.empty() )
+		fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
+	if ( !standalone.empty() )
+		fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
+	fprintf (cfile, "?>");
+}
+
+void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<?xml ";
+
+	if ( !version.empty() )
+	{
+		(*stream) << "version=\"";
+		PutString( version, stream );
+		(*stream) << "\" ";
+	}
+	if ( !encoding.empty() )
+	{
+		(*stream) << "encoding=\"";
+		PutString( encoding, stream );
+		(*stream ) << "\" ";
+	}
+	if ( !standalone.empty() )
+	{
+		(*stream) << "standalone=\"";
+		PutString( standalone, stream );
+		(*stream) << "\" ";
+	}
+	(*stream) << "?>";
+}
+
+
+void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->version = version;
+	target->encoding = encoding;
+	target->standalone = standalone;
+}
+
+
+TiXmlNode* TiXmlDeclaration::Clone() const
+{	
+	TiXmlDeclaration* clone = new TiXmlDeclaration();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlUnknown::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+		fprintf( cfile, "    " );
+	fprintf( cfile, "<%s>", value.c_str() );
+}
+
+
+void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<" << value << ">";		// Don't use entities here! It is unknown.
+}
+
+
+void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+TiXmlNode* TiXmlUnknown::Clone() const
+{
+	TiXmlUnknown* clone = new TiXmlUnknown();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlAttributeSet::TiXmlAttributeSet()
+{
+	sentinel.next = &sentinel;
+	sentinel.prev = &sentinel;
+}
+
+
+TiXmlAttributeSet::~TiXmlAttributeSet()
+{
+	assert( sentinel.next == &sentinel );
+	assert( sentinel.prev == &sentinel );
+}
+
+
+void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
+{
+	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
+
+	addMe->next = &sentinel;
+	addMe->prev = sentinel.prev;
+
+	sentinel.prev->next = addMe;
+	sentinel.prev      = addMe;
+}
+
+void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node == removeMe )
+		{
+			node->prev->next = node->next;
+			node->next->prev = node->prev;
+			node->next = 0;
+			node->prev = 0;
+			return;
+		}
+	}
+	assert( 0 );		// we tried to remove a non-linked attribute.
+}
+
+const TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) const
+{
+	const TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlAttribute*	TiXmlAttributeSet::Find( const char * name )
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+#ifdef TIXML_USE_STL	
+TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
+{
+	TIXML_STRING tag;
+	tag.reserve( 8 * 1000 );
+	base.StreamIn( &in, &tag );
+
+	base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
+	return in;
+}
+#endif
+
+
+TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
+{
+	base.StreamOut (& out);
+	return out;
+}
+
+
+#ifdef TIXML_USE_STL	
+std::string & operator<< (std::string& out, const TiXmlNode& base )
+{
+   std::ostringstream os_stream( std::ostringstream::out );
+   base.StreamOut( &os_stream );
+   
+   out.append( os_stream.str() );
+   return out;
+}
+#endif
+
+
+TiXmlHandle TiXmlHandle::FirstChild() const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement() const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
Index: branches/heathaze/src/lib/parser/tinyxml/tinyxml.h
===================================================================
--- branches/heathaze/src/lib/parser/tinyxml/tinyxml.h	(revision 9940)
+++ branches/heathaze/src/lib/parser/tinyxml/tinyxml.h	(revision 9940)
@@ -0,0 +1,1513 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+
+#ifndef TINYXML_INCLUDED
+#define TINYXML_INCLUDED
+
+#define TIXML_USE_STL
+
+#ifdef _MSC_VER
+#pragma warning( push )
+#pragma warning( disable : 4530 )
+#pragma warning( disable : 4786 )
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+// Help out windows:
+#if defined( _DEBUG ) && !defined( DEBUG )
+#define DEBUG
+#endif
+
+#if defined( DEBUG ) && defined( _MSC_VER )
+#include <windows.h>
+#define TIXML_LOG OutputDebugString
+#else
+#define TIXML_LOG printf
+#endif
+
+#ifdef TIXML_USE_STL
+	#include <string>
+ 	#include <iostream>
+	#define TIXML_STRING	std::string
+	#define TIXML_ISTREAM	std::istream
+	#define TIXML_OSTREAM	std::ostream
+#else
+	#include "tinystr.h"
+	#define TIXML_STRING	TiXmlString
+	#define TIXML_OSTREAM	TiXmlOutStream
+#endif
+
+// Deprecated library function hell. Compilers want to use the
+// new safe versions. This probably doesn't fully address the problem,
+// but it gets closer. There are too many compilers for me to fully
+// test. If you get compilation troubles, undefine TIXML_SAFE
+
+#define TIXML_SAFE		// TinyXml isn't fully buffer overrun protected, safe code. This is work in progress.
+#ifdef TIXML_SAFE
+	#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
+		// Microsoft visual studio, version 6 and higher.
+		//#pragma message( "Using _sn* functions." )
+		#define TIXML_SNPRINTF _snprintf
+		#define TIXML_SNSCANF  _snscanf
+	#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+		// GCC version 3 and higher.s
+		//#warning( "Using sn* functions." )
+		#define TIXML_SNPRINTF snprintf
+		#define TIXML_SNSCANF  snscanf
+	#endif
+#endif
+
+class TiXmlDocument;
+class TiXmlElement;
+class TiXmlComment;
+class TiXmlUnknown;
+class TiXmlAttribute;
+class TiXmlText;
+class TiXmlDeclaration;
+class TiXmlParsingData;
+
+const int TIXML_MAJOR_VERSION = 2;
+const int TIXML_MINOR_VERSION = 4;
+const int TIXML_PATCH_VERSION = 2;
+
+/*	Internal structure for tracking location of items
+	in the XML file.
+*/
+struct TiXmlCursor
+{
+	TiXmlCursor()		{ Clear(); }
+	void Clear()		{ row = col = -1; }
+
+	int row;	// 0 based.
+	int col;	// 0 based.
+};
+
+
+// Only used by Attribute::Query functions
+enum
+{
+	TIXML_SUCCESS,
+	TIXML_NO_ATTRIBUTE,
+	TIXML_WRONG_TYPE
+};
+
+
+// Used by the parsing routines.
+enum TiXmlEncoding
+{
+	TIXML_ENCODING_UNKNOWN,
+	TIXML_ENCODING_UTF8,
+	TIXML_ENCODING_LEGACY
+};
+
+const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
+
+/** TiXmlBase is a base class for every class in TinyXml.
+	It does little except to establish that TinyXml classes
+	can be printed and provide some utility functions.
+
+	In XML, the document and elements can contain
+	other elements and other types of nodes.
+
+	@verbatim
+	A Document can contain:	Element	(container or leaf)
+							Comment (leaf)
+							Unknown (leaf)
+							Declaration( leaf )
+
+	An Element can contain:	Element (container or leaf)
+							Text	(leaf)
+							Attributes (not on tree)
+							Comment (leaf)
+							Unknown (leaf)
+
+	A Decleration contains: Attributes (not on tree)
+	@endverbatim
+*/
+class TiXmlBase
+{
+	friend class TiXmlNode;
+	friend class TiXmlElement;
+	friend class TiXmlDocument;
+
+public:
+	TiXmlBase()	:	userData(0) {}
+	virtual ~TiXmlBase()					{}
+
+	/**	All TinyXml classes can print themselves to a filestream.
+		This is a formatted print, and will insert tabs and newlines.
+
+		(For an unformatted stream, use the << operator.)
+	*/
+	virtual void Print( FILE* cfile, int depth ) const = 0;
+
+	/**	The world does not agree on whether white space should be kept or
+		not. In order to make everyone happy, these global, static functions
+		are provided to set whether or not TinyXml will condense all white space
+		into a single space or not. The default is to condense. Note changing this
+		values is not thread safe.
+	*/
+	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
+
+	/// Return the current white space setting.
+	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
+
+	/** Return the position, in the original source file, of this node or attribute.
+		The row and column are 1-based. (That is the first row and first column is
+		1,1). If the returns values are 0 or less, then the parser does not have
+		a row and column value.
+
+		Generally, the row and column value will be set when the TiXmlDocument::Load(),
+		TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
+		when the DOM was created from operator>>.
+
+		The values reflect the initial load. Once the DOM is modified programmatically
+		(by adding or changing nodes and attributes) the new values will NOT update to
+		reflect changes in the document.
+
+		There is a minor performance cost to computing the row and column. Computation
+		can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
+
+		@sa TiXmlDocument::SetTabSize()
+	*/
+	int Row() const			{ return location.row + 1; }
+	int Column() const		{ return location.col + 1; }	///< See Row()
+
+	void  SetUserData( void* user )			{ userData = user; }
+	void* GetUserData()						{ return userData; }
+
+	// Table that returs, for a given lead byte, the total number of bytes
+	// in the UTF-8 sequence.
+	static const int utf8ByteTable[256];
+
+	virtual const char* Parse(	const char* p,
+								TiXmlParsingData* data,
+								TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
+
+	enum
+	{
+		TIXML_NO_ERROR = 0,
+		TIXML_ERROR,
+		TIXML_ERROR_OPENING_FILE,
+		TIXML_ERROR_OUT_OF_MEMORY,
+		TIXML_ERROR_PARSING_ELEMENT,
+		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
+		TIXML_ERROR_READING_ELEMENT_VALUE,
+		TIXML_ERROR_READING_ATTRIBUTES,
+		TIXML_ERROR_PARSING_EMPTY,
+		TIXML_ERROR_READING_END_TAG,
+		TIXML_ERROR_PARSING_UNKNOWN,
+		TIXML_ERROR_PARSING_COMMENT,
+		TIXML_ERROR_PARSING_DECLARATION,
+		TIXML_ERROR_DOCUMENT_EMPTY,
+		TIXML_ERROR_EMBEDDED_NULL,
+		TIXML_ERROR_PARSING_CDATA,
+
+		TIXML_ERROR_STRING_COUNT
+	};
+
+protected:
+
+	// See STL_STRING_BUG
+	// Utility class to overcome a bug.
+	class StringToBuffer
+	{
+	  public:
+		StringToBuffer( const TIXML_STRING& str );
+		~StringToBuffer();
+		char* buffer;
+	};
+
+	static const char*	SkipWhiteSpace( const char*, TiXmlEncoding encoding );
+	inline static bool	IsWhiteSpace( char c )
+	{
+		return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
+	}
+
+	virtual void StreamOut (TIXML_OSTREAM *) const = 0;
+
+	#ifdef TIXML_USE_STL
+	    static bool	StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	    static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
+	#endif
+
+	/*	Reads an XML name into the string provided. Returns
+		a pointer just past the last character of the name,
+		or 0 if the function has an error.
+	*/
+	static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
+
+	/*	Reads text. Returns a pointer past the given end tag.
+		Wickedly complex options, but it keeps the (sensitive) code in one place.
+	*/
+	static const char* ReadText(	const char* in,				// where to start
+									TIXML_STRING* text,			// the string read
+									bool ignoreWhiteSpace,		// whether to keep the white space
+									const char* endTag,			// what ends this text
+									bool ignoreCase,			// whether to ignore case in the end tag
+									TiXmlEncoding encoding );	// the current encoding
+
+	// If an entity has been found, transform it into a character.
+	static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
+
+	// Get a character, while interpreting entities.
+	// The length can be from 0 to 4 bytes.
+	inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
+	{
+		assert( p );
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			*length = utf8ByteTable[ *((unsigned char*)p) ];
+			assert( *length >= 0 && *length < 5 );
+		}
+		else
+		{
+			*length = 1;
+		}
+
+		if ( *length == 1 )
+		{
+			if ( *p == '&' )
+				return GetEntity( p, _value, length, encoding );
+			*_value = *p;
+			return p+1;
+		}
+		else if ( *length )
+		{
+			//strncpy( _value, p, *length );	// lots of compilers don't like this function (unsafe),
+												// and the null terminator isn't needed
+			for( int i=0; p[i] && i<*length; ++i ) {
+				_value[i] = p[i];
+			}
+			return p + (*length);
+		}
+		else
+		{
+			// Not valid text.
+			return 0;
+		}
+	}
+
+	// Puts a string to a stream, expanding entities as it goes.
+	// Note this should not contian the '<', '>', etc, or they will be transformed into entities!
+	static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
+
+	static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
+
+	// Return true if the next characters in the stream are any of the endTag sequences.
+	// Ignore case only works for english, and should only be relied on when comparing
+	// to English words: StringEqual( p, "version", true ) is fine.
+	static bool StringEqual(	const char* p,
+								const char* endTag,
+								bool ignoreCase,
+								TiXmlEncoding encoding );
+
+	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
+
+	TiXmlCursor location;
+
+    /// Field containing a generic user pointer
+	void*			userData;
+
+	// None of these methods are reliable for any language except English.
+	// Good for approximation, not great for accuracy.
+	static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
+	static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
+	inline static int ToLower( int v, TiXmlEncoding encoding )
+	{
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			if ( v < 128 ) return tolower( v );
+			return v;
+		}
+		else
+		{
+			return tolower( v );
+		}
+	}
+	static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
+
+private:
+	TiXmlBase( const TiXmlBase& );				// not implemented.
+	void operator=( const TiXmlBase& base );	// not allowed.
+
+	struct Entity
+	{
+		const char*     str;
+		unsigned int	strLength;
+		char		    chr;
+	};
+	enum
+	{
+		NUM_ENTITY = 5,
+		MAX_ENTITY_LENGTH = 6
+
+	};
+	static Entity entity[ NUM_ENTITY ];
+	static bool condenseWhiteSpace;
+};
+
+
+/** The parent class for everything in the Document Object Model.
+	(Except for attributes).
+	Nodes have siblings, a parent, and children. A node can be
+	in a document, or stand on its own. The type of a TiXmlNode
+	can be queried, and it can be cast to its more defined type.
+*/
+class TiXmlNode : public TiXmlBase
+{
+	friend class TiXmlDocument;
+	friend class TiXmlElement;
+
+public:
+	#ifdef TIXML_USE_STL
+
+	    /** An input stream operator, for every class. Tolerant of newlines and
+		    formatting, but doesn't expect them.
+	    */
+	    friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
+
+	    /** An output stream operator, for every class. Note that this outputs
+		    without any newlines or formatting, as opposed to Print(), which
+		    includes tabs and new lines.
+
+		    The operator<< and operator>> are not completely symmetric. Writing
+		    a node to a stream is very well defined. You'll get a nice stream
+		    of output, without any extra whitespace or newlines.
+
+		    But reading is not as well defined. (As it always is.) If you create
+		    a TiXmlElement (for example) and read that from an input stream,
+		    the text needs to define an element or junk will result. This is
+		    true of all input streams, but it's worth keeping in mind.
+
+		    A TiXmlDocument will read nodes until it reads a root element, and
+			all the children of that root element.
+	    */
+	    friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
+
+		/// Appends the XML node or attribute to a std::string.
+		friend std::string& operator<< (std::string& out, const TiXmlNode& base );
+
+	#else
+	    // Used internally, not part of the public API.
+	    friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
+	#endif
+
+	/** The types of XML nodes supported by TinyXml. (All the
+			unsupported types are picked up by UNKNOWN.)
+	*/
+	enum NodeType
+	{
+		DOCUMENT,
+		ELEMENT,
+		COMMENT,
+		UNKNOWN,
+		TEXT,
+		DECLARATION,
+		TYPECOUNT
+	};
+
+	virtual ~TiXmlNode();
+
+	/** The meaning of 'value' changes for the specific type of
+		TiXmlNode.
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+
+		The subclasses will wrap this function.
+	*/
+	const char *Value() const { return value.c_str (); }
+
+    #ifdef TIXML_USE_STL
+	/** Return Value() as a std::string. If you only use STL,
+	    this is more efficient than calling Value().
+		Only available in STL mode.
+	*/
+	const std::string& ValueStr() const { return value; }
+	#endif
+
+	/** Changes the value of the node. Defined as:
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+	*/
+	void SetValue(const char * _value) { value = _value;}
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetValue( const std::string& _value )
+	{
+		StringToBuffer buf( _value );
+		SetValue( buf.buffer ? buf.buffer : "" );
+	}
+	#endif
+
+	/// Delete all the children of this node. Does not affect 'this'.
+	void Clear();
+
+	/// One step up the DOM.
+	TiXmlNode* Parent()							{ return parent; }
+	const TiXmlNode* Parent() const				{ return parent; }
+
+	const TiXmlNode* FirstChild()	const	{ return firstChild; }		///< The first child of this node. Will be null if there are no children.
+	TiXmlNode* FirstChild()					{ return firstChild; }
+	const TiXmlNode* FirstChild( const char * value ) const;			///< The first child of this node with the matching 'value'. Will be null if none found.
+	TiXmlNode* FirstChild( const char * value );						///< The first child of this node with the matching 'value'. Will be null if none found.
+
+	const TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
+	TiXmlNode* LastChild()	{ return lastChild; }
+	const TiXmlNode* LastChild( const char * value ) const;			/// The last child of this node matching 'value'. Will be null if there are no children.
+	TiXmlNode* LastChild( const char * value );
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* FirstChild( const std::string& _value ) const	{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* FirstChild( const std::string& _value )				{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* LastChild( const std::string& _value ) const	{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* LastChild( const std::string& _value )				{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** An alternate way to walk the children of a node.
+		One way to iterate over nodes is:
+		@verbatim
+			for( child = parent->FirstChild(); child; child = child->NextSibling() )
+		@endverbatim
+
+		IterateChildren does the same thing with the syntax:
+		@verbatim
+			child = 0;
+			while( child = parent->IterateChildren( child ) )
+		@endverbatim
+
+		IterateChildren takes the previous child as input and finds
+		the next one. If the previous child is null, it returns the
+		first. IterateChildren will return null when done.
+	*/
+	const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( TiXmlNode* previous );
+
+	/// This flavor of IterateChildren searches for children with a particular 'value'
+	const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous );
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const	{	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) {	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	#endif
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
+
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+
+		NOTE: the node to be added is passed by pointer, and will be
+		henceforth owned (and deleted) by tinyXml. This method is efficient
+		and avoids an extra copy, but should be used with care as it
+		uses a different memory model than the other insert functions.
+
+		@sa InsertEndChild
+	*/
+	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
+
+	/** Add a new node related to this. Adds a child before the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
+
+	/** Add a new node related to this. Adds a child after the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
+
+	/** Replace a child of this node.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
+
+	/// Delete a child of this node.
+	bool RemoveChild( TiXmlNode* removeThis );
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling() const			{ return prev; }
+	TiXmlNode* PreviousSibling()						{ return prev; }
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling( const char * ) const;
+	TiXmlNode* PreviousSibling( const char * );
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* PreviousSibling( const std::string& _value ) const	{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* PreviousSibling( const std::string& _value ) 			{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* NextSibling( const std::string& _value) const		{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* NextSibling( const std::string& _value) 					{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* NextSibling() const				{ return next; }
+	TiXmlNode* NextSibling()							{ return next; }
+
+	/// Navigate to a sibling node with the given 'value'.
+	const TiXmlNode* NextSibling( const char * ) const;
+	TiXmlNode* NextSibling( const char * );
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement() const;
+	TiXmlElement* NextSiblingElement();
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement( const char * ) const;
+	TiXmlElement* NextSiblingElement( const char * );
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* NextSiblingElement( const std::string& _value) const	{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* NextSiblingElement( const std::string& _value)				{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement()	const;
+	TiXmlElement* FirstChildElement();
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement( const char * value ) const;
+	TiXmlElement* FirstChildElement( const char * value );
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* FirstChildElement( const std::string& _value ) const	{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* FirstChildElement( const std::string& _value )				{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** Query the type (as an enumerated value, above) of this node.
+		The possible types are: DOCUMENT, ELEMENT, COMMENT,
+								UNKNOWN, TEXT, and DECLARATION.
+	*/
+	int Type() const	{ return type; }
+
+	/** Return a pointer to the Document this node lives in.
+		Returns null if not in a document.
+	*/
+	const TiXmlDocument* GetDocument() const;
+	TiXmlDocument* GetDocument();
+
+	/// Returns true if this node has no children.
+	bool NoChildren() const						{ return !firstChild; }
+
+	const TiXmlDocument* ToDocument()	const		{ return ( this && type == DOCUMENT ) ? (const TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlElement*  ToElement() const			{ return ( this && type == ELEMENT  ) ? (const TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlComment*  ToComment() const			{ return ( this && type == COMMENT  ) ? (const TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlUnknown*  ToUnknown() const			{ return ( this && type == UNKNOWN  ) ? (const TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlText*	   ToText()    const		{ return ( this && type == TEXT     ) ? (const TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlDeclaration* ToDeclaration() const	{ return ( this && type == DECLARATION ) ? (const TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	TiXmlDocument* ToDocument()			{ return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlElement*  ToElement()			{ return ( this && type == ELEMENT  ) ? (TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlComment*  ToComment()			{ return ( this && type == COMMENT  ) ? (TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlUnknown*  ToUnknown()			{ return ( this && type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlText*	   ToText()   			{ return ( this && type == TEXT     ) ? (TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlDeclaration* ToDeclaration()	{ return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Create an exact duplicate of this node and return it. The memory must be deleted
+		by the caller.
+	*/
+	virtual TiXmlNode* Clone() const = 0;
+
+protected:
+	TiXmlNode( NodeType _type );
+
+	// Copy to the allocated object. Shared functionality between Clone, Copy constructor,
+	// and the assignment operator.
+	void CopyTo( TiXmlNode* target ) const;
+
+	#ifdef TIXML_USE_STL
+	    // The real work of the input operator.
+	    virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
+	#endif
+
+	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
+	TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
+
+	TiXmlNode*		parent;
+	NodeType		type;
+
+	TiXmlNode*		firstChild;
+	TiXmlNode*		lastChild;
+
+	TIXML_STRING	value;
+
+	TiXmlNode*		prev;
+	TiXmlNode*		next;
+
+private:
+	TiXmlNode( const TiXmlNode& );				// not implemented.
+	void operator=( const TiXmlNode& base );	// not allowed.
+};
+
+
+/** An attribute is a name-value pair. Elements have an arbitrary
+	number of attributes, each with a unique name.
+
+	@note The attributes are not TiXmlNodes, since they are not
+		  part of the tinyXML document object model. There are other
+		  suggested ways to look at this problem.
+*/
+class TiXmlAttribute : public TiXmlBase
+{
+	friend class TiXmlAttributeSet;
+
+public:
+	/// Construct an empty attribute.
+	TiXmlAttribute() : TiXmlBase()
+	{
+		document = 0;
+		prev = next = 0;
+	}
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlAttribute( const std::string& _name, const std::string& _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+	#endif
+
+	/// Construct an attribute with a name and value.
+	TiXmlAttribute( const char * _name, const char * _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+
+	const char*		Name()  const		{ return name.c_str (); }		///< Return the name of this attribute.
+	const char*		Value() const		{ return value.c_str (); }		///< Return the value of this attribute.
+	int				IntValue() const;									///< Return the value of this attribute, converted to an integer.
+	double			DoubleValue() const;								///< Return the value of this attribute, converted to a double.
+
+	/** QueryIntValue examines the value string. It is an alternative to the
+		IntValue() method with richer error checking.
+		If the value is an integer, it is stored in 'value' and
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE.
+
+		A specialized but useful call. Note that for success it returns 0,
+		which is the opposite of almost all other TinyXml calls.
+	*/
+	int QueryIntValue( int* _value ) const;
+	/// QueryDoubleValue examines the value string. See QueryIntValue().
+	int QueryDoubleValue( double* _value ) const;
+
+	void SetName( const char* _name )	{ name = _name; }				///< Set the name of this attribute.
+	void SetValue( const char* _value )	{ value = _value; }				///< Set the value.
+
+	void SetIntValue( int _value );										///< Set the value from an integer.
+	void SetDoubleValue( double _value );								///< Set the value from a double.
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetName( const std::string& _name )
+	{
+		StringToBuffer buf( _name );
+		SetName ( buf.buffer ? buf.buffer : "error" );
+	}
+	/// STL std::string form.
+	void SetValue( const std::string& _value )
+	{
+		StringToBuffer buf( _value );
+		SetValue( buf.buffer ? buf.buffer : "error" );
+	}
+	#endif
+
+	/// Get the next sibling attribute in the DOM. Returns null at end.
+	const TiXmlAttribute* Next() const;
+	TiXmlAttribute* Next();
+	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
+	const TiXmlAttribute* Previous() const;
+	TiXmlAttribute* Previous();
+
+	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
+	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
+	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
+
+	/*	Attribute parsing starts: first letter of the name
+						 returns: the next char after the value end quote
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	// Prints this Attribute to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+	// [internal use]
+	// Set the document pointer so the attribute can report errors.
+	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
+
+private:
+	TiXmlAttribute( const TiXmlAttribute& );				// not implemented.
+	void operator=( const TiXmlAttribute& base );	// not allowed.
+
+	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
+	TIXML_STRING name;
+	TIXML_STRING value;
+	TiXmlAttribute*	prev;
+	TiXmlAttribute*	next;
+};
+
+
+/*	A class used to manage a group of attributes.
+	It is only used internally, both by the ELEMENT and the DECLARATION.
+
+	The set can be changed transparent to the Element and Declaration
+	classes that use it, but NOT transparent to the Attribute
+	which has to implement a next() and previous() method. Which makes
+	it a bit problematic and prevents the use of STL.
+
+	This version is implemented with circular lists because:
+		- I like circular lists
+		- it demonstrates some independence from the (typical) doubly linked list.
+*/
+class TiXmlAttributeSet
+{
+public:
+	TiXmlAttributeSet();
+	~TiXmlAttributeSet();
+
+	void Add( TiXmlAttribute* attribute );
+	void Remove( TiXmlAttribute* attribute );
+
+	const TiXmlAttribute* First()	const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	TiXmlAttribute* First()					{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	const TiXmlAttribute* Last() const		{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+	TiXmlAttribute* Last()					{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+
+	const TiXmlAttribute*	Find( const char * name ) const;
+	TiXmlAttribute*	Find( const char * name );
+
+private:
+	//*ME:	Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
+	//*ME:	this class must be also use a hidden/disabled copy-constructor !!!
+	TiXmlAttributeSet( const TiXmlAttributeSet& );	// not allowed
+	void operator=( const TiXmlAttributeSet& );	// not allowed (as TiXmlAttribute)
+
+	TiXmlAttribute sentinel;
+};
+
+
+/** The element is a container class. It has a value, the element name,
+	and can contain other elements, text, comments, and unknowns.
+	Elements also contain an arbitrary number of attributes.
+*/
+class TiXmlElement : public TiXmlNode
+{
+public:
+	/// Construct an element.
+	TiXmlElement (const char * in_value);
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlElement( const std::string& _value );
+	#endif
+
+	TiXmlElement( const TiXmlElement& );
+
+	void operator=( const TiXmlElement& base );
+
+	virtual ~TiXmlElement();
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+	*/
+	const char* Attribute( const char* name ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an integer,
+		the integer value will be put in the return 'i', if 'i'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, int* i ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an double,
+		the double value will be put in the return 'd', if 'd'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, double* d ) const;
+
+	/** QueryIntAttribute examines the attribute - it is an alternative to the
+		Attribute() method with richer error checking.
+		If the attribute is an integer, it is stored in 'value' and
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE. If the attribute
+		does not exist, then TIXML_NO_ATTRIBUTE is returned.
+	*/
+	int QueryIntAttribute( const char* name, int* _value ) const;
+	/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
+	int QueryDoubleAttribute( const char* name, double* _value ) const;
+	/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
+	int QueryFloatAttribute( const char* name, float* _value ) const {
+		double d;
+		int result = QueryDoubleAttribute( name, &d );
+		if ( result == TIXML_SUCCESS ) {
+			*_value = (float)d;
+		}
+		return result;
+	}
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char* name, const char * _value );
+
+    #ifdef TIXML_USE_STL
+	const char* Attribute( const std::string& name ) const				{ return Attribute( name.c_str() ); }
+	const char* Attribute( const std::string& name, int* i ) const		{ return Attribute( name.c_str(), i ); }
+	const char* Attribute( const std::string& name, double* d ) const	{ return Attribute( name.c_str(), d ); }
+	int QueryIntAttribute( const std::string& name, int* _value ) const	{ return QueryIntAttribute( name.c_str(), _value ); }
+	int QueryDoubleAttribute( const std::string& name, double* _value ) const { return QueryDoubleAttribute( name.c_str(), _value ); }
+
+	/// STL std::string form.
+	void SetAttribute( const std::string& name, const std::string& _value )
+	{
+		StringToBuffer n( name );
+		StringToBuffer v( _value );
+		if ( n.buffer && v.buffer )
+			SetAttribute (n.buffer, v.buffer );
+	}
+	///< STL std::string form.
+	void SetAttribute( const std::string& name, int _value )
+	{
+		StringToBuffer n( name );
+		if ( n.buffer )
+			SetAttribute (n.buffer, _value);
+	}
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char * name, int value );
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetDoubleAttribute( const char * name, double value );
+
+	/** Deletes an attribute with the given name.
+	*/
+	void RemoveAttribute( const char * name );
+    #ifdef TIXML_USE_STL
+	void RemoveAttribute( const std::string& name )	{	RemoveAttribute (name.c_str ());	}	///< STL std::string form.
+	#endif
+
+	const TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
+	TiXmlAttribute* FirstAttribute() 				{ return attributeSet.First(); }
+	const TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
+	TiXmlAttribute* LastAttribute()					{ return attributeSet.Last(); }
+
+	/** Convenience function for easy access to the text inside an element. Although easy
+		and concise, GetText() is limited compared to getting the TiXmlText child
+		and accessing it directly.
+
+		If the first child of 'this' is a TiXmlText, the GetText()
+		returns the character string of the Text node, else null is returned.
+
+		This is a convenient method for getting the text of simple contained text:
+		@verbatim
+		<foo>This is text</foo>
+		const char* str = fooElement->GetText();
+		@endverbatim
+
+		'str' will be a pointer to "This is text".
+
+		Note that this function can be misleading. If the element foo was created from
+		this XML:
+		@verbatim
+		<foo><b>This is text</b></foo>
+		@endverbatim
+
+		then the value of str would be null. The first child node isn't a text node, it is
+		another element. From this XML:
+		@verbatim
+		<foo>This is <b>text</b></foo>
+		@endverbatim
+		GetText() will return "This is ".
+
+		WARNING: GetText() accesses a child node - don't become confused with the
+				 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
+				 safe type casts on the referenced node.
+	*/
+	const char* GetText() const;
+
+	/// Creates a new Element and returns it - the returned element is a copy.
+	virtual TiXmlNode* Clone() const;
+	// Print the Element to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: next char past '<'
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected:
+
+	void CopyTo( TiXmlElement* target ) const;
+	void ClearThis();	// like clear, but initializes 'this' object as well
+
+	// Used to be public [internal use]
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+
+	/*	[internal use]
+		Reads the "value" of the element -- another element, or text.
+		This should terminate with the current end tag.
+	*/
+	const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+private:
+
+	TiXmlAttributeSet attributeSet;
+};
+
+
+/**	An XML comment.
+*/
+class TiXmlComment : public TiXmlNode
+{
+public:
+	/// Constructs an empty comment.
+	TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
+	TiXmlComment( const TiXmlComment& );
+	void operator=( const TiXmlComment& base );
+
+	virtual ~TiXmlComment()	{}
+
+	/// Returns a copy of this Comment.
+	virtual TiXmlNode* Clone() const;
+	/// Write this Comment to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: at the ! of the !--
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected:
+	void CopyTo( TiXmlComment* target ) const;
+
+	// used to be public
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+
+private:
+
+};
+
+
+/** XML text. A text node can have 2 ways to output the next. "normal" output
+	and CDATA. It will default to the mode it was parsed from the XML file and
+	you generally want to leave it alone, but you can change the output mode with
+	SetCDATA() and query it with CDATA().
+*/
+class TiXmlText : public TiXmlNode
+{
+	friend class TiXmlElement;
+public:
+	/** Constructor for text element. By default, it is treated as
+		normal, encoded text. If you want it be output as a CDATA text
+		element, set the parameter _cdata to 'true'
+	*/
+	TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	virtual ~TiXmlText() {}
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	#endif
+
+	TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )	{ copy.CopyTo( this ); }
+	void operator=( const TiXmlText& base )							 	{ base.CopyTo( this ); }
+
+	/// Write this text object to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/// Queries whether this represents text using a CDATA section.
+	bool CDATA()					{ return cdata; }
+	/// Turns on or off a CDATA representation of text.
+	void SetCDATA( bool _cdata )	{ cdata = _cdata; }
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected :
+	///  [internal use] Creates a new Element and returns it.
+	virtual TiXmlNode* Clone() const;
+	void CopyTo( TiXmlText* target ) const;
+
+	virtual void StreamOut ( TIXML_OSTREAM * out ) const;
+	bool Blank() const;	// returns true if all white space and new lines
+	// [internal use]
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	bool cdata;			// true if this should be input and output as a CDATA style text element
+};
+
+
+/** In correct XML the declaration is the first entry in the file.
+	@verbatim
+		<?xml version="1.0" standalone="yes"?>
+	@endverbatim
+
+	TinyXml will happily read or write files without a declaration,
+	however. There are 3 possible attributes to the declaration:
+	version, encoding, and standalone.
+
+	Note: In this version of the code, the attributes are
+	handled as special cases, not generic attributes, simply
+	because there can only be at most 3 and they are always the same.
+*/
+class TiXmlDeclaration : public TiXmlNode
+{
+public:
+	/// Construct an empty declaration.
+	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
+
+#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDeclaration(	const std::string& _version,
+						const std::string& _encoding,
+						const std::string& _standalone );
+#endif
+
+	/// Construct.
+	TiXmlDeclaration(	const char* _version,
+						const char* _encoding,
+						const char* _standalone );
+
+	TiXmlDeclaration( const TiXmlDeclaration& copy );
+	void operator=( const TiXmlDeclaration& copy );
+
+	virtual ~TiXmlDeclaration()	{}
+
+	/// Version. Will return an empty string if none was found.
+	const char *Version() const			{ return version.c_str (); }
+	/// Encoding. Will return an empty string if none was found.
+	const char *Encoding() const		{ return encoding.c_str (); }
+	/// Is this a standalone document?
+	const char *Standalone() const		{ return standalone.c_str (); }
+
+	/// Creates a copy of this Declaration and returns it.
+	virtual TiXmlNode* Clone() const;
+	/// Print this declaration to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected:
+	void CopyTo( TiXmlDeclaration* target ) const;
+	// used to be public
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut ( TIXML_OSTREAM * out) const;
+
+private:
+
+	TIXML_STRING version;
+	TIXML_STRING encoding;
+	TIXML_STRING standalone;
+};
+
+
+/** Any tag that tinyXml doesn't recognize is saved as an
+	unknown. It is a tag of text, but should not be modified.
+	It will be written back to the XML, unchanged, when the file
+	is saved.
+
+	DTD tags get thrown into TiXmlUnknowns.
+*/
+class TiXmlUnknown : public TiXmlNode
+{
+public:
+	TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )	{}
+	virtual ~TiXmlUnknown() {}
+
+	TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )		{ copy.CopyTo( this ); }
+	void operator=( const TiXmlUnknown& copy )										{ copy.CopyTo( this ); }
+
+	/// Creates a copy of this Unknown and returns it.
+	virtual TiXmlNode* Clone() const;
+	/// Print this Unknown to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected:
+	void CopyTo( TiXmlUnknown* target ) const;
+
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut ( TIXML_OSTREAM * out ) const;
+
+private:
+
+};
+
+
+/** Always the top level node. A document binds together all the
+	XML pieces. It can be saved, loaded, and printed to the screen.
+	The 'value' of a document node is the xml file name.
+*/
+class TiXmlDocument : public TiXmlNode
+{
+public:
+	/// Create an empty document, that has no name.
+	TiXmlDocument();
+	/// Create a document with a name. The name of the document is also the filename of the xml.
+	TiXmlDocument( const char * documentName );
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDocument( const std::string& documentName );
+	#endif
+
+	TiXmlDocument( const TiXmlDocument& copy );
+	void operator=( const TiXmlDocument& copy );
+
+	virtual ~TiXmlDocument() {}
+
+	/** Load a file using the current document value.
+		Returns true if successful. Will delete any existing
+		document data before loading.
+	*/
+	bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the current document value. Returns true if successful.
+	bool SaveFile() const;
+	/// Load a file using the given filename. Returns true if successful.
+	bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given filename. Returns true if successful.
+	bool SaveFile( const char * filename ) const;
+
+	#ifdef TIXML_USE_STL
+	bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )			///< STL std::string version.
+	{
+		StringToBuffer f( filename );
+		return ( f.buffer && LoadFile( f.buffer, encoding ));
+	}
+	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
+	{
+		StringToBuffer f( filename );
+		return ( f.buffer && SaveFile( f.buffer ));
+	}
+	#endif
+
+	/** Parse the given null terminated block of xml data. Passing in an encoding to this
+		method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
+		to use that encoding, regardless of what TinyXml might otherwise try to detect.
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+	/** Get the root element -- the only top level element -- of the document.
+		In well formed XML, there should only be one. TinyXml is tolerant of
+		multiple elements at the document level.
+	*/
+	const TiXmlElement* RootElement() const		{ return FirstChildElement(); }
+	TiXmlElement* RootElement()					{ return FirstChildElement(); }
+
+	/** If an error occurs, Error will be set to true. Also,
+		- The ErrorId() will contain the integer identifier of the error (not generally useful)
+		- The ErrorDesc() method will return the name of the error. (very useful)
+		- The ErrorRow() and ErrorCol() will return the location of the error (if known)
+	*/
+	bool Error() const						{ return error; }
+
+	/// Contains a textual (english) description of the error if one occurs.
+	const char * ErrorDesc() const	{ return errorDesc.c_str (); }
+
+	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
+		prefer the ErrorId, this function will fetch it.
+	*/
+	int ErrorId()	const				{ return errorId; }
+
+	/** Returns the location (if known) of the error. The first column is column 1,
+		and the first row is row 1. A value of 0 means the row and column wasn't applicable
+		(memory errors, for example, have no row/column) or the parser lost the error. (An
+		error in the error reporting, in that case.)
+
+		@sa SetTabSize, Row, Column
+	*/
+	int ErrorRow()	{ return errorLocation.row+1; }
+	int ErrorCol()	{ return errorLocation.col+1; }	///< The column where the error occured. See ErrorRow()
+
+	/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
+		to report the correct values for row and column. It does not change the output
+		or input in any way.
+
+		By calling this method, with a tab size
+		greater than 0, the row and column of each node and attribute is stored
+		when the file is loaded. Very useful for tracking the DOM back in to
+		the source file.
+
+		The tab size is required for calculating the location of nodes. If not
+		set, the default of 4 is used. The tabsize is set per document. Setting
+		the tabsize to 0 disables row/column tracking.
+
+		Note that row and column tracking is not supported when using operator>>.
+
+		The tab size needs to be enabled before the parse or load. Correct usage:
+		@verbatim
+		TiXmlDocument doc;
+		doc.SetTabSize( 8 );
+		doc.Load( "myfile.xml" );
+		@endverbatim
+
+		@sa Row, Column
+	*/
+	void SetTabSize( int _tabsize )		{ tabsize = _tabsize; }
+
+	int TabSize() const	{ return tabsize; }
+
+	/** If you have handled the error, it can be reset with this call. The error
+		state is automatically cleared if you Parse a new XML block.
+	*/
+	void ClearError()						{	error = false;
+												errorId = 0;
+												errorDesc = "";
+												errorLocation.row = errorLocation.col = 0;
+												//errorLocation.last = 0;
+											}
+
+	/** Dump the document to standard out. */
+	void Print() const						{ Print( stdout, 0 ); }
+
+	/// Print this Document to a FILE stream.
+	virtual void Print( FILE* cfile, int depth = 0 ) const;
+	// [internal use]
+	void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+protected :
+	virtual void StreamOut ( TIXML_OSTREAM * out) const;
+	// [internal use]
+	virtual TiXmlNode* Clone() const;
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	void CopyTo( TiXmlDocument* target ) const;
+
+	bool error;
+	int  errorId;
+	TIXML_STRING errorDesc;
+	int tabsize;
+	TiXmlCursor errorLocation;
+	bool useMicrosoftBOM;		// the UTF-8 BOM were found when read. Note this, and try to write.
+};
+
+
+/**
+	A TiXmlHandle is a class that wraps a node pointer with null checks; this is
+	an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
+	DOM structure. It is a separate utility class.
+
+	Take an example:
+	@verbatim
+	<Document>
+		<Element attributeA = "valueA">
+			<Child attributeB = "value1" />
+			<Child attributeB = "value2" />
+		</Element>
+	<Document>
+	@endverbatim
+
+	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
+	easy to write a *lot* of code that looks like:
+
+	@verbatim
+	TiXmlElement* root = document.FirstChildElement( "Document" );
+	if ( root )
+	{
+		TiXmlElement* element = root->FirstChildElement( "Element" );
+		if ( element )
+		{
+			TiXmlElement* child = element->FirstChildElement( "Child" );
+			if ( child )
+			{
+				TiXmlElement* child2 = child->NextSiblingElement( "Child" );
+				if ( child2 )
+				{
+					// Finally do something useful.
+	@endverbatim
+
+	And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
+	of such code. A TiXmlHandle checks for null	pointers so it is perfectly safe
+	and correct to use:
+
+	@verbatim
+	TiXmlHandle docHandle( &document );
+	TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element();
+	if ( child2 )
+	{
+		// do something useful
+	@endverbatim
+
+	Which is MUCH more concise and useful.
+
+	It is also safe to copy handles - internally they are nothing more than node pointers.
+	@verbatim
+	TiXmlHandle handleCopy = handle;
+	@endverbatim
+
+	What they should not be used for is iteration:
+
+	@verbatim
+	int i=0;
+	while ( true )
+	{
+		TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element();
+		if ( !child )
+			break;
+		// do something
+		++i;
+	}
+	@endverbatim
+
+	It seems reasonable, but it is in fact two embedded while loops. The Child method is
+	a linear walk to find the element, so this code would iterate much more than it needs
+	to. Instead, prefer:
+
+	@verbatim
+	TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element();
+
+	for( child; child; child=child->NextSiblingElement() )
+	{
+		// do something
+	}
+	@endverbatim
+*/
+class TiXmlHandle
+{
+public:
+	/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
+	TiXmlHandle( TiXmlNode* _node )					{ this->node = _node; }
+	/// Copy constructor
+	TiXmlHandle( const TiXmlHandle& ref )			{ this->node = ref.node; }
+	TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
+
+	/// Return a handle to the first child node.
+	TiXmlHandle FirstChild() const;
+	/// Return a handle to the first child node with the given name.
+	TiXmlHandle FirstChild( const char * value ) const;
+	/// Return a handle to the first child element.
+	TiXmlHandle FirstChildElement() const;
+	/// Return a handle to the first child element with the given name.
+	TiXmlHandle FirstChildElement( const char * value ) const;
+
+	/** Return a handle to the "index" child with the given name.
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( const char* value, int index ) const;
+	/** Return a handle to the "index" child.
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( int index ) const;
+	/** Return a handle to the "index" child element with the given name.
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( const char* value, int index ) const;
+	/** Return a handle to the "index" child element.
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( int index ) const;
+
+	#ifdef TIXML_USE_STL
+	TiXmlHandle FirstChild( const std::string& _value ) const				{ return FirstChild( _value.c_str() ); }
+	TiXmlHandle FirstChildElement( const std::string& _value ) const		{ return FirstChildElement( _value.c_str() ); }
+
+	TiXmlHandle Child( const std::string& _value, int index ) const			{ return Child( _value.c_str(), index ); }
+	TiXmlHandle ChildElement( const std::string& _value, int index ) const	{ return ChildElement( _value.c_str(), index ); }
+	#endif
+
+	/// Return the handle as a TiXmlNode. This may return null.
+	TiXmlNode* Node() const			{ return node; }
+	/// Return the handle as a TiXmlElement. This may return null.
+	TiXmlElement* Element() const	{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+	/// Return the handle as a TiXmlText. This may return null.
+	TiXmlText* Text() const			{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+	/// Return the handle as a TiXmlUnknown. This may return null;
+	TiXmlUnknown* Unknown() const			{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+
+private:
+	TiXmlNode* node;
+};
+
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
+
+#endif
+
Index: branches/heathaze/src/lib/parser/tinyxml/tinyxmlerror.cc
===================================================================
--- branches/heathaze/src/lib/parser/tinyxml/tinyxmlerror.cc	(revision 9940)
+++ branches/heathaze/src/lib/parser/tinyxml/tinyxmlerror.cc	(revision 9940)
@@ -0,0 +1,52 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include "tinyxml.h"
+
+// The goal of the seperate error file is to make the first
+// step towards localization. tinyxml (currently) only supports
+// english error messages, but the could now be translated.
+//
+// It also cleans up the code a bit.
+//
+
+const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
+{
+	"No error",
+	"Error",
+	"Failed to open file",
+	"Memory allocation failed.",
+	"Error parsing Element.",
+	"Failed to read Element name",
+	"Error reading Element value.",
+	"Error reading Attributes.",
+	"Error: empty tag.",
+	"Error reading end tag.",
+	"Error parsing Unknown.",
+	"Error parsing Comment.",
+	"Error parsing Declaration.",
+	"Error document empty.",
+	"Error null (0) or unexpected EOF found in input stream.",
+	"Error parsing CDATA.",
+};
Index: branches/heathaze/src/lib/parser/tinyxml/tinyxmlparser.cc
===================================================================
--- branches/heathaze/src/lib/parser/tinyxml/tinyxmlparser.cc	(revision 9940)
+++ branches/heathaze/src/lib/parser/tinyxml/tinyxmlparser.cc	(revision 9940)
@@ -0,0 +1,1572 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must 
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and 
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source 
+distribution.
+*/
+
+#include "tinyxml.h"
+#include <ctype.h>
+#include <stddef.h>
+
+//#define DEBUG_PARSER
+
+// Note tha "PutString" hardcodes the same list. This
+// is less flexible than it appears. Changing the entries
+// or order will break putstring.	
+TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = 
+{
+	{ "&amp;",  5, '&' },
+	{ "&lt;",   4, '<' },
+	{ "&gt;",   4, '>' },
+	{ "&quot;", 6, '\"' },
+	{ "&apos;", 6, '\'' }
+};
+
+// Bunch of unicode info at:
+//		http://www.unicode.org/faq/utf_bom.html
+// Including the basic of this table, which determines the #bytes in the
+// sequence from the lead byte. 1 placed for invalid sequences --
+// although the result will be junk, pass it through as much as possible.
+// Beware of the non-characters in UTF-8:	
+//				ef bb bf (Microsoft "lead bytes")
+//				ef bf be
+//				ef bf bf 
+
+const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+const int TiXmlBase::utf8ByteTable[256] = 
+{
+	//	0	1	2	3	4	5	6	7	8	9	a	b	c	d	e	f
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x00
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x10
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x20
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x30
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x40
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x50
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x60
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x70	End of ASCII range
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x80 0x80 to 0xc1 invalid
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x90 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xa0 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xb0 
+		1,	1,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xc0 0xc2 to 0xdf 2 byte
+		2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xd0
+		3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	// 0xe0 0xe0 to 0xef 3 byte
+		4,	4,	4,	4,	4,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1	// 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
+};
+
+
+void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
+{
+	const unsigned long BYTE_MASK = 0xBF;
+	const unsigned long BYTE_MARK = 0x80;
+	const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+	if (input < 0x80) 
+		*length = 1;
+	else if ( input < 0x800 )
+		*length = 2;
+	else if ( input < 0x10000 )
+		*length = 3;
+	else if ( input < 0x200000 )
+		*length = 4;
+	else
+		{ *length = 0; return; }	// This code won't covert this correctly anyway.
+
+	output += *length;
+
+	// Scary scary fall throughs.
+	switch (*length) 
+	{
+		case 4:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 3:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 2:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 1:
+			--output; 
+			*output = (char)(input | FIRST_BYTE_MARK[*length]);
+	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalpha( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalpha( anyByte );
+//	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalnum( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalnum( anyByte );
+//	}
+}
+
+
+class TiXmlParsingData
+{
+	friend class TiXmlDocument;
+  public:
+	void Stamp( const char* now, TiXmlEncoding encoding );
+
+	const TiXmlCursor& Cursor()	{ return cursor; }
+
+  private:
+	// Only used by the document!
+	TiXmlParsingData( const char* start, int _tabsize, int row, int col )
+	{
+		assert( start );
+		stamp = start;
+		tabsize = _tabsize;
+		cursor.row = row;
+		cursor.col = col;
+	}
+
+	TiXmlCursor		cursor;
+	const char*		stamp;
+	int				tabsize;
+};
+
+
+void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
+{
+	assert( now );
+
+	// Do nothing if the tabsize is 0.
+	if ( tabsize < 1 )
+	{
+		return;
+	}
+
+	// Get the current row, column.
+	int row = cursor.row;
+	int col = cursor.col;
+	const char* p = stamp;
+	assert( p );
+
+	while ( p < now )
+	{
+		// Treat p as unsigned, so we have a happy compiler.
+		const unsigned char* pU = (const unsigned char*)p;
+
+		// Code contributed by Fletcher Dunn: (modified by lee)
+		switch (*pU) {
+			case 0:
+				// We *should* never get here, but in case we do, don't
+				// advance past the terminating null character, ever
+				return;
+
+			case '\r':
+				// bump down to the next line
+				++row;
+				col = 0;				
+				// Eat the character
+				++p;
+
+				// Check for \r\n sequence, and treat this as a single character
+				if (*p == '\n') {
+					++p;
+				}
+				break;
+
+			case '\n':
+				// bump down to the next line
+				++row;
+				col = 0;
+
+				// Eat the character
+				++p;
+
+				// Check for \n\r sequence, and treat this as a single
+				// character.  (Yes, this bizarre thing does occur still
+				// on some arcane platforms...)
+				if (*p == '\r') {
+					++p;
+				}
+				break;
+
+			case '\t':
+				// Eat the character
+				++p;
+
+				// Skip to next tab stop
+				col = (col / tabsize + 1) * tabsize;
+				break;
+
+			case TIXML_UTF_LEAD_0:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					if ( *(p+1) && *(p+2) )
+					{
+						// In these cases, don't advance the column. These are
+						// 0-width spaces.
+						if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
+							p += 3;	
+						else
+							{ p +=3; ++col; }	// A normal character.
+					}
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+
+			default:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					// Eat the 1 to 4 byte utf8 character.
+					int step = TiXmlBase::utf8ByteTable[*((unsigned char*)p)];
+					if ( step == 0 )
+						step = 1;		// Error case from bad encoding, but handle gracefully.
+					p += step;
+
+					// Just advance one column, of course.
+					++col;
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+		}
+	}
+	cursor.row = row;
+	cursor.col = col;
+	assert( cursor.row >= -1 );
+	assert( cursor.col >= -1 );
+	stamp = p;
+	assert( stamp );
+}
+
+
+const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
+{
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+	if ( encoding == TIXML_ENCODING_UTF8 )
+	{
+		while ( *p )
+		{
+			const unsigned char* pU = (const unsigned char*)p;
+			
+			// Skip the stupid Microsoft UTF-8 Byte order marks
+			if (	*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==TIXML_UTF_LEAD_1 
+				 && *(pU+2)==TIXML_UTF_LEAD_2 )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbeU )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbfU )
+			{
+				p += 3;
+				continue;
+			}
+
+			if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )		// Still using old rules for white space.
+				++p;
+			else
+				break;
+		}
+	}
+	else
+	{
+		while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )
+			++p;
+	}
+
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+/*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	for( ;; )
+	{
+		if ( !in->good() ) return false;
+
+		int c = in->peek();
+		// At this scope, we can't get to a document. So fail silently.
+		if ( !IsWhiteSpace( c ) || c <= 0 )
+			return true;
+
+		*tag += (char) in->get();
+	}
+}
+
+/*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag )
+{
+	//assert( character > 0 && character < 128 );	// else it won't work in utf-8
+	while ( in->good() )
+	{
+		int c = in->peek();
+		if ( c == character )
+			return true;
+		if ( c <= 0 )		// Silent failure: can't get document at this scope
+			return false;
+
+		in->get();
+		*tag += (char) c;
+	}
+	return false;
+}
+#endif
+
+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
+{
+	*name = "";
+	assert( p );
+
+	// Names start with letters or underscores.
+	// Of course, in unicode, tinyxml has no idea what a letter *is*. The
+	// algorithm is generous.
+	//
+	// After that, they can be letters, underscores, numbers,
+	// hyphens, or colons. (Colons are valid ony for namespaces,
+	// but tinyxml can't tell namespaces from names.)
+	if (    p && *p 
+		 && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
+	{
+		while(		p && *p
+				&&	(		IsAlphaNum( (unsigned char ) *p, encoding ) 
+						 || *p == '_'
+						 || *p == '-'
+						 || *p == '.'
+						 || *p == ':' ) )
+		{
+			(*name) += *p;
+			++p;
+		}
+		return p;
+	}
+	return 0;
+}
+
+const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
+{
+	// Presume an entity, and pull it out.
+    TIXML_STRING ent;
+	int i;
+	*length = 0;
+
+	if ( *(p+1) && *(p+1) == '#' && *(p+2) )
+	{
+		unsigned long ucs = 0;
+		ptrdiff_t delta = 0;
+		unsigned mult = 1;
+
+		if ( *(p+2) == 'x' )
+		{
+			// Hexadecimal.
+			if ( !*(p+3) ) return 0;
+
+			const char* q = p+3;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != 'x' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else if ( *q >= 'a' && *q <= 'f' )
+					ucs += mult * (*q - 'a' + 10);
+				else if ( *q >= 'A' && *q <= 'F' )
+					ucs += mult * (*q - 'A' + 10 );
+				else 
+					return 0;
+				mult *= 16;
+				--q;
+			}
+		}
+		else
+		{
+			// Decimal.
+			if ( !*(p+2) ) return 0;
+
+			const char* q = p+2;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != '#' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else 
+					return 0;
+				mult *= 10;
+				--q;
+			}
+		}
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			// convert the UCS to UTF-8
+			ConvertUTF32ToUTF8( ucs, value, length );
+		}
+		else
+		{
+			*value = (char)ucs;
+			*length = 1;
+		}
+		return p + delta + 1;
+	}
+
+	// Now try to match it.
+	for( i=0; i<NUM_ENTITY; ++i )
+	{
+		if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
+		{
+			assert( strlen( entity[i].str ) == entity[i].strLength );
+			*value = entity[i].chr;
+			*length = 1;
+			return ( p + entity[i].strLength );
+		}
+	}
+
+	// So it wasn't an entity, its unrecognized, or something like that.
+	*value = *p;	// Don't put back the last one, since we return it!
+	return p+1;
+}
+
+
+bool TiXmlBase::StringEqual( const char* p,
+							 const char* tag,
+							 bool ignoreCase,
+							 TiXmlEncoding encoding )
+{
+	assert( p );
+	assert( tag );
+	if ( !p || !*p )
+	{
+		assert( 0 );
+		return false;
+	}
+
+	const char* q = p;
+
+	if ( ignoreCase )
+	{
+		while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )
+			return true;
+	}
+	else
+	{
+		while ( *q && *tag && *q == *tag )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )		// Have we found the end of the tag, and everything equal?
+			return true;
+	}
+	return false;
+}
+
+const char* TiXmlBase::ReadText(	const char* p, 
+									TIXML_STRING * text, 
+									bool trimWhiteSpace, 
+									const char* endTag, 
+									bool caseInsensitive,
+									TiXmlEncoding encoding )
+{
+    *text = "";
+	if (    !trimWhiteSpace			// certain tags always keep whitespace
+		 || !condenseWhiteSpace )	// if true, whitespace is always kept
+	{
+		// Keep all the white space.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding )
+			  )
+		{
+			int len;
+			char cArr[4] = { 0, 0, 0, 0 };
+			p = GetChar( p, cArr, &len, encoding );
+			text->append( cArr, len );
+		}
+	}
+	else
+	{
+		bool whitespace = false;
+
+		// Remove leading white space:
+		p = SkipWhiteSpace( p, encoding );
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding ) )
+		{
+			if ( *p == '\r' || *p == '\n' )
+			{
+				whitespace = true;
+				++p;
+			}
+			else if ( IsWhiteSpace( *p ) )
+			{
+				whitespace = true;
+				++p;
+			}
+			else
+			{
+				// If we've found whitespace, add it before the
+				// new character. Any whitespace just becomes a space.
+				if ( whitespace )
+				{
+					(*text) += ' ';
+					whitespace = false;
+				}
+				int len;
+				char cArr[4] = { 0, 0, 0, 0 };
+				p = GetChar( p, cArr, &len, encoding );
+				if ( len == 1 )
+					(*text) += cArr[0];	// more efficient
+				else
+					text->append( cArr, len );
+			}
+		}
+	}
+	return p + strlen( endTag );
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlDocument::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	// The basic issue with a document is that we don't know what we're
+	// streaming. Read something presumed to be a tag (and hope), then
+	// identify it, and call the appropriate stream method on the tag.
+	//
+	// This "pre-streaming" will never read the closing ">" so the
+	// sub-tag can orient itself.
+
+	if ( !StreamTo( in, '<', tag ) ) 
+	{
+		SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return;
+	}
+
+	while ( in->good() )
+	{
+		int tagIndex = (int) tag->length();
+		while ( in->good() && in->peek() != '>' )
+		{
+			int c = in->get();
+			if ( c <= 0 )
+			{
+				SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+				break;
+			}
+			(*tag) += (char) c;
+		}
+
+		if ( in->good() )
+		{
+			// We now have something we presume to be a node of 
+			// some sort. Identify it, and call the node to
+			// continue streaming.
+			TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
+
+			if ( node )
+			{
+				node->StreamIn( in, tag );
+				bool isElement = node->ToElement() != 0;
+				delete node;
+				node = 0;
+
+				// If this is the root element, we're done. Parsing will be
+				// done by the >> operator.
+				if ( isElement )
+				{
+					return;
+				}
+			}
+			else
+			{
+				SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+				return;
+			}
+		}
+	}
+	// We should have returned sooner.
+	SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+}
+
+#endif
+
+const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
+{
+	ClearError();
+
+	// Parse away, at the document level. Since a document
+	// contains nothing but other tags, most of what happens
+	// here is skipping white space.
+	if ( !p || !*p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	// Note that, for a document, this needs to come
+	// before the while space skip, so that parsing
+	// starts from the pointer we are given.
+	location.Clear();
+	if ( prevData )
+	{
+		location.row = prevData->cursor.row;
+		location.col = prevData->cursor.col;
+	}
+	else
+	{
+		location.row = 0;
+		location.col = 0;
+	}
+	TiXmlParsingData data( p, TabSize(), location.row, location.col );
+	location = data.Cursor();
+
+	if ( encoding == TIXML_ENCODING_UNKNOWN )
+	{
+		// Check for the Microsoft UTF-8 lead bytes.
+		const unsigned char* pU = (const unsigned char*)p;
+		if (	*(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0
+			 && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1
+			 && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 )
+		{
+			encoding = TIXML_ENCODING_UTF8;
+			useMicrosoftBOM = true;
+		}
+	}
+
+    p = SkipWhiteSpace( p, encoding );
+	if ( !p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	while ( p && *p )
+	{
+		TiXmlNode* node = Identify( p, encoding );
+		if ( node )
+		{
+			p = node->Parse( p, &data, encoding );
+			LinkEndChild( node );
+		}
+		else
+		{
+			break;
+		}
+
+		// Did we get encoding info?
+		if (    encoding == TIXML_ENCODING_UNKNOWN
+			 && node->ToDeclaration() )
+		{
+			TiXmlDeclaration* dec = node->ToDeclaration();
+			const char* enc = dec->Encoding();
+			assert( enc );
+
+			if ( *enc == 0 )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;	// incorrect, but be nice
+			else 
+				encoding = TIXML_ENCODING_LEGACY;
+		}
+
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	// Was this empty?
+	if ( !firstChild ) {
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding );
+		return 0;
+	}
+
+	// All is well.
+	return p;
+}
+
+void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
+{	
+	// The first error in a chain is more accurate - don't set again!
+	if ( error )
+		return;
+
+	assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
+	error   = true;
+	errorId = err;
+	errorDesc = errorString[ errorId ];
+
+	errorLocation.Clear();
+	if ( pError && data )
+	{
+		data->Stamp( pError, encoding );
+		errorLocation = data->Cursor();
+	}
+}
+
+
+TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
+{
+	TiXmlNode* returnNode = 0;
+
+	p = SkipWhiteSpace( p, encoding );
+	if( !p || !*p || *p != '<' )
+	{
+		return 0;
+	}
+
+	TiXmlDocument* doc = GetDocument();
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+
+	// What is this thing? 
+	// - Elements start with a letter or underscore, but xml is reserved.
+	// - Comments: <!--
+	// - Decleration: <?xml
+	// - Everthing else is unknown to tinyxml.
+	//
+
+	const char* xmlHeader = { "<?xml" };
+	const char* commentHeader = { "<!--" };
+	const char* dtdHeader = { "<!" };
+	const char* cdataHeader = { "<![CDATA[" };
+
+	if ( StringEqual( p, xmlHeader, true, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Declaration\n" );
+		#endif
+		returnNode = new TiXmlDeclaration();
+	}
+	else if ( StringEqual( p, commentHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Comment\n" );
+		#endif
+		returnNode = new TiXmlComment();
+	}
+	else if ( StringEqual( p, cdataHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing CDATA\n" );
+		#endif
+		TiXmlText* text = new TiXmlText( "" );
+		text->SetCDATA( true );
+		returnNode = text;
+	}
+	else if ( StringEqual( p, dtdHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(1)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+	else if (    IsAlpha( *(p+1), encoding )
+			  || *(p+1) == '_' )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Element\n" );
+		#endif
+		returnNode = new TiXmlElement( "" );
+	}
+	else
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(2)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+
+	if ( returnNode )
+	{
+		// Set the parent, so it can report errors
+		returnNode->parent = this;
+	}
+	else
+	{
+		if ( doc )
+			doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+	return returnNode;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlElement::StreamIn (TIXML_ISTREAM * in, TIXML_STRING * tag)
+{
+	// We're called with some amount of pre-parsing. That is, some of "this"
+	// element is in "tag". Go ahead and stream to the closing ">"
+	while( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c ;
+		
+		if ( c == '>' )
+			break;
+	}
+
+	if ( tag->length() < 3 ) return;
+
+	// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
+	// If not, identify and stream.
+
+	if (    tag->at( tag->length() - 1 ) == '>' 
+		 && tag->at( tag->length() - 2 ) == '/' )
+	{
+		// All good!
+		return;
+	}
+	else if ( tag->at( tag->length() - 1 ) == '>' )
+	{
+		// There is more. Could be:
+		//		text
+		//		closing tag
+		//		another node.
+		for ( ;; )
+		{
+			StreamWhiteSpace( in, tag );
+
+			// Do we have text?
+			if ( in->good() && in->peek() != '<' ) 
+			{
+				// Yep, text.
+				TiXmlText text( "" );
+				text.StreamIn( in, tag );
+
+				// What follows text is a closing tag or another node.
+				// Go around again and figure it out.
+				continue;
+			}
+
+			// We now have either a closing tag...or another node.
+			// We should be at a "<", regardless.
+			if ( !in->good() ) return;
+			assert( in->peek() == '<' );
+			int tagIndex = (int) tag->length();
+
+			bool closingTag = false;
+			bool firstCharFound = false;
+
+			for( ;; )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->peek();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				
+				if ( c == '>' )
+					break;
+
+				*tag += (char) c;
+				in->get();
+
+				if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
+				{
+					firstCharFound = true;
+					if ( c == '/' )
+						closingTag = true;
+				}
+			}
+			// If it was a closing tag, then read in the closing '>' to clean up the input stream.
+			// If it was not, the streaming will be done by the tag.
+			if ( closingTag )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->get();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				assert( c == '>' );
+				*tag += (char) c;
+
+				// We are done, once we've found our closing tag.
+				return;
+			}
+			else
+			{
+				// If not a closing tag, id it, and stream.
+				const char* tagloc = tag->c_str() + tagIndex;
+				TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
+				if ( !node )
+					return;
+				node->StreamIn( in, tag );
+				delete node;
+				node = 0;
+
+				// No return: go around from the beginning: text, closing tag, or node.
+			}
+		}
+	}
+}
+#endif
+
+const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	TiXmlDocument* document = GetDocument();
+
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
+		return 0;
+	}
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	if ( *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
+		return 0;
+	}
+
+	p = SkipWhiteSpace( p+1, encoding );
+
+	// Read the name.
+	const char* pErr = p;
+
+    p = ReadName( p, &value, encoding );
+	if ( !p || !*p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
+		return 0;
+	}
+
+    TIXML_STRING endTag ("</");
+	endTag += value;
+	endTag += ">";
+
+	// Check for and read attributes. Also look for an empty
+	// tag or an end tag.
+	while ( p && *p )
+	{
+		pErr = p;
+		p = SkipWhiteSpace( p, encoding );
+		if ( !p || !*p )
+		{
+			if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+			return 0;
+		}
+		if ( *p == '/' )
+		{
+			++p;
+			// Empty tag.
+			if ( *p  != '>' )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );		
+				return 0;
+			}
+			return (p+1);
+		}
+		else if ( *p == '>' )
+		{
+			// Done with attributes (if there were any.)
+			// Read the value -- which can include other
+			// elements -- read the end tag, and return.
+			++p;
+			p = ReadValue( p, data, encoding );		// Note this is an Element method, and will set the error if one happens.
+			if ( !p || !*p )
+				return 0;
+
+			// We should find the end tag now
+			if ( StringEqual( p, endTag.c_str(), false, encoding ) )
+			{
+				p += endTag.length();
+				return p;
+			}
+			else
+			{
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+		}
+		else
+		{
+			// Try to read an attribute:
+			TiXmlAttribute* attrib = new TiXmlAttribute();
+			if ( !attrib )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
+				return 0;
+			}
+
+			attrib->SetDocument( document );
+			const char* pErr = p;
+			p = attrib->Parse( p, data, encoding );
+
+			if ( !p || !*p )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
+				delete attrib;
+				return 0;
+			}
+
+			// Handle the strange case of double attributes:
+			TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
+			if ( node )
+			{
+				node->SetValue( attrib->Value() );
+				delete attrib;
+				return 0;
+			}
+
+			attributeSet.Add( attrib );
+		}
+	}
+	return p;
+}
+
+
+const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+
+	// Read in text and elements in any order.
+	const char* pWithWhiteSpace = p;
+	p = SkipWhiteSpace( p, encoding );
+
+	while ( p && *p )
+	{
+		if ( *p != '<' )
+		{
+			// Take what we have, make a text element.
+			TiXmlText* textNode = new TiXmlText( "" );
+
+			if ( !textNode )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding );
+				    return 0;
+			}
+
+			if ( TiXmlBase::IsWhiteSpaceCondensed() )
+			{
+				p = textNode->Parse( p, data, encoding );
+			}
+			else
+			{
+				// Special case: we want to keep the white space
+				// so that leading spaces aren't removed.
+				p = textNode->Parse( pWithWhiteSpace, data, encoding );
+			}
+
+			if ( !textNode->Blank() )
+				LinkEndChild( textNode );
+			else
+				delete textNode;
+		} 
+		else 
+		{
+			// We hit a '<'
+			// Have we hit a new element or an end tag? This could also be
+			// a TiXmlText in the "CDATA" style.
+			if ( StringEqual( p, "</", false, encoding ) )
+			{
+				return p;
+			}
+			else
+			{
+				TiXmlNode* node = Identify( p, encoding );
+				if ( node )
+				{
+					p = node->Parse( p, data, encoding );
+					LinkEndChild( node );
+				}				
+				else
+				{
+					return 0;
+				}
+			}
+		}
+		pWithWhiteSpace = p;
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	if ( !p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
+	}	
+	return p;
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlUnknown::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	if ( !p || !*p || *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
+		return 0;
+	}
+	++p;
+    value = "";
+
+	while ( p && *p && *p != '>' )
+	{
+		value += *p;
+		++p;
+	}
+
+	if ( !p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
+	}
+	if ( *p == '>' )
+		return p+1;
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlComment::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+
+		if ( c == '>' 
+			 && tag->at( tag->length() - 2 ) == '-'
+			 && tag->at( tag->length() - 3 ) == '-' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	value = "";
+
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	const char* startTag = "<!--";
+	const char* endTag   = "-->";
+
+	if ( !StringEqual( p, startTag, false, encoding ) )
+	{
+		document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
+		return 0;
+	}
+	p += strlen( startTag );
+	p = ReadText( p, &value, false, endTag, false, encoding );
+	return p;
+}
+
+
+const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p ) return 0;
+
+	int tabsize = 4;
+	if ( document )
+		tabsize = document->TabSize();
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	// Read the name, the '=' and the value.
+	const char* pErr = p;
+	p = ReadName( p, &name, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+		return 0;
+	}
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p || *p != '=' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+
+	++p;	// skip '='
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+	
+	const char* end;
+
+	if ( *p == '\'' )
+	{
+		++p;
+		end = "\'";
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else if ( *p == '"' )
+	{
+		++p;
+		end = "\"";
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else
+	{
+		// All attribute values should be in single or double quotes.
+		// But this is such a common error that the parser will try
+		// its best, even without them.
+		value = "";
+		while (    p && *p										// existence
+				&& !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r'	// whitespace
+				&& *p != '/' && *p != '>' )						// tag end
+		{
+			value += *p;
+			++p;
+		}
+	}
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	if ( cdata )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+
+		if ( c == '>' 
+			 && tag->at( tag->length() - 2 ) == ']'
+			 && tag->at( tag->length() - 3 ) == ']' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+	else
+	{
+		while ( in->good() )
+		{
+			int c = in->peek();	
+			if ( c == '<' )
+				return;
+			if ( c <= 0 )
+			{
+				TiXmlDocument* document = GetDocument();
+				if ( document )
+					document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+				return;
+			}
+
+			(*tag) += (char) c;
+			in->get();
+		}
+	}
+}
+#endif
+
+const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	value = "";
+	TiXmlDocument* document = GetDocument();
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	const char* const startTag = "<![CDATA[";
+	const char* const endTag   = "]]>";
+
+	if ( cdata || StringEqual( p, startTag, false, encoding ) )
+	{
+		cdata = true;
+
+		if ( !StringEqual( p, startTag, false, encoding ) )
+		{
+			document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
+			return 0;
+		}
+		p += strlen( startTag );
+
+		// Keep all the white space, ignore the encoding, etc.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, false, encoding )
+			  )
+		{
+			value += *p;
+			++p;
+		}
+
+		TIXML_STRING dummy; 
+		p = ReadText( p, &dummy, false, endTag, false, encoding );
+		return p;
+	}
+	else
+	{
+		bool ignoreWhite = true;
+
+		const char* end = "<";
+		p = ReadText( p, &value, ignoreWhite, end, false, encoding );
+		if ( p )
+			return p-1;	// don't truncate the '<'
+		return 0;
+	}
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlDeclaration::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;
+		}
+	}
+}
+#endif
+
+const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
+{
+	p = SkipWhiteSpace( p, _encoding );
+	// Find the beginning, find the end, and look for
+	// the stuff in-between.
+	TiXmlDocument* document = GetDocument();
+	if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
+		return 0;
+	}
+	if ( data )
+	{
+		data->Stamp( p, _encoding );
+		location = data->Cursor();
+	}
+	p += 5;
+
+	version = "";
+	encoding = "";
+	standalone = "";
+
+	while ( p && *p )
+	{
+		if ( *p == '>' )
+		{
+			++p;
+			return p;
+		}
+
+		p = SkipWhiteSpace( p, _encoding );
+		if ( StringEqual( p, "version", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			version = attrib.Value();
+		}
+		else if ( StringEqual( p, "encoding", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			encoding = attrib.Value();
+		}
+		else if ( StringEqual( p, "standalone", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			standalone = attrib.Value();
+		}
+		else
+		{
+			// Read over whatever it is.
+			while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
+				++p;
+		}
+	}
+	return 0;
+}
+
+bool TiXmlText::Blank() const
+{
+	for ( unsigned i=0; i<value.length(); i++ )
+		if ( !IsWhiteSpace( value[i] ) )
+			return false;
+	return true;
+}
+
Index: branches/heathaze/src/lib/physics/Makefile.am
===================================================================
--- branches/heathaze/src/lib/physics/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/physics/Makefile.am	(revision 9940)
@@ -0,0 +1,21 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXphysics.a
+
+libORXphysics_a_SOURCES = physics_interface.cc \
+                          physics_connection.cc \
+                          physics_engine.cc \
+                          fields/field.cc \
+                          fields/gravity.cc \
+                          fields/point_gravity.cc \
+                          fields/twirl.cc
+
+noinst_HEADERS= physics_interface.h \
+                physics_connection.h \
+                physics_engine.h \
+                fields/fields.h \
+                fields/field.h \
+                fields/gravity.h \
+                fields/point_gravity.h \
+                fields/twirl.h
Index: branches/heathaze/src/lib/physics/fields/field.cc
===================================================================
--- branches/heathaze/src/lib/physics/fields/field.cc	(revision 9940)
+++ branches/heathaze/src/lib/physics/fields/field.cc	(revision 9940)
@@ -0,0 +1,85 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "field.h"
+
+#include "physics_engine.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+ObjectListDefinition(Field);
+
+/**
+ * @brief standard constructor
+*/
+Field::Field ()
+{
+  this->init();
+}
+
+/**
+ * @brief standard deconstructor
+ */
+Field::~Field ()
+{
+   PhysicsEngine::getInstance()->removeField(this);
+}
+
+/**
+  * @brief initializes a Field
+ */
+void Field::init()
+{
+  this->registerObject(this, Field::_objectList);
+  this->setMagnitude(1);
+  this->setAttenuation(0);
+
+  PhysicsEngine::getInstance()->addField(this);
+}
+
+/**
+ * @param root The XML-element to load settings from
+ */
+void Field::loadParams(const TiXmlElement* root)
+{
+  PNode::loadParams(root);
+
+  LoadParam(root, "magnitude", this, Field, setMagnitude)
+      .describe("sets the magnitude of this Field")
+      .defaultValues(1.0f);
+
+  LoadParam(root, "attenuation", this, Field, setAttenuation)
+      .describe("sets the attenuation of this Field.");
+
+}
+
+/**
+ * @param magnitude the magnitude of the Field.
+*/
+void Field::setMagnitude(float magnitude)
+{
+  this->magnitude = magnitude;
+}
+
+/**
+ * @param attenuation The attenuation of the Field (the bigger the smaller the region of influence)
+*/
+void Field::setAttenuation(float attenuation)
+{
+  this->attenuation = attenuation;
+}
Index: branches/heathaze/src/lib/physics/fields/field.h
===================================================================
--- branches/heathaze/src/lib/physics/fields/field.h	(revision 9940)
+++ branches/heathaze/src/lib/physics/fields/field.h	(revision 9940)
@@ -0,0 +1,63 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file field.h
+ * abstract definition of a Physical Field
+ *
+ * This is a totally abstract class, that only enables different Physical Fields to
+ * exist on a common Level.
+ */
+
+#ifndef _FIELD_H
+#define _FIELD_H
+
+#include "p_node.h"
+
+// FORWARD DECLARATION
+class TiXmlElement;
+
+
+//! An abstract class that represents a Force.
+class Field : public PNode
+{
+  ObjectListDeclaration(Field);
+ public:
+  Field();
+  virtual ~Field();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  /**
+    * @param data This is the data given to this force, to calculate the ForceVector
+    * @returns The Force Vector
+  */
+  virtual Vector calcForce(const Vector& data) const = 0;
+
+  void setMagnitude(float magnitude);
+  /** @returns The Magnitude of the Field */
+  inline const float& getMagnitude() const {return this->magnitude;}
+
+  void setAttenuation(float attenuation);
+  /** @returns The Attenuation of the Fiels */
+  inline const float& getAttenuation() const {return this->attenuation;}
+
+ private:
+  float magnitude;                //!< The strength of the field
+  float attenuation;              //!< The Attenuation (the bigger the shorter the influenced distance).
+};
+
+#endif /* _FIELD_H */
Index: branches/heathaze/src/lib/physics/fields/fields.h
===================================================================
--- branches/heathaze/src/lib/physics/fields/fields.h	(revision 9940)
+++ branches/heathaze/src/lib/physics/fields/fields.h	(revision 9940)
@@ -0,0 +1,40 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*! 
+ * @file fields.h
+  *  collection of all Headers of all the different fileds there are in the 
+    PhysicsEngine
+*/
+
+
+#ifndef _FILEDS_H
+#define _FIELDS_H
+
+/* The superclass */
+#include "field.h"
+
+/* subclasses Fields without Position */
+#include "gravity.h"
+
+/* subclasses of field with position */
+#include "point_gravity.h"
+#include "twirl.h"
+
+/* many more fields */
+
+
+
+#endif /* _FIELDS_H */
Index: branches/heathaze/src/lib/physics/fields/gravity.cc
===================================================================
--- branches/heathaze/src/lib/physics/fields/gravity.cc	(revision 9940)
+++ branches/heathaze/src/lib/physics/fields/gravity.cc	(revision 9940)
@@ -0,0 +1,60 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "gravity.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Gravity, CL_FIELD_GRAVITY);
+
+CREATE_FACTORY(Gravity);
+
+Gravity::Gravity(const TiXmlElement* root)
+{
+  this->registerObject(this, Gravity::_objectList);
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+
+*/
+Gravity::~Gravity ()
+{
+  // delete what has to be deleted here
+}
+
+void Gravity::loadParams(const TiXmlElement* root)
+{
+  Field::loadParams(root);
+}
+
+/**
+ *  calculates the Gravity on any point in space
+ * @param data The Position of the Point in space to attache gravity to.
+ * @returns The force.
+*/
+Vector Gravity::calcForce(const Vector& data) const
+{
+  return Vector(0,-1,0) * this->getMagnitude();
+}
+
+
Index: branches/heathaze/src/lib/physics/fields/gravity.h
===================================================================
--- branches/heathaze/src/lib/physics/fields/gravity.h	(revision 9940)
+++ branches/heathaze/src/lib/physics/fields/gravity.h	(revision 9940)
@@ -0,0 +1,32 @@
+/*!
+ * @file gravity.h
+  *  Definition of ...
+
+*/
+
+#ifndef _GRAVITY_H
+#define _GRAVITY_H
+
+#include "field.h"
+
+// FORWARD DECLARATION
+
+
+
+//! A class for ...
+class Gravity : public Field {
+  ObjectListDeclaration(Gravity);
+
+ public:
+  Gravity(const TiXmlElement* root = NULL);
+  virtual ~Gravity();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual Vector calcForce(const Vector& data) const;
+
+ private:
+
+};
+
+#endif /* _GRAVITY_H */
Index: branches/heathaze/src/lib/physics/fields/point_gravity.cc
===================================================================
--- branches/heathaze/src/lib/physics/fields/point_gravity.cc	(revision 9940)
+++ branches/heathaze/src/lib/physics/fields/point_gravity.cc	(revision 9940)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "point_gravity.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(PointGravity, CL_FIELD_POINT_GRAVITY);
+
+
+/**
+ *  standard constructor
+   @todo this constructor is not jet implemented - do it
+*/
+PointGravity::PointGravity ()
+{
+  this->registerObject(this, PointGravity::_objectList);
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+PointGravity::~PointGravity ()
+{
+  // delete what has to be deleted here
+}
+
+/**
+ *  calculates the PointGravity on any point in space
+ * @param data The Position of the Point in space to attache PointGravity to.
+ * @returns The force.
+*/
+Vector PointGravity::calcForce(const Vector& data) const
+{
+  return (this->getAbsCoor() - data) * this->getMagnitude();
+}
+
+
Index: branches/heathaze/src/lib/physics/fields/point_gravity.h
===================================================================
--- branches/heathaze/src/lib/physics/fields/point_gravity.h	(revision 9940)
+++ branches/heathaze/src/lib/physics/fields/point_gravity.h	(revision 9940)
@@ -0,0 +1,30 @@
+/*!
+ * @file point_gravity.h
+  *  Definition of ...
+
+*/
+
+#ifndef _POINT_GRAVITY_H
+#define _POINT_GRAVITY_H
+
+#include "field.h"
+
+// FORWARD DECLARATION
+
+
+
+//! A class for ...
+class PointGravity : public Field {
+  ObjectListDeclaration(PointGravity);
+
+ public:
+  PointGravity();
+  virtual ~PointGravity();
+
+  virtual Vector calcForce(const Vector& data) const;
+
+ private:
+
+};
+
+#endif /* _POINT_GRAVITY_H */
Index: branches/heathaze/src/lib/physics/fields/twirl.cc
===================================================================
--- branches/heathaze/src/lib/physics/fields/twirl.cc	(revision 9940)
+++ branches/heathaze/src/lib/physics/fields/twirl.cc	(revision 9940)
@@ -0,0 +1,56 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "twirl.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Twirl, CL_FIELD_TWIRL);
+
+
+/**
+ *  standard constructor
+   @todo this constructor is not jet implemented - do it
+*/
+Twirl::Twirl ()
+{
+  this->registerObject(this, Twirl::_objectList);
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+Twirl::~Twirl ()
+{
+  // delete what has to be deleted here
+}
+
+/**
+ *  calculates the Twirl on any point in space
+ * @param data The Position of the Point in space to attache twirl to.
+ * @returns The force.
+*/
+Vector Twirl::calcForce(const Vector& data) const
+{
+  return /*this->getAbsDir()*/ Vector(0,1,0).cross(this->getAbsCoor() - data)
+    * this->getMagnitude();
+}
+
+
Index: branches/heathaze/src/lib/physics/fields/twirl.h
===================================================================
--- branches/heathaze/src/lib/physics/fields/twirl.h	(revision 9940)
+++ branches/heathaze/src/lib/physics/fields/twirl.h	(revision 9940)
@@ -0,0 +1,30 @@
+/*!
+ * @file twirl.h
+  *  Definition of ...
+
+*/
+
+#ifndef _TWIRL_H
+#define _TWIRL_H
+
+#include "field.h"
+
+// FORWARD DECLARATION
+
+
+
+//! A class for ...
+class Twirl : public Field {
+  ObjectListDeclaration(Twirl);
+
+ public:
+  Twirl();
+  virtual ~Twirl();
+
+  virtual Vector calcForce(const Vector& data) const;
+
+ private:
+
+};
+
+#endif /* _TWIRL_H */
Index: branches/heathaze/src/lib/physics/physics_connection.cc
===================================================================
--- branches/heathaze/src/lib/physics/physics_connection.cc	(revision 9940)
+++ branches/heathaze/src/lib/physics/physics_connection.cc	(revision 9940)
@@ -0,0 +1,110 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "physics_connection.h"
+
+#include "physics_engine.h"
+#include "debug.h"
+
+#include "fields/field.h"
+#include "particles/particle_system.h"
+#include "physics_interface.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinition(PhysicsConnection);
+CREATE_FACTORY(PhysicsConnection);
+/**
+ *  creates a PhysicsConnection
+*/
+PhysicsConnection::PhysicsConnection(PhysicsInterface* subject, Field* field)
+{
+  this->registerObject(this, PhysicsConnection::_objectList);
+  this->type = PCON_PhysIField;
+
+  this->subject = subject;
+  this->field = field;
+
+  PhysicsEngine::getInstance()->addConnection(this);
+}
+
+PhysicsConnection::PhysicsConnection(const TiXmlElement* root)
+{
+  this->registerObject(this, PhysicsConnection::_objectList);
+  this->type = PCON_PhysIField;
+
+  BaseObject::loadParams(root);
+
+  LoadParam(root, "subject", this, PhysicsConnection, setSubject)
+      .describe("set the subject by a name");
+
+  LoadParam(root, "field", this, PhysicsConnection, setField)
+      .describe("set the field by name");
+
+  PhysicsEngine::getInstance()->addConnection(this);
+}
+
+/**
+ *  standard deconstructor
+
+*/
+PhysicsConnection::~PhysicsConnection ()
+{
+  PhysicsEngine::getInstance()->removeConnection(this);
+}
+
+/**
+ * @param subjectName the name of the Subject for this PhysicsConnection
+*/
+void PhysicsConnection::setSubject(const std::string& subjectName)
+{
+  this->subject = PhysicsEngine::getInstance()->getPhysicsInterfaceByName(subjectName);
+  if (this->subject == NULL)
+  {
+    PRINTF(2)("subject: (%s) not found for PhysicsConnection\n", subjectName.c_str());
+  }
+  else
+    PRINTF(5)("subject::%s\n", this->subject->getCName());
+}
+
+/**
+* @param fieldName the Name of the Field for this connection
+*/
+void PhysicsConnection::setField(const std::string& fieldName)
+{
+  this->field = PhysicsEngine::getInstance()->getFieldByName(fieldName);
+  if (this->field == NULL)
+  {
+    PRINTF(2)("field: (%s) not found for PhysicsConnection\n", fieldName.c_str());
+  }
+  else
+    PRINTF(5)("field::%s\n", this->field->getCName());
+
+}
+
+/**
+  *  applies the Force to some Object.
+*/
+void PhysicsConnection::apply() const
+{
+  if (likely(this->type == PCON_PhysIField && this->field->getMagnitude() != 0.0
+      && this->subject != NULL && this->field != NULL))
+      this->subject->applyField(this->field);
+  else ;
+}
Index: branches/heathaze/src/lib/physics/physics_connection.h
===================================================================
--- branches/heathaze/src/lib/physics/physics_connection.h	(revision 9940)
+++ branches/heathaze/src/lib/physics/physics_connection.h	(revision 9940)
@@ -0,0 +1,51 @@
+/*!
+ * @file physics_connection.h
+ *  Definition of The Physical Connection Class.
+ * @todo
+*/
+
+#ifndef _PHYSICS_CONNECTION_H
+#define _PHYSICS_CONNECTION_H
+
+#include "base_object.h"
+// Forward Declaration
+class PhysicsInterface;
+class ParticleSystem;
+class Field;
+
+//! An enumerator for different ConnectionTypes
+typedef enum PCON_Type
+{
+  PCON_PhysIPhysI = 1,
+  PCON_PhysIField = 2
+};
+
+
+// Forward Declaration
+
+//! A class that Handles Physical Connection between different subjects
+class PhysicsConnection : public BaseObject
+{
+  ObjectListDeclaration(PhysicsConnection);
+ public:
+  PhysicsConnection(PhysicsInterface* subject, Field* field);
+  //  PhysicsConnection(PhysicsInterface* partnerOne, PhysicsInterface* partnerTwo);
+  PhysicsConnection(const TiXmlElement* root);
+
+  virtual ~PhysicsConnection();
+
+  void setSubject(const std::string& subjectName);
+  void setField(const std::string& fieldName);
+
+  void apply() const;
+
+ private:
+  PCON_Type type;                    //!< What kind of connection this is.
+
+  PhysicsInterface* subject;         //!< The main Subject of this Connection.
+  PhysicsInterface* partner2;        //!< The second partner of this Connection.
+
+  Field* field;                      //!< The field to connect either subject of ParticleSystem to.
+};
+
+#endif /* _PHYSICS_CONNECTION_H */
Index: branches/heathaze/src/lib/physics/physics_engine.cc
===================================================================
--- branches/heathaze/src/lib/physics/physics_engine.cc	(revision 9940)
+++ branches/heathaze/src/lib/physics/physics_engine.cc	(revision 9940)
@@ -0,0 +1,247 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "physics_engine.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param_xml.h"
+
+
+
+ObjectListDefinition(PhysicsEngine);
+/**
+ * @brief standard constructor
+ */
+PhysicsEngine::PhysicsEngine()
+{
+  this->registerObject(this, PhysicsEngine::_objectList);
+  this->setName("PhysicsEngine");
+  this->interfaces = NULL;
+}
+
+/**
+ *  the singleton reference to this class
+*/
+PhysicsEngine* PhysicsEngine::singletonRef = NULL;
+
+/**
+ *  standard deconstructor
+
+*/
+PhysicsEngine::~PhysicsEngine()
+{
+  // delete all PhysicsConnections that are still in existence
+  while (this->connections.size() > 0)
+  {
+    PhysicsConnection* connection = this->connections.front();
+    this->connections.pop_front();
+    delete connection;
+  }
+//
+//   // delete all PhysicsInterfaces, still in existence (this could be dangerous)
+//   tIterator<PhysicsInterface>* itPI = this->interfaces->getIterator();
+//   PhysicsInterface* enumPI = itPI->firstElement();
+//   while (enumPI)
+//   {
+//     delete enumPI;
+//
+//     enumPI = itPI->nextElement();
+//   }
+//   delete itPI;
+//
+//   // delete all PhysicsFields, still in existence (this could be dangerous)
+//   tIterator<Field>* itF = this->fields->getIterator();
+//   Field* enumF = itF->firstElement();
+//   while (enumF)
+//   {
+//     delete enumF;
+//
+//     enumF = itF->nextElement();
+//   }
+//   delete itF;
+
+  PhysicsEngine::singletonRef = NULL;
+}
+
+/**
+* @param root the XML-element to load settings from
+ */
+void PhysicsEngine::loadParams(const TiXmlElement* root)
+{
+  LoadParamXML(root, "Fields", this, PhysicsEngine, loadFields)
+      .describe("loads a list of fields");
+
+  LoadParamXML(root, "Connections", this, PhysicsEngine, loadConnections)
+      .describe("loads a list of fields");
+}
+
+/**
+ * @param root the XML-element to Load the PhysicsField from
+ */
+void PhysicsEngine::loadFields(const TiXmlElement* root)
+{
+  PRINTF(4)("Loading Physical Fields\n");
+
+  const TiXmlElement* element = root->FirstChildElement();
+  while (element != NULL)
+  {
+    Factory::fabricate(element);
+
+    element = element->NextSiblingElement();
+  }
+}
+
+/**
+ * @param root the XML-element to load the PhysicsConnection from
+ */
+void PhysicsEngine::loadConnections(const TiXmlElement* root)
+{
+  PRINTF(4)("Loading Physical Connections\n");
+
+  const TiXmlElement* element = root->FirstChildElement();
+  while (element != NULL)
+  {
+    Factory::fabricate(element);
+
+    element = element->NextSiblingElement();
+  }
+}
+
+/**
+* @param physicsInterfaceName the Name of the PhysicsInterface to search for
+  @returns the PhysicsInterface if found, or NULL if not
+ */
+PhysicsInterface* PhysicsEngine::getPhysicsInterfaceByName(const std::string& physicsInterfaceName) const
+{
+  return PhysicsInterface::objectList().getObject(physicsInterfaceName);
+}
+
+/**
+ *  adds a Field to the list of handeled fields
+ * @param field the field to add
+
+   this is normally done in the constructor of any Field
+*/
+void PhysicsEngine::addField(Field* field)
+{
+  this->fields.push_back(field);
+}
+
+/**
+ *  removes a Field from the list of handeled fields
+ * @param field the field to remove
+
+   this is normally done in the destructor of any Field
+*/
+void PhysicsEngine::removeField(Field* field)
+{
+  this->fields.remove(field);
+}
+
+/**
+* @param fieldName the Name of the PhysicsInterface to search for
+  @returns the Field if found, or NULL if not
+ */
+Field* PhysicsEngine::getFieldByName(const std::string& fieldName) const
+{
+  std::list<Field*>::const_iterator field;
+  for (field = this->fields.begin(); field != this->fields.end(); field++)
+    if (fieldName == (*field)->getName())
+      return (*field);
+  return NULL;
+}
+
+
+
+/**
+ *  adds A Physical Connection to the List of Connections
+ * @param connection the Connection to add
+
+   Usually this is done through the constructor of PhysicshConnections
+*/
+void PhysicsEngine::addConnection(PhysicsConnection* connection)
+{
+  this->connections.push_back(connection);
+}
+
+/**
+ *  removes A Physical Connection from the List of Connections
+ * @param connection the Connection to remove
+
+   Usually this is done through the destructor of PhysicsConnections
+*/
+void PhysicsEngine::removeConnection(PhysicsConnection* connection)
+{
+  this->connections.remove(connection);
+}
+
+/**
+* @param physicsConnectionName the Name of the PhysicsInterface to search for
+  @returns the PhysicsConnection if found, or NULL if not
+ */
+PhysicsConnection* PhysicsEngine::getPhysicsConnectionByName(const std::string& physicsConnectionName) const
+{
+  std::list<PhysicsConnection*>::const_iterator pc;
+  for (pc = this->connections.begin(); pc != this->connections.end(); pc++)
+    if (physicsConnectionName == (*pc)->getName())
+      delete (*pc);
+  return NULL;
+}
+
+
+
+/**
+ *  Steps through all the Connections and Ticks them
+ * @param dt The time Passed in Seconds
+
+   This function brings a flow into the whole animation
+*/
+void PhysicsEngine::tick(float dt)
+{
+  /* go through all the PhysicsInterface(s) and tick them,
+  meaning let the fields work */
+  std::list<PhysicsConnection*>::iterator pc;
+  for (pc = this->connections.begin(); pc != this->connections.end(); pc++)
+    (*pc)->apply();
+
+  /* actually tick all the PhysicsInterfaces. Move the objects around */
+
+  ObjectList<PhysicsInterface>::const_iterator it;
+  for (it = PhysicsInterface::objectList().begin();
+       it != PhysicsInterface::objectList().end();
+       ++it)
+      (*it)->tickPhys(dt);
+}
+
+
+
+/**
+ *  print out interesting debug information of this class
+*/
+void PhysicsEngine::debug() const
+{
+  PRINT(0)("====================================\n");
+  PRINT(0)("= Physics-Engine debug information =\n");
+  PRINT(0)("====================================\n");
+  PRINT(0)(" reference: %p\n", this);
+  if (this->interfaces != NULL)
+    PRINT(0)(" number of Interfaces: %d\n", this->interfaces->size());
+  PRINT(0)(" number of Fields: %d\n", this->fields.size());
+  PRINT(0)(" number of Connections: %d\n", this->connections.size());
+
+  PRINT(0)("==============================PHYS==\n");
+}
Index: branches/heathaze/src/lib/physics/physics_engine.h
===================================================================
--- branches/heathaze/src/lib/physics/physics_engine.h	(revision 9940)
+++ branches/heathaze/src/lib/physics/physics_engine.h	(revision 9940)
@@ -0,0 +1,62 @@
+/*!
+ * @file physics_engine.h
+  *  Definition of the PhysicsEngine-singleton Class
+
+*/
+
+#ifndef _PHYSICS_ENGINE_H
+#define _PHYSICS_ENGINE_H
+
+#include "base_object.h"
+
+#include "physics_connection.h"
+#include "physics_interface.h"
+#include "fields/field.h"
+#include <list>
+
+// Forward Declaration
+template<class T> class tList;
+class TiXmlElement;
+
+//! A class, that brings things into motion through Physics.
+class PhysicsEngine : public BaseObject
+{
+  ObjectListDeclaration(PhysicsEngine);
+public:
+  virtual ~PhysicsEngine();
+  /** @returns a Pointer to the only object of this Class */
+  inline static PhysicsEngine* getInstance() { if (!singletonRef) singletonRef = new PhysicsEngine();  return singletonRef; };
+
+  virtual void loadParams(const TiXmlElement* root);
+  void loadFields(const TiXmlElement* root);
+  void loadConnections(const TiXmlElement* root);
+
+  PhysicsInterface*      getPhysicsInterfaceByName(const std::string& physicsInterfaceName) const;
+
+  void                   addField(Field* field);
+  void                   removeField(Field* field);
+  Field*                 getFieldByName(const std::string& fieldName) const;
+
+  void                   addConnection(PhysicsConnection* connection);
+  void                   removeConnection(PhysicsConnection* connection);
+  PhysicsConnection*     getPhysicsConnectionByName(const std::string& physicsConnectionName) const;
+
+
+  void                   tick(float dt);
+
+  void                   debug() const;
+
+private:
+  PhysicsEngine();
+
+private:
+  static PhysicsEngine*         singletonRef;         //!< the singleton reference of the PhysicsEngine
+
+  std::list<Field*>             fields;               //!< a list of physicsl fields.
+  std::list<PhysicsConnection*> connections;          //!< a list of physical connections.
+  const std::list<BaseObject*>* interfaces;           //!< The list of physical interfaces.
+};
+
+
+
+#endif /* _PHYSICS_ENGINE_H */
Index: branches/heathaze/src/lib/physics/physics_interface.cc
===================================================================
--- branches/heathaze/src/lib/physics/physics_interface.cc	(revision 9940)
+++ branches/heathaze/src/lib/physics/physics_interface.cc	(revision 9940)
@@ -0,0 +1,122 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+   bensch: renamed the file
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "physics_interface.h"
+#include "physics_engine.h"
+
+#include "fields/field.h"
+#include "p_node.h"
+
+#include "string.h"
+#include "stdincl.h"
+
+
+
+ObjectListDefinition(PhysicsInterface);
+/**
+ * @brief standard constructor
+ */
+PhysicsInterface::PhysicsInterface ()
+{
+  this->registerObject(this, PhysicsInterface::_objectList);
+
+  this->mass = 1;
+  this->massChildren = 0;
+  this->forceSum = Vector(0, 0, 0);
+  this->bForceApplied = false;
+}
+
+/**
+ *  standard deconstructor
+*/
+PhysicsInterface::~PhysicsInterface ()
+{
+}
+
+/**
+ *  recalculates the total mass of all the children of this node
+
+   (only availiable for PNodes)
+*/
+void PhysicsInterface::recalcMass()
+{
+  /*
+    PNode* massCalcPNode = dynamic_cast<PNode*>(this);  //! @todo not sure if this will work ....
+    float massSum = 0;
+
+    tIterator<PNode>* iterator = massCalcPNode->children->getIterator();
+    PNode* pn = iterator->firstElement();
+    while( pn != NULL)
+    {
+    // todo: find out if children are PhysicsInterface in an efficient way
+    if (strcmp( pn->getClassCName(), "PhysicsInterface")) {
+    massSum += ((PhysicsInterface*)pn)->getTotalMass();
+    }
+    pn = iterator->nextElement();
+    }
+    delete iterator;
+
+    if (massSum != this->massChildren ) {
+    this->massChildren = massSum;
+    if (strcmp( massCalcPNode->parent->getClassCName(), "PhysicsInterface"))
+    ((PhysicsInterface*)massCalcPNode->parent)->recalcMass();
+    } else {
+    this->massChildren = massSum;
+    }
+  */
+}
+
+/**
+ *  applyes a field to this Object
+ * @param field the field to apply
+ *
+ * this function is virtual, and !must be reimplemented if the Member is !NOT! a PNode
+*/
+void PhysicsInterface::applyField(Field* field)
+{
+  PNode* tmp = dynamic_cast<PNode*>((BaseObject*)this);
+  this->forceSum += field->calcForce(tmp->getAbsCoor());
+  this->bForceApplied = true;
+}
+
+void PhysicsInterface::applyForce(const Vector& force)
+{
+  this->forceSum += force;
+  this->bForceApplied = true;
+}
+
+/**
+ *  ticks the PhysicsEffect
+ * @param dt: the value about which to tick
+*/
+void PhysicsInterface::tickPhys( float dt )
+{
+  //  Vector acc = this->forceSum / ( this->massChildren + this->mass );
+  PNode* coorTick =  dynamic_cast<PNode*>((BaseObject*)this);
+  if (coorTick != NULL )
+    coorTick->shiftCoor((coorTick->getVelocity()+ this->forceSum/this->mass*dt)*dt);
+
+  if (this->bForceApplied)
+  {
+    this->bForceApplied = false;
+    this->forceSum = Vector(0,0,0);
+  }
+}
Index: branches/heathaze/src/lib/physics/physics_interface.h
===================================================================
--- branches/heathaze/src/lib/physics/physics_interface.h	(revision 9940)
+++ branches/heathaze/src/lib/physics/physics_interface.h	(revision 9940)
@@ -0,0 +1,67 @@
+/*!
+ * @file physics_interface.h
+  *  a physics interface simulating a body with a mass
+*/
+
+#ifndef _PHYSICS_INTERFACE_H
+#define _PHYSICS_INTERFACE_H
+
+#include "base_object.h"
+
+#include "vector.h"
+#include "quaternion.h"
+#ifndef NULL
+#define NULL 0          //!< NULL
+#endif
+
+// Forward Declaration
+class Field;
+
+//! A Physics interface
+/**
+   The PhysicsInterface is an extension to Any other object,
+   that can be used to turn it to be Physcally animated.
+   Still you have to connect fields.
+   IMPORTANT is, that when using PNodes this baseclass is ok.
+   BUT, when using any other class that does not by itself implement
+   PNode you __MUST__ implement all the virtual functions by your own
+*/
+class PhysicsInterface : virtual public BaseObject
+{
+  ObjectListDeclaration(PhysicsInterface);
+ public:
+  PhysicsInterface();
+  virtual ~PhysicsInterface();
+  /** @param mass the mass to set for this node. */
+  inline void setMass( float mass ) { this->mass = mass; };
+  /** @returns the mass of the node. */
+  inline float getMass( void ) const { return mass; };
+  /** @returns the mass of this node plus all its children (only valid for PNodes). */
+  inline float getTotalMass( void ) const { return mass + massChildren; };
+
+  /** @returns the velocity */
+  inline const Vector getVelocity() { return this->velocity; }
+  /** @returns the acceleration */
+  inline const Vector getAcceleration() { return this->acceleration; }
+
+  virtual void applyForce(const Vector& force);
+  virtual void applyField(Field* field);
+  virtual void tickPhys( float dt );
+
+ protected:
+  virtual void recalcMass();
+
+
+ private:
+  float          mass;                  //!< Mass of this object
+  float          massChildren;          //!< Sum of the masses of the children nodes
+
+  Vector         velocity;              //!< the velocity of the masspoint
+  Vector         acceleration;          //!< acceleration of the masspoint
+
+  Vector         forceSum;              //!< Total central force for this tick
+  Quaternion     momentumSum;           //!< Total momentum in this tick
+  bool           bForceApplied;         //!< If a force was applied to this object.
+};
+
+#endif /* _PHYSICS_INTERFACE_H */
Index: branches/heathaze/src/lib/script_engine/Makefile.am
===================================================================
--- branches/heathaze/src/lib/script_engine/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/Makefile.am	(revision 9940)
@@ -0,0 +1,50 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+
+LIB_PREFIX=$(MAINSRCDIR)/lib
+include $(MAINSRCDIR)/lib/BuildLibs.am
+
+
+
+INCLUDES= -I../../../extern_libs
+
+noinst_LIBRARIES = libORXscript.a
+
+libORXscript_a_SOURCES = \
+		script_class.cc \
+		script_method.cc \
+                script.cc \
+                script_manager.cc \
+		executor_lua_state.cc
+
+AM_CPPFLAGS= @LUA_INCLUDES@
+
+noinst_HEADERS = \
+                lunar.h\
+                script.h\
+                script_manager.h \
+		script_class.h \
+		script_method.h \
+		executor_lua_state.h
+
+
+
+
+check_PROGRAMS = example
+example_DEPENDENCIES = \
+                $(MAINSRCDIR)/world_entities/libORXwe.a \
+                $(libORXlibs_a_LIBRARIES_) \
+                $(MAINSRCDIR)/util/libORXutils.a
+example_LDADD = \
+                $(MAINSRCDIR)/util/libORXutils.a \
+                $(libORXlibs_a_LIBRARIES_) \
+                libORXscript.a -L../../../extern_libs @LUA_LIBS@ \
+                $(MAINSRCDIR)/world_entities/libORXwe.a \
+                $(libORXlibs_a_LIBRARIES_) \
+                $(MAINSRCDIR)/util/libORXutils.a
+
+example_SOURCES= \
+                example.cc \
+                \
+                ../util/executor/executor_lua.cc
Index: branches/heathaze/src/lib/script_engine/account.cc
===================================================================
--- branches/heathaze/src/lib/script_engine/account.cc	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/account.cc	(revision 9940)
@@ -0,0 +1,35 @@
+
+
+
+#include <iostream>
+
+#include "luaincl.h"
+#include "base_object.h"
+#include "lunar.h"
+
+#include "script_class.h"
+
+
+class Account : public BaseObject
+{
+  lua_Number m_balance;
+public:
+  Account(lua_State *L)      { m_balance = luaL_checknumber(L, 1); }
+  Account(double balance=0)    : m_balance(balance) { this->setClassID(CL_ACCOUNT, "Account"); }
+
+  void deposit (float value) { m_balance += value; };
+  void withdraw(float value) { m_balance -= value; };
+  float balance() { return m_balance; };
+
+  int deposit (lua_State *L) { m_balance += luaL_checknumber(L, 1); return 0; }
+  int withdraw(lua_State *L) { m_balance -= luaL_checknumber(L, 1); return 0; }
+  int balance (lua_State *L) { lua_pushnumber(L, m_balance); return 1; }
+  ~Account() { printf("deleted Account (%p)\n", this); }
+};
+
+
+
+CREATE_SCRIPTABLE_CLASS(Account, CL_ACCOUNT,
+                        addMethod("deposit", ExecutorLua1<Account, float>(&Account::deposit))
+                        ->addMethod("withdraw", ExecutorLua1<Account, float>(&Account::withdraw))
+                        ->addMethod("balance", ExecutorLua0ret<Account, float>(&Account::balance)));
Index: branches/heathaze/src/lib/script_engine/config.h
===================================================================
--- branches/heathaze/src/lib/script_engine/config.h	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/config.h	(revision 9940)
@@ -0,0 +1,56 @@
+/* config.h.  Generated by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#define HAVE_LIBDL 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Name of package */
+#define PACKAGE "lua_test"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "lua_test"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "lua_test 0.0.1-alpha"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "lua_test"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.0.1-alpha"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.0.1-alpha"
Index: branches/heathaze/src/lib/script_engine/example.cc
===================================================================
--- branches/heathaze/src/lib/script_engine/example.cc	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/example.cc	(revision 9940)
@@ -0,0 +1,148 @@
+
+#include <iostream>
+
+#include "luaincl.h"
+#include "lunar.h"
+#include "script.h"
+
+// create classdummys for the scripts
+CREATE_SCRIPTABLE_CLASS(Account, CL_ACCOUNT)
+CREATE_SCRIPTABLE_CLASS(Object, CL_TEST_OBJECT)
+
+    class Account : public BaseObject {
+      lua_Number m_balance;
+    public:
+      static const char className[];
+      static Lunar<Account>::RegType methods[];
+
+      Account(lua_State *L)      { m_balance = luaL_checknumber(L, 1); }
+      Account(double balance=0)    : m_balance(balance) { }
+
+      void deposit (float value) { m_balance += value; };
+      void withdraw(float value) { m_balance -= value; };
+      float balance() { return m_balance; };
+
+      int deposit (lua_State *L) { m_balance += luaL_checknumber(L, 1); return 0; }
+      int withdraw(lua_State *L) { m_balance -= luaL_checknumber(L, 1); return 0; }
+      int balance (lua_State *L) { lua_pushnumber(L, m_balance); return 1; }
+      ~Account() { printf("deleted Account (%p)\n", this); }
+    };
+
+    const char Account::className[] = "Account";
+
+    Lunar<Account>::RegType Account::methods[] = {
+      {"deposit", new ExecutorLua1<Account, float>(&Account::deposit)},
+      {"withdraw", new ExecutorLua1<Account, float>(&Account::withdraw)},
+      {"balance", new ExecutorLua0ret<Account, float>(&Account::balance)},
+      {0,NULL}
+    };
+
+
+    class Object : public BaseObject {
+      public:
+        static const char className[];
+        static Lunar<Object>::RegType methods[];
+
+        Object(lua_State* L) {callCount = 0; }
+        Object(){callCount = 0;};
+        ~Object() { printf("deleted Object (%p)\n", this); }
+
+        //meber functions
+        void takeParam(int i)
+        {
+         printf("Lua passed %i to c++\n",i);
+        }
+
+        int printName(lua_State* L)
+        {
+          this->printName();
+          return 0;
+        }
+
+        void printName()
+        {
+          callCount ++;
+          printf("Hi i'm object %p ! This is the %i. call.\n",this,callCount);
+        }
+
+        int getCallCount(){ return callCount; }
+
+      private:
+        int callCount;
+
+    };
+
+    const char Object::className[] = "Object";
+
+    Lunar<Object>::RegType Object::methods[] = {
+      {"printName", new ExecutorLua0<Object>(&Object::printName)},
+      {"getCallCount", new ExecutorLua0ret<Object, int>(&Object::getCallCount)},
+      {"takeParam", new ExecutorLua1<Object, int>(&Object::takeParam)},
+      {0,0}
+    };
+
+    int main(int argc, char *argv[])
+    {
+      std::string file("lunartest2.lua");
+     // Script script;
+      Script* script = ScriptManager::getInstance()->getScriptByFile(file);
+      printf("-------------------------- top of the stack:%i\n",lua_gettop(script->getLuaState()));
+
+      // Register classes with the script
+      // Lunar<Account>::Register(&script);
+      //Lunar<Object>::Register(&script);
+
+      //Object* obj= new Object();
+      //Account a;
+      //Account *b = new Account(30);
+
+      // Add instances to the script
+      //Lunar<Object>::insertObject(&script,obj,"Obj",true);
+      //Lunar<Account>::insertObject(&script,&a,"a",false);
+      //Lunar<Account>::insertObject(&script,b,"b",true);
+       //printf("-------------------------- top of the stack:%i\n",lua_gettop(script.getLuaState()));
+
+      //Load a file
+      //std::string file("lunartest2.lua");
+
+      //if(script.loadFile(file))
+        //printf("File %s succefully loaded\n", file.c_str());
+      //printf("-------------------------- top of the stack:%i\n",lua_gettop(script.getLuaState()));
+
+      //execute a function
+      printf("----------- main -----------\n");
+      std::string main("main");
+      if( script->selectFunction(main,3))
+       printf("function %s selected\n",main.c_str());
+
+      script->pushParam(3.14159,main);
+      script->executeFunction();
+
+      float retf = script->getReturnedFloat();
+      printf("main returned %f\n",retf);
+
+
+      if(script->getReturnedBool())
+       printf("main returned true\n");
+      else
+       printf("main returned false\n");
+
+      int ret = script->getReturnedInt();
+      printf("main returned %i\n",ret);
+
+      //printf("-------------------------- top of the stack:%i\n",lua_gettop(script.getLuaState()));
+      //execute a 2nd function
+      printf("----------- test -----------\n");
+      std::string test("test");
+      if( script->selectFunction(test,0))
+       printf("function %s selected\n",test.c_str());
+
+      script->executeFunction();
+
+
+      //if(argc>1) lua_dofile(script.getLuaState(), argv[1]);
+      printf("-------------------------- top of the stack:%i\n",lua_gettop(script->getLuaState()));
+
+      return 0;
+    }
+
Index: branches/heathaze/src/lib/script_engine/executor_lua_state.cc
===================================================================
--- branches/heathaze/src/lib/script_engine/executor_lua_state.cc	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/executor_lua_state.cc	(revision 9940)
@@ -0,0 +1,28 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "executor_lua_state.h"
+
+#include "lunar.h"
+
+std::string temp[7];
+
+
+template<typename type> type fromLua(lua_State* state, int index) { type *obj = Lunar<type>::check(state, 1); lua_remove(state, 1); return obj; };
+template<typename type> void toLua(lua_State* state, type value) { Lunar<type>::push(state, value, false); };
+
+template<> const std::string& fromLua<const std::string&>(lua_State* state, int index) { temp[index] = lua_tostring(state, index); return temp[index]; };
Index: branches/heathaze/src/lib/script_engine/executor_lua_state.h
===================================================================
--- branches/heathaze/src/lib/script_engine/executor_lua_state.h	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/executor_lua_state.h	(revision 9940)
@@ -0,0 +1,105 @@
+/*!
+ * @file executor_lua_state.h
+ * Definition of a Executor that takes lua_State* as input.
+ */
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+
+#ifndef __EXECUTOR_LUA_STATE_H_
+#define __EXECUTOR_LUA_STATE_H_
+
+
+#include "executor/executor_generic.h"
+
+#include "luaincl.h"
+
+#ifdef FUNCTOR_CALL_TYPE
+ #undef FUNCTOR_CALL_TYPE
+#endif
+//! Define the Functor call type as lua_State*.
+#define FUNCTOR_CALL_TYPE lua_State*
+
+/**
+ * @brief Converts a lua_State into any type.
+ * @param state the State to get the value from.
+ * @param index the position inside of the lua_State to get the value from.
+ * @returns The value if found.
+ */
+template<typename type> type fromLua(lua_State* state, int index);
+/** @see template<typename type> inline type fromLua(lua_State* state, int index) */
+template<> inline bool fromLua<bool>(lua_State* state, int index) { return lua_toboolean(state, index); };
+/** @see template<typename type> inline type fromLua(lua_State* state, int index) */
+template<> inline int fromLua<int>(lua_State* state, int index) { return (int)lua_tonumber(state, index); };
+/** @see template<typename type> inline type fromLua(lua_State* state, int index) */
+template<> inline unsigned int fromLua<unsigned int>(lua_State* state, int index) { return (unsigned int)lua_tonumber(state, index); };
+/** @see template<typename type> inline type fromLua(lua_State* state, int index) */
+template<> inline float fromLua<float>(lua_State* state, int index) { return (float)lua_tonumber(state, index); };
+/** @see template<typename type> inline type fromLua(lua_State* state, int index) */
+template<> inline char fromLua<char>(lua_State* state, int index) { return (char)lua_tonumber(state, index); };
+/** @see template<typename type> inline type fromLua(lua_State* state, int index) */
+template<> const std::string& fromLua<const std::string&>(lua_State* state, int index);
+
+
+/**
+ * @brief writes a value into a lua_State.
+ * @param state the state to write into.
+ * @param value the Value of type to write into the State.
+ */
+template<typename type> void toLua(lua_State* state, type value);
+/** @see template<typename type> void toLua(lua_State* state, type value) */
+template<> inline void toLua<bool>(lua_State* state, bool value) { lua_pushboolean(state, (int) value); };
+/** @see template<typename type> void toLua(lua_State* state, type value) */
+template<> inline void toLua<int>(lua_State* state, int value)  { lua_pushnumber(state, (lua_Number) value); };
+/** @see template<typename type> void toLua(lua_State* state, type value) */
+template<> inline void toLua<unsigned int>(lua_State* state, unsigned int value){ lua_pushnumber(state, (lua_Number) value); };
+/** @see template<typename type> void toLua(lua_State* state, type value) */
+template<> inline void toLua<float>(lua_State* state, float value) { lua_pushnumber(state, (lua_Number) value); };
+/** @see template<typename type> void toLua(lua_State* state, type value) */
+template<> inline void toLua<char>(lua_State* state, char value) { lua_pushnumber(state, (lua_Number) value); };
+/** @see template<typename type> void toLua(lua_State* state, type value) */
+template<> inline void toLua<const std::string&>(lua_State* state, const std::string& value) { lua_pushstring (state, value.c_str()); }
+
+
+
+//! A Class, that evaluates a lua_State and converts indices into different Types.
+template<> class ExecutorEvaluater <lua_State*>
+{
+public:
+  /** @brief Executes the Evaluater
+   * @param CallValue the Value that should be converted
+   * @param defaults the default Values.
+   */
+  template <typename ToType, int index>
+  static ToType getValue(lua_State*& CallValue, const MultiType* const defaults)
+  {
+    return (fromLua<ToType>(CallValue, index+1));
+  }
+  /**
+   * @param state the state to write into
+   * @param value the Value to write there.
+   */
+  template <typename FromType>
+  static void storeRet(lua_State*& state, FromType value)
+  {
+    toLua<FromType>(state, value);
+  }
+  /** @returns the Null Value of a lua_State*, namely (pointer-type) NULL */
+  static lua_State*& defaultValue() { static lua_State* nullState; return nullState; };
+};
+
+#endif /* __EXECUTOR_LUA_STATE_H_ */
Index: branches/heathaze/src/lib/script_engine/luaincl.h
===================================================================
--- branches/heathaze/src/lib/script_engine/luaincl.h	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/luaincl.h	(revision 9940)
@@ -0,0 +1,13 @@
+
+#ifndef __LUA_INCL_H__
+#define __LUA_INCL_H__
+
+
+extern "C" {
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+}
+
+#endif /* __LUA_INCL_H__ */
+
Index: branches/heathaze/src/lib/script_engine/lunar.h
===================================================================
--- branches/heathaze/src/lib/script_engine/lunar.h	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/lunar.h	(revision 9940)
@@ -0,0 +1,286 @@
+#ifndef _LUNAR_H
+#define _LUNAR_H
+
+#include <string>
+#include <cassert>
+#include "script.h"
+
+#include "luaincl.h"
+#include "script_method.h"
+
+
+
+template <typename T> class Lunar
+{
+  typedef struct { T *pT; }
+  userdataType;
+public:
+  typedef Executor<lua_State*>* mfp;
+  typedef struct { const char *name; mfp mfunc; }
+  RegType;
+
+
+  static void Register(Script* script, const std::string& className, const ScriptMethod* scriptMethods)
+  {
+    if(script != NULL)
+      Register(script->getLuaState(), className, scriptMethods);
+  }
+
+  static void Register(lua_State *L, const std::string& className, const ScriptMethod* scriptMethods)
+  {
+    Lunar<T>::className = className;
+    Lunar<T>::scriptMethods = scriptMethods;
+    lua_newtable(L);
+    int methods = lua_gettop(L);
+
+    luaL_newmetatable(L, Lunar<T>::className.c_str());
+    int metatable = lua_gettop(L);
+
+    // store method table in globals so that
+    // scripts can add functions written in Lua.
+    lua_pushvalue(L, methods);
+    set(L, LUA_GLOBALSINDEX, Lunar<T>::className.c_str());
+
+    // hide metatable from Lua getmetatable()
+    lua_pushvalue(L, methods);
+    set(L, metatable, "__metatable");
+
+    lua_pushvalue(L, methods);
+    set(L, metatable, "__index");
+
+    lua_pushcfunction(L, tostring_T);
+    set(L, metatable, "__tostring");
+
+    lua_pushcfunction(L, gc_T);
+    set(L, metatable, "__gc");
+
+    lua_newtable(L);                // mt for method table
+    lua_pushcfunction(L, new_T);
+    lua_pushvalue(L, -1);           // dup new_T function
+    set(L, methods, "new");         // add new_T to method table
+    set(L, -3, "__call");           // mt.__call = new_T
+    lua_setmetatable(L, methods);
+
+    // fill method table with methods from class T
+    /* as it was originally
+    for (RegType *l = T::methods; l->name; l++)
+    {
+      lua_pushstring(L, l->name);
+      lua_pushlightuserdata(L, (void*)l);
+      lua_pushcclosure(L, thunk, 1);
+      lua_settable(L, methods);
+  }*/
+    for (unsigned int i = 0; i < Lunar<T>::scriptMethods->size(); i++)
+    {
+      lua_pushstring(L, Lunar<T>::scriptMethods->name(i).c_str());
+      lua_pushlightuserdata(L, (void*)Lunar<T>::scriptMethods->executor(i));
+      lua_pushcclosure(L, thunk, 1);
+      lua_settable(L, methods);
+    }
+    lua_pop(L, 2);  // drop metatable and method table
+  }
+
+  // call named lua method from userdata method table
+  static int call(lua_State *L, const char *method,
+                  int nargs=0, int nresults=LUA_MULTRET, int errfunc=0)
+  {
+    int base = lua_gettop(L) - nargs;  // userdata index
+    if (!luaL_checkudata(L, base, Lunar<T>::className.c_str()))
+    {
+      lua_settop(L, base-1);           // drop userdata and args
+      lua_pushfstring(L, "not a valid %s userdata", Lunar<T>::className.c_str());
+      return -1;
+    }
+
+    lua_pushstring(L, method);         // method name
+    lua_gettable(L, base);             // get method from userdata
+    if (lua_isnil(L, -1))
+    {            // no method?
+      lua_settop(L, base-1);           // drop userdata and args
+      lua_pushfstring(L, "%s missing method '%s'", Lunar<T>::className.c_str(), method);
+      return -1;
+    }
+    lua_insert(L, base);               // put method under userdata, args
+
+    int status = lua_pcall(L, 1+nargs, nresults, errfunc);  // call method
+    if (status)
+    {
+      const char *msg = lua_tostring(L, -1);
+      if (msg == NULL) msg = "(error with no message)";
+      lua_pushfstring(L, "%s:%s status = %d\n%s",
+                      Lunar<T>::className.c_str(), method, status, msg);
+      lua_remove(L, base);             // remove old message
+      return -1;
+    }
+    return lua_gettop(L) - base + 1;   // number of results
+  }
+
+  // push onto the Lua stack a userdata containing a pointer to T object
+  static int push(lua_State *L, T *obj, bool gc=false)
+  {
+    if (!obj) { lua_pushnil(L); return 0; }
+    luaL_getmetatable(L, Lunar<T>::className.c_str());  // lookup metatable in Lua registry
+    if (lua_isnil(L, -1)) luaL_error(L, "%s missing metatable", Lunar<T>::className.c_str());
+    int mt = lua_gettop(L);
+    subtable(L, mt, "userdata", "v");
+    userdataType *ud =
+      static_cast<userdataType*>(pushuserdata(L, obj, sizeof(userdataType)));
+    if (ud)
+    {
+      ud->pT = obj;  // store pointer to object in userdata
+      lua_pushvalue(L, mt);
+      lua_setmetatable(L, -2);
+      if (gc == false)
+      {
+        lua_checkstack(L, 3);
+        subtable(L, mt, "do not trash", "k");
+        lua_pushvalue(L, -2);
+        lua_pushboolean(L, 1);
+        lua_settable(L, -3);
+        lua_pop(L, 1);
+      }
+    }
+    lua_replace(L, mt);
+    lua_settop(L, mt);
+    return mt;  // index of userdata containing pointer to T object
+  }
+
+
+  static int insertObject(lua_State* L, T* obj, const std::string& name, bool gc=false)
+  {
+    int objectRef = push(L, obj, gc);
+
+    lua_pushlstring(L, name.c_str(), name.size());
+    lua_pushvalue(L, objectRef );
+    lua_settable(L, LUA_GLOBALSINDEX );
+
+    return objectRef;
+  }
+
+
+  static int insertObject(Script* script, T* obj, const std::string& name, bool gc=false)
+  {
+    assert (script != NULL);
+    return insertObject(script->getLuaState(), obj, name, gc);
+  }
+
+  // get userdata from Lua stack and return pointer to T object
+  static T *check(lua_State *L, int narg)
+  {
+    userdataType *ud =
+      static_cast<userdataType*>(luaL_checkudata(L, narg, Lunar<T>::className.c_str()));
+    if(!ud) luaL_typerror(L, narg, Lunar<T>::className.c_str());
+    return ud->pT;  // pointer to T object
+  }
+
+private:
+  Lunar();  // hide default constructor
+
+  // member function dispatcher
+  static int thunk(lua_State *L)
+  {
+    // stack has userdata, followed by method args
+    T *obj = check(L, 1);  // get 'self', or if you prefer, 'this'
+    lua_remove(L, 1);  // remove self so member function args start at index 1
+    // get member function from upvalue
+    mfp l = static_cast<mfp>(lua_touserdata(L, lua_upvalueindex(1)));
+    (*l)(obj, L);  // call member function
+    return l->hasRetVal()? 1 : 0;
+  }
+
+  // create a new T object and
+  // push onto the Lua stack a userdata containing a pointer to T object
+  static int new_T(lua_State *L)
+  {
+    lua_remove(L, 1);   // use classname:new(), instead of classname.new()
+    T *obj = new T();  // call constructor for T objects
+    push(L, obj, true); // gc_T will delete this object
+    return 1;           // userdata containing pointer to T object
+  }
+
+  // garbage collection metamethod
+  static int gc_T(lua_State *L)
+  {
+    if (luaL_getmetafield(L, 1, "do not trash"))
+    {
+      lua_pushvalue(L, 1);  // dup userdata
+      lua_gettable(L, -2);
+      if (!lua_isnil(L, -1)) return 0;  // do not delete object
+    }
+    userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1));
+    T *obj = ud->pT;
+    if (obj) delete obj;  // call destructor for T objects
+    return 0;
+  }
+
+  static int tostring_T (lua_State *L)
+  {
+    char buff[32];
+    userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1));
+    T *obj = ud->pT;
+    sprintf(buff, "%p", obj);
+    lua_pushfstring(L, "%s (%s)", Lunar<T>::className.c_str(), buff);
+    return 1;
+  }
+
+  static void set(lua_State *L, int table_index, const char *key)
+  {
+    lua_pushstring(L, key);
+    lua_insert(L, -2);  // swap value and key
+    lua_settable(L, table_index);
+  }
+
+  static void weaktable(lua_State *L, const char *mode)
+  {
+    lua_newtable(L);
+    lua_pushvalue(L, -1);  // table is its own metatable
+    lua_setmetatable(L, -2);
+    lua_pushliteral(L, "__mode");
+    lua_pushstring(L, mode);
+    lua_settable(L, -3);   // metatable.__mode = mode
+  }
+
+  static void subtable(lua_State *L, int tindex, const char *name, const char *mode)
+  {
+    lua_pushstring(L, name);
+    lua_gettable(L, tindex);
+    if (lua_isnil(L, -1))
+    {
+      lua_pop(L, 1);
+      lua_checkstack(L, 3);
+      weaktable(L, mode);
+      lua_pushstring(L, name);
+      lua_pushvalue(L, -2);
+      lua_settable(L, tindex);
+    }
+  }
+
+  static void *pushuserdata(lua_State *L, void *key, size_t sz)
+  {
+    void *ud = 0;
+    lua_pushlightuserdata(L, key);
+    lua_gettable(L, -2);     // lookup[key]
+    if (lua_isnil(L, -1))
+    {
+      lua_pop(L, 1);         // drop nil
+      lua_checkstack(L, 3);
+      ud = lua_newuserdata(L, sz);  // create new userdata
+      lua_pushlightuserdata(L, key);
+      lua_pushvalue(L, -2);  // dup userdata
+      lua_settable(L, -4);   // lookup[key] = userdata
+    }
+    return ud;
+  }
+
+  private:
+    static std::string className;
+    static const ScriptMethod* scriptMethods;
+};
+
+template <typename T>
+    std::string Lunar<T>::className = "";
+template <typename T>
+    const ScriptMethod* Lunar<T>::scriptMethods = NULL;
+
+#endif /* _LUNAR_H */
+
Index: branches/heathaze/src/lib/script_engine/lunartest2.lua
===================================================================
--- branches/heathaze/src/lib/script_engine/lunartest2.lua	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/lunartest2.lua	(revision 9940)
@@ -0,0 +1,58 @@
+function printf(...) io.write(string.format(unpack(arg))) end
+
+function Account:show()
+  printf("Account balance = $%0.02f\n", self:balance())
+end
+
+parent = {}
+
+function parent:rob(amount)
+  amount = amount or self:balance()
+  self:withdraw(amount)
+  return amount
+end
+
+getmetatable(Account).__index = parent
+
+
+function test()
+io.write("Hi i'm test\n")
+end
+
+
+function main(arg)
+  io.write("hello i am main!\n")
+  -- use parameter
+  io.write("main received ", arg)
+  io.write(" as parameter\n")
+
+ 
+  --call member of an inserted object
+  Obj:printName()
+
+  --create object of a registered type
+  o = Object()
+  o:printName()
+
+  --take returnvalue from c
+  callCount = Obj:getCallCount()
+  io.write("callCount is now ",callCount)
+  io.write("\n")
+
+  --pass parameters to a c++ method
+  Obj:takeParam(3)
+
+  --print object information
+  print('a =', a)
+  print('b =', b)
+  print('metatable =', getmetatable(a))
+  print('Account =', Account)
+  table.foreach(Account, print)
+
+  a:show() a:deposit(50.30) a:show() a:withdraw(25.10) a:show()
+  Obj:printName()
+
+  return 2,false,2.72
+
+  --debug.debug()
+end
Index: branches/heathaze/src/lib/script_engine/object.cc
===================================================================
--- branches/heathaze/src/lib/script_engine/object.cc	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/object.cc	(revision 9940)
@@ -0,0 +1,46 @@
+
+#include <iostream>
+
+#include "base_object.h"
+#include "lunar.h"
+
+#include "script_class.h"
+
+
+class Object : public BaseObject
+{
+public:
+  Object(lua_State* L) {callCount = 0; }
+  Object(){callCount = 0;this->setClassID(CL_TEST_OBJECT, "Object");};
+  ~Object() { printf("deleted Object (%p)\n", this); }
+
+  //meber functions
+  void takeParam(int i)
+  {
+    printf("Lua passed %i to c++\n",i);
+  }
+
+  int printName(lua_State* L)
+  {
+    this->printName();
+    return 0;
+  }
+
+  void printName()
+  {
+    callCount ++;
+    printf("Hi i'm object %p ! This is the %i. call.\n",this,callCount);
+  }
+
+  int getCallCount(){ return callCount; }
+
+private:
+  int callCount;
+
+};
+
+
+CREATE_SCRIPTABLE_CLASS(Object, CL_TEST_OBJECT,
+                        addMethod("printName", ExecutorLua0<Object>(&Object::printName))
+                        ->addMethod("getCallCount", ExecutorLua0ret<Object, int>(&Object::getCallCount))
+                        ->addMethod("takeParam", ExecutorLua1<Object, int>(&Object::takeParam)));
Index: branches/heathaze/src/lib/script_engine/script.cc
===================================================================
--- branches/heathaze/src/lib/script_engine/script.cc	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/script.cc	(revision 9940)
@@ -0,0 +1,428 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Silvan Nellen
+   co-programmer: Benjamin Grauer
+*/
+
+#include "script.h"
+#include "script_class.h"
+#include "luaincl.h"
+#include "debug.h"
+
+#include "loading/resource_manager.h"
+#include "loading/load_param.h"
+#include "parser/tinyxml/tinyxml.h"
+
+ObjectListDefinition(Script);
+
+
+Script::Script(const TiXmlElement* root)
+{
+  this->registerObject(this, Script::_objectList);
+
+  returnCount = argumentCount = 0;
+
+  luaState = lua_open();
+
+  luaopen_base(luaState);
+  luaopen_table(luaState);
+  luaopen_io(luaState);
+  luaopen_string(luaState);
+  luaopen_math(luaState);
+  luaopen_debug(luaState);
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+Script::Script(const std::string& filename)
+{
+  this->registerObject(this, Script::_objectList);
+
+  returnCount = argumentCount = 0;
+
+  luaState = lua_open();
+
+  luaopen_base(luaState);
+  luaopen_table(luaState);
+  luaopen_io(luaState);
+  luaopen_string(luaState);
+  luaopen_math(luaState);
+  luaopen_debug(luaState);
+
+  this->loadFile(filename);
+
+}
+
+Script::~Script()
+{
+  lua_setgcthreshold(luaState, 0);  // collected garbage
+  lua_close(luaState);
+}
+
+
+void Script::loadParams(const TiXmlElement* root)
+{
+  //printf(("Loading params for %p \n",this);
+  BaseObject::loadParams(root);
+
+ LOAD_PARAM_START_CYCLE(root, object);
+  {
+    LoadParam_CYCLE(object, "object", this, Script, addObject)
+       .describe("The name of an object that is needed by a script");
+  }
+ LOAD_PARAM_END_CYCLE(object);
+
+
+  LoadParam(root, "file", this, Script, loadFileNoRet)
+      .describe("the fileName of the script, that should be loaded into this world")
+      .defaultValues("");
+}
+
+
+
+bool Script::loadFile(const std::string& filename)
+ {
+   std::string filedest(Resources::ResourceManager::getInstance()->mainGlobalPath().name());
+   filedest += "/scripts/" + filename;
+
+   this->addThisScript();
+   this->registerStandartClasses();
+
+   if(currentFile.length() != 0)
+   {
+     printf("SCRIPT %s : ERROR: Could not load %s because an other file is already loaded: %s\n",currentFile.c_str(),filename.c_str(), currentFile.c_str());
+     return false;
+    }
+
+   int error = luaL_loadfile (luaState, filedest.c_str());
+
+   if(error == 0)
+   {
+     currentFile = filename;
+     error = lua_pcall(luaState, 0, 0, 0);
+
+     if(error == 0)
+     {
+      return true;
+     }
+     else
+     {
+       printf("SCRIPT %s : ERROR: while loading file %s: \n",currentFile.c_str(),filename.c_str());
+       reportError(error);
+     }
+
+   }
+   else
+   {
+     printf("SCRIPT %s : ERROR: while loading file %s: \n",currentFile.c_str(),filename.c_str());
+     reportError(error);
+   }
+
+   return false;
+ }
+
+
+ void Script::addObject(const std::string& className, const std::string& objectName)
+ {
+   //printf(("Script %s: I am about to add %s of class %s\n",this->getName(),objectName.c_str(),className.c_str());
+
+   ScriptClass* scriptClass = ScriptClass::objectList().getObject(className);
+  // printf(("The script class for %s is at %p \n",className.c_str(),scriptClass);
+   WorldObject tmpObj;
+   if (scriptClass != NULL)
+   {
+     tmpObj.type = className;
+     if( !classIsRegistered(className) )
+     {
+       scriptClass->registerClass(this);
+     }
+
+     BaseObject* object = ObjectListBase::getBaseObject(className, objectName);
+    // printf(("%s is at %p \n",objectName.c_str(),object);
+     if (object != NULL && !objectIsAdded(objectName))
+     {
+        scriptClass->insertObject(this, object, false);
+        tmpObj.name = objectName;
+        registeredObjects.push_back(tmpObj);
+     }
+   }
+ }
+
+
+
+
+ bool Script::executeFile()
+ {
+   PRINTF(2)("script.executeFile is not implemented yet\n");
+   /*if(currentFile.length() != 0)
+   {
+    int error = lua_pcall(luaState, 0, 0, 0);
+    if( error == 0)
+      return true;
+     else
+      {
+       reportError(error);
+       return false;
+      }
+ }*/
+   return false;
+ }
+
+ bool Script::selectFunction(const std::string& functionName, int retCount)
+ {
+   if(returnCount == 0 && currentFunction.length() == 0) //no return values left on the stack and no other function selected
+   {
+   lua_pushlstring(luaState, functionName.c_str(), functionName.size() );
+   lua_gettable(luaState, LUA_GLOBALSINDEX);
+
+   if(lua_isfunction( luaState , -1))
+   {
+     returnCount = retCount;
+     argumentCount = 0;
+     currentFunction = functionName;
+     return true;
+   }
+   else
+    return false;
+   }
+   else
+     printf("SCRIPT %s : ERROR: There is an other function active ( %s ) or there are unremoved return values on the stack. Please remove them first.\n",currentFile.c_str(),currentFunction.c_str());
+   return false;
+ }
+
+ //return number of returned values
+ bool Script::executeFunction()
+ {
+   if(currentFunction.length() != 0 )
+   {
+    int error = lua_pcall(luaState, argumentCount, returnCount,0);
+    if(error != 0)
+    {
+      PRINTF(1)("Script '%s' : Failed to execute function '%s': \n",currentFile.c_str(),currentFunction.c_str());
+     reportError(error);
+     //clean up
+     currentFunction.assign("");
+     argumentCount = returnCount = 0;
+     return false;
+    }
+    else
+    {
+      currentFunction.assign("");//a function gets unusable after beeing called for the first time
+      argumentCount = 0;
+      return true;
+    }
+   }
+   else
+     PRINTF(1)("SCRIPT '%s' : no function selected.\n",currentFile.c_str());
+
+   return false;
+ }
+
+
+ //overload this function to add different types
+ bool Script::pushParam(int param, std::string& toFunction)
+ {
+   if(currentFunction == toFunction)
+   {
+     lua_pushnumber(luaState, (lua_Number) param);
+     argumentCount++;
+     return true;
+   }
+   else
+   {
+     printf("SCRIPT %s : ERROR: Couldn't add parameter because the wrong function is selected: %s instead of %s\n",currentFile.c_str(), currentFunction.c_str(), toFunction.c_str());
+    return false;
+   }
+
+ }
+
+
+ bool Script::pushParam(float param, std::string& toFunction)
+ {
+   if(currentFunction.compare(toFunction) == 0)
+   {
+     lua_pushnumber(luaState,(lua_Number) param);
+     argumentCount++;
+     return true;
+   }
+   else
+   {
+     printf("SCRIPT %s : ERROR: Couldn't add parameter because the wrong function is selected: %s instead of %s\n",currentFile.c_str(), currentFunction.c_str(), toFunction.c_str());
+     return false;
+   }
+
+ }
+
+ bool Script::pushParam(double param, std::string& toFunction)
+ {
+   if(currentFunction.compare(toFunction) == 0)
+   {
+     lua_pushnumber(luaState,(lua_Number) param);
+     argumentCount++;
+     return true;
+   }
+   else
+   {
+     printf("SCRIPT %s : ERROR: Couldn't add parameter because the wrong function is selected: %s instead of %s\n",currentFile.c_str(), currentFunction.c_str(), toFunction.c_str());
+     return false;
+   }
+
+ }
+
+ int Script::getReturnedInt()
+ {
+   int returnValue = 0;
+   if(returnCount > 0)
+   {
+     if(lua_isnumber(luaState, -1*returnCount))
+     {
+       returnValue = (int)lua_tonumber(luaState, -1*returnCount);
+       lua_remove(luaState,-1*returnCount);
+       returnCount--;
+
+     }
+   }
+   return returnValue;
+ }
+
+
+ bool Script::getReturnedBool()
+ {
+   bool returnValue = false;
+   if(returnCount > 0)
+   {
+     if(lua_isboolean(luaState, -1*returnCount))
+     {
+       returnValue = (bool)lua_toboolean(luaState, -1*returnCount);
+       lua_remove(luaState,-1*returnCount);
+       returnCount--;
+     }
+     else
+       printf("SCRIPT %s : ERROR: Trying to retreive non bolean value\n",this->currentFile.c_str());
+   }
+   return returnValue;
+ }
+
+float Script::getReturnedFloat()
+ {
+   float returnValue = 0.0f;
+   if(returnCount > 0)
+   {
+     if(lua_isnumber(luaState, -1*returnCount))
+     {
+       returnValue = (float)lua_tonumber(luaState, -1*returnCount);
+       lua_remove(luaState,-1*returnCount);
+       returnCount--;
+     }
+   }
+   return returnValue;
+ }
+
+ void Script::getReturnedString(std::string& string)
+ {
+   const char* returnValue = "";
+   if(returnCount > 0)
+   {
+     if(lua_isstring(luaState, -1*returnCount))
+     {
+       returnValue = lua_tostring(luaState, -1*returnCount);
+       lua_remove(luaState,-1*returnCount);
+       returnCount--;
+     }
+   }
+  string.assign(returnValue);
+ }
+
+
+void Script::addThisScript()
+{
+  ScriptClass* scriptClass = ScriptClass::objectList().getObject("Script");
+
+  if (scriptClass != NULL)
+   {
+     scriptClass->registerClass(this);
+     scriptClass->insertObject(this, this,"thisscript", false);
+   }
+}
+
+ int Script::reportError(int error)
+ {
+ if(error != 0)
+ {
+  const char *msg = lua_tostring(luaState, -1);
+  if (msg == NULL) msg = "(error with no message)\n";
+  printf("ERROR: %s\n", msg);
+  lua_pop(luaState, 1);
+ }
+  return error;
+ }
+
+ bool Script::registerStandartClasses()
+ {
+   bool success = false;
+
+   //this->registerClass(std::string("Vector"));
+    this->registerClass("ScriptTrigger");
+  //  this->registerClass("AttractorMine");
+
+   return success;
+ }
+
+
+ void Script::registerClass( const std::string& className)
+ {
+   ScriptClass* scriptClass = ScriptClass::objectList().getObject(className);
+   //printf(("The script class for %s is at %p \n",className.c_str(),scriptClass);
+
+   WorldObject tmpObj;
+   if (scriptClass != NULL)
+   {
+     tmpObj.type = className;
+     if( !classIsRegistered(className) )
+     {
+       static_cast<ScriptClass*>(scriptClass)->registerClass(this);
+       tmpObj.name = "";
+       registeredObjects.push_back(tmpObj);
+       return;
+     }
+   }
+
+ }
+
+ bool Script::classIsRegistered(const std::string& type)
+ {
+   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
+   {
+     if( (*it).type == type)
+     {
+       return true;
+     }
+   }
+   return false;
+ }
+
+
+
+ bool Script::objectIsAdded(const std::string& name)
+ {
+   for(std::list<WorldObject>::const_iterator it = registeredObjects.begin(); it != registeredObjects.end(); it++ )
+   {
+     if( (*it).name == name)
+     {
+       return true;
+     }
+   }
+   return false;
+
+
+ }
Index: branches/heathaze/src/lib/script_engine/script.h
===================================================================
--- branches/heathaze/src/lib/script_engine/script.h	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/script.h	(revision 9940)
@@ -0,0 +1,83 @@
+/*!
+ * @file scrip.h
+ *  wrapper for a lua_State
+ */
+
+#ifndef _SCRIPT_H
+#define _SCRIPT_H
+
+
+#include "base_object.h"
+
+#include <list>
+
+struct lua_State;
+
+struct WorldObject
+{
+  std::string name;
+  std::string type;
+};
+
+class Script : public BaseObject
+{
+  ObjectListDeclaration(Script);
+  public:
+    Script(const TiXmlElement* root = NULL);
+    Script(const std::string& filename);
+    ~Script();
+
+    /// LOADING
+    void loadParams(const TiXmlElement* root);
+
+    void loadFileNoRet(const std::string& filename) { loadFile(filename); };
+    bool loadFile(const std::string& filename);
+    void addObject( const std::string& className,const std::string& objectName);
+    void registerClass(const std::string& className);                           //!< Register a class but dont add any instances
+
+    /// QUERRYING
+    /** @returns fileName */
+    std::string getFileName() { return currentFile; }
+    lua_State* getLuaState() const { return luaState; }
+
+
+
+    /// EXECUTING
+    // first select function
+    bool selectFunction(const std::string& functionName, int retCount);
+
+    // push parameters for luafunction
+    bool  pushParam(int param, std::string& toFunction);
+    bool  pushParam(float param, std::string& toFunction);
+    bool  pushParam(double param, std::string& toFunction);
+
+    // Execute the Function
+    bool executeFunction();
+
+     // get returned values in the order the lua function returns it
+    int   getReturnedInt();
+    bool  getReturnedBool();
+    float getReturnedFloat();
+    void  getReturnedString(std::string& string);
+
+    bool executeFile();
+
+  private:
+    void addThisScript();
+    int  reportError(int error);                      //!< Get errormessage from the lua stack and print it.
+    bool registerStandartClasses();                   //!< Register all the classes that the script might need
+    bool classIsRegistered(const std::string& type);  //!< Checks wheter the class "type" has already been registered with the script
+    bool objectIsAdded(const std::string& name);      //!< Checks wheter the object "name" has already been added to the script
+
+    lua_State*              luaState;                //!< The lua_State that the Script works on
+    std::string             currentFile;             //!< The file that is loaded in the script
+    std::string             currentFunction;         //!< The name of the current active function (the one that gets the pushed parameter)
+    int                     argumentCount;           //!< Number of arguments for the current function
+    int                     returnCount;             //!< Number of return values of the current function
+
+    std::list<WorldObject>  registeredObjects;       //!< The list of all the objects and their type that have been registered with this script
+
+
+
+};
+#endif /* _SCRIPT_H */
Index: branches/heathaze/src/lib/script_engine/script_class.cc
===================================================================
--- branches/heathaze/src/lib/script_engine/script_class.cc	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/script_class.cc	(revision 9940)
@@ -0,0 +1,54 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "script_class.h"
+#include "script.h"
+#include "debug.h"
+#include <cassert>
+
+ObjectListDefinition(ScriptClass);
+
+CREATE_SCRIPTABLE_CLASS(Script,
+                    addMethod("addObject", Executor2<Script, lua_State*,const std::string&, const std::string& >(&Script::addObject))
+                    ->addMethod("registerClass", Executor1<Script, lua_State*,const std::string&>(&Script::registerClass))
+                    ->addMethod("selectFunction", Executor2ret<Script, lua_State*, bool, const std::string&, int >(&Script::selectFunction))
+                    ->addMethod("executeFunction", Executor0ret<Script, lua_State*,bool >(&Script::executeFunction))
+                     );
+/**
+ * @brief standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+ScriptClass::ScriptClass(const std::string& name, const ClassID& classID, ScriptMethod* scriptMethods)
+    : BaseObject(name), _classID(classID)
+{
+  PRINTF(4)("Name %s\n", name.c_str());
+  assert(scriptMethods != NULL);
+  this->registerObject(this, ScriptClass::_objectList);
+
+  this->_classID = classID;
+
+  this->_scriptMethods = scriptMethods;
+}
+
+
+/**
+ * standard deconstructor
+*/
+ScriptClass::~ScriptClass ()
+{
+  delete this->_scriptMethods;
+}
Index: branches/heathaze/src/lib/script_engine/script_class.h
===================================================================
--- branches/heathaze/src/lib/script_engine/script_class.h	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/script_class.h	(revision 9940)
@@ -0,0 +1,73 @@
+/*!
+ * @file script_class.h
+ * @brief Definition of ...
+*/
+
+#ifndef _SCRIPT_CLASS_H
+#define _SCRIPT_CLASS_H
+
+#include "base_object.h"
+
+#include "script.h"
+#include "lunar.h"
+#include "script_method.h"
+
+
+/**
+ * Creates a factory to a Loadable Class.
+ * this should be used at the beginning of all the Classes that should be loadable (in the cc-file)
+ */
+#define CREATE_SCRIPTABLE_CLASS(CLASS_NAME, SCRIPT_METHODS) \
+    tScriptClass<CLASS_NAME> global_##CLASS_NAME##_ScriptableClass(#CLASS_NAME, CLASS_NAME::staticClassID(), (new ScriptMethod)->SCRIPT_METHODS)
+
+
+//! A class for ...
+class ScriptClass : public BaseObject
+{
+  ObjectListDeclaration(ScriptClass);
+
+public:
+  virtual ~ScriptClass();
+
+  virtual void registerClass(Script* script) = 0;
+  virtual int insertObject(Script* L, BaseObject* obj, bool gc=false) = 0;
+  virtual int insertObject(Script* L, BaseObject* obj, const std::string& name, bool gc=false) = 0;
+
+  const ScriptMethod* scriptMethods() const { return this->_scriptMethods; }
+
+protected:
+  ScriptClass(const std::string& name, const ClassID& classID, ScriptMethod* scriptMethods);
+
+private:
+  ClassID             _classID;
+  ScriptMethod*       _scriptMethods;
+};
+
+
+
+
+template <class T>
+class tScriptClass : public ScriptClass
+{
+public:
+  tScriptClass(const std::string& name, ClassID classID, ScriptMethod* scriptMethods)
+      : ScriptClass(name, classID, scriptMethods)
+  { }
+
+  virtual void registerClass(Script* script)
+  {
+    Lunar<T>::Register(script, this->getName(), this->scriptMethods());
+  }
+  virtual int insertObject(Script* L, BaseObject* obj, bool gc=false)
+  {
+    return Lunar<T>::insertObject(L, dynamic_cast<T*>(obj), obj->getName(), gc);
+  }
+
+  virtual int insertObject(Script* L, BaseObject* obj,const std::string& name, bool gc=false)
+  {
+    return Lunar<T>::insertObject(L, dynamic_cast<T*>(obj), name, gc);
+  }
+};
+
+
+#endif /* _SCRIPT_CLASS_H */
Index: branches/heathaze/src/lib/script_engine/script_manager.cc
===================================================================
--- branches/heathaze/src/lib/script_engine/script_manager.cc	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/script_manager.cc	(revision 9940)
@@ -0,0 +1,106 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Silvan Nellen
+   co-programmer: Benjamin Grauer
+*/
+
+
+#include <string>
+#include <list>
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "script_manager.h"
+#include "lunar.h"
+
+#include "script.h"
+#include "script_trigger.h"
+#include "luaincl.h"
+#include "loading/load_param_xml.h"
+
+
+
+ScriptManager::ScriptManager(const TiXmlElement* root)
+{
+  this->setName("ScriptManager");
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+
+ScriptManager::~ScriptManager()
+{
+  this->flush();
+}
+
+
+void ScriptManager::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+  {
+    LoadParamXML(root, "Scripts", this, ScriptManager, createScripts);
+
+    LoadParamXML(root, "ScriptTriggers", this, ScriptManager, createTriggers);
+  } // make shure that the loading process is finished
+
+  // fill the scripts and triggers (doing that on runtime is very slow!)
+}
+
+
+
+void  ScriptManager::flush()
+{
+  //Delete all scripts as they aren't deleted automatically
+  while(!Script::objectList().empty())
+    delete Script::objectList().front();
+  //Delete all triggers
+  while(!ScriptTrigger::objectList().empty())
+    delete ScriptTrigger::objectList().front();
+
+}
+
+void  ScriptManager::createScripts(const TiXmlElement* scripts)
+{
+
+  LOAD_PARAM_START_CYCLE(scripts, object);
+  {
+    new Script(object);
+  }
+  LOAD_PARAM_END_CYCLE(object);
+
+}
+
+void ScriptManager::createTriggers(const TiXmlElement* triggers)
+{
+  LOAD_PARAM_START_CYCLE(triggers, object);
+  {
+    new ScriptTrigger(object);
+  }
+  LOAD_PARAM_END_CYCLE(object);
+
+}
+
+
+Script* ScriptManager::getScriptByFile(const std::string& file)
+{
+  for (ObjectList<Script>::const_iterator it = Script::objectList().begin();
+       it != Script::objectList().end();
+       ++it)
+    if( ((*it))->getFileName().compare(file) == 0)
+      return (*it);
+
+  return NULL;
+
+}
Index: branches/heathaze/src/lib/script_engine/script_manager.h
===================================================================
--- branches/heathaze/src/lib/script_engine/script_manager.h	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/script_manager.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file script_manager.h
+ *  manages the scripts
+ */
+
+#ifndef _SCRIPT_MANAGER_H
+#define _SCRIPT_MANAGER_H
+
+#include <list>
+
+#include "base_object.h"
+#include "script.h"
+
+
+class ScriptTrigger;
+class Scriptable;
+
+class ScriptManager : public BaseObject
+{
+ public:
+   ScriptManager(const TiXmlElement* root = NULL);
+   ~ScriptManager();
+
+  /// LOADING
+  virtual void loadParams(const TiXmlElement* root);
+
+  /// QUERY PROCESS
+  Script* getScriptByFile(const std::string& file);
+
+  void  flush();                                   //!< Resets the script manager
+
+ private:
+   void  createScripts(const TiXmlElement* scripts);
+   void  createTriggers(const TiXmlElement* triggers);
+
+   static ScriptManager*             singletonRef;   //!< Reference to this class
+};
+#endif
Index: branches/heathaze/src/lib/script_engine/script_method.cc
===================================================================
--- branches/heathaze/src/lib/script_engine/script_method.cc	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/script_method.cc	(revision 9940)
@@ -0,0 +1,49 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "script_method.h"
+
+/**
+ * @param standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+ScriptMethod::ScriptMethod()
+{ }
+
+ScriptMethod* ScriptMethod::addMethod(const std::string& methodName, const Executor<lua_State*>& executor)
+{
+  this->methods.push_back(ScriptMethod::Method(methodName, executor));
+
+  return this;
+}
+
+ScriptMethod::Method::Method(const std::string& name, const Executor<lua_State*>& executor)
+{
+  this->name = name;
+  this->executor = executor.clone();
+}
+
+/**
+ * standard deconstructor
+*/
+ScriptMethod::~ScriptMethod()
+{
+  for (unsigned int i = 0; i < methods.size(); i ++)
+  {
+    delete methods[i].executor;
+  };
+}
Index: branches/heathaze/src/lib/script_engine/script_method.h
===================================================================
--- branches/heathaze/src/lib/script_engine/script_method.h	(revision 9940)
+++ branches/heathaze/src/lib/script_engine/script_method.h	(revision 9940)
@@ -0,0 +1,39 @@
+/*!
+ * @file script_method.h
+ * @brief Definition of ...
+*/
+
+#ifndef _SCRIPT_METHOD_H
+#define _SCRIPT_METHOD_H
+
+#include <vector>
+
+#include "executor_lua_state.h"
+#include "executor/executor_member.h"
+
+class ScriptMethod
+{
+public:
+  ScriptMethod();
+  ~ScriptMethod();
+
+  ScriptMethod* addMethod(const std::string& methodName, const Executor<lua_State*>& executor);
+
+  unsigned int size() const { return methods.size(); };
+
+  const std::string& name(unsigned int methodNumber) const { return methods[methodNumber].name; };
+  const Executor<lua_State*>* executor(unsigned int methodNumber) const { return methods[methodNumber].executor; };
+
+
+private:
+  struct Method
+  {
+    Method(const std::string& name, const Executor<lua_State*>& executor);
+    std::string             name;
+    Executor<lua_State*>*   executor;
+  };
+
+  std::vector<Method> methods;
+};
+
+#endif /* _SCRIPT_METHOD_H */
Index: branches/heathaze/src/lib/shell/Makefile.am
===================================================================
--- branches/heathaze/src/lib/shell/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/shell/Makefile.am	(revision 9940)
@@ -0,0 +1,23 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXshell.a
+
+libORXshell_a_SOURCES = \
+		shell.cc \
+		shell_input.cc \
+		shell_command.cc \
+		shell_command_class.cc \
+		shell_completion.cc \
+		shell_completion_plugin.cc
+
+
+noinst_HEADERS= \
+		shell.h \
+		shell_input.h \
+		shell_command_class.h \
+		shell_command.h \
+		shell_completion.h \
+		shell_completion_plugin.h
+
+EXTRA_DIST = some_shell_commands.cc
Index: branches/heathaze/src/lib/shell/shell.cc
===================================================================
--- branches/heathaze/src/lib/shell/shell.cc	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell.cc	(revision 9940)
@@ -0,0 +1,535 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
+
+#include "shell.h"
+#include "shell_command.h"
+#include "debug_buffer.h"
+#include "shell_input.h"
+
+#include "multi_line_text.h"
+
+#include "graphics_engine.h"
+#include "material.h"
+#include "event_handler.h"
+#include "debug.h"
+
+namespace OrxShell
+{
+  ObjectListDefinition(Shell);
+
+  /**
+   * standard constructor
+   */
+  Shell::Shell ()
+  {
+    this->registerObject(this, Shell::_objectList);
+
+    this->setName("Shell");
+
+    this->shellBuffer = DebugBuffer::getInstance();
+
+    // EVENT-Handler subscription of '`' to all States.
+    this->subscribeEvent(ES_ALL, SDLK_BACKQUOTE);
+    this->subscribeEvent(ES_ALL, SDLK_F12);
+    this->subscribeEvent(ES_SHELL, SDLK_PAGEUP);
+    this->subscribeEvent(ES_SHELL, SDLK_PAGEDOWN);
+    this->subscribeEvent(ES_SHELL, EV_VIDEO_RESIZE);
+    EventHandler::getInstance()->withUNICODE(ES_SHELL, true);
+
+    // BUFFER
+    this->bufferIterator = this->shellBuffer->getBuffer().begin();
+
+    // INPUT LINE
+    this->setLayer(E2D_LAYER_ABOVE_ALL);
+    this->shellInput.setLayer(E2D_LAYER_ABOVE_ALL);
+
+    // Element2D and generals
+    this->setSizeX2D(GraphicsEngine::getInstance()->getResolutionX());
+    this->setAbsCoor2D(3, -400);
+    this->textSize = 15;
+    this->lineSpacing = 0;
+    this->bActive = false;
+    this->fontFile = SHELL_DEFAULT_FONT;
+
+    this->setBufferDisplaySize(10);
+
+    this->setTextColor(SHELL_DEFAULT_TEXT_COLOR);
+    this->setBackgroundColor(SHELL_DEFAULT_BACKGROUND_COLOR);
+
+
+    this->deactivate();
+  }
+
+  /**
+   * @brief standard deconstructor
+   */
+  Shell::~Shell ()
+  {
+    // delete the displayable Buffers
+    while (!this->bufferText.empty())
+    {
+      delete this->bufferText.front();
+      this->bufferText.pop_front();
+    }
+  }
+
+  /**
+   * @brief activates the shell
+   *
+   * This also feeds the Last few lines from the main buffers into the displayBuffer
+   */
+  void Shell::activate()
+  {
+    if (this->bActive == true)
+      PRINTF(3)("The shell is already active\n");
+    this->bActive = true;
+    this->activate2D();
+
+    EventHandler::getInstance()->pushState(ES_SHELL);
+
+    this->setRelCoorSoft2D(0, 0, 5);
+
+    this->linesProcessed = this->shellBuffer->getLineCount();
+    std::list<std::string>::const_iterator textLine = this->bufferIterator = this->shellBuffer->getBuffer().begin();
+    for (std::list<MultiLineText*>::iterator text = this->bufferText.begin(); text != this->bufferText.end(); ++text)
+    {
+      (*text)->setVisibility(true);
+      if (textLine !=  this->shellBuffer->getBuffer().end())
+      {
+        (*text)->setText((*textLine));
+        textLine++;
+      }
+      else
+        (*text)->setText("");
+    }
+    this->shellInput.setVisibility(true);
+    this->updateResolution( GraphicsEngine::getInstance()->getResolutionX());
+    this->repositionText();
+  }
+
+  /**
+   * @brief deactiveates the Shell.
+   */
+  void Shell::deactivate()
+  {
+    if (this->bActive == false)
+      PRINTF(3)("The shell is already inactive\n");
+    this->bActive = false;
+    this->deactivate2D();
+
+    EventHandler::getInstance()->popState();
+
+    this->setRelCoorSoft2D(0, -(int)this->shellHeight, 5);
+
+    for (std::list<MultiLineText*>::iterator text = this->bufferText.begin(); text != this->bufferText.end(); ++text)
+      (*text)->setVisibility(false);
+    this->shellInput.setVisibility(false);
+
+    // Go to the End again.
+    this->bufferIterator = this->shellBuffer->getBuffer().begin();
+  }
+
+  /**
+   * @brief sets the File to load the fonts from
+   * @param fontFile the file to load the font from
+   *
+   * it is quite important, that the font pointed too really exists!
+   * (be aware that within orxonox fontFile is relative to the Data-Dir)
+   */
+  void Shell::setFont(const std::string& fontFile)
+  {
+    this->fontFile = fontFile;
+
+    this->applySettings();
+  }
+
+  /**
+   * @brief sets the size of the text and spacing
+   * @param textSize the size of the Text in Pixels
+   * @param lineSpacing the size of the Spacing between two lines in pixels
+   *
+   * this also rebuilds the entire Text, inputLine and displayBuffer,
+   * to be accurate again.
+   */
+  void Shell::setTextSize(unsigned int textSize, unsigned int lineSpacing)
+  {
+    this->textSize = textSize;
+    this->lineSpacing = lineSpacing;
+
+    this->applySettings();
+  }
+
+  /**
+   * @brief sets the color of the Font.
+   * @param r: red
+   * @param g: green
+   * @param b: blue
+   * @param a: alpha-value.
+   */
+  void Shell::setTextColor(float r, float g, float b, float a)
+  {
+    this->textColor[0] = r;
+    this->textColor[1] = g;
+    this->textColor[2] = b;
+    this->textColor[3] = a;
+
+    this->applySettings();
+  }
+
+  /**
+   * @brief sets the color of the Backgrond.
+   * @param r: red
+   * @param g: green
+   * @param b: blue
+   * @param a: alpha-value.
+   */
+  void Shell::setBackgroundColor(float r, float g, float b, float a)
+  {
+    this->backgroundMaterial.setDiffuse(r, g, b);
+    this->backgroundMaterial.setTransparency(a);
+  }
+
+  /**
+   * @brief sets a nice background image to the Shell's background
+   * @param fileName the filename of the Image to load
+   */
+  void Shell::setBackgroundImage(const std::string& fileName)
+  {
+    this->backgroundMaterial.setDiffuseMap(fileName);
+  }
+
+
+  /**
+   * @brief updates the Shell's Width
+   * @param width the new Width.
+   */
+  void Shell::updateResolution(unsigned int width)
+  {
+    if (width == this->getSizeX2D())
+      return;
+    this->setSizeX2D(width);
+    for (std::list<MultiLineText*>::iterator textIt = this->bufferText.begin(); textIt != this->bufferText.end(); ++textIt)
+      (*textIt)->setLineWidth(width);
+  }
+
+  /**
+   * @brief repositiones all the Texts to their position.
+   */
+  void Shell::repositionText()
+  {
+    int linePos = -1;
+    std::list<MultiLineText*>::iterator textIt;
+    for (textIt = this->bufferText.begin() ; textIt != this->bufferText.end(); ++textIt )
+    {
+      linePos += (*textIt)->getLineCount();
+      (*textIt)->setRelCoorSoft2D(this->calculateLinePosition(linePos), 8);
+    }
+  }
+
+
+  /**
+   * @brief applies the Shells Settings to a single Text of the Shell.
+   * @param text the Text to apply the settings to.
+   */
+  void Shell::applyTextSettings(Text* text)
+  {
+    text->setSize(this->textSize);
+    text->setFont(this->fontFile, this->textSize);
+    text->setColor(this->textColor[0], this->textColor[1], this->textColor[2]);
+    text->setBlending(this->textColor[3]);
+    text->setLayer(this->getLayer());
+    if (text->getParent2D() != this)
+      text->setParent2D(this);
+  }
+
+  /**
+   * @brief resets the Values of all visible shell's commandos to the Shell's stored values
+   *
+   * this functions synchronizes the stored Data with the visible one.
+   */
+  void Shell::applySettings()
+  {
+    this->applyTextSettings(&this->shellInput);
+    this->shellInput.setRelCoor2D(15, (this->textSize + this->lineSpacing)*(this->bufferDisplaySize));
+
+    /* Here we create a Copy of the Buffer, so that we do not f**k up the List when some
+     * output is routed from Some other Thread or by Changing any Values.
+     */
+    std::list<MultiLineText*> bufferTextCopy = this->bufferText;
+    for (std::list<MultiLineText*>::iterator textIt = bufferTextCopy.begin(); textIt != bufferTextCopy.end(); ++textIt)
+    {
+      this->applyTextSettings(*textIt);
+      (*textIt)->setLineSpacing(this->lineSpacing);
+      (*textIt)->setLineWidth(this->getSizeX2D() * GraphicsEngine::getInstance()->getResolutionX());
+    }
+    this->repositionText();
+
+    this->shellHeight = (this->textSize + this->lineSpacing) * (bufferDisplaySize+1);
+  }
+
+  /**
+   * @brief sets The count of Lines to display in the buffer.
+   * @param bufferDisplaySize the count of lines to display in the Shell-Buffer.
+   */
+  void Shell::setBufferDisplaySize(unsigned int bufferDisplaySize)
+  {
+    unsigned int oldSize = this->bufferText.size();
+    if (oldSize > bufferDisplaySize)
+    {
+      for (unsigned int i = bufferDisplaySize; i <= oldSize; i++)
+      {
+        delete this->bufferText.back();
+        this->bufferText.pop_back();
+      }
+    }
+    else if (oldSize < bufferDisplaySize)
+    {
+      for (unsigned int i = oldSize; i <= bufferDisplaySize; i++)
+      {
+        this->bufferText.push_back(new MultiLineText);
+      }
+    }
+    this->bufferDisplaySize = bufferDisplaySize;
+    this->applySettings();
+  }
+
+  /**
+   * @brief deletes all the Buffers
+   */
+  void Shell::flush()
+  {
+    for (std::list<MultiLineText*>::iterator textIt = this->bufferText.begin(); textIt != this->bufferText.end(); ++textIt)
+    {
+      (*textIt)->setText("");  // remove all chars from the BufferTexts.
+    }
+    this->shellBuffer->flush();
+    // BUFFER FLUSHING
+  }
+
+  /**
+   * @brief prints out some text to the input-buffers
+   * @param text the text to output.
+   */
+  void Shell::printToDisplayBuffer(const std::string& text)
+  {
+    // Remove Last Entry and prepend it to the front.
+    this->bufferText.push_front(this->bufferText.back());
+    this->bufferText.pop_back();
+
+    // Set the new Text.
+    this->bufferText.front()->setText(text);
+    this->bufferIterator = this->shellBuffer->getBuffer().begin();
+
+    // The LineCount will be started here.
+
+    // The First Line gets a special Animation
+    this->bufferText.front()->setRelCoor2D(this->calculateLinePosition(0)- Vector2D(-1000,0));
+
+    // Move all lines one Entry up.
+    this->repositionText();
+  }
+
+
+  /**
+   * @brief moves the Display buffer (up + or down - )
+   * @param lineCount the count by which to shift the InputBuffer.
+   *
+   * @todo make this work
+   */
+  void Shell::moveDisplayBuffer(int lineCount)
+  {
+    // moving the iterator to the right position (counting the steps)
+    int moves = 0;
+    while (moves != lineCount)
+    {
+      if (moves < lineCount)
+      {
+        if(this->bufferIterator == --this->shellBuffer->getBuffer().end())
+          break;
+        ++moves;
+        ++this->bufferIterator;
+      }
+      else
+      {
+        if (this->bufferIterator == this->shellBuffer->getBuffer().begin())
+          break;
+        --moves;
+        --this->bufferIterator;
+      }
+    }
+
+
+    // redisplay the buffers
+    std::list<MultiLineText*>::iterator textIt;
+
+    // Give a Graphical Representation that no move is possible.
+    if (moves == 0)
+    {
+      int linePos = -1;
+      for (textIt = this->bufferText.begin(); textIt != this->bufferText.end(); ++textIt)
+      {
+        linePos += (*textIt)->getLineCount();
+        (*textIt)->setRelCoor2D(this->calculateLinePosition(linePos)+ Vector2D(20,0));
+        (*textIt)->setRelCoorSoft2D(this->calculateLinePosition(linePos), 10);
+      }
+      return;
+    }
+
+    // Move all the Lines.
+    int linePos = moves;
+    std::list<std::string>::const_iterator it = this->bufferIterator;
+    for (textIt = this->bufferText.begin(); textIt != this->bufferText.end(); ++textIt, ++it)
+    {
+      if (it == this->shellBuffer->getBuffer().end())
+      {
+        PRINTF(1)("LAST LINE REACHED\n");
+        break;
+      }
+
+
+      (*textIt)->setRelCoor2D(calculateLinePosition( (linePos++ > 0) ? linePos : 0));
+      (*textIt)->setText((*it));
+    }
+    while (textIt != this->bufferText.end())
+    {
+      (*textIt)->setText("");
+      textIt++;
+    }
+
+    this->repositionText();
+  }
+
+  /**
+   * @brief clears the Shell (empties all buffers)
+   */
+  void Shell::clear()
+  {
+    this->flush();
+    DebugBuffer::addBufferLineStatic("orxonox - shell\n ==================== \n", NULL);
+  }
+
+  /**
+   * @brief listens for some event
+   * @param event the Event happened
+   */
+  void Shell::process(const Event &event)
+  {
+    if (event.bPressed)
+    {
+      if (event.type == SDLK_BACKQUOTE || event.type == SDLK_F12)
+      {
+        if (this->bActive == false)
+          this->activate();
+        else
+          this->deactivate();
+      }
+      else if (event.type == SDLK_PAGEUP)
+      {
+        this->moveDisplayBuffer(+this->bufferDisplaySize-1);
+      }
+      else if (event.type == SDLK_PAGEDOWN)
+      {
+        this->moveDisplayBuffer(-this->bufferDisplaySize+1);
+      }
+    }
+    else if (event.type == EV_VIDEO_RESIZE)
+    {
+      this->updateResolution(event.resize.w);
+      this->repositionText();
+    }
+  }
+
+  void Shell::tick(float dt)
+  {
+    if (this->linesProcessed < this->shellBuffer->getLineCount())
+    {
+      unsigned int pollLines = this->shellBuffer->getLineCount() - this->linesProcessed;
+      if (this->bufferText.size() < pollLines)
+        pollLines = this->bufferText.size();
+      if (unlikely(this->shellBuffer->getBuffer().size() < pollLines))
+        pollLines = this->shellBuffer->getBuffer().size();
+
+      std::list<std::string>::const_iterator line = this->shellBuffer->getBuffer().begin();
+      unsigned int i;
+      for(i = 0; i < pollLines; i++)
+        line ++;
+      for (i = 0; i < pollLines; i++)
+      {
+        this->printToDisplayBuffer((*--line));
+      }
+    }
+    this->linesProcessed = this->shellBuffer->getLineCount();
+  }
+
+
+  /**
+   * displays the Shell
+   */
+  void Shell::draw() const
+  {
+    // transform for alignment.
+    // setting the Blending effects
+
+    this->backgroundMaterial.select();
+
+    glBegin(GL_TRIANGLE_STRIP);
+
+    glTexCoord2f(0, 0);
+    glVertex2f(this->getAbsCoor2D().x,   this->getAbsCoor2D().y  );
+
+    glTexCoord2f(1, 0);
+    glVertex2f(GraphicsEngine::getInstance()->getResolutionX() - this->getAbsCoor2D().x, this->getAbsCoor2D().y  );
+
+    glTexCoord2f(0, 1);
+    glVertex2f(this->getAbsCoor2D().x, this->getAbsCoor2D().y + this->shellHeight);
+
+    glTexCoord2f(1, 1);
+    glVertex2f(GraphicsEngine::getInstance()->getResolutionX() - this->getAbsCoor2D().x, this->getAbsCoor2D().y + this->shellHeight);
+
+    glEnd();
+  }
+
+  ///////////////////////
+  // HELPER FUNCTIONS  //
+  ///////////////////////
+
+  /**
+   * @brief calculates the position of a Buffer-Display Line
+   * @param lineNumber the lineNumber from the bottom to calculate the position from
+   * @returns the Position of the Line.
+   */
+  Vector2D Shell::calculateLinePosition(unsigned int lineNumber)
+  {
+    return Vector2D(5.0f, (float)(this->textSize + this->lineSpacing)*(float)((int)this->bufferDisplaySize - (int)lineNumber - (int)1));
+  }
+
+
+
+  /**
+   * @brief displays some nice output from the Shell
+   */
+  void Shell::debug() const
+  {
+    PRINT(3)("Debugging output to console (not this shell)\n");
+
+    //   if (this->pressedKey != SDLK_FIRST)
+    //     printf("%s::%f %f\n", SDLKToKeyname(this->pressedKey), this->delayed, this->repeatDelay);
+
+
+    this->shellBuffer->debug();
+  }
+}
Index: branches/heathaze/src/lib/shell/shell.h
===================================================================
--- branches/heathaze/src/lib/shell/shell.h	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell.h	(revision 9940)
@@ -0,0 +1,117 @@
+/*!
+ * @file shell.h
+ * Definition of a on-screen-shell
+ *
+ * @todo Buffer Display in different Colors for different debug mode.
+ * @todo choose color of the Font and the background.
+ */
+
+#ifndef _SHELL_H
+#define _SHELL_H
+
+#include "element_2d.h"
+#include "event_listener.h"
+
+#include "shell_input.h"
+#include "debug_buffer.h"
+#include "material.h"
+
+#define         SHELL_DEFAULT_FONT              "fonts/final_frontier.ttf"
+#define         SHELL_DEFAULT_TEXT_COLOR        0.0f, 1.0f, 0.0f, 1.0f
+#define         SHELL_DEFAULT_BACKGROUND_COLOR  0.0f, 0.0f, 0.0f, 1.0f
+
+// FORWARD DECLARATION
+class MultiLineText;
+class ShellInput;
+class Material;
+
+//! Namespace of the Shell of ORXONOX.
+namespace OrxShell
+{
+  //! A class that is able to redirect all output to a openGL-Shell, and that one can use to input some commands
+  /**
+   * the major idea is, that all the Output can be redirected to the Shell,
+   * and does not have to be displayed to the opening Shell, this is good,
+   * for developers using Windows, where all output is otherwise redirected
+   * to stdout.txt
+   *
+   * Furthermore the Shell should enable us, to input some simple commands
+   * Each Class can check itself in to the Shell, and listen for commands.
+   *
+   * more info:
+   * @see ShellCommand
+   * @see shell_command.h
+   * @see shell_buffer.h
+   * @see shell_input.h
+   * @see shell_completion.h
+   */
+  class Shell : public Element2D, public EventListener
+  {
+    ObjectListDeclaration(Shell);
+  public:
+    Shell();
+    virtual ~Shell();
+
+    void activate();
+    void deactivate();
+    /** @returns true if the Shell is active, false otherwise. */
+    inline bool isActive() const { return this->bActive; };
+
+    void setFont(const std::string& fontFile);
+    void setTextSize(unsigned int textSize, unsigned int lineSpacing = 1);
+    void setTextColor(float r, float g, float b, float a);
+    void setBackgroundColor(float r, float g, float b, float a);
+    void setBackgroundImage(const std::string& fileName);
+
+    // BUFFERS
+    void setBufferDisplaySize(unsigned int bufferDisplaySize);
+    void printToDisplayBuffer(const std::string& text);
+    void moveDisplayBuffer(int lineCount);
+
+    void flush();
+
+    void clear();
+
+    // EventListener
+    virtual void process(const Event &event);
+    // Element2D-functions
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+
+    void debug() const;
+
+  private:
+    void updateResolution(unsigned int width);
+    void repositionText();
+    void applyTextSettings(Text* text);
+    void applySettings();
+    // helpers //
+    Vector2D calculateLinePosition(unsigned int lineNumber);
+
+  private:
+    // GENERAL
+    DebugBuffer*                shellBuffer;            //!< The local ShellBuffer.
+
+    bool                        bActive;                //!< If the shell is active.
+    unsigned int                shellHeight;            //!< The hight of the Shell in Pixels.
+    unsigned int                lineSpacing;            //!< The Spacing between lines.
+    unsigned int                textSize;               //!< The size of the text.
+    float                       textColor[4];           //!< The text's color [r,g,b,a].
+    std::string                 fontFile;               //!< The file containing the font.
+    Material                    backgroundMaterial;     //!< A material for the background.
+
+    // HANDLING TEXT INPUT
+    ShellInput                  shellInput;             //!< The inputLine of the Shell.
+    // BUFFER
+    unsigned int                bufferDisplaySize;      //!< The Size of the Display-buffer, in lines (not in characters).
+    std::list<MultiLineText*>   bufferText;             //!< A list of stored bufferTexts for the display of the buffer.
+
+    unsigned long               linesProcessed;         //!< How many Lines have been processed.
+
+    std::list<std::string>::const_iterator  bufferIterator;         //!< used to move through and print the Buffer
+  };
+
+}
+
+#endif /* _SHELL_H */
Index: branches/heathaze/src/lib/shell/shell_command.cc
===================================================================
--- branches/heathaze/src/lib/shell/shell_command.cc	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell_command.cc	(revision 9940)
@@ -0,0 +1,482 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
+
+#include "shell_command.h"
+#include "shell_command_class.h"
+
+#include "shell_input.h"
+#include "shell.h"
+
+#include "compiler.h"
+#include "helper_functions.h"
+#include "debug.h"
+
+#include "key_names.h"
+
+namespace OrxShell
+{
+  ObjectListDefinition(ShellCommand);
+
+  SHELL_COMMAND(debug, ShellCommandClass, help);
+
+  SHELL_COMMAND(help, ShellInput, help)
+  ->describe("retrieve some help about the input mode")
+  ->setAlias("help");
+
+  SHELL_COMMAND(clear, Shell, clear)
+  ->describe("Clears the shell from unwanted lines (empties all buffers)")
+  ->setAlias("clear");
+  SHELL_COMMAND(deactivate, Shell, deactivate)
+  ->describe("Deactivates the Shell. (moves it into background)")
+  ->setAlias("hide");
+  SHELL_COMMAND(textsize, Shell, setTextSize)
+  ->describe("Sets the size of the Text size, linespacing")
+  ->defaultValues(15, 0);
+  SHELL_COMMAND(textcolor, Shell, setTextColor)
+  ->describe("Sets the Color of the Shells Text (red, green, blue, alpha)")
+  ->defaultValues(SHELL_DEFAULT_TEXT_COLOR);
+  SHELL_COMMAND(backgroundcolor, Shell, setBackgroundColor)
+  ->describe("Sets the Color of the Shells Background (red, green, blue, alpha)")
+  ->defaultValues(SHELL_DEFAULT_BACKGROUND_COLOR);
+  SHELL_COMMAND(backgroundimage, Shell, setBackgroundImage)
+  ->describe("sets the background image to load for the Shell")
+  ->completionPlugin(0, OrxShell::CompletorFileSystem());
+  SHELL_COMMAND(font, Shell, setFont)
+  ->describe("Sets the font of the Shell")
+  ->defaultValues(SHELL_DEFAULT_FONT)
+  ->completionPlugin(0, OrxShell::CompletorFileSystem(".ttf", "fonts/"));
+
+  /**
+   * @brief constructs and registers a new Command
+   * @param commandName the name of the Command
+   * @param className the name of the class to apply this command to
+   * @param paramCount the count of parameters this command takes
+   */
+  ShellCommand::ShellCommand(const std::string& commandName, const std::string& className, Executor<const SubString>* executor)
+  {
+    PRINTF(4)("create shellcommand '%s' for class '%s'\n", commandName.c_str(), className.c_str());
+    this->registerObject(this, ShellCommand::_objectList);
+    this->setName(commandName);
+
+    // copy the executor:
+    this->executor = executor;
+
+    for (unsigned int i = 0; i < this->executor->getParamCount(); i++)
+      this->completors.push_back(new CompletorDefault(&this->executor->getDefaultValue(i)));
+    this->alias = NULL;
+
+    //  this->classID = classID;
+    this->shellClass = ShellCommandClass::acquireCommandClass(className);
+    assert (this->shellClass != NULL);
+    this->shellClass->registerCommand(this);
+  }
+
+  /**
+   * @brief deconstructs a ShellCommand
+   */
+  ShellCommand::~ShellCommand()
+  {
+    this->shellClass->unregisterCommand(this);
+    if (this->alias != NULL)
+      delete this->alias;
+    while (!this->completors.empty())
+    {
+      delete this->completors.back();
+      this->completors.pop_back();
+    }
+    delete this->executor;
+  }
+
+  /**
+   * @brief registers a new ShellCommand
+   */
+  ShellCommand* ShellCommand::registerCommand(const std::string& commandName, const std::string& className, Executor<const SubString>* executor)
+  {
+    if (ShellCommand::exists(commandName, className))
+    {
+      delete executor;
+      return NULL;
+    }
+    else
+      return new ShellCommand(commandName, className, executor);
+
+  }
+
+  /**
+   * @brief unregister an existing commandName
+   * @param className the name of the Class the command belongs to.
+   * @param commandName the name of the command itself
+   */
+  void ShellCommand::unregisterCommand(const std::string& commandName, const std::string& className)
+  {
+    ShellCommandClass* cmdClass = ShellCommandClass::acquireCommandClass(className);
+    if (cmdClass != NULL)
+    {
+      CmdList::iterator cmd;
+      for (cmd = cmdClass->_commandList.begin(); cmd != cmdClass->_commandList.end(); cmd++)
+        if (commandName == (*cmd)->getName())
+        {
+          delete (*cmd);
+          break;
+        }
+    }
+  }
+
+  /**
+   * @brief gets a command if it has already been registered.
+   * @param commandName the name of the Command
+   * @param cmdClass the CommandClass of the Class the command is in.
+   * @returns The Registered Command, or NULL if it does not exist.
+   */
+  const ShellCommand* const ShellCommand::getCommand(const std::string& commandName, const ShellCommandClass* cmdClass)
+  {
+    assert(cmdClass != NULL);
+
+    CmdList::const_iterator elem;
+    for (unsigned int i = 0; i < cmdClass->_commandList.size(); i++)
+    {
+      if (commandName == cmdClass->_commandList[i]->getName())
+        return (cmdClass->_commandList[i]);
+    }
+    return NULL;
+  }
+
+
+  /**
+   * @brief gets a command if it has already been registered.
+   * @param commandName the name of the Command
+   * @param className the name of the Class the command is in.
+   * @returns The Registered Command, or NULL if it does not exist.
+   */
+  const ShellCommand* const ShellCommand::getCommand(const std::string& commandName, const std::string& className)
+  {
+    const ShellCommandClass* checkClass = ShellCommandClass::getCommandClass(className);
+    if (likely(checkClass != NULL))
+      return ShellCommand::getCommand(commandName, checkClass);
+    else
+      return NULL;
+  }
+
+  /**
+   * @brief takes out an InputLine, searching for a Command.
+   * @see const ShellCommand* const ShellCommand::getCommandFromInput(const SubString& strings)
+   * @param inputLine: the Input to analyse.
+   * @param paramBegin: The begin of the Splitted SubStrings entry of the Parameters section.
+   * @returns: The ShellCommand if found.
+   */
+  const ShellCommand* const ShellCommand::getCommandFromInput(const std::string& inputLine, unsigned int& paramBegin, std::vector<BaseObject*>* boList)
+  {
+    return ShellCommand::getCommandFromInput(SubString(inputLine, SubString::WhiteSpaces), paramBegin, boList);
+  }
+
+  /**
+   * @brief takes out an InputLine, searching for a Command.
+   * @param strings: the Input to analyse.
+   * @param paramBegin: The begin of the Splitted SubStrings entry of the Parameters section.
+   * @returns: The ShellCommand if found.
+   */
+  const ShellCommand* const ShellCommand::getCommandFromInput(const SubString& strings, unsigned int& paramBegin, std::vector<BaseObject*>* boList)
+  {
+    // no input, no Command.
+    if (strings.size() == 0)
+    {
+      paramBegin = 0;
+      return NULL;
+    }
+
+    // CHECK FOR ALIAS
+    std::vector<ShellCommandAlias*>::const_iterator alias;
+    for (alias = ShellCommandAlias::getAliases().begin(); alias != ShellCommandAlias::getAliases().end(); alias++ )
+    {
+      if (strings[0] == (*alias)->getName())
+      {
+        assert ((*alias)->getCommand() != NULL && (*alias)->getCommand()->shellClass != NULL);
+        // Search for Objects.
+        if (strings.size() == 1)
+        {
+          if (fillObjectList("", (*alias)->getCommand(), boList))
+            ;
+        }
+        else
+        {
+          if (!fillObjectList(strings[1], (*alias)->getCommand(), boList))
+            fillObjectList("", (*alias)->getCommand(), boList);
+        }
+        paramBegin = 1;
+        return (*alias)->getCommand();
+      }
+    }
+
+    // CHECK FOR COMMAND_CLASS
+    const ShellCommandClass* cmdClass = ShellCommandClass::getCommandClass(strings[0]);
+    if (cmdClass != NULL)
+    {
+      const ShellCommand* retCmd = NULL;
+      // Function/Command right after Class
+      if (strings.size() >= 1)
+      {
+        // Search for Objects.
+        retCmd = ShellCommand::getCommand((strings.size() > 1) ? strings[1] : "", cmdClass);
+        if (retCmd != NULL)
+        {
+          paramBegin = 2;
+          fillObjectList("", retCmd, boList);
+          return retCmd;
+        }
+      }
+      // Function/Command after Class and 'Object'
+      if (retCmd == NULL && strings.size() >= 2)
+      {
+        retCmd = ShellCommand::getCommand((strings.size() > 2) ? strings[2] : "", cmdClass);
+        if (retCmd != NULL)
+        {
+          paramBegin = 3;
+          fillObjectList(strings[1], retCmd, boList);
+          return retCmd;
+        }
+      }
+      if (retCmd != NULL) // check for the paramBegin.
+        return retCmd;
+    }
+    // Nothing usefull found at all.
+    paramBegin = 0;
+    return NULL;
+  }
+
+  /**
+   * @brief fills the ObjectList boList with Objects that can be reffered to by cmd.
+   * @param objectDescriptor: the ObjectName (beginning, full name or empty) to fill the List with
+   * @param cmd: The Command to complete Objects for.
+   * @param boList: The List of BaseObject's that will be filled with found entries.
+   * @returns: true if more than one Entry was fond, else (false , or if boList is NULL).
+   */
+  bool ShellCommand::fillObjectList(const std::string& objectDescriptor, const ShellCommand* cmd, std::vector<BaseObject*>* boList)
+  {
+    assert (cmd != NULL && cmd->shellClass != NULL);
+    if(boList == NULL)
+      return false;
+
+    const ObjectListBase* const objectList = ObjectListBase::getObjectList(cmd->shellClass->getName());
+    if (objectList != NULL)
+    {
+      ObjectListBase::base_list list;
+      objectList->getBaseObjectList(&list);
+      ObjectListBase::base_iterator it;
+
+      // No Description given (only for speedup)
+      if (objectDescriptor.empty())
+      {
+        for (it = list.begin(); it != list.end(); it++)
+          boList->push_back(*it);
+      }
+      // some description
+      else
+      {
+        for (it = list.begin(); it != list.end(); it++)
+          if (!nocaseCmp(objectDescriptor, (*it)->getName(), objectDescriptor.size()))
+            boList->push_back(*it);
+      }
+    }
+    return !boList->empty();
+  }
+
+  /**
+   * @brief checks if a command has already been registered.
+   * @param commandName the name of the Command
+   * @param className the name of the Class the command should apply to.
+   * @returns true, if the command is registered/false otherwise
+   *
+   * This is used internally, to see, if we have multiple command subscriptions.
+   * This is checked in the registerCommand-function.
+   */
+  bool ShellCommand::exists(const std::string& commandName, const std::string& className)
+  {
+    return (ShellCommand::getCommand(commandName, className) != NULL);
+  }
+
+
+  /**
+   * @brief executes commands
+   * @param executionString the string containing the following input
+   * ClassName [ObjectName] functionName [parameter1[,parameter2[,...]]]
+   * @return true on success, false otherwise.
+   */
+  bool ShellCommand::execute(const std::string& executionString)
+  {
+    SubString inputSplits(executionString, SubString::WhiteSpacesWithComma);
+
+    // if we do not have any input return
+    if (inputSplits.empty())
+      return false;
+
+    unsigned int paramBegin;
+    const ShellCommand* sc = NULL;
+    std::vector<BaseObject*> boList;
+    sc = getCommandFromInput(inputSplits, paramBegin, &boList);
+    if (sc != NULL)
+    {
+
+      if(sc->executor->getType() == Executor<const SubString>::FunctionStatic )
+      {
+	PRINT(0)("Static Command '%s' of Class '%s' with parameters\n", sc->getCName(), sc->shellClass->getCName());
+	(*sc->executor)(NULL, inputSplits.subSet(paramBegin));
+      }
+      else
+        for(std::vector<BaseObject*>::const_iterator bo = boList.begin(); bo != boList.end(); ++bo)
+        {
+          PRINT(0)("Command '%s' on '%s::%s'\n", sc->getCName(), (*bo)->getClassCName(), (*bo)->getCName());
+          (*sc->executor)((*bo), inputSplits.subSet(paramBegin));
+        }
+      return true;
+    }
+    return false;
+  }
+
+
+  /**
+   * @brief lets a command be described
+   * @param description the description of the Given command
+   */
+  ShellCommand* ShellCommand::describe(const std::string& description)
+  {
+    if (this == NULL)
+      return NULL;
+    this->description = description;
+    return this;
+  }
+
+  /**
+   * @brief adds an Alias to this Command
+   * @param alias the name of the Alias to set
+   * @returns itself
+   */
+  ShellCommand* ShellCommand::setAlias(const std::string& alias)
+  {
+    if (this == NULL)
+      return NULL;
+
+    if (this->alias != NULL)
+    {
+      PRINTF(2)("not more than one Alias allowed for functions (%s::%s)\n", this->getCName(), this->shellClass->getCName());
+    }
+    else
+    {
+      ShellCommandAlias* aliasCMD = new ShellCommandAlias(alias, this);
+      this->alias = aliasCMD;
+    }
+    return this;
+  }
+
+  /**
+   * @brief set the default values of the executor
+   * @param value0 the first default value
+   * @param value1 the second default value
+   * @param value2 the third default value
+   * @param value3 the fourth default value
+   * @param value4 the fifth default value
+   */
+  ShellCommand* ShellCommand::defaultValues(const MultiType& value0, const MultiType& value1,
+      const MultiType& value2, const MultiType& value3,
+      const MultiType& value4)
+  {
+    if (this == NULL || this->executor == NULL)
+      return NULL;
+
+    this->executor->defaultValues(value0, value1, value2, value3, value4);
+
+    return this;
+  }
+
+  ShellCommand* ShellCommand::completionPlugin(unsigned int parameter, const CompletorPlugin& completorPlugin)
+  {
+    if (this == NULL || this->executor == NULL)
+      return NULL;
+
+    if (parameter >= this->executor->getParamCount())
+    {
+      PRINTF(1)("Parameter %d not inside of valid ParameterCount %d of Command %s::%s\n",
+                parameter, this->executor->getParamCount(), this->getCName(), this->shellClass->getCName());
+    }
+    else
+    {
+      //       if(this->completors[parameter] == NULL)
+      //       delete this->completors[parameter];
+      //       this->completors[parameter] = completorPlugin.clone();
+    }
+    return this;
+  }
+
+  /**
+   * @brief prints a Help string from this Command
+   */
+  void ShellCommand::help() const
+  {
+    PRINT(0)("%s ", this->getCName());
+  }
+
+  /**
+   * @brief converts a Parameter to a String
+   * @param parameter the Parameter we have.
+   * @returns the Name of the Parameter at Hand
+   */
+  const std::string& ShellCommand::paramToString(long parameter)
+  {
+    return MultiType::MultiTypeToString((MT_Type)parameter);
+  }
+
+
+
+  ///////////
+  // ALIAS //
+  ///////////
+
+  /**
+   * @param aliasName the name of the Alias
+   * @param command the Command, to associate this alias with
+   */
+  ShellCommandAlias::ShellCommandAlias(const std::string& aliasName, ShellCommand* command)
+  {
+    this->aliasName = aliasName;
+    this->command = command;
+    ShellCommandAlias::aliasList.push_back(this);
+  };
+
+  ShellCommandAlias::~ShellCommandAlias()
+  {
+    std::vector<ShellCommandAlias*>::iterator delA = std::find(aliasList.begin(), aliasList.end(), this);
+    if (delA != aliasList.end())
+      ShellCommandAlias::aliasList.push_back(this);
+
+  }
+
+  std::vector<ShellCommandAlias*> ShellCommandAlias::aliasList;
+  /**
+  * @brief collects the Aliases registered to the ShellCommands
+  * @param stringList a List to paste the Aliases into.
+  * @returns true on success, false otherwise
+   */
+
+  bool ShellCommandAlias::getCommandListOfAlias(std::list<std::string>& stringList)
+  {
+    std::vector<ShellCommandAlias*>::iterator alias;
+    for (alias = ShellCommandAlias::aliasList.begin(); alias != ShellCommandAlias::aliasList.end(); alias++)
+      stringList.push_back((*alias)->getName());
+    return true;
+  }
+
+
+}
Index: branches/heathaze/src/lib/shell/shell_command.h
===================================================================
--- branches/heathaze/src/lib/shell/shell_command.h	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell_command.h	(revision 9940)
@@ -0,0 +1,132 @@
+/*!
+ * @file shell_command.h
+ * Definition of a on-screen-shell
+ */
+
+#ifndef _SHELL_COMMAND_H
+#define _SHELL_COMMAND_H
+
+#include "base_object.h"
+
+/// THIS IS USED TO LOAD CONSTANT AND STATIC FUNCTIONS EASILY.
+#include "executor/executor_substring.h"
+#include "executor/functor_member.h"
+#include "executor/functor_const_member.h"
+#include "executor/functor_static.h"
+
+#include "shell_completion_plugin.h"
+
+#define     SHELL_COMMAND_MAX_SIZE      //!< The maximum size of a Shell Command
+
+namespace OrxShell
+{
+  // FORWARD DECLARATION
+  class ShellCommandClass;
+  class ShellCommandAlias;
+  class CompletorPlugin;
+
+  /**
+   * @brief an easy to use Macro to create a Command
+   * @param command the name of the command (without "" around the string)
+   * @param class the name of the class to apply this command to (without the "" around the string)
+   * @param function the function to call
+   *
+   * MEANING:
+   *  ShellCommand* someUniqueVarName =
+   *       ShellCommand<ClassName>::registerCommand("commandNameInShell", "ClassName", &ClassName::FunctionToCall);
+   *
+   * In the Shell you would call this Command using:
+   * $ ClassName [ObjectName] commandNameInShell [parameters]
+   */
+#define SHELL_COMMAND(command, class, function) \
+           OrxShell::ShellCommand* shell_command_##class##_##command = OrxShell::ShellCommand::registerCommand(#command, #class, createExecutor<class, BaseObject>(&class::function))
+
+  /**
+   * @brief an easy to use Macro to create a Command
+   * @param command the name of the command (without "" around the string)
+   * @param class the name of the class to apply this command to (without the "" around the string)
+   * @param function the function to call
+   *
+   * MEANING:
+   *  ShellCommand* someUniqueVarName =
+   *       ShellCommand<ClassName>::registerCommand("commandNameInShell", "ClassName", &ClassName::FunctionToCall);
+   *
+   * In the Shell you would call this Command using:
+   * $ ClassName [ObjectName] commandNameInShell [parameters]
+   */
+#define SHELL_COMMAND_STATIC(command, class, function) \
+           OrxShell::ShellCommand* shell_command_##class##_##command = OrxShell::ShellCommand::registerCommand(#command, #class, createExecutor<class, BaseObject>(function))
+
+
+
+  //! a baseClass for all possible ShellCommands
+  class ShellCommand : public BaseObject
+  {
+    ObjectListDeclaration(ShellCommand);
+
+    friend class ShellCommandClass;
+  public:
+    static bool execute (const std::string& executionString);
+
+    ShellCommand* describe(const std::string& description);
+    ShellCommand* setAlias(const std::string& alias);
+    ShellCommand* defaultValues(const MultiType& value0 = MT_NULL, const MultiType& value1 = MT_NULL,
+                                const MultiType& value2 = MT_NULL, const MultiType& value3 = MT_NULL,
+                                const MultiType& value4 = MT_NULL);
+    ShellCommand* completionPlugin(unsigned int parameter, const CompletorPlugin& completorPlugin);
+
+    static ShellCommand* registerCommand(const std::string& commandName, const std::string& className, Executor<const SubString>* executor);
+    static void unregisterCommand(const std::string& commandName, const std::string& className);
+    static const ShellCommand* const getCommand(const std::string& commandName, const std::string& className);
+    static const ShellCommand* const getCommand(const std::string& commandName, const ShellCommandClass* cmdClass);
+    static bool exists(const std::string& commandName, const std::string& className);
+    static const ShellCommand* const getCommandFromInput(const std::string& inputLine, unsigned int& paramBegin, std::vector<BaseObject*>* boList = NULL);
+    static const ShellCommand* const getCommandFromInput(const SubString& strings, unsigned int& paramBegin, std::vector<BaseObject*>* boList = NULL);
+
+    const ShellCommandClass* const getCommandClass() const { return this->shellClass; };
+    const ShellCommandAlias* const getAlias() const { return this->alias; }
+    unsigned int getParamCount() const { return this->executor->getParamCount(); }
+    const CompletorPlugin* const getCompletorPlugin(unsigned int i) const { return this->completors[i]; };
+
+    void help() const;
+
+  protected:
+    ShellCommand(const std::string& commandName, const std::string& className, Executor<const SubString>* executor);
+    virtual ~ShellCommand();
+
+    static bool fillObjectList(const std::string& objectDescriptor, const ShellCommand* cmd, std::vector<BaseObject*>* boList);
+    static const std::string& paramToString(long parameter);
+
+  private:
+    ShellCommandClass*               shellClass;            //!< A Pointer to the Shell-Class this Command belongs to.
+    ShellCommandAlias*               alias;                 //!< An Alias for the Class.
+
+    std::string                      description;           //!< A description for this commnand. (initially ""). Assigned with (create)->describe("blablabla");
+    std::vector<CompletorPlugin*>    completors;            //!< Completors for the Parameters
+    Executor<const SubString>*       executor;              //!< The Executor, that really executes the Function.
+  };
+
+  //! A Class, that handles aliases.
+  class ShellCommandAlias
+  {
+  public:
+    ShellCommandAlias(const std::string& aliasName, ShellCommand* command);
+    ~ShellCommandAlias();
+
+    /** @returns the Name of the Alias. */
+    const std::string& getName() const { return this->aliasName; };
+    /** @returns the Command, this Alias is asociated with */
+    ShellCommand* getCommand() const { return this->command; };
+    static bool getCommandListOfAlias(std::list<std::string>& stringList);
+    static const std::vector<ShellCommandAlias*>& getAliases() { return ShellCommandAlias::aliasList; };
+
+  private:
+    std::string     aliasName;       //!< the name of the Alias
+    ShellCommand*   command;         //!< a pointer to the command, this alias executes.
+
+    static std::vector<ShellCommandAlias*> aliasList; //!< A list of Aliases to A Commands.
+  };
+
+}
+
+#endif /* _SHELL_COMMAND_H */
Index: branches/heathaze/src/lib/shell/shell_command_class.cc
===================================================================
--- branches/heathaze/src/lib/shell/shell_command_class.cc	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell_command_class.cc	(revision 9940)
@@ -0,0 +1,211 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
+
+#include "shell_command_class.h"
+
+#include "shell_command.h"
+
+#include "debug.h"
+#include "compiler.h"
+
+
+
+namespace OrxShell
+{
+  ObjectListDefinition(ShellCommandClass);
+
+  CmdClassList* ShellCommandClass::_commandClassList = NULL;
+
+  /**
+   * @brief creates a new ShellCommandClass
+   * @param className the Name of the command-class to create
+   */
+  ShellCommandClass::ShellCommandClass(const std::string& className)
+      : _className(className)
+  {
+    this->registerObject(this, ShellCommandClass::_objectList);
+    this->setName(className);
+
+    if (ShellCommandClass::_commandClassList == NULL)
+      ShellCommandClass::_commandClassList = new CmdClassList;
+    ShellCommandClass::_commandClassList->push_back(this);
+  }
+
+  /**
+   * destructs the shellCommandClass again
+   */
+  ShellCommandClass::~ShellCommandClass()
+  {
+    while(!this->_commandList.empty())
+      delete this->_commandList.back();
+
+    if (ShellCommandClass::_commandClassList != NULL)
+    {
+      CmdClassList::iterator delClass = std::find(ShellCommandClass::_commandClassList->begin(), ShellCommandClass::_commandClassList->end(), this);
+      if (delClass != ShellCommandClass::_commandClassList->end())
+        ShellCommandClass::_commandClassList->erase(delClass);
+    }
+  }
+
+  /**
+   * @param command the Command to register.
+   */
+  void ShellCommandClass::registerCommand(ShellCommand* command)
+  {
+    this->_commandList.push_back(command);
+  }
+
+  /**
+   * @brief Unregisters a command.
+   * @param command the Command to unregister.
+   */
+  void ShellCommandClass::unregisterCommand(ShellCommand* command)
+  {
+    CmdList::iterator delC = std::find(this->_commandList.begin(), this->_commandList.end(), command);
+    if (delC != this->_commandList.end())
+      this->_commandList.erase(delC);
+  }
+
+  /**
+   * @brief unregisters all Commands that exist
+   */
+  void ShellCommandClass::unregisterAllCommands()
+  {
+    // unregister all commands and Classes
+    CmdClassList::iterator classIT;
+    if (ShellCommandClass::_commandClassList == NULL)
+      return;
+
+    while (!ShellCommandClass::_commandClassList->empty())
+      delete ShellCommandClass::_commandClassList->back();
+    delete ShellCommandClass::_commandClassList;
+    ShellCommandClass::_commandClassList = NULL;
+  }
+
+
+  /**
+   * @brief collects the Commands registered to some class.
+   * @param className the name of the Class to collect the Commands from.
+   * @param stringList a List to paste the Commands into.
+   * @returns true on success, false otherwise
+   */
+  bool ShellCommandClass::getCommandListOfClass(const std::string& className, std::list<std::string>& stringList)
+  {
+    if (ShellCommandClass::_commandClassList == NULL)
+      return false;
+
+
+    CmdClassList::const_iterator elem;
+    for(elem = ShellCommandClass::_commandClassList->begin(); elem != ShellCommandClass::_commandClassList->end(); elem++)
+    {
+      if (className == (*elem)->getName())
+      {
+        CmdList::iterator command;
+        for(command = (*elem)->_commandList.begin(); command != (*elem)->_commandList.end(); command++)
+          stringList.push_back((*command)->getName());
+        return true;
+      }
+    }
+    return false;
+  }
+
+
+  /**
+   * @brief checks if a Class is already registered to the Commands' class-stack
+   * @param className the Name of the Class to check for
+   * @returns the CommandClass if found, NULL otherwise
+   */
+  ShellCommandClass* ShellCommandClass::getCommandClass(const std::string& className)
+  {
+    if (ShellCommandClass::_commandClassList == NULL)
+      return false;
+
+
+    CmdClassList::const_iterator classIT;
+    for (classIT = ShellCommandClass::_commandClassList->begin(); classIT != ShellCommandClass::_commandClassList->end(); classIT++)
+      if (className == (*classIT)->_className)
+        return (*classIT);
+    return NULL;
+  }
+
+  /**
+   * @brief checks if a Class is already registered to the Commands' class-stack
+   * @param className the Name of the Class to check for
+   * @returns the CommandClass if found, NULL otherwise
+   */
+  bool ShellCommandClass::exists(const std::string& className)
+  {
+    return (ShellCommandClass::getCommandClass(className) != NULL);
+  }
+
+
+  /**
+   * @brief searches for a CommandClass
+   * @param className the name of the CommandClass
+   * @returns the CommandClass if found, or a new CommandClass if not
+   */
+  ShellCommandClass* ShellCommandClass::acquireCommandClass(const std::string& className)
+  {
+    ShellCommandClass* cmdClass = ShellCommandClass::getCommandClass(className);
+    if (cmdClass != NULL)
+      return (cmdClass);
+    return new ShellCommandClass(className);
+  }
+
+  /**
+   * @brief displays help about ShellCommandClass
+   * @param className: the Class of Commands to show help about
+   */
+  void ShellCommandClass::help(const std::string& className)
+  {
+    if (ShellCommandClass::_commandClassList == NULL)
+    {
+      PRINT(0)("No Commands Registered\n");
+      return;
+    }
+    if (className.empty())
+      PRINT(0)("===== Displaying %d registered Classes:\n", ShellCommandClass::_commandClassList->size());
+
+
+    CmdClassList::iterator classIT;
+    for (classIT = ShellCommandClass::_commandClassList->begin(); classIT != ShellCommandClass::_commandClassList->end(); classIT++)
+    {
+      if (className.empty() || className == (*classIT)->_className)
+      {
+        PRINT(0)("Class:'%s' registered %d commands: \n", (*classIT)->_className.c_str(), (*classIT)->_commandList.size());
+        CmdList::const_iterator cmdIT;
+        for (cmdIT = (*classIT)->_commandList.begin(); cmdIT != (*classIT)->_commandList.end(); cmdIT++)
+        {
+          PRINT(0)("  command:'%s' : params:%d: ", (*cmdIT)->getCName(), (*cmdIT)->executor->getParamCount());
+          /// FIXME
+          /*          for (unsigned int i = 0; i< elem->paramCount; i++)
+            PRINT(0)("%s ", ShellCommand::paramToString(elem->parameters[i]));*/
+          if (!(*cmdIT)->description.empty())
+            PRINT(0)("- %s", (*cmdIT)->description.c_str());
+          PRINT(0)("\n");
+        }
+        if (likely(!className.empty()))
+          return;
+      }
+    }
+    PRINTF(3)("Class '%s' not found in Command's classes\n", className.c_str());
+  }
+}
+
+
+
+
Index: branches/heathaze/src/lib/shell/shell_command_class.h
===================================================================
--- branches/heathaze/src/lib/shell/shell_command_class.h	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell_command_class.h	(revision 9940)
@@ -0,0 +1,62 @@
+/*!
+ * @file shell_command_class.h
+ * Definition of a on-screen-shell
+ */
+
+#ifndef _SHELL_COMMAND_CLASS_H
+#define _SHELL_COMMAND_CLASS_H
+
+#include "base_object.h"
+#include <vector>
+#include <list>
+
+namespace OrxShell
+{
+  // FORWARD DECLARATION
+  class ShellCommand;
+  class ShellCommandAlias;
+  class ShellCommandClass;
+
+  typedef std::vector<ShellCommand*>      CmdList;
+  typedef std::vector<ShellCommandClass*> CmdClassList;
+
+
+  //! A class to hold all Classes that have (once) registered Commands.
+  class ShellCommandClass : public BaseObject
+  {
+    ObjectListDeclaration(ShellCommandClass);
+
+    friend class ShellCommand;
+  public:
+    /** @returns the CommandClassList */
+    static const CmdClassList& getCommandClassList() { return *ShellCommandClass::_commandClassList; };
+
+    static bool getCommandListOfClass(const std::string& className, std::list<std::string>& stringList);
+
+    static void unregisterAllCommands();
+    static ShellCommandClass* getCommandClass(const std::string& className);
+    ClassID getClassID();
+    static bool exists(const std::string& className);
+
+    static void help (const std::string& className = "");
+
+    static void debug();
+
+  private:
+    ShellCommandClass(const std::string& className);
+    static ShellCommandClass* acquireCommandClass(const std::string& className);
+    virtual ~ShellCommandClass();
+
+
+    void registerCommand(ShellCommand* command);
+    void unregisterCommand(ShellCommand* command);
+
+  private:
+    const std::string                      _className;                 //!< The Name of the Class. This should match the ClassName of the Commands Class.
+    CmdList                                _commandList;               //!< A list of Commands from this Class
+
+    static CmdClassList*                   _commandClassList;          //!< A list of Classes
+  };
+}
+
+#endif /* _SHELL_COMMAND_H */
Index: branches/heathaze/src/lib/shell/shell_completion.cc
===================================================================
--- branches/heathaze/src/lib/shell/shell_completion.cc	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell_completion.cc	(revision 9940)
@@ -0,0 +1,350 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
+
+#include "shell_completion.h"
+#include "shell_command_class.h"
+#include "shell_completion_plugin.h"
+
+#include "shell_command.h"
+
+#include "helper_functions.h"
+#include "debug.h"
+
+namespace OrxShell
+{
+
+  /**
+   * @brief standard constructor
+   */
+  ShellCompletion::ShellCompletion()
+  { }
+
+
+  /**
+   * @brief standard deconstructor
+   */
+  ShellCompletion::~ShellCompletion ()
+  { }
+
+
+
+  /**
+   * @brief autocompletes the Shell's inputLine
+   * @param input the input to complete, will most possibly be changed.
+   * @returns true, if a result was found, false otherwise
+   */
+  bool ShellCompletion::autoComplete(std::string& input)
+  {
+    ClassID classID;
+    const ObjectListBase* objectList = NULL;      //< the list of Objects stored in classID's ClassList
+    bool emptyComplete = false;                      //< if the completion input is empty string. e.g ""
+    long completeType = NullCompletion;              //< the Type we'd like to complete.
+    std::string completeString = "";                 //< the string to complete.
+    unsigned int completeParam = 0;                  //< The Parameter to finish.
+    const ShellCommand* command = NULL;              //< The Command.
+
+
+    PRINTF(5)("AutoComplete on input\n");
+    this->clearCompletionList();
+
+    // Check if we are in a input. eg. the supplied string "class " and now we complete either function or object
+    if (input.empty() || input[input.size()-1] == ' ')
+      emptyComplete = true;
+
+    // CREATE INPUTS
+    SubString inputSplits(input, SubString::WhiteSpacesWithComma);
+
+    // What String will be completed
+    if (!emptyComplete && inputSplits.size() >= 1)
+      completeString = inputSplits.getString(inputSplits.size()-1);
+
+    // CLASS/ALIAS COMPLETION (on first argument)
+    if (inputSplits.size() == 0 || (!emptyComplete && inputSplits.size() == 1))
+    {
+      completeType |= ClassCompletion;
+      completeType |= AliasCompletion;
+    }
+
+    // OBJECT/FUNCTION COMPLETIONS
+    else if ((emptyComplete && inputSplits.size() == 1) ||
+             (!emptyComplete && inputSplits.size() == 2))
+    {
+      objectList = ObjectListBase::getObjectList(inputSplits[0]);
+      if (objectList != NULL)
+        classID = objectList->identity();
+      if (classID != NullClass::staticClassID())
+        completeType |= ObjectCompletion;
+      completeType |= FunctionCompletion;
+    }
+    // Complete the last Function
+    else if ((emptyComplete && inputSplits.size() == 2 ) ||
+             (!emptyComplete && inputSplits.size() == 3))
+    {
+      if (ObjectListBase::getBaseObject(inputSplits[0], inputSplits[1]))
+        completeType |= FunctionCompletion;
+    }
+
+    // Looking for ParameterCompletions.
+    {
+      unsigned int parameterBegin;
+      if ((command = ShellCommand::getCommandFromInput(inputSplits, parameterBegin)) != NULL)
+      {
+        completeType |= ParamCompletion;
+        if (emptyComplete)
+          completeParam = inputSplits.size() - parameterBegin;
+        else
+          completeParam = inputSplits.size() - parameterBegin - 1;
+      }
+    }
+
+    if (completeType & ClassCompletion)
+      this->objectComplete(completeString, &ShellCommandClass::objectList());
+    if (completeType & ObjectCompletion)
+      this->objectComplete(completeString, objectList);
+    if (completeType & FunctionCompletion)
+      this->commandComplete(completeString, inputSplits[0]);
+    if (completeType & AliasCompletion)
+      this->aliasComplete(completeString);
+    if (completeType & ParamCompletion)
+      this->paramComplete(completeString, command, completeParam);
+
+    this->generalComplete(input, completeString);
+    return true;
+  }
+
+  /**
+   * @brief autocompletes an ObjectName
+   * @param objectBegin the beginning string of a Object
+   * @param classID the ID of the Class to search for.
+   * @return true on success, false otherwise
+   */
+  bool ShellCompletion::objectComplete(const std::string& objectBegin, const ObjectListBase* objectList)
+  {
+    assert (objectList != NULL);
+
+    CompletionType type = ObjectCompletion;
+    if (objectList == &ShellCommandClass::objectList())
+      type = ClassCompletion;
+
+    ObjectListBase::base_list list;
+    objectList->getBaseObjectList(&list);
+
+    if (!this->addToCompleteList(list, objectBegin, type))
+     return false;
+
+    return true;
+  }
+
+  /**
+   * @brief completes a Command
+   * @param commandBegin the beginning of the function String
+   * @param classID the class' ID to complete the function of
+   */
+  bool ShellCompletion::commandComplete(const std::string& commandBegin, const std::string& className)
+  {
+    std::list<std::string> fktList;
+    ShellCommandClass::getCommandListOfClass(className, fktList);
+    if (!this->addToCompleteList(fktList, commandBegin, FunctionCompletion))
+      return false;
+    return true;
+  }
+
+  /**
+   * @brief completes an Alias
+   * @param aliasBegin the beginning of the Alias-String to complete
+   * @returns true on succes, false if something went wrong
+   */
+  bool ShellCompletion::aliasComplete(const std::string& aliasBegin)
+  {
+    std::list<std::string> aliasList;
+    ShellCommandAlias::getCommandListOfAlias(aliasList);
+    if (!this->addToCompleteList(aliasList, aliasBegin, AliasCompletion))
+      return false;
+    return true;
+  }
+
+  /**
+   * @brief completes Parameters.
+   * @param paramBegin: Begin of the Parameters.
+   * @returns true on succes, false if something went wrong
+   */
+  bool ShellCompletion::paramComplete(const std::string& paramBegin, const ShellCommand* command, unsigned int paramNumber)
+  {
+    if (paramNumber >= command->getParamCount())
+    {
+      PRINT(0)("Last Parameter reached\n");
+      return false;
+    }
+    std::vector<std::string> completed;
+    command->getCompletorPlugin(paramNumber)->addToCompleteList(completed, paramBegin);
+    for (unsigned int i = 0; i < completed.size(); i++)
+      this->completionList.push_back(CompletionElement(completed[i], ParamCompletion));
+    return true;
+  }
+
+
+  /**
+   * @brief completes the inputline on grounds of an inputList
+   * @param input the Input to complete.
+   * @param begin the String to search in the inputList, and to extend with it.
+   * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::"
+   * @param addBack what should be added at the end of the completion
+   * @param addFront what should be added to the front of one finished completion
+   * @return true if ok, false otherwise
+   */
+  bool ShellCompletion::generalComplete(std::string& input,
+                                        const std::string& begin, const std::string& displayAs,
+                                        const std::string& addBack, const std::string& addFront)
+  {
+    if (completionList.size() == 0)
+      return false;
+
+    CompletionElement addElem = completionList.front();
+    const std::string& addString = addElem.name;
+    unsigned int addLength = addString.size();
+    unsigned int inputLenght = begin.size();
+
+    // Determin the longest Match (starting with the first candidate in full length).
+    CompletionType changeType = NullCompletion;
+    std::vector<CompletionElement>::iterator charIT;
+    for (charIT = completionList.begin(); charIT != completionList.end(); charIT++)
+    {
+      if ((*charIT).type != changeType)
+      {
+        if (changeType != NullCompletion)
+          PRINT(0)("\n");
+        PRINT(0)("%s: ", ShellCompletion::typeToString((*charIT).type).c_str());
+        changeType = (*charIT).type;
+      }
+      PRINTF(0)("%s ", (*charIT).name.c_str());
+      for (unsigned int i = inputLenght; i < addLength; i++)
+        if (addString[i] != (*charIT).name[i])
+          addLength = i;
+    }
+    PRINT(0)("\n");
+
+    if (addLength >= inputLenght)
+    {
+      std::string adder = addString;
+      adder.resize(addLength);
+
+      input.resize(input.size()-inputLenght);
+      input += adder;
+
+      if (completionList.size() == 1)
+      {
+        if ( addBack != "")
+          input += addBack;
+        input += ' ';
+      }
+    }
+    return true;
+  }
+
+  /**
+   * @brief searches for classes, which beginn with completionBegin
+   * @param inputList the List to parse through
+   * @param completionBegin the beginning string
+   * !! The strings MUST NOT be deleted !!
+   */
+  bool ShellCompletion::addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, CompletionType type)
+  {
+    unsigned int searchLength = completionBegin.size();
+
+    std::list<std::string>::const_iterator string;
+    for (string = inputList.begin(); string != inputList.end(); string++)
+    {
+      if ((*string).size() >= searchLength &&
+          !nocaseCmp(*string, completionBegin, searchLength))
+      {
+        this->completionList.push_back(CompletionElement (*string, type));
+      }
+    }
+    return true;
+  }
+
+  /**
+   * @brief searches for classes, which beginn with completionBegin
+   * @param inputList the List to parse through
+   * @param completionBegin the beginning string
+   * !! The strings MUST NOT be deleted !!
+   */
+  bool ShellCompletion::addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, CompletionType type)
+  {
+    unsigned int searchLength = completionBegin.size();
+
+    std::list<BaseObject*>::const_iterator bo;
+    for(bo = inputList.begin(); bo != inputList.end(); bo++)
+    {
+      if ((*bo)->getName().size() >= searchLength &&
+          !nocaseCmp((*bo)->getName(), completionBegin, searchLength))
+      {
+        // set all the spaces to "\\ "
+        std::string name = (*bo)->getName();
+        for(unsigned int i = 0; i < name.size(); i++)
+        {
+          if (name[i] == ' ')
+            name.replace(i++, 1, "\\ ");
+        }
+        this->completionList.push_back(CompletionElement(name, type));
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * @brief deletes the Completion List.
+   *
+   * This is done at the beginning of each completion-run
+   */
+  void ShellCompletion::clearCompletionList()
+  {
+    this->completionList.clear();
+  }
+
+  const std::string& ShellCompletion::typeToString(CompletionType type)
+  {
+    switch (type)
+    {
+      default:// SHELLC_NONE
+      return typeNames[0];
+      case  ClassCompletion:
+      return typeNames[1];
+      case ObjectCompletion:
+      return typeNames[2];
+      case FunctionCompletion:
+      return typeNames[3];
+      case AliasCompletion:
+      return typeNames[4];
+      case ParamCompletion:
+      return typeNames[5];
+    }
+  }
+
+
+  const std::string ShellCompletion::typeNames[] =
+    {
+      "error",
+      "class",
+      "object",
+      "function",
+      "alias",
+      "parameter",
+    };
+
+}
Index: branches/heathaze/src/lib/shell/shell_completion.h
===================================================================
--- branches/heathaze/src/lib/shell/shell_completion.h	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell_completion.h	(revision 9940)
@@ -0,0 +1,81 @@
+/*!
+ * @file shell_completion.h
+ * @brief The Shell Completion Tasks
+ *
+ * @todo if the second string is a Command, the third should not be completed!
+ * @todo also make some completion for registered (or special) Types
+*/
+
+#ifndef _SHELL_COMPLETION_H
+#define _SHELL_COMPLETION_H
+
+#include <vector>
+#include <list>
+#include <string>
+
+// FORWARD DECLARATION
+class BaseObject;
+class ObjectListBase;
+
+namespace OrxShell
+{
+  class ShellCommand;
+
+  //! A class for Completing the an InputString.
+  class ShellCompletion
+  {
+      //! an enumerator for different types the Shell can complete.
+      typedef enum {
+        NullCompletion         = 0,
+        ClassCompletion        = 1,
+        ObjectCompletion       = 2,
+        FunctionCompletion     = 4,
+        AliasCompletion        = 8,
+        ParamCompletion        = 16,
+    } CompletionType;
+
+      //! A struct for ShellElements (these are used as containers to identify an Input for what it is)
+      struct CompletionElement
+      {
+        CompletionElement(std::string name, CompletionType type) : name(name), type(type) {}
+        std::string     name;     //!< the Name of the Element to be completed.
+        CompletionType  type;     //!< the type of the Element
+      };
+
+    public:
+      ShellCompletion();
+      virtual ~ShellCompletion();
+
+
+      // Functions to produce the Complete Lists.
+      bool autoComplete(std::string& input);
+
+      static const std::string& typeToString(ShellCompletion::CompletionType type);
+
+    private:
+      bool objectComplete(const std::string& objectBegin, const ObjectListBase* const objectList);
+      bool commandComplete(const std::string& commandBegin, const std::string& className);
+      bool aliasComplete(const std::string& aliasBegin);
+      bool paramComplete(const std::string& paramBegin, const ShellCommand* command, unsigned int paramNumber);
+
+      // Generally Completes.
+      bool generalComplete(std::string& input,
+                           const std::string& begin, const std::string& displayAs = "%s",
+                           const std::string& addBack = "", const std::string& addFront = "");
+
+
+      bool addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, ShellCompletion::CompletionType type);
+      bool addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, ShellCompletion::CompletionType type);
+
+      // Helpers.
+      void clearCompletionList();
+
+    private:
+      std::vector<CompletionElement>  completionList;          //!< A list of completions, that are io.
+
+      static const std::string        typeNames[];             //!< A list of Completion-Type-Names.
+  };
+
+}
+
+#endif /* _SHELL_COMPLETION_H */
Index: branches/heathaze/src/lib/shell/shell_completion_plugin.cc
===================================================================
--- branches/heathaze/src/lib/shell/shell_completion_plugin.cc	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell_completion_plugin.cc	(revision 9940)
@@ -0,0 +1,163 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
+
+#include "shell_completion_plugin.h"
+#include "shell_command_class.h"
+
+#include "shell_command.h"
+
+#include "helper_functions.h"
+#include "loading/resource_manager.h"
+
+#include "filesys/directory.h"
+#include "debug.h"
+
+namespace OrxShell
+{
+  CompletorDefault::CompletorDefault(const MultiType* value)
+      :_value(value)
+  { }
+
+  void CompletorDefault::addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) const
+  {
+    PRINT(0)("Requires '%s'\n", MultiType::MultiTypeToString(this->_value->getType()).c_str());
+  }
+
+  CompletorPlugin* CompletorDefault::clone() const
+  {
+    return new CompletorDefault(this->_value);
+  }
+
+
+
+
+
+  void CompletorStringArray::addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) const
+  {
+    printf("TEST\n");
+    unsigned int inputLen = completionBegin.size();
+    for (unsigned int i = 0; i < this->_size; ++i)
+    {
+      printf("%s\n", this->_stringArray[i].c_str());
+      if (!nocaseCmp(this->_stringArray[i], completionBegin, inputLen))
+        completionList.push_back(this->_stringArray[i]);
+    }
+  }
+
+  CompletorPlugin* CompletorStringArray::clone() const
+  {
+    return new CompletorStringArray(this->_stringArray, this->_size);
+  }
+
+
+  CompletorList::CompletorList(const std::list<std::string>* list)
+  {
+    this->_list = list;
+  }
+
+  void CompletorList::addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) const
+  {
+    unsigned int inputLen = completionBegin.size();
+    std::list<std::string>::const_iterator it;
+    for (it = this->_list->begin(); it != this->_list->end(); ++it)
+      if (!nocaseCmp((*it), completionBegin, inputLen))
+        completionList.push_back(*it);
+  }
+
+  CompletorPlugin* CompletorList::clone() const
+  {
+    return new CompletorList(this->_list);
+  }
+
+
+  CompletorFileSystem::CompletorFileSystem(const std::string& fileExtension,
+      const std::string& subDir)
+      : _fileExtension(fileExtension), _subDir(subDir)
+  {  }
+
+
+  void CompletorFileSystem::addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) const
+  {
+    Directory dir;
+
+    if (completionBegin.empty()) // if we do not yet have the beginning of the line, start with the chosen startDir.
+    {
+      dir.setFileName(Resources::ResourceManager::getInstance()->mainGlobalPath().name() + this->_subDir);
+      dir.open();
+      for(unsigned int i = 0; i < dir.fileCount(); i++ )
+      {
+        completionList.push_back(this->_subDir + "/" + dir[i]);
+      }
+    }
+    else
+    {
+      bool grabbedDir = false;
+      std::string directoryName;
+      std::string::size_type pos = completionBegin.find_last_of("/");
+      if (pos != std::string::npos)
+        directoryName = completionBegin.substr(0, pos);
+
+      dir.setFileName(Resources::ResourceManager::getInstance()->mainGlobalPath().name() + directoryName);
+      dir.open();
+
+      std::string fileName;
+      std::string currFile;
+      for(unsigned int i = 0; i < dir.fileCount(); i++)
+      {
+        currFile = dir[i];
+        if (currFile[0] == '.')
+         continue;
+
+        if (directoryName.empty())
+          fileName = currFile;
+        else
+          fileName = directoryName + '/' + currFile;
+
+        if (!nocaseCmp(completionBegin, fileName, completionBegin.size())  &&
+             (this->_fileExtension.empty() || fileName.find(this->_fileExtension) != std::string::npos))
+        {
+          printf ("File %s\n", fileName.c_str());
+          completionList.push_back(fileName);
+          continue;
+        }
+	printf("%s\n", (Resources::ResourceManager::getInstance()->mainGlobalPath().name() + fileName).c_str());
+        if (!nocaseCmp(completionBegin, fileName, completionBegin.size()) &&
+	     Resources::ResourceManager::getInstance()->checkFileInMainPath(fileName))
+        {
+          printf("Dir %s\n", fileName.c_str());
+          grabbedDir = true;
+          completionList.push_back(fileName + "/");
+        }
+      }
+
+      if (completionList.size() == 1 && grabbedDir)
+      {
+        std::string dir = completionList[0];
+        completionList.clear();
+        this->addToCompleteList(completionList, dir);
+      }
+    }
+  }
+
+  CompletorPlugin* CompletorFileSystem::clone() const
+  {
+    return new CompletorFileSystem(this->_fileExtension, this->_subDir);
+  }
+
+
+}
+
Index: branches/heathaze/src/lib/shell/shell_completion_plugin.h
===================================================================
--- branches/heathaze/src/lib/shell/shell_completion_plugin.h	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell_completion_plugin.h	(revision 9940)
@@ -0,0 +1,96 @@
+/*!
+ * @file shell_completion_plugin.h
+ * @brief The Shell Completion Plugin
+ */
+
+#ifndef _SHELL_COMPLETION_PLUGIN_H
+#define _SHELL_COMPLETION_PLUGIN_H
+
+#include <list>
+#include <vector>
+#include <string>
+#include "multi_type.h"
+
+namespace OrxShell
+{
+  //! The Base of All Completors
+  class CompletorPlugin
+  {
+    public:
+      virtual void addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) const = 0;
+      virtual ~CompletorPlugin() { };
+
+      virtual CompletorPlugin* clone() const = 0;
+    protected:
+      CompletorPlugin() {};
+  };
+
+  class CompletorDefault : public CompletorPlugin
+  {
+    public:
+      CompletorDefault(const MultiType* value);
+      virtual void addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) const;
+
+      virtual CompletorPlugin* clone() const;
+    private:
+      const MultiType*    _value;
+  };
+
+
+  //! Completor that completes static Arrays of Strings.
+  class CompletorStringArray : public CompletorPlugin
+  {
+    public:
+      CompletorStringArray(const std::string* stringArray, unsigned int size)
+          : _stringArray(stringArray), _size(size) {};
+      virtual void addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) const;
+
+      virtual CompletorPlugin* clone() const;
+    private:
+      const std::string*   _stringArray;
+      unsigned int         _size;
+  };
+
+
+  class CompletorList : public CompletorPlugin
+  {
+    public:
+      CompletorList(const std::list<std::string>* list);
+      virtual void addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) const;
+      virtual CompletorPlugin* clone() const;
+
+    private:
+      const std::list<std::string>* _list;
+  };
+
+
+
+  //! Completor that completes FileSystem Entries.
+  class CompletorFileSystem : public CompletorPlugin
+  {
+    public:
+      CompletorFileSystem(const std::string& fileExtension = "",
+                          const std::string& subDir = "");
+      virtual void addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) const;
+      virtual CompletorPlugin* clone() const;
+
+    private:
+      std::string             _fileExtension;
+      std::string             _subDir;
+  };
+
+
+
+
+  //! A Templated Completor
+  template<typename CLASS> class CompletorTList : public CompletorPlugin
+  {
+    public:
+      CompletorTList(const std::list<CLASS*>& completionList);
+      virtual void addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin)
+      {};
+      virtual CompletorPlugin* clone() const;
+  };
+
+}
+#endif /* _SHELL_COMPLETION_PLUGIN_H */
Index: branches/heathaze/src/lib/shell/shell_input.cc
===================================================================
--- branches/heathaze/src/lib/shell/shell_input.cc	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell_input.cc	(revision 9940)
@@ -0,0 +1,395 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
+
+#include "shell_input.h"
+
+#include "shell_command.h"
+#include "shell_command_class.h"
+
+#include "debug.h"
+#include "compiler.h"
+#include "key_names.h"
+
+
+namespace OrxShell
+{
+  ObjectListDefinition(ShellInput);
+
+  /**
+   * @brief constructor
+   * this also generates a ShellCompletion automatically.
+  */
+  ShellInput::ShellInput ()
+      : Text ("")
+  {
+    this->registerObject(this, ShellInput::_objectList);
+
+    this->pressedKey = SDLK_FIRST;
+
+    this->historyIT = ShellInput::history.begin();
+    this->setHistoryLength(50);
+    this->historyScrolling = false;
+    this->delayed = 0;
+    this->setRepeatDelay(.3, .05);
+
+    // subscribe all keyboard commands to ES_SHELL
+    for (int i = 1; i < SDLK_LAST; i++)
+    {
+      //if (!this->isEventSubscribed(ES_SHELL, i))
+      this->subscribeEvent(ES_SHELL, i);
+    }
+    // unsubscribe unused TODO improve.
+    this->unsubscribeEvent(ES_SHELL, SDLK_BACKQUOTE);
+    this->unsubscribeEvent(ES_SHELL, SDLK_F12);
+    this->unsubscribeEvent(ES_SHELL, SDLK_PAGEUP);
+    this->unsubscribeEvent(ES_SHELL, SDLK_PAGEDOWN);
+  }
+
+  std::list<std::string> ShellInput::history;
+
+  /**
+   * @brief standard deconstructor
+   */
+  ShellInput::~ShellInput ()
+  {}
+
+  /**
+   * @brief sets the Repeate-delay and rate
+   * @param repeatDelay the Delay it takes, to repeate a key
+   * @param repeatRate the rate to repeate a pressed key
+   */
+  void ShellInput::setRepeatDelay(float repeatDelay, float repeatRate)
+  {
+    this->repeatDelay = repeatDelay;
+    this->repeatRate = repeatRate;
+  }
+
+  /**
+   * @brief deletes the InputLine
+   */
+  void ShellInput::flush()
+  {
+    this->inputLineBegin.clear();
+    this->inputLineEnd.clear();
+    this->clear();
+  }
+
+  /**
+   * @brief sets the entire text of the InputLine to text
+   * @param text the new Text to set as InputLine
+   */
+  void ShellInput::setInputText(const std::string& text)
+  {
+    this->inputLineBegin = text;
+    this->inputLineEnd.clear();
+    this->setText(text);
+  }
+
+
+  /**
+   * @brief adds one character to the inputLine
+   * @param character the character to add to the inputLine
+   */
+  void ShellInput::addCharacter(char character)
+  {
+    if (this->historyScrolling)
+    {
+      this->history.pop_back();
+      this->historyScrolling = false;
+    }
+
+    this->inputLineBegin += character;
+    this->setText(this->inputLineBegin + this->inputLineEnd);
+  }
+
+  /**
+   * @brief adds multiple Characters to thr inputLine
+   * @param characters a \\0 terminated char-array to add to the InputLine
+   */
+  void ShellInput::addCharacters(const std::string& characters)
+  {
+    if (this->historyScrolling)
+    {
+      this->history.pop_back();
+      this->historyScrolling = false;
+    }
+
+    this->inputLineBegin += characters;
+    this->setText(this->inputLineBegin + this->inputLineEnd);
+  }
+
+  /**
+   * @brief removes characterCount characters from the InputLine
+   * @param characterCount the count of Characters to remove from the input Line
+   */
+  void ShellInput::removeCharacters(unsigned int characterCount)
+  {
+    if (this->historyScrolling)
+    {
+      this->history.pop_back();
+      this->historyScrolling = false;
+    }
+    if (this->inputLineBegin.size() < characterCount)
+      characterCount = this->inputLineBegin.size();
+
+    this->inputLineBegin.erase(this->inputLineBegin.size() - characterCount, this->inputLineBegin.size());
+    this->setText(this->inputLineBegin + this->inputLineEnd);
+  }
+
+  /**
+   * @brief executes the command stored in the inputLine
+   * @return true if the command was commited successfully, false otherwise
+   */
+  bool ShellInput::executeCommand()
+  {
+    if (this->getInput().empty())
+      return false;
+    DebugBuffer::addBufferLineStatic("Execute Command: %s\n", this->getInput().c_str());
+
+    ShellCommand::execute(this->getInput());
+
+    // removing the eventually added Entry (from scrolling) to the List
+    if (this->historyScrolling)
+    {
+      this->history.pop_back();
+      this->historyScrolling = false;
+    }
+
+    // adding the new Command to the History
+    if (history.empty() || history.back() != this->getInput())
+      this->history.push_back(this->getInput());
+    if (this->history.size() > this->historyLength)
+    {
+      this->history.pop_front();
+    }
+
+    this->flush();
+
+    return true;
+  }
+
+
+  /**
+   * @brief moves one entry up in the history.
+   */
+  void ShellInput::historyMoveUp()
+  {
+    if (!this->historyScrolling)
+    {
+      this->history.push_back(this->getInput());
+      this->historyScrolling = true;
+      this->historyIT = --this->history.end();
+    }
+
+    if(this->historyIT != this->history.begin())
+    {
+      std::string prevElem = *(--this->historyIT);
+      /*if (prevElem == NULL) /// TODO STD
+        return;
+      else */
+      {
+        this->flush();
+        this->setInputText(prevElem);
+      }
+    }
+  }
+
+  /**
+   * @brief moves one entry down in the history
+   */
+  void ShellInput::historyMoveDown()
+  {
+    if (!this->historyScrolling)
+      return;
+    if (!this->history.empty() && this->historyIT != --this->history.end())
+    {
+      std::string nextElem = *(++this->historyIT);
+      /*    if (nextElem == NULL) /// TODO FIX STD
+        return;
+      else */
+      {
+        this->flush();
+        this->setInputText(nextElem);
+      }
+    }
+  }
+
+  /**
+   * @brief moves the cursor chars Characters to the right.
+   * @param chars how much to move the cursor.
+   */
+  void ShellInput::moveCursor(int chars)
+  {
+    if (chars > 0)
+    {
+      PRINTF(5)("move cursor %d to the right\n", chars);
+      if (chars >= (int) this->inputLineEnd.size())
+        chars = inputLineEnd.size();
+      this->inputLineBegin += this->inputLineEnd.substr(0, chars);
+      this->inputLineEnd.erase(0, chars);
+    }
+    else if (chars < 0)
+    {
+      chars = -chars;
+      PRINTF(5)("move cursor %d to the left\n", chars);
+
+      if (chars >= (int) this->inputLineBegin.size())
+	chars = inputLineBegin.size();
+      this->inputLineEnd = this->inputLineBegin.substr(this->inputLineBegin.size() - chars) + this->inputLineEnd;
+      this->inputLineBegin.erase(this->inputLineBegin.size() - chars);
+    }
+  }
+
+
+  /**
+   * @brief prints out some nice help about the Shell
+   */
+  void ShellInput::help(const std::string& className, const std::string& functionName)
+  {
+    if (className.empty())
+    {
+      PRINT(0)("== Help for the most important Shell-commands\n");
+      PRINT(0)("  F1 - HELP; F2 - DEBUG; '`' - open/close shell\n");
+      PRINT(0)("  input order:\n");
+      PRINT(0)("   ClassName [objectName] function [parameter1, [parameter2 ...]]  or\n");
+      PRINT(0)("   Alias [parameter]\n");
+      PRINT(0)("- Also try 'help className' or pushing 'TAB'\n");
+    }
+    else if (!className.empty() && functionName.empty())
+    {
+      ShellCommandClass::help(className);
+      //PRINTF(1)("%s::%s\n", className, functionName);
+    }
+  }
+
+  /**
+   * @brief ticks the ShellInput
+   * @param dt the time passed since the last update
+   */
+  void ShellInput::tick(float dt)
+  {
+    if (this->delayed > 0.0)
+      this->delayed -= dt;
+    else if (this->pressedKey != SDLK_FIRST )
+    {
+      this->delayed = this->repeatRate;
+      switch (this->pressedKey )
+      {
+        case SDLK_BACKSPACE:
+        this->removeCharacters(1);
+        break;
+        case SDLK_UP:
+        this->historyMoveUp();
+        break;
+        case SDLK_DOWN:
+        this->historyMoveDown();
+        break;
+        default:
+        {
+          if (likely(pressedKey < 127))
+            this->addCharacter(this->pressedKey);
+        }
+      }
+    }
+  }
+
+  /**
+   * @brief listens for some event
+   * @param event the Event happened
+   */
+  void ShellInput::process(const Event &event)
+  {
+    if (event.bPressed)
+    {
+      PRINTF(5)("Shell received command %s\n", SDLKToKeyname(event.type).c_str());
+      if (event.type == SDLK_F1)
+        this->help();
+      else if (event.type == SDLK_F2)
+      {
+        ;//this->debug();
+      }
+      else if (event.type == SDLK_UP)
+      {
+        this->historyMoveUp();
+        this->pressedKey = event.type;
+        this->pressedEvent = event.type;
+      }
+      else if (event.type == SDLK_DOWN)
+      {
+        this->historyMoveDown();
+        this->pressedKey = event.type;
+        this->pressedEvent = event.type;
+      }
+      else if (event.type == SDLK_LEFT)
+      {
+        this->moveCursor(-1);
+        this->pressedKey = event.type;
+        this->pressedEvent = event.type;
+      }
+      else if (event.type == SDLK_RIGHT)
+      {
+        this->moveCursor(+1);
+        this->pressedKey = event.type;
+        this->pressedEvent = event.type;
+      }
+      else if (event.type == SDLK_TAB)
+      {
+        this->completion.autoComplete(this->inputLineBegin);
+        this->setText(this->getInput());
+      }
+      else if (event.type == SDLK_BACKSPACE)
+      {
+        this->delayed = this->repeatDelay;
+        this->pressedKey = SDLK_BACKSPACE;
+        this->pressedEvent = SDLK_BACKSPACE;
+        this->removeCharacters(1);
+      }
+      else if (event.type == SDLK_DELETE)
+      {
+	if (!this->inputLineEnd.empty())
+	{
+	  this->inputLineEnd.erase(0, 1);
+	  this->setText(this->getInput());
+	}
+      }
+      else if (event.type == SDLK_RETURN)
+      {
+        this->executeCommand();
+        this->pressedKey = event.type;
+        this->pressedEvent = event.type;
+      }
+      // any other keyboard key
+      else if (likely(event.type < 127))
+      {
+        this->addCharacter(event.x);
+        this->pressedKey = event.x;
+        this->pressedEvent = event.type;
+      }
+      this->delayed = this->repeatDelay;
+    }
+    else // if(!event.bPressed)
+    {
+      if (this->pressedEvent == event.type)
+      {
+        this->pressedEvent = 0;
+        this->pressedKey = 0;
+        this->delayed = 0.0;
+      }
+    }
+  }
+
+}
Index: branches/heathaze/src/lib/shell/shell_input.h
===================================================================
--- branches/heathaze/src/lib/shell/shell_input.h	(revision 9940)
+++ branches/heathaze/src/lib/shell/shell_input.h	(revision 9940)
@@ -0,0 +1,85 @@
+/*!
+ * @file shell_input.h
+ * @brief Shell Input is an InputLine for the Shell.
+ *
+ * @todo move around in the InputText with the cursor (SDLK_LEFT/SDLK_RIGHT)
+ * @todo blinking curson (can blink with the speed of the RepeatDelay)
+*/
+
+#ifndef _SHELL_INPUT_H
+#define _SHELL_INPUT_H
+
+#include "text.h"
+#include "event_listener.h"
+#include "shell_completion.h"
+
+#include <list>
+
+namespace OrxShell
+{
+  // FORWARD DECLARATION
+  class ShellCompletion;
+
+  //! An InputLine for the Shell
+  /**
+   * The ShellInput has the ability to catch and display user input.
+   * The ShellInput is auto-completed after the user presses [TAB]
+   * The ShellInput is executed (and sent back to the Application) on Pressing [ENTER]
+   * [UP] and [DOWN] move through the history of allready given commands.
+   */
+  class ShellInput : public Text,  public EventListener
+  {
+    ObjectListDeclaration(ShellInput);
+
+  public:
+    ShellInput();
+    virtual ~ShellInput();
+
+    /** @returns the inputLine */
+    std::string getInput() const { return this->inputLineBegin + this->inputLineEnd; };
+
+    // InputLine
+    void setInputText(const std::string& text);
+    void addCharacter(char character);
+    void addCharacters(const std::string& characters);
+    void removeCharacters(unsigned int characterCount = 1);
+    void flush();
+
+    void setRepeatDelay(float repeatDelay, float repeatRate);
+
+    bool executeCommand();
+
+    /** sets the count of the History's entries */
+    void setHistoryLength(unsigned int historyLength) { this->historyLength = historyLength; };
+    void historyMoveUp();
+    void historyMoveDown();
+
+    void moveCursor(int chars);
+
+    void help(const std::string& className = "", const std::string& function = "");
+
+    virtual void tick(float dt);
+    virtual void process(const Event &event);
+
+  private:
+    // HANDLING TEXT INPUT
+    ShellCompletion                   completion;       //!< The Completion Interface.
+
+    std::string                       inputLineBegin;   //!< The Line up to the cursor.
+    std::string                       inputLineEnd;     //!< The Line from the cursor on
+
+    float                             repeatRate;       //!< The Repeat-Delay.
+    float                             repeatDelay;      //!< The delay of the first Character of a given Character.
+    float                             delayed;          //!< how much of the delay is remaining.
+    Uint16                            pressedKey;       //!< the pressed key that will be repeated.
+    Uint16                            pressedEvent;     //!< The Event, that lead to the pressing of the Key.
+
+    static std::list<std::string>     history;          //!< The history of given commands.
+    std::list<std::string>::iterator  historyIT;        //!< The locator that tells us, where we are in the history.
+    unsigned int                      historyLength;    //!< The maximum length of the InputHistory.
+    bool                              historyScrolling; //!< true if we are scrolling through the history.
+  };
+
+}
+
+#endif /* _SHELL_INPUT_H */
Index: branches/heathaze/src/lib/shell/some_shell_commands.cc
===================================================================
--- branches/heathaze/src/lib/shell/some_shell_commands.cc	(revision 9940)
+++ branches/heathaze/src/lib/shell/some_shell_commands.cc	(revision 9940)
@@ -0,0 +1,73 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file some_shell_commands.cc
+ * @brief All the ShellCommands, that should not pollute the SourceCode.
+ *
+ * This File is here, so that we do not have to pollute the Library-files
+ * with unneccessary other modules.
+ * Like this
+ */
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "shell/shell_command.h"
+using namespace OrxShell;
+
+#include "network_game_rules.h"
+SHELL_COMMAND(say, NetworkGameRules, shellSay)->setAlias("say");
+
+#include "player_stats.h"
+SHELL_COMMAND(nick, PlayerStats, shellNick)->setAlias("nick");
+
+// #include "class_list.h"
+//   SHELL_COMMAND(debug, ClassList, ClassList::debugS)
+//       ->describe("Shows all registered classes, if param1: is a valid ClassName only values of this class are shown. param2: how much output")
+//       ->defaultValues(MT_NULL, 1);
+
+#include "p_node.h"
+SHELL_COMMAND(debugNode, PNode, debugNode);
+SHELL_COMMAND(setPosition, PNode, setAbsCoor);
+
+#include "render_2d.h"
+SHELL_COMMAND(toggleNodeVisibility, Render2D, toggleNodesVisibility);
+
+
+#include "material.h"
+SHELL_COMMAND(setDiffuseTexture, Material, setDiffuseMap)
+->defaultValues(MT_NULL, (int)GL_TEXTURE_2D)
+->completionPlugin(0, CompletorFileSystem());
+
+#include "loading/resource_manager.h"
+namespace Resources {
+  SHELL_COMMAND(debug, ResourceManager, debug);
+  SHELL_COMMAND(load, ResourceManager, loadFromLoadStringHACK);
+  SHELL_COMMAND(unload, ResourceManager, unloadAllBelowKeepLevelINT);
+}
+
+#include "loading/load_param_class_description.h"
+SHELL_COMMAND_STATIC(printAll, LoadParamClassDescription, &LoadParamClassDescription::printAll)
+->defaultValues(MT_NULL, true);
+SHELL_COMMAND_STATIC(capture, LoadParamClassDescription, &LoadParamClassDescription::captureDescriptions)
+    ->defaultValues(true);
+
+#include "loading/game_loader.h"
+SHELL_COMMAND(quit, GameLoader, stop)
+    ->describe("quits the game")
+    ->setAlias("orxoquit");
+
+#include "object_list.h"
+SHELL_COMMAND_STATIC(debugAll, ObjectListBase, &ObjectListBase::debugAll);
Index: branches/heathaze/src/lib/sound/Makefile.am
===================================================================
--- branches/heathaze/src/lib/sound/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/sound/Makefile.am	(revision 9940)
@@ -0,0 +1,18 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXsound.a
+
+libORXsound_a_SOURCES = sound_engine.cc \
+			sound_source.cc \
+			sound_buffer.cc \
+			sound_buffer_data.cc \
+			resource_sound_buffer.cc \
+                        ogg_player.cc
+
+noinst_HEADERS = sound_engine.h \
+		 sound_source.h \
+		 sound_buffer.h \
+		 sound_buffer_data.h \
+		 resource_sound_buffer.h \
+                 ogg_player.h
Index: branches/heathaze/src/lib/sound/ogg_player.cc
===================================================================
--- branches/heathaze/src/lib/sound/ogg_player.cc	(revision 9940)
+++ branches/heathaze/src/lib/sound/ogg_player.cc	(revision 9940)
@@ -0,0 +1,558 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+    Beware:
+   The Ogg-Player is a __Threaded__ Stream, this means, that invoking play()
+   creates a Thread, that loops through the Music-File. The Thread seems
+   to be safe, but it is not guarantied.
+
+   -------------------------------------------------------------------
+   A Simple Version of this can be found at http://www.devmaster.net
+   Thanks a lot for the nice work, and the easy portability to our Project.
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SOUND
+
+#include <iostream>
+
+#include "ogg_player.h"
+
+#include "sound_engine.h"
+
+#include "debug.h"
+#include "compiler.h"
+
+#include "helper_functions.h"
+#include "sdlincl.h"
+
+namespace OrxSound
+{
+  ObjectListDefinition(OggPlayer);
+  /**
+   * initializes an Ogg-player from a file
+   * @param fileName the file to load
+   */
+  OggPlayer::OggPlayer(const std::string& fileName)
+  {
+    this->registerObject(this, OggPlayer::_objectList);
+
+    this->state = OggPlayer::None;
+
+    this->source = 0;
+    this->buffers[0] = 0;
+    this->buffers[1] = 0;
+    this->musicThreadID = NULL;
+
+    if (!fileName.empty())
+    {
+      if (this->open(fileName))
+        this->setName(fileName);
+    }
+
+  }
+
+  /**
+   * @brief deletes the OggPlayer
+   */
+  OggPlayer::~OggPlayer()
+  {
+    this->release();
+  }
+
+  ///////////////
+  // INTERFACE //
+  ///////////////
+  /**
+   * @brief opens a file for playback
+   * @param fileName the file to open
+   */
+  bool OggPlayer::open(const std::string& fileName)
+  {
+    OrxThread::MutexLock musicLock(&this->musicMutex);
+    // release old Ogg-File (if loaded)
+    if (this->state & OggPlayer::FileOpened)
+      this->release();
+
+    // allocating Buffers
+    if (this->buffers[0] == 0)
+      alGenBuffers(2, this->buffers);
+    SoundEngine::checkError("Allocating Buffers", __LINE__);
+    if (this->buffers[0] != 0 && this->buffers[1] != 0)
+      state |= OggPlayer::BuffersAllocated;
+    else
+    {
+      PRINTF(2)("Unable to allocate al-Buffers\n");
+      this->release();
+      return false;
+    }
+    // allocating source
+    if (this->source == 0)
+      SoundEngine::getInstance()->popALSource(this->source);
+    if (this->source != 0)
+      state |= OggPlayer::SourceAllocated;
+    else
+    {
+      PRINTF(2)("No more Sources Availiable (maybe you should consider raising the source-count.)\n");
+      this->release();
+      return false;
+    }
+
+    // opening the FILE;
+    int result;
+    if(!(oggFile = fopen(fileName.c_str(), "rb")))
+    {
+      PRINTF(2)("Could not open Ogg file.");
+      this->release();
+      return false;
+    }
+    // reading the Stream.
+    if((result = ov_open(oggFile, &oggStream, NULL, 0)) < 0)
+    {
+      PRINTF(2)("Could not open Ogg stream. %s", getVorbisError(result));
+      fclose(oggFile);
+      this->release();
+      return false;
+    }
+    this->state |= OggPlayer::FileOpened;
+
+    // acquiring the vorbis-properties.
+    vorbisInfo = ov_info(&oggStream, -1);
+    vorbisComment = ov_comment(&oggStream, -1);
+    this->retrieveFileInfo(&oggStream);
+
+    if(vorbisInfo->channels == 1)
+      format = AL_FORMAT_MONO16;
+    else
+      format = AL_FORMAT_STEREO16;
+
+    // setting the Source Properties.
+    alSource3f(source, AL_POSITION,        0.0, 0.0, 0.0);
+    alSource3f(source, AL_VELOCITY,        0.0, 0.0, 0.0);
+    alSource3f(source, AL_DIRECTION,       0.0, 0.0, 0.0);
+    alSourcef (source, AL_ROLLOFF_FACTOR,  0.0          );
+    alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE      );
+    alSourcef (source, AL_GAIN,            SoundEngine::getInstance()->getMusicVolume());
+    SoundEngine::checkError("OggPlayer::open()::SetSourceProperties", __LINE__);
+
+    // Set to State Stopped
+    this->state |= OggPlayer::Stopped;
+    return true;
+  }
+
+
+  /**
+   * @brief start Playing Music.
+   * @returns true on success false otherwise.
+   */
+  bool OggPlayer::play()
+  {
+    if (!(this->state & OggPlayer::FileOpened))
+      return false;
+
+    this->state &= ~(OggPlayer::Stopped | OggPlayer::Paused);
+
+    if (!this->playback())
+      return false;
+
+    if (this->musicThreadID == NULL)
+      return ((this->musicThreadID = SDL_CreateThread(OggPlayer::musicThread, (void*)this)) != NULL);
+    return true;
+  }
+
+  /**
+   * @brief stop the OggPlayer from Playing.
+   */
+  void OggPlayer::stop()
+  {
+    this->state &= ~(OggPlayer::Playing | OggPlayer::Paused);
+    this->state |= OggPlayer::Stopped;
+
+    this->suspend();
+    this->rewind();
+  }
+
+  /**
+   * @brief Pause the Playing.
+   */
+  void OggPlayer::pause()
+  {
+    this->state &= ~OggPlayer::Playing;
+
+    if (!(this->state & OggPlayer::Stopped))
+      this->state |= OggPlayer::Paused;
+
+    this->suspend();
+  }
+
+  /**
+   * @brief rewind to the beginning, and play (if already playing)
+   */
+  void OggPlayer::rewind()
+  {
+    this->jumpTo(0.0f);
+  }
+
+  /**
+   * @brief jump to Second timeCode in the MusicFile
+   * @param timeCode where to jump to.
+   */
+  void OggPlayer::jumpTo(float timeCode)
+  {
+
+    if (this->state & OggPlayer::FileOpened)
+    {
+      OrxThread::MutexLock musicLock(&this->musicMutex);
+      ov_time_seek(&this->oggStream, timeCode);
+    }
+  }
+
+  /**
+   * @returns the Length of the Music in Seconds
+   */
+  float OggPlayer::length()
+  {
+    if (this->state & OggPlayer::FileOpened)
+      return ov_time_total(&this->oggStream, -1);
+    else
+      return 0.0f;
+  }
+
+
+  /**
+   * @returns true if the file is playing
+   */
+  bool OggPlayer::isPlaying()
+  {
+    if (!(this->state & OggPlayer::FileOpened))
+      return false;
+    ALenum state;
+
+    alGetSourcei(this->source, AL_SOURCE_STATE, &state);
+
+    return (state == AL_PLAYING);
+  }
+
+
+
+  ////////////////////////
+  // INTERNAL FUNCTIONS //
+  ////////////////////////
+  /**
+   * @brief creates a Thread for Playing back the music even if the rest of the Engine is slow
+   * @param oggPlayer the OggPlayer to play back
+   * @returns -1 on error.
+   */
+  int OggPlayer::musicThread(void* oggPlayer)
+  {
+    if (oggPlayer == NULL)
+      return -1;
+    OggPlayer* ogg = (OggPlayer*)oggPlayer;
+
+    PRINTF(4)("STARTIG AUDIO THREAD\n");
+    while (ogg->state & OggPlayer::Playing)
+    {
+      {
+        OrxThread::MutexLock musicLock(&ogg->musicMutex);
+        ogg->update();
+      }
+      SDL_Delay(1);
+    }
+    PRINTF(4)("End the AudioThread\n");
+    return 0;
+  }
+
+
+  /**
+   * @brief plays back the sound
+   * @return true if running, false otherwise
+   */
+  bool OggPlayer::playback()
+  {
+    if (!(this->state & OggPlayer::FileOpened))
+      return false;
+
+    if(this->state & OggPlayer::Playing)
+      return true;
+    this->state |= OggPlayer::Playing;
+
+    OrxThread::MutexLock musicLock(&this->musicMutex);
+    if(!this->stream(this->buffers[0]) || !this->stream(this->buffers[1]))
+    {
+      this->state &= ~OggPlayer::Playing;
+      return false;
+    }
+
+    alSourceQueueBuffers(this->source, 2, this->buffers);
+    if (DEBUG_LEVEL >= 3)
+      SoundEngine::checkError("OggPlayer::playback()::alSourceQueueBuffers", __LINE__);
+
+    alSourcePlay(this->source);
+    if (DEBUG_LEVEL >= 3)
+      SoundEngine::checkError("OggPlayer::playback()::alSourcePlay", __LINE__);
+    return true;
+  }
+
+
+  /**
+   * @brief waits for the AudioThread to be finished.
+   */
+  void OggPlayer::suspend()
+  {
+    if (this->musicThreadID != NULL)
+    {
+      assert (!(this->state & Playing));
+      SDL_WaitThread(this->musicThreadID, NULL);
+      this->musicThreadID = NULL;
+    }
+    if (this->state & OggPlayer::SourceAllocated)
+    {
+      alSourceStop(this->source);
+      alSourcei(this->source, AL_BUFFER, 0);
+    }
+  }
+
+  /**
+   * @brief updates the stream, this has to be done every few parts of a second, for sound-consistency
+   * @returns true, if the Sound is playing flawlessly
+   */
+  bool OggPlayer::update()
+  {
+    int processed = 0;
+    bool active = true;
+
+    alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
+
+    if (DEBUG_LEVEL >= 3)
+      SoundEngine::checkError("OggPlayer::update()::alGetSourceI", __LINE__);
+
+    while(processed--)
+    {
+      ALuint buffer;
+
+      alSourceUnqueueBuffers(source, 1, &buffer);
+      if (DEBUG_LEVEL >= 3)
+        SoundEngine::checkError("OggPlayer::update()::unqueue", __LINE__);
+
+      active = stream(buffer);
+
+      alSourceQueueBuffers(source, 1, &buffer);
+      if (DEBUG_LEVEL >= 3)
+        SoundEngine::checkError("OggPlayer::update()::queue", __LINE__);
+    }
+
+    int play;
+    alGetSourcei(source, AL_SOURCE_STATE, &play);
+
+    if (play != AL_PLAYING)
+    {
+      alSourcePlay(source);
+      PRINTF(2)("Filling Audio Gap\n");
+    }
+
+
+    return active;
+  }
+
+  /**
+   * @brief gets a new Stream from buffer
+   * @param buffer the buffer to get the stream from
+   * @return true, if everything worked as planed
+   */
+  bool OggPlayer::stream(ALuint buffer)
+  {
+    if (unlikely(!(this->state & Playing)))
+      return false;
+    char pcm[OGG_PLAYER_BUFFER_SIZE];
+    int  size = 0;
+    int  section;
+    int  result;
+
+    while(size < OGG_PLAYER_BUFFER_SIZE)
+    {
+      result = ov_read(&this->oggStream, pcm + size, OGG_PLAYER_BUFFER_SIZE - size, 0, 2, 1, &section);
+
+      if(result > 0)
+        size += result;
+      else if(result < 0)
+        throw getVorbisError(result);
+      else /* eof */
+        ov_time_seek(&this->oggStream, 0.0);
+    }
+
+    if(size == 0)
+      return false;
+/*#ifdef SDL_BIG_ENDIAN
+			int cnt = wavLength/2;
+			Uint16* wavBufferAsShorts = ( Uint16* )wavBuffer;
+			for ( int i = 0; i < cnt; ++i, ++wavBufferAsShorts )
+				*wavBufferAsShorts = SDL_Swap16( *wavBufferAsShorts );
+#endif*/
+    alBufferData(buffer, format, pcm, size, vorbisInfo->rate);
+    if (DEBUG_LEVEL >= 3)
+      SoundEngine::checkError("OggPlayer::stream()::BUFFER", __LINE__);
+
+    return true;
+  }
+
+
+  /**
+   * @brief releases a stream
+   */
+  void OggPlayer::release()
+  {
+    if (this->state & OggPlayer::SourceAllocated)
+    {
+      assert(alIsSource(this->source));
+      if (this->state & OggPlayer::Playing);
+      {
+        // Kill the Music Thread.
+        this->state &= ~OggPlayer::Playing;
+        this->suspend();
+
+        SoundEngine::checkError("OggPlayer::release()::alSourceStop", __LINE__);
+      }
+      empty();
+      alSourcei(this->source, AL_BUFFER, 0);
+      SoundEngine::getInstance()->pushALSource(this->source);
+      this->source = 0;
+      this->state &= ~SourceAllocated;
+    }
+    if (this->state & OggPlayer::BuffersAllocated)
+    {
+      assert (this->buffers[0] != 0 && this->buffers[1] != 0);
+      alDeleteBuffers(2, buffers);
+      SoundEngine::checkError("OggPlayer::release()::alDeleteBuffers", __LINE__);
+      this->buffers[0] = 0;
+      this->buffers[1] = 0;
+      this->state &= ~OggPlayer::BuffersAllocated;
+    }
+
+    if (this->state & OggPlayer::FileOpened)
+    {
+      ov_clear(&oggStream);
+      this->state &= ~OggPlayer::FileOpened;
+    }
+
+  }
+
+
+  /**
+   * @brief empties the buffers
+   */
+  void OggPlayer::empty()
+  {
+    int queued;
+
+    alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
+
+    while(queued--)
+    {
+      ALuint buffer;
+
+      alSourceUnqueueBuffers(source, 1, &buffer);
+      SoundEngine::checkError("OggPlayer::empty()::unqueue Buffers", __LINE__);
+    }
+  }
+
+
+  void OggPlayer::retrieveFileInfo(OggVorbis_File* file)
+  {
+    vorbis_comment* comment = ov_comment(file, -1);
+    if (comment == NULL)
+    {
+      PRINTF(2)("Retrieving Comment of %s failed\n", this->getCName());
+      return;
+    }
+    for (int i = 0; i < comment->comments; ++i)
+    {
+      if (!nocaseCmp("artist=", comment->user_comments[i], 7))
+        this->_artist = comment->user_comments[i]+7;
+      if (!nocaseCmp("title=", comment->user_comments[i], 6))
+        this->_title = comment->user_comments[i] + 6;
+      if (!nocaseCmp("album=", comment->user_comments[i], 6))
+        this->_album = comment->user_comments[i]+6;
+    }
+  }
+
+
+  /////////////////////
+  // DEBUG_LEVEL FUNCTIONS //
+  /////////////////////
+  /**
+   * displays some info about the ogg-file
+   */
+  void OggPlayer::debug() const
+  {
+    std::cout
+    << "version         " << vorbisInfo->version         << "\n"
+    << "channels        " << vorbisInfo->channels        << "\n"
+    << "rate (hz)       " << vorbisInfo->rate            << "\n"
+    << "bitrate upper   " << vorbisInfo->bitrate_upper   << "\n"
+    << "bitrate nominal " << vorbisInfo->bitrate_nominal << "\n"
+    << "bitrate lower   " << vorbisInfo->bitrate_lower   << "\n"
+    << "bitrate window  " << vorbisInfo->bitrate_window  << "\n"
+    << "\n"
+    << "vendor " << vorbisComment->vendor << "\n";
+
+    for(int i = 0; i < vorbisComment->comments; i++)
+      std::cout << "   " << vorbisComment->user_comments[i] << "\n";
+
+    std::cout << std::endl;
+  }
+
+
+  void OggPlayer::printState() const
+  {
+    PRINTF(0)("OggPlayer is in the following States: ");
+    if (this->state & OggPlayer::FileOpened)
+      PRINT(0)("FileOpened ");
+    if (this->state & OggPlayer::SourceAllocated)
+      PRINT(0)("SourceAllocated ");
+    if (this->state & OggPlayer::BuffersAllocated)
+      PRINT(0)("BuffersAllocated ");
+    if (this->state & OggPlayer::Stopped)
+      PRINT(0)("Stopped ");
+    if (this->state & OggPlayer::Playing)
+      PRINT(0)("Playing ");
+    if (this->state & OggPlayer::Paused)
+      PRINT(0)("Paused ");
+    if (this->state & OggPlayer::Error)
+      PRINT(0)("Error ");
+    PRINT(0)("\n");
+  }
+
+  /**
+   * returns errors
+   * @param code the error-code
+   * @return the error as a String
+   */
+  const char* OggPlayer::getVorbisError(int code)
+  {
+    switch(code)
+    {
+      case OV_EREAD:
+        return ("Read from media.");
+      case OV_ENOTVORBIS:
+        return ("Not Vorbis data.");
+      case OV_EVERSION:
+        return ("Vorbis version mismatch.");
+      case OV_EBADHEADER:
+        return ("Invalid Vorbis header.");
+      case OV_EFAULT:
+        return ("Internal logic fault (bug or heap/stack corruption.");
+      default:
+        return ("Unknown Ogg error.");
+    }
+  }
+
+}
Index: branches/heathaze/src/lib/sound/ogg_player.h
===================================================================
--- branches/heathaze/src/lib/sound/ogg_player.h	(revision 9940)
+++ branches/heathaze/src/lib/sound/ogg_player.h	(revision 9940)
@@ -0,0 +1,109 @@
+/*!
+ * @file ogg_player.h
+ * Ogg-Player definition
+ */
+
+
+#ifndef _OGG_PLAYER_H
+#define _OGG_PLAYER_H
+
+#include "base_object.h"
+
+#include "alincl.h"
+#include <ogg/ogg.h>
+#include <vorbis/vorbisfile.h>
+#include "util/threading.h"
+
+struct File;
+
+
+#define OGG_PLAYER_BUFFER_SIZE (8096 * 2)
+
+namespace OrxSound
+{
+  // the definition of a Ogg-Player
+  class OggPlayer : public BaseObject
+  {
+    ObjectListDeclaration(OggPlayer);
+
+  public:
+    /**
+     * An enumerator defining in what State the OggPlayer is.
+     * The OggPlayer can be in multiple States listed here.
+     * It can as an example be in FileOpened and Stopped.
+     */
+    typedef enum {
+      None                   = 0x000,   //!< Initialized
+      FileOpened             = 0x100,   //!< File is Opened
+      SourceAllocated        = 0x200,   //!< Source is Allocated.
+      BuffersAllocated       = 0x400,   //!< 2 Buffers are Allocated.
+      Stopped                = 0x010,   //!< OggPlayer is stopped.
+      Playing                = 0x020,   //!< OggPlayer is Playing.
+      Paused                 = 0x040,   //!< OggPlayer is Paused.
+      Error                  = 0x001,   //!< An Error has occured.
+    } State;
+
+    OggPlayer(const std::string& fileName = "");
+    virtual ~OggPlayer();
+    /** @param state compare this State with the internal State @returns true on match */
+    bool operator==(OggPlayer::State state) { return this->state & state; };
+
+    bool open(const std::string& fileName = "");
+
+    bool play();
+    void stop();
+    void pause();
+    void rewind(); // convenience
+    void jumpTo(float timeCode);
+
+    float length();
+    bool isPlaying();
+    bool getState() { return this->state; };
+
+    const std::string& artist() const { return this->_artist; };
+    const std::string& title() const { return this->_title; };
+    const std::string& album() const { return this->_album; };
+
+
+    void debug() const;
+    void printState() const;
+    const char* getVorbisError(int code);
+
+
+  private:
+    static int musicThread(void* oggPlayer);
+    bool playback();
+    void suspend();
+    bool update();
+
+    void release();
+
+    bool stream(ALuint buffer);
+    void empty();
+
+    void retrieveFileInfo(OggVorbis_File* file);
+
+  private:
+    FILE*               oggFile;              //!< general file-handler, to open the sound-file
+    OggVorbis_File      oggStream;            //!< The stream this Ogg-player is playing back
+    vorbis_info*        vorbisInfo;           //!< The information held in the opened ogg-file
+    vorbis_comment*     vorbisComment;        //!< Comments about the ogg-file
+
+    ALuint              buffers[2];           //!< buffers that handle sequentially buffering of the audio
+    ALuint              source;               //!< The source we play back on
+    ALenum              format;               //!< The format we play back
+    unsigned int        state;                //!< The States the OggPlayer is in (this can be multiple entries from OggPlayer::State).
+
+    SDL_Thread*         musicThreadID;        //!< The Thread in which music is Played back.
+    OrxThread::Mutex    musicMutex;           //!< A Mutex so that the two threads do not interfere.
+
+
+
+    std::string         _title;               //!< Song Title.
+    std::string         _artist;              //!< Artist Name of the current song.
+    std::string         _album;               //!< Album Name of the current song.
+    std::string         _vendor;              //!< Vendor Name of the current song.
+  };
+
+}
+#endif /* _OGG_PLAYER_H */
Index: branches/heathaze/src/lib/sound/resource_sound_buffer.cc
===================================================================
--- branches/heathaze/src/lib/sound/resource_sound_buffer.cc	(revision 9940)
+++ branches/heathaze/src/lib/sound/resource_sound_buffer.cc	(revision 9940)
@@ -0,0 +1,36 @@
+
+#include "resource_sound_buffer.h"
+#include "debug.h"
+
+
+namespace OrxSound
+{
+  ObjectListDefinition(ResourceSoundBuffer);
+
+  ResourceSoundBuffer::ResourceSoundBuffer(const std::string& soundName, const Resources::KeepLevel& keepLevel)
+      : SoundBuffer(), Resource(&ResourceSoundBuffer::type)
+  {
+    this->registerObject(this, ResourceSoundBuffer::_objectList);
+    Resources::StorePointer* ptr = this->acquireResource(soundName);
+
+    if (ptr)
+    {
+      assert(!static_cast<ResourceSoundBuffer::SoundBufferResourcePointer*>(ptr)->ptr().isNull());
+      PRINTF(5)("FOUND SOUND: %s\n", soundName.c_str());
+      this->acquireData(static_cast<ResourceSoundBuffer::SoundBufferResourcePointer*>(ptr)->ptr());
+    }
+    else
+    {
+      PRINTF(5)("SOUND NOT FOUND: %s\n", soundName.c_str());
+      std::string fileName = this->Resource::locateFile(soundName);
+      this->SoundBuffer::load(fileName);
+      this->Resource::addResource(new ResourceSoundBuffer::SoundBufferResourcePointer(soundName, keepLevel, this->SoundBuffer::dataPointer()));
+    }
+  }
+
+
+  Resources::tType<ResourceSoundBuffer> ResourceSoundBuffer::type("SoundBuffer");
+
+  ResourceSoundBuffer::SoundBufferResourcePointer::SoundBufferResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const SoundBufferData::Pointer& data)
+      : Resources::StorePointer(loadString, keepLevel) , pointer(data)
+{}}
Index: branches/heathaze/src/lib/sound/resource_sound_buffer.h
===================================================================
--- branches/heathaze/src/lib/sound/resource_sound_buffer.h	(revision 9940)
+++ branches/heathaze/src/lib/sound/resource_sound_buffer.h	(revision 9940)
@@ -0,0 +1,41 @@
+/*!
+ * @file resource_sound_buffer.h
+ * @brief Contains the ResourceSoundBuffer class, that handles the Resource-specific loading part of the SoundBuffer.
+ *
+ */
+
+#ifndef _RESOURCE_SOUND_BUFFER_H
+#define _RESOURCE_SOUND_BUFFER_H
+
+#include "util/loading/resource.h"
+#include "sound_buffer.h"
+
+namespace OrxSound
+{
+  class ResourceSoundBuffer : public SoundBuffer, public Resources::Resource
+  {
+    ObjectListDeclaration(ResourceSoundBuffer);
+  public:
+    ResourceSoundBuffer(const std::string& soundName,
+			const Resources::KeepLevel& keepLevel = Resources::KeepLevel());
+    static ResourceSoundBuffer createFromString(const std::string& loadString, const Resources::KeepLevel& keepLevel = Resources::KeepLevel())
+    { return ResourceSoundBuffer(loadString, keepLevel); };
+
+  private:
+  class SoundBufferResourcePointer : public Resources::StorePointer
+    {
+    public:
+      SoundBufferResourcePointer(const std::string& loadString, const Resources::KeepLevel& keepLevel, const SoundBufferData::Pointer& data);
+      inline const SoundBufferData::Pointer& ptr() const { return pointer; }
+      virtual bool last() const { return pointer.count() == 1; }
+    private:
+      SoundBufferData::Pointer pointer;
+    };
+
+  private:
+    static Resources::tType<ResourceSoundBuffer> type;
+  };
+}
+
+
+#endif /* _RESOURCE_SOUND_BUFFER_H */
Index: branches/heathaze/src/lib/sound/sound_buffer.cc
===================================================================
--- branches/heathaze/src/lib/sound/sound_buffer.cc	(revision 9940)
+++ branches/heathaze/src/lib/sound/sound_buffer.cc	(revision 9940)
@@ -0,0 +1,59 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SOUND
+
+#include "sound_buffer.h"
+
+
+namespace OrxSound
+{
+  ObjectListDefinition(SoundBuffer);
+  //////////////////
+  /* SOUND-BUFFER */
+  //////////////////
+  SoundBuffer::SoundBuffer()
+      : data(new SoundBufferData)
+  {
+    this->registerObject(this, SoundBuffer::_objectList);
+  }
+  /**
+   * @brief Creates a Soundbuffer out of an inputfile
+   * @param fileName The name of the File
+   */
+  SoundBuffer::SoundBuffer(const std::string& fileName)
+      : data(new SoundBufferData)
+  {
+    this->registerObject(this, SoundBuffer::_objectList);
+    this->load(fileName);
+  }
+
+  SoundBuffer::SoundBuffer(const SoundBuffer& buffer)
+      : data(buffer.data)
+  {
+    this->registerObject(this, SoundBuffer::_objectList);
+  }
+
+  SoundBuffer::SoundBuffer(const SoundBufferData::Pointer& dataPointer)
+      : data(dataPointer)
+  {
+    this->registerObject(this, SoundBuffer::_objectList);
+  };
+
+  SoundBuffer::~SoundBuffer()
+  {
+  }
+
+}
Index: branches/heathaze/src/lib/sound/sound_buffer.h
===================================================================
--- branches/heathaze/src/lib/sound/sound_buffer.h	(revision 9940)
+++ branches/heathaze/src/lib/sound/sound_buffer.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file sound_buffer.h
+ * @brief Definition of the sound-buffer-class
+*/
+
+#ifndef _SOUND_BUFFER_H
+#define _SOUND_BUFFER_H
+
+#include "base_object.h"
+#include "sound_buffer_data.h"
+
+namespace OrxSound
+{
+  //! A class that represents a datastructure to play Sounds.
+  class SoundBuffer : virtual public BaseObject
+  {
+    ObjectListDeclaration(SoundBuffer);
+  public:
+    SoundBuffer();
+    SoundBuffer(const SoundBuffer& buffer);
+    SoundBuffer(const SoundBufferData::Pointer& dataPointer);
+    SoundBuffer(const std::string& fileName);
+    virtual ~SoundBuffer();
+
+    /** @brief assignment operator */
+    SoundBuffer& operator=(const SoundBuffer& buffer) { this->data = buffer.data; return *this; };
+    bool operator==(const SoundBuffer& buffer) const {return this->data == buffer.data; };
+
+    /** @see SoundBufferData::load */
+    inline bool load(const std::string& fileName) { return this->data->load(fileName); };
+    /** @see SoundBufferData::loadWav */
+    inline bool loadWAV(const std::string& fileName) { return this->data->loadWAV(fileName); };
+    /** @see SoundBufferData::loadOgg */
+    inline bool loadOGG(const std::string& fileName) { return this->data->loadOGG(fileName); };
+
+    /** @returns the ID of the buffer used in this SoundBuffer */
+    inline ALuint getID() const { return this->data->getID(); }
+    inline bool loaded() const { return this->data->loaded(); }
+
+    /** @returns the DataPointer */
+    const SoundBufferData::Pointer& dataPointer() const { return data; }
+    /** @param dataPointer the data to acquire @brief Buffer shall acquire dataPointers data */
+    void acquireData(const SoundBufferData::Pointer& dataPointer)  { data = dataPointer; };
+
+  private:
+    SoundBufferData::Pointer    data;                //!< Pointer to the Stored Data
+  };
+}
+#endif /* _SOUND_BUFFER_H */
Index: branches/heathaze/src/lib/sound/sound_buffer_data.cc
===================================================================
--- branches/heathaze/src/lib/sound/sound_buffer_data.cc	(revision 9940)
+++ branches/heathaze/src/lib/sound/sound_buffer_data.cc	(revision 9940)
@@ -0,0 +1,193 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SOUND
+
+#include "sound_buffer_data.h"
+
+#include "sound_engine.h"
+
+#include "sdlincl.h"
+#include <cassert>
+#include "debug.h"
+#include "sys/stat.h"
+#include "helper_functions.h"
+
+/*#ifdef HAVE_SDL_SDL_H
+ #include <SDL/SDL.h>
+ // #include <SDL/SDL_endian.h>
+#else
+ #include <SDL.h>
+ //#include <SDL_endian.h>
+#endif*/
+namespace OrxSound
+{
+  ObjectListDefinition(SoundBufferData);
+  //////////////////
+  /* SOUND-BUFFER */
+  //////////////////
+  /**
+   * @brief Creates a SoundbufferData out of an inputfile
+   * @param fileName The name of the File
+   */
+  SoundBufferData::SoundBufferData()
+  {
+    this->registerObject(this, SoundBufferData::_objectList);
+    this->bufferID = 0;
+
+    this->size = 0;
+    this->loop = AL_FALSE;
+    this->bLoaded = false;
+  }
+
+  SoundBufferData::~SoundBufferData()
+  {
+    //  SoundEngine::getInstance()->removeBuffer(this);
+    alDeleteBuffers(1, &this->bufferID);
+    SoundEngine::checkError("SoundBuffer: Delete Buffer", __LINE__);
+  }
+
+  /**
+   * @brief check the File-extension and loads either Wav of Ogg
+   * @param fileName the Name of the File to load.
+   * @returns true on success (file found, and loaded.)
+   */
+  bool SoundBufferData::load(const std::string& fileName)
+  {
+    // generate a Buffer
+    alGenBuffers(1, &this->bufferID);
+    SoundEngine::checkError("Generate Buffer", __LINE__);
+    if (!nocaseCmp(fileName.substr(fileName.size() - 3), "WAV"))
+    {
+      return this->loadWAV(fileName);
+    }
+    else if (!nocaseCmp(fileName.substr(fileName.size() - 3), "OGG"))
+      return this->loadOGG(fileName);
+    else
+      return false;
+  }
+
+  /**
+   * @brief loads a Waveform from the local fileSystem into this Source.
+   * @param fileName the Name of the File to Load.
+   * @returns true on success.
+   */
+  bool SoundBufferData::loadWAV(const std::string& fileName)
+  {
+    SDL_AudioSpec wavSpec;
+    Uint32 wavLength;
+    Uint8 *wavBuffer;
+
+    /* Load the WAV */
+    if( SDL_LoadWAV(fileName.c_str(), &wavSpec, &wavBuffer, &wavLength) == NULL)
+    {
+      PRINTF(2)("Could not open %s: %s\n", fileName.c_str(), SDL_GetError());
+      return false;
+    }
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+    if ( !( wavSpec.format == AUDIO_U8 || wavSpec.format == AUDIO_S8 ) )
+    {
+      int cnt = wavLength/2;
+      Uint16* wavBufferAsShorts = ( Uint16* )wavBuffer;
+      for ( int i = 0; i < cnt; ++i, ++wavBufferAsShorts )
+        *wavBufferAsShorts = SDL_Swap16( *wavBufferAsShorts );
+    }
+#endif
+    alBufferData(this->bufferID, SoundBufferData::sdlAudioSpecToAlFormat(&wavSpec),
+                 wavBuffer, wavLength, wavSpec.freq);
+
+    SDL_FreeWAV(wavBuffer);
+    if (SoundEngine::checkError("Could not load Wave file", __LINE__))
+    {
+      this->bLoaded = true;
+      return true;
+    }
+    else
+      return false;
+  }
+
+
+#ifndef AL_FORMAT_VORBIS_EXT
+#define AL_FORMAT_VORBIS_EXT 0x100030
+#endif
+  /**
+   * @brief loads an OGG-file into a SOundBuffer
+   * @param fileName the Name of the File to load.
+   * @returns true on success (file exists and is fully loaded), false otherwise.
+   */
+  bool SoundBufferData::loadOGG(const std::string& fileName)
+  {
+    void*     ovdata;
+    FILE*     fh;
+
+    fh = fopen( fileName.c_str() , "rb") ;
+    if( fh != NULL )
+    {
+      struct stat sbuf ;
+
+      if(stat( fileName.c_str(), &sbuf ) != -1)
+      {
+        ovdata = malloc(sbuf.st_size);
+        if(ovdata != NULL)
+        {
+          fread( ovdata, 1, sbuf.st_size, fh);
+
+          alBufferData( this->bufferID,
+                        AL_FORMAT_VORBIS_EXT,
+                        ovdata,
+                        sbuf.st_size,
+                        1) ;
+          SoundEngine::checkError("Could not load OGG file", __LINE__);
+
+          free(ovdata);
+        }
+        fclose(fh);
+      }
+      else
+        return false;
+    }
+    else
+      return false;
+
+    this->bLoaded = true;
+    return true ;
+  }
+
+
+  /**
+   * @brief converts an SDL_AudioSpec into a valid OpenAL AUDIO_FORMAT enumerator
+   * @param audiospec the AudioSpec to convert.
+   * @returns the AL_FORMAT
+   */
+  ALenum SoundBufferData::sdlAudioSpecToAlFormat(const SDL_AudioSpec* audiospec)
+  {
+    assert (audiospec != NULL);
+    bool stereo = true;
+    bool is16Bit = true;
+    if (audiospec->format == AUDIO_U8 || audiospec->format == AUDIO_S8)
+      is16Bit = false;
+    if (audiospec->channels == 1)
+      stereo = false;
+
+    if (!stereo && !is16Bit)
+      return AL_FORMAT_MONO8;
+    else if (!stereo && is16Bit)
+      return AL_FORMAT_MONO16;
+    else if (stereo && !is16Bit)
+      return AL_FORMAT_STEREO8;
+    else /* if (stereo && is16Bit) */
+      return AL_FORMAT_STEREO16;
+  }
+}
Index: branches/heathaze/src/lib/sound/sound_buffer_data.h
===================================================================
--- branches/heathaze/src/lib/sound/sound_buffer_data.h	(revision 9940)
+++ branches/heathaze/src/lib/sound/sound_buffer_data.h	(revision 9940)
@@ -0,0 +1,48 @@
+/*!
+ * @file sound_buffer_data.h
+ * @brief Definition of the sound-buffer-datacontainer-class
+*/
+
+#ifndef _SOUND_BUFFER_DATA_H
+#define _SOUND_BUFFER_DATA_H
+
+#include "base_object.h"
+#include "alincl.h"
+#include "util/count_pointer.h"
+
+// FORWARD DECLARATION
+typedef struct SDL_AudioSpec;
+
+namespace OrxSound
+{
+  //! A class that represents a datastructure to play Sounds.
+  class SoundBufferData : public BaseObject
+  {
+    ObjectListDeclaration(SoundBufferData);
+  public:
+    typedef CountPointer<SoundBufferData> Pointer;
+
+  public:
+    SoundBufferData();
+    virtual ~SoundBufferData();
+
+    bool load(const std::string& fileName);
+    bool loadWAV(const std::string& fileName);
+    bool loadOGG(const std::string& fileName);
+
+    /** @returns the ID of the buffer used in this SoundBuffer */
+    inline ALuint getID() const { return this->bufferID; }
+    inline bool loaded() const { return bLoaded; };
+
+  private:
+    ALenum sdlAudioSpecToAlFormat(const SDL_AudioSpec* audiospec);
+
+  private:
+    ALuint        bufferID;             //!< The address of the Buffer.
+
+    ALsizei       size;                 //!< The size of the Buffer.
+    ALboolean     loop;                 //!< loop information.
+    bool          bLoaded;               //!< If the Sound was loaded this is true.
+  };
+}
+#endif /* _SOUND_BUFFER_DATA_H */
Index: branches/heathaze/src/lib/sound/sound_engine.cc
===================================================================
--- branches/heathaze/src/lib/sound/sound_engine.cc	(revision 9940)
+++ branches/heathaze/src/lib/sound/sound_engine.cc	(revision 9940)
@@ -0,0 +1,416 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   code has been taken from http://www.devmaster.net/articles.php?catID=6
+   The code has been applied to our needs, and many things have been changed.
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SOUND
+
+#include "sound_engine.h"
+
+#include "p_node.h"
+#include "debug.h"
+#include "parser/preferences/preferences.h"
+#include "globals.h"
+#include "resource_sound_buffer.h"
+
+namespace OrxSound
+{
+  ObjectListDefinition(SoundEngine);
+  //////////////////
+  /* SOUND-ENGINE */
+  //////////////////
+  /**
+   * @brief standard constructor
+  */
+  SoundEngine::SoundEngine ()
+  {
+    this->registerObject(this, SoundEngine::_objectList);
+    this->setName("SoundEngine");
+
+    this->listener = NULL;
+
+    this->device = NULL;
+    this->context = NULL;
+
+    this->maxSourceCount = 32;
+
+    this->effectsVolume = .80;
+    this->musicVolume = .75;
+
+    this->sourceMutex = SDL_CreateMutex();
+  }
+
+  /**
+   * @brief the singleton reference to this class
+  */
+  SoundEngine* SoundEngine::singletonRef = NULL;
+
+  /**
+   * @brief standard destructor
+   */
+  SoundEngine::~SoundEngine ()
+  {
+    // deleting all the SoundSources
+    while (!SoundSource::objectList().empty())
+      delete (SoundSource::objectList().front());
+
+    while(!this->ALSources.empty())
+    {
+      if (alIsSource(this->ALSources.top()))
+      {
+        alDeleteSources(1, &this->ALSources.top());
+        SoundEngine::checkError("Deleting Source", __LINE__);
+      }
+      else
+        PRINTF(1)("%d is not a Source\n", this->ALSources.top());
+
+      this->ALSources.pop();
+    }
+
+    // deleting all the SoundBuffers
+    //    while(!SoundBuffer::objectList().empty())
+    //ResourceManager::getInstance()->unload(SoundBuffer::objectList().front());
+
+    // removing openAL from AudioResource
+    //! @todo this should be terminated through alc
+    //alutExit();
+
+    SDL_DestroyMutex(this->sourceMutex);
+
+    SoundEngine::singletonRef = NULL;
+  }
+
+  /**
+   * @brief loads the settings of the SoundEngine from an ini-file
+   */
+  void SoundEngine::loadSettings()
+  {
+    MultiType channels = Preferences::getInstance()->getString(CONFIG_SECTION_AUDIO, CONFIG_NAME_AUDIO_CHANNELS, "32");
+    this->maxSourceCount = channels.getInt();
+
+    MultiType effectsVolume = Preferences::getInstance()->getString(CONFIG_SECTION_AUDIO, CONFIG_NAME_EFFECTS_VOLUME, "80");
+    this->effectsVolume = effectsVolume.getFloat()/100.0;
+
+    MultiType musicVolume = Preferences::getInstance()->getString(CONFIG_SECTION_AUDIO, CONFIG_NAME_MUSIC_VOLUME, "75");
+    this->musicVolume = musicVolume.getFloat()/100.0;
+  }
+
+  /**
+   * @brief creates a new SoundSource.
+   * @param fileName The Name to load the SoundBuffer from
+   * @param sourceNode The sourceNode to bind this SoundSource to.
+   * @returns The newly created SoundSource
+   *
+   * acctualy this is nothing more than a wrapper around the ResourceManager.
+  */
+  SoundSource* SoundEngine::createSource(const std::string& fileName, PNode* sourceNode)
+  {
+    SoundBuffer buffer;
+    if (!fileName.empty())
+    {
+      buffer = ResourceSoundBuffer(fileName);
+      if (!buffer.loaded())
+        PRINTF(2)("Wav-Sound %s could not be loaded onto new Source\n", fileName.c_str());
+    }
+    return new SoundSource(sourceNode, buffer);
+  }
+
+  /**
+   * @brief Sets the doppler values of openAL
+   * @param dopplerFactor the extent of the doppler-effect
+   * @param dopplerVelocity the Speed the sound travels
+  */
+  void SoundEngine::setDopplerValues(ALfloat dopplerFactor, ALfloat dopplerVelocity)
+  {
+    alDopplerFactor(dopplerFactor);
+    this->checkError("Setting Doppler Factor", __LINE__);
+
+    alDopplerVelocity(dopplerVelocity);
+    this->checkError("Setting Doppler Velocity", __LINE__);
+  }
+
+
+  /**
+   * @brief retrieves an OpenAL Source from the availiable Sources.
+   * @param source the Source to fill with the Value.
+   */
+  void SoundEngine::popALSource(ALuint& source)
+  {
+    assert (source == 0);
+    /// @TODO try to create more sources if needed
+    if (!this->ALSources.empty())
+    {
+      SDL_mutexP(this->sourceMutex);
+      source = this->ALSources.top();
+      this->ALSources.pop();
+      SDL_mutexV(this->sourceMutex);
+    }
+  }
+
+
+  /**
+   * @brief Pushes an OpenAL Source back into the Stack of known sources
+   * @param source the Source to push onto the top of the SourceStack
+   */
+  void SoundEngine::pushALSource(ALuint& source)
+  {
+    if (source != 0)
+    {
+      SDL_mutexP(this->sourceMutex);
+      this->ALSources.push(source);
+      SDL_mutexV(this->sourceMutex);
+    }
+  };
+
+
+  /**
+   * @brief updates all The positions, Directions and Velocities of all Sounds
+   */
+  void SoundEngine::update()
+  {
+    // updating the Listeners Position
+    if (likely(this->listener != NULL))
+    {
+      alListener3f(AL_POSITION,
+                   this->listener->getAbsCoor().x,
+                   this->listener->getAbsCoor().y,
+                   this->listener->getAbsCoor().z);
+      alListener3f(AL_VELOCITY,
+                   this->listener->getVelocity().x,
+                   this->listener->getVelocity().y,
+                   this->listener->getVelocity().z);
+      Vector absDirV = this->listener->getAbsDirV();
+      ALfloat orientation [6] = {1,0,0, absDirV.x, absDirV.y, absDirV.z};
+      alListenerfv(AL_ORIENTATION, orientation);
+      SoundEngine::checkError("SoundEngine::update() - Listener Error", __LINE__);
+    }
+    else
+      PRINTF(2)("no listener defined\n");
+
+    // updating all the Sources positions
+    ObjectList<SoundSource>::const_iterator sourceIT;
+    for (sourceIT = SoundSource::objectList().begin();
+         sourceIT != SoundSource::objectList().end();
+         sourceIT++)
+    {
+      if ((*sourceIT)->isPlaying())
+      {
+        int play = 0x000;
+        alGetSourcei((*sourceIT)->getID(), AL_SOURCE_STATE, &play);
+        if (DEBUG_LEVEL > 2)
+          SoundEngine::checkError("SoundEngine::update() Play", __LINE__);
+        if(play == AL_PLAYING)
+        {
+          if (likely((*sourceIT)->getNode() != NULL))
+          {
+            alSource3f((*sourceIT)->getID(), AL_POSITION,
+                       (*sourceIT)->getNode()->getAbsCoor().x,
+                       (*sourceIT)->getNode()->getAbsCoor().y,
+                       (*sourceIT)->getNode()->getAbsCoor().z);
+            if (DEBUG_LEVEL > 2)
+              SoundEngine::checkError("SoundEngine::update() Set Source Position", __LINE__);
+            alSource3f((*sourceIT)->getID(), AL_VELOCITY,
+                       (*sourceIT)->getNode()->getVelocity().x,
+                       (*sourceIT)->getNode()->getVelocity().y,
+                       (*sourceIT)->getNode()->getVelocity().z);
+            if (DEBUG_LEVEL > 2)
+              SoundEngine::checkError("SoundEngine::update() Set Source Velocity", __LINE__);
+          }
+        }
+        else
+        {
+          (*sourceIT)->stop();
+        }
+      }
+    }
+    SoundEngine::checkError("SoundEngine::update()", __LINE__);
+  }
+
+
+  /**
+   *  initializes Audio in general
+  */
+  bool SoundEngine::initAudio()
+  {
+    //   ALenum result;
+    //   PRINTF(3)("Initialisazing openAL sound engine\n");
+    //   const char* defaultDevice =(const char*) alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
+    //   const char* deviceList = (const char*)alcGetString(NULL,ALC_DEVICE_SPECIFIER);
+    //   const char* devWalk = deviceList;
+    //   //  if (alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE)
+    //   { // try out enumeration extension
+    //     PRINTF(3)("Enumeration-extension found\n");
+    //
+    //     PRINTF(3)("Default device: %s\n", defaultDevice);
+    //     do
+    //     {
+    //       PRINTF(3)("%s\n", devWalk);
+    //       devWalk += strlen(devWalk)+1;
+    //     }
+    //     while (devWalk[0] != '\0');
+    //  }
+
+    // INITIALIZING THE DEVICE:
+    //   char deviceName[] =
+    //   #ifdef __WIN32__
+    //     "Direct3D";
+    //   #else
+    //     "'( ( devices '( native null ) ) )";
+    //   #endif
+
+    this->device = alcOpenDevice(NULL);
+    this->checkALCError("opening Device", __LINE__);
+
+    PRINTF(4)("Audio-Specifier: %s\n", (const char*)alcGetString(this->device, ALC_DEVICE_SPECIFIER));
+    PRINTF(4)("Audio-Extensions: %s\n", (const char*)alcGetString(this->device, ALC_EXTENSIONS));
+
+
+    this->context = alcCreateContext(this->device, NULL);
+    this->checkALCError("creating Context", __LINE__);
+
+    alcMakeContextCurrent(this->context);
+    this->checkALCError("making Context Current", __LINE__);
+    // #endif
+
+    this->setDopplerValues(SOUND_DOPPLER_FACTOR, SOUND_DOPPLER_VELOCITY);
+    this->allocateSources(this->maxSourceCount);
+    this->checkError("Allocating Sources", __LINE__);
+
+    return true;
+  }
+
+
+  /**
+   * Allocates openAL sources
+   * @param count how many sources to allocate
+   * @returns true on success, false if at least one source could not be allocated
+   */
+  bool SoundEngine::allocateSources(unsigned int count)
+  {
+    unsigned int failCount = 0;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      ALuint source = 0;
+
+      alGenSources(1, &source);
+      this->checkError("allocate Source", __LINE__);
+      if (!alIsSource(source))
+      {
+        PRINTF(5)("not allocated Source\n");
+        failCount++;
+        continue;
+      }
+
+      alSourcef (source, AL_PITCH,    1.0      );
+      alSourcef (source, AL_GAIN,     this->getEffectsVolume() );
+      alSourcei (source, AL_LOOPING,  AL_FALSE );
+      this->ALSources.push(source);
+    }
+    if (failCount == 0)
+      return true;
+    else
+    {
+      PRINTF(2)("Failed to allocate %d of %d SoundSources\n", failCount, count);
+      return false;
+    }
+  }
+
+  /**
+   * @brief checks for an OpenAL error
+   * @param error the ErrorMessage to display
+   * @param line on what line did the error occure.
+   */
+  bool SoundEngine::checkError(const std::string& error, unsigned int line)
+  {
+    ALenum errorCode;
+    if ((errorCode = alGetError()) != AL_NO_ERROR)
+    {
+      //PRINTF(1)("Error %s (line:%d): '%s'\n", error.c_str(), line, SoundEngine::getALErrorString(errorCode));
+      return false;
+    }
+    else
+      return true;
+  }
+
+  /**
+   * @brief check for an ALC error.
+   * @brief error the Error-String to display
+   * @param line on that line, the error occured (debugging mode).
+   */
+  bool SoundEngine::checkALCError(const std::string& error, unsigned int line)
+  {
+    ALenum errorCode;
+    if ((errorCode = alcGetError(this->device)) != ALC_NO_ERROR)
+    {
+      PRINTF(1)("Error %s (line:%d): '%s'\n", error.c_str(), line, SoundEngine::getALCErrorString(errorCode));
+      return false;
+    }
+    else
+      return true;
+  }
+
+
+
+  void SoundEngine::listDevices()
+  {
+    printf("%s\n",(const char*)alcGetString(NULL, ALC_DEVICE_SPECIFIER));
+  }
+
+  /**
+   *  Transforms AL-errors into something readable
+   * @param err The error found
+  */
+  const char* SoundEngine::getALErrorString(ALenum err)
+  {
+    switch(err)
+    {
+      default:
+      case AL_NO_ERROR:
+      return ("AL_NO_ERROR");
+      case AL_INVALID_NAME:
+      return ("AL_INVALID_NAME");
+      case AL_INVALID_ENUM:
+      return ("AL_INVALID_ENUM");
+      case AL_INVALID_VALUE:
+      return ("AL_INVALID_VALUE");
+      case AL_INVALID_OPERATION:
+      return ("AL_INVALID_OPERATION");
+      case AL_OUT_OF_MEMORY:
+      return ("AL_OUT_OF_MEMORY");
+    };
+  }
+
+
+  const char* SoundEngine::getALCErrorString(ALenum err)
+  {
+    switch(err)
+    {
+      default:
+      case ALC_NO_ERROR:
+      return ("AL_NO_ERROR");
+      case ALC_INVALID_DEVICE:
+      return ("ALC_INVALID_DEVICE");
+      case ALC_INVALID_CONTEXT:
+      return("ALC_INVALID_CONTEXT");
+      case ALC_INVALID_ENUM:
+      return("ALC_INVALID_ENUM");
+      case ALC_INVALID_VALUE:
+      return ("ALC_INVALID_VALUE");
+      case ALC_OUT_OF_MEMORY:
+      return("ALC_OUT_OF_MEMORY");
+    };
+  }
+}
Index: branches/heathaze/src/lib/sound/sound_engine.h
===================================================================
--- branches/heathaze/src/lib/sound/sound_engine.h	(revision 9940)
+++ branches/heathaze/src/lib/sound/sound_engine.h	(revision 9940)
@@ -0,0 +1,85 @@
+/*!
+ * @file sound_engine.h
+ * Definition of the SoundEngine singleton Class
+ */
+
+#ifndef _SOUND_ENGINE_H
+#define _SOUND_ENGINE_H
+
+#include "base_object.h"
+#include "alincl.h"
+
+#include "sound_buffer.h"
+#include "sound_source.h"
+
+#include <list>
+#include <stack>
+#include "threading.h"
+
+#define SOUND_DOPPLER_FACTOR       0.001          //!< A factor for the audible doppler effect
+#define SOUND_DOPPLER_VELOCITY     500            //!< A factor for the TravelSpeed of sound
+
+// FORWARD DECLARATION
+class PNode;
+namespace OrxSound
+{
+  //! A class that handles audio via the openAudioLibrary
+  class SoundEngine : public BaseObject
+  {
+    ObjectListDeclaration(SoundEngine);
+    public:
+    virtual ~SoundEngine();
+    /** @returns a Pointer to the only object of this Class */
+    inline static SoundEngine* getInstance() { if (!SoundEngine::singletonRef) SoundEngine::singletonRef = new SoundEngine();  return SoundEngine::singletonRef; };
+
+    SoundSource* createSource(const std::string& fileName, PNode* sourceNode = NULL);
+    void loadSettings();
+    bool initAudio();
+
+    /** @param listener the listener in the scene */
+    void setListener(const PNode* listener) { this->listener = listener; };
+    void setDopplerValues(ALfloat dopplerFactor, ALfloat dopplerVelocity);
+
+
+
+    /** @returns the Music Volume in % */
+    inline float getMusicVolume() { return this->musicVolume; };
+    /** @returns the Effects Volume in % */
+    inline float getEffectsVolume() { return this->effectsVolume; };
+
+    void update();
+
+    // administrative
+    void popALSource(ALuint& source);
+    void pushALSource(ALuint& source);
+
+    // error handling:
+    static bool checkError(const std::string& error, unsigned int line);
+    bool checkALCError(const std::string& error, unsigned int line);
+    static const char* getALErrorString(ALenum err);
+    static const char* getALCErrorString(ALenum err);
+
+  private:
+    SoundEngine();
+    bool allocateSources(unsigned int count);
+
+    void listDevices();
+
+  private:
+    static SoundEngine*            singletonRef;             //!< Reference to this class
+
+    ALCdevice*                     device;                   //!< the used audio-device.
+    ALCcontext*                    context;                  //!< the context, currently in use.
+
+    float                          musicVolume;              //!< the maximum volume of the music in % (0f,1f]
+    float                          effectsVolume;            //!< the maximum volume of sound-effects in % (0f,1f]
+    const PNode*                   listener;                 //!< The listener of the Scene
+
+    unsigned int                   maxSourceCount;           //!< How many Sources is the Maximum
+    std::stack<ALuint>             ALSources;                //!< A list of real openAL-Sources, the engine allocates, and stores for reuse.
+
+    SDL_mutex*                     sourceMutex;              //!< A mutex so we can not harm the stack
+  };
+}
+
+#endif /* _SOUND_ENGINE_H */
Index: branches/heathaze/src/lib/sound/sound_source.cc
===================================================================
--- branches/heathaze/src/lib/sound/sound_source.cc	(revision 9940)
+++ branches/heathaze/src/lib/sound/sound_source.cc	(revision 9940)
@@ -0,0 +1,369 @@
+/*
+  orxonox - the future of 3D-vertical-scrollers
+
+  Copyright (C) 2004 orx
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+  ### File Specific:
+  main-programmer: Benjamin Grauer
+  co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SOUND
+
+#include "sound_source.h"
+#include "sound_engine.h"
+
+#include "compiler.h"
+#include "debug.h"
+
+namespace OrxSound
+{
+  ObjectListDefinition(SoundSource);
+  /**
+  * @brief creates a SoundSource at position sourceNode with the SoundBuffer buffer
+  */
+  SoundSource::SoundSource(const PNode* sourceNode, const SoundBuffer& buffer)
+  {
+    this->registerObject(this, SoundSource::_objectList);
+    // adding the Source to the SourcesList of the SoundEngine
+    this->buffer = buffer;
+    this->sourceNode = sourceNode;
+    this->resident = false;
+
+    this->sourceID = 0;
+    this->bPlay = false;
+  }
+
+
+  /**
+  * @brief construct a SoundSource out of the another soundSource
+  * @param source the Source to create this source from.
+  *
+  * Copies the buffer from source to this Source.
+  * Acquires a new SourceID if source is Playing.
+  */
+  SoundSource::SoundSource(const SoundSource& source)
+  {
+    this->registerObject(this, SoundSource::_objectList);
+
+    // adding the Source to the SourcesList of the SoundEngine
+    this->buffer = source.buffer;
+    this->sourceNode = source.sourceNode;
+    this->resident = source.resident;
+
+    this->sourceID = 0;
+    if (source.bPlay == true)
+    {
+      this->bPlay = true;
+      SoundEngine::getInstance()->popALSource(this->sourceID);
+    }
+    else
+      this->bPlay = false;
+  }
+
+
+  /**
+  * @brief paste a copy of the source into this Source.
+  * @param source the SoundSource to paste into this one.
+  * @returns a Reference to this Source.
+  *
+  */
+  SoundSource& SoundSource::operator=(const SoundSource& source)
+  {
+    this->buffer = source.buffer;
+    this->sourceNode = sourceNode;
+    this->resident = source.resident;
+
+    if (source.bPlay)
+      this->play();
+    else
+      this->stop();
+
+    return *this;
+  }
+
+
+  /**
+  * @brief compares two Sources with each other.
+  * @param source the Source to compare against this One.
+  * Two Sources are the same, if the PNodes match, and the Sound Played are the same.
+  * The alSource must not match, because no two Sources can have the same alSource.
+  */
+  bool SoundSource::operator==(const SoundSource& source)
+  {
+    return (this->buffer == source.buffer &&
+            this->bPlay == source.bPlay &&
+            this->sourceNode == source.sourceNode);
+  }
+
+
+  /**
+  * @brief deletes a SoundSource
+  */
+  SoundSource::~SoundSource()
+  {
+    this->stop();
+    if (this->sourceID != 0)
+      SoundEngine::getInstance()->pushALSource(this->sourceID);
+  }
+
+
+  /**
+  * @brief Plays back a SoundSource
+  */
+  void SoundSource::play()
+  {
+    if (this->retrieveSource())
+    {
+      if (this->bPlay)
+        alSourceStop(this->sourceID);
+
+      alSourcei (this->sourceID, AL_BUFFER, this->buffer.getID());
+      alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
+      alSourcef (this->sourceID, AL_GAIN, 1);
+      alSourcePlay(this->sourceID);
+
+      if (DEBUG_LEVEL >= 3)
+        SoundEngine::checkError("Play Source", __LINE__);
+      this->bPlay = true;
+    }
+  }
+
+
+  /**
+  * @brief Plays back buffer on this Source
+  * @param buffer the buffer to play back on this Source
+  */
+  void SoundSource::play(const SoundBuffer& buffer)
+  {
+    if (!this->retrieveSource())
+    {
+      PRINTF(3)("No more Free sources (You might consider raising the Source-Count).\n");
+      return;
+    }
+
+    alSourceStop(this->sourceID);
+    alSourcei (this->sourceID, AL_BUFFER, buffer.getID());
+    alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
+    alSourcef (this->sourceID, AL_GAIN, 1);
+
+    alSourcePlay(this->sourceID);
+
+    if (unlikely(this->buffer.getID() != 0))
+      alSourcei (this->sourceID, AL_BUFFER, this->buffer.getID());
+    this->bPlay = true;
+
+    if (DEBUG_LEVEL >= 3)
+      SoundEngine::checkError("Play Source", __LINE__);
+  }
+
+
+  /**
+   * @brief Plays back buffer on this Source with gain
+   * @param buffer the buffer to play back on this Source
+   * @param gain the gain of the sound buffer
+  */
+  void SoundSource::play(const SoundBuffer& buffer, float gain)
+  {
+    if (!this->retrieveSource())
+    {
+      PRINTF(3)("No more Free sources (You might consider raising the Source-Count).\n");
+      return;
+    }
+
+    alSourceStop(this->sourceID);
+    alSourcei (this->sourceID, AL_BUFFER, buffer.getID());
+    alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
+    alSourcef (this->sourceID, AL_GAIN, gain);
+
+    alSourcePlay(this->sourceID);
+
+    if (unlikely(this->buffer.getID() != 0))
+      alSourcei (this->sourceID, AL_BUFFER, this->buffer.getID());
+    this->bPlay = true;
+
+    if (DEBUG_LEVEL >= 3)
+      SoundEngine::checkError("Play Source", __LINE__);
+  }
+
+  /**
+   * @brief Plays back buffer on this Source with gain and looping possibility
+   * @param buffer the buffer to play back on this Source
+   *  @param gain the gain of the sound buffer
+   * @param loop if true, sound gets looped
+   */
+  void SoundSource::play(const SoundBuffer& buffer, float gain, bool loop)
+  {
+    if (!this->retrieveSource())
+    {
+      PRINTF(3)("No more Free sources (You might consider raising the Source-Count).\n");
+      return;
+    }
+
+    alSourceStop(this->sourceID);
+    alSourcei (this->sourceID, AL_BUFFER, buffer.getID());
+
+    if (loop)
+      alSourcei (this->sourceID, AL_LOOPING,  AL_TRUE);
+    else
+      alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
+
+    alSourcef (this->sourceID, AL_GAIN, gain);
+
+    alSourcePlay(this->sourceID);
+
+    if (unlikely(this->buffer.getID() != 0))
+      alSourcei (this->sourceID, AL_BUFFER, this->buffer.getID());
+    this->bPlay = true;
+
+    if (DEBUG_LEVEL >= 3)
+      SoundEngine::checkError("Play Source", __LINE__);
+  }
+
+  /**
+   * @brief Changes the volume of an (active) buffer
+   * @param buffer the buffer to play back on this Source
+   * @param gain the new gain value
+   */
+  void SoundSource::gain(const SoundBuffer& buffer, float gain)
+  {
+    // alSourcei (this->sourceID, AL_BUFFER, buffer->getID());
+    alSourcef (this->sourceID, AL_GAIN, gain);
+  }
+
+  /**
+   * @brief Stops playback of a SoundSource
+   */
+  void SoundSource::stop()
+  {
+    this->bPlay = false;
+    if (this->sourceID != 0)
+    {
+      this->bPlay = false;
+      if (this->sourceID != 0)
+      {
+        alSourceStop(this->sourceID);
+        if (DEBUG_LEVEL >= 3)
+          SoundEngine::checkError("StopSource", __LINE__);
+        alSourcei(this->sourceID, AL_BUFFER, 0);
+        if (!this->resident)
+          SoundEngine::getInstance()->pushALSource(this->sourceID);
+        this->sourceID = 0;
+      }
+    }
+  }
+
+  /**
+  * @brief Pauses Playback of a SoundSource
+  */
+  void SoundSource::pause()
+  {
+    alSourcePause(this->sourceID);
+    if (DEBUG_LEVEL >= 3)
+      SoundEngine::checkError("Pause Source", __LINE__);
+  }
+
+
+  /**
+  * @brief Rewinds Playback of a SoundSource
+  */
+  void SoundSource::rewind()
+  {
+    alSourceRewind(this->sourceID);
+
+    if (DEBUG_LEVEL >= 3)
+      SoundEngine::checkError("Rewind Source", __LINE__);
+  }
+
+
+  /**
+  * @brief sets the RolloffFactor of the Sound emitted from the SoundSource
+  * @param rolloffFactor The Factor described
+  *
+  * this tells openAL how fast the Sounds decay outward from the Source
+  */
+  void SoundSource::setRolloffFactor(ALfloat rolloffFactor)
+  {
+    alSourcef(this->sourceID, AL_ROLLOFF_FACTOR, rolloffFactor);
+
+    if (DEBUG_LEVEL >= 3)
+      SoundEngine::checkError("Set Source Rolloff-factor", __LINE__);
+  }
+
+
+  /**
+  * @brief sets the Positional this Source should be attached to.
+  * @param sourceNode the Source this is attached to.
+  * If sourceNode == NULL then the Source will be centered, and Audio will be played on all channels.
+  */
+  void SoundSource::setSourceNode(const PNode* sourceNode)
+  {
+    this->sourceNode = sourceNode;
+  }
+
+  /**
+  * @brief retrieve a Source.
+  */
+  bool SoundSource::retrieveSource()
+  {
+    if (this->sourceID != 0)
+      return true;
+    else
+    {
+      SoundEngine::getInstance()->popALSource(this->sourceID);
+      if (this->sourceID != 0)
+      {
+        if (unlikely(this->sourceNode == NULL))
+          resetSource(this->sourceID);
+        return true;
+      }
+    }
+    return false;
+  }
+
+
+  /**
+  * @brief reset an alSource to its default Values.
+  */
+  void SoundSource::resetSource(ALuint sourceID)
+  {
+    alSource3f(sourceID, AL_POSITION,        0.0, 0.0, 0.0);
+    alSource3f(sourceID, AL_VELOCITY,        0.0, 0.0, 0.0);
+    alSource3f(sourceID, AL_DIRECTION,       0.0, 0.0, 0.0);
+    alSourcef (sourceID, AL_ROLLOFF_FACTOR,  0.0          );
+    //alSourcei (sourceID, AL_SOURCE_RELATIVE, AL_TRUE      );
+    alSourcef (sourceID, AL_GAIN,            SoundEngine::getInstance()->getEffectsVolume());
+  }
+
+
+  /**
+  * @brief Fades in a Source over a time period
+  * @param duration time perios to fade in
+  */
+  void SoundSource::fadein(const SoundBuffer& buffer, ALfloat duration)
+  {
+    //if (this->buffer && this->retrieveSource())
+    //{
+
+    for (ALfloat n = 0.0; n < 1.0; n+=.01)
+    {
+      alSourcef(this->sourceID, AL_GAIN, n);
+      // sleep(1);
+    }
+
+    //  alSourcePlay(this->sourceID);
+
+    //  if (DEBUG_LEVEL >= 3)
+    //    SoundEngine::checkError("Loop Source", __LINE__);
+    //  this->bPlay = true;
+    //}
+
+  }
+
+
+}
Index: branches/heathaze/src/lib/sound/sound_source.h
===================================================================
--- branches/heathaze/src/lib/sound/sound_source.h	(revision 9940)
+++ branches/heathaze/src/lib/sound/sound_source.h	(revision 9940)
@@ -0,0 +1,72 @@
+/*!
+* @file sound_source.h
+* @brief Definition of the SoundSource.
+*/
+
+#ifndef _SOUND_SOURCE_H
+#define _SOUND_SOURCE_H
+
+#include "base_object.h"
+#include "sound_buffer.h"
+#include "alincl.h"
+
+// FORWARD DECLARATION
+class PNode;
+namespace OrxSound
+{
+  //! A class that represents a SoundSource
+  class SoundSource : public BaseObject
+  {
+    ObjectListDeclaration(SoundSource);
+  public:
+    SoundSource(const PNode* sourceNode = NULL, const SoundBuffer& buffer = SoundBuffer());
+    SoundSource(const SoundSource& source);
+    SoundSource& operator=(const SoundSource& source);
+    bool operator==(const SoundSource& source);
+
+    virtual ~SoundSource();
+
+    // user interaction
+    void play();
+    void play(const SoundBuffer& buffer);
+    void play(const SoundBuffer& buffer, float gain);
+    void play(const SoundBuffer& buffer, float gain, bool loop);
+
+    void gain(const SoundBuffer& buffer, float gain);
+
+    void stop();
+    void pause();
+    void rewind();
+    void fadein(const SoundBuffer& buffer, ALfloat duration);
+
+    // development functions
+    /** @returns The ID of this Source */
+    inline ALuint getID() const { return this->sourceID; };
+    /** @returns true, if the Source is Playing */
+    inline bool isPlaying() const { return this->bPlay; };
+    void setSourceNode(const PNode* sourceNode);
+    /** @returns the SoundBuffer of this Source */
+    inline const SoundBuffer& getBuffer() const { return this->buffer; };
+    /** @returns the SourceNode of this Source */
+    inline const PNode* getNode() const { return this->sourceNode; };
+    /** @param resident if the Source is Resident */
+    inline void setResident(bool resident) { this->resident = resident; };
+    /** @returns true if the alSource is Resident */
+    inline bool isResident() const { return this->resident; };
+
+    void setRolloffFactor(ALfloat rolloffFactor);
+
+    static void resetSource(ALuint sourceID);
+
+  private:
+    bool                   retrieveSource();
+
+  private:
+    bool                   bPlay;       //!< If the Source is Playing.
+    bool                   resident;    //!< If the alSource should be resident (if true, the alSource will be returned on deletion).
+    ALuint                 sourceID;    //!< The ID of the Source
+    SoundBuffer            buffer;      //!< The buffer to play in this source.
+    const PNode*           sourceNode;  //!< The SourceNode representing the position/velocity... of this source.
+  };
+}
+#endif /* _SOUND_SOURCE_H */
Index: branches/heathaze/src/lib/util/Makefile.am
===================================================================
--- branches/heathaze/src/lib/util/Makefile.am	(revision 9940)
+++ branches/heathaze/src/lib/util/Makefile.am	(revision 9940)
@@ -0,0 +1,80 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = \
+		libORXlibutil.a \
+		libORXexecutor.a
+
+libORXexecutor_a_SOURCES = \
+		executor/executor_substring.cc
+
+libORXlibutil_a_SOURCES = \
+		substring.cc \
+		color.cc \
+		helper_functions.cc \
+		multi_type.cc \
+		debug_buffer.cc \
+		\
+		loading/resource_manager.cc \
+		loading/resource.cc \
+		loading/game_loader.cc \
+		loading/load_param.cc \
+		loading/load_param_description.cc \
+		loading/load_param_class_description.cc \
+		loading/factory.cc \
+		loading/fast_factory.cc \
+		\
+		filesys/file.cc \
+		filesys/directory.cc \
+		filesys/net_link.cc \
+		\
+		threading.cc \
+		timer.cc
+
+#		loading/dynamic_loader.cc
+
+
+noinst_HEADERS = \
+		substring.h \
+		multi_type.h \
+		color.h \
+		helper_functions.h \
+		debug.h \
+		debug_buffer.h \
+		\
+		\
+		executor/executor.h \
+		executor/executor_xml.h \
+		executor/executor_substring.h \
+		executor/executor_generic.h \
+		executor/executor_member.h \
+		executor/executor_const_member.h \
+		executor/executor_static.h \
+		\
+		executor/functor_list.h \
+		executor/functor_generic.h \
+		executor/functor_member.h \
+		executor/functor_const_member.h \
+		executor/functor_static.h \
+		\
+		\
+		filesys/file.h \
+		filesys/directory.h \
+		filesys/net_link.h \
+		\
+		threading.h \
+		timer.h \
+		\
+		loading/resource_manager.h \
+		loading/resource.h \
+		loading/game_loader.h \
+		loading/load_param.h \
+		loading/load_param_xml.h \
+		loading/load_param_description.h \
+		loading/load_param_class_description.h \
+		loading/factory.h \
+		loading/fast_factory.h \
+		loading/dynamic_loader.h \
+		\
+		count_pointer.h \
+		list.h
Index: branches/heathaze/src/lib/util/color.cc
===================================================================
--- branches/heathaze/src/lib/util/color.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/color.cc	(revision 9940)
@@ -0,0 +1,263 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "color.h"
+#include <stdio.h>
+
+
+//! Red Color
+const Color Color::red(1,0,0, 1);
+//! Green Color
+const Color Color::green(0,1,0, 1) ;
+//! blue Color
+const Color Color::blue(0,0,1, 1);
+//! White Color
+const Color Color::white(1,1,1, 1);
+//! Black Color
+const Color Color::black(0,0,0,1);
+
+/**
+ * @brief slerps the Color in the HSV color space into the direction of c
+ * @param c the Color to slerp to
+ * @param v the Value to slerp 0 means stay at *this, 1 means at c.
+ */
+void Color::slerpHSV(const Color& c, float v)
+{
+  this->a() += (c.a() - this->a()) * v;
+  Vector from(r(), g(), b());
+  Vector to(c.r(), c.g(), c.b());
+
+  from = RGBtoHSV(from);
+  to = RGBtoHSV(to);
+
+  from += (to - from) * v;
+
+  to = HSVtoRGB(from);
+
+  this->r() = to.x;
+  this->g() = to.y;
+  this->b() = to.z;
+}
+
+/**
+ * @brief simple slerp wrapper.
+ * @param from from this color
+ * @param to to this one
+ * @param v how much
+ * @see void Color::slerpHSV(const Color& c, float v)
+ */
+Color Color::slerpHSVColor(const Color& from, const Color& to, float v)
+{
+  Color fromColor(from);
+  fromColor.slerpHSV(to, v);
+  return fromColor;
+}
+
+/**
+ * @brief nice and simple debug output for the colors (colorless :) )
+ */
+void Color::debug() const
+{
+  printf("r:%0.2f g:%0.2f, b:%0.2f, a:%0.2f\n", r(), g(), b(), a());
+}
+
+
+
+/**
+ * @brief transforms from RGB to HSVtoRGB
+ * @param RGB: the RGB-color [0-1]
+ * @returns HSV: with values (h[0-360(degree)],s[0,1],v[0,1])
+ */
+Vector Color::RGBtoHSV(const Vector& RGB)
+{
+  Vector HSV;
+  RGBtoHSV(RGB, HSV);
+  return HSV;
+}
+
+/**
+ * @brief transforms from RGB to HSVtoRGB
+ * @param RGB: the RGB-color [0-1]
+ * @param HSV: with values (h[0-360(degree)],s[0,1],v[0,1])
+ */
+void Color::RGBtoHSV(const Vector& RGB, Vector& HSV)
+{
+  float r = RGB.x;
+  float g = RGB.y;
+  float b = RGB.z;
+
+  float h=0,s=1.0,v=1.0;
+  float max_v,min_v,diff,r_dist,g_dist,b_dist;
+  float undefined = 0.0;
+
+  max_v = maxrgb(r,g,b);
+  min_v = minrgb(r,g,b);
+  diff = max_v - min_v;
+  v = max_v;
+
+  if( max_v != 0 )
+    s = diff/max_v;
+  else
+    s = 0.0;
+  if( s == 0 )
+    h = undefined;
+  else
+  {
+    r_dist = (max_v - r)/diff;
+    g_dist = (max_v - g)/diff;
+    b_dist = (max_v - b)/diff;
+    if( r == max_v )
+      h = b_dist - g_dist;
+    else
+      if( g == max_v )
+        h = 2 + r_dist - b_dist;
+      else
+        if( b == max_v )
+          h = 4 + g_dist - r_dist;
+        else
+          printf("rgb2hsv::How did I get here?\n");
+    h *= 60.;
+    if( h < 0)
+      h += 360.0;
+  }
+  HSV = Vector(h, s, v);
+}
+
+/**
+ * @brief converts a Color from HSV to RGBtoHSV
+ * @param HSV: Vector with values (h[0-360(degree)],s[0,1],v[0,1])
+ * @returns RGB: Vector [0-1]
+ */
+Vector Color::HSVtoRGB(const Vector& HSV)
+{
+  Vector RGB;
+  HSVtoRGB(HSV, RGB);
+  return RGB;
+}
+
+/**
+ * @brief converts a Color from HSV to RGBtoHSV
+ * @param HSV: Vector with values (h[0-360(degree)],s[0,1],v[0,1])
+ * @param RGB: Vector [0-1]
+ */
+void Color::HSVtoRGB(const Vector& HSV, Vector& RGB)
+{
+  float h = HSV.x;
+  float s = HSV.y;
+  float v = HSV.z;
+  float r=0, g=0, b=0;
+  float f,p,q,t;
+  int i;
+
+  if( s == 0 )
+  {
+    r = v;
+    g = v;
+    b = v;
+  }
+  else
+  {
+    if(h >= 360.)
+      h = h - (float)((int)(ceilf(h) / 360.0));
+    h /= 60.;
+    i = (int) h;
+    f = h - i;
+    p = v*(1-s);
+    q = v*(1-(s*f));
+    t = v*(1-s*(1-f));
+    switch(i)
+    {
+      case 0:
+        r = v;
+        g = t;
+        b = p;
+        break;
+      case 1:
+        r = q;
+        g = v;
+        b = p;
+        break;
+      case 2:
+        r = p;
+        g = v;
+        b = t;
+        break;
+      case 3:
+        r = p;
+        g = q;
+        b = v;
+        break;
+      case 4:
+        r = t;
+        g = p;
+        b = v;
+        break;
+      case 5:
+        r = v;
+        g = p;
+        b = q;
+        break;
+      default:
+        r = 1.0;
+        g = 1.0;
+        b = 1.0;
+        //printf("hsv2rgb::How did I get here?\n");
+        // printf("h: %f, s: %f, v: %f; i:  %d\n",hin,s,v,i);
+        break;
+    }
+  }
+  RGB = Vector(r,g,b);
+}
+
+
+/**
+ * @returns the maximum of r g and a.
+ * @param r Red.
+ * @param g Green
+ * @param b Blue
+ */
+float Color::maxrgb(float r, float g, float b)
+{
+  float max;
+  if( r > g)
+    max = r;
+  else
+    max = g;
+  if( b > max )
+    max = b;
+  return( max );
+}
+
+/**
+ * @returns the minimum of r g and a.
+ * @param r Red.
+ * @param g Green
+ * @param b Blue
+ */
+float Color::minrgb(float r,float g,float b)
+{
+  float min;
+
+  if( r < g)
+    min = r;
+  else
+    min = g;
+  if( b < min )
+    min = b;
+  return( min );
+}
+
Index: branches/heathaze/src/lib/util/color.h
===================================================================
--- branches/heathaze/src/lib/util/color.h	(revision 9940)
+++ branches/heathaze/src/lib/util/color.h	(revision 9940)
@@ -0,0 +1,116 @@
+/*!
+ * @file color.h
+ * @brief Definition of color-calculations
+ *
+ * TODO CONVERT THE VECTORS to COLORS!!
+ *
+ * code borrowed from:
+ * http://www.easyrgb.com/math.php
+*/
+
+#ifndef _COLOR_H
+#define _COLOR_H
+
+#include "vector.h"
+
+//! A Class that handles Colors.
+/**
+ * A Color is a collection of 4 values:
+ * <ul>
+ *  <li>Red</li>
+ *  <li>Green</li>
+ *  <li>Blue</li>
+ *  <li>Alpha</li>
+ * </ul>
+ * With these four values any color of the entire spectrum can be defined.
+ *
+ * By default a Color lies between 0 and 1 for each component.
+ * for example [1,0,0,.5] means red and half visible.
+ */
+class Color
+{
+public:
+  /** @param r red, @param g green @param b blue @param a alpha @brief constructs a Color. */
+  Color(float r = 0.0f, float g = 0.0f, float b = 0.0f, float a = 1.0f) { _rgba[0] = r; _rgba[1] = g; _rgba[2] = b; _rgba[3] = a; };
+  /** @param c Color @brief copy constructor */
+  Color(const Color& c) { _rgba[0] = c.r(); _rgba[1] = c.g(); _rgba[2] = c.b(); _rgba[3] = c.a(); }
+
+  /** @param c the Color to set to this color @returns the copied color */
+  inline const Color& operator=(const Color& c) { _rgba[0] = c.r(); _rgba[1] = c.g(); _rgba[2] = c.b(); _rgba[3] = c.a(); return *this; };
+  /** @param c the color to compare @returns true on match. @brief compares two colors */
+  inline bool operator==(const Color& c) const { return (r() == c.r() && g() == c.g() && b() == c.b() && a() == c.a()); };
+
+  /** @returns the i'th Value of the Color @param i part of the color 0:r, 1:g, 2:b, 3:a */
+  inline float& operator[](unsigned int i) { return _rgba[i]; }
+  /** @returns a Constant Value of the color. @param i part of the color 0:r, 1:g, 2:b, 3:a */
+  inline const float& operator[](unsigned int i) const { return _rgba[i]; }
+
+  /** @returns the red part. */
+  inline float r() const { return _rgba[0]; }
+  /** @returns the reference to the red part */
+  inline float& r() { return _rgba[0]; }
+  /** @returns the green part. */
+  inline float g() const { return _rgba[1]; }
+  /** @returns the reference to the green part */
+  inline float& g() { return _rgba[1]; }
+  /** @returns the blue part */
+  inline float b() const { return _rgba[2]; }
+  /** @returns the reference to the blue part */
+  inline float& b() { return _rgba[2]; }
+  /** @returns the alpha part */
+  inline float a() const { return _rgba[3]; }
+  /** @returns the reference to the alpha part */
+  inline float& a() { return _rgba[3]; }
+
+
+  /** @param r red, @param g green @param b blue @param a alpha @brief sets the color. */
+  void setColor(float r = 0.0f, float g = 0.0f, float b = 0.0f, float a = 1.0f) { _rgba[0] = r; _rgba[1] = g; _rgba[2] = b; _rgba[3] = a; };
+  /** @param c the color to set. @brief sets the color. */
+  void setColor(const Color& c) { r() = c.r();  g()= c.g(); b() = c.b(); a() = c.a(); };
+
+  /** @returns the distance to the color @param c the color to calculate the distance to. */
+  inline float dist(const Color& c) const { return (sqrt((r()-c.r())*(r()-c.r()) + (g()-c.g())*(g()-c.g()) + (b()-c.b())*(b()-c.b()) + (a()-c.a())*(a()-c.a()))); }
+  /// Maths
+  /** @param c the color to add to this one @returns the two added colors */
+  inline const Color& operator+=(const Color& c) { r()+=c.r(); g()+=c.g(); b()+=c.b(); a()+=c.a(); return *this; };
+  /** @returns the result of the added colors @param c the color to add */
+  inline Color operator+(const Color& c) const { return Color(r()+c.r(), g()+c.g(), b()+c.b(), a()+c.a()); };
+  /** @param c the color to substract to this one @returns the two substracted colors */
+  inline const Color& operator-=(const Color& c) { r()-=c.r(); g()-=c.g(); b()-=c.b(); a()-=c.a(); return *this; };
+  /** @returns the result of the substracted colors @param c the color to substract */
+  inline Color operator-(const Color& c) const { return Color(r()-c.r(), g()-c.g(), b()-c.b(), a()-c.a()); };
+  /** @param v the multiplier @returns the Color multiplied by v */
+  inline const Color& operator*=(float v) { r()*=v, g()*=v, b()*=v, a()*=v; return *this; };
+  /** @param v the multiplier @returns a multiplied color */
+  inline Color operator*(float v) const { return Color(r()*v, g()*v, b()*v, a()*v); };
+
+  /** @param c the color to slerp to @param v how much to slerp [0:1] @brief moves the color into the direction of another color */
+  void slerp(const Color& c, float v) { *this += (c - *this) * v; };
+  void slerpHSV(const Color& c, float v);
+  static Color slerpHSVColor(const Color& from, const Color& to, float v);
+
+  void debug() const;
+
+  /// STATIC TRANSFORMATIONS
+public:
+  static Vector RGBtoHSV (const Vector& RGB);
+  static void RGBtoHSV (const Vector& RGB, Vector& HSV);
+  static Vector HSVtoRGB (const Vector& HSV);
+  static void HSVtoRGB (const Vector& HSV, Vector& RGB);
+
+private:
+  static float minrgb(float r, float g, float b);
+  static float maxrgb(float r, float g, float b);
+
+public:
+  static const Color red;
+  static const Color green;
+  static const Color blue;
+  static const Color white;
+  static const Color black;
+
+private:
+  float       _rgba[4]; //!< Color Values [r,g,b,a] (red green blue alpha)
+};
+
+#endif /* _COLOR_H */
Index: branches/heathaze/src/lib/util/count_pointer.h
===================================================================
--- branches/heathaze/src/lib/util/count_pointer.h	(revision 9940)
+++ branches/heathaze/src/lib/util/count_pointer.h	(revision 9940)
@@ -0,0 +1,63 @@
+/*!
+ * @file count_pointer.h Contains the Counted Pointer Class, that points to Member-Objects.
+ */
+
+#ifndef _COUNT_POINTER_H
+#define _COUNT_POINTER_H
+
+template <typename X> class CountPointer
+{
+public:
+  explicit CountPointer(X* p = NULL) // allocate a new counter
+      : itsCounter(NULL) { if (p) itsCounter = new counter(p); }
+  ~CountPointer() { release(); }
+  CountPointer(const CountPointer& r) { acquire(r.itsCounter); }
+  CountPointer& operator=(const CountPointer& r)
+  {
+    if (this != &r)
+    {
+      release();
+      acquire(r.itsCounter);
+    }
+    return *this;
+  }
+  bool operator==(const CountPointer& r) const { return this->itsCounter->ptr == r.itsCounter->ptr; };
+  inline X& operator*()  const { return *itsCounter->ptr; }
+  inline X* operator->() const { return itsCounter->ptr; }
+  inline bool unique()   const { return (itsCounter ? itsCounter->count == 1 : true); }
+  inline bool isNull()   const { return (!itsCounter); }
+
+  unsigned int count() const { return (this->itsCounter ? itsCounter->count : 0); }
+private:
+
+  struct counter
+  {
+    counter(X* p = NULL, unsigned c = 1) : ptr(p), count(c) {}
+    X*          ptr;
+    unsigned    count;
+  }
+  * itsCounter;
+
+  void acquire(counter* c)
+  {
+    // increment the count
+    itsCounter = c;
+    if (c) ++c->count;
+  }
+
+  void release()
+  {
+    // decrement the count, delete if it is 0
+    if (itsCounter)
+    {
+      if (--itsCounter->count == 0)
+      {
+        delete itsCounter->ptr;
+        delete itsCounter;
+      }
+      itsCounter = NULL;
+    }
+  }
+};
+
+#endif /* _COUNT_POINTER_H */
Index: branches/heathaze/src/lib/util/debug.h
===================================================================
--- branches/heathaze/src/lib/util/debug.h	(revision 9940)
+++ branches/heathaze/src/lib/util/debug.h	(revision 9940)
@@ -0,0 +1,313 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file debug.h
+ * @briefHandles output to console for different Verbose-Modes.
+ *
+ * There are two main modes HARD and SOFT. HARD is precessed during compileTime where SOFT is for runtime.
+ * @li HARD: One can choose between different modes. see: // DEFINE_MODULES
+ * @li SOFT: If you want each module can have its own variable for processing. just pass it to DEBUG_MODULE_SOFT
+ */
+
+#ifndef _DEBUG_H
+#define _DEBUG_H
+
+#include "defs/confincl.h"
+#ifndef NO_BUFFER
+#include "debug_buffer.h"
+#endif /* NO_BUFFER */
+
+#include <stdio.h>
+
+// DEFINE ERROR MODES
+#define ORX_NONE            0
+#define ORX_ERR             1
+#define ORX_WARN            2
+#define ORX_INFO            3
+#define ORX_DEBUG           4
+#define ORX_vDEBUG          5
+
+extern int verbose;
+
+//definitions
+#ifndef MODULAR_DEBUG
+ #define HARD_DEBUG_LEVEL ORX_DEBUG
+ #define SOFT_DEBUG_LEVEL verbose
+#else /* MODULAR_DEBUG */
+ #ifndef DEBUG_MODULE_SOFT
+  #define SOFT_DEBUG_LEVEL verbose
+ #else /* DEBUG_MODULE_SOFT */
+  #define SOFT_DEBUG_LEVEL DEBUG_MODULE_SOFT
+ #endif /* DEBUG_MODULE_SOFT */
+
+ #ifndef DEBUG_SPECIAL_MODULE
+  #define HARD_DEBUG_LEVEL DEBUG
+ #else /* DEBUG_SPECIAL_MODULE */
+  ////////////////////
+  // DEFINE MODULES //
+  ////////////////////
+  // FRAMEWORK
+  #define DEBUG_MODULE_BASE                  2
+  #define DEBUG_MODULE_ORXONOX               2
+  #define DEBUG_MODULE_WORLD                 2
+  #define DEBUG_MODULE_NETWORK               2
+
+  // LOADING
+  #define DEBUG_MODULE_LOAD                  2
+  #define DEBUG_MODULE_IMPORTER              2
+
+  // ENGINES
+  #define DEBUG_MODULE_GRAPHICS              2
+  #define DEBUG_MODULE_EVENT                 2
+  #define DEBUG_MODULE_PHYSICS               2
+  #define DEBUG_MODULE_GARBAGE_COLLECTOR     2
+  #define DEBUG_MODULE_OBJECT_MANAGER        2
+  #define DEBUG_MODULE_ANIM                  2
+  #define DEBUG_MODULE_COLLISION_DETECTION   2
+  #define DEBUG_MODULE_COLLISION_REACTION    2
+  #define DEBUG_MODULE_SPATIAL_SEPARATION    2
+  #define DEBUG_MODULE_GUI                   2
+  #define DEBUG_MODULE_SOUND                 2
+
+  // MISC
+  #define DEBUG_MODULE_TRACK_MANAGER         2
+  #define DEBUG_MODULE_MATH                  2
+
+  #define DEBUG_MODULE_PNODE                 2
+  #define DEBUG_MODULE_WORLD_ENTITY          2
+
+  #define DEBUG_MODULE_STORY_ENTITY          2
+  #define DEBUG_MODULE_GAME_RULES            2
+
+  #define DEBUG_MODULE_WEAPON                2
+
+  #define HARD_DEBUG_LEVEL DEBUG_SPECIAL_MODULE
+
+ #endif /* DEBUG_SPECIAL_MODULE */
+#endif /* MODULAR_DEBUG */
+
+///////////////////////////////////////////////////
+/// PRINTF: prints with filename and linenumber ///
+///////////////////////////////////////////////////
+#define PRINTFORX_NONE    PRINTF0
+#define PRINTFORX_ERR     PRINTF1
+#define PRINTFORX_WARN    PRINTF2
+#define PRINTFORX_INFO    PRINTF3
+#define PRINTFORX_DEBUG   PRINTF4
+#define PRINTFORX_VDEBUG  PRINTF5
+
+#if DEBUG_LEVEL <= 3
+#define PRINTF(x)        PRINT(x)
+#endif
+#ifndef NO_SHELL
+#define PRINT_EXEC       DebugBuffer::addBufferLineStatic
+#define COUT_EXEC        std::cout
+#else /* NO_SHELL */
+#define PRINT_EXEC       printf
+#define COUT_EXEC        std::cout
+#endif
+
+#ifndef PRINTF
+#ifdef ORX_DEBUG
+
+#define PRINTF(x) \
+           PRINTF ## x
+
+#if HARD_DEBUG_LEVEL >= ORX_ERR
+#define PRINTF1 \
+    if (SOFT_DEBUG_LEVEL >= ORX_ERR) \
+      printf("(EE)::%s:%d:", __FILE__, __LINE__), PRINT_EXEC
+#else
+#define PRINTF1 if (ORX_NONE) PRINT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_WARN
+#define PRINTF2 \
+     if (SOFT_DEBUG_LEVEL >= ORX_WARN) \
+       printf("(WW)::%s:%d:", __FILE__, __LINE__), PRINT_EXEC
+
+#else
+#define PRINTF2 if (ORX_NONE) PRINT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_INFO
+#define PRINTF3 \
+     if (SOFT_DEBUG_LEVEL >= ORX_INFO) \
+       printf("(II)::%s:%d:", __FILE__, __LINE__), PRINT_EXEC
+#else
+#define PRINTF3 if (ORX_NONE) PRINT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_DEBUG
+#define PRINTF4 \
+     if (SOFT_DEBUG_LEVEL >= ORX_DEBUG) \
+       printf("(DD)::%s:%d:", __FILE__, __LINE__), PRINT_EXEC
+#else
+#define PRINTF4 if (ORX_NONE) PRINT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_vDEBUG
+#define PRINTF5 \
+     if (SOFT_DEBUG_LEVEL >= ORX_vDEBUG) \
+       printf("(VD)::%s:%d:", __FILE__, __LINE__), PRINT_EXEC
+#else
+#define PRINTF5 if (ORX_NONE) PRINT_EXEC
+#endif
+
+#else
+#define PRINTF(x) if (ORX_NONE) PRINT_EXEC
+#endif
+
+#define PRINTF0 \
+    printf("%s:%d::", __FILE__, __LINE__), PRINT_EXEC
+#endif
+
+///////////////////////////////////////////////////
+///  PRINT: just prints output as is            ///
+///////////////////////////////////////////////////
+#define PRINTORX_NONE    PRINT0
+#define PRINTORX_ERR     PRINT1
+#define PRINTORX_WARN    PRINT2
+#define PRINTORX_INFO    PRINT3
+#define PRINTORX_DEBUG   PRINT4
+#define PRINTORX_vDEBUG  PRINT5
+
+#ifdef  DEBUG_LEVEL
+#define PRINT(x) \
+  PRINT ## x
+
+#if HARD_DEBUG_LEVEL >= ORX_ERR
+#define PRINT1  \
+  if (SOFT_DEBUG_LEVEL >= ORX_ERR)  \
+    PRINT_EXEC
+#else
+#define PRINT1 if (ORX_NONE) PRINT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_WARN
+#define PRINT2 \
+  if (SOFT_DEBUG_LEVEL >= ORX_WARN) \
+    PRINT_EXEC
+
+#else
+#define PRINT2 if (ORX_NONE) PRINT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_INFO
+#define PRINT3 \
+  if (SOFT_DEBUG_LEVEL >= ORX_INFO) \
+    PRINT_EXEC
+#else
+#define PRINT3 if (ORX_NONE) PRINT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_DEBUG
+#define PRINT4 \
+  if (SOFT_DEBUG_LEVEL >= ORX_DEBUG) \
+    PRINT_EXEC
+#else
+#define PRINT4 if (ORX_NONE) PRINT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_vDEBUG
+#define PRINT5 \
+     if (SOFT_DEBUG_LEVEL >= ORX_vDEBUG) \
+       PRINT_EXEC
+#else
+#define PRINT5 if (ORX_NONE) PRINT_EXEC
+#endif
+
+
+#else
+#define PRINT(x) if (ORX_NONE) PRINT_EXEC
+#endif
+
+#define PRINT0 \
+  PRINT_EXEC
+
+
+
+////////////////////////////////////////////////////////
+///  COUT: just prints output as is with std::cout   ///
+////////////////////////////////////////////////////////
+#define COUTORX_NONE    COUT0
+#define COUTORX_ERR     COUT1
+#define COUTORX_WARN    COUT2
+#define COUTORX_INFO    COUT3
+#define COUTORX_DEBUG   COUT4
+#define COUTORX_vDEBUG  COUT5
+
+#ifdef  DEBUG_LEVEL
+#define COUT(x) \
+  COUT ## x
+
+#if HARD_DEBUG_LEVEL >= ORX_ERR
+#define COUT1  \
+  if (SOFT_DEBUG_LEVEL >= ORX_ERR)  \
+    COUT_EXEC
+#else
+#define COUT1 if (ORX_NONE)\
+    COUT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_WARN
+#define COUT2 \
+  if (SOFT_DEBUG_LEVEL >= ORX_WARN) \
+    COUT_EXEC
+
+#else
+#define COUT2 if (ORX_NONE) \
+    COUT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_INFO
+#define COUT3 \
+  if (SOFT_DEBUG_LEVEL >= ORX_INFO) \
+    COUT_EXEC
+#else
+#define COUT3 if (ORX_NONE) \
+    COUT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_DEBUG
+#define COUT4 \
+  if (SOFT_DEBUG_LEVEL >= ORX_DEBUG) \
+    COUT_EXEC
+#else
+#define COUT4 if (ORX_NONE) \
+    COUT_EXEC
+#endif
+
+#if HARD_DEBUG_LEVEL >= ORX_vDEBUG
+#define COUT5 \
+     if (SOFT_DEBUG_LEVEL >= ORX_vDEBUG) \
+       COUT_EXEC
+#else
+#define COUT5 if (ORX_NONE) \
+    COUT_EXEC
+#endif
+
+
+#else
+#define COUT(x) if (ORX_NONE) \
+    COUT_EXEC
+#endif
+
+#define COUT0 \
+  COUT_EXEC
+
+
+#endif /* _DEBUG_H */
Index: branches/heathaze/src/lib/util/debug_buffer.cc
===================================================================
--- branches/heathaze/src/lib/util/debug_buffer.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/debug_buffer.cc	(revision 9940)
@@ -0,0 +1,133 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#include "debug_buffer.h"
+
+#include <stdarg.h>
+
+#include "debug.h"
+#include "compiler.h"
+#include "threading.h"
+
+/**
+ * @brief standard constructor
+ */
+DebugBuffer::DebugBuffer ()
+{
+  DebugBuffer::singletonRef = this;
+
+  this->lineCount = 0;
+  this->bufferArray[0] = '\0';
+
+  this->setMaxBufferSize(100);
+}
+
+DebugBuffer* DebugBuffer::singletonRef = NULL;
+std::list<std::string> DebugBuffer::buffer;
+char DebugBuffer::bufferArray[DEBUG_BUFFER_SIZE] = "";
+
+
+/**
+ * @brief standard deconstructor
+ */
+DebugBuffer::~DebugBuffer ()
+{
+  DebugBuffer::singletonRef = NULL;
+}
+
+/**
+ * @brief deletes all the Buffers
+ */
+void DebugBuffer::flush()
+{
+  this->buffer.clear();
+}
+
+/**
+ * @brief adds a new Line to the List of Buffers
+ * @param line the Line as in the first argument in printf
+ */
+void DebugBuffer::addBufferLineStatic(const char* line, ...)
+{
+  static OrxThread::Mutex DebugBuffer__bufferMutex;
+
+  OrxThread::MutexLock bufferLock(&DebugBuffer__bufferMutex);
+
+  va_list arguments;
+  va_start(arguments, line);
+  vsnprintf(DebugBuffer::bufferArray, DEBUG_BUFFER_SIZE, line, arguments);
+  va_end(arguments);
+
+#if DEBUG_LEVEL < 3
+  if (DebugBuffer::singletonRef == NULL)
+#endif
+    printf(DebugBuffer::bufferArray);
+#if DEBUG_LEVEL < 3
+  else
+#else
+  if (DebugBuffer::singletonRef != NULL)
+#endif
+    DebugBuffer::singletonRef->addBufferLine(DebugBuffer::bufferArray);
+}
+
+/**
+ * @brief add a Line to the List of Buffers
+ * @param line
+ * @param arguments
+ *
+ * This function Adds one line to the buffer.
+ * and displays the line as the First Line of the display-buffer
+ */
+void DebugBuffer::addBufferLine(const char* line)
+{
+  std::string inputBuffer = this->keepBuffer + line;
+
+  unsigned int lineBegin = 0;
+  unsigned int lineEnd = 0;
+  // adding all the new Lines
+  while (lineEnd < inputBuffer.size())
+  {
+    lineBegin = lineEnd;
+    lineEnd = inputBuffer.find('\n', (lineBegin == 0) ? 0: ++lineBegin);
+    if (likely(lineEnd != std::string::npos ))
+    {
+      this->lineCount++;
+      this->buffer.push_front(inputBuffer.substr(lineBegin, lineEnd - lineBegin));
+    }
+    else      // No end of Line reached.
+    {
+      this->keepBuffer = inputBuffer.substr(lineBegin, inputBuffer.size() - lineBegin);
+      break;
+    }
+
+    if (inputBuffer[lineBegin] == '\n')
+      lineBegin++, lineEnd++;
+
+    if (this->buffer.size() > this->maxBufferSize)
+      this->buffer.pop_back();
+  }
+}
+
+/**
+ * @brief displays some nice output from the Debug
+ */
+void DebugBuffer::debug() const
+{
+  PRINT(3)("Debugging output to console (not this debug)\n");
+
+  std::list<std::string>::const_iterator bufferLine;
+  for (bufferLine = --this->buffer.end(); bufferLine != this->buffer.begin(); --bufferLine)
+    printf((*bufferLine).c_str());
+}
Index: branches/heathaze/src/lib/util/debug_buffer.h
===================================================================
--- branches/heathaze/src/lib/util/debug_buffer.h	(revision 9940)
+++ branches/heathaze/src/lib/util/debug_buffer.h	(revision 9940)
@@ -0,0 +1,63 @@
+/*!
+ * @file debug_buffer.h
+ * @brief The Debug buffer Tasks
+ * @see debug.h
+*/
+
+#ifndef _DEBUG_BUFFER_H
+#define _DEBUG_BUFFER_H
+
+#include <string>
+#include <list>
+
+#define      DEBUG_BUFFER_SIZE       16384         //!< The Size of the input-buffers (should be large enough to carry any kind of input)
+
+  //! A class handling output from orxonox via debug.h
+  /**
+   * the DebugBuffer redirects output from PRINTF(x) to the Debug and STDOUT
+   * the DebugBuffer is a front-filling queue of limited length, that has the
+   * youngest added Entry at the beginning, and the oldest at the end.
+   */
+  class DebugBuffer
+  {
+  public:
+    virtual ~DebugBuffer();
+    /** @returns a Pointer to the only object of this Class */
+    inline static DebugBuffer* getInstance() { if (!DebugBuffer::singletonRef) DebugBuffer::singletonRef = new DebugBuffer();  return DebugBuffer::singletonRef; };
+    /** @returns true if this class is instanciated, false otherwise */
+    inline static bool isInstanciated() { return (DebugBuffer::singletonRef == NULL)?false:true; };
+
+    static void addBufferLineStatic(const char* line, ...);
+    void addBufferLine(const char* line);
+
+    /// BUFFER
+    /** @param bufferSize the new Buffer-Size */
+    void setMaxBufferSize(unsigned int maxBufferSize) { this->maxBufferSize = maxBufferSize; };
+    void flush();
+
+    /** @returns the List of stings from the Buffer */
+    const std::list<std::string>& getBuffer() const { return this->buffer; };
+    /** @returns the Count of lines processed by the Debug. */
+    inline unsigned long getLineCount() const { return this->lineCount; };
+    /** @returns the Current Buffer Size. */
+    inline unsigned int getBufferSize() const { return this->buffer.size(); };
+
+    void debug() const;
+
+  private:
+    DebugBuffer();
+
+  private:
+    static DebugBuffer*           singletonRef;                       //!< The singleton-reference to the only memeber of this class.
+    unsigned int                  maxBufferSize;                      //!< The Size of the buffer
+
+    std::string                   keepBuffer;                         //!< a BUFFER to have multi-non-newLine commands be copied into the debug.
+
+    unsigned long                 lineCount;                          //!< how many Lines have been written out so far.
+
+    // The Beginning of buffer (buffer.front()) is the last added line.
+    static char                   bufferArray[DEBUG_BUFFER_SIZE];     //!< a BUFFER for fast writing
+    static std::list<std::string> buffer;                             //!< A list of stored char-arrays(strings) to store the history
+  };
+
+#endif /* _DEBUG_BUFFER_H */
Index: branches/heathaze/src/lib/util/executor/executor.h
===================================================================
--- branches/heathaze/src/lib/util/executor/executor.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/executor.h	(revision 9940)
@@ -0,0 +1,218 @@
+/*!
+ * @file executor.h
+ * Definition of an Executor
+ */
+
+#ifndef _EXECUTOR_H
+#define _EXECUTOR_H
+
+#include "base_object.h"
+
+#include "multi_type.h"
+
+//! The maximum Count of Arguments of the Executor
+/** This is Hardcoded, for each Executor. */
+#define EXECUTOR_MAX_ARGUMENTS                7
+
+
+/** @returns the Type of an Argument taken by the Executor */
+template<typename type> inline MT_Type ExecutorParamType() { return MT_EXT1; };
+/** @returns the Type of an Argument taken by the Executor in this case MT_BOOL */
+template<> inline MT_Type ExecutorParamType<bool>() { return MT_BOOL; };
+/** @returns the Type of an Argument taken by the Executor in this case MT_INT*/
+template<> inline MT_Type ExecutorParamType<int>() { return MT_INT; };
+/** @returns the Type of an Argument taken by the Executor in this case MT_UINT*/
+template<> inline MT_Type ExecutorParamType<unsigned int>() { return MT_UINT; };
+/** @returns the Type of an Argument taken by the Executor in this case MT_FLOAT*/
+template<> inline MT_Type ExecutorParamType<float>() { return MT_FLOAT; };
+/** @returns the Type of an Argument taken by the Executor in this case MT_CHAR*/
+template<> inline MT_Type ExecutorParamType<char>() { return MT_CHAR; };
+/** @returns the Type of an Argument taken by the Executor in this case MT_STRING*/
+template<> inline MT_Type ExecutorParamType<const std::string&>() { return MT_STRING; };
+
+////////////////
+// BASE CLASS //
+////////////////
+//! a BaseClass for all possible Executors
+/**
+ * An Executor is an Object, that is able to call Objects of Any type (class)
+ * and execute a function with given parameters on it.
+ *
+ * The Executor is able to handle:
+ *  Objects of any Class (Templated)
+ *  Default Values
+ *  Functions with up to 5 parameters (more seems overhead, split up the function)
+ *  Functions with many types (@see functor_list.h)
+ */
+template <typename CallType, class BaseClass = BaseObject> class Executor
+{
+public:
+  //! an enumerator for the definition of the Type.
+  typedef enum {
+    FunctionMember,      //!< The function is neither Static nor Constant
+    FunctionStatic,      //!< The Function is Static and pointing to either a Static Member or a C-style function.
+    FunctionConstMember, //!< The Function is Constant and pointing to a Member that does not change the Object.
+  } FunctionType;
+
+public:
+  virtual ~Executor() {};
+
+  // RETRIEVE INFORMATION
+  /** @param i the i'th defaultValue, @returns reference to the MultiType */
+  inline MultiType& getDefaultValue(unsigned int i) { return defaultValue[i]; };
+  /** @returns the default Values as a List */
+  inline const MultiType* const getDefaultValues() { return defaultValue; };
+
+  /** @returns the Type of this Function (either static or objective) */
+  inline FunctionType getType() const { return this->functionType; };
+
+  /** @returns the Count of Parameters this Executor takes */
+  inline unsigned int getParamCount() const { return this->paramCount; };
+  /** @returns true if the Executor has a return Value. */
+  inline bool hasRetVal() const { return bRetVal; };
+
+  /** executes a Command. @param object the Object, @param values The Value of type CallType to pass to the Executor. */
+  virtual void operator()(BaseClass* object, CallType& values) const = 0;
+
+  /**
+   * @brief set the default values of the executor
+   * @param value0 the first default value
+   * @param value1 the second default value
+   * @param value2 the third default value
+   * @param value3 the fourth default value
+   * @param value4 the fifth default value
+   * @param value5 the sixth default value
+   * @param value6 the seventh default value
+   * @returns itself
+   * @note: THIS FUNCTION WILL BE REPLACED BY A CONFIGURATOR (most probably).
+  */
+  Executor* defaultValues(const MultiType& value0 = MT_NULL, const MultiType& value1 = MT_NULL,
+                          const MultiType& value2 = MT_NULL, const MultiType& value3 = MT_NULL,
+                          const MultiType& value4 = MT_NULL, const MultiType& value5 = MT_NULL,
+                          const MultiType& value6 = MT_NULL)
+  {
+    const MultiType* value[5];
+    value[0] = &value0;
+    value[1] = &value1;
+    value[2] = &value2;
+    value[3] = &value3;
+    value[4] = &value4;
+    value[5] = &value5;
+    value[6] = &value6;
+    for (unsigned int i = 0; i < this->paramCount; i++)
+    {
+      if (*value[i] != MT_NULL)
+      {
+        this->defaultValue[i].setValueOf(*value[i]);
+        this->defaultValue[i].storeString();
+      }
+    }
+    return this;
+  }
+
+  /** @returns the Clone as a new Copy of the Executor. */
+  virtual Executor<CallType, BaseClass>* clone () const = 0;
+
+
+protected:
+  //! Now follows a List of Executor Constructors, to be fast in creating.
+  //! Creates an Executor with no Argument.
+  Executor(bool hasRetVal, FunctionType functionType = FunctionMember)
+  : bRetVal(hasRetVal), paramCount(0), functionType(functionType)
+  { };
+
+  //! Creates an Executor with 1 Argument.
+  Executor(bool hasRetVal, const MultiType& param0,
+	   FunctionType functionType = FunctionMember)
+  : bRetVal(hasRetVal), paramCount(1), functionType(functionType)
+  {
+    this->defaultValue[0] = param0;
+  };
+
+  //! Creates an Executor with 2 Arguments.
+  Executor(bool hasRetVal, const MultiType& param0, const MultiType& param1,
+	   FunctionType functionType = FunctionMember)
+  : bRetVal(hasRetVal), paramCount(2), functionType(functionType)
+  {
+    this->defaultValue[0] = param0;
+    this->defaultValue[1] = param1;
+  };
+
+  //! Creates an Executor with 3 Arguments.
+  Executor(bool hasRetVal, const MultiType& param0, const MultiType& param1,
+	   const MultiType& param2,
+	   FunctionType functionType = FunctionMember)
+  : bRetVal(hasRetVal), paramCount(3), functionType(functionType)
+  {
+    this->defaultValue[0] = param0;
+    this->defaultValue[1] = param1;
+    this->defaultValue[2] = param2;
+  };
+
+  //! Creates an Executor with 4 Arguments.
+  Executor(bool hasRetVal, const MultiType& param0, const MultiType& param1,
+	   const MultiType& param2, const MultiType& param3,
+	   FunctionType functionType = FunctionMember)
+  : bRetVal(hasRetVal), paramCount(4), functionType(functionType)
+  {
+    this->defaultValue[0] = param0;
+    this->defaultValue[1] = param1;
+    this->defaultValue[2] = param2;
+    this->defaultValue[3] = param3;
+  };
+
+  //! Creates an Executor with 5 Arguments.
+  Executor(bool hasRetVal, const MultiType& param0, const MultiType& param1,
+	   const MultiType& param2, const MultiType& param3,
+	   const MultiType& param4,
+	   FunctionType functionType = FunctionMember)
+  : bRetVal(hasRetVal), paramCount(5), functionType(functionType)
+  {
+    this->defaultValue[0] = param0;
+    this->defaultValue[1] = param1;
+    this->defaultValue[2] = param2;
+    this->defaultValue[3] = param3;
+    this->defaultValue[4] = param4;
+  };
+
+  //! Creates an Executor with 6 Arguments.
+  Executor(bool hasRetVal, const MultiType& param0, const MultiType& param1,
+	   const MultiType& param2, const MultiType& param3,
+	   const MultiType& param4, const MultiType& param5,
+	   FunctionType functionType = FunctionMember)
+  : bRetVal(hasRetVal), paramCount(6), functionType(functionType)
+  {
+    this->defaultValue[0] = param0;
+    this->defaultValue[1] = param1;
+    this->defaultValue[2] = param2;
+    this->defaultValue[3] = param3;
+    this->defaultValue[4] = param4;
+    this->defaultValue[5] = param5;
+  };
+
+  //! Creates an Executor with 7 Arguments.
+  Executor(bool hasRetVal, const MultiType& param0, const MultiType& param1,
+	   const MultiType& param2, const MultiType& param3,
+	   const MultiType& param4, const MultiType& param5,
+	   const MultiType& param6,
+	   FunctionType functionType = FunctionMember)
+  : bRetVal(hasRetVal), paramCount(7), functionType(functionType)
+  {
+    this->defaultValue[0] = param0;
+    this->defaultValue[1] = param1;
+    this->defaultValue[2] = param2;
+    this->defaultValue[3] = param3;
+    this->defaultValue[4] = param4;
+    this->defaultValue[5] = param5;
+    this->defaultValue[6] = param6;
+  };
+
+protected:
+  const bool                  bRetVal;          //!< True if the Executor has a return Value.
+  const unsigned int          paramCount;       //!< the count of parameters.
+  MultiType                   defaultValue[7];  //!< Default Values.
+
+  const FunctionType          functionType;     //!< What Type of Function it is.
+};
+
+#endif /* _EXECUTOR_H */
Index: branches/heathaze/src/lib/util/executor/executor_const_member.h
===================================================================
--- branches/heathaze/src/lib/util/executor/executor_const_member.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/executor_const_member.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file executor_const_member.h
+ * Definition of an Executor to Member Functions
+ */
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+#ifndef __EXECUTOR_CONST_MEMBER_H_
+#define __EXECUTOR_CONST_MEMBER_H_
+
+/// Define all Constructs, that define an Executor.
+//! The Name to be attached to the functional (for normal, static, and const modes)
+#define __EXECUTOR_FUNCTIONAL_NAME(ParamCount, Ext)   Executor##ParamCount##Ext##_const
+
+//! if Functional is constant calling
+#define __EXECUTOR_FUNCTIONAL_CONST              const
+//! The Execution-mode (either static or objective)
+#define __EXECUTOR_FUNCTIONAL_FUNCTION_EXEC      dynamic_cast<T*>(object)->*(functionPointer)
+//! The Function-Pointer, and how to save it internally.
+#define __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER   T::*functionPointer
+//! The Type of Function
+#define __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE       Executor<CallType, BaseClass>::FunctionConstMember
+
+
+/// We want to include __EXECUTOR_GENERIC_H again, with current settings.
+
+#include "executor_generic.h"
+
+#undef __EXECUTOR_FUNCTIONAL_NAME
+
+#undef __EXECUTOR_FUNCTIONAL_CONST
+#undef __EXECUTOR_FUNCTIONAL_FUNCTION_EXEC
+#undef __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER
+#undef __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE
+
+#endif /* __EXECUTOR_CONST_MEMBER_H_ */
Index: branches/heathaze/src/lib/util/executor/executor_generic.h
===================================================================
--- branches/heathaze/src/lib/util/executor/executor_generic.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/executor_generic.h	(revision 9940)
@@ -0,0 +1,456 @@
+/*!
+ * @file executor_generic.h
+ * Definition of a Generic Executor
+ */
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+
+#ifndef __EXECUTOR_GENERIC_H_
+#define __EXECUTOR_GENERIC_H_
+
+
+#include "executor.h"
+/**
+ * @brief this is a Template Class used as an evaluater.
+ *
+ * Trait to determine a default Value for any Type,
+ * and to define the Convertible, and how it is transformed into the
+ * corresponding SubTypes over the operator().
+ *
+ * This Class must be reimplemented for each Convertible and all of its
+ *  conversion-members.
+ *
+ * e.g: Convertible SubSting, that splits up into many Stings
+ *      conversion-members: (int) can be transformed from a String.
+ */
+template<typename FromType> class ExecutorEvaluater
+{
+public:
+  /** @brief Executes the Evaluater
+   * @param CallValue the Value that should be converted
+   * @param defaults the default Values.
+   */
+  template <typename ToType, int index>
+  static ToType getValue(FromType& CallValue, const MultiType* const defaults)
+  {
+    assert(0 && "Might want to extend the ExecutorEvaluater::getValue function in an 'Explicit Specialized Template Class'");
+    return defaultValue;
+  }
+  /** @param @storeTo Stores the returned value here. @param value The Value to Store. @note invers of getValue */
+  static void storeRet(FromType& storeTo, FromType value)
+  {
+    assert (0 && "Might want to extend the ExecutorEvaluater::storeRet function in an 'Explicit Specialized Template Class'");
+  }
+  /** @returns the Default Value of ToType */
+  static FromType& defaultValue() { static FromType defaultValue; return defaultValue; };
+};
+#endif /* __EXECUTOR_GENERIC_H_ */
+
+
+#ifdef __EXECUTOR_FUNCTIONAL_NAME
+///////////
+//// 0 ////
+///////////
+//! @brief ExecutorClass, that can execute Functions without any parameters.
+template<class T, typename CallType, class BaseClass = BaseObject, template<typename> class Evaluater = ExecutorEvaluater>
+class __EXECUTOR_FUNCTIONAL_NAME(0,) :public Executor<CallType, BaseClass>
+{
+private:
+  /** @brief the FunctioPointer. */
+  void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)() __EXECUTOR_FUNCTIONAL_CONST;
+
+public:
+  /**
+   * @brief constructs the Executor.
+   * @param __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER the FunctionPointer to the Calling Function.
+   */
+  __EXECUTOR_FUNCTIONAL_NAME(0,) (void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)() __EXECUTOR_FUNCTIONAL_CONST )
+      : Executor<CallType, BaseClass>(false, __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE), functionPointer(functionPointer)
+  {};
+
+  /**
+   * @brief executes the Functional
+   * @param object the Object the action should be executed on.
+   * @param eval the CallType to get the Parameters from.
+   */
+  virtual void operator()(BaseClass* object, CallType& eval = Evaluater<CallType>::defaultValue()) const
+  {
+    (__EXECUTOR_FUNCTIONAL_FUNCTION_EXEC)();
+  };
+
+  /**
+   * @brief copies the Executor
+   * @returns a new Executor that's a copy of this one.
+   */
+  virtual Executor<CallType, BaseClass>* clone() const
+  {
+    return new __EXECUTOR_FUNCTIONAL_NAME(0,)<T, CallType, BaseClass>(this->functionPointer);
+  };
+};
+
+
+
+///////////
+//// 1 ////
+///////////
+//! @brief ExecutorClass, that can execute Functions with one parameter.
+template<class T, typename CallType, typename type0, class BaseClass = BaseObject, template<typename> class Evaluater = ExecutorEvaluater>
+class __EXECUTOR_FUNCTIONAL_NAME(1,) : public Executor<CallType, BaseClass>
+{
+private:
+  /** @brief the FunctioPointer. */
+  void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0) __EXECUTOR_FUNCTIONAL_CONST;
+
+public:
+  /**
+   * @brief constructs the Executor.
+   * @param __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER the FunctionPointer to the Calling Function.
+   */
+  __EXECUTOR_FUNCTIONAL_NAME(1,) (void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0) __EXECUTOR_FUNCTIONAL_CONST)
+      : Executor<CallType, BaseClass>(false, ExecutorParamType<type0>(), __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE), functionPointer(functionPointer)
+  {};
+
+  /**
+   * @brief executes the Functional
+   * @param object the Object the action should be executed on.
+   * @param eval the CallType to get the Parameters from.
+   */
+  virtual void operator()(BaseClass* object, CallType& eval = Evaluater<CallType>::defaultValue()) const
+  {
+    (__EXECUTOR_FUNCTIONAL_FUNCTION_EXEC)(
+	Evaluater<CallType>::template getValue<type0, 0>(eval, this->defaultValue));
+  };
+
+  /**
+   * @brief copies the Executor
+   * @returns a new Executor that's a copy of this one.
+   */
+  virtual Executor<CallType, BaseClass>* clone() const
+  {
+    return  new __EXECUTOR_FUNCTIONAL_NAME(1,)<T, CallType, type0, BaseClass>(this->functionPointer);
+  };
+};
+
+
+
+///////////
+//// 2 ////
+///////////
+//! @brief ExecutorClass, that can execute Functions with two parameters.
+template<class T, typename CallType, typename type0, typename type1, class BaseClass = BaseObject, template<typename> class Evaluater = ExecutorEvaluater>
+class __EXECUTOR_FUNCTIONAL_NAME(2,) : public Executor<CallType, BaseClass>
+{
+private:
+  /** @brief the FunctioPointer. */
+  void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1) __EXECUTOR_FUNCTIONAL_CONST;
+
+public:
+  /**
+   * @brief constructs the Executor.
+   * @param __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER the FunctionPointer to the Calling Function.
+   */
+  __EXECUTOR_FUNCTIONAL_NAME(2,) (void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1) __EXECUTOR_FUNCTIONAL_CONST)
+      : Executor<CallType, BaseClass>(false, ExecutorParamType<type0>(), ExecutorParamType<type1>(), __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE), functionPointer(functionPointer)
+  {};
+
+  /**
+   * @brief executes the Functional
+   * @param object the Object the action should be executed on.
+   * @param eval the CallType to get the Parameters from.
+   */
+  virtual void operator()(BaseClass* object, CallType& eval = Evaluater<CallType>::defaultValue()) const
+  {
+    (__EXECUTOR_FUNCTIONAL_FUNCTION_EXEC)(
+      Evaluater<CallType>::template getValue<type0, 0>(eval, this->defaultValue),
+      Evaluater<CallType>::template getValue<type1, 1>(eval, this->defaultValue));
+  };
+
+  /**
+   * @brief copies the Executor
+   * @returns a new Executor that's a copy of this one.
+   */
+  virtual Executor<CallType, BaseClass>* clone() const
+  {
+    return new __EXECUTOR_FUNCTIONAL_NAME(2,)<T, CallType, type0, type1, BaseClass>(this->functionPointer);
+  };
+};
+
+
+
+///////////
+//// 3 ////
+///////////
+//! @brief ExecutorClass, that can execute Functions with three parameters.
+template<class T, typename CallType, typename type0, typename type1, typename type2, class BaseClass = BaseObject, template<typename> class Evaluater = ExecutorEvaluater>
+class __EXECUTOR_FUNCTIONAL_NAME(3,) : public Executor<CallType, BaseClass>
+{
+private:
+  /** @brief the FunctioPointer. */
+  void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1, type2) __EXECUTOR_FUNCTIONAL_CONST;
+
+public:
+  /**
+   * @brief constructs the Executor.
+   * @param __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER the FunctionPointer to the Calling Function.
+   */
+  __EXECUTOR_FUNCTIONAL_NAME(3,) (void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1, type2) __EXECUTOR_FUNCTIONAL_CONST)
+      : Executor<CallType, BaseClass>(false, ExecutorParamType<type0>(), ExecutorParamType<type1>(), ExecutorParamType<type2>(), __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE), functionPointer(functionPointer)
+  {};
+
+  /**
+   * @brief executes the Functional
+   * @param object the Object the action should be executed on.
+   * @param eval the CallType to get the Parameters from.
+   */
+  virtual void operator()(BaseClass* object, CallType& eval = Evaluater<CallType>::defaultValue()) const
+  {
+    (__EXECUTOR_FUNCTIONAL_FUNCTION_EXEC)(
+      Evaluater<CallType>::template getValue<type0, 0>(eval, this->defaultValue),
+      Evaluater<CallType>::template getValue<type1, 1>(eval, this->defaultValue),
+      Evaluater<CallType>::template getValue<type2, 2>(eval, this->defaultValue));
+  };
+
+  /**
+   * @brief copies the Executor
+   * @returns a new Executor that's a copy of this one.
+   */
+  virtual Executor<CallType, BaseClass>* clone() const
+  {
+    return new __EXECUTOR_FUNCTIONAL_NAME(3,)<T, CallType, type0, type1, type2, BaseClass>(this->functionPointer);
+  };
+};
+
+
+
+///////////
+//// 4 ////
+///////////
+//! @brief ExecutorClass, that can execute Functions with four parameters.
+template<class T, typename CallType, typename type0, typename type1, typename type2, typename type3, class BaseClass = BaseObject, template<typename> class Evaluater = ExecutorEvaluater>
+class __EXECUTOR_FUNCTIONAL_NAME(4,) : public Executor<CallType, BaseClass>
+{
+private:
+  /** @brief the FunctioPointer. */
+  void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1, type2, type3) __EXECUTOR_FUNCTIONAL_CONST;
+
+public:
+  /**
+   * @brief constructs the Executor.
+   * @param __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER the FunctionPointer to the Calling Function.
+   */
+  __EXECUTOR_FUNCTIONAL_NAME(4,) (void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1, type2, type3) __EXECUTOR_FUNCTIONAL_CONST)
+      : Executor<CallType, BaseClass>(false, ExecutorParamType<type0>(), ExecutorParamType<type1>(), ExecutorParamType<type2>(), ExecutorParamType<type3>(), __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE), functionPointer(functionPointer)
+  {};
+
+  /**
+  * @brief executes the Functional
+  * @param object the Object the action should be executed on.
+  * @param eval the CallType to get the Parameters from.
+   */
+  virtual void operator()(BaseClass* object, CallType& eval = Evaluater<CallType>::defaultValue()) const
+  {
+    (__EXECUTOR_FUNCTIONAL_FUNCTION_EXEC)(
+      Evaluater<CallType>::template getValue<type0, 0>(eval, this->defaultValue),
+      Evaluater<CallType>::template getValue<type1, 1>(eval, this->defaultValue),
+      Evaluater<CallType>::template getValue<type2, 2>(eval, this->defaultValue),
+      Evaluater<CallType>::template getValue<type3, 3>(eval, this->defaultValue));
+  };
+
+  /**
+   * @brief copies the Executor
+   * @returns a new Executor that's a copy of this one.
+   */
+  virtual Executor<CallType, BaseClass>* clone() const
+  {
+    return new __EXECUTOR_FUNCTIONAL_NAME(4,)<T, CallType, type0, type1, type2, type3, BaseClass>(this->functionPointer);
+  };
+};
+
+
+
+///////////
+//// 5 ////
+///////////
+//! @brief ExecutorClass, that can execute Functions with five parameters.
+template<class T, typename CallType, typename type0, typename type1, typename type2, typename type3, typename type4, class BaseClass = BaseObject, template<typename> class Evaluater = ExecutorEvaluater>
+class __EXECUTOR_FUNCTIONAL_NAME(5,) : public Executor<CallType, BaseClass>
+{
+private:
+  /** @brief the FunctioPointer. */
+  void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1, type2, type3, type4) __EXECUTOR_FUNCTIONAL_CONST;
+
+public:
+  /**
+   * @brief constructs the Executor.
+   * @param __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER the FunctionPointer to the Calling Function.
+   */
+  __EXECUTOR_FUNCTIONAL_NAME(5,) (void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1, type2, type3, type4) __EXECUTOR_FUNCTIONAL_CONST)
+      : Executor<CallType, BaseClass>(false, ExecutorParamType<type0>(), ExecutorParamType<type1>(), ExecutorParamType<type2>(), ExecutorParamType<type3>(), ExecutorParamType<type4>(), __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE), functionPointer(functionPointer)
+  {};
+
+  /**
+  * @brief executes the Functional
+  * @param object the Object the action should be executed on.
+  * @param eval the CallType to get the Parameters from.
+   */
+  virtual void operator()(BaseClass* object, CallType& eval = Evaluater<CallType>::defaultValue()) const
+  {
+    (__EXECUTOR_FUNCTIONAL_FUNCTION_EXEC)(
+      Evaluater<CallType>::template getValue<type0, 0>(eval, this->defaultValue),
+      Evaluater<CallType>::template getValue<type1, 1>(eval, this->defaultValue),
+      Evaluater<CallType>::template getValue<type2, 2>(eval, this->defaultValue),
+      Evaluater<CallType>::template getValue<type3, 3>(eval, this->defaultValue),
+      Evaluater<CallType>::template getValue<type4, 4>(eval, this->defaultValue));
+  };
+
+  /**
+   * @brief copies the Executor
+   * @returns a new Executor that's a copy of this one.
+   */
+  virtual Executor<CallType, BaseClass>* clone() const
+  {
+    return new __EXECUTOR_FUNCTIONAL_NAME(5,)<T, CallType, type0, type1, type2, type3, type4, BaseClass>(this->functionPointer);
+  };
+};
+
+
+////////////////////
+//// 0 & RETURN ////
+////////////////////
+//! @brief ExecutorClass, that can execute Functions with one parameter.
+template<class T, typename CallType, typename ReturnType, class BaseClass = BaseObject, template<typename> class Evaluater = ExecutorEvaluater>
+class __EXECUTOR_FUNCTIONAL_NAME(0,ret) : public Executor<CallType, BaseClass>
+{
+private:
+  /** @brief the FunctioPointer. */
+  ReturnType (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)() __EXECUTOR_FUNCTIONAL_CONST;
+
+public:
+  /**
+   * @brief constructs the Executor.
+   * @param __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER the FunctionPointer to the Calling Function.
+   */
+  __EXECUTOR_FUNCTIONAL_NAME(0,ret) (ReturnType (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)() __EXECUTOR_FUNCTIONAL_CONST)
+      : Executor<CallType, BaseClass>(true, __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE), functionPointer(functionPointer)
+  {};
+
+  /**
+     * @brief executes the Functional
+     * @param object the Object the action should be executed on.
+     * @param eval the CallType to get the Parameters from.
+   */
+  virtual void operator()(BaseClass* object, CallType& eval = Evaluater<CallType>::defaultValue()) const
+  {
+    Evaluater<CallType>::template storeRet<ReturnType>(eval, (__EXECUTOR_FUNCTIONAL_FUNCTION_EXEC)());
+  };
+
+  /**
+     * @brief copies the Executor
+     * @returns a new Executor that's a copy of this one.
+   */
+  virtual Executor<CallType, BaseClass>* clone() const
+  {
+    return  new __EXECUTOR_FUNCTIONAL_NAME(0,ret)<T, CallType, ReturnType, BaseClass>(this->functionPointer);
+  };
+};
+
+////////////////////
+//// 1 & RETURN ////
+////////////////////
+//! @brief ExecutorClass, that can execute Functions with one parameter.
+template<class T, typename CallType, typename ReturnType, typename type0, class BaseClass = BaseObject, template<typename> class Evaluater = ExecutorEvaluater>
+class __EXECUTOR_FUNCTIONAL_NAME(1,ret) : public Executor<CallType, BaseClass>
+{
+private:
+  /** @brief the FunctioPointer. */
+  ReturnType (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0) __EXECUTOR_FUNCTIONAL_CONST;
+
+public:
+  /**
+   * @brief constructs the Executor.
+   * @param __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER the FunctionPointer to the Calling Function.
+   */
+  __EXECUTOR_FUNCTIONAL_NAME(1,ret) (ReturnType (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0) __EXECUTOR_FUNCTIONAL_CONST)
+      : Executor<CallType, BaseClass>(true, ExecutorParamType<type0>(), __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE), functionPointer(functionPointer)
+  {};
+
+  /**
+     * @brief executes the Functional
+     * @param object the Object the action should be executed on.
+     * @param eval the CallType to get the Parameters from.
+   */
+  virtual void operator()(BaseClass* object, CallType& eval = Evaluater<CallType>::defaultValue()) const
+  {
+    Evaluater<CallType>::template storeRet<ReturnType>(eval, (__EXECUTOR_FUNCTIONAL_FUNCTION_EXEC)(
+          Evaluater<CallType>::template getValue<type0, 0>(eval, this->defaultValue)));
+  };
+
+  /**
+     * @brief copies the Executor
+     * @returns a new Executor that's a copy of this one.
+   */
+  virtual Executor<CallType, BaseClass>* clone() const
+  {
+    return  new __EXECUTOR_FUNCTIONAL_NAME(1,ret)<T, CallType, ReturnType, type0, BaseClass>(this->functionPointer);
+  };
+};
+
+
+////////////////////
+//// 2 & RETURN ////
+////////////////////
+//! @brief ExecutorClass, that can execute Functions with one parameter.
+template<class T, typename CallType, typename ReturnType, typename type0, typename type1, class BaseClass = BaseObject, template<typename> class Evaluater = ExecutorEvaluater>
+class __EXECUTOR_FUNCTIONAL_NAME(2,ret) : public Executor<CallType, BaseClass>
+{
+private:
+  /** @brief the FunctioPointer. */
+  ReturnType (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1) __EXECUTOR_FUNCTIONAL_CONST;
+
+public:
+  /**
+   * @brief constructs the Executor.
+   * @param __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER the FunctionPointer to the Calling Function.
+   */
+  __EXECUTOR_FUNCTIONAL_NAME(2,ret) (ReturnType (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1) __EXECUTOR_FUNCTIONAL_CONST)
+      : Executor<CallType, BaseClass>(true, ExecutorParamType<type0>(), __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE), functionPointer(functionPointer)
+  {};
+
+  /**
+     * @brief executes the Functional
+     * @param object the Object the action should be executed on.
+     * @param eval the CallType to get the Parameters from.
+   */
+  virtual void operator()(BaseClass* object, CallType& eval = Evaluater<CallType>::defaultValue()) const
+  {
+    Evaluater<CallType>::template storeRet<ReturnType>(eval, (__EXECUTOR_FUNCTIONAL_FUNCTION_EXEC)(
+          Evaluater<CallType>::template getValue<type0, 0>(eval, this->defaultValue),
+          Evaluater<CallType>::template getValue<type1, 1>(eval, this->defaultValue)));
+  };
+
+  /**
+     * @brief copies the Executor
+     * @returns a new Executor that's a copy of this one.
+   */
+  virtual Executor<CallType, BaseClass>* clone() const
+  {
+    return  new __EXECUTOR_FUNCTIONAL_NAME(2,ret)<T, CallType, ReturnType, type0, type1, BaseClass>(this->functionPointer);
+  };
+};
+
+#endif /* __EXECUTOR_FUNCTIONAL_NAME */
Index: branches/heathaze/src/lib/util/executor/executor_member.h
===================================================================
--- branches/heathaze/src/lib/util/executor/executor_member.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/executor_member.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file executor_member.h
+ * Definition of an Executor to Member Functions
+ */
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+#ifndef __EXECUTOR_MEMBER_H_
+#define __EXECUTOR_MEMBER_H_
+
+/// Define all Constructs, that define an Executor.
+//! The Name to be attached to the functional (for normal, static, and const modes)
+#define __EXECUTOR_FUNCTIONAL_NAME(ParamCount, Ext)   Executor##ParamCount##Ext
+//! if Functional is constant calling
+#define __EXECUTOR_FUNCTIONAL_CONST
+//! The Execution-mode (either static or objective)
+#define __EXECUTOR_FUNCTIONAL_FUNCTION_EXEC      dynamic_cast<T*>(object)->*(functionPointer)
+//! The Function-Pointer, and how to save it internally.
+#define __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER   T::*functionPointer
+//! The Type of Function
+#define __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE       Executor<CallType, BaseClass>::FunctionMember
+
+
+/// We want to include __EXECUTOR_GENERIC_H again, with current settings.
+#include "executor_generic.h"
+
+
+#undef __EXECUTOR_FUNCTIONAL_NAME
+#undef __EXECUTOR_FUNCTIONAL_CONST
+#undef __EXECUTOR_FUNCTIONAL_FUNCTION_EXEC
+#undef __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER
+#undef __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE
+
+#endif /* __EXECUTOR_MEMBER_H_ */
Index: branches/heathaze/src/lib/util/executor/executor_static.h
===================================================================
--- branches/heathaze/src/lib/util/executor/executor_static.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/executor_static.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file executor_static.h
+ * Definition of an Executor to Static Functions (either Static-Class or C-Style)
+ */
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+#ifndef __EXECUTOR_STATIC_H_
+#define __EXECUTOR_STATIC_H_
+
+/// Define all Constructs, that define an Executor.
+
+//! The Name to be attached to the functional (for normal, static, and const modes)
+#define __EXECUTOR_FUNCTIONAL_NAME(ParamCount, Ext)   Executor##ParamCount##Ext##_static
+
+//! if Functional is constant calling
+#define __EXECUTOR_FUNCTIONAL_CONST
+//! The Execution-mode (either static or objective)
+#define __EXECUTOR_FUNCTIONAL_FUNCTION_EXEC      functionPointer
+//! The Function-Pointer, and how to save it internally.
+#define __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER   *functionPointer
+//! The Type of Function
+#define __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE       Executor<CallType, BaseClass>::FunctionStatic
+
+
+/// We want to include __EXECUTOR_GENERIC_H again, with current settings.
+#include "executor_generic.h"
+
+#undef __EXECUTOR_FUNCTIONAL_NAME
+
+#undef __EXECUTOR_FUNCTIONAL_CONST
+#undef __EXECUTOR_FUNCTIONAL_FUNCTION_EXEC
+#undef __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER
+#undef __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE
+
+#endif /* __EXECUTOR_STATIC_H_ */
Index: branches/heathaze/src/lib/util/executor/executor_substring.cc
===================================================================
--- branches/heathaze/src/lib/util/executor/executor_substring.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/executor_substring.cc	(revision 9940)
@@ -0,0 +1,142 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#include "executor_substring.h"
+#include "helper_functions.h"
+
+/**
+ * @brief converts an input string into a value, if no value was converted, uses defaultValue.
+ * @param input the input as a String.
+ * @param defaultValue the Default Value set, if the input could not be converted into type.
+ * @returns either the converted value or defaultValue.
+ */
+template<> bool fromString<bool>(const std::string& input, bool defaultValue) { return isBool(input, defaultValue); };
+/**
+ * @brief converts an input string into a value, if no value was converted, uses defaultValue.
+ * @param input the input as a String.
+ * @param defaultValue the Default Value set, if the input could not be converted into type.
+ * @returns either the converted value or defaultValue.
+ */
+template<> int fromString<int>(const std::string& input, int defaultValue) { return isInt(input, defaultValue); };
+/**
+ * @brief converts an input string into a value, if no value was converted, uses defaultValue.
+ * @param input the input as a String.
+ * @param defaultValue the Default Value set, if the input could not be converted into type.
+ * @returns either the converted value or defaultValue.
+ */
+template<> unsigned int fromString<unsigned int>(const std::string& input, unsigned int defaultValue) { return isInt(input, defaultValue); };
+/**
+ * @brief converts an input string into a value, if no value was converted, uses defaultValue.
+ * @param input the input as a String.
+ * @param defaultValue the Default Value set, if the input could not be converted into type.
+ * @returns either the converted value or defaultValue.
+ */
+template<> float fromString<float>(const std::string& input, float defaultValue) { return isFloat(input, defaultValue); };
+/**
+ * @brief converts an input string into a value, if no value was converted, uses defaultValue.
+ * @param input the input as a String.
+ * @param defaultValue the Default Value set, if the input could not be converted into type.
+ * @returns either the converted value or defaultValue.
+ */
+template<> char fromString<char>(const std::string& input, char defaultValue) { return isInt(input, defaultValue); };
+/**
+ * @brief converts an input string into a value, if no value was converted, uses defaultValue.
+ * @param input the input as a String.
+ * @param defaultValue the Default Value set, if the input could not be converted into type.
+ * @returns either the converted value or defaultValue.
+ */
+template<> const std::string& fromString<const std::string&>(const std::string& input, const std::string& defaultValue) { return (input.size() > 0) ? input : defaultValue; };
+
+
+/**
+ * @brief converts to any type from a MultiType
+ * @param multi the MultiType to convert.
+ * @returns the converted Value.
+ */
+template<> bool fromMulti<bool>(const MultiType& multi) { return multi.getBool(); };
+/**
+ * @brief converts to any type from a MultiType
+ * @param multi the MultiType to convert.
+ * @returns the converted Value.
+ */
+template<> int fromMulti<int>(const MultiType& multi) { return multi.getInt(); }
+/**
+ * @brief converts to any type from a MultiType
+ * @param multi the MultiType to convert.
+ * @returns the converted Value.
+ */
+template<> unsigned int fromMulti<unsigned int>(const MultiType& multi) { return multi.getInt(); };
+/**
+ * @brief converts to any type from a MultiType
+ * @param multi the MultiType to convert.
+ * @returns the converted Value.
+ */
+template<> float fromMulti<float>(const MultiType& multi) { return multi.getFloat(); };
+/**
+ * @brief converts to any type from a MultiType
+ * @param multi the MultiType to convert.
+ * @returns the converted Value.
+ */
+template<> char fromMulti<char>(const MultiType& multi) { return multi.getChar(); };
+/**
+ * @brief converts to any type from a MultiType
+ * @param multi the MultiType to convert.
+ * @returns the converted Value.
+ */
+template<> const std::string& fromMulti<const std::string&>(const MultiType& multi) { return multi.getConstString(); };
+
+
+/**
+ * @brief retrieves a default value from an array of default values, at possition i.
+ * @param defaultValues the Array of default values.
+ * @param i the index.
+ * @returns the Default Value at Position i
+ */
+template<> bool getDefault<bool>(const MultiType* const defaultValues, unsigned int i) { return defaultValues[i].getBool(); };
+/**
+ * @brief retrieves a default value from an array of default values, at possition i.
+ * @param defaultValues the Array of default values.
+ * @param i the index.
+ * @returns the Default Value at Position i
+ */
+template<> int getDefault<int>(const MultiType* const defaultValues, unsigned int i) { return defaultValues[i].getInt(); };
+/**
+ * @brief retrieves a default value from an array of default values, at possition i.
+ * @param defaultValues the Array of default values.
+ * @param i the index.
+ * @returns the Default Value at Position i
+ */
+template<> unsigned int getDefault<unsigned int>(const MultiType* const defaultValues, unsigned int i) { return defaultValues[i].getInt(); };
+/**
+ * @brief retrieves a default value from an array of default values, at possition i.
+ * @param defaultValues the Array of default values.
+ * @param i the index.
+ * @returns the Default Value at Position i
+ */
+template<> float getDefault<float>(const MultiType* const defaultValues, unsigned int i) { return defaultValues[i].getFloat(); };
+/**
+ * @brief retrieves a default value from an array of default values, at possition i.
+ * @param defaultValues the Array of default values.
+ * @param i the index.
+ * @returns the Default Value at Position i
+ */
+template<> char getDefault<char>(const MultiType* const defaultValues, unsigned int i) { return defaultValues[i].getChar(); };
+/**
+ * @brief retrieves a default value from an array of default values, at possition i.
+ * @param defaultValues the Array of default values.
+ * @param i the index.
+ * @returns the Default Value at Position i
+ */
+template<> const std::string& getDefault<const std::string&>(const MultiType* const defaultValues, unsigned int i) { return defaultValues[i].getStoredString(); };
Index: branches/heathaze/src/lib/util/executor/executor_substring.h
===================================================================
--- branches/heathaze/src/lib/util/executor/executor_substring.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/executor_substring.h	(revision 9940)
@@ -0,0 +1,100 @@
+/*!
+ * @file executor_substring.h
+ * Definition of a Generic Executor
+ */
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+
+#ifndef __EXECUTOR_SUBSTRING_H_
+#define __EXECUTOR_SUBSTRING_H_
+
+
+#include "executor_generic.h"
+#include "substring.h"
+#ifdef FUNCTOR_CALL_TYPE
+ #undef FUNCTOR_CALL_TYPE
+#endif
+//! Use SubString as the FUNCTION_CALL_TYPE so that we can easily extend the Engine.
+#define FUNCTOR_CALL_TYPE const SubString
+
+/**
+ * @brief converts an input string into a value, if no value was converted, uses defaultValue.
+ * @param input the input as a String.
+ * @param defaultValue the Default Value set, if the input could not be converted into type.
+ * @returns either the converted value or defaultValue.
+ */
+template<typename type> type fromString(const std::string& input, type defaultValue) { return defaultValue; };
+template<> bool fromString<bool>(const std::string& input, bool defaultValue);
+template<> int fromString<int>(const std::string& input, int defaultValue);
+template<> unsigned int fromString<unsigned int>(const std::string& input, unsigned int defaultValue);
+template<> float fromString<float>(const std::string& input, float defaultValue);
+template<> char fromString<char>(const std::string& input, char defaultValue);
+template<> const std::string& fromString<const std::string&>(const std::string& input, const std::string& defaultValue);
+
+/**
+ * @brief converts to any type from a MultiType
+ * @param multi the MultiType to convert.
+ * @returns the converted Value.
+ */
+template<typename type> type fromMulti(const MultiType& multi) { /* return defaultValue; */ };
+template<> bool fromMulti<bool>(const MultiType& multi);
+template<> int fromMulti<int>(const MultiType& multi);
+template<> unsigned int fromMulti<unsigned int>(const MultiType& multi);
+template<> float fromMulti<float>(const MultiType& multi);
+template<> char fromMulti<char>(const MultiType& multi);
+template<> const std::string& fromMulti<const std::string&>(const MultiType& multi);
+
+/**
+ * @brief retrieves a default value from an array of default values, at possition i.
+ * @param defaultValues the Array of default values.
+ * @param i the index.
+ * @returns the Default Value at Position i
+ */
+template<typename type> type getDefault(const MultiType* const defaultValues, unsigned int i) { return (type)0; };
+template<> bool getDefault<bool>(const MultiType* const defaultValues, unsigned int i);
+template<> int getDefault<int>(const MultiType* const defaultValues, unsigned int i);
+template<> unsigned int getDefault<unsigned int>(const MultiType* const defaultValues, unsigned int i);
+template<> float getDefault<float>(const MultiType* const defaultValues, unsigned int i);
+template<> char getDefault<char>(const MultiType* const defaultValues, unsigned int i);
+template<> const std::string& getDefault<const std::string&>(const MultiType* const defaultValues, unsigned int i);
+
+
+/**
+ * @brief to remove writing errors, this function is Used.
+ * @param sub The SubString to use
+ * @param default The default Values.
+ */
+template<> class ExecutorEvaluater <const SubString>
+{
+public:
+  /** @brief Executes the Evaluater
+   * @param CallValue the Value that should be converted
+   * @param defaults the default Values.
+   */
+  template <typename ToType, int index>
+  static ToType getValue(const SubString& CallValue, const MultiType* const defaults)
+  {
+    return (CallValue.size() > index) ?
+           fromString<ToType>(CallValue[index], getDefault<ToType>(defaults, index)) :
+           fromMulti<ToType>(defaults[index]);
+  }
+  /** @returns the default Value of a SubString, namely NullSubString or SubString() */
+  static const SubString& defaultValue() { return SubString::NullSubString; };
+};
+
+#endif /* __EXECUTOR_SUBSTRING_H_ */
Index: branches/heathaze/src/lib/util/executor/executor_xml.h
===================================================================
--- branches/heathaze/src/lib/util/executor/executor_xml.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/executor_xml.h	(revision 9940)
@@ -0,0 +1,71 @@
+/*!
+ * @file executor_xml.h
+ * Definition of a on-screen-shell
+ */
+
+#ifndef _EXECUTOR_XML_H
+#define _EXECUTOR_XML_H
+
+#include "executor.h"
+#include "compiler.h"
+#include "debug.h"
+
+#include "parser/tinyxml/tinyxml.h"
+
+//! Executes a Function with a const TiXmlElement* parameter.
+/**
+ * This is a Special Executor, that finds ParamName in root as XML-sub-element
+ * This is especially usefull, if you have to Load a SubElement from root in a new Function
+ * What must be defined is a XML-root to search the ParameterName under an  a Function to call.
+ */
+template<class T, class BaseClass = BaseObject> class ExecutorXML : public Executor<const TiXmlElement*>
+{
+public:
+  /**
+   * @brief Constructor of a ExecutorXML
+   * @param function a Function to call
+   * @param root The XML root to search paramName under
+   * @param paramName the ParameterName the search in root, and lookup the TiXmlElement from
+   */
+  ExecutorXML(void(T::*function)(const TiXmlElement*), const TiXmlElement* root, const std::string& paramName)
+      : Executor<const TiXmlElement*>(false, MT_EXT1)
+  {
+    PRINTF(4)("Loading %s from XML-element %p\n", paramName.c_str(), root);
+
+    if (likely(root != NULL))
+      this->element = root->FirstChildElement(paramName);
+    else
+      this->element = NULL;
+
+    this->paramName = paramName;
+    this->functionPointer = function;
+  }
+
+  /**
+   * @brief clones an ExecutorXML, used to copy this Element.
+   * @returns a _new_ Copy of this Executor
+   */
+  virtual Executor<const TiXmlElement*>* clone () const
+  {
+    return new ExecutorXML<T>(functionPointer, element, paramName);
+  }
+
+  /**
+   * @brief executes the Command on BaseObject
+   * @param object the BaseObject to execute this Executor on
+   * @param element ignored in this case
+   */
+  virtual void operator()(BaseObject* object, const TiXmlElement*& element) const
+  {
+    assert (object != NULL);
+    if (this->element != NULL)
+      (dynamic_cast<T*>(object)->*(functionPointer))(this->element);
+  }
+
+private:
+  void    (T::*functionPointer)(const TiXmlElement*);  //!< The functionPointer to the function to be called.
+  const   TiXmlElement* element;                       //!< The XML-element to call.
+  std::string           paramName;                     //!< The Name of the Parameter this Executor should call.
+};
+
+#endif /* _EXECUTOR_XML_H */
Index: branches/heathaze/src/lib/util/executor/functor_const_member.h
===================================================================
--- branches/heathaze/src/lib/util/executor/functor_const_member.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/functor_const_member.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file functor_const_member.h
+ * Definition of an Functor
+ */
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+#ifndef __FUNCTOR_CONST_MEMBER_H_
+#define __FUNCTOR_CONST_MEMBER_H_
+
+#include "executor_const_member.h"
+
+/// Define all Constructs, that define an Executor.
+//! The Name to be attached to the functional (for normal, static, and const modes)
+#define __EXECUTOR_FUNCTIONAL_NAME(ParamCount, Ext)   Executor##ParamCount##Ext##_const
+//! if Functional is constant calling
+#define __EXECUTOR_FUNCTIONAL_CONST              const
+//! The Function-Pointer, and how to save it internally.
+#define __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER   T::*functionPointer
+//! The Type of Function
+#define __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE       Executor<CallType, BaseClass>::FunctionMember
+
+/// Now we include The generic Functor, that generate the functions.
+#include "functor_generic.h"
+
+#undef __EXECUTOR_FUNCTIONAL_NAME
+#undef __EXECUTOR_FUNCTIONAL_CONST
+#undef __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER
+#undef __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE
+
+
+
+#endif /* __FUNCTOR_CONST_MEMBER_H_ */
Index: branches/heathaze/src/lib/util/executor/functor_generic.h
===================================================================
--- branches/heathaze/src/lib/util/executor/functor_generic.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/functor_generic.h	(revision 9940)
@@ -0,0 +1,105 @@
+/*!
+ * @file functor_generic.h
+ * Definition of an Executor
+ */
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+// // // // // // // // // // // // //
+//// EXTENSION TO HIDE CONSTRUCT /////
+// // // // // // // // // // // // //
+/**
+ * @brief enables us to easily retrieve an Executor of Class T with modular Argument-count, (without thinking about args at all)
+ * @param CallType the Type of Executor to generate
+ */
+#define EXECUTOR_FUNCTIONAL_CREATOR0(CallType) \
+template<class T, class BaseClass> Executor<CallType, BaseClass>* createExecutor(void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)() __EXECUTOR_FUNCTIONAL_CONST) \
+{ \
+  return new __EXECUTOR_FUNCTIONAL_NAME(0,)<T, CallType, BaseClass>(functionPointer); \
+}
+
+/**
+ * @brief enables us to easily retrieve an Executor of Class T with modular Argument-count, (without thinking about args at all)
+ * @param CallType the Type of Executor to generate
+ * @param type0 for internal usage: the first Argument
+ */
+#define EXECUTOR_FUNCTIONAL_CREATOR1(CallType, type0) \
+template<class T, class BaseClass> Executor<CallType, BaseClass>* createExecutor(void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0) __EXECUTOR_FUNCTIONAL_CONST) \
+{ \
+  return new __EXECUTOR_FUNCTIONAL_NAME(1,)<T, CallType, type0, BaseClass>(functionPointer); \
+}
+
+/**
+ * @brief enables us to easily retrieve an Executor of Class T with modular Argument-count, (without thinking about args at all)
+ * @param CallType the Type of Executor to generate
+ * @param type0 for internal usage: the first Argument
+ * @param type1 for internal usage: the second Argument
+ */
+#define EXECUTOR_FUNCTIONAL_CREATOR2(CallType, type0, type1) \
+template<class T, class BaseClass> Executor<CallType, BaseClass>* createExecutor(void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1) __EXECUTOR_FUNCTIONAL_CONST) \
+{ \
+  return new __EXECUTOR_FUNCTIONAL_NAME(2,)<T, CallType, type0, type1, BaseClass>(functionPointer); \
+}
+
+/**
+ * @brief enables us to easily retrieve an Executor of Class T with modular Argument-count, (without thinking about args at all)
+ * @param CallType the Type of Executor to generate
+ * @param type0 for internal usage: the first Argument
+ * @param type1 for internal usage: the second Argument
+ * @param type2 for internal usage: the third Argument
+ */
+#define EXECUTOR_FUNCTIONAL_CREATOR3(CallType, type0, type1, type2) \
+template<class T, class BaseClass> Executor<CallType, BaseClass>* createExecutor(void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1, type2) __EXECUTOR_FUNCTIONAL_CONST) \
+{ \
+  return new __EXECUTOR_FUNCTIONAL_NAME(3,)<T, CallType, type0, type1, type2, BaseClass>(functionPointer); \
+}
+
+/**
+ * @brief enables us to easily retrieve an Executor of Class T with modular Argument-count, (without thinking about args at all)
+ * @param CallType the Type of Executor to generate
+ * @param type0 for internal usage: the first Argument
+ * @param type1 for internal usage: the second Argument
+ * @param type2 for internal usage: the third Argument
+ * @param type3 for internal usage: the fourth Argument
+ */
+#define EXECUTOR_FUNCTIONAL_CREATOR4(CallType, type0, type1, type2, type3) \
+template<class T, class BaseClass> Executor<CallType, BaseClass>* createExecutor(void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1, type2, type3) __EXECUTOR_FUNCTIONAL_CONST) \
+{ \
+  return new __EXECUTOR_FUNCTIONAL_NAME(4,)<T, CallType, type0, type1, type2, type3, BaseClass>(functionPointer); \
+}
+
+/**
+ * @brief enables us to easily retrieve an Executor of Class T with modular Argument-count, (without thinking about args at all)
+ * @param CallType the Type of Executor to generate
+ * @param type0 for internal usage: the first Argument
+ * @param type1 for internal usage: the second Argument
+ * @param type2 for internal usage: the third Argument
+ * @param type3 for internal usage: the fourth Argument
+ * @param type4 for internal usage: the fifth Argument
+ */
+#define EXECUTOR_FUNCTIONAL_CREATOR5(CallType, type0, type1, type2, type3, type4) \
+template<class T, class BaseClass> Executor<CallType, BaseClass>* createExecutor(void (__EXECUTOR_FUNCTIONAL_FUNCTION_POINTER)(type0, type1, type2, type3, type4) __EXECUTOR_FUNCTIONAL_CONST) \
+{ \
+    return new __EXECUTOR_FUNCTIONAL_NAME(5,)<T, CallType, type0, type1, type2, type3, type4, BaseClass>(functionPointer); \
+}
+
+/**
+ * Creates the FunctionCallers imediately
+ */
+#define FUNCTOR_LIST(x) EXECUTOR_FUNCTIONAL_CREATOR ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+
Index: branches/heathaze/src/lib/util/executor/functor_list.h
===================================================================
--- branches/heathaze/src/lib/util/executor/functor_list.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/functor_list.h	(revision 9940)
@@ -0,0 +1,77 @@
+/*!
+ * @file functor_list.h
+ * all the Different types of Functions one can include by using a simple createExecutor call
+ * with a FunctionPointer as Argument
+ */
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+*/
+
+
+#ifdef FUNCTOR_LIST
+  FUNCTOR_LIST(0)(FUNCTOR_CALL_TYPE);
+  //! makes functions with one string
+  FUNCTOR_LIST(1)(FUNCTOR_CALL_TYPE, const std::string&);
+  //! makes functions with two strings
+  FUNCTOR_LIST(2)(FUNCTOR_CALL_TYPE, const std::string&, const std::string&);
+  //! makes functions with three strings
+  FUNCTOR_LIST(3)(FUNCTOR_CALL_TYPE, const std::string&, const std::string&, const std::string&);
+  //! makes functions with four strings
+  FUNCTOR_LIST(4)(FUNCTOR_CALL_TYPE, const std::string&, const std::string&, const std::string&, const std::string&);
+
+
+  //! makes functions with one bool
+  FUNCTOR_LIST(1)(FUNCTOR_CALL_TYPE, bool);
+
+  //! makes functions with one int
+  FUNCTOR_LIST(1)(FUNCTOR_CALL_TYPE, int);
+  //! makes functions with two ints
+  FUNCTOR_LIST(2)(FUNCTOR_CALL_TYPE, int, int);
+  //! makes functions with three ints
+  FUNCTOR_LIST(3)(FUNCTOR_CALL_TYPE, int, int, int);
+  //! makes functions with four ints
+  FUNCTOR_LIST(4)(FUNCTOR_CALL_TYPE, int, int, int, int);
+
+
+  //! makes functions with one unsigned int
+  FUNCTOR_LIST(1)(FUNCTOR_CALL_TYPE, unsigned int);
+  //! makes functions with two unsigned ints
+  FUNCTOR_LIST(2)(FUNCTOR_CALL_TYPE, unsigned int, unsigned int);
+  //! makes functions with three unsigned ints
+  FUNCTOR_LIST(3)(FUNCTOR_CALL_TYPE, unsigned int, unsigned int, unsigned int);
+  //! makes functions with four unsigned ints
+  FUNCTOR_LIST(4)(FUNCTOR_CALL_TYPE, unsigned int, unsigned int, unsigned int, unsigned int);
+
+  //! makes functions with one float
+  FUNCTOR_LIST(1)(FUNCTOR_CALL_TYPE, float);
+  //! makes functions with two floats
+  FUNCTOR_LIST(2)(FUNCTOR_CALL_TYPE, float, float);
+  //! makes functions with three floats
+  FUNCTOR_LIST(3)(FUNCTOR_CALL_TYPE, float, float, float);
+  //! makes functions with four floats
+  FUNCTOR_LIST(4)(FUNCTOR_CALL_TYPE, float, float, float, float);
+  //! makes functions with four floats
+  FUNCTOR_LIST(5)(FUNCTOR_CALL_TYPE, float, float, float, float, float);
+
+  //! mixed values:
+  FUNCTOR_LIST(2)(FUNCTOR_CALL_TYPE, const std::string&, bool);
+  FUNCTOR_LIST(2)(FUNCTOR_CALL_TYPE, const std::string&, int);
+  FUNCTOR_LIST(2)(FUNCTOR_CALL_TYPE, const std::string&, float);
+  FUNCTOR_LIST(2)(FUNCTOR_CALL_TYPE, unsigned int, long);
+  FUNCTOR_LIST(2)(FUNCTOR_CALL_TYPE, const std::string&, unsigned int);
+
+  FUNCTOR_LIST(3)(FUNCTOR_CALL_TYPE, const std::string&, float, unsigned int);
+  FUNCTOR_LIST(4)(FUNCTOR_CALL_TYPE, const std::string&, float, unsigned int, unsigned int);
+  FUNCTOR_LIST(3)(FUNCTOR_CALL_TYPE, const std::string&, int, unsigned int);
+  FUNCTOR_LIST(3)(FUNCTOR_CALL_TYPE, const std::string&, unsigned int, unsigned int);
+
+  FUNCTOR_LIST(5)(FUNCTOR_CALL_TYPE, float, float, float, float, const std::string&);
+
+#endif /* FUNCTOR_LIST */
Index: branches/heathaze/src/lib/util/executor/functor_member.h
===================================================================
--- branches/heathaze/src/lib/util/executor/functor_member.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/functor_member.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file functor_member.h
+ * Definition of an Functor
+ */
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+#ifndef __FUNCTOR_MEMBER_H_
+#define __FUNCTOR_MEMBER_H_
+
+#include "executor_member.h"
+
+/// Define all Constructs, that define an Executor.
+//! The Name to be attached to the functional (for normal, static, and const modes)
+#define __EXECUTOR_FUNCTIONAL_NAME(ParamCount, Ext)   Executor##ParamCount##Ext
+//! if Functional is constant calling
+#define __EXECUTOR_FUNCTIONAL_CONST
+//! The Function-Pointer, and how to save it internally.
+#define __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER   T::*functionPointer
+//! The Type of Function
+#define __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE       Executor<CallType, BaseClass>::FunctionMember
+
+
+/// Now we include The generic Functor, that generate the functions.
+#include "functor_generic.h"
+
+
+#undef __EXECUTOR_FUNCTIONAL_NAME
+#undef __EXECUTOR_FUNCTIONAL_CONST
+#undef __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER
+#undef __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE
+
+
+
+#endif /* __FUNCTOR_MEMBER_H_ */
Index: branches/heathaze/src/lib/util/executor/functor_static.h
===================================================================
--- branches/heathaze/src/lib/util/executor/functor_static.h	(revision 9940)
+++ branches/heathaze/src/lib/util/executor/functor_static.h	(revision 9940)
@@ -0,0 +1,48 @@
+/*!
+ * @file functor_static.h
+ * Definition of Functors to Functions of Static Type
+ */
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+#ifndef __FUNCTOR_STATIC_H_
+#define __FUNCTOR_STATIC_H_
+
+#include "executor_static.h"
+
+/// Define all Constructs, that define an Executor.
+//! The Name to be attached to the functional (for normal, static, and const modes)
+#define __EXECUTOR_FUNCTIONAL_NAME(ParamCount, Ext)   Executor##ParamCount##Ext##_static
+//! if Functional is constant calling
+#define __EXECUTOR_FUNCTIONAL_CONST
+//! The Function-Pointer, and how to save it internally.
+#define __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER   *functionPointer
+//! The Type of Function
+#define __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE       Executor<CallType, BaseClass>::FunctionStatic
+
+/// Now we include The generic Functor, that generate the functions.
+#include "functor_generic.h"
+
+
+#undef __EXECUTOR_FUNCTIONAL_NAME
+#undef __EXECUTOR_FUNCTIONAL_CONST
+#undef __EXECUTOR_FUNCTIONAL_FUNCTION_POINTER
+#undef __EXECUTOR_FUNCTIONAL_FUNCTIONTYPE
+
+
+
+#endif /* __FUNCTOR_STATIC_H_ */
Index: branches/heathaze/src/lib/util/filesys/directory.cc
===================================================================
--- branches/heathaze/src/lib/util/filesys/directory.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/filesys/directory.cc	(revision 9940)
@@ -0,0 +1,218 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   Borrowed the Main code from 'Bart Vanhauwaert' (license below)
+   and adopted it to my likings.
+*/
+
+/**
+ * Copyright (C) 2002 Bart Vanhauwaert
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * for any purpose is hereby granted without fee. This license
+ * includes (but is not limited to) standalone compilation or as part
+ * of a larger project.
+ *
+ * This software is provided "as is" without express or implied warranty.
+ *
+ * For a full statement on warranty and terms and conditions for
+ * copying, distribution and modification, please see the comment block
+ * at the end of this file.
+ *
+ * Version 1
+ *
+ */
+
+#include "directory.h"
+
+#if not defined (__WIN32__)
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+const char Directory::delimiter = '/';
+#else
+#include <windows.h>
+#include <winbase.h>
+const char Directory::delimiter = '\\';
+#endif
+
+#include <iostream>
+
+/**
+ * @brief Constructs a Directory handler.
+ * @param directoryName the name of the Directory to access.
+ */
+Directory::Directory(const std::string& directoryName)
+    : File(directoryName)
+{
+  this->_opened = false;
+}
+
+/**
+ * @brief construct a Copy of directory.
+ * @param directory the Directory to copy.
+ */
+Directory::Directory(const Directory& directory)
+    : File(directory)
+{
+  this->_opened = directory._opened;
+  this->_fileNames = directory._fileNames;
+}
+
+
+/**
+ * @brief destructs the Directory.
+ */
+Directory::~Directory()
+{
+  this->close();
+}
+
+
+/**
+ * @brief openes the Directory
+ * @returns true on success, false on error. (does not exist, no rights -> test with functions of File)
+ *
+ * Fills the List of Files, and sets the Directory to open state
+ */
+bool Directory::open()
+{
+  if (this->_opened)
+    this->close();
+
+  // Openes the Directory for reading:
+#if not defined(__WIN32__)
+  DIR* handle;
+  handle = opendir(this->name().c_str());
+  if (!handle)
+  {
+    std::cerr << "could not open directory " << this->name() << " for reading" << std::endl;
+    return false;
+  }
+
+  dirent* entry;
+  while ((entry = readdir(handle)) != NULL)
+    this->_fileNames.push_back(entry->d_name);
+  closedir(handle);
+
+#else
+  HANDLE handle;
+
+  // First check the attributes trying to access a non-Directory with
+  // FindFirstFile takes ages
+  DWORD attrs = GetFileAttributes(this->name().c_str());
+  if ( (attrs == 0xFFFFFFFF) || ((attrs && FILE_ATTRIBUTE_DIRECTORY) == 0) )
+  {
+    return false;
+  }
+  std::string Full(this->name());
+  // Circumvent a problem in FindFirstFile with c:\\* as parameter
+  if ( (Full.length() > 0) && (Full[Full.length()-1] != '\\') )
+    Full += "\\";
+  WIN32_FIND_DATA entry;
+  handle = FindFirstFile( (Full+"*").c_str(), &entry);
+  if (handle == INVALID_HANDLE_VALUE)
+  {
+    std::cerr << "could not open directory " << this->name() << " for reading" << std::endl;
+    return false;
+  }
+  else
+  {
+    this->_fileNames.push_back(entry.cFileName);
+  }
+  int ok;
+  while ((ok = FindNextFile(handle, &entry)) != 0)
+    this->_fileNames.push_back(entry.cFileName);
+  FindClose(handle);
+#endif /* __WIN_32__ */
+
+  this->_opened = true;
+  return true;
+}
+
+/**
+ * @brief closes the directory
+ * @returns true.
+ *
+ * Clears the List of Files in the Directory.
+ */
+bool Directory::close()
+{
+  this->_opened = false;
+  this->_fileNames.clear();
+  return true;
+}
+
+
+/**
+ * @brief creates the directory
+ * @returns true on success, false on error
+ */
+bool Directory::create()
+{
+#if not defined (__WIN32__)
+  return (!mkdir(this->name().c_str(), 0777));
+#else
+  return (!CreateDirectory(this->name().c_str(), NULL));
+#endif
+}
+
+
+Directory Directory::operator+(const Directory& dir) const
+{
+  return Directory(*this) += dir;
+}
+
+/**
+ * @param dir the Directory to append to this one (say this one is "/var", then dir can be "log")
+ * @returns The Directory appended by dir.
+ *
+ * @note the Directoy will again be closed even if it was opened previously!
+ */
+Directory& Directory::operator+=(const Directory& dir)
+{
+  this->setFileName(this->name() + Directory::delimiter + dir.name());
+  return *this;
+}
+
+/**
+ * @brief Traverses the Directory tree one step up. (Parent Directory)
+ * @returns a Reference to the Directory.
+ */
+Directory& Directory::operator--()
+{
+}
+
+
+/**
+ * @brief Traverses the Directory tree one step up. (Parent Directory)
+ * @param int the PostFix iterator
+ * @returns a Reference to the Directory.
+ */
+Directory& Directory::operator--(int)
+{
+}
+
+/**
+ * @returns The Parent Directory.
+ */
+Directory Directory::parentDir() const
+{
+
+}
+
+File operator+(const Directory& dir, const File& file)
+{
+  return File(dir.name() + Directory::delimiter + file.name());
+}
Index: branches/heathaze/src/lib/util/filesys/directory.h
===================================================================
--- branches/heathaze/src/lib/util/filesys/directory.h	(revision 9940)
+++ branches/heathaze/src/lib/util/filesys/directory.h	(revision 9940)
@@ -0,0 +1,116 @@
+/*!
+ * @file directory.h
+ * @brief Definition of the Directory Handler class
+ */
+
+
+/**
+ * Copyright (C) 2002 Bart Vanhauwaert
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * for any purpose is hereby granted without fee. This license
+ * includes (but is not limited to) standalone compilation or as part
+ * of a larger project.
+ *
+ * This software is provided "as is" without express or implied warranty.
+ *
+ * For a full statement on warranty and terms and conditions for
+ * copying, distribution and modification, please see the comment block
+ * at the end of this file.
+ *
+ * Version 1
+ *
+ */
+
+#ifndef __DIRECTORY_H_
+#define __DIRECTORY_H_
+
+#include "file.h"
+#include <vector>
+
+//! A Directory is a Special file, that contains multiple Files.
+/**
+ * @example Correct usage
+ * Directory dir("/var/log");
+ * dir.open();
+ * if (dir.fileNameInDir("emerge.log"))
+ *  { // do stuff; }
+ */
+class Directory : public File
+{
+public:
+  Directory(const std::string& directoryName = "");
+  Directory(const Directory& directory);
+  virtual ~Directory();
+
+  virtual bool open();
+  virtual bool close();
+
+  bool create();
+
+  Directory operator+(const Directory& dir) const;
+  Directory& operator+=(const Directory& dir);
+  Directory& operator--();
+  Directory& operator--(int);
+  Directory parentDir() const;
+
+
+  /** @returns if the Directory was opened */
+  bool isOpen() const { return this->_opened; }
+  /** @returns the FileCount (count of files contained in this directory) */
+  unsigned int fileCount() const { return _fileNames.size(); };
+  /** @returns the FileNames contained inside of the Directory */
+  const std::vector<std::string>& fileNames() const { return this->_fileNames; };
+  /** @returns the i'th FileName @param fileNumber the fileNumber (must not bigger than fileCount()) */
+  const std::string& operator[](unsigned int fileNumber) const { return this->_fileNames[fileNumber]; };
+  /** @returns a formated string containing the FileName, prepended with the directory-Name */
+  std::string fileNameInDir(unsigned int fileNumber) const { return this->name() + Directory::delimiter + _fileNames[fileNumber]; };
+  /** @returns a File pointing to the File @param fileNumber the fileNumber (must not bigger than fileCount()) */
+  File getFile(unsigned int fileNumber) const { return File(fileNameInDir(fileNumber)); };
+
+public:
+  static const char           delimiter;        //!< A Delimiter (*nix: '/', windows: '\\')
+
+private:
+  bool                        _opened;          //!< If the directory was opened.
+  std::vector<std::string>    _fileNames;       //!< The List of Files contained in the directory. (will be filled when open was called.)
+};
+
+File operator+(const Directory& dir, const File& file);
+
+#endif /* __DIRECTORY_H_ */
+
+/**
+ *
+ * The "library", above, refers to the collection of software functions
+ * and/or data contained in this file, prepared so as to be conveniently
+ * compiled and linked with application programs (which use some of those
+ * functions and data) to form executables.
+ *
+ *                             NO WARRANTY
+ *
+ * 1. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+ * WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+ * EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+ * OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+ * LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+ * THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+ *
+ * 2. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ * WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+ * AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+ * FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+ * LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+ * RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+ * FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+ * SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGES.
+ *
+ * END OF TERMS AND CONDITIONS
+ *
+ */
+
Index: branches/heathaze/src/lib/util/filesys/file.cc
===================================================================
--- branches/heathaze/src/lib/util/filesys/file.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/filesys/file.cc	(revision 9940)
@@ -0,0 +1,373 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#include "file.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+#include <iostream>
+#include <fstream>
+
+#ifdef __unix__
+#include <unistd.h>
+#elif __WIN32__ || _MS_DOS_
+#include <dir.h>
+#else
+//#include <direct.h>
+#endif
+
+/**
+ * @brief default constructor.
+ */
+File::File()
+{
+  this->init();
+}
+
+/**
+ * @brief A File will be constructed and stated from a given FileName.
+ * @param fileName the FileName to load and stat.
+ */
+File::File(const std::string& fileName)
+{
+  this->init();
+  this->setFileName(fileName);
+}
+
+/**
+ * @brief A File will be constructed and stated from a given other File.
+ * @param file the File to get the Name from.
+ */
+File::File(const File& file)
+{
+  this->init();
+  this->setFileName(file.name());
+}
+
+File::~File()
+{
+  this->close();
+
+  if (this->_status)
+    delete this->_status;
+}
+
+
+/**
+ * @brief initializes the File
+ *
+ * Stats the File, looks if it exists and sets the hadle to 0
+ */
+void File::init()
+{
+  this->_handle = 0;
+  this->_status = NULL;
+}
+
+
+/**
+ * @brief sets a new File to apply to this File.
+ * @param fileName the Filename of the File to access.
+ */
+void File::setFileName(const std::string& fileName)
+{
+  this->close();
+  this->_name = fileName;
+  File::homeDirCheck(this->_name);
+  this->statFile();
+}
+
+/**
+ * @brief sets the file to the new File.
+ * @param fileName the FileName to set the File to.
+ * @returns this File.
+ */
+File& File::operator=(const std::string& fileName)
+{
+  this->setFileName(fileName);
+  return *this;
+}
+
+/**
+ * @brief sets the file to the new File.
+ * @param file the File to set the File to.
+ * @returns this File.
+ */
+File& File::operator=(const File& file)
+{
+  this->setFileName(file.name());
+  return *this;
+}
+
+/**
+ * @brief compares two files.
+ * @param fileName the File to compare against the stored one.
+ * @returns true if the filenames match.
+ */
+bool File::operator==(const std::string& fileName) const
+{
+  return (this->_name == fileName);
+}
+
+/**
+ * @brief compares two files.
+ * @param file the File to compare against the stored one.
+ * @returns true if the filenames match.
+ */
+bool File::operator==(const File& file) const
+{
+  return (this->_name == file.name());
+}
+
+
+/**
+ * @brief stats a File.
+ * Gathers information about the File, like permissions, and if it exists.
+ */
+void File::statFile()
+{
+  if (this->_status == NULL)
+    this->_status = new struct stat;
+  // Check the End of the FileName and chop away any \ and //
+  std::string name = this->_name;
+  while (name[name.size()-1] == '/' ||
+	 name[name.size()-1] == '\\')
+    name.resize(name.size()-1);
+  if (stat(name.c_str(), this->_status))
+  {
+    delete this->_status;
+    this->_status = NULL;
+  }
+}
+
+bool File::open(OpenMode mode)
+{
+#warning implement
+  return false;
+}
+
+bool File::close()
+{
+#warning implement
+  return false;
+}
+
+bool File::exists() const
+{
+  return (this->_status != NULL);
+}
+
+/**
+ * @brief checks if the file is a Link (symlink/hardlink on UNIX)
+ * @returns true if the File is a Link, false otherwise (on windows always false)
+ */
+bool File::isLink() const
+{
+#ifndef __WIN32__
+  return (this->_status != NULL && this->_status->st_mode & (S_IFLNK));
+#else
+  return false;
+#endif
+}
+
+/**
+ * @brief checks if the File is a regular File
+ * @returns true if the File is a Regular file.
+ */
+bool File::isFile() const
+{
+  return (this->_status != NULL && this->_status->st_mode & (S_IFREG));
+}
+
+/**
+ * @brief Checks if the File is a Directory
+ * @returns true if it is a directory/symlink false otherwise
+ */
+bool File::isDirectory() const
+{
+  return (this->_status != NULL && this->_status->st_mode & (S_IFDIR));
+}
+
+
+/// FIXME NEXT THREE FUNCTIONS
+bool File::isReadable() const
+{
+#ifndef __WIN32__
+  return (this->_status != NULL && this->_status->st_mode & (S_IRUSR));
+#else
+  return (this->_status != NULL);
+#endif
+}
+bool File::isWriteable() const
+{
+#ifndef __WIN32__
+  return (this->_status != NULL && this->_status->st_mode & (S_IWUSR));
+#else
+  return (this->_status != NULL);
+#endif
+}
+bool File::isExecutable() const
+{
+#ifndef __WIN32__
+  return (this->_status != NULL && this->_status->st_mode & (S_IXUSR));
+#else
+  return (this->_status != NULL);
+#endif
+}
+
+/**
+ * @brief copies the File to another File.
+ * @param destination the Destination File.
+ * @returns true on success, false otherwise.
+ */
+bool File::copy(const File& destination)
+{
+  if (*this == destination)
+  {
+    std::cout << "files are the Same '" << this->_name << "'\n";
+    return false;
+  }
+  char ch;
+  std::ifstream iFile(this->_name.c_str());
+  std::ofstream oFile(destination.name().c_str());
+  while (iFile.get(ch))
+  {
+    oFile.put(ch);
+  }
+  return true;
+}
+
+/**
+ * @brief renames the File (move)
+ * @param destination the Destination to move this file to.
+ * @returns true on success, false otherwise.
+ *
+ * if the File was opened, it will be closed throuh this function.
+ * The File will also be closed, if the File was not renamed.
+ */
+bool File::rename(const File& destination)
+{
+  this->close();
+
+  if (!std::rename(this->_name.c_str(), destination.name().c_str()))
+  {
+    this->_name = destination.name();
+    this->statFile();
+    return true;
+  }
+  return false;
+}
+
+/**
+ * @brief touches the File.
+ * @returns true if the file could have been touched. false otherwise.
+ *
+ * Touching a File means creating it.
+ */
+bool File::touch()
+{
+  FILE* stream;
+  if( (stream = fopen (this->_name.c_str(), "w")) == NULL)
+  {
+    std::cout << "could not touch '" << this->_name << "' for writing\n";
+    return false;
+  }
+  fclose(stream);
+
+  this->statFile();
+  return true;
+}
+
+/**
+ * @brief delete the File on the Disk
+ * @returns true on success, false otherwise.
+ */
+bool File::remove()
+{
+  if (!this->exists())
+    return false;
+
+  this->close();
+  unlink(this->_name.c_str());
+  delete this->_status;
+  this->_status = NULL;
+
+  return true;
+}
+
+/**
+ * @brief transforms a Relative path to an absolute one.
+ * @param fileName the Absolute Path.
+ */
+void File::relToAbs(std::string& relFileName)
+{
+  if (relFileName.empty())
+    return ;
+  if (relFileName[0] !=  '/')
+  {
+    if (relFileName[0] == '.' && relFileName[1] != '.')
+      relFileName.erase(0);
+    relFileName = File::cwd() + relFileName;
+  }
+}
+
+/**
+ * @brief converts an Absolute Filename to a Relative one
+ * @param absFileName the FileName to convert. The Relative path will be stored in absFileName.
+ */
+void File::absToRel(std::string& absFileName)
+{
+  if (absFileName.find(cwd()) == 0)
+    absFileName.replace(0, File::cwd().size(), ".");
+}
+
+
+std::string File::_cwd = "";
+
+/**
+ * @returns the Current Woring Directory
+ */
+const std::string& File::cwd()
+{
+  if (File::_cwd.empty())
+  {
+    char cwd[1024];
+    char* errorCode = getcwd(cwd, 1024);
+    if (errorCode == 0)
+      return File::_cwd;
+
+    File::_cwd = cwd;
+  }
+  return File::_cwd;
+}
+
+/**
+ * @brief check if fileName has the '~/` prepended.
+ * @returns the fileName in absolute coordinate.
+ */
+void File::homeDirCheck(std::string& fileName)
+{
+  if (fileName.size() < 2 || fileName[0] != '~' || fileName[1] != '/')
+    return;
+  std::string homeDir;
+#ifdef __WIN32__
+  homeDir = getenv("USERPROFILE");
+#else
+  homeDir = getenv("HOME");
+#endif
+  fileName = homeDir + fileName.substr(1);
+}
Index: branches/heathaze/src/lib/util/filesys/file.h
===================================================================
--- branches/heathaze/src/lib/util/filesys/file.h	(revision 9940)
+++ branches/heathaze/src/lib/util/filesys/file.h	(revision 9940)
@@ -0,0 +1,83 @@
+/*!
+ * @file file.h
+ * @brief Definition of File Handler class
+ */
+
+#ifndef __FILE_H_
+#define __FILE_H_
+
+
+#include <string>
+struct stat;
+
+//! A Class to Handle Files.
+class File
+{
+  public:
+  //! How the File should be opened.
+  typedef enum
+  {
+    ReadOnly,      //!< ReadOnly mode
+    WriteOnly,     //!< WriteOnly mode
+    ReadWrite,     //!< Read and Write mode together
+    Append,        //!< Append at the end.
+  } OpenMode;
+
+public:
+  File();
+  File(const std::string& fileName);
+  File(const File& file);
+  virtual ~File();
+
+  /// Set-Up
+  void setFileName(const std::string& fileName);
+  File& operator=(const std::string& fileName);
+  File& operator=(const File& file);
+
+  /// Comparison
+  bool operator==(const std::string& fileName) const;
+  bool operator==(const File& file) const;
+
+  virtual bool open(OpenMode mode);
+  virtual bool close();
+  int handle() const { return this->_handle; };
+
+  /** @returns the FileName of this File */
+  const std::string& name() const { return this->_name; };
+
+  /// Testing
+  bool exists() const;
+  bool isLink() const;
+  bool isFile() const;
+  bool isDirectory() const;
+  bool isReadable() const;
+  bool isWriteable() const;
+  bool isExecutable() const;
+
+
+  /// Operate on the FileSystem
+  bool copy(const File& destination);
+  bool rename(const File& destination);
+  bool touch();
+  bool remove();
+
+  /// Transformations
+  static void relToAbs(std::string& relFileName);
+  static void absToRel(std::string& absFileName);
+  static const std::string& cwd();
+
+  private:
+    void init();
+    void statFile();
+    void homeDirCheck(std::string& fileName);
+
+  private:
+    int                 _handle;          //!< The FileHandle (if set).
+    std::string         _name;            //!< The Name of the File.
+    stat*               _status;          //!< The Stat of the File.
+
+    static std::string  _cwd;             //!< The currend Working directory.
+
+};
+
+#endif /* __FILE_H_ */
Index: branches/heathaze/src/lib/util/filesys/net_link.cc
===================================================================
--- branches/heathaze/src/lib/util/filesys/net_link.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/filesys/net_link.cc	(revision 9940)
@@ -0,0 +1,83 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#include "net_link.h"
+#include "debug.h"
+
+
+#ifdef __OSX__
+#include <ApplicationServices/ApplicationServices.h>
+#elif defined __WIN32__
+//#include <shellapi.h>
+#endif
+
+
+NetLink::NetLink(const std::string& linkName)
+{
+  this->_link = linkName;
+}
+
+
+void NetLink::openInBrowser() const
+{
+  SDL_CreateThread(NetLink::openupInBrowser, (void*)&this->_link);
+}
+
+OrxThread::Mutex NetLink::_mutex;
+std::string NetLink::_defaultBrowser = "firefox";
+std::list<std::string> NetLink::_browserList = NetLink::buildBrowserList();
+
+
+
+
+int NetLink::openupInBrowser(void* url)
+{
+  OrxThread::MutexLock lock(&NetLink::_mutex);
+
+  std::string URL = *(std::string*)url;
+#ifdef __linux__
+  system ((std::string(NetLink::defaultBrowser()) + " " + URL).c_str());
+
+#elif defined __OSX__
+  CFURLRef url_handle = CFURLCreateWithBytes (NULL, (UInt8 *)URL.c_str(), URL.size(),
+                                              kCFStringEncodingASCII, NULL);
+  LSOpenCFURLRef (url_handle, NULL);
+  CFRelease (url_handle);
+
+#elif defined __WIN32__
+  /*  ShellExecute(GetActiveWindow(),
+               "open", URL.c_str(), NULL, NULL, SW_SHOWNORMAL);
+}*/
+#endif
+  PRINTF(3)("loaded external webpage %s\n", URL.c_str());
+
+  return 0;
+}
+
+void NetLink::setDefaultBrowser(const std::string& browserName)
+{
+  OrxThread::MutexLock lock(&NetLink::_mutex);
+  NetLink::_defaultBrowser = browserName;
+}
+
+std::list<std::string> NetLink::buildBrowserList()
+{
+  std::list<std::string> browserList;
+  browserList.push_back("firefox");
+  browserList.push_back("mozilla");
+  browserList.push_back("konqueror");
+
+  return  browserList;
+}
Index: branches/heathaze/src/lib/util/filesys/net_link.h
===================================================================
--- branches/heathaze/src/lib/util/filesys/net_link.h	(revision 9940)
+++ branches/heathaze/src/lib/util/filesys/net_link.h	(revision 9940)
@@ -0,0 +1,53 @@
+/*!
+ * @file net_link.h
+ * @brief Definition of a NetLink class
+ * NetLink is a File link to a page of file link to the Internet,
+ * or the local file-system
+ *
+ * Opening a link should be made easy through this class
+ *
+ * !! DANGER IT IS POSSIBLE TO EXECUTE ALL PROGRAMMS WITH USER'S RIGHTS
+ * !! ON THE DESIGNATED MACHINE
+ * !! THIS CLASS SHOULD BE USED WITH CAUTION WHEN USING OVER IN NETWORK
+ * !! MODE
+ */
+
+#ifndef __NET_LINK_H__
+#define __NET_LINK_H__
+
+#include <string>
+#include <list>
+
+#include "threading.h"
+
+//! NetLink is a File and Link executer for Internet Links
+/**
+ * @example: NetLink("http://www.orxonox.net").openInBrowser();
+ */
+class NetLink
+{
+public:
+  NetLink(const std::string& linkName);
+
+  void openInBrowser() const;
+
+  static void setDefaultBrowser(const std::string& browserName);
+  static const std::string& defaultBrowser() {  return NetLink::_defaultBrowser; };
+
+private:
+  static int openupInBrowser(void* url);
+
+  static std::list<std::string> buildBrowserList();
+
+
+private:
+  std::string                     _link;             //!< Linkname
+
+
+  // static lists.
+  static OrxThread::Mutex         _mutex;            //!< One mutex to lock them all.
+  static std::string              _defaultBrowser;   //!< The default Browser.
+  static std::list<std::string>   _browserList;
+};
+
+#endif /** __NET_LINK_H__ */
Index: branches/heathaze/src/lib/util/helper_functions.cc
===================================================================
--- branches/heathaze/src/lib/util/helper_functions.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/helper_functions.cc	(revision 9940)
@@ -0,0 +1,165 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "helper_functions.h"
+#include "stdlibincl.h"
+
+
+
+/**
+ * @brief checks if the input was a bool
+ * @param BOOL a String that holds a bool: must be one of those: 1,0,true,false(case-insensitive)
+ * @param defaultValue a default value that is set, if BOOL is corrupt
+ * @return returns the bool, if BOOL was correct otherwise defaultValue
+ */
+bool isBool(const std::string& BOOL, bool defaultValue)
+{
+  if (BOOL.empty())
+    return defaultValue;
+  if(BOOL[0] == '1' || BOOL == "true" )
+    return true;
+  else if (BOOL[0] == '0' || BOOL == "false")
+    return false;
+  else
+    return defaultValue;
+}
+
+
+/**
+ * @brief checks if the input was a int
+ * @param INT a String that holds an int.
+ * @param defaultValue a default value that is set, if INT is corrupt
+ * @return returns the contained int, if INT was correct otherwise defaultValue
+ */
+int isInt(const std::string& INT, int defaultValue)
+{
+  if (INT.empty())
+    return defaultValue;
+  char* endPtr = NULL;
+
+  int result = strtol(INT.c_str(), &endPtr, 10);
+
+  if ( endPtr >= INT.c_str() && endPtr < INT.c_str()+ INT.size())
+    return defaultValue;
+  else
+    return result;
+}
+
+
+/**
+ * @brief checks if the input was a float
+ * @param FLOAT a String that holds an float.
+ * @param defaultValue a default value that is set, if FLOAT is corrupt
+ * @return returns the contained float, if FLOAT was correct otherwise defaultValue
+ */
+float isFloat(const std::string& FLOAT, float defaultValue)
+{
+  if (FLOAT.empty())
+    return defaultValue;
+  char* endPtr = NULL;
+  double result = strtod(FLOAT.c_str(), &endPtr);
+
+  if ( endPtr >= FLOAT.c_str() && endPtr < FLOAT.c_str() + FLOAT.size())
+    return defaultValue;
+  else
+    return result;
+}
+
+
+/**
+ * @brief checks if the input was a string
+ * @param STING a String(char-array) that holds an string.
+ * @param defaultValue a default value that is set, if STRING is corrupt
+ * @return returns the contained string (char-array), if STRING was correct otherwise defaultValue
+ */
+const char* isCString(const std::string& STRING, const char* defaultValue)
+{
+  if (STRING.size() > 0)
+    return STRING.c_str();
+  else
+    return defaultValue;
+}
+
+/**
+ * @brief checks if the input was a string
+ * @param STING a String(char-array) that holds an string.
+ * @param defaultValue a default value that is set, if STRING is corrupt
+ * @return returns the contained string (char-array), if STRING was correct otherwise defaultValue
+ */
+const std::string& isString(const std::string& STRING, const std::string& defaultValue)
+{
+  if (STRING.size() > 0)
+    return STRING;
+  else
+    return defaultValue;
+}
+
+
+/**
+ * @brief compares two strings without ignoring the case
+ * @param s1 first string
+ * @param s2 second string
+ */
+int nocaseCmp(const std::string& s1, const std::string& s2)
+{
+  std::string::const_iterator it1=s1.begin();
+  std::string::const_iterator it2=s2.begin();
+
+  //stop when either string's end has been reached
+  while ( (it1!=s1.end()) && (it2!=s2.end()) )
+  {
+    if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
+      // return -1 to indicate smaller than, 1 otherwise
+      return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
+    //proceed to the next character in each string
+    ++it1;
+    ++it2;
+  }
+  size_t size1=s1.size(), size2=s2.size();// cache lengths
+  //return -1,0 or 1 according to strings' lengths
+  if (size1==size2)
+    return 0;
+  return (size1<size2) ? -1 : 1;
+}
+
+
+/**
+ * @brief compares two strings without ignoring the case
+ * @param s1 first string
+ * @param s2 second string
+ * @param len how far from the beginning to start.
+ */
+int nocaseCmp(const std::string& s1, const std::string& s2, unsigned int len)
+{
+  if (len == 0)
+    return 0;
+  std::string::const_iterator it1=s1.begin();
+  std::string::const_iterator it2=s2.begin();
+
+  //stop when either string's end has been reached
+  while ( (it1!=s1.end()) && (it2!=s2.end()) && len-- > 0)
+  {
+    if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
+      // return -1 to indicate smaller than, 1 otherwise
+      return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
+    //proceed to the next character in each string
+    ++it1;
+    ++it2;
+  }
+  return 0;
+}
+
Index: branches/heathaze/src/lib/util/helper_functions.h
===================================================================
--- branches/heathaze/src/lib/util/helper_functions.h	(revision 9940)
+++ branches/heathaze/src/lib/util/helper_functions.h	(revision 9940)
@@ -0,0 +1,27 @@
+/*!
+ * @file helper_functions.h
+ * @brief Definition of some minor helper-functions
+*/
+
+#ifndef _HELPER_FUNCTIONS_H
+#define _HELPER_FUNCTIONS_H
+
+#include <string>
+
+// FORWARD DECLARATION
+
+/***********************
+*** HELPER FUNCTIONS ***
+***********************/
+bool          isBool(const std::string& BOOL, bool defaultValue);
+int           isInt(const std::string& INT, int defaultValue);
+float         isFloat(const std::string& FLOAT, float defaultValue);
+const char*   isCString(const std::string& STRING, const char* defaultValue);
+const std::string& isString(const std::string& STRING, const std::string& defaultValue);
+
+
+int           nocaseCmp(const std::string& s1, const std::string& s2);
+int           nocaseCmp(const std::string& s1, const std::string& s2, unsigned int len);
+
+
+#endif /* _HELPER_FUNCTIONS_H */
Index: branches/heathaze/src/lib/util/list.h
===================================================================
--- branches/heathaze/src/lib/util/list.h	(revision 9940)
+++ branches/heathaze/src/lib/util/list.h	(revision 9940)
@@ -0,0 +1,647 @@
+/*!
+ * @file list.h
+ * a File that includes a List-template
+ */
+
+#ifndef _T_LIST_H
+#define _T_LIST_H
+
+#include "compiler.h"
+#ifndef NULL
+#define NULL 0                                       //!< this will define NULL
+#endif
+
+template<class T> class tIterator;
+
+//! a list element of the tList,
+template<class T> struct listElement
+{
+  listElement*        prev;                          //!< pointer to the previous listElement in the list
+  T*                  curr;                          //!< pointer to the list payload/container
+  listElement*        next;                          //!< pointer to the next listElement
+};
+
+/**
+ *  the list template class
+
+   you will use this as a generic list for all type of objects
+ */
+template<class T> class tList
+{
+  friend class tIterator<T>;
+
+  public:
+    tList ();
+    ~tList ();
+
+    void add(T* entity);
+    void addAtBeginning(T* entity); //!< @todo This should be made with an ENUM
+    void addAtIteratorPosition(T* entity, tIterator<T>* itereator);
+    void remove(const T* entity);
+    void removeFromLast(const T* entity);
+    void removeLast();
+    void flush();
+    T* firstElement() const;
+    T* lastElement() const;
+    bool isEmpty() const;
+    unsigned int getSize() const;
+    bool inList(T* entity) const;
+    tIterator<T>* getIterator() const;
+    T* nextElement(T* toEntity);
+    T* toArray();
+
+  private:
+    unsigned int       size;             //!< the size (lenght) of the list
+    listElement<T>*    first;            //!< pointer to the first element
+    listElement<T>*    last;             //!< pointer to the last element
+    listElement<T>*    currentEl;        //!< pointer to the current element
+};
+
+
+/**
+ *  the constructor
+ */
+template<class T>
+    inline tList<T>::tList ()
+{
+  this->currentEl = NULL;
+  this->first = NULL;
+  this->last = NULL;
+  this->size = 0;
+}
+
+
+/**
+ *  the deconstructor
+
+   this will delete only the list. ATTENTION: the list is deleted, but the objects in the list will remain
+ */
+template<class T>
+    inline tList<T>::~tList ()
+{
+  this->currentEl = this->first;
+  listElement<T>* le;
+  while(this->currentEl != NULL)
+  {
+    le = this->currentEl->next;
+    delete this->currentEl;
+    this->currentEl = le;
+  }
+  this->first = NULL;
+  this->last = NULL;
+  this->currentEl = NULL;
+  this->size = 0;
+}
+
+
+/**
+ *  add an entity to the list
+ * @param entity: the entity to add
+ */
+template<class T>
+    inline void tList<T>::add(T* entity)
+{
+  if( unlikely(entity == NULL)) return;
+  listElement<T>* el = new listElement<T>;
+  el->prev = this->last;
+  el->curr = entity;
+  el->next = NULL;
+
+  this->last = el;
+
+  if( unlikely(el->prev == NULL)) this->first = el; /* if first element */
+  else el->prev->next = el;
+  this->size++;
+}
+
+/**
+ *  add an entity to the list
+ * @param entity: the entity to add
+ */
+template<class T>
+    inline void tList<T>::addAtBeginning(T* entity)
+{
+  if( unlikely(entity == NULL)) return;
+
+  listElement<T>* el = new listElement<T>;
+  el->next = this->first;
+  el->curr = entity;
+  el->prev = NULL;
+
+  this->first = el;
+
+  if( unlikely(el->next == NULL)) this->last = el; /* if first element */
+  else el->next->prev = el;
+  this->size++;
+}
+
+/**
+ * add an entity at an iterators position
+ * @param entity the entity to add
+ * @param iterator the iterator get the Positional from
+ *
+ * this works best with an iterator walking with
+ * firstElement() ; nextStep();
+ * or
+ * lastElement(); prevStep();
+ */
+template<class T>
+    inline void tList<T>::addAtIteratorPosition(T* entity, tIterator<T>* iterator)
+{
+  // rule out unusable
+  if (unlikely(entity == NULL))
+    return;
+  // on any error (or next == NULL) add using default add-function
+  if (unlikely(iterator == NULL || iterator->getList() == NULL) ||
+      iterator->tmpEl == NULL || iterator->tmpEl->next == NULL)
+    return this->add(entity);
+  // on prev == NULL add with addAtBeginning-function
+  if (unlikely(iterator->tmpEl->prev == NULL))
+    return addAtBeginning(entity);
+  else
+  {
+    listElement<T>* el = new listElement<T>;
+    el->next = iterator->tmpEl->next;
+    el->curr = entity;
+    el->prev = iterator->tmpEl->prev;
+
+    el->next->prev = el;
+    el->prev->next = el;
+  }
+}
+
+/**
+ * remove an entity from the list
+ * @param entity: the entity to be removed
+ */
+template<class T>
+    inline void tList<T>::remove(const T* entity)
+{
+  this->currentEl = this->first;
+  while( this->currentEl != NULL)
+  {
+    if( unlikely(this->currentEl->curr == entity))
+    {
+      // erstes element?
+      if( unlikely(this->currentEl->prev == NULL)) this->first = this->currentEl->next;
+      else this->currentEl->prev->next = this->currentEl->next;
+
+      // letztes element?
+      if( unlikely(this->currentEl->next == NULL)) this->last = this->currentEl->prev;
+      else this->currentEl->next->prev = this->currentEl->prev;
+
+      delete this->currentEl;
+      this->size--;
+      return;
+    }
+    this->currentEl = this->currentEl->next;
+  }
+}
+
+/**
+ * remove an entity from the list
+ * @param entity: the entity to be removed
+ *
+ * this algorithm starts at the end of the List, working its way to the front
+ * for finding the right entity.
+ */
+template<class T>
+    inline void tList<T>::removeFromLast(const T* entity)
+{
+  this->currentEl = this->last;
+  while( this->currentEl != NULL)
+  {
+    if( unlikely(this->currentEl->curr == entity))
+    {
+      // erstes element?
+      if( unlikely(this->currentEl->prev == NULL)) this->first = this->currentEl->next;
+      else this->currentEl->prev->next = this->currentEl->next;
+
+      // letztes element?
+      if( unlikely(this->currentEl->next == NULL)) this->last = this->currentEl->prev;
+      else this->currentEl->next->prev = this->currentEl->prev;
+
+      delete this->currentEl;
+      this->size--;
+      return;
+    }
+    this->currentEl = this->currentEl->prev;
+  }
+}
+
+
+/**
+ * removes the Last Element of the List
+ */
+ template<class T>
+     inline void tList<T>::removeLast()
+{
+  if( unlikely(this->last == NULL))
+    return;
+
+  // only one element in the list (and its not NULL :D )
+  if( unlikely(this->last == this->first))
+  {
+    delete this->first;
+    this->first = NULL;
+    this->last = NULL;
+    this->size--;
+  }
+  else
+  {
+    listElement<T>* delLast = this->last;
+    this->last->prev->next = NULL;
+    this->last = this->last->prev;
+    delete delLast;
+  }
+}
+
+
+/**
+ *  this will delete all objects from the list, this can be very dangerous if there are ghost objects in the list.
+ */
+template<class T>
+    inline void tList<T>::flush()
+{
+  this->currentEl = this->first;
+
+  listElement<T>* le;
+  while( this->currentEl != NULL)
+  {
+    le = this->currentEl->next;
+    delete this->currentEl->curr;
+    delete this->currentEl;
+    this->currentEl = le;
+  }
+  this->first = NULL;
+  this->last = NULL;
+  this->currentEl = NULL;
+  this->size = 0;
+}
+
+
+/**
+ *  returns the first element of the list
+ * @returns first element
+ */
+template<class T>
+    inline T* tList<T>::firstElement() const
+{
+  return this->first->curr;
+}
+
+
+/**
+ *  function returns the last element of the list
+ * @returns the last element
+ */
+template<class T>
+    inline T* tList<T>::lastElement() const
+{
+  return this->last->curr;
+}
+
+
+/**
+ *  returns true if the list is empty
+ * @returns true if the list is empty
+ */
+template<class T>
+    inline bool tList<T>::isEmpty() const
+{
+  return (this->size == 0)?true:false;
+}
+
+
+/**
+ *  checks if an entity is in the List.
+ * @param entity The entity to check for in the entire List.
+ * @returns true if it is, false otherwise
+ */
+template<class T>
+    inline bool tList<T>::inList(T* entity) const
+{
+  // pre checks
+  if( unlikely(entity == NULL)) return false;
+
+  // search in the List
+  listElement<T>* el = this->first;
+  while( this->currentEl != NULL)
+  {
+    if( this->currentEl->curr == entity)
+      return true;
+
+    el = this->currentEl->next;
+  }
+}
+
+
+/**
+ *  this returns the number of elements in the list
+ * @returns number of elements
+ */
+template<class T>
+    inline unsigned int tList<T>::getSize() const
+{
+  return this->size;
+}
+
+
+/**
+ *  creates an itereator object and returns it
+ * @returns the iterator object to this list
+
+   You will use this, if you want to iterate through the list
+ */
+template<class T>
+    inline tIterator<T>* tList<T>::getIterator() const
+{
+  return new tIterator<T>(this);
+}
+
+
+
+/**
+ *  this returns the next element after toEntity or the first if toEntity is last
+ * @param toEntity: the entity after which is an entity, that has to be returned, sorry, terrible phrase
+ * @returns the element after toEntity
+ */
+template<class T>
+    inline T* tList<T>::nextElement(T* toEntity)
+{
+  //if( this->last == this->first == NULL) return NULL;
+  if(this->size == 0) return NULL;
+  if( toEntity == NULL) return this->first->curr;
+  if( toEntity == this->last->curr ) return this->first->curr;
+  this->currentEl = this->first;
+  while(this->currentEl->curr != toEntity && this->currentEl->next != NULL)
+  {
+    this->currentEl = this->currentEl->next;
+  }
+  if(this->currentEl == NULL) return NULL;
+  return this->currentEl->next->curr;
+}
+
+
+/**
+ *  creates an array out of the list (ATTENTION: not implemented)
+ * @returns pointer to the array beginning
+
+   ATTENTION: function is not implemented and wont do anything
+ */
+template<class T>
+    T* tList<T>::toArray()
+{
+  return NULL;
+}
+
+
+
+
+/**
+    *  an iterator class
+
+   this enables the user to iterate through a list very easely
+ */
+template<class T> class tIterator
+{
+  friend class tList<T>;
+  public:
+    tIterator(const tList<T>* list);
+    ~tIterator();
+
+    T* firstElement();
+    T* lastElement();
+    T* nextElement();
+    T* prevElement();
+    T* seekElement(const T* element);
+    T* iteratorElement(const tIterator<T>* iterator);
+    bool compareListPointer(const tList<T>* list) const;
+    inline const tList<T>* getList() const { return this->list; };
+    /** another way to iterate through the list
+     * !! THIS IS NOT MEANT FOR DELETION
+     */
+    T* prevStep();
+    T* nextStep();
+    T* getCurrent();
+
+  private:
+    listElement<T>*    currentEl;                      //!< pointer to the current list element in the iterator
+    listElement<T>*    tmpEl;                          //!< temp listElemnt pointer
+    const tList<T>*    list;                           //!< The List, that we want to iterate through
+};
+
+
+/**
+ *  iterator constructor
+ * @param startElement:  the first list element from the tList
+ *
+ * normaly you will use it like this:
+ **********************************************************
+ * tIterator<char>* nameIterator = nameList->getIterator();
+ * char name* = nameIterator->firstElement();
+ * while( name != NULL)
+ *  {
+ *   PRINTF(3)("found name: %s in list\n", name);
+ *   name = nameIterator->nextElement();
+ *  }
+ * delete nameIterator;
+ * ********************************************************
+ */
+template<class T>
+  inline tIterator<T>::tIterator (const tList<T>* list)
+{
+  this->currentEl = NULL;
+  this->tmpEl = NULL;
+  this->list = list;
+}
+
+
+/**
+ *  the destructor
+ */
+template<class T>
+    inline tIterator<T>::~tIterator ()
+{
+  this->currentEl = NULL;
+  this->tmpEl = NULL;
+  this->list = NULL;
+}
+
+/**
+ * this returns the first element of the iterator list
+ * @returns first element
+ */
+template<class T>
+    inline T* tIterator<T>::firstElement ()
+{
+  this->tmpEl = this->list->first;
+  if( likely(this->tmpEl != NULL))
+  {
+    this->currentEl = this->tmpEl->next;
+    return this->tmpEl->curr;
+  }
+  else
+    return NULL;
+}
+
+/**
+ * this returns the last element of the iterator list
+ * @returns last element
+ */
+template<class T>
+    inline T* tIterator<T>::lastElement ()
+{
+  this->tmpEl = this->list->last;
+  if( likely(this->tmpEl != NULL))
+  {
+    this->currentEl = tmpEl->prev;
+    return this->tmpEl->curr;
+  }
+  else
+    return NULL;
+}
+
+
+/**
+ *  use it to iterate through the list
+ * @returns next list element
+ */
+template<class T>
+    inline T* tIterator<T>::nextElement ()
+{
+  if( unlikely(this->currentEl == NULL))
+    return NULL;
+
+  this->tmpEl = this->currentEl;
+  this->currentEl = this->currentEl->next;
+
+  return this->tmpEl->curr;
+}
+
+
+/**
+ *  use it to iterate backwards through the list
+ * @returns next list element
+ */
+template<class T>
+    inline T* tIterator<T>::prevElement ()
+{
+  if( unlikely(this->currentEl == NULL))
+    return NULL;
+
+  this->tmpEl = this->currentEl;
+  this->currentEl = this->currentEl->prev;
+
+  return this->tmpEl->curr;
+}
+
+
+/**
+ *  gets the element after the selected one, sets the iterator to this point in the list
+ * @param element the element to seek
+ * @returns current list element
+ */
+template<class T>
+    inline T* tIterator<T>::seekElement (const T* element)
+{
+  if( unlikely(element == NULL))
+  {
+    this->currentEl = NULL;
+    return NULL;
+  }
+  this->tmpEl = this->list->first;
+  while( this->tmpEl != NULL)
+  {
+    if( unlikely(this->tmpEl->curr == element))
+    {
+      this->currentEl = this->tmpEl;
+      return this->currentEl->curr;
+    }
+    this->tmpEl = this->tmpEl->next;
+  }
+  this->currentEl = NULL;
+  return NULL;
+}
+
+/**
+ * grabs the iterator entity from another iterator
+ * @param iterator the iterator to grab the local currentEl from
+ * @returns the grabbed element (current). NULL if not found, or not defined
+ *
+ * Both iterators must be from the same List!
+ */
+template<class T>
+    T* tIterator<T>::iteratorElement(const tIterator<T>* iterator)
+{
+  if( unlikely(iterator != NULL && iterator->list == this->list))
+  {
+    this->currentEl = iterator->currentEl;
+    if (this->currentEl != NULL)
+      return this->currentEl->curr;
+    else
+      return NULL;
+  }
+  else
+  {
+    this->currentEl = NULL;
+    return NULL;
+  }
+}
+
+template<class T>
+    bool tIterator<T>::compareListPointer(const tList<T>* list) const
+{
+  return (this->list == list)?true:false;
+}
+
+
+/**
+ *  use it to move through the list without interfering with the iteration
+ * @returns previous list element
+ *
+ * this stepping mode will !not! step beyond the boundraries of the List!
+ */
+template<class T>
+    inline T* tIterator<T>::nextStep ()
+{
+  if( unlikely(this->tmpEl == NULL || this->tmpEl->next == NULL))
+    return NULL;
+  else
+  {
+    this->tmpEl = this->tmpEl->next;
+    return tmpEl->curr;
+  }
+}
+
+/**
+ *  use it to move backwards through the list without interfering with the itereation
+ * @returns next list element
+ *
+ * this stepping mode will !not! step beyond the boundraries of the List!
+ */
+template<class T>
+    inline T* tIterator<T>::prevStep ()
+{
+  if( unlikely(this->tmpEl == NULL || this->tmpEl->prev == NULL))
+    return NULL;
+  else
+  {
+    this->tmpEl = this->tmpEl->prev;
+    return tmpEl->curr;
+  }
+}
+
+/**
+ * @returns the current Element
+ */
+template<class T>
+    inline T* tIterator<T>::getCurrent()
+{
+  if (likely(this->tmpEl != NULL))
+    return this->tmpEl->curr;
+  else
+    return NULL;
+}
+
+#endif /* _T_LIST_H */
Index: branches/heathaze/src/lib/util/loading/dynamic_loader.cc
===================================================================
--- branches/heathaze/src/lib/util/loading/dynamic_loader.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/dynamic_loader.cc	(revision 9940)
@@ -0,0 +1,85 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOADING
+
+#include "dynamic_loader.h"
+#include "debug.h"
+
+#ifndef __WIN32__
+#include <dlfcn.h>
+
+
+
+ObjectListDefinition(DynamicLoader);
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+DynamicLoader::DynamicLoader (const std::string& libName)
+    : Factory(libName)
+{
+  this->registerObject(this, DynamicLoader::_objectList);
+
+  this->handle = NULL;
+
+  if (loadDynamicLib(libName));
+  this->setName(&libName[0]);
+}
+
+
+/**
+ * standard deconstructor
+*/
+DynamicLoader::~DynamicLoader ()
+{
+  // delete what has to be deleted here
+  if (this->handle != NULL)
+    dlclose(this->handle);
+}
+
+
+bool DynamicLoader::loadDynamicLib(const std::string& libName)
+{
+  this->handle = dlopen(&libName[0], RTLD_NOW);
+  if(this->handle == NULL)
+  {
+    return false;
+  }
+  void *mkr = dlsym( this->handle, "maker");
+  return (mkr != NULL);
+}
+
+bool DynamicLoader::loadDyLib(const std::string& libName)
+{
+  void* handle;
+  handle = dlopen(&libName[0], RTLD_NOW);
+  if(handle == NULL)
+  {
+    PRINTF(0)("unable to load %s\n", &libName[0]);
+    return false;
+  }
+//  void *mkr = dlsym("maker");
+  return true;
+}
+
+
+BaseObject* DynamicLoader::fabricateObject(const TiXmlElement* root) const
+{
+  /// FIXME
+  return NULL;
+}
+#endif
Index: branches/heathaze/src/lib/util/loading/dynamic_loader.h
===================================================================
--- branches/heathaze/src/lib/util/loading/dynamic_loader.h	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/dynamic_loader.h	(revision 9940)
@@ -0,0 +1,37 @@
+/*!
+ * @file dynamic_loader.h
+ * @brief Definition of The Dynamic Loader Factory.
+*/
+
+#ifndef _DYNAMIC_LOADER_H
+#define _DYNAMIC_LOADER_H
+
+#include "util/loading/factory.h"
+
+#include <string>
+
+#define DYNAMIC_LINKAGE_FACTORY(CLASS_NAME, CLASS_ID) \
+          void* DynamicCreator(const TiXmlElement* root) { return new CLASS_NAME(root); };
+
+// FORWARD DECLARATION
+
+//! A class for ...
+class DynamicLoader : public Factory
+{
+  ObjectListDeclaration(DynamicLoader);
+
+public:
+  DynamicLoader(const std::string& libName);
+  virtual ~DynamicLoader();
+
+  bool loadDynamicLib(const std::string& libName);
+  virtual BaseObject* fabricateObject(const TiXmlElement* root = NULL) const;
+
+  static bool loadDyLib(const std::string& libName);
+
+
+private:
+  void*      handle;
+};
+
+#endif /* _DYNAMIC_LOADER_H */
Index: branches/heathaze/src/lib/util/loading/factory.cc
===================================================================
--- branches/heathaze/src/lib/util/loading/factory.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/factory.cc	(revision 9940)
@@ -0,0 +1,161 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOADING
+
+#include "factory.h"
+#include "debug.h"
+//#include "shell_command.h"
+
+ObjectListDefinition(Factory);
+
+//SHELL_COMMAND(create, Factory, fabricate);
+
+/**
+ * @brief constructor
+ *
+ * set everything to zero and define factoryName
+ */
+Factory::Factory (const ClassID& classID)
+    : _classID(classID)
+{
+  PRINTF(4)("Factory::create(%s::%d)\n", classID.name().c_str(), classID.id());
+  //this->registerObject(this, Factory::_objectList);
+  this->setName(classID.name());
+
+  Factory::_factoryIDMap[classID] = this;
+  Factory::_factoryStringMap[classID.name()] = this;
+}
+
+/** @brief A Map of all Factories ordered by ID. */
+Factory::FactoryIDMap Factory::_factoryIDMap;
+
+/** @brief A Map of all Factories ordered by Name. */
+Factory::FactoryStringMap Factory::_factoryStringMap;
+
+/**
+ * @brief destructor
+ */
+Factory::~Factory ()
+{
+  FactoryIDMap::iterator it = Factory::_factoryIDMap.find(this->_classID);
+  if (it != Factory::_factoryIDMap.end() && (*it).second == this)
+    Factory::_factoryIDMap.erase(it);
+
+  FactoryStringMap::iterator stringIt = Factory::_factoryStringMap.find(this->_classID.name());
+  if (stringIt != Factory::_factoryStringMap.end() && (*stringIt).second == this)
+    Factory::_factoryStringMap.erase(stringIt);
+}
+
+/**
+ * @param classID match a classID with this classID
+ * @returns true on match, false otherwise
+ */
+bool Factory::operator==(int classID) const
+{
+  return (this->_classID == classID);
+}
+
+
+/**
+ * @brief Compares the Factories Name against a given ClassName
+ * @param className the Name of the Class to Query
+ * @returns true on match, false otherwise.
+ */
+bool Factory::operator==(const std::string& className) const
+{
+  return (this->_classID.name() == className);
+}
+
+
+/**
+ * @brief Creates a new Object of type root->Value() (name)
+ * @param root the XML-Root to match for the newly created Object
+ * @returns a new Object of Type root->Value() on match, NULL otherwise
+ */
+BaseObject* Factory::fabricate(const TiXmlElement* root)
+{
+  FactoryStringMap::const_iterator it = Factory::_factoryStringMap.find(root->Value());
+  if (it != Factory::_factoryStringMap.end())
+  {
+    PRINTF(2)("Create a new Object of type %s\n", (*it).second->getCName());
+    return (*it).second->fabricateObject(root);
+  }
+  else
+  {
+    PRINTF(2)("Could not Fabricate an Object of Class '%s'\n", root->Value());
+    return NULL;
+  }
+}
+
+
+/**
+ * @brief Creates a new Object of type className
+ * @param className the ClassName to match for the newly created Object
+ * @returns a new Object of Type className on match, NULL otherwise
+ */
+BaseObject* Factory::fabricate(const std::string& className)
+{
+  FactoryStringMap::const_iterator it = Factory::_factoryStringMap.find(className);
+  if (it != Factory::_factoryStringMap.end())
+  {
+    PRINTF(2)("Create a new Object of type %s\n", (*it).second->getCName());
+    return (*it).second->fabricateObject(NULL);
+  }
+  else
+  {
+    PRINTF(2)("Could not Fabricate an Object of Class '%s'\n", className.c_str());
+    return NULL;
+  }
+}
+
+/**
+ * @brief Creates a new Object of type classID
+ * @param classID the ClassID to match for the newly created Object
+ * @returns a new Object of Type classID on match, NULL otherwise
+ */
+BaseObject* Factory::fabricate(const ClassID& classID)
+{
+  FactoryIDMap::const_iterator it = Factory::_factoryIDMap.find(classID);
+  if (it != Factory::_factoryIDMap.end())
+  {
+    PRINTF(4)("Create a new Object of type %s\n", (*it).second->getCName());
+    return (*it).second->fabricateObject(NULL);
+  }
+  else
+  {
+    PRINTF(2)("Could not Fabricate an Object of ClassID '%d'\n", classID.id());
+    return NULL;
+  }
+}
+
+
+/**
+ * @brief print out some nice litte debug information about the Factory.
+ */
+void Factory::debug() const
+{
+  PRINTF(0)("Factory of class '%s' with ClassID: %d\n", this->_classID.name().c_str(), this->_classID.id());
+}
+
+/**
+ * @brief Prints out some nice Debug information about all factories
+ */
+void Factory::debugAll()
+{
+  PRINTF(0)("Debugging all %d Factories\n", Factory::_factoryStringMap.size());
+  Factory::FactoryStringMap::const_iterator it;
+  for (it = Factory::_factoryStringMap.begin(); it != Factory::_factoryStringMap.end(); ++it)
+    (*it).second->debug();
+}
Index: branches/heathaze/src/lib/util/loading/factory.h
===================================================================
--- branches/heathaze/src/lib/util/loading/factory.h	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/factory.h	(revision 9940)
@@ -0,0 +1,115 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+*/
+
+/*!
+ * @file factory.h
+ * @brief A loadable object handler
+*/
+
+
+#ifndef __FACTORY_H
+#define __FACTORY_H
+
+class BaseObject;
+
+#include "parser/tinyxml/tinyxml.h"
+#include "base_object.h"
+#include <map>
+
+/**
+ * Creates a factory to a Loadable Class.
+ * this should be used at the beginning of all the Classes that should be loadable (in the cc-file)
+ */
+#define CREATE_FACTORY(CLASS_NAME) \
+    tFactory<CLASS_NAME> global_##CLASS_NAME##_Factory = tFactory<CLASS_NAME>(CLASS_NAME::staticClassID())
+
+//! The Factory is a loadable object handler
+class Factory : public BaseObject
+{
+  //! Declare the ObjectList at the BaseObject List
+  ObjectListDeclaration(Factory);
+public:
+  virtual ~Factory ();
+
+  static  BaseObject* fabricate(const std::string& className);
+  static  BaseObject* fabricate(const ClassID& classID);
+  static  BaseObject* fabricate(const TiXmlElement* root);
+
+  bool operator==(int classID) const;
+  bool operator==(const std::string& className) const;
+  /** @param classID the ID to compare @returns true if the ID's match */
+  bool operator==(const ClassID& classID) const { return _classID == classID; };
+
+
+  void debug() const;
+  static void debugAll();
+
+protected:
+  Factory (const ClassID& id);
+  /**
+   * @brief The core function of the Factory. Creates objects of the Factories Type.
+   * @param root The TiXmlElement of the Factory.
+   * @returns the created Object in BaseType* format.
+   */
+  virtual BaseObject* fabricateObject(const TiXmlElement* root = NULL) const = 0;
+
+private:
+  //! Copy Constructor is hidden.
+  Factory (const Factory&) {};
+
+protected:
+  /** The Type of the FactoryMap that is sorted by ID */
+  typedef std::map<const ClassID, Factory*>  FactoryIDMap;
+  /** The Type of the FactoryMap that is sorted by Name */
+  typedef std::map<std::string, Factory*>    FactoryStringMap;
+
+  const ClassID                 _classID;              //!< The Class-Identifyer of the Factory.
+  static FactoryIDMap           _factoryIDMap;         //!< List of Registered Factories
+  static FactoryStringMap       _factoryStringMap;     //!< List of Registered Factories
+};
+
+/**
+ *  @brief a factory that is able to load any kind of Object
+ * (this is a Functor)
+ */
+template<class T> class tFactory : public Factory
+{
+public:
+  /**
+   * @brief creates a new type Factory to enable the loading of T
+   * @param classID the ID of the Class to be created.
+   */
+  tFactory (const ClassID& classID)
+      : Factory(classID)
+  {  }
+  /**
+   * @brief copy constructor
+   * @param factory the Factory to copy
+   */
+  tFactory (const tFactory& factory) : Factory(factory._classID) {};
+
+  /**
+   * @brief fabricates an Object of type T, with the constructor T::T(const TiXmlElemnt*)
+   * @param root the TiXmlElement T should load parameters from.
+   * @return the newly fabricated T.
+   */
+  virtual BaseObject* fabricateObject(const TiXmlElement* root = NULL) const
+  {
+    return new T(root);
+  }
+};
+
+#endif /* _FACTORY_H */
+
Index: branches/heathaze/src/lib/util/loading/fast_factory.cc
===================================================================
--- branches/heathaze/src/lib/util/loading/fast_factory.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/fast_factory.cc	(revision 9940)
@@ -0,0 +1,281 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
+
+#include "fast_factory.h"
+
+#include "compiler.h"
+#include "debug.h"
+
+
+ObjectListDefinition(FastFactory);
+
+/**
+ * @brief Initializes a FastFactory
+ * @param classID the ClassID this Class belongs to (the top-most)
+ * @param fastFactoryName the Name of the ObjectClass-handled here
+ * @return a new FastFactory
+ */
+FastFactory::FastFactory (const ClassID& classID, const std::string& fastFactoryName)
+{
+  this->registerObject(this, FastFactory::_objectList);
+  this->setName(fastFactoryName);
+
+  this->storedClassID = classID;
+  this->next = NULL;
+
+  this->deadList = NULL;
+  this->unusedContainers = NULL;
+
+  this->storedDeadObjects = 0;
+
+  FastFactory::registerFastFactory(this);
+}
+
+/** a reference to the First FastFactory */
+FastFactory* FastFactory::first = NULL;
+
+/**
+ *  destructor
+ * deletes all the Instances of the FastFactory.
+ */
+FastFactory::~FastFactory ()
+{
+  if (this == first)
+    this->first = NULL;
+  this->flush();
+
+  if (this->next)
+    delete this->next;
+}
+
+/**
+ * deletes all FastFactories
+ */
+void FastFactory::deleteAll()
+{
+  if (FastFactory::first)
+    delete FastFactory::first;
+}
+
+/**
+ * registers a Factory to the List of known factories.
+ * @param fastFactory The factory to add
+ *
+ * needed, to step through all the FastFactories.
+ */
+void FastFactory::registerFastFactory(FastFactory* fastFactory)
+{
+  PRINTF(4)("Registered FastFactory for '%s'\n", fastFactory->getCName());
+
+  if( FastFactory::first == NULL)
+    FastFactory::first = fastFactory;
+  else
+  {
+    FastFactory* tmpFac = FastFactory::first;
+    while( tmpFac->next != NULL)
+      tmpFac = tmpFac->next;
+    tmpFac->setNext(fastFactory);
+  }
+}
+
+/**
+ * searches for a FastFactory
+ * @param classID the ClassID of the FastFactory to search for
+ * @returns true if found, false otherwise.
+ */
+FastFactory* FastFactory::searchFastFactory(const ClassID& classID)
+{
+  if (FastFactory::first == NULL)
+    return NULL;
+  else
+  {
+    FastFactory* tmpFac = FastFactory::first;
+    while (tmpFac != NULL)
+    {
+      if (tmpFac->storedClassID == classID)
+        return tmpFac;
+      tmpFac = tmpFac->next;
+    }
+  }
+  return NULL;
+}
+
+/**
+ * searches for a FastFactory
+ * @param classID the ClassID of the FastFactory to search for
+ * @returns true if found, false otherwise.
+ */
+FastFactory* FastFactory::searchFastFactory(const std::string& fastFactoryName)
+{
+  if (FastFactory::first == NULL)
+    return NULL;
+  else
+  {
+    FastFactory* tmpFac = FastFactory::first;
+    while (tmpFac != NULL)
+    {
+      if (fastFactoryName == tmpFac->getCName())
+        return tmpFac;
+      tmpFac = tmpFac->next;
+    }
+  }
+  return NULL;
+}
+
+/**
+ * Removes all the stored Containers, and sets the Lists back to emptienes.
+ * @param hardFLUSH if true the containing Objects will also be deleted !! THIS IS DANGEROUS !!
+ */
+void FastFactory::flushAll(bool hardFLUSH)
+{
+  FastFactory* tmpFac = FastFactory::first;
+  while (tmpFac != NULL)
+  {
+    PRINTF(4)("DELETEING ALL OF %s\n",tmpFac->getCName());
+    tmpFac->flush(hardFLUSH);
+    tmpFac = tmpFac->next;
+  }
+}
+
+/**
+ * ereases all the remaining containers, without deleting the stored Objects inside of them.
+ * @param hardFLUSH if the the containing Objects will also be deleted !! THIS IS DANGEROUS !!
+ */
+void FastFactory::flush(bool hardFLUSH)
+{
+  FastObjectMember* tmpMember = this->deadList, *delMember = NULL;
+  while (tmpMember != NULL)
+  {
+    delMember = tmpMember;
+    tmpMember = tmpMember->next;
+    if (hardFLUSH)
+      delete delMember->objectPointer;
+    delete delMember;
+  }
+  this->deadList = NULL;
+
+  tmpMember = this->unusedContainers;
+  while (tmpMember != NULL)
+  {
+    delMember = tmpMember;
+    tmpMember = tmpMember->next;
+    delete delMember;
+  }
+  this->unusedContainers = NULL;
+}
+
+/**
+ * generates count new Object of the Corresponding class. (precaching)
+ * @param count How many instances of the class should be generated.
+ */
+void FastFactory::prepare(unsigned int count)
+{
+/*  if (this->storedDeadObjects + this->storedLivingObjects >= count)
+  {
+  PRINTF(3)("not creating new Objects for class %s, because the requested count already exists\n", this->getClassCName());
+}*/
+  for (unsigned int i = this->storedDeadObjects; i < count; i++)
+  {
+    this->fabricate();
+  }
+}
+
+/**
+ * gives back live to one Object.
+ * @return the Object to resurrect.
+ */
+BaseObject* FastFactory::resurrect()
+{
+  PRINTF(4)("Resurecting Object of type %s\n", this->getCName());
+  if (unlikely(this->deadList == NULL))
+  {
+    PRINTF(3)("The deadList of Class %s is empty, this may be either because it has not been filled yet, or the cache is to small.\n" \
+        "  Developer: try increasing the count with FastFactory::prepare(contHigher than actual)\n" \
+        "    Fabricating a new %s\n", this->getCName(), this->getCName());
+    this->fabricate();
+    return this->resurrect();
+  }
+  else
+  {
+    FastObjectMember* tmpC = this->deadList;
+    this->deadList = this->deadList->next;
+
+    tmpC->next = this->unusedContainers;
+    this->unusedContainers = tmpC;
+
+    return tmpC->objectPointer;
+  }
+}
+
+/**
+ * gives back live to one Object.
+ * @param classID the class From which to resurrect an Object.
+ * @return the Object to resurrect, NULL if classID is not found.
+ */
+BaseObject* FastFactory::resurrect(const ClassID& classID)
+{
+  FastFactory* tmpFac = FastFactory::getFirst();
+
+  while (tmpFac != NULL)
+  {
+    if (classID == tmpFac->storedClassID)
+      return tmpFac->resurrect();
+    tmpFac = tmpFac->next;
+  }
+  return NULL;
+}
+
+/**
+ * kills Object object, meaning, that it will be stored in the deadList of the FastFactory, and waiting for resurrection
+ * @param object the Object to kill.
+ *
+ * synony that would be really grate would be abolish, but this is more like exterminate than pause-mode.
+ */
+void FastFactory::kill(BaseObject* object)
+{
+  FastObjectMember* tmpC;
+  if (unlikely(this->unusedContainers == NULL))
+  {
+    tmpC = new FastObjectMember;
+  }
+  else
+  {
+    tmpC = this->unusedContainers;
+    this->unusedContainers = this->unusedContainers->next;
+  }
+
+  tmpC->next = this->deadList;
+  tmpC->objectPointer = object;
+  this->deadList = tmpC;
+}
+
+
+void FastFactory::kill(BaseObject* object, bool searchForFastFactory)
+{
+  if (likely(searchForFastFactory == true))
+  {
+    FastFactory* tmpFac = FastFactory::first;
+    while (tmpFac != NULL)
+    {
+      if (object->isA(tmpFac->storedClassID))
+      {
+        tmpFac->kill(object);
+        return;
+      }
+      tmpFac = tmpFac->next;
+    }
+  }
+}
Index: branches/heathaze/src/lib/util/loading/fast_factory.h
===================================================================
--- branches/heathaze/src/lib/util/loading/fast_factory.h	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/fast_factory.h	(revision 9940)
@@ -0,0 +1,176 @@
+/*!
+ * @file fast_factory.h
+ * The ObjectManager (FastFactory) is designed, to automatically generate and remove
+ * (without to much overhead) many instances of different classes.
+ *
+ * It is especially usefull for objects, that come only for a short time into existence,
+ * and get killed after a small amount of time (like shots).
+ *
+ * The Creation of an Object is usually done in the Weapon Class, where one subscribes
+ * a Projectile with:
+ * this->bulletFactory = tFastFactory<TestBullet>::getFastFactory(CL_TEST_BULLET, "TestBullet");
+ * (this might change over time).
+ * Then you can at loading time initialize an amount of the class with something like:
+ * this->bulletFactory->prepare(100); // creates 100 entities of TestBullet (dead ones)
+ * afterwards one can just retrieve an Object form the Class with
+ * this->bulletFactory->resurrect();  // this returns a BaseObject an Object of the class.
+ *
+ * The big difference to the FastFactory-class is, that this one is used more for the purpose
+ * of fast game-interaction than for loading. althought one can also load FastFactorized classes
+ * it is not the main topic.
+ */
+
+#ifndef _FAST_FACTORY_H
+#define _FAST_FACTORY_H
+
+#include "base_object.h"
+/**
+ * Creates a FastFactory to a Createable FastFactory.
+ */
+#define CREATE_FAST_FACTORY(CLASS_NAME, CLASS_ID) \
+  FastFactory* global_##CLASS_NAME##_FastFactory = tFastFactory<CLASS_NAME>::getFastFactory(CLASS_ID, #CLASS_NAME)
+/**
+ * Creates a FastFactory for a Class' static function named ClassName::fastFactory.
+ * @param CLASS_NAME the name of the Class to create the fast-factory for.
+ * @param CLASS_ID the ID of the class to create the fast-factory for @see "class_id_DEPRECATED.h"
+ *
+ * notice, that the Class to be called, must implement:
+ * static FastFactory*         fastFactory;
+ */
+#define CREATE_FAST_FACTORY_STATIC(CLASS_NAME) \
+  FastFactory* CLASS_NAME::fastFactory = tFastFactory<CLASS_NAME>::getFastFactory(CLASS_NAME::staticClassID(), #CLASS_NAME)
+
+//! A struct, that holds Lists of Objects of a certain type.
+typedef struct FastObjectMember
+{
+  BaseObject*          objectPointer;      //!< Pointer to the Object Stored in this Class (if it is the DeadList, else it is bork)
+
+  FastObjectMember*    next;               //!< the next stored FastObjectMember. (or NULL if this is the last one stored in either the deadList or the unusedContainers)
+};
+
+//! The FastFactory is a fast loadable object creator, and Dynamic List of dead object handler.
+/**
+ * The ObjectManager (FastFactory) is designed, to automatically generate and remove
+ * (without to much overhead) many instances of different classes.
+ *
+ * FastFactory is needed to glue all the tFastFactories together.
+ * It is also the general class that implements the necessary functions
+ * to generate, resurrect kill and stuff...
+ */
+class FastFactory : public BaseObject
+{
+  ObjectListDeclaration(FastFactory);
+
+public:
+  virtual ~FastFactory ();
+  static void deleteAll();
+
+  // functions to push and pop elements of this class
+  BaseObject* resurrect();
+  static BaseObject* resurrect(const ClassID& classID);
+  void kill(BaseObject* object);
+  static void kill(BaseObject* object, bool searchForFastFactory);
+
+  void prepare(unsigned int count);
+
+  static void flushAll(bool hardFLUSH = false);
+  void flush(bool hardFLUSH = false);
+
+  /** @returns the first FastFactory */
+  inline static FastFactory* getFirst() { return FastFactory::first; };
+
+  static FastFactory* searchFastFactory(const ClassID& classID);
+  static FastFactory* searchFastFactory(const std::string& fastFactoryName);
+
+  const ClassID& getStoredID() const { return this->storedClassID; };
+
+protected:
+  FastFactory (const ClassID& classID, const std::string& fastFactoryName = "");
+
+  /** sets the Next factory in the list @param nextFactory the next factory */
+  inline void setNext( FastFactory* nextFastFactory) { this->next = nextFastFactory; };
+  /** @returns the next FastFactory */
+  FastFactory* getNext() const { return this->next; };
+
+  /** generates a new Object of the Class T */
+  virtual void fabricate() = 0;
+
+private:
+  static void registerFastFactory(FastFactory* fastFactory);
+
+protected:
+  ClassID            storedClassID;        //!< The classID of the specified class.
+  unsigned int          storedDeadObjects;    //!< How many dead objects are stored in this class
+
+  FastObjectMember*     deadList;             //!< A List of all stored dead Objects of this class.
+  FastObjectMember*     unusedContainers;     //!< This is a List of unused containers, that will be reused by kill.
+
+private:
+  static FastFactory*   first;                //!< A pointer to the first FastFactory.
+
+  FastFactory*          next;                 //!< pointer to the next FastFactory.
+};
+
+
+
+/**
+ *  a FastFactory that is able to load any kind of Object from a ClassID
+ * (this is a Functor)
+ */
+template<class T>
+class tFastFactory : public FastFactory
+{
+public:
+  static tFastFactory<T>* getFastFactory(const ClassID& classID, const std::string& fastFactoryName);
+
+private:
+  tFastFactory(const ClassID& classID, const std::string& fastFactoryName);
+
+  virtual void fabricate();
+};
+
+/**
+ * construnts a FastFactory with
+ * @param fastFactoryName the name of the FastFactory
+ * @param fastFactory the ID of the class
+ * @todo (can this be written in another form??)
+ */
+template<class T>
+tFastFactory<T>::tFastFactory(const ClassID& classID, const std::string& fastFactoryName)
+    : FastFactory(classID, fastFactoryName)
+{}
+
+/**
+ * creates (if not existent) a Factory of Class T, and assigns some values to it
+ * @param classID the ClassID to assign to this class
+ * @param fastFactoryName the name to assign
+ * @returns The FastFactory if existent a new Factory if not.
+ */
+template<class T>
+tFastFactory<T>* tFastFactory<T>::getFastFactory(const ClassID& classID, const std::string& fastFactoryName)
+{
+  tFastFactory<T>* tmpFac = NULL;
+  if (FastFactory::getFirst() != NULL)
+    tmpFac = static_cast<tFastFactory<T>*>(FastFactory::getFirst()->searchFastFactory(classID));
+
+  if (tmpFac != NULL)
+    return tmpFac;
+  else
+    return new tFastFactory<T>(classID, fastFactoryName);
+}
+
+/**
+ * fabricates an Object of Class T, that corresponds to classID.
+ */
+template<class T>
+void tFastFactory<T>::fabricate()
+{
+  FastObjectMember* tmpFirstDead = new FastObjectMember;
+  tmpFirstDead->objectPointer = new T();
+  tmpFirstDead->next = this->deadList;
+  ++this->storedDeadObjects;
+
+  this->deadList = tmpFirstDead;
+}
+
+#endif /* _FAST_FACTORY_H */
Index: branches/heathaze/src/lib/util/loading/game_loader.cc
===================================================================
--- branches/heathaze/src/lib/util/loading/game_loader.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/game_loader.cc	(revision 9940)
@@ -0,0 +1,305 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
+
+#include "game_loader.h"
+#include "util/loading/load_param.h"
+#include "util/loading/resource_manager.h"
+#include "debug.h"
+#include "campaign.h"
+
+#include "key_mapper.h"
+
+ObjectListDefinition(GameLoader);
+
+GameLoader* GameLoader::singletonRef = NULL;
+
+
+/**
+ *  simple constructor
+ */
+GameLoader::GameLoader ()
+{
+  this->registerObject(this, GameLoader::_objectList);
+  this->setName("GameLoader");
+  this->bRun = true;
+}
+
+
+/**
+ *  simple deconstructor
+ */
+GameLoader::~GameLoader ()
+{
+  if( this->currentCampaign)
+    delete this->currentCampaign;
+  this->currentCampaign = NULL;
+
+  GameLoader::singletonRef = NULL;
+}
+
+
+/**
+ *  initializes the GameLoader
+ */
+ErrorMessage GameLoader::init()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->init();
+
+  this->subscribeEvent(ES_GAME, KeyMapper::PEV_PAUSE);
+  this->subscribeEvent(ES_ALL, EV_MAIN_QUIT);          //< External Quit Event
+  this->subscribeEvent(ES_GAME, KeyMapper::PEV_QUIT);
+  this->subscribeEvent(ES_GAME, KeyMapper::PEV_NEXT_WORLD);
+  this->subscribeEvent(ES_GAME, KeyMapper::PEV_PREVIOUS_WORLD);
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  reads a campaign definition file into a campaign class
+ * @param fileName to be loaded
+ * @returns the loaded campaign
+ *
+ * this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
+ */
+ErrorMessage GameLoader::loadCampaign(const std::string& fileName)
+{
+  ErrorMessage errorCode;
+  std::string campaignName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+  if (!campaignName.empty())
+  {
+    this->currentCampaign = this->fileToCampaign(campaignName);
+  }
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  reads a campaign definition file into a campaign class
+ * @param fileName to be loaded
+ * @returns the loaded campaign
+ *
+ * this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
+ */
+ErrorMessage GameLoader::loadNetworkCampaign(const std::string& fileName)
+{
+  ErrorMessage errorCode;
+  std::string campaignName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+  if (!campaignName.empty())
+  {
+    this->currentCampaign = this->fileToCampaign(campaignName);
+  }
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  loads a debug campaign for test purposes only.
+ * @param campaignID the identifier of the campaign.
+ * @returns error message if not able to do so.
+ */
+ErrorMessage GameLoader::loadDebugCampaign(Uint32 campaignID)
+{
+  switch(campaignID)
+  {
+      /*
+         Debug Level 0: Debug level used to test the base frame work.
+         As you can see, all storyentity data is allocated before game
+         start. the storyentity will load themselfs shortly before start
+         through the StoryEntity::init() funtion.
+      */
+    case DEBUG_CAMPAIGN_0:
+      {
+        /*        Campaign* debugCampaign = new Campaign();
+
+                World* world0 = new World(DEBUG_WORLD_0);
+                world0->setNextStoryID(WORLD_ID_1);
+                debugCampaign->addEntity(world0, WORLD_ID_0);
+
+                World* world1 = new World(DEBUG_WORLD_1);
+                world1->setNextStoryID(WORLD_ID_2);
+                debugCampaign->addEntity(world1, WORLD_ID_1);
+
+                World* world2 = new World(DEBUG_WORLD_2);
+                world2->setNextStoryID(WORLD_ID_GAMEEND);
+                debugCampaign->addEntity(world2, WORLD_ID_2);
+
+                this->currentCampaign = debugCampaign;
+                break;*/
+      }
+  }
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  starts the current entity
+ * @returns error code if this action has caused a error
+ */
+ErrorMessage GameLoader::start()
+{
+  if(this->currentCampaign != NULL)
+  {
+    this->currentCampaign->start();
+  }
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  stops the current entity
+ * @returns error code if this action has caused a error
+ *
+ *  ATTENTION: this function shouldn't call other functions, or if so, they must return
+ *  after finishing. If you ignore or forget to do so, the current entity is not able to
+ *  terminate and it will run in the background or the ressources can't be freed or even
+ *  worse: are freed and the program will end in a segmentation fault!
+ *  hehehe, have ya seen it... :)
+ */
+void GameLoader::stop()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->stop();
+}
+
+
+/**
+ *  pause the current entity
+ * @returns error code if this action has caused a error
+ *
+ * this pauses the current entity or passes this call forth to the running entity.
+ */
+ErrorMessage GameLoader::pause()
+{
+  this->isPaused = true;
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->pause();
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  resumes a pause
+ * @returns error code if this action has caused a error
+ *
+ *  this resumess the current entity or passes this call forth to the running entity.
+ */
+ErrorMessage GameLoader::resume()
+{
+  this->isPaused = false;
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->resume();
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  reads a campaign definition file into a campaign class
+ * @param fileName to be loaded
+ * @returns the loaded campaign
+ *
+ * this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
+ */
+Campaign* GameLoader::fileToCampaign(const std::string& fileName)
+{
+  /* do not entirely load the campaign. just the current world
+     before start of each world, it has to be initialized so it
+     can load everything it needs into memory then.
+  */
+
+  if( fileName.empty())
+  {
+    PRINTF(2)("No filename specified for loading");
+    return NULL;
+  }
+
+  TiXmlDocument XMLDoc(fileName);
+  // load the campaign document
+  if( !XMLDoc.LoadFile(fileName))
+  {
+    // report an error
+    PRINTF(1)("Could not load XML File %s: %s @ %d:%d\n", fileName.c_str(), XMLDoc.ErrorDesc(), XMLDoc.ErrorRow(), XMLDoc.ErrorCol());
+    return NULL;
+  }
+
+  // check basic validity
+  TiXmlElement* root = XMLDoc.RootElement();
+  assert( root != NULL);
+
+  if( strcmp( root->Value(), "Campaign"))
+  {
+    // report an error
+    PRINTF(2)("Specified XML File is not an orxonox campaign file (Campaign element missing)\n");
+    return NULL;
+  }
+
+  // construct campaign
+  return new Campaign( root);
+}
+
+
+
+/**
+ *  handle keyboard commands
+ * @param event the event to handle
+ */
+void GameLoader::process(const Event& event)
+{
+  if( event.type == KeyMapper::PEV_NEXT_WORLD)
+  {
+    if( likely(event.bPressed))
+    {
+      this->switchToNextLevel();
+    }
+  }
+  else if( event.type == KeyMapper::PEV_PAUSE)
+  {
+    if( likely(event.bPressed))
+    {
+      if(this->isPaused)
+        this->resume();
+      else
+        this->pause();
+    }
+  }
+  else if( event.type == KeyMapper::PEV_QUIT)
+  {
+    if( event.bPressed) this->stop();
+  }
+  else if (event.type == EV_MAIN_QUIT)
+    this->stop();
+}
+
+
+/**
+ *  this changes to the next level
+ */
+void GameLoader::switchToNextLevel()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->switchToNextLevel();
+}
+
Index: branches/heathaze/src/lib/util/loading/game_loader.h
===================================================================
--- branches/heathaze/src/lib/util/loading/game_loader.h	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/game_loader.h	(revision 9940)
@@ -0,0 +1,77 @@
+/*!
+ * @file game_loader.h
+ *  loads campaigns, worlds and all other story_entities
+*/
+
+#ifndef _GAME_LOADER_H
+#define _GAME_LOADER_H
+
+//#include "stdincl.h"
+#include "story_def.h"
+#include "comincl.h"
+#include "event_listener.h"
+
+#include "error.h"
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class Campaign;
+class World;
+class Factory;
+class TiXmlElement;
+class BaseObject;
+class Event;
+
+//! The GameLoader
+/**
+ *  The game loader loads all game date. this is performed in the following way:
+ * 1. Read the structure of campaings and worlds
+ * 2. Create the instances of the tree: here _ALL_ StoryEntities are created
+ *    also if they are not yet used. the worlds should load their data in
+ *    the StoryEntity::load() and StoryEntity::init() functions! NOWHERE ELSE!
+ *    Elsewhere, all the data will be allocated at the beginning... mess...
+ * 3. StoryEntities are load() and init() before they start
+ * 4. once the gamloader starts the game there will be a campaing starting a
+ *    world. this is done by callaing those StoryEntity::start()
+*/
+class GameLoader : public EventListener
+{
+  ObjectListDeclaration(GameLoader);
+  public:
+  virtual ~GameLoader ();
+  /**  this class is a singleton class @returns an instance of itself  */
+  static GameLoader* getInstance() { if(singletonRef == NULL) singletonRef = new GameLoader(); return singletonRef; }
+
+  ErrorMessage loadCampaign(const std::string& name);
+  ErrorMessage loadDebugCampaign(Uint32 campaignID);
+  ErrorMessage loadNetworkCampaign(const std::string& fileName);
+
+  ErrorMessage init();
+  ErrorMessage start();
+  void stop();
+  ErrorMessage pause();
+  ErrorMessage resume();
+
+  void switchToNextLevel();
+
+  void process(const Event &event);
+
+
+ private:
+  GameLoader ();
+
+  Campaign* fileToCampaign(const std::string& name);
+
+
+ private:
+  static GameLoader*     singletonRef;         //!< The singleton-reference to this object
+
+  Uint32                 startTime;            //!< start time of the campaign
+  bool                   isPaused;             //!< if the game is paused
+  bool                   bRun;                 //!< true if stop
+
+  Campaign*              currentCampaign;      //!< reference to the current campaign playing
+};
+
+#endif /* _GAME_LOADER_H */
Index: branches/heathaze/src/lib/util/loading/load_param.cc
===================================================================
--- branches/heathaze/src/lib/util/loading/load_param.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/load_param.cc	(revision 9940)
@@ -0,0 +1,108 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOADING
+
+#include "load_param.h"
+#include "load_param_class_description.h"
+#include "compiler.h"
+#include "debug.h"
+/**
+ * @brief Constructs a new LoadParameter
+ * @param root the XML-element to load this Parameter from
+ * @param paramName the Parameter to load
+ * @param inLoadCycle If we are in a LoadCycle (loading differs.).
+ */
+LoadParamBase::LoadParamBase(const TiXmlElement* root, const std::string& paramName, bool inLoadCycle)
+    :  paramName(paramName), inLoadCycle(inLoadCycle)
+{
+  // determin the LoadString.
+  if (likely(!inLoadCycle))
+    this->loadElem = grabParameterElement(root, paramName);
+  else if (paramName == root->Value())
+    this->loadElem = (TiXmlElement*)root->FirstChild();
+  else
+    this->loadElem = NULL;
+}
+
+
+/**
+ * @param classID the ID of the class. This is needed to identify into what class this Parameter belongs.
+ * @param descriptionText The text to set as a description for this Parameter
+ * @returns a pointer to itself.
+ */
+void LoadParamBase::describe(const ClassID& classID, const std::string& descriptionText)
+{
+  PRINTF(5)("Describing Class '%s'(id:%d) Parameter '%s': description '%s'\n",
+            classID.name().c_str(), classID.id(), paramName.c_str(), descriptionText.c_str());
+
+  if (LoadParamClassDescription::descriptionsCaptured())
+    LoadParamClassDescription::describeClass(classID, paramName, descriptionText);
+}
+
+/**
+ * @brief sets the Values of the Description to a usefull text.
+ */
+void LoadParamBase::setDescriptionValues(const ClassID& classID, unsigned int paramCount, const MultiType* const defaultValues, bool retVal)
+{
+  if(LoadParamClassDescription::descriptionsCaptured())
+    LoadParamClassDescription::setValuesOf(classID, paramName, paramCount, defaultValues, retVal);
+}
+
+
+//////////////////////
+// HELPER FUNCTIONS //
+//////////////////////
+/**
+ * @param root: The XML-element to grab a parameter from
+ * @param parameterName: the parameter to grab
+ * @returns the Value of the parameter if found, NULL otherwise
+*/
+std::string LoadParamBase::grabParameter(const TiXmlElement* root, const std::string& parameterName)
+{
+  const TiXmlElement* const element = grabParameterElement(root, parameterName);
+  if (element != NULL)
+    return element->Value();
+  else
+  {
+    static std::string empty("");
+    return empty;
+  }
+}
+
+/**
+ * @param root: The XML-element to grab a parameter from
+ * @param parameterName: the parameter to grab
+ * @returns the Element of the parameter if found, NULL otherwise
+ */
+const TiXmlElement* LoadParamBase::grabParameterElement(const TiXmlElement* root, const std::string& parameterName)
+{
+  const TiXmlElement* element;
+  const TiXmlNode* node;
+
+  if (root == NULL)
+    return NULL;
+
+  element = root->FirstChildElement( parameterName);
+  if( element == NULL) return NULL;
+
+  node = element->FirstChild();
+  while( node != NULL)
+  {
+    if( node->ToText()) return (TiXmlElement*)node;
+    node = node->NextSibling();
+  }
+  return NULL;
+}
Index: branches/heathaze/src/lib/util/loading/load_param.h
===================================================================
--- branches/heathaze/src/lib/util/loading/load_param.h	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/load_param.h	(revision 9940)
@@ -0,0 +1,159 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file load_param.h
+ * A Class and macro-functions, that makes our lives easy to load-in parameters
+ */
+
+#ifndef _LOAD_PARAM_H
+#define _LOAD_PARAM_H
+
+#include "util/executor/executor_substring.h"
+#include "util/executor/executor_member.h"
+#include "util/executor/functor_member.h"
+
+#include "parser/tinyxml/tinyxml.h"
+
+// Forward Declaration //
+class LoadClassDescription;
+class LoadParamDescription;
+class TiXmlElement;
+
+/**
+ * Loads a Parameter from ROOT named PARAMETER_NAME
+ * onto OBJECT of CLASS, trough FUNCTION
+ * @param ROOT the TiXmlElement to load the Parameter from
+ * @param PARAMETER_NAME the Name of the Parameter to load
+ * @param OBJECT The BaseObject to load the new setting to.
+ * @param CLASS What Class the BaseObejct is of (this is for identifying the Functuon)
+ * @param FUNCTION The function of Class to Load (if you want to call &CLASS::FUNCTION write FUNCTION here).
+ */
+#define LoadParam(ROOT, PARAMETER_NAME, OBJECT, CLASS, FUNCTION) \
+         CLoadParam<CLASS>(ROOT, PARAMETER_NAME, OBJECT, createExecutor<CLASS, CLASS>(&CLASS::FUNCTION), false)
+
+/**
+ * @brief Does essentially the same as LoadParam, but within a Cycle in an ordered fashion.
+ *
+ * This Function looks in each Element, if the PARAMETER_NAME matches, and loads onto OBJECT
+ * of CLASS the ROOT through FUNCTION
+ *
+ * @see LoadParam(ROOT, PARAMETER_NAME, OBJECT, CLASS, FUNCTION)
+ */
+#define LoadParam_CYCLE(ROOT, PARAMETER_NAME, OBJECT, CLASS, FUNCTION) \
+         CLoadParam<CLASS>(ROOT, PARAMETER_NAME, OBJECT, createExecutor<CLASS, CLASS>(&CLASS::FUNCTION), true)
+
+/**
+ * this Starts a Cycle in the Loading Process
+ * be aware, that in the cycle the first parameter of load_param should because
+ * called element, and that you must say true at the Fith parameter, or it will fail
+ * also you will have to close the Cycle again with LOAD_PARAM_END_CYCLE
+ *
+ * @param ROOT The root XLM-element to search element under.
+ * @param ELEMENT the element to search
+ */
+#define LOAD_PARAM_START_CYCLE(ROOT, ELEMENT) \
+  const TiXmlElement* ELEMENT; \
+  ELEMENT= ROOT->FirstChildElement(); \
+  while( ELEMENT != NULL) \
+{
+/**
+   * closes a LoadParam Loop
+   * @see LOAD_PARAM_START_CYCLE
+   * @param ELEMENT the Element to step through.
+ */
+#define LOAD_PARAM_END_CYCLE(ELEMENT) \
+  ELEMENT = ELEMENT->NextSiblingElement(); \
+}
+
+
+/**************************
+**** REAL DECLARATIONS ****
+**************************/
+//!< A BaseClass for all LoadParam's.
+class LoadParamBase
+{
+protected:
+  LoadParamBase(const TiXmlElement* root, const std::string& paramName, bool inLoadCycle = false);
+
+protected:
+  void describe(const ClassID& classID, const std::string& descriptionText);
+  void setDescriptionValues(const ClassID& classID, unsigned int paramCount, const MultiType* const defaultValues, bool retVal = false);
+
+public:
+  static std::string grabParameter(const TiXmlElement* root, const std::string& parameterName);
+  static const TiXmlElement* grabParameterElement(const TiXmlElement* root, const std::string& parameterName);
+
+protected:
+  const std::string        paramName;            //!< The Name of the Parameter this LoadParams applies to.
+  bool                     inLoadCycle;          //!< If the Parameter is in a LoadCycle.
+
+  const TiXmlElement*      loadElem;             //!< The Element to load.
+};
+
+
+//! The Loading Class of the LoadParam, that acctually executes the loading process.
+template <class OperateClass> class CLoadParam : public LoadParamBase
+{
+public:
+  /**
+   * @brief generates a LoadParam based on:
+   * @param root the Root Element to load onto the object. @param paramName the Parameter name that is loaded.
+   * @param object the Object to apply the changes on. @param executor the Functional Object, that actually executes the function Call.
+   * @param inLoadCycle If we are inside of a loading cycle. (Loading will be different here)
+   */
+  CLoadParam(const TiXmlElement* root, const std::string& paramName, OperateClass* object, Executor<const SubString, OperateClass>* executor, bool inLoadCycle = false)
+      : LoadParamBase(root, paramName, inLoadCycle)
+  {
+    assert (executor != NULL);
+    this->object = object;
+    this->executor = executor;
+  }
+  virtual ~CLoadParam()
+  {
+    std::string loadString;
+    if (this->loadElem != NULL &&  this->loadElem->ToText())
+    {
+      loadString = this->loadElem->Value();
+      if (!loadString.empty())
+      {
+        /*	PRINTF(4)("Loading value '%s' with Parameters '%s' onto: %s::%s\n",
+        	this->paramName.c_str(), loadString.c_str(), this->object->getClassCName(), this->object->getCName());*/
+        (*this->executor)(this->object, SubString(loadString, ",", SubString::WhiteSpaces, false, '\\'));
+      }
+    }
+    this->setDescriptionValues(OperateClass::staticClassID(), executor->getParamCount(), executor->getDefaultValues(), executor->hasRetVal());
+    delete this->executor;
+  }
+  /**
+   * @brief set the default values of the executor
+   * @param value0 the first default value   @param value1 the second default value
+   * @param value2 the third default value   @param value3 the fourth default value
+   * @param value4 the fifth default value
+   */
+  CLoadParam& defaultValues(const MultiType& value0 = MT_NULL, const MultiType& value1 = MT_NULL,
+                            const MultiType& value2 = MT_NULL, const MultiType& value3 = MT_NULL,
+                            const MultiType& value4 = MT_NULL)
+  { this->executor->defaultValues(value0, value1, value2, value3, value4); return *this;  };
+  //! Describes a LoadParam
+  CLoadParam& describe(const std::string& descriptionText) { LoadParamBase::describe(OperateClass::staticClassID(), descriptionText); return *this; };
+  //     CLoadParam& attribute(const std::string& attributeName, const Executor<SubString>& executor);
+
+private:
+  Executor<const SubString, OperateClass>*         executor;            //!< The Executor, that actually executes the Loading process.
+  OperateClass*                                    object;              //!< The Object this LoadParam operates on.
+};
+
+#endif /* _LOAD_PARAM_H */
Index: branches/heathaze/src/lib/util/loading/load_param_class_description.cc
===================================================================
--- branches/heathaze/src/lib/util/loading/load_param_class_description.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/load_param_class_description.cc	(revision 9940)
@@ -0,0 +1,171 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#include "load_param_class_description.h"
+
+#include "multi_type.h"
+#include "debug.h"
+#include <cassert>
+
+/**
+ * @brief A list, that holds all the classes that are loadable (classes not objects!!)
+ */
+LoadParamClassDescription::ClassDescriptionMap LoadParamClassDescription::_classList;
+
+/**
+ * @brief if the description of Parameters should be executed
+ */
+bool LoadParamClassDescription::_captureDescriptions = false;
+
+/**
+ * @param className the name of the class to be loadable
+ */
+LoadParamClassDescription::LoadParamClassDescription(const std::string& className)
+    : _className(className)
+{ }
+
+
+/**
+ * @brief clears all LoadParamDescriptions.
+ */
+void LoadParamClassDescription::deleteAllDescriptions()
+{
+  LoadParamClassDescription::_classList.clear();
+}
+
+
+/**
+ * @brief describes a LoadParam-parameter.
+ * @param classID the ID of the class.
+ * @param paramName the Name of the Parameter.
+ * @param descriptionText the Test to set.
+ */
+void LoadParamClassDescription::describeClass(const ClassID& classID,
+    const std::string& paramName,
+    const std::string& descriptionText)
+{
+  ParamDescriptionMap::iterator it = LoadParamClassDescription::getParamDescription(classID, paramName);
+
+  (*it).second.setDescription(descriptionText);
+}
+
+/**
+ * @brief sets Values of the specified LoadParam-parameter.
+ * @param classID the ID of the class.
+ * @param paramName the name of the Parameter.
+ * @param paramCount the count of Parameters this LoadParam takes.
+ * @param defaultValues the default Values.
+ * @param retVal if the Parameter takes return Values.
+ */
+void LoadParamClassDescription::setValuesOf(const ClassID& classID,
+    const std::string& paramName,
+    unsigned int paramCount,
+    const MultiType* const defaultValues,
+    bool retVal)
+{
+  ParamDescriptionMap::iterator it = LoadParamClassDescription::getParamDescription(classID, paramName);
+  (*it).second.setValues(paramCount, defaultValues, retVal);
+}
+
+
+/**
+ * @brief finds the Iterator to the ParameterDescription paramName matching classID
+ * @param classID the ClassID to match.
+ * @param paramName the name of the parameter in the Class.
+ * @returns the iterator on match.
+ *
+ * @note this function creates the Element classID.name()::paramName on the go if it does not exist.
+ */
+LoadParamClassDescription::ParamDescriptionMap::iterator
+LoadParamClassDescription::getParamDescription(const ClassID& classID, const std::string& paramName)
+{
+  /// Locate the ClassDescription first
+  ClassDescriptionMap::iterator classIt = LoadParamClassDescription::_classList.find(classID);
+  if (classIt == LoadParamClassDescription::_classList.end())
+  {
+    LoadParamClassDescription::_classList[classID] = LoadParamClassDescription(classID.name());
+    classIt = LoadParamClassDescription::_classList.find(classID);
+  }
+  // At this position the class-iterator should point to a valid usefull position.
+  assert(classIt != LoadParamClassDescription::_classList.end());
+
+  /// Now locate the description with paramName.
+  ParamDescriptionMap::iterator paramIt = (*classIt).second._parameters.find(paramName);
+  if (paramIt == (*classIt).second._parameters.end())
+  {
+    (*classIt).second._parameters[paramName] = LoadParamDescription(paramName);
+    paramIt = (*classIt).second._parameters.find(paramName);
+  }
+  // at this position the param-iterator should
+  assert (paramIt != (*classIt).second._parameters.end());
+
+  return (paramIt);
+}
+
+/**
+ * @brief prints out a nice output about this Classes Loading, and their parameters
+ * @param stream the stream to write to.
+ * @param withComments if Comments should be included.
+ */
+void LoadParamClassDescription::print(FILE* stream, bool withComments) const
+{
+  fprintf(stream, "<%s>\n", this->_className.c_str());
+  for (ParamDescriptionMap::const_iterator param = this->_parameters.begin();
+       param != this->_parameters.end();
+       ++param)
+  {
+    (*param).second.print(stream, withComments);
+  }
+  fprintf(stream, "</%s>\n\n", this->_className.c_str());
+}
+
+
+/**
+ * @brief prints out all loadable Classes, and their parameters
+ * @param fileName prints the output to a File
+ * @param withComments if Comments should be included.
+ */
+void LoadParamClassDescription::printAll(const std::string& fileName, bool withComments)
+{
+  FILE* stream;
+  if( (stream = fopen (fileName.c_str(), "w")) == NULL)
+  {
+    PRINTF(2)("File '%s' could not be opened for writing\n Printing to stdout\n", fileName.c_str());
+    LoadParamClassDescription::printAllTo(stdout, withComments);
+    return;
+  }
+  else
+    LoadParamClassDescription::printAllTo(stream, withComments);
+
+  fclose (stream);
+}
+
+/**
+ * @brief prints out all loadable Classes, and their parameters to a stream
+ * @param stream the stream to print to.
+ * @param withComments if Comments should be included.
+ */
+void LoadParamClassDescription::printAllTo(FILE* stream, bool withComments)
+{
+  fprintf(stream, "===============================================================\n");
+  fprintf(stream, " Listing all the Loadable Options (loaded since Game started).\n\n");
+  for (ClassDescriptionMap::const_iterator classIt = LoadParamClassDescription::_classList.begin();
+       classIt != LoadParamClassDescription::_classList.end();
+       classIt ++)
+  {
+    (*classIt).second.print(stream, withComments);
+  }
+  fprintf(stream, "===============================================================\n");
+}
Index: branches/heathaze/src/lib/util/loading/load_param_class_description.h
===================================================================
--- branches/heathaze/src/lib/util/loading/load_param_class_description.h	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/load_param_class_description.h	(revision 9940)
@@ -0,0 +1,84 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file load_param_class_description.h
+ * A Class and macro-functions, that makes our lives easy to load-in parameters
+ */
+
+#ifndef _LOAD_PARAM_CLASS_DESCRIPTION_H
+#define _LOAD_PARAM_CLASS_DESCRIPTION_H
+
+#include "load_param_description.h"
+#include "class_id.h"
+#include <map>
+// Forward Declaration //
+class MultiType;
+
+//! A class for descriptions of a loadable module
+class LoadParamClassDescription
+{
+public:
+  LoadParamClassDescription(const std::string& className = "");
+
+  //! Compares a LoadParamClassDescription with a String.
+  bool operator==(const std::string& className) const { return this->_className == className; };
+  //! Compares two LoadParamClassDescription with each other
+  bool operator==(const LoadParamClassDescription& classDescr) const { return this->_className == classDescr._className; };
+  //! Compares two LoadParamClassDescription with each other, using the less operator
+  bool operator<(const LoadParamClassDescription& classDescr) const { return this->_className < classDescr._className; }
+
+
+  static void describeClass(const ClassID& classID,
+                            const std::string& paramName,
+                            const std::string& descriptionText);
+  static void setValuesOf(const ClassID& classID,
+                          const std::string& paramName,
+                          unsigned int paramCount,
+                          const MultiType* const defaultValues,
+                          bool retVal = false);
+
+  /** @param createThem: if the Parameters should be created/stored. */
+  static void captureDescriptions(bool createThem) { _captureDescriptions = createThem; };
+  /** @returns if the Parameters are created/stored. */
+  static bool descriptionsCaptured() { return _captureDescriptions; };
+
+  static void deleteAllDescriptions();
+
+  void print(FILE* stream = stdout, bool withComments = true) const;
+  static void printAll(const std::string& fileName = "", bool withComments = true);
+  static void printAllTo(FILE* stream = stdout, bool withComments = true);
+
+private:
+  //! A Type definition for the Map of Class Descriptions
+  typedef std::map<ClassID, LoadParamClassDescription>  ClassDescriptionMap;
+  //! A type definition for the Map of Parameter Descriptions inside of Class-descriptions.
+  typedef std::map<std::string, LoadParamDescription>   ParamDescriptionMap;
+
+private:
+  static ParamDescriptionMap::iterator getParamDescription(const ClassID& classID, const std::string& paramName);
+
+private:
+
+  static bool                                  _captureDescriptions;    //!< if parameter-description should be enabled globally.
+
+  static ClassDescriptionMap                   _classList;              //!< a list, that stores all the loadable classes. (after one instance has been loaded)
+
+private:
+  std::string                                  _className;              //!< name of the class
+  ParamDescriptionMap                          _parameters;             //!< List of parameters this class knows.
+};
+
+#endif /* _LOAD_PARAM_CLASS_DESCRIPTION_H */
Index: branches/heathaze/src/lib/util/loading/load_param_description.cc
===================================================================
--- branches/heathaze/src/lib/util/loading/load_param_description.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/load_param_description.cc	(revision 9940)
@@ -0,0 +1,100 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#include "load_param_description.h"
+
+#include "multi_type.h"
+#include "debug.h"
+
+/**
+ * @brief Creates a Description of a LoadParam
+ * @param paramName the name of the parameter to load
+ */
+LoadParamDescription::LoadParamDescription(const std::string& paramName)
+    : _name(paramName), _parameterCount(0)
+{ }
+
+/**
+ * @param descriptionText The text to set as a description for this Parameter
+ */
+void LoadParamDescription::setDescription(const std::string& descriptionText)
+{
+  this->_description = descriptionText;
+}
+
+/**
+ * @brief sets the Values of the LoadParam in the Description.
+ * @param paramCount the count of arguments the underlying paramDescription takes.
+ * @param defaultValues the default Values the underlying parameter takes.
+ * @param retVal if the underlying parameter has a return value
+ */
+void LoadParamDescription::setValues(unsigned int paramCount,
+                                     const MultiType* const defaultValues,
+                                     bool retVal)
+{
+  this->_parameterCount = paramCount;
+  for (unsigned int i = 0; i < paramCount; ++i)
+  {
+    this->_defaultValues.push_back(defaultValues[i].getString());
+    this->_types.push_back(MultiType::MultiTypeToString(defaultValues[i].getType()));
+  }
+
+}
+
+
+/**
+ * @brief prints out this parameter, its input method and the description (if availiable)
+ * @param stream the stream to print to.
+ * @param withComments if the comments should be appended.
+ */
+void LoadParamDescription::print(FILE* stream, bool withComments) const
+{
+  fprintf(stream, " <%s>", this->_name.c_str());
+  for (unsigned int i = 0; i < this->_parameterCount; i++)
+  {
+    if (i > 0)
+      fprintf(stream, ",");
+    fprintf(stream, "%s", this->_types[i].c_str());
+  }
+  fprintf(stream, "</%s>", this->_name.c_str());
+  // here the comments are printed out.
+  if (withComments)
+  {
+    if (!this->_description.empty())
+      fprintf(stream, " <!-- %s", this->_description.c_str());
+    // default values
+    if (this->_parameterCount > 0)
+    {
+      fprintf(stream, " (Default: ");
+      for (unsigned int i = 0; i < this->_parameterCount; i++)
+      {
+        if (i > 0)
+          fprintf(stream, ", ");
+        if (this->_types[i] == "string")
+        { // leave brackets !!
+          fprintf(stream, "\"%s\"", this->_defaultValues[i].c_str());
+        }
+        else
+        {
+          fprintf(stream, "%s", this->_defaultValues[i].c_str());
+        }
+      }
+      fprintf(stream, ")");
+    }
+    if (!this->_description.empty() || this->_parameterCount > 0)
+      fprintf(stream, " -->");
+  }
+  fprintf(stream, "\n");
+}
Index: branches/heathaze/src/lib/util/loading/load_param_description.h
===================================================================
--- branches/heathaze/src/lib/util/loading/load_param_description.h	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/load_param_description.h	(revision 9940)
@@ -0,0 +1,65 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file load_param_description.h
+ * A Class and macro-functions, that makes our lives easy to load-in parameters
+ */
+
+#ifndef _LOAD_PARAM_DESCRIPTION_H
+#define _LOAD_PARAM_DESCRIPTION_H
+
+#include <vector>
+#include <string>
+
+// Forward Declaration //
+class MultiType;
+
+/************************
+*** DESCRIPTION STUFF ***
+************************/
+//! A class that handles the description of loadable parameters
+class LoadParamDescription
+{
+public:
+  LoadParamDescription(const std::string& paramName = "");
+
+  //! Compares a LoadParamDescription with a String.
+  bool operator==(const std::string& paramName) const { return this->_name == paramName; };
+  //! Compares two LoadParamDescription
+  bool operator==(const LoadParamDescription& paramDescr) const { return this->_name == paramDescr._name; };
+  //! Compares two LoadParamDescription with the less operator
+  bool operator<(const LoadParamDescription& paramDescr) const { return this->_name < paramDescr._name; };
+
+  void setDescription(const std::string& descriptionText);
+  void setValues(unsigned int paramCount,
+                 const MultiType* const defaultValues,
+                 bool retVal = false);
+
+  /** @returns the descriptionString */
+  const std::string& description() { return this->_description; };
+
+  void print(FILE* stream = stdout, bool withComments = true) const;
+
+private:
+  std::string                _name;                  //!< The Name of the Parameter.
+  unsigned int               _parameterCount;        //!< The Count of parameters.
+  std::string                _description;           //!< A longer description about this function.
+
+  std::vector<std::string>   _types;                 //!< A Vector of types of this Parameter.
+  std::vector<std::string>   _defaultValues;         //!< A Vector of defaultValues of this Parameter.
+};
+
+#endif /* _LOAD_PARAM_DESCRIPTION_H */
Index: branches/heathaze/src/lib/util/loading/load_param_xml.h
===================================================================
--- branches/heathaze/src/lib/util/loading/load_param_xml.h	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/load_param_xml.h	(revision 9940)
@@ -0,0 +1,86 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file load_param_xml.h
+ * A Class and macro-functions, that makes our lives easy to load-in parameters from XML
+ */
+
+#ifndef _LOAD_PARAM_XML_H
+#define _LOAD_PARAM_XML_H
+
+#include "load_param.h"
+#include "executor/executor_xml.h"
+
+/**
+ * @brief Loads a Parameter from ROOT named PARAMETER_NAME
+ * onto OBJECT of CLASS, trough FUNCTION
+ * @param ROOT the TiXmlElement to load the Parameter from
+ * @param PARAMETER_NAME the Name of the Parameter to load
+ * @param OBJECT The BaseObject to load the new setting to.
+ * @param CLASS What Class the BaseObejct is of (this is for identifying the Functuon)
+ * @param FUNCTION The function of Class to Load (if you want to call &CLASS::FUNCTION write FUNCTION here).
+ */
+#define LoadParamXML(ROOT, PARAMETER_NAME, OBJECT, CLASS, FUNCTION) \
+         XmlLoadParam<CLASS>(ROOT, PARAMETER_NAME, OBJECT, new ExecutorXML<CLASS, CLASS>(&CLASS::FUNCTION, ROOT, PARAMETER_NAME), false)
+
+
+/**
+ * @brief Does essentially the same as LoadParamXML, but within a Cycle in an ordered fashion.
+ *
+ * This Function looks in each Element, if the PARAMETER_NAME matches, and loads onto OBJECT
+ * of CLASS the ROOT through FUNCTION
+ *
+ * @see LoadParamXML(ROOT, PARAMETER_NAME, OBJECT, CLASS, FUNCTION)
+ */
+#define LoadParamXML_CYCLE(ROOT, PARAMETER_NAME, OBJECT, CLASS, FUNCTION) \
+         XmlLoadParam<CLASS>(ROOT, PARAMETER_NAME, OBJECT, new ExecutorXML<CLASS, CLASS>(&CLASS::FUNCTION, ROOT, PARAMETER_NAME), true)
+
+//! A Class that can load XML tags onto an Object.
+template <class OperateClass = BaseObject> class XmlLoadParam : public LoadParamBase
+{
+public:
+  /**
+   * @brief generates a LoadParam based on
+   * @param root the Root Element to load onto the object.
+   * @param paramName the Parameter name that is loaded.
+   * @param object the Object to apply the changes on.
+   * @param executor the Functional Object, that actually executes the function Call.
+   * @param inLoadCycle If we are inside of a loading cycle. (Loading will be different here)
+   */
+  XmlLoadParam(const TiXmlElement* root, const std::string& paramName, OperateClass* object, Executor<const TiXmlElement*>* executor, bool inLoadCycle = false)
+      : LoadParamBase(root, paramName, inLoadCycle), object(object) , executor(executor)
+  {
+    assert(this->object != NULL);
+    assert(this->executor != NULL);
+  }
+
+  /** @brief executes and destroys the executor */
+  virtual ~XmlLoadParam()
+  {
+    this->setDescriptionValues(OperateClass::staticClassID(), executor->getParamCount(), executor->getDefaultValues(), executor->hasRetVal());
+    (*this->executor)(this->object, this->loadElem);
+    delete this->executor;
+  }
+
+  /** @param descriptionText the description @returns self @brief describes the Loading parameter. */
+  XmlLoadParam& describe(const std::string& descriptionText) { LoadParamBase::describe(OperateClass::staticClassID(), descriptionText); return *this; };
+
+private:
+  OperateClass*                        object;         //!< The Object to apply this to.
+  Executor<const TiXmlElement*>*    executor;       //!< The Executor, that does the actual loading process.
+};
+
+#endif /* _LOAD_PARAM_XML_H */
Index: branches/heathaze/src/lib/util/loading/resource.cc
===================================================================
--- branches/heathaze/src/lib/util/loading/resource.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/resource.cc	(revision 9940)
@@ -0,0 +1,292 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
+
+#include "resource.h"
+#include "resource_manager.h"
+
+#include "debug.h"
+
+
+namespace Resources
+{
+  //! Define an ObjectList for the Resources
+  ObjectListDefinition(Resource);
+
+
+  /**
+   * @brief standard constructor
+   * @param type the Type this resource belongs to.
+   */
+  Resource::Resource (Type* type)
+      : _pointer(NULL), _type(type)
+  {
+    this->registerObject(this, Resource::_objectList);
+  }
+
+  /**
+   * @brief standard deconstructor
+   */
+  Resource::~Resource ()
+  {
+    // delete what has to be deleted here
+  }
+
+  /**
+   * @brief Locates a File inside of the Resources Paths and returns the appended path.
+   *
+   * @param fileName the Name of the file to look for.
+   * @returns the Name of the File prepended with the PAth it is in, if found, empty String ("") otherwise.
+   *
+   * This Function searches in (ordered):
+   * 1. mainGlobalPath (from ResourceManger)
+   * 2. all of the global Paths (from ResourceManger)
+   * 3. all of the Resources Paths (from Resources::Type)
+   *
+   * in each of these directory, first "./" is searched, and afterwards all of the subDirs (from Resources::Type) are searched.
+   *
+   * @todo finish it!!
+   */
+  std::string Resource::locateFile(const std::string& fileName) const
+  {
+    if ((ResourceManager::getInstance()->mainGlobalPath() + File(fileName)).exists() )
+      return (ResourceManager::getInstance()->mainGlobalPath() + File(fileName)).name();
+
+    std::string locatedFile;
+    locatedFile = locateFileInSubDir(ResourceManager::getInstance()->mainGlobalPath(), fileName);
+    if (!locatedFile.empty())
+    {
+      return locatedFile;
+    }
+
+    if (File(fileName).exists())
+      return fileName;
+
+    return (ResourceManager::getInstance()->mainGlobalPath() + File(fileName)).name();
+  }
+
+  /**
+   * @brief tests in all the SubDirectories defined in Resource under Directory if the fileName exists.
+   * @param directory the directory to in what to search for all subdirectories for.
+   * @param fileName the Name of the File to query for
+   * @return true on success.
+   */
+  std::string Resource::locateFileInSubDir(const Directory& directory, const std::string& fileName) const
+  {
+    std::vector<Directory>::const_iterator it;
+    for (it = this->_type->resourceSubPaths().begin(); it != this->_type->resourceSubPaths().end(); ++it)
+    {
+      Directory dir = directory + (*it);
+      File file = dir + File(fileName);
+      if ((dir+ File(fileName)).exists())
+        return (dir+File(fileName)).name();
+    }
+    return "";
+  }
+
+
+  /**
+   * @param loadString the Identifier of the Resource.
+   * @returns a Store-Pointer to the Resource if found, NULL otherwise
+   */
+  StorePointer* Resource::acquireResource(const std::string& loadString)
+  {
+    //const Type* const type = _resourceTypes[this->_type->id()];
+
+    for (unsigned int i = 0; i < _type->storedResources().size(); ++i)
+    {
+      if (_type->storedResources()[i]->loadString() == loadString)
+        return _type->storedResources()[i];
+    }
+
+    return NULL;
+  }
+
+  /**
+   * @brief registers a StorePointer to a Resource's Type.
+   * @param pointer the StorePointer to register.
+   */
+  void Resource::addResource(StorePointer* pointer)
+  {
+    assert(pointer != NULL);
+    this->_type->addResource(pointer);
+  }
+
+
+
+
+
+
+  ///////////////////
+  //// KEEPLEVEL ////
+  ///////////////////
+
+  //! Constructs a default KeepLevel as Set in the ResourceManager via setDefaultKeepLevel.
+  KeepLevel::KeepLevel()
+  {
+    this->_keepLevel = ResourceManager::getInstance()->defaultKeepLevel().keepLevel();
+  }
+  /**
+   * @param keepLevel the level to set.
+   */
+  KeepLevel::KeepLevel(unsigned int keepLevel)
+  {
+    _keepLevel = keepLevel;
+  }
+
+  /**
+   * @brief constructor of a KeepLevel.
+   * @param keepLevelName the Name of the KeepLevel. Must be one Name of the defined Names in the ResourceManager.
+   *
+   * @note the Name is transformed into an Integer for fast interpretation.
+   */
+  KeepLevel::KeepLevel(const std::string& keepLevelName)
+  {
+    this->_keepLevel = ResourceManager::getInstance()->getKeepLevelID(keepLevelName);
+  }
+
+  /**
+   * @returns the name of the KeepLevel.
+   */
+  const std::string& KeepLevel::name() const
+  {
+    return ResourceManager::getInstance()->getKeepLevelName(this->_keepLevel);
+  }
+
+
+
+  ///////////////////////
+  //// STORE POINTER ////
+  ///////////////////////
+  /**
+   * @brief allocates a StorePointer.
+   * @param loadString An identifier String that is unique between all resources of this type.
+   * @param keepLevel the KeepLevel at wich to keep this resource.
+   */
+  StorePointer::StorePointer(const std::string& loadString, const KeepLevel& keeplevel)
+      : _loadString(loadString), _keepLevel(keeplevel)
+  {
+    PRINTF(4)("Acquired a Resource with LoadString '%s' and KeepLevel '%s'\n", _loadString.c_str(), _keepLevel.name().c_str());
+  }
+
+  StorePointer::~StorePointer()
+  {
+    PRINTF(4)("Deleting Stored Resource '%s' from KeepLevel '%s'\n", _loadString.c_str(), _keepLevel.name().c_str());
+  };
+
+
+
+  //////////////
+  //// TYPE ////
+  //////////////
+  /**
+   * @brief allocates a Type.
+   * @param typeName the Name of the Type to be stored in this Container.
+   */
+  Type::Type(const std::string& typeName)
+      : _typeName(typeName)
+  {
+    ResourceManager::getInstance()->registerType(this);
+    PRINTF(4)("Created ResourceType '%s'\n", typeName.c_str());
+  }
+
+  //! Destructs a Type.
+  Type::~Type()
+  {
+    ResourceManager::getInstance()->unregisterType(this);
+  }
+
+  /**
+   * @brief adds a Resource to this Resource's type.
+   * @param resource the Resource to add.
+   */
+  void Type::addResource(StorePointer* resource)
+  {
+    this->_storedResources.push_back(resource);
+  }
+
+  /**
+   * @brief adds a Path to the Type's resource-paths.
+   * @param path the path-name to add.
+   */
+  bool Type::addResourcePath(const std::string& path)
+  {
+    std::vector<Directory>::const_iterator it;
+    for (it = this->_resourcePaths.begin(); it != this->_resourcePaths.end(); ++it)
+      if ((*it) == path)
+        return false;
+    this->_resourcePaths.push_back(path);
+    return true;
+
+  }
+
+  /**
+   * @brief Adds a SubPath to the Type's resource-subpaths.
+   * @param subPath the subpath to add.
+   */
+  bool Type::addResourceSubPath(const std::string& subPath)
+  {
+    std::vector<Directory>::const_iterator it;
+    for (it = this->_resourceSubPaths.begin(); it != this->_resourceSubPaths.end(); ++it)
+      if ((*it) == subPath)
+        return false;
+    this->_resourceSubPaths.push_back(subPath);
+    return true;
+  }
+
+  /**
+   * @brief Unloads all Resources below a certain Level.
+   * @param keepLevel the KeepLevel at what to remove the Resources from.
+   */
+  void Type::unloadAllBelowKeepLevel(const Resources::KeepLevel& keepLevel)
+  {
+    std::vector<Resources::StorePointer*>::iterator it, it2;
+    bool finished = false;
+
+    while (!finished)
+    {
+      finished = true;
+      for (it = this->_storedResources.begin(); it != this->_storedResources.end();++it)
+        if((*it)->keepLevel() < keepLevel && (*it)->last())
+        {
+          delete (*it);
+          this->_storedResources.erase(it);
+          finished = false;
+          break;
+        }
+    }
+  }
+
+  /**
+   * @brief print out some nice Debug information in a beatifully designed style
+   */
+  void Type::debug() const
+  {
+    PRINT(0)(" ResourceType '%s' stores %d Resources\n", this->_typeName.c_str(), this->_storedResources.size());
+    PRINT(0)("  Paths:\n");
+    for (unsigned int i = 0; i < this->_resourcePaths.size(); ++i)
+      PRINT(0)("    %s\n", this->_resourcePaths[i].name().c_str());
+    PRINT(0)("  Sub-Paths:");
+    for (unsigned int i = 0; i < this->_resourceSubPaths.size(); ++i)
+      PRINT(0)(" '%s'", this->_resourceSubPaths[i].name().c_str());
+    PRINT(0)("\n");
+
+    PRINT(0)("  Loaded Resources:\n");
+    std::vector<Resources::StorePointer*>::const_iterator it;
+    for (it = this->_storedResources.begin(); it != this->_storedResources.end(); ++it)
+      PRINT(0)("    '%s' : KeepLevel '%s'\n", (*it)->loadString().c_str(), (*it)->keepLevel().name().c_str());
+  }
+}
Index: branches/heathaze/src/lib/util/loading/resource.h
===================================================================
--- branches/heathaze/src/lib/util/loading/resource.h	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/resource.h	(revision 9940)
@@ -0,0 +1,195 @@
+/*!
+ * @file resource.h
+ * @brief Definition of a Resource.
+*/
+
+#ifndef _RESOURCE_H
+#define _RESOURCE_H
+
+#include "base_object.h"
+#include <string>
+#include <vector>
+#include <set>
+
+#include "filesys/directory.h"
+
+//! A Namespace Resources and ResourceHandling is defined in.
+namespace Resources
+{
+  //! The KeepLevel handles the unloading of Resources.
+  /**
+   * Allocating a Resource also appends a KeepLevel to the Resource.
+   * When the Resource is not used anymore it is decided on the grounds of the KeepLevel,
+   * if the Resource should be deleted. (e.g. at the end of a Level, Campaign, or something like this).
+   */
+  class KeepLevel
+  {
+  public:
+    KeepLevel();
+    KeepLevel(unsigned int keepLevel);
+    KeepLevel(const std::string& keepLevelName);
+
+    //! Compare equality
+    inline bool operator==(const KeepLevel& keepLevel) const { return this->_keepLevel == keepLevel._keepLevel; };
+    //! Compares inequality
+    inline bool operator!=(const KeepLevel& keepLevel) const { return this->_keepLevel != keepLevel._keepLevel; };
+    //! Compares less/equal than
+    inline bool operator<=(const KeepLevel& keepLevel) const { return this->_keepLevel <= keepLevel._keepLevel; };
+    //! Compares less than
+    inline bool operator<(const KeepLevel& keepLevel) const { return this->_keepLevel < keepLevel._keepLevel; };
+
+    /** @returns the KeepLevel as a number */
+    inline unsigned int keepLevel() const { return _keepLevel; };
+    const std::string& name() const;
+  private:
+    unsigned int                _keepLevel;              //!< The KeepLevel a Resource is in.
+  };
+
+
+  ///////////////////
+  // STORE POINTER //
+  ///////////////////
+  //! Stores a Resource-Pointer, the LoadString and it's keepLevel.
+  class StorePointer
+  {
+  public:
+    //! Virtual Destructor, that removes the Stored information-pointer.
+    virtual ~StorePointer();
+
+    /** @returns the LoadString this resource was loaded with */
+    const std::string& loadString() const { return _loadString; };
+    /** @returns the KeepLevel of this resource */
+    const Resources::KeepLevel& keepLevel() const { return _keepLevel; };
+
+    virtual bool last() const = 0;
+
+    protected:
+      StorePointer(const std::string& loadString, const Resources::KeepLevel& keeplevel);
+
+    private:
+      StorePointer(const StorePointer&) : _keepLevel(0) {};
+
+  private:
+    std::string                 _loadString;             //!< An identifier, to match when loading a File.
+    Resources::KeepLevel        _keepLevel;              //!< The Priority of this resource. (can only be increased, so none else will delete this)
+  };
+
+
+
+  ///////////////////
+  // RESOURCE TYPE //
+  ///////////////////
+  //! A Type of Resources.
+  /**
+   * The Type is used to store the Pointers to already loaded Resources,
+   * and also to store type-specific properties.
+   * These are the Loading Paths, the subpaths and so on.
+   */
+  class Type
+  {
+  public:
+    virtual ~Type();
+    /** @returns true if the names match @param typeName the Name to compare. @brief compare the Type with a Name */
+    bool operator==(const std::string& typeName) const { return this->_typeName == typeName; };
+
+    ////////////////////
+    //// EXTENSIONS ////
+    void addExtension(const std::string& extension);
+
+    ///////////////
+    //// PATHS ////
+    bool addResourcePath(const std::string& path);
+    bool addResourceSubPath(const std::string& subPath);
+
+    /// Retrieve Functions
+    /** @returns the name of the stored Class this Type loads Resources for */
+    const std::string& storedClassName() const { return _typeName; };
+    /** @returns the ID of the Type != ClassID */
+    /** @returns the type-specific paths this Resource searches in. */
+    const std::vector<Directory>& resourcePaths() const { return _resourcePaths; };
+    /** @returns the Type specific SubPaths this Resource Searches in @see std::vector<std::string>  _resourceSubPaths */
+    const std::vector<Directory>& resourceSubPaths() const { return _resourceSubPaths; };
+    /** @returns the Pointers to the Stored resources. @note do not use this, for more than some lookup */
+    const std::vector<Resources::StorePointer*>& storedResources() const { return _storedResources; };
+
+    ///////////////////////////////
+    //// LOADING AND UNLOADING ////
+    virtual void createFromString(const std::string& loadString, const KeepLevel& keepLevel = KeepLevel()) = 0;
+    void unloadAllBelowKeepLevel(const Resources::KeepLevel& keepLevel);
+
+    ///////////////////
+    //// INTERNALS ////
+    void addResource(Resources::StorePointer* resource);
+
+    ///////////////
+    //// DEBUG ////
+    void debug() const;
+
+  protected:
+    Type(const std::string& typeName);
+
+  private:
+    Type(const Type& type) {};
+  private:
+    const std::string                     _typeName;          //!< Name of the Type. (Name of the Resource this loads.)
+    std::vector<Directory>                _resourcePaths;     //!< The Paths to search for files in this type
+    std::vector<Directory>                _resourceSubPaths;  //!< The subpaths that will be searched under all the _resourcePaths.
+    std::vector<std::string>              _fileExtensions;    //!< File Extensions, this Resource supports.
+
+    std::vector<Resources::StorePointer*> _storedResources;   //!< An array of all the stored Resources.
+  };
+
+  /**
+   * @brief A Type Definition Class for any Object that is resourceable.
+   *
+   * This Class's main reason of Existence is, that resources can be dynamically
+   * created over a loadString. For this the Type of Resource is required, and the Resource must
+   * itself support the 'void createFromString(const std::string&)' function.
+   */
+  template<class T> class tType : public Type
+  {
+  public:
+    /** Create the ResourceType @see Type(const std::string&) */
+    tType(const std::string& typeName) : Type(typeName) {};
+    /** @param loadString the String to load a Resource with @brief tries to create a Resource of Type T with a loadString */
+    virtual void createFromString(const std::string& loadString, const KeepLevel& keepLevel = KeepLevel()) { T::createFromString(loadString, keepLevel); }
+  };
+
+
+
+  /////////////////////
+  // RESOURCE ITSELF //
+  /////////////////////
+  //! A Resource is an Object, that can be loaded from Disk
+  /**
+   * The Resource Hanldes the location and stores pointers to data that can be retrieved.
+   */
+  class Resource : virtual public BaseObject
+  {
+    ObjectListDeclaration(Resource);
+
+  public:
+    Resource(Resources::Type* type);
+    virtual ~Resource();
+
+    /** @brief reloads the underlying resource */
+    virtual bool reload() { return false; };
+    /** @brief unloads the underlying Resource */
+    virtual bool unload() { return false; };
+
+    std::string locateFile(const std::string& fileName) const;
+
+  protected:
+    Resources::StorePointer* acquireResource(const std::string& loadString);
+    void addResource(Resources::StorePointer* pointer);
+
+  private:
+    std::string locateFileInSubDir(const Directory& directory, const std::string& fileName) const;
+
+  private:
+    Resources::StorePointer*       _pointer;                         //!< Virtual Pointer to the ResourceData.
+    Resources::Type*               _type;                            //!< Type of the Resource.
+  };
+}
+
+#endif /* _RESOURCE_H */
Index: branches/heathaze/src/lib/util/loading/resource_manager.cc
===================================================================
--- branches/heathaze/src/lib/util/loading/resource_manager.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/resource_manager.cc	(revision 9940)
@@ -0,0 +1,256 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
+
+#include "resource_manager.h"
+#include "debug.h"
+
+#include <algorithm>
+#include <cassert>
+
+
+namespace Resources
+{
+  /// Definition of the ResourceManager's ObjectList.
+  ObjectListDefinition(ResourceManager);
+  //! Singleton Reference to the ResourceManager
+  ResourceManager* ResourceManager::_singletonRef = NULL;
+
+
+  /**
+   * @brief standard constructor
+  */
+  ResourceManager::ResourceManager ()
+  : _defaultKeepLevel(0)
+  {
+    this->registerObject(this, ResourceManager::_objectList);
+    this->setName("ResourceManager");
+    this->_mainGlobalPath = Directory("./");
+  }
+
+
+  /**
+   * @brief standard destructor
+  */
+  ResourceManager::~ResourceManager ()
+  {
+    this->unloadAllBelowKeepLevel(this->_keepLevelNames.size());
+    ResourceManager::_singletonRef = NULL;
+  }
+
+  /**
+   * @brief Registers a new Type to the ResourceManager.
+   * @param type the Type to register.
+   */
+  void ResourceManager::registerType(Resources::Type* type)
+  {
+    this->_resourceTypes.push_back(type);
+    PRINTF(5)("ResourceType '%s' added\n", type->storedClassName().c_str());
+  }
+
+  /**
+   * @brief Unregisters a new Type to the ResourceManager.
+   * @param type the Type to unregister.
+   */
+  void ResourceManager::unregisterType(Resources::Type* type)
+  {
+    std::vector<Resources::Type*>::iterator it = std::find (this->_resourceTypes.begin(), this->_resourceTypes.end(), type);
+    if (it != this->_resourceTypes.end())
+    {
+      this->_resourceTypes.erase(it);
+      PRINTF(5)("ResourceType '%s' removed\n", type->storedClassName().c_str());
+    }
+  }
+
+  /**
+   * @brief Sets the main Global path (the main path Resources are searched for)
+   * @param directory the directory to set.
+   * @see Resource::locateFile
+   */
+  void ResourceManager::setMainGlobalPath(const Directory& directory)
+  {
+    this->_mainGlobalPath = directory;
+    this->_mainGlobalPath.open();
+  }
+
+  /**
+   * @brief add a Global search path. (global paths besided the main path.)
+   * @param directory a directory to add.
+   */
+  void ResourceManager::addGlobalPath(const Directory& directory)
+  {
+    std::vector<Directory>::const_iterator it = std::find(this->_globalPaths.begin(), this->_globalPaths.end(), directory);
+    if (it == this->_globalPaths.end())
+      this->_globalPaths.push_back(directory);
+  }
+
+  /**
+   * @brief add a ResourcePath to a Type's Paths.
+   * @param resourceName the Type's name of Resource to add the path to.
+   * @param pathName pathName the Name of the path to add.
+   * @return true on success. (if a path was added (no duplicate, and resourceName existed).
+   */
+  bool ResourceManager::addResourcePath(const std::string& resourceName, const std::string& pathName)
+  {
+    std::vector<Resources::Type*>::iterator it;
+    for (it = this->_resourceTypes.begin(); it != this->_resourceTypes.end(); ++it)
+      if (*(*it) == resourceName)
+        return (*it)->addResourcePath(pathName);
+    PRINTF(2)("ResourcePath %s could not be added to the ResourceType %s\n", pathName.c_str(), resourceName.c_str());
+    return false;
+  }
+
+  /**
+   * @brief add a ResourcePath to a Type's SubPaths.
+   * @param resourceName the Type's name of Resource to add the subpath to.
+   * @param pathName pathName the Name of the path to add.
+   * @return true on success. (if a path was added (no duplicate, and resourceName existed).
+   */
+  bool ResourceManager::addResourceSubPath(const std::string& resourceName, const std::string& pathName)
+  {
+    std::vector<Resources::Type*>::iterator it;
+    for (it = this->_resourceTypes.begin(); it != this->_resourceTypes.end(); ++it)
+      if (*(*it) == resourceName)
+        return (*it)->addResourceSubPath(pathName);
+    PRINTF(2)("ResourceSubPath %s could not be added to the ResourceType %s\n", pathName.c_str(), resourceName.c_str());
+    return false;
+  }
+
+  /**
+   * @brief checks wether a File is inside of the MainPath.
+   * @param fileInside the file to check
+   * @return true if the file is inside.
+   */
+  bool ResourceManager::checkFileInMainPath(const File& fileInside)
+  {
+    return (this->_mainGlobalPath + fileInside).exists();
+  }
+
+  /**
+   * @brief prepends the fileName by the MainGlobalPath (same as mainGlobalPath + '/' + fileName).
+   * @param fileName The FileName to prepend
+   * @returns the prepended file-name
+   */
+  std::string ResourceManager::prependAbsoluteMainPath(const std::string& fileName)
+  {
+    return (this->_mainGlobalPath + File(fileName)).name();
+  }
+
+  /**
+   * @brief add a KeepLevelName (this function just counts upwards).
+   * @param keepLevelName the Name of the KeepLevel to set.
+   * @returns the Level the Name was set to.
+   */
+  unsigned int ResourceManager::addKeepLevelName(const std::string& keepLevelName)
+  {
+    this->_keepLevelNames.push_back(keepLevelName);
+    return _keepLevelNames.size()-1;
+  }
+
+  /**
+   * @param keepLevelName the Name of the KeepLevel.
+   * @returns the ID of the KeepLevel named keepLevelName
+   */
+  unsigned int ResourceManager::getKeepLevelID(const std::string& keepLevelName) const
+  {
+    for (unsigned int i = 0; i < this->_keepLevelNames.size(); ++i)
+      if (this->_keepLevelNames[i] == keepLevelName)
+        return i;
+
+    PRINTF(2)("KeepLevel '%s' not found. Using 0 instead\n", keepLevelName.c_str());
+    return 0;
+  }
+
+  /**
+   * @param keepLevelID the ID to check.
+   * @return the name of the KeepLevel.
+   */
+  const std::string& ResourceManager::getKeepLevelName(unsigned int keepLevelID) const
+  {
+    assert(keepLevelID < this->_keepLevelNames.size());
+    return this->_keepLevelNames[keepLevelID];
+  }
+
+
+  /**
+   * @brief loads a Resource from a TypeName and a loadString.
+   * @param resourceTypeName The Name of the Type to what to load a Resource from.
+   * @param loadString the loadString to load in the Type.
+   */
+  void ResourceManager::loadFromLoadString(const std::string& resourceTypeName, const std::string& loadString, const KeepLevel& keepLevel)
+  {
+    std::vector<Resources::Type*>::const_iterator it;
+    for (it = this->_resourceTypes.begin(); it != this->_resourceTypes.end(); ++it)
+    {
+      if (*(*it) == resourceTypeName)
+      {
+	(*it)->createFromString(loadString, keepLevel);
+	/// TODO check if the resource was allocated!!
+	return ;
+      }
+    }
+    return ;
+  }
+
+  /**
+   * @brief unloads all Resources below a certain threshhold.
+   * @param keepLevel the KeepLevel below which to erase.
+   *
+   * @not Resources will only be erased, if th keepLevel is below, and the resources are not
+   * referenced anymore.
+   */
+  void ResourceManager::unloadAllBelowKeepLevel(const Resources::KeepLevel& keepLevel)
+  {
+    std::vector<Resources::Type*>::const_iterator it;
+    for (it = this->_resourceTypes.begin(); it != this->_resourceTypes.end(); ++it)
+    {
+      (*it)->unloadAllBelowKeepLevel(keepLevel);
+    }
+  }
+
+
+  /**
+   * @brief outputs debug information about the ResourceManager
+   */
+  void ResourceManager::debug() const
+  {
+    PRINT(0)("/==RM================================\\\n");
+    PRINT(0)("| RESOURCE-MANAGER DEBUG INFORMATION |\n");
+    PRINT(0)("\\====================================/\n");
+    PRINT(0)(" MainGlobal search path is %s\n", this->_mainGlobalPath.name().c_str());
+    if(!this->_globalPaths.empty())
+    {
+      PRINT(0)(" Additional Global search Paths are: ");
+      for (unsigned int i = 0; i < this->_globalPaths.size(); ++i)
+        PRINT(0)("'%s' ", this->_globalPaths[i].name().c_str());
+      PRINT(0)("\n");
+    }
+    PRINT(0)(" Listing %d Types: \n", this->_resourceTypes.size());
+    std::vector<Resources::Type*>::const_iterator it;
+    for (it = this->_resourceTypes.begin(); it != this->_resourceTypes.end(); ++it)
+    {
+      (*it)->debug();
+      if (it != --this->_resourceTypes.end())
+        PRINT(0)(" ------------------------------------\n ");
+    }
+
+    PRINT(0)("KeepLevels are: ");
+    for (unsigned int i = 0; i < this->_keepLevelNames.size(); ++i)
+      PRINT(0)("%d:'%s'  ", i, this->_keepLevelNames[i].c_str());
+    PRINT(0)("\n");
+    PRINT(0)("=================================RM==/\n");
+  }
+}
Index: branches/heathaze/src/lib/util/loading/resource_manager.h
===================================================================
--- branches/heathaze/src/lib/util/loading/resource_manager.h	(revision 9940)
+++ branches/heathaze/src/lib/util/loading/resource_manager.h	(revision 9940)
@@ -0,0 +1,87 @@
+/*!
+ * @file resource_manager.h
+ */
+
+#ifndef _RESOURCE_MANAGER_H
+#define _RESOURCE_MANAGER_H
+
+#include "resource.h"
+#include "filesys/file.h"
+#include "filesys/directory.h"
+
+namespace Resources
+{
+
+  class ResourceManager : public BaseObject
+  {
+    ObjectListDeclaration(ResourceManager);
+  public:
+    ///////////////////////
+    //// INSTANZIATION ////
+    /** @returns a Pointer to the only object of this Class */
+    inline static ResourceManager* getInstance() { if (!_singletonRef) _singletonRef = new ResourceManager();  return _singletonRef; };
+    /** @brief deletes the Instance if it exists. */
+    inline static void deleteInstance() { if (_singletonRef) delete _singletonRef; };
+
+    ////////////////////////
+    //// RESOURCE PATHS ////
+    void setMainGlobalPath(const Directory& directory);
+    void addGlobalPath(const Directory& directory);
+
+    bool addResourcePath(const std::string& resourceName, const std::string& pathName);
+    bool addResourceSubPath(const std::string& resourceName, const std::string& pathName);
+    void registerType(Resources::Type* type);
+    void unregisterType(Resources::Type* type);
+
+    /** @returns the main global search Path */
+    const Directory& mainGlobalPath() const { return _mainGlobalPath; };
+    /** @returns all global paths without mainGlobalPath */
+    const std::vector<Directory>& globalPaths() const { return _globalPaths; };
+
+    ////////////////////
+    //// KEEPLEVELS ////
+    unsigned int addKeepLevelName(const std::string& keepLevelName);
+    unsigned int getKeepLevelID(const std::string& keepLevelName) const;
+    const std::string& getKeepLevelName(unsigned int keepLevelID) const;
+    void setDefaultKeepLevel(const KeepLevel& keepLevel) { this->_defaultKeepLevel = keepLevel; };
+    const KeepLevel& defaultKeepLevel() const { return this->_defaultKeepLevel; };
+
+    //////////////////////////
+    //// GENERAL QUERIES ////
+    /** @returns the Types of Resources */
+    const std::vector<Resources::Type*> resourceTypes() const { return _resourceTypes; };
+
+    bool checkFileInMainPath(const File& fileInside);
+    std::string prependAbsoluteMainPath(const std::string& fileName);
+
+    ////////////////////////////////////////
+    //// RESOURCE LOADING AND UNLOADING ////
+    void loadFromLoadString(const std::string& resourceTypeName, const std::string& loadString, const KeepLevel& keepLevel = KeepLevel());
+    void loadFromLoadStringHACK(const std::string& resourceTypeName, const std::string& loadString) { this->loadFromLoadString(resourceTypeName, loadString); };
+
+    void unloadAllBelowKeepLevel(const Resources::KeepLevel& keepLevel);
+    void unloadAllBelowKeepLevelINT(unsigned int level) { unloadAllBelowKeepLevel(level); };
+
+    ///////////////
+    //// DEBUG ////
+    void debug() const;
+
+  private:
+    ResourceManager();
+    virtual ~ResourceManager();
+
+  private:
+    static ResourceManager*            _singletonRef;       //!< singleton Reference
+
+    Directory                          _mainGlobalPath;     //!< The main include directory (default at "./")
+    std::vector<Directory>             _globalPaths;        //!< Additional Global include directories.
+
+    std::vector<Resources::Type*>      _resourceTypes;      //!< A Vector of all the stored ResourceTypes @see Resources::Type
+
+    std::vector<std::string>           _keepLevelNames;     //!< Names of KeepLevels @see Resources::KeepLevel
+    KeepLevel                          _defaultKeepLevel;   //!< The default KeepLevel.
+  };
+
+}
+
+#endif /* _RESOURCE_MANAGER_H */
Index: branches/heathaze/src/lib/util/multi_type.cc
===================================================================
--- branches/heathaze/src/lib/util/multi_type.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/multi_type.cc	(revision 9940)
@@ -0,0 +1,536 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "multi_type.h"
+
+#include <sstream>
+
+#ifdef DEBUG
+#include "debug.h"
+#endif
+
+/**
+ * @brief creates a multiType without any stored value at all.
+ */
+MultiType::MultiType(MT_Type type)
+{
+  this->type = type;
+  switch (this->type)
+  {
+    default:
+    this->value.Float = 0.0f;
+    break;
+    case MT_BOOL:
+    this->value.Bool = false;
+    break;
+    case MT_INT:
+    this->value.Int = 0;
+    break;
+    case MT_FLOAT:
+    this->value.Float = 0.0f;
+    break;
+    case MT_CHAR:
+    this->value.Char = '\0';
+    break;
+    case MT_STRING:
+    this->storedString = "";
+    break;
+  }
+}
+/**
+ * @brief creates a multiType out of a boolean
+ * @param value the Value of this MulitType
+ */
+MultiType::MultiType(bool value)
+{
+  this->setBool(value);
+}
+
+/**
+ * @brief creates a multiType out of an integer
+ * @param value the Value of this MulitType
+ */
+MultiType::MultiType(int value)
+{
+  this->setInt(value);
+}
+
+/**
+ * @brief creates a multiType out of a float (double)
+ * @param value the Value of this MulitType
+ */
+MultiType::MultiType(double value)
+{
+  this->setFloat(value);
+}
+
+/**
+ * @brief creates a multiType out of a char
+ * @param value the Value of this MulitType
+ */
+MultiType::MultiType(char value)
+{
+  this->setChar(value);
+}
+
+/**
+ * @brief creates a multiType out of a String
+ * @param value the Value of this MulitType
+ */
+MultiType::MultiType(const std::string& value)
+{
+  this->setString(value);
+}
+
+/**
+ * @brief constructs a new MultiType from another one (copy)
+ */
+MultiType::MultiType(const MultiType& multiType)
+{
+  *this = multiType;
+}
+
+/**
+ * @brief standard deconstructor
+*/
+MultiType::~MultiType ()
+{ }
+
+/**
+ * @brief copy operator
+ * @param mt: the entity to copy
+ * @returns A Copy of itself. (strings inside are copied as well)
+ */
+MultiType& MultiType::operator= (const MultiType& mt)
+{
+  this->type = mt.type;
+  this->value = mt.value;
+  this->storedString = mt.storedString;
+
+  return *this;
+}
+
+/**
+ * @brief checks if the two Multitypes match
+ * @param mt MultiType to check against this one
+ * @returns true on match. false otherwise
+ *
+ * Two MultiType match if and only if
+ *  1. the internal Type is the same
+ *  2. the stored values match
+ */
+bool MultiType::operator==(const MultiType& mt) const
+{
+  if (this->type != mt.type)
+    return false;
+
+  switch (this->type)
+  {
+    case MT_NULL:
+    return true;
+    case MT_BOOL:
+    return (this->value.Bool == mt.value.Bool);
+    case MT_INT:
+    return (this->value.Int == mt.value.Int);
+    case MT_CHAR:
+    return (this->value.Char == mt.value.Char);
+    case MT_FLOAT:
+    return (this->value.Float == mt.value.Float);
+    case MT_STRING:
+    return (this->storedString == mt.storedString);
+    default:
+    return false;
+  }
+}
+
+
+/**
+ * @brief sets the type of this MultiType and resets to the default value
+ * @param type the new Type
+ */
+void MultiType::setType(MT_Type type)
+{
+  if (this->type == type)
+    return;
+
+  switch (type)
+  {
+    case MT_BOOL:
+    this->setBool(this->getBool());
+    break;
+    case MT_INT:
+    this->setInt(this->getInt());
+    break;
+    case MT_FLOAT:
+    this->setFloat(this->getFloat());
+    break;
+    case MT_CHAR:
+    this->setChar(this->getChar());
+    break;
+    case MT_STRING:
+    this->setString(this->getString());
+    break;
+    default:
+    this->type = type;
+  }
+}
+
+/**
+ * @brief sets the Value of mt without changing the type of this MultiType
+ * @param mt: the MultiType to get the value from
+ *
+ * This is a pure Value copy. The current type will be preserved.
+ */
+void MultiType::setValueOf(const MultiType& mt)
+{
+  MT_Type prevType = this->type;
+
+  *this = mt;
+  this->setType(prevType);
+}
+
+
+/**
+ * @brief sets a new Value to the MultiType
+ * @param value the new Value as a bool
+ */
+void MultiType::setBool(bool value)
+{
+  this->type = MT_BOOL;
+  this->value.Bool = value;
+}
+
+/**
+ * @brief sets a new Value to the MultiType
+ * @param value the new Value as an int
+ */
+void MultiType::setInt(int value)
+{
+  this->type = MT_INT;
+  this->value.Int = value;
+}
+
+/**
+ * @brief sets a new Value to the MultiType
+ * @param value the new Value as a float
+ */
+void MultiType::setFloat(float value)
+{
+  this->type = MT_FLOAT;
+  this->value.Float = value;
+}
+
+/**
+ * @brief sets a new Value to the MultiType
+ * @param value the new Value as a char
+ */
+void MultiType::setChar(char value)
+{
+  this->type = MT_CHAR;
+  this->value.Char = value;
+}
+
+/**
+ * @brief sets a new Value to the MultiType
+ * @param value the new Value as a String
+ */
+void MultiType::setString(const std::string& value)
+{
+  this->type = MT_STRING;
+  this->storedString = value;
+}
+
+/**
+ * @brief stores any value to the string.
+ * @note this Value can be grabbed by using the getStoredString function.
+ */
+void MultiType::storeString()
+{
+  if (!(this->type & MT_STRING))
+    this->storedString = this->getString();
+}
+
+/**************************
+*** RETRIEVAL FUNCTIONS ***
+**************************/
+/**
+ * @returns the Value of this MultiType as a int
+ */
+bool MultiType::getBool() const
+{
+  // default case:
+  if (this->type & MT_BOOL)
+    return this->value.Bool;
+  // Special Cases:
+  else if (this->type & MT_INT) return (this->value.Int == 0)? false : true;
+  else if (this->type & MT_FLOAT) return (this->value.Float == 0.0f)? false : true;
+  else if (this->type & MT_CHAR) return (this->value.Char == '\0')? false : true;
+  else if (this->type & MT_STRING) return (this->storedString == "true" ||
+                                            this->storedString == "TRUE" ||
+                                            this->storedString != "0"); // TODO make this better...
+
+  return false;
+}
+
+/**
+ * @returns the Value of this MultiType as a int
+ */
+int MultiType::getInt() const
+{
+  // default case:
+  if (this->type & MT_INT)
+    return this->value.Int;
+  if (this->type & MT_BOOL) return (this->value.Bool)? 1 : 0;
+  else if (this->type & MT_FLOAT) return (int) this->value.Float;
+  else if (this->type & MT_CHAR) return (int) this->value.Char;
+  else if (this->type & MT_STRING)
+  {
+    std::stringstream ssStream(this->storedString);
+    int iReturn;
+    ssStream >> iReturn;
+    return iReturn;
+  }
+  return 0;
+}
+
+
+/**
+ * @returns the Value of this MultiType as a float
+ */
+float MultiType::getFloat() const
+{
+  // default case:
+  if (this->type & MT_FLOAT)
+    return this->value.Float;
+  if (this->type & MT_BOOL) return (this->value.Bool == true)? 1.0f : 0.0f;
+  else if (this->type & MT_INT) return (float) this->value.Int;
+  else if (this->type & MT_CHAR) return (float) this->value.Char;
+  else if (this->type & MT_STRING)
+  {
+    char* endPtr = NULL;
+    double result = strtod(this->storedString.c_str(), &endPtr);
+    if ( endPtr >= this->storedString.c_str() && endPtr < this->storedString.c_str() + this->storedString.size())
+      return 0.0f;
+    else
+      return result;
+  }
+  return 0.0f;
+}
+
+
+/**
+ * @returns the Value of this MultiType as a char
+ */
+char MultiType::getChar() const
+{
+  // default case:
+  if (this->type & MT_INT)
+    return this->value.Int;
+  if (this->type & MT_BOOL) return (this->value.Bool)? 'y' : 'n';
+  else if (this->type & MT_INT) return (int) this->value.Int;
+  else if (this->type & MT_FLOAT) return (char) this->value.Float;
+  else if (this->type & MT_STRING) return this->storedString[0];
+
+  return '\0';
+}
+
+
+/**
+ * @returns the Value of this MultiType as a String
+ */
+std::string MultiType::getString() const
+{
+  // default case:
+  if (this->type & MT_STRING)
+    return this->storedString;
+  else
+  {
+    if (this->type & MT_BOOL) return (this->value.Bool)? "true" : "false";
+
+    else if (this->type & MT_INT)
+    {
+      char tmpString[32];
+      sprintf(tmpString, "%d", this->value.Int);
+      return tmpString;
+    }
+    else if (this->type & MT_FLOAT)
+    {
+      char tmpString[64];
+      sprintf(tmpString, "%f", this->value.Float);
+      return tmpString;
+    }
+    else if (this->type & MT_CHAR)
+    {
+      char tmpString[2];
+      tmpString[0] = this->value.Char;
+      tmpString[1] = '\0';
+      return tmpString;
+    }
+  }
+  return "";
+}
+
+/**
+ * @brief returns a Constant string (actually this is slower than getString()
+ * @returns a constant string of the stored version's one.
+ * @note this  could lead to a inconsistency of data AND IS HIGHLY NON_THREAD_SAFE!
+ * PLEASE THINK ABOUT USING THE getStoredString function in conjunction with storeString().
+ */
+const std::string& MultiType::getConstString() const
+{
+  MultiType::constString = this->getString();
+  return MultiType::constString;
+}
+
+/**
+ * @brief returns the currently stored string.
+ * @returns the Stored string.
+ * @note Storing a string works as follows: \\
+ * MultiType a(3);  // Creates a MultiType of Type int with value 3 \\
+ * a.storeString(); // Stores the String in the internal structure. \\
+ * std::string name = a.getStoredString();
+ *
+ * This would be the same as
+ * name = a.getString();
+ * but with much more const'ness.
+ */
+const std::string& MultiType::getStoredString() const
+{
+  MultiType::constString = this->getString();
+  return MultiType::constString;
+}
+
+/**
+ * @returns a formated c-string of the held value
+ */
+const char* MultiType::getCString()
+{
+  if (this->type & MT_STRING) return this->storedString.c_str();
+  else
+  {
+    this->storedString = this->getString();
+    return this->storedString.c_str();
+  }
+}
+
+/**
+ * @brief prints out some nice debug output
+ */
+void MultiType::debug() const
+{
+#ifdef DEBUG
+  PRINT(0)
+#else
+  printf
+#endif
+  ("MultiType of Type '%s' :: Values: BOOL: '%d', INT: '%d', FLOAT: '%f', CHAR: '%c', STRING '%s'\n",
+   MultiType::MultiTypeToString(this->type).c_str(),
+   this->getBool(),
+   this->getInt(),
+   this->getFloat(),
+   this->getChar(),
+   this->getString().c_str()
+  );
+}
+
+
+/**
+ * @brief Resets the MultiType to default values.
+ */
+void MultiType::reset()
+{
+  switch ( this->type )
+  {
+    case MT_BOOL:
+    this->setBool(false);
+    break;
+    case MT_INT:
+    this->setInt(0);
+    break;
+    case MT_FLOAT:
+    this->setFloat(0.0f);
+    break;
+    case MT_CHAR:
+    this->setChar('\0');
+    break;
+    case MT_STRING:
+    this->setString("");
+    break;
+    default:
+#ifdef DEBUG
+    PRINTF(2)("Unknown Type not reseting\n");
+#endif
+    break;
+  }
+}
+
+/**
+ * @brief converts a MT_Type into a String
+ * @param type: the MT_Type
+ * @returns: the Type as a constant String (do not delete)
+ */
+const std::string& MultiType::MultiTypeToString(MT_Type type)
+{
+  switch ( type )
+  {
+    case MT_BOOL:
+    return MultiType::typeNames[1];
+    case MT_INT:
+    return MultiType::typeNames[2];
+    case MT_FLOAT:
+    return MultiType::typeNames[3];
+    case MT_CHAR:
+    return MultiType::typeNames[4];
+    case MT_STRING:
+    return MultiType::typeNames[5];
+    default:
+    return MultiType::typeNames[0];
+  }
+}
+
+/**
+ * @brief converts a String into a MT_Type
+ * @param type: the Type as a String
+ * @returns: the Type as MT_Type
+ */
+MT_Type MultiType::StringToMultiType(const std::string& type)
+{
+  if (type == MultiType::typeNames[1])
+    return MT_BOOL;
+  if (type == MultiType::typeNames[2])
+    return MT_INT;
+  if (type == MultiType::typeNames[3])
+    return MT_FLOAT;
+  if (type == MultiType::typeNames[4])
+    return MT_CHAR;
+  if (type == MultiType::typeNames[5])
+    return MT_STRING;
+
+  return MT_NULL;
+}
+
+
+std::string MultiType::constString = "";
+const std::string MultiType::typeNames[] =
+  {
+    "NONE",      //0
+    "bool",      //1
+    "int",       //2
+    "float",     //3
+    "char",      //4
+    "string"     //5
+  };
Index: branches/heathaze/src/lib/util/multi_type.h
===================================================================
--- branches/heathaze/src/lib/util/multi_type.h	(revision 9940)
+++ branches/heathaze/src/lib/util/multi_type.h	(revision 9940)
@@ -0,0 +1,136 @@
+/*!
+ * @file multi_type.h
+ * @brief Definition of a MultiType, that is able to hold one Value of many types.
+ */
+
+#ifndef _MULTI_TYPE_H
+#define _MULTI_TYPE_H
+
+#include <string>
+
+// FORWARD DECLARATION
+
+//! An enumerator defining Types, that can be stored inside a MultiType.
+typedef enum
+{
+  MT_NULL            = 0,                  //!< No Value at all.
+  MT_BOOL            = 1,                  //!< A bool Value.
+  MT_INT             = 2,                  //!< An int Value.
+  MT_UINT            = 2,                  //!< A insigned int Value.
+  MT_LONG            = 2,                  //!< A long Value
+  MT_FLOAT           = 4,                  //!< A float Value.
+  MT_CHAR            = 8,                  //!< A single char.
+  MT_STRING          = 16,                 //!< An entire String.
+  MT_EXT1            = 32,                 //!< An external Type.
+  MT_EXT2            = 64,                 //!< An external Type.
+} MT_Type;
+
+
+
+//! A class that encapsulates multiple differen types.
+/**
+ * Only one Value can be Stored inside this Class, but it can have any type: @see MT_Type.
+ */
+class MultiType {
+  public:
+    MultiType(MT_Type type = MT_NULL);
+    MultiType(bool value);
+    MultiType(int value);
+    MultiType(double value);
+    MultiType(char value);
+    MultiType(const std::string& value);
+    MultiType(const MultiType& multiType);
+    virtual ~MultiType();
+
+    MultiType& operator=(const MultiType& mt);
+    /** @param value the value to set (here a bool) @returns the MultiType where this the bool is stored */
+    MultiType& operator=(bool value) { this->setBool(value); return *this; };
+    /** @param value the value to set (here an int) @returns the MultiType where this the int is stored */
+    MultiType& operator=(int value) { this->setInt(value); return *this; };
+    /** @param value the value to set (here an int) @returns the MultiType where this the float is stored */
+    MultiType& operator=(float value) { this->setFloat(value); return *this; };
+    /** @param value the value to set (here a char) @returns the MultiType where this the char is stored */
+    MultiType& operator=(char value) { this->setChar(value); return *this; };
+    /** @param value the value to set (here a string) @returns the MultiType where this the string is stored */
+    MultiType& operator=(const std::string& value) { this->setString(value); return *this; };
+
+    bool operator==(const MultiType& mt) const;
+    /** @param value the value to compare this MultiType against @returns true if comparison was io */
+    bool operator==(bool value) const { return (this->getBool() == value); };
+    /** @param value the value to compare this MultiType against @returns true if comparison was io */
+    bool operator==(int value) const { return (this->getInt() == value); };
+    /** @param value the value to compare this MultiType against @returns true if comparison was io */
+    bool operator==(float value) const { return (this->getFloat() ==  value); };
+    /** @param value the value to compare this MultiType against @returns true if comparison was io */
+    bool operator==(char value) const { return (this->getChar() == value); };
+    /** @param value the value to compare this MultiType against @returns true if comparison was io */
+    bool operator==(const std::string& value) const { return (this->getString() == value); };
+    /** @param type the Type to compare this MultiType against @returns true if the types matched */
+    bool operator==(MT_Type type) const { return (this->type == type); }
+    /** @param type the type to compare this MultiType against @returns true if the types do not match */
+    bool operator!=(MT_Type type) const { return (this->type != type); }
+
+    void setType(MT_Type type);
+
+    void setBool(bool value);
+    void setInt(int value);
+    void setFloat(float value);
+    void setChar(char value);
+    void setString(const std::string& value);
+
+    // for your convenience.
+    /** @param value the value to set. Here a bool */
+    inline void setValue(bool value) { this->setBool(value); };
+    /** @param value the value to set. Here an int */
+    inline void setValue(int value) { this->setInt(value); };
+    /** @param value the value to set. Here a float */
+    inline void setValue(float value) { this->setFloat(value); };
+    /** @param value the value to set. Here a char */
+    inline void setValue(char value) { this->setChar(value); };
+    /** @param value the value to set. Here a char array (string) */
+    inline void setValue(const char* value) { this->setString(value); };
+    /** @param value the value to set. Here a string */
+    inline void setValue(const std::string& value) { this->setString(value); };
+    void setValueOf(const MultiType& mt);
+
+    /** @returns the Type of the Value stored in this MultiType */
+    inline MT_Type getType() const { return this->type; };
+
+    void storeString();
+
+    /* RETRIEVING FUNCTIONS */
+    bool getBool() const;
+    int getInt() const;
+    float getFloat() const;
+    char getChar() const;
+    const char* getCString();
+    std::string getString() const;
+    const std::string& getConstString() const;
+    const std::string& getStoredString() const;
+
+    void reset();
+
+    void debug() const;
+
+    static const std::string& MultiTypeToString(MT_Type type);
+    static MT_Type StringToMultiType(const std::string& type);
+
+  private:
+    //! A union, that combines types into as little memory as possible.
+    union MultiTypeValue
+    {
+      bool                       Bool;              //!< If it is a BOOL
+      int                        Int;               //!< If it is an INT
+      float                      Float;             //!< If it is a FLOAT
+      char                       Char;              //!< If it is a CHAR
+    }                            value;             //!< The Value.
+    std::string                  storedString;      //!< The Stored String.
+    MT_Type                      type;              //!< The Type stored in this MultiType
+
+
+    static std::string           constString;       //!< A String for returning Constant strings.
+
+    static const std::string     typeNames[];       //!< List of TypeNames for conversion.
+};
+
+#endif /* _MULTI_TYPE_H */
Index: branches/heathaze/src/lib/util/sigslot/signal.h
===================================================================
--- branches/heathaze/src/lib/util/sigslot/signal.h	(revision 9940)
+++ branches/heathaze/src/lib/util/sigslot/signal.h	(revision 9940)
@@ -0,0 +1,2229 @@
+/**
+ * @file signal.h
+ * @adaption from the beautiful sigslot implementation of sarah Thompson
+ */
+
+// sigslot.h: Signal/Slot classes
+//
+// Written by Sarah Thompson (sarah@telergy.com) 2002.
+//
+// License: Public domain. You are free to use this code however you like, with the proviso that
+//          the author takes on no responsibility or liability for any use.
+//
+// QUICK DOCUMENTATION
+//
+//        (see also the full documentation at http://sigslot.sourceforge.net/)
+//
+// #define switches
+//     SIGSLOT_PURE_ISO                   - Define this to force ISO C++ compliance. This also disables
+//                                         all of the thread safety support on platforms where it is
+//                                         available.
+//
+//     SIGSLOT_USE_POSIX_THREADS          - Force use of Posix threads when using a C++ compiler other than
+//                                          gcc on a platform that supports Posix threads. (When using gcc,
+//                                          this is the default - use SIGSLOT_PURE_ISO to disable this if
+//                                          necessary)
+//
+//     SIGSLOT_DEFAULT_MT_POLICY          - Where thread support is enabled, this defaults to multi_threaded_global.
+//                                          Otherwise, the default is single_threaded. #define this yourself to
+//                                          override the default. In pure ISO mode, anything other than
+//                                          single_threaded will cause a compiler error.
+//
+// PLATFORM NOTES
+//
+//     Win32                              - On Win32, the WIN32 symbol must be #defined. Most mainstream
+//                                          compilers do this by default, but you may need to define it
+//                                          yourself if your build environment is less standard. This causes
+//                                          the Win32 thread support to be compiled in and used automatically.
+//
+//     Unix/Linux/BSD, etc.                - If you're using gcc, it is assumed that you have Posix threads
+//                                          available, so they are used automatically. You can override this
+//                                          (as under Windows) with the SIGSLOT_PURE_ISO switch. If you're using
+//                                          something other than gcc but still want to use Posix threads, you
+//                                          need to #define SIGSLOT_USE_POSIX_THREADS.
+//
+//     ISO C++                            - If none of the supported platforms are detected, or if
+//                                          SIGSLOT_PURE_ISO is defined, all multithreading support is turned off,
+//                                          along with any code that might cause a pure ISO C++ environment to
+//                                          complain. Before you ask, gcc -ansi -pedantic won't compile this
+//                                          library, but gcc -ansi is fine. Pedantic mode seems to throw a lot of
+//                                          errors that aren't really there. If you feel like investigating this,
+//                                          please contact the author.
+//
+//
+// THREADING MODES
+//
+//     single_threaded                    - Your program is assumed to be single threaded from the point of view
+//                                          of signal/slot usage (i.e. all objects using signals and slots are
+//                                          created and destroyed from a single thread). Behaviour if objects are
+//                                          destroyed concurrently is undefined (i.e. you'll get the occasional
+//                                          segmentation fault/memory exception).
+//
+//     multi_threaded_global              - Your program is assumed to be multi threaded. Objects using signals and
+//                                          slots can be safely created and destroyed from any thread, even when
+//                                          connections exist. In multi_threaded_global mode, this is achieved by a
+//                                          single global mutex (actually a critical section on Windows because they
+//                                          are faster). This option uses less OS resources, but results in more
+//                                          opportunities for contention, possibly resulting in more context switches
+//                                          than are strictly necessary.
+//
+//     multi_threaded_local               - Behaviour in this mode is essentially the same as multi_threaded_global,
+//                                          except that each signal, and each object that inherits has_slots, all
+//                                          have their own mutex/critical section. In practice, this means that
+//                                          mutex collisions (and hence context switches) only happen if they are
+//                                          absolutely essential. However, on some platforms, creating a lot of
+//                                          mutexes can slow down the whole OS, so use this option with care.
+//
+// USING THE LIBRARY
+//
+//        See the full documentation at http://sigslot.sourceforge.net/
+//
+//
+
+#ifndef SIGNAL_H__
+#define SIGNAL_H__
+
+#include <set>
+#include <list>
+
+#include "slot.h"
+
+
+namespace sigslot
+{
+  template<class mt_policy>
+  class _connection_base0
+  {
+  public:
+    virtual ~_connection_base0() {};
+    virtual has_slots<mt_policy>* getdest() const = 0;
+    virtual void emit() = 0;
+    virtual _connection_base0* clone() = 0;
+    virtual _connection_base0* duplicate(has_slots<mt_policy>* pnewdest) = 0;
+  };
+
+  template<class arg1_type, class mt_policy>
+  class _connection_base1
+  {
+  public:
+    virtual ~_connection_base1() {};
+    virtual has_slots<mt_policy>* getdest() const = 0;
+    virtual void emit(arg1_type) = 0;
+    virtual _connection_base1<arg1_type, mt_policy>* clone() = 0;
+    virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
+  };
+
+  template<class arg1_type, class arg2_type, class mt_policy>
+  class _connection_base2
+  {
+  public:
+    virtual ~_connection_base2() {};
+    virtual has_slots<mt_policy>* getdest() const = 0;
+    virtual void emit(arg1_type, arg2_type) = 0;
+    virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() = 0;
+    virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class mt_policy>
+  class _connection_base3
+  {
+  public:
+    virtual ~_connection_base3() {};
+    virtual has_slots<mt_policy>* getdest() const = 0;
+    virtual void emit(arg1_type, arg2_type, arg3_type) = 0;
+    virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* clone() = 0;
+    virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy>
+  class _connection_base4
+  {
+  public:
+    virtual ~_connection_base4() {};
+    virtual has_slots<mt_policy>* getdest() const = 0;
+    virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type) = 0;
+    virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* clone() = 0;
+    virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class mt_policy>
+  class _connection_base5
+  {
+  public:
+    virtual ~_connection_base5() {};
+    virtual has_slots<mt_policy>* getdest() const = 0;
+    virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type,
+                      arg5_type) = 0;
+    virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, mt_policy>* clone() = 0;
+    virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class arg6_type, class mt_policy>
+  class _connection_base6
+  {
+  public:
+    virtual ~_connection_base6() {};
+    virtual has_slots<mt_policy>* getdest() const = 0;
+    virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,
+                      arg6_type) = 0;
+    virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, mt_policy>* clone() = 0;
+    virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class arg6_type, class arg7_type, class mt_policy>
+  class _connection_base7
+  {
+  public:
+    virtual ~_connection_base7() {};
+    virtual has_slots<mt_policy>* getdest() const = 0;
+    virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,
+                      arg6_type, arg7_type) = 0;
+    virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, arg7_type, mt_policy>* clone() = 0;
+    virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy>
+  class _connection_base8
+  {
+  public:
+    virtual ~_connection_base8() {};
+    virtual has_slots<mt_policy>* getdest() const = 0;
+    virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type,
+                      arg6_type, arg7_type, arg8_type) = 0;
+    virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone() = 0;
+    virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0;
+  };
+
+  template<class mt_policy>
+  class _signal_base0 : public _signal_base<mt_policy>
+  {
+  public:
+    typedef std::list<_connection_base0<mt_policy> *>  connections_list;
+
+    _signal_base0()
+    {
+      ;
+    }
+
+    _signal_base0(const _signal_base0& s)
+        : _signal_base<mt_policy>(s)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = s.m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_connect(this);
+        m_connected_slots.push_back((*it)->clone());
+
+        ++it;
+      }
+    }
+
+    ~_signal_base0()
+    {
+      disconnect_all();
+    }
+
+    void disconnect_all()
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_disconnect(this);
+        delete *it;
+
+        ++it;
+      }
+
+      m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
+    }
+
+    void disconnect(has_slots<mt_policy>* pclass)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == pclass)
+        {
+          delete *it;
+          m_connected_slots.erase(it);
+          pclass->signal_disconnect(this);
+          return;
+        }
+
+        ++it;
+      }
+    }
+
+    void slot_disconnect(has_slots<mt_policy>* pslot)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        typename connections_list::iterator itNext = it;
+        ++itNext;
+
+        if((*it)->getdest() == pslot)
+        {
+          m_connected_slots.erase(it);
+          //                        delete *it;
+        }
+
+        it = itNext;
+      }
+    }
+
+    void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == oldtarget)
+        {
+          m_connected_slots.push_back((*it)->duplicate(newtarget));
+        }
+
+        ++it;
+      }
+    }
+
+  protected:
+    connections_list m_connected_slots;
+  };
+
+  template<class arg1_type, class mt_policy>
+  class _signal_base1 : public _signal_base<mt_policy>
+  {
+  public:
+    typedef std::list<_connection_base1<arg1_type, mt_policy> *>  connections_list;
+
+    _signal_base1()
+    {
+      ;
+    }
+
+    _signal_base1(const _signal_base1<arg1_type, mt_policy>& s)
+        : _signal_base<mt_policy>(s)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = s.m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_connect(this);
+        m_connected_slots.push_back((*it)->clone());
+
+        ++it;
+      }
+    }
+
+    void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == oldtarget)
+        {
+          m_connected_slots.push_back((*it)->duplicate(newtarget));
+        }
+
+        ++it;
+      }
+    }
+
+    ~_signal_base1()
+    {
+      disconnect_all();
+    }
+
+    void disconnect_all()
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_disconnect(this);
+        delete *it;
+
+        ++it;
+      }
+
+      m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
+    }
+
+    void disconnect(has_slots<mt_policy>* pclass)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == pclass)
+        {
+          delete *it;
+          m_connected_slots.erase(it);
+          pclass->signal_disconnect(this);
+          return;
+        }
+
+        ++it;
+      }
+    }
+
+    void slot_disconnect(has_slots<mt_policy>* pslot)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        typename connections_list::iterator itNext = it;
+        ++itNext;
+
+        if((*it)->getdest() == pslot)
+        {
+          m_connected_slots.erase(it);
+          //                        delete *it;
+        }
+
+        it = itNext;
+      }
+    }
+
+
+  protected:
+    connections_list m_connected_slots;
+  };
+
+  template<class arg1_type, class arg2_type, class mt_policy>
+  class _signal_base2 : public _signal_base<mt_policy>
+  {
+  public:
+    typedef std::list<_connection_base2<arg1_type, arg2_type, mt_policy> *>
+    connections_list;
+
+    _signal_base2()
+    {
+      ;
+    }
+
+    _signal_base2(const _signal_base2<arg1_type, arg2_type, mt_policy>& s)
+        : _signal_base<mt_policy>(s)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = s.m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_connect(this);
+        m_connected_slots.push_back((*it)->clone());
+
+        ++it;
+      }
+    }
+
+    void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == oldtarget)
+        {
+          m_connected_slots.push_back((*it)->duplicate(newtarget));
+        }
+
+        ++it;
+      }
+    }
+
+    ~_signal_base2()
+    {
+      disconnect_all();
+    }
+
+    void disconnect_all()
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_disconnect(this);
+        delete *it;
+
+        ++it;
+      }
+
+      m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
+    }
+
+    void disconnect(has_slots<mt_policy>* pclass)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == pclass)
+        {
+          delete *it;
+          m_connected_slots.erase(it);
+          pclass->signal_disconnect(this);
+          return;
+        }
+
+        ++it;
+      }
+    }
+
+    void slot_disconnect(has_slots<mt_policy>* pslot)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        typename connections_list::iterator itNext = it;
+        ++itNext;
+
+        if((*it)->getdest() == pslot)
+        {
+          m_connected_slots.erase(it);
+          //                        delete *it;
+        }
+
+        it = itNext;
+      }
+    }
+
+  protected:
+    connections_list m_connected_slots;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class mt_policy>
+  class _signal_base3 : public _signal_base<mt_policy>
+  {
+  public:
+    typedef std::list<_connection_base3<arg1_type, arg2_type, arg3_type, mt_policy> *>
+    connections_list;
+
+    _signal_base3()
+    {
+      ;
+    }
+
+    _signal_base3(const _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>& s)
+        : _signal_base<mt_policy>(s)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = s.m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_connect(this);
+        m_connected_slots.push_back((*it)->clone());
+
+        ++it;
+      }
+    }
+
+    void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == oldtarget)
+        {
+          m_connected_slots.push_back((*it)->duplicate(newtarget));
+        }
+
+        ++it;
+      }
+    }
+
+    ~_signal_base3()
+    {
+      disconnect_all();
+    }
+
+    void disconnect_all()
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_disconnect(this);
+        delete *it;
+
+        ++it;
+      }
+
+      m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
+    }
+
+    void disconnect(has_slots<mt_policy>* pclass)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == pclass)
+        {
+          delete *it;
+          m_connected_slots.erase(it);
+          pclass->signal_disconnect(this);
+          return;
+        }
+
+        ++it;
+      }
+    }
+
+    void slot_disconnect(has_slots<mt_policy>* pslot)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        typename connections_list::iterator itNext = it;
+        ++itNext;
+
+        if((*it)->getdest() == pslot)
+        {
+          m_connected_slots.erase(it);
+          //                        delete *it;
+        }
+
+        it = itNext;
+      }
+    }
+
+  protected:
+    connections_list m_connected_slots;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy>
+  class _signal_base4 : public _signal_base<mt_policy>
+  {
+  public:
+    typedef std::list<_connection_base4<arg1_type, arg2_type, arg3_type,
+    arg4_type, mt_policy> *>  connections_list;
+
+    _signal_base4()
+    {
+      ;
+    }
+
+    _signal_base4(const _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s)
+        : _signal_base<mt_policy>(s)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = s.m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_connect(this);
+        m_connected_slots.push_back((*it)->clone());
+
+        ++it;
+      }
+    }
+
+    void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == oldtarget)
+        {
+          m_connected_slots.push_back((*it)->duplicate(newtarget));
+        }
+
+        ++it;
+      }
+    }
+
+    ~_signal_base4()
+    {
+      disconnect_all();
+    }
+
+    void disconnect_all()
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_disconnect(this);
+        delete *it;
+
+        ++it;
+      }
+
+      m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
+    }
+
+    void disconnect(has_slots<mt_policy>* pclass)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == pclass)
+        {
+          delete *it;
+          m_connected_slots.erase(it);
+          pclass->signal_disconnect(this);
+          return;
+        }
+
+        ++it;
+      }
+    }
+
+    void slot_disconnect(has_slots<mt_policy>* pslot)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        typename connections_list::iterator itNext = it;
+        ++itNext;
+
+        if((*it)->getdest() == pslot)
+        {
+          m_connected_slots.erase(it);
+          //                        delete *it;
+        }
+
+        it = itNext;
+      }
+    }
+
+  protected:
+    connections_list m_connected_slots;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class mt_policy>
+  class _signal_base5 : public _signal_base<mt_policy>
+  {
+  public:
+    typedef std::list<_connection_base5<arg1_type, arg2_type, arg3_type,
+    arg4_type, arg5_type, mt_policy> *>  connections_list;
+
+    _signal_base5()
+    {
+      ;
+    }
+
+    _signal_base5(const _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type,
+                  arg5_type, mt_policy>& s)
+        : _signal_base<mt_policy>(s)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = s.m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_connect(this);
+        m_connected_slots.push_back((*it)->clone());
+
+        ++it;
+      }
+    }
+
+    void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == oldtarget)
+        {
+          m_connected_slots.push_back((*it)->duplicate(newtarget));
+        }
+
+        ++it;
+      }
+    }
+
+    ~_signal_base5()
+    {
+      disconnect_all();
+    }
+
+    void disconnect_all()
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_disconnect(this);
+        delete *it;
+
+        ++it;
+      }
+
+      m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
+    }
+
+    void disconnect(has_slots<mt_policy>* pclass)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == pclass)
+        {
+          delete *it;
+          m_connected_slots.erase(it);
+          pclass->signal_disconnect(this);
+          return;
+        }
+
+        ++it;
+      }
+    }
+
+    void slot_disconnect(has_slots<mt_policy>* pslot)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        typename connections_list::iterator itNext = it;
+        ++itNext;
+
+        if((*it)->getdest() == pslot)
+        {
+          m_connected_slots.erase(it);
+          //                        delete *it;
+        }
+
+        it = itNext;
+      }
+    }
+
+  protected:
+    connections_list m_connected_slots;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class arg6_type, class mt_policy>
+  class _signal_base6 : public _signal_base<mt_policy>
+  {
+  public:
+    typedef std::list<_connection_base6<arg1_type, arg2_type, arg3_type,
+    arg4_type, arg5_type, arg6_type, mt_policy> *>  connections_list;
+
+    _signal_base6()
+    {
+      ;
+    }
+
+    _signal_base6(const _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type,
+                  arg5_type, arg6_type, mt_policy>& s)
+        : _signal_base<mt_policy>(s)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = s.m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_connect(this);
+        m_connected_slots.push_back((*it)->clone());
+
+        ++it;
+      }
+    }
+
+    void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == oldtarget)
+        {
+          m_connected_slots.push_back((*it)->duplicate(newtarget));
+        }
+
+        ++it;
+      }
+    }
+
+    ~_signal_base6()
+    {
+      disconnect_all();
+    }
+
+    void disconnect_all()
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_disconnect(this);
+        delete *it;
+
+        ++it;
+      }
+
+      m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
+    }
+
+    void disconnect(has_slots<mt_policy>* pclass)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == pclass)
+        {
+          delete *it;
+          m_connected_slots.erase(it);
+          pclass->signal_disconnect(this);
+          return;
+        }
+
+        ++it;
+      }
+    }
+
+    void slot_disconnect(has_slots<mt_policy>* pslot)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        typename connections_list::iterator itNext = it;
+        ++itNext;
+
+        if((*it)->getdest() == pslot)
+        {
+          m_connected_slots.erase(it);
+          //                        delete *it;
+        }
+
+        it = itNext;
+      }
+    }
+
+  protected:
+    connections_list m_connected_slots;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class arg6_type, class arg7_type, class mt_policy>
+  class _signal_base7 : public _signal_base<mt_policy>
+  {
+  public:
+    typedef std::list<_connection_base7<arg1_type, arg2_type, arg3_type,
+    arg4_type, arg5_type, arg6_type, arg7_type, mt_policy> *>  connections_list;
+
+    _signal_base7()
+    {
+      ;
+    }
+
+    _signal_base7(const _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type,
+                  arg5_type, arg6_type, arg7_type, mt_policy>& s)
+        : _signal_base<mt_policy>(s)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = s.m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_connect(this);
+        m_connected_slots.push_back((*it)->clone());
+
+        ++it;
+      }
+    }
+
+    void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == oldtarget)
+        {
+          m_connected_slots.push_back((*it)->duplicate(newtarget));
+        }
+
+        ++it;
+      }
+    }
+
+    ~_signal_base7()
+    {
+      disconnect_all();
+    }
+
+    void disconnect_all()
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_disconnect(this);
+        delete *it;
+
+        ++it;
+      }
+
+      m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
+    }
+
+    void disconnect(has_slots<mt_policy>* pclass)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == pclass)
+        {
+          delete *it;
+          m_connected_slots.erase(it);
+          pclass->signal_disconnect(this);
+          return;
+        }
+
+        ++it;
+      }
+    }
+
+    void slot_disconnect(has_slots<mt_policy>* pslot)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        typename connections_list::iterator itNext = it;
+        ++itNext;
+
+        if((*it)->getdest() == pslot)
+        {
+          m_connected_slots.erase(it);
+          //                        delete *it;
+        }
+
+        it = itNext;
+      }
+    }
+
+  protected:
+    connections_list m_connected_slots;
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy>
+  class _signal_base8 : public _signal_base<mt_policy>
+  {
+  public:
+    typedef std::list<_connection_base8<arg1_type, arg2_type, arg3_type,
+    arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy> *>
+    connections_list;
+
+    _signal_base8()
+    {
+      ;
+    }
+
+    _signal_base8(const _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type,
+                  arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>& s)
+        : _signal_base<mt_policy>(s)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = s.m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = s.m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_connect(this);
+        m_connected_slots.push_back((*it)->clone());
+
+        ++it;
+      }
+    }
+
+    void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == oldtarget)
+        {
+          m_connected_slots.push_back((*it)->duplicate(newtarget));
+        }
+
+        ++it;
+      }
+    }
+
+    ~_signal_base8()
+    {
+      disconnect_all();
+    }
+
+    void disconnect_all()
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::const_iterator it = m_connected_slots.begin();
+      typename connections_list::const_iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        (*it)->getdest()->signal_disconnect(this);
+        delete *it;
+
+        ++it;
+      }
+
+      m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());
+    }
+
+    void disconnect(has_slots<mt_policy>* pclass)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        if((*it)->getdest() == pclass)
+        {
+          delete *it;
+          m_connected_slots.erase(it);
+          pclass->signal_disconnect(this);
+          return;
+        }
+
+        ++it;
+      }
+    }
+
+    void slot_disconnect(has_slots<mt_policy>* pslot)
+    {
+      lock_block<mt_policy> lock(this);
+      typename connections_list::iterator it = m_connected_slots.begin();
+      typename connections_list::iterator itEnd = m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        typename connections_list::iterator itNext = it;
+        ++itNext;
+
+        if((*it)->getdest() == pslot)
+        {
+          m_connected_slots.erase(it);
+          //                        delete *it;
+        }
+
+        it = itNext;
+      }
+    }
+
+  protected:
+    connections_list m_connected_slots;
+  };
+
+
+  template<class dest_type, class mt_policy>
+  class _connection0 : public _connection_base0<mt_policy>
+  {
+  public:
+    _connection0()
+    {
+      m_pobject = NULL;
+      m_pmemfun = NULL;
+    }
+
+    _connection0(dest_type* pobject, void (dest_type::*pmemfun)())
+    {
+      m_pobject = pobject;
+      m_pmemfun = pmemfun;
+    }
+
+    virtual _connection_base0<mt_policy>* clone()
+    {
+      return new _connection0<dest_type, mt_policy>(*this);
+    }
+
+    virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
+    {
+      return new _connection0<dest_type, mt_policy>(dynamic_cast<dest_type*>(pnewdest), m_pmemfun);
+    }
+
+    virtual void emit()
+    {
+      (m_pobject->*m_pmemfun)();
+    }
+
+    virtual has_slots<mt_policy>* getdest() const
+    {
+      return m_pobject;
+    }
+
+  private:
+    dest_type* m_pobject;
+    void (dest_type::* m_pmemfun)();
+  };
+
+  template<class dest_type, class arg1_type, class mt_policy>
+  class _connection1 : public _connection_base1<arg1_type, mt_policy>
+  {
+  public:
+    _connection1()
+    {
+      m_pobject = NULL;
+      m_pmemfun = NULL;
+    }
+
+    _connection1(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type))
+    {
+      m_pobject = pobject;
+      m_pmemfun = pmemfun;
+    }
+
+    virtual _connection_base1<arg1_type, mt_policy>* clone()
+    {
+      return new _connection1<dest_type, arg1_type, mt_policy>(*this);
+    }
+
+    virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
+    {
+      return new _connection1<dest_type, arg1_type, mt_policy>(dynamic_cast<dest_type*>(pnewdest), m_pmemfun);
+    }
+
+    virtual void emit(arg1_type a1)
+    {
+      (m_pobject->*m_pmemfun)(a1);
+    }
+
+    virtual has_slots<mt_policy>* getdest() const
+    {
+      return m_pobject;
+    }
+
+  private:
+    dest_type* m_pobject;
+    void (dest_type::* m_pmemfun)(arg1_type);
+  };
+
+  template<class dest_type, class arg1_type, class arg2_type, class mt_policy>
+  class _connection2 : public _connection_base2<arg1_type, arg2_type, mt_policy>
+  {
+  public:
+    _connection2()
+    {
+      m_pobject = NULL;
+      m_pmemfun = NULL;
+    }
+
+    _connection2(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
+                 arg2_type))
+    {
+      m_pobject = pobject;
+      m_pmemfun = pmemfun;
+    }
+
+    virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone()
+    {
+      return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>(*this);
+    }
+
+    virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
+    {
+      return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>(dynamic_cast<dest_type*>(pnewdest), m_pmemfun);
+    }
+
+    virtual void emit(arg1_type a1, arg2_type a2)
+    {
+      (m_pobject->*m_pmemfun)(a1, a2);
+    }
+
+    virtual has_slots<mt_policy>* getdest() const
+    {
+      return m_pobject;
+    }
+
+  private:
+    dest_type* m_pobject;
+    void (dest_type::* m_pmemfun)(arg1_type, arg2_type);
+  };
+
+  template<class dest_type, class arg1_type, class arg2_type, class arg3_type, class mt_policy>
+  class _connection3 : public _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>
+  {
+  public:
+    _connection3()
+    {
+      m_pobject = NULL;
+      m_pmemfun = NULL;
+    }
+
+    _connection3(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type))
+    {
+      m_pobject = pobject;
+      m_pmemfun = pmemfun;
+    }
+
+    virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* clone()
+    {
+      return new _connection3<dest_type, arg1_type, arg2_type, arg3_type, mt_policy>(*this);
+    }
+
+    virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
+    {
+      return new _connection3<dest_type, arg1_type, arg2_type, arg3_type, mt_policy>(dynamic_cast<dest_type*>(pnewdest), m_pmemfun);
+    }
+
+    virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3)
+    {
+      (m_pobject->*m_pmemfun)(a1, a2, a3);
+    }
+
+    virtual has_slots<mt_policy>* getdest() const
+    {
+      return m_pobject;
+    }
+
+  private:
+    dest_type* m_pobject;
+    void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type);
+  };
+
+  template<class dest_type, class arg1_type, class arg2_type, class arg3_type,
+  class arg4_type, class mt_policy>
+  class _connection4 : public _connection_base4<arg1_type, arg2_type,
+        arg3_type, arg4_type, mt_policy>
+  {
+  public:
+    _connection4()
+    {
+      m_pobject = NULL;
+      m_pmemfun = NULL;
+    }
+
+    _connection4(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type, arg4_type))
+    {
+      m_pobject = pobject;
+      m_pmemfun = pmemfun;
+    }
+
+    virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* clone()
+    {
+      return new _connection4<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>(*this);
+    }
+
+    virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
+    {
+      return new _connection4<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>(dynamic_cast<dest_type*>(pnewdest), m_pmemfun);
+    }
+
+    virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3,
+                      arg4_type a4)
+    {
+      (m_pobject->*m_pmemfun)(a1, a2, a3, a4);
+    }
+
+    virtual has_slots<mt_policy>* getdest() const
+    {
+      return m_pobject;
+    }
+
+  private:
+    dest_type* m_pobject;
+    void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type,
+                                  arg4_type);
+  };
+
+  template<class dest_type, class arg1_type, class arg2_type, class arg3_type,
+  class arg4_type, class arg5_type, class mt_policy>
+  class _connection5 : public _connection_base5<arg1_type, arg2_type,
+        arg3_type, arg4_type, arg5_type, mt_policy>
+  {
+  public:
+    _connection5()
+    {
+      m_pobject = NULL;
+      m_pmemfun = NULL;
+    }
+
+    _connection5(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type, arg4_type, arg5_type))
+    {
+      m_pobject = pobject;
+      m_pmemfun = pmemfun;
+    }
+
+    virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, mt_policy>* clone()
+    {
+      return new _connection5<dest_type, arg1_type, arg2_type, arg3_type, arg4_type,
+             arg5_type, mt_policy>(*this);
+    }
+
+    virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
+    {
+      return new _connection5<dest_type, arg1_type, arg2_type, arg3_type, arg4_type,
+      arg5_type, mt_policy>(dynamic_cast<dest_type*>(pnewdest), m_pmemfun);
+    }
+
+    virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+                      arg5_type a5)
+    {
+      (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5);
+    }
+
+    virtual has_slots<mt_policy>* getdest() const
+    {
+      return m_pobject;
+    }
+
+  private:
+    dest_type* m_pobject;
+    void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,
+                                  arg5_type);
+  };
+
+  template<class dest_type, class arg1_type, class arg2_type, class arg3_type,
+  class arg4_type, class arg5_type, class arg6_type, class mt_policy>
+  class _connection6 : public _connection_base6<arg1_type, arg2_type,
+        arg3_type, arg4_type, arg5_type, arg6_type, mt_policy>
+  {
+  public:
+    _connection6()
+    {
+      m_pobject = NULL;
+      m_pmemfun = NULL;
+    }
+
+    _connection6(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type))
+    {
+      m_pobject = pobject;
+      m_pmemfun = pmemfun;
+    }
+
+    virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, mt_policy>* clone()
+    {
+      return new _connection6<dest_type, arg1_type, arg2_type, arg3_type, arg4_type,
+             arg5_type, arg6_type, mt_policy>(*this);
+    }
+
+    virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
+    {
+      return new _connection6<dest_type, arg1_type, arg2_type, arg3_type, arg4_type,
+      arg5_type, arg6_type, mt_policy>(dynamic_cast<dest_type*>(pnewdest), m_pmemfun);
+    }
+
+    virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+                      arg5_type a5, arg6_type a6)
+    {
+      (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6);
+    }
+
+    virtual has_slots<mt_policy>* getdest() const
+    {
+      return m_pobject;
+    }
+
+  private:
+    dest_type* m_pobject;
+    void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,
+                                  arg5_type, arg6_type);
+  };
+
+  template<class dest_type, class arg1_type, class arg2_type, class arg3_type,
+  class arg4_type, class arg5_type, class arg6_type, class arg7_type, class mt_policy>
+  class _connection7 : public _connection_base7<arg1_type, arg2_type,
+        arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>
+  {
+  public:
+    _connection7()
+    {
+      m_pobject = NULL;
+      m_pmemfun = NULL;
+    }
+
+    _connection7(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type))
+    {
+      m_pobject = pobject;
+      m_pmemfun = pmemfun;
+    }
+
+    virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, arg7_type, mt_policy>* clone()
+    {
+      return new _connection7<dest_type, arg1_type, arg2_type, arg3_type, arg4_type,
+             arg5_type, arg6_type, arg7_type, mt_policy>(*this);
+    }
+
+    virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
+    {
+      return new _connection7<dest_type, arg1_type, arg2_type, arg3_type, arg4_type,
+      arg5_type, arg6_type, arg7_type, mt_policy>(dynamic_cast<dest_type*>(pnewdest), m_pmemfun);
+    }
+
+    virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+                      arg5_type a5, arg6_type a6, arg7_type a7)
+    {
+      (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7);
+    }
+
+    virtual has_slots<mt_policy>* getdest() const
+    {
+      return m_pobject;
+    }
+
+  private:
+    dest_type* m_pobject;
+    void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,
+                                  arg5_type, arg6_type, arg7_type);
+  };
+
+  template<class dest_type, class arg1_type, class arg2_type, class arg3_type,
+  class arg4_type, class arg5_type, class arg6_type, class arg7_type,
+  class arg8_type, class mt_policy>
+  class _connection8 : public _connection_base8<arg1_type, arg2_type,
+        arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>
+  {
+  public:
+    _connection8()
+    {
+      m_pobject = NULL;
+      m_pmemfun = NULL;
+    }
+
+    _connection8(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type,
+                 arg7_type, arg8_type))
+    {
+      m_pobject = pobject;
+      m_pmemfun = pmemfun;
+    }
+
+    virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone()
+    {
+      return new _connection8<dest_type, arg1_type, arg2_type, arg3_type, arg4_type,
+             arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>(*this);
+    }
+
+    virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type,
+    arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest)
+    {
+      return new _connection8<dest_type, arg1_type, arg2_type, arg3_type, arg4_type,
+      arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>(dynamic_cast<dest_type*>(pnewdest), m_pmemfun);
+    }
+
+    virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+                      arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8)
+    {
+      (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7, a8);
+    }
+
+    virtual has_slots<mt_policy>* getdest() const
+    {
+      return m_pobject;
+    }
+
+  private:
+    dest_type* m_pobject;
+    void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type,
+                                  arg5_type, arg6_type, arg7_type, arg8_type);
+  };
+
+  template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
+  class signal0 : public _signal_base0<mt_policy>
+  {
+  public:
+    signal0()
+    {
+      ;
+    }
+
+    signal0(const signal0<mt_policy>& s)
+        : _signal_base0<mt_policy>(s)
+    {
+      ;
+    }
+
+    template<class desttype>
+    void connect(desttype* pclass, void (desttype::*pmemfun)())
+    {
+      lock_block<mt_policy> lock(this);
+      _connection0<desttype, mt_policy>* conn =
+        new _connection0<desttype, mt_policy>(pclass, pmemfun);
+      this->m_connected_slots.push_back(conn);
+      pclass->signal_connect(this);
+    }
+
+    void emit()
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base0<mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base0<mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit();
+
+        it = itNext;
+      }
+    }
+
+    void operator()()
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base0<mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base0<mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit();
+
+        it = itNext;
+      }
+    }
+  };
+
+  template<class arg1_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
+  class signal1 : public _signal_base1<arg1_type, mt_policy>
+  {
+  public:
+    signal1()
+    {
+      ;
+    }
+
+    signal1(const signal1<arg1_type, mt_policy>& s)
+        : _signal_base1<arg1_type, mt_policy>(s)
+    {
+      ;
+    }
+
+    template<class desttype>
+    void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type))
+    {
+      lock_block<mt_policy> lock(this);
+      _connection1<desttype, arg1_type, mt_policy>* conn =
+        new _connection1<desttype, arg1_type, mt_policy>(pclass, pmemfun);
+      this->m_connected_slots.push_back(conn);
+      pclass->signal_connect(this);
+    }
+
+    void emit(arg1_type a1)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base1<arg1_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base1<arg1_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1);
+
+        it = itNext;
+      }
+    }
+
+    void operator()(arg1_type a1)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base1<arg1_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base1<arg1_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1);
+
+        it = itNext;
+      }
+    }
+  };
+
+  template<class arg1_type, class arg2_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
+  class signal2 : public _signal_base2<arg1_type, arg2_type, mt_policy>
+  {
+  public:
+    signal2()
+    {
+      ;
+    }
+
+    signal2(const signal2<arg1_type, arg2_type, mt_policy>& s)
+        : _signal_base2<arg1_type, arg2_type, mt_policy>(s)
+    {
+      ;
+    }
+
+    template<class desttype>
+    void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
+                 arg2_type))
+    {
+      lock_block<mt_policy> lock(this);
+      _connection2<desttype, arg1_type, arg2_type, mt_policy>* conn = new
+          _connection2<desttype, arg1_type, arg2_type, mt_policy>(pclass, pmemfun);
+      this->m_connected_slots.push_back(conn);
+      pclass->signal_connect(this);
+    }
+
+    void emit(arg1_type a1, arg2_type a2)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2);
+
+        it = itNext;
+      }
+    }
+
+    void operator()(arg1_type a1, arg2_type a2)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2);
+
+        it = itNext;
+      }
+    }
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
+  class signal3 : public _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>
+  {
+  public:
+    signal3()
+    {
+      ;
+    }
+
+    signal3(const signal3<arg1_type, arg2_type, arg3_type, mt_policy>& s)
+        : _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>(s)
+    {
+      ;
+    }
+
+    template<class desttype>
+    void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type))
+    {
+      lock_block<mt_policy> lock(this);
+      _connection3<desttype, arg1_type, arg2_type, arg3_type, mt_policy>* conn =
+        new _connection3<desttype, arg1_type, arg2_type, arg3_type, mt_policy>(pclass,
+            pmemfun);
+      this->m_connected_slots.push_back(conn);
+      pclass->signal_connect(this);
+    }
+
+    void emit(arg1_type a1, arg2_type a2, arg3_type a3)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3);
+
+        it = itNext;
+      }
+    }
+
+    void operator()(arg1_type a1, arg2_type a2, arg3_type a3)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3);
+
+        it = itNext;
+      }
+    }
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
+  class signal4 : public _signal_base4<arg1_type, arg2_type, arg3_type,
+        arg4_type, mt_policy>
+  {
+  public:
+    signal4()
+    {
+      ;
+    }
+
+    signal4(const signal4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s)
+        : _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>(s)
+    {
+      ;
+    }
+
+    template<class desttype>
+    void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type, arg4_type))
+    {
+      lock_block<mt_policy> lock(this);
+      _connection4<desttype, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>*
+      conn = new _connection4<desttype, arg1_type, arg2_type, arg3_type,
+             arg4_type, mt_policy>(pclass, pmemfun);
+      this->m_connected_slots.push_back(conn);
+      pclass->signal_connect(this);
+    }
+
+    void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3, a4);
+
+        it = itNext;
+      }
+    }
+
+    void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3, a4);
+
+        it = itNext;
+      }
+    }
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
+  class signal5 : public _signal_base5<arg1_type, arg2_type, arg3_type,
+        arg4_type, arg5_type, mt_policy>
+  {
+  public:
+    signal5()
+    {
+      ;
+    }
+
+    signal5(const signal5<arg1_type, arg2_type, arg3_type, arg4_type,
+            arg5_type, mt_policy>& s)
+        : _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type,
+        arg5_type, mt_policy>(s)
+    {
+      ;
+    }
+
+    template<class desttype>
+    void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type, arg4_type, arg5_type))
+    {
+      lock_block<mt_policy> lock(this);
+      _connection5<desttype, arg1_type, arg2_type, arg3_type, arg4_type,
+      arg5_type, mt_policy>* conn = new _connection5<desttype, arg1_type, arg2_type,
+                                    arg3_type, arg4_type, arg5_type, mt_policy>(pclass, pmemfun);
+      this->m_connected_slots.push_back(conn);
+      pclass->signal_connect(this);
+    }
+
+    void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+              arg5_type a5)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3, a4, a5);
+
+        it = itNext;
+      }
+    }
+
+    void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+                    arg5_type a5)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3, a4, a5);
+
+        it = itNext;
+      }
+    }
+  };
+
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class arg6_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
+  class signal6 : public _signal_base6<arg1_type, arg2_type, arg3_type,
+        arg4_type, arg5_type, arg6_type, mt_policy>
+  {
+  public:
+    signal6()
+    {
+      ;
+    }
+
+    signal6(const signal6<arg1_type, arg2_type, arg3_type, arg4_type,
+            arg5_type, arg6_type, mt_policy>& s)
+        : _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type,
+        arg5_type, arg6_type, mt_policy>(s)
+    {
+      ;
+    }
+
+    template<class desttype>
+    void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type))
+    {
+      lock_block<mt_policy> lock(this);
+      _connection6<desttype, arg1_type, arg2_type, arg3_type, arg4_type,
+      arg5_type, arg6_type, mt_policy>* conn =
+        new _connection6<desttype, arg1_type, arg2_type, arg3_type,
+        arg4_type, arg5_type, arg6_type, mt_policy>(pclass, pmemfun);
+      this->m_connected_slots.push_back(conn);
+      pclass->signal_connect(this);
+    }
+
+    void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+              arg5_type a5, arg6_type a6)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3, a4, a5, a6);
+
+        it = itNext;
+      }
+    }
+
+    void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+                    arg5_type a5, arg6_type a6)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3, a4, a5, a6);
+
+        it = itNext;
+      }
+    }
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class arg6_type, class arg7_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
+  class signal7 : public _signal_base7<arg1_type, arg2_type, arg3_type,
+        arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>
+  {
+  public:
+    signal7()
+    {
+      ;
+    }
+
+    signal7(const signal7<arg1_type, arg2_type, arg3_type, arg4_type,
+            arg5_type, arg6_type, arg7_type, mt_policy>& s)
+        : _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type,
+        arg5_type, arg6_type, arg7_type, mt_policy>(s)
+    {
+      ;
+    }
+
+    template<class desttype>
+    void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type,
+                 arg7_type))
+    {
+      lock_block<mt_policy> lock(this);
+      _connection7<desttype, arg1_type, arg2_type, arg3_type, arg4_type,
+      arg5_type, arg6_type, arg7_type, mt_policy>* conn =
+        new _connection7<desttype, arg1_type, arg2_type, arg3_type,
+        arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>(pclass, pmemfun);
+      this->m_connected_slots.push_back(conn);
+      pclass->signal_connect(this);
+    }
+
+    void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+              arg5_type a5, arg6_type a6, arg7_type a7)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3, a4, a5, a6, a7);
+
+        it = itNext;
+      }
+    }
+
+    void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+                    arg5_type a5, arg6_type a6, arg7_type a7)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3, a4, a5, a6, a7);
+
+        it = itNext;
+      }
+    }
+  };
+
+  template<class arg1_type, class arg2_type, class arg3_type, class arg4_type,
+  class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
+  class signal8 : public _signal_base8<arg1_type, arg2_type, arg3_type,
+        arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>
+  {
+  public:
+    signal8()
+    {
+      ;
+    }
+
+    signal8(const signal8<arg1_type, arg2_type, arg3_type, arg4_type,
+            arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>& s)
+        : _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type,
+        arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>(s)
+    {
+      ;
+    }
+
+    template<class desttype>
+    void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
+                 arg2_type, arg3_type, arg4_type, arg5_type, arg6_type,
+                 arg7_type, arg8_type))
+    {
+      lock_block<mt_policy> lock(this);
+      _connection8<desttype, arg1_type, arg2_type, arg3_type, arg4_type,
+      arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* conn =
+        new _connection8<desttype, arg1_type, arg2_type, arg3_type,
+        arg4_type, arg5_type, arg6_type, arg7_type,
+        arg8_type, mt_policy>(pclass, pmemfun);
+      this->m_connected_slots.push_back(conn);
+      pclass->signal_connect(this);
+    }
+
+    void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+              arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8);
+
+        it = itNext;
+      }
+    }
+
+    void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4,
+                    arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8)
+    {
+      lock_block<mt_policy> lock(this);
+      typename _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>::connections_list::const_iterator itNext, it = this->m_connected_slots.begin();
+      typename _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>::connections_list::const_iterator itEnd = this->m_connected_slots.end();
+
+      while(it != itEnd)
+      {
+        itNext = it;
+        ++itNext;
+
+        (*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8);
+
+        it = itNext;
+      }
+    }
+  };
+
+}
+; // namespace sigslot
+
+#endif /* SIGNAL_H__ */
+
Index: branches/heathaze/src/lib/util/sigslot/slot.h
===================================================================
--- branches/heathaze/src/lib/util/sigslot/slot.h	(revision 9940)
+++ branches/heathaze/src/lib/util/sigslot/slot.h	(revision 9940)
@@ -0,0 +1,307 @@
+/**
+ * @file slot.h
+ * @brief Slots part of Signal Slot library from Sarah Thopson
+ * @see signal.h for more information and license.
+ */
+
+#ifndef SLOT_H__
+#define SLOT_H__
+
+#include <set>
+#include <list>
+
+
+#if defined(SIGSLOT_PURE_ISO) || (!defined(WIN32) && !defined(__GNUG__) && !defined(SIGSLOT_USE_POSIX_THREADS))
+#	define _SIGSLOT_SINGLE_THREADED
+#elif defined(WIN32)
+#	define _SIGSLOT_HAS_WIN32_THREADS
+#	include <windows.h>
+#elif defined(__GNUG__) || defined(SIGSLOT_USE_POSIX_THREADS)
+#	define _SIGSLOT_HAS_POSIX_THREADS
+#	include <pthread.h>
+#else
+#	define _SIGSLOT_SINGLE_THREADED
+#endif
+
+#ifndef SIGSLOT_DEFAULT_MT_POLICY
+#	ifdef _SIGSLOT_SINGLE_THREADED
+#		define SIGSLOT_DEFAULT_MT_POLICY single_threaded
+#	else
+#		define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local
+#	endif
+#endif
+
+namespace sigslot
+{
+
+  class single_threaded
+  {
+    public:
+      single_threaded()
+      {
+        ;
+      }
+
+      virtual ~single_threaded()
+      {
+        ;
+      }
+
+      virtual void lock()
+      {
+        ;
+      }
+
+      virtual void unlock()
+      {
+        ;
+      }
+  };
+
+#ifdef _SIGSLOT_HAS_WIN32_THREADS
+  // The multi threading policies only get compiled in if they are enabled.
+  class multi_threaded_global
+  {
+    public:
+      multi_threaded_global()
+      {
+        static bool isinitialised = false;
+
+        if(!isinitialised)
+        {
+          InitializeCriticalSection(get_critsec());
+          isinitialised = true;
+        }
+      }
+
+      multi_threaded_global(const multi_threaded_global&)
+      {
+        ;
+      }
+
+      virtual ~multi_threaded_global()
+      {
+        ;
+      }
+
+      virtual void lock()
+      {
+        EnterCriticalSection(get_critsec());
+      }
+
+      virtual void unlock()
+      {
+        LeaveCriticalSection(get_critsec());
+      }
+
+    private:
+      CRITICAL_SECTION* get_critsec()
+      {
+        static CRITICAL_SECTION g_critsec;
+        return &g_critsec;
+      }
+  };
+
+  class multi_threaded_local
+  {
+    public:
+      multi_threaded_local()
+      {
+        InitializeCriticalSection(&m_critsec);
+      }
+
+      multi_threaded_local(const multi_threaded_local&)
+      {
+        InitializeCriticalSection(&m_critsec);
+      }
+
+      virtual ~multi_threaded_local()
+      {
+        DeleteCriticalSection(&m_critsec);
+      }
+
+      virtual void lock()
+      {
+        EnterCriticalSection(&m_critsec);
+      }
+
+      virtual void unlock()
+      {
+        LeaveCriticalSection(&m_critsec);
+      }
+
+    private:
+      CRITICAL_SECTION m_critsec;
+  };
+#endif // _SIGSLOT_HAS_WIN32_THREADS
+
+#ifdef _SIGSLOT_HAS_POSIX_THREADS
+  // The multi threading policies only get compiled in if they are enabled.
+  class multi_threaded_global
+  {
+    public:
+      multi_threaded_global()
+      {
+        pthread_mutex_init(get_mutex(), NULL);
+      }
+
+      multi_threaded_global(const multi_threaded_global&)
+      {
+        ;
+      }
+
+      virtual ~multi_threaded_global()
+      {
+        ;
+      }
+
+      virtual void lock()
+      {
+        pthread_mutex_lock(get_mutex());
+      }
+
+      virtual void unlock()
+      {
+        pthread_mutex_unlock(get_mutex());
+      }
+
+    private:
+      pthread_mutex_t* get_mutex()
+      {
+        static pthread_mutex_t g_mutex;
+        return &g_mutex;
+      }
+  };
+
+  class multi_threaded_local
+  {
+    public:
+      multi_threaded_local()
+      {
+        pthread_mutex_init(&m_mutex, NULL);
+      }
+
+      multi_threaded_local(const multi_threaded_local&)
+      {
+        pthread_mutex_init(&m_mutex, NULL);
+      }
+
+      virtual ~multi_threaded_local()
+      {
+        pthread_mutex_destroy(&m_mutex);
+      }
+
+      virtual void lock()
+      {
+        pthread_mutex_lock(&m_mutex);
+      }
+
+      virtual void unlock()
+      {
+        pthread_mutex_unlock(&m_mutex);
+      }
+
+    private:
+      pthread_mutex_t m_mutex;
+  };
+#endif // _SIGSLOT_HAS_POSIX_THREADS
+
+  template<class mt_policy>
+  class lock_block
+  {
+    public:
+      mt_policy *m_mutex;
+
+      lock_block(mt_policy *mtx)
+          : m_mutex(mtx)
+      {
+        m_mutex->lock();
+      }
+
+      ~lock_block()
+      {
+        m_mutex->unlock();
+      }
+  };
+
+
+
+
+  template<class mt_policy>
+  class has_slots;
+
+
+  template<class mt_policy>
+  class _signal_base : public mt_policy
+  {
+    public:
+      virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0;
+      virtual void slot_duplicate(const has_slots<mt_policy>* poldslot, has_slots<mt_policy>* pnewslot) = 0;
+  };
+
+  template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
+  class has_slots //: public mt_policy
+  {
+    private:
+      typedef std::set<_signal_base<mt_policy> *> sender_set;
+      typedef typename sender_set::const_iterator const_iterator;
+
+    public:
+      has_slots()
+      {
+        ;
+      }
+
+      has_slots(const has_slots& hs)
+//          : mt_policy(hs)
+      {
+        //lock_block<mt_policy> lock(this);
+        const_iterator it = hs.m_senders.begin();
+        const_iterator itEnd = hs.m_senders.end();
+
+        while(it != itEnd)
+        {
+          (*it)->slot_duplicate(&hs, this);
+          m_senders.insert(*it);
+          ++it;
+        }
+      }
+
+      void signal_connect(_signal_base<mt_policy>* sender)
+      {
+        //lock_block<mt_policy> lock(this);
+        m_senders.insert(sender);
+      }
+
+      void signal_disconnect(_signal_base<mt_policy>* sender)
+      {
+        //lock_block<mt_policy> lock(this);
+        m_senders.erase(sender);
+      }
+
+      virtual ~has_slots()
+      {
+        disconnect_all();
+      }
+
+      void disconnect_all()
+      {
+        //lock_block<mt_policy> lock(this);
+        const_iterator it = m_senders.begin();
+        const_iterator itEnd = m_senders.end();
+
+        while(it != itEnd)
+        {
+          (*it)->slot_disconnect(this);
+          ++it;
+        }
+
+        m_senders.erase(m_senders.begin(), m_senders.end());
+      }
+
+    private:
+      sender_set m_senders;
+  };
+}
+
+#endif /* SLOT_H__ */
Index: branches/heathaze/src/lib/util/smooth.h
===================================================================
--- branches/heathaze/src/lib/util/smooth.h	(revision 9940)
+++ branches/heathaze/src/lib/util/smooth.h	(revision 9940)
@@ -0,0 +1,43 @@
+
+/*!
+ * @file smooth.h
+ * @brief Definition of Smooth Class.
+ */
+
+#ifndef __SMOOTH_H__
+#define __SMOOTH_H__
+
+namespace VariableHandler
+{
+
+
+  template <typename var_type = float> class LinearIteration
+  {
+    public:
+      static void step(var_type* current, const var_type& fromValue, const var_type& toValue, float stepping);
+      static bool reached(const var_type& current, const var_type& toValue) const;
+  };
+
+
+  //! A class to handle smoothness of Variables.
+  /** 
+   * With this smoothing can be achived for many different types of variables.
+   */
+  template <typename var_type = float, class iteration_type = LinearIteration<var_type> > class Smooth
+  {
+    public:
+      Smooth();
+
+      const var_type& from() const { return _from; }
+      const var_type& current() const { return _current; };
+      const var_type& to() const { return _to; }
+
+      inline void tick(float dt) { if (!iteration_type::reached(_current, _to)) iteration_type::step(&_current, _from, _to, dt); };
+
+    private:
+      var_type     _from;
+      var_type     _current;
+      var_type     _to;
+  };
+}
+#endif /* __SMOOTH_H__ */
Index: branches/heathaze/src/lib/util/substring.cc
===================================================================
--- branches/heathaze/src/lib/util/substring.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/substring.cc	(revision 9940)
@@ -0,0 +1,458 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+
+   2005-06-10: some naming conventions
+
+//
+//  splitLine
+//  STL string tokenizer
+//
+//  Created by Clemens Wacha.
+//  Version 1.0
+//  Copyright (c) 2005 Clemens Wacha. All rights reserved.
+//
+
+*/
+
+#include "substring.h"
+
+/**
+ * @brief default constructor
+ */
+SubString::SubString()
+{}
+
+
+/**
+ * @brief create a SubString from
+ * @param string the String to Spilit
+ * @param delimiter the Character at which to split string (delimiter)
+ */
+SubString::SubString(const std::string& string, char delimiter)
+{
+  this->split(string, delimiter);
+}
+
+
+/**
+ * @brief Splits a String into multiple splitters.
+ * @param string the String to split
+ * @param delimiters multiple set of characters at what to split. (delimiters)
+ * @param delimiterNeighbours neighbours of the delimiters, that will be erased only when near a delimiter.
+ * @param emptyEntries If empty entries should be allewed or removed.
+ * @param escapeChar The Escape Character that overrides splitters commends and so on...
+ * @param safemode_char within these characters splitting won't happen
+ * @param comment_char the Comment character.
+ */
+SubString::SubString(const std::string& string,
+                     const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries,
+                     char escapeChar, char safemode_char, char comment_char)
+{
+  SubString::splitLine(this->strings, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, safemode_char, comment_char);
+}
+
+/**
+ * @brief creates a SubSet of a SubString.
+ * @param subString the SubString to take a set from.
+ * @param subSetBegin the beginning to the end
+ */
+SubString::SubString(const SubString& subString, unsigned int subSetBegin)
+{
+  for (unsigned int i = subSetBegin; i < subString.size(); i++)
+    this->strings.push_back(subString[i]);
+}
+
+
+/**
+ * @brief creates a SubSet of a SubString.
+ * @param subString the SubString to take a Set from
+ * @param subSetBegin the beginning to the end
+ * @param subSetEnd the end of the SubSet (max subString.size() will be checked internaly)
+ */
+SubString::SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd)
+{
+  for (unsigned int i = subSetBegin; i < subString.size() || i < subSetEnd; i++)
+    this->strings.push_back(subString[i]);
+}
+
+/**
+ * @brief creates a Substring from a count and values set.
+ * @param argc: the Arguments Count.
+ * @param argv: Argument Values.
+ */
+SubString::SubString(unsigned int argc, const char** argv)
+{
+  for(unsigned int i = 0; i < argc; ++i)
+    this->strings.push_back(std::string(argv[i]));
+}
+
+/**
+ * @brief removes the object from memory
+ */
+SubString::~SubString()
+{ }
+
+/** @brief An empty String */
+// const std::string SubString::emptyString = "";
+/** @brief Helper that gets you a String consisting of all White Spaces */
+const std::string SubString::WhiteSpaces = " \n\t";
+/** @brief Helper that gets you a String consisting of all WhiteSpaces and the Comma */
+const std::string SubString::WhiteSpacesWithComma = " \n\t,";
+/** An Empty SubString */
+const SubString SubString::NullSubString = SubString();
+
+/**
+ * @brief stores the Value of subString in this SubString
+ * @param subString will be copied into this String.
+ * @returns this SubString.
+ */
+SubString& SubString::operator=(const SubString& subString)
+{
+  this->strings = subString.strings;
+  return *this;
+}
+
+
+/**
+ * @brief comparator.
+ * @param subString the SubString to compare against this one.
+ * @returns true if the Stored Strings match
+ */
+bool SubString::operator==(const SubString& subString) const
+{
+  return (this->strings == subString.strings);
+}
+
+/**
+ * @brief comparator.
+ * @param subString the SubString to compare against this one.
+ * @returns true if the Stored Strings match
+ */
+bool SubString::compare(const SubString& subString) const
+{
+  return (*this == subString);
+}
+
+/**
+ * @brief comparator.
+ * @param subString the SubString to compare against this one.
+ * @param length how many entries to compare. (from 0 to length)
+ * @returns true if the Stored Strings match
+ */
+bool SubString::compare(const SubString& subString, unsigned int length) const
+{
+  if (length > this->size() || length > subString.size())
+    return false;
+
+  for (unsigned int i = 0; i < length; i++)
+    if (this->strings[i] != subString.strings[i])
+      return false;
+  return true;
+}
+
+
+/**
+ * @brief append operator
+ * @param subString the String to append.
+ * @returns a SubString where this and subString are appended.
+ */
+SubString SubString::operator+(const SubString& subString) const
+{
+  return SubString(*this) += subString;
+}
+
+
+/**
+ * @brief append operator.
+ * @param subString append subString to this SubString.
+ * @returns this substring appended with subString
+ */
+SubString& SubString::operator+=(const SubString& subString)
+{
+  for (unsigned int i = 0; i < subString.size(); i++)
+    this->strings.push_back(subString[i]);
+  return *this;
+}
+
+
+/**
+ * @brief Split the String at
+ * @param string where to split
+ * @param splitter delimiter.
+ */
+unsigned int SubString::split(const std::string& string, char splitter)
+{
+  this->strings.clear();
+  char split[2];
+  split[0] = splitter;
+  split[1] = '\0';
+  SubString::splitLine(this->strings, string, split);
+  return strings.size();
+}
+
+
+/**
+ * @brief Splits a String into multiple splitters.
+ * @param string the String to split
+ * @param delimiters multiple set of characters at what to split. (delimiters)
+ * @param delimiterNeighbours: Neighbours to the Delimiters that will be erased too.
+ * @param emptyEntries: If empty entries are added to the List of SubStrings
+ * @param escapeChar The Escape Character that overrides splitters commends and so on...
+ * @param safemode_char within these characters splitting won't happen
+ * @param comment_char the Comment character.
+ */
+unsigned int SubString::split(const std::string& string,
+                              const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries,
+                              char escapeChar,char safemode_char, char comment_char)
+{
+  this->strings.clear();
+  SubString::splitLine(this->strings, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, safemode_char, comment_char);
+  return this->strings.size();
+}
+
+
+/**
+ * @brief joins together all Strings of this Substring.
+ * @param delimiter the String between the subStrings.
+ * @returns the joined String.
+ */
+std::string SubString::join(const std::string& delimiter) const
+{
+  if (!this->strings.empty())
+  {
+    std::string retVal = this->strings[0];
+    for (unsigned int i = 1; i < this->strings.size(); i++)
+      retVal += delimiter + this->strings[i];
+    return retVal;
+  }
+  else
+  {
+    static std::string empty;
+    return empty;
+  }
+}
+
+
+/**
+ * @brief creates a SubSet of a SubString.
+ * @param subSetBegin the beginning to the end
+ * @returns the SubSet
+ *
+ * This function is added for your convenience, and does the same as
+ * SubString::SubString(const SubString& subString, unsigned int subSetBegin)
+ */
+SubString SubString::subSet(unsigned int subSetBegin) const
+{
+  return SubString(*this, subSetBegin);
+}
+
+
+/**
+ * @brief creates a SubSet of a SubString.
+ * @param subSetBegin the beginning to
+ * @param subSetEnd the end of the SubSet to select (if bigger than subString.size() it will be downset.)
+ * @returns the SubSet
+ *
+ * This function is added for your convenience, and does the same as
+ * SubString::SubString(const SubString& subString, unsigned int subSetBegin)
+ */
+SubString SubString::subSet(unsigned int subSetBegin, unsigned int subSetEnd) const
+{
+  return SubString(*this, subSetBegin, subSetEnd);
+}
+
+
+/**
+ * @brief splits line into tokens and stores them in ret.
+ * @param ret the Array, where the Splitted strings will be stored in
+ * to the beginning of the current token is stored
+ * @param line the inputLine to split
+ * @param delimiters a String of Delimiters (here the input will be splitted)
+ * @param delimiterNeighbours Naighbours to the Delimitter, that will be removed if they are to the left or the right of a Delimiter.
+ * @param emptyEntries: if empty Strings are added to the List of Strings.
+ * @param escape_char: Escape carater (escapes splitters)
+ * @param safemode_char: the beginning of the safemode is marked with this
+ * @param comment_char: the beginning of a comment is marked with this: (until the end of a Line)
+ * @param start_state: the Initial state on how to parse the String.
+ * @returns SPLIT_LINE_STATE the parser was in when returning
+ *
+ * This is the Actual Splitting Algorithm from Clemens Wacha
+ * Supports delimiters, escape characters,
+ * ignores special  characters between safemode_char and between comment_char and linend '\n'.
+ */
+SubString::SPLIT_LINE_STATE
+SubString::splitLine(std::vector<std::string>& ret,
+                     const std::string& line,
+                     const std::string& delimiters,
+                     const std::string& delimiterNeighbours,
+                     bool emptyEntries,
+                     char escape_char,
+                     char safemode_char,
+                     char comment_char,
+                     SPLIT_LINE_STATE start_state)
+{
+  SPLIT_LINE_STATE state = start_state;
+  unsigned int i = 0;
+  unsigned int fallBackNeighbours = 0;
+
+  std::string token;
+
+  if(start_state != SL_NORMAL && ret.size() > 0)
+  {
+    token = ret[ret.size()-1];
+    ret.pop_back();
+  }
+
+  while(i < line.size())
+  {
+    switch(state)
+    {
+      case SL_NORMAL:
+        if(line[i] == escape_char)
+        {
+          state = SL_ESCAPE;
+        }
+        else if(line[i] == safemode_char)
+        {
+          state = SL_SAFEMODE;
+        }
+        else if(line[i] == comment_char)
+        {
+          if (fallBackNeighbours > 0)
+            token = token.substr(0, token.size() - fallBackNeighbours);
+          /// FINISH
+          if(emptyEntries || token.size() > 0)
+          {
+            ret.push_back(token);
+            token.clear();
+          }
+          token += line[i];       // EAT
+          state = SL_COMMENT;
+        }
+        else if(delimiters.find(line[i]) != std::string::npos)
+        {
+          // line[i] is a delimiter
+          if (fallBackNeighbours > 0)
+            token = token.substr(0, token.size() - fallBackNeighbours);
+          /// FINISH
+          if(emptyEntries || token.size() > 0)
+          {
+            ret.push_back(token);
+            token.clear();
+          }
+          state = SL_NORMAL;
+        }
+        else
+        {
+          if (delimiterNeighbours.find(line[i]) != std::string::npos)
+          {
+            if (token.size() > 0)
+              ++fallBackNeighbours;
+            else
+            {
+              i++;
+              continue;
+            }
+          }
+          else
+            fallBackNeighbours = 0;
+          token += line[i];       // EAT
+        }
+        break;
+      case SL_ESCAPE:
+        if(line[i] == 'n') token += '\n';
+        else if(line[i] == 't') token += '\t';
+        else if(line[i] == 'v') token += '\v';
+        else if(line[i] == 'b') token += '\b';
+        else if(line[i] == 'r') token += '\r';
+        else if(line[i] == 'f') token += '\f';
+        else if(line[i] == 'a') token += '\a';
+        else if(line[i] == '?') token += '\?';
+        else token += line[i];  // EAT
+        state = SL_NORMAL;
+        break;
+      case SL_SAFEMODE:
+        if(line[i] == safemode_char)
+        {
+          state = SL_NORMAL;
+        }
+        else if(line[i] == escape_char)
+        {
+          state = SL_SAFEESCAPE;
+        }
+        else
+        {
+          token += line[i];       // EAT
+        }
+        break;
+
+      case SL_SAFEESCAPE:
+        if(line[i] == 'n') token += '\n';
+        else if(line[i] == 't') token += '\t';
+        else if(line[i] == 'v') token += '\v';
+        else if(line[i] == 'b') token += '\b';
+        else if(line[i] == 'r') token += '\r';
+        else if(line[i] == 'f') token += '\f';
+        else if(line[i] == 'a') token += '\a';
+        else if(line[i] == '?') token += '\?';
+        else token += line[i];  // EAT
+        state = SL_SAFEMODE;
+        break;
+
+      case SL_COMMENT:
+        if(line[i] == '\n')
+        {
+          /// FINISH
+          if(token.size() > 0)
+          {
+            ret.push_back(token);
+            token.clear();
+          }
+          state = SL_NORMAL;
+        }
+        else
+        {
+          token += line[i];       // EAT
+        }
+        break;
+
+      default:
+        // nothing
+        break;
+    }
+    i++;
+  }
+
+  /// FINISH
+  if (fallBackNeighbours > 0)
+    token = token.substr(0, token.size() - fallBackNeighbours);
+  if(emptyEntries || token.size() > 0)
+  {
+    ret.push_back(token);
+    token.clear();
+  }
+  return(state);
+}
+
+
+/**
+ * @brief Some nice debug information about this SubString
+ */
+void SubString::debug() const
+{
+  printf("Substring-information::count=%d ::", this->strings.size());
+  for (unsigned int i = 0; i < this->strings.size(); i++)
+    printf("s%d='%s'::", i, this->strings[i].c_str());
+  printf("\n");
+}
Index: branches/heathaze/src/lib/util/substring.h
===================================================================
--- branches/heathaze/src/lib/util/substring.h	(revision 9940)
+++ branches/heathaze/src/lib/util/substring.h	(revision 9940)
@@ -0,0 +1,119 @@
+/*!
+ * @file substring.h
+ * @brief a small class to get the parts of a string separated by commas
+ *
+ * This class is also identified as a Tokenizer. It splits up one long
+ * String into multiple small ones by a designated Delimiter.
+ *
+ * Substring is Advanced, and it is possible, to split a string by ','
+ * but also removing leading and trailing spaces around the comma.
+ *
+ * @example
+ * Split the String std::string st = "1345, The new empire   , is , orxonox"
+ * is splitted with:
+ * SubString(st, ',', " \n\t")
+ * into
+ * "1345", "The new empire", "is", "orxonox"
+ * As you can see, the useless spaces around ',' were removed.
+ */
+
+#ifndef __SUBSTRING_H__
+#define __SUBSTRING_H__
+
+#include <vector>
+#include <string>
+
+
+//! A class that can load one string and split it in multipe ones
+/**
+ * SubString is a very Powerfull way to create a SubSet from a String
+ * It can be used, to Split strings append them and join them again.
+ */
+class SubString
+{
+public:
+  //! An enumerator for the State the Parser is in
+  typedef enum {
+    SL_NORMAL,            //!< Normal state
+    SL_ESCAPE,            //!< After an escape character
+    SL_SAFEMODE,          //!< In safe mode (between "" mostly).
+    SL_SAFEESCAPE,        //!< In safe mode with the internal escape character, that escapes even the savemode character.
+    SL_COMMENT,           //!< In Comment mode.
+  } SPLIT_LINE_STATE;
+
+
+public:
+  SubString();
+  SubString(const std::string& string, char delimiter = ',');
+  SubString(const std::string& string,
+            const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries=false,
+            char escapeChar ='\\', char safemode_char = '"', char comment_char = '\0');
+  SubString(unsigned int argc, const char** argv);
+  /** @brief create a Substring as a copy of another one. @param subString the SubString to copy. */
+  SubString(const SubString& subString) { *this = subString; };
+  SubString(const SubString& subString, unsigned int subSetBegin);
+  SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd);
+  ~SubString();
+
+  // operate on the SubString
+  SubString& operator=(const SubString& subString);
+  bool operator==(const SubString& subString) const;
+  bool compare(const SubString& subString) const;
+  bool compare(const SubString& subString, unsigned int length) const;
+  SubString operator+(const SubString& subString) const;
+  SubString& operator+=(const SubString& subString);
+  /** @param subString the String to append @returns appended String. @brief added for convenience */
+  SubString& append(const SubString subString) { return (*this += subString); };
+
+  /////////////////////////////////////////
+  // Split and Join the any String. ///////
+  unsigned int split(const std::string& string = "", char delimiter = ',');
+  unsigned int split(const std::string& string,
+                     const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries = false,
+                     char escapeChar ='\\', char safemode_char = '"', char comment_char = '\0');
+  std::string join(const std::string& delimiter = " ") const;
+  ////////////////////////////////////////
+
+  // retrieve a SubSet from the String
+  SubString subSet(unsigned int subSetBegin) const;
+  SubString subSet(unsigned int subSetBegin, unsigned int subSetEnd) const;
+
+  // retrieve Information from within
+  /** @returns true if the SubString is empty */
+  inline bool empty() const { return this->strings.empty(); };
+  /** @returns the count of Strings stored in this substring */
+  inline unsigned int size() const { return this->strings.size(); };
+  /** @param i the i'th String @returns the i'th string from the subset of Strings */
+  inline const std::string& operator[](unsigned int i) const { return this->strings[i]; };
+  /** @param i the i'th String @returns the i'th string from the subset of Strings */
+  inline const std::string& getString(unsigned int i) const { return (*this)[i]; };
+  /** @returns the front of the StringList. */
+  inline const std::string& front() const { return this->strings.front(); };
+  /** @returns the back of the StringList. */
+  inline const std::string& back() const { return this->strings.back(); };
+  /** @brief removes the back of the strings list. */
+  inline void pop_back() { this->strings.pop_back(); };
+
+  // the almighty algorithm.
+  static SPLIT_LINE_STATE splitLine(std::vector<std::string>& ret,
+                                    const std::string& line,
+                                    const std::string& delimiters = SubString::WhiteSpaces,
+                                    const std::string& delimiterNeighbours = "",
+                                    bool emptyEntries = false,
+                                    char escape_char = '\\',
+                                    char safemode_char = '"',
+                                    char comment_char = '\0',
+                                    SPLIT_LINE_STATE start_state = SL_NORMAL);
+  // debugging.
+  void debug() const;
+
+public:
+  static const std::string WhiteSpaces;
+  static const std::string WhiteSpacesWithComma;
+  static const SubString   NullSubString;
+
+private:
+  std::vector<std::string>  strings;                      //!< strings produced from a single string splitted in multiple strings
+};
+
+#endif /* __SUBSTRING_H__ */
Index: branches/heathaze/src/lib/util/threading.cc
===================================================================
--- branches/heathaze/src/lib/util/threading.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/threading.cc	(revision 9940)
@@ -0,0 +1,42 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "threading.h"
+
+
+
+namespace OrxThread
+{
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+// Thread::Thread()
+// {
+// }
+
+
+/**
+ * standard deconstructor
+*/
+// Thread::~Thread()
+// {
+//   // delete what has to be deleted here
+// }
+
+}
Index: branches/heathaze/src/lib/util/threading.h
===================================================================
--- branches/heathaze/src/lib/util/threading.h	(revision 9940)
+++ branches/heathaze/src/lib/util/threading.h	(revision 9940)
@@ -0,0 +1,65 @@
+/*!
+ * @file threading.h
+ * @brief Definition of Thread Classes.
+ *
+ * These are mainly Classes, that are used for wrapping around SDL_thread
+*/
+
+#ifndef _THREADING_H
+#define _THREADING_H
+
+#ifdef HAVE_SDL_H
+ #include <SDL_thread.h>
+#else
+ #include <SDL/SDL_thread.h>
+#endif
+
+namespace OrxThread
+{
+  //! A class for Wrapping Threads
+  class Thread
+  {
+  public:
+    Thread(int (*fn)(void *), void *data) { this->thread = SDL_CreateThread(fn, data); };
+    virtual ~Thread() { SDL_KillThread(this->thread); }
+    void exit ( int returnCode = 0 );
+    bool isFinished () const;
+    bool isRunning () const;
+    void wait() { SDL_WaitThread(this->thread, NULL); };
+
+    void start();
+    void terminate();
+
+
+  private:
+    SDL_Thread* thread;
+
+  };
+
+  class Mutex
+  {
+  public:
+    Mutex() {  this->mutex = SDL_CreateMutex(); };
+    ~Mutex() { SDL_DestroyMutex(this->mutex); }
+
+    void lock() { SDL_mutexP(mutex); };
+    void unlock() { SDL_mutexV(mutex); };
+
+    SDL_mutex* getMutex() const { return this->mutex; };
+  private:
+    SDL_mutex* mutex;
+  };
+
+  //! A Class that locks a Mutex within its scope
+  class MutexLock
+  {
+  public:
+    //! Locks the Mutex mutex in this Scope.
+    MutexLock(Mutex* mutex) { SDL_mutexP(mutex->getMutex()); this->mutex = mutex; };
+    ~MutexLock() { SDL_mutexV(mutex->getMutex()); };
+  private:
+    Mutex* mutex;         //!< The Mutex to lock.
+  };
+}
+
+#endif /* _THREADING_H */
Index: branches/heathaze/src/lib/util/timer.cc
===================================================================
--- branches/heathaze/src/lib/util/timer.cc	(revision 9940)
+++ branches/heathaze/src/lib/util/timer.cc	(revision 9940)
@@ -0,0 +1,47 @@
+/**
+ * @file timer.cc
+ * @brief A Timer class, that handles all about time.
+ *
+ * code borrowed from audiere. http://www.audiere.org
+ */
+
+#include "timer.h"
+
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef __WIN32__
+#include <windows.h>
+int gettimeofday
+      (struct timeval* tp, void* tzp) {
+    DWORD t;
+    t = timeGetTime();
+    tp->tv_sec = t / 1000;
+    tp->tv_usec = 1000 * (t % 1000 );
+    /* 0 indicates success. */
+    return 0;
+}
+#endif
+
+/**
+ * @returns the current time in Second exact to the micro-second
+ */
+double Timer::getNow() {
+
+#if HAVE_CLOCK_GETTIME
+
+   // use the POSIX realtime clock to get the current time
+    struct timespec tp;
+    int result = clock_gettime(CLOCK_REALTIME, &tp);
+    if (result == 0) {
+      return tp.tv_sec * tp.tv_nsec / 1000000000.0;
+    }
+#endif
+
+    // can't use realtime clock!  Try to use gettimeofday
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    return tv.tv_sec + tv.tv_usec / 1000000.0;
+}
+
Index: branches/heathaze/src/lib/util/timer.h
===================================================================
--- branches/heathaze/src/lib/util/timer.h	(revision 9940)
+++ branches/heathaze/src/lib/util/timer.h	(revision 9940)
@@ -0,0 +1,36 @@
+/*!
+ * @file timer.h
+ * @brief Definition of Time Class.
+ *
+ * Here is a Class that is for measuring time,
+ * getting the current time, and stepping through time.
+ *
+ * @todo: Implement:
+ * 1. TimeStep
+ * 2. ApproxTimer
+ * 3. Class that handles the time-stepping
+ * 4. Transformations from one time-coding into another:
+ * 5. debug of Timer.
+ */
+
+#ifndef __TIMER_H__
+#define __TIMER_H__
+
+//! A class to handle time itself
+class Timer
+{
+public:
+  Timer();
+  Timer(int time);
+
+  void debug() const;
+
+  /// STATIC PUBLIC MEMBERS
+  static double getNow();
+
+  private:
+    double         _lastTime;
+    double         _timeStep;
+};
+
+#endif /* __TIMER_H__ */
Index: branches/heathaze/src/orxonox.cc
===================================================================
--- branches/heathaze/src/orxonox.cc	(revision 9940)
+++ branches/heathaze/src/orxonox.cc	(revision 9940)
@@ -0,0 +1,578 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer: injected ResourceManager/GraphicsEngine/GUI
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ORXONOX
+#include "orxonox.h"
+
+#include "globals.h"
+
+#include "gui/qt/qt_gui.h"
+#include "gui/qt/qt_gui_datadir_fallback.h"
+
+#include "parser/ini_parser/ini_parser.h"
+#include "util/loading/game_loader.h"
+#include "util/signal_handler.h"
+
+//ENGINES
+#include "graphics_engine.h"
+#include "sound_engine.h"
+#include "util/loading/resource_manager.h"
+
+#include "cd_engine.h"
+#include "event_handler.h"
+
+#include "loading/fast_factory.h"
+
+#include "subprojects/benchmark.h"
+
+#include "shell_command_class.h"
+#include "shell_command.h"
+
+#include "network_manager.h"
+#include "shared_network_data.h"
+
+#include "state.h"
+#include "lib/parser/preferences/cmd_line_prefs_reader.h"
+#include "lib/parser/preferences/ini_file_prefs_reader.h"
+#include <string.h>
+
+int verbose = 5;
+
+
+
+SHELL_COMMAND(restart, Orxonox, restart);
+
+REGISTER_ARG_FLAG( l, license,    "misc",  "showLicenseAndExit", "Prints the license and exit",      "1" );
+REGISTER_ARG_FLAG( c, client,     "game",  "gameType",           "Connect to Server (-H)",           "multiplayer_client" );
+REGISTER_ARG_FLAG( s, server,     "game",  "gameType",           "Start Orxonox as Game Server",     "multiplayer_master_server" );
+REGISTER_ARG_FLAG( x, proxy,      "game",  "gameType",           "Start Orxonox as Proxy Server",    "multiplayer_proxy_server" );
+REGISTER_ARG_ARG(  H, host,       "game",  "host",               "Host to connect to",               "host");
+REGISTER_ARG_ARG(  p, port,       "game",  "port",               "Port to use",                      "port" );
+REGISTER_ARG_FLAG( g, gui,        "game",  "showGui",            "starts the orxonox with the configuration GUI", "1");
+
+REGISTER_ARG_FLAG( f, fullscreen, "video", "Fullscreen-mode",    "start Orxonox in fullscreen mode", "1");
+REGISTER_ARG_FLAG( w, windowed,   "video", "Fullscreen-mode",    "start Orxonox in windowed mode",   "0");
+REGISTER_ARG_ARG(  r, resolution, "video", "Resolution",         "sets resolution / window size",    "res");
+REGISTER_ARG_FLAG( d, dedicated,  "video", "Norender-mode",      "the scene is not rendered",        "1" );
+
+REGISTER_ARG_FLAG( a, audio,      "audio", "Disable-Audio",      "Enable audio",                     "0" );
+REGISTER_ARG_FLAG( m, mute ,      "audio", "Disable-Audio",      "Disable audio",                    "1" );
+REGISTER_ARG_ARG(  _, audio_channels, "audio", "Audio-Channels", "Sets # audio channels", "num" );
+REGISTER_ARG_ARG(  _, music_volume, "audio", "Music-Volume", "Sets music volume", "vol" );
+REGISTER_ARG_ARG(  _, effects_volume, "audio", "Effects-Volume", "Sets effects volume", "vol" );
+
+#ifndef __WIN32__
+REGISTER_ARG_FLAG( _, write_bt_to_file, "misc", "bt-to-file", "Write backtrace to file", "1");
+#endif
+
+REGISTER_ARG_ARG(  t, telnetport,  "network","telnetport",        "Port to use for network debug output",               "port" );
+REGISTER_ARG_ARG(  _, write_dict,  "compression", "writedict",    "write packets to DATA/dicts/newdict",               "numBytes" );
+
+ObjectListDefinition(Orxonox);
+
+/**
+ *  create a new Orxonox
+
+   In this funcitons only global values are set. The game will not be started here.
+*/
+Orxonox::Orxonox ()
+{
+  this->registerObject(this, Orxonox::_objectList);
+  this->setName("orxonox-main");
+
+  this->argc = 0;
+  this->argv = NULL;
+
+  /* this way, there is no network enabled: */
+  this->serverName = "";
+  this->port = -1;
+
+  this->configFileName = "";
+}
+
+/**
+ *  remove Orxonox from memory
+*/
+Orxonox::~Orxonox ()
+{
+  // game-specific
+  delete GameLoader::getInstance();
+
+  // class-less services/factories
+  FastFactory::deleteAll();
+  OrxShell::ShellCommandClass::unregisterAllCommands();
+
+  // handlers
+  Resources::ResourceManager::deleteInstance(); // deletes the Resource Manager
+
+  // engines
+  delete CDEngine::getInstance();
+  delete OrxSound::SoundEngine::getInstance();
+  delete GraphicsEngine::getInstance(); // deleting the Graphics
+  delete EventHandler::getInstance();
+
+  Resources::ResourceManager::deleteInstance();
+  // output-buffer
+  delete DebugBuffer::getInstance();
+
+  SDL_QuitSubSystem(SDL_INIT_TIMER);
+
+
+  ObjectListBase::debugAll(1);
+
+  Preferences::getInstance()->save();
+
+  PRINT(3)
+  (
+    "===================================================\n" \
+    "Thanks for playing orxonox.\n" \
+    "visit: http://www.orxonox.net for new versions.\n" \
+    "===================================================\n" \
+    ORXONOX_LICENSE_SHORT
+  );
+
+  Orxonox::singletonRef = NULL;
+}
+
+/**
+ *  this is a singleton class to prevent duplicates
+ */
+Orxonox* Orxonox::singletonRef = NULL;
+
+// DANGEROUS
+void Orxonox::restart()
+{
+  //   int argc = this->argc;
+  //   char** argv = this->argv;
+  //
+  //   Orxonox *orx = Orxonox::getInstance();
+  //
+  //   delete orx;
+  //
+  //   orx = Orxonox::getInstance();
+  //
+  //   if((*orx).init(argc, argv) == -1)
+  //   {
+  //     PRINTF(1)("! Orxonox initialization failed\n");
+  //     return;
+  //   }
+  //
+  //   printf("finished inizialisation\n");
+  //   orx->start();
+}
+
+/**
+ * @brief this finds the config file
+ * @returns the new config-fileName
+ * Since the config file varies from user to user and since one may want to specify different config files
+ * for certain occasions or platforms this function finds the right config file for every occasion and stores
+ * it's path and name into configfilename
+*/
+const std::string& Orxonox::getConfigFile ()
+{
+  File orxConfFile("orxonox.conf");
+  if (orxConfFile.isFile())
+  {
+    this->configFileName =  "orxonox.conf";
+  }
+  else
+    this->configFileName = File(DEFAULT_CONFIG_FILE).name();
+
+  PRINTF(3)("Parsed Config File: '%s'\n", this->configFileName.c_str());
+  return this->configFileName;
+}
+
+/**
+ * initialize Orxonox with command line
+ */
+int Orxonox::init (int argc, char** argv, const std::string & name, int port)
+{
+  this->argc = argc;
+  this->argv = argv;
+
+  this->serverName = name;
+  this->port = port;
+
+  // initialize the Config-file
+  this->getConfigFile();
+
+  // windows must not write into stdout.txt and stderr.txt
+  /*#ifdef __WIN32__
+  freopen( "CON", "w", stdout );
+  freopen( "CON", "w", stderr );
+  #endif*/
+
+  // initialize everything
+  SDL_Init(0);
+  if( initVideo() == -1)
+    return -1;
+  if( initResources () == -1)
+    return -1;
+  if( initSound() == -1)
+    return -1;
+  if( initInput() == -1)
+    return -1;
+  if( initNetworking () == -1)
+    return -1;
+  if( initMisc () == -1)
+    return -1;
+
+  return 0;
+}
+
+
+/**
+ * initializes SDL and OpenGL
+ */
+int Orxonox::initVideo()
+{
+  PRINTF(3)("> Initializing video\n");
+
+  GraphicsEngine::getInstance();
+
+  GraphicsEngine::getInstance()->initFromPreferences();
+
+  std::string iconName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath("pictures/fighter-top-32x32.bmp");
+  if (!iconName.empty())
+  {
+    GraphicsEngine::getInstance()->setWindowName(PACKAGE_NAME " " PACKAGE_VERSION, iconName);
+  }
+  return 0;
+}
+
+
+/**
+ * initializes the sound engine
+ */
+int Orxonox::initSound()
+{
+  PRINT(3)("> Initializing sound\n");
+  // SDL_InitSubSystem(SDL_INIT_AUDIO);
+  OrxSound::SoundEngine::getInstance();
+
+  OrxSound::SoundEngine::getInstance()->loadSettings();
+  OrxSound::SoundEngine::getInstance()->initAudio();
+  return 0;
+}
+
+
+/**
+ * initializes input functions
+ */
+int Orxonox::initInput()
+{
+  PRINT(3)("> Initializing input\n");
+
+  EventHandler::getInstance()->init();
+  EventHandler::getInstance()->subscribe(GraphicsEngine::getInstance(), ES_ALL, EV_VIDEO_RESIZE);
+
+  return 0;
+}
+
+
+/**
+ * initializes network system
+ */
+int Orxonox::initNetworking()
+{
+  PRINT(3)("> Initializing networking\n");
+  std::string gameType = Preferences::getInstance()->getString( "game", "gameType", "" );
+
+  if( gameType == "multiplayer_client")
+  {    // we are a client
+    State::setOnline(true);
+    SharedNetworkData::getInstance()->setNodeType(NET_CLIENT);
+    NetworkManager::getInstance()->createClient(this->serverName, port);
+  }
+  else if( gameType == "multiplayer_master_server")
+  {    // we are a master server
+    State::setOnline(true);
+    SharedNetworkData::getInstance()->setNodeType(NET_MASTER_SERVER);
+
+    NetworkManager::getInstance()->createMasterServer(port);
+  }
+  else if( gameType == "multiplayer_proxy_server")
+  {    // we are a proxy server
+    State::setOnline(true);
+    SharedNetworkData::getInstance()->setNodeType(NET_PROXY_SERVER_ACTIVE);
+    NetworkManager::getInstance()->createProxyServer(port);
+  }
+
+  return 0;
+
+}
+
+//#include "util/loading/dynamic_loader.h"
+/**
+ * initializes and loads resource files
+ */
+int Orxonox::initResources()
+{
+  PRINTF(3)("> Initializing resources\n");
+
+  PRINT(3)("initializing ResourceManager\n");
+
+  // init the resource manager
+  std::string dataPath = Preferences::getInstance()->getString(CONFIG_SECTION_GENERAL, CONFIG_NAME_DATADIR, "");
+  if (dataPath!= "")
+  {
+    Resources::ResourceManager::getInstance()->setMainGlobalPath(dataPath) ;
+    if(!Resources::ResourceManager::getInstance()->checkFileInMainPath(File(DEFAULT_DATA_DIR_CHECKFILE)))
+    {
+      PRINTF(1)("Data Could not be located in %s\n", dataPath.c_str());
+    }
+  }
+  while (!Resources::ResourceManager::getInstance()->checkFileInMainPath(File(DEFAULT_DATA_DIR_CHECKFILE)))
+  {
+
+    PRINTF(1)("The DataDirectory %s could not be verified\n\nh" \
+              "!!!  Please Change in File %s Section %s Entry %s to a suitable value !!!\n",
+              Resources::ResourceManager::getInstance()->mainGlobalPath().name().c_str(),
+              this->configFileName.c_str(),
+              CONFIG_SECTION_GENERAL,
+              CONFIG_NAME_DATADIR );
+    OrxGui::Gui* gui = new OrxGui::QtGuiDataDirFallback(argc, argv);
+    gui->startGui();
+    if (gui->getState() == OrxGui::Gui::Quitting)
+      return(-1);
+    delete gui;
+    Resources::ResourceManager::getInstance()->setMainGlobalPath(Preferences::getInstance()->getString(CONFIG_SECTION_GENERAL, CONFIG_NAME_DATADIR, ""));
+  }
+
+  //! @todo this is a hack and should be loadable
+  Resources::ResourceManager::getInstance()->addResourceSubPath("Texture", "maps");
+  Resources::ResourceManager::getInstance()->addResourceSubPath("Texture", "pictures");
+
+  Resources::ResourceManager::getInstance()->addResourceSubPath("SoundBuffer", "sound");
+  Resources::ResourceManager::getInstance()->addResourceSubPath("SoundBuffer", "music");
+
+  Resources::ResourceManager::getInstance()->addResourceSubPath("Shader", "shaders");
+  Resources::ResourceManager::getInstance()->addResourceSubPath("OBJ", "models");
+
+  Resources::ResourceManager::getInstance()->addKeepLevelName("Imediately");
+  Resources::ResourceManager::getInstance()->addKeepLevelName("LevelEnd");
+  Resources::ResourceManager::getInstance()->addKeepLevelName("CampaignEnd");
+  Resources::ResourceManager::getInstance()->addKeepLevelName("GameEnd");
+  Resources::ResourceManager::getInstance()->setDefaultKeepLevel(std::string("GameEnd"));
+
+  return 0;
+}
+
+/**
+ * initializes miscelaneous features
+ * @return -1 on failure
+ */
+int Orxonox::initMisc()
+{
+  DebugBuffer::getInstance();
+
+  // start the collision detection engine
+  CDEngine::getInstance();
+
+  return 0;
+}
+
+/**
+ *  starts the orxonox game or menu
+ * here is the central orxonox state manager. There are currently two states
+ * - menu
+ * - game-play
+ * both states manage their states themselfs again.
+*/
+void Orxonox::start()
+{
+
+  this->gameLoader = GameLoader::getInstance();
+
+  if( this->port != -1)
+    this->gameLoader->loadNetworkCampaign("worlds/DefaultNetworkCampaign.oxc");
+  else
+    this->gameLoader->loadCampaign("worlds/DefaultCampaign.oxc");                       /* start orxonox in single player mode */
+
+  //  this->gameLoader->loadDebugCampaign(DEBUG_CAMPAIGN_0);
+  this->gameLoader->init();
+  this->gameLoader->start();
+}
+
+
+/**
+ * handles sprecial events from localinput
+ * @param event: an event not handled by the CommandNode
+ */
+// void Orxonox::graphicsHandler(SDL_Event* event)
+// {
+//   // Handle special events such as reshape, quit, focus changes
+//   switch (event->type)
+//     {
+//     case SDL_VIDEORESIZE:
+//       GraphicsEngine* tmpGEngine = GraphicsEngine::getInstance();
+//       tmpGEngine->resolutionChanged(event->resize);
+//       break;
+//     }
+// }
+
+
+
+
+
+
+bool showGui = false;
+
+/**********************************
+*** ORXONOX MAIN STARTING POINT ***
+**********************************/
+/**
+ *
+ *  main function
+ *
+ * here the journey begins
+*/
+int main(int argc, char** argv)
+{
+  CmdLinePrefsReader prefs;
+
+  IniFilePrefsReader ini(File(DEFAULT_CONFIG_FILE).name());
+  Preferences::getInstance()->setUserIni(File(DEFAULT_CONFIG_FILE).name());
+
+  prefs.parse(argc, argv);
+
+  if ( Preferences::getInstance()->getString("misc", "showLicenseAndExit", "") == "1" )
+  {
+    PRINT(0)(ORXONOX_LICENSE_SHORT);
+    return 0;
+  }
+
+  if ( Preferences::getInstance()->getString("misc", "bt-to-file", "1") == "1" )
+  {
+    SignalHandler::getInstance()->doCatch( argv[0], "orxonox.backtrace" );
+    SignalHandler::getInstance()->registerCallback( EventHandler::releaseMouse, NULL );
+  }
+
+  if( Preferences::getInstance()->getString("game", "showGui", "") == "1" )
+    showGui = true;
+  else if( Preferences::getInstance()->getString( "game", "gameType", "" ) == "multiplayer_master_server" ||
+           Preferences::getInstance()->getString( "game", "gameType", "" ) == "multiplayer_proxy_server" ||
+           Preferences::getInstance()->getString( "game", "gameType", "" ) == "multiplayer_client" )
+    return startNetworkOrxonox(argc, argv);
+
+  return startOrxonox(argc, argv, "", -1);
+}
+
+
+
+/**
+ * starts orxonox in network mode
+ * @param argc parameters count given to orxonox
+ * @param argv parameters given to orxonox
+ */
+int startNetworkOrxonox(int argc, char** argv)
+{
+
+  std::string gameType = Preferences::getInstance()->getString( "game", "gameType", "" );
+
+  if ( gameType == "multiplayer_client" )
+  {
+    int port = Preferences::getInstance()->getInt( "game", "port", DEFAULT_ORXONOX_PORT );
+    std::string host = Preferences::getInstance()->getString( "game", "host", "" );
+
+    if ( host == "" )
+    {
+      printf("You need to specify a host to connect to ( -H <host> )\n");
+      return 1;
+    }
+
+    printf("Starting Orxonox as client: connecting to %s, on port %i\n", host.c_str(), port);
+
+    startOrxonox(argc, argv, host.c_str(), port);
+  }
+  else if ( gameType == "multiplayer_master_server" )
+  {
+    int port = Preferences::getInstance()->getInt( "game", "port", DEFAULT_ORXONOX_PORT );
+
+    printf("Starting Orxonox as server: listening on port %i\n", port);
+
+    startOrxonox(argc, argv, "", port);
+  }
+  else if ( gameType == "multiplayer_proxy_server" )
+  {
+    int port = Preferences::getInstance()->getInt( "game", "port", DEFAULT_ORXONOX_PORT );
+
+    printf("Starting Orxonox as proxy server: listening on port %i\n", port);
+
+    startOrxonox(argc, argv, "", port);
+  }
+  return 1;
+}
+
+
+
+/**
+ * starts orxonox
+ * @param argc parameters count given to orxonox
+ * @param argv parameters given to orxonox
+ */
+int startOrxonox(int argc, char** argv, const std::string & name, int port)
+{
+  // checking for existence of the configuration-files, or if the lock file is still used
+  if (showGui || (!File("./orxonox.conf").isFile() &&
+                  !File(DEFAULT_CONFIG_FILE).isFile())
+#if DEBUG_LEVEL <= 3 // developers do not need to see the GUI, when orxonox fails
+      || ResourceManager::isFile(DEFAULT_LOCK_FILE)
+#endif
+     )
+  {
+    File lockFile(DEFAULT_LOCK_FILE);
+    if (lockFile.isFile())
+      lockFile.remove();
+
+    // starting the GUI
+    OrxGui::QtGui gui(argc, argv);
+    gui.startGui();
+
+    if (gui.getState() & OrxGui::Gui::Quitting)
+      return 0;
+
+  }
+
+  PRINT(0)(">>> Starting Orxonox <<<\n");
+
+  File(DEFAULT_LOCK_FILE).touch();
+
+  Orxonox *orx = Orxonox::getInstance();
+
+  if( orx->init(argc, argv, name, port) == -1)
+  {
+    PRINTF(1)("! Orxonox initialization failed\n");
+    return -1;
+  }
+
+  PRINTF(5)("finished inizialisation\n");
+  orx->start();
+
+  delete orx;
+  File("~/.orxonox/orxonox.lock").remove();
+  return 0;
+}
Index: branches/heathaze/src/orxonox.h
===================================================================
--- branches/heathaze/src/orxonox.h	(revision 9940)
+++ branches/heathaze/src/orxonox.h	(revision 9940)
@@ -0,0 +1,65 @@
+/*!
+ * @file orxonox.h
+ * Orxonox core functions
+*/
+
+#ifndef _ORXONOX_H
+#define _ORXONOX_H
+
+#include "base_object.h"
+
+class WorldEntity;
+class GameLoader;
+
+//! orxonox core singleton class
+/**
+*/
+class Orxonox : public BaseObject {
+  ObjectListDeclaration(Orxonox);
+
+ public:
+  virtual ~Orxonox ();
+  /** @returns a Pointer to the only object of this Class */
+  inline static Orxonox* getInstance() { if (!singletonRef) singletonRef = new Orxonox();  return singletonRef; };
+
+  int init(int argc, char** argv, const std::string & name, int port);
+
+  void restart();
+
+  void start();
+
+ private:
+  Orxonox ();
+
+  int initResources ();
+  int initVideo ();
+  int initSound ();
+  int initInput ();
+  int initNetworking ();
+  int initMisc ();
+
+  const std::string& getConfigFile ();
+
+ private:
+  static Orxonox*   singletonRef;            //!< singleton reference to orxonox
+
+  std::string       configFileName;          //!< Filename of the configuration-file.
+  GameLoader*       gameLoader;              //!< The gameLoader
+
+  unsigned int      argc;                    //!< Count of Arguments of orxonox
+  char**            argv;                    //!< Values of th Arguments of orxonox.
+
+  std::string       serverName;              //!< Name of the Orxonox client if == "" -> server
+  int               port;                    //!< number of the network port of the server/client if == -1 no network
+};
+
+
+////////////////////////
+// Start-up functions //
+////////////////////////
+
+int startNetworkOrxonox(int argc, char** argv);
+int startOrxonox(int argc, char** argv, const std::string & clientName, int port);
+
+#endif /* _ORXONOX_H */
+
Index: branches/heathaze/src/proto/proto_class.cc
===================================================================
--- branches/heathaze/src/proto/proto_class.cc	(revision 9940)
+++ branches/heathaze/src/proto/proto_class.cc	(revision 9940)
@@ -0,0 +1,50 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "proto_class.h"
+ObjectListDefinition(ProtoClass);
+
+
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+ProtoClass::ProtoClass ()
+{
+  this->registerObject(this, ProtoClass::_objectList);
+
+   /* If you make a new class, what is most probably the case when you write this file
+      don't forget to:
+       1. Add the new file new_class.cc to the ./src/Makefile.am
+
+      Advanced Topics:
+      - if you want to let your object be managed via the ObjectManager make sure to read
+        the object_manager.h header comments. You will use this most certanly only if you
+        make many objects of your class, like a weapon bullet.
+   */
+}
+
+
+/**
+ * standard deconstructor
+*/
+ProtoClass::~ProtoClass ()
+{
+  // delete what has to be deleted here
+}
Index: branches/heathaze/src/proto/proto_class.h
===================================================================
--- branches/heathaze/src/proto/proto_class.h	(revision 9940)
+++ branches/heathaze/src/proto/proto_class.h	(revision 9940)
@@ -0,0 +1,27 @@
+/*!
+ * @file proto_class.h
+ * @brief Definition of ...
+*/
+
+#ifndef _PROTO_CLASS_H
+#define _PROTO_CLASS_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+
+
+//! A class for ...
+class ProtoClass : public BaseObject {
+  ObjectListDeclaration(ProtoClass);
+ public:
+  ProtoClass();
+  virtual ~ProtoClass();
+
+
+ private:
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: branches/heathaze/src/proto/proto_singleton.cc
===================================================================
--- branches/heathaze/src/proto/proto_singleton.cc	(revision 9940)
+++ branches/heathaze/src/proto/proto_singleton.cc	(revision 9940)
@@ -0,0 +1,41 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "proto_singleton.h"
+ObjectListDefinition(ProtoSingleton);
+
+/**
+ * standard constructor
+ */
+ProtoSingleton::ProtoSingleton ()
+{
+  this->registerObject(this, ProtoSingleton::_objectList);
+  this->setName("ProtoSingleton");
+}
+
+/**
+ *  the singleton reference to this class
+ */
+ProtoSingleton* ProtoSingleton::singletonRef = NULL;
+
+/**
+   @brief standard deconstructor
+ */
+ProtoSingleton::~ProtoSingleton ()
+{
+  ProtoSingleton::singletonRef = NULL;
+}
Index: branches/heathaze/src/proto/proto_singleton.h
===================================================================
--- branches/heathaze/src/proto/proto_singleton.h	(revision 9940)
+++ branches/heathaze/src/proto/proto_singleton.h	(revision 9940)
@@ -0,0 +1,28 @@
+/*!
+ * @file proto_singleton.h
+ * @brief Definition of the ... singleton Class
+*/
+
+#ifndef _PROTO_SINGLETON_H
+#define _PROTO_SINGLETON_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+//! A default singleton class.
+class ProtoSingleton : public BaseObject {
+  ObjectListDeclaration(ProtoSingleton);
+
+
+ public:
+  virtual ~ProtoSingleton(void);
+  /** @returns a Pointer to the only object of this Class */
+  inline static ProtoSingleton* getInstance(void) { if (!singletonRef) singletonRef = new ProtoSingleton();  return singletonRef; };
+
+ private:
+  ProtoSingleton(void);
+  static ProtoSingleton* singletonRef;
+};
+
+#endif /* _PROTO_SINGLETON_H */
Index: branches/heathaze/src/proto/proto_world_entity.cc
===================================================================
--- branches/heathaze/src/proto/proto_world_entity.cc	(revision 9940)
+++ branches/heathaze/src/proto/proto_world_entity.cc	(revision 9940)
@@ -0,0 +1,113 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+#include "proto_world_entity.h"
+
+
+
+
+/**
+ * constructs and loads a ProtoWorldEntity from a XML-element
+ * @param root the XML-element to load from
+ */
+ProtoWorldEntity::ProtoWorldEntity(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * standard deconstructor
+ */
+ProtoWorldEntity::~ProtoWorldEntity ()
+{
+
+}
+
+
+/**
+ * initializes the ProtoWorldEntity
+ * @todo change this to what you wish
+ */
+void ProtoWorldEntity::init()
+{
+  this->setClassID(CL_PROTO_WORLD_ENTITY, "ProtoWorldEntity");
+
+  /**
+   * @todo: Write CL_PROTO_WORLD_ENTITY INTO THE src/defs/class_id.h (your own definition)
+   */
+
+}
+
+
+/**
+ * loads a ProtoWorldEntity from a XML-element
+ * @param root the XML-element to load from
+ * @todo make the class Loadable
+ */
+void ProtoWorldEntity::loadParams(const TiXmlElement* root)
+{
+  // all the clases this Entity is directly derived from must be called in this way, to load all settings.
+  WorldEntity::loadParam(root);
+
+
+  /**
+   * @todo: make the class Loadable
+   */
+}
+
+
+/**
+ * advances the ProtoWorldEntity about time seconds
+ * @param time the Time to step
+ */
+ProtoWorldEntity::tick(float time)
+{
+
+}
+
+/**
+ * draws this worldEntity
+ */
+void ProtoWorldEntity::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  float matrix[4][4];
+
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  /* rotate */
+  this->getAbsDir().matrix(matrix);
+  glMultMatrixf((float*)matrix);
+
+  if (model)
+    model->draw();
+  glPopMatrix();
+}
+
+
+/**
+ *
+ *
+ */
+void ProtoWorldEntity::collidesWith (WorldEntity* entity, const Vector& location)
+{
+
+}
Index: branches/heathaze/src/proto/proto_world_entity.h
===================================================================
--- branches/heathaze/src/proto/proto_world_entity.h	(revision 9940)
+++ branches/heathaze/src/proto/proto_world_entity.h	(revision 9940)
@@ -0,0 +1,34 @@
+/*!
+ * @file proto_world_entity.h
+ * @brief description
+*/
+
+#ifndef _PROTO_WORLD_ENTITY_H
+#define _PROTO_WORLD_ENTITY_H
+
+#include "world_entity.h"
+
+//! A Class to ...
+class ProtoWorldEntity : public WorldEntity
+{
+
+ public:
+  ProtoWorldEntity(const TiXmlElement* root = NULL);
+  virtual ~ProtoWorldEntity();
+
+  virtual void loadParams(const TiXmlElement* root);
+  void init();
+
+  virtual void postSpawn ();
+  virtual void leftWorld ();
+
+
+  virtual void draw() const;
+  virtual void tick(float time);
+  virtual void collidesWith (WorldEntity* entity, const Vector& location);
+
+ private:
+
+};
+
+#endif /* _PROTO_WORLD_ENTITY_H */
Index: branches/heathaze/src/story_entities/Makefile.am
===================================================================
--- branches/heathaze/src/story_entities/Makefile.am	(revision 9940)
+++ branches/heathaze/src/story_entities/Makefile.am	(revision 9940)
@@ -0,0 +1,34 @@
+#MAINSRCDIR=..
+#include $(MAINSRCDIR)/defs/include_paths.am
+
+StoryEntities_SOURCES_ = \
+		story_entities/story_entity.cc \
+		story_entities/campaign.cc \
+		story_entities/campaign_data.cc \
+		story_entities/game_world.cc \
+		story_entities/game_world_data.cc \
+		story_entities/single_player_world.cc \
+		story_entities/single_player_world_data.cc \
+		story_entities/multi_player_world.cc \
+		story_entities/multi_player_world_data.cc \
+		story_entities/movie_loader.cc \
+		\
+		story_entities/menu/game_menu.cc \
+		story_entities/menu/glgui_imagebutton.cc
+
+StoryEntities_HEADERS_ = \
+		story_entities/story_entity.h \
+		story_entities/story_def.h \
+		story_entities/campaign.h \
+		story_entities/campaign_data.h \
+		story_entities/game_world.h \
+		story_entities/game_world_data.h \
+		story_entities/single_player_world.h \
+		story_entities/single_player_world_data.h \
+		story_entities/multi_player_world.h \
+		story_entities/multi_player_world_data.h \
+		story_entities/movie_loader.h \
+		\
+		story_entities/menu/game_menu.h \
+		story_entities/menu/glgui_imagebutton.h
+
Index: branches/heathaze/src/story_entities/campaign.cc
===================================================================
--- branches/heathaze/src/story_entities/campaign.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/campaign.cc	(revision 9940)
@@ -0,0 +1,170 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_STORY_ENTITY
+
+#include "campaign.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+#include "state.h"
+
+#include "campaign_data.h"
+#include "debug.h"
+
+
+
+ObjectListDefinition(Campaign);
+
+/**
+ *  the constructor
+ * @param root the XML root element
+ *
+ * this constructor is always called in a XML context (loading procedure)
+ */
+Campaign::Campaign ( TiXmlElement* root)
+{
+  this->registerObject(this, Campaign::_objectList);
+
+  PRINTF(4)("Loading Campaign...\n");
+  assert( root != NULL);
+
+  this->bReturnToMenu = false;
+
+  this->campaignData = new CampaignData(root);
+  this->loadParams(root);
+
+}
+
+
+/**
+ * the campaign destructor
+ */
+Campaign::~Campaign ()
+{
+  if( this->campaignData)
+    delete this->campaignData;
+}
+
+
+/**
+ *  loads the Parameters of a Campaign
+ * @param root: The XML-element to load from
+ */
+void Campaign::loadParams(const TiXmlElement* root)
+{
+  StoryEntity::loadParams(root);
+
+  PRINTF(4)("Loaded Campaign specific stuff\n");
+}
+
+
+/**
+ *  starts the campaing with a specific ID
+ * @param storyID the id of the StoryEntity
+ */
+bool Campaign::start()
+{
+  PRINTF(2)("Starting Campaign nr. %i\n", this->getStoryID());
+
+  this->bRunning = true;
+  this->bReturnToMenu = false;
+  this->run();
+
+  return true;
+}
+
+
+/**
+ *  pauses the campaign
+ */
+bool Campaign::pause()
+{
+  return (this->bPaused = true);
+}
+
+
+/**
+ *  resumes the campaign after a pause
+ */
+bool Campaign::resume()
+{
+  PRINTF(4)("Resuming the current Campaign\n");
+  return (this->bPaused = false);
+}
+
+
+/**
+ *  stops the campaign
+ */
+bool Campaign::stop()
+{
+  PRINTF(4)("Stopping the current Campaign\n");
+  if( State::getMenuID() != -1)
+    this->bReturnToMenu = true;
+  else
+    this->bRunning = false;  // fast exit
+  if( this->currentEntity != NULL)
+  {
+    this->currentEntity->stop();
+  }
+
+  return true;
+}
+
+
+/**
+ *  runs the campaign
+ */
+void Campaign::run()
+{
+  ErrorMessage       errorCode;
+//  int                storyID = WORLD_ID_0;
+
+  for( this->currentEntity = this->campaignData->getFirstLevel(), this->bRunning = true;
+       this->currentEntity != NULL && this->bRunning;
+       this->currentEntity = this->campaignData->getNextLevel())
+  {
+    PRINTF(0)("Campaign is starting StoryEntity nr:%i\n", this->currentEntity->getStoryID());
+
+    // check if return to menu
+    if( this->bReturnToMenu)
+    {
+      this->currentEntity = this->campaignData->getLevel(WORLD_ID_MENU);
+      this->bReturnToMenu = false;
+    }
+
+    this->campaignData->setCurrentEntity(this->currentEntity);
+
+    this->currentEntity->init();
+    this->currentEntity->loadData();
+    this->currentEntity->start();
+    this->currentEntity->unloadData();
+  }
+  PRINTF(2)("There is no StoryEnity left to play, quitting game\n");
+}
+
+
+/**
+ *  this changes to the next level
+ */
+void Campaign::switchToNextLevel()
+{
+  PRINTF(4)("Switching to the next StoryEntity\n");
+  this->currentEntity->stop();
+}
+
+
Index: branches/heathaze/src/story_entities/campaign.h
===================================================================
--- branches/heathaze/src/story_entities/campaign.h	(revision 9940)
+++ branches/heathaze/src/story_entities/campaign.h	(revision 9940)
@@ -0,0 +1,43 @@
+/*!
+ * @file campaign.h
+ * definition of the campaign
+ */
+
+#ifndef _CAMPAIGN_H
+#define _CAMPAIGN_H
+
+
+#include "story_entity.h"
+
+
+class TiXmlElement;
+class CampaignData;
+
+
+//! A class that represents a game Campaign that contains other StoryEntities like GameWorlds, movies, etc.
+class Campaign : public StoryEntity
+{
+  ObjectListDeclaration(Campaign);
+  public:
+    Campaign( TiXmlElement* root);
+    virtual ~Campaign ();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual bool start();
+    virtual bool stop();
+    virtual bool pause();
+    virtual bool resume();
+    virtual void run();
+
+    void switchToNextLevel();
+
+
+  private:
+    StoryEntity*                        currentEntity;          //!< reference to the current StoryEntity
+    CampaignData*                       campaignData;           //!< reference to the CampaignData
+
+    bool                                bReturnToMenu;          //!< is true, if the StoryEntity should return to the Mainmenu after termination
+};
+
+#endif /* _CAMPAIGN_H */
Index: branches/heathaze/src/story_entities/campaign_data.cc
===================================================================
--- branches/heathaze/src/story_entities/campaign_data.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/campaign_data.cc	(revision 9940)
@@ -0,0 +1,157 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_STORY_ENTITY
+
+#include "campaign_data.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param_xml.h"
+
+#include "story_entity.h"
+
+#include "debug.h"
+
+
+
+ObjectListDefinition(CampaignData);
+
+/**
+ * constructor for CampaignData
+ */
+CampaignData::CampaignData(const TiXmlElement* root)
+{
+  this->registerObject(this, CampaignData::_objectList);
+
+  this->currentEntity = NULL;
+
+  this->loadParams(root);
+}
+
+
+/**
+ * destructor for CampaignData
+ */
+CampaignData::~CampaignData()
+{
+  PRINTF(4)("Deleting CampaignData\n");
+  while( !this->storyEntities.empty())
+  {
+    StoryEntity* bo = this->storyEntities.back();
+    this->storyEntities.pop_back();
+    PRINTF(4)("CampaignData is been deleted: nr %i\n", bo->getStoryID());
+    delete bo;
+  }
+}
+
+
+/**
+ * @brief loads the Parameters of a Campaign
+ * @param root: The XML-element to load from
+ */
+void CampaignData::loadParams(const TiXmlElement* root)
+{
+  LoadParamXML(root, "WorldList", this, CampaignData, loadDataDyn)
+      .describe("A List of Worlds to be loaded in this Campaign");
+}
+
+
+/**
+ * @brief loads a WorldList
+ * @param root: the XML-element to load from
+ */
+void CampaignData::loadDataDyn(const TiXmlElement* root)
+{
+  if( root == NULL)
+    return;
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    StoryEntity* created = dynamic_cast<StoryEntity*>(Factory::fabricate(element));
+    if( created != NULL)
+      this->addStoryEntity(created);
+    PRINTF(4)("Created a new StoryEntity and added it to the Campaign: id=%i\n", created->getStoryID());
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+
+/**
+ *  add the StoryEntity to the campaign data tank
+ * @param se the StoryEntity to add
+ */
+void CampaignData::addStoryEntity(StoryEntity* se)
+{
+  this->storyEntities.push_back(se);
+}
+
+
+/**
+ *  switch to the next level in the list and return it
+ */
+StoryEntity* CampaignData::getFirstLevel()
+{
+  int                            nextStoryID;
+  int                            storyID;
+  std::list<StoryEntity*>::iterator   it;
+
+  nextStoryID = 0;
+  this->currentEntity = NULL;
+  for( it = this->storyEntities.begin(); it != this->storyEntities.end(); it++)
+  {
+    storyID = (*it)->getStoryID();
+    if( storyID == nextStoryID)
+      this->currentEntity = (*it);
+  }
+  return this->currentEntity;
+}
+
+
+/**
+ *  switch to the next level in the list and return it
+ */
+StoryEntity* CampaignData::getNextLevel()
+{
+  int                            nextStoryID;
+  int                            storyID;
+  std::list<StoryEntity*>::iterator   it;
+
+  nextStoryID = this->currentEntity->getNextStoryID();
+  this->currentEntity = NULL;
+  for( it = this->storyEntities.begin(); it != this->storyEntities.end(); it++)
+  {
+    storyID = (*it)->getStoryID();
+    if( storyID == nextStoryID)
+      this->currentEntity = (*it);
+  }
+  return this->currentEntity;
+}
+
+
+
+/**
+ * @param storyID the story ID to look for
+ * @returns a pointer to a StoryEntity with the storyID
+ */
+StoryEntity* CampaignData::getLevel(int storyID)
+{
+  std::list<StoryEntity*>::iterator   it;
+  for( it = this->storyEntities.begin(); it != this->storyEntities.end(); it++)
+  {
+    if( storyID == (*it)->getStoryID())
+      return (*it);
+  }
+  return NULL;
+}
+
Index: branches/heathaze/src/story_entities/campaign_data.h
===================================================================
--- branches/heathaze/src/story_entities/campaign_data.h	(revision 9940)
+++ branches/heathaze/src/story_entities/campaign_data.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file campaign_data.h
+ * definition of the campaign data tank
+ */
+
+#ifndef _CAMPAIGN_DATA_H
+#define _CAMPAIGN_DATA_H
+
+
+#include "data_tank.h"
+#include <list>
+
+class StoryEntity;
+
+//! A class that contains the data of the Campaign object
+class CampaignData : public DataTank
+{
+  ObjectListDeclaration(CampaignData);
+
+public:
+  CampaignData(const TiXmlElement* root);
+  virtual ~CampaignData();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void addStoryEntity(StoryEntity* se);
+
+  StoryEntity* getFirstLevel();
+  StoryEntity* getNextLevel();
+  StoryEntity* getLevel(int storyID);
+
+  /** @param storyEntity the current entity to be set */
+  inline void setCurrentEntity(StoryEntity* storyEntity) { this->currentEntity = storyEntity; }
+  /** @return the current StoryEntity played*/
+  inline StoryEntity* getCurrentEntity() { return this->currentEntity; }
+
+private:
+  void loadDataDyn(const TiXmlElement* root);
+
+private:
+  StoryEntity*                  currentEntity;                //!< reference to the currently used StoryEntity
+  std::list<StoryEntity*>       storyEntities;                //!< list of story entities
+};
+
+
+#endif /* _CAMPAIGN_DATA_H */
+
Index: branches/heathaze/src/story_entities/dedicated_server_world.cc
===================================================================
--- branches/heathaze/src/story_entities/dedicated_server_world.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/dedicated_server_world.cc	(revision 9940)
@@ -0,0 +1,69 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+#include "dedicated_server_world.h"
+
+#include "state.h"
+#include "class_list.h"
+
+#include "util/loading/load_param.h"
+#include "loading/fast_factory.h"
+#include "util/loading/factory.h"
+
+#include "world_entity.h"
+#include "npcs/npc_test1.h"
+
+
+
+
+//! This creates a Factory to fabricate a DedicatedServerWorld
+CREATE_FACTORY(DedicatedServerWorld, CL_DEDICATED_SERVER_WORLD);
+
+
+
+DedicatedServerWorld::DedicatedServerWorld(const TiXmlElement* root)
+  : GameWorld(root)
+{
+  this->setClassID(CL_DEDICATED_SERVER_WORLD, "DedicatedServerWorld");
+  this->setName("DedicatedServerWorld uninitialized");
+
+  this->loadParams(root);
+}
+
+
+/**
+ *  remove the DedicatedServerWorld from memory
+ *
+ *  delete everything explicitly, that isn't contained in the parenting tree!
+ *  things contained in the tree are deleted automaticaly
+ */
+DedicatedServerWorld::~DedicatedServerWorld ()
+{
+  PRINTF(3)("DedicatedServerWorld::~DedicatedServerWorld() - deleting current world\n");
+}
+
+
+/**
+ * loads the parameters of a DedicatedServerWorld from an XML-element
+ * @param root the XML-element to load from
+ */
+void DedicatedServerWorld::loadParams(const TiXmlElement* root)
+{
+  GameWorld::loadParams(root);
+
+  PRINTF(4)("Loaded DedicatedServerWorld specific stuff\n");
+}
+
Index: branches/heathaze/src/story_entities/dedicated_server_world.h
===================================================================
--- branches/heathaze/src/story_entities/dedicated_server_world.h	(revision 9940)
+++ branches/heathaze/src/story_entities/dedicated_server_world.h	(revision 9940)
@@ -0,0 +1,33 @@
+/*!
+ * @file dedicated_server_world.h
+ *  Holds and manages all dedicated server data
+ */
+
+#ifndef _DEDICATED_SERVER_WORLD_H
+#define _DEDICATED_SERVER_WORLD_H
+
+#include "game_world.h"
+
+
+class TiXmlElement;
+
+
+//! The game world
+/**
+ *  this class initializes everything that should be displayed inside of the current level.
+ *  it is the main driving factor during gameplay.
+ */
+class DedicatedServerWorld : public GameWorld
+{
+
+  public:
+    DedicatedServerWorld (const TiXmlElement* root = NULL);
+    virtual ~DedicatedServerWorld ();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+  private:
+
+};
+
+#endif /* _DEDICATED_SERVER_WORLD_H */
Index: branches/heathaze/src/story_entities/game_world.cc
===================================================================
--- branches/heathaze/src/story_entities/game_world.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/game_world.cc	(revision 9940)
@@ -0,0 +1,727 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+#include "game_world.h"
+#include "game_world_data.h"
+
+#include "state.h"
+
+#include "util/loading/game_loader.h"
+#include "util/timer.h"
+
+#include "player.h"
+#include "camera.h"
+#include "environment.h"
+#include "terrain.h"
+#include "test_entity.h"
+#include "terrain.h"
+#include "playable.h"
+#include "environments/mapped_water.h"
+
+#include "light.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param_xml.h"
+#include "loading/fast_factory.h"
+#include "shell_command.h"
+
+#include "graphics_engine.h"
+#include "weather_effects/atmospheric_engine.h"
+#include "event_handler.h"
+#include "sound_engine.h"
+#include "cd_engine.h"
+#include "network_manager.h"
+#include "physics_engine.h"
+
+#include "glmenu_imagescreen.h"
+#include "shell.h"
+
+#include "ogg_player.h"
+#include "shader.h"
+
+#include "animation_player.h"
+
+#include "game_rules.h"
+
+#include "script_class.h"
+ObjectListDefinition(GameWorld);
+CREATE_SCRIPTABLE_CLASS(GameWorld,
+			addMethod("setPlaymode", Executor1<GameWorld, lua_State*,const std::string&>(&GameWorld::setPlaymode))
+                        ->addMethod("setSoundtrack", Executor1<GameWorld, lua_State*, const std::string&>(&GameWorld::setSoundtrack))
+                       );
+
+SHELL_COMMAND(speed, GameWorld, setSpeed) ->describe("set the Speed of the Level");
+SHELL_COMMAND(playmode, GameWorld, setPlaymode)
+->describe("Set the Playmode of the current Level")
+->completionPlugin(0, OrxShell::CompletorStringArray(Playable::playmodeNames, Playable::PlaymodeCount));
+
+SHELL_COMMAND(togglePNodeVisibility, GameWorld, togglePNodeVisibility);
+SHELL_COMMAND(showBVLevel, GameWorld, toggleBVVisibility);
+
+
+GameWorld::GameWorld()
+    : StoryEntity()
+{
+  this->registerObject(this, GameWorld::_objectList);
+  this->setName("Preloaded World - no name yet");
+
+  this->gameTime = 0.0f;
+  this->setSpeed(1.0f);
+  this->shell = NULL;
+
+  this->showPNodes = false;
+  this->showBV = false;
+  this->showBVLevel = 3;
+
+  this->dataXML = NULL;
+  this->gameRules = NULL;
+}
+
+/**
+ *  remove the GameWorld from memory
+ *
+ *  delete everything explicitly, that isn't contained in the parenting tree!
+ *  things contained in the tree are deleted automaticaly
+ */
+GameWorld::~GameWorld ()
+{
+  PRINTF(4)("Deleted GameWorld\n");
+
+}
+
+
+
+/**
+ * loads the parameters of a GameWorld from an XML-element
+ * @param root the XML-element to load from
+ */
+void GameWorld::loadParams(const TiXmlElement* root)
+{
+  StoryEntity::loadParams(root);
+
+  PRINTF(4)("Loaded GameWorld specific stuff\n");
+}
+
+
+/**
+ * this is executed just before load
+ *
+ * since the load function sometimes needs data, that has been initialized
+ * before the load and after the proceeding storyentity has finished
+*/
+ErrorMessage GameWorld::init()
+{
+  /* init the world interface */
+  this->shell = new OrxShell::Shell();
+
+  State::setCurrentStoryEntity(dynamic_cast<StoryEntity*>(this));
+  this->dataTank->init();
+
+  /* initialize some engines and graphical elements */
+  AnimationPlayer::getInstance();
+  PhysicsEngine::getInstance();
+  CREngine::getInstance();
+
+  State::setScriptManager(&this->scriptManager);
+
+  return ErrorMessage();
+}
+
+/**
+ *  loads the GameWorld by initializing all resources, and set their default values.
+ */
+ErrorMessage GameWorld::loadData()
+{
+  this->displayLoadScreen();  State::setScriptManager(&this->scriptManager);
+
+
+  PRINTF(4)("Loading the GameWorld\n");
+
+  PRINTF(3)("> Loading world: '%s'\n", getLoadFile().c_str());
+  //  TiXmlElement* element;
+  //  GameLoader* loader = GameLoader::getInstance();
+
+  if( getLoadFile().empty())
+  {
+    PRINTF(1)("GameWorld has no path specified for loading\n");
+    return (ErrorMessage(213,"Path not specified","GameWorld::load()"));
+  }
+
+  TiXmlDocument* XMLDoc = new TiXmlDocument( getLoadFile());
+  // load the xml world file for further loading
+  if( !XMLDoc->LoadFile())
+  {
+    PRINTF(1)("loading XML File: %s @ %s:l%d:c%d\n", XMLDoc->ErrorDesc(), this->getLoadFile().c_str(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
+    delete XMLDoc;
+    return ErrorMessage(213,"XML File parsing error","GameWorld::load()");
+  }
+  // check basic validity
+  TiXmlElement* root = XMLDoc->RootElement();
+  assert( root != NULL);
+  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
+  {
+    // report an error
+    PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
+    delete XMLDoc;
+    return ErrorMessage(213,"Path not a WorldDataFile","GameWorld::load()");
+  }
+  /* the whole loading process for the GameWorld */
+  this->dataTank->loadData(root);
+  this->dataXML = (TiXmlElement*)root->Clone();
+
+  //remove this after finished testing !!!!
+  //Object* obj= new Object();
+  //obj->setName("Obj");
+  //Account* a = new Account();
+  //a->setName("a");
+  //Account *b = new Account(30);
+  //b->setName("b");
+
+
+  LoadParamXML(root, "ScriptManager", &this->scriptManager, ScriptManager, loadParams);
+
+  delete XMLDoc;
+  this->releaseLoadScreen();
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  unload the data of this GameWorld
+ */
+ErrorMessage GameWorld::unloadData()
+{
+
+  PRINTF(3)("GameWorld::~GameWorld() - unloading the current GameWorld\n");
+  this->scriptManager.flush();
+
+  delete this->shell;
+
+  this->dataTank->unloadData();
+
+  this->shell = NULL;
+  delete AnimationPlayer::getInstance();
+  delete PhysicsEngine::getInstance();
+  delete CREngine::getInstance();
+
+  State::setCurrentStoryEntity(NULL);
+  if (this->dataXML)
+    delete this->dataXML;
+
+  return ErrorMessage();
+}
+
+
+void GameWorld::setSoundtrack(const std::string& soundTrack)
+{
+  if (this->dataTank != NULL)
+  {
+    this->dataTank->setSoundTrack(soundTrack);
+    this->dataTank->music->play();
+  }
+}
+
+
+/**
+ *  starts the GameWorld
+ */
+bool GameWorld::start()
+{
+  this->bPaused = false;
+  this->bRunning = true;
+  State::setScriptManager(&this->scriptManager); //make sure we have the right script manager
+  this->run();
+
+  return true;
+}
+
+
+/**
+ *  stops the world.
+ */
+bool GameWorld::stop()
+{
+  PRINTF(3)("GameWorld::stop() - got stop signal\n");
+  State::setScriptManager(NULL);
+  return (this->bRunning = false);
+}
+
+
+/**
+ *  pauses the game
+ */
+bool GameWorld::pause()
+{
+  return (this->bPaused = true);
+}
+
+
+/**
+ *  ends the pause Phase
+ */
+bool GameWorld::resume()
+{
+  return(this->bPaused = false);
+}
+
+
+/**
+ *  main loop of the world: executing all world relevant function
+ *
+ * in this loop we synchronize (if networked), handle input events, give the heart-beat to
+ * all other member-entities of the world (tick to player, enemies etc.), checking for
+ * collisions drawing everything to the screen.
+ */
+void GameWorld::run()
+{
+  PRINTF(3)("GameWorld::mainLoop() - Entering main loop\n");
+
+  // initialize Timing
+  this->cycle = 0;
+  for (unsigned int i = 0; i < TICK_SMOOTH_VALUE; i++)
+    this->frameTimes[i] = 0.01f;
+  this->dtS = 0.0f;
+  this->lastFrame = Timer::getNow();
+
+  if (this->dataTank->music != NULL)
+    this->dataTank->music->play();
+
+  while( this->bRunning) /* @todo implement pause */
+  {
+    /* process intput */
+    this->handleInput ();
+    if( !this->bRunning)
+      break;
+
+    /* network synchronisation */
+    this->synchronize ();
+    /* process time */
+    this->tick ();
+
+
+    /* update the state */
+    //this->update (); /// LESS REDUNDANCY.
+    //      PNode::getNullParent()->updateNode(this->dtS);
+    PNode::getNullParent()->updateNode(this->dtS);
+
+    /* collision detection */
+    this->collisionDetection ();
+    /* collision reaction */
+    this->collisionReaction ();
+
+    /* check the game rules */
+    this->checkGameRules();
+
+    /* update the state */
+    this->update ();
+    /* draw everything */
+    this->display ();
+
+  }
+
+  PRINTF(4)("GameWorld::mainLoop() - Exiting the main loop\n");
+}
+
+
+void GameWorld::setPlaymode(Playable::Playmode playmode)
+{
+  if (this->dataTank->localPlayer &&
+      this->dataTank->localPlayer->getPlayable() &&
+      this->dataTank->localPlayer->getPlayable()->setPlaymode(playmode))
+  {
+    PRINTF(4)("Set Playmode to %d:%s\n", playmode, Playable::playmodeToString(playmode).c_str());
+  }
+  else
+  {
+    PRINTF(2)("Unable to set Playmode %d:'%s'\n", playmode, Playable::playmodeToString(playmode).c_str());
+  }
+}
+
+void GameWorld::setPlaymode(const std::string& playmode)
+{
+  this->setPlaymode(Playable::stringToPlaymode(playmode));
+}
+
+/**
+ *  synchronize local data with remote data
+*/
+void GameWorld::synchronize ()
+{}
+
+
+/**
+ *  run all input processing
+
+   the command node is the central input event dispatcher. the node uses the even-queue from
+   sdl and has its own event-passing-queue.
+*/
+void GameWorld::handleInput ()
+{
+  EventHandler::getInstance()->process();
+}
+
+
+/**
+ * @brief ticks a WorldEntity list
+ * @param entityList list of the WorldEntities
+ * @param dt time passed since last frame
+ */
+void GameWorld::tick(ObjectManager::EntityList entityList, float dt)
+{
+  ObjectManager::EntityList::iterator entity, next;
+  next = entityList.begin();
+  while (next != entityList.end())
+  {
+    entity = next++;
+    (*entity)->tick(dt);
+  }
+}
+
+
+/**
+ *  advance the timeline
+ *
+ * this calculates the time used to process one frame (with all input handling, drawing, etc)
+ * the time is mesured in ms and passed to all world-entities and other classes that need
+ * a heart-beat.
+ */
+void GameWorld::tick ()
+{
+  if( !this->bPaused)
+  {
+    // CALCULATE FRAMERATE
+    Uint32 frameTimesIndex;
+    Uint32 i;
+    double currentFrame = Timer::getNow();
+
+    if (currentFrame - this->lastFrame < .01)
+    {
+      SDL_Delay((int)(1000.0 * (0.01 - (currentFrame - lastFrame))));
+      currentFrame = Timer::getNow();
+    }
+
+
+    frameTimesIndex = this->cycle % TICK_SMOOTH_VALUE;
+    this->frameTimes[frameTimesIndex] = currentFrame - this->lastFrame;
+    this->lastFrame = currentFrame;
+    ++this->cycle;
+    this->dtS = 0.0;
+    for (i = 0; i < TICK_SMOOTH_VALUE; i++)
+      this->dtS += this->frameTimes[i];
+    this->dtS = this->dtS / TICK_SMOOTH_VALUE * speed;
+
+    // TICK everything
+    for (i = 0; i < this->dataTank->tickLists.size(); ++i)
+      this->tick(this->dataTank->objectManager->getEntityList(this->dataTank->tickLists[i]), this->dtS);
+
+    /* update tick the rest */
+    this->dataTank->localCamera->tick(this->dtS);
+    AnimationPlayer::getInstance()->tick(this->dtS);
+    PhysicsEngine::getInstance()->tick(this->dtS);
+
+    GraphicsEngine::getInstance()->tick(this->dtS);
+    AtmosphericEngine::getInstance()->tick(this->dtS);
+
+    if( likely(this->dataTank->gameRule != NULL))
+      this->dataTank->gameRule->tick(this->dtS);
+
+  }
+}
+
+
+/**
+ *  this function gives the world a consistant state
+ *
+ * after ticking (updating the world state) this will give a constistant
+ * state to the whole system.
+ */
+void GameWorld::update()
+{
+  PNode::getNullParent()->updateNode (this->dtS);
+  OrxSound::SoundEngine::getInstance()->update();
+
+  this->applyCameraSettings();
+  GraphicsEngine::getInstance()->update(this->dtS);
+}
+
+
+/**
+ * kicks the CDEngine to detect the collisions between the object groups in the world
+ */
+void GameWorld::collisionDetection()
+{
+  // object-object collision detection
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_00),
+      this->dataTank->objectManager->getEntityList(OM_GROUP_01_PROJ));
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_01),
+      this->dataTank->objectManager->getEntityList(OM_GROUP_00_PROJ));
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_01),
+      this->dataTank->objectManager->getEntityList(OM_GROUP_00));
+
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_01),
+      this->dataTank->objectManager->getEntityList(OM_GROUP_02));
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_02),
+      this->dataTank->objectManager->getEntityList(OM_GROUP_01_PROJ));
+
+
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_00),
+      this->dataTank->objectManager->getEntityList(OM_COMMON));
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_01),
+      this->dataTank->objectManager->getEntityList(OM_COMMON));
+
+  // ground collision detection: BSP Model
+  CDEngine::getInstance()->checkCollisionGround(this->dataTank->objectManager->getEntityList(OM_GROUP_00));
+  CDEngine::getInstance()->checkCollisionGround(this->dataTank->objectManager->getEntityList(OM_GROUP_01));
+}
+
+
+void GameWorld::collisionReaction()
+{
+  CREngine::getInstance()->handleCollisions();
+}
+
+
+/**
+ *  check the game rules: winning conditions, etc.
+ *
+ */
+void GameWorld::checkGameRules()
+{
+  if( this->gameRules)
+    this->gameRules->tick(this->dtS);
+}
+
+
+/**
+ *  render the current frame
+ *
+ * clear all buffers and draw the world
+ */
+void GameWorld::display ()
+{
+
+  // if this server is a dedicated server the game workd does not need to be drawn
+  if( !GraphicsEngine::getInstance()->isDedicated())
+  {
+    // render the reflection texture
+    this->renderPassReflection();
+    // redner the refraction texture
+    this->renderPassRefraction();
+  }
+  // render all
+  this->renderPassAll();
+
+  // flip buffers
+  GraphicsEngine::swapBuffers();
+}
+
+
+/**
+ * @brief draws all entities in the list drawList
+ * @param drawList the List of entities to draw.
+ */
+void GameWorld::drawEntityList(const ObjectManager::EntityList& drawList) const
+{
+  ObjectManager::EntityList::const_iterator entity;
+  for (entity = drawList.begin(); entity != drawList.end(); entity++)
+    if ((*entity)->isVisible())
+      (*entity)->draw();
+}
+
+
+void GameWorld::applyCameraSettings()
+{
+  this->dataTank->localCamera->apply ();
+  this->dataTank->localCamera->project ();
+  GraphicsEngine::storeMatrices();
+}
+
+
+
+/**
+ * reflection rendering for water surfaces
+ */
+void GameWorld::renderPassReflection()
+{
+  // clear buffer
+  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+  //  glLoadIdentity();
+
+  MappedWater* mw;
+
+  for (ObjectList<MappedWater>::const_iterator it = MappedWater::objectList().begin();
+       it != MappedWater::objectList().end();
+       ++it)
+  {
+    mw =  (*it);
+
+    //camera and light
+    //this->dataTank->localCamera->apply ();
+    //this->dataTank->localCamera->project ();
+
+    LightManager::getInstance()->draw();
+
+
+    // prepare for reflection rendering
+    mw->activateReflection();
+
+    // draw everything to be included in the reflection
+    this->drawEntityList(State::getObjectManager()->getReflectionList());
+    //       for (unsigned int i = 0; i < this->dataTank->drawLists.size(); ++i)
+    //         this->drawEntityList(State::getObjectManager()->getEntityList(this->dataTank->drawLists[i]));
+
+    // clean up from reflection rendering
+    mw->deactivateReflection();
+  }
+
+}
+
+
+/**
+ *  refraction rendering for water surfaces
+ */
+void GameWorld::renderPassRefraction()
+{
+  // clear buffer
+  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+  //glLoadIdentity();
+
+  MappedWater* mw;
+
+  for (ObjectList<MappedWater>::const_iterator it = MappedWater::objectList().begin();
+       it != MappedWater::objectList().end();
+       ++it)
+  {
+    mw =  dynamic_cast<MappedWater*>(*it);
+
+    //camera and light
+    //this->dataTank->localCamera->apply ();
+    //this->dataTank->localCamera->project ();
+    // prepare for reflection rendering
+    mw->activateRefraction();
+
+
+    LightManager::getInstance()->draw();
+    // draw everything to be included in the reflection
+    this->drawEntityList(State::getObjectManager()->getReflectionList());
+    //       for (unsigned int i = 0; i < this->dataTank->drawLists.size(); ++i)
+    //         this->drawEntityList(State::getObjectManager()->getEntityList(this->dataTank->drawLists[i]));
+
+    // clean up from reflection rendering
+    mw->deactivateRefraction();
+  }
+}
+
+
+/**
+ *  this render pass renders the whole wolrd
+ */
+void GameWorld::renderPassAll()
+{
+  // clear buffer
+  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+  GraphicsEngine* engine = GraphicsEngine::getInstance();
+
+
+  // glEnable(GL_DEPTH_TEST);
+  // glEnable(GL_LIGHTING);
+
+  // set Lighting
+  LightManager::getInstance()->draw();
+
+  // only render the world if its not dedicated mode
+  if( !GraphicsEngine::getInstance()->isDedicated())
+  {
+    /* Draw the BackGround */
+    this->drawEntityList(State::getObjectManager()->getEntityList(OM_BACKGROUND));
+    engine->drawBackgroundElements();
+
+    /* draw all WorldEntiy groups */
+    for (unsigned int i = 0; i < this->dataTank->drawLists.size(); ++i)
+      this->drawEntityList(State::getObjectManager()->getEntityList(this->dataTank->drawLists[i]));
+
+    AtmosphericEngine::getInstance()->draw();
+
+    if( unlikely( this->showBV))
+    {
+      CDEngine* engine = CDEngine::getInstance();
+      for (unsigned int i = 0; i < this->dataTank->drawLists.size(); ++i)
+        engine->drawBV(State::getObjectManager()->getEntityList(this->dataTank->drawLists[i]), this->showBVLevel);
+    }
+
+    if( unlikely(this->showPNodes))
+      PNode::getNullParent()->debugDraw(0);
+
+    // draw the game ruls
+    if( likely(this->dataTank->gameRule != NULL))
+      this->dataTank->gameRule->draw();
+  }
+
+  engine->draw();
+}
+
+
+/**
+ *  shows the loading screen
+ */
+void GameWorld::displayLoadScreen ()
+{
+  PRINTF(3)("GameWorld::displayLoadScreen - start\n");
+  this->dataTank->glmis = new GLMenuImageScreen();
+  this->dataTank->glmis->setMaximum(8);
+  PRINTF(3)("GameWorld::displayLoadScreen - end\n");
+}
+
+
+/**
+ *  removes the loadscreen, and changes over to the game
+ */
+void GameWorld::releaseLoadScreen()
+{
+  PRINTF(3)("GameWorld::releaseLoadScreen - start\n");
+  this->dataTank->glmis->setValue(this->dataTank->glmis->getMaximum());
+  PRINTF(3)("GameWorld::releaseLoadScreen - end\n");
+}
+
+
+
+/**
+ * @brief toggles the PNode visibility in the world (drawn as boxes)
+ */
+void GameWorld::togglePNodeVisibility()
+{
+  this->showPNodes = !this->showPNodes;
+};
+
+
+/**
+ * @brief toggles the bounding volume (BV) visibility
+*/
+void GameWorld::toggleBVVisibility(int level)
+{
+  if( level < 1)
+    this->showBV = false;
+  else
+  {
+    this->showBV = true;
+    this->showBVLevel = level;
+  }
+
+};
+
Index: branches/heathaze/src/story_entities/game_world.h
===================================================================
--- branches/heathaze/src/story_entities/game_world.h	(revision 9940)
+++ branches/heathaze/src/story_entities/game_world.h	(revision 9940)
@@ -0,0 +1,118 @@
+/*!
+ * @file game_world.h
+ *  container for all game worlds (singleplayers, multiplayers..)
+ */
+
+#ifndef _GAME_WORLD_H
+#define _GAME_WORLD_H
+
+
+#include "story_entity.h"
+#include "game_world_data.h"
+#include "playable.h"
+#include "script_manager.h"
+
+namespace OrxShell { class Shell; };
+class WorldEntity;
+class GameRules;
+
+
+/** How many frames time values to keep
+ * The higher the value the smoother the result is...
+ * Don't make it 0 or less :)
+ */
+#define TICK_SMOOTH_VALUE 10
+
+//! The game world
+/**
+ *  this class initializes everything that should be displayed inside of the current level.
+ *  it is the main driving factor during gameplay.
+ */
+class GameWorld : public StoryEntity
+{
+  ObjectListDeclaration(GameWorld);
+
+public:
+  GameWorld ();
+  virtual ~GameWorld ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  /* functions from story-entity */
+  virtual ErrorMessage init();
+  virtual ErrorMessage loadData();
+  virtual ErrorMessage unloadData();
+
+  virtual bool start();
+  virtual bool stop();
+  virtual bool pause();
+  virtual bool resume();
+  virtual void run();
+
+  void setPlaymode(Playable::Playmode playmode);
+  void setPlaymode(const std::string& playmode);
+  /**  this returns the current game time @returns elapsed game time     */
+  inline double getGameTime() { return this->gameTime; }
+  /** sets the game speed @param speed speed of the Game */
+  inline void setSpeed(float speed) { this->speed = speed; };
+  /**  returns the track path of this world @returns the track path */
+
+
+  void setSoundtrack(const std::string& soundTrack);
+  void togglePNodeVisibility();
+  void toggleBVVisibility(int level);
+
+  inline void setSky(WorldEntity* sky) { this->dataTank->sky = sky; }
+
+
+protected:
+  /* world - running functions */
+  virtual void synchronize();
+  virtual void handleInput();
+  virtual void tick(ObjectManager::EntityList worldEntity, float dt);
+  virtual void tick();
+  virtual void update();
+  virtual void checkGameRules();
+  virtual void collisionDetection();
+  virtual void collisionReaction();
+
+  void applyCameraSettings();
+  void drawEntityList(const ObjectManager::EntityList& drawList ) const;
+  virtual void renderPassReflection();
+  virtual void renderPassRefraction();
+  virtual void renderPassAll();
+
+
+  virtual void display();
+
+
+private:
+  void displayLoadScreen();
+  void releaseLoadScreen();
+
+
+protected:
+  GameWorldData*      dataTank;                     //!< reference to the GameWorld Data Tank
+  TiXmlElement*       dataXML;                      //!< The XML-Element this World has been loaded with.
+
+  bool                showPNodes;                   //!< if the PNodes should be visible.
+  bool                showBV;                       //!< if the Bounding Volumes should be visible.
+  int                 showBVLevel;                  //!< the depth level of the displayed bounding volumes
+
+  /* world timing */
+  double              lastFrame;                    //!< last time of frame (in MiliSeconds)
+  Uint32              cycle;                        //!< The cycle we are in (starts with 0 and rises with every frame)
+  float               dtS;                          //!< The time needed for caluculations in seconds
+  float               speed;                        //!< how fast the game flows
+  double              gameTime;                     //!< this is where the game time is saved
+  double              frameTimes[TICK_SMOOTH_VALUE];//!< The time used for the last TICK_SMOOTH_VALUE's frames.
+
+  GameRules*          gameRules;                    //!< Pointer to the data structure containig the game rules
+
+private:
+  /* external modules interfaces */
+  ScriptManager       scriptManager;
+  OrxShell::Shell*    shell;
+};
+
+#endif /* _GAME_WORLD_H */
Index: branches/heathaze/src/story_entities/game_world_data.cc
===================================================================
--- branches/heathaze/src/story_entities/game_world_data.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/game_world_data.cc	(revision 9940)
@@ -0,0 +1,417 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+#include <fstream>
+#include <iostream>
+
+#include "game_world_data.h"
+
+#include "state.h"
+#include "substring.h"
+
+#include "util/loading/game_loader.h"
+#include "util/loading/resource_manager.h"
+
+#include "world_entity.h"
+#include "player.h"
+#include "camera.h"
+#include "terrain.h"
+#include "skybox.h"
+#include "md2/md2Model.h"
+#include "world_entities/projectiles/projectile.h"
+#include "npcs/npc_test1.h"
+#include "playable.h"
+
+#include "light.h"
+
+#include "util/loading/factory.h"
+#include "loading/fast_factory.h"
+#include "util/loading/load_param_xml.h"
+
+#include "graphics_engine.h"
+#include "graphics_effect.h"
+#include "weather_effects/atmospheric_engine.h"
+#include "event_handler.h"
+#include "sound_engine.h"
+#include "cd_engine.h"
+#include "network_manager.h"
+#include "physics_engine.h"
+
+#include "glmenu_imagescreen.h"
+
+#include "game_rules.h"
+
+#include "ogg_player.h"
+#include "shader.h"
+
+
+ObjectListDefinition(GameWorldData);
+/**
+ * constructor of the GameWorldData
+ */
+GameWorldData::GameWorldData()
+{
+  this->registerObject(this, GameWorldData::_objectList);
+
+  this->glmis = NULL;
+
+  this->localCamera = NULL;
+  this->localPlayer = NULL;
+  this->sky = NULL;
+  this->terrain = NULL;
+
+  this->music = NULL;
+  this->objectManager = NULL;
+  this->gameRule = NULL;
+}
+
+
+/**
+ * destructor for the GameWorldData
+ */
+GameWorldData::~GameWorldData()
+{}
+
+
+
+/**
+ *  initialize the GameWorldData
+ */
+ErrorMessage GameWorldData::init()
+{
+  this->objectManager = new ObjectManager();
+  State::setObjectManager(this->objectManager);
+
+  PNode::getNullParent();
+  this->localCamera = new Camera();
+  this->localCamera->setName ("GameWorld-Camera");
+  State::setCamera(this->localCamera, this->localCamera->getTarget());
+
+  LightManager::getInstance();
+
+//  GraphicsEngine::getInstance()->displayFPS(true);
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  loads the data from the xml file
+ * @param root reference to the xml root element
+ */
+ErrorMessage GameWorldData::loadData(const TiXmlElement* root)
+{
+  assert (root != NULL);
+  // load the parameters
+  // name
+  std::string string = LoadParamBase::grabParameter( root, "name");
+  if( string.empty() )
+  {
+    PRINTF(2)("GameWorld is missing a proper 'name'\n");
+    this->setName("Unknown");
+  }
+  else
+    this->setName(string.c_str());
+
+  this->loadGUI(root);
+  this->loadWorldEntities(root);
+  this->loadScene(root);
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  unloads the data from the xml file
+ */
+ErrorMessage GameWorldData::unloadData()
+{
+  this->unloadGUI();
+  this->unloadWorldEntities();
+  this->unloadScene();
+
+  return ErrorMessage();
+}
+
+
+/**
+ * @brief loads the GUI data
+ * @param root reference to the xml root element
+ */
+ErrorMessage GameWorldData::loadGUI(const TiXmlElement* root)
+{
+  const TiXmlElement* element = root->FirstChildElement("LoadScreen");
+  if( element == NULL)
+  {
+    PRINTF(2)("no LoadScreen specified, loading default\n");
+
+    glmis->setBackgroundImage("pictures/load_screen.jpg");
+    this->glmis->setMaximum(8);
+    //     this->glmis->draw();
+  }
+  else
+  {
+    this->glmis->loadParams(element);
+    //     this->glmis->draw();
+  }
+  this->glmis->draw();
+
+  return ErrorMessage();
+}
+
+
+/**
+ * @brief unloads the GUI data
+ */
+ErrorMessage GameWorldData::unloadGUI()
+{
+  delete this->glmis;
+
+  return ErrorMessage();
+}
+
+
+/**
+ * @brief loads the world entities from the xml file
+ * @param root reference to the xml root parameter
+ */
+ErrorMessage GameWorldData::loadWorldEntities(const TiXmlElement* root)
+{
+  const TiXmlElement* element = root->FirstChildElement("WorldEntities");
+  bool mouseCaptured = EventHandler::getInstance()->grabbedEvents();
+  EventHandler::getInstance()->grabEvents(false);
+
+  if( element == NULL)
+  {
+    PRINTF(1)("GameWorld is missing 'WorldEntities'\n");
+  }
+  else
+  {
+    element = element->FirstChildElement();
+    // load Players/Objects/Whatever
+    PRINTF(4)("Loading WorldEntities\n");
+    while( element != NULL)
+    {
+      BaseObject* created = Factory::fabricate(element);
+      if( created != NULL )
+        PRINTF(4)("Created a %s: %s\n", created->getClassCName(), created->getCName());
+
+      //todo do this more elegant
+      if( element->Value() == "SkyBox" && created->isA(SkyBox::staticClassID()))
+      {
+        this->sky = dynamic_cast<WorldEntity*>(created);
+        State::setSkyBox(dynamic_cast<SkyBox*>(this->sky));
+      }
+      if( element->Value() == "Terrain" && created->isA(Terrain::staticClassID()))
+      {
+        this->terrain = dynamic_cast<Terrain*>(created);
+        CDEngine::getInstance()->setTerrain(terrain);
+      }
+      element = element->NextSiblingElement();
+      this->glmis->step(); //! @todo temporary
+    }
+    PRINTF(4)("Done loading WorldEntities\n");
+  }
+
+  // Create a Player
+  this->localPlayer = new Player();
+  State::setPlayer(this->localPlayer);
+
+  Playable* playable;
+  if (!Playable::objectList().empty())
+  {
+    /// TODO Make this also loadable
+    this->localPlayer->setPlayable(Playable::objectList().front());
+  }
+
+  // Fill the EntityLists. Tick then Draw:
+  this->tickLists.push_back(OM_DEAD_TICK);
+  this->tickLists.push_back(OM_ENVIRON);
+  this->tickLists.push_back(OM_COMMON);
+  this->tickLists.push_back(OM_GROUP_00);
+  this->tickLists.push_back(OM_GROUP_00_PROJ);
+  this->tickLists.push_back(OM_GROUP_01);
+  this->tickLists.push_back(OM_GROUP_01_PROJ);
+  this->tickLists.push_back(OM_GROUP_02);
+
+  this->drawLists.push_back(OM_ENVIRON_NOTICK);
+  this->drawLists.push_back(OM_ENVIRON);
+  this->drawLists.push_back(OM_GROUP_00);
+  this->drawLists.push_back(OM_GROUP_00_PROJ);
+  this->drawLists.push_back(OM_GROUP_01);
+  this->drawLists.push_back(OM_GROUP_01_PROJ);
+  this->drawLists.push_back(OM_GROUP_02);
+  this->drawLists.push_back(OM_COMMON);
+
+  /* init the pnode tree */
+  PNode::getNullParent()->init();
+
+  EventHandler::getInstance()->grabEvents(mouseCaptured);
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  unloads the world entities
+ */
+ErrorMessage GameWorldData::unloadWorldEntities()
+{
+  FastFactory::flushAll(true);
+  GraphicsEngine::getInstance()->displayFPS(false);
+  // erease everything that is left.
+  //secondary cleanup of PNodes;
+  while (!PNode::objectList().empty())
+    delete PNode::objectList().front();
+
+  /* remove the player object */
+  if( this->localPlayer)
+    delete this->localPlayer;
+  State::setPlayer(NULL);
+  this->localPlayer = NULL;
+  this->localCamera = NULL;
+  State::setCamera(NULL, NULL);
+  this->sky = NULL;
+  this->terrain = NULL;
+
+  while (!GraphicsEffect::objectList().empty())
+    delete GraphicsEffect::objectList().front();
+
+
+  while (!Element2D::objectList().empty())
+    delete Element2D::objectList().front();
+
+  // At this Point all the WorldEntites should be unloaded.
+  this->tickLists.clear();
+  this->drawLists.clear();
+
+  // unload the resources loaded in this Level !!
+  /// FIXME TODO HACK!!
+//  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
+
+  if (State::getObjectManager() == this->objectManager)
+  {
+    State::setObjectManager(NULL);
+    delete this->objectManager;
+  }
+  this->objectManager = NULL;
+
+  if(State::getSkyBox())
+    State::setSkyBox(NULL);
+
+  this->glmis = NULL;
+
+  return ErrorMessage();
+}
+
+
+/**
+ * @brief loads the scene data
+ * @param root reference to the xml root element
+ */
+ErrorMessage GameWorldData::loadScene(const TiXmlElement* root)
+{
+  LoadParamXML(root, "LightManager", LightManager::getInstance(), LightManager, loadParams);
+  LoadParamXML(root, "GraphicsEngine", GraphicsEngine::getInstance(), GraphicsEngine, loadParams);
+  LoadParamXML(root, "AtmosphericEngine", AtmosphericEngine::getInstance(), AtmosphericEngine, loadParams);
+
+  LoadParam(root, "Music", this, GameWorldData, setSoundTrack);
+
+  LoadParamXML(root, "GameRule", this, GameWorldData, loadGameRule);
+
+  LoadParam(root, "clip-region", this->localCamera, Camera, setClipRegion);
+
+
+  //LoadParamXML(root, "ParticleEngine", ParticleEngine::getInstance(), ParticleEngine, loadParams);
+  //LoadParamXML(root, "PhysicsEngine", PhysicsEngine::getInstance(), PhysicsEngine, loadParams);
+
+  if( this->sky != NULL)
+    this->localCamera->addChild(this->sky);
+  OrxSound::SoundEngine::getInstance()->setListener(this->localCamera);
+
+  return ErrorMessage();
+}
+
+
+
+/**
+ *  unloads the scene data
+ */
+ErrorMessage GameWorldData::unloadScene()
+{
+  /* delete some garphics and scene eingines */
+  delete LightManager::getInstance();
+  delete AtmosphericEngine::getInstance();
+
+  if (this->music != NULL)
+    this->setSoundTrack("");
+
+  /* unload the shaders */
+  Shader::suspendShader();
+
+  State::setGameRules(NULL);
+
+  return ErrorMessage();
+}
+
+
+void GameWorldData::setSoundTrack(const std::string& name)
+{
+  if (this->music != NULL)
+    delete this->music;
+  this->music = NULL;
+
+  if (!name.empty())
+  {
+    PRINTF(3)("Setting Sound Track to %s\n", name.c_str());
+    std::string oggFile = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(name);
+    this->music = new OrxSound::OggPlayer(oggFile);
+    if (this->localPlayer != NULL)
+      this->localPlayer->hud().notifyUser(std::string("Playing SoundTrack: ") + this->music->artist() + " - " + this->music->title());
+
+    //(OggPlayer*)ResourceManager::getInstance()->load(name, OGG, RP_LEVEL);
+    //assert(this->music->isA(CL_SOUND_OGG_PLAYER));
+  }
+}
+
+
+void GameWorldData::loadGameRule(const TiXmlElement* root)
+{
+  const TiXmlElement* element = root->FirstChildElement();
+  while( element != NULL)
+  {
+    PRINTF(2)("============ GameRules ==\n");
+    PRINTF(2)("creating %s\n", element->Value());
+    BaseObject* created = Factory::fabricate(element);
+    if (created != NULL && created->isA(GameRules::staticClassID()))
+    {
+      this->gameRule = dynamic_cast<GameRules*>(created);
+      State::setGameRules(this->gameRule);
+      // if there is a valid game rule loaded, return because it is not thought to load multiple game rules
+      return;
+    }
+    else
+    {
+      PRINTF(1)("Could not create a %s\n", element->Value());
+      delete created;
+    }
+    element = element->NextSiblingElement();
+  }
+}
+
+
+
Index: branches/heathaze/src/story_entities/game_world_data.h
===================================================================
--- branches/heathaze/src/story_entities/game_world_data.h	(revision 9940)
+++ branches/heathaze/src/story_entities/game_world_data.h	(revision 9940)
@@ -0,0 +1,73 @@
+/*!
+ * @file game_world_data.h
+ *  container for all game world data
+ */
+
+#ifndef _GAME_WORLD_DATA_H
+#define _GAME_WORLD_DATA_H
+
+#include "sdlincl.h"
+#include "data_tank.h"
+#include "error.h"
+#include "object_manager.h"
+
+class Camera;
+class Player;
+class Terrain;
+class WorldEntity;
+
+class GLMenuImageScreen;
+
+namespace OrxSound {class OggPlayer;}
+class GameRules;
+
+
+//! The game world data
+/**
+ * this class is a containter for the data of the GameWorld. It just loads and unloads it
+ * the game start/stop process is not contained here and can be found in the GameWorld class.
+ */
+class GameWorldData : public DataTank
+{
+  ObjectListDeclaration(GameWorldData);
+  public:
+    GameWorldData();
+    virtual ~GameWorldData();
+
+    virtual ErrorMessage init();
+    virtual ErrorMessage loadData(const TiXmlElement* root);
+    virtual ErrorMessage unloadData();
+
+    /* interface functions */
+    void setSoundTrack(const std::string& name);
+    void loadGameRule(const TiXmlElement* root);
+
+
+  protected:
+    virtual ErrorMessage loadGUI(const TiXmlElement* root);
+    virtual ErrorMessage loadWorldEntities(const TiXmlElement* root);
+    virtual ErrorMessage loadScene(const TiXmlElement* root);
+
+    virtual ErrorMessage unloadGUI();
+    virtual ErrorMessage unloadWorldEntities();
+    virtual ErrorMessage unloadScene();
+
+  public:
+    GLMenuImageScreen*            glmis;          //!< The Level-Loader Display
+
+    Camera*                       localCamera;    //!< The current camera
+    Player*                       localPlayer;    //!< The player, you fly through the level.
+    WorldEntity*                  sky;            //!< The environmental sky of orxonox
+    Terrain*                      terrain;        //!< The terrain - ground
+
+    OrxSound::OggPlayer*          music;          //!< Reference to the SoundEngine's music player (OggPlayer)
+    ObjectManager*                objectManager;  //!< Reference to the objects manager
+
+    GameRules*                    gameRule;       //!< Reference to the game rules of this game
+
+    std::vector<OM_LIST>          tickLists;      //!< The Lists in the GameWorld that should be ticked.
+    std::vector<OM_LIST>          drawLists;      //!< The Lists in the GameWorld, that should be drawn.
+};
+
+#endif /* _GAME_WORLD_DATA_H */
+
Index: branches/heathaze/src/story_entities/menu/game_menu.cc
===================================================================
--- branches/heathaze/src/story_entities/menu/game_menu.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/menu/game_menu.cc	(revision 9940)
@@ -0,0 +1,612 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "game_menu.h"
+
+#include "event_handler.h"
+
+#include "state.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "graphics_engine.h"
+#include "camera.h"
+#include "sound_engine.h"
+
+#include "sound_source.h"
+
+#include "glgui.h"
+#include "menu/glgui_imagebutton.h"
+
+#include "glgui_text.h"
+
+#include "network_manager.h"
+
+#include "parser/preferences/preferences.h"
+
+#include "class_id_DEPRECATED.h"
+//! This creates a Factory to fabricate a GameMenu
+ObjectListDefinitionID(GameMenu, CL_GAME_MENU);
+CREATE_FACTORY(GameMenu);
+
+
+GameMenu::GameMenu(const TiXmlElement* root)
+    : GameWorld()
+{
+  this->registerObject(this, GameMenu::_objectList);
+  this->setName("GameMenu uninitialized");
+
+  this->dataTank = new GameMenuData();
+
+  this->cameraVector = Vector(50.0, 0.0, 0.0);
+
+  if (root != NULL)
+    this->loadParams(root);
+
+  State::setMenuID(this->getNextStoryID());
+}
+
+/**
+*  @brief remove the GameMenu from memory
+*
+*  delete everything explicitly, that isn't contained in the parenting tree!
+*  things contained in the tree are deleted automaticaly
+*/
+GameMenu::~GameMenu ()
+{
+  PRINTF(3)("GameMenu::~GameMenu() - deleting current world\n");
+
+  if( this->dataTank)
+    delete this->dataTank;
+  OrxGui::GLGuiHandler::deleteInstance( );
+}
+
+
+/**
+* @brief loads the parameters of a GameMenu from an XML-element
+* @param root the XML-element to load from
+*/
+void GameMenu::loadParams(const TiXmlElement* root)
+{
+  /* skip the GameWorld, since it does not define any useful loadParams for this class */
+  //static_cast<GameWorld*>(this)->loadParams(root);
+  GameWorld::loadParams(root);
+
+  PRINTF(4)("Loaded GameMenu specific stuff\n");
+}
+
+
+/**
+* @brief this is executed just before load
+*
+* since the load function sometimes needs data, that has been initialized
+* before the load and after the proceeding storyentity has finished
+*/
+ErrorMessage GameMenu::init()
+{
+  /* call underlying init funciton */
+  GameWorld::init();
+
+  this->subscribeEvent(ES_MENU, SDLK_UP);
+  this->subscribeEvent(ES_MENU, SDLK_DOWN);
+  this->subscribeEvent(ES_MENU, SDLK_RETURN);
+  this->subscribeEvent(ES_MENU, SDLK_SPACE);
+  this->subscribeEvent(ES_MENU, SDLK_ESCAPE);
+
+  this->dataTank->localCamera->setRelCoor(this->cameraVector);
+
+  GraphicsEngine::getInstance()->displayFPS(false);
+
+  return ErrorMessage();
+}
+
+
+/**
+* @brief load the data
+*/
+ErrorMessage GameMenu::loadData()
+{
+  this->mainMenuBox = NULL;
+
+  this->levelsBox = NULL;
+  this->networkBox = NULL;
+
+  this->clientNetworkBox = NULL;
+  this->serverNetworkBox = NULL;
+
+  this->optionsBox = NULL;
+  this->generalBox = NULL;
+  this->audioBox = NULL;
+  this->videoBox = NULL;
+  this->controlBox = NULL;
+  this->levelsBox = NULL;
+
+  this->currentlyOpened = NULL;
+
+  return GameWorld::loadData();
+}
+
+
+void GameMenu::showMainMenu()
+{
+  if (mainMenuBox == NULL)
+  {
+    this->mainMenuBox = new OrxGui::GLGuiBox();
+    {
+      OrxGui::GLGuiButton* startButton = new OrxGui::GLGuiPushButton("Play");
+      startButton->released.connect(this, &GameMenu::showCampaigns);
+      this->mainMenuBox->pack(startButton);
+      startButton->select();
+
+      OrxGui::GLGuiButton* networkButton = new OrxGui::GLGuiPushButton("MultiPlayer");
+      networkButton->released.connect(this, &GameMenu::showMultiPlayer);
+      this->mainMenuBox->pack(networkButton);
+
+      OrxGui::GLGuiButton* optionsButton = new OrxGui::GLGuiPushButton("Options");
+      optionsButton->released.connect(this, &GameMenu::showOptionsMenu);
+      this->mainMenuBox->pack(optionsButton);
+
+
+      OrxGui::GLGuiButton* quitButton = new OrxGui::GLGuiPushButton("Quit");
+      this->mainMenuBox->pack(quitButton);
+      quitButton->released.connect(this, &GameMenu::quitMenu);
+    }
+  }
+  this->mainMenuBox->showAll();
+
+
+  this->mainMenuBox->setRelCoor2D(200, 100);
+}
+
+
+void GameMenu::showCampaigns()
+{
+  if (this->levelsBox == NULL)
+  {
+    this->levelsBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
+    {
+      OrxGui::GLGuiBox* labelBox = new OrxGui::GLGuiBox();
+
+      OrxGui::GLGuiImage* image = new OrxGui::GLGuiImage();
+      image->show();
+      image->setWidgetSize( 250, 200);
+      image->setAbsCoor2D(400, 150);
+      image->setForegroundColor(Color( 1,1,1,.6));
+
+      bool first = true;
+      for(ObjectList<StoryEntity>::const_iterator it = StoryEntity::objectList().begin();
+	  it != StoryEntity::objectList().end();
+	  ++it)
+      {
+        StoryEntity* se = *it;
+        if( se->isContainedInMenu())
+        {
+
+	  PRINTF(3)("Load image %s\n", se->getMenuScreenshoot().c_str());
+          OrxGui::GLGuiImageButton* button = new OrxGui::GLGuiImageButton(se->getName(), se->getStoryID(), se->getMenuScreenshoot(), image);
+          button->startLevel.connect(this, &GameMenu::startLevel);
+          labelBox->pack(button);
+
+          if (first)
+          {
+            first = !first;
+            button->select();
+          }
+
+          // generating screenshoot item
+          /*
+          ImageEntity* ie = new ImageEntity();
+          ie->setVisibility(false);
+          ie->setBindNode((const PNode*)NULL);
+          ie->setTexture(se->getMenuScreenshoot());
+          ie->setRelCoor2D(State::getResX() / 2.0f + 250.0f, State::getResY() / 2.0f);
+          ie->setSize2D(140.0f, 105.0f);
+          this->menuLayers[1].screenshootList.push_back(ie);
+          */
+        }
+      }
+
+      this->levelsBox->pack(labelBox);
+      this->levelsBox->pack(image);
+    }
+
+  }
+
+  this->showSecondLevelElement(this->levelsBox);
+
+}
+
+void GameMenu::showMultiPlayer()
+{
+  if (this->networkBox == NULL)
+  {
+    this->networkBox = new OrxGui::GLGuiBox( OrxGui::Horizontal );
+    {
+      OrxGui::GLGuiBox * box = new OrxGui::GLGuiBox();
+
+      OrxGui::GLGuiButton* clientButton = new OrxGui::GLGuiPushButton("Client");
+      box->pack(clientButton);
+      clientButton->released.connect(this, &GameMenu::showClientMenu);
+
+      OrxGui::GLGuiButton* serverButton = new OrxGui::GLGuiPushButton("Server");
+      box->pack(serverButton);
+      serverButton->released.connect(this, &GameMenu::showServerMenu);
+
+      networkBox->pack( box );
+    }
+  }
+
+  this->showSecondLevelElement(this->networkBox);
+
+}
+
+void GameMenu::showOptionsMenu()
+{
+  if (this->optionsBox == NULL)
+  {
+    this->optionsBox = new OrxGui::GLGuiBox();
+    {
+      OrxGui::GLGuiTextfield* WARNtext = new OrxGui::GLGuiTextfield();
+      WARNtext->setText("PLEASE USE THE EXTERNAL GUI\n FOR ORXONOX CONFIGURATION\n (start with './orxonox -g')");
+      optionsBox->pack(WARNtext);
+
+
+      OrxGui::GLGuiButton* generalButton = new OrxGui::GLGuiPushButton("General");
+      optionsBox->pack(generalButton);
+
+      OrxGui::GLGuiButton* audioButton = new OrxGui::GLGuiPushButton("Audio");
+      optionsBox->pack(audioButton);
+
+      OrxGui::GLGuiButton* videoButton = new OrxGui::GLGuiPushButton("Video");
+      optionsBox->pack(videoButton);
+
+      OrxGui::GLGuiButton* controlButton = new OrxGui::GLGuiPushButton("Control");
+      optionsBox->pack(controlButton);
+
+
+      //      for (unsigned int i = 0; i <
+      //OrxGui::GLGuiButton*
+
+    }
+  }
+
+  this->showSecondLevelElement(this->optionsBox);
+}
+
+
+void GameMenu::showSecondLevelElement(OrxGui::GLGuiBox* element)
+{
+  if (this->currentlyOpened != NULL && this->currentlyOpened != element)
+    this->currentlyOpened->hideAll();
+
+  element->showAll();
+  element->setRelCoor2D(200, 100);
+
+  this->currentlyOpened = element;
+
+  this->mainMenuBox->setRelCoorSoft2D(50, 100, 5);
+}
+
+
+
+
+
+void GameMenu::startLevel(int levelID)
+{
+  this->setNextStoryID( levelID);
+  this->stop();
+}
+
+/**
+* @brief set the Sound to play when switching menu entry.
+* @param selectorSound the sound to load.
+*/
+void GameMenu::setSelectorSound(const std::string& selectorSound)
+{
+  this->selectorSource = OrxSound::SoundEngine::getInstance()->createSource(selectorSound, NULL);
+}
+
+ErrorMessage GameMenu::unloadData()
+{
+  this->unsubscribeEvents(ES_MENU);
+
+  return GameWorld::unloadData();
+}
+
+
+/**
+* @brief start the menu
+*/
+bool GameMenu::start()
+{
+  EventHandler::getInstance()->pushState(ES_MENU);
+
+  this->showMainMenu();
+  OrxGui::GLGuiHandler::getInstance()->activateCursor();
+  OrxGui::GLGuiHandler::getInstance()->activate();
+
+  /* now call the underlying*/
+  return GameWorld::start();
+}
+
+
+
+/**
+* stop the menu
+*/
+bool GameMenu::stop()
+{
+  EventHandler::getInstance()->popState();
+
+  /* now call the underlying*/
+  return GameWorld::stop();
+}
+
+
+/**
+*  override the standard tick for more functionality
+*/
+void GameMenu::tick()
+{
+  GameWorld::tick();
+
+  // Make the GLGui tick.
+  OrxGui::GLGuiHandler::getInstance()->tick(this->dtS);
+
+  this->animateScene(this->dtS);
+}
+
+
+/**
+* @brief no collision detection in the menu
+*/
+void GameMenu::collide()
+{
+  //   this->dataTank->localCamera->
+}
+
+
+/**
+* @brief animate the scene
+*/
+void GameMenu::animateScene(float dt)
+{
+  Quaternion q(/*0.00005*/ dt * .1, Vector(0.0, 1.0, 0.0));
+  this->cameraVector = q.apply(this->cameraVector);
+  this->dataTank->localCamera->setRelCoor(this->cameraVector);
+  this->dataTank->localCamera->getTarget()->setRelCoorSoft(0,0,0);
+}
+
+void GameMenu::quitMenu()
+{
+  this->setNextStoryID(WORLD_ID_GAMEEND);
+  this->stop();
+}
+
+
+/**
+* @brief event dispatcher funciton
+* @param event the incoming event
+*/
+void GameMenu::process(const Event &event)
+{
+  if( event.type == SDLK_ESCAPE && event.bPressed == true)
+  {
+    this->setNextStoryID(WORLD_ID_GAMEEND);
+    this->stop();
+  }
+
+}
+
+
+
+/**********************************************************************************************
+GameMenuData
+**********************************************************************************************/
+
+
+/**
+* GameMenuData constructor
+*/
+GameMenuData::GameMenuData()
+{}
+
+/**
+* GameMenuData decontructor
+*/
+GameMenuData::~GameMenuData()
+{}
+
+
+/**
+*  initialize the GameWorldDataData
+*/
+ErrorMessage GameMenuData::init()
+{
+  /* call underlying function */
+  return GameWorldData::init();
+}
+
+
+/**
+*  loads the GUI data
+* @param root reference to the xml root element
+*/
+ErrorMessage GameMenuData::loadGUI(const TiXmlElement* root)
+{
+  /* call underlying function */
+  return GameWorldData::loadGUI(root);
+}
+
+
+/**
+*  unloads the GUI data
+*/
+ErrorMessage GameMenuData::unloadGUI()
+{
+  /* call underlying function */
+  return GameWorldData::unloadGUI();
+}
+
+
+/**
+*  overloads the GameWorld::loadWorldEntities(...) class since the menu WorldEntity loading is different (less loading stuff)
+* @param root reference to the xml root parameter
+*/
+ErrorMessage GameMenuData::loadWorldEntities(const TiXmlElement* root)
+{
+  return GameWorldData::loadWorldEntities(root);
+}
+
+
+/**
+*  unloads the world entities from the xml file
+*/
+ErrorMessage GameMenuData::unloadWorldEntities()
+{
+  /* call underlying function */
+  return GameWorldData::unloadWorldEntities();
+}
+
+
+/**
+*  loads the scene data
+* @param root reference to the xml root element
+*/
+ErrorMessage GameMenuData::loadScene(const TiXmlElement* root)
+{
+  /* call underlying function */
+  return GameWorldData::loadScene(root);
+}
+
+
+/**
+*  unloads the scene data
+*/
+ErrorMessage GameMenuData::unloadScene()
+{
+  /* call underlying function */
+  return GameWorldData::unloadScene();
+}
+
+/**
+ * show controls to join network game
+ */
+void GameMenu::showClientMenu( )
+{
+  if ( this->serverNetworkBox )
+  {
+    this->networkBox->unpack( this->serverNetworkBox );
+    this->serverNetworkBox->hideAll();
+    //delete this->serverNetworkBox;
+    //this->serverNetworkBox = NULL;
+  }
+
+  if ( !this->clientNetworkBox )
+  {
+    this->clientNetworkBox = new OrxGui::GLGuiBox();
+    {
+      OrxGui::GLGuiText * text = new OrxGui::GLGuiText();
+      text->setText( "Host:" );
+      this->clientNetworkBox->pack( text );
+
+      this->ipInputLine = new OrxGui::GLGuiInputLine( );
+      this->ipInputLine->setText( Preferences::getInstance()->getString( "multiplayer", "lastVisitedServer", "localhost" ) );
+      this->clientNetworkBox->pack( this->ipInputLine );
+      //this->ipInputLine->enterPushed.connect(this, &GameMenu::connectToServer); /// redo this.
+      this->ipInputLine->select();
+
+      OrxGui::GLGuiButton* connectButton = new OrxGui::GLGuiPushButton("Connect");
+      clientNetworkBox->pack(connectButton);
+      connectButton->released.connect(this, &GameMenu::connectToServer);
+    }
+  }
+
+  this->networkBox->pack( this->clientNetworkBox );
+
+  this->clientNetworkBox->showAll();
+
+  //this->clientNetworkBox->setAbsCoor2D( 300.0f, 100.0f );
+}
+
+/**
+ * show controls to create new network game
+ */
+void GameMenu::showServerMenu( )
+{
+  if ( this->clientNetworkBox )
+  {
+    this->networkBox->unpack( this->clientNetworkBox );
+    this->clientNetworkBox->hideAll();
+    //delete this->clientNetworkBox;
+    //this->clientNetworkBox = NULL;
+  }
+
+  if ( !this->serverNetworkBox )
+  {
+    this->serverNetworkBox = new OrxGui::GLGuiBox();
+    {
+      OrxGui::GLGuiText * text = new OrxGui::GLGuiText();
+      text->setText( "Map:" );
+      this->serverNetworkBox->pack( text );
+
+      OrxGui::GLGuiText * text2 = new OrxGui::GLGuiText();
+      text2->setText( "Multiplayer TeamDeathMatch Arena" );
+      this->serverNetworkBox->pack( text2 );
+
+      OrxGui::GLGuiButton* createButton = new OrxGui::GLGuiPushButton("Create Server");
+      serverNetworkBox->pack(createButton);
+      createButton->released.connect(this, &GameMenu::createMasterServer);
+    }
+  }
+
+  this->networkBox->pack( this->serverNetworkBox );
+
+  this->serverNetworkBox->showAll();
+
+  //this->serverNetworkBox->setAbsCoor2D( 300.0f, 100.0f );
+}
+
+/**
+ * connect to host
+ */
+void GameMenu::connectToServer( )
+{
+  PRINTF(0)("Connecting to %s\n", this->ipInputLine->_getText().c_str() );
+
+  State::setOnline(true);
+  NetworkManager::getInstance()->createClient( this->ipInputLine->_getText(), 9999 );
+
+  Preferences::getInstance()->setString( "multiplayer", "lastVisitedServer", this->ipInputLine->_getText() );
+
+  this->startLevel( 5 );
+}
+
+void GameMenu::createMasterServer( )
+{
+  PRINTF(0)("Create server\n" );
+
+  State::setOnline(true);
+  NetworkManager::getInstance()->createMasterServer( 9999 );
+
+  this->startLevel( 5 );
+}
+
+
+
Index: branches/heathaze/src/story_entities/menu/game_menu.h
===================================================================
--- branches/heathaze/src/story_entities/menu/game_menu.h	(revision 9940)
+++ branches/heathaze/src/story_entities/menu/game_menu.h	(revision 9940)
@@ -0,0 +1,122 @@
+/*!
+ * @file game_menu.h
+ *  a StoryEntity that contains a simple game menu
+ */
+
+#ifndef _GAME_MENU_H
+#define _GAME_MENU_H
+
+
+#include "game_world.h"
+#include "game_world_data.h"
+#include <vector>
+#include "glgui.h"
+
+namespace OrxSound { class SoundSource; }
+
+//! a simple game menu based on a story entity
+/**
+ * This is a simple menu, that is based on the StoryEntity. Therefore this menu is absolutly
+ * loadable and is exchangeable very easely :D
+ */
+class GameMenu : virtual public GameWorld, virtual public EventListener
+{
+  ObjectListDeclaration(GameMenu);
+  public:
+    GameMenu(const TiXmlElement* root = NULL);
+    virtual ~GameMenu();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual ErrorMessage init();
+    virtual ErrorMessage loadData();
+    virtual ErrorMessage unloadData();
+
+    virtual bool start();
+    virtual bool stop();
+
+    virtual void process(const Event &event);
+
+
+    void startLevel(int level);
+
+    void showMainMenu();
+    void showCampaigns();
+    void showMultiPlayer();
+    void showOptionsMenu();
+
+    void showClientMenu();
+    void connectToServer();
+
+    void showServerMenu();
+    void createMasterServer();
+
+
+    void quitMenu();
+
+  protected:
+    virtual void tick();
+    virtual void collide();
+
+
+  private:
+    void showSecondLevelElement(OrxGui::GLGuiBox* element);
+
+
+    void animateScene(float dt);
+    void switchMenuLayer(int layer1, int layer2);
+    void sliderTo(const Element2D* element, float bias = 0.0f);
+    void setSelectorSound(const std::string& selectorSound);
+
+
+
+
+  private:
+    OrxGui::GLGuiBox*                 mainMenuBox;
+    OrxGui::GLGuiBox*                 levelsBox;
+    OrxGui::GLGuiBox*                 networkBox;
+
+    OrxGui::GLGuiBox*                 clientNetworkBox;
+    OrxGui::GLGuiInputLine*           ipInputLine;
+
+    OrxGui::GLGuiBox*                 serverNetworkBox;
+
+    OrxGui::GLGuiBox*                 optionsBox;
+    OrxGui::GLGuiBox*                 generalBox;
+    OrxGui::GLGuiBox*                 audioBox;
+    OrxGui::GLGuiBox*                 videoBox;
+    OrxGui::GLGuiBox*                 controlBox;
+
+    OrxGui::GLGuiBox*                 currentlyOpened;
+
+    Vector                            cameraVector;
+
+    OrxSound::SoundSource*            selectorSource;
+};
+
+
+
+//! the simple game menu data
+class GameMenuData : public GameWorldData
+{
+
+  public:
+    GameMenuData();
+    virtual ~GameMenuData();
+
+    virtual ErrorMessage init();
+
+
+  protected:
+    virtual ErrorMessage loadGUI(const TiXmlElement* root);
+    virtual ErrorMessage loadWorldEntities(const TiXmlElement* root);
+    virtual ErrorMessage loadScene(const TiXmlElement* root);
+
+    virtual ErrorMessage unloadGUI();
+    virtual ErrorMessage unloadWorldEntities();
+    virtual ErrorMessage unloadScene();
+
+};
+
+
+#endif /* _GAME_WORLD_H */
Index: branches/heathaze/src/story_entities/menu/glgui_imagebutton.cc
===================================================================
--- branches/heathaze/src/story_entities/menu/glgui_imagebutton.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/menu/glgui_imagebutton.cc	(revision 9940)
@@ -0,0 +1,87 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+#include "glgui_imagebutton.h"
+
+#include "debug.h"
+
+namespace OrxGui
+{
+
+  GLGuiImageButton::GLGuiImageButton(const std::string& label, unsigned int levelID, const std::string& imageName, GLGuiImage* image)
+      : GLGuiPushButton(label)
+  {
+    this->imageName = imageName;
+    this->levelID = levelID;
+    this->image = image;
+
+    image->loadImageFromFile(imageName);
+  }
+
+  GLGuiImageButton::~GLGuiImageButton()
+  {}
+
+  void GLGuiImageButton::releasing(const Vector2D& pos, bool focused)
+  {
+    GLGuiPushButton::releasing(pos, focused);
+    if (focused)
+      this->startLevel.emit(this->levelID);
+  }
+
+  void GLGuiImageButton::receivedFocus()
+  {
+    PRINTF(4)("%s:: %s\n", this->label().c_str(), this->imageName.c_str());
+
+    this->image->loadImageFromFile(this->imageName);
+  }
+  void GLGuiImageButton::removedFocus()
+  {}
+
+
+  void GLGuiImageButton::showing()
+  {
+    GLGuiPushButton::showing();
+
+    //this->image->show();
+  }
+
+  void GLGuiImageButton::hiding()
+  {
+    GLGuiPushButton::hiding();
+
+    //this->image->hide();
+  }
+
+  bool GLGuiImageButton::processEvent(const Event& event)
+  {
+    if (event.type == SDLK_SPACE)
+    {
+      if (event.bPressed)
+  //      emit(pushed());
+        ;
+      else
+      {
+//        emit(released());
+        startLevel.emit(this->levelID);
+      }
+      return true;
+    }
+    return false;
+  }
+
+
+
+}
Index: branches/heathaze/src/story_entities/menu/glgui_imagebutton.h
===================================================================
--- branches/heathaze/src/story_entities/menu/glgui_imagebutton.h	(revision 9940)
+++ branches/heathaze/src/story_entities/menu/glgui_imagebutton.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file glgui_imagebutton.h
+ *
+ */
+
+#ifndef _GLGUI_IMAGEBUTTON_H
+#define _GLGUI_IMAGEBUTTON_H
+
+#include "glgui_pushbutton.h"
+#include "event_listener.h"
+
+#include "glgui_image.h"
+
+//! Namespace of the GLGuiImageButton of ORXONOX.
+namespace OrxGui
+{
+  class GLGuiImageButton : public GLGuiPushButton
+  {
+  public:
+    GLGuiImageButton(const std::string& label, unsigned int levelID, const std::string& imageName, GLGuiImage* image);
+    virtual ~GLGuiImageButton();
+
+
+    void push();
+    void release();
+
+    sigslot::signal1<int> startLevel;
+
+  protected:
+    virtual void releasing(const Vector2D& pos, bool focused);
+    virtual void receivedFocus();
+    virtual void removedFocus();
+
+    virtual void showing();
+    virtual void hiding();
+
+    virtual bool processEvent(const Event& event);
+  private:
+    unsigned int        levelID;
+    std::string         imageName;
+    GLGuiImage*         image;
+
+  private:
+
+  };
+
+}
+
+#endif /* _GLGUI_IMAGEBUTTON_H */
Index: branches/heathaze/src/story_entities/movie_loader.cc
===================================================================
--- branches/heathaze/src/story_entities/movie_loader.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/movie_loader.cc	(revision 9940)
@@ -0,0 +1,154 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: David Hasenfratz, Stefan Lienhard
+   co-programmer:
+*/
+
+#include "movie_loader.h"
+
+#include "movie_player.h"
+#include "util/loading/factory.h"
+#include "event_handler.h"
+#include "graphics_engine.h"
+#include "util/loading/load_param.h"
+#include "state.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(MovieLoader, CL_MOVIE_LOADER);
+CREATE_FACTORY(MovieLoader);
+
+MovieLoader::MovieLoader(const TiXmlElement* root)
+{
+  this->registerObject(this, MovieLoader::_objectList);
+
+  movie_player = new MoviePlayer();
+  this->loadParams(root);
+}
+
+MovieLoader::~MovieLoader()
+{
+  delete this->movie_player;
+}
+
+
+
+void MovieLoader::loadParams(const TiXmlElement* root)
+{
+  StoryEntity::loadParams(root);
+
+  LoadParam(root, "movie", this, MovieLoader, loadMovie);
+  LoadParam(root, "fps", this, MovieLoader, setFPS);
+}
+
+void MovieLoader::setFPS(float fps)
+{
+  this->movie_player->setFPS(fps);
+}
+
+void MovieLoader::loadMovie(const std::string& filename)
+{
+  movie_player->loadMovie(filename);
+}
+
+
+ErrorMessage MovieLoader::init() {}
+
+
+ErrorMessage MovieLoader::loadData() {}
+
+
+ErrorMessage MovieLoader::unloadData()
+{
+  this->unsubscribeEvents(ES_GAME);
+}
+
+bool MovieLoader::start()
+{
+  EventHandler::getInstance()->pushState(ES_GAME);
+
+  this->movie_player->start(0);
+
+  this->bRunning = true;
+  this->run();
+}
+
+bool MovieLoader::stop()
+{
+  EventHandler::getInstance()->popState();
+
+  this->bRunning = false;
+}
+
+bool MovieLoader::pause() { }
+bool MovieLoader::resume() { }
+
+void MovieLoader::run()
+{
+  // first timestamp for t = 0
+  this->lastFrame = SDL_GetTicks ();
+
+  while( this->bRunning)
+  {
+    EventHandler::getInstance()->process();
+    this->tick();
+    this->draw();
+  }
+}
+
+void MovieLoader::process(const Event &event) {}
+
+void MovieLoader::draw() const
+{
+  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+
+  GraphicsEngine::enter2DMode();
+
+  glPushAttrib(GL_ENABLE_BIT);
+  glEnable(GL_TEXTURE_2D);
+  glBindTexture(GL_TEXTURE_2D, movie_player->getTexture());
+
+  glColor3f(1.0, 1.0, 1.0);
+
+  glBegin(GL_QUADS);
+    glTexCoord2f(0.0f, 0.0f); glVertex2f( 0, 0);
+    glTexCoord2f(0.0f, 1.0f); glVertex2f( 0, State::getResY());
+    glTexCoord2f(1.0f, 1.0f); glVertex2f( State::getResX(), State::getResY());
+    glTexCoord2f(1.0f, 0.0f); glVertex2f( State::getResX(), 0);
+  glEnd();
+
+  glPopAttrib();
+  GraphicsEngine::leave2DMode();
+
+  SDL_GL_SwapBuffers();
+}
+
+
+void MovieLoader::tick()
+{
+  // get timestamp
+  currentFrame = SDL_GetTicks();
+
+  // calculate time difference in milliseconds (Uint32)
+  this->dt = currentFrame - this->lastFrame;
+  // calculate time difference in seconds (float)
+  this->dts = (float)this->dt / 1000.0f;
+
+  movie_player->tick(dts);
+
+  if (movie_player->getStatus() == STOP)
+    this->bRunning = false;
+
+  this->lastFrame = currentFrame;
+}
Index: branches/heathaze/src/story_entities/movie_loader.h
===================================================================
--- branches/heathaze/src/story_entities/movie_loader.h	(revision 9940)
+++ branches/heathaze/src/story_entities/movie_loader.h	(revision 9940)
@@ -0,0 +1,53 @@
+/*!
+ * @file movie_loader.h
+ *  loads a movie
+ */
+
+#ifndef _MOVIE_LOADER_H
+#define _MOVIE_LOADER_H
+
+
+#include "story_entity.h"
+#include "event_listener.h"
+
+class MoviePlayer;
+
+class MovieLoader : public StoryEntity, virtual public EventListener
+{
+  ObjectListDeclaration(MovieLoader);
+  private:
+    MoviePlayer* movie_player;
+
+    Uint32              lastFrame;
+    Uint32              currentFrame;
+    Uint32              dt;                           // time needed to calculate this frame (in milliSeconds)
+    float               dts;
+
+  public:
+    MovieLoader(const TiXmlElement* root);
+    virtual ~MovieLoader();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    /* functions from story-entity */
+    virtual ErrorMessage init();
+    virtual ErrorMessage loadData();
+    virtual ErrorMessage unloadData();
+
+    virtual bool start();
+    virtual bool stop();
+    virtual bool pause();
+    virtual bool resume();
+    virtual void run();
+
+    virtual void process(const Event &event);
+
+  private:
+    void loadMovie(const std::string& filename);
+    void setFPS(float fps);
+    void tick();
+    void draw() const;
+
+};
+
+#endif /* _MOVIE_LOADER_H */
Index: branches/heathaze/src/story_entities/multi_player_world.cc
===================================================================
--- branches/heathaze/src/story_entities/multi_player_world.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/multi_player_world.cc	(revision 9940)
@@ -0,0 +1,165 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "multi_player_world.h"
+#include "multi_player_world_data.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+#include "shell_command.h"
+
+#include "cd_engine.h"
+
+#include "network_manager.h"
+#include "network_game_manager.h"
+
+#include "state.h"
+
+
+#include "glgui_handler.h"
+
+//! Register a command to print some multiplayer world infos
+SHELL_COMMAND(debug, MultiPlayerWorld, debug);
+
+#include "class_id_DEPRECATED.h"
+//! This creates a Factory to fabricate a MultiPlayerWorld
+ObjectListDefinitionID(MultiPlayerWorld, CL_MULTI_PLAYER_WORLD);
+CREATE_FACTORY(MultiPlayerWorld);
+
+MultiPlayerWorld::MultiPlayerWorld(const TiXmlElement* root)
+  : GameWorld()
+{
+  this->registerObject(this, MultiPlayerWorld::_objectList);
+
+  this->dataTank = new MultiPlayerWorldData();
+
+  this->loadParams(root);
+}
+
+
+/**
+ *  remove the MultiPlayerWorld from memory
+ *
+ *  delete everything explicitly, that isn't contained in the parenting tree!
+ *  things contained in the tree are deleted automaticaly
+ */
+MultiPlayerWorld::~MultiPlayerWorld ()
+{
+  PRINTF(3)("MultiPlayerWorld::~MultiPlayerWorld() - deleting current world\n");
+  if( this->dataTank)
+    delete this->dataTank;
+  OrxGui::GLGuiHandler::deleteInstance( );
+}
+
+
+/**
+ * loads the parameters of a MultiPlayerWorld from an XML-element
+ * @param root the XML-element to load from
+ */
+void MultiPlayerWorld::loadParams(const TiXmlElement* root)
+{
+  GameWorld::loadParams(root);
+
+  PRINTF(4)("Creating a MultiPlayerWorld\n");
+}
+
+
+/**
+ *  synchronizes the network since this is a network world
+ *
+ * this function overrides the synchrinize from the GameWorld
+ */
+void MultiPlayerWorld::synchronize()
+{
+  NetworkManager::getInstance()->synchronize(this->dtS);
+}
+
+
+/**
+ * kicks the CDEngine to detect the collisions between the object groups in the world
+ */
+void MultiPlayerWorld::collisionDetection()
+{
+  //CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_PLAYERS), this->dataTank->objectManager->getEntityList(OM_PLAYERS));
+
+  PRINTF(5)("\n-----------------------------------------\nchecking OM_PLAYERS vs OM_GROUP_01_PROJ\n\n");
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_PLAYERS),
+    this->dataTank->objectManager->getEntityList(OM_GROUP_00_PROJ));
+  PRINTF(5)("\n-----------------------------------------\nchecking OM_PLAYERS vs OM_GROUP_01_PROJ\n\n");
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_PLAYERS),
+    this->dataTank->objectManager->getEntityList(OM_GROUP_01_PROJ));
+  PRINTF(5)("\n-----------------------------------------\nchecking OM_PLAYERS vs OM_PLAYERS_PROJ\n\n");
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_PLAYERS),
+    this->dataTank->objectManager->getEntityList(OM_PLAYERS_PROJ));
+
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_00),
+  this->dataTank->objectManager->getEntityList(OM_PLAYERS));
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_01),
+  this->dataTank->objectManager->getEntityList(OM_PLAYERS));
+
+
+
+  PRINTF(5)("\n-----------------------------------------\nchecking OM_GROUP_00 vs OM_GROUP_01_PROJ\n\n");
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_00),
+    this->dataTank->objectManager->getEntityList(OM_GROUP_01_PROJ));
+  PRINTF(5)("\n-----------------------------------------\nchecking OM_GROUP_00 vs OM_GROUP_01\n\n");
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_00),
+    this->dataTank->objectManager->getEntityList(OM_GROUP_01));
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_00),
+    this->dataTank->objectManager->getEntityList(OM_PLAYERS_PROJ));
+
+  PRINTF(5)("\n-----------------------------------------\nchecking OM_GROUP_01 vs OM_GROUP_00_PROJ\n\n");
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_01),
+    this->dataTank->objectManager->getEntityList(OM_GROUP_00_PROJ));
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_01),
+    this->dataTank->objectManager->getEntityList(OM_GROUP_00));
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getEntityList(OM_GROUP_01),
+    this->dataTank->objectManager->getEntityList(OM_PLAYERS_PROJ));
+
+
+
+    // ground collision detection: BSP Model
+  CDEngine::getInstance()->checkCollisionGround(this->dataTank->objectManager->getEntityList(OM_GROUP_00));
+  CDEngine::getInstance()->checkCollisionGround(this->dataTank->objectManager->getEntityList(OM_GROUP_01));
+  CDEngine::getInstance()->checkCollisionGround(this->dataTank->objectManager->getEntityList(OM_PLAYERS));
+}
+
+
+/**
+ * some debug ouptut - shell command
+ */
+void MultiPlayerWorld::debug()
+{
+  ((MultiPlayerWorldData*)this->dataTank)->debug();
+}
+
+/**
+ * cleanup
+ * @return
+ */
+ErrorMessage MultiPlayerWorld::unloadData( )
+{
+
+  GameWorld::unloadData();
+
+  delete NetworkManager::getInstance();
+  delete NetworkGameManager::getInstance();
+
+  State::setOnline( false );
+
+  return ErrorMessage();
+}
Index: branches/heathaze/src/story_entities/multi_player_world.h
===================================================================
--- branches/heathaze/src/story_entities/multi_player_world.h	(revision 9940)
+++ branches/heathaze/src/story_entities/multi_player_world.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file multi_player_world.h
+  *  Holds and manages all game data
+*/
+
+#ifndef _MULTI_PLAYER_WORLD_H
+#define _MULTI_PLAYER_WORLD_H
+
+#include "game_world.h"
+
+
+class TiXmlElement;
+class MultiPlayerWorldData;
+
+
+//! The multiplayer game world
+/**
+ *  this class initializes everything that should be displayed inside of the current level.
+ *  it is the main driving factor during gameplay.
+ */
+class MultiPlayerWorld : public GameWorld {
+  ObjectListDeclaration(MultiPlayerWorld);
+ public:
+  MultiPlayerWorld (const TiXmlElement* root = NULL);
+  virtual ~MultiPlayerWorld ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual ErrorMessage unloadData();
+
+  void debug();
+
+  protected:
+    virtual void synchronize();
+    virtual void collisionDetection();
+};
+
+#endif /* _MULTI_PLAYER_WORLD_H */
Index: branches/heathaze/src/story_entities/multi_player_world_data.cc
===================================================================
--- branches/heathaze/src/story_entities/multi_player_world_data.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/multi_player_world_data.cc	(revision 9940)
@@ -0,0 +1,362 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "multi_player_world_data.h"
+
+#include "state.h"
+#include "substring.h"
+
+#include "util/loading/game_loader.h"
+#include "cd_engine.h"
+
+#include "p_node.h"
+#include "world_entity.h"
+#include "player.h"
+#include "camera.h"
+#include "environment.h"
+#include "terrain.h"
+#include "test_entity.h"
+#include "terrain.h"
+#include "md2/md2Model.h"
+#include "world_entities/projectiles/projectile.h"
+#include "npcs/npc_test1.h"
+#include "playable.h"
+
+#include "util/loading/factory.h"
+#include "loading/fast_factory.h"
+#include "util/loading/load_param.h"
+
+#include "network_manager.h"
+#include "network_game_manager.h"
+#include "player_stats.h"
+
+#include "proxy/network_settings.h"
+
+#include "glmenu_imagescreen.h"
+
+
+/**
+ * constructor of the GameWorldDataData
+ */
+MultiPlayerWorldData::MultiPlayerWorldData()
+    : GameWorldData()
+{
+  this->toggle = false;
+}
+
+
+/**
+ * destructor for the GameWorldDataData
+ */
+MultiPlayerWorldData::~MultiPlayerWorldData()
+{}
+
+
+/**
+ *  initialize the GameWorldDataData
+ */
+ErrorMessage MultiPlayerWorldData::init()
+{
+  /* call underlying function */
+  return GameWorldData::init();
+}
+
+
+/**
+ *  loads the GUI data
+ * @param root reference to the xml root element
+ */
+ErrorMessage MultiPlayerWorldData::loadGUI(const TiXmlElement* root)
+{
+  /* call underlying function */
+  return GameWorldData::loadGUI(root);
+}
+
+
+/**
+ *  unloads the GUI data
+ */
+ErrorMessage MultiPlayerWorldData::unloadGUI()
+{
+  /* call underlying function */
+  return GameWorldData::unloadGUI();
+}
+
+
+/**
+ *  overloads the GameWorld::loadWorldEntities(...) class since the network WorldEntity loading is different
+ * @param root reference to the xml root parameter
+ */
+ErrorMessage MultiPlayerWorldData::loadWorldEntities(const TiXmlElement* root)
+{
+  const TiXmlElement* element = NULL;
+
+  if( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
+  {
+    /* load the spawning points */
+    element = root->FirstChildElement("SpawningPoints");
+    if( element == NULL)
+    {
+      PRINTF(1)("NetworkWorld is missing 'SpawningPoints'\n");
+    }
+    else
+    {
+      element = element->FirstChildElement();
+      // load Players/Objects/Whatever
+      PRINTF(4)("Loading Spawning Points\n");
+      while( element != NULL)
+      {
+        BaseObject* created = Factory::fabricate(element);
+        if( created != NULL )
+          printf("Created a Spawning Point %s: %s\n", created->getClassCName(), created->getCName());
+
+        element = element->NextSiblingElement();
+        glmis->step();
+      }
+      PRINTF(4)("Done loading Spawning Points\n");
+    }
+  }
+
+  /* load the WorldEntities */
+  element = root->FirstChildElement("WorldEntities");
+  if( element == NULL)
+  {
+    PRINTF(1)("NetworkWorld is missing 'WorldEntities'\n");
+  }
+  else
+  {
+    element = element->FirstChildElement();
+
+    if( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
+    {
+      while( element != NULL)
+      {
+        /* pass the entity to the NetworkGameManager to be created */
+        BaseObject* created = Factory::fabricate(element);
+        if( created != NULL )
+          PRINTF(1)("Created a %s: %s (0x%8x) from %s\n", created->getClassCName(), created->getCName(), created->getLeafClassID(), element->Value());
+        else
+          PRINTF(1)("NetworkWorld: could not create this entity\n");
+
+        if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox"))
+          this->sky = dynamic_cast<WorldEntity*>(created);
+        if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
+        {
+          this->terrain = dynamic_cast<Terrain*>(created);
+          CDEngine::getInstance()->setTerrain(terrain);
+        }
+
+        element = element->NextSiblingElement();
+
+
+        glmis->step();
+        PRINTF(4)("Done loading NetworkWorldEntities\n");
+      }
+    }
+    else
+    {
+      while( element != NULL)
+      {
+        PRINTF(0)("load: %s\n", element->Value());
+        if( !strcmp(element->Value(), "Terrain") || !strcmp(element->Value(), "Building")  )
+        {
+
+          /* pass the entity to the NetworkGameManager to be created */
+          BaseObject* created = Factory::fabricate(element);
+
+          if( created != NULL )
+            PRINTF(1)("Created a %s: %s (0x%8x) from %s\n", created->getClassCName(), created->getCName(), created->getLeafClassID(), element->Value());
+          else
+            PRINTF(1)("NetworkWorld: could not create this entity\n");
+
+          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox"))
+            this->sky = dynamic_cast<WorldEntity*>(created);
+          if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
+          {
+            this->terrain = dynamic_cast<Terrain*>(created);
+            CDEngine::getInstance()->setTerrain(terrain);
+          }
+
+          glmis->step();
+          PRINTF(4)("Done loading NetworkWorldEntities\n");
+        }
+        element = element->NextSiblingElement();
+      }
+    }
+
+
+    if( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
+    {
+      this->localPlayer = new Player();
+
+#if 0
+      Playable* playable;
+      const std::list<BaseObject*>* playableList = ClassList::getList(CL_PLAYABLE);
+      assert( playableList != NULL);
+
+      if (playableList != NULL)
+      {
+        playable = dynamic_cast<Playable*>(playableList->front());
+        this->localPlayer->setPlayable(playable);
+        playable->toList(OM_GROUP_00);
+        playable->setAbsCoor(213.37, 57.71, -47.98);
+        playable->setPlayDirection(Quaternion(M_PI, Vector(0.0, 1.0, 0.0)));
+      }
+#endif
+    }
+    else
+    {
+      /* create a Player */
+      this->localPlayer = new Player();
+    }
+
+
+    /* init the pnode tree */
+    PNode::getNullParent()->init();
+  }
+    // Fill the EntityLists. Tick then Draw:
+  this->tickLists.push_back(OM_DEAD_TICK);
+  this->tickLists.push_back(OM_ENVIRON);
+  this->tickLists.push_back(OM_COMMON);
+  this->tickLists.push_back(OM_PLAYERS);
+  this->tickLists.push_back(OM_PLAYERS_PROJ);
+  this->tickLists.push_back(OM_GROUP_00);
+  this->tickLists.push_back(OM_GROUP_00_PROJ);
+  this->tickLists.push_back(OM_GROUP_01);
+  this->tickLists.push_back(OM_GROUP_01_PROJ);
+
+  this->drawLists.push_back(OM_ENVIRON_NOTICK);
+  this->drawLists.push_back(OM_ENVIRON);
+  this->drawLists.push_back(OM_COMMON);
+  this->drawLists.push_back(OM_PLAYERS);
+  this->drawLists.push_back(OM_PLAYERS_PROJ);
+  this->drawLists.push_back(OM_GROUP_00);
+  this->drawLists.push_back(OM_GROUP_00_PROJ);
+  this->drawLists.push_back(OM_GROUP_01);
+  this->drawLists.push_back(OM_GROUP_01_PROJ);
+
+  State::setPlayer(this->localPlayer);
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  unloads the world entities from the xml file
+ */
+ErrorMessage MultiPlayerWorldData::unloadWorldEntities()
+{
+  /* call underlying function */
+  return GameWorldData::unloadWorldEntities();
+}
+
+
+/**
+ *  loads the scene data
+ * @param root reference to the xml root element
+ */
+ErrorMessage MultiPlayerWorldData::loadScene(const TiXmlElement* root)
+{
+  /* call underlying function */
+  GameWorldData::loadScene(root);
+
+//   LoadParamXML(root, "NetworkSettings", NetworkSettings::getInstance(), NetworkSettings, loadNetworkSettings);
+
+  // create server playable
+  if ( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
+  {
+    NetworkGameManager::getInstance()->signalNewPlayer( 0 );
+    State::getPlayer()->setPlayable( PlayerStats::getStats( 0 )->getPlayable() );
+  }
+
+  return ErrorMessage();
+}
+
+
+/**
+ *  unloads the scene data
+ */
+ErrorMessage MultiPlayerWorldData::unloadScene()
+{
+  // delete the proxy settings
+  delete NetworkSettings::getInstance();
+
+  /* call underlying function */
+  return GameWorldData::unloadScene();
+}
+
+
+/**
+ * some debug output
+ */
+void MultiPlayerWorldData::debug()
+{
+  PRINT(0)("==================================================\n");
+
+  Playable* playable;
+
+  for (ObjectList<Playable>::const_iterator entity = Playable::objectList().begin();
+       entity != Playable::objectList().end();
+      ++entity)
+  {
+    Playable* p = *entity;
+    PRINTF(0)("Got a playable, class: %s, name: %s, uid: %i\n", (*entity)->getClassCName(), (*entity)->getCName(), p->getUniqueID());
+  }
+
+
+  if( this->toggle)
+  {
+    playable = Playable::objectList().front();
+    this->localPlayer->setPlayable(playable);
+    this->toggle = !this->toggle;
+  }
+  else
+  {
+    playable = Playable::objectList().back();
+    this->localPlayer->setPlayable(playable);
+    this->toggle = !this->toggle;
+  }
+
+
+  Playable* pl = this->localPlayer->getPlayable();
+  PRINTF(0)("The current regisered playable is hid: %i\n", pl->getUniqueID());
+
+
+  PNode* cam = State::getCameraTargetNode();
+  PRINT(0)("Camera has target - class: %s, name: %s, uid: %i\n", cam->getClassCName(), cam->getCName(), cam->getUniqueID());
+
+  PRINT(0)("==================================================\n");
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: branches/heathaze/src/story_entities/multi_player_world_data.h
===================================================================
--- branches/heathaze/src/story_entities/multi_player_world_data.h	(revision 9940)
+++ branches/heathaze/src/story_entities/multi_player_world_data.h	(revision 9940)
@@ -0,0 +1,42 @@
+/*!
+ * @file multi_player_world_data.h
+ *  container for all multiplayer game world data
+ */
+
+#ifndef _MULTI_PLAYER_WORLD_DATA_H
+#define _MULTI_PLAYER_WORLD_DATA_H
+
+
+#include "game_world_data.h"
+
+
+class TiXmlElement;
+
+
+//! The multiplayer world data
+class MultiPlayerWorldData : public GameWorldData
+{
+
+  public:
+    MultiPlayerWorldData();
+    virtual ~MultiPlayerWorldData();
+
+    virtual ErrorMessage init();
+
+    void debug();
+
+
+  protected:
+    virtual ErrorMessage loadGUI(const TiXmlElement* root);
+    virtual ErrorMessage loadWorldEntities(const TiXmlElement* root);
+    virtual ErrorMessage loadScene(const TiXmlElement* root);
+
+    virtual ErrorMessage unloadGUI();
+    virtual ErrorMessage unloadWorldEntities();
+    virtual ErrorMessage unloadScene();
+
+  private:
+    bool toggle;
+};
+
+#endif /* _MULTI_PLAYER_WORLD_DATA_H */
Index: branches/heathaze/src/story_entities/single_player_world.cc
===================================================================
--- branches/heathaze/src/story_entities/single_player_world.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/single_player_world.cc	(revision 9940)
@@ -0,0 +1,74 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "single_player_world.h"
+#include "single_player_world_data.h"
+
+#include "state.h"
+#include "debug.h"
+
+#include "util/loading/load_param.h"
+#include "loading/fast_factory.h"
+#include "util/loading/factory.h"
+
+#include "world_entity.h"
+#include "npcs/npc_test1.h"
+
+
+#include "class_id_DEPRECATED.h"
+//! This creates a Factory to fabricate a SinglePlayerWorld
+ObjectListDefinitionID(SinglePlayerWorld, CL_SINGLE_PLAYER_WORLD);
+CREATE_FACTORY(SinglePlayerWorld);
+
+SinglePlayerWorld::SinglePlayerWorld(const TiXmlElement* root)
+  : GameWorld()
+{
+  this->registerObject(this, SinglePlayerWorld::_objectList);
+  this->setName("SinglePlayerWorld uninitialized");
+
+  this->dataTank = new SinglePlayerWorldData();
+
+  this->loadParams(root);
+}
+
+
+/**
+ *  remove the SinglePlayerWorld from memory
+ *
+ *  delete everything explicitly, that isn't contained in the parenting tree!
+ *  things contained in the tree are deleted automaticaly
+ */
+SinglePlayerWorld::~SinglePlayerWorld ()
+{
+  PRINTF(3)("SinglePlayerWorld::~SinglePlayerWorld() - deleting current world\n");
+
+  if( this->dataTank)
+    delete this->dataTank;
+}
+
+
+/**
+ * loads the parameters of a SinglePlayerWorld from an XML-element
+ * @param root the XML-element to load from
+ */
+void SinglePlayerWorld::loadParams(const TiXmlElement* root)
+{
+  GameWorld::loadParams(root);
+
+  PRINTF(4)("Loaded SinglePlayerWorld specific stuff\n");
+}
+
Index: branches/heathaze/src/story_entities/single_player_world.h
===================================================================
--- branches/heathaze/src/story_entities/single_player_world.h	(revision 9940)
+++ branches/heathaze/src/story_entities/single_player_world.h	(revision 9940)
@@ -0,0 +1,33 @@
+/*!
+ * @file single_player_world.h
+ *  Holds and manages all single player game data
+ */
+
+#ifndef _SINGLE_PLAYER_WORLD_H
+#define _SINGLE_PLAYER_WORLD_H
+
+
+#include "game_world.h"
+
+
+class TiXmlElement;
+class SinglePlayerWorldData;
+
+
+//! The game world
+/**
+ *  this class initializes everything that should be displayed inside of the current level.
+ *  it is the main driving factor during gameplay.
+ */
+class SinglePlayerWorld : public GameWorld
+{
+  ObjectListDeclaration(SinglePlayerWorld);
+
+  public:
+    SinglePlayerWorld (const TiXmlElement* root = NULL);
+    virtual ~SinglePlayerWorld ();
+
+    virtual void loadParams(const TiXmlElement* root);
+};
+
+#endif /* _SINGLE_PLAYER_WORLD_H */
Index: branches/heathaze/src/story_entities/single_player_world_data.cc
===================================================================
--- branches/heathaze/src/story_entities/single_player_world_data.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/single_player_world_data.cc	(revision 9940)
@@ -0,0 +1,112 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "single_player_world_data.h"
+
+#include "util/loading/load_param.h"
+
+
+
+
+
+/**
+ * constructor of the GameWorldDataData
+ */
+SinglePlayerWorldData::SinglePlayerWorldData()
+  : GameWorldData()
+{}
+
+
+/**
+ * destructor for the GameWorldDataData
+ */
+SinglePlayerWorldData::~SinglePlayerWorldData()
+{}
+
+
+/**
+ *  initialize the GameWorldDataData
+ */
+ErrorMessage SinglePlayerWorldData::init()
+{
+  /* call underlying function */
+  return GameWorldData::init();
+}
+
+
+/**
+ *  loads the GUI data
+ * @param root reference to the xml root element
+ */
+ErrorMessage SinglePlayerWorldData::loadGUI(const TiXmlElement* root)
+{
+  /* call underlying function */
+  return GameWorldData::loadGUI(root);
+}
+
+
+/**
+ *  unloads the GUI data
+ */
+ErrorMessage SinglePlayerWorldData::unloadGUI()
+{
+  /* call underlying function */
+  return GameWorldData::unloadGUI();
+}
+
+
+/**
+ *  overloads the GameWorld::loadWorldEntities(...) class since the network WorldEntity loading is different
+ * @param root reference to the xml root parameter
+ */
+ErrorMessage SinglePlayerWorldData::loadWorldEntities(const TiXmlElement* root)
+{
+  /* call underlying function */
+  return GameWorldData::loadWorldEntities(root);
+}
+
+
+/**
+ *  unloads the world entities from the xml file
+ */
+ErrorMessage SinglePlayerWorldData::unloadWorldEntities()
+{
+  /* call underlying function */
+  return GameWorldData::unloadWorldEntities();
+}
+
+
+/**
+ *  loads the scene data
+ * @param root reference to the xml root element
+ */
+ErrorMessage SinglePlayerWorldData::loadScene(const TiXmlElement* root)
+{
+  /* call underlying function */
+  return GameWorldData::loadScene(root);
+}
+
+
+/**
+ *  unloads the scene data
+ */
+ErrorMessage SinglePlayerWorldData::unloadScene()
+{
+  /* call underlying function */
+  return GameWorldData::unloadScene();
+}
+
Index: branches/heathaze/src/story_entities/single_player_world_data.h
===================================================================
--- branches/heathaze/src/story_entities/single_player_world_data.h	(revision 9940)
+++ branches/heathaze/src/story_entities/single_player_world_data.h	(revision 9940)
@@ -0,0 +1,37 @@
+/*!
+ * @file single_player_world_data.h
+ *  container for all singleplayer game world data
+ */
+
+#ifndef _SINGLE_PLAYER_WORLD_DATA_H
+#define _SINGLE_PLAYER_WORLD_DATA_H
+
+
+#include "game_world_data.h"
+
+
+class TiXmlElement;
+
+
+//! The singleplayer world data
+class SinglePlayerWorldData : public GameWorldData
+{
+
+  public:
+    SinglePlayerWorldData();
+    virtual ~SinglePlayerWorldData();
+
+    virtual ErrorMessage init();
+
+
+  protected:
+    virtual ErrorMessage loadGUI(const TiXmlElement* root);
+    virtual ErrorMessage loadWorldEntities(const TiXmlElement* root);
+    virtual ErrorMessage loadScene(const TiXmlElement* root);
+
+    virtual ErrorMessage unloadGUI();
+    virtual ErrorMessage unloadWorldEntities();
+    virtual ErrorMessage unloadScene();
+};
+
+#endif /* _SINGLE_PLAYER_WORLD_DATA_H */
Index: branches/heathaze/src/story_entities/story_def.h
===================================================================
--- branches/heathaze/src/story_entities/story_def.h	(revision 9940)
+++ branches/heathaze/src/story_entities/story_def.h	(revision 9940)
@@ -0,0 +1,27 @@
+
+#ifndef _STORY_DEF_H
+#define _STORY_DEF_H
+
+
+#define DEBUG_CAMPAIGN_0 1000
+#define DEBUG_CAMPAIGN_1 1001
+#define DEBUG_CAMPAIGN_2 1002
+
+#define DEBUG_WORLD_0 100
+#define DEBUG_WORLD_1 101
+#define DEBUG_WORLD_2 102
+
+
+#define WORLD_ID_0 0
+#define WORLD_ID_1 1
+#define WORLD_ID_2 2
+#define WORLD_ID_3 3
+#define WORLD_ID_4 4
+#define WORLD_ID_5 5
+
+#define WORLD_ID_MENU    0
+#define WORLD_ID_GAMEEND 999
+
+#define MAX_STORY_ENTITIES 99 //!< maximal StoryEntities in a Campaign
+
+#endif /* _STORY_DEF_H */
Index: branches/heathaze/src/story_entities/story_entity.cc
===================================================================
--- branches/heathaze/src/story_entities/story_entity.cc	(revision 9940)
+++ branches/heathaze/src/story_entities/story_entity.cc	(revision 9940)
@@ -0,0 +1,187 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "story_entity.h"
+
+#include "loading/load_param.h"
+#include "loading/resource_manager.h"
+
+#include "debug.h"
+
+ObjectListDefinition(StoryEntity);
+
+/**
+ *  default constructor initializes all needed data
+ */
+StoryEntity::StoryEntity ()
+{
+  this->registerObject(this, StoryEntity::_objectList);
+
+  this->bInit = false;
+  this->bPaused = false;
+  this->bRunning = false;
+
+  this->loadFile = "";
+  this->storyID = -1;
+  this->description = "";
+  this->menuItemImage = "";
+  this->menuScreenshoot = "";
+  this->nextStoryID = WORLD_ID_GAMEEND;
+  this->bMenuEntry = false;
+}
+
+
+/**
+ *  deconstructor
+ */
+StoryEntity::~StoryEntity ()
+{}
+
+
+/**
+ *  loads the Parameters of a Campaign
+ * @param root: The XML-element to load from
+ */
+void StoryEntity::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+
+  LoadParam(root, "identifier", this, StoryEntity, setStoryID)
+  .describe("A Unique Identifier for this StoryEntity");
+
+  LoadParam(root, "path", this, StoryEntity, setLoadFile)
+  .describe("DEPRICATED FORM OF file. The Filename of this StoryEntity (relative from the data-dir)");
+
+  LoadParam(root, "file", this, StoryEntity, setLoadFile)
+  .describe("The Filename of this StoryEntity (relative from the data-dir)");
+
+  LoadParam(root, "nextid", this, StoryEntity, setNextStoryID)
+  .describe("Sets the ID of the next StoryEntity");
+
+  LoadParam(root, "menu-entry", this, StoryEntity, addToGameMenu)
+      .describe("If this entry is 1, the world is contained in the SimpleGameMenu");
+
+
+
+  // so we can also do these things in the Campaign. (will be overwritten from the entities file)
+  LoadParam(root, "description", this, StoryEntity, setDescription)
+      .describe("Sets the description of this StoryEntity");
+
+  LoadParam(root, "menu-item-image", this, StoryEntity, setMenuItemImage)
+      .describe("If this entry is 1, the world is contained in the SimpleGameMenu");
+
+  LoadParam(root, "screenshoot", this, StoryEntity, setMenuScreenshoot)
+      .describe("If this entry is 1, the world is contained in the SimpleGameMenu");
+
+  PRINTF(4)("Loaded StoryEntity specific stuff\n");
+}
+
+
+/**
+ *  sets the track path of this world
+ * @param name the name of the path
+ */
+void StoryEntity::setLoadFile(const std::string& fileName)
+{
+  if (File(fileName).isFile())
+  {
+    this->loadFile =  fileName;
+  }
+  else
+    this->loadFile = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(fileName);
+
+  this->grabWorldInfo();
+}
+
+
+/**
+ * sets the descroption of this StoryEntity
+ * @param name name
+ */
+void StoryEntity::setDescription(const std::string& description)
+{
+  this->description = description;
+}
+
+/**
+ * sets the id of the next story entity: StoryEntities can choose their following entity themselfs.
+ * the entity id defined here  will be startet after this entity ends. this can be convenient if you
+ * want to have a non linear story with switches.
+ * @param nextStoryID the story id of the next StoryEntity
+ */
+void StoryEntity::setNextStoryID(int nextStoryID)
+{
+  this->nextStoryID = nextStoryID;
+}
+
+/**
+ * @brief grabs settings needed for displaying a MenuScreen.
+ */
+void StoryEntity::grabWorldInfo()
+{
+  PRINTF(3)("Grabbing the Worlds Settings\n", this->getLoadFile().c_str());
+  if( getLoadFile().empty())
+        return;
+  TiXmlDocument XMLDoc(this->getLoadFile());
+  // load the xml world file for further loading
+  if( !XMLDoc.LoadFile())
+  {
+    PRINTF(1)("loading XML File: %s @ %s:l%d:c%d\n", XMLDoc.ErrorDesc(), this->getLoadFile().c_str(), XMLDoc.ErrorRow(), XMLDoc.ErrorCol());
+    return;
+  }
+  TiXmlElement* root = XMLDoc.RootElement();
+  if (root == NULL)
+    return;
+
+  if (root->Value() != NULL && !strcmp(root->Value(), "WorldDataFile"))
+  {
+    BaseObject::loadParams(root);
+
+    LoadParam(root, "description", this, StoryEntity, setDescription)
+    .describe("Sets the description of this StoryEntity");
+
+    LoadParam(root, "menu-item-image", this, StoryEntity, setMenuItemImage)
+    .describe("If this entry is 1, the world is contained in the SimpleGameMenu");
+
+    LoadParam(root, "screenshoot", this, StoryEntity, setMenuScreenshoot)
+    .describe("If this entry is 1, the world is contained in the SimpleGameMenu");
+  }
+}
+
+/**
+ * sets the menu item image of this StoryEntity
+ * @param name name
+ */
+void StoryEntity::setMenuItemImage(const std::string& image)
+{
+  this->menuItemImage = image;
+}
+
+
+/** sets the menu screenshoot of this StoryEntity
+ * @param name name
+ */
+void StoryEntity::setMenuScreenshoot(const std::string& image)
+{
+  this->menuScreenshoot = image;
+}
+
+
Index: branches/heathaze/src/story_entities/story_entity.h
===================================================================
--- branches/heathaze/src/story_entities/story_entity.h	(revision 9940)
+++ branches/heathaze/src/story_entities/story_entity.h	(revision 9940)
@@ -0,0 +1,106 @@
+/*!
+ * @file story_entity.h
+ *  holds the base class of everything that is playable - that is part of the story
+ */
+
+
+#ifndef _STORY_ENTITY_H
+#define _STORY_ENTITY_H
+
+#include "base_object.h"
+#include "story_def.h"
+#include "error.h"
+
+
+typedef enum StoryEntityState
+{
+  SE_STATE_RUN     = 0,
+  SE_STATE_STOP,
+  SE_STATE_PAUSE,
+
+  SE_STATE_NUM
+};
+
+
+//! A class that represents something to play in orxonox. it is a container for worlds, movies, mission briefings, etc...
+class StoryEntity : virtual public BaseObject
+{
+  ObjectListDeclaration(StoryEntity);
+
+public:
+  StoryEntity ();
+  virtual ~StoryEntity ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  /* initialisation and loading */
+  /** initializes a Story Entity to the needed values */
+  virtual ErrorMessage init() { return ErrorMessage(); };
+  /** called to load the data into the StoryEntity*/
+  virtual ErrorMessage loadData() { return ErrorMessage(); };
+  /** function that unloads the data from the StoryEntity */
+  virtual ErrorMessage unloadData() { return ErrorMessage(); };
+
+  /* running, stopping and pausing */
+  /** starts the Entity. Starts the main cycle */
+  virtual bool start() = 0;
+  /**  Stops the entity. */
+  virtual bool stop() = 0;
+  /** pauses the Entity, you can resume the game by calling the resume() function */
+  virtual bool pause() = 0;
+  /** resumes a paused StoryEntity */
+  virtual bool resume() = 0;
+  /** function that is been called when the StoryEntity is started via start() */
+  virtual void run() = 0;
+
+  /* properties interface */
+  /** returns the state of this StoryEntity */
+  StoryEntityState getState();
+
+  /** sets the story id of the current entity, this enables it to be identified in a global context.  @param storyID the story id */
+  inline void setStoryID(int storyID) { this->storyID = storyID; }
+  /** sets the story id of the current entity, this enables it to be identified in a  global context. @returns  the story id  */
+  inline int getStoryID() { return this->storyID; }
+
+  void setLoadFile(const std::string& fileName);
+  /** @returns the Filename this StoryEntity was loaded with */
+  const std::string& getLoadFile() const { return this->loadFile; }
+
+  void setNextStoryID(int nextStoryID);
+  /**  gets the story id of the current entity @returns story id */
+  inline int getNextStoryID() const { return this->nextStoryID; }
+  inline void setDescription(const std::string& description);
+  /** @returns the description of this StoryEntity */
+  inline const std::string& getDescription() { return this->description; }
+
+  void grabWorldInfo();
+  /** toggle the menu visibility: SimpleMenu specific */
+  inline void addToGameMenu(bool toggle) { this->bMenuEntry = toggle; }
+  /** @returns true if the GameWorld should be contained in the SimpleMenu: SimpleMenu specific */
+  inline bool isContainedInMenu() { return this->bMenuEntry; }
+  /** sets the menu item image of this StoryEntity @param name name */
+  inline void setMenuItemImage(const std::string& image);
+  /** @returns the menu item image of this StoryEntity */
+  inline const std::string& getMenuItemImage() { return this->menuItemImage; }
+  inline void setMenuScreenshoot(const std::string& image);
+  /** @returns the menu screenshoot of this StoryEntity */
+  inline const std::string& getMenuScreenshoot() { return this->menuScreenshoot; }
+
+protected:
+  bool          bInit;             //!< if the entity is initialized, this has to be true.
+  bool          bRunning;          //!< is true if the entity is running
+  bool          bPaused;           //!< is true if the entity is paused
+
+
+private:
+  int           storyID;          //!< this is the number of this entity, identifying it in a list/tree...
+  int           nextStoryID;      //!< if this entity has finished, this entity shall be called
+  std::string   loadFile;         //!< The file from which this world is loaded
+
+  std::string   description;      //!< the description of the StoryEntity
+  std::string   menuItemImage;    //!< the item image of the StoryEntity
+  std::string   menuScreenshoot;  //!< the screenshoot of the StoryEntity
+  bool          bMenuEntry;       //!< If true, this GameWorld apears in the SimpleMenu: SimpleMenu specific
+};
+
+#endif /* _STORY_ENTITY_H */
Index: branches/heathaze/src/subprojects/Makefile.am
===================================================================
--- branches/heathaze/src/subprojects/Makefile.am	(revision 9940)
+++ branches/heathaze/src/subprojects/Makefile.am	(revision 9940)
@@ -0,0 +1,10 @@
+SUBDIRS = importer \
+          particles \
+          collision_detection \
+          network \
+          testmain
+
+noinst_HEADERS = framework.h
+
+
+EXTRA_DIST = framework.cc
Index: branches/heathaze/src/subprojects/benchmark.cc
===================================================================
--- branches/heathaze/src/subprojects/benchmark.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/benchmark.cc	(revision 9940)
@@ -0,0 +1,470 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+
+*/
+
+
+#if defined __linux__
+
+#include "list.h"
+#include "world_entity.h"
+#include "vector.h"
+#include "player.h"
+#include "base_object.h"
+
+#include <stdlib.h>
+#include <asm/msr.h>
+//#include <linux/timex.h>
+
+
+#define LIST_MAX 1000
+#define VECTOR_MAX 1000000
+#define ITERATIONS 10000
+
+
+int startBenchmarks()
+{
+
+  printf("===========================================================\n");
+  printf("=                      BENCHMARKS                         =\n");
+  printf("===========================================================\n");
+  printf(" the author is not paying any attention to cacheing effects\n");
+  printf(" of the CPU.\n\n");
+  printf("[title]\t\t\t\t\t     [cycles]\t[loops]\n\n");
+  //  printf("------------------------------------------------------------\n\n");
+
+  // first measure the time overhead:
+  unsigned long ini, end, dt;
+  rdtscl(ini); rdtscl(end);
+  dt = end - ini;
+
+  int type = -1;
+  /* type   -1 == all
+     type    0 == framework
+     type    1 == vector
+     type    2 == quaternion
+     type    3 == lists
+  */
+  if(type == 0 || type == -1)
+    {
+      /* framework test*/
+
+      printf("Generating Objects:\t\t\t\t\t%i\n", ITERATIONS);
+      /* ************WorldEntity class test************** */
+      WorldEntity* w = NULL;
+      int i = 0;
+      unsigned long mittel = 0;
+
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+          WorldEntity* w = new WorldEntity();
+
+          rdtscl(end);
+          delete w;
+          mittel += (end - ini - dt);
+        }
+      float mi = mittel / (float)ITERATIONS;
+      printf(" Generate a WorldEntity object:\t\t%11.2f\n", mi);
+
+      /*
+        mittel = 0;
+        for(i = 0; i < ITERATIONS; ++i)
+        {
+        rdtscl(ini);
+
+        WorldEntity* w = new Primitive(P_SPHERE);
+
+        rdtscl(end);
+        delete w;
+        mittel += (end - ini - dt);
+        }
+        mi = mittel / (float)ITERATIONS;
+        printf(" Generate a Primitive  object:\t\t%11.2f\n", mi);
+      */
+
+      mittel = 0;
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+          Vector* v = new Vector();
+
+          rdtscl(end);
+          delete v;
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)ITERATIONS;
+      printf(" Generate a Vector object:\t\t%11.2f\n", mi);
+
+
+     mittel = 0;
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+          Quaternion* q = new Quaternion();
+
+          rdtscl(end);
+          delete q;
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)ITERATIONS;
+      printf(" Generate a Quaternion object:\t\t%11.2f\n", mi);
+
+
+
+
+      printf("\nCalling function inline &| virtual, \t\t\t%i\n", ITERATIONS);
+      mittel = 0;
+      w = new WorldEntity();
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+          w->tick(0.0f);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+          }
+      //delete w;
+      mi = mittel / (float)ITERATIONS;
+      printf(" Virt funct tick() of WE: \t\t%11.2f\n", mi);
+
+
+      mittel = 0;
+      WorldEntity wo;
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+          wo.tick(0.0f);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+          }
+      //delete w;
+      mi = mittel / (float)ITERATIONS;
+      printf(" Inl virt funct tick() of WE v2: \t%11.2f\n", mi);
+
+
+      mittel = 0;
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+//          bo->isFinalized();
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+          }
+      //delete w;
+      mi = mittel / (float)ITERATIONS;
+      printf(" Inl funct BaseObject::isFinazlized(): \t%11.2f\n", mi);
+
+
+      tList<WorldEntity>* list = new tList<WorldEntity>();
+
+
+      /* ************Primitvie class test************** */
+      list = new tList<WorldEntity>();
+
+
+      /*
+        mittel = 0;
+        w = new Primitive(P_SPHERE);
+        for(i = 0; i < ITERATIONS; ++i)
+        {
+        rdtscl(ini);
+
+        w->tick(0.0f);
+
+        rdtscl(end);
+        mittel += (end - ini - dt);
+        }
+        mi = mittel / (float)ITERATIONS;
+        printf(" Call function tick() of Prim:\t\t%11.2f\n", mi);
+      */
+
+    }
+
+  if(type == 1 || type == -1)
+    {
+      printf("\nDoing some simple vector operations: \t\t\t%i\n", VECTOR_MAX);
+      /* vector test */
+      Vector* a = new Vector(1.3, 5.3, 4.1);
+      Vector* b = new Vector(0.4, 2.5, 6.2);
+      Vector* c = new Vector();
+
+      unsigned long mittel, ini, end;
+      float mi;
+      int i = 0;
+      // addition
+      mittel = 0;
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          *c = *a + *b;
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" Addition of two vectors:\t\t%11.2f\n", mi);
+
+      // multiplikation
+
+      mittel = 0;
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          *c = a->cross( *b);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" CrossMult of two vectors:\t\t%11.2f\n", mi);
+
+    }
+  if( type == 2 || type == -1)
+    {
+      /* quaternion test */
+      printf("\nDoing some simple quaternion operations: \t\t%i\n", VECTOR_MAX);
+      /* vector test */
+      Quaternion* a = new Quaternion();
+      Quaternion* b = new Quaternion();
+      Quaternion* c = new Quaternion();
+
+      unsigned long mittel, ini, end;
+      float mi;
+      int i = 0;
+      // quaternion generieren mit spez konstruktor
+      mittel = 0;
+      Vector* qa = new Vector(4.6, 9.3, 0.4);
+      Vector* qb = new Vector(3.5, 6.1, 4.3);
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          Quaternion* qu = new Quaternion(*qa, *qb);
+
+          rdtscl(end);
+          delete qu;
+          mittel += (end - ini - dt);
+        }
+      delete a;
+      delete b;
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" Gen. quatern. betw. two vectors:\t%11.2f\n", mi);
+
+
+      // multiplication
+      mittel = 0;
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          *c = *a * *b;
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" Multiplying two quat.(=rot): a * b\t%11.2f\n", mi);
+
+
+
+      // rotating a vector by a quaternion
+      mittel = 0;
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          *qa = a->apply(*qb);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" Rot a vec by a quat: q->apply(v)\t%11.2f\n", mi);
+
+
+
+      // generate rotation matrix
+      mittel = 0;
+      float matrix[4][4];
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          a->matrix(matrix);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" Generate rot matrix: q->matrix(m)\t%11.2f\n", mi);
+    }
+  if( type == 3 || type == -1)
+    {
+      /* list tests*/
+      printf("\nList operations tests: \t\t\t\t\t%i\n", LIST_MAX);
+      tList<char>* list = new tList<char>();
+      char* name;
+
+      printf(" Adding[1..10] elements to list, found:\n");
+      list->add("1");
+      list->add("2");
+      list->add("3");
+      list->add("4");
+      list->add("5");
+      list->add("6");
+      list->add("7");
+      list->add("8");
+      list->add("9");
+      list->add("10");
+
+      /*give list out */
+      tIterator<char>* iterator = list->getIterator();
+      name = iterator->firstElement();
+      printf("  List Elements: \t\t");
+      while( name != NULL)
+        {
+          printf("%s,", name);
+          name = iterator->nextElement();
+        }
+      delete iterator;
+      printf("\n");
+
+
+      /*removing some elements from the list*/
+      printf(" Removing elements [2,3,6,8,10], adding [11] now found:\n");
+      list->remove("2");
+      list->remove("3");
+      list->remove("6");
+      list->remove("8");
+      list->remove("10");
+      list->add("11");
+      /*give list out */
+      iterator = list->getIterator();
+      name = iterator->firstElement();
+      printf("  List Elements: \t\t");
+      while( name != NULL)
+        {
+          printf("%s,", name);
+          name = iterator->nextElement();
+        }
+      delete iterator;
+      printf("\n");
+
+      delete list;
+      printf("\nChecking list performance:\t\t\t\t%i\n", LIST_MAX);
+
+      tList<int>* plist = new tList<int>();
+      unsigned long mittel, ini, end;
+      float mi;
+      int i = 0;
+      mittel = 0;
+      for(i = 0; i < LIST_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          plist->add(&i);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)LIST_MAX;
+      printf(" Adding reference to list:\t\t%11.2f\n", mi);
+
+      mittel = 0;
+      for(i = 0; i < LIST_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          plist->remove(&i);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)LIST_MAX;
+      printf(" Removing 1st reference from list:\t%11.2f\n", mi);
+
+
+      printf("\nList operations tests: \t\t\t\t\t%i\n", LIST_MAX);
+      list = new tList<char>();
+      printf(" Adding[1..10] elements to list, found:\n");
+      list->add("1");
+      list->add("2");
+      list->add("3");
+      list->add("4");
+      list->add("5");
+      list->add("6");
+      list->add("7");
+      list->add("8");
+      list->add("9");
+      list->add("10");
+
+      /*give list out */
+      iterator = list->getIterator();
+      name = iterator->firstElement();
+      printf("  List Elements: \t\t");
+      while( name != NULL)
+        {
+          printf("%s,", name);
+          name = iterator->nextElement();
+        }
+      delete iterator;
+      printf("\n");
+
+
+      int c = 0;
+      printf(" Going trough list with nextElement(el) func: ");
+      name = list->firstElement();
+      while(c < 20)
+        {
+          printf("%s,", name);
+          name = list->nextElement(name);
+          c++;
+        }
+      printf("\n");
+    }
+
+    return 0;
+}
+
+#else
+
+#include "debug.h"
+
+int startBenchmarks()
+{
+  PRINTF(1)("Benchmark is not implemented in this system\n");
+}
+
+#endif
Index: branches/heathaze/src/subprojects/benchmark.h
===================================================================
--- branches/heathaze/src/subprojects/benchmark.h	(revision 9940)
+++ branches/heathaze/src/subprojects/benchmark.h	(revision 9940)
@@ -0,0 +1,13 @@
+/*!
+ * @file benchmark.h
+  *  benchmark functions
+*/
+
+
+#ifndef _BENCHMARK_H
+#define _BENCHMARK_H
+
+int startBenchmarks();
+
+
+#endif /* _BENCHMARK_H */
Index: branches/heathaze/src/subprojects/collision_detection/Makefile.am
===================================================================
--- branches/heathaze/src/subprojects/collision_detection/Makefile.am	(revision 9940)
+++ branches/heathaze/src/subprojects/collision_detection/Makefile.am	(revision 9940)
@@ -0,0 +1,36 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+LIB_PREFIX=$(MAINSRCDIR)/lib
+include $(MAINSRCDIR)/lib/BuildLibs.am
+
+
+bin_PROGRAMS = collision
+
+DEPENDENCIES = \
+		$(MAINSRCDIR)/world_entities/libORXwe.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/util/libORXutils.a
+
+LDADD = \
+		$(MAINSRCDIR)/util/libORXutils.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/world_entities/libORXwe.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/util/libORXutils.a \
+		$(GTK2_LIBS) $(GTHREAD_LIBS) $(CURL_LIBS)
+
+
+collision_CPPFLAGS =  \
+		-DGUI_MODULE   \
+		$(GTK2_CFLAGS) $(GTHREAD_CFLAGS) $(CURL_CFLAGS) $(MSBITFIELDS)
+
+collision_SOURCES= \
+		../framework.cc \
+		collision_detection.cc \
+		collision_test_entity.cc \
+		\
+		$(MAINSRCDIR)/world_entities/space_ships/space_ship.cc \
+		$(MAINSRCDIR)/world_entities/weapons/test_gun.cc
+
+noinst_HEADERS  =  collision_test_entity.h
Index: branches/heathaze/src/subprojects/collision_detection/collision_detection.cc
===================================================================
--- branches/heathaze/src/subprojects/collision_detection/collision_detection.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/collision_detection/collision_detection.cc	(revision 9940)
@@ -0,0 +1,439 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+
+   this file extends the framework file, so it renders what i want.
+*/
+
+#include "framework.h"
+
+#include "fields.h"
+#include "stdlibincl.h"
+#include "light.h"
+
+#include "cd_engine.h"
+#include "bv_tree.h"
+
+#include "md2/md2Model.h"
+#include "model.h"
+#include "collision_test_entity.h"
+#include "list.h"
+
+#include "graphics_engine.h"
+
+#include "state.h"
+
+Model* mod;
+MD2Model* model;
+int drawMode;
+int depth;
+float iterata;
+tList<WorldEntity>* entityList;
+
+int lastFrame, currentFrame, dt;
+bool drawModel = false;
+
+WorldEntity* a;
+WorldEntity* b;
+//Terrain* c;
+bool animateModel = false;
+
+
+
+void Framework::moduleInit(int argc, char** argv)
+{
+  GraphicsEngine::getInstance()->setWindowName("Collision Cluster", "collision");
+
+  CDEngine::getInstance();
+
+  State::setObjectManager(new ObjectManager);
+  /* Primitive Data Test */
+//   sVec3D* data = new sVec3D[6];
+//   float tmp[6][3] = {{0.0, 4.2, 2.4}, {3.0, 3.0, 2.0}, {5.0, 1.0, 6.0}, {6.5, 1.0, 3.0}, {7.0, 3.0, 5.0}, {8.0, 6.0, 6.0}};
+//   for(int i = 0; i < 6; ++i)
+//   {
+//     data[i][0] = tmp[i][0];
+//     data[i][1] = tmp[i][1];
+//     data[i][2] = tmp[i][2];
+//   }
+//   CDEngine::getInstance()->debugSpawnTree(5, data, 6);
+
+  /* MD2 Model Test */
+//   model = new MD2Model("models/tris.md2", "models/tris.pcx");
+//   model->tick(0.1f);
+//   CDEngine::getInstance()->debugSpawnTree(9, model->data->pVertices, model->data->numVertices);
+
+  /* OBJ - Model Test */
+//   mod = (Model*)ResourceManager::getInstance()->load("models/reaplow.obj", OBJ, RP_CAMPAIGN);
+//   CDEngine::getInstance()->debugSpawnTree(9, (sVec3D*)mod->getVertexArray(), mod->getVertexArrayCount());
+
+   entityList = new tList<WorldEntity>();
+
+   if (argc > 1)
+   {
+     printf("Loading model %s\n", argv[1]);
+     b = new CollisionTestEntity(argv[1]); b->setName("Jaeger");
+   }
+   else
+   {
+     printf("----------------------- WARNING ---------------------\n\n");
+     printf("no path specified, using default model: models/ships/fighter.obj\n\n");
+     printf("----------------------- WARNING ---------------------\n");
+     b = new CollisionTestEntity("models/test/cd_test_0.obj"); b->setName("Jaeger");
+   }
+//   b->setRelCoor(0.0, 0.0, -20.0);
+//   b->setRelDir(Quaternion(-M_PI/2.0f, Vector(0.0, 1.0, 0.0)));
+   if(b != NULL)
+     printf("model successfully loaded\n");
+   entityList->add(b);
+
+
+//   a = new Terrain();
+
+
+//   entityList->add(b);
+
+  //CDEngine::getInstance()->setEntityList(entityList);
+
+  LightManager* lightMan = LightManager::getInstance();
+  lightMan->setAmbientColor(.1,.1,.1);
+  (new Light())->setAbsCoor(-5.0, 50.0, -40.0);
+  (new Light())->setAbsCoor(100, 80, 60);
+
+
+  /* properties */
+  drawMode = DRAW_MODEL;
+  depth = 0;
+  dt = lastFrame = currentFrame = 0;
+  iterata = 0.05f;
+
+  moduleHelp();
+}
+
+
+void Framework::moduleEventHandler(SDL_Event* event)
+{
+  switch (event->type)
+  {
+    case SDL_KEYDOWN:
+      switch (event->key.keysym.sym)
+      {
+        case SDLK_a:
+          drawMode |= DRAW_ALL;
+          break;
+        case SDLK_0:
+        {
+          printf("Setting tree depth = 0\n");
+          depth = 0;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_1:
+        {
+          printf("Setting tree depth = 1\n");
+          depth = 1;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_2:
+        {
+          printf("Setting tree depth = 2\n");
+          depth = 2;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_3:
+        {
+          printf("Setting tree depth = 3\n");
+          depth = 3;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_4:
+        {
+          printf("Setting tree depth = 4\n");
+          depth = 4;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_5:
+        {
+          printf("Setting tree depth = 5\n");
+          depth = 5;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_6:
+        {
+          printf("Setting tree depth = 6\n");
+          depth = 6;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_s:
+          if(drawMode & DRAW_SEPARATING_PLANE)
+          {
+            int temp = drawMode & DRAW_SEPARATING_PLANE;
+            drawMode ^= temp;
+            printf("Removing Separation Plane\n");
+          }
+          else
+          {
+            drawMode |= DRAW_SEPARATING_PLANE;
+            printf("Drawing Separation Plane\n");
+          }
+
+          break;
+        case SDLK_p:
+          if(drawMode & DRAW_BV_POLYGON)
+          {
+            int temp = drawMode & DRAW_BV_POLYGON;
+            drawMode ^= temp;
+            printf("Removing OBB Polygons\n");
+          }
+          else
+          {
+            drawMode |= DRAW_BV_POLYGON;
+            printf("Drawing OBB Polygons\n");
+          }
+          break;
+        case SDLK_o:
+          if(iterata == 0.0f)
+          {
+            iterata = 0.05f;
+          }
+          else
+          {
+            iterata = 0.0f;
+          }
+          break;
+
+      }
+  }
+}
+
+
+void Framework::moduleTick(float dt)
+{
+
+  //CDEngine::getInstance()->checkCollisions();
+
+
+ // b->shiftCoor(Vector(0.0, 0.0, iterata * dt * 12.0f));
+
+
+  tIterator<WorldEntity>* iterator = entityList->getIterator();
+  WorldEntity* entity = iterator->firstElement();
+  while( entity != NULL)
+  {
+    if( unlikely(animateModel))
+      entity->tick(dt);
+    entity = iterator->nextElement();
+  }
+  delete iterator;
+}
+
+
+void Framework::moduleDraw() const
+{
+  //CDEngine::getInstance()->debugDraw(depth, drawMode);
+
+  tIterator<WorldEntity>* iterator = entityList->getIterator();
+  WorldEntity* entity = iterator->firstElement();
+  while( entity != NULL)
+  {
+    if( likely(drawModel))
+      entity->draw();
+    entity->drawBVTree(depth, drawMode);
+   // printf("%i, %i\n", depth, drawMode);
+    entity = iterator->nextElement();
+  }
+  delete iterator;
+
+  LightManager::getInstance()->draw();
+}
+
+
+void Framework::moduleHelp(void) const
+{
+  printf("\n\n===========================");
+  printf("Collision Detection Modler:\n");
+  printf("Key Bindings:\n");
+  printf(" -| Displaying Polygons\t\t p\n");
+  printf(" -| Displaying Separation Plane\t s\n");
+  printf("\n");
+  printf(" -| Tree Depth 0\t\t 0\n");
+  printf(" -| Tree Depth 1\t\t 1\n");
+  printf(" -| Tree Depth 2\t\t 2\n");
+  printf(" -| Tree Depth 3\t\t 3\n");
+  printf(" -| Tree Depth 4\t\t 4\n");
+  printf(" -| Tree Depth 5\t\t 5\n");
+  printf("===========================\n\n");
+
+}
+
+int boxPolygons(GtkWidget* nonInterest, void* widget)
+{
+  if(drawMode & DRAW_BV_POLYGON)
+  {
+    int temp = drawMode & DRAW_BV_POLYGON;
+    drawMode ^= temp;
+    printf("Removing OBB Polygons\n");
+  }
+  else
+  {
+    drawMode |= DRAW_BV_POLYGON;
+    printf("Drawing OBB Polygons\n");
+  }
+}
+
+int seperatingPlanes(GtkWidget* nonInterest, void* widget)
+{
+  if(drawMode & DRAW_SEPARATING_PLANE)
+  {
+    int temp = drawMode & DRAW_SEPARATING_PLANE;
+    drawMode ^= temp;
+    printf("Removing Separation Plane\n");
+  }
+  else
+  {
+    drawMode |= DRAW_SEPARATING_PLANE;
+    printf("Drawing Separation Plane\n");
+  }
+}
+
+
+int blendedBox(GtkWidget* nonInterest, void* widget)
+{
+  if(drawMode & DRAW_BV_BLENDED)
+  {
+    int temp = drawMode & DRAW_BV_BLENDED;
+    drawMode ^= temp;
+    printf("Removing OBB Polygons\n");
+  }
+  else
+  {
+    drawMode |= DRAW_BV_BLENDED;
+    printf("Drawing OBB Polygons\n");
+  }
+}
+
+
+int drawModels(GtkWidget* nonInterest, void* widget)
+{
+  drawModel = !drawModel;
+}
+
+
+int animateModels(GtkWidget* nonInterest, void* widget)
+{
+  animateModel = !animateModel;
+}
+
+
+int drawPoints(GtkWidget* nonInterest, void* widget)
+{
+  if(drawMode & DRAW_POINTS)
+  {
+    int temp = drawMode & DRAW_POINTS;
+    drawMode ^= temp;
+
+  }
+  else
+  {
+    drawMode |= DRAW_POINTS;
+    printf("Drawing OBB Polygons\n");
+  }
+}
+
+
+int treeDepth(GtkWidget* nonInterest, void* widget)
+{
+  Option* option = (Option*) widget;
+  const char* name = option->getTitle();
+  char* value = option->save();
+
+  depth = atoi(value);
+  printf("Setting tree depth = %i\n", depth);
+  int temp = drawMode & DRAW_ALL;
+  drawMode ^= temp;
+  drawMode |= DRAW_SINGLE;
+
+  delete value;
+}
+
+
+void Framework::moduleInitGui(int argc, char** argv)
+{
+  Window* guiMainWindow = NULL;
+
+  initGUI(0, NULL);
+
+  guiMainWindow = new Window("Collision_detection");
+  {
+    Box* windowBox = new Box('v');
+    {
+      CheckButton* BoxPolygons = new CheckButton("Draw OBB Polygons");
+      BoxPolygons->connectSignal("clicked", (void*)BoxPolygons, boxPolygons);
+      windowBox->fill(BoxPolygons);
+
+
+      CheckButton* BlendedBox = new CheckButton("Draw OBB Blended");
+      BlendedBox->connectSignal("clicked", (void*)BlendedBox, blendedBox);
+      windowBox->fill(BlendedBox);
+
+
+      CheckButton* DrawModels = new CheckButton("Draw Models");
+      DrawModels->connectSignal("clicked", (void*)DrawModels, drawModels);
+      windowBox->fill(DrawModels);
+
+
+
+      CheckButton* AnimateModels = new CheckButton("Animate Models");
+      AnimateModels->connectSignal("clicked", (void*)AnimateModels, animateModels);
+      windowBox->fill(AnimateModels);
+
+
+      CheckButton* DrawPoints = new CheckButton("Draw Points");
+      DrawPoints->connectSignal("clicked", (void*)DrawPoints, drawPoints);
+      windowBox->fill(DrawPoints);
+
+
+      CheckButton* SeperatingPlanes = new CheckButton("SeperatingPlanes");
+      SeperatingPlanes->connectSignal("clicked", (void*)SeperatingPlanes, seperatingPlanes);
+      windowBox->fill(SeperatingPlanes);
+
+
+      Slider* TreeDepth = new Slider("TreeDepth", 0, 17);
+      TreeDepth->connectSignal("value_changed", (void*)TreeDepth, treeDepth);
+      windowBox->fill(TreeDepth);
+    }
+    guiMainWindow->fill(windowBox);
+  }
+  Window::mainWindow->showall();
+  Window::mainWindow->setSize(300, 500);
+}
Index: branches/heathaze/src/subprojects/collision_detection/collision_test_entity.cc
===================================================================
--- branches/heathaze/src/subprojects/collision_detection/collision_test_entity.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/collision_detection/collision_test_entity.cc	(revision 9940)
@@ -0,0 +1,81 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "collision_test_entity.h"
+
+#include "util/loading/resource_manager.h"
+
+#include "vector.h"
+#include "objModel.h"
+#include "obb_tree.h"
+#include "util/loading/factory.h"
+
+
+CREATE_FACTORY(CollisionTestEntity, CL_ENVIRONMENT);
+
+/**
+ *  creates an environment
+*/
+CollisionTestEntity::CollisionTestEntity (const char* modelName) : WorldEntity()
+{
+  this->init();
+  this->loadModel(modelName, 1.0f, 0, 10);
+/*  this->buildObbTree(0);*/
+
+}
+
+/**
+ * create an environment out of a XML-element
+ * @param root the XML-element to load the CollisionTestEntity from
+ */
+CollisionTestEntity::CollisionTestEntity(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  deletes an environment
+*/
+CollisionTestEntity::~CollisionTestEntity ()
+{}
+
+/**
+ * initialize an CollisionTestEntity
+ */
+void CollisionTestEntity::init()
+{
+  this->setClassID(CL_ENVIRONMENT, "CollisionTestEntity");
+}
+
+/**
+ * loads the Settings of an CollisionTestEntity from an XML-element.
+ * @param root the XML-element to load the ELements properties from
+ */
+void CollisionTestEntity::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+
+/**
+ *  ticks the environment
+ * @param time the time about which to tick
+*/
+void CollisionTestEntity::tick (float time) {}
+
Index: branches/heathaze/src/subprojects/collision_detection/collision_test_entity.h
===================================================================
--- branches/heathaze/src/subprojects/collision_detection/collision_test_entity.h	(revision 9940)
+++ branches/heathaze/src/subprojects/collision_detection/collision_test_entity.h	(revision 9940)
@@ -0,0 +1,34 @@
+/*!
+  \file collision_test_entity.h
+  \brief This file handles the collision_test_entity of the game
+*/
+
+#ifndef _COLLISION_TEST_ENTITY_H
+#define _COLLISION_TEST_ENTITY_H
+
+#include "world_entity.h"
+
+//! collision_test_entity of orxonox
+/**
+   everything that does not interact with the player comes here
+   Collision_Test_Entity is a container for all the worldEntities that are non-interactive
+*/
+class CollisionTestEntity : public WorldEntity
+{
+  friend class World;
+
+ public:
+  CollisionTestEntity (const char* modelName);
+  CollisionTestEntity (const TiXmlElement* root);
+  virtual ~CollisionTestEntity ();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+
+
+  virtual void tick (float time);
+
+};
+
+#endif /* _COLLISION_TEST_ENTITY_H */
Index: branches/heathaze/src/subprojects/framework.cc
===================================================================
--- branches/heathaze/src/subprojects/framework.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/framework.cc	(revision 9940)
@@ -0,0 +1,372 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#include "framework.h"
+
+
+#include "p_node.h"
+#include "state.h"
+#include "debug.h"
+#include "light.h"
+#include "util/loading/resource_manager.h"
+#include "camera.h"
+#include "util/preferences.h"
+#include "globals.h"
+
+int verbose;
+
+void Framework::init(void)
+{
+  GraphicsEngine::getInstance()->initFromPreferences();
+
+  LightManager::getInstance();
+
+  std::string dataPath = //Preferences::getInstance()->getString(CONFIG_SECTION_GENERAL, CONFIG_NAME_DATADIR, "");
+      "/home/boenzlip/orxonox/data/trunk/";
+  printf("%s\n", dataPath.c_str());
+  if (!dataPath.empty())
+  {
+    if (!ResourceManager::getInstance()->setDataDir(dataPath))
+    {
+      PRINTF(1)("Data Could not be located\n");
+      exit(-1);
+    }
+  }
+
+  if (!ResourceManager::getInstance()->verifyDataDir(DEFAULT_DATA_DIR_CHECKFILE))
+  {
+    PRINTF(1)("The DataDirectory %s could not be verified\n" \
+        "  Please Change in File %s Section %s Entry %s to a suitable value\n",
+    ResourceManager::getInstance()->getDataDir().c_str(),
+    DEFAULT_CONFIG_FILE,
+    CONFIG_SECTION_GENERAL,
+    CONFIG_NAME_DATADIR);
+    exit(-1);
+  }
+}
+
+
+void* Framework::mainLoop(void* tmp)
+{
+  Framework* framework = Framework::getInstance();
+
+  // initialize Timing
+  framework->cycle = 0;
+  for (unsigned int i = 0; i < TICK_SMOOTH_VALUE; i++)
+    framework->frameTimes[i] = 100;
+  framework->dtS = 0.0f;
+  framework->lastFrame = SDL_GetTicks ();
+
+
+  while(!framework->isFinished)
+    {
+#ifdef GUI_MODULE
+      while(gtk_events_pending())
+        gtk_main_iteration();
+#endif
+      // keyhandler returns false if sdl gets quit by some event
+      framework->eventHandler();
+
+      // tick the scene
+      float dt = framework->tick();
+
+      PNode::getNullParent()->updateNode(dt);
+
+      // Draw the scene
+      framework->draw(dt);
+
+    }
+}
+
+bool Framework::draw(float dt)
+{
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+  camera->apply();
+  camera->project();
+
+
+  this->moduleDraw();
+
+
+  SDL_GL_SwapBuffers(); // Swap the buffers
+}
+
+
+float Framework::tick()
+{
+      // CALCULATE FRAMERATE
+  Uint32 frameTimesIndex;
+  Uint32 getTicks;
+  Uint32 i;
+
+  frameTimesIndex = this->cycle % TICK_SMOOTH_VALUE;
+  getTicks = SDL_GetTicks();
+  this->frameTimes[frameTimesIndex] = getTicks - this->lastFrame;
+  this->lastFrame = getTicks;
+  ++this->cycle;
+  this->dtS = 0;
+  for (i = 0; i < TICK_SMOOTH_VALUE; i++)
+    this->dtS += this->frameTimes[i];
+  this->dtS = this->dtS / TICK_SMOOTH_VALUE / 1000.0f * speed;
+
+  this->camera->tick(dtS);
+
+  this->moduleTick(dtS);
+
+  return dtS;
+}
+
+
+bool Framework::eventHandler()
+{
+  // This is the main loop for the entire program and it will run until done==TRUE
+  {
+    // And poll for events
+    SDL_Event event;
+    while(SDL_PollEvent(&event))
+    {
+      moduleEventHandler(&event);
+
+      switch (event.type) {
+      case SDL_MOUSEMOTION:
+        {
+          Vector view = camera->getTarget()->getAbsCoor() - camera->getAbsCoor();
+          Vector up = Vector(0, 1, 0);
+          up = camera->getAbsDir().apply(up);
+          Vector h = up.cross(view);
+          Vector v = h.cross(view);
+          h.normalize();
+          v.normalize();
+          float distance = view.len();
+
+          Vector newCameraPos = camera->getAbsCoor();
+          Vector newTargetPos = camera->getTarget()->getAbsCoor();
+          int changed = 0;
+
+          if (mouseDown[1])
+            {
+              newCameraPos = camera->getRelCoor()+ (h * event.motion.xrel - v * event.motion.yrel) * .005 * distance;
+              changed += 1;
+            }
+          if (mouseDown[3])
+            {
+              newTargetPos = camera->getTarget()->getRelCoor() + (h * event.motion.xrel - v * event.motion.yrel) * .005 * distance;
+              changed += 2;
+            }
+
+          Vector newView = newTargetPos - newCameraPos;
+
+          if (changed == 1)
+            camera->setRelCoor(newCameraPos + newView * (1- distance/newView.len()));
+          else if (changed == 2)
+            camera->getTarget()->setRelCoor(newTargetPos - newView * (1-distance/newView.len()));
+          else if (changed == 3)
+            {
+              camera->setRelCoor(newCameraPos);
+              camera->getTarget()->setRelCoor(newTargetPos);
+            }
+
+        }
+        break;
+      case SDL_MOUSEBUTTONDOWN:
+        switch (event.button.button)
+          {
+          case 4:
+            PRINTF(4)("MouseWheel up\n");
+            camera->setRelCoor(camera->getRelCoor() + (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1);
+            break;
+          case 5:
+            PRINTF(4)("MouseWheel down\n");
+            camera->setRelCoor(camera->getRelCoor() - (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1);
+            break;
+          case 1:
+          case 2:
+          case 3:
+            mouseDown[event.button.button] = true;
+            break;
+          }
+
+        break;
+      case SDL_MOUSEBUTTONUP:
+        switch (event.button.button)
+          {
+          case 1:
+          case 2:
+          case 3:
+            mouseDown[event.button.button] = false;
+            break;
+          }
+        break;
+      case SDL_VIDEORESIZE:
+        GraphicsEngine::getInstance()->resolutionChanged(event.resize);
+        break;
+      case SDL_KEYDOWN:
+        switch (event.key.keysym.sym)
+          {
+          case SDLK_q:
+          case SDLK_ESCAPE:
+#ifdef GUI_MODULE
+            quitGui(NULL, NULL);
+#else
+            this->quit();
+#endif
+            break;
+          case SDLK_a:
+            camera->setRelCoor(camera->getRelCoor() + (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1);
+            break;
+          case SDLK_z:
+            camera->setRelCoor(camera->getRelCoor() - (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1);
+            break;
+          case SDLK_r:
+            camera->setAbsCoor(Vector(10, 10, 10));
+            camera->getTarget()->setAbsCoor(Vector());
+            break;
+          case SDLK_h:
+            this->printHelp();
+            break;
+          case SDLK_c:
+            for (int i = 0; i < 3; i++)
+              {
+                backgroundColor[i] += .1;
+                if (backgroundColor[i] > 1.0)
+                  backgroundColor[i] = 1.0;
+                GraphicsEngine::setBackgroundColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], backgroundColor[3]);
+              }
+            break;
+          case SDLK_x:
+            for (int i = 0; i < 3; i++)
+              {
+                backgroundColor[i] -= .1;
+                if (backgroundColor[i] < 0.0)
+                  backgroundColor[i] = 0.0;
+                GraphicsEngine::setBackgroundColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], backgroundColor[3]);
+              }
+            break;
+          }
+        break;
+
+        // If a quit event was recieved
+      case SDL_QUIT:
+        // then we're done and we'll end this program
+#ifdef GUI_MODULE
+            quitGui(NULL, NULL);
+#else
+            this->quit();
+#endif
+        break;
+      default:
+        break;
+      }
+
+    }
+
+    // Get the state of the keyboard keys
+    keys = SDL_GetKeyState(NULL);
+
+    // and check if ESCAPE has been pressed. If so then quit
+    if(keys[SDLK_ESCAPE]) return false;
+  }
+  return true;
+}
+
+void Framework::quit(void)
+{
+  this->isFinished = true;
+}
+
+Framework* Framework::singletonRef = NULL;
+
+Framework::Framework()
+{
+  this->init();
+
+  camera = new Camera();
+  State::setCamera(camera, camera->getTarget());
+  camera->setAbsCoor(Vector(10, 10, 10));
+
+  this->isFinished = false;
+
+  this->lastFrame = 0;
+
+
+  // Build the font from a TGA image font.tga in the data directory
+  // Hide the mouse cursor
+  SDL_ShowCursor(2);
+
+  for (int i = 0; i < MOUSE_BUTTON_COUNT; i++)
+    mouseDown[i] = false;
+  for (int i = 0; i < 4; i++)
+    backgroundColor[i] = 0;
+}
+
+Framework::~Framework()
+{
+  delete GraphicsEngine::getInstance();
+
+  Framework::singletonRef = NULL;
+}
+
+
+
+void Framework::printHelp(void) const
+{
+  PRINT(0)(" Help for the frameWork\n");
+  PRINT(0)("========================\n");
+  PRINT(0)("h - print this Help\n");
+  PRINT(0)("a - zoom in\n");
+  PRINT(0)("z - zoom out\n");
+  PRINT(0)("r - reset camera position\n");
+  PRINT(0)("x - background color darker\n");
+  PRINT(0)("c - background color brighter\n");
+
+
+  PRINT(0)("\n");
+  PRINT(0)("mouse wheel - zoom\n");
+  PRINT(0)("mouse left button - rotate the camera around its target\n");
+  PRINT(0)("mouse right button - rotate the camera's target around the camera\n");
+  PRINT(0)("mouse left-and-right button - move the camera and the target\n");
+
+  this->moduleHelp();
+
+}
+
+#ifdef GUI_MODULE
+int quitGui(GtkWidget* widget, void* data)
+{
+#ifdef HAVE_GTK2
+  while(gtk_events_pending()) gtk_main_iteration();
+  Framework::getInstance()->quit();
+#endif /* HAVE_GTK2 */
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+  verbose = 3;
+
+  Framework* framework = Framework::getInstance();
+
+  framework->moduleInit(argc, argv);
+#ifdef GUI_MODULE
+  framework->moduleInitGui(argc, argv);
+#endif
+  framework->mainLoop(NULL);
+
+  delete framework;
+  // Kill the GL & SDL screens
+  // And quit
+  return 0;
+}
Index: branches/heathaze/src/subprojects/framework.h
===================================================================
--- branches/heathaze/src/subprojects/framework.h	(revision 9940)
+++ branches/heathaze/src/subprojects/framework.h	(revision 9940)
@@ -0,0 +1,80 @@
+#ifndef _FRAMEWORK_H
+#define _FRAMEWORK_H
+
+#include "vector.h"
+#include "glincl.h"
+#include "debug.h"
+#include "graphics_engine.h"
+
+#ifdef GUI_MODULE
+#include "gui_gtk.h"
+#endif
+
+#define MOUSE_BUTTON_COUNT 3
+
+#define TICK_SMOOTH_VALUE 10
+
+class Camera;
+
+class Framework {
+  public:
+    virtual ~Framework();
+
+    /** \returns a Pointer to the only object of this Class */
+    inline static    Framework* getInstance(void) { if (!singletonRef) singletonRef = new Framework();  return singletonRef; };
+
+  public:
+    void             moduleInit(int argc, char** argv);
+#ifdef GUI_MODULE
+    void             moduleInitGui(int argc, char** argv);
+#endif
+    void             moduleEventHandler(SDL_Event* event);
+  void               moduleTick(float dt);
+  void               moduleDraw(void) const;
+
+  void               moduleHelp(void) const;
+
+
+  void               init(void);
+  static void*       mainLoop(void* tmp);
+  bool               draw(float dt);
+  float              tick();
+  bool               eventHandler();
+  void               quit();
+
+  static void*       mainloopGui(void* tmp);
+
+  void               printHelp(void) const;
+
+
+  private:
+    Framework();
+
+  private:
+    static Framework*           singletonRef;
+
+    Camera*                     camera;
+
+    bool                        isFinished;
+
+    int                         movement [4];
+    float                       backgroundColor[4];
+
+    /* world timing */
+    Uint32              lastFrame;                    //!< last time of frame (in MiliSeconds)
+    Uint32              cycle;                        //!< The cycle we are in (starts with 0 and rises with every frame)
+    float               dtS;                          //!< The time needed for caluculations in seconds
+    float               speed;                        //!< how fast the game flows
+    double              gameTime;                     //!< this is where the game time is saved
+    Uint32              frameTimes[TICK_SMOOTH_VALUE];//!< The time used for the last TICK_SMOOTH_VALUE's frames.
+
+    Uint8*                      keys;        // This variable will be used in the keyboard routine
+    bool                        mouseDown[MOUSE_BUTTON_COUNT];
+
+};
+
+#ifdef GUI_MODULE
+int quitGui(GtkWidget* widget, void* data);
+#endif
+
+#endif /* _FRAMEWORK_H */
Index: branches/heathaze/src/subprojects/importer/Makefile.am
===================================================================
--- branches/heathaze/src/subprojects/importer/Makefile.am	(revision 9940)
+++ branches/heathaze/src/subprojects/importer/Makefile.am	(revision 9940)
@@ -0,0 +1,46 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+LIB_PREFIX=$(MAINSRCDIR)/lib
+include $(MAINSRCDIR)/lib/BuildLibs.am
+
+
+importer_LDFLAGS = \
+		$(MWINDOWS)
+
+
+bin_PROGRAMS = \
+		importer \
+		multitex
+# 		movie_player_test
+
+DEPENDENCIES = \
+		$(MAINSRCDIR)/world_entities/libORXwe.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/util/libORXutils.a
+
+LDADD = \
+		$(MAINSRCDIR)/util/libORXutils.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/world_entities/libORXwe.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/util/libORXutils.a
+
+importer_SOURCES= \
+		../framework.cc \
+		importer.cc \
+		$(MAINSRCDIR)/world_entities/space_ships/space_ship.cc \
+		$(MAINSRCDIR)/world_entities/weapons/test_gun.cc
+
+
+multitex_SOURCES= \
+		../framework.cc \
+                multitex.cc \
+		$(MAINSRCDIR)/world_entities/space_ships/space_ship.cc \
+		$(MAINSRCDIR)/world_entities/weapons/test_gun.cc
+
+# movie_player_test_SOURCES= \
+# 		../framework.cc \
+# 		movie_player_test.cc \
+# 		$(MAINSRCDIR)/world_entities/space_ships/space_ship.cc \
+# 		$(MAINSRCDIR)/world_entities/weapons/test_gun.cc
Index: branches/heathaze/src/subprojects/importer/importer.cc
===================================================================
--- branches/heathaze/src/subprojects/importer/importer.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/importer/importer.cc	(revision 9940)
@@ -0,0 +1,105 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   this file extends the framework file, so it renders what i want.
+*/
+
+#include "framework.h"
+
+#include "light.h"
+
+#include "objModel.h"
+#include "md2/md2Model.h"
+#include "primitive_model.h"
+#include <stdlib.h>
+
+#include "vertex_array_model.h"
+
+#include "util/loading/resource_manager.h"
+
+Model* obj;
+
+void Framework::moduleInit(int argc, char** argv)
+{
+  ResourceManager::getInstance()->addImageDir("./");
+
+  for (int i = 0; i < argc; i++)
+  {
+    printf("%s\n", argv[i]);
+  }
+  ResourceManager::getInstance()->addImageDir("");
+
+
+  if (argc>=3)
+  {
+    if( strstr(argv[1], ".obj") != NULL)
+      obj = new OBJModel (argv[1], atof(argv[2]));
+    else if( strstr(argv[1], ".md2") != NULL)
+    {
+      obj = new MD2Model(argv[1], argv[2]);
+      ((MD2Model*)obj)->tick(0.1f);
+    }
+  }
+  else if (argc>=2)
+  {
+    if( strstr(argv[1], ".obj") != NULL)
+      obj = new OBJModel(argv[1]);
+    else if( strstr(argv[1], ".md2") != NULL) {
+      obj = new MD2Model(argv[1], "fake_texture.bad");
+      obj = new MD2Model(argv[1], argv[2]);
+      ((MD2Model*)obj)->tick(0.1f);
+    }
+  }
+ // else
+    obj = new PrimitiveModel(PRIM_CYLINDER);
+
+
+  ResourceManager::getInstance()->debug();
+
+  LightManager* lightMan = LightManager::getInstance();
+  lightMan->setAmbientColor(.1,.1,.1);
+  (new Light())->setAbsCoor(5.0, 10.0, 40.0);
+  (new Light())->setAbsCoor(-10, -20, -100);
+}
+
+void Framework::moduleEventHandler(SDL_Event* event)
+{
+  switch (event->type)
+    {
+    case SDL_KEYDOWN:
+      switch (event->key.keysym.sym)
+        {
+        case SDLK_i:
+          break;
+        }
+    }
+}
+
+void Framework::moduleTick(float dt)
+{
+
+}
+
+void Framework::moduleDraw(void) const
+{
+  LightManager::getInstance()->draw();
+  obj->draw();
+
+}
+
+
+void Framework::moduleHelp(void) const
+{
+
+}
Index: branches/heathaze/src/subprojects/importer/movie_player_test.cc
===================================================================
--- branches/heathaze/src/subprojects/importer/movie_player_test.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/importer/movie_player_test.cc	(revision 9940)
@@ -0,0 +1,85 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: David Hasenfratz
+   co-programmer: ...
+
+   this file extends the framework file, so it renders what i want.
+*/
+
+#include <stdlib.h>
+
+#include "framework.h"
+#include "movie_player.h"
+
+MoviePlayer* movie_player;
+
+void Framework::moduleInit(int argc, char** argv)
+{
+  if( argc <= 1)
+  {
+    printf("Wrong arguments try following notations:\n");
+    printf("./movie_player_test [media_file]\n");
+    exit(0);
+  }
+
+  movie_player = new MoviePlayer(argv[1]);
+
+  
+  movie_player->printInformation();
+}
+
+void Framework::moduleEventHandler(SDL_Event* event)
+{
+  switch (event->type)
+  {
+    case SDL_KEYDOWN:
+      switch (event->key.keysym.sym)
+      {
+        case SDLK_1:
+          movie_player->start(0);
+          break;
+        case SDLK_2:
+          movie_player->resume();
+          break;
+        case SDLK_3:
+          movie_player->pause();
+          break;
+        case SDLK_4:
+          movie_player->stop();
+          break;
+        case SDLK_9:
+          movie_player->setFPS(movie_player->getFPS() - 1);
+          PRINTF(0)("fps: %0.2f\n", movie_player->getFPS());
+          break;
+        case SDLK_0:
+          movie_player->setFPS(movie_player->getFPS() + 1);
+          PRINTF(0)("fps: %0.2f\n", movie_player->getFPS());
+          break;
+      }
+  }
+}
+
+void Framework::moduleTick(float dt)
+{
+  movie_player->tick(dt);
+}
+
+void Framework::moduleDraw(void) const
+{
+  movie_player->draw();
+}
+
+
+void Framework::moduleHelp(void) const
+{
+
+}
Index: branches/heathaze/src/subprojects/importer/multitex.cc
===================================================================
--- branches/heathaze/src/subprojects/importer/multitex.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/importer/multitex.cc	(revision 9940)
@@ -0,0 +1,119 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: David Hasenfratz
+   co-programmer: ...
+
+   this file extends the framework file, so it renders what i want.
+*/
+
+#include "framework.h"
+
+#include "light.h"
+
+#include "material.h"
+#include "primitive_model.h"
+#include <stdlib.h>
+
+#include "media_container.h"
+
+Model* obj;
+Material* testMat;
+MediaContainer* media_container;
+
+int counter = 0;
+float timer = 0;
+float fps;
+
+
+void Framework::moduleInit(int argc, char** argv)
+{
+  if( argc <= 1)
+  {
+    printf("Wrong arguments try following notations:\n");
+    printf("./multitex [media_file]\n");
+    exit(0);
+  }
+
+  media_container = new MediaContainer(argv[1]);
+
+  testMat = new Material;
+  testMat->setDiffuseMap("maps/radialTransparency.png");
+  obj = new PrimitiveModel(PRIM_PLANE, 10.0);
+
+  LightManager* lightMan = LightManager::getInstance();
+  lightMan->setAmbientColor(.1,.1,.1);
+  (new Light())->setAbsCoor(5.0, 10.0, 40.0);
+  (new Light())->setAbsCoor(-10, -20, -100);
+
+  fps = media_container->getFPS();
+}
+
+void Framework::moduleEventHandler(SDL_Event* event)
+{
+  switch (event->type)
+    {
+    case SDL_KEYDOWN:
+      switch (event->key.keysym.sym)
+        {
+        case SDLK_1:
+          obj = new PrimitiveModel(PRIM_CUBE, 10.0);
+          break;
+        case SDLK_2:
+          obj = new PrimitiveModel(PRIM_SPHERE, 10.0);
+          break;
+        case SDLK_3:
+          obj = new PrimitiveModel(PRIM_PLANE, 10.0);
+          break;
+        // increase fps
+        case SDLK_9:
+          fps++;
+          PRINTF(0)("fps: %0.2f\n", fps);
+          break;
+        // decrease fps
+        case SDLK_8:
+          if(fps > 0)
+            fps--;
+          PRINTF(0)("fps: %0.2f\n", fps);
+          break;
+        }
+    }
+}
+
+void Framework::moduleTick(float dt)
+{
+  timer += dt;
+
+  if(counter != fps * timer)
+  {
+    counter = fps * timer;
+
+    if (counter >= media_container->getFrameCount())
+    {
+      timer = 0;
+      counter = 0;
+    }
+  }
+}
+
+void Framework::moduleDraw(void) const
+{
+  testMat->select();
+  glBindTexture(GL_TEXTURE_2D, media_container->getFrameTexture(counter));
+  obj->draw();
+
+  LightManager::getInstance()->draw();
+}
+
+void Framework::moduleHelp(void) const
+{
+
+}
Index: branches/heathaze/src/subprojects/network/Makefile.am
===================================================================
--- branches/heathaze/src/subprojects/network/Makefile.am	(revision 9940)
+++ branches/heathaze/src/subprojects/network/Makefile.am	(revision 9940)
@@ -0,0 +1,38 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+LIB_PREFIX=$(MAINSRCDIR)/lib
+include $(MAINSRCDIR)/lib/BuildLibs.am
+
+
+bin_PROGRAMS = network
+
+
+network_CPPFLAGS = 
+#-DNO_SHELL -DNO_SHELL_COMMAND
+
+network_DEPENDENCIES = \
+		$(MAINSRCDIR)/world_entities/libORXwe.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/util/libORXutils.a
+
+network_LDADD = \
+		$(MAINSRCDIR)/util/libORXutils.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/world_entities/libORXwe.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/util/libORXutils.a
+
+
+network_SOURCES=  network_unit_test.cc \
+                  simple_sync.cc \
+		  read_sync.cc \
+		  write_sync.cc
+
+
+
+noinst_HEADERS  =  network_unit_test.h \
+                   simple_sync.h \
+		   read_sync.h \
+		   write_sync.h
+
Index: branches/heathaze/src/subprojects/network/README
===================================================================
--- branches/heathaze/src/subprojects/network/README	(revision 9940)
+++ branches/heathaze/src/subprojects/network/README	(revision 9940)
@@ -0,0 +1,21 @@
+
+To use the NetworkUnitTest:
+
+1. Compile and link Orxonox (following the guide you find on www.orxonox.net)
+2. Compile the network binary by typing: make
+
+Now will want to do some of the following:
+
+Distributed Network Test:
+=========================
+1. Start the server: 
+
+./network --server 9999
+
+2. Start the client on an other console/host: 
+
+./network --client dns-name-of-other-host.com 9999
+
+have fun seeing the msgs floating around
+
+
Index: branches/heathaze/src/subprojects/network/isolated_unit_test.cc
===================================================================
--- branches/heathaze/src/subprojects/network/isolated_unit_test.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/network/isolated_unit_test.cc	(revision 9940)
@@ -0,0 +1,15 @@
+
+
+
+#include "../../lib/network/converter.h"
+
+
+int main(int argc, char** argv)
+{
+ 
+  float x = 3234.0f;
+  
+  byte* b = Converter::floatToByteArray(x);
+  
+  return 0;
+}
Index: branches/heathaze/src/subprojects/network/network_unit_test.cc
===================================================================
--- branches/heathaze/src/subprojects/network/network_unit_test.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/network/network_unit_test.cc	(revision 9940)
@@ -0,0 +1,539 @@
+
+#include "stdlibincl.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include "shell_buffer.h"
+#include "class_list.h"
+
+#include "network_manager.h"
+#include "network_socket.h"
+#include "server_socket.h"
+#include "udp_server_socket.h"
+#include "udp_socket.h"
+#include "network_stream.h"
+#include "synchronizeable.h"
+#include "converter.h"
+#include "state.h"
+#include "shared_network_data.h"
+#include "message_manager.h"
+#include "network_log.h"
+
+#include "simple_sync.h"
+#include "read_sync.h"
+
+int verbose = 4;
+
+
+/* outputs the help */
+int startHelp(int argc, char** argv)
+{
+  printf("Network is a network unit test\n");
+  printf(" --help                     this output\n");
+  printf(" -st,  --sockettest         test network_socket\n");
+  printf(" -ft,  --frameworktest      test the network module\n");
+  printf(" --server [port number]     creates a test server\n");
+  printf(" --client [address] [port]  connects to a server\n");
+  printf(" --listen [address] [port]  just listens to this connection");
+  printf("\n");
+}
+
+
+/* test SDL network socket */
+int testSocket(int argc, char** argv)
+{
+  UdpServerSocket server(9999);
+
+  NetworkSocket* client1 = new UdpSocket("localhost", 9999);
+
+  NetworkSocket* server1 = NULL;
+  while ( server1 == NULL )
+  {
+    server.update();
+    server1 = server.getNewSocket();
+  }
+
+  assert( server1->isOk() );
+
+  NetworkSocket* client2 = new UdpSocket("localhost", 9999);
+
+  NetworkSocket* server2 = NULL;
+  while ( server2 == NULL )
+  {
+    server.update();
+    server2 = server.getNewSocket();
+  }
+
+  char buf[1024];
+
+  printf("read from client1 before sending data\n");
+  printf("result: %d bytes\n", client1->readPacket((byte*)buf, 1024));
+
+  printf("read from client2 before sending data\n");
+  printf("result: %d bytes\n", client2->readPacket((byte*)buf, 1024));
+
+  int n;
+  char * str1 = "client1 to server";
+  char * str2 = "server1 to client";
+  char * str3 = "client2 to server";
+  char * str4 = "server2 to client";
+  n = client1->writePacket((byte*)str1, strlen(str1)+1);
+  printf("%d bytes send from client1\n", n);
+  n = server1->writePacket((byte*)str2, strlen(str2)+1);
+  printf("%d bytes send from server1\n", n);
+  n = client2->writePacket((byte*)str3, strlen(str3)+1);
+  printf("%d bytes send from client2\n", n);
+  n = server2->writePacket((byte*)str4, strlen(str4)+1);
+  printf("%d bytes send from server2\n", n);
+  SDL_Delay(10);
+
+  server.update();
+
+  printf("read from server1\n");
+  n = server1->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from server2\n");
+  n = server2->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from client1\n");
+  n = client1->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from client2\n");
+  n = client2->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+
+  //22222222222222222222222222222222222222222
+  n = client1->writePacket((byte*)str1, strlen(str1)+1);
+  printf("%d bytes send from client1\n", n);
+  n = server1->writePacket((byte*)str2, strlen(str2)+1);
+  printf("%d bytes send from server1\n", n);
+  n = client2->writePacket((byte*)str3, strlen(str3)+1);
+  printf("%d bytes send from client2\n", n);
+  n = server2->writePacket((byte*)str4, strlen(str4)+1);
+  printf("%d bytes send from server2\n", n);
+  SDL_Delay(10);
+
+  server.update();
+
+  printf("read from server1\n");
+  n = server1->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from server2\n");
+  n = server2->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from client1\n");
+  n = client1->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from client2\n");
+  n = client2->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  //sending bigger packets than 255 is not supported
+#if 0
+  printf("try to send more than 255 bytes\n");
+  printf("result: %d\n", client1->writePacket((byte*)buf, 1000));
+
+  server1->writePacket((byte*)str1, strlen(str1)+1);
+  SDL_Delay(500);
+  printf("try to read with a too small buffer\n");
+  printf("result: %d\n", client1->readPacket((byte*)buf, strlen(str1)));
+#endif
+
+  delete client1;
+  delete client2;
+  delete server1;
+  delete server2;
+
+  return 0;
+}
+
+
+int testFramework(int argc, char** argv)
+{
+  printf("=================\n");
+  printf("TestFramework\n");
+  printf("=================\n");
+
+  Synchronizeable* clientSync = new SimpleSync( std::string("Client") );
+  Synchronizeable* serverSync = new SimpleSync( std::string("Server") );
+
+  unsigned int port = 9999;
+
+  /* create the network manager */
+  NetworkManager* nm = NetworkManager::getInstance();
+
+  /* initialize the network manager */
+  nm->initialize();
+
+  /* create a server stream */
+  nm->createMasterServer(port);
+
+  /* esatblish a connection */
+  IP ip;
+  int error = SDLNet_ResolveHost(&ip, "127.0.0.1", port);
+  //SDLNet_ResolveHost(&ip, "localhost", port);
+  if(error == -1)
+    printf("\n\nerror on address resolution, program inconsistancy\n\n");
+  nm->createClient("localhost", port);
+  nm->connectSynchronizeable( *clientSync );
+  /* adding some break for connection setup */
+  SDL_Delay(20);
+
+  /* synchronize the data 1 time (increment for longer tests) */
+  for( int i = 0; i < 3; i++)
+  {
+    nm->synchronize( 1000 );
+    /* simulate the network delay */
+    SDL_Delay(50);
+  }
+
+  printf("Test finished\n");
+
+
+  /* delete the network manager again */
+  delete nm;
+
+  delete clientSync;
+  delete serverSync;
+
+  return 0;
+}
+
+bool testCB( MessageType messageType, byte * data, int dataLength, void * someData, int userId )
+{
+  printf("GOT MESSAGE: %s\n", data);
+  return true;
+}
+
+/**
+ *
+ * @param argc
+ * @param argv
+ * @return
+ */
+int startServer(int argc, char** argv)
+{
+
+
+  State::setOnline(true);
+  SharedNetworkData::getInstance()->setGameServer( true );
+  printf("Starting Server on port %i\n", 9999);
+
+  NetworkManager* netMan = NetworkManager::getInstance();
+
+  netMan->initialize();
+
+  netMan->createMasterServer(/**ss, */ 9999);
+
+  SimpleSync* ss = new SimpleSync("Server");
+  ss->setSynchronized( true );
+
+  NetworkLog::getInstance()->listen( 8888 );
+
+  //MessageManager::getInstance()->initUser( 1 );
+  MessageManager::getInstance()->registerMessageHandler( TESTMESSAGEID, testCB, NULL );
+
+  SDL_Delay(20);
+
+  for(;;)
+  {
+    MessageManager::getInstance()->sendMessage( TESTMESSAGEID, (byte*)"server to client", 18, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
+    netMan->synchronize( 100 );
+    SDL_Delay(100);
+    ss->debug();
+  }
+
+  delete netMan;
+  delete ss;
+
+
+  return 0;
+}
+
+
+int startClient(int argc, char** argv)
+{
+
+
+  State::setOnline(true);
+  NetworkManager* netMan = NetworkManager::getInstance();
+
+
+  netMan->initialize();
+
+  std::string host;
+
+  if ( argc > 2 )
+    host = argv[2];
+  else
+    host = "localhost";
+
+  netMan->createClient(host, 9999);
+
+//  SimpleSync* ss = new SimpleSync("SimpleSync");
+//  ss->setSynchronized( true );
+//  netMan->connectSynchronizeable( *ss );
+
+  NetworkLog::getInstance()->listen( 7777 );
+
+  SimpleSync * ss = NULL;
+
+  //MessageManager::getInstance()->initUser( 0 );
+  MessageManager::getInstance()->registerMessageHandler( TESTMESSAGEID, testCB, NULL );
+
+  for(;;)
+  {
+    netMan->synchronize( 100 );
+    MessageManager::getInstance()->sendMessage( TESTMESSAGEID, (byte*)"client to server", 18, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
+    ss = dynamic_cast<SimpleSync*>(ClassList::getObject( "Server", CL_SIMPLE_SYNC ) );
+    SDL_Delay(100);
+    if (ss)
+      ss->debug();
+  }
+
+
+  delete netMan;
+  delete ss;
+
+  return 0;
+}
+
+
+
+int startListen(int argc, char** argv)
+{
+  if( argc < 3)
+  {
+    printf(" Wrong arguments try following notations:\n");
+    printf("   --listen [server ip] [port number]\n");
+    printf("   --listen [server name] [port number]\n");
+    return 0;
+  }
+
+  char* name = argv[2];
+  int port = atoi(argv[3]);
+  printf("Connecting to %s, on port %i\n", name, port);
+
+  IP ip;
+  int error = SDLNet_ResolveHost(&ip, name, port);
+  if(error == -1)
+    printf("\n\nerror on address resolution, program inconsistancy\n\n");
+
+  NetworkManager* netMan = NetworkManager::getInstance();
+  Synchronizeable* ss = new SimpleSync("SimpleSync\0");
+
+  netMan->createClient( name, port );
+  netMan->connectSynchronizeable( *ss );
+
+  for(;;)
+  {
+    netMan->synchronize( 1000 );
+    SDL_Delay(10);
+  }
+
+
+  delete netMan;
+  delete ss;
+
+  return 0;
+}
+
+void testFloatConverter(float f)
+{
+#if 0
+  char* s = Converter::floatToBinString(f);
+  printf("%f = ", f);
+  printf(s); printf("\n");
+
+  byte* res = Converter::floatToByteArray(f);
+  printf("Byte Array: ");
+  for (int i = 0; i < 4; i++)
+//    printf("%i  ", res[i]);
+  printf("\n");
+
+  float b = Converter::byteArrayToFloat(res);
+  printf("ReConvert: %f \n", b);
+#endif
+}
+
+void testFloatConverter2(float f)
+{
+#if 0
+  char* s = Converter::floatToBinString(f);
+  printf("### %f = ", f);
+  printf(s); printf("\n");
+
+  byte* res = Converter::_floatToByteArray(f);
+  printf("Byte Array: ");
+  for (int i = 0; i < 4; i++)
+    printf("%i  ", res[i]);
+  printf("\n");
+
+  float b = Converter::_byteArrayToFloat(res);
+  printf("ReConvert: %f \n", b);
+#endif
+}
+int converter(int argc, char** argv)
+{
+  /*
+  int x = 200564786;
+  printf("To convert: %i\n", x);
+  byte* res = Converter::intToByteArray(x);
+  for (int i = 0; i < 4; i++)
+    printf("%i  ", res[i]);
+  printf("\n");
+
+  int z = Converter::byteArrayToInt(res);
+
+  printf("ReConvert: %i\n", z);
+
+
+  //float a = 5.4f;
+  //float b = 2.0f;
+  //printf("%f mod %f = %f", a, b, a % b);
+
+  printf("\n");
+
+  */
+  /*
+  float y;
+  char* s;
+
+  y = 12.0f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+
+  y = 24549026.0f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+
+  y = 12.4e20f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+
+  y = 4.7824f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+
+  y = -4.7824f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+
+  y = -14.35e14f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+                                                            */
+
+
+  /*
+  float a = 12.3f;
+
+  char* s = Converter::floatToBinString(a);
+  printf("%f = ", a);
+  printf(s); printf("\n");
+
+  byte* res = Converter::floatToByteArray(a);
+  printf("Byte Array: \n");
+  for (int i = 0; i < 4; i++)
+    printf("%i  ", res[i]);
+  printf("\n");
+
+  float b = Converter::byteArrayToFloat(res);
+  printf("ReConvert: %f \n", b);
+  */
+//  testFloatConverter(12.3e-53f); printf("\n");
+//  testFloatConverter(134.26455646546548741661675165f); printf("\n");
+ // testFloatConverter(35.67e14f); printf("\n");
+
+  testFloatConverter(12.3e-7f); printf("\n");
+  testFloatConverter(134.26455646546548741661675165f); printf("\n");
+  testFloatConverter(35.67e14f); printf("\n");
+
+  return 0;
+}
+
+
+
+/**
+ *
+ *  main function
+ *
+ * here the journey begins
+ */
+int main(int argc, char** argv)
+{
+  int i;
+  // here the pre-arguments are loaded, these are needed to go either to orxonx itself, Help, or Benchmark.
+  for(i = 1; i < argc; ++i)
+  {
+    //else if(!strcmp( "--gui", argv[i]) || !strcmp("-g", argv[i])) showGui = true;
+    if (! strcmp( "--sockettest", argv[i]) || !strcmp("-st", argv[i]))
+      return testSocket(argc, argv);
+    else if (! strcmp( "--frameworktest", argv[i]) || !strcmp("-ft", argv[i]))
+      return testFramework(argc, argv);
+    else if (! strcmp( "--server", argv[i]) || !strcmp("-s", argv[i]))
+      return startServer(argc, argv);
+    else if (! strcmp( "--client", argv[i]) || !strcmp("-c", argv[i]))
+      return startClient(argc, argv);
+    else if (! strcmp( "--listen", argv[i]) || !strcmp("-l", argv[i]))
+      return startListen(argc, argv);
+    else if (! strcmp( "--converter", argv[i]) || !strcmp("-o", argv[i]))
+      return converter(argc, argv);
+  }
+
+  startHelp(argc, argv);
+
+  return 0;
+}
+
+
+//bool ShellBuffer::addBufferLineStatic(const char* line, ...)
+//{
+  //va_list arguments;
+  //vprintf(line, arguments);
+  //  printf("%s", line);
+//}
Index: branches/heathaze/src/subprojects/network/network_unit_test.h
===================================================================
--- branches/heathaze/src/subprojects/network/network_unit_test.h	(revision 9940)
+++ branches/heathaze/src/subprojects/network/network_unit_test.h	(revision 9940)
@@ -0,0 +1,24 @@
+/*!
+ * @file network_unit_test.h
+ * A network unit test modules: to test the the network lib without starting orxonox
+ */
+
+/* you will want to add such a a line at your header file also, since it will
+   prevent c++ from including your code twice*/
+#ifndef _NETWORK_UNIT_TEST_H
+#define _NETWORK_UNIT_TEST_H
+
+
+
+class NetworkUnitTest
+{
+  public:
+    NetworkUnitTest();
+    virtual ~NetworkUnitTest();
+
+    void start();
+    void stop();
+
+};
+
+#endif /* _NETWORK_UNIT_TEST */
Index: branches/heathaze/src/subprojects/network/read_sync.cc
===================================================================
--- branches/heathaze/src/subprojects/network/read_sync.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/network/read_sync.cc	(revision 9940)
@@ -0,0 +1,100 @@
+/*
+  orxonox - the future of 3D-vertical-scrollers
+
+  Copyright (C) 2004 orx
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+      the Free Software Foundation; either version 2, or (at your option)
+      any later version.
+
+### File Specific:
+    main-programmer: Patrick Boenzli
+    co-programmer:
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+          For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "read_sync.h"
+
+#include "debug.h"
+
+
+/**
+ *  default constructor
+ */
+ReadSync::ReadSync(const char* name)
+  : Synchronizeable()
+{
+  /* define the local buffer size */
+
+  this->inLength = 100;
+  this->recLength = 0;
+  this->inData = new byte[this->inLength];
+
+  /* init the buffer data */
+  for( int i = 0; i < this->inLength; i++)
+  {
+    this->inData[i] = 0;
+  }
+
+}
+
+
+/**
+ *  default destructor deletes all unneded stuff
+ */
+ReadSync::~ReadSync()
+{
+
+  if( this->inData)
+    delete[] this->inData;
+}
+
+
+/**
+ *  write data to Synchronizeable
+ */
+int ReadSync::writeBytes(const byte* data, int length, int sender)
+{
+  PRINTF(0)("ReadSync: got %i bytes of data\n", length);
+  this->recLength = length;
+  if(this->inLength < length)
+    PRINTF(0)("ERROR: local buffer is smaller than the data to receive.\n");
+
+  /* copy the data localy */
+  for( int i = 0; i < length; i++)
+  {
+    this->inData[i] = data[i];
+  }
+  /* and debug output */
+  this->writeDebug();
+}
+
+
+/**
+ *  read data from Synchronizeable
+ */
+int ReadSync::readBytes(byte* data, int maxLength, int * reciever)
+{
+  return 0;
+}
+
+
+void ReadSync::writeDebug() const
+{
+  PRINTF(0)("Write in bytes: \t(0 <-) |");
+  for(int i = 0; i < this->recLength; i++)
+  {
+    PRINT(0)(" [%u] ",this->inData[i]);
+  }
+  PRINT(0)("|\n");
+}
+
+
+void ReadSync::readDebug() const
+{}
Index: branches/heathaze/src/subprojects/network/read_sync.h
===================================================================
--- branches/heathaze/src/subprojects/network/read_sync.h	(revision 9940)
+++ branches/heathaze/src/subprojects/network/read_sync.h	(revision 9940)
@@ -0,0 +1,33 @@
+/*!
+ * @file simple_sync.h
+ *  implementation of a network sync test
+ */
+
+#ifndef _READ_SYNC
+#define _READ_SYNC
+
+#include "synchronizeable.h"
+
+
+class ReadSync : public Synchronizeable
+  {
+  public:
+    ReadSync(const char* name);
+    virtual ~ReadSync();
+
+    virtual int writeBytes(const byte* data, int length, int sender);
+    virtual int readBytes(byte* data, int maxLength, int * reciever);
+
+
+  private:
+    virtual void writeDebug() const;
+    virtual void readDebug() const;
+
+
+  private:
+    byte* inData;
+    int   inLength;
+    int   recLength;
+  };
+
+#endif /* _READ_SYNC */
Index: branches/heathaze/src/subprojects/network/simple_sync.cc
===================================================================
--- branches/heathaze/src/subprojects/network/simple_sync.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/network/simple_sync.cc	(revision 9940)
@@ -0,0 +1,74 @@
+/*
+  orxonox - the future of 3D-vertical-scrollers
+
+  Copyright (C) 2004 orx
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+      the Free Software Foundation; either version 2, or (at your option)
+      any later version.
+
+### File Specific:
+    main-programmer: Patrick Boenzli
+    co-programmer:
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+          For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "simple_sync.h"
+
+#include "class_id_DEPRECATED.h"
+#include "loading/fast_factory.h"
+#include "lib/util/loading/factory.h"
+
+#include "debug.h"
+
+CREATE_FACTORY(SimpleSync, CL_SIMPLE_SYNC);
+
+
+/**
+ *  default constructor
+ */
+SimpleSync::SimpleSync( std::string name )
+{
+  setName( name );
+  this->setClassID( CL_SIMPLE_SYNC, "SimpleSync" );
+  in = 0;
+  out = 1;
+  syncStr = "hallo test test";
+  id = this->registerVarId( new SynchronizeableInt( &in, &out, "var", PERMISSION_ALL ) );
+  registerVar( new SynchronizeableString( &syncStr, &syncStr, "syncStr" ) );
+}
+
+
+/**
+ *  default destructor deletes all unneded stuff
+ */
+SimpleSync::~SimpleSync()
+{
+}
+
+void SimpleSync::debug( )
+{
+  printf("IN: %d OUT: %d\n", in, out);
+  printf("str: %s\n", syncStr.c_str());
+}
+
+SimpleSync::SimpleSync( const TiXmlElement * root )
+{
+  setName( "" );
+  this->setClassID( CL_SIMPLE_SYNC, "SimpleSync" );
+  in = 0;
+  out = 1;
+  syncStr = "hallo test test";
+  id = this->registerVarId( new SynchronizeableInt( &in, &out, "var", PERMISSION_ALL ) );
+  registerVar( new SynchronizeableString( &syncStr, &syncStr, "syncStr" ) );
+}
+
+
+
+
Index: branches/heathaze/src/subprojects/network/simple_sync.h
===================================================================
--- branches/heathaze/src/subprojects/network/simple_sync.h	(revision 9940)
+++ branches/heathaze/src/subprojects/network/simple_sync.h	(revision 9940)
@@ -0,0 +1,29 @@
+/*!
+ * @file simple_sync.h
+ *  implementation of a network sync test
+ */
+
+#ifndef _SIMPLE_SYNC
+#define _SIMPLE_SYNC
+
+#include "synchronizeable.h"
+
+
+class SimpleSync : public Synchronizeable
+  {
+  public:
+    SimpleSync( std::string name);
+    SimpleSync(const TiXmlElement* root = NULL);
+    virtual ~SimpleSync();
+    
+    void debug();
+
+
+  private:
+    int in;
+    int out;
+    std::string syncStr;
+    int id;
+  };
+
+#endif /* _SIMPLE_SYNC */
Index: branches/heathaze/src/subprojects/network/write_sync.cc
===================================================================
--- branches/heathaze/src/subprojects/network/write_sync.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/network/write_sync.cc	(revision 9940)
@@ -0,0 +1,123 @@
+/*
+  orxonox - the future of 3D-vertical-scrollers
+
+  Copyright (C) 2004 orx
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+      the Free Software Foundation; either version 2, or (at your option)
+      any later version.
+
+### File Specific:
+    main-programmer: Patrick Boenzli
+    co-programmer:
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+          For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "write_sync.h"
+
+#include "debug.h"
+
+
+/**
+ *  default constructor
+ */
+WriteSync::WriteSync(const char* name)
+  : Synchronizeable()
+{
+  /* define the local buffer size */
+  this->outLength = 10;
+  this->recLength = 0;
+  this->inLength = 40;
+  this->outData = new byte[this->outLength];
+  this->inData = new byte[this->inLength];
+
+  /* init the buffer data */
+  for( int i = 0; i < this->outLength; i++)
+  {
+    this->outData[i] = i;
+  }
+  for( int i = 0; i < this->inLength; i++)
+  {
+    this->inData[i] = 0;
+  }
+
+}
+
+
+/**
+ *  default destructor deletes all unneded stuff
+ */
+WriteSync::~WriteSync()
+{
+  if( this->outData)
+    delete[] this->outData;
+  if( this->inData)
+    delete[] this->inData;
+}
+
+
+/**
+ *  write data to Synchronizeable
+ */
+int WriteSync::writeBytes(const byte* data, int length, int sender)
+{
+  PRINTF(0)("WriteSync: got %i bytes of data\n", length);
+  this->recLength = length;
+  if(this->inLength < length)
+    PRINTF(0)("ERROR: local buffer is smaller than the data to receive.\n");
+
+  /* copy the data localy */
+  for( int i = 0; i < length; i++)
+  {
+    this->inData[i] = data[i];
+  }
+  /* and debug output */
+  this->writeDebug();
+}
+
+
+/**
+ *  read data from Synchronizeable
+ */
+int WriteSync::readBytes(byte* data, int maxLength, int * reciever)
+{
+  PRINTF(0)("WriteSync: sent %i bytes of data\n", this->outLength);
+
+  /* debug msg */
+  this->readDebug();
+
+  /* write the test message */
+  for( int i = 0; i < this->outLength; i++)
+    data[i] = this->outData[i];
+
+  /* return the length of the test */
+  return this->outLength;
+}
+
+
+void WriteSync::writeDebug() const
+{
+  PRINTF(0)("Write in bytes: \t(0 <-) |");
+  for(int i = 0; i < this->recLength; i++)
+  {
+    PRINT(0)(" [%u] ",this->inData[i]);
+  }
+  PRINT(0)("|\n");
+}
+
+
+void WriteSync::readDebug() const
+{
+  PRINTF(0)("Read out bytes: \t(0 ->) |");
+  for(int i = 0; i < this->outLength; i++)
+  {
+    PRINT(0)(" [%u] ",this->outData[i]);
+  }
+  PRINT(0)("|\n");
+}
Index: branches/heathaze/src/subprojects/network/write_sync.h
===================================================================
--- branches/heathaze/src/subprojects/network/write_sync.h	(revision 9940)
+++ branches/heathaze/src/subprojects/network/write_sync.h	(revision 9940)
@@ -0,0 +1,35 @@
+/*!
+ * @file simple_sync.h
+ *  implementation of a network sync test
+ */
+
+#ifndef _WRITE_SYNC
+#define _WRITE_SYNC
+
+#include "synchronizeable.h"
+
+
+class WriteSync : public Synchronizeable
+  {
+  public:
+    WriteSync(const char* name);
+    virtual ~WriteSync();
+
+    virtual int writeBytes(const byte* data, int length, int sender);
+    virtual int readBytes(byte* data, int maxLength, int * reciever);
+
+
+  private:
+    virtual void writeDebug() const;
+    virtual void readDebug() const;
+
+
+  private:
+    byte* inData;
+    int   inLength;
+    int   recLength;
+    byte* outData;
+    int   outLength;
+  };
+
+#endif /* _WRITE_SYNC */
Index: branches/heathaze/src/subprojects/others/TTFtoIMG.cc
===================================================================
--- branches/heathaze/src/subprojects/others/TTFtoIMG.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/others/TTFtoIMG.cc	(revision 9940)
@@ -0,0 +1,89 @@
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+#include <string>
+
+
+TTF_Font* fontTTF = NULL;
+
+int getMaxHeight()
+{
+  if (fontTTF != NULL)
+    return TTF_FontHeight(fontTTF);
+  else
+    return 0;
+}
+
+
+void createAsciiImage(const std::string& fileName, unsigned int size)
+{
+  if (fontTTF == NULL)
+    return;
+  int height = getMaxHeight();
+
+  //
+  SDL_Color tmpColor = {0, 0, 0};
+  // Surface definition.
+  SDL_Rect tmpRect; // this represents a Rectangle for blitting.
+  SDL_Surface* tmpSurf =  SDL_CreateRGBSurface(SDL_SWSURFACE,
+                                               height*16, height*16,
+                                               32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
+                                               0x000000FF,
+                                               0x0000FF00,
+                                               0x00FF0000,
+                                               0xFF000000
+#else
+                                               0xFF000000,
+                                               0x00FF0000,
+                                               0x0000FF00,
+                                               0x000000FF
+#endif
+                                              );
+  tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;
+  SDL_SetClipRect(tmpSurf, &tmpRect);
+  int maxLineHeight = 0;
+
+  int posX, posY;
+  // all the interessting Glyphs
+  for (posY = 0; posY < 16; posY++)
+  {
+    for (posX = 0; posX < 16; posX++)
+    {
+      SDL_Surface* glyphSurf = NULL;
+      if (fontTTF != NULL)
+      {
+        SDL_Color white = {255, 255, 255};
+        glyphSurf = TTF_RenderGlyph_Blended(fontTTF, posX+16*posY, white);
+      }
+      if( glyphSurf != NULL )
+      {
+        tmpRect.x = height*posX;
+        tmpRect.y = height*posY;
+        SDL_SetAlpha(glyphSurf, 0, 0);
+
+        SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);
+        SDL_FreeSurface(glyphSurf);
+      }
+    }
+  }
+  SDL_SaveBMP(tmpSurf, fileName.c_str());
+  SDL_FreeSurface(tmpSurf);
+}
+
+
+
+int main (int argc, const char** argv)
+{
+  SDL_Init(0);
+  TTF_Init();
+  unsigned int renderSize = 32;
+
+  fontTTF = TTF_OpenFont(argv[1], renderSize);
+
+  createAsciiImage(argv[2], renderSize);
+
+  //  delete fontTTF;
+  TTF_Quit();
+  SDL_Quit();
+}
Index: branches/heathaze/src/subprojects/particles/Makefile.am
===================================================================
--- branches/heathaze/src/subprojects/particles/Makefile.am	(revision 9940)
+++ branches/heathaze/src/subprojects/particles/Makefile.am	(revision 9940)
@@ -0,0 +1,42 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+
+bin_PROGRAMS = particles
+
+particles_LDADD = $(MAINSRCDIR)/lib/physics/libORXphysics.a \
+                  $(MAINSRCDIR)/lib/event/libORXevent.a \
+                  $(MAINSRCDIR)/lib/particles/libORXparticles.a \
+                  $(MAINSRCDIR)/lib/shell/libORXshell.a \
+                  $(MAINSRCDIR)/lib/sound/libORXsound.a \
+                  $(MAINSRCDIR)/lib/graphics/libORXgraphics.a \
+                  $(MAINSRCDIR)/lib/graphics/importer/libORXimporter.a \
+                  $(MAINSRCDIR)/lib/physics/libORXphysics.a \
+                  $(MAINSRCDIR)/lib/tinyxml/libtinyxml.a \
+                  $(MAINSRCDIR)/lib/collision_detection/libORXcd.a \
+                  $(GTK2_LIBS) $(GTHREAD_LIBS) $(CURL_LIBS)
+
+particles_CPPFLAGS =  -DGUI_MODULE  \
+                      $(GTK2_CFLAGS) $(GTHREAD_CFLAGS) $(CURL_CFLAGS) $(MSBITFIELDS)
+
+particles_SOURCES= ../framework.cc \
+                   particle_fun.cc \
+                   $(MAINSRCDIR)/lib/graphics/light.cc \
+                   $(MAINSRCDIR)/util/state.cc \
+                   $(MAINSRCDIR)/world_entities/camera.cc \
+                   $(MAINSRCDIR)/world_entities/world_entity.cc \
+                   $(MAINSRCDIR)/lib/graphics/graphics_engine.cc \
+                   $(MAINSRCDIR)/lib/lang/base_object.cc \
+                   $(MAINSRCDIR)/lib/lang/class_list.cc \
+                   $(MAINSRCDIR)/lib/math/vector.cc \
+                   $(MAINSRCDIR)/util/loading/resource_manager.cc \
+                   $(MAINSRCDIR)/lib/coord/p_node.cc \
+                   $(MAINSRCDIR)/lib/gui/gtk_gui/gui_gtk.cc \
+                   $(MAINSRCDIR)/lib/util/substring.cc \
+                   $(MAINSRCDIR)/util/loading/load_param.cc \
+                   $(MAINSRCDIR)/util/loading/load_param_description.cc \
+		   $(MAINSRCDIR)/lib/util/helper_functions.cc \
+                   $(MAINSRCDIR)/util/loading/factory.cc \
+                   $(MAINSRCDIR)/lib/util/color.cc \
+                   $(MAINSRCDIR)/lib/parser/ini_parser/ini_parser.cc
+
Index: branches/heathaze/src/subprojects/particles/particle_fun.cc
===================================================================
--- branches/heathaze/src/subprojects/particles/particle_fun.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/particles/particle_fun.cc	(revision 9940)
@@ -0,0 +1,470 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   this file extends the framework file, so it renders what i want.
+*/
+
+#include "framework.h"
+
+#include "physics_engine.h"
+#include "particle_engine.h"
+#include "fields.h"
+#include "stdlibincl.h"
+#include "graphics_engine.h"
+#include "light.h"
+#include "util/loading/resource_manager.h"
+
+#include <dirent.h>
+
+#define PINIT_EMISSION_RATE          50
+#define PINIT_EMISSION_VELOCITY      5.0
+#define PINIT_EMISSION_MOMENTUM      1.0
+#define PINIT_SPREAD_ANGLE           0.1
+#define PINIT_EMITTER_TYPE           EMITTER_DOT
+#define PINIT_EMITTER_SIZE           1.0
+#define PINIT_START_RADIUS           5.0
+#define PINIT_END_RADIUS             0.0
+#define PINIT_LIFESPAN               1.0
+#define PINIT_CONSERVE_FACTOR        1.0
+#define PINIT_PARTICLE_TYPE          PARTICLE_SPRITE
+#define PINIT_INHERIT_SPEED          0.0
+#define PINIT_PARTICLE_MASS          1.0
+#define PINIT_MODEL_DIRECTORY        "models/"
+
+
+Field* twirl;
+Field* gravity;
+Field* pointGravity;
+
+void Framework::moduleInit(int argc, char** argv)
+{
+  GraphicsEngine::getInstance()->setWindowName("ParticlesFun", "particles");
+
+  verbose = 5;
+  ParticleEngine::getInstance();
+  PhysicsEngine::getInstance();
+
+
+  // Creating a Test Particle System
+
+  ParticleSystem* system = new ParticleSystem(100000, PINIT_PARTICLE_TYPE);
+  system->setRadius(0, PINIT_START_RADIUS, 0 );
+  system->setRadius(1, PINIT_END_RADIUS, 0 );
+  system->setLifeSpan(PINIT_LIFESPAN);
+
+  system->setConserve(PINIT_CONSERVE_FACTOR);
+  //system->setMass(5,3,6);
+
+  // Creating a Test Particle Emitter
+  ParticleEmitter* emitter = new ParticleEmitter(Vector(0 , 1, 0));
+  emitter->setEmissionRate(PINIT_EMISSION_RATE);
+  emitter->setEmissionVelocity(PINIT_EMISSION_VELOCITY ,0);
+  emitter->setSpread(PINIT_SPREAD_ANGLE ,0);
+  emitter->setType(PINIT_EMITTER_TYPE);
+  emitter->setSize(PINIT_EMITTER_SIZE);
+  emitter->setAbsCoor(Vector(3,0,0));
+  // Add the Flow from the Emitter into the System
+  ParticleEngine::getInstance()->addConnection(emitter, system);
+
+
+  twirl = new Twirl();
+  twirl->setMagnitude(0);
+  gravity = new Gravity();
+  gravity->setMagnitude(0);
+  pointGravity = new PointGravity();
+  pointGravity->setMagnitude(0);
+
+  new PhysicsConnection(system, gravity);
+  new PhysicsConnection(system, twirl);
+  new PhysicsConnection(system, pointGravity);
+
+  (new Light)->setAbsCoor(10, 10, 10);
+
+}
+
+void Framework::moduleEventHandler(SDL_Event* event)
+{
+  switch (event->type)
+    {
+    case SDL_KEYDOWN:
+      switch (event->key.keysym.sym)
+        {
+        case SDLK_i:
+          ParticleEngine::getInstance()->debug();
+          PhysicsEngine::getInstance()->debug();
+          break;
+        }
+    }
+}
+
+void Framework::moduleTick(float dt)
+{
+  PhysicsEngine::getInstance()->tick(dt);
+  ParticleEngine::getInstance()->tick(dt);
+}
+
+void Framework::moduleDraw() const
+{
+  ParticleEngine::getInstance()->draw();
+}
+
+
+void Framework::moduleHelp(void) const
+{
+  PRINT(0)("\n");
+  PRINT(0)("i - Particle-state Information\n\n");
+  PRINT(0)("\n");
+}
+
+int emitterChange(GtkWidget* nonInterest, void* widget)
+{
+  Option* option = (Option*) widget;
+  const char* name = option->getTitle();
+  char* value = option->save();
+
+  ParticleEmitter* tmpEmit = ParticleEngine::getInstance()->getEmitterByNumber(1);
+  if (tmpEmit)
+    {
+      if (!strcmp(name, "EmissionRate"))
+        {
+          tmpEmit->setEmissionRate(atof(value));
+          PRINT(4)("EmissionRate set to %f\n", atof(value));
+        }
+      else if (!strcmp(name, "Velocity"))
+        {
+          tmpEmit->setEmissionVelocity(atof(value));
+          PRINT(4)("Velocity set to %f\n", atof(value));
+        }
+      else if (!strcmp(name, "Momentum"))
+        {
+          tmpEmit->setEmissionMomentum(atof(value));
+          PRINT(4)("Momentum set to %f\n", atof(value));
+        }
+      else if(!strcmp(name, "SpreadAngle"))
+        {
+          tmpEmit->setSpread(atof(value), 0);
+          PRINT(4)("SpreadAngle set to %f\n", atof(value));
+        }
+      else if(!strcmp(name, "EmitterType"))
+        {
+          if (!strcmp(value, "EMITTER_DOT"))
+            tmpEmit->setType(EMITTER_DOT);
+          else if (!strcmp(value, "EMITTER_PLANE"))
+            tmpEmit->setType(EMITTER_PLANE);
+          else if (!strcmp(value, "EMITTER_CUBE"))
+            tmpEmit->setType(EMITTER_CUBE);
+          PRINT(4)("EmitterType set to %s\n", value);
+        }
+      else if(!strcmp(name, "EmitterSize"))
+        {
+          tmpEmit->setSize(atof(value));
+          PRINT(4)("EmitterSize set to %f\n", atof(value));
+        }
+        else if (!strcmp(name, "InheritSpeed"))
+        {
+          tmpEmit->setInheritSpeed(atof(value));
+          PRINT(4)("ParticleInheritSpeed set to %f\n", atof(value));
+        }
+    }
+  delete value;
+}
+
+
+int systemChange(GtkWidget* nonInterest, void* widget)
+{
+  Option* option = (Option*) widget;
+  const char* name = option->getTitle();
+  char* value = option->save();
+
+  ParticleSystem* tmpSys = ParticleEngine::getInstance()->getSystemByNumber(1);
+  if (tmpSys)
+    {
+      if (!strcmp(name, "StartRadius"))
+        {
+          tmpSys->setRadius(0, atof(value));
+          PRINT(4)("ParticleStartRadius set to %f\n", atof(value));
+        }
+      else if (!strcmp(name, "EndRadius"))
+        {
+          tmpSys->setRadius( 1, atof(value));
+          PRINT(4)("ParticleEndRadius set to %f\n", atof(value));
+        }
+
+      else if (!strcmp(name, "LifeSpan"))
+        {
+          tmpSys->setLifeSpan(atof(value));
+          PRINT(4)("ParticleLifeSpan set to %f\n", atof(value));
+        }
+
+      else if (!strcmp(name, "Mass"))
+        {
+          tmpSys->setMass(0, atof(value));
+          PRINT(4)("ParticleMass set to %f\n", atof(value));
+        }
+
+      else if (!strcmp(name, "ConserveFactor"))
+        {
+          tmpSys->setConserve(atof(value));
+          PRINT(4)("ParticleConserveFactor set to %f\n", atof(value));
+        }
+
+      else if (!strcmp(name, "ParticleType"))
+        {
+          if (!strcmp(value, "PARTICLE_DOT"))
+            tmpSys->setType(PARTICLE_DOT);
+          else if (!strcmp(value, "PARTICLE_SPARK"))
+            tmpSys->setType(PARTICLE_SPARK);
+          else if (!strcmp(value, "PARTICLE_SPRITE"))
+            tmpSys->setType(PARTICLE_SPRITE);
+
+          PRINT(4)("ParticleType set to %s\n", value);
+        }
+        else if(!strcmp(name, "ParticleModel"))
+        {
+          char* modelName = new char[strlen(PINIT_MODEL_DIRECTORY) + strlen(value)+1];
+          sprintf(modelName, "%s%s", PINIT_MODEL_DIRECTORY, value);
+          tmpSys->loadModel(modelName);
+          delete modelName;
+        }
+      else if (!strcmp(name, "RandomColor"))
+        {
+          tmpSys->setColor(0, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, 1);
+          tmpSys->setColor(.5, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, .5);
+          tmpSys->setColor(.5, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, 0);
+        }
+    }
+  delete value;
+}
+
+int fieldsChange(GtkWidget* nonInterest, void* widget)
+{
+  Option* option = (Option*) widget;
+  const char* name = option->getTitle();
+  char* value = option->save();
+
+
+  if (!strcmp(name, "Gravity"))
+    {
+      gravity->setMagnitude(atof(value));
+    }
+
+  else if (!strcmp(name, "Twirl"))
+    {
+      twirl->setMagnitude(atof(value));
+    }
+
+  else if (!strcmp(name, "PointGravity"))
+    {
+      pointGravity->setMagnitude(atof(value));
+    }
+
+}
+
+void Framework::moduleInitGui(int argc, char** argv)
+{
+  Window* guiMainWindow = NULL;
+
+  initGUI(0, NULL);
+
+  guiMainWindow = new Window("ParticlesFUN");
+  {
+    Box* windowBox = new Box('h');
+    {
+      Frame* emitterFrame = new Frame("emitter-settings");
+      {
+        Box* emitterBox = new Box('v');
+        {
+          emitterBox->fill(new Label("EmissionRate"));
+          Slider* EmissionRate = new Slider("EmissionRate", 0, 1000);
+          EmissionRate->connectSignal("value_changed", (void*)EmissionRate, emitterChange );
+          EmissionRate->setValue(PINIT_EMISSION_RATE);
+          EmissionRate->redraw();
+          emitterBox->fill(EmissionRate);
+
+          emitterBox->fill(new Label("Velocity"));
+          Slider* velocity = new Slider("Velocity", 0, 20);
+          velocity->setExactness(2);
+          velocity->connectSignal("value_changed", (void*)velocity, emitterChange );
+          velocity->setValue(PINIT_EMISSION_VELOCITY);
+          velocity->redraw();
+          emitterBox->fill(velocity);
+
+          emitterBox->fill(new Label("Momentum"));
+          Slider* Momentum = new Slider("Momentum", 0, 20);
+          Momentum->setExactness(2);
+          Momentum->connectSignal("value_changed", (void*)Momentum, emitterChange );
+          Momentum->setValue(PINIT_EMISSION_MOMENTUM);
+          Momentum->redraw();
+          emitterBox->fill(Momentum);
+
+          emitterBox->fill(new Label("SpreadAngle"));
+          Slider* SpreadAngle = new Slider("SpreadAngle", 0, M_PI);
+          SpreadAngle->setExactness(3);
+          SpreadAngle->connectSignal("value_changed", (void*)SpreadAngle, emitterChange );
+          SpreadAngle->setValue(PINIT_SPREAD_ANGLE);
+          SpreadAngle->redraw();
+          emitterBox->fill(SpreadAngle);
+
+          emitterBox->fill(new Label("EmitterType"));
+          Menu* EmitterType = new Menu("EmitterType");
+          EmitterType->addItem("EMITTER_DOT");
+          EmitterType->addItem("EMITTER_PLANE");
+          EmitterType->addItem("EMITTER_CUBE");
+          EmitterType->connectSignal("changed", (void*)EmitterType, emitterChange );
+          EmitterType->load("EMITTER_DOT");
+          emitterBox->fill(EmitterType);
+
+          emitterBox->fill(new Label("EmitterSize"));
+          Slider* EmitterSize = new Slider("EmitterSize", 0, 100);
+          EmitterSize->setExactness(1);
+          EmitterSize->connectSignal("value_changed", (void*)EmitterSize, emitterChange );
+          EmitterSize->setValue(PINIT_EMITTER_SIZE);
+          EmitterSize->redraw();
+          emitterBox->fill(EmitterSize);
+
+          emitterBox->fill(new Label("InheritSpeed"));
+          Slider* InheritSpeed = new Slider("InheritSpeed", 0, 1);
+          InheritSpeed->setExactness(3);
+          InheritSpeed->connectSignal("value_changed", (void*)InheritSpeed, emitterChange );
+          emitterBox->fill(InheritSpeed);
+        }
+        emitterFrame->fill(emitterBox);
+      }
+      windowBox->fill(emitterFrame);
+
+      Frame* systemFrame = new Frame("system-settings");
+      {
+        Box* systemBox = new Box('v');
+        {
+          systemBox->fill(new Label("StartRadius"));
+          Slider* StartRadius = new Slider("StartRadius", 0, 10);
+          StartRadius->setExactness(3);
+          StartRadius->connectSignal("value_changed", (void*)StartRadius, systemChange );
+          StartRadius->setValue(PINIT_START_RADIUS);
+          StartRadius->redraw();
+          systemBox->fill(StartRadius);
+
+          systemBox->fill(new Label("EndRadius"));
+          Slider* EndRadius = new Slider("EndRadius", 0, 10);
+          EndRadius->setExactness(3);
+          EndRadius->connectSignal("value_changed", (void*)EndRadius, systemChange );
+          EndRadius->setValue(PINIT_END_RADIUS);
+          EndRadius->redraw();
+          systemBox->fill(EndRadius);
+
+          systemBox->fill(new Label("ParticleMass"));
+          Slider* Mass = new Slider("Mass", 0, 10);
+          Mass->setExactness(2);
+          Mass->connectSignal("value_changed", (void*)Mass, systemChange );
+          Mass->setValue(PINIT_PARTICLE_MASS);
+          Mass->redraw();
+          systemBox->fill(Mass);
+
+
+          systemBox->fill(new Label("LifeSpan"));
+          Slider* LifeSpan = new Slider("LifeSpan", 0, 10);
+          LifeSpan->setExactness(3);
+          LifeSpan->connectSignal("value_changed", (void*)LifeSpan, systemChange );
+          LifeSpan->setValue(PINIT_LIFESPAN);
+          LifeSpan->redraw();
+          systemBox->fill(LifeSpan);
+
+          systemBox->fill(new Label("ConserveFactor"));
+          Slider* ConserveFactor = new Slider("ConserveFactor", 0, 1);
+          ConserveFactor->setExactness(3);
+          ConserveFactor->connectSignal("value_changed", (void*)ConserveFactor, systemChange );
+          ConserveFactor->setValue(PINIT_CONSERVE_FACTOR);
+          ConserveFactor->redraw();
+          systemBox->fill(ConserveFactor);
+
+          systemBox->fill(new Label("ParticleType"));
+          Menu* ParticleType = new Menu("ParticleType");
+          ParticleType->addItem("PARTICLE_DOT");
+          ParticleType->addItem("PARTICLE_SPARK");
+          ParticleType->addItem("PARTICLE_SPRITE");
+          ParticleType->connectSignal("changed", (void*)ParticleType, systemChange );
+          ParticleType->load("PARTICLE_SPRITE");
+          systemBox->fill(ParticleType);
+
+          systemBox->fill(new Label("ParticleModel"));
+          Menu* ParticleModel = new Menu("ParticleModel");
+          {
+            DIR* directory;
+            directory = opendir(ResourceManager::getFullName(PINIT_MODEL_DIRECTORY));
+            dirent* file;
+            while(file = readdir(directory))
+              if(strstr(file->d_name, ".obj"))
+                 ParticleModel->addItem(file->d_name);
+          }
+          ParticleModel->connectSignal("changed", (void*)ParticleModel, systemChange );
+          systemBox->fill(ParticleModel);
+
+
+          Button* RandomColor = new Button("RandomColor");
+          RandomColor->connectSignal("released", (void*)RandomColor, systemChange);
+          systemBox->fill(RandomColor);
+
+        }
+        systemFrame->fill(systemBox);
+      }
+      windowBox->fill(systemFrame);
+
+      Frame* fieldsFrame = new Frame("Field-Settings");
+      {
+        Box* fieldsBox = new Box('v');
+        {
+          fieldsBox->fill(new Label("Gravity"));
+          Slider* Gravity = new Slider("Gravity", 0, 10);
+          Gravity->setExactness(1);
+          Gravity->connectSignal("value_changed", (void*)Gravity, fieldsChange );
+          Gravity->setValue(0);
+          Gravity->redraw();
+          fieldsBox->fill(Gravity);
+
+
+          fieldsBox->fill(new Label("Twirl"));
+          Slider* Twirl = new Slider("Twirl", 0, 10);
+          Twirl->setExactness(1);
+          Twirl->connectSignal("value_changed", (void*)Twirl, fieldsChange );
+          Twirl->setValue(0);
+          Twirl->redraw();
+          fieldsBox->fill(Twirl);
+
+
+          fieldsBox->fill(new Label("PointGravity"));
+          Slider* PointGravity = new Slider("PointGravity", 0, 10);
+          PointGravity->setExactness(1);
+          PointGravity->connectSignal("value_changed", (void*)PointGravity, fieldsChange );
+          PointGravity->setValue(0);
+          PointGravity->redraw();
+          fieldsBox->fill(PointGravity);
+
+        }
+        fieldsFrame->fill(fieldsBox);
+      }
+      windowBox->fill(fieldsFrame);
+
+      Button* quitButton = new Button("quit");
+
+      quitButton->connectSignal("clicked", NULL, quitGui);
+      //  Window::mainWindow->connectSignal("remove", this, GuiExec::quitGui);
+      Window::mainWindow->connectSignal("destroy", NULL, quitGui);
+      windowBox->fill(quitButton);
+
+    }
+    guiMainWindow->fill(windowBox);
+  }
+  Window::mainWindow->showall();
+  Window::mainWindow->setSize(300, 500);
+}
Index: branches/heathaze/src/subprojects/recapture_mouse/Makefile.am
===================================================================
--- branches/heathaze/src/subprojects/recapture_mouse/Makefile.am	(revision 9940)
+++ branches/heathaze/src/subprojects/recapture_mouse/Makefile.am	(revision 9940)
@@ -0,0 +1,29 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+LIB_PREFIX=$(MAINSRCDIR)/lib
+include $(MAINSRCDIR)/lib/BuildLibs.am
+
+
+recapturemouse_LDFLAGS = \
+		$(MWINDOWS)
+
+
+bin_PROGRAMS = \
+		recapturemouse
+
+
+DEPENDENCIES = \
+		$(MAINSRCDIR)/world_entities/libORXwe.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/util/libORXutils.a
+
+LDADD = \
+		$(MAINSRCDIR)/util/libORXutils.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/world_entities/libORXwe.a \
+		$(libORXlibs_a_LIBRARIES_) \
+		$(MAINSRCDIR)/util/libORXutils.a
+
+recapturemouse_SOURCES= \
+		recapturer.cc
Index: branches/heathaze/src/subprojects/recapture_mouse/recapturer.cc
===================================================================
--- branches/heathaze/src/subprojects/recapture_mouse/recapturer.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/recapture_mouse/recapturer.cc	(revision 9940)
@@ -0,0 +1,27 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   this file extends the framework file, so it renders what i want.
+*/
+
+#include "event_handler.h"
+
+int verbose = 3;
+
+int main(int argc, char** argv)
+{
+  EventHandler::getInstance()->grabEvents(true);
+  EventHandler::getInstance()->grabEvents(false);
+  exit(-1);
+}
Index: branches/heathaze/src/subprojects/testmain/Makefile.am
===================================================================
--- branches/heathaze/src/subprojects/testmain/Makefile.am	(revision 9940)
+++ branches/heathaze/src/subprojects/testmain/Makefile.am	(revision 9940)
@@ -0,0 +1,13 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+
+AM_LDFLAGS=$(MWINDOWS)
+
+#"-O3 -pedantic -fPIC -ffast-math -I/usr/X11R6/include"
+
+
+bin_PROGRAMS=testmain
+testmain_SOURCES= testmain.cc
+
+noinst_HEADERS= 
Index: branches/heathaze/src/subprojects/testmain/testmain.cc
===================================================================
--- branches/heathaze/src/subprojects/testmain/testmain.cc	(revision 9940)
+++ branches/heathaze/src/subprojects/testmain/testmain.cc	(revision 9940)
@@ -0,0 +1,16 @@
+#include <dirent.h>
+#include <stdio.h>
+
+int main(int argc, char** argv)
+{
+  DIR* directory;
+  directory = opendir("/");
+  dirent* test;
+
+  while(test = readdir(directory))
+  {
+    printf("%s\n", test->d_name);
+  }
+
+
+}
Index: branches/heathaze/src/util/Makefile.am
===================================================================
--- branches/heathaze/src/util/Makefile.am	(revision 9940)
+++ branches/heathaze/src/util/Makefile.am	(revision 9940)
@@ -0,0 +1,57 @@
+MAINSRCDIR=..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXutils.a
+
+libORXutils_a_SOURCES = \
+			object_manager.cc \
+			state.cc \
+			hud.cc \
+			\
+			game_rules.cc \
+			network_game_rules.cc \
+			multiplayer_team_deathmatch.cc \
+			singleplayer_shootemup.cc \
+			\
+			\
+			\
+			mission_goal.cc\
+			kill_target.cc\
+			kill.cc \
+			\
+			signal_handler.cc \
+			\
+			animation/animation3d.cc \
+			animation/animation.cc \
+			animation/animation_player.cc \
+			\
+			track/pilot_node.cc
+
+#			track/track_manager.cc \
+			track/track_node.cc
+
+noinst_HEADERS =        \
+			object_manager.h \
+			state.h \
+			hud.h \
+			\
+			game_rules.h \
+			network_game_rules.h \
+			multiplayer_team_deathmatch.h \
+			singleplayer_shootemup.h \
+			\
+			mission_goal.cc\
+			kill_target.h\
+			kill.h \
+			\
+			signal_handler.h \
+			\
+			animation/animation3d.h \
+			animation/animation.h \
+			animation/animation_player.h \
+			animation/t_animation.h \
+			\
+			track/pilot_node.h
+
+#			track/track_manager.h \
+			track/track_node.h
Index: branches/heathaze/src/util/animation/animation.cc
===================================================================
--- branches/heathaze/src/util/animation/animation.cc	(revision 9940)
+++ branches/heathaze/src/util/animation/animation.cc	(revision 9940)
@@ -0,0 +1,135 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ANIM
+
+#include "animation.h"
+#include "debug.h"
+#include "animation_player.h"
+
+ObjectListDefinition(Animation);
+/**
+ *  creates a new Animation
+
+   This also adds the Animation automatically to the AnimationPlayer's list
+*/
+Animation::Animation()
+{
+  this->registerObject(this, Animation::_objectList);
+
+  // initialize a beginning KeyFrame, that will be deleted afterwards
+  this->keyFrameCount = 0;
+  this->bDelete = false;
+  this->baseObject = NULL;
+
+  // setting default values
+  this->keyFramesToPlay = -1;
+  this->localTime = 0.0;
+  this->bRunning = false;
+
+  AnimationPlayer::getInstance()->addAnimation(this);
+}
+
+/**
+ *  destructs the Animation
+
+   this also takes the animation out of the AnimationPlayer's list (if it is there)
+*/
+Animation::~Animation()
+{
+  AnimationPlayer::getInstance()->removeAnimation(this);
+}
+
+
+/**
+ *  Sets the infinitymode
+ * @param postInfinity How the Animation should advance after the last Keyframe
+*/
+void Animation::setInfinity(ANIM_INFINITY postInfinity)
+{
+  this->postInfinity = postInfinity;
+}
+
+/**
+ *  handles the Animation if it gets out of boundraries eg. if animation is finished.
+*/
+void Animation::handleInfinity()
+{
+  switch (this->postInfinity)
+    {
+    case ANIM_INF_CONSTANT:
+      this->localTime = 0.0;
+      this->bRunning = false;
+      break;
+    case ANIM_INF_REPLAY:
+      this->rewind();
+      this->bRunning = true;
+      break;
+    case ANIM_INF_REWIND:
+      this->stop();
+      break;
+    case ANIM_INF_DELETE: // this will possibly never be made
+      this->bDelete = true;
+      break;
+    }
+}
+
+/**
+ *  plays the animation back from the current Time forward
+*/
+void Animation::play()
+{
+  this->keyFramesToPlay = -1;
+  this->bRunning = true;
+}
+
+/**
+ *  plays the Next n keyframes
+ * @param n the Count of keyFrames to play.
+*/
+void Animation::playNextKeyframes(int n)
+{
+  this->keyFramesToPlay = n-1;
+  this->bRunning = true;
+}
+
+/**
+ *  Stops the animation. eg. pause(); rewind();
+*/
+void Animation::stop()
+{
+  this->keyFramesToPlay = -1;
+  this->rewind();
+  this->bRunning = true;
+  this->tick(0.0);
+  this->bRunning = false;
+}
+
+/**
+ *  Pauses the animation. Stays at the current Time
+*/
+void Animation::pause()
+{
+  this->bRunning = false;
+}
+
+/**
+ *  replays the animation, eg. rewind();play();
+*/
+void Animation::replay()
+{
+  this->rewind();
+  this->play();
+}
Index: branches/heathaze/src/util/animation/animation.h
===================================================================
--- branches/heathaze/src/util/animation/animation.h	(revision 9940)
+++ branches/heathaze/src/util/animation/animation.h	(revision 9940)
@@ -0,0 +1,139 @@
+/*!
+ * @file animation.h
+    A Subclass for all animations in orxonox
+*/
+
+#ifndef _ANIMATION_H
+#define _ANIMATION_H
+
+#include "base_object.h"
+#include "debug.h"
+
+#include "list.h"
+// FORWARD DECLARATION
+
+//! An enumerator of Functions to describe the flow of the Animation
+/**
+   @todo check with Patrick it of
+
+   description in speed to the next keyframe:
+   ANIM_CONSTANT: 0, infinity.
+   ANIM_LINEAR: equal
+   ANIM_SINE: fast, slow, fast
+   ANIM_COSINE: slow, fast, slow
+   ANIM_EXP: slow, fast
+   ANIM_NEG_EXP: fast, slow
+   ANIM_RANDOM: eratic
+
+   ANIM_NULL: !!DO NOT USE THIS!! only for internal handling
+
+   deprecated QUADRATIC
+*/
+typedef enum ANIM_FUNCTION
+{
+  ANIM_NULL         = 0,
+  ANIM_CONSTANT     = 1,
+  ANIM_LINEAR       = 2,
+  ANIM_SINE         = 3,
+  ANIM_COSINE       = 4,
+  ANIM_EXP          = 5,
+  ANIM_NEG_EXP      = 6,
+  ANIM_QUADRATIC    = 7,
+  ANIM_RANDOM       = 8,
+};
+
+#define ANIM_DEFAULT_FUNCTION ANIM_LINEAR      //!< A default function to choose from the above set
+
+//! An enumerator describing what the animation should do after the last keyframe.
+/**
+   ANIM_INF_CONSTANT stays at the end of the animation
+   ANIM_INF_REPLAY loops back to the beginning and replays the animation
+   ANIM_INF_REWIND loops back to the beginning and then stops the animation
+   ANIM_INF_DELETE deletes the animation. !! THIS IS DANGEROUS !! only do this with non-class variables
+*/
+typedef enum ANIM_INFINITY
+{
+  ANIM_INF_CONSTANT,
+  ANIM_INF_REPLAY,
+  ANIM_INF_REWIND,
+  ANIM_INF_DELETE
+}; //, ANIM_INF_LINEAR, ANIM_INF_PINGPONG};
+
+//! A Superclass for describing an animation (all animations will be derived from this one)
+/** implement in subclasses:
+ *
+ * De-/Constructor
+ * Animation Functions
+ * virtual tick
+ * addKeyFrame
+ * List of keyFrames
+ * currentKeyFrame/nextKeyFrame
+ * virtual rewind, to go to the first Keyframe. (other functions will call this one)
+*/
+class Animation : public BaseObject
+{
+  ObjectListDeclaration(Animation);
+public:
+  virtual ~Animation();
+
+  void setInfinity(ANIM_INFINITY postInfinity = ANIM_INF_CONSTANT);
+
+  void play(); // equals resume();
+  void playNextKeyframes(int n = 1);
+  void stop();
+  void pause();
+  void replay();
+  //! A virtual function that should change to the first keyframe.
+  virtual void rewind() = 0;
+
+  /** A virtual function that ticks the animation @param dt the time passed */
+  virtual void tick(float dt) = 0;
+
+  /** @returns the BaseObject, this animation operates on */
+  BaseObject* getBaseObject() const { return this->baseObject; };
+
+  /** @returns if the Animation should be deleted */
+  inline bool ifDelete() { return bDelete; };
+
+protected:
+  Animation();
+
+  void handleInfinity();
+
+protected:
+  // variables
+  float                 localTime;              //!< The Time passed since the beginning of the currentKeyFrame.
+  ANIM_INFINITY         postInfinity;           //!< describing what the animation should do after the last keyframe.
+
+  BaseObject*           baseObject;             //!< The same as object in the derived classes, but with reference to BaseObject
+  unsigned int          keyFrameCount;          //!< The Count of KeyFrames.
+  int                   keyFramesToPlay;        //!< How many more Keyframes to play. if negative it will be ignored if 0 stop.
+  bool                  bRunning;               //!< If the animation is running
+  bool                  bDelete;                //!< If true, the animation will be deleted through the AnimationPlayer.
+};
+
+
+
+
+/**********************TEST*******************************/
+//! a simple testClass for the animation
+class aTest
+{
+public:
+  inline aTest() { last = 0.0;}
+  /** a little debug information to show the results of this class @param f new value */
+  inline void littleDebug(float f) {  diff = f - last; printf("f=%f, diff=%f\n", f,diff); last = f;}
+private:
+  float     diff;           //!< difference from the last value
+  float     last;           //!< the last calculated value
+};
+
+//aTest::aTest() {}
+//aTest::~aTest() {}
+
+//void aTest::littleDebug(float f)
+
+/**********************TEST*******************************/
+
+
+#endif /* _ANIMATION_H */
Index: branches/heathaze/src/util/animation/animation3d.cc
===================================================================
--- branches/heathaze/src/util/animation/animation3d.cc	(revision 9940)
+++ branches/heathaze/src/util/animation/animation3d.cc	(revision 9940)
@@ -0,0 +1,486 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+   2005-04-17: Benjamin Grauer
+          Rewritte all functions, so it will fit into the Animation-class
+   2005-04-25: Patrick Boenzli
+          Extended the framework to support quatSlerp rotations. Each frame now supports diff mov/rot types. Implemented mov/rot functions
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ANIM
+
+#include "animation3d.h"
+
+#include "p_node.h"
+
+
+
+/**
+ *  standard constructor
+*/
+Animation3D::Animation3D(PNode* object)
+{
+  this->object = object;
+
+  // create a new List
+  this->keyFrameList = new tList<KeyFrame3D>();
+  KeyFrame3D* tmpKeyFrame = new KeyFrame3D;
+  tmpKeyFrame->position = Vector();
+  tmpKeyFrame->direction = Quaternion();
+  keyFrameList->add(tmpKeyFrame);
+
+  this->currentKeyFrame = tmpKeyFrame;
+  this->nextKeyFrame = tmpKeyFrame;
+
+  this->animFuncMov = NULL;//&Animation3D::mLinear;
+  this->animFuncRot = NULL;//&Animation3D::rLinear;
+
+}
+
+/**
+ *  standard deconstructor
+
+   deletes all the Keyframes
+*/
+Animation3D::~Animation3D()
+{
+  // delete all the KeyFrames
+  tIterator<KeyFrame3D>* itKF = keyFrameList->getIterator();
+  KeyFrame3D*  enumKF = itKF->firstElement();
+  while (enumKF)
+    {
+      delete enumKF;
+      enumKF = itKF->nextElement();
+    }
+  delete itKF;
+  delete this->keyFrameList;
+}
+
+/**
+ *  rewinds the Animation to the beginning (first KeyFrame and time == 0)
+*/
+void Animation3D::rewind()
+{
+  this->currentKeyFrame = keyFrameList->firstElement();
+  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
+  this->localTime = 0.0;
+  this->setAnimFuncMov(this->currentKeyFrame->animFuncMov);
+  this->setAnimFuncRot(this->currentKeyFrame->animFuncRot);
+}
+
+/**
+ *  Appends a new Keyframe
+ * @param position The position of the new Keyframe
+ * @param direction The direction of the new Keyframe.
+ * @param duration The duration from the new KeyFrame to the next one
+ * @param animFuncMov The function to animate position between this keyFrame and the next one
+ * @param animFuncRot The function to animate rotation between this keyFrame and the next one
+*/
+void Animation3D::addKeyFrame(Vector position, Quaternion direction, float duration,
+                              ANIM_FUNCTION animFuncMov, ANIM_FUNCTION animFuncRot)
+{
+  // some small check
+  if (duration <= 0.0)
+    duration = 1.0;
+  // if the Rotation-Animation-function is set ANIM_NULL, animFuncRot will match animFuncRot
+//  if (animFuncMov == ANIM_NULL)
+//    animFuncMov = ANIM_DEFAULT_FUNCTION;
+//  if (animFuncRot == ANIM_NULL)
+//    animFuncRot = animFuncMov;
+
+  KeyFrame3D* tmpKeyFrame;
+
+  // when adding the first frame
+  if (this->keyFrameCount == 0)
+    {
+      tmpKeyFrame = this->keyFrameList->firstElement();
+      //this->setAnimFuncMov(animFuncMov);
+      //this->setAnimFuncRot(animFuncRot);
+    }
+  else
+    {
+      tmpKeyFrame = new KeyFrame3D;
+      // when adding the second frame
+      if (this->currentKeyFrame == this->nextKeyFrame)
+        this->nextKeyFrame = tmpKeyFrame;
+      this->keyFrameList->add(tmpKeyFrame);
+    }
+
+  tmpKeyFrame->position = position;
+  //tmpKeyFrame->lastPosition = position;
+  tmpKeyFrame->direction = direction;
+  tmpKeyFrame->duration = duration;
+  tmpKeyFrame->animFuncMov = animFuncMov;
+  tmpKeyFrame->animFuncRot = animFuncRot;
+  this->keyFrameCount++;
+}
+
+/**
+ *  ticks the Animation
+ * @param dt how much time to tick
+*/
+void Animation3D::tick(float dt)
+{
+  if (this->bRunning)
+    {
+      this->localTime += dt;
+      if (localTime >= this->currentKeyFrame->duration)
+        {
+          if (likely(this->keyFramesToPlay != 0))
+            {
+              if (unlikely(this->keyFramesToPlay > 0))
+                --this->keyFramesToPlay;
+              // switching to the next Key-Frame
+              this->localTime -= this->currentKeyFrame->duration;
+              this->currentKeyFrame = this->nextKeyFrame;
+              // checking, if we should still Play the animation
+              if (this->currentKeyFrame == this->keyFrameList->lastElement())
+                this->handleInfinity();
+              this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
+              this->setAnimFuncMov(this->currentKeyFrame->animFuncMov);
+              this->setAnimFuncRot(this->currentKeyFrame->animFuncRot);
+            }
+          else
+            this->pause();
+        }
+      /* now animate it */
+      if (likely(this->animFuncMov != NULL))
+        (this->*animFuncMov)(this->localTime);
+      if (likely(this->animFuncRot != NULL))
+        (this->*animFuncRot)(this->localTime);
+    }
+}
+
+
+/*==Movement Section==========================================================*/
+
+/**
+ *  Sets The kind of movment Animation between this keyframe and the next one
+ * @param animFuncMov: The Type of Animation to set
+*/
+void Animation3D::setAnimFuncMov(ANIM_FUNCTION animFuncMov)
+{
+  switch (animFuncMov)
+    {
+    case ANIM_CONSTANT:
+      this->animFuncMov = &Animation3D::mConstant;
+      break;
+    case ANIM_LINEAR:
+      this->animFuncMov = &Animation3D::mLinear;
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->currentKeyFrame->lastPosition = Vector();
+      break;
+    case ANIM_SINE:
+      this->animFuncMov = &Animation3D::mSine;
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->currentKeyFrame->lastPosition = Vector();
+      break;
+    case ANIM_COSINE:
+      this->animFuncMov = &Animation3D::mCosine;
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->currentKeyFrame->lastPosition = Vector();
+      break;
+    case ANIM_EXP:
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->animFuncMov = &Animation3D::mExp;
+      break;
+    case ANIM_NEG_EXP:
+      this->animFuncMov = &Animation3D::mNegExp;
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->expFactorMov = -1.0 / this->currentKeyFrame->duration * logf(DELTA_X_3D);
+      this->currentKeyFrame->lastPosition = Vector();
+      break;
+    case ANIM_QUADRATIC:
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->animFuncMov = &Animation3D::mQuadratic;
+      break;
+    case ANIM_RANDOM:
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->animFuncMov = &Animation3D::mRandom;
+      break;
+    default:
+      this->animFuncMov = NULL;
+      break;
+    }
+}
+
+/**
+ *  stays at the value of the currentKeyFrame
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::mConstant(float timePassed) const
+{
+  //this->object->setRelCoor(this->currentKeyFrame->position);
+
+  /*
+    this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
+    this->tmpVect = this->tmpVect * this->localTime / this->currentKeyFrame->duration;
+    this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
+    this->lastPosition = this->tmpVect;
+  */
+}
+
+/**
+ *  linear interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement also do this for direction
+*/
+void Animation3D::mLinear(float timePassed) const
+{
+  Vector v = (this->nextKeyFrame->position - this->currentKeyFrame->position) * (timePassed/this->currentKeyFrame->duration);
+  this->object->shiftCoor(v - this->currentKeyFrame->lastPosition);
+  this->currentKeyFrame->lastPosition = v;
+}
+
+/**
+ *  a Sinusodial Interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::mSine(float timePassed) const
+{
+  Vector v;
+  if( timePassed  < this->currentKeyFrame->duration/2.0)
+    v = (this->nextKeyFrame->position - this->currentKeyFrame->position) * sin( M_PI * timePassed /this->currentKeyFrame->duration) / 2.0;
+  else
+    v = (this->nextKeyFrame->position - this->currentKeyFrame->position) * (2.0 + sin( M_PI * (- timePassed /this->currentKeyFrame->duration)) )/ 2.0;
+
+  this->object->shiftCoor(v - this->currentKeyFrame->lastPosition);
+  this->currentKeyFrame->lastPosition = v;
+}
+
+
+/**
+ *  a cosine interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::mCosine(float timePassed) const
+{
+  Vector v;
+  v = (this->nextKeyFrame->position - this->currentKeyFrame->position) * (1.0 + cos( M_PI * timePassed / this->currentKeyFrame->duration))/2.0;
+  this->object->shiftCoor(v - this->currentKeyFrame->lastPosition);
+  this->currentKeyFrame->lastPosition = v;
+
+
+  /*
+  this->object->setRelCoor( this->nextKeyFrame->position -
+                            (this->nextKeyFrame->position - this->currentKeyFrame->position) *
+                            (1.0 + cos( M_PI * timePassed / this->currentKeyFrame->duration))/2.0);
+  */
+}
+
+
+
+/**
+ *  an exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::mExp(float timePassed) const
+{
+  PRINTF(0)("no exp animation3d defined\n");
+  this->mLinear(timePassed);
+}
+
+/**
+ *  a negative exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::mNegExp(float timePassed) const
+{
+  Vector v;
+  v = (this->nextKeyFrame->position - this->currentKeyFrame->position) * (1.0 - expf(- timePassed * expFactorMov));
+  this->object->shiftCoor(v - this->currentKeyFrame->lastPosition);
+  this->currentKeyFrame->lastPosition = v;
+
+  /*
+  this->object->setRelCoor( this->currentKeyFrame->position +
+                            (this->nextKeyFrame->position - this->currentKeyFrame->position) *
+                            (1.0 - expf(- timePassed * expFactorMov)) );
+  */
+}
+
+
+/**
+ *  a quadratic interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::mQuadratic(float timePassed) const
+{
+  PRINTF(0)("no quadratic animation3d defined\n");
+  this->mLinear(timePassed);
+}
+
+/**
+ *  some random animation (fluctuating)
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::mRandom(float timePassed) const
+{
+  /*
+  this->object->setRelCoor(this->currentKeyFrame->position +
+                           (this->nextKeyFrame->position - this->currentKeyFrame->position) * (float)rand()/(float)RAND_MAX);
+  this->object->setRelDir(this->currentKeyFrame->direction +
+                          (this->nextKeyFrame->direction - this->currentKeyFrame->direction)* (float)rand()/(float)RAND_MAX);
+  */
+}
+
+
+/*==Rotation Section==========================================================*/
+
+
+/**
+ *  Sets The kind of rotation Animation between this keyframe and the next one
+ * @param animFuncRot: The Type of Animation to set
+*/
+void Animation3D::setAnimFuncRot(ANIM_FUNCTION animFuncRot)
+{
+  switch (animFuncRot)
+    {
+    case ANIM_CONSTANT:
+      this->animFuncRot = &Animation3D::rConstant;
+      break;
+    case ANIM_LINEAR:
+      this->animFuncRot = &Animation3D::rLinear;
+      break;
+    case ANIM_SINE:
+      this->animFuncRot = &Animation3D::rSine;
+      break;
+    case ANIM_COSINE:
+      this->animFuncRot = &Animation3D::rCosine;
+      break;
+    case ANIM_EXP:
+      this->animFuncRot = &Animation3D::rExp;
+      break;
+    case ANIM_NEG_EXP:
+      this->animFuncRot = &Animation3D::rNegExp;
+      this->expFactorRot = -1.0 / this->currentKeyFrame->duration * logf(DELTA_X_3D);
+      break;
+    case ANIM_QUADRATIC:
+      this->animFuncRot = &Animation3D::rQuadratic;
+      break;
+    case ANIM_RANDOM:
+      this->animFuncRot = &Animation3D::rRandom;
+      break;
+
+    default:
+      this->animFuncRot = NULL;
+    }
+}
+
+
+/**
+ *  stays at the value of the currentKeyFrame
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::rConstant(float timePassed) const
+{
+  this->object->setRelDir(this->currentKeyFrame->direction);
+}
+
+/**
+ *  linear interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement also do this for direction
+*/
+void Animation3D::rLinear(float timePassed) const
+{
+  this->object->setRelDir(Quaternion::quatSlerp( this->nextKeyFrame->direction,
+                          this->currentKeyFrame->direction,
+                          timePassed/this->currentKeyFrame->duration) );
+}
+
+/**
+ *  a Sinusodial Interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::rSine(float timePassed) const
+{
+  float scale;
+  if( timePassed < this->currentKeyFrame->duration / 2.0)
+    scale = sin( M_PI * timePassed / this->currentKeyFrame->duration);
+  else
+    scale = 1.0 - sin( M_PI * timePassed / this->currentKeyFrame->duration);
+
+  this->object->setRelDir(Quaternion::quatSlerp( this->nextKeyFrame->direction,
+                          this->currentKeyFrame->direction,
+                          scale) );
+}
+
+
+/**
+ *  a cosine interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::rCosine(float timePassed) const
+{
+  float scale = cos(M_PI * timePassed / this->currentKeyFrame->duration);
+  this->object->setRelDir(Quaternion::quatSlerp( this->nextKeyFrame->direction,
+                          this->currentKeyFrame->direction,
+                          scale) );
+}
+
+
+
+/**
+ *  an exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::rExp(float timePassed) const
+{
+  PRINTF(2)("exp rotation function not implemented\n");
+}
+
+/**
+ *  a negative exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::rNegExp(float timePassed) const
+{
+  float scale = (1.0 - expf(- timePassed * expFactorRot));
+  this->object->setRelDir(Quaternion::quatSlerp( this->nextKeyFrame->direction,
+                          this->currentKeyFrame->direction,
+                          scale) );
+}
+
+
+/**
+ *  a quadratic interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::rQuadratic(float timePassed) const
+{
+  PRINTF(0)("quadratic rotation alg not implemented\n");
+}
+
+/**
+ *  some random animation (fluctuating)
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::rRandom(float timePassed) const
+{
+  PRINTF(0)("random rotation alg not implemented\n");
+}
Index: branches/heathaze/src/util/animation/animation3d.h
===================================================================
--- branches/heathaze/src/util/animation/animation3d.h	(revision 9940)
+++ branches/heathaze/src/util/animation/animation3d.h	(revision 9940)
@@ -0,0 +1,84 @@
+/*!
+ * @file animation3d.h
+*/
+
+
+#include "animation.h"
+
+#include "vector.h"
+#include "quaternion.h"
+class PNode;
+
+#define DELTA_X_3D 0.05  //!< the percentag of the distance that doesn't have to be done by neg_exp (asymptotical) ~ maschinendelta
+
+//! KeyFrame3D Struct
+/**
+   This represents one point with direction of the animation
+*/
+typedef struct KeyFrame3D {
+  float             duration;              //!< The duration of this KeyFrame
+  Vector            position;              //!< The position of this KeyFrame
+  Vector            lastPosition;          //!< The last known position
+  Quaternion        direction;             //!< The direction of this KeyFrame
+  ANIM_FUNCTION     animFuncMov;           //!< with whitch function to iterate movement to the next KeyFrame3D
+  ANIM_FUNCTION     animFuncRot;           //!< with whitch function to iterate rotation to the next KeyFrame3D
+};
+
+//! Animation Class for 3D-transformations (movement and rotation)
+/**
+   This represents an animation for a object
+*/
+class Animation3D : public Animation
+{
+ public:
+  Animation3D(PNode* object);
+  virtual ~Animation3D();
+
+  virtual void rewind();
+
+  void addKeyFrame(Vector position, Quaternion direction,
+                   float time, ANIM_FUNCTION animFuncMov = ANIM_DEFAULT_FUNCTION,
+                   ANIM_FUNCTION animFuncRot = ANIM_NULL);
+  //  void addKeyFrame(KeyFrame3D* frame);
+
+  virtual void tick(float dt);
+
+ private:
+  // animation functions
+  void setAnimFuncMov(ANIM_FUNCTION animFunc);
+  void setAnimFuncRot(ANIM_FUNCTION animFunc);
+  void mConstant(float timePassed) const;
+  void mLinear(float timePassed) const;
+  void mSine(float timePassed) const;
+  void mCosine(float timePassed) const;
+  void mExp(float timePassed) const;
+  void mNegExp(float timePassed) const;
+  void mQuadratic(float timePassed) const;
+  void mRandom(float timePassed) const;
+  void rConstant(float timePassed) const;
+  void rLinear(float timePassed) const;
+  void rSine(float timePassed) const;
+  void rCosine(float timePassed) const;
+  void rExp(float timePassed) const;
+  void rNegExp(float timePassed) const;
+  void rQuadratic(float timePassed) const;
+  void rRandom(float timePassed) const;
+  //  ANIM_FUNCTION animFunc;
+  void (Animation3D::*animFuncMov)(float) const;      //!< A Function for the AnimationType
+  void (Animation3D::*animFuncRot)(float) const;      //!< A Function for the AnimationType
+
+
+ private:
+  KeyFrame3D*          currentKeyFrame;               //!< The current KeyFrame
+  KeyFrame3D*          nextKeyFrame;                  //!< The KeyFrame we iterate to
+  tList<KeyFrame3D>*   keyFrameList;                  //!< The KeyFrameList
+
+
+  // more class-local description
+  PNode*               object;                        //!< The Object from which to Animate something
+  Vector               lastPosition;                  //!< last Object
+  Vector               tmpVect;                       //!< temporary vector
+  float                deltaT;                        //!< time passed since last
+  float                expFactorMov;                  //!< exponential Factor for movement
+  float                expFactorRot;                  //!< exponential Factor for rotation
+};
Index: branches/heathaze/src/util/animation/animation_player.cc
===================================================================
--- branches/heathaze/src/util/animation/animation_player.cc	(revision 9940)
+++ branches/heathaze/src/util/animation/animation_player.cc	(revision 9940)
@@ -0,0 +1,164 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ANIM
+
+#include "animation_player.h"
+
+#include "compiler.h"
+
+
+
+ObjectListDefinition(AnimationPlayer);
+/**
+ *  standard constructor
+*/
+AnimationPlayer::AnimationPlayer ()
+{
+  this->registerObject(this, AnimationPlayer::_objectList);
+  this->setName("AnimationPlayer");
+
+  this->play();
+}
+
+/**
+ *  the singleton reference to this class
+*/
+AnimationPlayer* AnimationPlayer::singletonRef = NULL;
+
+/**
+ *  standard deconstructor
+
+   !! DANGER !! when unloading the AnimationPlayer no other Function
+   should reference any Animations, from the animationList because it
+   automatically deletes them.
+   This usually happens when unloading a World.
+*/
+AnimationPlayer::~AnimationPlayer ()
+{
+  // deleting the Animation List AND all the elements of the List
+  this->flush();
+
+  AnimationPlayer::singletonRef = NULL;
+}
+
+/**
+ *  adds an Animation to the AnimationList.
+ * @param animation the Animation to handle
+
+   when adding a Animation the Animation will too be deleted when
+   the AnimationPlayer gets deleted. Consider not adding it, or
+   unadding it with animation->notHandled();
+*/
+void AnimationPlayer::addAnimation(Animation* animation)
+{
+  this->animationList.push_back(animation);
+}
+
+/**
+ *  removes an Animation from the Animation List, WITHOUT deleting it.
+ * @param animation the Anmination to remove from the List
+*/
+void AnimationPlayer::removeAnimation(Animation* animation)
+{
+  this->animationList.remove(animation);
+}
+
+/**
+ *  empties the list AND deletes all the Animations
+*/
+void AnimationPlayer::flush()
+{
+  // deleting the Animation List AND all the elements of the List
+  while(this->animationList.size() > 0)
+  {
+    Animation* anim = this->animationList.front();
+    this->animationList.pop_front();
+    delete anim;
+  }
+}
+
+/**
+ *  Ticks all the animations in animationList
+ * @param timePassed the time passed since the last tick.
+ */
+void AnimationPlayer::tick(float timePassed)
+{
+  if (this->bRunning)
+  {
+      // iterate through all the animations and tick them.
+    std::list<Animation*>::iterator anim;
+    for (anim = this->animationList.begin(); anim != this->animationList.end(); anim++)
+    {
+      (*anim)->tick(timePassed);
+      if(unlikely((*anim)->ifDelete()))
+      {
+        this->animationList.remove(*anim);
+        delete *anim;
+      }
+    }
+  }
+}
+/**
+ *  starts playing the AnimationPlayer
+ */
+void AnimationPlayer::play()
+{
+  this->bRunning = true;
+}
+
+/**
+ *  pauses playing of the AnimationPlayer
+ */
+void AnimationPlayer::pause()
+{
+  this->bRunning = false;
+}
+
+/**
+ * @returns the animation from a certain baseobject
+   if multiple are found, it just retruns the first one
+   if none is found it returns NULL
+*/
+Animation* AnimationPlayer::getAnimationFromBaseObject(const BaseObject* baseObject) const
+{
+  std::list<Animation*>::const_iterator anim;
+  for (anim = this->animationList.begin(); anim != this->animationList.end(); anim++)
+    if((*anim)->getBaseObject() == baseObject)
+      return *anim;
+  return NULL;
+}
+
+
+
+/**
+ *  Outputs some nice debug-information
+*/
+void AnimationPlayer::debug()
+{
+  PRINT(0)("+------------------------------------+\n");
+  PRINT(0)("+ ANIMATION PLAYER DEBUG INFORMATION +\n");
+  PRINT(0)("+------------------------------------+\n");
+  PRINT(0)("| Reference: %p\n", this);
+  PRINT(0)("| CountOfAnims %d\n", this->animationList.size());
+  PRINT(0)("-Animation Information---------------+\n");
+  // Per ANIMATION DEBUG
+  std::list<Animation*>::iterator anim;
+  for (anim = this->animationList.begin(); anim != this->animationList.end(); anim++)
+    {
+      //      anim->debug();
+    }
+  PRINT(0)("+--------------------------------AP--+\n");
+}
Index: branches/heathaze/src/util/animation/animation_player.h
===================================================================
--- branches/heathaze/src/util/animation/animation_player.h	(revision 9940)
+++ branches/heathaze/src/util/animation/animation_player.h	(revision 9940)
@@ -0,0 +1,65 @@
+/*!
+ * @file animation_player.h
+*/
+
+#ifndef _ANIMATION_PLAYER_H
+#define _ANIMATION_PLAYER_H
+
+#include "base_object.h"
+#include "animation.h"
+
+#include <list>
+
+/* FORWARD DECLARATION */
+
+//! A AnimationPlayer, that handles the animation of all the Animations in the scene.
+/**
+   <b>AnimationPlayer usage:</b> \n
+
+   <b>Initialisation</b>: AnimationPlayer::getInstance() does the trick this is
+   usually done when initializing a world \n
+   <b>Adding Animations</b>: create an Animation the following Way:
+   \li Anim* animation = new Anim(); // also use any other Subclass of Animation to initialize this
+   \li set some parameters: also see the specific classes for more info
+   \n
+   if you do not want a specific Animation to be handled by the AnimationPlayer, you have to
+   unload it explicitely with animation->doNotHandle();
+   \n
+   eveything else will be done by the AnimationPlayer itself.\n
+*/
+class AnimationPlayer : public BaseObject
+{
+  ObjectListDeclaration(AnimationPlayer);
+
+public:
+  /** @returns a Pointer to the only object of this Class */
+  inline static AnimationPlayer* getInstance() { if (!singletonRef) singletonRef = new AnimationPlayer();  return singletonRef; };
+
+  virtual ~AnimationPlayer();
+
+  // animation handling
+  void addAnimation(Animation* animation);
+  void removeAnimation(Animation* animation);
+  void flush();
+
+  // time functions
+  void tick(float timePassed);
+  void play();
+  void pause();
+
+  Animation* getAnimationFromBaseObject(const BaseObject* baseObject) const;
+
+  void debug();
+
+private:
+  /* singleton */
+  AnimationPlayer();
+  static AnimationPlayer*      singletonRef;          //!< SingletonReference to this class.
+
+  /* class specific */
+  std::list<Animation*>        animationList;         //!< A List of Animations to be handled.
+  bool                         bRunning;              //!< If the AnimationPlayer is running.
+};
+
+
+#endif /* _ANIMATION_PLAYER_H */
Index: branches/heathaze/src/util/animation/t_animation.h
===================================================================
--- branches/heathaze/src/util/animation/t_animation.h	(revision 9940)
+++ branches/heathaze/src/util/animation/t_animation.h	(revision 9940)
@@ -0,0 +1,354 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file t_animation.h
+*/
+
+#ifndef _T_ANIMATION_H
+#define _T_ANIMATION_H
+
+#include "animation.h"
+
+#define DELTA_X 0.05  //!< the percentag of the distance that doesnt have to be done by neg_exp (asymptotical) ~ maschinendelta
+
+//! A Struct for Keyframes that simply hold a float
+typedef struct KeyFrameF
+{
+  float duration;             //!< duration of this keyframe
+  float value;                //!< value of this keyframe
+  ANIM_FUNCTION animFunc;     //!< with whitch function to iterate to the next KeyFrameF
+};
+
+
+//! A Class to handle some animation for single floated values.
+template<class T> class tAnimation : public Animation
+{
+ public:
+  tAnimation(T* object = NULL, void (T::*funcToAnim)(float) = NULL);
+  virtual ~tAnimation();
+
+  void setFuncToAnim(T* object, void (T::*funcToAnim)(float));
+
+  void addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc = ANIM_DEFAULT_FUNCTION);
+
+  virtual void rewind();
+  virtual void tick(float dt);
+
+ private:
+  // animation functions
+  void setAnimFunc(ANIM_FUNCTION animFunc);
+  float constant(float timePassed) const;
+  float linear(float timePassed) const;
+  float sine(float timePassed) const;
+  float cosine(float timePassed) const;
+  float exp(float timePassed) const;
+  float negExp(float timePassed) const;
+  float quadratic(float timePassed) const;
+  float random(float timePassed) const;
+
+
+  //  ANIM_FUNCTION animFunc
+  float (tAnimation<T>::*animFunc)(float) const;  //!< A Function for the AnimationType
+
+  KeyFrameF* currentKeyFrame;                     //!< The current KeyFrame
+  KeyFrameF* nextKeyFrame;                        //!< The KeyFrame we iterate to
+  tList<KeyFrameF>* keyFrameList;                 //!< The KeyFrameList
+
+  T* object;                                      //!< The Object from which to Animate something
+  void (T::*funcToAnim)(float);                   //!< The function to Animate
+
+  float expFactor;                                //!< some factors
+};
+
+
+
+/**
+ *  standard constructor
+*/
+template<class T>
+tAnimation<T>::tAnimation (T* object, void (T::*funcToAnim)(float))
+{
+  // create a new List
+  this->keyFrameList = new tList<KeyFrameF>();
+  KeyFrameF* tmpKeyFrame = new KeyFrameF;
+  tmpKeyFrame->value = 0.0;
+  tmpKeyFrame->duration = 1.0;
+  keyFrameList->add(tmpKeyFrame);
+
+  this->currentKeyFrame = tmpKeyFrame;
+  this->nextKeyFrame = tmpKeyFrame;
+
+  this->animFunc = &tAnimation<T>::linear;
+
+  this->setFuncToAnim(object, funcToAnim);
+}
+
+
+/**
+ *  standard deconstructor
+
+   deletes all the Keyframes
+*/
+template<class T>
+tAnimation<T>::~tAnimation ()
+{
+  // delete all the KeyFrames
+  tIterator<KeyFrameF>* itKF = keyFrameList->getIterator();
+  KeyFrameF*  enumKF = itKF->firstElement();
+  while (enumKF)
+    {
+      delete enumKF;
+      enumKF = itKF->nextElement();
+    }
+  delete itKF;
+  delete this->keyFrameList;
+}
+
+/**
+ *  rewinds the Animation to the beginning (first KeyFrame and time == 0)
+*/
+template<class T>
+void tAnimation<T>::rewind()
+{
+  this->currentKeyFrame = keyFrameList->firstElement();
+  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
+  this->localTime = 0.0;
+  this->setAnimFunc(this->currentKeyFrame->animFunc);
+}
+
+/**
+ *  sets the Function we want to animate
+ * @param object from what object do we want to animate
+ * @param funcToAnim which function
+*/
+template<class T>
+void tAnimation<T>::setFuncToAnim(T* object, void (T::*funcToAnim)(float))
+{
+  this->baseObject = this->object = object;
+  this->funcToAnim = funcToAnim;
+}
+
+/**
+ *  Appends a new Keyframe
+ * @param value the value of the new KeyFrame
+ * @param duration The duration from the new KeyFrame to the next one
+ * @param animFunc The function to animate between this keyFrame and the next one
+*/
+template<class T>
+void tAnimation<T>::addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc)
+{
+  // some small check
+  if (duration <= 0.0)
+    duration = 1.0;
+  if (animFunc == ANIM_NULL)
+    animFunc = ANIM_DEFAULT_FUNCTION;
+
+  KeyFrameF* tmpKeyFrame;
+
+  // when adding the first frame
+  if (this->keyFrameCount == 0)
+    {
+      tmpKeyFrame = this->keyFrameList->firstElement();
+      this->setAnimFunc(animFunc);
+    }
+  else
+    {
+      tmpKeyFrame = new KeyFrameF;
+      // when adding the second frame
+      if (this->currentKeyFrame == this->nextKeyFrame)
+        this->nextKeyFrame = tmpKeyFrame;
+      this->keyFrameList->add(tmpKeyFrame);
+    }
+
+  tmpKeyFrame->value = value;
+  tmpKeyFrame->duration = duration;
+  tmpKeyFrame->animFunc = animFunc;
+  this->keyFrameCount++;
+}
+
+/**
+ *  ticks the Animation
+ * @param dt how much time to tick
+*/
+template<class T>
+void tAnimation<T>::tick(float dt)
+{
+  if (this->bRunning)
+    {
+      this->localTime += dt;
+      if (localTime >= this->currentKeyFrame->duration)
+        {
+          if (likely(this->keyFramesToPlay != 0))
+            {
+              if (unlikely(this->keyFramesToPlay > 0))
+                --this->keyFramesToPlay;
+              // switching to the next Key-Frame
+              this->localTime -= this->currentKeyFrame->duration;
+
+              this->currentKeyFrame = this->nextKeyFrame;
+              // checking, if we should still Play the animation
+              if (this->currentKeyFrame == this->keyFrameList->lastElement())
+                this->handleInfinity();
+              this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
+
+              //printf("%p from:%f to:%f\n", this->currentKeyFrame,this->currentKeyFrame->value, this->nextKeyFrame->value);
+              this->setAnimFunc(this->currentKeyFrame->animFunc);
+            }
+          else
+            this->pause();
+        }
+
+      (this->object->*(funcToAnim))((this->*animFunc)(this->localTime));
+    }
+}
+
+/**
+ *  Sets The kind of Animation between this keyframe and the next one
+ * @param animFunc The Type of Animation to set
+*/
+template<class T>
+void tAnimation<T>::setAnimFunc(ANIM_FUNCTION animFunc)
+{
+  switch (animFunc)
+    {
+    default:
+    case ANIM_CONSTANT:
+      this->animFunc = &tAnimation<T>::constant;
+      break;
+    case ANIM_LINEAR:
+      this->animFunc = &tAnimation<T>::linear;
+      break;
+    case ANIM_SINE:
+      this->animFunc = &tAnimation<T>::sine;
+      break;
+    case ANIM_COSINE:
+      this->animFunc = &tAnimation<T>::cosine;
+      break;
+    case ANIM_EXP:
+      this->animFunc = &tAnimation<T>::exp;
+      break;
+    case ANIM_NEG_EXP:
+        this->animFunc = &tAnimation<T>::negExp;
+        expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
+        break;
+    case ANIM_QUADRATIC:
+      this->animFunc = &tAnimation<T>::quadratic;
+      break;
+    case ANIM_RANDOM:
+      this->animFunc = &tAnimation<T>::random;
+      break;
+    }
+}
+
+
+// animation functions
+/**
+ *  stays at the value of the currentKeyFrame
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::constant(float timePassed) const
+{
+  return this->currentKeyFrame->value;
+}
+
+/**
+ *  linear interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::linear(float timePassed) const
+{
+  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
+    * (timePassed / this->currentKeyFrame->duration);
+}
+
+/**
+ *  a Sinusodial Interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::sine(float timePassed) const
+{
+  if (timePassed * 2.0 < this->currentKeyFrame->duration)
+    return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
+      * sin( M_PI * timePassed / this->currentKeyFrame->duration)/2;
+  else
+    return this->nextKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
+      * sin( M_PI * (1.0 - timePassed / this->currentKeyFrame->duration))/2;
+  /*
+  printf("::%f::::%f::\n",timePassed/this->currentKeyFrame->duration,retVal);
+  return retVal;
+  */
+}
+
+/**
+ *  a cosine interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::cosine(float timePassed) const
+{
+  return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
+    (this->currentKeyFrame->value - this->nextKeyFrame->value) *
+    cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
+}
+
+/**
+ *  an exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::exp(float timePassed) const
+{
+  return this->linear(timePassed);
+}
+
+/**
+ *  a negative exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::negExp(float timePassed) const
+{
+  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
+  float e = d * (1.0 - expf(- timePassed * expFactor));
+  return  this->currentKeyFrame->value - e;
+}
+
+/**
+ *  a quadratic interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::quadratic(float timePassed) const
+{
+  return this->linear(timePassed);
+}
+
+/**
+ *  some random animation (fluctuating)
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::random(float timePassed) const
+{
+  return this->currentKeyFrame->value +
+    (this->nextKeyFrame->value - this->currentKeyFrame->value) *
+    (float)rand()/(float)RAND_MAX;
+}
+
+#endif /* _T_ANIMATION_H */
Index: branches/heathaze/src/util/game_rules.cc
===================================================================
--- branches/heathaze/src/util/game_rules.cc	(revision 9940)
+++ branches/heathaze/src/util/game_rules.cc	(revision 9940)
@@ -0,0 +1,96 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_MODULE_GAME_RULES
+
+#include "game_rules.h"
+
+#include "util/loading/load_param_xml.h"
+#include "util/loading/factory.h"
+
+#include "util/mission_goal.h"
+
+#include "shared_network_data.h"
+
+#include "debug.h"
+
+
+
+ObjectListDefinition(GameRules);
+
+/**
+ * constructor
+ */
+GameRules::GameRules(const TiXmlElement* root)
+{
+  this->registerObject(this, GameRules::_objectList);
+}
+
+/**
+ * decontsructor
+ */
+GameRules::~GameRules()
+{}
+
+
+
+void GameRules::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+
+  LoadParamXML(root, "MissionGoal", this, GameRules, loadMissionGoal)
+      .describe("an XML-Element to load the missions from");
+}
+
+
+
+void GameRules::loadMissionGoal(const TiXmlElement* root)
+{
+  PRINTF(4)("Trying to load MissionGoals\n");
+  const TiXmlElement* element = root->FirstChildElement();
+  while( element != NULL)
+  {
+    PRINTF(4)("============ MissionGoal\n");
+    PRINTF(4)("Adding Mission Goal:%s\n", element->Value());
+    BaseObject* created = Factory::fabricate(element);
+    if (created != NULL /*&& created->isA(CL_GAME_RULES)*/)
+    {
+      MissionGoal* mg = dynamic_cast<MissionGoal*>(created);
+      this->addMissionGoal(mg);
+      // if there is a valid game rule loaded, break because it is not thought to load multiple game rules
+      break;
+    }
+    else
+    {
+      PRINTF(1)("Could not create a %s\n", element->Value());
+      delete created;
+    }
+    element = element->NextSiblingElement();
+  }
+}
+
+/**
+ * adding a kill event to the kill list
+ * @param kill the kill object containing all infos
+ */
+void GameRules::registerKill(const Kill& kill)
+{
+  if ( SharedNetworkData::getInstance()->isClient() || SharedNetworkData::getInstance()->isProxyServerActive())
+    return;
+
+  PRINTF(4)("Received Event: Kill\n");
+
+  this->killList.push_back( kill );
+}
+
Index: branches/heathaze/src/util/game_rules.h
===================================================================
--- branches/heathaze/src/util/game_rules.h	(revision 9940)
+++ branches/heathaze/src/util/game_rules.h	(revision 9940)
@@ -0,0 +1,62 @@
+
+/*!
+ * @file game_rules.h
+ * Defines game rules for this game
+ */
+
+#ifndef _GAME_RULES_H
+#define _GAME_RULES_H
+
+#include "base_object.h"
+#include <list>
+#include <vector>
+
+#include "kill.h"
+
+class TiXmlElement;
+class ObjectManager;
+class Player;
+class MissionGoal;
+class Kill;
+
+
+class GameRules : virtual public BaseObject
+{
+  ObjectListDeclaration(GameRules);
+
+  public:
+    GameRules(const TiXmlElement* root);
+    virtual ~GameRules();
+
+    virtual void loadParams(const TiXmlElement* root = NULL);
+    void loadMissionGoal(const TiXmlElement* root = NULL);
+
+
+    /** adding an mission goal to the game rules @param missionGoal the mission goal to add */
+    inline void addMissionGoal(MissionGoal* missionGoal) { this->missionList.push_back(missionGoal); }
+    /** adding a kill event to the kill list @param kill the kill object containing all infos */
+    void registerKill(const Kill& kill);
+    virtual void registerSpawn( WorldEntity * we ){}
+
+    virtual void onPlayerSpawn() {}
+    virtual void onPlayerDeath() {}
+
+    virtual void tick(float dt) = 0;
+    /** draws the stuff from the game rules if there is any need to */
+    void draw() {}
+
+
+  protected:
+    virtual void checkGameRules() {}
+
+
+  protected:
+    ObjectManager*              pObjectManager;         //!< reference to the current Object Manager
+    Player*                     localPlayer;            //!< reference to the local player
+    std::vector<MissionGoal*>   missionList;            //!< list of mission goals
+
+    std::list<Kill>             killList;               //!<  list of kills in the world
+};
+
+
+#endif /* _GAME_RULES_H */
Index: branches/heathaze/src/util/hud.cc
===================================================================
--- branches/heathaze/src/util/hud.cc	(revision 9940)
+++ branches/heathaze/src/util/hud.cc	(revision 9940)
@@ -0,0 +1,241 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "hud.h"
+
+#include "state.h"
+#include "debug.h"
+
+#include "world_entities/weapons/weapon_manager.h"
+#include "glgui_widget.h"
+
+#include "glgui_inputline.h"
+#include "specials/glgui_notifier.h"
+#include "elements/glgui_radar.h"
+
+
+
+/// HACK
+#include "player.h"
+#include "playable.h"
+
+ObjectListDefinition(Hud);
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+Hud::Hud ()
+{
+  this->registerObject(this, Hud::_objectList);
+
+  //this->setSize2D(
+  this->weaponManager = NULL;
+  this->energyWidget = NULL;
+  this->shieldWidget = NULL;
+  this->armorWidget = NULL;
+  this->resX = 1;
+  this->resY = 1;
+
+  this->inputLine = new OrxGui::GLGuiInputLine();
+  this->inputLine->setParent2D(this);
+  this->notifier = new OrxGui::GLGuiNotifier();
+  this->notifier->setParent2D(this);
+  notifier->setAbsCoor2D(100,100);
+
+  this->_radar = new OrxGui::GLGuiRadar();
+
+  this->subscribeEvent(ES_ALL, EV_VIDEO_RESIZE);
+  this->subscribeEvent(ES_ALL, SDLK_TAB);
+
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+Hud::~Hud ()
+{
+  delete this->inputLine;
+  delete this->notifier;
+
+  delete this->_radar;
+  // delete what has to be deleted here
+}
+
+
+void Hud::loadParams(const TiXmlElement* root)
+{
+  Element2D::loadParams(root);
+}
+
+void Hud::notifyUser(const std::string& message)
+{
+  this->notifier->pushNotifyMessage(message);
+}
+
+void Hud::setBackGround()
+{}
+
+void Hud::setEnergyWidget(OrxGui::GLGuiWidget* widget)
+{
+  // decopple old widget
+  if (this->energyWidget != NULL)
+  {
+    this->energyWidget->hide();
+  }
+
+  this->energyWidget = widget;
+  if (this->energyWidget != NULL)
+  {
+    this->energyWidget->show();
+    this->energyWidget->setBackgroundTexture( "hud_energy_background.png");
+    /*    this->energyWidget->frontMaterial().setDiffuseMap("hud_energy_bar.png");
+        this->energyWidget->frontMaterial().setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);*/
+  }
+
+  this->updateResolution();
+}
+
+void Hud::setShiledWidget(OrxGui::GLGuiWidget* widget)
+{}
+
+void Hud::setArmorWidget(OrxGui::GLGuiWidget* widget)
+{}
+
+void Hud::setWeaponManager(WeaponManager* weaponMan)
+{
+  if (this->weaponManager != NULL)
+  {
+    for (unsigned int i = 0; i < this->weaponManager->getSlotCount(); i++)
+    {
+      Weapon* weapon = this->weaponManager->getWeapon(i);
+      if (weapon != NULL)
+      {
+        weapon->getEnergyWidget()->hide();
+        this->weaponsWidgets.remove(weapon->getEnergyWidget());
+      }
+    }
+  }
+
+  this->weaponManager = weaponMan;
+
+  this->updateWeaponManager();
+  //  this->updateResolution();
+}
+
+void Hud::updateWeaponManager()
+{
+  // hide all the Widgets
+  std::list<OrxGui::GLGuiWidget*>::iterator weaponWidget;
+  for (weaponWidget = this->weaponsWidgets.begin(); weaponWidget != this->weaponsWidgets.end(); weaponWidget++)
+  {
+    (*weaponWidget)->hide();
+  }
+  this->weaponsWidgets.clear();
+
+  // add all that we need again.
+  if (this->weaponManager != NULL)
+    for (unsigned int i = 0; i < this->weaponManager->getSlotCount(); i++)
+    {
+      Weapon* weapon = this->weaponManager->getWeapon(i);
+      if (weapon != NULL)
+      {
+        //PRINTF(0)("WEAPON %s::%s in Slots\n", weapon->getClassCName(), weapon->getName());
+        weapon->getEnergyWidget()->show();
+        weapon->getEnergyWidget()->setBackgroundColor(Color(.8,.2,.11, 0.1));
+        weapon->getEnergyWidget()->setFrontColor(Color( .2,.5,.7,.6));
+        //      weapon->getEnergyWidget()->frontMaterial().setTransparency(.6);
+        this->weaponsWidgets.push_back(weapon->getEnergyWidget());
+      }
+    }
+  this->updateResolution();
+}
+
+void Hud::addWeaponWidget(OrxGui::GLGuiWidget* widget)
+{}
+
+void Hud::removeWeaponWidget(OrxGui::GLGuiWidget* widget)
+{}
+
+void Hud::updateResolution()
+{
+  this->resX = State::getResX();
+  this->resY = State::getResY();
+
+  this->setSize2D(.2 * this->resX, this->resY);
+  this->notifier->setAbsCoor2D(0.7 * this->resX, 0.3 * this->resY);
+  this->notifier->setWidgetSize(0.25 * this->resX, 0.6 * this->resY);
+
+
+  if (State::getPlayer() && State::getPlayer()->getPlayable() && State::getObjectManager())
+  {
+    PRINTF(4)("UPDATING RADAR\n");
+    this->_radar->setCenterNode(State::getPlayer()->getPlayable());
+    this->_radar->addEntityList(&State::getObjectManager()->getEntityList((OM_LIST)(State::getPlayer()->getPlayable()->getOMListNumber()+1)), Color(.4, .4, 1.0));
+    this->_radar->addEntityList(&State::getObjectManager()->getEntityList(OM_GROUP_02), Color(1.0, .2, .2));
+    this->_radar->setAbsCoor2D(0.8 * this->resX, 0.01 * this->resY);
+    this->_radar->setWidgetSize(0.2 * this->resX, 0.2 * this->resY);
+    this->_radar->setRange(300);
+    this->_radar->show();
+  }
+
+
+  if (this->energyWidget != NULL)
+  {
+    this->energyWidget->setAbsCoor2D(0.0 * this->resX, 0.85 * this->resY);
+    this->energyWidget->setWidgetSize(.25 * this->resX, 0.1 * this->resY);
+  }
+
+
+  std::list<OrxGui::GLGuiWidget*>::iterator weaponWidget;
+  Vector2D pos(0.3, .9);
+  for (weaponWidget = this->weaponsWidgets.begin(); weaponWidget != this->weaponsWidgets.end(); weaponWidget++, pos.x+=.2)
+  {
+    if (pos.x > .8)
+    {
+      pos.x = 0.3;
+      pos.y -= .1;
+
+    }
+    (*weaponWidget)->setAbsCoor2D(pos.x*this->resX, pos.y*this->resY);
+    (*weaponWidget)->setWidgetSize(.02*this->resX, .1 *this->resY);
+    (*weaponWidget)->show();
+    //printf("update thing %s::%s\n", (*weaponWidget)->getClassCName(), (*weaponWidget)->getName());
+  }
+}
+
+void Hud::draw() const
+{
+  //  GLGuiWidget::draw();
+}
+
+
+void Hud::process(const Event &event)
+{
+  if (event.type == EV_VIDEO_RESIZE)
+    this->updateResolution();
+  else if (event.type == SDLK_TAB)
+  {
+    /// TODO SHOW THE INPUT-LINE
+  //  this->inputLine->select();
+  }
+
+
+}
+
+
Index: branches/heathaze/src/util/hud.h
===================================================================
--- branches/heathaze/src/util/hud.h	(revision 9940)
+++ branches/heathaze/src/util/hud.h	(revision 9940)
@@ -0,0 +1,74 @@
+/*!
+ * @file hud.h
+ * @brief Definition of the ingame HUD.
+*/
+
+#ifndef _HUD_H
+#define _HUD_H
+
+#include "element_2d.h"
+#include "event_listener.h"
+
+
+// FORWARD DECLARATION
+class WeaponManager;
+namespace OrxGui {
+  class GLGuiWidget;
+  class GLGuiNotifier;
+  class GLGuiInputLine;
+  class GLGuiRadar;
+}
+
+//! A class that renders a HUD (Heads Up Display for User Information).
+class Hud : public Element2D, public EventListener
+{
+  ObjectListDeclaration(Hud);
+
+public:
+  Hud();
+  virtual ~Hud();
+
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void notifyUser(const std::string& message);
+
+
+  void setBackGround();
+  void setEnergyWidget(OrxGui::GLGuiWidget* widget);
+  void setShiledWidget(OrxGui::GLGuiWidget* widget);
+  void setArmorWidget(OrxGui::GLGuiWidget* widget);
+  void setWeaponManager(WeaponManager* weaponMan);
+
+  void addWeaponWidget(OrxGui::GLGuiWidget* widget);
+  void removeWeaponWidget(OrxGui::GLGuiWidget* widget);
+
+  OrxGui::GLGuiRadar* radar() const { return _radar; };
+
+  void updateWeaponManager();
+
+  void draw() const;
+  virtual void process(const Event &event);
+
+
+  private:
+    void updateResolution();
+
+private:
+  unsigned int             resX;
+  unsigned int             resY;
+
+  OrxGui::GLGuiWidget*     energyWidget;
+  OrxGui::GLGuiWidget*     shieldWidget;
+  OrxGui::GLGuiWidget*     armorWidget;
+
+  OrxGui::GLGuiNotifier*   notifier;
+  OrxGui::GLGuiInputLine*  inputLine;
+  OrxGui::GLGuiRadar*      _radar;
+
+  WeaponManager*           weaponManager;
+
+  std::list<OrxGui::GLGuiWidget*> weaponsWidgets; //!< WeaponWidgets will be displayed one after another
+};
+
+#endif /* _HUD_H */
Index: branches/heathaze/src/util/kill.cc
===================================================================
--- branches/heathaze/src/util/kill.cc	(revision 9940)
+++ branches/heathaze/src/util/kill.cc	(revision 9940)
@@ -0,0 +1,23 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "kill.h"
+
+#include "world_entity.h"
+
+
+
+
Index: branches/heathaze/src/util/kill.h
===================================================================
--- branches/heathaze/src/util/kill.h	(revision 9940)
+++ branches/heathaze/src/util/kill.h	(revision 9940)
@@ -0,0 +1,36 @@
+/*!
+ * @file kill.h
+ * @brief Definition of a playable kill. Generated in the case when some playable dies
+*/
+
+#ifndef _KILL_H
+#define _KILL_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+class WorldEntity;
+class Playable;
+
+//! A representing a kill event
+class Kill
+{
+
+  public:
+    Kill(WorldEntity* killer, WorldEntity* victim) {  this->killer = killer; this->victim = victim; }
+    Kill(WorldEntity* killer, Playable* victim) {this->killer = killer; this->victim = (WorldEntity*)victim;}
+    virtual ~Kill() {}
+
+    /** @returns reference to the killer world entity, does not need to exist */
+    inline WorldEntity* getKiller() const { return this->killer; }
+    /** @returns reference to the victim world entity, does not need to exist */
+    inline WorldEntity* getVictim() const { return this->victim; }
+
+  private:
+    WorldEntity*         killer;                   //!< reference to the killer world entity
+    WorldEntity*         victim;                   //!< reference to the victim world entity
+
+};
+
+#endif /* _KILL_H */
Index: branches/heathaze/src/util/kill_target.cc
===================================================================
--- branches/heathaze/src/util/kill_target.cc	(revision 9940)
+++ branches/heathaze/src/util/kill_target.cc	(revision 9940)
@@ -0,0 +1,63 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GAME_RULES
+
+#include "kill_target.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(KillTarget, CL_KILL_TARGET);
+CREATE_FACTORY(KillTarget);
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+KillTarget::KillTarget (const TiXmlElement* root)
+        : MissionGoal(root) {
+  this->registerObject(this, KillTarget::_objectList);
+
+    if( root != NULL)
+        this->loadParams(root);
+}
+
+
+/**
+ * standard deconstructor
+*/
+KillTarget::~KillTarget () {
+}
+
+
+void KillTarget::loadParams(const TiXmlElement* root) {
+    MissionGoal::loadParams(root);
+
+    LoadParam(root, "numberofkills", this, KillTarget, setNumberOfKills)
+    .describe("sets the number of kills a target has to be killed");
+    LoadParam(root, "targetclassid", this, KillTarget, setTargetClassID)
+    .describe("sets the targets class id");
+}
+
+
+MissionState KillTarget::checkMissionGoal(float dt)
+{
+
+}
+
Index: branches/heathaze/src/util/kill_target.h
===================================================================
--- branches/heathaze/src/util/kill_target.h	(revision 9940)
+++ branches/heathaze/src/util/kill_target.h	(revision 9940)
@@ -0,0 +1,41 @@
+/*!
+ * @file mission_goal.h
+ * @brief Definition of a killtarget mission goal
+*/
+
+#ifndef _KILL_TARGET_H
+#define _KILL_TARGET_H
+
+#include "mission_goal.h"
+
+
+class TiXmlElement;
+
+
+
+//! A class representing a mission goal to kill a specific amount of a specific object type
+class KillTarget : public MissionGoal
+{
+  ObjectListDeclaration(KillTarget);
+
+  public:
+    KillTarget(const TiXmlElement* root);
+    virtual ~KillTarget();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+
+    void setNumberOfKills( int kills) { this->numberOfKills = kills; }
+    void setTargetClassID( int classID) { this->targetClassID = classID; }
+    void setTargetClassName( char* className) {}
+
+
+    virtual MissionState checkMissionGoal(float dt);
+
+
+  private:
+    int numberOfKills;                                                 //!< the amount of kills of this kind
+    int targetClassID;                                                 //!< id of the target class
+};
+
+#endif /* _KILL_TARGET_H */
Index: branches/heathaze/src/util/mission_goal.cc
===================================================================
--- branches/heathaze/src/util/mission_goal.cc	(revision 9940)
+++ branches/heathaze/src/util/mission_goal.cc	(revision 9940)
@@ -0,0 +1,66 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GAME_RULES
+
+#include "mission_goal.h"
+#include "game_rules.h"
+
+#include "state.h"
+#include "util/loading/load_param.h"
+
+
+
+ObjectListDefinition(MissionGoal);
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+MissionGoal::MissionGoal (const TiXmlElement* root)
+{
+  this->registerObject(this, MissionGoal::_objectList);
+
+   this->missionState = MS_PASSIVE;
+   // add the mission to the current game rule
+   GameRules* gr = State::getGameRules();
+   if( gr)
+     gr->addMissionGoal(this);
+
+   if( root != NULL)
+     this->loadParams(root);
+}
+
+
+/**
+ * standard deconstructor
+*/
+MissionGoal::~MissionGoal ()
+{
+
+}
+
+/**
+ * loading parameter function: more help on the wiki pages
+ */
+void MissionGoal::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+
+  LoadParam(root, "title", this, MissionGoal, setMissionName)
+      .describe("sets the title of the mission");
+  LoadParam(root, "description", this, MissionGoal, setMissionDescription)
+      .describe("sets the mission description");
+}
+
Index: branches/heathaze/src/util/mission_goal.h
===================================================================
--- branches/heathaze/src/util/mission_goal.h	(revision 9940)
+++ branches/heathaze/src/util/mission_goal.h	(revision 9940)
@@ -0,0 +1,63 @@
+/*!
+ * @file mission_goal.h
+ * @brief General definition of mission goals
+*/
+
+#ifndef _MISSION_GOAL_H
+#define _MISSION_GOAL_H
+
+#include "base_object.h"
+
+
+class TiXmlElement;
+
+
+typedef enum MissionState
+{
+  MS_ACCOMPLISHED = 0,
+  MS_ACCEPTED,
+  MS_FAILED,
+  MS_PASSIVE,
+
+  MS_NUMBER
+};
+
+
+//! A class representing a mission goal
+class MissionGoal : public BaseObject {
+  ObjectListDeclaration(MissionGoal);
+
+ public:
+  MissionGoal(const TiXmlElement* root);
+  virtual ~MissionGoal();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  /** sets the mission name @param missionName: the string containig the mission title */
+  inline void setMissionName(const std::string& missionName) { this->missionName = missionName; }
+  /** @return the mission title */
+  inline std::string getMissionName() { return this->missionName; }
+
+  /** sets the mission description @param descrtiption: the string containing the description */
+  inline void setMissionDescription(const std::string& description) { this->missionDescription = description; }
+  /** gets the mission description @returns the string containing the description */
+  inline std::string getMissionDescription() { return this->missionDescription; }
+
+  /** sets the mission state @param missionState  state of the mission*/
+  inline void setMissionState(MissionState state) { this->missionState = state; }
+  /** @returns the current mission state */
+  inline MissionState getMissionState() { return this->missionState; }
+
+  virtual MissionState checkMissionGoal(float dt) = 0;
+
+
+ protected:
+   std::string      missionName;                                           //!< the title of the mission
+   // perhaps there will be more than one description soon: a long and short version for different parsts in the gui
+   std::string      missionDescription;                                    //!< the text description of the mission
+
+   MissionState     missionState;                                          //!< the state of this mission
+
+};
+
+#endif /* _MISSION_GOAL_H */
Index: branches/heathaze/src/util/multiplayer_team_deathmatch.cc
===================================================================
--- branches/heathaze/src/util/multiplayer_team_deathmatch.cc	(revision 9940)
+++ branches/heathaze/src/util/multiplayer_team_deathmatch.cc	(revision 9940)
@@ -0,0 +1,845 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_MODULE_GAME_RULES
+
+#include <map>
+
+#include "multiplayer_team_deathmatch.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "render2D/image_plane.h"
+#include "state.h"
+
+#include "player.h"
+#include "playable.h"
+#include "space_ships/space_ship.h"
+
+
+#include "shared_network_data.h"
+#include "terrain.h"
+#include "space_ships/space_ship.h"
+
+#include "network_game_manager.h"
+
+#include "event_handler.h"
+
+#include "glgui.h"
+
+#include "story_entity.h"
+
+#include "shell_command.h"
+
+#include "spawning_point.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(MultiplayerTeamDeathmatch, CL_MULTIPLAYER_TEAM_DEATHMATCH);
+CREATE_FACTORY(MultiplayerTeamDeathmatch);
+/**
+ * constructor
+ */
+MultiplayerTeamDeathmatch::MultiplayerTeamDeathmatch(const TiXmlElement* root)
+    : NetworkGameRules(root)
+{
+  this->registerObject(this, MultiplayerTeamDeathmatch::_objectList);
+
+  this->bLocalPlayerDead = false;
+  this->deathTimeout = 10.0f;     // 5 seconds
+  this->timeout = 0.0f;
+  this->numTeams = 2;
+  this->currentGameState = GAMESTATE_PRE_GAME;
+  this->gameStateTimer = 3.0f;
+  this->bShowTeamChange = false;
+
+  this->box = NULL;
+  this->table = NULL;
+  this->statsBox = NULL;
+
+  this->localPlayer = State::getPlayer();
+
+  if( root != NULL)
+    this->loadParams(root);
+
+  subscribeEvent( ES_GAME, SDLK_o );
+  subscribeEvent( ES_GAME, SDLK_TAB );
+  subscribeEvent( ES_GAME, SDLK_F1 );
+  subscribeEvent( ES_MENU, KeyMapper::PEV_FIRE1 );
+
+  this->input = new OrxGui::GLGuiInputLine();
+  this->input->setAbsCoor2D(180, 5);
+  this->input->enterPushed.connect(this, &MultiplayerTeamDeathmatch::onInputEnter);
+}
+
+/**
+ * decontsructor
+ */
+MultiplayerTeamDeathmatch::~MultiplayerTeamDeathmatch()
+{
+  unsubscribeEvent( ES_GAME, SDLK_o );
+  unsubscribeEvent( ES_GAME, SDLK_TAB );
+  unsubscribeEvent( ES_GAME, SDLK_F1 );
+  unsubscribeEvent( ES_MENU, KeyMapper::PEV_FIRE1 );
+
+  if ( this->input )
+  {
+    delete this->input;
+    this->input = NULL;
+  }
+}
+
+
+
+void MultiplayerTeamDeathmatch::loadParams(const TiXmlElement* root)
+{
+  GameRules::loadParams(root) ;
+
+  LoadParam(root, "death-penalty-timeout", this, MultiplayerTeamDeathmatch, setDeathPenaltyTimeout)
+  .describe("sets the time in seconds a player has to wait for respawn");
+
+  LoadParam(root, "max-kills", this, MultiplayerTeamDeathmatch, setMaxKills)
+  .describe("sets the maximal kills for winning condition");
+
+  LoadParam(root, "num-teams", this, MultiplayerTeamDeathmatch, setNumTeams)
+  .describe("sets number of teams");
+
+}
+
+
+/**
+ * time tick
+ * @param dt time
+ */
+void MultiplayerTeamDeathmatch::tick(float dt)
+{
+  tickStatsTable();
+  //on client side hostId is -1 until hanshake finished
+  if ( SharedNetworkData::getInstance()->getHostID() < 0 )
+    return;
+
+  if ( currentGameState == GAMESTATE_PRE_GAME || currentGameState == GAMESTATE_GAME )
+  {
+    if ( PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() ) &&
+         box == NULL &&
+         (PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )->getPreferedTeamId() == TEAM_NOTEAM || bShowTeamChange )
+
+       )
+    {
+      EventHandler::getInstance()->pushState( ES_MENU );
+
+      OrxGui::GLGuiHandler::getInstance()->activateCursor();
+
+      box = new OrxGui::GLGuiBox();
+      box->setAbsCoor2D( 300, 100 );
+
+      if( SharedNetworkData::getInstance()->isClient() ||  SharedNetworkData::getInstance()->isProxyServerActive())
+      {
+        OrxGui::GLGuiPushButton * buttonSpectator = new OrxGui::GLGuiPushButton("Spectator");
+        box->pack( buttonSpectator );
+        buttonSpectator->released.connect(this, &MultiplayerTeamDeathmatch::onButtonSpectator);
+
+        OrxGui::GLGuiPushButton * buttonRandom = new OrxGui::GLGuiPushButton("Random");
+        box->pack( buttonRandom );
+        buttonRandom->released.connect(this, &MultiplayerTeamDeathmatch::onButtonRandom);
+
+        OrxGui::GLGuiPushButton * buttonTeam0 = new OrxGui::GLGuiPushButton("Blue Team");
+        box->pack( buttonTeam0 );
+        buttonTeam0->released.connect(this, &MultiplayerTeamDeathmatch::onButtonTeam0);
+
+        OrxGui::GLGuiPushButton * buttonTeam1 = new OrxGui::GLGuiPushButton("Red Team");
+        box->pack( buttonTeam1 );
+        buttonTeam1->released.connect(this, &MultiplayerTeamDeathmatch::onButtonTeam1);
+      }
+      else
+      {
+        OrxGui::GLGuiText* text = new OrxGui::GLGuiText();
+        text->setText("Server Mode: not able to play at this node");
+        box->pack( text);
+      }
+
+
+      if ( bShowTeamChange )
+      {
+        OrxGui::GLGuiPushButton * buttonCancel = new OrxGui::GLGuiPushButton("Cancel");
+        box->pack( buttonCancel );
+        buttonCancel->released.connect(this, &MultiplayerTeamDeathmatch::onButtonCancel);
+      }
+
+      OrxGui::GLGuiPushButton * buttonExit = new OrxGui::GLGuiPushButton("Exit");
+      box->pack( buttonExit );
+      buttonExit->released.connect(this, &MultiplayerTeamDeathmatch::onButtonExit);
+
+      box->showAll();
+    }
+  }
+
+  //   if( PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() ) )
+  //   {
+  //     PRINTF(0)("prefered team id: %i, noteam: %i\n", PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )->getPreferedTeamId(), TEAM_NOTEAM);
+  //   }
+
+  // check if the menu should be removed and the game state should be entered
+  if ( box != NULL &&
+       PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() ) &&
+       PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )->getPreferedTeamId() != TEAM_NOTEAM &&
+       !bShowTeamChange
+     )
+  {
+    delete box;
+    box = NULL;
+
+    OrxGui::GLGuiHandler::getInstance()->deactivateCursor( true );
+
+    EventHandler::getInstance()->popState();
+  }
+
+  if ( box != NULL )
+  {
+    OrxGui::GLGuiHandler::getInstance()->tick( dt );
+  }
+
+  assignPlayable();
+
+  if ( SharedNetworkData::getInstance()->isClient() || SharedNetworkData::getInstance()->isProxyServerActive())
+    return;
+
+  //handle kills
+  while ( this->killList.begin() != this->killList.end() )
+  {
+    PRINTF(0)("KKKKKKKKIIIIIIIIILLLLLLLLLLLLL\n");
+    onKill( this->killList.begin()->getVictim(), this->killList.begin()->getKiller() );
+    this->killList.erase( this->killList.begin() );
+  }
+
+
+
+  gameStateTimer -= dt;
+  //PRINTF(0)("TICK %f\n", gameStateTimer);
+
+  if ( currentGameState != GAMESTATE_GAME && gameStateTimer < 0 )
+    nextGameState();
+
+  this->currentGameState = NetworkGameManager::getInstance()->getGameState();
+
+  if ( currentGameState == GAMESTATE_GAME )
+  {
+    handleTeamChanges();
+  }
+
+  this->calculateTeamScore();
+
+  this->checkGameRules();
+
+  // is the local player dead and inactive
+  if( unlikely(this->bLocalPlayerDead))
+  {
+    this->timeout += dt;
+    PRINTF(0)("TICK DEATH: %f of %f\n", this->timeout, this->deathTimeout);
+    // long enough dead?
+    if( this->timeout >= this->deathTimeout)
+    {
+      this->timeout = 0.0f;
+      // respawn
+      PRINTF(0)("RESPAWN\n");
+      (State::getPlayer())->getPlayable()->respawn();
+    }
+  }
+}
+
+
+/**
+ * draws the stuff
+ */
+void MultiplayerTeamDeathmatch::draw()
+{
+  if( unlikely( this->bLocalPlayerDead))
+  {
+  }
+}
+
+
+/**
+ * check the game rules for consistency
+ */
+void MultiplayerTeamDeathmatch::checkGameRules()
+{
+  if ( SharedNetworkData::getInstance()->isClient() || SharedNetworkData::getInstance()->isProxyServerActive())
+    return;
+
+  // check for max killing count
+  for ( int i = 0; i<numTeams; i++ )
+  {
+    if ( teamScore[i] >= maxKills )
+    {
+      nextGameState();
+    }
+  }
+}
+
+/**
+ * find group for new player
+ * @return group id
+ */
+int MultiplayerTeamDeathmatch::getTeamForNewUser()
+{
+  return TEAM_NOTEAM;
+}
+
+ClassID MultiplayerTeamDeathmatch::getPlayableClassId( int userId, int team )
+{
+  if ( team == TEAM_NOTEAM || team == TEAM_SPECTATOR )
+    return ObjectListBase::retrieveIdentity("Spectator");
+
+  if ( team == 0 || team == 1 )
+    return ObjectListBase::retrieveIdentity("TurbineHover");
+
+  assert( false );
+}
+
+
+std::string MultiplayerTeamDeathmatch::getPlayableModelFileName( int userId, int team, const ClassID& classId )
+{
+  if (classId == CL_TURBINE_HOVER)
+    return "models/ships/hoverglider_mainbody.obj";
+  if ( team == 0 )
+    return "models/creatures/doom_guy.md2";
+  else if ( team == 1 )
+    return "models/creatures/male.md2";
+  else
+    return "";
+}
+
+std::string MultiplayerTeamDeathmatch::getPlayableModelTextureFileName( int userId, int team, const ClassID& classId )
+{
+  if ( classId == CL_FPS_PLAYER )
+  {
+    if ( team == 0 )
+      return "maps/doom_guy.png";
+    else
+      return "maps/male_fiend.pcx";
+  }
+
+  return "";
+}
+
+float MultiplayerTeamDeathmatch::getPlayableScale( int userId, int team, const ClassID& classId )
+{
+  if ( classId == ObjectListBase::retrieveIdentity(CL_FPS_PLAYER))
+  {
+    return 10.0f;
+  }
+
+  return 1.0f;
+}
+
+/**
+ * calculate team score
+ */
+void MultiplayerTeamDeathmatch::calculateTeamScore( )
+{
+  teamScore.clear();
+
+  for ( int i = 0; i<numTeams; i++ )
+    teamScore[i] = 0;
+
+  for (ObjectList<PlayerStats>::const_iterator it = PlayerStats::objectList().begin();
+       it != PlayerStats::objectList().end();
+       ++it)
+  {
+    PlayerStats & stats = *(*it);
+
+    if ( stats.getTeamId() >= 0 )
+    {
+      teamScore[stats.getTeamId()] += stats.getScore();
+    }
+  }
+}
+
+/**
+ * get team for player who choose to join random team
+ * @return smallest team
+ */
+int MultiplayerTeamDeathmatch::getRandomTeam( )
+{
+  std::map<int,int> playersInTeam;
+
+  for ( int i = 0; i<numTeams; i++ )
+    playersInTeam[i] = 0;
+
+  for (ObjectList<PlayerStats>::const_iterator it = PlayerStats::objectList().begin();
+       it != PlayerStats::objectList().end();
+       ++it)
+  {
+    PlayerStats & stats = *(*it);
+
+    if ( stats.getTeamId() >= 0 )
+    {
+      playersInTeam[stats.getTeamId()]++;
+    }
+  }
+
+
+  int minPlayers = 0xFFFF;
+  int minTeam = -1;
+
+  for ( int i = 0; i<numTeams; i++ )
+  {
+    if ( playersInTeam[i] < minPlayers )
+    {
+      minTeam = i;
+      minPlayers = playersInTeam[i];
+    }
+  }
+
+  assert( minTeam != -1 );
+
+  return minTeam;
+}
+
+void MultiplayerTeamDeathmatch::nextGameState( )
+{
+  if ( currentGameState == GAMESTATE_PRE_GAME )
+  {
+    NetworkGameManager::getInstance()->setGameState( GAMESTATE_GAME );
+
+    return;
+  }
+
+  if ( currentGameState == GAMESTATE_GAME )
+  {
+    NetworkGameManager::getInstance()->setGameState( GAMESTATE_POST_GAME );
+
+    return;
+  }
+
+  if ( currentGameState == GAMESTATE_POST_GAME )
+  {
+    //State::getCurrentStoryEntity()->stop();
+    this->bShowTeamChange = false;
+
+    return;
+  }
+}
+
+/**
+ *  this handles team changes but only on the master server
+ */
+void MultiplayerTeamDeathmatch::handleTeamChanges( )
+{
+  for (ObjectList<PlayerStats>::const_iterator it = PlayerStats::objectList().begin();
+       it != PlayerStats::objectList().end();
+       ++it)
+  {
+    PlayerStats & stats = *(*it);
+
+    if ( stats.getTeamId() != stats.getPreferedTeamId() )
+    {
+      if ( stats.getPreferedTeamId() == TEAM_SPECTATOR || ( stats.getPreferedTeamId() >= 0 && stats.getPreferedTeamId() < numTeams ) )
+      {
+        teamChange( stats.getAssignedUserId() );
+      }
+    }
+  }
+
+  //now serve player who want join a random team
+  for (ObjectList<PlayerStats>::const_iterator it = PlayerStats::objectList().begin();
+       it != PlayerStats::objectList().end();
+       ++it)
+  {
+    PlayerStats & stats = *(*it);
+
+    if ( stats.getTeamId() != stats.getPreferedTeamId() )
+    {
+      if ( stats.getPreferedTeamId() == TEAM_RANDOM )
+      {
+        stats.setPreferedTeamId( getRandomTeam() );
+        teamChange( stats.getAssignedUserId() );
+      }
+    }
+  }
+}
+
+
+
+/**
+ * changes the team
+ * @param userId the user changing team (userId)
+ */
+void MultiplayerTeamDeathmatch::teamChange( int userId )
+{
+  assert( PlayerStats::getStats( userId ) );
+  PlayerStats & stats = *(PlayerStats::getStats( userId ));
+
+  stats.setTeamId( stats.getPreferedTeamId() );
+
+  Playable * oldPlayable = stats.getPlayable();
+
+
+  ClassID       playableClassId  = getPlayableClassId( userId, stats.getPreferedTeamId() );
+  std::string   playableModel    = getPlayableModelFileName( userId, stats.getPreferedTeamId(), playableClassId );
+  std::string   playableTexture  = getPlayableModelTextureFileName( userId, stats.getPreferedTeamId(), playableClassId );
+  float         playableScale    = getPlayableScale( userId, stats.getPreferedTeamId(), playableClassId );
+
+  BaseObject * bo = Factory::fabricate( playableClassId );
+
+  assert( bo != NULL );
+  assert( bo->isA( CL_PLAYABLE ) );
+
+  Playable & playable = *(dynamic_cast<Playable*>(bo));
+
+  playable.loadMD2Texture( playableTexture );
+  playable.loadModel( playableModel, playableScale );
+  playable.setOwner( userId );
+  playable.setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
+  playable.setSynchronized( true );
+
+  stats.setPlayableClassId( playableClassId );
+  stats.setPlayableUniqueId( playable.getUniqueID() );
+  stats.setModelFileName( playableModel );
+  stats.setTeamId( stats.getPreferedTeamId() );
+
+  playable.setTeam(stats.getPreferedTeamId());
+
+
+  this->respawnPlayable( &playable, stats.getPreferedTeamId(), 0.0f );
+
+  if ( oldPlayable )
+  {
+    delete oldPlayable;
+  }
+}
+
+
+void MultiplayerTeamDeathmatch::onButtonExit( )
+{
+  State::getCurrentStoryEntity()->stop();
+  this->bShowTeamChange = false;
+}
+
+void MultiplayerTeamDeathmatch::onButtonRandom( )
+{
+  NetworkGameManager::getInstance()->prefereTeam( TEAM_RANDOM );
+  this->bShowTeamChange = false;
+}
+
+void MultiplayerTeamDeathmatch::onButtonTeam0( )
+{
+  NetworkGameManager::getInstance()->prefereTeam( 0 );
+  this->bShowTeamChange = false;
+}
+
+void MultiplayerTeamDeathmatch::onButtonTeam1( )
+{
+  NetworkGameManager::getInstance()->prefereTeam( 1 );
+  this->bShowTeamChange = false;
+}
+
+void MultiplayerTeamDeathmatch::onButtonSpectator( )
+{
+  NetworkGameManager::getInstance()->prefereTeam( TEAM_SPECTATOR );
+  this->bShowTeamChange = false;
+}
+
+void MultiplayerTeamDeathmatch::assignPlayable( )
+{
+  if ( PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() ) )
+    PlayerStats::getStats( SharedNetworkData::getInstance()->getHostID() )->getPlayable();
+}
+
+
+/**
+ * function that processes events from the handler
+ * @param event: the event
+ * @todo replace SDLK_o with something from KeyMapper
+ */
+void MultiplayerTeamDeathmatch::process( const Event & event )
+{
+  if ( event.type == SDLK_o )
+  {
+    if ( event.bPressed )
+      this->bShowTeamChange = true;
+  }
+  else if ( event.type == SDLK_F1 )
+  {
+    if ( this->statsBox && !this->bLocalPlayerDead && event.bPressed )
+    {
+      PRINTF(5)("hide stats\n");
+      this->hideStats();
+    }
+    else if ( !this->statsBox && event.bPressed )
+    {
+      PRINTF(5)("show stats\n");
+      this->showStats();
+    }
+  }
+  else if ( event.type == SDLK_TAB )
+  {
+    if ( currentGameState == GAMESTATE_GAME && event.bPressed && !EventHandler::getInstance()->isPressed( SDLK_RALT ) && !EventHandler::getInstance()->isPressed( SDLK_LALT ) )
+    {
+      EventHandler::getInstance()->pushState( ES_MENU );
+      OrxGui::GLGuiHandler::getInstance()->activateCursor();
+      OrxGui::GLGuiHandler::getInstance()->deactivateCursor();
+      input->show();
+      input->giveMouseFocus();
+      input->setText("say ");
+    }
+  }
+  else if ( this->bLocalPlayerDead && statsBox && event.type == KeyMapper::PEV_FIRE1 )
+  {
+    this->hideStats();
+  }
+}
+
+void MultiplayerTeamDeathmatch::onButtonCancel( )
+{
+  this->bShowTeamChange = false;
+}
+
+
+
+/**
+ * this method is called by NetworkGameManger when he recieved a chat message
+ * @param userId senders user id
+ * @param message message string
+ * @param messageType some int
+ */
+void MultiplayerTeamDeathmatch::handleChatMessage( int userId, const std::string & message, int messageType )
+{
+  std::string name = "unknown";
+
+  if ( PlayerStats::getStats( userId ) )
+  {
+    name = PlayerStats::getStats( userId )->getNickName();
+  }
+
+  PRINTF(0)("CHATMESSAGE %s (%d): %s\n", name.c_str(), userId, message.c_str() );
+  State::getPlayer()->hud().notifyUser(name + ": " + message);
+}
+
+void MultiplayerTeamDeathmatch::onInputEnter( const std::string & text )
+{
+  EventHandler::getInstance()->popState();
+  input->breakMouseFocus();
+  input->hide();
+  input->setText("");
+
+  std::string command = text;
+
+  //HACK insert " in say commands so user doesn't have to type them
+  if ( command.length() >= 4 && command[0] == 's' && command[1] == 'a' && command[2] == 'y' && command[3] == ' ' )
+  {
+    command.insert( 4, "\"" );
+    command = command + "\"";
+  }
+
+  OrxShell::ShellCommand::execute( command );
+}
+
+/**
+ * show table with frags
+ */
+void MultiplayerTeamDeathmatch::showStats( )
+{
+  statsBox = new OrxGui::GLGuiBox();
+  statsBox->setAbsCoor2D( 100, 100 );
+
+  this->table = new OrxGui::GLGuiTable(10,5);
+
+  statsBox->pack( this->table );
+
+  statsBox->showAll();
+}
+
+/**
+ * hide table with frags
+ */
+void MultiplayerTeamDeathmatch::hideStats( )
+{
+  if ( statsBox )
+  {
+    delete statsBox;
+    statsBox = NULL;
+  }
+}
+
+/**
+ * fill stats table with values
+ */
+void MultiplayerTeamDeathmatch::tickStatsTable( )
+{
+  if ( !this->statsBox )
+    return;
+
+  std::vector<std::string> headers;
+  headers.push_back("Blue Team");
+  headers.push_back("");
+  headers.push_back("");
+  headers.push_back("Red Team");
+  headers.push_back("");
+  this->table->setHeader(headers);
+
+  ScoreList scoreList = PlayerStats::getScoreList();
+
+  char st[10];
+  int i = 0;
+
+  i = 2;
+  for ( TeamScoreList::const_iterator it = scoreList[0].begin(); it != scoreList[0].end(); it++ )
+  {
+    this->table->setEntry( i, 0, it->name );
+    snprintf( st, 10, "%d", it->score );
+    this->table->setEntry( i, 1, st );
+    this->table->setEntry( i, 2, "" );
+    i++;
+  }
+
+  i = 2;
+  for ( TeamScoreList::const_iterator it = scoreList[1].begin(); it != scoreList[1].end(); it++ )
+  {
+    this->table->setEntry( i, 3, it->name );
+    snprintf( st, 10, "%d", it->score );
+    this->table->setEntry( i, 4, st );
+    i++;
+  }
+
+}
+
+/**
+ * this function is called when a player kills another one or himself
+ * @param killedUserId
+ * @param userId
+ */
+void MultiplayerTeamDeathmatch::onKill( WorldEntity * victim, WorldEntity * killer )
+{
+  if ( !victim )
+  {
+    PRINTF(0)("victim == NULL\n");
+    return;
+  }
+  if ( !killer )
+  {
+    PRINTF(0)("killer == NULL\n");
+    return;
+  }
+
+  int killerUserId = killer->getOwner();
+  int victimUserId = victim->getOwner();
+
+  PRINTF(0)("%d %d %x %x %s %s\n", killerUserId, victimUserId, killer, victim, killer->getClassCName(), victim->getClassCName());
+
+  PlayerStats & victimStats = *PlayerStats::getStats( victimUserId );
+  PlayerStats & killerStats = *PlayerStats::getStats( killerUserId );
+
+  if ( killerStats.getPlayable() == NULL || victimStats.getPlayable() == NULL)
+  {
+    PRINTF(0)("killerStats.getPlayable() != NULL || victimStats.getPlayable() != NULL\n");
+    PRINTF(0)("%x %x %x %x\n", killerStats.getPlayable(), killer, victimStats.getPlayable(), victim );
+    PRINTF(0)("%d %d %d %d\n", killerStats.getPlayable()->getUniqueID(), killer->getUniqueID(), victimStats.getPlayable()->getUniqueID(), victim->getUniqueID() );
+    return;
+  }
+
+  //check for suicide
+  if ( killerUserId != victimUserId )
+  {
+    //check for teamkill
+    if ( victimStats.getTeamId() != killerStats.getTeamId() )
+    {
+      killerStats.setScore( killerStats.getScore() + 1 );
+    }
+    else
+    {
+      killerStats.setScore( killerStats.getScore() - 1 );
+    }
+  }
+  else
+    killerStats.setScore( killerStats.getScore() - 1 );
+
+  if ( victimUserId == SharedNetworkData::getInstance()->getHostID() )
+  {
+    this->bLocalPlayerDead = true;
+    this->showStats();
+  }
+
+  this->respawnPlayable( victimStats.getPlayable(), victimStats.getTeamId(), 3.0f );
+}
+
+/**
+ * this function is called on player respawn
+ * @param userId
+ */
+void MultiplayerTeamDeathmatch::onRespawn( int userId )
+{
+  if ( userId == SharedNetworkData::getInstance()->getHostID() )
+  {
+    this->bLocalPlayerDead = false;
+    this->hideStats();
+  }
+}
+
+/**
+ * this function is called on player respawn
+ * @param we
+ */
+void MultiplayerTeamDeathmatch::registerSpawn( WorldEntity * we )
+{
+  onRespawn( we->getOwner() );
+}
+
+
+/**
+ * respawns a playable in the world via spawning points
+ * @param playable the playable to respawn
+ * @param teamId the teamId to use
+ * @param delay time delay for delayed spawning
+ */
+void MultiplayerTeamDeathmatch::respawnPlayable( Playable * playable, int teamId, float delay )
+{
+
+  std::vector<SpawningPoint*> spList;
+
+  for (ObjectList<SpawningPoint>::const_iterator it = SpawningPoint::objectList().begin();
+       it != SpawningPoint::objectList().end();
+       ++it)
+  {
+    SpawningPoint * sp = (*it);
+
+    if ( sp->getTeamId() == teamId )
+      spList.push_back( sp );
+  }
+
+  if ( spList.size() == 0 )
+  {
+    for (ObjectList<SpawningPoint>::const_iterator it = SpawningPoint::objectList().begin();
+	 it != SpawningPoint::objectList().end();
+	 ++it)
+    {
+      SpawningPoint * sp = (*it);
+
+      if ( sp->getTeamId() < 0 )
+        spList.push_back( sp );
+    }
+  }
+
+  assert( spList.size() != 0 );
+
+  int n = (int)((float)spList.size() * (float)rand()/(float)RAND_MAX);
+
+  spList[n]->pushEntity( playable, delay );
+}
+
+
Index: branches/heathaze/src/util/multiplayer_team_deathmatch.h
===================================================================
--- branches/heathaze/src/util/multiplayer_team_deathmatch.h	(revision 9940)
+++ branches/heathaze/src/util/multiplayer_team_deathmatch.h	(revision 9940)
@@ -0,0 +1,114 @@
+
+/*!
+ * @file multiplayer_team_deathmatch.h
+ * Defines game rules for team deathmatch games
+ *
+ * currently there are only two teams supported
+ */
+
+#ifndef _MULTIPLAYER_TEAM_DEATHMATCH_H
+#define _MULTIPLAYER_TEAM_DEATHMATCH_H
+
+#include "network_game_rules.h"
+
+#include "glgui.h"
+#include "specials/glgui_notifier.h"
+
+class TiXmlElement;
+class ObjectManager;
+class Player;
+class ImagePlane;
+
+enum
+{
+  GAMESTATE_PRE_GAME = 0,
+  GAMESTATE_GAME,
+  GAMESTATE_POST_GAME
+};
+
+
+class MultiplayerTeamDeathmatch : public NetworkGameRules, public EventListener
+{
+  ObjectListDeclaration(MultiplayerTeamDeathmatch);
+
+  public:
+    MultiplayerTeamDeathmatch(const TiXmlElement* root = NULL);
+    virtual ~MultiplayerTeamDeathmatch();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual int getTeamForNewUser();
+    virtual ClassID getPlayableClassId( int userId, int team );
+    virtual std::string getPlayableModelTextureFileName( int userId, int team, const ClassID& classId );
+    virtual std::string getPlayableModelFileName( int userId, int team, const ClassID& classId );
+    virtual float getPlayableScale( int userId, int team, const ClassID& classId );
+
+    virtual void registerSpawn( WorldEntity * we );
+
+    virtual void tick(float dt);
+    void draw();
+
+    inline void setDeathPenaltyTimeout(float time) { this->deathTimeout = time; }
+    inline void setMaxKills(int kills) { this->maxKills = kills; }
+
+    inline void setNumTeams( int numTeams ){ this->numTeams = numTeams; }
+    inline int getNumTeams(){ return this->numTeams; }
+
+    int getRandomTeam();
+
+    virtual void process(const Event &event);
+
+    void onKill( WorldEntity * victim, WorldEntity * killer );
+    void onRespawn( int userId );
+
+    virtual void handleChatMessage( int userId, const std::string & message, int messageType );
+
+    void respawnPlayable( Playable * playable, int teamId, float delay );
+
+  protected:
+    virtual void checkGameRules();
+
+  private:
+    bool               bLocalPlayerDead;           //!< true if the local player is dead
+    float              deathTimeout;               //!< timeout a player cannot play if he/she dies
+    float              timeout;                    //!< time counted if player dead
+    int                maxKills;                   //!< max kills for winning condition
+
+    int                numTeams;                   //!< number of teams
+
+    std::map<int,int>  teamScore;                  //!< team score
+
+    int                currentGameState;           //!< game state
+    float              gameStateTimer;             //!< if less than 0 -> change game state
+
+    bool               bShowTeamChange;            //!< if true -> show team change dialog
+
+    OrxGui::GLGuiBox* box;
+
+    OrxGui::GLGuiInputLine* input;
+
+    void calculateTeamScore();
+    void nextGameState();
+    void handleTeamChanges();
+    void teamChange( int userId );
+    void assignPlayable();
+
+    void onButtonSpectator();
+    void onButtonRandom();
+    void onButtonTeam0();
+    void onButtonTeam1();
+    void onButtonCancel();
+    void onButtonExit();
+
+    void onInputEnter( const std::string & text );
+
+    OrxGui::GLGuiBox* statsBox;
+    OrxGui::GLGuiTable* table;
+    void tickStatsTable();
+
+    void showStats();
+    void hideStats();
+};
+
+
+#endif /* _MULTIPLAYER_TEAM_DEATHMATCH_H */
Index: branches/heathaze/src/util/network_game_rules.cc
===================================================================
--- branches/heathaze/src/util/network_game_rules.cc	(revision 9940)
+++ branches/heathaze/src/util/network_game_rules.cc	(revision 9940)
@@ -0,0 +1,77 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "network_game_rules.h"
+
+#include "network_game_manager.h"
+
+
+
+ObjectListDefinition(NetworkGameRules);
+
+/**
+ * standard constructor
+ */
+NetworkGameRules::NetworkGameRules ( const TiXmlElement* root )
+    : GameRules( root )
+{
+  this->registerObject(this, NetworkGameRules::_objectList);
+}
+
+
+/**
+ * standard deconstructor
+ */
+NetworkGameRules::~NetworkGameRules ()
+{}
+
+
+std::string NetworkGameRules::getPlayableModelTextureFileName( int userId, int team, const ClassID& classId )
+{
+  return "";
+}
+
+std::string NetworkGameRules::getPlayableModelFileName( int uesrId, int team, const ClassID& classId )
+{
+  return "models/ships/reap_#.obj";
+}
+
+ClassID NetworkGameRules::getPlayableClassId( int userId, int team )
+{
+  const ObjectListBase* objList = ObjectListBase::getObjectList("SpaceShip");
+  if (objList != NULL)
+    return objList->identity();
+  else
+    return ClassID();
+}
+
+int NetworkGameRules::getTeamForNewUser( )
+{
+  return 0;
+}
+
+
+void NetworkGameRules::shellSay( const std::string & message )
+{
+  NetworkGameManager::getInstance()->sendChatMessage( message, 0 );
+}
+
+
+float NetworkGameRules::getPlayableScale( int userId, int team, const ClassID& classId )
+{
+  return 1.0f;
+}
Index: branches/heathaze/src/util/network_game_rules.h
===================================================================
--- branches/heathaze/src/util/network_game_rules.h	(revision 9940)
+++ branches/heathaze/src/util/network_game_rules.h	(revision 9940)
@@ -0,0 +1,40 @@
+/*!
+ * @file network_game_rules.h
+ * @brief Definition of NetworkGameRules
+ */
+
+#ifndef _NETWORK_GAME_RULES_H
+#define _NETWORK_GAME_RULES_H
+
+#include "game_rules.h"
+
+#include "player_stats.h"
+
+class TiXmlElement;
+
+class NetworkGameRules : public GameRules
+{
+  ObjectListDeclaration(NetworkGameRules);
+
+  public:
+    NetworkGameRules( const TiXmlElement* root );
+    virtual ~NetworkGameRules();
+
+    virtual int getTeamForNewUser();
+    virtual ClassID getPlayableClassId( int userId, int team );
+    virtual std::string getPlayableModelFileName( int userId, int team, const ClassID& classId );
+    virtual std::string getPlayableModelTextureFileName( int userId, int team, const ClassID& classId );
+    virtual float getPlayableScale( int userId, int team, const ClassID& classId );
+
+    virtual PlayerStats * getNewPlayerStats( int userId ){ return new PlayerStats( userId ); }
+
+    virtual void handleChatMessage( int userId, const std::string & message, int messageType ) = 0;
+
+    void shellSay( const std::string & message );
+
+
+  private:
+
+};
+
+#endif /* _NETWORK_GAME_RULES_H */
Index: branches/heathaze/src/util/object_manager.cc
===================================================================
--- branches/heathaze/src/util/object_manager.cc	(revision 9940)
+++ branches/heathaze/src/util/object_manager.cc	(revision 9940)
@@ -0,0 +1,254 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "object_manager.h"
+
+#include "world_entity.h"
+
+#include "shell_command.h"
+
+#include <cassert>
+#include "debug.h"
+
+
+SHELL_COMMAND(debug, ObjectManager, debug)
+    ->defaultValues("", 0);
+
+ObjectListDefinition(ObjectManager);
+/**
+ * @brief standard constructor
+ */
+ObjectManager::ObjectManager ()
+{
+  this->registerObject(this, ObjectManager::_objectList);
+   this->setName("ObjectManager");
+
+   pNodeList = NULL;
+}
+
+
+/**
+ * @brief standard deconstructor
+ *
+ * this also removes ALL entitites in existence.
+ */
+ObjectManager::~ObjectManager ()
+{
+  this->flush();
+}
+
+/**
+ * @brief flushes all entities
+ *
+ * this function deletes all entities that exist within the ObjectManager.
+ * It does this by poping each list from the front, and delete the given object.
+ *
+ * automatically called by a destructor.
+ */
+void ObjectManager::flush()
+{
+  for (unsigned int i = 0; i < OM_SIZE; ++i)
+    while(!this->entityLists[i].empty())
+      delete this->entityLists[i].front();
+
+  // delete reflection list
+  this->reflectionList.clear();
+}
+
+
+/**
+ * @brief moves an Entity from an old list to a new One
+ * @param entity the entity to move.
+ * @param omList the new List to move the entity to.
+ *
+ * this will erase the entity from the old list
+ */
+void ObjectManager::toList (WorldEntity* entity, OM_LIST omList)
+{
+  assert (omList != OM_SIZE);
+
+  if (likely(entity->getOMListNumber() != OM_INIT))
+    this->entityLists[entity->getOMListNumber()].erase(entity->getEntityIterator());
+
+  if (likely(omList != OM_INIT))
+  {
+    this->entityLists[omList].push_back(entity);
+    entity->getEntityIterator() = --this->entityLists[omList].end();
+    entity->getOMListNumber() = omList;
+  }
+}
+
+
+/**
+ * @see ObjectManager::toList(WorldEntity* OM_LIST)
+ * @param entity the entity to move.
+ * @param omList the new List to move the entity to.
+ *
+ * this function also does a transformation from omList as char* to OM_LIST.
+ */
+void ObjectManager::toList (WorldEntity* entity, const std::string& omList)
+{
+  this->toList(entity, ObjectManager::StringToOMList(omList));
+}
+
+
+
+/**
+ * @returns a new List with a list of WorldEntities of distance Radius from center
+ */
+  /*
+void ObjectManager::distanceFromObject(EntityList& entities, const PNode& center, float radius, const ClassID& classID)
+{
+  TODO FIXME
+
+  const std::list<BaseObject*>* entityList = ClassList::getList(classID);
+  if (entityList != NULL)
+  {
+
+    std::list<BaseObject*>::const_iterator node;
+    for (node = entityList->begin(); node != entityList->end(); node++)
+      if ((dynamic_cast<PNode*>(*node)->getAbsCoor() - center.getAbsCoor()).len() < radius)
+        entities.push_back(dynamic_cast<WorldEntity*>(*node));
+  }
+}
+  */
+
+
+/**
+ * @brief print out nice debug information about Elements in the list OM_LIST
+ * @param omList the List to debug.
+ * @param level: level 0: only show list info; level 1: also show entities and their names.
+ */
+void ObjectManager::debug(OM_LIST omList, unsigned int level) const
+{
+  if (omList != OM_INIT || omList == OM_SIZE)
+  {
+    PRINT(0)(" +ObjectManager-LIST: '%s'==size='%d'==---\n", ObjectManager::OMListToString((OM_LIST)omList).c_str(), this->entityLists[omList].size());
+  //  if (level >= 1)
+    {
+      ObjectManager::EntityList::const_iterator entity;
+      for (entity = this->entityLists[omList].begin(); entity != this->entityLists[omList].end(); entity++)
+      {
+        PRINT(0)(" | %s::%s\n",(*entity)->getClassCName(), (*entity)->getCName());
+      }
+    }
+  }
+  else
+    PRINTF(2)("Invalid query. for OM_INIT-LIST or OM_SIZE\n");
+}
+
+
+/**
+ * @brief prints out very nice debug information
+ * @param listName the Name of the list to get Debug information from
+ * @param level: level 0: only show list info; level 1: also show entities and their names.
+ */
+void ObjectManager::debug(const std::string& listName, unsigned int level)
+{
+  PRINT(0)("=================================\n");
+  PRINT(0)("=ObjectManager-DEBUG=============\n");
+  PRINT(0)("=================================\n");
+  if (listName.empty())
+    for (unsigned int i = 0; i < OM_SIZE; ++i)
+      debug((OM_LIST) i, level);
+  else
+    debug(ObjectManager::StringToOMList(listName));
+  PRINT(0)("=========================== OM ==\n");
+}
+
+
+
+/**
+ * @brief transforms an omList into a String (usefull for debugging).
+ * @param omList the OM_LIST to be transformed into a String.
+ * @returns the String transformed from omList.
+ */
+const std::string& ObjectManager::OMListToString(OM_LIST omList)
+{
+  if (omList == OM_INIT || omList == OM_SIZE)
+    return ObjectManager::objectManagerListNames[OM_NULL];
+
+  printf("%d\n", omList);
+  return ObjectManager::objectManagerListNames[omList];
+}
+
+
+
+/**
+ * @brief transforms a String into an OM_LIST (usefull for debugging/Loading).
+ * @param listName the OM_LIST-name to be transformed into an OM_LIST.
+ * @returns the OM_LIST transformed from listName. or the default, if not found or NULL.
+ */
+OM_LIST ObjectManager::StringToOMList(const std::string& listName)
+{
+  if (unlikely(listName.empty())) return OM_DEFAULT_LIST;
+
+  for(unsigned int i = 0; i < OM_SIZE; ++i) {
+    if(listName == ObjectManager::objectManagerListNames[i]) {
+      return (OM_LIST)i;
+    }
+  }
+  return OM_NULL;
+}
+
+
+
+const std::string ObjectManager::objectManagerListNames[] = {
+    "null",
+    "dead",
+    "dead-tick",
+    "environ-notick",
+    "environ",
+    "background",
+    "common",
+
+    "players",
+    "players-proj",
+
+    "group00",
+    "group00-proj",
+    "group01",
+    "group01-proj",
+    "group02",
+    "group02-proj",
+    "group03",
+    "group03-proj",
+    "group04",
+    "group04-proj",
+    "group05",
+    "group05-proj",
+    "group06",
+    "group06-proj",
+    "group07",
+    "group07-proj",
+    "group08",
+    "group08-proj",
+    "group09",
+    "group09-proj",
+    "group10",
+    "group10-proj",
+    "group11",
+    "group11-proj",
+    "group12",
+    "group12-proj",
+    "group13",
+    "group13-proj",
+    "group14",
+    "group14-proj",
+    "group15",
+    "group15-proj"
+};
Index: branches/heathaze/src/util/object_manager.h
===================================================================
--- branches/heathaze/src/util/object_manager.h	(revision 9940)
+++ branches/heathaze/src/util/object_manager.h	(revision 9940)
@@ -0,0 +1,121 @@
+/*!
+ * @file object_manager.h
+ * @brief Definition of the ObjectManager.
+ */
+
+#ifndef _OBJECT_MANAGER_H
+#define _OBJECT_MANAGER_H
+
+#include "base_object.h"
+#include <list>
+#include <vector>
+
+/// Enumerator for Managed Object Lists
+typedef enum {
+  OM_NULL             =  0,
+  OM_DEAD,
+  OM_DEAD_TICK,
+  OM_ENVIRON_NOTICK,
+  OM_ENVIRON,
+  OM_BACKGROUND,
+  OM_COMMON,
+
+  OM_PLAYERS,
+  OM_PLAYERS_PROJ,
+
+  OM_GROUP_00,
+  OM_GROUP_00_PROJ,
+  OM_GROUP_01,
+  OM_GROUP_01_PROJ,
+  OM_GROUP_02,
+  OM_GROUP_02_PROJ,
+  OM_GROUP_03,
+  OM_GROUP_03_PROJ,
+  OM_GROUP_04,
+  OM_GROUP_04_PROJ,
+  OM_GROUP_05,
+  OM_GROUP_05_PROJ,
+  OM_GROUP_06,
+  OM_GROUP_06_PROJ,
+  OM_GROUP_07,
+  OM_GROUP_07_PROJ,
+  OM_GROUP_08,
+  OM_GROUP_08_PROJ,
+  OM_GROUP_09,
+  OM_GROUP_09_PROJ,
+  OM_GROUP_10,
+  OM_GROUP_10_PROJ,
+  OM_GROUP_11,
+  OM_GROUP_11_PROJ,
+  OM_GROUP_12,
+  OM_GROUP_12_PROJ,
+  OM_GROUP_13,
+  OM_GROUP_13_PROJ,
+  OM_GROUP_14,
+  OM_GROUP_14_PROJ,
+  OM_GROUP_15,
+  OM_GROUP_15_PROJ,
+
+  OM_SIZE,
+
+
+  OM_INIT             = -1, //!< DO NOT USE THIS. (WorldEntity Internal).
+} OM_LIST;
+
+#define OM_DEFAULT_LIST  OM_NULL
+
+
+// FORWARD DECLARATION
+class PNode;
+class WorldEntity;
+
+//! A powerfull handler for the Object (WorldEntities) in the World.
+class ObjectManager : public BaseObject
+{
+  ObjectListDeclaration(ObjectManager);
+public:
+  typedef std::list<WorldEntity*> EntityList;      //!< A type definition to make it easy to use EntityLists.
+
+  ObjectManager();
+  virtual ~ObjectManager();
+
+  void flush();
+
+  void toList (WorldEntity* entity, OM_LIST omList = OM_DEFAULT_LIST);
+  void toList (WorldEntity* entity, const std::string& omList);
+
+
+  /** @returns the List (listnumber) of objects. @param listNumber the List to get. */
+  EntityList& getEntityList(OM_LIST listNumber) { return this->entityLists[listNumber]; }
+  /** @returns a constant LIST of Objects. @param listNumber the objectList to returns */
+  const EntityList& getEntityList(OM_LIST listNumber) const { return this->entityLists[listNumber]; }
+
+  template <class T> static void distanceFromObject(EntityList& entities, const PNode& center, float radius, ObjectList<T>& list);
+
+  void debug(OM_LIST omList, unsigned int level = 0) const;
+  void debug(const std::string& listName = "", unsigned int level = 0);
+
+  static OM_LIST StringToOMList(const std::string& listName);
+  static const std::string& OMListToString(OM_LIST omList);
+
+
+  void toReflectionList( WorldEntity* entity) { this->reflectionList.push_back(entity); }
+  /** @returns the list of all reflected objects in the world */
+  EntityList& getReflectionList() { return this->reflectionList; }
+  /** @returns the static list of all reflected objects in the world */
+  const EntityList& getReflectionList() const { return this->reflectionList; }
+
+
+
+
+private:
+  const std::list<BaseObject>*            pNodeList;                //!< The List of PNodes.
+
+  EntityList                              entityLists[OM_SIZE];     //!< The ObjectLists.
+
+  static const std::string                objectManagerListNames[]; //!< Names of all the lists
+
+  EntityList                              reflectionList;           //!< A list of all reflected objects in the world
+};
+
+#endif /* _OBJECT_MANAGER_H */
Index: branches/heathaze/src/util/signal_handler.cc
===================================================================
--- branches/heathaze/src/util/signal_handler.cc	(revision 9940)
+++ branches/heathaze/src/util/signal_handler.cc	(revision 9940)
@@ -0,0 +1,292 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+*/
+
+#include "signal_handler.h"
+#include <assert.h>
+
+SignalHandler * SignalHandler::singletonRef = NULL;
+
+#ifndef __WIN32__
+
+#include <wait.h>
+
+SignalHandler::SignalHandler()
+{
+}
+
+/**
+ * register signal handlers for SIGSEGV and SIGABRT
+ * @param appName path to executable eg argv[0]
+ * @param fileName filename to append backtrace to
+ */
+void SignalHandler::doCatch( const std::string & appName, const std::string & fileName )
+{
+  this->appName = appName;
+  this->fileName = fileName;
+  
+  // make sure doCatch is only called once without calling dontCatch
+  assert( sigRecList.size() == 0 );
+
+  catchSignal( SIGSEGV );
+  catchSignal( SIGABRT );
+}
+
+/**
+ * restore previous signal handlers
+ */
+void SignalHandler::dontCatch()
+{
+  for ( SignalRecList::iterator it = sigRecList.begin(); it != sigRecList.end(); it++ )
+  {
+    signal( it->signal, it->handler );
+  }
+
+  sigRecList.clear();
+}
+
+/**
+ * catch signal sig
+ * @param sig signal to catch
+ */
+void SignalHandler::catchSignal( int sig )
+{
+  sig_t handler = signal( sig, SignalHandler::sigHandler );
+
+  assert( handler != SIG_ERR );
+
+  SignalRec rec;
+  rec.signal = sig;
+  rec.handler = handler;
+
+  sigRecList.push_front( rec );
+}
+
+/**
+ * sigHandler is called when receiving signals
+ * @param sig 
+ */
+void SignalHandler::sigHandler( int sig )
+{
+  for ( SignalCallbackList::iterator it = SignalHandler::getInstance()->callbackList.begin(); it != SignalHandler::getInstance()->callbackList.end(); it++  )
+  {
+    (*(it->cb))( it->someData );
+  }
+
+  std::string sigName = "UNKNOWN";
+  
+  switch ( sig )
+  {
+    case SIGSEGV:
+      sigName = "SIGSEGV";
+      break;
+    case SIGABRT:
+      sigName = "SIGABRT";
+      break;
+  }
+
+  printf( "recieved signal %s\ntry to write backtrace to file orxonox.backtrace\n", sigName.c_str() );
+  
+  int sigPipe[2];
+  if ( pipe(sigPipe) == -1 )
+  {
+    perror("pipe failed!\n");
+    exit(EXIT_FAILURE);
+  }
+  
+  int sigPid = fork();
+
+  if ( sigPid == -1 )
+  {
+    perror("fork failed!\n");
+    exit(EXIT_FAILURE);
+  }
+
+  // gdb will be attached to this process
+  if ( sigPid == 0 )
+  {
+    getInstance()->dontCatch();
+    // wait for message from parent when it has attached gdb
+    int someData;
+
+    read( sigPipe[0], &someData, sizeof(someData) );
+
+    if ( someData != 0x12345678 )
+    {
+      printf("something went wrong :(\n");
+    }
+
+    return;
+  }
+
+  int gdbIn[2];
+  int gdbOut[2];
+  int gdbErr[2];
+  
+  if ( pipe(gdbIn) == -1 || pipe(gdbOut) == -1 || pipe(gdbErr) == -1 )
+  {
+    perror("pipe failed!\n");
+    kill( sigPid, SIGTERM );
+    waitpid( sigPid, NULL, 0 );
+    exit(EXIT_FAILURE);
+  }
+
+  int gdbPid = fork();
+  // this process will run gdb
+  
+  if ( gdbPid == -1 )
+  {
+    perror("fork failed\n");
+    kill( sigPid, SIGTERM );
+    waitpid( sigPid, NULL, 0 );
+    exit(EXIT_FAILURE);
+  }
+  
+  if ( gdbPid == 0 )
+  {
+    // start gdb
+    
+    close(gdbIn[1]);
+    close(gdbOut[0]);
+    close(gdbErr[0]);
+
+    dup2( gdbIn[0], STDIN_FILENO );
+    dup2( gdbOut[1], STDOUT_FILENO );
+    dup2( gdbErr[1], STDERR_FILENO );
+    
+    execlp( "sh", "sh", "-c", "gdb", (void*)NULL);
+  }
+
+  char cmd[256];
+  snprintf( cmd, 256, "file %s\nattach %d\nc\n", getInstance()->appName.c_str(), sigPid );
+  write( gdbIn[1], cmd, strlen(cmd) );
+
+  int charsFound = 0;
+  int promptFound = 0;
+  char byte;
+  while ( read( gdbOut[0], &byte, 1 ) == 1 )
+  {
+    if ( 
+      charsFound == 0 && byte == '(' ||
+      charsFound == 1 && byte == 'g' ||
+      charsFound == 2 && byte == 'd' ||
+      charsFound == 3 && byte == 'b' ||
+      charsFound == 4 && byte == ')' ||
+      charsFound == 5 && byte == ' '
+        )
+          charsFound++;
+    else
+      charsFound = 0;
+
+    if ( charsFound == 6 )
+    {
+      promptFound++;
+      charsFound = 0;
+    }
+
+    if ( promptFound == 3 )
+    {
+      break;
+    }
+  }
+  
+  int someData = 0x12345678;
+  write( sigPipe[1], &someData, sizeof(someData) );
+
+  write( gdbIn[1], "bt\nk\nq\n", 7 );
+
+  
+  charsFound = 0;
+  promptFound = 0;
+  std::string bt;
+  while ( read( gdbOut[0], &byte, 1 ) == 1 )
+  {
+    bt += std::string( &byte, 1 );
+
+    if ( 
+      charsFound == 0 && byte == '(' ||
+      charsFound == 1 && byte == 'g' ||
+      charsFound == 2 && byte == 'd' ||
+      charsFound == 3 && byte == 'b' ||
+      charsFound == 4 && byte == ')' ||
+      charsFound == 5 && byte == ' '
+        )
+          charsFound++;
+    else
+      charsFound = 0;
+
+    if ( charsFound == 6 )
+    {
+      promptFound++;
+      charsFound = 0;
+      bt += "\n";
+    }
+
+    if ( promptFound == 3 )
+    {
+      break;
+    }
+  }
+
+
+  waitpid( sigPid, NULL, 0 );
+  waitpid( gdbPid, NULL, 0 );
+  
+  int wsRemoved = 0;
+
+  while ( wsRemoved < 2 && bt.length() > 0 )
+  {
+    if ( bt[1] == '\n' )
+      wsRemoved++;
+    bt.erase(0, 1);
+  }
+
+  if ( bt.length() > 0 )
+    bt.erase(0, 1);
+
+  time_t now = time(NULL);
+
+  std::string timeString = "\n\n\n\n"
+	                   "=======================================================\n"
+	                   "= time: " + std::string(ctime(&now)) +
+			   "=======================================================\n";
+  bt.insert(0, timeString);
+  
+  FILE * f = fopen( getInstance()->fileName.c_str(), "a" );
+
+  if ( !f )
+  {
+    perror( ( std::string( "could not append to " ) + getInstance()->fileName ).c_str() );
+    exit(EXIT_FAILURE);
+  }
+
+  if ( fwrite( bt.c_str(), 1, bt.length(), f ) != bt.length() )
+  {
+    printf( ( std::string("could not write %d byte to ") + getInstance()->fileName ).c_str(), bt.length());
+    exit(EXIT_FAILURE);
+  }
+
+  exit(EXIT_FAILURE);
+}
+
+void SignalHandler::registerCallback( SignalCallback cb, void * someData )
+{
+  SignalCallbackRec rec;
+  rec.cb = cb;
+  rec.someData = someData;
+  
+  callbackList.push_back(rec);
+}
+
+#endif /* __WIN32__ */
Index: branches/heathaze/src/util/signal_handler.h
===================================================================
--- branches/heathaze/src/util/signal_handler.h	(revision 9940)
+++ branches/heathaze/src/util/signal_handler.h	(revision 9940)
@@ -0,0 +1,75 @@
+/*!
+ * @file signalhandler.h
+ * Defines game rules for this game
+ */
+
+#ifndef _SIGNAL_HANDLER_H
+#define _SIGNAL_HANDLER_H
+
+#include <list>
+#include <string>
+
+typedef int (*SignalCallback)( void * someData );
+
+#ifndef __WIN32__
+#include <signal.h>
+
+struct SignalRec
+{
+  int signal;
+  sig_t handler;
+};
+
+struct SignalCallbackRec
+{
+  SignalCallback cb;
+  void * someData;
+};
+
+
+typedef std::list<SignalRec> SignalRecList;
+typedef std::list<SignalCallbackRec> SignalCallbackList;
+
+class SignalHandler
+{
+  private:
+    SignalHandler();
+  public:
+    inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; }
+    ~SignalHandler(){ SignalHandler::singletonRef = NULL; }
+
+    void registerCallback( SignalCallback cb, void * someData );
+
+    void doCatch( const std::string & appName, const std::string & fileName );
+    void dontCatch();
+
+  private:
+    static void sigHandler( int sig );
+
+    void catchSignal( int sig );
+    SignalRecList sigRecList;
+
+    SignalCallbackList callbackList;
+
+    static SignalHandler * singletonRef;
+
+    std::string appName;
+    std::string fileName;
+};
+
+#else /* if defined __WIN32__ */
+class SignalHandler
+{
+ public:
+   inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; };
+   void doCatch( const std::string & appName, const std::string & fileName ) {};
+  void dontCatch() {};
+  void registerCallback( SignalCallback cb, void * someData ) {};
+
+ private:
+    static SignalHandler * singletonRef;
+};
+#endif
+
+#endif /* _SIGNAL_HANDLER_H */
+
Index: branches/heathaze/src/util/singleplayer_shootemup.cc
===================================================================
--- branches/heathaze/src/util/singleplayer_shootemup.cc	(revision 9940)
+++ branches/heathaze/src/util/singleplayer_shootemup.cc	(revision 9940)
@@ -0,0 +1,122 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_MODULE_GAME_RULES
+
+#include "singleplayer_shootemup.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "mission_goal.h"
+
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(SingleplayerShootemup, CL_SINGLEPLAYER_SHOOTEMUP);
+CREATE_FACTORY(SingleplayerShootemup);
+
+/**
+ * constructor
+ */
+SingleplayerShootemup::SingleplayerShootemup(const TiXmlElement* root)
+  : GameRules(root)
+{
+  this->registerObject(this, SingleplayerShootemup::_objectList);
+
+  if( root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ * decontsructor
+ */
+SingleplayerShootemup::~SingleplayerShootemup()
+{
+}
+
+
+
+void SingleplayerShootemup::loadParams(const TiXmlElement* root)
+{
+  GameRules::loadParams(root) ;
+
+   LoadParam(root, "death-screen-image", this, SingleplayerShootemup, setDeathScreen)
+       .describe("sets the death screen image");
+
+}
+
+
+
+void SingleplayerShootemup::setDeathScreen(const std::string& imageName)
+{}
+
+
+
+/**
+ * called when the player enters the game
+ * @param player the spawned player
+ */
+void SingleplayerShootemup::onPlayerSpawn()
+{
+}
+
+
+/**
+ * when the player is killed
+ * @param player the killed player
+ */
+void SingleplayerShootemup::onPlayerDeath()
+{
+}
+
+
+/**
+ * time tick
+ * @param dt time
+ */
+void SingleplayerShootemup::tick(float dt)
+{
+  this->checkGameRules(dt);
+}
+
+
+/**
+ * draws the stuff
+ */
+void SingleplayerShootemup::draw()
+{}
+
+
+/**
+ * check the game rules for consistency
+ */
+void SingleplayerShootemup::checkGameRules(float dt)
+{
+//   PRINTF(0)("===========| Printing Mission State:\n");
+  for (std::vector<MissionGoal*>::iterator it = this->missionList.begin(); it != this->missionList.end(); it++)
+  {
+    if( (*it)->checkMissionGoal(dt) != MS_ACCOMPLISHED)
+    {
+//       PRINTF(0)("  Mission \"%s\" is not finished yet\n", (*it)->getMissionName().c_str());
+    }
+  }
+}
+
+
+
+
+
+
Index: branches/heathaze/src/util/singleplayer_shootemup.h
===================================================================
--- branches/heathaze/src/util/singleplayer_shootemup.h	(revision 9940)
+++ branches/heathaze/src/util/singleplayer_shootemup.h	(revision 9940)
@@ -0,0 +1,45 @@
+
+/*!
+ * @file multiplayer_team_deathmatch.h
+ * Defines game rules for team deathmatch games
+ *
+ * currently there are only two teams supported
+ */
+
+#ifndef _SINGLEPLAYER_SHOOTEMUP_H
+#define _SINGLEPLAYER_SHOOTEMUP_H
+
+#include "game_rules.h"
+
+
+class TiXmlElement;
+
+
+class SingleplayerShootemup : public GameRules
+{
+  ObjectListDeclaration(SingleplayerShootemup);
+  public:
+    SingleplayerShootemup(const TiXmlElement* root = NULL);
+    virtual ~SingleplayerShootemup();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void onPlayerSpawn();
+    virtual void onPlayerDeath();
+
+    virtual void tick(float dt);
+    void draw();
+
+    void setDeathScreen(const std::string& imageName);
+
+
+  protected:
+    virtual void checkGameRules(float dt);
+
+
+  private:
+
+};
+
+
+#endif /* _SINGLEPLAYER_SHOOTEMUP_H */
Index: branches/heathaze/src/util/state.cc
===================================================================
--- branches/heathaze/src/util/state.cc	(revision 9940)
+++ branches/heathaze/src/util/state.cc	(revision 9940)
@@ -0,0 +1,64 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "state.h"
+
+
+#include "camera.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+
+
+
+
+Camera* State::camera = NULL;
+CameraTarget* State::cameraTarget = NULL;
+
+PNode* State::cameraNode = NULL;
+PNode* State::cameraTargetNode = NULL;
+
+SkyBox* State::skyBox = NULL;
+
+ObjectManager* State::objectManager = NULL;
+ScriptManager* State::scriptManager = NULL;
+
+unsigned int State::resX = 1;
+unsigned int State::resY = 1;
+
+StoryEntity* State::storyEntity = NULL;
+GameRules* State::gameRules = NULL;
+
+Player* State::player = NULL;
+
+bool State::bOnline = false;
+
+int State::menuID = -1;
+
+
+/**
+ *  sets camera and target of the current Camera
+*/
+void State::setCamera(Camera* camera, CameraTarget* cameraTarget)
+{
+  State::camera = camera;
+  State::cameraTarget = cameraTarget;
+  State::cameraNode = camera;
+  State::cameraTargetNode = cameraTarget;
+}
Index: branches/heathaze/src/util/state.h
===================================================================
--- branches/heathaze/src/util/state.h	(revision 9940)
+++ branches/heathaze/src/util/state.h	(revision 9940)
@@ -0,0 +1,136 @@
+/*!
+ * @file state.h
+ * Definition of the States Class
+*/
+
+#ifndef _STATE_H
+#define _STATE_H
+
+
+// FORWARD DECLARATION
+class PNode;
+class Camera;
+class CameraTarget;
+class WorldEntity;
+class Player;
+class SkyBox;
+class StoryEntity;
+class ObjectManager;
+class GameRules;
+
+class ScriptManager;
+
+
+//! handles states about orxonox's most importatn objects
+/**
+ * This is an abstract Class-container, not really a Class.
+ * in this Class only static references to the most important
+ * Objects/List/etc. are stored.
+ */
+class State {
+
+ public:
+   //////////////
+   /// CAMERA ///
+   //////////////
+  /** @param camera the PNode to the Camera, @param cameraTarget the PNode to the Camera's target */
+  static void setCamera(Camera* camera, CameraTarget* cameraTarget);
+  static inline Camera* getCamera() { return State::camera; };
+  static inline CameraTarget* getCameraTarget() { return State::cameraTarget; };
+  /** @returns a Pointer to the PNode of the Camera */
+  static inline PNode* getCameraNode() { return State::cameraNode; };
+  /** @returns a Pointer to the CameraTarget */
+  static inline PNode* getCameraTargetNode() { return State::cameraTargetNode; };
+
+  ////////////////
+  /// SKYBOX   ///
+  ////////////////
+  /** @returns the current SkyBox */
+  static inline SkyBox* getSkyBox() { return State::skyBox; };
+  /** @param skyBox the SkyBox */
+  static inline void setSkyBox(SkyBox* skyBox) { State::skyBox = skyBox; };
+
+  //////////////////////
+  /// OBJECT-MANAGER ///
+  //////////////////////
+  /** @param objectManager the new Current ObjectManager */
+  static inline void setObjectManager(ObjectManager* objectManager) { State::objectManager = objectManager; };
+  /** @returns the current ObjectManager. */
+  static inline ObjectManager* getObjectManager() { return State::objectManager; };
+
+  static inline void setResolution(unsigned int resX, unsigned int resY) { State::resX = resX; State::resY = resY; };
+  static inline unsigned int getResX() { return State::resX; };
+  static inline unsigned int getResY() { return State::resY; };
+
+  //////////////////////
+  /// STORY-ENTITY   ///
+  //////////////////////
+  /** @param storyEntity sets the current StoryEntity that is been played */
+  static inline void setCurrentStoryEntity(StoryEntity* storyEntity) { State::storyEntity = storyEntity; };
+  /** @returns the current StoryEntity played */
+  static inline StoryEntity* getCurrentStoryEntity() { return State::storyEntity; };
+
+  /** @param gameRules sets the current GameRules */
+  static inline void setGameRules(GameRules* gameRules) { State::gameRules = gameRules; }
+  /** @returns the GameRules reference*/
+  static inline GameRules* getGameRules() { return State::gameRules; }
+
+  //////////////
+  /// PLAYER ///
+  //////////////
+  /** @param player sets the current local player */
+  static inline void setPlayer(Player* player) { State::player = player; };
+  /** @returns the local player*/
+  static inline Player* getPlayer() { return State::player; };
+
+
+  ///////////////
+  /// NETWORK ///
+  ///////////////
+  /** sets the online stat (multiplayer network) @param bOnline is true if node is online */
+  static inline void setOnline(bool bOnline) { State::bOnline = bOnline; }
+  /** @returns true if this node is online (multiplayer network game) */
+  static bool isOnline() { return State::bOnline; }
+
+
+
+  ////////////////////
+  /// SCRIPT_ENGINE ///
+  ////////////////////
+  static void setScriptManager(ScriptManager* scriptManager) { State::scriptManager = scriptManager; };
+  static ScriptManager* getScriptManager() { return State::scriptManager; };
+
+  ////////////
+  /// Menu ///
+  ////////////
+  /** sets the menu mode @param mode true if always exit to menu */
+  static inline void setMenuID(int menuID) { State::menuID = menuID; }
+  /** @returns the menu mode */
+  static inline int getMenuID() { return State::menuID;}
+
+
+
+ private:
+  State();
+
+  static Camera*                camera;             //!< The current Camera.
+  static CameraTarget*          cameraTarget;       //!< The Camera Target.
+  static PNode*                 cameraNode;         //!< A reference to the camera
+  static PNode*                 cameraTargetNode;   //!< A reference to the cameraTarget
+  static PNode*                 nullParent;         //!< A reference to the Null-PNode.
+  static ObjectManager*         objectManager;      //!< A reference to the current ObjectManager
+  static StoryEntity*           storyEntity;        //!< A reference to the current StoryEntity played
+  static GameRules*             gameRules;          //!< A reference to the GameRules
+  static Player*                player;             //!< A reference to the Player
+
+  static SkyBox*                skyBox;            //!< The SkyBox used in the current world.
+
+  static  ScriptManager*        scriptManager;     //!< The ScriptManager.
+
+  static unsigned int           resX;              //!< The X Resolution of the screen.
+  static unsigned int           resY;              //!< The Y Resolution of the screen.
+  static int                    menuID;            //!< -1 on default, otherwise orxonox's Menu ID
+  static bool                   bOnline;           //!< Is true if this node is in multiplayer mode (via network)
+  };
+
+#endif /* _STATE_H */
Index: branches/heathaze/src/util/track/pilot_node.cc
===================================================================
--- branches/heathaze/src/util/track/pilot_node.cc	(revision 9940)
+++ branches/heathaze/src/util/track/pilot_node.cc	(revision 9940)
@@ -0,0 +1,126 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+
+   bensch: added comments
+*/
+
+
+#include "pilot_node.h"
+#include "event.h"
+#include "key_mapper.h"
+
+
+ObjectListDefinition(PilotNode);
+/**
+ *  standard constructor
+*/
+PilotNode::PilotNode ()
+{
+  this->registerObject(this, PilotNode::_objectList);
+   this->setName("PilotNode");
+
+   travelSpeed = 30.0;
+   velocity = new Vector();
+   bUp = bDown = bLeft = bRight = false;
+}
+
+/**
+ *  standard deconstructor
+*/
+PilotNode::~PilotNode ()
+{
+
+}
+
+/**
+  *  ticks the node
+  * @param time the time about whitch to tick                                           \
+*/
+void PilotNode::tick(float time)
+{
+  this->move(time);
+}
+
+
+/**
+ *  action if player moves
+ * @param time the timeslice since the last frame
+*/
+void PilotNode::move (float time)
+{
+  Vector accel(0.0, 0.0, 0.0);
+  /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */
+  /* calculate the direction in which the craft is heading  */
+  //Vector direction (1.0, 0.0, 0.0);
+  //direction = this->absDirection.apply (direction);
+  //Vector orthDirection (0.0, 0.0, 1.0);
+  //orthDirection = orthDirection.cross (direction);
+
+   Quaternion q = this->getAbsDir();
+   Vector direction(1,0,0);
+   direction = q.apply(direction);
+
+
+
+   Vector orthDirection(0,0,1);
+   orthDirection = q.apply(orthDirection);
+
+   if( this->bUp)
+     accel = accel+(direction*acceleration);
+   if( this->bDown)
+     accel = accel -(direction*acceleration);
+   if( this->bLeft)
+     accel = accel - (orthDirection*acceleration);
+   if( this->bRight)
+     accel = accel + (orthDirection*acceleration);
+
+   Vector move = accel * time;
+   this->shiftCoor (move);
+
+   Quaternion q1(-M_PI/4 * this->roll/40000.0, Vector(0,0,1));
+   Quaternion q2(-M_PI/4 * this->pitch/30000.0, Vector(0,1,0));
+   //this->shiftDir(q1*q2);
+   this->shiftDir(q1*q2);
+}
+
+/**
+ *  handles events
+ * @param event the event that occured
+*/
+void PilotNode::process( const Event &event)
+{
+  if( event.type == KeyMapper::PEV_FORWARD)
+    {
+      this->bUp = event.bPressed;
+    }
+  else if( event.type == KeyMapper::PEV_BACKWARD)
+    {
+      this->bDown = event.bPressed;
+    }
+  else if( event.type == KeyMapper::PEV_RIGHT)
+    {
+      this->bRight= event.bPressed;
+    }
+  else if( event.type == KeyMapper::PEV_LEFT)
+    {
+      this->bLeft = event.bPressed;
+    }
+  else if( event.type == EV_MOUSE_MOTION)
+    {
+      this->pitch = event.x - 400;
+      this->roll = event.y - 300;
+    }
+}
Index: branches/heathaze/src/util/track/pilot_node.h
===================================================================
--- branches/heathaze/src/util/track/pilot_node.h	(revision 9940)
+++ branches/heathaze/src/util/track/pilot_node.h	(revision 9940)
@@ -0,0 +1,46 @@
+/*!
+ * @file pilot_node.h
+  *  Definition of a PilotNode
+*/
+
+
+#ifndef _PILOT_NODE_H
+#define _PILOT_NODE_H
+
+#include "world_entity.h"
+#include "event_listener.h"
+
+class Event;
+
+//! The PilotNode is a node that enables the is driven by the Mouse
+class PilotNode : public WorldEntity, public EventListener {
+  ObjectListDeclaration(PilotNode);
+
+ public:
+  PilotNode ();
+  virtual ~PilotNode ();
+
+  virtual void tick(float time);
+
+  virtual void process(const Event &event);
+
+ private:
+  void move(float time);
+
+ private:
+  bool        bUp;            //!< up button pressed.
+  bool        bDown;          //!< down button pressed.
+  bool        bLeft;          //!< left button pressed.
+  bool        bRight;         //!< right button pressed.
+
+  int         pitch;          //!< the pitch of the node
+  int         roll;           //!< the roll of the node
+
+  Vector*     velocity;       //!< the velocity of the player.
+  float       travelSpeed;    //!< the current speed of the player (to make soft movement)
+  float       acceleration;   //!< the acceleration of the player.
+
+
+};
+
+#endif /* _PILOT_NODE_H */
Index: branches/heathaze/src/util/track/track_manager.cc
===================================================================
--- branches/heathaze/src/util/track/track_manager.cc	(revision 9940)
+++ branches/heathaze/src/util/track/track_manager.cc	(revision 9940)
@@ -0,0 +1,1204 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_TRACK_MANAGER
+
+#include "track_manager.h"
+
+#include "base_object.h"
+#include "util/loading/load_param.h"
+#include "p_node.h"
+#include "track_node.h"
+#include "stdincl.h"
+#include "text.h"
+#include "t_animation.h"
+
+
+#include "parser/tinyxml/tinyxml.h"
+#include "substring.h"
+
+#include <stdarg.h>
+
+
+
+/**
+ *  initializes a TrackElement (sets the default values)
+*/
+TrackElement::TrackElement()
+{
+  this->setClassID(CL_TRACK_ELEMENT, "TrackElement");
+
+  this->isFresh = true;
+  this->isHotPoint = false;
+  this->isSavePoint = false;
+  this->isFork = false;
+  this->isJoined = false;
+  this->mainJoin = false;
+  this->ID = -1;
+  this->startingTime = 0;
+  this->duration = TMAN_DEFAULT_DURATION;
+  this->endTime = 1;
+  this->jumpTime = 0;
+  this->width = TMAN_DEFAULT_WIDTH;
+  this->nodeCount = 0;
+  this->curve = NULL;
+  this->childCount = 0;
+  this->children = NULL;
+
+  this->history = NULL;
+
+  this->subject = NULL;
+  this->condFunc = &TrackElement::random;
+}
+
+/**
+  *  destroys all alocated memory)
+    @todo eventually when deleting a TrackElement you would not like to delete all its preceding TrackElements
+*/
+TrackElement::~TrackElement()
+{
+  // deleting the Curve
+  delete this->curve;
+
+  // deleting all the Children of this TrackNode.
+  if ((!this->isJoined &&this->childCount > 0)
+      || (this->isJoined && this->mainJoin)) // only if this is the MainJoin.
+    {
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      while (enumElem)
+        {
+          delete enumElem;
+          enumElem = iterator->nextElement();
+        }
+      delete iterator;
+      delete this->children;
+    }
+}
+
+/**
+ * Searches through all the TrackElements for trackID.
+ * @param trackID The ID to search for.
+ * @returns The TrackElement if Found, NULL otherwise.
+*/
+TrackElement* TrackElement::findByID(unsigned int trackID)
+{
+  // return if Found.
+  if (this->ID == trackID)
+    return this;
+  // search all children
+  if (this->childCount > 0)
+    {
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      TrackElement* tmpElem = NULL;
+      while (enumElem)
+        {
+          if ((tmpElem = enumElem->findByID(trackID)) != NULL)
+            return tmpElem;
+          enumElem = iterator->nextElement();
+        }
+      delete iterator;
+    }
+  // if not found
+  return NULL;
+}
+
+
+/**
+ *  Searches through all the TrackElements for a trackName
+ * @param trackName The name to search for.
+ * @returns The TrackElement if Found, NULL otherwise.
+*/
+TrackElement* TrackElement::findByName(const std::string& trackName)
+{
+  // return if Found.
+  if (this->getName() && !strcmp(this->getName(), trackName))
+    return this;
+  // search all children
+  if (this->childCount > 0)
+    {
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      TrackElement* tmpElem;
+      while (enumElem)
+        {
+          if ((tmpElem = enumElem->findByName(trackName)))
+            return tmpElem;
+          enumElem = iterator->nextElement();
+        }
+      delete iterator;
+    }
+  // if not found
+  return NULL;
+}
+
+/**
+ *  checks if there are any BackLoops in the Track
+ * @returns true if NO loop was found, false Otherwise
+   You actually have to act on false!!
+*/
+bool TrackElement::backLoopCheck() const
+{
+  tList<const TrackElement>* trackList = new tList<const TrackElement>;
+
+  this->backLoopCheckAtomic(trackList);
+
+  delete trackList;
+  // only returns if everything worked out
+  return true;
+}
+
+/**
+ *  checks if there are any BackLoops in the Track.
+ * @param trackList A list of stored tracks, to search in.
+ * @returns true if NO loop was found, false Otherwise
+   You actually have to act on false!!
+*/
+bool TrackElement::backLoopCheckAtomic(tList<const TrackElement>* trackList) const
+{
+  if (trackList->inList(this))
+    return false;
+
+  trackList->add(this);
+
+  if (this->children)
+    {
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      while (enumElem)
+        {
+          if (!enumElem->backLoopCheckAtomic(trackList))
+            return false;
+        }
+      delete iterator;
+    }
+  return true;
+}
+
+
+/**
+ * @param childCount which child to return
+ * @returns the n-the children (starting at 0).
+   Be aware, that when the trackElement has no Children, NULL will be returned
+*/
+TrackElement* TrackElement::getChild(unsigned int childCount) const
+{
+  // if the the trackElement has no children return NULL.
+  if (this->childCount == 0)
+    return NULL;
+  // we cannot return the childCount+m's Child, so we return the last.
+  if (childCount > this->childCount)
+    childCount = this->childCount;
+
+  tIterator<TrackElement>* iterator = this->children->getIterator();
+  TrackElement* enumElem = iterator->firstElement();
+  for (unsigned int i = 0; i < childCount; i++)
+    enumElem = iterator->nextElement();
+  delete iterator;
+  return enumElem;
+}
+
+/**
+ *  prints out debug information about this TrackElement
+*/
+void TrackElement::debug() const
+{
+  PRINT(0)("--== TrackElement:%i ==--", this->ID);
+  if(this->getName())
+    PRINT(0)("--++Name: %s++--", this->getName());
+  if(this->isFresh)
+    PRINT(0)("  -- has not jet eddited in any way --\n");
+  PRINT(0)("\n   TimeTable: startingTime=%f; endTime=%f; duration=%f; jumpTime=%f\n", this->startingTime, this->endTime, this->duration, this->jumpTime);
+  PRINT(0)("   consists of %d Points\n", this->nodeCount);
+  if (this->childCount == 0)
+    PRINT(0)("   has no child\n");
+  else if (this->childCount == 1)
+    PRINT(0)("   has 1 child: =%d=\n", this->getChild(0)->ID);
+  else if (this->childCount > 1)
+    {
+      PRINT(0)("   has %d children: ", this->childCount);
+      //TrackElement* enumElem = this->children->enumerate();
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      while (enumElem)
+        {
+          PRINT(0)("=%d= ", enumElem->ID);
+          enumElem = iterator->nextElement();
+        }
+      delete iterator;
+      PRINT(0)("\n");
+    }
+
+  if(this->isHotPoint)
+    PRINT(0)("   is a special Point:\n");
+  if(this->isSavePoint)
+    PRINT(0)("    is a SavePoint\n");
+  if(this->isFork)
+    {
+      PRINT(0)("    is A Fork with with %d children.\n", this->childCount);
+    }
+  if(this->isJoined)
+    PRINT(0)("   is Joined at the End\n");
+
+  if(!this->backLoopCheck()) /* this should not happen */
+    PRINT(2)(" THERE IS A BACKLOOP TO THIS ELEMENT\n");
+}
+
+/**
+ *  CONDITION that chooses the first child for the decision (static)
+ * @param nothing Nothing in this function
+ * @returns the chosen child
+*/
+int TrackElement::lowest(const void* nothing) const
+{
+  return 0;
+}
+
+/**
+ *  CONDITION that chooses the last child for the decision (static)
+ * @param nothing Nothing in this function
+ * @returns the chosen child
+*/
+int TrackElement::highest(const void* nothing) const
+{
+  return this->childCount-1;
+}
+
+/**
+ *  CONDITION that chooses a random child for the decision (static)
+ * @param nothing Nothing in this function
+ * @returns the chosen child
+*/
+int TrackElement::random(const void* nothing) const
+{
+  int i = (int)floor ((float)rand()/(float)RAND_MAX * (float)this->childCount);
+  if (i >= this->childCount)
+    return this->childCount-1;
+  else
+    return i;
+}
+
+/**
+ *  CONDITION that chooses child 0, if the node(probably Player)
+   is left of its parent (z<0)) and 1/right otherwise.
+ * @param node The node to act upon.
+ * @returns the chosen child
+*/
+int TrackElement::leftRight(const void* node) const
+{
+  PNode* tmpNode = (PNode*)node;
+
+  if (tmpNode->getRelCoor().z < 0)
+    return 0;
+  else
+    return 1;
+}
+
+
+/**
+ *  CONDITION that chooses the child, that has the nearest distance to the node (probably player).
+ * @param node The node to act upon.
+ * @returns the chosen child
+
+   This is rather dangerous, because one must carefully set the points on the curve.
+   The best Way is to set the nodes as wide away of each other as possible,
+   but take into consideration, that if the nodes are to far from a center node, the center will be chosen.
+   (play with this!!).
+*/
+int TrackElement::nearest(const void* node) const
+{
+  PNode* tmpNode = (PNode*)node;
+
+  Vector nodeRelCoord = tmpNode->getRelCoor();
+  float minDist = 100000000;
+  int childNumber = 0;
+  int i = 0;
+
+  //TrackElement* enumElem = this->children->enumerate();
+  tIterator<TrackElement>* iterator = this->children->getIterator();
+  TrackElement* enumElem = iterator->firstElement();
+  while (enumElem)
+    {
+      float dist = (nodeRelCoord - enumElem->curve->getNode(4)).len();
+      if (dist < minDist)
+        {
+          minDist = dist;
+          childNumber = i;
+        }
+      i++;
+      enumElem = iterator->nextElement();
+    }
+  delete iterator;
+
+  PRINTF(4)("PathDecision with nearest algorithm: %d\n", childNumber);
+  return childNumber;
+}
+
+
+////////////////////////
+///// TRACKMANAGER /////
+////////////////////////
+/**
+ *  standard constructor
+
+*/
+TrackManager::TrackManager()
+{
+  this->setClassID(CL_TRACK_MANAGER, "TrackManager");
+  this->setName("TrackManager");
+
+  TrackManager::singletonRef = this; // do this because otherwise the TrackNode cannot get The instance of the TrackManager
+
+  PRINTF(3)("Initializing the TrackManager\n");
+  // setting up the First TrackElement
+  this->firstTrackElem = new TrackElement();
+  this->firstTrackElem->ID = 1;
+  this->firstTrackElem->setName("root");
+
+  this->currentTrackElem = firstTrackElem;
+
+  this->curveType = CURVE_BEZIER;
+  this->localTime = 0;
+  this->maxTime = 0;
+  this->trackElemCount = 1;
+
+  this->trackNode = new TrackNode();
+  this->setBindSlave(this->trackNode);
+  // initializing the Text
+  this->trackText = new Text("fonts/earth.ttf", 30);
+  this->trackText->setAlignment(E2D_ALIGN_SCREEN_CENTER);
+  // initializing the Animation for the Text.
+  this->textAnimation = new tAnimation<Text>(this->trackText, &Text::setBlending);
+  this->textAnimation->addKeyFrame(1.0, 3.0, ANIM_NEG_EXP);
+  this->textAnimation->addKeyFrame(0.0, .001);
+  this->textAnimation->setInfinity(ANIM_INF_CONSTANT);
+}
+
+
+/**
+ *  loads a trackElement from a TiXmlElement
+ * @param root the TiXmlElement to load the Data from
+*/
+void TrackManager::loadParams(const TiXmlElement* root)
+{
+  double x, y, z, d;
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+
+    LoadParam_CYCLE(element, "WorkOn", this, TrackManager, workOnS)
+        .describe("Selects a TrackElement (by name) to work on");
+
+    LoadParam_CYCLE(element, "Point", this, TrackManager, addPoint)
+        .describe("Adds a new Point to the currently selected TrackElement");
+
+    LoadParam_CYCLE(element, "Duration", this, TrackManager, setDuration)
+        .describe("Sets the Duration of the currently selected TrackElement");
+
+    LoadParam_CYCLE(element, "HotPoint", this, TrackManager, addHotPoint)
+        .describe("Sets a new Point that acts as a hot point. meaning, the curve will flow through this Point");
+
+    LoadParam_CYCLE(element, "SavePoint", this, TrackManager, setSavePointS)
+        .describe("Sets the current selected Point to a Savepoint, meaning that the curve will be ended and a new one starts, and that one starts again from this point on");
+
+    LoadParam_CYCLE(element, "Fork", this, TrackManager, forkS)
+        .describe("Forks the Path into multiple forked Path names seperated by ','");
+
+    LoadParam_CYCLE(element, "Join", this, TrackManager, joinS)
+        .describe("Joins multiple joining Path names seperated by ','");
+
+      /*
+    if( !strcmp( element->Value(), "Fork"))
+    {
+    container = element->FirstChild();
+    if( container->ToText())
+        {
+        assert( container->Value() != NULL);
+        PRINTF(4)("Loaded Fork: %s\n", container->Value());
+        forkS(container->Value());
+        }
+        }
+      */
+      /*
+        if( !strcmp( element->Value(), "Join"))
+        {
+        container = element->FirstChild();
+        if( container->ToText())
+        {
+        assert( container->Value() != NULL);
+        PRINTF0("Loaded Join: %s\n", container->Value());
+        joinS(container->Value());
+        }
+        }
+      */
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ *  standard destructor
+*/
+TrackManager::~TrackManager()
+{
+  PRINTF(3)("Destruct TrackManager\n");
+
+  PRINTF(4)("Deleting all the TrackElements\n");
+  delete this->firstTrackElem;
+
+  delete this->trackText;
+  // the tracknode should be deleted here, but is deleted by pNode: -> null_parent
+
+  // we do not have a TrackManager anymore
+  TrackManager::singletonRef = NULL;
+}
+
+//! Singleton Reference to TrackManager
+TrackManager* TrackManager::singletonRef = NULL;
+
+// INITIALIZE //
+/**
+ *  reserves Space for childCount children
+ * @param childCount The Count of children to make space for.
+ * @param trackElem The TrackElement to appy this to. (if NULL chose this->currentTrackElement)
+*/
+void TrackManager::initChildren(unsigned int childCount, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  trackElem->childCount = childCount;
+  trackElem->mainJoin = true;  // this tells join, that this one is the Main Join, if it tries to join multiple Tracks
+  trackElem->children =  new tList<TrackElement>();
+  for (int i = 0; i < childCount; i++)
+    {
+      // create a new Element
+      TrackElement* newElem = new TrackElement();
+      // setting up the new ID
+      newElem->ID = ++trackElemCount;
+      // setting up the Time
+      newElem->startingTime = trackElem->endTime + trackElem->jumpTime;
+      // adds the conection Point
+      this->addPointV(trackElem->curve->getNode(trackElem->curve->getNodeCount()),
+                     newElem);
+      // add the new child to the childList.
+      trackElem->children->add(newElem);
+    }
+
+  // setting the Name of the new TrackElement to the name of the last one + _childI
+
+  if (trackElem->getName())
+    {
+      for (int i = 0; i < trackElem->childCount; i++)
+      {
+        char* childName = new char[strlen(trackElem->getName())+10];
+        sprintf(childName, "%s_child%d", trackElem->getName(), i);
+        trackElem->getChild(i)->setName(childName);
+      }
+    }
+  // select the first Child to work on.
+  this->currentTrackElem = trackElem->getChild(0);
+}
+
+
+/**
+ *  Sets the trackID we are working on.
+ * @param trackID the trackID we are working on
+*/
+void TrackManager::workOn(unsigned int trackID)
+{
+  TrackElement* tmpElem = this->firstTrackElem->findByID(trackID);
+  if (tmpElem)
+    this->currentTrackElem = tmpElem;
+  else
+    PRINTF(2)("TrackElement %d not Found, leaving unchanged\n", trackID);
+  PRINTF(4)("now Working on %d\n", this->currentTrackElem->ID);
+}
+
+/**
+ *  Sets the TrackElement to work on
+ * @param trackName the Name of the Track to work on
+*/
+void TrackManager::workOnS(const std::string& trackName)
+{
+  TrackElement* tmpElem = this->firstTrackElem->findByName(trackName);
+  if (tmpElem)
+    this->currentTrackElem = tmpElem;
+  else
+    PRINTF(2)("TrackElement %s not Found, leaving unchanged\n", trackName);
+  PRINTF(4)("now Working on %d\n", this->currentTrackElem->ID);
+}
+
+/**
+ *  Sets the Type of the Curve
+ * @param curveType The Type to set
+ * @param trackElem the TrackElement that should get a new Curve.
+
+ *  this will possibly get obsolete during the process.
+*/
+void TrackManager::setCurveType(CurveType curveType, TrackElement* trackElem)
+{
+  if (!trackElem->isFresh)
+    {
+      PRINTF(2)("It is not possible to change the type of a Curve after you have have appended some points to it\n");
+      return;
+    }
+  this->curveType = curveType;
+  switch (curveType)
+    {
+    case CURVE_BEZIER:
+      trackElem->curve = new BezierCurve();
+      break;
+    }
+}
+
+/**
+ * @param duration the duration of the TrackElement
+   \see void TrackManager::setDuration(float duration, TrackElement* trackElem)
+*/
+void TrackManager::setDuration(float duration)
+{
+  this->setDuration(duration, NULL);
+}
+
+/**
+ *  Sets the duration of the current path in seconds.
+ * @param duration The duration in seconds.
+ * @param trackElem The TrackElement to apply this to.
+*/
+void TrackManager::setDuration(float duration, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  trackElem->duration = duration;
+  trackElem->endTime = trackElem->startingTime + duration;
+}
+
+/**
+ *  adds a point to trackElem
+ * @param x x coord
+ * @param y y coord
+ * @param z z coord
+ * @param trackElem The TrackElement to add the Point to
+*/
+void TrackManager::addPoint(float x, float y, float z)
+{
+  this->addPointV(Vector(x,y,z));
+}
+
+/**
+ *  adds a point to trackElem
+ * @param newPoint The point to add.
+ * @param trackElem The TrackElement to add the Point to
+*/
+void TrackManager::addPointV(Vector newPoint, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  if (trackElem->isFresh)
+    {
+      this->setCurveType(TMAN_DEFAULT_CURVETYPE, trackElem);
+      trackElem->isFresh = false;
+    }
+  trackElem->curve->addNode(newPoint);
+  trackElem->nodeCount++;
+}
+
+/**
+ *  adds a new Hot Point
+ * @param x: the x coordinate of the hotpoint
+ * @param y: the y coordinate of the hotpoint
+ * @param z: the z coordinate of the hotpoint
+   \see int TrackManager::addHotPointV(Vector newPoint, TrackElement* trackElem)
+*/
+void TrackManager::addHotPoint(float x, float y, float z)
+{
+  this->addHotPointV(Vector(x, y, z));
+}
+
+/**
+ *  adds save/splitpoint.
+ * @param newPoint The point to add.
+ * @param trackElem if supplied it will add a hotpoint on this TrackElement
+ * @returns A Pointer to a newly appended Curve
+*/
+int TrackManager::addHotPointV(Vector newPoint, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  PRINTF(4)("setting up a HotPoint\n");
+  if (trackElem->isFresh)
+    {
+      trackElem->isFresh = false;
+    }
+
+  // @todo HotPoint Handling.
+  trackElem->curve->addNode(newPoint);
+  trackElem->nodeCount++;
+  this->initChildren(1, trackElem);
+}
+
+/**
+   @todo this must be better
+*/
+void TrackManager::setSavePointS(const std::string& nextElementName)
+{
+  this->setSavePoint(NULL);
+  if (strcmp(nextElementName, ""))
+    this->firstTrackElem->findByID(this->trackElemCount)->setName(nextElementName);
+}
+
+/**
+ *  Sets the last HotPoint into a savePoint.
+ * @param trackElem The TrackElement to appy this to. (if NULL chose this->currentTrackElement)
+ * @returns A Pointer to a newly appended Curve
+
+   If no HotPoint was defined the last added Point will be rendered into a savePoint. \n
+   If the HotPoint was defined as a fork the Point will \b not be set into a savePoint.
+*/
+void TrackManager::setSavePoint(TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  PRINTF(4)("setting up a SavePoint.\n");
+  if (trackElem->isFork || trackElem->isSavePoint)
+    {
+      PRINTF(2)("%d is already finished \n", trackElem->ID);
+      return;
+    }
+  trackElem->isSavePoint = true;
+  trackElem->isHotPoint = true;
+
+  this->initChildren(1, trackElem);
+}
+
+/**
+ *  adds some interessting non-linear movments through the level.
+ * @param count The Count of children the fork will produce
+
+   If no HotPoint was defined the last added Point will be rendered into a fork. \n
+   If the HotPoint was defined as a savePoint the Point will \b not be set into a fork.
+*/
+void TrackManager::fork(unsigned int count, ...)
+{
+  int* trackIDs = new int[count];
+  this->forkV(count, trackIDs, NULL);
+  va_list ID;
+  va_start (ID, count);
+  for(int i = 0; i < count; i++)
+    {
+      *va_arg (ID, int*) = trackIDs[i];
+    }
+  va_end(ID);
+  delete []trackIDs;
+}
+
+/**
+ * @param count how many children to produce
+ * @param ... the information on the children (these are the Stings of their names
+   \see TrackManager::fork(unsigned int count, ...)
+
+   does the same as fork, but has an array of strings as an input.
+*/
+void TrackManager::forkS(unsigned int count, ...)
+{
+  int* trackIDs = new int[count];
+  this->forkV(count, trackIDs, NULL);
+  va_list name;
+  va_start (name, count);
+  for(int i = 0; i < count; i++)
+    {
+      this->firstTrackElem->findByID(trackIDs[i])->setName(va_arg(name, const std::string&));
+    }
+  va_end(name);
+  delete []trackIDs;
+}
+
+/**
+   \see TrackManager::fork(unsigned int count, ...)
+*/
+void TrackManager::forkS(const std::string& forkString)
+{
+  SubString strings(forkString, ',');
+
+  int* trackIDs = new int[strings.getCount()];
+  this->forkV(strings.getCount(), trackIDs, NULL);
+
+  for(int i = 0; i < strings.getCount(); i++)
+    {
+      this->firstTrackElem->findByID(trackIDs[i])->setName(strings.getString(i));
+    }
+  delete []trackIDs;
+}
+
+/**
+ *  adds some interessting non-linear movments through the level.
+ * @param count The Count of childrens the current HotPoint will have.
+ * @param trackIDs A Pointer to an Array of ints which will hold the trackID's (the user will have to reserve space for this).
+ * @param trackNames the names for the tracks as a char-arrey-array
+ * @param trackElem The TrackElement to appy this to. (if NULL choose this->currentTrackElement)
+   \see TrackManager::fork(unsigned int count, ...)
+*/
+void TrackManager::forkV(unsigned int count, int* trackIDs, char** trackNames, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  PRINTF(4)("Forking with %d children\n", count);
+  if (trackElem->isSavePoint)
+    return;
+  trackElem->isFork = true;
+  trackElem->isHotPoint = true;
+  for(int i = 0; i < count; i++)
+    trackIDs[i]=this->trackElemCount+1+i;
+  this->initChildren(count, trackElem);
+}
+
+/**
+ *  decides under what condition a certain Path will be chosen.
+ * @param trackID the trackID to apply this to.
+ * @param cond the CONDITION of the decision
+ * @param subject the Subject that will be decided upon with CONDITION cond.
+*/
+void TrackManager::condition(unsigned int trackID, CONDITION cond, void* subject)
+{
+  this->condition(cond, subject, this->firstTrackElem->findByID(trackID));
+}
+
+/**
+ *  decides under what condition a certain Path will be chosen.
+ * @param cond the CONDITION of the decision
+ * @param subject the Subject that will be decided upon with CONDITION cond.
+ * @param trackElem The TrackElement to appy this to. (if NULL chose this->currentTrackElement)
+*/
+void TrackManager::condition(CONDITION cond, void* subject, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  if (!trackElem->isFork)
+    {
+      PRINTF(2)("%d is not a Fork, and no condition can be set in this case\n", trackElem->ID);
+      return;
+    }
+  else
+    {
+      switch (cond)
+        {
+        case LOWEST:
+          trackElem->condFunc = &TrackElement::lowest;
+          break;
+        case HIGHEST:
+          trackElem->condFunc = &TrackElement::highest;
+          break;
+        case RANDOM:
+          trackElem->condFunc = &TrackElement::random;
+          break;
+        case LEFTRIGHT:
+          trackElem->condFunc = &TrackElement::leftRight;
+          break;
+        case NEAREST:
+          trackElem->condFunc = &TrackElement::nearest;
+          break;
+        case ENEMYKILLED:
+          break;
+        }
+      trackElem->subject=subject;
+    }
+}
+
+/**
+ *  joins some tracks together again.
+ * @param count The count of Paths to join.
+
+   Join will set the localTime to the longest time a Path has to get to this Point. \n
+   Join will join all curves to the first curve, meaning that all the tangents will be matched.
+*/
+void TrackManager::join(unsigned int count, ...)
+{
+  int* trackIDs = new int [count];
+  va_list ID;
+  va_start (ID, count);
+  for(int i = 0; i < count; i++)
+    {
+      trackIDs[i] = va_arg (ID, int);
+    }
+  va_end(ID);
+  this->joinV(count, trackIDs);
+  delete []trackIDs;
+}
+
+/**
+ *  Joins some Tracks together again.
+ * @param count The count of trackElements to join
+   \see void TrackManager::join(unsigned int count, ...)
+
+   The difference to void TrackManager::join(unsigned int count, ...) is, that this function takes
+   the Names of the TrackElements as inputs and not their ID
+*/
+void TrackManager::joinS(unsigned int count, ...)
+{
+  int* trackIDs = new int [count];
+  va_list NAME;
+  va_start (NAME, count);
+  for(int i = 0; i < count; i++)
+    {
+      const std::string& name = va_arg (NAME, char*);
+      TrackElement* tmpElem = this->firstTrackElem->findByName(name);
+      if (tmpElem)
+        trackIDs[i] = tmpElem->ID;
+      else
+        PRINTF(1)("Trying to join a Track, of which the name does not exist: %s\n", name);
+    }
+  va_end(NAME);
+  this->joinV(count, trackIDs);
+  delete []trackIDs;
+}
+
+/**
+   \see void TrackManager::join(unsigned int count, ...)
+*/
+void TrackManager::joinS(const std::string& joinString)
+{
+  SubString strings(joinString, ',');
+
+  int* trackIDs = new int[strings.getCount()];
+  this->joinV(strings.getCount(), trackIDs);
+
+  for(unsigned int i = 0; i < strings.getCount(); i++)
+    {
+      TrackElement* tmpElem = this->firstTrackElem->findByName(strings.getString(i).c_str());
+      if (tmpElem != NULL)
+        trackIDs[i] = tmpElem->ID;
+      else
+      {
+        PRINTF(1)("Trying to join a Track, of which the name does not exist: %s\n", strings.getString(i).c_str());
+        trackIDs[i] = -1;
+      }
+    }
+  this->joinV(strings.getCount(), trackIDs);
+  delete []trackIDs;
+}
+
+/**
+ *  joins some tracks together again.
+ * @param count The count of Paths to join.
+ * @param trackIDs an Array with the trackID's to join
+ *
+ * @see void TrackManager::join(unsigned int count, ...)
+*/
+void TrackManager::joinV(unsigned int count, int* trackIDs)
+{
+  TrackElement* tmpTrackElem;
+  TrackElement* tmpJoinElem;
+  for (unsigned int i = 0; i < count; i++)
+    if (!this->firstTrackElem->findByID(trackIDs[i]))
+      {
+        PRINTF(1)("Trying to Connect Paths that do not exist yet: %d\n Not Joining Anything\n", trackIDs[i]);
+        return;
+      }
+
+
+  PRINTF(3)("Joining %d tracks and merging to Track %d\n", count, trackIDs[0]);
+
+  // checking if there is a back-loop-connection and ERROR if it is.
+  tmpTrackElem = this->firstTrackElem->findByID(trackIDs[0]);
+  if (!tmpTrackElem->backLoopCheck())
+    {
+      PRINTF(2)("Backloop connection detected at joining trackElements\n -> TRACK WILL NOT BE JOINED\n");
+      return;
+    }
+
+  TrackElement* firstJoint =   this->firstTrackElem->findByID(trackIDs[0]);
+  float tmpLatestTime = firstJoint->endTime;
+
+  Vector tmpEndPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount());
+  Vector tmpTangentPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount()-1);
+  Vector tmpc2Point = firstJoint->curve->getNode(firstJoint->curve->getNodeCount()-2);
+  firstJoint->isJoined = true;
+  //  firstJoint->mainJoin = true;
+  if(!firstJoint->isHotPoint)
+    this->setSavePoint(firstJoint);
+  // Timing:
+  for (unsigned int i = 0; i < count; i++)
+    {
+      if(tmpJoinElem = this->firstTrackElem->findByID(trackIDs[i]))
+        {
+          if (tmpJoinElem->childCount == 0
+              && tmpJoinElem->endTime > tmpLatestTime)
+            tmpLatestTime = tmpJoinElem->endTime;
+        }
+    }
+  // time the main Join.
+  firstJoint->jumpTime = tmpLatestTime - firstJoint->endTime;
+
+  // Joining:
+  for (int i = 1; i < count; i++)
+    {
+      if( tmpJoinElem = this->firstTrackElem->findByID(trackIDs[i]))
+        {
+          if (tmpJoinElem->childCount > 0)
+            printf("!!This Curve has children, and as such will not be joined!!\n You can try joining other childless TrackElements to this one!");
+          else
+            {
+              this->addPointV(tmpc2Point, tmpJoinElem);
+              this->addPointV(tmpTangentPoint, tmpJoinElem);
+              this->addPointV(tmpEndPoint, tmpJoinElem);
+              // time all other Joins
+              tmpJoinElem->jumpTime = tmpLatestTime - tmpJoinElem->endTime;
+
+              //Copying Joint-Info
+              tmpJoinElem->children = firstJoint->children;
+              tmpJoinElem->childCount = firstJoint->childCount;
+              tmpJoinElem->isSavePoint = firstJoint->isSavePoint;
+              tmpJoinElem->isFork = firstJoint->isFork;
+
+              tmpJoinElem->isJoined = true;
+            }
+        }
+    }
+  if(firstJoint->children)
+    {
+      //TrackElement* enumElem = firstJoint->children->enumerate();
+      tIterator<TrackElement>* iterator = firstJoint->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      while (enumElem)
+        {
+          PRINTF(5)("Setting startingTime of %d to %f.\n", enumElem->ID, tmpLatestTime);
+          enumElem->startingTime = tmpLatestTime;
+          enumElem->endTime = tmpLatestTime + enumElem->duration;
+
+          enumElem = iterator->nextElement();
+        }
+      delete iterator;
+    }
+}
+
+/**
+ *  finalizes the TrackSystem. after this it will not be editable anymore
+
+   @todo check for any inconsistencies, output errors
+*/
+void TrackManager::finalize()
+{
+  for (int i = 1; i<= trackElemCount ;i++)
+    {
+      TrackElement* tmpElem = this->firstTrackElem->findByID(i);
+      if( tmpElem->childCount > 0 && tmpElem->mainJoin)
+        {
+          tIterator<TrackElement>* iterator = tmpElem->children->getIterator();
+          TrackElement* enumElem = iterator->firstElement();
+          //TrackElement* enumElem = tmpElem->children->enumerate();
+          while (enumElem)
+            {
+
+              // c1-continuity
+              enumElem->curve->addNode(enumElem->curve->getNode(0) +
+                                                   ((enumElem->curve->getNode(0) -
+                                                    tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-1))
+                                                    ),2);
+              enumElem->nodeCount++;
+              // c2-continuity
+              enumElem->curve->addNode((tmpElem->curve->getNode(tmpElem->curve->getNodeCount())-
+                                                    tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-1)) * 4 +
+                                                   tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-2), 3);
+              enumElem->nodeCount++;
+              PRINTF(5)("accelerations: %d-in: count: %d, %f, %f, %f\n                  %d-out: count: %d %f, %f, %f\n",
+                     tmpElem->ID, tmpElem->nodeCount,
+                     tmpElem->curve->calcAcc(0.999).x, tmpElem->curve->calcAcc(0.999).y, tmpElem->curve->calcAcc(0.999).z,
+                     enumElem->ID, enumElem->nodeCount,
+                     enumElem->curve->calcAcc(0).x, enumElem->curve->calcAcc(0).y, enumElem->curve->calcAcc(0).z);
+
+              enumElem = iterator->nextElement();
+            }
+          delete iterator;
+        }
+    }
+  for (int i = 1; i <= trackElemCount;i++)
+    if (this->firstTrackElem->findByID(i)->endTime > this->maxTime)
+      this->maxTime = this->firstTrackElem->findByID(i)->endTime; // very bad implemented :/
+}
+
+
+// RUNTIME //
+
+/**
+ *  calculates the Position for the localTime of the Track.
+ * @returns the calculated Position
+*/
+Vector TrackManager::calcPos() const
+{
+  return this->currentTrackElem->curve->calcPos((this->localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
+}
+
+/**
+ *  calculates the Rotation for the localTime of the Track.
+ * @returns the calculated Rotation
+*/
+Vector TrackManager::calcDir() const
+{
+  return this->currentTrackElem->curve->calcDir((this->localTime - this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
+}
+
+/**
+ * @returns the current Width of the track
+*/
+float TrackManager::getWidth() const
+{
+  return this->currentTrackElem->width;
+}
+
+/**
+ *  Advances the local-time of the Track around dt
+ * @param dt The time about which to advance.
+
+   This function also checks, if the TrackElement has to be changed.
+*/
+void TrackManager::tick(float dt)
+{
+  PRINTF(4)("CurrentTrackID: %d, LocalTime is: %f, timestep is: %f\n", this->currentTrackElem->ID, this->localTime, dt);
+  if (this->localTime <= this->firstTrackElem->duration)
+    this->jumpTo(this->localTime);
+  if (this->localTime <= this->maxTime)
+    this->localTime += dt;
+  if (this->localTime > this->currentTrackElem->endTime
+      && this->currentTrackElem->children)
+    {
+      if (this->currentTrackElem->jumpTime != 0.0)
+        this->jumpTo(this->localTime + this->currentTrackElem->jumpTime);
+      // jump to the next TrackElement and also set the history of the new Element to the old one.
+      TrackElement* tmpHistoryElem = this->currentTrackElem;
+      this->currentTrackElem = this->currentTrackElem->getChild(this->choosePath(this->currentTrackElem));
+      this->currentTrackElem->history = tmpHistoryElem;
+      if (this->currentTrackElem->getName())
+        {
+          this->trackText->setText(this->currentTrackElem->getName());
+          this->textAnimation->replay();
+        }
+    }
+  if (this->bindSlave)
+    {
+      Vector tmp = this->calcPos();
+      Quaternion quat = Quaternion(this->calcDir(), Vector(this->currentTrackElem->curve->calcAcc((localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration).x,1,this->currentTrackElem->curve->calcAcc((localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration).z));
+
+      Vector v(0.0, 1.0, 0.0);
+      Quaternion q(-PI/2, v);
+      quat = quat * q;
+
+      this->bindSlave->setAbsCoor(tmp);
+      this->bindSlave->setAbsDir(quat);
+    }
+}
+
+/**
+ *  Jumps to a certain point on the Track.
+ * @param time The time on the Track to jump to.
+
+   This should be used to Jump backwards on a Track, because moving forward means to change between the Path. (it then tries to choose the default.)
+   Max is trackLengthMax.
+*/
+void TrackManager::jumpTo(float time)
+{
+  if (time == 0)
+    {
+      this->currentTrackElem = this->firstTrackElem;
+      if (this->currentTrackElem->getName())
+        {
+          this->trackText->setText(this->currentTrackElem->getName());
+          this->textAnimation->play();
+        }
+    }
+  this->localTime = time;
+}
+
+/**
+ *  a Function that decides which Path we should follow.
+ * @param trackElem The Path to choose.
+
+*/
+int TrackManager::choosePath(TrackElement* trackElem)
+{
+  return (trackElem->*(trackElem->condFunc))(trackElem->subject);
+}
+
+/**
+ *  Sets the PNode, that should be moved along the Tack
+ * @param bindSlave the PNode to set
+*/
+void TrackManager::setBindSlave(PNode* bindSlave)
+{
+  this->bindSlave = bindSlave;
+}
+
+/**
+ * @returns the main TrackNode
+*/
+PNode* TrackManager::getTrackNode()
+{
+  return this->trackNode;
+}
+
+// DEBUG //
+
+/**
+ *  Imports a model of the Graph into the OpenGL-environment.
+ * @param dt The Iterator used in seconds for Painting the Graph.
+
+   This is for testing facility only. Do this if you want to see the Path inside the Level.
+   eventually this will all be packed into a gl-list.
+*/
+void TrackManager::drawGraph(float dt) const
+{
+  for (int i = 1; i <= trackElemCount; i++)
+    {
+      glBegin(GL_LINE_STRIP);
+      TrackElement* tmpElem = this->firstTrackElem->findByID(i);
+      if (tmpElem->curve)
+        for(float f = 0.0; f < 1.0; f+=dt)
+          {
+            //      printf("%f, %f, %f\n",trackManager->calcPos().x, trackManager->calcPos().y, trackManager->calcPos().z);
+            Vector tmpVector = tmpElem->curve->calcPos(f);
+            glVertex3f(tmpVector.x, tmpVector.y, tmpVector.z);
+          }
+      glEnd();
+    }
+}
+
+/**
+ *  outputs debug information about the trackManager
+ * @param level how much debug
+*/
+void TrackManager::debug(unsigned int level) const
+{
+  PRINT(0)("=========================================\n");
+  PRINT(0)("= CLASS TRACKMANAGER::debug information =\n");
+  PRINT(0)("=========================================\n");
+  //  PRINT(0)("Status is: %
+  PRINT(0)(" Consists of %d elements\n", this->trackElemCount);
+  PRINT(0)(" localTime is: %f\n", this->localTime);
+  if (level >= 2)
+    {
+      for (int i = 1; i <= trackElemCount; i++)
+        {
+          TrackElement* tmpElem = this->firstTrackElem->findByID(i);
+          tmpElem->debug();
+        }
+    }
+  PRINT(0)("-----------------------------------------\n");
+}
Index: branches/heathaze/src/util/track/track_manager.h
===================================================================
--- branches/heathaze/src/util/track/track_manager.h	(revision 9940)
+++ branches/heathaze/src/util/track/track_manager.h	(revision 9940)
@@ -0,0 +1,205 @@
+/*!
+ * @file track_manager.h
+ *  manages all tracks defined in the world and the path the player takes
+ *
+ * it is a container for all tracks and all track-nodes. it manages the movement of
+ * the track helper-parent (that drives the player). it is responsable for calculating
+ * smooth curves etc.
+*/
+
+
+#ifndef _TRACK_MANAGER_H
+#define _TRACK_MANAGER_H
+
+#include "curve.h"
+#include "base_object.h"
+
+#ifndef NULL
+#define NULL   0  //!< NULL
+#endif
+
+// Forward Definition
+class PNode;
+class Text;
+class TiXmlElement;
+template<class T> class tAnimation;
+
+// Static Definitions
+
+//! The default Curve-Type to set for the whole path (if not chosen otherwise).
+#define     TMAN_DEFAULT_CURVETYPE    CURVE_BEZIER
+//! A default value for the duration for each TrackElement
+#define     TMAN_DEFAULT_DURATION     10
+//! A default width for the width of a TrackElement
+#define     TMAN_DEFAULT_WIDTH        10
+
+//! A Graph-Element, that holds the curve-structure of a Level.
+/**
+   A TrackElement is used, to define the structure of the Track itself.
+   It is a graph and not a tree, because paths can fork and join again.
+*/
+class TrackElement : public BaseObject
+{
+ public:
+  TrackElement();
+  virtual ~TrackElement();
+
+  TrackElement* findByID(unsigned int trackID);
+  TrackElement* findByName(const std::string& trackName);
+  bool backLoopCheck() const;
+
+  TrackElement* getChild(unsigned int childNumber) const;
+
+ private:
+  bool backLoopCheckAtomic(tList<const TrackElement>* trackList) const;
+
+ public:
+  // atributes
+  bool                  isFresh;              //!< If no Points where added until now
+  bool                  isHotPoint;           //!< If the first node is a specialPoint;
+  bool                  isSavePoint;          //!< If the first node is a savePoint
+  bool                  isFork;               //!< If the first node is a Fork
+  bool                  isJoined;             //!< If the End of the Curve is joined.
+  bool                  mainJoin;             //!< If the End of the Curve is joined, and this is the one Curve the others join to.
+  int                   ID;                   //!< The ID of this TrackElement
+  float                 startingTime;         //!< The time at which this Track begins.
+  float                 duration;             //!< The time used to cross this TrackElement (curve).
+  float                 endTime;              //!< The time at which this Track ends.
+  float                 jumpTime;             //!< The Time this Track has to jump to its preceding Track (only >0 if Track isJoined==true)
+  float                 width;                //!< Th width of the Path. This tells the Player(s), how far he(they) can go to the left/right.
+  int                   nodeCount;            //!< The count of points this TrackElement has.
+  Curve*                curve;                //!< The Curve of this TrackElement
+  int                   childCount;           //!< The number of Children This TrackElement has.
+  tList<TrackElement>*  children;             //!< A TrackElement can have a Tree of following TrackElements.
+
+
+  // runtime
+  TrackElement* history;     //!< a pointer to the last TrackElement we were on. This is if you want to walk the path backwards again.
+
+  void debug() const;
+
+  // CONDITION FUNCTIONS and STUFF
+  void* subject;             //!< The Subject the Condition should act upon.
+  int (TrackElement::*condFunc)(const void*) const; //!< Pointer to the condition function
+
+  int lowest(const void* nothing) const;
+  int highest(const void* nothing) const;
+  int random(const void* nothing) const;
+
+  int leftRight(const void* node) const;
+  int nearest(const void* node) const;
+  // todo  int enemyKilled(void* entity);
+
+};
+
+//! the Condition to choose between the different ways of the game.
+enum CONDITION {LOWEST, HIGHEST, RANDOM, LEFTRIGHT, NEAREST, ENEMYKILLED};
+
+//! The TrackManager handles the flow of the Players through the game.
+/**
+
+   <b>The TrackManager works as followed:</b> \n
+     \n
+   <b>1. Initialize it, by setting up the Graph. You can do this by using the following Commands.</b>
+    \li workOn(): changes the ID that will be altered through the changes.
+    \li setCurveType(): lets you set the CurveType of the Curve we are Working on. (default is BezierCurve, set this as early as possible, for this uses resources).
+    \li setDuration(): sets the length of the current path in seconds.
+    \li addPoint(): adds a point to the Curve.
+    \li addHotPoint(): adds save/splitpoint.\n
+    \li fork(): adds some interessting non-linear movments through the level (fork will force addHotPoint if not done then).
+    \li condition(): decides under what condition a certain Path will be chosen.
+    \li join(): joins some tracks together again. Join will set the localTime to the longest time a Path has to get to this Point)
+    \li setSavePoint(): Sets a HotPoint into a savePoint. A Savepoint can be used as a rollbackpoint if a Player gets shot.
+
+    HotPoints and Joins are at the beginning of a TrackElement. \n
+    SavePoints and Forks are at the end of a TrackElement \n
+    look out: <b>SAVEPOINTS CAN NOT BE FORKS</b> (but joins), because the condition is really hard to guess if you do not give some impuls. \n
+\n
+   <b> 2. Runtime knows the following: </b>
+    \li calcPos(): returns the current position on the track
+    \li calcDir(): returns the current Direction the track is flying on.
+    \li tick(): makes a Step on the Path. increases localTime by dt.
+    \li choosePath(): a Function that decides which Path we should follow.
+
+   TrackManager can be handled as a StateMachine.
+   \n\n
+    Names:
+    \li TrackManager: handles Tracks
+    \li Track:        The Track that the ship can follow
+    \li Path:         one way through the Level, that is dependent on conditionals.
+    \li Conditional:  A decition making device, that chooses betwen different TrackElements for the Path.
+    \li TrackElement: A Part of A whole Track
+*/
+class TrackManager : public BaseObject
+{
+ public:
+  virtual ~TrackManager();
+  /** @returns a Pointer to the only object of this Class */
+  inline static TrackManager* getInstance() { if (!singletonRef) singletonRef = new TrackManager();  return singletonRef; };
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  // Methods to change the Path (initialisation)
+  void workOn(unsigned int trackID);
+  void workOnS(const std::string& trackName);
+
+  /** \see setCurveType(CurveType curveType, TrackElement* trackElem); @param curveType the type of the Curve */
+  inline void setCurveType(CurveType curveType) { this->setCurveType (curveType, this->currentTrackElem);};
+  void setCurveType(CurveType curveType, TrackElement* trackElem);
+  void setDuration(float duration);
+  void setDuration(float duration, TrackElement* trackElem);
+  void addPoint(float x, float y, float z);
+  void addPointV(Vector newPoint, TrackElement* trackElem = NULL);
+  void addHotPoint(float x, float y, float z);
+  int addHotPointV(Vector newPoint, TrackElement* trackElem = NULL);
+  void setSavePointS(const std::string& nextElementName);
+  void setSavePoint(TrackElement* trackElem = NULL);
+  void fork(unsigned int count, ...);
+  void forkS(unsigned int count, ...);
+  void forkS(const std::string& forkString);
+  void forkV(unsigned int count, int* trackIDs, char** trackNames, TrackElement* trackElem = NULL);
+  void condition(unsigned int trackID, CONDITION cond, void* subject);
+  void condition(CONDITION cond, void* subject, TrackElement* trackElem = NULL);
+  void join(unsigned int count, ...);
+  void joinS(const std::string& joinString);
+  void joinS(unsigned int cound, ...);
+  void joinV(unsigned int count, int* trackIDs);
+  void finalize();
+
+  // Methods to calculate the position on the Path (runtime)
+  inline Vector calcPos() const;
+  inline Vector calcDir() const;
+  float getWidth() const;
+  void tick(float dt);
+  void jumpTo(float time);
+  inline int choosePath(TrackElement* trackElem);
+
+  void setBindSlave(PNode* bindSlave);
+  PNode* getTrackNode();
+
+  // DEBUG //
+  void drawGraph(float dt) const;
+  void debug(unsigned int level) const;
+
+ private:
+  TrackManager();
+  void initChildren(unsigned int childCount, TrackElement* trackElem = NULL);
+
+ private:
+  static TrackManager* singletonRef;           //!< There may only be one TrackManager.
+
+  TrackElement*        firstTrackElem;         //!< The first TrackElement that exists.
+  TrackElement*        currentTrackElem;       //!< The TrackElement we are working on.
+  CurveType            curveType;              //!< The CurveType the entire TrackSystem will have.
+  float                localTime;              //!< The time that has been passed since the traveling the Track.
+  float                maxTime;                //!< The maximal time the track has.
+  int                  trackElemCount;         //!< The count of TrackElements that exist.
+
+  // external
+  PNode*               bindSlave;              //!< The node that is slave to the TrackManager. This node will be moved while update the TrackManager, and must NOT move itself.
+  PNode*               trackNode;              //!< The main TrackNode of this Track.
+  Text*                trackText;              //!< The text to display when switching between Worlds.
+  tAnimation<Text>*    textAnimation;          //!< An Animation for the Text. (for fading it out on trackName-change)
+};
+
+#endif /* _TRACK_MANAGER_H */
Index: branches/heathaze/src/util/track/track_node.cc
===================================================================
--- branches/heathaze/src/util/track/track_node.cc	(revision 9940)
+++ branches/heathaze/src/util/track/track_node.cc	(revision 9940)
@@ -0,0 +1,44 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+#include "track_node.h"
+
+#include "track_manager.h"
+
+
+ObjectListDefinition(TracNode);
+/**
+ *  standard constructor
+*/
+TrackNode::TrackNode ()
+{
+  this->registerObject(this, TracNode::_objectList);
+  this->setName("TrackNode");
+
+  PNode::getNullParent()->addChild(this);
+  this->trackManager = TrackManager::getInstance();
+  this->setParentMode(PNODE_ALL);
+}
+
+/**
+ *  standard deconstructor
+*/
+TrackNode::~TrackNode ()
+{
+
+}
Index: branches/heathaze/src/util/track/track_node.h
===================================================================
--- branches/heathaze/src/util/track/track_node.h	(revision 9940)
+++ branches/heathaze/src/util/track/track_node.h	(revision 9940)
@@ -0,0 +1,32 @@
+/*!
+ * @file track_node.h
+  *  Definition of the TrackNode are located here
+
+    the TrackNode is the node, that follows the Track (and the TrackManager)
+    through the level.
+    Under normal confitions the Plyaer(s) are
+*/
+
+
+#ifndef _TRACK_NODE_H
+#define _TRACK_NODE_H
+
+#include "p_node.h"
+
+/* FORWARD DECLARATION */
+class TrackManager;
+
+//! A node that follows the track.
+class TrackNode : public PNode
+{
+  ObjectListDeclaratrion(TracNode);
+ public:
+  TrackNode ();
+  virtual ~TrackNode ();
+
+ private:
+  TrackManager* trackManager;         //!< reference to the TrackManager
+
+};
+
+#endif /* _TRACK_NODE_H */
Index: branches/heathaze/src/world_entities/Makefile.am
===================================================================
--- branches/heathaze/src/world_entities/Makefile.am	(revision 9940)
+++ branches/heathaze/src/world_entities/Makefile.am	(revision 9940)
@@ -0,0 +1,72 @@
+MAINSRCDIR=..
+include $(MAINSRCDIR)/defs/include_paths.am
+include WorldEntities.am
+
+noinst_LIBRARIES = libORXwe.a
+
+## THESE ARE THE BASE CLASSES OF ALL WORLD_ENTITIES
+libORXwe_a_SOURCES = \
+		world_entity.cc \
+		\
+		camera.cc \
+		playable.cc \
+		player.cc \
+		\
+		npcs/npc.cc \
+		\
+		weapons/weapon_manager.cc \
+		weapons/crosshair.cc \
+		weapons/weapon.cc \
+		weapons/ammo_container.cc \
+		projectiles/projectile.cc \
+		\
+		extendable.cc \
+		power_ups/power_up.cc \
+		power_ups/param_power_up.cc \
+		power_ups/weapon_power_up.cc \
+		\
+		spawning_point.cc \
+		\
+		\
+		effects/explosion.cc \
+		effects/billboard.cc \
+		\
+		\
+		elements/glgui_energywidget.cc
+
+
+noinst_HEADERS  = \
+		world_entity.h \
+		\
+		camera.h \
+		extendable.h \
+		playable.h \
+		player.h \
+		\
+		npcs/npc.h \
+		\
+		weapons/weapon_manager.h \
+		weapons/crosshair.h \
+		weapons/weapon.h \
+		weapons/ammo_container.h \
+		projectiles/projectile.h \
+		\
+		power_ups/power_up.h \
+		power_ups/param_power_up.h \
+		power_ups/weapon_power_up.h \
+		\
+		spawning_point.h \
+		\
+		\
+		effects/explosion.h \
+		effects/billboard.h \
+		\
+		\
+		\
+		elements/glgui_energywidget.h \
+		\
+		\
+		$(WorldEntities_HEADERS_)
+
+
+EXTRA_DIST = WorldEntities.am
Index: branches/heathaze/src/world_entities/WorldEntities.am
===================================================================
--- branches/heathaze/src/world_entities/WorldEntities.am	(revision 9940)
+++ branches/heathaze/src/world_entities/WorldEntities.am	(revision 9940)
@@ -0,0 +1,203 @@
+## THE SUBCLASSES. THESE MUST BE DYNAMICALLY LINKED OR COMPILED IN DIRECTLY
+WorldEntities_SOURCES_ = \
+                world_entities/npcs/npc_test1.cc \
+                world_entities/npcs/npc_test.cc \
+                world_entities/npcs/ground_turret.cc \
+                world_entities/npcs/space_turret.cc \
+                world_entities/npcs/network_turret.cc \
+                world_entities/npcs/generic_npc.cc \
+                world_entities/npcs/door.cc \
+                world_entities/npcs/gate.cc \
+                world_entities/npcs/repair_station.cc \
+                world_entities/npcs/attractor_mine.cc \
+                \
+                world_entities/environment.cc \
+                world_entities/skysphere.cc \
+                world_entities/skybox.cc \
+                world_entities/skydome.cc \
+                world_entities/terrain.cc \
+                world_entities/satellite.cc \
+                world_entities/movie_entity.cc \
+                world_entities/recorder.cc \
+                world_entities/character_attributes.cc \
+                world_entities/test_entity.cc \
+                world_entities/planet.cc \
+                world_entities/bsp_entity.cc \
+                \
+                world_entities/weapons/test_gun.cc \
+                world_entities/weapons/laser_cannon.cc \
+                world_entities/weapons/turret.cc \
+                world_entities/weapons/aiming_turret.cc \
+                world_entities/weapons/targeting_turret.cc \
+                world_entities/weapons/cannon.cc \
+                world_entities/weapons/hyperblaster.cc \
+                world_entities/weapons/aim.cc \
+                world_entities/weapons/aiming_system.cc \
+                world_entities/weapons/fps_sniper_rifle.cc \
+                world_entities/weapons/boomerang_gun.cc \
+                \
+                world_entities/projectiles/bomb.cc \
+                world_entities/projectiles/laser.cc \
+                world_entities/projectiles/rail_projectile.cc \
+                world_entities/projectiles/test_bullet.cc \
+                world_entities/projectiles/rocket.cc \
+                world_entities/projectiles/guided_missile.cc \
+                world_entities/projectiles/boomerang_projectile.cc \
+                world_entities/projectiles/hyperblast.cc \
+                \
+                world_entities/power_ups/turret_power_up.cc \
+                world_entities/power_ups/laser_power_up.cc \
+                \
+                world_entities/space_ships/space_ship.cc \
+                world_entities/space_ships/helicopter.cc \
+                world_entities/space_ships/hover.cc \
+                world_entities/space_ships/turbine_hover.cc \
+                world_entities/space_ships/spacecraft_2d.cc \
+                world_entities/space_ships/collision_probe.cc \
+                world_entities/space_ships/cruizer.cc \
+                world_entities/creatures/md2_creature.cc \
+                world_entities/creatures/fps_player.cc \
+                world_entities/spectator.cc \
+                \
+                \
+                world_entities/environments/water.cc \
+                world_entities/environments/model_entity.cc \
+                world_entities/environments/building.cc \
+                world_entities/environments/mapped_water.cc \
+                \
+                world_entities/elements/image_entity.cc \
+                world_entities/elements/text_element.cc \
+                world_entities/elements/glgui_radar.cc \
+                \
+                world_entities/effects/lightning_bolt.cc \
+                \
+                world_entities/script_trigger.cc \
+                \
+                \
+                world_entities/particles/particle_emitter.cc \
+		world_entities/particles/dot_emitter.cc \
+		world_entities/particles/box_emitter.cc \
+		world_entities/particles/plane_emitter.cc \
+		\
+		world_entities/particles/particle_system.cc \
+		world_entities/particles/sprite_particles.cc \
+		world_entities/particles/spark_particles.cc \
+		world_entities/particles/model_particles.cc \
+		world_entities/particles/dot_particles.cc \
+		\
+		world_entities/particles/quick_animation.cc \
+		\
+		\
+		world_entities/weather_effects/atmospheric_engine.cc \
+		world_entities/weather_effects/weather_effect.cc \
+		world_entities/weather_effects/cloud_effect.cc \
+		world_entities/weather_effects/sun_effect.cc \
+		world_entities/weather_effects/fog_effect.cc \
+		world_entities/weather_effects/volfog_effect.cc \
+		world_entities/weather_effects/rain_effect.cc \
+		world_entities/weather_effects/snow_effect.cc \
+		world_entities/weather_effects/lightning_effect.cc \
+		world_entities/weather_effects/lense_flare.cc
+
+
+
+
+
+
+WorldEntities_HEADERS_ = \
+                npcs/npc_test.h \
+                npcs/npc_test1.h \
+                npcs/ground_turret.h \
+                npcs/space_turret.h \
+                npcs/network_turret.h \
+                npcs/door.cc \
+                npcs/repair_station.h \
+                npcs/attractor_mine.h \
+                \
+                environment.h \
+                skysphere.h \
+                skybox.h \
+                skydome.h \
+                terrain.h \
+                satellite.h \
+                movie_entity.h \
+                recorder.h \
+                character_attributes.h \
+                test_entity.h \
+                planet.h \
+                bsp_entity.h \
+                \
+                weapons/test_gun.h \
+                weapons/laser_cannon.cc \
+                weapons/cannon.h \
+                weapons/hyperblaster.h \
+                weapons/turret.h \
+                weapons/aiming_turret.h \
+                weapons/targeting_turret.h \
+                weapons/boomerang_gun.h \
+                weapons/aim.h \
+                weapons/aiming_system.h \
+                weapons/fps_sniper_rifle.h \
+                \
+                projectiles/bomb.h \
+                projectiles/laser.h \
+                projectiles/rail_projectile.h \
+                projectiles/test_bullet.h \
+                projectiles/rocket.h \
+                projectiles/guided_missile.h \
+                projectiles/boomerang_projectile.h \
+                projectiles/hyperblast.h \
+                \
+                power_ups/turret_power_up.h \
+                power_ups/laser_power_up.h \
+                \
+                space_ships/space_ship.h \
+                space_ships/helicopter.h \
+                space_ships/hover.h \
+                space_ships/turbine_hover.h \
+                space_ships/spacecraft_2d.h \
+                space_ships/collision_probe.h \
+                space_ships/cruizer.h \
+                creatures/md2_creature.h \
+                creatures/fps_player.h \
+                spectator.h \
+                \
+                environments/water.h \
+                environments/model_entity.h \
+                environments/building.h \
+                environments/mapped_water.h \
+                \
+                elements/image_entity.h \
+                elements/text_element.h \
+                elements/glgui_radar.h \
+                \
+                effects/lightning_bolt.h \
+                \
+                script_trigger.h \
+                \
+                \
+		particles/particle_emitter.h \
+		particles/dot_emitter.h \
+		particles/box_emitter.h \
+		particles/plane_emitter.h \
+		\
+		particles/particle_system.h \
+		particles/sprite_particles.h \
+		particles/spark_particles.h \
+		particles/model_particles.h \
+		particles/dot_particles.h \
+		\
+		particles/quick_animation.h \
+		\
+		\
+		weather_effects/atmospheric_engine.h \
+		weather_effects/weather_effect.h \
+		weather_effects/sun_effect.h \
+		weather_effects/fog_effect.h \
+		weather_effects/volfog_effect.h \
+		weather_effects/rain_effect.h \
+		weather_effects/snow_effect.h \
+		weather_effects/cloud_effect.h \
+		weather_effects/lightning_effect.h \
+		weather_effects/lense_flare.h
+
Index: branches/heathaze/src/world_entities/bsp_entity.cc
===================================================================
--- branches/heathaze/src/world_entities/bsp_entity.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/bsp_entity.cc	(revision 9940)
@@ -0,0 +1,145 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Claudio Botta
+   co-programmer: ...
+*/
+
+#include "bsp_entity.h"
+
+#include "debug.h"
+#include "loading/resource_manager.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(BspEntity, CL_BSP_ENTITY);
+CREATE_FACTORY(BspEntity);
+
+
+/**
+ * constructs and loads a BspEntity from a XML-element
+ * @param root the XML-element to load from
+ */
+BspEntity::BspEntity(const TiXmlElement* root)
+{
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * standard deconstructor
+ */
+BspEntity::~BspEntity ()
+{
+  if( this->bspManager != NULL)
+    delete this->bspManager;
+}
+
+
+
+/**
+ * initializes the BspEntity
+ * @todo change this to what you wish
+ */
+void BspEntity::init()
+{
+  this->registerObject(this, BspEntity::_objectList);
+
+  this->bspManager = NULL;
+
+  this->name_handle = registerVarId( new SynchronizeableString( &this->name, &this->name_write, "name", PERMISSION_MASTER_SERVER ) );
+
+  this->setSynchronized( true );
+}
+
+
+void BspEntity::setName(const std::string& name)
+{
+  PRINTF(0)("+++++++++++ LOADING NAME %s\n", name.c_str());
+
+  this->name = name;
+
+  // Check wether file exists....
+  if ( File(Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(name)).exists()  ) {
+
+    this->bspManager = new BspManager(this);
+
+    if(this->bspManager->load(name.c_str(), 0.1f) == -1 ) {
+      this->bspManager = NULL;
+
+    } else {
+      this->toList(OM_ENVIRON); // Success!!!
+    }
+  } else {
+    this->bspManager = NULL;
+    this->toList(OM_DEAD);
+  }
+}
+
+
+/**
+ * loads a BspEntity from a XML-element
+ * @param root the XML-element to load from
+ * @todo make the class Loadable
+ */
+void BspEntity::loadParams(const TiXmlElement* root)
+{
+  // all the clases this Entity is directly derived from must be called in this way, to load all settings.
+  // WorldEntity::loadParam(root);
+
+  LoadParam(root, "Name", this, BspEntity, setName)
+  .describe("Sets the of the BSP file.");
+
+  /*  LoadParam(root, "Scale", this, BSpEntity, setScale)
+        .describe("Sets the scale factore of the bsp level.");
+  */
+
+  /**
+   * @todo: make the class Loadable
+   */
+}
+
+
+/**
+ * advances the BspEntity about time seconds
+ * @param time the Time to step
+ */
+void BspEntity::tick(float time)
+{
+  this->bspManager->tick(time);
+}
+
+
+/**
+ * draws this worldEntity
+ */
+void BspEntity::draw () const
+{
+  this->bspManager->draw();
+}
+
+
+/**
+ *
+ *
+ */
+void BspEntity::collidesWith (WorldEntity* entity, const Vector& location)
+{}
+
+void BspEntity::varChangeHandler( std::list< int > & id )
+{
+  if ( std::find( id.begin(), id.end(), this->name_handle ) != id.end() )
+  {
+    this->setName( this->name_write );
+  }
+}
Index: branches/heathaze/src/world_entities/bsp_entity.h
===================================================================
--- branches/heathaze/src/world_entities/bsp_entity.h	(revision 9940)
+++ branches/heathaze/src/world_entities/bsp_entity.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file bsp_entity.h
+ * @brief description
+*/
+
+#ifndef _BSP_ENTITY_H
+#define _BSP_ENTITY_H
+
+#include "world_entity.h"
+#include "bsp_manager.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+
+
+//! A Class to ...
+class BspEntity : public WorldEntity
+{
+  ObjectListDeclaration(BspEntity);
+ public:
+  BspEntity(const TiXmlElement* root = NULL);
+  virtual ~BspEntity();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setName(const std::string& name);
+
+  void init();
+
+  virtual void varChangeHandler( std::list<int> & id );
+
+  virtual void draw() const;
+  virtual void tick(float time);
+  virtual void collidesWith (WorldEntity* entity, const Vector& location);
+
+  /** @returns the BspManager of this entity */
+  inline BspManager* getBspManager() { return this->bspManager; }
+
+ private:
+   BspManager* bspManager;
+
+   std::string name;                   //!< store name
+   std::string name_write;             //!< temp variable to store name
+   int name_handle;                    //!< handle for name
+
+};
+
+#endif /* _BSP_ENTITY_H */
Index: branches/heathaze/src/world_entities/camera.cc
===================================================================
--- branches/heathaze/src/world_entities/camera.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/camera.cc	(revision 9940)
@@ -0,0 +1,231 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "camera.h"
+#include "key_mapper.h"
+#include "glincl.h"
+
+ObjectListDefinition(Camera);
+
+/**
+ *  creates a Camera
+*/
+Camera::Camera()
+{
+  this->registerObject(this, Camera::_objectList);
+  this->setName("camera");
+  this->target = new CameraTarget();
+
+  this->subscribeEvent(ES_GAME, KeyMapper::PEV_VIEW0);
+  this->subscribeEvent(ES_GAME, KeyMapper::PEV_VIEW1);
+  this->subscribeEvent(ES_GAME, KeyMapper::PEV_VIEW2);
+  this->subscribeEvent(ES_GAME, KeyMapper::PEV_VIEW3);
+  this->subscribeEvent(ES_GAME, KeyMapper::PEV_VIEW4);
+  this->subscribeEvent(ES_GAME, KeyMapper::PEV_VIEW5);
+
+  this->setFovy(90);
+  this->setAspectRatio(1.2f);
+  this->setClipRegion(.1, 10000);
+
+  this->setViewMode(Camera::ViewNormal);
+
+  this->setParentMode(PNODE_ALL);
+}
+
+/**
+ *  default destructor
+*/
+Camera::~Camera()
+{}
+
+/**
+ *  focuses the Camera onto a Target
+ * @param target the new PNode the Camera should look at.
+*/
+void Camera::lookAt(PNode* target)
+{
+  this->target->setParent(target);
+}
+
+/**
+ * @returns The PNode of the Target (from there you can get position and so on
+*/
+PNode* Camera::getTargetNode() const
+{
+  return (PNode*)this->target;
+}
+
+/**
+ *  sets a new AspectRatio
+ * @param aspectRatio the new aspect ratio to set (width / height)
+*/
+void Camera::setAspectRatio(float aspectRatio)
+{
+  this->aspectRatio = aspectRatio;
+}
+
+/**
+ * Sets a new clipping region
+ * @param nearClip The near clip plane
+ * @param farClip The far clip plane
+*/
+void Camera::setClipRegion(float nearClip, float farClip)
+{
+  this->nearClip = nearClip;
+  this->farClip = farClip;
+}
+
+/**
+ *  sets the new VideoMode and initializes iteration to it.
+ * @param mode the mode to change to.
+*/
+void Camera::setViewMode(ViewMode mode)
+{
+  currentMode = mode;
+  switch (mode)
+  {
+    default:
+    case Camera::ViewNormal:
+      this->toFovy = 60.0;
+      this->setRelCoorSoft(-10, 5, 0);
+      this->target->setRelCoorSoft(0,0,0);
+      break;
+    case Camera::ViewBehind:
+      break;
+    case Camera::ViewFront:
+      this->toFovy = 120.0;
+      this->setRelCoorSoft(4, 0, 0, 5);
+      this->target->setRelCoorSoft(Vector(10,0,0), 5);
+      break;
+    case Camera::ViewLeft:
+      this->toFovy = 90;
+      this->setRelCoorSoft(0, 1, -10, .5);
+      this->target->setRelCoorSoft(0,0,0);
+      break;
+    case Camera::ViewRight:
+      this->toFovy = 90;
+      this->setRelCoorSoft(Vector(0, 1, 10));
+      this->target->setRelCoorSoft(0,0,0);
+      break;
+    case Camera::ViewTop:
+      this->toFovy= 120;
+      this->setRelCoorSoft(Vector(30, 50, 0));
+      this->target->setRelCoorSoft(35,0,0);
+  }
+}
+
+
+/**
+ *  Updates the position of the camera.
+ * @param dt: The time that elapsed.
+*/
+void Camera::tick(float dt)
+{
+  //update frustum plane
+  this->viewVector = (this->target->getAbsCoor() - this->getAbsCoor()).getNormalized();
+  this->frustumPlane = Plane(this->viewVector, this->getAbsCoor() + this->viewVector * 0.1);
+
+  this->upVector =  this->getAbsDirV();
+
+
+  float tmpFovy = (this->toFovy - this->fovy);
+  if (tmpFovy > 0.01)
+    this->fovy += tmpFovy * fabsf(dt);
+}
+
+
+/**
+ *  initialize rendering perspective according to this camera
+ *
+ * This is called immediately before the rendering cycle starts, it sets all global
+ * rendering options as well as the GL_PROJECTION matrix according to the camera.
+ */
+void Camera::apply ()
+{
+  // switching to Projection Matrix
+  glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+
+  gluPerspective(this->fovy,
+                 this->aspectRatio,
+                 this->nearClip,
+                 this->farClip);
+
+
+    // setting up the perspective
+  // speed-up feature
+  glMatrixMode (GL_MODELVIEW);
+  glLoadIdentity();
+
+
+}
+
+void Camera::project()
+{
+  Vector cameraPosition = this->getAbsCoor();
+  Vector targetPosition = this->target->getAbsCoor();
+
+       // Setting the Camera Eye, lookAt and up Vectors
+  gluLookAt(cameraPosition.x, cameraPosition.y, cameraPosition.z,
+            targetPosition.x, targetPosition.y, targetPosition.z,
+            this->upVector.x, this->upVector.y, this->upVector.z);
+}
+
+
+/**
+ *  processes an event
+ * @param event: the event to process
+*/
+void Camera::process(const Event &event)
+{
+  if( event.type == KeyMapper::PEV_VIEW0)
+  {
+    this->setViewMode(Camera::ViewNormal);
+  }
+  else if( event.type == KeyMapper::PEV_VIEW1)
+  {
+    this->setViewMode(Camera::ViewBehind);
+  }
+  else if( event.type == KeyMapper::PEV_VIEW2)
+  {
+    this->setViewMode(Camera::ViewFront);
+  }
+  else if( event.type == KeyMapper::PEV_VIEW3)
+  {
+    this->setViewMode(Camera::ViewLeft);
+  }
+  else if( event.type == KeyMapper::PEV_VIEW4)
+  {
+    this->setViewMode(Camera::ViewRight);
+  }
+  else if( event.type == KeyMapper::PEV_VIEW5)
+  {
+    this->setViewMode(Camera::ViewTop);
+  }
+}
+
+
+///////////////////
+// CAMERA-TARGET //
+///////////////////
+
+ObjectListDefinition(CameraTarget);
+CameraTarget::CameraTarget()
+{
+  this->registerObject(this, CameraTarget::_objectList);
+  //  this->setParentMode(PNODE_MOVEMENT);
+}
+
Index: branches/heathaze/src/world_entities/camera.h
===================================================================
--- branches/heathaze/src/world_entities/camera.h	(revision 9940)
+++ branches/heathaze/src/world_entities/camera.h	(revision 9940)
@@ -0,0 +1,96 @@
+/*!
+ * @file camera.h
+ * Viewpoint controlling class definitions
+*/
+
+#ifndef _CAMERA_H
+#define _CAMERA_H
+
+#include "p_node.h"
+#include "event_listener.h"
+#include "plane.h"
+
+class World;
+class CameraTarget;
+class Event;
+
+
+//! Camera
+/**
+ * This class controls the viewpoint from which the World is rendered.
+*/
+class Camera : public PNode, public EventListener
+{
+  ObjectListDeclaration(Camera);
+public:
+  //! an enumerator for different types of view
+  typedef enum ViewMode
+  {
+    ViewNormal,
+    ViewBehind,
+    ViewFront,
+    ViewLeft,
+    ViewRight,
+    ViewTop
+  };
+
+  Camera();
+  virtual ~Camera();
+
+  void lookAt(PNode* target);
+  CameraTarget* getTarget() const { return this->target; };
+  PNode* getTargetNode() const;
+
+  void setAspectRatio(float aspectRatio);
+  void setClipRegion(float nearClip, float farClip);
+
+  /** @param fovy new field of view factor (in degrees) */
+  void setFovy(float fovy) { this->fovy = fovy; };
+  /** @param fovy new field of view factor (in degrees) to iterate to */
+  void setToFovy(float toFovy) { this->toFovy = toFovy; };
+
+  void setViewMode(Camera::ViewMode mode);
+  inline const Vector& getViewVector() const { return this->viewVector; }
+  inline const Vector& getUpVector() const { return this->upVector; }
+  inline const Plane& getViewFrustum() const { return this->frustumPlane; }
+
+  inline float distance(const Vector& distance) const { return this->frustumPlane.distancePoint(distance); }
+  inline float distance(const PNode* node) const { return distance(node->getAbsCoor()); }
+
+  void tick(float dt);
+  void apply ();
+  void project();
+
+  void process(const Event &event);
+
+private:
+  CameraTarget*     target;          //!< The Target of the Camera (where this Camera Looks at)
+
+  float             fovy;            //!< The field of view Angle (in degrees).
+  float             aspectRatio;     //!< The aspect ratio (width / height).
+  float             nearClip;        //!< The near clipping plane.
+  float             farClip;         //!< The far clipping plane.
+
+  float             toFovy;          //!< The fovy-mode to iterate to.
+  Camera::ViewMode  currentMode;     //!< The ViewMode the camera is in
+
+  Vector            delay;
+  Plane             frustumPlane;    //!< plane that marks the view frustum
+  Vector            viewVector;      //!< the direction of the camera view
+  Vector            upVector;        //!< direction of the up vector
+};
+
+//! A CameraTarget is where the Camera is looking at.
+class CameraTarget : public PNode
+{
+  friend class Camera;             //! The CameraTarget is a friend of Camera. noone else needs a CameraTarget, so noone else can create it.
+  ObjectListDeclaration(CameraTarget);
+
+private:
+  CameraTarget();
+
+public:
+};
+
+
+#endif /* _CAMERA_H */
Index: branches/heathaze/src/world_entities/character_attributes.cc
===================================================================
--- branches/heathaze/src/world_entities/character_attributes.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/character_attributes.cc	(revision 9940)
@@ -0,0 +1,378 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+#include "character_attributes.h"
+
+
+ObjectListDefinition(CharacterAttributes);
+
+
+/**
+ *  standard constructor
+   @todo this constructor is not jet implemented - do it
+*/
+CharacterAttributes::CharacterAttributes ()
+{
+  this->registerObject(this, CharacterAttributes::_objectList);
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+CharacterAttributes::~CharacterAttributes ()
+{
+}
+
+
+/*=====================health=====================*/
+
+/**
+ *  sets the health of the character
+ * @param helath
+ */
+void CharacterAttributes::setHealth(int health)
+{
+  this->health = health;
+}
+
+/**
+ *  adds health to the charater
+ * @param health
+ * @returns health that couldnt be added due to healt limit, 0 if everything worked as normal
+ */
+int CharacterAttributes::addHealth(int health)
+{
+  this->health += health;
+  int rest = this->healthMax - this->health;
+  if( rest < 0)
+    {
+      this->health = this->healthMax;
+      return 0;
+    }
+  return rest;
+}
+
+/**
+ *  remove health due to damager for example
+ * @param amount of health
+ * @returns false if health is zero -> dead
+ */
+bool CharacterAttributes::substractHealth(int health)
+{
+  this->health -= health;
+  if( this->health < 0)
+    {
+      this->health = 0;
+      return false;
+    }
+  return true;
+}
+
+/**
+ *  gets the current amount of health
+ * @returns health
+ */
+int CharacterAttributes::getHealth()
+{
+  return this->health;
+}
+
+
+/**
+ *  sets maximum health
+ * @param health
+
+   if healthMax = 0 -> unlimited
+ */
+void CharacterAttributes::setHealthMax(int healthMax)
+{
+  this->healthMax = healthMax;
+}
+
+/**
+ *  gets health maximium
+ * @returns the health maximum
+ */
+int CharacterAttributes::getHealthMax()
+{
+  return this->healthMax;
+}
+
+
+/*======================armor/ shields===================== */
+/**
+ *  sets the shild strength
+ * @param strength
+ */
+void CharacterAttributes::setShieldStrength(int shieldStrength)
+{
+  this->shieldStrength = shieldStrength;
+}
+
+/**
+ *  adds shield strength
+ * @param strength
+
+   there is currently no limit to shieldstrength
+ */
+void CharacterAttributes::addShieldStrength(int shiledStrength)
+{
+  this->shieldStrength += shieldStrength;
+}
+
+/**
+ *  substracts shield strength
+ * @param strength
+ * @returns amount of shield strength below zero after substraction. Magic: Troumble. if everything works allright, it returns 0
+ */
+int CharacterAttributes::substractShieldStrength(int shieldStrength)
+{
+  int rest = this->shieldStrength -= shieldStrength;
+  if( rest < 0)
+    {
+      this->shieldStrength = 0;
+      return -rest;
+    }
+  return 0;
+}
+
+/**
+ *  gets shield strength
+ * @returns the shield strength
+ */
+int CharacterAttributes::getShieldStrength()
+{
+  return this->shieldStrength;
+}
+
+
+/*=====================damage=====================*/
+/**
+ *  sets the amount of base damage dealt to all aircrafts
+ * @param damage
+
+   There can be a difference between arms that hit a ground/air craft. Eg.
+   a tank will react differently to explosives than something in the air
+   (think about physics)
+ */
+void CharacterAttributes::setDamageToAirCraft(int damage)
+{
+  this->damageToAirCraft = damage;
+}
+
+/**
+ *  gets the amount of base damage
+ * @returns base damage to aircrafts
+
+   There can be a difference between arms that hit a ground/air craft. Eg.
+   a tank will react differently to explosives than something in the air
+   (think about physics)
+ */
+int CharacterAttributes::getDamageToAirCraft()
+{
+  return this->damageToAirCraft;
+}
+
+
+/**
+ *  sets the amount of base damage dealt to all groundcrafts
+ * @param damage
+
+   There can be a difference between arms that hit a ground/air craft. Eg.
+   a tank will react differently to explosives than something in the air
+   (think about physics)
+ */
+void CharacterAttributes::setDamageToGroundCraft(int damage)
+{
+  this->damageToGroundCraft = damage;
+}
+
+/**
+ * gets the amount of base damage
+ * @returns base damage to groundcrafts
+
+   There can be a difference between arms that hit a ground/air craft. Eg.
+   a tank will react differently to explosives than something in the air
+   (think about physics)
+ */
+int CharacterAttributes::getDamageToGroundCraft()
+{
+  return this->damageToGroundCraft;
+}
+
+
+/**
+ *  sets the damage modifier to the damage that is dealed via laser weapons
+ * @param modifier [0..1]
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+void CharacterAttributes::setDamageLaserModifier(float modifier)
+{
+  this->damageLaserModifier = modifier;
+}
+
+/**
+ *  gets the damage modifier to the damage that is dealed via laser weapons
+ * @returns damage modifier
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+float CharacterAttributes::getDamageLaserModifier()
+{
+  return this->damageLaserModifier;
+}
+
+
+/**
+ *  sets the damage modifier to the damage that is dealed via plasma weapons
+ * @param damage modifier
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+void CharacterAttributes::setDamagePlasmaModifier(float modifier)
+{
+  this->damagePlasmaModifier = modifier;
+}
+
+/**
+ *  gets the damage modifier to the damage that is dealed plasma weapons
+ * @returns damage modifier
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+float CharacterAttributes::getDamagePlasmaModifier()
+{
+  return this->damagePlasmaModifier;
+}
+
+
+/**
+ *  sets the damage modifier to the damage that is dealed via explosives
+ * @param damage modifier
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+void CharacterAttributes::setDamageExplosiveModifier(float modifier)
+{
+  this->damageExplosiveModifier = modifier;
+}
+
+/**
+ *  sets the damage modifier to the damage that is dealed via explosives
+ * @returns damage modifier
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+float CharacterAttributes::getDamageExplosiveModifier()
+{
+  return this->damageExplosiveModifier;
+}
+
+
+/*=====================energy=====================*/
+/**
+ *  sets the amount of energy
+ * @param energy
+ */
+void CharacterAttributes::setEnergy(int energy)
+{
+  this->energy = energy;
+}
+
+/**
+ *  adds energy to the system
+ * @param amount of energy
+ * @returns amount of energy that is too much due to energy limit
+ */
+int CharacterAttributes::addEnergy(int addEnergy)
+{
+  this->energy += addEnergy;
+  int rest = this->energyMax - this->energy;
+  if(rest < 0)
+    {
+      this->energy = 0;
+      return rest;
+    }
+  return 0;
+}
+
+/**
+ *  substracts energy from a system
+ * @param amount of energy
+ * @returns false if there is no energy anymore
+ */
+bool CharacterAttributes::substractEnergy(int subEnergy)
+{
+  this->energy -= subEnergy;
+  if(this->energy < 0)
+    {
+      this->energy = 0;
+      return false;
+    }
+  return true;
+}
+
+/**
+ *  gets the amount of energy
+ * @returns energy
+ */
+int CharacterAttributes::getEnergy()
+{
+  return this->energy;
+}
+
+
+/**
+ *  sets the energy consumption
+ * @param amount of energy
+*/
+void CharacterAttributes::setEnergyConsumption(int energy)
+{
+  this->energyConsumption = energy;
+}
+
+/**
+ *  gets the energy consumption
+ * @returns amount of energy
+*/
+int CharacterAttributes::getEnergyConsumption()
+{
+  return this->energyConsumption;
+}
+
+
+/**
+ *  sets the maximum energy level
+ * @param amount of energy
+*/
+void CharacterAttributes::setEnergyMax(int energy)
+{
+  this->energyMax = energy;
+}
+
+/**
+ *  gets the max energy level
+ * @returns amount of energy
+*/
+int CharacterAttributes::getEnergyMax()
+{
+  return this->energyMax;
+}
Index: branches/heathaze/src/world_entities/character_attributes.h
===================================================================
--- branches/heathaze/src/world_entities/character_attributes.h	(revision 9940)
+++ branches/heathaze/src/world_entities/character_attributes.h	(revision 9940)
@@ -0,0 +1,92 @@
+/*!
+ * @file character_attributes.h
+ * Definition of the attributes of a character (healt, armor,.. ) whatever is important to the character
+ */
+
+#ifndef _CHARACTER_ATTRIBUTES_H
+#define _CHARACTER_ATTRIBUTES_H
+
+#include "base_object.h"
+
+
+//! A class including all important information about a character
+/**
+  its not yet clear, what the character-attributes will be.
+*/
+class CharacterAttributes : public BaseObject {
+    ObjectListDeclaration(CharacterAttributes);
+
+ public:
+  CharacterAttributes();
+  virtual ~CharacterAttributes();
+
+  /* health */
+  void setHealth(int health);
+  int addHealth(int health);
+  bool substractHealth(int health);
+  int getHealth();
+
+  void setHealthMax(int healthMax);
+  int getHealthMax();
+
+
+  /* armor/ shields */
+  void setShieldStrength(int shieldStrength);
+  void addShieldStrength(int shiledStrength);
+  int substractShieldStrength(int shieldStrength);
+  int getShieldStrength();
+
+
+  /* damage */
+  void setDamageToAirCraft(int damage);
+  int getDamageToAirCraft();
+
+  void setDamageToGroundCraft(int damage);
+  int getDamageToGroundCraft();
+
+  void setDamageLaserModifier(float modifier);
+  float getDamageLaserModifier();
+
+  void setDamagePlasmaModifier(float modifier);
+  float getDamagePlasmaModifier();
+
+  void setDamageExplosiveModifier(float modifier);
+  float getDamageExplosiveModifier();
+
+
+  /* energy */
+  void setEnergy(int energy);
+  int addEnergy(int addEnergy);
+  bool substractEnergy(int subEnergy);
+  int getEnergy();
+
+  void setEnergyConsumption(int energy);
+  int getEnergyConsumption();
+
+  void setEnergyMax(int energy);
+  int getEnergyMax();
+
+
+ private:
+  /* healt */
+  int health;                        //<! the healt of a projectile
+  int healthMax;                     //<! the max healt of a projectile, =0 if no limit
+
+  /* armor/ shields */
+  int shieldStrength;                //<! the shiled strength of a character, =0 if no shields
+
+  /* damage */
+  int damageToAirCraft;              //<! damage dealt to a air craft in case of a hit
+  int damageToGroundCraft;           //<! damage dealt to a ground craft in case of a hit
+
+  float damageLaserModifier;         //<! [0..1] the damage from laser is multiplied with this modifier. there can be things in the world, that are immune to certain damage
+  float damagePlasmaModifier;        //<! [0..1] the damage from plasma is multiplied with this modifier. there can be things in the world, that are immune to certain damage
+  float damageExplosiveModifier;      //<! [0..1] the damage from exposives (rockets, tnt,...) is multiplied with this modifier. there can be things in the world, that are immune to certain damage
+
+  /* energy */
+  int energyConsumption;             //<! if the character defines an action, it will consume energy
+  int energy;                        //<! the current amount of energy saved in this part
+  int energyMax;                     //<! the maximal energy a character can handle
+};
+
+#endif /* _CHARACTER_ATTRIBUTES_H */
Index: branches/heathaze/src/world_entities/creatures/fps_player.cc
===================================================================
--- branches/heathaze/src/world_entities/creatures/fps_player.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/creatures/fps_player.cc	(revision 9940)
@@ -0,0 +1,499 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+
+*/
+
+#include "fps_player.h"
+
+#include "interactive_model.h"
+#include "state.h"
+
+#include "src/lib/util/loading/factory.h"
+
+#include "md2/md2Model.h"
+
+#include "weapons/weapon_manager.h"
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+#include "weapons/fps_sniper_rifle.h"
+#include "weapons/aiming_system.h"
+
+#include "aabb.h"
+#include "bsp_entity.h"
+
+#include "key_mapper.h"
+
+#include "debug.h"
+
+#include "shared_network_data.h"
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(FPSPlayer, CL_FPS_PLAYER);
+CREATE_FACTORY(FPSPlayer);
+
+#include "script_class.h"
+CREATE_SCRIPTABLE_CLASS(FPSPlayer,
+			addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
+			    ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
+			    ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
+			    ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
+                       );
+
+
+/**
+ *  destructs the FPSPlayer, deletes alocated memory
+ */
+FPSPlayer::~FPSPlayer ()
+{
+  this->setPlayer(NULL);
+
+  if( this->aimingSystem)
+    delete this->aimingSystem;
+}
+
+
+/**
+ *  creates a new FPSPlayer from Xml Data
+ * @param root the xml element containing FPSPlayer data
+ *
+ */
+FPSPlayer::FPSPlayer(const TiXmlElement* root)
+{
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+
+}
+
+
+/**
+ * initializes a FPSPlayer
+ */
+void FPSPlayer::init()
+{
+  this->registerObject(this, FPSPlayer::_objectList);
+
+  this->bLeft = false;
+  this->bRight = false;
+  this->bForward = false;
+  this->bBackward = false;
+  this->bJump = false;
+  this->bPosBut = false;
+  this->bFire = false;
+
+  this->xMouse = 0.0f;
+  this->yMouse = 0.0f;
+
+  this->setHealthMax(100);
+  this->setHealth(80);
+
+  this->fallVelocity = 0.0f;
+  this->jumpForce = 0.0f;
+
+  this->cameraNode.setParent(this);
+
+  this->attitude = this->getAbsDir().getAttitude();
+  this->heading = this->getAbsDir().getHeading();
+
+  //add events to the eventlist
+  registerEvent(KeyMapper::PEV_FORWARD);
+  registerEvent(KeyMapper::PEV_BACKWARD);
+  registerEvent(KeyMapper::PEV_LEFT);
+  registerEvent(KeyMapper::PEV_RIGHT);
+  registerEvent(KeyMapper::PEV_FIRE1);
+  registerEvent(KeyMapper::PEV_JUMP);
+  registerEvent(EV_MOUSE_MOTION);
+
+
+
+  // weapon manager for the fps
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+  Weapon* wpRight = new FPSSniperRifle(0);
+  wpRight->setName("testGun Right");
+/*  Weapon* wpLeft = new TestGun(1);*/
+//   Weapon* wpLeft = new Turret();
+//   wpLeft->setName("testGun Left");
+
+//   this->addWeapon(wpLeft, 1, 0);
+  if( State::isOnline())
+    this->addWeapon(wpRight,1, 0);
+  this->getWeaponManager().changeWeaponConfig(1);
+
+  this->getWeaponManager().setSlotCount(2);
+  this->getWeaponManager().setSlotDirection(0, Quaternion(M_PI_4*-0.55f, Vector(0,0,1)));
+  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+  this->getWeaponManager().setSlotDirection(1, Quaternion(M_PI_4*.5, Vector(1,0,0)));
+  this->getWeaponManager().setSlotPosition(0, Vector(1.5, -0.7, 1.1));
+  this->getWeaponManager().setSlotPosition(1, Vector(5.0, 0.0, 0.0));
+
+//   this->getWeaponManager().getFixedTarget()->setRelDir(Quaternion(M_PI_4*-0.6f, Vector(0,0,1)));
+
+
+  this->getWeaponManager().setParentNode(&this->cameraNode);
+  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
+
+  this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
+  this->getWeaponManager().getFixedTarget()->setRelCoor(1000,0,0);
+
+  this->aimingSystem = new AimingSystem(this);
+  //this->addChild(this->aimingSystem);
+  wpRight->addChild(this->aimingSystem);
+//   this->getWeaponManager().sl
+
+
+  // network registration
+  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bJump, &bJump, "bJump", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableFloat( &heading, &heading, "heading", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableFloat( &attitude, &attitude, "attitude", PERMISSION_OWNER ) );
+
+    //subscribe to collision reaction
+  this->subscribeReaction(CREngine::CR_PHYSICS_FULL_WALK, BspEntity::staticClassID());
+
+  this->initWeapon = false;
+  this->damageTicker = 0.0f;
+
+  if( State::isOnline())
+    toList( OM_PLAYERS );
+}
+
+
+/**
+ * loads the Settings of a FPSPlayer from an XML-element.
+ * @param root the XML-element to load the Spaceship's properties from
+ */
+void FPSPlayer::loadParams(const TiXmlElement* root)
+{
+  Playable::loadParams(root);
+}
+
+void FPSPlayer::setPlayDirection(const Quaternion& quat, float speed)
+{
+  this->attitude = this->getAbsDir().getAttitude();
+  this->heading = this->getAbsDir().getHeading();
+}
+
+
+void FPSPlayer::reset()
+{
+  this->bLeft = false;
+  this->bRight = false;
+  this->bForward = false;
+  this->bBackward = false;
+  this->xMouse = 0.0f;
+  this->yMouse = 0.0f;
+
+  this->setHealth(80);
+}
+
+
+void FPSPlayer::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( true );
+
+  State::getCameraNode()->setParentSoft(&this->cameraNode);
+  State::getCameraTargetNode()->setParentSoft(&this->cameraNode);
+
+  this->getWeaponManager().getFixedTarget()->setParent(State::getCameraTargetNode());
+  this->getWeaponManager().getFixedTarget()->setRelCoor(0,0,0);
+
+  if ( !State::isOnline() )
+  {
+    this->respawn();
+  }
+}
+
+void FPSPlayer::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+  this->detachCamera();
+}
+
+
+
+/**
+ *  the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+ */
+void FPSPlayer::tick (float time)
+{
+
+  if ( !this->initWeapon )
+  {
+    this->initWeapon = true;
+
+    this->cameraNode.setParentMode(PNODE_ROTATE_AND_MOVE);
+
+    this->getWeaponManager().getParentNode()->setParentMode(PNODE_ROTATE_AND_MOVE);
+    this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
+    this->getWeaponManager().getFixedTarget()->setParentMode(PNODE_ROTATE_AND_MOVE);
+
+
+    this->aimingSystem->toList(OM_GROUP_01);
+    this->aimingSystem->setParent(&this->cameraNode);
+//     this->aimingSystem->setParentMode(PNODE_ROTATE_AND_MOVE);
+    this->aimingSystem->setRelDir(Quaternion(M_PI_4*-0.58f, Vector(0,0,1)));
+    this->aimingSystem->setRelCoor(0, -1, -1);
+
+
+    AABB* box = this->getModelAABB();
+    if( box != NULL)
+    {
+      float f = 1.0;
+      this->cameraNode.setRelCoor(0, box->halfLength[1] * f, 0);
+//       this->cameraNode.setRelCoor(10, box->halfLength[1] * f, 0);
+
+      float v = 0.1f;
+      this->getWeaponManager().setSlotPosition(0, Vector(-8.0, box->halfLength[1] * v, 1.1));
+      this->getWeaponManager().setSlotPosition(1, Vector(5.0, box->halfLength[1] * v, 0.0));
+    }
+  }
+
+
+  this->getWeaponManager().tick(time);
+  if( this->bFire)
+  {
+    this->getWeaponManager().fire();
+
+//     WorldEntity* target = this->aimingSystem->getNearestTarget();
+//     if( target != NULL)
+//     {
+//       PRINTF(0)("hit hit hit, got: %s\n", target->getClassCName());
+//     }
+//     else
+//     {
+//       PRINTF(0)("nothing hit\n");
+//     }
+  }
+
+
+  //dealing damage
+
+  if ( State::isOnline() && (SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/))
+  {
+    this->damageTicker -= time;
+
+    if ( this->damageTicker <= 0.0f && this->beFire() )
+    {
+      this->damageTicker = 0.25;
+
+      WorldEntity * victim = aimingSystem->getNearestTarget();
+
+      if ( victim )
+      {
+        PRINTF(0)("FIRE: hit %s\n", victim->getClassCName());
+        victim->hit( 20, this );
+      }
+      else
+      {
+        PRINTF(0)("FIRE: nothing hit\n");
+      }
+    }
+  }
+
+
+  if( ( xMouse != 0 || yMouse != 0 ) && (this->getOwner() == SharedNetworkData::getInstance()->getHostID() || !State::isOnline() ) )
+  {
+    xMouse *= time ;
+    yMouse *= time ;
+
+    heading -= xMouse;
+    attitude-= yMouse;
+
+
+    if ( attitude > 1.95 )
+      attitude = 1.95;
+    else if ( attitude < -1.07 )
+      attitude = -1.07;
+
+    xMouse = yMouse = 0;
+  }
+
+  this->setAbsDir(Quaternion(heading, Vector(0,1,0)));
+  this->cameraNode.setRelDir(Quaternion( attitude, Vector( 0, 0, 1 ) ));
+
+  Vector velocity;
+
+  if ( this->bForward )
+  {
+    velocity += this->getAbsDirX();
+  }
+
+  if ( this->bBackward )
+  {
+    velocity -= this->getAbsDirX();
+  }
+
+  if ( this->bRight )
+  {
+    velocity += this->getAbsDirZ();
+  }
+
+  if ( this->bLeft )
+  {
+    velocity -= this->getAbsDirZ();
+  }
+
+
+  velocity *= 100;
+
+  if( this->bJump && likely(this->getModel(0) != NULL))
+  {
+    if( this->jumpForce < 1.0f)
+    {
+      this->jumpForce = 300.0f;
+
+      if( ((InteractiveModel*)this->getModel(0))->getAnimation() != JUMP)
+        ((InteractiveModel*)this->getModel(0))->setAnimation(JUMP);
+    }
+  }
+  else if(velocity.len() != 0.0f)
+  {
+    if( ((InteractiveModel*)this->getModel(0))->getAnimation() != RUN)
+      ((InteractiveModel*)this->getModel(0))->setAnimation(RUN);
+  }
+  else
+  {
+    if( ((InteractiveModel*)this->getModel(0))->getAnimation() != STAND)
+      ((InteractiveModel*)this->getModel(0))->setAnimation(STAND);
+  }
+
+
+  velocity.y += this->jumpForce;
+  if( this->jumpForce > 1.0f)
+    this->jumpForce *= 0.9f;
+
+
+  // physical falling of the player
+  if( !this->isOnGround())
+  {
+    this->fallVelocity += 300.0f * time;
+    velocity -= Vector(0.0, 1.0, 0.0) * this->fallVelocity;
+
+//     PRINTF(0)("vel %f\n", this->fallVelocity);
+  }
+  else
+  {
+    this->fallVelocity = 0.0f;
+  }
+
+  this->shiftCoor( velocity*time );
+
+
+
+
+
+
+
+  if( likely(this->getModel(0) != NULL) && this->getModel(0)->isA(CL_INTERACTIVE_MODEL))
+  {
+    ((InteractiveModel*)this->getModel(0))->tick(time);
+
+    // handle animations differently
+
+
+
+
+
+//     else if( this->bFire && likely(this->getModel(0) != NULL))
+//     {
+//       if( ((InteractiveModel*)this->getModel(0))->getAnim() != ATTACK)
+//         ((InteractiveModel*)this->getModel(0))->setAnimation(ATTACK);
+//     }
+//     else if( fabs(move.len()) > 0.0f && likely(this->getModel(0) != NULL))
+//     {
+//       if( ((InteractiveModel*)this->getModel(0))->getAnim() != RUN)
+//         ((InteractiveModel*)this->getModel(0))->setAnimation(RUN);
+//     }
+//     else if (likely(this->getModel(0) != NULL))
+//     {
+//       if( ((InteractiveModel*)this->getModel(0))->getAnimation() != STAND)
+//         ((InteractiveModel*)this->getModel(0))->setAnimation(STAND);
+//     }
+  }
+
+  this->setOnGround(false);
+  this->aimingSystem->flushList();
+}
+
+
+
+/**
+ *  draws the MD2Creature after transforming it.
+ */
+void FPSPlayer::draw () const
+{
+  // only draw if this entity is not the player since the player nevers sees himself
+  if( this->getCurrentPlayer() == NULL)
+    WorldEntity::draw();
+}
+
+
+
+/**
+ * process
+ */
+void FPSPlayer::process(const Event &event)
+{
+  Playable::process(event);
+
+  if( event.type == KeyMapper::PEV_LEFT)
+    this->bLeft = event.bPressed;
+  else if( event.type == KeyMapper::PEV_RIGHT)
+    this->bRight = event.bPressed;
+  else if( event.type == KeyMapper::PEV_FORWARD)
+    this->bForward = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == KeyMapper::PEV_BACKWARD)
+    this->bBackward = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+    this->xMouse += event.xRel;
+    this->yMouse += event.yRel;
+  }
+  else if( event.type == KeyMapper::PEV_JUMP)
+  {
+    this->bJump = event.bPressed;
+  }
+  else if( event.type == KeyMapper::PEV_FIRE1)
+  {
+    this->bFire = event.bPressed;
+  }
+}
+
+
+void FPSPlayer::respawn( )
+{
+  if( State::isOnline())
+    toList( OM_PLAYERS );
+
+  this->damageTicker = 0.0f;
+
+  Playable::respawn();
+}
+
+
+void FPSPlayer::destroy( WorldEntity* killer )
+{
+  Playable::destroy( killer );
+
+  toList( OM_DEAD );
+}
+
Index: branches/heathaze/src/world_entities/creatures/fps_player.h
===================================================================
--- branches/heathaze/src/world_entities/creatures/fps_player.h	(revision 9940)
+++ branches/heathaze/src/world_entities/creatures/fps_player.h	(revision 9940)
@@ -0,0 +1,72 @@
+/*!
+ * @file fps_player.h
+ * Implements a playable for fps games
+ */
+
+#ifndef _FPS_PLAYER_H
+#define _FPS_PLAYER_H
+
+
+#include "playable.h"
+
+
+class AimingSystem;
+
+
+class FPSPlayer : public Playable
+{
+  ObjectListDeclaration(FPSPlayer);
+
+  public:
+    FPSPlayer(const TiXmlElement* root = NULL);
+    virtual ~FPSPlayer();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void setPlayDirection(const Quaternion& rot, float speed = 0.0f);
+
+    virtual void enter();
+    virtual void leave();
+
+    virtual void reset();
+
+    virtual void destroy(WorldEntity* killer);
+    virtual void respawn();
+
+    virtual void tick(float time);
+    virtual void draw() const;
+
+
+    virtual void process(const Event &event);
+
+  private:
+    void init();
+
+    bool                  bLeft;
+    bool                  bRight;
+    bool                  bForward;
+    bool                  bBackward;
+    bool                  bJump;              //!< jumping
+    bool                  bPosBut;             //!< position button
+    bool                  bFire;              //!< fire button
+
+    float                 xMouse;             //!< mouse moved in x-Direction
+    float                 yMouse;             //!< mouse moved in y-Direction
+
+
+    float                 heading;
+    float                 attitude;
+
+    PNode                 cameraNode;
+
+    float                 fallVelocity;        //!< velocity for falling down
+    float                 jumpForce;           //!< the jump force
+
+    bool                  initWeapon;
+
+    AimingSystem*         aimingSystem;        //!< aiming system of the player
+
+    float                 damageTicker;        //!< ticker for dealing damage
+};
+
+#endif
Index: branches/heathaze/src/world_entities/creatures/md2_creature.cc
===================================================================
--- branches/heathaze/src/world_entities/creatures/md2_creature.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/creatures/md2_creature.cc	(revision 9940)
@@ -0,0 +1,376 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "executor/executor.h"
+#include "md2_creature.h"
+
+#include "objModel.h"
+#include "md2/md2Model.h"
+#include "state.h"
+
+#include "weapons/weapon_manager.h"
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+
+#include "util/loading/factory.h"
+#include "key_mapper.h"
+
+#include "graphics_engine.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(MD2Creature, CL_MD2_CREATURE);
+CREATE_FACTORY(MD2Creature);
+
+/**
+ *  destructs the MD2Creature, deletes alocated memory
+ */
+MD2Creature::~MD2Creature ()
+{
+  this->setPlayer(NULL);
+}
+
+/**
+ * loads a MD2Creatures information from a specified file.
+ * @param fileName the name of the File to load the MD2Creature from (absolute path)
+ */
+MD2Creature::MD2Creature(const std::string& fileName)
+{
+  this->init();
+  TiXmlDocument doc(fileName);
+
+  if(!doc.LoadFile())
+  {
+    PRINTF(2)("Loading file %s failed for md2 creature.\n", fileName.c_str());
+    return;
+  }
+
+  this->loadParams(doc.RootElement());
+}
+
+/**
+ *  creates a new MD2Creature from Xml Data
+ * @param root the xml element containing MD2Creature data
+
+   @todo add more parameters to load
+*/
+MD2Creature::MD2Creature(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * initializes a MD2Creature
+ */
+void MD2Creature::init()
+{
+  PRINTF(4)("MD2CREATURE INIT\n");
+  //  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->registerObject(this, MD2Creature::_objectList);
+
+  this->toList(OM_GROUP_01);
+
+  //weapons:
+  Weapon* wpRight = new TestGun(0);
+  wpRight->setName("testGun Right");
+  Weapon* wpLeft = new TestGun(1);
+  wpLeft->setName("testGun Left");
+  Weapon* cannon = dynamic_cast<Weapon*>(Factory::fabricate("Cannon"));
+
+  cannon->setName("BFG");
+
+  this->addWeapon(wpLeft, 1, 0);
+  this->addWeapon(wpRight,1 ,1);
+  this->getWeaponManager().changeWeaponConfig(0);
+
+
+  // pnode camera issue
+  this->cameraConnNode.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->cameraConnNode.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
+  this->cameraConnNode.setName("CameraConnectorNode");
+  this->addChild(&this->cameraConnNode);
+  this->cameraConnNode.addChild(State::getCameraTargetNode());
+  this->cameraConnNode.addChild(State::getCameraNode());
+  State::getCameraTargetNode()->setRelCoor(10,0,0);
+
+
+
+  // control initialisation
+  this->mouseDirX *= Quaternion( M_PI * 0.75f, Vector(0,1,0));
+
+  bUp = bDown = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = bStrafeL = bStrafeR = bJump = false;
+  bFire = false;
+  xMouse = yMouse = 0;
+  mouseSensitivity = 0.003;
+  airViscosity = 0.0;
+  cycle = 0.0;
+
+  travelSpeed =300.0;
+  this->velocity = Vector(0.0,0.0,0.0);
+
+
+  //add events to the eventlist
+  //add events to the eventlist
+  registerEvent(KeyMapper::PEV_FORWARD);
+  registerEvent(KeyMapper::PEV_BACKWARD);
+  registerEvent(KeyMapper::PEV_LEFT);
+  registerEvent(KeyMapper::PEV_RIGHT);
+  registerEvent(KeyMapper::PEV_UP);
+  registerEvent(KeyMapper::PEV_DOWN);
+  registerEvent(KeyMapper::PEV_FIRE1);
+  registerEvent(KeyMapper::PEV_NEXT_WEAPON);
+  registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
+  registerEvent(EV_MOUSE_MOTION);
+  this->registerEvent(SDLK_SPACE);
+
+
+
+  this->getWeaponManager().setSlotCount(7);
+
+  this->getWeaponManager().setSlotPosition(0, Vector(-0.5, .2, -1.9));
+  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(1, Vector(-0.5, .2, 1.9));
+  this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(2, Vector(-1.5, .5, -.5));
+  this->getWeaponManager().setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(3, Vector(-1.5, .5, .5));
+  this->getWeaponManager().setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(4, Vector(-1.5, -.5, .5));
+  this->getWeaponManager().setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(5, Vector(-1.5, -.5, -.5));
+  this->getWeaponManager().setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
+  //
+  this->getWeaponManager().setSlotPosition(6, Vector(-1, 0.0, 0));
+  this->getWeaponManager().setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+  //
+
+  this->cameraConnNode.addChild(this->getWeaponManager().getFixedTarget());
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+  this->getWeaponManager().getFixedTarget()->setRelCoor(0,0,0);
+
+}
+
+
+/**
+ * loads the Settings of a MD2Creature from an XML-element.
+ * @param root the XML-element to load the MD2Creature's properties from
+ */
+void MD2Creature::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+
+void MD2Creature::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( true);
+
+  State::getCameraNode()->setParent(&this->cameraConnNode);
+  State::getCameraNode()->setRelCoor(0, 0,0);
+  State::getCameraTargetNode()->setParentSoft(&this->cameraConnNode);
+
+}
+
+void MD2Creature::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+  this->detachCamera();
+}
+
+
+/**
+ *  effect that occurs after the MD2Creature is spawned
+*/
+void MD2Creature::postSpawn ()
+{}
+
+/**
+ *  the action occuring if the MD2Creature left the game
+*/
+void MD2Creature::leftWorld ()
+{}
+
+/**
+ *  this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void MD2Creature::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  PRINTF(0)("Collided with the md2 model\n");
+}
+
+/**
+ *  draws the MD2Creature after transforming it.
+*/
+void MD2Creature::draw () const
+{
+  if (this->getCurrentPlayer() != NULL)
+    WorldEntity::draw();
+
+  this->cameraConnNode.debugDraw(0);
+}
+
+
+/**
+ *  the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+*/
+void MD2Creature::tick (float time)
+{
+  Playable::tick(time);
+  if( likely(this->getModel(0) != NULL))
+    ((MD2Model*)this->getModel(0))->tick(time);
+
+
+  // MD2Creature controlled movement
+  this->calculateVelocity(time);
+  Vector move = this->velocity * time;
+  this->shiftCoor (move);
+
+
+  // handle animations differently
+  if( this->bJump && likely(this->getModel(0) != NULL))
+  {
+    ((MD2Model*)this->getModel(0))->setAnimation(JUMP);
+  }
+  else if( this->bFire && likely(this->getModel(0) != NULL))
+  {
+    if( ((MD2Model*)this->getModel(0))->getAnimation() != ATTACK)
+      ((MD2Model*)this->getModel(0))->setAnimation(ATTACK);
+  }
+  else if( fabs(move.len()) > 0.0f && likely(this->getModel(0) != NULL))
+  {
+    if( ((MD2Model*)this->getModel(0))->getAnimation() != RUN)
+      ((MD2Model*)this->getModel(0))->setAnimation(RUN);
+  }
+  else if (likely(this->getModel(0) != NULL))
+  {
+    if( ((MD2Model*)this->getModel(0))->getAnimation() != STAND)
+      ((MD2Model*)this->getModel(0))->setAnimation(STAND);
+  }
+
+
+  //orient the MD2Creature in direction of the mouse
+//   this->setAbsDir(mouseDirX);
+//    this->cameraConnNode.setRelDir(mouseDirY);
+
+  this->cameraConnNode.setRelDir(mouseDirY);
+  this->setAbsDir(this->mouseDirX);
+}
+
+
+/**
+ *  calculate the velocity
+ * @param time the timeslice since the last frame
+*/
+void MD2Creature::calculateVelocity (float time)
+{
+  Vector accel(0.0, 0.0, 0.0);
+  /*
+  Vector rot(0.0, 0.0, 0.0); // wird ben�igt fr Helicopter
+  */
+  //float rotVal = 0.0;
+  /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */
+  /* calculate the direction in which the craft is heading  */
+
+  if( bMouseMotion)
+  {
+    this->mouseDirX *= Quaternion(-M_PI / 4.0f * this->xMouse*mouseSensitivity, Vector(0,1,0));
+    this->mouseDirY *= Quaternion(-M_PI / 4.0f * this->yMouse*mouseSensitivity, Vector(0,0,1));
+    this->bMouseMotion = false;
+  }
+
+  if( this->bUp )
+  {
+    accel += (this->getAbsDirX())*2;
+  }
+
+  if( this->bDown )
+  {
+    accel -= (this->getAbsDirX())*2;
+  }
+
+  if( this->bLeft/* > -this->getRelCoor().z*2*/)
+  {
+    this->shiftDir(Quaternion(time, Vector(0,1,0)));
+  }
+  if( this->bRight /* > this->getRelCoor().z*2*/)
+  {
+    this->shiftDir(Quaternion(-time, Vector(0,1,0)));
+  }
+
+
+  if( this->bStrafeL /* > -this->getRelCoor().z*2*/)
+  {
+    accel -= this->getAbsDirZ() * 2.0f;
+  }
+  if( this->bStrafeR /* > this->getRelCoor().z*2*/)
+  {
+    accel += this->getAbsDirZ() * 2.0f;
+  }
+  if (this->bAscend )
+  {
+    this->shiftDir(Quaternion(time, Vector(0,0,1)));
+  }
+  if (this->bDescend )
+  {
+    this->shiftDir(Quaternion(-time, Vector(0,0,1)));
+  }
+
+  velocity = accel * 40.0f;
+  //rot.normalize();
+  //this->setRelDirSoft(Quaternion(rotVal, rot), 5);
+}
+
+
+/**
+ * @todo switch statement ??
+ */
+void MD2Creature::process(const Event &event)
+{
+  Playable::process(event);
+  if( event.type == KeyMapper::PEV_LEFT)
+    this->bStrafeL = event.bPressed;
+  else if( event.type == KeyMapper::PEV_RIGHT)
+    this->bStrafeR = event.bPressed;
+  else if( event.type == KeyMapper::PEV_FORWARD)
+    this->bUp = event.bPressed;
+  else if( event.type == KeyMapper::PEV_BACKWARD)
+    this->bDown = event.bPressed;
+  else if( event.type == SDLK_SPACE)
+    this->bJump = event.bPressed;
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+    this->bMouseMotion = true;
+    this->xMouse = event.xRel;
+    this->yMouse = event.yRel;
+  }
+}
Index: branches/heathaze/src/world_entities/creatures/md2_creature.h
===================================================================
--- branches/heathaze/src/world_entities/creatures/md2_creature.h	(revision 9940)
+++ branches/heathaze/src/world_entities/creatures/md2_creature.h	(revision 9940)
@@ -0,0 +1,79 @@
+/*!
+ * @file md2_creature.h
+ * Implements the control of a md2 model
+ */
+
+#ifndef _MD2_CREATURE_H
+#define _MD2_CREATURE_H
+
+#include "playable.h"
+
+
+template<class T> class tList;
+class Vector;
+class Event;
+
+class MD2Creature : public Playable
+{
+  ObjectListDeclaration(MD2Creature);
+
+  public:
+
+    MD2Creature(const std::string& fileName);
+    MD2Creature(const TiXmlElement* root = NULL);
+    virtual ~MD2Creature();
+
+    virtual void loadParams(const TiXmlElement* root);
+    virtual void setPlayDirection(const Quaternion& rot, float speed = 0.0f) {/* FIXME */};
+
+    virtual void enter();
+    virtual void leave();
+
+    virtual void postSpawn();
+    virtual void leftWorld();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+    virtual void tick(float time);
+    virtual void draw() const;
+
+    virtual void process(const Event &event);
+
+
+
+  private:
+    void init();
+
+    void calculateVelocity(float time);
+
+    bool                  bUp;                //!< up button pressed.
+    bool                  bDown;              //!< down button pressed.
+    bool                  bLeft;              //!< left button pressed.
+    bool                  bRight;             //!< right button pressed.
+    bool                  bAscend;            //!< ascend button pressed.
+    bool                  bDescend;           //!< descend button presses.
+    bool                  bFire;              //!< fire button pressed.
+    bool                  bRollL;             //!< rolling button pressed (left)
+    bool                  bRollR;             //!< rolling button pressed (right)
+    bool                  bStrafeL;           //!< strafe to the left side
+    bool                  bStrafeR;           //!< strafe to the rith side
+    bool                  bJump;              //!< jump
+    bool                  bMouseMotion;       //!< mouse motion evet
+
+    PNode                 cameraConnNode;     //!< The Node the camera is connected to.
+
+    float                 xMouse;             //!< mouse moved in x-Direction
+    float                 yMouse;             //!< mouse moved in y-Direction
+    float                 mouseSensitivity;   //!< the mouse sensitivity
+    float                 cycle;              //!< hovercycle
+
+    Vector                velocity;           //!< the velocity of the player.
+    Quaternion            mouseDirX;           //!< the direction where the player wants to fly
+    Quaternion            mouseDirY;           //!< the direction where the player wants to fly
+    float                 travelSpeed;        //!< the current speed of the player (to make soft movement)
+    float                 acceleration;       //!< the acceleration of the player.
+
+    float                 airViscosity;
+
+};
+
+#endif /* _MD2_CREATURE_H */
Index: branches/heathaze/src/world_entities/effects/billboard.cc
===================================================================
--- branches/heathaze/src/world_entities/effects/billboard.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/effects/billboard.cc	(revision 9940)
@@ -0,0 +1,172 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: David Hasenfratz
+*/
+
+#include "billboard.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "graphics_engine.h"
+#include "material.h"
+#include "glincl.h"
+#include "state.h"
+
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Billboard, CL_BILLBOARD);
+CREATE_FACTORY(Billboard);
+
+/**
+ * standart constructor
+ */
+Billboard::Billboard (const TiXmlElement* root)
+{
+  this->init();
+
+  if( root)
+    this->loadParams(root);
+}
+
+
+/**
+ * destroys a Billboard
+ */
+Billboard::~Billboard ()
+{
+  if (this->material)
+    delete this->material;
+}
+
+
+/**
+ * initializes the Billboard
+ */
+void Billboard::init()
+{
+  this->registerObject(this, Billboard::_objectList);
+  this->setName("Billboard");
+
+  this->toList(OM_COMMON);
+
+  this->material = new Material();
+  this->setAbsCoor(0, 0, 0);
+  //this->setVisibiliy(true);
+  this->setSize(5, 5);
+}
+
+
+/**
+ *  load params
+ * @param root TiXmlElement object
+ */
+void Billboard::loadParams(const TiXmlElement* root)
+{
+  /*LoadParam(root, "texture", this->material, Material, setDiffuseMap)
+      .describe("the texture-file to load onto the Billboard");
+
+  LoadParam(root, "size", this, Billboard, setSize)
+  .describe("the size of the Billboard in Pixels");*/
+}
+
+
+/**
+ * sets the size of the Billboard.
+ * @param size the size in pixels
+ */
+void Billboard::setSize(float sizeX, float sizeY)
+{
+  this->sizeX = sizeX;
+  this->sizeY = sizeY;
+}
+
+
+/**
+ * sets the material to load
+ * @param textureFile The texture-file to load
+ */
+void Billboard::setTexture(const std::string& textureFile)
+{
+  this->material->setDiffuseMap(textureFile);
+}
+
+
+/**
+ * ticks the Billboard
+ * @param dt the time to ticks
+ */
+void Billboard::tick(float dt)
+{
+}
+
+
+/**
+ * draws the billboard
+ */
+void Billboard::draw() const
+{
+  if( !this->isVisible())
+    return;
+
+  glPushAttrib(GL_ENABLE_BIT);
+  glDisable(GL_LIGHTING);
+  glDisable(GL_FOG);
+
+  glPushMatrix();
+
+  //glTranslatef(this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z);
+  //glTranslatef(0,0,0);
+  this->material->select();
+
+  const PNode* camera = State::getCameraNode();  //!< @todo MUST be different
+  Vector cameraPos = camera->getAbsCoor();
+  Vector cameraTargetPos = State::getCameraTargetNode()->getAbsCoor();
+  Vector view = cameraTargetPos - cameraPos;
+  Vector up = Vector(0, 1, 0);
+  up = camera->getAbsDir().apply(up);
+  Vector h = up.cross(view);
+  Vector v = h.cross(view);
+  h.normalize();
+  v.normalize();
+
+  v *= sizeX;
+  h *= sizeY;
+
+//v += this->getAbsCoor();
+    //PRINTF(0)("sizeX: %f sizeY: %f\n", sizeX, sizeY);
+  glBegin(GL_QUADS);
+  glTexCoord2f(0.0f, 0.0f);
+  glVertex3f(this->getAbsCoor().x - h.x - v.x,
+             this->getAbsCoor().y - h.y - v.y,
+             this->getAbsCoor().z - h.z - v.z);
+  glTexCoord2f(1.0f, 0.0f);
+  glVertex3f( this->getAbsCoor().x + h.x - v.x,
+              this->getAbsCoor().y + h.y - v.y,
+              this->getAbsCoor().z + h.z - v.z);
+  glTexCoord2f(1.0f, 1.0f);
+  glVertex3f(this->getAbsCoor().x + h.x + v.x,
+             this->getAbsCoor().y + h.y + v.y,
+             this->getAbsCoor().z + h.z + v.z);
+  glTexCoord2f(0.0f, 1.0f);
+  glVertex3f(this->getAbsCoor().x - h.x + v.x,
+             this->getAbsCoor().y - h.y + v.y,
+             this->getAbsCoor().z - h.z + v.z);
+  glEnd();
+
+
+  glPopMatrix();
+
+  glPopAttrib();
+}
Index: branches/heathaze/src/world_entities/effects/billboard.h
===================================================================
--- branches/heathaze/src/world_entities/effects/billboard.h	(revision 9940)
+++ branches/heathaze/src/world_entities/effects/billboard.h	(revision 9940)
@@ -0,0 +1,35 @@
+/*!
+ * @file billboard.h
+ */
+
+#ifndef _BILLBOARD_H
+#define _BILLBOARD_H
+
+#include "world_entity.h"
+
+class Material;
+class TiXmlElement;
+
+class Billboard : public WorldEntity
+{
+  ObjectListDeclaration(Billboard);
+  public:
+    Billboard(const TiXmlElement* root = NULL);
+    virtual ~Billboard();
+
+    void init();
+    void loadParams(const TiXmlElement* root);
+
+    void setSize(float sizeX, float sizeY);
+    void setTexture(const std::string& textureFile);
+
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+  private:
+    Material*        material;
+    float sizeX;
+    float sizeY;
+};
+
+#endif /* _BILLBOARD_H */
Index: branches/heathaze/src/world_entities/effects/explosion.cc
===================================================================
--- branches/heathaze/src/world_entities/effects/explosion.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/effects/explosion.cc	(revision 9940)
@@ -0,0 +1,117 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "explosion.h"
+
+#include "loading/fast_factory.h"
+
+#include "state.h"
+
+#include "particles/box_emitter.h"
+#include "particles/sprite_particles.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Explosion, CL_EXPLOSION);
+CREATE_FAST_FACTORY_STATIC(Explosion);
+
+/**
+ *  standard constructor
+*/
+Explosion::Explosion ()
+{
+  this->registerObject(this, Explosion::_objectList);
+  this->toList(OM_DEAD_TICK);
+
+  this->emitter = new BoxEmitter(Vector(10,10,10), 200, 45, M_2_PI);
+  this->emitter->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+
+  this->lifeCycle = 0.0f;
+  this->lifeTime = .5f;
+
+}
+
+
+/**
+ *  standard deconstructor
+*/
+Explosion::~Explosion ()
+{
+  delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (Explosion::explosionParticles != NULL && Explosion::objectList().size() <= 1)
+     Explosion::explosionParticles = NULL;
+}
+
+SpriteParticles* Explosion::explosionParticles = NULL;
+
+void Explosion::explode(PNode* position, const Vector& size)
+{
+  Explosion* explosion = dynamic_cast<Explosion*>(Explosion::fastFactory->resurrect());
+  explosion->setAbsCoor(position->getAbsCoor());
+  explosion->emitter->setSize(size);
+  explosion->activate();
+}
+
+
+void Explosion::activate()
+{
+  if (unlikely(Explosion::explosionParticles == NULL))
+  {
+    Explosion::explosionParticles = new SpriteParticles(5000);
+    Explosion::explosionParticles->setName("ExplosionExplosionParticles");
+    Explosion::explosionParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    Explosion::explosionParticles->setLifeSpan(1.5, .3);
+    Explosion::explosionParticles->setRadius(0.0, 10);
+    Explosion::explosionParticles->setRadius(.5, 30.0);
+    Explosion::explosionParticles->setRadius(1.0, 10.0);
+    Explosion::explosionParticles->setColor(0.0, 1,0,0,1);
+    Explosion::explosionParticles->setColor(0.5, .8,.8,0,.5);
+    Explosion::explosionParticles->setColor(0.8, .8,.8,.3,.3);
+    Explosion::explosionParticles->setColor(1.0, 1,1,1,.0);
+  }
+
+  this->emitter->setSystem(Explosion::explosionParticles);
+  this->emitter->updateNode(.01);
+  this->emitter->updateNode(.01);
+  this->toList(OM_DEAD_TICK);
+  this->lifeCycle = 0.0;
+}
+
+
+void Explosion::deactivate()
+{
+  this->emitter->setSystem(NULL);
+  this->toList(OM_DEAD);
+  Explosion::fastFactory->kill(this);
+}
+
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param time since last tick
+*/
+void Explosion::tick (float dt)
+{
+  this->lifeCycle += dt;
+  if(this->lifeTime < this->lifeCycle)
+    this->deactivate();
+}
Index: branches/heathaze/src/world_entities/effects/explosion.h
===================================================================
--- branches/heathaze/src/world_entities/effects/explosion.h	(revision 9940)
+++ branches/heathaze/src/world_entities/effects/explosion.h	(revision 9940)
@@ -0,0 +1,39 @@
+/*!
+ * @file explosion.h
+ * @brief a Explosion Projectile
+*/
+
+#ifndef _EXPLOSION_H
+#define _EXPLOSION_H
+
+#include "world_entity.h"
+
+class SpriteParticles;
+class BoxEmitter;
+class FastFactory;
+
+class Explosion : public WorldEntity
+{
+  ObjectListDeclaration(Explosion);
+  public:
+    static void explode (PNode* position, const Vector& size);
+
+    Explosion ();
+    virtual ~Explosion ();
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void tick (float time);
+
+  private:
+    static FastFactory*        fastFactory;
+
+    float                      lifeTime;
+    float                      lifeCycle;
+
+    static SpriteParticles*    explosionParticles;
+    BoxEmitter*                emitter;
+};
+
+#endif /* _EXPLOSION_H */
Index: branches/heathaze/src/world_entities/effects/lightning_bolt.cc
===================================================================
--- branches/heathaze/src/world_entities/effects/lightning_bolt.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/effects/lightning_bolt.cc	(revision 9940)
@@ -0,0 +1,146 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+
+#include "lightning_bolt.h"
+
+#include "util/loading/factory.h"
+#include "material.h"
+
+#include "sound/resource_sound_buffer.h"
+
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(LightningBolt, CL_LIGHTNING_BOLT);
+CREATE_FACTORY(LightningBolt);
+
+/**
+ *  standard constructor
+*/
+LightningBolt::LightningBolt (const TiXmlElement* root)
+{
+  this->registerObject(this, LightningBolt::_objectList);
+
+  this->toList(OM_COMMON);
+
+  this->bRender = false;
+  this->time = 0.0;
+  this->flashFrequency = 0.6f;
+  this->flashConstTime = 0.07f;
+
+  this->material = new Material();
+  this->material->setDiffuseMap("maps/lightning_bolt.png");
+  //this->offset = Vector(-1440.00, 100.00, 280.00);
+
+  this->setAbsCoor(offset);
+  this->width = 100.0f;
+  this->height = 300.0f;
+  this->bNewCoordinate = false;
+
+  this->seedX = 200.f;
+  this->seedZ = 500.0f;
+  this->seedTime = 4.0f;
+
+  this->soundSource.setSourceNode(this);
+
+  this->thunderBuffer = OrxSound::ResourceSoundBuffer("sound/atmosphere/thunder.wav");
+}
+
+
+/**
+ *  standard deconstructor
+*/
+LightningBolt::~LightningBolt ()
+{
+}
+
+void LightningBolt::activate()
+{
+}
+
+
+void LightningBolt::deactivate()
+{
+
+}
+
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param time since last tick
+*/
+void LightningBolt::tick (float dt)
+{
+  this->time += dt;
+
+  if( this->time > this->flashFrequency)
+  {
+    this->bRender = true;
+    this->time = 0.0f;
+    this->soundSource.play(this->thunderBuffer);
+  }
+  else if( this->bRender && this->time > this->flashConstTime)
+  {
+    this->bRender = false;
+    this->time = 0.0f;
+    this->bNewCoordinate = true;
+  }
+
+  if( this->bNewCoordinate)
+  {
+    this->flashFrequency = this->seedTime * (float)rand()/(float)RAND_MAX + 0.1;
+    this->setAbsCoor( - 800.0f - this->seedX * (float)rand()/(float)RAND_MAX, 250.00, -200.0f + this->seedZ * (float)rand()/(float)RAND_MAX);
+    this->bNewCoordinate = false;
+  }
+}
+
+
+void LightningBolt::draw() const
+{
+  if( this->bRender)
+  {
+
+    glPushMatrix();
+    glTranslatef (this->getAbsCoor ().x,
+                  this->getAbsCoor ().y,
+                  this->getAbsCoor ().z);
+
+    glRotatef(90, 0.0f,1.0f,0.0f);
+
+//     Vector tmpRot = drawPart->orientation.getSpacialAxis();
+//     glRotatef (drawPart->orientation.getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+//     glPushAttrib(GL_ENABLE_BIT);
+//     glDisable(GL_LIGHTING);
+//     glDisable(GL_BLEND);
+
+    this->material->select();
+
+    glBegin(GL_QUADS);
+    glTexCoord2f(1.0f, 1.0f); glVertex3f(-width/2, -height/2,  0.0f);
+    glTexCoord2f(0.0f, 1.0f); glVertex3f( width/2, -height/2,  0.0f);
+    glTexCoord2f(0.0f, 0.0f); glVertex3f( width/2,  height/2,  0.0f);
+    glTexCoord2f(1.0f, 0.0f); glVertex3f(-width/2,  height/2,  0.0f);
+    glEnd();
+
+//     glPopAttrib();
+
+    glPopMatrix();
+  }
+}
+
+
Index: branches/heathaze/src/world_entities/effects/lightning_bolt.h
===================================================================
--- branches/heathaze/src/world_entities/effects/lightning_bolt.h	(revision 9940)
+++ branches/heathaze/src/world_entities/effects/lightning_bolt.h	(revision 9940)
@@ -0,0 +1,57 @@
+/*!
+ * @file lightning_bolt.h
+ * @brief a LightningBolt Projectile
+ *  Der Effekt soll folgenderma�n funktionieren:
+ * -> Ein Partikel mit einer Blitz-Textur soll sehr schnell erscheinen,
+ * -> w�rend er an Intensit� zunimmt soll die Beleuchtung der gerenderten Szene entsprechend zunehmen.
+ * -> Je mehr Blitze zum gleichen Zeitpunkt sichtbar sind, desto heller soll die Beleuchtung werden, das hei� die Helligkeitszunahme pro Blitz soll Additiv sein.
+ * -> Ein Partikel soll ebenfalls sehr schnell wieder verblassen, dabei soll die Beleuchtung entsprechend der vorhergehenden Zunahme wieder abnehmen (Additiv)
+ */
+
+#ifndef _LIGHTNING_BOLT_H
+#define _LIGHTNING_BOLT_H
+
+#include "world_entity.h"
+
+#include "sound_buffer.h"
+#include "sound_source.h"
+
+class Material;
+
+class LightningBolt : public WorldEntity
+{
+  ObjectListDeclaration(LightningBolt);
+  public:
+    LightningBolt(const TiXmlElement* root = NULL);
+    virtual ~LightningBolt ();
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void tick(float time);
+    virtual void draw() const;
+
+  private:
+    float flashFrequency;                   //!< frequency to activate itself
+    float flashRisingTime;                  //!< time to rise
+    float flashConstTime;                   //!< time to be drawn
+    float flashFallTime;                    //!< time to fall
+
+    float time;                             //!< time
+
+    bool  bRender;
+    bool  bNewCoordinate;
+    Material*      material;
+    Vector         offset;
+    float width;
+    float height;
+
+    float seedX;
+    float seedZ;
+    float seedTime;
+
+    OrxSound::SoundSource    soundSource;
+    OrxSound::SoundBuffer    thunderBuffer;
+};
+
+#endif /* _LIGHTNING_BOLT_H */
Index: branches/heathaze/src/world_entities/elements/glgui_energywidget.cc
===================================================================
--- branches/heathaze/src/world_entities/elements/glgui_energywidget.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/elements/glgui_energywidget.cc	(revision 9940)
@@ -0,0 +1,102 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "glgui_energywidget.h"
+
+#include "multi_type.h"
+
+namespace OrxGui
+{
+  /**
+   * @brief standard constructor
+   */
+  GLGuiEnergyWidget::GLGuiEnergyWidget ()
+  {
+    //   this->setClassID(CL_PROTO_ID, "GLGuiEnergyWidget");
+
+    this->_bar.setSize2D(100, 30);
+    this->pack(&this->_name);
+    this->pack(&this->_valueText);
+    this->_bar.setParent2D(&this->_valueText);
+
+    this->_name.setForegroundColor(Color(1,1,1,.8));
+    this->_valueText.setChangedTextColor(Color::white);
+
+    //this->setBackgroundTexture("maps/gui_element_background_2.png");
+    this->setBackgroundColor(Color(.5,.5,.5,1));
+
+    //this->_name.setBackgroundTexture(Texture());
+    //this->_valueText.setBackgroundTexture("maps/gui_element_background_2.png");
+    this->_bar.setBackgroundTexture(Texture());
+    this->_bar.setBackgroundColor(Color(0,0,0,0));
+    this->_bar.setForegroundTexture("maps/gui_element_background_faded.png");
+    this->_bar.setForegroundColor(Color(.5, .5, .5, 1));
+    this->_bar.setChangedValueColor(Color::black);
+  }
+
+
+  /**
+   * @brief standard deconstructor
+   */
+  GLGuiEnergyWidget::~GLGuiEnergyWidget ()
+  {
+  }
+
+
+  void GLGuiEnergyWidget::setDisplayedName(const std::string& name)
+  {
+    this->_name.setText(name);
+    this->_bar.setWidgetSize(this->_name.getSize2D());
+  }
+
+  void GLGuiEnergyWidget::setMaximum(float max)
+  {
+    this->_bar.setMaximum(max);
+  }
+
+  void GLGuiEnergyWidget::setValue(float value)
+  {
+    MultiType val(value);
+    val.setType(MT_INT);
+
+
+    this->_bar.setValue(value);
+    this->_bar.setForegroundColor(Color::slerpHSVColor(Color::red, Color::green, value/this->_bar.maximum()));
+    this->_bar.setFrontColor(Color(1,1,1,1), true);
+    this->_valueText.setText(val.getString());
+  }
+
+  void GLGuiEnergyWidget::resize()
+  {
+    GLGuiBox::resize();
+  }
+
+
+  void GLGuiEnergyWidget::showing()
+  {
+    this->_name.show();
+    this->_valueText.show();
+    this->_bar.show();
+  }
+
+  void GLGuiEnergyWidget::hiding()
+  {
+    this->_name.hide();
+    this->_valueText.hide();
+    this->_bar.hide();
+  }
+}
Index: branches/heathaze/src/world_entities/elements/glgui_energywidget.h
===================================================================
--- branches/heathaze/src/world_entities/elements/glgui_energywidget.h	(revision 9940)
+++ branches/heathaze/src/world_entities/elements/glgui_energywidget.h	(revision 9940)
@@ -0,0 +1,40 @@
+/*!
+ * @file glgui_energywidget.h
+ * @brief Definition of an EnergyWidget, that displays a bar and a Text
+*/
+
+#ifndef _GLGUI_ENERGY_WIDGET_H
+#define _GLGUI_ENERGY_WIDGET_H
+
+#include "glgui_box.h"
+#include "glgui_bar.h"
+#include "glgui_text.h"
+
+namespace OrxGui
+{
+
+  //! A class for ...
+  class GLGuiEnergyWidget : public GLGuiBox
+  {
+
+  public:
+    GLGuiEnergyWidget();
+    virtual ~GLGuiEnergyWidget();
+
+    void setDisplayedName(const std::string& name);
+    void setMaximum(float max);
+    void setValue(float value);
+
+  protected:
+    virtual void resize();
+    virtual void showing();
+    virtual void hiding();
+
+  private:
+    GLGuiText               _name;
+    GLGuiText               _valueText;
+    GLGuiBar                _bar;
+
+  };
+}
+#endif /* _GLGUI_ENERGY_WIDGET_H */
Index: branches/heathaze/src/world_entities/elements/glgui_radar.cc
===================================================================
--- branches/heathaze/src/world_entities/elements/glgui_radar.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/elements/glgui_radar.cc	(revision 9940)
@@ -0,0 +1,169 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "glgui_radar.h"
+#include "world_entity.h"
+
+#include "debug.h"
+
+namespace OrxGui
+{
+  /**
+   * @brief standard constructor
+   */
+  GLGuiRadar::GLGuiRadar ()
+  {
+    this->init();
+  }
+
+
+  /**
+   * @brief standard deconstructor
+   */
+  GLGuiRadar::~GLGuiRadar ()
+  {}
+
+  void GLGuiRadar::init()
+  {
+    this->setBackgroundTexture("gui_radar.png");
+
+    this->_updateInterval = .01f;
+    this->_timePassed = 0.0f;
+    this->_range = 100.0f;
+    this->_centerNode = NULL;
+  }
+
+  void GLGuiRadar::setCenterNode(const PNode* center)
+  {
+    this->_centerNode = center;
+  }
+
+  void GLGuiRadar::addEntityList(const std::list<WorldEntity*>* entityList, const Color& color)
+  {
+    for (unsigned int i = 0; i < this->_dotLists.size(); ++i)
+      if (_dotLists[i].entityList == entityList)
+        return;
+
+    GLGuiRadar::DotList dotList;
+    dotList.dotColor = color;
+    dotList.entityList = entityList;
+
+    this->_dotLists.push_back(dotList);
+  }
+
+  void GLGuiRadar::removeEntityList(const std::list<WorldEntity*>* entityList)
+  {
+    std::vector<DotList>::iterator it;
+    for (it = this->_dotLists.begin(); it != this->_dotLists.end(); ++it)
+      if ((*it).entityList == entityList)
+      {
+        this->_dotLists.erase(it);
+        break;
+      }
+  }
+
+
+  void GLGuiRadar::setRange(float range)
+  {
+    this->_range = range;
+  }
+
+
+  void GLGuiRadar::setAttenuation(Attenuation attenuation)
+  {
+    this->_attenuation = attenuation;
+  }
+
+
+  void GLGuiRadar::tick(float dt)
+  {
+    _timePassed+=dt;
+
+    if (_timePassed > _updateInterval)
+    {
+      _timePassed = 0 ; //-=_updateInterval;
+      this->updateRadar();
+    }
+
+  }
+
+  void GLGuiRadar::updateRadar()
+  {
+    if (_centerNode == NULL)
+    {
+      for (unsigned int i = 0; i < this->_dotLists.size(); ++i)
+        this->_dotLists[i].positions.clear();
+      return;
+    }
+
+    std::list<WorldEntity*>::const_iterator it;
+    for (unsigned int i = 0; i < this->_dotLists.size(); ++i)
+    {
+      this->_dotLists[i].positions.clear();
+
+      for (it = _dotLists[i].entityList->begin(); it != _dotLists[i].entityList->end(); ++it)
+      {
+        if (_centerNode->distance(*it) < this->_range)
+        {
+          this->_dotLists[i].positions.push_back(Vector2D(((*it)->getAbsCoor().x - _centerNode->getAbsCoor().x) * this->getSizeX2D() ,
+                                                 ((*it)->getAbsCoor().z - _centerNode->getAbsCoor().z) * this->getSizeY2D()  )
+                                                 / (2.0f * _range));
+        }
+
+      }
+
+    }
+  }
+
+
+  void GLGuiRadar::draw() const
+  {
+    this->beginDraw();
+    GLGuiWidget::draw();
+
+    if (likely(this->_centerNode != NULL))
+    {
+      glTranslatef(this->getSizeX2D()/2.0f, this->getSizeY2D()/2.0f, 0);
+      glRotatef((this->_centerNode->getAbsDir().getHeading() - M_PI_2)* 180.0 /M_PI , 0, 0, 1);
+
+      glPointSize(4.0f);
+      for (unsigned int i = 0; i < this->_dotLists.size(); ++i)
+      {
+        glColor4fv(&_dotLists[i].dotColor[0]);
+        for (unsigned int j = 0; j < this->_dotLists[i].positions.size(); ++j)
+        {
+          glBegin(GL_POINTS);
+          glVertex2f(this->_dotLists[i].positions[j].x, this->_dotLists[i].positions[j].y);
+          glEnd();
+        }
+      }
+    }
+    this->endDraw();
+  }
+
+
+  void GLGuiRadar::resize()
+  {
+    GLGuiWidget::resize();
+  }
+
+
+  void GLGuiRadar::showing()
+  {}
+
+  void GLGuiRadar::hiding()
+{}}
Index: branches/heathaze/src/world_entities/elements/glgui_radar.h
===================================================================
--- branches/heathaze/src/world_entities/elements/glgui_radar.h	(revision 9940)
+++ branches/heathaze/src/world_entities/elements/glgui_radar.h	(revision 9940)
@@ -0,0 +1,75 @@
+/*!
+ * @file glgui_radar.h
+ * @brief Definition of an Radar, that displays a bar and a Text
+*/
+
+#ifndef _GLGUI_RADAR_H
+#define _GLGUI_RADAR_H
+
+#include "glgui_widget.h"
+
+class PNode;
+class WorldEntity;
+
+namespace OrxGui
+{
+
+  //! A class for ...
+  class GLGuiRadar : public GLGuiWidget
+  {
+  public:
+    typedef enum {
+      Linear,
+      Exponential,
+    } Attenuation;
+
+  public:
+    GLGuiRadar();
+    virtual ~GLGuiRadar();
+
+    void addEntityList(const std::list<WorldEntity*>* entityList, const Color& color);
+    void removeEntityList(const std::list<WorldEntity*>* entityList);
+
+    void setRange(float range);
+
+    void setCenterNode(const PNode* center);
+    void setUpdateInterval(float updateInterval) { this->_updateInterval = updateInterval; };
+    void setAttenuation(Attenuation attenuation);
+
+
+    float range() const { return this->_range; }
+
+    void updateRadar();
+
+    virtual void tick(float dt);
+    void draw() const;
+
+  protected:
+    virtual void resize();
+    virtual void showing();
+    virtual void hiding();
+
+  private:
+    void init();
+
+  private:
+    typedef struct
+    {
+      Color                           dotColor;
+      const std::list<WorldEntity*>*  entityList;
+      std::vector<Vector2D>           positions;
+    }
+    DotList;
+
+    const PNode*                      _centerNode;
+    std::vector<DotList>              _dotLists;
+
+    Attenuation                       _attenuation;
+    float                             _range;
+
+
+    float                             _updateInterval;
+    float                             _timePassed;
+  };
+}
+#endif /* _GLGUI_RADAR_H */
Index: branches/heathaze/src/world_entities/elements/image_entity.cc
===================================================================
--- branches/heathaze/src/world_entities/elements/image_entity.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/elements/image_entity.cc	(revision 9940)
@@ -0,0 +1,161 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "image_entity.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "graphics_engine.h"
+#include "material.h"
+#include "glincl.h"
+#include "state.h"
+
+
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(ImageEntity, CL_IMAGE_ENTITY);
+CREATE_FACTORY(ImageEntity);
+
+
+/**
+ * standart constructor
+ */
+ImageEntity::ImageEntity (const TiXmlElement* root)
+{
+  this->init();
+  if(root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * destroys a ImageEntity
+*/
+ImageEntity::~ImageEntity ()
+{
+  if (this->material)
+    delete this->material;
+}
+
+
+/**
+ * initializes the ImageEntity
+ */
+void ImageEntity::init()
+{
+  this->registerObject(this, ImageEntity::_objectList);
+  this->setName("ImageEntity");
+
+  this->setLayer(E2D_LAYER_TOP);
+  this->setRotationSpeed(5);
+  this->setSize(GraphicsEngine::getInstance()->getResolutionX()/10.0, GraphicsEngine::getInstance()->getResolutionY()/10.0);
+
+  this->setBindNode(this);
+  this->material = new Material;
+  this->setTexture("pictures/error_texture.png");
+  this->bBillboarding = false;
+}
+
+
+void ImageEntity::loadParams(const TiXmlElement* root)
+{
+  PNode::loadParams(root);
+  Element2D::loadParams(root);
+
+  LoadParam(root, "texture", this, ImageEntity, setTexture)
+      .describe("the texture-file to load onto the ImageEntity");
+
+  LoadParam(root, "size", this, ImageEntity, setSize)
+      .describe("the size of the ImageEntity in Pixels");
+
+  LoadParam(root, "rotation-speed", this, ImageEntity, setRotationSpeed)
+      .describe("the Speed with which the ImageEntity should rotate");
+
+  LoadParam(root, "billboarding", this, ImageEntity, toggleBillboarding)
+      .describe("sets the Billboard to always look in the direction of the Player");
+}
+
+
+/**
+ * sets the size of the ImageEntity.
+ * @param size the size in pixels
+ */
+void ImageEntity::setSize(float sizeX, float sizeY)
+{
+  this->setSize2D(sizeX, sizeY);
+}
+
+
+/**
+ * sets the material to load
+ * @param textureFile The texture-file to load onto the crosshair
+ */
+void ImageEntity::setTexture(const std::string& textureFile)
+{
+  this->material->setDiffuseMap(textureFile);
+}
+
+
+/** this turns on/off the billboarding of this WorldEntity
+ *
+ * This means that the image will always look in the direction of the Player
+ */
+void ImageEntity::toggleBillboarding()
+{
+  this->bBillboarding = !this->bBillboarding;
+}
+
+
+/**
+ * ticks the ImageEntity
+ * @param dt the time to ticks
+ */
+void ImageEntity::tick(float dt)
+{
+
+}
+
+
+/**
+ * draws the crosshair
+ */
+void ImageEntity::draw() const
+{
+  if( !this->isVisible())
+    return;
+
+  glPushMatrix();
+  glTranslatef(this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
+
+  //glRotatef(this->getAbsDir2D(), 0,0,1);
+  this->material->select();
+  glBegin(GL_TRIANGLE_STRIP);
+  glTexCoord2f(0, 0);
+  glVertex2f(-this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(1, 0);
+  glVertex2f(this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(0, 1);
+  glVertex2f(-this->getSizeX2D(), this->getSizeY2D());
+  glTexCoord2f(1, 1);
+  glVertex2f(this->getSizeX2D(), this->getSizeY2D());
+  glEnd();
+  glPopMatrix();
+
+}
Index: branches/heathaze/src/world_entities/elements/image_entity.h
===================================================================
--- branches/heathaze/src/world_entities/elements/image_entity.h	(revision 9940)
+++ branches/heathaze/src/world_entities/elements/image_entity.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file image_entity.h
+ *  Definition of an ImageEntity
+ */
+
+#ifndef _IMAGE_ENTITY_H
+#define _IMAGE_ENTITY_H
+
+#include "p_node.h"
+#include "element_2d.h"
+#include "event_listener.h"
+
+#include "vector.h"
+
+
+// FORWARD DECLARATION
+class Model;
+class Material;
+class TiXmlElement;
+
+//! A class that enables the
+class ImageEntity : public PNode, public Element2D {
+  ObjectListDeclaration(ImageEntity);
+
+ public:
+  ImageEntity(const TiXmlElement* root = NULL);
+  virtual ~ImageEntity();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setSize(float sizeX, float sizeY);
+  void setTexture(const std::string& textureFile);
+  /** @param rotationSpeed the speed at what the crosshair should rotate */
+  void setRotationSpeed(float rotationSpeed) { this->rotationSpeed = rotationSpeed; };
+  void toggleBillboarding();
+
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+ private:
+   Material*        material;             //!< a material for the Aim.
+   float            rotationSpeed;        //!< Speed of the Rotation.
+   bool             bBillboarding;        //!< true if billboarding is on
+};
+
+#endif /* _IMAGE_ENTITY_H */
Index: branches/heathaze/src/world_entities/elements/text_element.cc
===================================================================
--- branches/heathaze/src/world_entities/elements/text_element.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/elements/text_element.cc	(revision 9940)
@@ -0,0 +1,81 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "text_element.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "graphics_engine.h"
+#include "state.h"
+
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(TextElement, CL_TEXT_ELEMENT);
+CREATE_FACTORY(TextElement);
+
+
+/**
+ * standart constructor
+ */
+TextElement::TextElement (const TiXmlElement* root)
+{
+  this->registerObject(this, TextElement::_objectList);
+  this->setName("TextElement");
+
+  this->setLayer(E2D_LAYER_TOP);
+  this->setSize(GraphicsEngine::getInstance()->getResolutionX()/10.0);
+
+  this->setSize(20);
+  this->setFont("fonts/earth.ttf");
+  this->setAlignment(TEXT_ALIGN_CENTER);
+
+  if(root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * destroys a TextElement
+*/
+TextElement::~TextElement ()
+{
+}
+
+
+void TextElement::loadParams(const TiXmlElement* root)
+{
+  Element2D::loadParams(root);
+
+  LoadParam(root, "size", this, Text, setSize);
+
+  LoadParam(root, "text", this, TextElement, setText);
+
+  LoadParam(root, "font", this, TextElement, setFont);
+}
+
+void TextElement::setText(const std::string& text)
+{
+  Text::setText(text);
+}
+
+void TextElement::setFont(const std::string& font)
+{
+  Text::setFont(font, (unsigned int)this->getSizeY2D());
+}
Index: branches/heathaze/src/world_entities/elements/text_element.h
===================================================================
--- branches/heathaze/src/world_entities/elements/text_element.h	(revision 9940)
+++ branches/heathaze/src/world_entities/elements/text_element.h	(revision 9940)
@@ -0,0 +1,39 @@
+/*!
+ * @file text_element.h
+ *  Definition of an TextElement
+ */
+
+#ifndef _TEXT_ELEMENT_H
+#define _TEXT_ELEMENT_H
+
+#include "p_node.h"
+#include "text.h"
+#include "event_listener.h"
+
+#include "vector.h"
+
+
+// FORWARD DECLARATION
+class Model;
+class Material;
+class TiXmlElement;
+
+//! A class that enables the
+class TextElement : public Text {
+  ObjectListDeclaration(TextElement);
+
+ public:
+  TextElement(const TiXmlElement* root = NULL);
+  virtual ~TextElement();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setText(const std::string& text);
+  void setFont(const std::string& font);
+
+ private:
+
+};
+
+#endif /* _TEXT_ELEMENT_H */
Index: branches/heathaze/src/world_entities/environment.cc
===================================================================
--- branches/heathaze/src/world_entities/environment.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/environment.cc	(revision 9940)
@@ -0,0 +1,83 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "environment.h"
+
+#include "objModel.h"
+#include "obb_tree.h"
+#include "util/loading/factory.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Environment, CL_ENVIRONMENT);
+CREATE_FACTORY(Environment);
+
+/**
+ *  creates an environment
+*/
+Environment::Environment () : WorldEntity()
+{
+  this->init();
+  this->loadModel("models/ships/bolido.obj");
+//   if(this->obbTree == NULL)
+//     this->obbTree = new OBBTree(4, (sVec3D*)this->model->getVertexArray(), this->model->getVertexCount());
+}
+
+/**
+ * create an environment out of a XML-element
+ * @param root the XML-element to load the Environment from
+ */
+Environment::Environment(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  deletes an environment
+*/
+Environment::~Environment ()
+{}
+
+/**
+ * initialize an Environment
+ */
+void Environment::init()
+{
+  this->registerObject(this, Environment::_objectList);
+  this->toList(OM_ENVIRON);
+}
+
+/**
+ * loads the Settings of an Environment from an XML-element.
+ * @param root the XML-element to load the ELements properties from
+ */
+void Environment::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+
+/**
+ *  ticks the environment
+ * @param time the time about which to tick
+*/
+void Environment::tick (float time) {}
+
+
Index: branches/heathaze/src/world_entities/environment.h
===================================================================
--- branches/heathaze/src/world_entities/environment.h	(revision 9940)
+++ branches/heathaze/src/world_entities/environment.h	(revision 9940)
@@ -0,0 +1,34 @@
+/*!
+  \file environment.h
+  \brief This file handles the environment of the game
+*/
+
+#ifndef _ENVIRONEMENT_H
+#define _ENVIRONEMENT_H
+
+#include "world_entity.h"
+
+//! environment of orxonox
+/**
+   everything that does not interact with the player comes here
+   Environment is a container for all the worldEntities that are non-interactive
+*/
+class Environment : public WorldEntity
+{
+  ObjectListDeclaration(Environment);
+
+ public:
+  Environment ();
+  Environment (const TiXmlElement* root);
+  virtual ~Environment ();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+
+
+  virtual void tick (float time);
+
+};
+
+#endif /* _ENVIRONEMENT_H */
Index: branches/heathaze/src/world_entities/environments/building.cc
===================================================================
--- branches/heathaze/src/world_entities/environments/building.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/environments/building.cc	(revision 9940)
@@ -0,0 +1,49 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "building.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Building, CL_BUILDING);
+CREATE_FACTORY(Building);
+
+/**
+ *  initializes a skybox from a XmlElement
+*/
+Building::Building(const TiXmlElement* root)
+{
+  this->registerObject(this, Building::_objectList);
+  this->toList(OM_ENVIRON_NOTICK);
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ *  default destructor
+*/
+Building::~Building()
+{
+}
+
+
Index: branches/heathaze/src/world_entities/environments/building.h
===================================================================
--- branches/heathaze/src/world_entities/environments/building.h	(revision 9940)
+++ branches/heathaze/src/world_entities/environments/building.h	(revision 9940)
@@ -0,0 +1,28 @@
+/*!
+ * @file building.h
+ *  Definition of the Building, that handles the Display of an atmosphere for orxonox.
+ */
+
+#ifndef _BUILDING_H
+#define _BUILDING_H
+
+/* INCLUDES */
+#include "world_entity.h"
+
+/* FORWARD DECLARATION */
+
+//! A Class to handle a Building
+class Building : public WorldEntity
+{
+  ObjectListDeclaration(Building);
+  public:
+  Building(const TiXmlElement* root);
+
+  virtual ~Building();
+
+};
+
+#endif  /* _BUILDING_H */
+
+
+
Index: branches/heathaze/src/world_entities/environments/mapped_water.cc
===================================================================
--- branches/heathaze/src/world_entities/environments/mapped_water.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/environments/mapped_water.cc	(revision 9940)
@@ -0,0 +1,845 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Stefan Lienard
+   co-programmer: ...
+*/
+
+#include "mapped_water.h"
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "state.h"
+#include "t_animation.h"
+#include <cmath>
+#include "glgui.h"
+#include "shell_command.h"
+#include "script_class.h"
+
+#include "resource_shader.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(MappedWater, CL_MAPPED_WATER);
+CREATE_FACTORY(MappedWater);
+
+SHELL_COMMAND(gui, MappedWater, toggleGui);
+SHELL_COMMAND(output, MappedWater, saveParams);
+
+CREATE_SCRIPTABLE_CLASS(MappedWater,
+                        addMethod("waterUV", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeWaterUV))
+                        ->addMethod("waterFlow", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeWaterFlow))
+                        ->addMethod("shineSize", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeShineSize))
+                        ->addMethod("shineStrength", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeShineStrength))
+                        ->addMethod("reflStrength", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeReflStrength))
+                        ->addMethod("refraction", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeRefraction))
+                        ->addMethod("waterHeight", Executor2<MappedWater, lua_State*, float, float>(&MappedWater::fadeWaterHeight))
+                        ->addMethod("waterColor", Executor4<MappedWater, lua_State*, float, float, float, float>(&MappedWater::fadeWaterColor)));
+
+
+/**
+ * @brief constructor
+ * @param root xml data
+ */
+MappedWater::MappedWater(const TiXmlElement* root)
+{
+  this->registerObject(this, MappedWater::_objectList);
+  this->toList(OM_ENVIRON);
+
+  /// sets start values and parameters
+  this->initParams();
+  // now the standard values were loaded, if the values are specified in the .oxw file
+  // loadParams will overwrite the standard values with the specified values
+  if (root != NULL)
+    this->loadParams(root);
+
+  /// initialization of the textures
+  this->initTextures();
+
+  /// initialization of the shaders
+  this->initShaders();
+
+  /// calculation of the 4 verts of the water quad
+  this->calcVerts();
+
+  // init gui
+  this->box = NULL;
+}
+
+/**
+ * @brief deltes shader and the uniform used by the camera
+ */
+MappedWater::~MappedWater()
+{
+  delete cam_uni;
+  delete color_uni;
+  delete light_uni;
+  delete shineSize_uni;
+  delete shineStrength_uni;
+  delete reflStrength_uni;
+  delete refr_uni;
+}
+
+/**
+ * @brief initialization of loadable parameters, sets start standard values
+ */
+void MappedWater::initParams()
+{
+  // those standardvalues will be overwritten if they're also set in the oxw file
+  this->setWaterPos(0, 0, 0);
+  this->setWaterSize(100, 100);
+  this->setWaterUV(9);
+  this->setWaterFlow(0.08f);
+  this->setLightPos(0, 10, 0);
+  this->setWaterAngle(0);
+  this->setNormalMapScale(0.25f);
+  this->setWaterColor(0.1f, 0.2f, 0.4f);
+  this->setShineSize(128);
+  this->setShineStrength(0.7f);
+  this->setReflStrength(1.0f);
+  this->setRefraction(0.009f);
+
+  // initialization of the texture coords, speeds etc...
+  // normalUV wont change anymore
+  this->normalUV = this->waterUV * this->kNormalMapScale;
+  // move and move2 are used for the reflection and refraction, the values are changed in tick()
+  this->move = 0;
+  this->move2 = this->move * this->kNormalMapScale;
+
+  // initalize fading bools
+  this->bFadeWaterHeight = false;
+  this->bFadeWaterUV = false;
+  this->bFadeWaterFlow = false;
+  this->bFadeShineSize = false;
+  this->bFadeShineStrength = false;
+  this->bFadeReflStrength = false;
+  this->bFadeRefraction = false;
+  this->bFadeWaterColor = false;
+}
+
+/**
+ * @brief initialization of the textures
+ */
+void MappedWater::initTextures()
+{
+  // sets parameters for the textures
+  this->textureSize = 512;
+  unsigned int channels = 32;
+  GLenum type = GL_RGBA;
+
+  // set up refleciton texture
+  Texture reflTex(GL_TEXTURE_2D, this->textureSize, this->textureSize, channels, type);
+  mat.setDiffuseMap(reflTex, 0);
+  // set up refraction texture
+  Texture refrTex(GL_TEXTURE_2D, this->textureSize, this->textureSize, channels, type);
+  mat.setDiffuseMap(refrTex, 1);
+  // load normal map
+  mat.setDiffuseMap("pictures/water_normalmap.bmp", GL_TEXTURE_2D, 2);
+  // load dudv map
+  mat.setDiffuseMap("pictures/water_dudvmap.bmp", GL_TEXTURE_2D, 3);
+
+  // sets texture parameters for reflection texture
+  glBindTexture(GL_TEXTURE_2D, this->mat.diffuseTextureID(0));
+  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+  // sets texture parameters for refraction texture
+  glBindTexture(GL_TEXTURE_2D, this->mat.diffuseTextureID(1));
+  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+}
+
+/**
+ * @brief initialization of the shaders
+ */
+void MappedWater::initShaders()
+{
+  // load shader files
+  shader = ResourceShader( "shaders/mapped_water.vert", "shaders/mapped_water.frag");
+
+  this->shader.activateShader();
+  // Set the variable "reflection" to correspond to the first texture unit
+  Shader::Uniform(shader, "reflection").set(0);
+  // Set the variable "refraction" to correspond to the second texture unit
+  Shader::Uniform(shader, "refraction").set(1);
+  // Set the variable "normalMap" to correspond to the third texture unit
+  Shader::Uniform(shader, "normalMap").set(2);
+  // Set the variable "dudvMap" to correspond to the fourth texture unit
+  Shader::Uniform(shader, "dudvMap").set(3);
+  // Set the variable "depthMap" to correspond to the fifth texture unit
+  Shader::Uniform(shader, "depthMap").set(1);
+  // Give the variable "waterColor" a blue color
+  color_uni = new Shader::Uniform(shader, "waterColor");
+  color_uni->set(waterColor.x, waterColor.y, waterColor.z, 1.0f);
+  // Give the variable "lightPos" our hard coded light position
+  light_uni = new Shader::Uniform(shader, "lightPos");
+  light_uni->set(lightPos.x, lightPos.y, lightPos.z, 1.0f);
+  // Set the variable "shine"
+  shineSize_uni = new Shader::Uniform(shader, "kShine");
+  shineSize_uni->set(this->shineSize);
+  // Set the variable "shineStrength"
+  shineStrength_uni = new Shader::Uniform(shader, "shineStrength");
+  shineStrength_uni->set(this->shineStrength);
+  // Set the variable "reflStrength"
+  reflStrength_uni = new Shader::Uniform(shader, "reflStrength");
+  reflStrength_uni->set(this->reflStrength);
+  // Set the variable "refraction"
+  refr_uni = new Shader::Uniform(shader, "kRefraction");
+  refr_uni->set(this->refraction);
+  // uniform for the camera position
+  cam_uni = new Shader::Uniform(shader, "cameraPos");
+
+  this->shader.deactivateShader();
+}
+
+/**
+ * @brief calculates the 4 verts of the water quad
+ */
+void MappedWater::calcVerts()
+{
+  float deg2radtemp = this->waterAngle / 180 * PI;
+
+  this->waterVerts[2] = this->waterVerts[0] + cos(deg2radtemp) * this->xWidth;
+  this->waterVerts[3] = this->waterVerts[1] + sin(deg2radtemp) * this->xWidth;
+  this->waterVerts[4] = this->waterVerts[0] + cos(deg2radtemp) * this->xWidth - sin(deg2radtemp) * this->zWidth;
+  this->waterVerts[5] = this->waterVerts[1] + sin(deg2radtemp) * this->xWidth + cos(deg2radtemp) * this->zWidth;
+  this->waterVerts[6] = this->waterVerts[0] - sin(deg2radtemp) * this->zWidth;
+  this->waterVerts[7] = this->waterVerts[1] + cos(deg2radtemp) * this->zWidth;
+}
+
+/**
+ * @brief resets the waterColor in the Shader
+ * @param r new value for red
+ * @param g new value for green
+ * @param b new value for blue
+ */
+void MappedWater::resetWaterColor(float r, float g, float b)
+{
+  this->shader.activateShader();
+  this->waterColor = Vector(r, g, b);
+
+  // Give the variable "waterColor" a color
+  color_uni->set(waterColor.x, waterColor.y, waterColor.z, 1.0f);
+
+  this->shader.deactivateShader();
+}
+
+/**
+ * @brief resets the shininess in the Shader
+ * @param shine new value for the shininess
+ */
+void MappedWater::resetShineSize(float shine)
+{
+  this->shader.activateShader();
+  this->shineSize = shine;
+
+  // Set the variable "shine"
+  shineSize_uni->set(this->shineSize);
+
+  this->shader.deactivateShader();
+}
+
+/**
+ * @brief resets the strength of the specular reflection in the Shader
+ * @param strength new value for the strength of the specular reflection
+ */
+void MappedWater::resetShineStrength(float strength)
+{
+  this->shader.activateShader();
+  this->shineStrength = strength;
+
+  // Set the variable "shine"
+  shineStrength_uni->set(this->shineStrength);
+
+  this->shader.deactivateShader();
+}
+
+/**
+ * @brief resets the strength of the reflection in the Shader
+ * @param strength new value for the strength of the reflection
+ */
+void MappedWater::resetReflStrength(float strength)
+{
+  this->shader.activateShader();
+  this->reflStrength = strength;
+
+  // Set the variable "shine"
+  reflStrength_uni->set(this->reflStrength);
+
+  this->shader.deactivateShader();
+}
+
+/**
+ * @brief resets the refraction in the Shader
+ * @param refraction new value for the refraction
+ */
+void MappedWater::resetRefraction(float refraction)
+{
+  this->shader.activateShader();
+  this->refraction = refraction;
+
+  // Set the variable "shine"
+  refr_uni->set(this->refraction);
+
+  this->shader.deactivateShader();
+}
+
+/**
+ * @brief resets the lightPos in the Shader
+ * @param x new x value
+ * @param y new y value
+ * @param z new z value
+ */
+void MappedWater::resetLightPos(float x, float y, float z)
+{
+  this->shader.activateShader();
+  this->lightPos = Vector(x, y, z);
+
+  // Give the variable "lightPos" our hard coded light position
+  light_uni->set(lightPos.x, lightPos.y, lightPos.z, 1.0f);
+
+  this->shader.deactivateShader();
+}
+
+/**
+ * @brief ends the refraction and saves the graphic buffer into a texture
+ * @param root xml data
+ */
+void MappedWater::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "waterpos", this, MappedWater, setWaterPos);
+  LoadParam(root, "watersize", this, MappedWater, setWaterSize);
+  LoadParam(root, "wateruv", this, MappedWater, setWaterUV);
+  LoadParam(root, "waterflow", this, MappedWater, setWaterFlow);
+  LoadParam(root, "lightpos", this, MappedWater, setLightPos);
+  LoadParam(root, "waterangle", this, MappedWater, setWaterAngle);
+  LoadParam(root, "normalmapscale", this, MappedWater, setNormalMapScale);
+  LoadParam(root, "shinesize", this, MappedWater, setShineSize);
+  LoadParam(root, "shinestrength", this, MappedWater, setShineStrength);
+  LoadParam(root, "reflstrength", this, MappedWater, setReflStrength);
+  LoadParam(root, "refraction", this, MappedWater, setRefraction);
+  LoadParam(root, "watercolor", this, MappedWater, setWaterColor);
+}
+
+/**
+ * @brief prints the xml code of the water params
+ */
+void MappedWater::saveParams()
+{
+  // it's not too nice, but it works fine
+  PRINT(0)("\nMappedWater XML Code:\n<MappedWater>\n");
+
+  PRINT(0)("  <waterpos>%f, %f, %f</waterpos>\n", this->waterVerts[0], this->waterHeight, this->waterVerts[1]);
+  PRINT(0)("  <watersize>%f, %f</watersize>\n", this->xWidth, this->zWidth);
+  PRINT(0)("  <wateruv>%f</wateruv>\n", this->waterUV);
+  PRINT(0)("  <waterflow>%f</waterflow>\n", this->waterFlow);
+  PRINT(0)("  <lightpos>%f, %f, %f</lightpos>\n", this->lightPos.x, this->lightPos.y, this->lightPos.z);
+  PRINT(0)("  <waterangle>%f</waterangle>\n", this->waterAngle);
+  PRINT(0)("  <normalmapscale>%f</normalmapscale>\n", this->kNormalMapScale);
+  PRINT(0)("  <shinesize>%f</shinesize>\n", this->shineSize);
+  PRINT(0)("  <shinestrength>%f</shinestrength>\n", this->shineStrength);
+  PRINT(0)("  <reflstrength>%f</reflstrength>\n", this->reflStrength);
+  PRINT(0)("  <refraction>%f</refraction>\n", this->refraction);
+  PRINT(0)("  <watercolor>%f, %f, %f</watercolor>\n", this->waterColor.x, this->waterColor.y, this->waterColor.z);
+
+  PRINT(0)("</MappedWater>\n");
+}
+
+/**
+ * @brief starts the slider gui that lets you edit all water parameters
+ */
+void MappedWater::toggleGui()
+{
+  if (this->box == NULL)
+  {
+    this->box = new OrxGui::GLGuiBox(OrxGui::Vertical);
+    {
+      OrxGui::GLGuiBox* waterColorBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
+      {
+        OrxGui::GLGuiText* waterColorText = new OrxGui::GLGuiText();
+        waterColorText->setText("WaterColor");
+        waterColorBox->pack(waterColorText);
+
+        OrxGui::GLGuiSlider* waterColorR = new OrxGui::GLGuiSlider();
+        waterColorR->setRange(0, 1.0f);
+        waterColorR->setValue(this->waterColor.x);
+        waterColorR->setStep(0.1f);
+        waterColorR->valueChanged.connect(this, &MappedWater::resetWaterColorR);
+        waterColorBox->pack(waterColorR);
+
+        OrxGui::GLGuiSlider* waterColorG = new OrxGui::GLGuiSlider();
+        waterColorG->setRange(0, 1.0f);
+        waterColorG->setStep(0.1f);
+        waterColorG->setValue(this->waterColor.y);
+        waterColorG->valueChanged.connect(this, &MappedWater::resetWaterColorG);
+        waterColorBox->pack(waterColorG);
+
+        OrxGui::GLGuiSlider* waterColorB = new OrxGui::GLGuiSlider();
+        waterColorB->setRange(0, 1.0f);
+        waterColorB->setStep(0.1f);
+        waterColorB->setValue(this->waterColor.z);
+        waterColorB->valueChanged.connect(this, &MappedWater::resetWaterColorB);
+        waterColorBox->pack(waterColorB);
+      }
+      this->box->pack(waterColorBox);
+
+      OrxGui::GLGuiBox* waterUVBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
+      {
+        OrxGui::GLGuiText* waterUVText = new OrxGui::GLGuiText();
+        waterUVText->setText("WaterUV");
+        waterUVBox->pack(waterUVText);
+
+        OrxGui::GLGuiSlider* waterUV = new OrxGui::GLGuiSlider();
+        waterUV->setRange(1, 20);
+        waterUV->setValue(this->waterUV);
+        waterUV->setStep(1);
+        waterUV->valueChanged.connect(this, &MappedWater::setWaterUV);
+        waterUVBox->pack(waterUV);
+      }
+      this->box->pack(waterUVBox);
+
+      OrxGui::GLGuiBox* waterFlowBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
+      {
+        OrxGui::GLGuiText* waterFlowText = new OrxGui::GLGuiText();
+        waterFlowText->setText("WaterFlow");
+        waterFlowBox->pack(waterFlowText);
+
+        OrxGui::GLGuiSlider* waterFlow = new OrxGui::GLGuiSlider();
+        waterFlow->setRange(0.01f, 2);
+        waterFlow->setValue(this->waterFlow);
+        waterFlow->setStep(0.02f);
+        waterFlow->valueChanged.connect(this, &MappedWater::setWaterFlow);
+        waterFlowBox->pack(waterFlow);
+      }
+      this->box->pack(waterFlowBox);
+
+      OrxGui::GLGuiBox* shineSizeBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
+      {
+        OrxGui::GLGuiText* shineSizeText = new OrxGui::GLGuiText();
+        shineSizeText->setText("ShineSize");
+        shineSizeBox->pack(shineSizeText);
+
+        OrxGui::GLGuiSlider* shineSize = new OrxGui::GLGuiSlider();
+        shineSize->setRange(1, 128);
+        shineSize->setValue(this->shineSize);
+        shineSize->setStep(1);
+        shineSize->valueChanged.connect(this, &MappedWater::resetShineSize);
+        shineSizeBox->pack(shineSize);
+      }
+      this->box->pack(shineSizeBox);
+
+      OrxGui::GLGuiBox* shineStrengthBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
+      {
+        OrxGui::GLGuiText* shineStrengthText = new OrxGui::GLGuiText();
+        shineStrengthText->setText("ShineStrength");
+        shineStrengthBox->pack(shineStrengthText);
+
+        OrxGui::GLGuiSlider* shineStrength = new OrxGui::GLGuiSlider();
+        shineStrength->setRange(0, 1);
+        shineStrength->setValue(this->shineStrength);
+        shineStrength->setStep(0.1f);
+        shineStrength->valueChanged.connect(this, &MappedWater::resetShineStrength);
+        shineStrengthBox->pack(shineStrength);
+      }
+      this->box->pack(shineStrengthBox);
+
+      OrxGui::GLGuiBox* reflStrengthBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
+      {
+        OrxGui::GLGuiText* reflStrengthText = new OrxGui::GLGuiText();
+        reflStrengthText->setText("ReflStrength");
+        reflStrengthBox->pack(reflStrengthText);
+
+        OrxGui::GLGuiSlider* reflStrength = new OrxGui::GLGuiSlider();
+        reflStrength->setRange(0, 1);
+        reflStrength->setValue(this->reflStrength);
+        reflStrength->setStep(0.1f);
+        reflStrength->valueChanged.connect(this, &MappedWater::resetReflStrength);
+        reflStrengthBox->pack(reflStrength);
+      }
+      this->box->pack(reflStrengthBox);
+
+      OrxGui::GLGuiBox* refractionBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
+      {
+        OrxGui::GLGuiText* refractionText = new OrxGui::GLGuiText();
+        refractionText->setText("Refraction");
+        refractionBox->pack(refractionText);
+
+        OrxGui::GLGuiSlider* refraction = new OrxGui::GLGuiSlider();
+        refraction->setRange(0.001f, 0.1f);
+        refraction->setValue(this->refraction);
+        refraction->setStep(0.004f);
+        refraction->valueChanged.connect(this, &MappedWater::resetRefraction);
+        refractionBox->pack(refraction);
+      }
+      this->box->pack(refractionBox);
+
+      OrxGui::GLGuiBox* lightPosBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
+      {
+        OrxGui::GLGuiText* lightPosText = new OrxGui::GLGuiText();
+        lightPosText->setText("LightPos");
+        lightPosBox->pack(lightPosText);
+
+        OrxGui::GLGuiSlider* lightPosX = new OrxGui::GLGuiSlider();
+        lightPosX->setRange(-4000, 4000);
+        lightPosX->setValue(this->lightPos.x);
+        lightPosX->setStep(15);
+        lightPosX->valueChanged.connect(this, &MappedWater::resetLightPosX);
+        lightPosBox->pack(lightPosX);
+
+        OrxGui::GLGuiSlider* lightPosY = new OrxGui::GLGuiSlider();
+        lightPosY->setRange(-4000, 4000);
+        lightPosY->setStep(15);
+        lightPosY->setValue(this->lightPos.y);
+        lightPosY->valueChanged.connect(this, &MappedWater::resetLightPosY);
+        lightPosBox->pack(lightPosY);
+
+        OrxGui::GLGuiSlider* lightPosZ = new OrxGui::GLGuiSlider();
+        lightPosZ->setRange(-4000, 4000);
+        lightPosZ->setStep(15);
+        lightPosZ->setValue(this->lightPos.z);
+        lightPosZ->valueChanged.connect(this, &MappedWater::resetLightPosZ);
+        lightPosBox->pack(lightPosZ);
+      }
+      this->box->pack(lightPosBox);
+
+      OrxGui::GLGuiBox* waterHeightBox = new OrxGui::GLGuiBox(OrxGui::Horizontal);
+      {
+        OrxGui::GLGuiText* waterHeightText = new OrxGui::GLGuiText();
+        waterHeightText->setText("WaterHeight");
+        waterHeightBox->pack(waterHeightText);
+
+        OrxGui::GLGuiSlider* waterHeight = new OrxGui::GLGuiSlider();
+        waterHeight->setRange(100, 370);
+        waterHeight->setValue(this->waterHeight);
+        waterHeight->setStep(4);
+        waterHeight->valueChanged.connect(this, &MappedWater::setWaterHeight);
+        waterHeightBox->pack(waterHeight);
+      }
+      this->box->pack(waterHeightBox);
+    }
+
+    this->box->showAll();
+    this->box->setAbsCoor2D(300, 40);
+    OrxGui::GLGuiHandler::getInstance()->activate();
+    OrxGui::GLGuiHandler::getInstance()->activateCursor();
+  }
+  else
+  {
+    OrxGui::GLGuiHandler::getInstance()->deactivate();
+    OrxGui::GLGuiHandler::getInstance()->deactivateCursor();
+    delete this->box;
+    this->box = NULL;
+  }
+}
+
+/**
+ * @brief activates the water shader and draws a quad with four textures on it
+ */
+void MappedWater::draw() const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  // don't use glRotate or glTranslate here... the shader won't work anymore
+
+  mat.select();
+
+  this->shader.activateShader();
+
+  // reset the camera uniform to the current cam position
+  Vector pos = State::getCameraNode()->getAbsCoor();
+  cam_uni->set(pos.x, pos.y, pos.z, 1.0f);
+
+  glDisable(GL_BLEND);
+
+  // TODO change texture coords, so water doesnt look distorted when xWidth != zWidth
+  glBegin(GL_QUADS);
+  // The back left vertice for the water
+  glMultiTexCoord2f(GL_TEXTURE0, 0, waterUV);                   // Reflection texture
+  glMultiTexCoord2f(GL_TEXTURE1, 0, waterUV - move);            // Refraction texture
+  glMultiTexCoord2f(GL_TEXTURE2, 0, normalUV + move2);          // Normal map texture
+  glMultiTexCoord2f(GL_TEXTURE3, 0, 0);                         // DUDV map texture
+  glVertex3f(this->waterVerts[0], this->waterHeight, this->waterVerts[1]);
+
+  // The front left vertice for the water
+  glMultiTexCoord2f(GL_TEXTURE0, 0, 0);                         // Reflection texture
+  glMultiTexCoord2f(GL_TEXTURE1, 0, -move);                     // Refraction texture
+  glMultiTexCoord2f(GL_TEXTURE2, 0, move2);                     // Normal map texture
+  glMultiTexCoord2f(GL_TEXTURE3, 0, 0);                         // DUDV map texture
+  glVertex3f(this->waterVerts[2], this->waterHeight, this->waterVerts[3]);
+
+  // The front right vertice for the water
+  glMultiTexCoord2f(GL_TEXTURE0, waterUV, 0);                   // Reflection texture
+  glMultiTexCoord2f(GL_TEXTURE1, waterUV, -move);               // Refraction texture
+  glMultiTexCoord2f(GL_TEXTURE2, normalUV, move2);              // Normal map texture
+  glMultiTexCoord2f(GL_TEXTURE3, 0, 0);                         // DUDV map texture
+  glVertex3f(this->waterVerts[4], this->waterHeight, this->waterVerts[5]);
+
+  // The back right vertice for the water
+  glMultiTexCoord2f(GL_TEXTURE0, waterUV, waterUV);             // Reflection texture
+  glMultiTexCoord2f(GL_TEXTURE1, waterUV, waterUV - move);      // Refraction texture
+  glMultiTexCoord2f(GL_TEXTURE2, normalUV, normalUV + move2);   // Normal map texture
+  glMultiTexCoord2f(GL_TEXTURE3, 0, 0);                         // DUDV map texture
+  glVertex3f(this->waterVerts[6], this->waterHeight, this->waterVerts[7]);
+  glEnd();
+
+  this->shader.deactivateShader();
+
+  mat.unselect();
+
+  glPopMatrix();
+}
+
+/**
+ * @brief tick tack, calculates the flow of the water
+ */
+void MappedWater::tick(float dt)
+{
+  // makes the water flow
+  this->move += this->waterFlow * dt;
+  this->move2 = this->move * this->kNormalMapScale;
+
+  // fading TODO fix this so it isnt hacky anymore
+  if(bFadeWaterUV)
+  {
+    this->waterUVFader = new tAnimation<MappedWater>(this, &MappedWater::setWaterUV);
+    this->waterUVFader->setInfinity(ANIM_INF_CONSTANT);
+
+    this->waterUVFader->addKeyFrame(this->waterUV, this->waterUVFadeTime, ANIM_LINEAR);
+    this->waterUVFader->addKeyFrame(this->newWaterUV, 0, ANIM_LINEAR);
+
+    bFadeWaterUV = false;
+    this->waterUVFader->replay();
+  }
+
+  if(bFadeWaterFlow)
+  {
+    this->waterFlowFader = new tAnimation<MappedWater>(this, &MappedWater::setWaterFlow);
+    this->waterFlowFader->setInfinity(ANIM_INF_CONSTANT);
+
+    this->waterFlowFader->addKeyFrame(this->waterFlow, this->waterFlowFadeTime, ANIM_LINEAR);
+    this->waterFlowFader->addKeyFrame(this->newWaterFlow, 0, ANIM_LINEAR);
+
+    bFadeWaterFlow = false;
+    this->waterFlowFader->replay();
+  }
+
+  if(bFadeShineSize)
+  {
+    this->shineSizeFader = new tAnimation<MappedWater>(this, &MappedWater::resetShineSize);
+    this->shineSizeFader->setInfinity(ANIM_INF_CONSTANT);
+
+    this->shineSizeFader->addKeyFrame(this->shineSize, this->shineSizeFadeTime, ANIM_LINEAR);
+    this->shineSizeFader->addKeyFrame(this->newShineSize, 0, ANIM_LINEAR);
+
+    bFadeShineSize = false;
+    this->shineSizeFader->replay();
+  }
+
+  if(bFadeShineStrength)
+  {
+    this->shineStrengthFader = new tAnimation<MappedWater>(this, &MappedWater::resetShineStrength);
+    this->shineStrengthFader->setInfinity(ANIM_INF_CONSTANT);
+
+    this->shineStrengthFader->addKeyFrame(this->shineStrength, this->shineStrengthFadeTime, ANIM_LINEAR);
+    this->shineStrengthFader->addKeyFrame(this->newShineStrength, 0, ANIM_LINEAR);
+
+    bFadeShineStrength = false;
+    this->shineStrengthFader->replay();
+  }
+
+  if(bFadeReflStrength)
+  {
+    this->reflStrengthFader = new tAnimation<MappedWater>(this, &MappedWater::resetReflStrength);
+    this->reflStrengthFader->setInfinity(ANIM_INF_CONSTANT);
+
+    this->reflStrengthFader->addKeyFrame(this->reflStrength, this->reflStrengthFadeTime, ANIM_LINEAR);
+    this->reflStrengthFader->addKeyFrame(this->newReflStrength, 0, ANIM_LINEAR);
+
+    bFadeReflStrength = false;
+    this->reflStrengthFader->replay();
+  }
+
+  if(bFadeRefraction)
+  {
+    this->refractionFader = new tAnimation<MappedWater>(this, &MappedWater::resetRefraction);
+    this->refractionFader->setInfinity(ANIM_INF_CONSTANT);
+
+    this->refractionFader->addKeyFrame(this->refraction, this->refractionFadeTime, ANIM_LINEAR);
+    this->refractionFader->addKeyFrame(this->newRefraction, 0, ANIM_LINEAR);
+
+    bFadeRefraction = false;
+    this->refractionFader->replay();
+  }
+
+  if(bFadeWaterHeight)
+  {
+    this->waterHeightFader = new tAnimation<MappedWater>(this, &MappedWater::setWaterHeight);
+    this->waterHeightFader->setInfinity(ANIM_INF_CONSTANT);
+
+    this->waterHeightFader->addKeyFrame(this->waterHeight, this->waterHeightFadeTime, ANIM_LINEAR);
+    this->waterHeightFader->addKeyFrame(this->newWaterHeight, 0, ANIM_LINEAR);
+
+    bFadeWaterHeight = false;
+    this->waterHeightFader->replay();
+  }
+
+  if(bFadeWaterColor)
+  {
+    this->waterColorRFader = new tAnimation<MappedWater>(this, &MappedWater::resetWaterColorR);
+    this->waterColorRFader->setInfinity(ANIM_INF_CONSTANT);
+
+    this->waterColorRFader->addKeyFrame(this->waterColor.x, this->waterColorFadeTime, ANIM_LINEAR);
+    this->waterColorRFader->addKeyFrame(this->newWaterColor.x, 0, ANIM_LINEAR);
+
+    this->waterColorRFader->replay();
+
+    this->waterColorGFader = new tAnimation<MappedWater>(this, &MappedWater::resetWaterColorG);
+    this->waterColorGFader->setInfinity(ANIM_INF_CONSTANT);
+
+    this->waterColorGFader->addKeyFrame(this->waterColor.y, this->waterColorFadeTime, ANIM_LINEAR);
+    this->waterColorGFader->addKeyFrame(this->newWaterColor.y, 0, ANIM_LINEAR);
+
+    this->waterColorGFader->replay();
+
+    this->waterColorBFader = new tAnimation<MappedWater>(this, &MappedWater::resetWaterColorB);
+    this->waterColorBFader->setInfinity(ANIM_INF_CONSTANT);
+
+    this->waterColorBFader->addKeyFrame(this->waterColor.z, this->waterColorFadeTime, ANIM_LINEAR);
+    this->waterColorBFader->addKeyFrame(this->newWaterColor.z, 0, ANIM_LINEAR);
+
+    this->waterColorBFader->replay();
+
+    bFadeWaterColor = false;
+  }
+}
+
+/**
+ * @brief prepares everything to render the reflection texutre
+ */
+void MappedWater::activateReflection()
+{
+  // To create the reflection texture we just need to set the view port
+  // to our texture map size, then render the current scene our camera
+  // is looking at to the already allocated texture unit.  Since this
+  // is a reflection of the top of the water surface we use clipping
+  // planes to only render the top of the world as a reflection.  If
+  // we are below the water we don't flip the reflection but just use
+  // the current view of the top as we are seeing through the water.
+  // When you look through water at the surface it isn't really reflected,
+  // only when looking down from above the water on the surface.
+
+  // save viewport matrix and change the viewport size
+  glPushAttrib(GL_VIEWPORT_BIT);
+  glViewport(0,0, textureSize, textureSize);
+
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  // If our camera is above the water we will render the scene flipped upside down.
+  // In order to line up the reflection nicely with the world we have to translate
+  // the world to the position of our reflected surface, multiplied by two.
+  glEnable(GL_CLIP_PLANE0);
+  Vector pos = State::getCameraNode()->getAbsCoor();
+
+  if(pos.y > waterHeight)
+  {
+    // Translate the world, then flip it upside down
+    glTranslatef(0, waterHeight * 2, 0);
+    glScalef(1, -1, 1);
+
+    // Since the world is updside down we need to change the culling to FRONT
+    glCullFace(GL_FRONT);
+
+    // Set our plane equation and turn clipping on
+    double plane[4] = {0, 1, 0, -waterHeight};
+    glClipPlane(GL_CLIP_PLANE0, plane);
+  }
+  else
+  {
+    // If the camera is below the water we don't want to flip the world,
+    // but just render it clipped so only the top is drawn.
+    double plane[4] = {0, 1, 0, waterHeight};
+    glClipPlane(GL_CLIP_PLANE0, plane);
+  }
+}
+
+/**
+ * @brief ends the reflection and saves the graphic buffer into a texture
+ */
+void MappedWater::deactivateReflection()
+{
+  glDisable(GL_CLIP_PLANE0);
+  glCullFace(GL_BACK);
+
+  // Create the texture and store it on the video card
+  mat.renderToTexture(0, GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureSize, textureSize);
+
+  glPopMatrix();
+  glPopAttrib();
+}
+
+/**
+ * @brief prepares everything to render the refraction texutre
+ */
+void MappedWater::activateRefraction()
+{
+  // To create the refraction and depth textures we do the same thing
+  // we did for the reflection texture, except we don't need to turn
+  // the world upside down.  We want to find the depth of the water,
+  // not the depth of the sky and above water terrain.
+
+  // save viewport matrix and change the viewport size
+  glPushAttrib(GL_VIEWPORT_BIT);
+  glViewport(0,0, textureSize, textureSize);
+
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  // If our camera is above the water we will render only the parts that
+  // are under the water.  If the camera is below the water we render
+  // only the stuff above the water.  Like the reflection texture, we
+  // incorporate clipping planes to only render what we need.
+
+  // If the camera is above water, render the data below the water
+  glEnable(GL_CLIP_PLANE0);
+  Vector pos = State::getCameraNode()->getAbsCoor();
+  if(pos.y > waterHeight)
+  {
+    double plane[4] = {0, -1, 0, waterHeight};
+    glClipPlane(GL_CLIP_PLANE0, plane);
+  }
+  // If the camera is below the water, only render the data above the water
+  else
+  {
+    glCullFace(GL_FRONT);
+    double plane[4] = {0, 1, 0, -waterHeight};
+    glClipPlane(GL_CLIP_PLANE0, plane);
+  }
+}
+
+/**
+ * @brief ends the refraction and saves the graphic buffer into a texture
+ */
+void MappedWater::deactivateRefraction()
+{
+  glDisable(GL_CLIP_PLANE0);
+  glCullFace(GL_BACK);
+
+  // Create the texture and store it on the video card
+  mat.renderToTexture(1, GL_TEXTURE_2D, 0, 0, 0, 0, 0, textureSize, textureSize);
+
+  glPopMatrix();
+  glPopAttrib();
+}
Index: branches/heathaze/src/world_entities/environments/mapped_water.h
===================================================================
--- branches/heathaze/src/world_entities/environments/mapped_water.h	(revision 9940)
+++ branches/heathaze/src/world_entities/environments/mapped_water.h	(revision 9940)
@@ -0,0 +1,181 @@
+ /*!
+ * @file mapped_water.h
+ *  worldentity for flat, cool looking, mapped water
+*/
+/*! example input in .oxw file with the standard values
+<MappedWater>
+  <waterpos>0,0,0</waterpos>
+  <watersize>100,100</watersize>
+  <wateruv>9</wateruv><!-- size of the waves -->
+  <waterflow>0.08</waterflow>
+  <lightpos>0,10,0</lightpos>
+  <waterangle>0</waterangle>
+  <normalmapscale>0.25</normalmapscale><!-- you won't see a big differnce if you change that -->
+  <shinesize>128</shinesize><!-- the bigger the value, the smaller the specular reflection point -->
+  <shinestrength>0.7</shinestrength>
+  <reflstrength>1</reflstrength>
+  <refraction>0.009</refraction>
+  <watercolor>0.1, 0.2, 0.4</watercolor>
+</MappedWater>
+*/
+
+
+#ifndef _MAPPED_WATER_H
+#define _MAPPED_WATER_H
+
+#include "world_entity.h"
+#include "material.h"
+#include "shader.h"
+
+namespace OrxGui { class GLGuiBox; };
+
+// forward declaration
+template <class T> class tAnimation;
+
+class MappedWater : public WorldEntity
+{
+  ObjectListDeclaration(MappedWater);
+public:
+  MappedWater(const TiXmlElement* root = NULL);
+  virtual ~MappedWater();
+
+  // worldentity functions
+  void loadParams(const TiXmlElement* root);
+  void saveParams();
+  void draw() const;
+  void tick(float dt);
+
+  // function to prepare renderpaths for creation of refleaction and reflaction textures
+  void activateReflection();
+  void deactivateReflection();
+  void activateRefraction();
+  void deactivateRefraction();
+
+  // slider gui to edit water params during gameplay
+  void toggleGui();
+
+  // functions to set parameters for the water, usually they're called through loadparam
+  void setLightPos(float x, float y, float z) { this->lightPos = Vector(x,y,z); }
+  void setWaterPos(float x, float y, float z) { this->waterHeight = y; this->waterVerts[0] = x; this->waterVerts[1] = z; }
+  void setWaterHeight(float y) { this->waterHeight = y;  }
+  void setWaterSize(float x, float z) { this->xWidth = x; this->zWidth = z; }
+  void setWaterAngle(float angle) { this->waterAngle = angle; }
+  void setWaterColor(float r, float g, float b) { this->waterColor = Vector(r,g,b); }
+  void setWaterUV(float uv) { this->waterUV = uv; }
+  void setWaterFlow(float flow) { this->waterFlow = flow; }
+  void setNormalMapScale(float scale) { this->kNormalMapScale = scale; }
+  void setShineSize(float shine) { this->shineSize = shine; }
+  void setShineStrength(float strength) { this->shineStrength = strength; }
+  void setReflStrength(float strength) { this->reflStrength = strength; }
+  void setRefraction(float refraction) { this->refraction = refraction; }
+
+  // functions to change water parameters during runtime
+  // to reset waterUV and waterFlow just use the normal set functions
+  // don't reset kNormalMapScale (because it won't change anything)
+  void resetLightPos(float x, float y, float z);
+  void resetLightPosX(float x) { this->resetLightPos(x, this->lightPos.y, this->lightPos.z); }
+  void resetLightPosY(float y) { this->resetLightPos(this->lightPos.x, y, this->lightPos.z); }
+  void resetLightPosZ(float z) { this->resetLightPos(this->lightPos.x, this->lightPos.y, z); }
+  void resetWaterPos(float x, float y, float z) { this->setWaterPos(x, y, z); this->calcVerts(); }
+  void resetWaterSize(float x, float z) { this->setWaterSize(x, z); this->calcVerts(); }
+  void resetWaterAngle(float angle) { this->setWaterAngle(angle); this->calcVerts(); }
+  void resetWaterColor(float r, float g, float b);
+  void resetWaterColorR(float r) { this->resetWaterColor(r, this->waterColor.y, this->waterColor.z); }
+  void resetWaterColorG(float g) { this->resetWaterColor(this->waterColor.x, g, this->waterColor.z); }
+  void resetWaterColorB(float b) { this->resetWaterColor(this->waterColor.x, this->waterColor.y, b); }
+  void resetShineSize(float shine);
+  void resetShineStrength(float strength);
+  void resetReflStrength(float strength);
+  void resetRefraction(float refraction);
+
+  // fading functions
+  void fadeWaterUV(float uv, float time) { this->newWaterUV = uv; this->waterUVFadeTime = time; this->bFadeWaterUV = true; }
+  void fadeWaterFlow(float flow, float time) { this->newWaterFlow = flow; this->waterFlowFadeTime = time; this->bFadeWaterFlow = true; }
+  void fadeShineSize(float shine, float time) { this->newShineSize = shine; this->shineSizeFadeTime = time; this->bFadeShineSize = true; }
+  void fadeShineStrength(float strength, float time) { this->newShineStrength = strength; this->shineStrengthFadeTime = time; this->bFadeShineStrength = true; }
+  void fadeReflStrength(float strength, float time) { this->newReflStrength = strength; this->reflStrengthFadeTime = time; this->bFadeReflStrength = true; }
+  void fadeRefraction(float refraction, float time) { this->newRefraction = refraction; this->refractionFadeTime = time; this->bFadeRefraction = true; }
+  void fadeWaterHeight(float y, float time) { this->newWaterHeight = y; this->waterHeightFadeTime = time; this->bFadeWaterHeight = true; }
+  void fadeWaterColor(float r, float g, float b, float time) { this->newWaterColor = Vector(r, g, b); this->waterColorFadeTime = time; this->bFadeWaterColor = true; }
+
+private:
+  void initParams();
+  void initTextures();
+  void initShaders();
+  void calcVerts();
+
+private:
+  Material                  mat;
+  Shader                    shader;
+  OrxGui::GLGuiBox*         box;
+
+  // water size and position
+  float                     waterHeight;            //!< position of the water
+  float                     waterVerts[8];          //!< coords of the 4 vertexes of the water quad
+  float                     xWidth, zWidth;         //!< size of the water quad
+  float                     waterAngle;             //!< defines how much the water will be turned around the point waterPos
+
+  // values for texture size, scale, texture coords
+  float                     move;
+  float                     move2;
+  float                     waterUV;                //!< size of the waves
+  float                     waterFlow;              //!< speed of the water
+  float                     normalUV;
+  float                     kNormalMapScale;
+  int                       textureSize;            //!< height and width of the texture
+
+  // values for the uniforms
+  Vector                    waterColor;             //!< color of the water
+  Vector                    lightPos;               //!< position of the light that is used to render the reflection
+  float                     shineSize;              //!< the bigger the value, the smaller the specular reflection point
+  float                     shineStrength;
+  float                     reflStrength;
+  float                     refraction;
+
+  // uniforms
+  Shader::Uniform*          cam_uni;                //!< uniform that is used for the camera position
+  Shader::Uniform*          light_uni;              //!< uniform that is used for the light position
+  Shader::Uniform*          color_uni;              //!< uniform that is used for the watercolor
+  Shader::Uniform*          shineSize_uni;          //!< uniform that is used for the specular shininessd of the water
+  Shader::Uniform*          shineStrength_uni;      //!< uniform that is used for the strenght of the specular reflection
+  Shader::Uniform*          reflStrength_uni;       //!< uniform that is used for the strength of the reflection
+  Shader::Uniform*          refr_uni;               //!< uniform that is used for the strength of the refraction
+
+  // fading TODO fix this so it isnt so hacky anymore
+  tAnimation<MappedWater>*  waterUVFader;
+  float                     newWaterUV;
+  float                     waterUVFadeTime;
+  bool                      bFadeWaterUV ;
+  tAnimation<MappedWater>*  waterFlowFader;
+  float                     newWaterFlow;
+  float                     waterFlowFadeTime;
+  bool                      bFadeWaterFlow;
+  tAnimation<MappedWater>*  shineSizeFader;
+  float                     newShineSize;
+  float                     shineSizeFadeTime;
+  bool                      bFadeShineSize;
+  tAnimation<MappedWater>*  shineStrengthFader;
+  float                     newShineStrength;
+  float                     shineStrengthFadeTime;
+  bool                      bFadeShineStrength;
+  tAnimation<MappedWater>*  reflStrengthFader;
+  float                     newReflStrength;
+  float                     reflStrengthFadeTime;
+  bool                      bFadeReflStrength;
+  tAnimation<MappedWater>*  refractionFader;
+  float                     newRefraction;
+  float                     refractionFadeTime;
+  bool                      bFadeRefraction;
+  tAnimation<MappedWater>*  waterHeightFader;
+  float                     newWaterHeight;
+  float                     waterHeightFadeTime;
+  bool                      bFadeWaterHeight;
+  tAnimation<MappedWater>*  waterColorRFader;
+  tAnimation<MappedWater>*  waterColorGFader;
+  tAnimation<MappedWater>*  waterColorBFader;
+  Vector                    newWaterColor;
+  float                     waterColorFadeTime;
+  bool                      bFadeWaterColor;
+};
+
+#endif
Index: branches/heathaze/src/world_entities/environments/model_entity.cc
===================================================================
--- branches/heathaze/src/world_entities/environments/model_entity.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/environments/model_entity.cc	(revision 9940)
@@ -0,0 +1,98 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "model_entity.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(ModelEntity, CL_MODEL_ENTITY);
+CREATE_FACTORY(ModelEntity);
+
+/**
+ *  initializes a skybox from a XmlElement
+*/
+ModelEntity::ModelEntity(const TiXmlElement* root)
+{
+  this->registerObject(this, ModelEntity::_objectList);
+  this->toList(OM_ENVIRON);
+
+  this->speed = NULL;
+  this->momentum = NULL;
+
+  this->setSynchronized(true);
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ *  default destructor
+*/
+ModelEntity::~ModelEntity()
+{
+  if (this->speed != NULL)
+    delete this->speed;
+  if (this->momentum)
+    delete this->momentum;
+}
+
+void ModelEntity::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "speed", this, ModelEntity, setSpeed);
+  LoadParam(root, "momentum", this, ModelEntity, setMomentum);
+}
+
+
+void ModelEntity::setSpeed(float x, float y, float z)
+{
+  if (this->speed == NULL)
+    this->speed = new Vector;
+  *this->speed = Vector(x,y,z);
+}
+
+void ModelEntity::setMomentum (float angle, float x, float y, float z)
+{
+  Vector v(x,y,z);
+  v.debug();
+  v.normalize();
+  v.debug();
+
+  if (this->momentum == NULL)
+    this->momentum = new Quaternion;
+  *this->momentum = Quaternion(angle, v);
+
+  this->momentum->debug();
+}
+
+void ModelEntity::tick(float dt)
+{
+  if (this->speed != NULL)
+    this->shiftCoor(*this->speed * dt);
+
+  if (this->momentum != NULL)
+  {
+    this->shiftDir((*this->momentum * dt ).getNormalized());
+    //this->getAbsDir().debug();
+  }
+}
Index: branches/heathaze/src/world_entities/environments/model_entity.h
===================================================================
--- branches/heathaze/src/world_entities/environments/model_entity.h	(revision 9940)
+++ branches/heathaze/src/world_entities/environments/model_entity.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file model_entity.h
+ *  Definition of the ModelEntity, that handles the Display of an atmosphere for orxonox.
+ */
+
+#ifndef _MODEL_ENTITY_H
+#define _MODEL_ENTITY_H
+
+/* INCLUDES */
+#include "world_entity.h"
+
+/* FORWARD DECLARATION */
+
+//! A Class to handle a ModelEntity
+class ModelEntity : public WorldEntity
+{
+  ObjectListDeclaration(ModelEntity);
+ public:
+  ModelEntity(const TiXmlElement* root);
+
+  virtual ~ModelEntity();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setSpeed(float x, float y, float z);
+  void setMomentum (float angle, float x, float y, float z);
+
+  virtual void tick(float dt);
+
+  private:
+    Vector*           speed;
+    Quaternion*       momentum;
+};
+
+#endif  /* _MODEL_ENTITY_H */
+
+
+
Index: branches/heathaze/src/world_entities/environments/water.cc
===================================================================
--- branches/heathaze/src/world_entities/environments/water.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/environments/water.cc	(revision 9940)
@@ -0,0 +1,317 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "water.h"
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+#include "grid.h"
+#include "material.h"
+
+#include "resource_shader.h"
+
+#include "skybox.h"
+#include "state.h"
+
+
+#include "network_game_manager.h"
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Water, CL_WATER);
+CREATE_FACTORY(Water);
+
+
+Water::Water(const TiXmlElement* root)
+{
+  this->registerObject(this, Water::_objectList);
+  this->toList(OM_ENVIRON);
+
+  this->resX = this->resY = 10;
+  this->sizeX = this->sizeY = 1.0f;
+  this->height = 0.5f;
+  this->grid = NULL;
+
+  this->velocities = NULL;
+  this->viscosity = 5;
+  this->cohesion = .0000000001;
+
+  if (root != NULL)
+    this->loadParams(root);
+
+  this->rebuildGrid();
+  this->waterShader = ResourceShader("shaders/water.vert", "shaders/water.frag");
+
+  // To test the Wave equation
+  //this->wave(5.0,4.0, 1, 10);
+
+  height_handle = registerVarId( new SynchronizeableFloat( &height, &height, "height", PERMISSION_MASTER_SERVER ) );
+  resX_handle = registerVarId( new SynchronizeableUInt( &resX, &resX, "resX", PERMISSION_MASTER_SERVER ) );
+  resY_handle = registerVarId( new SynchronizeableUInt( &resY, &resY, "resY", PERMISSION_MASTER_SERVER ) );
+  sizeX_handle = registerVarId( new SynchronizeableFloat( &sizeX, &sizeX, "sizeX", PERMISSION_MASTER_SERVER ) );
+  sizeY_handle = registerVarId( new SynchronizeableFloat( &sizeY, &sizeY, "sizeY", PERMISSION_MASTER_SERVER ) );
+}
+
+Water::~Water()
+{
+}
+
+void Water::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "size", this, Water, setSize)
+  .describe("the size of the WaterSurface")
+  .defaultValues(1.0f, 1.0f);
+
+  LoadParam(root, "resolution", this, Water, setResolution)
+  .describe("sets the resolution of the water surface")
+  .defaultValues(10, 10);
+
+  LoadParam(root, "height", this, Water, setHeight)
+  .describe("the height of the Waves")
+  .defaultValues(0.5f);
+}
+
+/**
+ * @brief rebuilds the Grid below the WaterSurface, killing all hight information
+ *
+ * This should be called on all subGrid changes except wave and tick.
+ */
+void Water::rebuildGrid()
+{
+  if (this->velocities != NULL)
+  {
+    assert (this->grid != NULL);
+    for (unsigned int i = 0; i < this->grid->rows(); i++)
+      delete[] this->velocities[i];
+    delete[] this->velocities;
+  }
+
+  //   WE DO NOT NEED THIS AS IT IS DONE IN WORLDENTITY->setModel();
+  //   if (this->grid != NULL)
+  //     this->grid = NULL;
+
+  this->grid = new Grid(this->sizeX, this->sizeY, this->resX, this->resY);
+  this->velocities = new float*[this->resX];
+  for (unsigned int i = 0; i < this->grid->rows(); i++)
+  {
+    this->velocities[i] = new float[this->resY];
+    for (unsigned int j = 0; j < this->resY; j++)
+      this->velocities[i][j] = 0.0;
+  }
+  this->setModel(this->grid, 0);
+}
+
+void Water::wave(float x, float y, float z, float force)
+{
+  unsigned int row = 0, column = 0;
+  if (!this->posToGridPoint( x, z, row, column))
+    return;
+  this->grid->height(row, column) -= force / ((y - this->getAbsCoor().y) +.1);
+}
+
+/**
+ * after this a rebuild() must be called
+ */
+void Water::setResolution(unsigned int resX, unsigned int resY)
+{
+  this->resX = resX;
+  this->resY = resY;
+}
+
+/**
+ * after this a rebuild() must be called
+ */
+void Water::setSize(float sizeX, float sizeY)
+{
+  this->sizeX = sizeX;
+  this->sizeY = sizeY;
+}
+
+void Water::setHeight(float height)
+{
+  this->height = height;
+}
+
+
+/**
+ * @brief calculated the Position in the Grid, this Point is nearest to
+ * @param x, the x-position over the Grid
+ * @param z: the z-Position(or y) over the Grid
+ * @param row returns the row if not out of range
+ * @param column returns the column if not out of range
+ * @returns true if a valid point is found, false if any x or y are out of range
+ */
+bool Water::posToGridPoint(float x, float z, unsigned int& row, unsigned int& column)
+{
+  float lower = this->getAbsCoor().y - this->sizeY *.5;
+  float left = this->getAbsCoor().x - this->sizeX *.5;
+  if (x > left && x < left + this->sizeX)
+    row = (unsigned int) ((x- left) / this->grid->gridSpacing());
+  else return false;
+  if (z > lower && z < lower + this->sizeY)
+    column = (unsigned int)((z-lower) / this->grid->gridSpacing());
+  else return false;
+  return true;
+}
+
+
+void Water::draw() const
+{
+  assert (this->grid != NULL);
+  {
+    glPushAttrib(GL_ENABLE_BIT);
+    glEnable(GL_TEXTURE_2D);
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+
+    /* translate */
+    glTranslatef (this->getAbsCoor ().x,
+                  this->getAbsCoor ().y,
+                  this->getAbsCoor ().z);
+    Vector tmpRot = this->getAbsDir().getSpacialAxis();
+    glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+     if (State::getSkyBox())
+     {
+       glBindTexture(GL_TEXTURE_2D, State::getSkyBox()->getTexture(SKY_RIGHT));
+       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+       glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+       glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+       glEnable(GL_TEXTURE_GEN_S);
+       glEnable(GL_TEXTURE_GEN_T);
+     }
+     glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+//    SkyBox::enableCubeMap();
+    this->grid->draw();
+    // this->waterShader->activateShader();
+    //  this->waterMaterial->select();
+    //Shader::deactivateShader();
+
+    SkyBox::disableCubeMap();
+    glDisable(GL_TEXTURE_GEN_S);
+    glDisable(GL_TEXTURE_GEN_T);
+
+    glPopMatrix();
+    glPopAttrib();
+  }
+}
+
+void Water::tick(float dt)
+{
+  ObjectManager::EntityList entityList = State::getObjectManager()->getEntityList(OM_GROUP_01_PROJ);
+  ObjectManager::EntityList::iterator entity = entityList.begin();
+  while (entity != entityList.end())
+  {
+    this->wave((*entity)->getAbsCoor(), 10.0*dt);
+    entity++;
+  }
+
+
+  if (unlikely(this->velocities == NULL))
+    return;
+  /*
+      THE OLD USELESS ALGORITHM
+    phase += dt *.1;
+    for (unsigned int i = 0; i < this->grid->rows(); i++)
+    {
+      for (unsigned int j = 0; j < this->grid->columns(); j++)
+      {
+        this->grid->height(i,j) = this->height*sin(((float)i/(float)this->grid->rows() *phase)+
+            this->height*cos((float)j/(float)this->grid->columns()) * phase * 2.0);
+      }
+    }
+    this->grid->rebuildNormals(this->height);*/
+
+
+  unsigned int i, j;
+  float u;
+
+  // wave/advection
+  // calc movement
+  for(j = 1; j < this->grid->rows() - 1; j++)
+  {
+    for(i = 1; i < this->grid->columns() - 1; i++)
+    {
+      u =  this->grid->height(i+1,j)+ this->grid->height(i-1, j) +
+           this->grid->height(i, j+1) + this->grid->height(i, j-1) -
+           4 * this->grid->height(i, j);
+      this->velocities[i][j] += dt * this->viscosity * this->viscosity * u / this->height;
+      this->grid->height(i, j) += dt * this->velocities[i][j]  /* + dt * this->cohesion * u / this->height;*/;
+      this->grid->height(i, j) *= .99;
+    }
+  }
+  // boundraries
+  for (j = 0; j < this->grid->rows(); j++)
+  {
+    this->grid->height(0,j) = this->grid->height(1,j);
+    this->grid->height(this->grid->rows()-1,j) = this->grid->height(this->grid->rows()-2, j);
+  }
+  for (i = 0; i < this->grid->rows(); i++)
+  {
+    this->grid->height(i,0) = this->grid->height(i,1);
+    this->grid->height(i,this->grid->columns()-1) = this->grid->height(i, this->grid->columns()-2);
+  }
+  /*
+  for(j = 1; j < this->grid->rows() - 1; j++) {
+      for(i = 1; i < this->grid->columns() - 1; i++) {
+        this->grid->height(i, j) += dt * this->velocities[i][j];
+      }
+    }*/
+
+  // calc normals
+  //   float l[3];
+  //   float m[3];
+  //   for(j = 1; j < this->grid->rows() -1; j++) {
+  //     for(i = 1; i < this->grid->columns() - 1; i++) {
+  //       l[0] = this->grid->vertexG(i, j-1).x - this->grid->vertexG(i, j+1).x;
+  //       l[1] = this->grid->vertexG(i, j-1).y - this->grid->vertexG(i, j+1).y;
+  //       l[2] = this->grid->vertexG(i, j-1).z - this->grid->vertexG(i, j+1).z;
+  //       m[0] = this->grid->vertexG(i-1,j).x - this->grid->vertexG(i+1, j).x;
+  //       m[1] = this->grid->vertexG(i-1,j).y - this->grid->vertexG(i+1, j).y;
+  //       m[2] = this->grid->vertexG(i-1,j).z - this->grid->vertexG(i+1, j).z;
+  //       this->grid->normalG(i, j).x = l[1] * m[2] - l[2] * m[1];
+  //       this->grid->normalG(i, j).y = l[2] * m[0] - l[0] * m[2];
+  //       this->grid->normalG(i, j).z = l[0] * m[1] - l[1] * m[0];
+  //     }
+  //   }
+  this->grid->rebuildNormals(this->height);
+}
+
+
+
+/**
+ * function to handle changes in synced vars
+ * @param id ids which have changed
+ */
+void Water::varChangeHandler( std::list< int > & id )
+{
+  if ( std::find( id.begin(), id.end(), height_handle ) != id.end() ||
+       std::find( id.begin(), id.end(), resX_handle ) != id.end() ||
+       std::find( id.begin(), id.end(), resY_handle ) != id.end() ||
+       std::find( id.begin(), id.end(), sizeX_handle ) != id.end() ||
+       std::find( id.begin(), id.end(), sizeY_handle ) != id.end()
+     )
+  {
+    this->rebuildGrid();
+  }
+
+  WorldEntity::varChangeHandler( id );
+}
Index: branches/heathaze/src/world_entities/environments/water.h
===================================================================
--- branches/heathaze/src/world_entities/environments/water.h	(revision 9940)
+++ branches/heathaze/src/world_entities/environments/water.h	(revision 9940)
@@ -0,0 +1,71 @@
+/*!
+ * @file water.h
+ *  Definition of the SkyBox, that handles the Display of an atmosphere for orxonox.
+ *
+ * A SkyBox is always centered at the current working Camera, and will only obey the cameras
+ * movment but not its rotation.
+*/
+
+#ifndef _WATER_H
+#define _WATER_H
+
+/* INCLUDES */
+#include "world_entity.h"
+#include "material.h"
+#include "shader.h"
+
+/* FORWARD DECLARATION */
+class Grid;
+
+//! A Class to handle a WaterEffects
+class Water : public WorldEntity
+{
+  ObjectListDeclaration(Water);
+  public:
+   Water(const TiXmlElement* root = NULL);
+   virtual ~Water();
+
+   void loadParams(const TiXmlElement* root);
+
+   void setResolution(unsigned int resX, unsigned int resY);
+   void setSize(float sizeX, float sizeY);
+   void setHeight(float height);
+   void rebuildGrid();
+
+   void wave(float x, float y, float z, float force);
+   inline void wave(Vector pos, float force) { this->wave(pos.x, pos.y, pos.z, force); };
+
+   void draw() const;
+   void tick(float dt);
+
+   virtual void varChangeHandler( std::list<int> & id );
+
+  private:
+    bool posToGridPoint(float x, float z, unsigned int& row, unsigned int& column);
+
+  private:
+    Grid*           grid;            //!< The water-surface-model to render with
+    float**         velocities;      //!< Velocities.
+    float           viscosity;       //!< Viscosity (bigger more like honey, smaller more like water).
+    float           cohesion;        //!< Cohesion.
+
+    Material        waterMaterial;
+    Shader          waterShader;
+
+    float           height;          //!< The hight of the Water
+    int             height_handle;   //!< Handle to notify about changes of height
+
+    unsigned int    resX, resY;      //!< Grid resolution
+    int             resX_handle;     //!< Handle to notify about changes of resX
+    int             resY_handle;     //!< Handle to notify about changes of resY
+    float           sizeX, sizeY;    //!< waters size
+    int             sizeX_handle;    //!< Handle to notify about changes of sizeX
+    int             sizeY_handle;    //!< Handle to notify about changes of sizeY
+
+    float phase;
+};
+
+#endif  /* _WATER_H */
+
+
+
Index: branches/heathaze/src/world_entities/extendable.cc
===================================================================
--- branches/heathaze/src/world_entities/extendable.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/extendable.cc	(revision 9940)
@@ -0,0 +1,3 @@
+#include "extendable.h"
+
+ObjectListDefinition(Extendable);
Index: branches/heathaze/src/world_entities/extendable.h
===================================================================
--- branches/heathaze/src/world_entities/extendable.h	(revision 9940)
+++ branches/heathaze/src/world_entities/extendable.h	(revision 9940)
@@ -0,0 +1,27 @@
+/*!
+ * @file extendable.h
+ * @brief Interface for Worldentities that can pick up powerups.
+*/
+
+#ifndef _EXTENDABLE_H
+#define _EXTENDABLE_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+class PowerUp;
+
+
+#include "power_ups/power_up.h"
+//! A class for Extendable Entities
+class Extendable : virtual public BaseObject {
+  ObjectListDeclaration(Extendable);
+
+  public:
+   virtual bool pickup(PowerUp* powerUp) { return false; };
+
+  protected:
+    Extendable() { this->registerObject(this, Extendable::_objectList); };
+};
+
+#endif /* _EXTENDABLE_H */
Index: branches/heathaze/src/world_entities/items/item_container.cc
===================================================================
--- branches/heathaze/src/world_entities/items/item_container.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/items/item_container.cc	(revision 9940)
@@ -0,0 +1,50 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "item_container.h"
+
+
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+ItemContainer::ItemContainer ()
+{
+   this->setClassID(CL_ITEM_CONTAINER, "ItemContainer");
+
+   /* If you make a new class, what is most probably the case when you write this file
+      don't forget to:
+       1. Add the new file new_class.cc to the ./src/Makefile.am
+       2. Add the class identifier to ./src/class_id.h eg. CL_NEW_CLASS
+
+      Advanced Topics:
+      - if you want to let your object be managed via the ObjectManager make sure to read
+        the object_manager.h header comments. You will use this most certanly only if you
+        make many objects of your class, like a weapon bullet.
+   */
+}
+
+
+/**
+ * standard deconstructor
+*/
+ItemContainer::~ItemContainer ()
+{
+  // delete what has to be deleted here
+}
Index: branches/heathaze/src/world_entities/items/item_container.h
===================================================================
--- branches/heathaze/src/world_entities/items/item_container.h	(revision 9940)
+++ branches/heathaze/src/world_entities/items/item_container.h	(revision 9940)
@@ -0,0 +1,27 @@
+/*!
+ * @file item_container.h
+ * @brief Definition of a Container for Items one can pick up
+ */
+
+#ifndef _ITEM_CONTAINER_H
+#define _ITEM_CONTAINER_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+
+
+//! A class for storing collected Items.
+class ItemContainer : public BaseObject {
+
+ public:
+  ItemContainer();
+  virtual ~ItemContainer();
+
+
+ private:
+
+};
+
+#endif /* _ITEM_CONTAINER_H */
Index: branches/heathaze/src/world_entities/movie_entity.cc
===================================================================
--- branches/heathaze/src/world_entities/movie_entity.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/movie_entity.cc	(revision 9940)
@@ -0,0 +1,169 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2005 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: David Hasenfratz, Stefan Lienhard
+   co-programmer:
+*/
+
+#include "movie_entity.h"
+
+#include "media_container.h"
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(MovieEntity, CL_MOVIE_ENTITY);
+CREATE_FACTORY(MovieEntity);
+
+/**
+ *  standard constructor
+ */
+MovieEntity::MovieEntity (const TiXmlElement* root)
+{
+  this->registerObject(this, MovieEntity::_objectList);
+
+  media_container = new MediaContainer();
+
+  axis = 0;
+  rotation = 0;
+  height = 20;
+  width = 20;
+  mediaLoaded = false;
+
+  this->toList(OM_COMMON);
+
+  if( root != NULL)
+    this->loadParams(root);
+
+  counter = 0;
+  timer = 0;
+}
+
+/**
+ *  standard destructor
+ */
+MovieEntity::~MovieEntity ()
+{
+  if( this->media_container)
+    delete this->media_container;
+}
+
+void MovieEntity::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "name", this, MovieEntity, loadMovie);
+  LoadParam(root, "axis", this, MovieEntity, setAxis);
+  LoadParam(root, "rotation", this, MovieEntity, setRotation);
+  LoadParam(root, "size", this, MovieEntity, setSize);
+  LoadParam(root, "fps", this, MovieEntity, setFPS);
+}
+
+void MovieEntity::setFPS(float fps)
+{
+  this->fps = fps;
+//PRINTF(0)("fps: %f\n", fps);
+}
+
+void MovieEntity::loadMovie(const std::string& filename)
+{
+  if(media_container->loadMedia(filename))
+  {
+    mediaLoaded = true;
+    fps = media_container->getFPS();
+  }
+  else
+    mediaLoaded = false;
+}
+
+void MovieEntity::setAxis(float axis)
+{
+//PRINTF(0)("fps: %f\n", fps);
+  this->axis = axis;
+}
+
+// Seconds for one loop
+void MovieEntity::setRotation(float rotation)
+{
+  this->rotation = rotation;
+}
+
+void MovieEntity::setSize(float width, float height)
+{
+  this->width = width;
+  this->height = height;
+}
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+
+   Handle all stuff that should update with time inside this method (movement, animation, etc.)
+ */
+void MovieEntity::tick(float time)
+{
+  if(!mediaLoaded)
+    return;
+
+  timer += time;
+
+  if(counter != fps * timer)
+  {
+    counter = (int)(fps * timer);
+
+    if ((unsigned int)counter >= media_container->getFrameCount())
+    {
+      timer = 0;
+      counter = 0;
+    }
+  }
+
+  axis += (time * rotation/360.0);
+}
+
+
+/**
+ *  the entity is drawn onto the screen with this function
+
+   This is a central function of an entity: call it to let the entity painted to the screen. Just override this function with whatever you want to be drawn.
+ */
+void MovieEntity::draw() const
+{
+//   if(!mediaLoaded)
+//     false;
+
+  glPushAttrib(GL_ENABLE_BIT);
+  glDisable(GL_LIGHTING);
+  glDisable(GL_BLEND);
+
+  glEnable(GL_TEXTURE_2D);
+  glBindTexture(GL_TEXTURE_2D, media_container->getFrameTexture(counter));
+
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  glRotatef(axis, 0.0f, 1.0f, 0.0f);
+//PRINTF(0)("axis: %f\n", axis);
+
+  glColor3f(1.0, 1.0, 1.0);
+
+  glBegin(GL_QUADS);
+    glTexCoord2f(1.0f, 1.0f); glVertex3f(-width/2, -height/2,  0.0f);
+    glTexCoord2f(0.0f, 1.0f); glVertex3f( width/2, -height/2,  0.0f);
+    glTexCoord2f(0.0f, 0.0f); glVertex3f( width/2,  height/2,  0.0f);
+    glTexCoord2f(1.0f, 0.0f); glVertex3f(-width/2,  height/2,  0.0f);
+  glEnd();
+
+  glPopMatrix();
+  glPopAttrib();
+}
Index: branches/heathaze/src/world_entities/movie_entity.h
===================================================================
--- branches/heathaze/src/world_entities/movie_entity.h	(revision 9940)
+++ branches/heathaze/src/world_entities/movie_entity.h	(revision 9940)
@@ -0,0 +1,48 @@
+/*!
+ * @file movie_entity.h
+ *  Definition of a Movie Screen
+ */
+
+#ifndef _MOVIE_ENTITY_H
+#define _MOVIE_ENTITY_H
+
+#include "world_entity.h"
+
+
+class MediaContainer;
+
+class MovieEntity : public WorldEntity
+{
+  ObjectListDeclaration(MovieEntity);
+  private:
+    MediaContainer* media_container;
+
+    int counter;
+    float timer;
+    float fps;
+
+    float axis;
+    float rotation;
+    float height;
+    float width;
+
+    bool mediaLoaded;
+
+  public:
+    MovieEntity (const TiXmlElement* root = NULL);
+    virtual ~MovieEntity ();
+
+    virtual void draw () const;
+    virtual void tick (float time);
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    void loadMovie(const std::string& filename);
+    void setAxis(float axis);
+    void setRotation(float rotation);
+    void setSize(float width, float height);
+    void setFPS(float fps);
+
+};
+
+#endif /* _MOVIE_ENTITY_H */
Index: branches/heathaze/src/world_entities/npcs/attractor_mine.cc
===================================================================
--- branches/heathaze/src/world_entities/npcs/attractor_mine.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/attractor_mine.cc	(revision 9940)
@@ -0,0 +1,155 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "attractor_mine.h"
+
+
+#include "shader.h"
+#include "state.h"
+#include "debug.h"
+
+#include "player.h"
+#include "playable.h"
+
+#include "loading/factory.h"
+#include "loading/load_param.h"
+
+#include "effects/explosion.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(AttractorMine, CL_ATTRACTOR_MINE);
+CREATE_FACTORY(AttractorMine);
+#include "script_class.h"
+CREATE_SCRIPTABLE_CLASS(AttractorMine,
+                        addMethod("setName", Executor1<BaseObject, lua_State*,const std::string&>(&BaseObject::setName))
+                        //Coordinates
+                        ->addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
+                        ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
+                        ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
+                        ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
+                       );
+
+
+
+
+AttractorMine::AttractorMine(const TiXmlElement* root)
+    : NPC(NULL)
+{
+  this->registerObject(this, AttractorMine::_objectList);
+
+  this->toList(OM_GROUP_02);
+
+  if ((float)rand()/RAND_MAX > .5f)
+    this->loadModel("models/ships/noxon_battle_drone.obj", .3);
+  else
+    this->loadModel("models/ships/noxon_battle_drone.obj", .2);
+
+  this->setDamage(30.0f);
+
+
+
+  this->shader = NULL;
+  //if (likely(Shader::checkShaderAbility()))
+//    this->shader = Shader::getShader("shaders/toon.vert", "shaders/toon.frag");
+
+  this->randomRotAxis = VECTOR_RAND(1);
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+AttractorMine::~AttractorMine ()
+{
+}
+
+void AttractorMine::loadParams(const TiXmlElement* root)
+{
+  NPC::loadParams(root);
+
+}
+
+
+void AttractorMine::destroy(WorldEntity* killer)
+{
+  Explosion::explode(this, Vector(10,10,10));
+  this->toList(OM_DEAD);
+
+}
+
+
+
+/**
+ *  the entity is drawn onto the screen with this function
+ *
+ * This is a central function of an entity: call it to let the entity painted to the screen.
+ * Just override this function with whatever you want to be drawn.
+ */
+void AttractorMine::draw() const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  float matrix[4][4];
+
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  /* rotate */
+  this->getAbsDir ().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+
+  //   if (this->shader != NULL && this->shader != Shader::getActiveShader())
+  //     shader->activateShader();
+
+  this->getModel()->draw();
+  //   shader->deactivateShader();
+
+
+  /*  if (this->model)
+      this->model->draw();*/
+  glPopMatrix();
+}
+
+
+void AttractorMine::tick(float dt)
+{
+  PNode* attractNode = State::getPlayer()->getPlayable();
+  if (attractNode != NULL)
+  {
+    if (this->distance(attractNode) < 80)
+    {
+      Vector dist = (attractNode->getAbsCoor() -  this->getAbsCoor());
+      float distance = dist.len();
+      this->velocity += dist * (( 250.0 - distance) / distance * dt);
+    }
+  }
+
+  this->shiftCoor(this->velocity * dt);
+
+  //  Vector direction = (State::getCameraTarget()->getAbsCoor() - this->getAbsCoor());
+
+  //if (directin.len() < 100)
+  //  this->shiftCoor(direction *dt * 5 * exp(-direction.len() / 30.0));
+  this->shiftDir(Quaternion(.5 * dt, this->randomRotAxis));
+
+}
+
+
+
Index: branches/heathaze/src/world_entities/npcs/attractor_mine.h
===================================================================
--- branches/heathaze/src/world_entities/npcs/attractor_mine.h	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/attractor_mine.h	(revision 9940)
@@ -0,0 +1,33 @@
+
+#ifndef _ATTRACTOR_MINE_H
+#define _ATTRACTOR_MINE_H
+
+#include "npc.h"
+
+class AI;
+class Shader;
+
+class AttractorMine : public NPC {
+  ObjectListDeclaration(AttractorMine);
+
+ public:
+  AttractorMine (const TiXmlElement* root = NULL);
+  virtual ~AttractorMine ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void addAI(AI* ai);
+
+  virtual void destroy(WorldEntity* killer);
+
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+ private:
+   Vector   randomRotAxis;
+   Shader*  shader;
+
+   Vector   velocity;
+};
+
+#endif /* _ATTRACTOR_MINE_H */
Index: branches/heathaze/src/world_entities/npcs/door.cc
===================================================================
--- branches/heathaze/src/world_entities/npcs/door.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/door.cc	(revision 9940)
@@ -0,0 +1,190 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+#include "interactive_model.h"
+
+
+#include "door.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Door, CL_DOOR);
+CREATE_FACTORY(Door);
+
+
+
+//! list of all different animations a std md2model supports
+sAnim Door::animationList[2] =
+{
+ // begin, end, fps, interruptable
+  {   0,  15,  30,  0 },   //!< OPEN
+  {   15, 29,  30,  0 }    //!< CLOSE
+};
+
+
+
+Door::Door(const TiXmlElement* root)
+{
+  this->registerObject(this, Door::_objectList);
+  this->scale = 1.0f;
+  this->actionRadius = 1.0;
+
+  if( root != NULL)
+    this->loadParams(root);
+
+  this->toList(OM_COMMON);
+  this->bLocked = false;
+  this->bOpen = false;
+
+  this->loadMD2Texture("maps/doors.jpg");
+  this->loadModel("models/creatures/doors.md2", this->scale);
+
+  this->setAnimation(DOOR_CLOSE, MD2_ANIM_ONCE);
+}
+
+
+Door::~Door ()
+{}
+
+
+
+/**
+ * loads the Settings of a MD2Creature from an XML-element.
+ * @param root the XML-element to load the MD2Creature's properties from
+ */
+void Door::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "action-radius", this, Door, setActionRadius)
+      .describe("sets the action radius of the door")
+      .defaultValues(3.0);
+  LoadParam(root, "scale", this, Door, setScale)
+      .describe("sets the scale of the door")
+      .defaultValues(1.0);
+}
+
+
+/**
+ * sets the animatin of this entity
+ */
+void  Door::setAnimation(int animNum, int playbackMode)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->setAnimation(animationList[animNum].firstFrame,
+                                                         animationList[animNum].lastFrame,
+                                                         animationList[animNum].fps,
+                                                         animationList[animNum].bStoppable,
+                                                         playbackMode);
+}
+
+
+/**
+ * ticks the door
+ * @param time: time since last tick
+ */
+void Door::tick (float time)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->tick(time);
+
+  if( !this->bOpen)
+  {
+    if( this->checkOpen())
+    {
+      this->open();
+    }
+  }
+  else
+  {
+    if( !this->checkOpen())
+    {
+      this->close();
+    }
+  }
+
+}
+
+
+/**
+ * open the door
+ */
+void Door::open()
+{
+  if( this->bLocked)
+    return;
+
+  this->setAnimation(DOOR_OPEN, MD2_ANIM_ONCE);
+  this->bOpen = true;
+}
+
+
+/**
+ * close the door
+ */
+void Door::close()
+{
+  this->setAnimation(DOOR_CLOSE, MD2_ANIM_ONCE);
+  this->bOpen = false;
+}
+
+
+#include "playable.h"
+#include "generic_npc.h"
+/**
+ * checks if the door is open
+ */
+bool Door::checkOpen()
+{
+
+  WorldEntity* entity;
+  float distance;
+
+  for (ObjectList<Playable>::const_iterator it = Playable::objectList().begin();
+       it != Playable::objectList().end();
+       ++it)
+  // for all players
+  {
+    entity = (*it);
+
+    distance = fabs((this->getAbsCoor() - entity->getAbsCoor()).len());
+    if( distance < this->actionRadius)
+      return true;
+  }
+
+
+
+  for (ObjectList<GenericNPC>::const_iterator it = GenericNPC::objectList().begin();
+       it != GenericNPC::objectList().end();
+       ++it)
+  {
+    entity = (*it);
+
+    distance = fabs((this->getAbsCoor() - entity->getAbsCoor()).len());
+    if( distance < this->actionRadius)
+      return true;
+  }
+
+  return false;
+}
+
+
+
Index: branches/heathaze/src/world_entities/npcs/door.h
===================================================================
--- branches/heathaze/src/world_entities/npcs/door.h	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/door.h	(revision 9940)
@@ -0,0 +1,62 @@
+#ifndef _DOOR_H
+#define _DOOR_H
+
+#include "world_entity.h"
+
+#include "md2/md2Model.h"
+
+class TiXmlElement;
+
+
+//! animation names enumeration
+typedef enum DoorAnimType
+{
+  DOOR_OPEN = 0,
+  DOOR_CLOSE,
+
+  DOOR_MAX_ANIMATIONS
+};
+
+
+class Door : public WorldEntity
+{
+  ObjectListDeclaration(Door);
+
+  public:
+    Door(const TiXmlElement* root = NULL);
+    virtual ~Door ();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    void setActionRadius(float radius) { this->actionRadius = radius; }
+    void setScale(float scale) { this->scale = scale; }
+
+    void open();
+    void close();
+
+    void lock() { this->bLocked = true; }
+    void unlock() { this->bLocked = false; }
+    bool isLocked() const { return this->bLocked; }
+
+
+    virtual void tick (float time);
+
+
+  private:
+    void init();
+    bool checkOpen();
+    void setAnimation(int animNum, int playbackMode = 0);
+
+
+  private:
+    bool           bOpen;             //!< true if the door is open
+    bool           bLocked;           //!< true if this door is locked
+    float          actionRadius;      //!< action radius
+    float          scale;             //!< the scale of the model
+
+    static sAnim   animationList[2];  //!< list of the animations
+
+
+};
+
+#endif /* _DOOR_H */
Index: branches/heathaze/src/world_entities/npcs/gate.cc
===================================================================
--- branches/heathaze/src/world_entities/npcs/gate.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/gate.cc	(revision 9940)
@@ -0,0 +1,229 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Silvan Nellen
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+#include "interactive_model.h"
+
+
+#include "gate.h"
+#include "effects/explosion.h"
+
+
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Gate, CL_GATE);
+CREATE_FACTORY(Gate);
+
+
+#include "script_class.h"
+CREATE_SCRIPTABLE_CLASS(Gate,
+			addMethod("hide", Executor0<WorldEntity, lua_State*>(&WorldEntity::hide))
+			    ->addMethod("unhide", Executor0<WorldEntity, lua_State*>(&WorldEntity::unhide))
+			    ->addMethod("destroy", Executor0<Gate, lua_State*>(&Gate::destroy))
+			    ->addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
+			    ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
+			    ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
+			    ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
+                       );
+
+
+
+//! list of all different animations a std md2model supports
+sAnim Gate::animationList[3] =
+{
+ // begin, end, fps, interruptable
+  {   0,  7,  30,  0 },    //!< OPEN
+  {   8, 15,  30,  0 },    //!< CLOSE
+  {  16, 18,  30,  0 }     //!< DIE
+};
+
+
+
+Gate::Gate(const TiXmlElement* root)
+{
+  this->registerObject(this, Gate::_objectList);
+  this->scale = 1.0f;
+  this->actionRadius = 1.0;
+  this->destroyed = false;
+
+  if( root != NULL)
+    this->loadParams(root);
+
+  this->toList(OM_COMMON);
+  this->bLocked = false;
+  this->bOpen = false;
+
+  this->loadMD2Texture("maps/wheel.jpg");
+  this->loadModel("models/creatures/hypergate.md2", this->scale);
+
+  this->setAnimation(GATE_CLOSE, MD2_ANIM_ONCE);
+}
+
+
+Gate::~Gate ()
+{}
+
+
+
+/**
+ * loads the Settings of a MD2Creature from an XML-element.
+ * @param root the XML-element to load the MD2Creature's properties from
+ */
+void Gate::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "action-radius", this, Gate, setActionRadius)
+      .describe("sets the action radius of the door")
+      .defaultValues(3.0);
+  LoadParam(root, "scale", this, Gate, setScale)
+      .describe("sets the scale of the door")
+      .defaultValues(1.0);
+}
+
+
+/**
+ * sets the animatin of this entity
+ */
+void  Gate::setAnimation(int animNum, int playbackMode)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->setAnimation(animationList[animNum].firstFrame,
+                                                         animationList[animNum].lastFrame,
+                                                         animationList[animNum].fps,
+                                                         animationList[animNum].bStoppable,
+                                                         playbackMode);
+}
+
+
+/**
+ * ticks the door
+ * @param time: time since last tick
+ */
+void Gate::tick (float time)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->tick(time);
+
+
+  if( !this->bOpen)
+  {
+    if( this->checkOpen())
+    {
+      this->open();
+    }
+  }
+  else
+  {
+    if( !this->checkOpen())
+    {
+      this->close();
+    }
+  }
+
+
+}
+
+
+/**
+ * open the door
+ */
+void Gate::open()
+{
+  if( this->bLocked || this->destroyed)
+    return;
+
+  this->setAnimation(GATE_OPEN, MD2_ANIM_ONCE);
+  this->bOpen = true;
+}
+
+
+/**
+ * close the door
+ */
+void Gate::close()
+{
+
+  if( this->destroyed)
+    return;
+
+  this->setAnimation(GATE_CLOSE, MD2_ANIM_ONCE);
+  this->bOpen = false;
+}
+
+
+void Gate::destroy()
+{
+  if( this->destroyed)
+    return;
+
+  this->setAnimation(GATE_DIE, MD2_ANIM_ONCE);
+
+  Explosion::explode(this, Vector(this->getScaling()/160,this->getScaling()/160,this->getScaling()/160));
+
+
+  this->destroyed = true;
+}
+
+#include "playable.h"
+#include "generic_npc.h"
+
+/**
+ * checks if the door is open
+ */
+bool Gate::checkOpen()
+{
+
+  std::list<BaseObject*>::const_iterator it;
+  WorldEntity* entity;
+  float distance;
+
+  // for all players
+  for (ObjectList<Playable>::const_iterator it = Playable::objectList().begin();
+       it != Playable::objectList().end();
+       ++it)
+  {
+    entity = (*it);
+
+    distance = fabs((this->getAbsCoor() - entity->getAbsCoor()).len());
+    if( distance < this->actionRadius)
+      return true;
+  }
+
+
+  for (ObjectList<GenericNPC>::const_iterator it = GenericNPC::objectList().begin();
+       it != GenericNPC::objectList().end();
+       ++it)
+  {
+    entity = (*it);
+
+    distance = fabs((this->getAbsCoor() - entity->getAbsCoor()).len());
+    if( distance < this->actionRadius)
+      return true;
+  }
+
+  return false;
+}
+
+
+
Index: branches/heathaze/src/world_entities/npcs/gate.h
===================================================================
--- branches/heathaze/src/world_entities/npcs/gate.h	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/gate.h	(revision 9940)
@@ -0,0 +1,67 @@
+#ifndef _GATE_H
+#define _GATE_H
+
+#include "world_entity.h"
+
+#include "md2/md2Model.h"
+
+class TiXmlElement;
+
+
+//! animation names enumeration
+typedef enum GateAnimType
+{
+  GATE_OPEN = 0,
+  GATE_CLOSE,
+  GATE_DIE,
+
+  GATE_MAX_ANIMATIONS
+};
+
+
+class Gate : public WorldEntity
+{
+  ObjectListDeclaration(Gate);
+
+  public:
+    Gate(const TiXmlElement* root = NULL);
+    virtual ~Gate ();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    void setActionRadius(float radius) { this->actionRadius = radius; }
+    void setScale(float scale) { this->scale = scale; }
+
+    void open();
+    void close();
+    void destroy();
+
+    void lock() { this->bLocked = true; }
+    void unlock() { this->bLocked = false; }
+    bool isLocked() const { return this->bLocked; }
+
+
+    virtual void tick (float time);
+
+
+  private:
+    void init();
+    bool checkOpen();
+    void setAnimation(int animNum, int playbackMode = 0);
+
+
+  private:
+    bool           destroyed;         //!< true if the door is destroyed
+    bool           bOpen;             //!< true if the door is open
+    bool           bLocked;           //!< true if this door is locked
+    float          actionRadius;      //!< action radius
+    float          scale;             //!< the scale of the model
+
+    static sAnim   animationList[3];  //!< list of the animations
+
+    bool           bDead;
+
+
+};
+
+#endif /* _GATE_H */
Index: branches/heathaze/src/world_entities/npcs/generic_npc.cc
===================================================================
--- branches/heathaze/src/world_entities/npcs/generic_npc.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/generic_npc.cc	(revision 9940)
@@ -0,0 +1,605 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "generic_npc.h"
+
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+#include "interactive_model.h"
+#include "md2/md2Model.h"
+
+#include "sound_buffer.h"
+#include "resource_sound_buffer.h"
+
+#include "sound/resource_sound_buffer.h"
+
+#include "bsp_entity.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(GenericNPC, CL_GENERIC_NPC);
+CREATE_FACTORY(GenericNPC);
+
+#include "script_class.h"
+CREATE_SCRIPTABLE_CLASS(GenericNPC,
+                        // Move
+                        addMethod("walkTo", Executor3<GenericNPC, lua_State*,float,float,float>(&GenericNPC::walkTo))
+                        ->addMethod("runTo", Executor3<GenericNPC, lua_State*,float,float,float>(&GenericNPC::runTo))
+                        ->addMethod("turnTo", Executor1<GenericNPC, lua_State*,float>(&GenericNPC::turnTo))
+                        ->addMethod("finalGoalReached", Executor0ret<GenericNPC, lua_State*,bool>(&GenericNPC::finalGoalReached))
+                        ->addMethod("stop", Executor0<GenericNPC, lua_State*>(&GenericNPC::stop))
+                        ->addMethod("resume", Executor0<GenericNPC, lua_State*>(&GenericNPC::resume))
+                        ->addMethod("playAnimation", Executor2<GenericNPC, lua_State*,int,int>(&GenericNPC::playAnimation))
+                        // Display
+                        ->addMethod("hide", Executor0<WorldEntity, lua_State*>(&WorldEntity::hide))
+                        ->addMethod("unhide", Executor0<WorldEntity, lua_State*>(&WorldEntity::unhide))
+                        // Coordinates
+                        ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
+                        ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
+                        ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
+                        ->addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
+                        ->addMethod("setAbsDir", Executor4<PNode, lua_State*,float,float,float,float>(&PNode::setAbsDir))
+                       );
+
+
+
+/**
+ * constructor
+ */
+GenericNPC::GenericNPC(const TiXmlElement* root)
+    : NPC(root)
+{
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * deconstructor
+ */
+GenericNPC::~GenericNPC ()
+{}
+
+
+/**
+ * initializing the npc enity
+ */
+void GenericNPC::init()
+{
+  this->registerObject(this, GenericNPC::_objectList);
+
+  this->toList(OM_GROUP_00);
+
+  this->soundBuffer = OrxSound::ResourceSoundBuffer("sound/rain.wav");
+
+  time = 30.0f;
+
+  this->behaviourList = new std::list<GenericNPC::Anim>;
+
+  // collision reaction registration
+  this->subscribeReaction(CREngine::CR_PHYSICS_GROUND_WALK, BspEntity::staticClassID());
+}
+
+
+/**
+ * loads the Settings of a MD2Creature from an XML-element.
+ * @param root the XML-element to load the MD2Creature's properties from
+ */
+void GenericNPC::loadParams(const TiXmlElement* root)
+{
+  NPC::loadParams(root);
+
+}
+
+
+/**
+ * sets the animation of this npc
+ * @param anumationIndex: the animation index
+ * @param anumPlaybackMode: the playback mode
+ */
+void GenericNPC::setAnimation(int animationIndex, int animPlaybackMode)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->setAnimation(animationIndex, animPlaybackMode);
+}
+
+
+
+/**
+ * @returns the current animation number
+ */
+int GenericNPC::getAnimation()
+{
+  if( likely(this->getModel(0) != NULL))
+    return ((InteractiveModel*)this->getModel(0))->getAnimation();
+  else
+    return -1;
+}
+
+
+
+/**
+ * @returns true if animation is finished
+ */
+bool GenericNPC::isAnimationFinished()
+{
+  if( likely(this->getModel(0) != NULL))
+    return ((InteractiveModel*)this->getModel(0))->isAnimationFinished();
+  else
+    return false;
+}
+
+
+/**
+ * sets the animation speed of this entity
+ */
+void GenericNPC::setAnimationSpeed(float speed)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->setAnimationSpeed(speed);
+}
+
+
+
+/**
+ * sets the animation of this npc
+ * @param anumationIndex: the animation index
+ * @param anumPlaybackMode: the playback mode
+ */
+void GenericNPC::playAnimation(int animationIndex, int animPlaybackMode)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->setAnimation(animationIndex, animPlaybackMode);
+
+}
+
+
+/**
+ * play a sound
+ * @param filename: name of the file
+ */
+void GenericNPC::playSound(const std::string& filename)
+{}
+
+
+
+/**
+ * stops the generic animation
+ */
+void GenericNPC::stop()
+{
+  this->animationStack.push(this->behaviourList);
+  this->behaviourList = new std::list<GenericNPC::Anim>;
+
+  if( this->getAnimation() != STAND)
+    this->setAnimation(STAND, MD2_ANIM_LOOP);
+}
+
+
+/**
+ * continue the generic animation
+ */
+void GenericNPC::resume()
+{
+  if( this->animationStack.size() == 0)
+    return;
+
+  delete this->behaviourList;
+  this->behaviourList = this->animationStack.top();
+  this->animationStack.pop();
+}
+
+
+/**
+ * each animation has to be initialized here
+ */
+/**
+ *
+ */
+void GenericNPC::initNPC()
+{
+  if (!this->behaviourList->empty())
+  {
+    GenericNPC::Anim currentAnimation = this->behaviourList->front();
+
+    switch(this->behaviourList->front().type)
+    {
+      case Walk:
+      {
+        if( this->getAnimation() != RUN)
+          this->setAnimation(RUN, MD2_ANIM_LOOP);
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor());
+        dir.y = 0.0f;
+        dir.normalize();
+        this->setAbsDir(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)));
+
+        this->setAnimationSpeed(0.5f);
+      }
+      break;
+      case Run:
+      {
+        if( this->getAnimation() != RUN)
+          this->setAnimation(RUN, MD2_ANIM_LOOP);
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
+        dir.y = 0.0f;
+        dir.getNormalized();
+        this->setAbsDir(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)));
+
+        this->setAnimationSpeed(1.0f);
+      }
+      break;
+      case Crouch:
+      {
+        if( this->getAnimation() != CROUCH_WALK)
+          this->setAnimation(CROUCH_WALK, MD2_ANIM_LOOP);
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
+        dir.y = 0.0f;
+        dir.getNormalized();
+        this->setAbsDir(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)));
+
+        this->setAnimationSpeed(1.0f);
+      }
+      break;
+      case LookAt:
+      if( this->getAnimation() != STAND)
+        this->setAnimation(STAND, MD2_ANIM_LOOP);
+      break;
+      case Shoot:
+      if( this->getAnimation() != STAND)
+        this->setAnimation(STAND, MD2_ANIM_LOOP);
+      break;
+
+      default:
+      if( this->getAnimation() != STAND)
+        this->setAnimation(STAND, MD2_ANIM_LOOP);
+      break;
+
+    }
+  }
+}
+
+
+void GenericNPC::nextStep()
+{
+  if (!this->behaviourList->empty())
+    this->behaviourList->pop_front();
+  else
+    return;
+
+
+  if (!this->behaviourList->empty())
+  {
+    GenericNPC::Anim currentAnimation = this->behaviourList->front();
+
+    switch( currentAnimation.type)
+    {
+      case Walk:
+      {
+        if( this->getAnimation() != RUN)
+          this->setAnimation(RUN, MD2_ANIM_LOOP);
+
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor());
+        dir.y = 0.0f;
+        dir.getNormalized();
+        this->setAbsDirSoft(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)), 4.0);
+
+        this->setAnimationSpeed(0.5f);
+      }
+      break;
+      case Run:
+      {
+        if( this->getAnimation() != RUN)
+          this->setAnimation(RUN, MD2_ANIM_LOOP);
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
+        dir.y = 0.0f;
+        dir.getNormalized();
+        this->setAbsDirSoft(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)), 4.0);
+
+        this->setAnimationSpeed(1.0f);
+      }
+      break;
+      case Crouch:
+      {
+        if( this->getAnimation() != CROUCH_WALK)
+          this->setAnimation(CROUCH_WALK, MD2_ANIM_LOOP);
+
+        Vector dir = (currentAnimation.v - this->getAbsCoor()).getNormalized();
+        dir.y = 0.0f;
+        dir.getNormalized();
+        this->setAbsDirSoft(Quaternion(dir, Vector(0.0, 1.0, 0.0)) * Quaternion(-M_PI_2, Vector(0.0, 1.0, 0.0)), 4.0);
+
+        this->setAnimationSpeed(1.0f);
+      }
+      break;
+      case LookAt:
+      {
+        if( this->getAnimation() != STAND)
+          this->setAnimation(STAND, MD2_ANIM_LOOP);
+      }
+      break;
+      case Shoot:
+      if( this->getAnimation() != STAND)
+        this->setAnimation(STAND, MD2_ANIM_LOOP);
+      break;
+
+      default:
+      if( this->getAnimation() != STAND)
+        this->setAnimation(STAND, MD2_ANIM_LOOP);
+      break;
+
+    }
+  }
+  else
+  {
+    this->setAnimation(STAND, MD2_ANIM_LOOP);
+  }
+}
+
+
+
+
+void GenericNPC::walkTo(const Vector& coordinate)
+{
+
+  GenericNPC::Anim anim;
+  anim.v = coordinate;
+  anim.type = Walk;
+  anim.speed = 30.0f;
+
+  if( this->behaviourList->empty())
+  {
+    this->behaviourList->push_back(anim);
+    this->initNPC();
+  }
+  else
+    this->behaviourList->push_back(anim);
+}
+
+void GenericNPC::walkTo(float x, float y, float z)
+{
+  //printf("Walking to %f, %f, %f \n",x,y,z);
+  this->walkTo(Vector(x,y,z));
+
+}
+
+/* running functions */
+void GenericNPC::runTo(const Vector& coordinate)
+{
+  GenericNPC::Anim anim;
+  anim.v = coordinate;
+  anim.type = Run;
+  anim.speed = 60.0f;
+
+  if( this->behaviourList->empty())
+  {
+    this->behaviourList->push_back(anim);
+    this->initNPC();
+  }
+  else
+    this->behaviourList->push_back(anim);
+}
+
+void GenericNPC::runTo(float x, float y, float z)
+{
+  this->runTo(Vector(x,y,z));
+}
+
+/* couching functinos */
+void GenericNPC::crouchTo(const Vector& coordinate)
+{
+  GenericNPC::Anim anim;
+  anim.v = coordinate;
+  anim.type = Crouch;
+
+  if( this->behaviourList->empty())
+  {
+    this->behaviourList->push_back(anim);
+    this->initNPC();
+  }
+  else
+    this->behaviourList->push_back(anim);
+}
+void GenericNPC::crouchTo(float x, float y, float z)
+{
+  this->crouchTo(Vector(x,y,z));
+}
+
+
+
+void GenericNPC::turnTo(float degreeInY)
+{
+  GenericNPC::Anim anim;
+  anim.q = Quaternion(Vector(0,1,0), degreeInY);
+  anim.type = TurnTo;
+
+  if( this->behaviourList->empty())
+  {
+    this->behaviourList->push_back(anim);
+    this->initNPC();
+  }
+  else
+    this->behaviourList->push_back(anim);
+}
+
+
+
+/**
+ * lookat a world entity
+ * @param worldEntity: the worldentity to look at
+ */
+void GenericNPC::lookAt(WorldEntity* worldEntity)
+{
+  GenericNPC::Anim anim;
+  anim.entity = worldEntity;
+  anim.type = LookAt;
+
+  if( this->behaviourList->empty())
+  {
+    this->behaviourList->push_back(anim);
+    this->initNPC();
+  }
+  else
+    this->behaviourList->push_back(anim);
+}
+
+
+
+
+/**
+ * talk to a world entity and play a sound/music/voice
+ * @param worldEntity: entity
+ * @param dialogNr: sound nr to be played (from the xml load tags)
+ */
+void GenericNPC::talkTo(WorldEntity* worldEntity, int dialogNr)
+{}
+
+
+/**
+ * world entity to shoot at if there is any weapon on the npc
+ * @param entity: entity to shoot entity
+ */
+void GenericNPC::shootAt(WorldEntity* entity)
+{}
+
+
+
+
+
+
+
+
+
+
+/**
+ * tick this world entity
+ * @param time: time in seconds expirded since the last tick
+ */
+void GenericNPC::tick (float dt)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->tick(dt);
+
+
+  if (!this->behaviourList->empty())
+  {
+    GenericNPC::Anim currentAnimation = this->behaviourList->front();
+
+    switch( currentAnimation.type)
+    {
+      case Walk:
+      {
+        Vector dest = currentAnimation.v - this->getAbsCoor();
+        dest.y = 0.0f;
+        if (dest.len() < .5)
+        {
+          this->nextStep();
+        }
+        else
+        {
+          Vector move = dest.getNormalized() * currentAnimation.speed * dt;
+          this->shiftCoor(move);
+        }
+      }
+      break;
+
+      case Run:
+      {
+        Vector dest = currentAnimation.v - this->getAbsCoor();
+        dest.y = 0.0f;
+        if (dest.len() < .5)
+          this->nextStep();
+        else
+        {
+          this->shiftCoor(dest.getNormalized() * currentAnimation.speed * dt);
+        }
+      }
+      break;
+
+      case Crouch:
+      {
+        Vector dest = currentAnimation.v - this->getAbsCoor();
+        dest.y = 0.0f;
+        if (dest.len() < .5)
+          this->nextStep();
+        else
+        {
+          this->shiftCoor(dest.getNormalized() * currentAnimation.speed * dt);
+        }
+      }
+      break;
+
+      case TurnTo:
+      //Quaternion direction = this->
+      break;
+
+      case LookAt:
+      break;
+
+      case Shoot:
+      break;
+
+      default:
+      break;
+
+    }
+  }
+
+  // physical falling of the player
+  if( !this->isOnGround())
+  {
+    this->fallVelocity += 300.0f * dt;
+    //velocity -= Vector(0.0, 1.0, 0.0) * this->fallVelocity;
+    // PRINTF(0)("%s is not on ground\n", this->getName());
+    this->shiftCoor(Vector(0, -this->fallVelocity * dt,0));
+
+  }
+  else
+  {
+    this->fallVelocity = 0.0f;
+  }
+
+}
+
+
+
+void GenericNPC::destroy(WorldEntity* killer)
+{
+  int randi = (int)(5.0f * (float)rand()/(float)RAND_MAX);
+
+  this->setAnimationSpeed(1.0f);
+
+  if( randi == 1)
+    this->setAnimation(DEATH_FALLBACK, MD2_ANIM_ONCE);
+  else if( randi == 2)
+    this->setAnimation(DEATH_FALLFORWARD, MD2_ANIM_ONCE);
+  else if( randi == 3)
+    this->setAnimation(DEATH_FALLBACKSLOW, MD2_ANIM_ONCE);
+  else if( randi == 4)
+    this->setAnimation(CROUCH_DEATH, MD2_ANIM_ONCE);
+  else
+    this->setAnimation(DEATH_FALLBACK, MD2_ANIM_ONCE);
+}
+
Index: branches/heathaze/src/world_entities/npcs/generic_npc.h
===================================================================
--- branches/heathaze/src/world_entities/npcs/generic_npc.h	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/generic_npc.h	(revision 9940)
@@ -0,0 +1,139 @@
+
+/*!
+ * @file generic_npc.h
+ * generic npc object
+ */
+
+#ifndef _GENERIC_ENTITY_H
+#define _GENERIC_ENTITY_H
+
+#include "npc.h"
+
+
+#include "sound_source.h"
+
+#include <stack>
+
+
+namespace OrxSound{ class SoundSource; }
+namespace OrxSound{ class SoundBuffer; }
+
+class TiXmlElement;
+class Animation3D;
+
+
+class GenericNPC : public NPC
+{
+  ObjectListDeclaration(GenericNPC);
+
+
+ public:
+  GenericNPC(const TiXmlElement* root = NULL);
+  virtual ~GenericNPC ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  /** sets the sound volume to @param vol: volume of the sound */
+  inline void setVolume(float vol) { this->soundVolume = vol; }
+
+
+
+  bool finalGoalReached() { return this->behaviourList->empty(); };
+
+  /* npc controlling functions to be Queued */
+  /* walking functions */
+  void walkTo(const Vector& coordinate);
+  void walkTo(float x, float y, float z);
+
+  /* running functions */
+  void runTo(const Vector& coordinate);
+  void runTo(float x, float y, float z);
+
+  /* couching functinos */
+  void crouchTo(const Vector& coordinate);
+  void crouchTo(float x, float y, float z);
+
+  /* stopping the movement */
+  void stop();
+  void resume();
+  void nextStep();
+
+  /* some oriantation functions */
+  void lookAt(WorldEntity* worldEntity);
+  void turnTo(float qu, float qx, float qy, float qz);
+  void turnTo(float degreeInY);
+
+  /* talking funcitons*/
+  void talkTo(WorldEntity* worldEntity, int dialogNr);
+
+  /* shooting functions */
+  void shootAt(WorldEntity* entity);
+
+
+  /* some generic control funtions */
+  void playAnimation(int animationIndex, int animPlaybackMode);
+  void playSound(const std::string& filename);
+
+  virtual void tick (float time);
+
+
+  virtual void destroy(WorldEntity* killer);
+
+  private:
+    void init();
+
+    void setAnimation(int animationIndex, int animPlaybackMode);
+    int getAnimation();
+    bool isAnimationFinished();
+    void setAnimationSpeed(float speed);
+
+    void initNPC();
+
+
+ private:
+
+   typedef enum {
+    Walk,
+    Run,
+    Crouch,
+    Jump,
+    TurnTo,
+    LookAt,
+    TalkTo,
+
+    Shoot,
+
+
+   } AnimType;
+
+   typedef struct Anim
+   {
+     Vector        v;
+     Quaternion    q;
+
+
+     WorldEntity*  entity;
+     float         speed;
+
+
+     AnimType      type;
+   };
+   typedef std::list<GenericNPC::Anim>     genNPCAnimList;
+
+
+
+   OrxSound::SoundSource                   soundSource;
+   OrxSound::SoundBuffer                   soundBuffer;
+   float                                   soundVolume;
+
+   std::list<GenericNPC::Anim>*            behaviourList;
+   std::stack<std::list<GenericNPC::Anim>*> animationStack;
+   Vector                                  destCoor;
+   Quaternion                              destDir;
+
+   Animation3D*                            currentAnim;
+   float                                   time;          //!< Duration of the action
+   float                                   fallVelocity;
+};
+
+#endif /* _GENERIC_ENTITY_H */
Index: branches/heathaze/src/world_entities/npcs/ground_turret.cc
===================================================================
--- branches/heathaze/src/world_entities/npcs/ground_turret.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/ground_turret.cc	(revision 9940)
@@ -0,0 +1,180 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Manuel Leuenberger
+   co-programmer: ...
+*/
+
+#include "ground_turret.h"
+#include "model.h"
+#include "world_entities/weapons/turret.h"
+
+#include "state.h"
+#include "playable.h"
+#include "player.h"
+
+
+#include "util/loading/factory.h"
+#include "network_game_manager.h"
+#include "util/loading/load_param.h"
+
+#include "effects/explosion.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(GroundTurret, CL_GROUND_TURRET);
+CREATE_FACTORY(GroundTurret);
+
+
+/**
+ * constructs and loads a GroundTurret from a XML-element
+ * @param root the XML-element to load from
+ */
+GroundTurret::GroundTurret(const TiXmlElement* root)
+    : NPC(root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * standard deconstructor
+ */
+GroundTurret::~GroundTurret ()
+{
+}
+
+
+/**
+ * initializes the GroundTurret
+ * @todo change this to what you wish
+ */
+void GroundTurret::init()
+{
+  this->registerObject(this, GroundTurret::_objectList);
+  this->loadModel("models/ground_turret_#.obj", 5);
+  this->left = NULL;
+  this->right = NULL;
+
+  this->setHealthMax(300);
+  this->setHealth(300);
+
+  this->weaponHolder[0].addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->weaponHolder[1].addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+
+  this->weaponHolder[0].setRelCoor(0,25,0);
+  this->weaponHolder[0].setParent(this);
+  this->weaponHolder[1].setParent(this);
+}
+
+
+/**
+ * @brief loads a GroundTurret from a XML-element
+ * @param root the XML-element to load from
+ * @todo make the class Loadable
+ */
+void GroundTurret::loadParams(const TiXmlElement* root)
+{
+  // all the clases this Entity is directly derived from must be called in this way, to load all settings.
+  NPC::loadParams(root);
+
+  /**
+   * @todo: make the class Loadable
+   */
+  const TiXmlElement* element;
+
+  element = root->FirstChildElement("weapon-left");
+  if (element != NULL) element = element->FirstChildElement();
+  this->left = dynamic_cast<Weapon*>( Factory::fabricate( element) );
+  if (this->left)
+  {
+    this->left->setParent(this);
+    this->left->toList(this->getOMListNumber());
+    this->left->setRelCoor(0,10,-5);
+    this->left->requestAction( WA_ACTIVATE);
+    this->left->setParent(&this->weaponHolder[0]);
+  }
+
+  element = root->FirstChildElement("weapon-right");
+  if (element != NULL)  if (element != NULL) element = element->FirstChildElement();
+  this->right = dynamic_cast<Weapon*>( Factory::fabricate( element) );
+  if (this->right)
+  {
+    this->right->setParent(this);
+    this->right->toList(this->getOMListNumber());
+    this->right->setRelCoor(0,10,5);
+    this->left->requestAction( WA_ACTIVATE);
+    this->right->setParent(&this->weaponHolder[0]);
+  }
+}
+
+/**
+ * advances the GroundTurret about time seconds
+ * @param time the Time to step
+ */
+void GroundTurret::tick(float dt)
+{
+  if(this->getHealth() > 0.0f
+    ) // HACK <--- YOU ARE THE MOTHERFUCKER
+  {
+    if (likely(this->left != NULL))
+    {
+      //    this->left->tickW(dt);
+      this->left->requestAction(WA_SHOOT);
+    }
+    if (likely(this->right != NULL))
+    {
+      //    this->right->tickW(dt);
+      this->right->requestAction(WA_SHOOT);
+    }
+  }
+}
+
+/**
+ * draws this worldEntity
+ */
+void GroundTurret::draw () const
+{
+  WorldEntity::draw();
+
+  if (this->left != NULL)
+    this->left->draw();
+  if (this->right != NULL)
+    this->right->draw();
+}
+
+
+
+/**
+ *
+ *
+ */
+void GroundTurret::postSpawn ()
+{
+}
+
+/**
+ *
+ *
+ */
+void GroundTurret::leftWorld ()
+{
+}
+
+void GroundTurret::destroy(WorldEntity* killer)
+{
+  this->setAbsDirSoft(Quaternion(-90, Vector(0,0,1)), 90);
+  Explosion::explode(this, Vector(10,10,10));
+
+  this->toList(OM_DEAD);
+}
Index: branches/heathaze/src/world_entities/npcs/ground_turret.h
===================================================================
--- branches/heathaze/src/world_entities/npcs/ground_turret.h	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/ground_turret.h	(revision 9940)
@@ -0,0 +1,41 @@
+/*!
+ * @file ground_turret.h
+ * @brief description
+*/
+
+#ifndef _GROUND_TURRET_H
+#define _GROUND_TURRET_H
+
+#include "npcs/npc.h"
+
+class Weapon;
+
+//! A Class to ...
+class GroundTurret : public NPC
+{
+  ObjectListDeclaration(GroundTurret);
+
+public:
+  GroundTurret(const TiXmlElement* root = NULL);
+  virtual ~GroundTurret();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void postSpawn ();
+  virtual void leftWorld ();
+
+  virtual void destroy(WorldEntity* killer);
+
+  virtual void draw() const;
+  virtual void tick(float time);
+
+private:
+  void init();
+
+
+private:
+  PNode  weaponHolder[2];
+  Weapon *left, *right;
+};
+
+#endif /* _GROUND_TURRET_H */
Index: branches/heathaze/src/world_entities/npcs/network_turret.cc
===================================================================
--- branches/heathaze/src/world_entities/npcs/network_turret.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/network_turret.cc	(revision 9940)
@@ -0,0 +1,188 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Manuel Leuenberger
+   co-programmer: ...
+*/
+
+#include "network_turret.h"
+#include "model.h"
+#include "world_entities/weapons/turret.h"
+
+#include "state.h"
+#include "playable.h"
+#include "player.h"
+
+
+#include "util/loading/factory.h"
+#include "network_game_manager.h"
+#include "util/loading/load_param.h"
+
+#include "effects/explosion.h"
+
+#include "weapons/aiming_turret.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(NetworkTurret, CL_NETWORK_TURRET);
+CREATE_FACTORY(NetworkTurret);
+
+
+/**
+ * constructs and loads a NetworkTurret from a XML-element
+ * @param root the XML-element to load from
+ */
+NetworkTurret::NetworkTurret(const TiXmlElement* root)
+    : NPC(root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * standard deconstructor
+ */
+NetworkTurret::~NetworkTurret ()
+{}
+
+
+/**
+ * initializes the NetworkTurret
+ * @todo change this to what you wish
+ */
+void NetworkTurret::init()
+{
+  this->registerObject(this, NetworkTurret::_objectList);
+  this->loadModel("models/ground_turret_#.obj", 5);
+
+  this->weapon = new AimingTurret();
+  this->weapon->loadModel("models/guns/turret2.obj", 10);
+  this->weapon->setParent(this);
+  this->weapon->toList(this->getOMListNumber());
+  this->weapon->setRelCoor(0,10,-5);
+  this->weapon->requestAction( WA_ACTIVATE);
+  this->weapon->setParent(&this->weaponHolder);
+
+  this->setHealthMax(300);
+  this->setHealth(300);
+
+  this->weaponHolder.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+
+  this->weaponHolder.setRelCoor(0,25,0);
+  this->weaponHolder.setParent(this);
+
+
+  this->targetGroup = OM_GROUP_01;
+  this->targetGroup_write = OM_GROUP_01;
+  this->targetGroup_handle = this->registerVarId( new SynchronizeableInt ( &targetGroup, &targetGroup_write, "targetgroup", PERMISSION_MASTER_SERVER ) );
+
+  this->setSynchronized( true );
+}
+
+
+/**
+ * @brief loads a NetworkTurret from a XML-element
+ * @param root the XML-element to load from
+ * @todo make the class Loadable
+ */
+void NetworkTurret::loadParams(const TiXmlElement* root)
+{
+  // all the clases this Entity is directly derived from must be called in this way, to load all settings.
+  NPC::loadParams(root);
+
+  LoadParam(root, "target-group", this, NetworkTurret, setTargetGroupS);
+}
+
+/**
+ * advances the NetworkTurret about time seconds
+ * @param time the Time to step
+ */
+void NetworkTurret::tick(float dt)
+{
+  ObjectManager::EntityList::iterator entity;
+  Vector diffVec;
+  for (entity = State::getObjectManager()->getEntityList((OM_LIST)this->targetGroup).begin();
+       entity != State::getObjectManager()->getEntityList((OM_LIST)this->targetGroup).end();
+       entity ++)
+  {
+    diffVec = ( (*entity)->getAbsCoor() - this->getAbsCoor() );
+
+    if ( diffVec.len() < 400.0 )//&&  acos( (this->source->getAbsDirX()).dot(diffVec)/(diffVec.len() * (this->source->getAbsDirX()).len() ) )  < angle)
+    {
+      //if (this->getParent() != (*entity))
+      {
+        this->weapon->requestAction(WA_SHOOT);
+        return;
+      }
+    }
+  }
+}
+
+/**
+ * draws this worldEntity
+ */
+void NetworkTurret::draw () const
+{
+  WorldEntity::draw();
+
+  if (this->weapon != NULL)
+    this->weapon->draw();
+}
+
+void NetworkTurret::setTargetGroup(int targetGroup)
+{
+  this->targetGroup = targetGroup;
+  this->weapon->setTargetGroup((OM_LIST)targetGroup);
+}
+
+
+void NetworkTurret::setTargetGroupS(const std::string& groupName)
+{
+  OM_LIST id = ObjectManager::StringToOMList(groupName);
+  if (id != OM_NULL)
+    this->setTargetGroup(id);
+  else
+    PRINTF(2)("List %s not found for targetting\n", groupName.c_str());
+}
+
+void NetworkTurret::varChangeHandler( std::list< int > & id )
+{
+  WorldEntity::varChangeHandler( id );
+
+  if ( std::find( id.begin(), id.end(), targetGroup_handle) != id.end() )
+  {
+    setTargetGroup( targetGroup_write );
+  }
+}
+
+/**
+ *
+ *
+ */
+void NetworkTurret::postSpawn ()
+{}
+
+/**
+ *
+ *
+ */
+void NetworkTurret::leftWorld ()
+{}
+
+void NetworkTurret::destroy(WorldEntity* killer)
+{
+  this->setAbsDirSoft(Quaternion(-90, Vector(0,0,1)), 90);
+  Explosion::explode(this, Vector(10,10,10));
+
+  this->toList(OM_DEAD);
+}
Index: branches/heathaze/src/world_entities/npcs/network_turret.h
===================================================================
--- branches/heathaze/src/world_entities/npcs/network_turret.h	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/network_turret.h	(revision 9940)
@@ -0,0 +1,52 @@
+/*!
+ * @file network_turret.h
+ * @brief description
+*/
+
+#ifndef _NETWORK_TURRET_H
+#define _NETWORK_TURRET_H
+
+#include "npcs/npc.h"
+
+class AimingTurret;
+
+//! A Class to ...
+class NetworkTurret : public NPC
+{
+  ObjectListDeclaration(NetworkTurret);
+public:
+  NetworkTurret(const TiXmlElement* root = NULL);
+  virtual ~NetworkTurret();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void postSpawn ();
+  virtual void leftWorld ();
+
+
+  virtual void destroy(WorldEntity* killer);
+
+  virtual void draw() const;
+  virtual void tick(float time);
+
+
+  void setTargetGroup(int targetGroup);
+  void setTargetGroupS(const std::string& targetGroup);
+
+  virtual void varChangeHandler( std::list<int> & id );
+
+
+private:
+  void init();
+
+private:
+  PNode  weaponHolder;
+  AimingTurret *weapon;
+
+  int    targetGroup;
+  int    targetGroup_write;
+
+  int    targetGroup_handle;
+};
+
+#endif /* _NETWORK_TURRET_H */
Index: branches/heathaze/src/world_entities/npcs/npc.cc
===================================================================
--- branches/heathaze/src/world_entities/npcs/npc.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/npc.cc	(revision 9940)
@@ -0,0 +1,53 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "npc.h"
+
+ObjectListDefinition(NPC);
+
+NPC::NPC(const TiXmlElement* root)
+{
+  this->registerObject(this, NPC::_objectList);
+
+  this->toList(OM_GROUP_00);
+
+}
+
+
+NPC::~NPC () {}
+
+
+
+/**
+ * adds an AI to this NPC
+ */
+void NPC::addAI(AI* ai)
+{}
+
+
+
+/**
+ * loads the xml tags
+ * @param root: root xml tag for this element
+ */
+void NPC::loadParams(const TiXmlElement* root)
+{
+   WorldEntity::loadParams(root);
+}
+
Index: branches/heathaze/src/world_entities/npcs/npc.h
===================================================================
--- branches/heathaze/src/world_entities/npcs/npc.h	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/npc.h	(revision 9940)
@@ -0,0 +1,24 @@
+
+#ifndef _NPC_H
+#define _NPC_H
+
+#include "world_entity.h"
+
+class AI;
+
+class NPC : public WorldEntity {
+  ObjectListDeclaration(NPC);
+ public:
+   NPC (const TiXmlElement* root);
+  virtual ~NPC ();
+
+  virtual void loadParams(const TiXmlElement* root = NULL);
+
+  void addAI(AI* ai);
+
+
+ private:
+
+};
+
+#endif /* _NPC_H */
Index: branches/heathaze/src/world_entities/npcs/npc_test.cc
===================================================================
--- branches/heathaze/src/world_entities/npcs/npc_test.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/npc_test.cc	(revision 9940)
@@ -0,0 +1,124 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "npc_test.h"
+#include "obb_tree.h"
+
+#include "shader.h"
+#include "state.h"
+#include "debug.h"
+
+#include "loading/factory.h"
+#include "loading/load_param.h"
+
+#include "effects/explosion.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(NPC2, CL_NPC_TEST2);
+CREATE_FACTORY(NPC2);
+
+NPC2::NPC2(const TiXmlElement* root)
+  : NPC(NULL)
+{
+  this->registerObject(this, NPC2::_objectList);
+
+  if ((float)rand()/RAND_MAX > .5f)
+    this->loadModel("models/ships/bolido.obj", 6);
+  else
+    this->loadModel("models/ships/gobblin.obj", 6);
+
+
+
+
+  this->shader = NULL;
+//  if (likely(Shader::checkShaderAbility()))
+    //this->shader = Shader::getShader("shaders/toon.vert", "shaders/toon.frag");
+
+  this->randomRotAxis = VECTOR_RAND(1);
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+NPC2::~NPC2 ()
+{}
+
+
+void NPC2::loadParams(const TiXmlElement* root)
+{
+  NPC::loadParams(root);
+
+}
+
+
+void NPC2::destroy(WorldEntity* killer)
+{
+  Explosion::explode(this, Vector(10,10,10));
+  this->toList(OM_DEAD);
+
+}
+
+
+
+/**
+ *  the entity is drawn onto the screen with this function
+ *
+ * This is a central function of an entity: call it to let the entity painted to the screen.
+ * Just override this function with whatever you want to be drawn.
+ */
+void NPC2::draw() const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  float matrix[4][4];
+
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  /* rotate */
+  this->getAbsDir ().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+
+//   if (this->shader != NULL && this->shader != Shader::getActiveShader())
+//     shader->activateShader();
+
+  this->getModel()->draw();
+//   shader->deactivateShader();
+
+
+/*  if (this->model)
+    this->model->draw();*/
+  glPopMatrix();
+}
+
+
+void NPC2::tick(float dt)
+{
+//  Vector direction = (State::getCameraTarget()->getAbsCoor() - this->getAbsCoor());
+
+  //if (directin.len() < 100)
+//  this->shiftCoor(direction *dt * 5 * exp(-direction.len() / 30.0));
+//  this->shiftDir(Quaternion(dt, this->randomRotAxis));
+
+}
+
+
+
Index: branches/heathaze/src/world_entities/npcs/npc_test.h
===================================================================
--- branches/heathaze/src/world_entities/npcs/npc_test.h	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/npc_test.h	(revision 9940)
@@ -0,0 +1,31 @@
+
+#ifndef _NPC22_H
+#define _NPC2_H
+
+#include "npc.h"
+
+class AI;
+class Shader;
+
+class NPC2 : public NPC {
+  ObjectListDeclaration(NPC2);
+
+ public:
+  NPC2 (const TiXmlElement* root);
+  virtual ~NPC2 ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void addAI(AI* ai);
+
+  virtual void destroy(WorldEntity* killer);
+
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+ private:
+   Vector   randomRotAxis;
+   Shader*  shader;
+};
+
+#endif /* _NPC2_H */
Index: branches/heathaze/src/world_entities/npcs/npc_test1.cc
===================================================================
--- branches/heathaze/src/world_entities/npcs/npc_test1.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/npc_test1.cc	(revision 9940)
@@ -0,0 +1,53 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "npc_test1.h"
+#include "obb_tree.h"
+
+#include "state.h"
+#include "power_ups/turret_power_up.h"
+#include "power_ups/laser_power_up.h"
+
+ObjectListDefinition(NPCTest1);
+
+NPCTest1::NPCTest1()
+  : NPC(NULL)
+{
+  this->registerObject(this, NPCTest1::_objectList);
+
+  if ((float)rand()/RAND_MAX > .5f)
+    this->loadModel("models/ships/bolido.obj", 2);
+  else
+    this->loadModel("models/ships/gobblin.obj", 2);
+
+  this->randomRotAxis =  VECTOR_RAND(1).getNormalized();
+}
+
+
+NPCTest1::~NPCTest1 () {}
+
+
+
+void NPCTest1::tick(float dt)
+{
+  this->shiftDir(Quaternion(dt, this->randomRotAxis));
+}
+
+
+
Index: branches/heathaze/src/world_entities/npcs/npc_test1.h
===================================================================
--- branches/heathaze/src/world_entities/npcs/npc_test1.h	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/npc_test1.h	(revision 9940)
@@ -0,0 +1,27 @@
+
+#ifndef _NPC_Test1_H
+#define _NPC_Test1_H
+
+#include "npc.h"
+
+class AI;
+
+class NPCTest1 : public NPC {
+  ObjectListDeclaration(NPCTest1);
+ public:
+  NPCTest1 ();
+  virtual ~NPCTest1 ();
+
+
+  void addAI(AI* ai);
+
+  virtual void tick(float dt);
+
+ private:
+   Vector   randomRotAxis;
+
+   WorldEntity* collider;
+
+};
+
+#endif /* _NPC_Test1_H */
Index: branches/heathaze/src/world_entities/npcs/repair_station.cc
===================================================================
--- branches/heathaze/src/world_entities/npcs/repair_station.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/repair_station.cc	(revision 9940)
@@ -0,0 +1,193 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+#include "interactive_model.h"
+
+
+#include "repair_station.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(RepairStation, CL_DOOR +1 );
+CREATE_FACTORY(RepairStation);
+
+
+
+//! list of all different animations a std md2model supports
+// sAnim RepairStation::animationList[2] =
+// {
+//  // begin, end, fps, interruptable
+//   {   0,  10,  30,  0 },   //!< OPEN
+//   {   10, 20,  30,  0 }    //!< CLOSE
+// };
+
+
+sAnim RepairStation::animationList[8] =
+{
+ // begin, end, fps, interruptable
+  {   0,  12,  20,  0 },   //!< CYCLE01
+  {   12, 24,  30,  0 },   //!< CYCLE02
+  {   24, 40,  10,  0 },   //!< CYCLE03
+  {   40, 55,  30,  0 },   //!< CYCLE04
+  {   55, 68,  20,  0 },   //!< CYCLE05
+  {   68, 81,  30,  0 },   //!< CYCLE06
+  {   81, 89,  40,  0 },   //!< CYCLE07
+  {   89, 99,  30,  0 }    //!< CYCLE08
+};
+
+
+
+RepairStation::RepairStation ()
+{
+  this->init();
+}
+
+
+RepairStation::RepairStation(const TiXmlElement* root)
+{
+  this->registerObject(this, RepairStation::_objectList);
+  this->scale = 1.0f;
+
+  if( root != NULL)
+    this->loadParams(root);
+
+  this->toList(OM_COMMON);
+
+  this->bActivated = true;
+  this->animationStep = 1;
+  this->animationCurrent = REPAIR_CYCLE01;
+
+  this->loadMD2Texture("maps/repairstation.jpg");
+  this->loadModel("models/creatures/repairstation.md2", this->scale);
+
+  this->setAnimation(REPAIR_CYCLE01, MD2_ANIM_ONCE);
+}
+
+
+RepairStation::~RepairStation ()
+{}
+
+
+
+/**
+ * loads the Settings of a MD2Creature from an XML-element.
+ * @param root the XML-element to load the MD2Creature's properties from
+ */
+void RepairStation::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "scale", this, RepairStation, setScale)
+      .describe("sets the scale of the repair station")
+      .defaultValues(1.0);
+}
+
+
+/**
+ * sets the animatin of this entity
+ */
+void  RepairStation::setAnimation(int animNum, int playbackMode)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->setAnimation(animationList[animNum].firstFrame,
+                                                         animationList[animNum].lastFrame,
+                                                         animationList[animNum].fps,
+                                                         animationList[animNum].bStoppable,
+                                                         playbackMode);
+}
+
+
+/**
+ * @returns the current animation number
+ */
+int RepairStation::getAnimation()
+{
+  if( likely(this->getModel(0) != NULL))
+    return ((InteractiveModel*)this->getModel(0))->getAnimation();
+  else
+    return -1;
+}
+
+
+
+/**
+ * @returns true if animation is finished
+ */
+bool RepairStation::isAnimationFinished()
+{
+  if( likely(this->getModel(0) != NULL))
+    return ((InteractiveModel*)this->getModel(0))->isAnimationFinished();
+  else
+    return false;
+}
+
+
+/**
+ * this activates the repair station and makes it working
+ */
+void RepairStation::activate()
+{
+  this->animationStep = 1;
+  this->bActivated = true;
+}
+
+
+/**
+ * this deactivates the repair station
+ */
+void RepairStation::deactivate()
+{
+  this->animationStep = 0;
+  this->bActivated = false;
+}
+
+
+/**
+ * this toggles the rotation direction
+ */
+void RepairStation::toggleRotation()
+{
+  this->animationStep *= -1;
+}
+
+
+/**
+ * ticks the door
+ * @param time: time since last tick
+ */
+void RepairStation::tick (float time)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((InteractiveModel*)this->getModel(0))->tick(time);
+
+  if( !this->bActivated)
+    return;
+
+  if( this->isAnimationFinished())
+  {
+    this->animationCurrent = (this->animationCurrent + this->animationStep) % REPAIR_MAX_ANIMATIONS;
+    this->setAnimation( this->animationCurrent, MD2_ANIM_ONCE);
+  }
+}
+
+
+
+
Index: branches/heathaze/src/world_entities/npcs/repair_station.h
===================================================================
--- branches/heathaze/src/world_entities/npcs/repair_station.h	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/repair_station.h	(revision 9940)
@@ -0,0 +1,64 @@
+#ifndef _REPAIR_STATION_H
+#define _REPAIR_STATION_H
+
+#include "world_entity.h"
+
+#include "md2/md2Model.h"
+
+class TiXmlElement;
+
+
+//! animation names enumeration
+typedef enum RepairStationAnimType
+{
+  REPAIR_CYCLE01 = 0,
+  REPAIR_CYCLE02,
+  REPAIR_CYCLE03,
+  REPAIR_CYCLE04,
+  REPAIR_CYCLE05,
+  REPAIR_CYCLE06,
+  REPAIR_CYCLE07,
+  REPAIR_CYCLE08,
+
+  REPAIR_MAX_ANIMATIONS
+};
+
+
+class RepairStation : public WorldEntity
+{
+  ObjectListDeclaration(RepairStation);
+  public:
+    RepairStation ();
+    RepairStation(const TiXmlElement* root);
+    virtual ~RepairStation ();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    void setScale(float scale) { this->scale = scale; }
+
+    void activate();
+    void deactivate();
+    void toggleRotation();
+
+    virtual void tick (float time);
+
+
+  private:
+    void setAnimation(int animNum, int playbackMode = 0);
+    int getAnimation();
+    bool isAnimationFinished();
+
+
+  private:
+    float          scale;             //!< the scale of the model
+
+    static sAnim   animationList[8];  //!< list of the animations
+
+    int            animationCurrent;  //!< number of the current animation
+    int            animationStep;     //!< the incrementation step of the animation
+
+    bool           bActivated;        //!< true if activated
+
+};
+
+#endif /* _REPAIR_STATION_H */
Index: branches/heathaze/src/world_entities/npcs/space_turret.cc
===================================================================
--- branches/heathaze/src/world_entities/npcs/space_turret.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/space_turret.cc	(revision 9940)
@@ -0,0 +1,245 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Manuel Leuenberger
+   co-programmer: ...
+*/
+
+#include "space_turret.h"
+#include "model.h"
+#include "world_entities/weapons/turret.h"
+
+#include "state.h"
+#include "playable.h"
+#include "player.h"
+
+
+#include "util/loading/factory.h"
+#include "network_game_manager.h"
+#include "util/loading/load_param.h"
+
+#include "effects/explosion.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(SpaceTurret, CL_SPACE_TURRET);
+CREATE_FACTORY(SpaceTurret);
+
+/**
+ * constructs and loads a SpaceTurret from a XML-element
+ * @param root the XML-element to load from
+ */
+SpaceTurret::SpaceTurret(const TiXmlElement* root)
+    : NPC(root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * standard deconstructor
+ */
+SpaceTurret::~SpaceTurret ()
+{}
+
+
+/**
+ * initializes the SpaceTurret
+ * @todo change this to what you wish
+ */
+void SpaceTurret::init()
+{
+  this->registerObject(this, SpaceTurret::_objectList);
+  this->loadModel("models/ground_turret_#.obj", 7.5);
+  this->loadModel("models/comet.obj", 1.0f, 3);
+  this->left = NULL;
+  this->right = NULL;
+
+  this->setHealthMax(100);
+  this->setHealth(30);
+
+  this->weaponHolder[0].addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->weaponHolder[1].addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+
+  this->weaponHolder[0].setRelCoor(0,25,0);
+  this->weaponHolder[0].setParent(this);
+  this->weaponHolder[1].setParent(this);
+
+  this->wLeftHandle = registerVarId( new SynchronizeableString( &this->wLeft, &this->wLeft, "weapon-left", PERMISSION_MASTER_SERVER ) );
+  this->wRightHandle = registerVarId( new SynchronizeableString( &this->wRight, &this->wRight, "weapon-right", PERMISSION_MASTER_SERVER ) );
+
+}
+
+
+/**
+ * loads a SpaceTurret from a XML-element
+ * @param root the XML-element to load from
+ * @todo make the class Loadable
+ */
+void SpaceTurret::loadParams(const TiXmlElement* root)
+{
+  // all the clases this Entity is directly derived from must be called in this way, to load all settings.
+  NPC::loadParams(root);
+
+
+  /**
+   * @todo: make the class Loadable
+   */
+  const TiXmlElement* element;
+
+  element = root->FirstChildElement("weapon-left");
+  if (element != NULL)
+    element = element->FirstChildElement();
+  if (element != NULL)
+    this->left = dynamic_cast<Weapon*>( Factory::fabricate( element) );
+  if (this->left)
+  {
+    this->wLeft = element->Value();
+
+    this->left->setParent(this);
+    this->left->toList(this->getOMListNumber());
+    this->left->setRelCoor(0,15,-7.5);
+    this->left->requestAction( WA_ACTIVATE);
+    this->left->setParent(&this->weaponHolder[0]);
+  }
+
+  element = root->FirstChildElement("weapon-right");
+  if (element != NULL)
+    element = element->FirstChildElement();
+  if (element != NULL)
+    this->right = dynamic_cast<Weapon*>( Factory::fabricate( element) );
+  if (this->right)
+  {
+    this->wRight = element->Value();
+
+    this->right->setParent(this);
+    this->right->toList(this->getOMListNumber());
+    this->right->setRelCoor(0,15,7.5);
+    this->left->requestAction( WA_ACTIVATE);
+    this->right->setParent(&this->weaponHolder[0]);
+  }
+}
+
+
+/**
+ * sets the left weapon called from net sync
+ * @param wLeft the left weapon string
+ */
+void SpaceTurret::setWeaponLeft(const std::string& wLeft)
+{}
+
+/**
+ * sets the left weapon called from net sync
+ * @param wRught the right weapon string
+ */
+void SpaceTurret::setWeaponRight(const std::string& wRight)
+{}
+
+/**
+ * advances the SpaceTurret about time seconds
+ * @param time the Time to step
+ */
+void SpaceTurret::tick(float dt)
+{
+  if(this->getHealth() > 0.0f && State::getPlayer() &&
+      State::getPlayer()->getPlayable() &&
+      State::getPlayer()->getPlayable()->distance(this) < 300) // HACK
+  {
+    if (likely(this->left != NULL))
+    {
+      //    this->left->tickW(dt);
+      this->left->requestAction(WA_SHOOT);
+    }
+    if (likely(this->right != NULL))
+    {
+      //    this->right->tickW(dt);
+      this->right->requestAction(WA_SHOOT);
+    }
+  }
+}
+
+/**
+ * draws this worldEntity
+ */
+void SpaceTurret::draw () const
+{
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  this->getModel()->draw();
+  if (this->getModel() != NULL)
+    this->getModel(3)->draw();
+  glPopMatrix();
+  /*
+    if (this->left != NULL)
+      this->left->draw();
+    if (this->right != NULL)
+      this->right->draw();*/
+}
+
+
+
+/**
+ *
+ *
+ */
+void SpaceTurret::postSpawn ()
+{}
+
+/**
+ *
+ *
+ */
+void SpaceTurret::leftWorld ()
+{}
+
+void SpaceTurret::destroy(WorldEntity* killer)
+{
+  this->setAbsDirSoft(Quaternion(-90, Vector(0,0,1)), 90);
+  Explosion::explode(this, Vector(10,10,10));
+
+  this->toList(OM_DEAD);
+
+  if (this->left)
+    this->left->toList(OM_DEAD);
+  if (this->right)
+    this->right->toList(OM_DEAD);
+
+}
+
+
+
+/**
+ * handler for changes on registred vars
+ * @param id id's which changed
+ */
+void SpaceTurret::varChangeHandler( std::list< int > & id )
+{
+  if ( std::find( id.begin(), id.end(), this->wLeftHandle ) != id.end())
+  {
+    this->setWeaponLeft(this->wLeft);
+  }
+
+  if ( std::find( id.begin(), id.end(), this->wRightHandle ) != id.end() )
+  {
+    this->setWeaponRight(this->wRight);
+  }
+
+
+  WorldEntity::varChangeHandler( id );
+}
+
Index: branches/heathaze/src/world_entities/npcs/space_turret.h
===================================================================
--- branches/heathaze/src/world_entities/npcs/space_turret.h	(revision 9940)
+++ branches/heathaze/src/world_entities/npcs/space_turret.h	(revision 9940)
@@ -0,0 +1,55 @@
+/*!
+ * @file space_turret.h
+ * @brief description
+*/
+
+#ifndef _SPACE_TURRET_H
+#define _SPACE_TURRET_H
+
+#include "npcs/npc.h"
+
+#include <string>
+#include <list>
+
+
+class Weapon;
+
+//! A Class to ...
+class SpaceTurret : public NPC
+{
+  ObjectListDeclaration(SpaceTurret);
+
+public:
+  SpaceTurret(const TiXmlElement* root = NULL);
+  virtual ~SpaceTurret();
+
+  virtual void loadParams(const TiXmlElement* root);
+  virtual void varChangeHandler( std::list< int > & id );
+
+
+  void setWeaponLeft(const std::string& wLeft);
+  void setWeaponRight(const std::string& wRight);
+
+  virtual void postSpawn ();
+  virtual void leftWorld ();
+
+  virtual void destroy(WorldEntity* killer);
+
+  virtual void draw() const;
+  virtual void tick(float time);
+
+private:
+  void init();
+
+
+private:
+  PNode  weaponHolder[2];
+  Weapon *left, *right;
+
+  std::string wLeft;
+  std::string wRight;
+  int wLeftHandle;
+  int wRightHandle;
+};
+
+#endif /* _SPACE_TURRET_H */
Index: branches/heathaze/src/world_entities/particles/box_emitter.cc
===================================================================
--- branches/heathaze/src/world_entities/particles/box_emitter.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/box_emitter.cc	(revision 9940)
@@ -0,0 +1,117 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "box_emitter.h"
+
+#include "particle_system.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(BoxEmitter, CL_BOX_EMITTER);
+CREATE_FACTORY(BoxEmitter);
+
+/**
+ *  standard constructor
+*/
+BoxEmitter::BoxEmitter(const Vector& size, float emissionRate, float velocity, float angle)
+    :  ParticleEmitter(emissionRate, velocity, angle)
+{
+  this->init();
+  this->setSize(size);
+}
+
+/**
+ *  constructs and loads a BoxEmitter from a XML-element
+ * @param root the XML-element to load from
+*/
+BoxEmitter::BoxEmitter(const TiXmlElement* root)
+    : ParticleEmitter()
+{
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard destructor
+
+   removes the EmitterSystem from the ParticleEngine
+*/
+BoxEmitter::~BoxEmitter ()
+{
+  this->setSystem(NULL);
+}
+
+/**
+  @brief initializes default values of a ParitcleEmitter
+*/
+void BoxEmitter::init()
+{
+  this->registerObject(this, BoxEmitter::_objectList);
+  this->setSize(1.0f,1.0f,1.0f);
+}
+
+void BoxEmitter::loadParams(const TiXmlElement* root)
+{
+  ParticleEmitter::loadParams(root);
+
+  LoadParam(root, "size", this, BoxEmitter, setSize)
+  .describe("The Size of the BoxEmitter: x, y, z")
+  .defaultValues(1.0f,1.0f,1.0f);
+}
+
+void BoxEmitter::setSize(float x, float y, float z)
+{
+  this->size = Vector (x,y,z);
+}
+
+
+void BoxEmitter::emitParticles(unsigned int count) const
+{
+  Vector inheritVelocity = this->getVelocity() * this->inheritSpeed;
+
+  Vector xDir = this->getAbsDirX() * this->size.x;
+  Vector yDir = this->getAbsDirY() * this->size.y;
+  Vector zDir = this->getAbsDirZ() * this->size.z;
+
+  for (unsigned int i = 0; i < count; i++)
+  {
+    Vector randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
+    randDir.normalize();
+    randDir = (Quaternion(angle + randomAngle *((float)rand()/RAND_MAX -.5), randDir)).apply(this->getAbsDirX());
+    Vector velocityV = randDir.getNormalized()*this->velocity + inheritVelocity;
+
+    Vector box = this->getAbsCoor() +
+                 xDir * ((float)rand()/RAND_MAX -.5) +
+                 yDir * ((float)rand()/RAND_MAX -.5) +
+                 zDir * ((float)rand()/RAND_MAX -.5);
+
+    // ROTATIONAL CALCULATION (this must not be done for all types of particles.)
+    randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
+    randDir.normalize();
+    Quaternion orient = Quaternion(M_PI, randDir);
+    Quaternion moment = Quaternion(this->momentum + this->momentumRandom, randDir);
+
+    this->getSystem()->addParticle(box, velocityV, orient, moment);
+
+  }
+}
Index: branches/heathaze/src/world_entities/particles/box_emitter.h
===================================================================
--- branches/heathaze/src/world_entities/particles/box_emitter.h	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/box_emitter.h	(revision 9940)
@@ -0,0 +1,46 @@
+/*!
+ * @file box_emitter.h
+ *  Definition of a BoxEmitter
+ */
+
+#ifndef _BOX_EMITTER_H
+#define _BOX_EMITTER_H
+
+#include "particle_emitter.h"
+
+#define BOX_EMITTER_DEFAULT_SIZE Vector(1.0f, 1.0f, 1.0f)
+
+//! A class to handle a Box Emitter.
+/**
+ * A Box Emitter is a special kind of emitter, that has the (underlying) PNode
+ * at its center, and from there on is a Box in the Direction of the PNode
+ * out around size in the corresponding directions
+ */
+class BoxEmitter : public ParticleEmitter
+{
+  ObjectListDeclaration(BoxEmitter);
+  friend class ParticleSystem;
+public:
+  BoxEmitter(const Vector& size = BOX_EMITTER_DEFAULT_SIZE,
+             float emissionRate = PARTICLE_EMITTER_DEFAULT_EMISSION_RATE,
+             float velocity = PARTICLE_EMITTER_DEFAULT_VELOCITY,
+             float angle = PARTICLE_EMITTER_DEFAULT_SPREAD);
+  BoxEmitter(const TiXmlElement* root);
+  virtual ~BoxEmitter();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setSize(float x, float y, float z);
+  void setSize(const Vector& size) { this->setSize(size.x, size.y, size.z); };
+
+protected:
+  virtual void emitParticles(unsigned int count) const;
+
+private:
+  void init();
+
+private:
+  Vector      size;
+};
+
+#endif /* _BOX_EMITTER_H */
Index: branches/heathaze/src/world_entities/particles/dot_emitter.cc
===================================================================
--- branches/heathaze/src/world_entities/particles/dot_emitter.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/dot_emitter.cc	(revision 9940)
@@ -0,0 +1,93 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "dot_emitter.h"
+
+#include "particle_system.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "debug.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(DotEmitter, CL_DOT_EMITTER);
+CREATE_FACTORY(DotEmitter);
+
+/**
+ *  standard constructor
+*/
+DotEmitter::DotEmitter(float emissionRate, float velocity, float angle)
+    : ParticleEmitter( emissionRate, velocity, angle)
+{
+  this->init();
+}
+
+/**
+ *  constructs and loads a DotEmitter from a XML-element
+ * @param root the XML-element to load from
+*/
+DotEmitter::DotEmitter(const TiXmlElement* root)
+    : ParticleEmitter()
+{
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard destructor
+
+   removes the EmitterSystem from the ParticleEngine
+*/
+DotEmitter::~DotEmitter ()
+{
+  this->setSystem(NULL);
+}
+
+/**
+  @brief initializes default values of a ParitcleEmitter
+*/
+void DotEmitter::init()
+{
+  this->registerObject(this, DotEmitter::_objectList);
+}
+
+void DotEmitter::emitParticles(unsigned int count) const
+{
+  Vector inheritVelocity = this->getVelocity() * this->inheritSpeed;
+
+  for (unsigned int i = 0; i < count; i++)
+  {
+    Vector randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
+    randDir.normalize();
+    randDir = (Quaternion(angle + randomAngle *((float)rand()/RAND_MAX -.5), randDir)).apply(this->getAbsDirX());
+    Vector velocityV = randDir.getNormalized()*this->velocity + inheritVelocity;
+
+    // ROTATIONAL CALCULATION (this must not be done for all types of particles.)
+    randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
+    randDir.normalize();
+    Quaternion orient = Quaternion(M_PI, randDir);
+    Quaternion moment = Quaternion(this->momentum + this->momentumRandom, randDir);
+
+    this->getSystem()->addParticle(this->getAbsCoor() + this->getVelocity()*.1*rand()/RAND_MAX,
+                                   velocityV, orient, moment);
+
+  }
+}
Index: branches/heathaze/src/world_entities/particles/dot_emitter.h
===================================================================
--- branches/heathaze/src/world_entities/particles/dot_emitter.h	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/dot_emitter.h	(revision 9940)
@@ -0,0 +1,29 @@
+/*!
+ * @file dot_emitter.h
+ *  Definition of a DotEmitter
+ */
+
+#ifndef _DOT_EMITTER_H
+#define _DOT_EMITTER_H
+
+#include "particle_emitter.h"
+
+//! A class to handle an Emitter.
+class DotEmitter : public ParticleEmitter
+{
+  ObjectListDeclaration(DotEmitter);
+
+  friend class ParticleSystem;
+public:
+  DotEmitter(float emissionRate = 1.0, float velocity = 1.0, float angle = .5);
+  DotEmitter(const TiXmlElement* root);
+  virtual ~DotEmitter();
+
+protected:
+  virtual void emitParticles(unsigned int count) const;
+
+private:
+  void init();
+};
+
+#endif /* _DOT_EMITTER_H */
Index: branches/heathaze/src/world_entities/particles/dot_particles.cc
===================================================================
--- branches/heathaze/src/world_entities/particles/dot_particles.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/dot_particles.cc	(revision 9940)
@@ -0,0 +1,111 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "dot_particles.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "material.h"
+#include "state.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(DotParticles, CL_DOT_PARTICLES);
+CREATE_FACTORY(DotParticles);
+
+
+/**
+ *  standard constructor
+ * @param maxCount the Count of particles in the System
+ * @param type The Type of the DotParticles
+*/
+DotParticles::DotParticles (unsigned int maxCount)
+  : ParticleSystem(maxCount)
+{
+  this->init();
+}
+
+/**
+ * @brief creates a Particle System out of a XML-element
+ * @param root: the XML-element to load from
+ */
+DotParticles::DotParticles(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+DotParticles::~DotParticles()
+{ }
+
+/**
+ * @brief initializes the DotParticles with default values
+*/
+void DotParticles::init()
+{
+  this->registerObject(this, DotParticles::_objectList);
+
+  this->material.setDiffuseMap("maps/radial-trans-noise.png");
+}
+
+
+/**
+ * loads Parameters from a TiXmlElement
+ * @param root the XML-element to load from.
+ */
+void DotParticles::loadParams(const TiXmlElement* root)
+{
+  ParticleSystem::loadParams(root);
+}
+
+/**
+ * @brief draws all the Particles of this System
+ *
+ * The Cases in this Function all do the same:
+ * Drawing all the particles with the appropriate Type.
+ * This is just the fastest Way to do this, but will most likely be changed in the future.
+ */
+void DotParticles::draw() const
+{
+  glPushAttrib(GL_ENABLE_BIT);
+
+  GLboolean checkLight = false;
+  glGetBooleanv(GL_LIGHTING, &checkLight);
+  if (checkLight == GL_TRUE)
+    glDisable(GL_LIGHTING);
+
+  glMatrixMode(GL_MODELVIEW);
+  glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
+
+  Particle* drawPart = particles;
+  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+  glBegin(GL_POINTS);
+  while (likely(drawPart != NULL))
+  {
+    glColor4fv(drawPart->color);
+    glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z);
+
+    drawPart = drawPart->next;
+  }
+  glEnd();
+  glPopAttrib();
+}
Index: branches/heathaze/src/world_entities/particles/dot_particles.h
===================================================================
--- branches/heathaze/src/world_entities/particles/dot_particles.h	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/dot_particles.h	(revision 9940)
@@ -0,0 +1,36 @@
+/*!
+ * @file dot_particles.h
+
+*/
+
+#ifndef _DOT_PARTICLE_SYSTEM_H
+#define _DOT_PARTICLE_SYSTEM_H
+
+#include "particle_system.h"
+#include "material.h"
+
+//! A class to handle ParticleSystems
+class DotParticles : public ParticleSystem
+{
+  ObjectListDeclaration(DotParticles);
+
+public:
+  DotParticles(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT);
+  DotParticles(const TiXmlElement* root);
+  virtual ~DotParticles();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  /** @returns the Material that lies on this particles */
+  inline const Material* getMaterial() const { return &this->material; };
+
+  virtual void draw() const;
+
+private:
+  void init();
+
+private:
+  Material          material;            //!< A Material for all the Particles.
+};
+
+#endif /* _DOT_PARTICLE_SYSTEM_H */
Index: branches/heathaze/src/world_entities/particles/engine/particle_engine.cc
===================================================================
--- branches/heathaze/src/world_entities/particles/engine/particle_engine.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/engine/particle_engine.cc	(revision 9940)
@@ -0,0 +1,454 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "particle_engine.h"
+
+#include "class_list.h"
+
+#include "debug.h"
+#include "stdlibincl.h"
+#include "util/loading/load_param.h"
+
+
+
+/**
+ *  standard constructor
+*/
+ParticleEngine::ParticleEngine ()
+{
+   this->setClassID(CL_PARTICLE_ENGINE, "ParticleEngine");
+   this->setName("ParticleEngine");
+
+   this->systemList = new tList<ParticleSystem>;
+   this->emitterList = new tList<ParticleEmitter>;
+   this->connectionList = new tList<ParticleConnection>;
+}
+
+/**
+ *  the singleton reference to this class
+*/
+ParticleEngine* ParticleEngine::singletonRef = NULL;
+
+/**
+ *  deletes all the system, emitters, connections and Lists
+*/
+ParticleEngine::~ParticleEngine ()
+{
+  /// @todo we must not do this, because PNoe does it for us
+  /// or we do this with help from ClassList, which essentially makes much more sense
+
+  // delete all remaining systems
+//   tIterator<ParticleSystem>* sysIt = this->systemList->getIterator();
+//   ParticleSystem* tmpSys = sysIt->firstElement();
+//   while(tmpSys)
+//     {
+//       delete tmpSys;
+//       tmpSys = sysIt->nextElement();
+//     }
+//   delete sysIt;
+   delete this->systemList;
+//
+   // delete all remaining emitters
+   tIterator<ParticleEmitter>* emitIt = this->emitterList->getIterator();
+   ParticleEmitter* tmpEmit = emitIt->firstElement();
+   while(tmpEmit)
+     {
+       delete tmpEmit;
+       tmpEmit = emitIt->nextElement();
+     }
+   delete emitIt;
+   delete this->emitterList;
+
+  // there should be no more Connections
+  if (this->connectionList->getSize() == 0)
+    delete this->connectionList;
+  else
+    PRINTF(2)("The Connection List is not empty. This should not happen.\n");
+
+  ParticleEngine::singletonRef = NULL;
+}
+
+/**
+  \brief loads the ParticleEngines settings and connections between particles and emitters
+* @param root the XML-element to load this from.
+ */
+void ParticleEngine::loadParams(const TiXmlElement* root)
+{
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    LoadParam_CYCLE(element, "connect", this, ParticleEngine, addConnection)
+        .describe("connects an Emitter to a System (emitterName, systemName)");
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ *  Adds a System to the System list.
+
+   this is done automatically when creating a ParticleSystem
+*/
+void ParticleEngine::addSystem(ParticleSystem* system)
+{
+  this->systemList->add(system);
+}
+
+/**
+ *  Adds an emitter to the emitterList
+
+   this is done automatically when creating a ParticleEmitter
+*/
+void ParticleEngine::addEmitter(ParticleEmitter* emitter)
+{
+  this->emitterList->add(emitter);
+}
+
+/**
+* @brief Connects a ParticleSystem to a ParticleSystem thus emitting Particles.
+* @param emitter the Emitter to connect to the System
+* @param system the System to connect to the Emitter
+*/
+void ParticleEngine::addConnection(const std::string& emitter, const std::string& system)
+{
+  ParticleEmitter* tmpEmit = dynamic_cast<ParticleEmitter*>(ClassList::getObject(emitter, CL_PARTICLE_EMITTER));//this->getEmitterByName(emitter);
+  ParticleSystem* tmpSys = dynamic_cast<ParticleSystem*>(ClassList::getObject(system, CL_PARTICLE_SYSTEM));//this->getSystemByName(system);
+
+  if (tmpEmit != NULL && tmpSys != NULL)
+    this->addConnection(tmpEmit, tmpSys);
+  else
+  {
+    if (tmpEmit == NULL)
+      PRINTF(2)("Emitter %s not found in the List of emitters, not connecting to %s\n", emitter.c_str(), system.c_str());
+    if (tmpEmit == NULL)
+      PRINTF(2)("System %s not found in the List of emitters, not connecting to %s\n", system.c_str(), emitter.c_str());
+  }
+}
+
+/**
+ *  Connects a ParticleSystem to a ParticleSystem thus emitting Particles.
+ * @param emitter the Emitter to connect to the System
+ * @param system the System to connect to the Emitter
+*/
+void ParticleEngine::addConnection(ParticleEmitter* emitter, ParticleSystem* system)
+{
+  // look, if we have already added this connection
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection)
+    {
+      if (tmpConnection->emitter == emitter && tmpConnection->system == system)
+        {
+          PRINTF(2)("Connection between Emitter and System already exists.\n");
+          delete tmpConIt;
+          return;
+        }
+
+      tmpConnection = tmpConIt->nextElement();
+    }
+  delete tmpConIt;
+
+
+
+  ParticleConnection* tmpCon = new ParticleConnection;
+  tmpCon->emitter = emitter;
+  tmpCon->system = system;
+
+  this->connectionList->add(tmpCon);
+}
+
+/**
+ *  Removes a system from the systemList and also removes all Connections to the System
+ * @param system The ParticleSystem to delete
+*/
+bool ParticleEngine::removeSystem(ParticleSystem* system)
+{
+  // remove any connections, that have this system within
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection != NULL)
+    {
+      if (tmpConnection->system == system)
+        this->breakConnection(tmpConnection);
+      tmpConnection = tmpConIt->nextElement();
+    }
+  delete tmpConIt;
+
+  // remove the System from the systemList.
+  this->systemList->remove(system);
+}
+
+/**
+ *  removes an emitter from the emitterList and also from all Connections it is attached to.
+ * @param emitter the ParticleEmitter to remove.
+*/
+bool ParticleEngine::removeEmitter(ParticleEmitter* emitter)
+{
+  // remove any connections, that have this emitter within
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection != NULL)
+    {
+      if (tmpConnection->emitter == emitter)
+        this->breakConnection(tmpConnection);
+      tmpConnection = tmpConIt->nextElement();
+    }
+  delete tmpConIt;
+
+  // remove the emitter from the emitterList
+  this->emitterList->remove(emitter);
+}
+
+
+/**
+ *  removes a Connection between an Emitter and a System
+ * @param connection the connection to remove
+ *
+ * \see bool ParticleEngine::breakConnection(ParticleEmitter* emitter, ParticleSystem* system)
+ */
+bool ParticleEngine::breakConnection(ParticleConnection* connection)
+{
+  this->connectionList->remove(connection);
+  return true;
+}
+
+/**
+ *  removes a Connection between an Emitter and a System
+ * @param emitter The emitter of the connection to remove
+ * @param system The system of the connection to remove
+ * @returns true, if the connection was broken, false if the conntection was not found
+ *
+ * only if both system and emitter are in the connection the Connection will be broken
+*/
+bool ParticleEngine::breakConnection(ParticleEmitter* emitter, ParticleSystem* system)
+{
+  // look, if we have already added this connection
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection)
+    {
+    if (tmpConnection->emitter == emitter && tmpConnection->system == system)
+      {
+        this->breakConnection(tmpConnection);
+        delete tmpConIt;
+        return true;
+      }
+    tmpConnection = tmpConIt->nextElement();
+    }
+  delete tmpConIt;
+  return false;
+}
+
+/**
+ *  removes a Connection between an Emitter and a System
+ * @param emitter The emitter of the connections to remove
+ * @returns the count of connections that were broken, 0 if no conntection was not found
+ */
+unsigned int ParticleEngine::breakConnections(ParticleEmitter* emitter)
+{
+  unsigned int retVal = 0;
+  // look, if we have already added this connection
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection)
+  {
+    if (tmpConnection->emitter == emitter)
+    {
+      this->breakConnection(tmpConnection);
+      retVal++;
+    }
+    tmpConnection = tmpConIt->nextElement();
+  }
+  delete tmpConIt;
+  return retVal;
+}
+
+
+/**
+ *  removes a Connection between an Emitter and a System
+ * @param system The system of the connections to remove
+ * @returns the count of connections that were broken, 0 if no conntection was not found
+ */
+unsigned int ParticleEngine::breakConnections(ParticleSystem* system)
+{
+  unsigned int retVal = 0;
+  // look, if we have already added this connection
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection)
+  {
+    if (tmpConnection->system == system)
+    {
+      this->breakConnection(tmpConnection);
+      retVal++;
+    }
+    tmpConnection = tmpConIt->nextElement();
+  }
+  delete tmpConIt;
+  return retVal;
+}
+
+/**
+ *  this function ticks all the ParticleSystems, so an animation will flow
+ * @param dt passed since last tick
+*/
+void ParticleEngine::tick(float dt)
+{
+  // ticks all the ParticleSystems
+//   tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
+//   ParticleSystem* tmpSys = tmpIt->firstElement();
+//   while(tmpSys)
+//     {
+//       tmpSys->tick(dt);
+//       tmpSys = tmpIt->nextElement();
+//     }
+//   delete tmpIt;
+
+  // add new Particles to each System connected to an Emitter.
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection)
+    {
+      tmpConnection->emitter->tick(dt, tmpConnection->system);
+      tmpConnection = tmpConIt->nextElement();
+    }
+  delete tmpConIt;
+}
+
+/**
+ *  draws all the systems and their Particles.
+*/
+void ParticleEngine::draw() const
+{
+  /*
+  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
+  ParticleSystem* tmpSys = tmpIt->firstElement();
+  while(tmpSys)
+    {
+      tmpSys->draw();
+      tmpSys = tmpIt->nextElement();
+    }
+  delete tmpIt;*/
+
+}
+
+/**
+ * @param number the n-th system to return
+ * @returns the system called by number or NULL if not found
+*/
+ParticleSystem* ParticleEngine::getSystemByNumber(unsigned int number) const
+{
+  int count = 0;
+  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
+  ParticleSystem* tmpSys = tmpIt->firstElement();
+  while(tmpSys)
+    {
+      count++;
+      if ( count == number)
+        {
+          delete tmpIt;
+          return tmpSys;
+        }
+      tmpSys = tmpIt->nextElement();
+    }
+  delete tmpIt;
+  return NULL;
+}
+
+/**
+ * @param number the n-th emitter to return
+ * @returns the emitter called by number or NULL if not found
+*/
+ParticleEmitter* ParticleEngine::getEmitterByNumber(unsigned int number) const
+{
+  int count = 0;
+  tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
+  ParticleEmitter* tmpEmit = tmpIt->firstElement();
+  while(tmpEmit)
+    {
+      count++;
+      if ( count == number)
+        {
+          delete tmpIt;
+          return tmpEmit;
+        }
+      tmpEmit = tmpIt->nextElement();
+    }
+  delete tmpIt;
+  return NULL;
+}
+
+/**
+ *  outputs some nice debug information
+*/
+void ParticleEngine::debug()
+{
+  PRINT(0)("+-----------------------------------+\n");
+  PRINT(0)("+ PARTICLE-ENGINE DEBUG INFORMATION +\n");
+  PRINT(0)("+-----------------------------------+\n");
+  PRINT(0)(" Reference: %p\n", ParticleEngine::singletonRef);
+  PRINT(0)(" Count: Emitters: %d; Systems: %d, Connections: %d\n",
+  this->emitterList->getSize(), this->systemList->getSize(), this->connectionList->getSize());
+
+  if (this->connectionList->getSize() > 0)
+  {
+    PRINT(0)(" Connections:\n");
+    PRINT(0)(" -----------------------------------\n");
+
+    tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+    ParticleConnection* tmpConnection = tmpConIt->firstElement();
+    while(tmpConnection)
+    {
+      PRINT(0)(" Emitter '%s' emitts into System '%s'\n", tmpConnection->emitter->getName(), tmpConnection->system->getName());
+      tmpConnection = tmpConIt->nextElement();
+    }
+    delete tmpConIt;
+  }
+
+  if (this->systemList->getSize() > 0)
+  {
+    tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
+    ParticleSystem* tmpSys = tmpIt->firstElement();
+    while(tmpSys)
+    {
+      tmpSys->debug();
+      tmpSys = tmpIt->nextElement();
+    }
+    delete tmpIt;
+  }
+  else
+  {
+    PRINT(0)("NO SYSTEMS\n");
+  }
+  if (this->emitterList->getSize() > 0)
+  {
+    tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
+    ParticleEmitter* tmpEmit = tmpIt->firstElement();
+    while(tmpEmit)
+    {
+      tmpEmit->debug();
+      tmpEmit = tmpIt->nextElement();
+    }
+    delete tmpIt;
+  }
+  else
+  {
+    PRINTF(0)("NO EMITTERS\n");
+  }
+
+  PRINT(0)("+--------------------------------PE-+\n");
+
+}
+
Index: branches/heathaze/src/world_entities/particles/engine/particle_engine.h
===================================================================
--- branches/heathaze/src/world_entities/particles/engine/particle_engine.h	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/engine/particle_engine.h	(revision 9940)
@@ -0,0 +1,72 @@
+/*!
+ * @file particle_engine.h
+  *  Definition of the ParticleEngine
+*/
+
+#ifndef _PARTICLE_ENGINE_H
+#define _PARTICLE_ENGINE_H
+
+#include "base_object.h"
+
+#include "particle_system.h"
+#include "particle_emitter.h"
+#include <list>
+
+#include "parser/tinyxml/tinyxml.h"
+
+// FORWARD DECLARATION
+
+//! A ParticleConnection enables us to emitt from any emitter into any other particleSystem
+typedef struct ParticleConnection
+{
+  ParticleEmitter*    emitter;     //!< The emitter to emit system from.
+  ParticleSystem*     system;      //!< The Particles emitted from emitter.
+};
+
+//! The physicsEngine handles and stores Systems and Emitters.
+/**
+   It is responsible for driving on the Particles (tick)
+   It draw particles (draw)
+   and it emitts particles into the system
+*/
+class ParticleEngine : public BaseObject {
+
+ public:
+  virtual ~ParticleEngine();
+  /** @returns a Pointer to the only object of this Class */
+  inline static ParticleEngine* getInstance() { if (!singletonRef) singletonRef = new ParticleEngine();  return singletonRef; };
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void tick(float dt);
+  void draw() const;
+
+  void addSystem(ParticleSystem* system);
+  void addEmitter(ParticleEmitter* emitter);
+  void addConnection(ParticleEmitter* emitter, ParticleSystem* system);
+  void addConnection(const std::string& emitter, const std::string& system);
+
+
+  bool removeSystem(ParticleSystem* system);
+  bool removeEmitter(ParticleEmitter* emitter);
+  bool breakConnection(ParticleConnection* connection);
+  bool breakConnection(ParticleEmitter* emitter, ParticleSystem* system);
+  unsigned int breakConnections(ParticleEmitter* emitter);
+  unsigned int breakConnections(ParticleSystem* system);
+
+   ParticleSystem* getSystemByNumber(unsigned int number) const;
+   ParticleEmitter* getEmitterByNumber(unsigned int number) const;
+
+  void debug();
+
+ private:
+  ParticleEngine();
+  static ParticleEngine* singletonRef;        //!< The reference to the engine.
+
+  std::list<ParticleSystem> systemList;          //!< A list of Systems handled by the ParticleEngine.
+  std::list<ParticleEmitter> emitterList;        //!< A list of Emitters handled by the ParticleEngine.
+
+  tList<ParticleConnection>* connectionList;  //!< A list of Connections between Systems and Emitters.
+};
+
+#endif /* _PARTICLE_ENGINE_H */
Index: branches/heathaze/src/world_entities/particles/model_particles.cc
===================================================================
--- branches/heathaze/src/world_entities/particles/model_particles.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/model_particles.cc	(revision 9940)
@@ -0,0 +1,140 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "model_particles.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "material.h"
+#include "state.h"
+#include "shell_command.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(ModelParticles, CL_MODEL_PARTICLES);
+CREATE_FACTORY(ModelParticles);
+
+SHELL_COMMAND(texture, ModelParticles, setMaterialTexture)
+->defaultValues("maps/evil-flower.png");
+
+
+
+/**
+ *  standard constructor
+ * @param maxCount the Count of particles in the System
+ * @param type The Type of the ModelParticles
+*/
+ModelParticles::ModelParticles (unsigned int maxCount)
+    : ParticleSystem(maxCount)
+{
+  this->init();
+}
+
+/**
+ * @brief creates a Particle System out of a XML-element
+ * @param root: the XML-element to load from
+ */
+ModelParticles::ModelParticles(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+ModelParticles::~ModelParticles()
+{ }
+
+/**
+ * @brief initializes the ModelParticles with default values
+*/
+void ModelParticles::init()
+{
+  this->registerObject(this, ModelParticles::_objectList);
+
+  this->material.setDiffuseMap("maps/radial-trans-noise.png");
+}
+
+
+/**
+ * loads Parameters from a TiXmlElement
+ * @param root the XML-element to load from.
+ */
+void ModelParticles::loadParams(const TiXmlElement* root)
+{
+  ParticleSystem::loadParams(root);
+
+  LoadParam(root, "texture", this, ModelParticles, setMaterialTexture);
+}
+
+/**
+ * @brief sets the Texutre that is placed onto the particles
+ * @param textureFile the Texture to load onto these ModelParticles
+ */
+void ModelParticles::setMaterialTexture(const std::string& textureFile)
+{
+  this->material.setDiffuseMap(textureFile);
+}
+
+/**
+ * @brief draws all the Particles of this System
+ *
+ * The Cases in this Function all do the same:
+ * Drawing all the particles with the appropriate Type.
+ * This is just the fastest Way to do this, but will most likely be changed in the future.
+ */
+void ModelParticles::draw() const
+{
+  glPushAttrib(GL_ENABLE_BIT);
+  Particle* drawPart = particles;
+
+  GLboolean checkLight = false;
+  glGetBooleanv(GL_LIGHTING, &checkLight);
+  if (checkLight == GL_TRUE)
+    glDisable(GL_LIGHTING);
+  glMatrixMode(GL_MODELVIEW);
+
+  this->material.select();
+  glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
+
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+  if (likely(this->getModel() != NULL))
+    while (likely(drawPart != NULL))
+    {
+      glPushMatrix();
+      glMatrixMode(GL_MODELVIEW);
+      /* move */
+      glTranslatef(drawPart->position.x, drawPart->position.y, drawPart->position.z);
+      /* scale */
+      glScalef(drawPart->radius, drawPart->radius, drawPart->radius);
+      /* rotate */
+      Vector tmpRot = drawPart->orientation.getSpacialAxis();
+      glRotatef (drawPart->orientation.getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+      this->getModel()->draw();
+
+      glPopMatrix();
+      drawPart = drawPart->next;
+    }
+  else
+    PRINTF(2)("no model loaded onto ParticleSystem-%s\n", this->getCName());
+  glPopAttrib();
+}
Index: branches/heathaze/src/world_entities/particles/model_particles.h
===================================================================
--- branches/heathaze/src/world_entities/particles/model_particles.h	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/model_particles.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file model_particles.h
+
+*/
+
+#ifndef _MODEL_PARTICLE_SYSTEM_H
+#define _MODEL_PARTICLE_SYSTEM_H
+
+#include "particle_system.h"
+#include "material.h"
+
+//! A class to handle ParticleSystems
+class ModelParticles : public ParticleSystem
+{
+  ObjectListDeclaration(ModelParticles);
+
+public:
+  ModelParticles(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT);
+  ModelParticles(const TiXmlElement* root);
+  virtual ~ModelParticles();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setMaterialTexture(const std::string& textureFile);
+
+  /** @returns the Material that lies on this particles */
+  inline const Material* getMaterial() const { return &this->material; };
+
+  virtual void draw() const;
+
+private:
+  void init();
+
+private:
+  Material          material;            //!< A Material for all the Particles.
+};
+
+#endif /* _MODEL_PARTICLE_SYSTEM_H */
Index: branches/heathaze/src/world_entities/particles/particle_emitter.cc
===================================================================
--- branches/heathaze/src/world_entities/particles/particle_emitter.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/particle_emitter.cc	(revision 9940)
@@ -0,0 +1,201 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "particle_emitter.h"
+
+#include "particle_system.h"
+
+#include "util/loading/load_param.h"
+#include "debug.h"
+
+ObjectListDefinition(ParticleEmitter);
+
+/**
+ *  standard constructor
+*/
+ParticleEmitter::ParticleEmitter(float emissionRate, float velocity, float angle)
+{
+  this->registerObject(this, ParticleEmitter::_objectList);
+
+  this->system = NULL;
+
+  this->setInheritSpeed(PARTICLE_EMITTER_DEFAULT_INHERIT_SPEED);
+  this->setEmissionMomentum(0);
+  this->setSpread(angle);
+  this->setEmissionRate(emissionRate);
+  this->setEmissionVelocity(velocity);
+
+  this->saveTime = 0.0;
+}
+
+/**
+ *  standard destructor
+
+   removes the EmitterSystem from the ParticleEngine
+*/
+ParticleEmitter::~ParticleEmitter ()
+{
+  this->setSystem(NULL);
+}
+
+/**
+ *  loads a ParticleEmitter from a XML-element
+ * @param root the XML-element to load from
+*/
+void ParticleEmitter::loadParams(const TiXmlElement* root)
+{
+  PNode::loadParams(root);
+
+  LoadParam(root, "rate", this, ParticleEmitter, setEmissionRate)
+    .describe("How many particles should be emittet from this emitter");
+
+  LoadParam(root, "inherit-speed", this, ParticleEmitter, setInheritSpeed)
+    .describe("the extent, the speed of the emitter has on the particles");
+
+  LoadParam(root, "emission-velocity", this, ParticleEmitter, setEmissionVelocity)
+    .describe("How fast the particles are emittet (their initial speed)");
+
+  LoadParam(root, "emission-momentum", this, ParticleEmitter, setEmissionMomentum)
+      .describe("How fast the particles rotation is at emissiontime (their initial momentum)");
+
+  LoadParam(root, "spread", this, ParticleEmitter, setSpread)
+    .describe("The angle the particles are emitted from (angle, deviation)");
+}
+
+void ParticleEmitter::setSystem(ParticleSystem* system)
+{
+  if (system != NULL)
+    system->addEmitter(this);
+  else if (this->system != NULL)
+    this->system->removeEmitter(this);
+}
+
+/**
+ *  this start the emitter
+*/
+void ParticleEmitter::start() {}
+
+
+/**
+ *  this stops the emitter
+*/
+void ParticleEmitter::stop() {}
+
+
+/**
+ *  set the emission rate
+ * @param emissionRate: sets the number of particles emitted per second
+
+   if you want to change the value of this variable during emission time (to make it more dynamic)
+   you may want to use the animation class
+*/
+void ParticleEmitter::setEmissionRate(float emissionRate)
+{
+  if (emissionRate > 0.0)
+    this->emissionRate = emissionRate;
+  else
+    this->emissionRate = 0.0;
+}
+
+/**
+ *  how much of the speed from the ParticleEmitter should flow onto the ParticleSystem
+ * @param value a Value between zero and one
+
+   if you want to change the value of this variable during emission time (to make it more dynamic)
+   you may want to use the animation class
+*/
+void ParticleEmitter::setInheritSpeed(float value)
+{
+  if (unlikely(value > 1.0))
+    this->inheritSpeed = 1;
+  else if (unlikely(value < 0.0))
+    this->inheritSpeed = 0;
+  else
+    this->inheritSpeed = value;
+}
+
+/**
+ *  set the angle of the emitter
+ * @param angle around the direction in which there are particles to be emitted
+ * @param randomAngle A random spread-angle, the +- randomness of this option
+
+   if you want to change the value of this variable during emission time (to make it more dynamic)
+   you may want to use the animation class
+*/
+void ParticleEmitter::setSpread(float angle, float randomAngle)
+{
+  this->angle = angle;
+  this->randomAngle = randomAngle;
+}
+
+/**
+ *  sets the initial velocity of all particles emitted
+ * @param velocity The starting velocity of the emitted particles
+ * @param randomVelocity A random starting velocity, the +- randomness of this option
+
+   if you want to change the value of this variable during emission time (to make it more dynamic)
+   you may want to use the animation class
+*/
+void ParticleEmitter::setEmissionVelocity(float velocity, float randomVelocity)
+{
+  this->velocity = velocity;
+  this->randomVelocity = randomVelocity;
+}
+
+/**
+ *  sets the initial Momentum of all particles emitted
+ * @param momentum the new Momentum (just a float for being not too complicated).
+ * @param randomMomentum variation from the given value.
+ */
+void ParticleEmitter::setEmissionMomentum(float momentum, float randomMomentum)
+{
+  this->momentum = momentum;
+  this->momentumRandom = randomMomentum;
+}
+
+/**
+ *  this set the time to life of a particle, after which it will die
+ * @param dt: the time to live in seconds
+ * @param system: the system into which to emitt
+
+   if you want to change the value of this variable during emission time (to make it more dynamic)
+   you may want to use the animation class
+*/
+void ParticleEmitter::tick(float dt)
+{
+  assert (this->system != NULL);
+  if (likely(dt > 0.0 && this->emissionRate > 0.0))
+  {
+    // saving the time (particles only partly emitted in this timestep)
+    float count = (dt+this->saveTime) * this->emissionRate;
+    this->saveTime = modff(count, &count) / this->emissionRate;
+    PRINTF(5)("emitting %f particles, saving %f seconds for the next timestep\n", count, this->saveTime);
+    if (count + this->system->getCount() > this->system->getMaxCount())
+      count = this->system->getMaxCount() - this->system->getCount();
+    if (likely(count > 0.0f))
+      this->emitParticles((unsigned int)count);
+  }
+}
+
+/**
+ *  outputs some nice debug information
+*/
+void ParticleEmitter::debug() const
+{
+  PRINT(0)(" ParticleEmitter %s::%s\n", this->getClassCName(), this->getCName());
+  PRINT(0)("  EmissionRate: %f, Speed: %f, SpreadAngle: %f\n", this->getEmissionRate(), this->getEmissionVelocity(), this->getSpread());
+}
Index: branches/heathaze/src/world_entities/particles/particle_emitter.h
===================================================================
--- branches/heathaze/src/world_entities/particles/particle_emitter.h	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/particle_emitter.h	(revision 9940)
@@ -0,0 +1,82 @@
+/*!
+ * @file particle_emitter.h
+  *  Definition of a ParticleEmitter
+*/
+
+#ifndef _PARTICLE_EMITTER_H
+#define _PARTICLE_EMITTER_H
+
+#include "p_node.h"
+
+// FORWARD DECLARATION
+class ParticleSystem;
+class TiXmlElement;
+
+// Default values
+#define PARTICLE_EMITTER_DEFAULT_SIZE              1.0
+#define PARTICLE_EMITTER_DEFAULT_EMISSION_RATE     50
+#define PARTICLE_EMITTER_DEFAULT_INHERIT_SPEED     0.0
+#define PARTICLE_EMITTER_DEFAULT_SPREAD            M_PI
+#define PARTICLE_EMITTER_DEFAULT_VELOCITY          1.0
+
+//! A class to handle an Emitter.
+class ParticleEmitter : public PNode
+{
+  ObjectListDeclaration(ParticleEmitter);
+  friend class ParticleSystem;
+public:
+  ParticleEmitter(float emissionRate = PARTICLE_EMITTER_DEFAULT_EMISSION_RATE,
+                  float velocity = PARTICLE_EMITTER_DEFAULT_VELOCITY,
+                  float angle = PARTICLE_EMITTER_DEFAULT_SPREAD);
+  virtual ~ParticleEmitter();
+
+  virtual void loadParams(const TiXmlElement* root = NULL);
+
+  /* controlling the emitter: interface */
+  void start();
+  void stop();
+  void tick(float dt);
+
+  void setSystem(ParticleSystem* system);
+  ParticleSystem* getSystem() const { return this->system; };
+
+  /* controlling the behavour: these can be used as Animation interfaces */
+  void setEmissionRate(float emissionRate);
+  void setInheritSpeed(float value);
+  void setSpread(float angle, float randomAngle = 0.0);
+  void setEmissionVelocity(float velocity, float randomVelocity = 0.0);
+  void setEmissionMomentum(float momentum, float randomMomentum = 0.0);
+
+  /** @returns the emissionRate */
+  inline float getEmissionRate() const { return this->emissionRate; };
+  /** @returns the inherit-speed-factor */
+  inline float getInheritSpeed() const { return this->inheritSpeed; };
+  /** @returns the SpreadAngle of the emitter */
+  inline float getSpread() const { return this->angle; };
+  /** @returns the EmissionVelocity of the emitter */
+  inline float getEmissionVelocity() const { return this->velocity; };
+  /** @returns the EmissionMomentum of this emitter */
+  inline float getEmissionMomentum() const { return this->momentum; };
+
+
+  void debug() const;
+
+protected:
+  virtual void emitParticles(unsigned int count) const = 0;
+
+protected:
+  float           inheritSpeed;      //!< How much speed the particle inherits from the Emitters speed.
+  float           angle;             //!< max angle from the direction of the emitter
+  float           randomAngle;       //!< random emission angle (angle +- angleRandom is the emitted angle.
+  float           velocity;          //!< the initial speed of a Particles.
+  float           randomVelocity;    //!< the random variation from the initial Speed.
+  float           momentum;          //!< The Initial spped of the Rotation.
+  float           momentumRandom;    //!< The random variation of the Momentum.
+
+private:
+  ParticleSystem* system;            //!< The ParticleSystem this Emitter Emits into.
+  float           saveTime;          //!< The time that was missing by the last Tick (otherwise there would be no emission when framefate is too big).
+  float           emissionRate;      //!< amount of particles per seconds emitted by emitter.
+};
+
+#endif /* _PARTICLE_EMITTER_H */
Index: branches/heathaze/src/world_entities/particles/particle_system.cc
===================================================================
--- branches/heathaze/src/world_entities/particles/particle_system.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/particle_system.cc	(revision 9940)
@@ -0,0 +1,483 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "particle_system.h"
+
+#include "particle_emitter.h"
+
+#include "physics/fields/field.h"
+#include "model.h"
+
+#include "util/loading/load_param_xml.h"
+#include "util/loading/factory.h"
+#include "material.h"
+#include "state.h"
+#include "shell_command.h"
+
+#include <algorithm>
+
+ObjectListDefinition(ParticleSystem);
+
+/**
+ *  standard constructor
+ * @param maxCount the Count of particles in the System
+ * @param type The Type of the ParticleSystem
+*/
+ParticleSystem::ParticleSystem (unsigned int maxCount)
+{
+  this->registerObject(this, ParticleSystem::_objectList);
+
+  this->setMaxCount(PARTICLE_DEFAULT_MAX_COUNT);
+  this->count = 0;
+  this->particles = NULL;
+  this->deadList = NULL;
+  this->conserve = 1.0;
+  this->lifeSpan = 1.0; this->randomLifeSpan = 0.0;
+
+  this->toList(OM_ENVIRON);
+
+  this->maxCount = maxCount;
+}
+
+/**
+ * @brief standard deconstructor
+ */
+ParticleSystem::~ParticleSystem()
+{
+  // deleting all the living Particles
+  while (this->particles)
+  {
+    Particle* tmpDelPart = this->particles;
+    this->particles = this->particles->next;
+    delete tmpDelPart;
+  }
+
+  // deleting all the dead particles
+  while (this->deadList)
+  {
+    Particle* tmpDelPart = this->deadList;
+    this->deadList = this->deadList->next;
+    delete tmpDelPart;
+  }
+
+  while(!this->emitters.empty())
+  {
+    this->removeEmitter(this->emitters.front());
+  }
+
+}
+
+
+/**
+ * @brief loads Parameters from a TiXmlElement
+ * @param root the XML-element to load from.
+ */
+void ParticleSystem::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+  PhysicsInterface::loadParams(root);
+
+  LoadParam(root, "max-count", this, ParticleSystem, setMaxCount)
+  .describe("the maximal count of Particles, that can be emitted into this system");
+
+  LoadParam(root, "life-span", this, ParticleSystem, setLifeSpan)
+  .describe("sets the life-span of the Particles.");
+
+  LoadParam(root, "conserve", this, ParticleSystem, setConserve)
+  .describe("sets the Conserve factor of the Particles (1.0: they keep all their energy, 0.0:they keep no energy)");
+
+  LoadParamXML(root, "emitters", this, ParticleSystem, loadEmitters);
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    element->ToText();
+    // PER-PARTICLE-ATTRIBUTES:
+    LoadParam_CYCLE(element, "radius", this, ParticleSystem, setRadius)
+    .describe("The Radius of each particle over time (TimeIndex [0-1], radius at TimeIndex, randomRadius at TimeIndex)");
+
+    LoadParam_CYCLE(element, "mass", this, ParticleSystem, setMass)
+    .describe("The Mass of each particle over time (TimeIndex: [0-1], mass at TimeIndex, randomMass at TimeIndex)");
+
+    LoadParam_CYCLE(element, "color", this, ParticleSystem, setColor)
+    .describe("The Color of each particle over time (TimeIndex: [0-1], red: [0-1], green: [0-1], blue: [0-1], alpha: [0-1])");
+  }
+  LOAD_PARAM_END_CYCLE(element);
+
+  LoadParam(root, "precache", this, ParticleSystem, precache)
+  .describe("Precaches the ParticleSystem for %1 seconds, %2 times per Second")
+  .defaultValues(1.0, 25.0);
+}
+
+/**
+ * @brief loads the Emitters from An XML-Root
+ * @param root the XML-Element to load all emitters from
+ */
+void ParticleSystem::loadEmitters(const TiXmlElement* root)
+{
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    BaseObject* emitter = Factory::fabricate(element);
+    if (emitter != NULL)
+    {
+      if (emitter->isA(ParticleEmitter::staticClassID()))
+        this->addEmitter(dynamic_cast<ParticleEmitter*>(emitter));
+      else
+      {
+        PRINTF(2)("Tried to load an Element of type '%s' that should be a ParticleEmitter onto '%s::%s'.\n",
+                  emitter->getClassCName(), this->getClassCName(), this->getCName());
+        delete emitter;
+      }
+    }
+    else
+    {
+      PRINTF(2)("Could not Generate Emitter for system %s::%s (wrong type in XML-format)\n", this->getClassCName(), getCName());
+    }
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ * @param maxCount the maximum count of particles that can be emitted
+ */
+void ParticleSystem::setMaxCount(unsigned int maxCount)
+{
+  this->maxCount = maxCount;
+  PRINTF(4)("MAXCOUNT of %s::%s is %d\n", this->getClassCName(), this->getCName(), maxCount);
+}
+
+// setting properties
+/**
+ * @brief Sets the lifespan of newly created particles
+ * @param lifeSpan the LifeSpan of each particle in the System
+ * @param randomLifeSpan the Deviation from lifeSpan (random Value).
+*/
+void ParticleSystem::setLifeSpan(float lifeSpan, float randomLifeSpan)
+{
+  this->lifeSpan = lifeSpan;
+  this->randomLifeSpan = randomLifeSpan;
+  PRINTF(4)("LifeTime of %s::%s is %f\n", this->getClassCName(), this->getCName(), lifeSpan);
+}
+
+/**
+ * @brief sets the conserve Factor of newly created particles
+ * @param conserve sets the conserve factor of each particle.
+ * Conserve is the ammount of energy a particle takes from the last Frame into the next.
+ * A Value of 1 means, that all energy is conserved, a Value of 0 means infinit friction.
+ */
+void ParticleSystem::setConserve(float conserve)
+{
+  if (conserve > 1.0)
+    this->conserve = 1.0;
+  else if (conserve < 0.0)
+    this->conserve = 0.0;
+  else
+    this->conserve = conserve;
+
+  PRINTF(4)("Conserve of %s::%s is %f\n", this->getClassCName(), this->getCName(), conserve);
+}
+
+/////////////////////////////
+/* Per-Particle Attributes */
+/////////////////////////////
+/**
+ * @brief sets a key in the radius-animation on a per-particle basis
+ * @param lifeCycleTime the time (partilceLifeTime/particleAge) [0-1]
+ * @param radius the radius at this position
+ * @param randRadius the randRadius at this position
+*/
+void ParticleSystem::setRadius(float lifeCycleTime, float radius, float randRadius)
+{
+  this->radiusAnim.changeValue(lifeCycleTime, radius);
+  this->randRadiusAnim.changeValue(lifeCycleTime, randRadius);
+
+  PRINTF(4)("Radius of %s::%s at timeSlice %f is %f with a Random of %f\n",
+    this->getClassCName(), this->getCName(), lifeCycleTime, radius, randRadius);
+}
+
+/**
+ * @brief sets a key in the mass-animation on a per-particle basis
+ * @param lifeCycleTime the time (partilceLifeTime/particleAge) [0-1]
+ * @param mass the mass at this position
+ * @param randMass the randomMass at this position
+*/
+void ParticleSystem::setMass(float lifeCycleTime, float mass, float randMass)
+{
+  this->massAnim.changeValue(lifeCycleTime, mass);
+  this->randMassAnim.changeValue(lifeCycleTime, randMass);
+}
+
+/**
+ * @brief sets a key in the color-animation on a per-particle basis
+ * @param lifeCycleTime: the time (partilceLifeTime/particleAge) [0-1]
+ * @param red: red
+ * @param green: green
+ * @param blue: blue
+ * @param alpha: alpha
+*/
+void ParticleSystem::setColor(float lifeCycleTime, float red, float green, float blue, float alpha)
+{
+  this->colorAnim[0].changeValue(lifeCycleTime, red);
+  this->colorAnim[1].changeValue(lifeCycleTime, green);
+  this->colorAnim[2].changeValue(lifeCycleTime, blue);
+  this->colorAnim[3].changeValue(lifeCycleTime, alpha);
+
+  PRINTF(4)("Color of %s::%s on timeslice %f is r:%f g:%f b:%f a:%f\n",
+    this->getClassCName(), this->getCName(), lifeCycleTime, red, green, blue, alpha);
+}
+
+/**
+ * @brief sets a key in the color-animation on a per-particle basis
+ * @param lifeCycleTime: the time (partilceLifeTime/particleAge) [0-1]
+ * @param color the Color.
+ */
+void ParticleSystem::setColor(float lifeCycleTime, const Color& color)
+{
+  this->setColor(lifeCycleTime, color.r(), color.g(), color.b(), color.a());
+}
+
+
+/**
+ * @brief adds an Emitter to this System.
+ * @param emitter the Emitter to add.
+ */
+void ParticleSystem::addEmitter(ParticleEmitter* emitter)
+{
+  assert (emitter != NULL);
+  if (emitter->getSystem() != NULL)
+    emitter->getSystem()->removeEmitter(emitter);
+  emitter->system = this;
+  this->emitters.push_back(emitter);
+}
+
+/**
+ * @brief removes a ParticleEmitter from this System
+ * @param emitter the Emitter to remove
+ */
+void ParticleSystem::removeEmitter(ParticleEmitter* emitter)
+{
+  assert (emitter != NULL);
+  emitter->system = NULL;
+  this->emitters.remove(emitter);
+  /*  std::list<ParticleEmitter*>::iterator it = std::find(this->emitters.begin(), this->emitters.end(), emitter);
+  if (it != this->emitters.end())
+    this->emitters.erase(it);*/
+}
+
+/**
+ * @brief does a Precaching, meaning, that the ParticleSystem(and its emitters) will be ticked force
+ * @param seconds: seconds
+ * @param ticksPerSeconds times per Second.
+ */
+void ParticleSystem::precache(unsigned int seconds, unsigned int ticksPerSecond)
+{
+  std::list<ParticleEmitter*>::iterator emitter;
+  for (emitter = this->emitters.begin(); emitter != this->emitters.end(); emitter++)
+    (*emitter)->updateNode(.1), (*emitter)->updateNode(.1);
+
+  PRINTF(4)("Precaching %s::%s %d seconds %d timesPerSecond\n", this->getClassCName(), this->getCName(), seconds, ticksPerSecond);
+  for (unsigned int i = 0; i < seconds*ticksPerSecond; i++)
+    this->tick(1.0/(float)ticksPerSecond);
+}
+
+
+/**
+ * @brief ticks the system.
+ * @param dt the time to tick all the Particles of the System
+
+   this is used to get all the particles some motion
+*/
+void ParticleSystem::tick(float dt)
+{
+  Particle* tickPart = particles;  // the particle to Tick
+  Particle* prevPart = NULL;
+  while (likely(tickPart != NULL))
+  {
+    // applying force to the System.
+    if (likely (tickPart->mass > 0.0))
+      tickPart->velocity += tickPart->extForce / tickPart->mass * dt;
+
+    tickPart->radius = radiusAnim.getValue(tickPart->lifeCycle)
+                       + randRadiusAnim.getValue(tickPart->lifeCycle) * tickPart->radiusRand;
+
+    tickPart->mass = massAnim.getValue(tickPart->lifeCycle)
+                     + randMassAnim.getValue(tickPart->lifeCycle) * tickPart->massRand;
+
+    tickPart->extForce = Vector(0,0,0);
+
+    // applying Color
+    this->colorAnim[0].getValue(tickPart->color[0], tickPart->lifeCycle);
+    this->colorAnim[1].getValue(tickPart->color[1], tickPart->lifeCycle);
+    this->colorAnim[2].getValue(tickPart->color[2], tickPart->lifeCycle);
+    this->colorAnim[3].getValue(tickPart->color[3], tickPart->lifeCycle);
+
+    // rendering new position.
+    tickPart->position += tickPart->velocity * dt;
+    tickPart->orientation *= tickPart->momentum *dt;
+
+    // many more to come
+
+    if (this->conserve < 1.0)
+    {
+      tickPart->velocity *= this->conserve;
+      tickPart->momentum *= this->conserve;
+    }
+    // find out if we have to delete tickPart
+    if (unlikely((tickPart->lifeCycle += dt/tickPart->lifeTime) >= 1.0))
+    {
+      // remove the particle from the list
+      if (likely(prevPart != NULL))
+      {
+        prevPart->next = tickPart->next;
+        tickPart->next = this->deadList;
+        this->deadList = tickPart;
+        tickPart = prevPart->next;
+      }
+      else
+      {
+        prevPart = NULL;
+        this->particles = tickPart->next;
+        tickPart->next = this->deadList;
+        this->deadList = tickPart;
+        tickPart = this->particles;
+      }
+      --this->count;
+    }
+    else
+    {
+      prevPart = tickPart;
+      tickPart = tickPart->next;
+    }
+  }
+
+  std::list<ParticleEmitter*>::iterator emitter;
+  for (emitter = this->emitters.begin(); emitter != this->emitters.end(); emitter++)
+    (*emitter)->tick(dt);
+}
+
+/**
+  *  applies some force to a Particle.
+  * @param field the Field to apply.
+ */
+void ParticleSystem::applyField(const Field* field)
+{
+  Particle* tickPart = particles;
+  while (tickPart)
+  {
+    tickPart->extForce += field->calcForce(tickPart->position);
+    tickPart = tickPart->next;
+  }
+}
+
+
+/**
+ * @returns the count of Faces of this ParticleSystem
+ */
+unsigned int ParticleSystem::getFaceCount() const
+{
+  return this->count;
+}
+
+/**
+ * @brief adds a new Particle to the System
+ * @param position the initial position, where the particle gets emitted.
+ * @param velocity the initial velocity of the particle.
+ * @param orientation the initial orientation of the Paritcle.
+ * @param momentum the initial momentum of the Particle (the speed of its rotation).
+ * @param data some more data given by the emitter
+*/
+void ParticleSystem::addParticle(const Vector& position, const Vector& velocity, const Quaternion& orientation, const Quaternion& momentum, unsigned int data)
+{
+  if (this->count <= this->maxCount)
+  {
+    // if it is the first Particle
+    if (unlikely(particles == NULL))
+    {
+      if (likely(deadList != NULL))
+      {
+        this->particles = this->deadList;
+        deadList = deadList->next;
+      }
+      else
+      {
+        PRINTF(5)("Generating new Particle\n");
+        this->particles = new Particle;
+      }
+      this->particles->next = NULL;
+    }
+    // filling the List from the beginning
+    else
+    {
+      Particle* tmpPart;
+      if (likely(deadList != NULL))
+      {
+        tmpPart = this->deadList;
+        deadList = deadList->next;
+      }
+      else
+      {
+        PRINTF(5)("Generating new Particle\n");
+        tmpPart = new Particle;
+      }
+      tmpPart->next = this->particles;
+      this->particles = tmpPart;
+    }
+    particles->lifeTime = this->lifeSpan + (float)(rand()/RAND_MAX)* this->randomLifeSpan;
+    particles->lifeCycle = 0.0;
+    particles->position = position;
+    particles->velocity = velocity;
+
+    particles->orientation = orientation;
+    particles->momentum = momentum;
+
+    //  particle->rotation = ; //! @todo rotation is once again something to be done.
+    particles->massRand = 2*(float)rand()/RAND_MAX -1;
+    particles->radiusRand = 2* (float)rand()/RAND_MAX -1;
+    particles->mass = this->massAnim.getValue(0.0) + this->randMassAnim.getValue(0.0)*particles->massRand;
+    particles->radius = this->radiusAnim.getValue(0.0) + this->randRadiusAnim.getValue(0.0)*particles->radiusRand;
+
+    ++this->count;
+  }
+  else
+    PRINTF(4)("maximum count of particles reached not adding any more\n");
+}
+
+/**
+ *  outputs some nice debug information
+*/
+void ParticleSystem::debug() const
+{
+  PRINT(0)("  ParticleCount: %d emitters: %d, maximumCount: %d :: filled %d%%\n",
+           this->count,
+           this->emitters.size(),
+           this->maxCount,
+           ((this->maxCount!=0)?100*this->count/this->maxCount:0));
+
+
+  PRINT(0)("  Coloring sceme: r:"), this->colorAnim[0].debug();
+  PRINT(0)("  Coloring sceme: g:"), this->colorAnim[1].debug();
+  PRINT(0)("  Coloring sceme: b:"), this->colorAnim[2].debug();
+  PRINT(0)("  Coloring sceme: a:"), this->colorAnim[3].debug();
+
+  if (likely(this->deadList != NULL))
+  {
+    PRINT(0)("  - ParticleDeadList is used: ");
+    int i = 1;
+    Particle* tmpPart = this->deadList;
+    while ((tmpPart = tmpPart->next) != NULL) { ++i; }
+    PRINT(0)("count: %d\n", i);
+  }
+}
Index: branches/heathaze/src/world_entities/particles/particle_system.h
===================================================================
--- branches/heathaze/src/world_entities/particles/particle_system.h	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/particle_system.h	(revision 9940)
@@ -0,0 +1,133 @@
+/*!
+ * @file particle_system.h
+
+*/
+
+#ifndef _PARTICLE_SYSTEM_H
+#define _PARTICLE_SYSTEM_H
+
+#include "world_entity.h"
+#include "physics_interface.h"
+
+#include "glincl.h"
+#include "vector.h"
+#include <list>
+#include "color.h"
+
+#include "quick_animation.h"
+
+// Forward Declaration
+class TiXmlElement;
+
+#define PARTICLE_DOT_MASK              0x000001     //!< A Mask if the Particles should be displayed as DOTs
+#define PARTICLE_SPARK_MASK            0x000010     //!< A Mask if the Particles should be displayed as SPARKs
+#define PARTICLE_SPRITE_MASK           0x000100     //!< A Mask if the Particles should be displayed as SPRITESs
+#define PARTICLE_MODEL_MASK            0x001000     //!< A Mask if the Particles should be displayed as MODELSs
+#define PARTICLE_WORDL_ENTITY_MASK     0x010000     //!< A Mask if the Particles should be displayed as WORLD_ENTITIEs
+#define PARTICLE_MULTI_MASK            0x100000     //!< A Mask if they are Multi-partilces
+
+#define PARTICLE_DEFAULT_MAX_COUNT    200               //!< A default count of particles in the system.
+
+// FORWARD DECLARATION
+class Material;
+class ParticleEmitter;
+class Field;
+
+//! A struct for one Particle
+typedef struct Particle
+{
+  float         lifeTime;            //!< The time this particle has to live.
+  float         lifeCycle;           //!< The fraction of time passed. (in percentage of its lifeTime)
+
+  Vector        position;            //!< The current position of this particle.
+  Vector        velocity;            //!< The current velocity of this Particle.
+  Vector        extForce;            //!< The external Force that influences this Particle.
+  Quaternion    orientation;         //!< The current orientation of this Particle.
+  Quaternion    momentum;            //!< The current angular momentum (spin) of this Particle.
+  float         mass;                //!< The mass of this Particle.
+  float         massRand;            //!< A random mass
+  float         radius;              //!< The current size of this Particle.
+  float         radiusRand;          //!< a random Radius
+  GLfloat       color [4];           //!< A Color for the particles.
+
+  Particle*     next;                //!< pointer to the next particle in the List. (NULL if no preceding one)
+};
+
+//! A class to handle ParticleSystems
+class ParticleSystem : public WorldEntity, public PhysicsInterface {
+  ObjectListDeclaration(ParticleSystem);
+
+ public:
+  ParticleSystem(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT);
+  virtual ~ParticleSystem();
+
+  virtual void loadParams(const TiXmlElement* root);
+  void loadEmitters(const TiXmlElement* root);
+
+  void setLifeSpan(float lifeSpan, float randomLifeSpan = 0.0);
+  void setConserve(float conserve);
+  void setMaxCount(unsigned int maxCount);
+
+  /* Per-Particle-Attributes */
+  void setRadius(float lifeCycleTime, float radius, float randRadius = 0.0);
+  void setMass(float lifeCycleTime, float mass, float randMass = 0.0);
+  void setColor(float lifeCycleTime, float red, float green, float blue, float alpha);
+  void setColor(float lifeCycleTime, const Color& color);
+
+  /** @returns the lifespan of the particles */
+  inline float getLifeSpan() const { return this->lifeSpan; };
+  /** @returns the starting-radius of the particles */
+  inline float getStartRadius() { return this->radiusAnim.getValue(0.0); };
+  /** @returns the end-radius of the particles */
+  inline float getEndRadius() { return this->radiusAnim.getValue(1.0); };
+  /** @returns the conserve-factor of the particles */
+  inline float getConserve() const { return this->conserve; };
+  /** @returns the initial mass of the particles */
+  inline float getMass() const { return this->initialMass; };
+
+  /** @returns the count of particles in this System */
+  inline unsigned int getCount() const { return this->count; };
+  /** @returns the maximum count of particles that can be contained by this System */
+  inline unsigned int getMaxCount() const { return this->maxCount; };
+
+  virtual unsigned int getFaceCount() const;
+
+  void addEmitter(ParticleEmitter* emitter);
+  void removeEmitter(ParticleEmitter* emitter);
+
+  virtual void applyField(const Field* field);
+  /** @brief this is an empty function, because the Physics are implemented in tick @param dt: useless here */
+  virtual void tickPhys(float dt) {};
+
+  void addParticle(const Vector& position, const Vector& velocity, const Quaternion& orientation, const Quaternion& momentum, unsigned int data = 0);
+
+  void precache(unsigned int seconds, unsigned int ticksPerSecond = 25);
+
+  virtual void tick(float dt);
+  virtual void draw() const = 0;
+
+  void debug() const;
+
+ protected:
+  float             conserve;            //!< How much energy gets conserved to the next Tick.
+  float             lifeSpan;            //!< Initial lifetime of a Particle.
+  float             randomLifeSpan;      //!< A random value for the Lifespan (around the initial lifetime)
+  float             initialMass;         //!< The initial Mass of the Particle
+  float             randomInitialMass;   //!< The random initial Mass of the Particle
+
+  unsigned int      maxCount;            //!< The maximum count of Particles.
+  unsigned int      count;               //!< The current count of Particles.
+  Particle*         particles;           //!< A list of particles of this System.
+  Particle*         deadList;            //!< A list of dead Particles in the System.
+
+  std::list<ParticleEmitter*> emitters;  //!< The Emitters that do emit into this System.
+
+  // per particle attributes
+  QuickAnimation    radiusAnim;          //!< Animation of the radius
+  QuickAnimation    randRadiusAnim;      //!< Animation of the random Value of the radius
+  QuickAnimation    massAnim;            //!< Animation of the mass
+  QuickAnimation    randMassAnim;        //!< Animation of the random Mass
+  QuickAnimation    colorAnim[4];        //!< Animation of the 4 colors (r,g,b,a)
+};
+
+#endif /* _PARTICLE_SYSTEM_H */
Index: branches/heathaze/src/world_entities/particles/plane_emitter.cc
===================================================================
--- branches/heathaze/src/world_entities/particles/plane_emitter.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/plane_emitter.cc	(revision 9940)
@@ -0,0 +1,116 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "plane_emitter.h"
+
+#include "particle_system.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(PlaneEmitter, CL_PLANE_EMITTER);
+CREATE_FACTORY(PlaneEmitter);
+
+/**
+ *  standard constructor
+*/
+PlaneEmitter::PlaneEmitter(const Vector2D& size, float emissionRate, float velocity, float angle)
+    :  ParticleEmitter(emissionRate, velocity, angle)
+{
+  this->init();
+  this->setSize(size);
+}
+
+/**
+ *  constructs and loads a PlaneEmitter from a XML-element
+ * @param root the XML-element to load from
+*/
+PlaneEmitter::PlaneEmitter(const TiXmlElement* root)
+    : ParticleEmitter()
+{
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard destructor
+
+   removes the EmitterSystem from the ParticleEngine
+*/
+PlaneEmitter::~PlaneEmitter ()
+{
+  this->setSystem(NULL);
+}
+
+/**
+  @brief initializes default values of a ParitcleEmitter
+*/
+void PlaneEmitter::init()
+{
+  this->registerObject(this, PlaneEmitter::_objectList);
+  this->setSize(1.0f, 1.0f);
+}
+
+void PlaneEmitter::loadParams(const TiXmlElement* root)
+{
+  ParticleEmitter::loadParams(root);
+
+  LoadParam(root, "size", this, PlaneEmitter, setSize)
+  .describe("The Size of the PlaneEmitter: x, y")
+  .defaultValues(1.0f,1.0f);
+}
+
+void PlaneEmitter::setSize(float x, float y)
+{
+  this->size = Vector2D(x, y);
+}
+
+
+void PlaneEmitter::emitParticles(unsigned int count) const
+{
+  Vector inheritVelocity = this->getVelocity() * this->inheritSpeed;
+
+  Vector xDir = this->getAbsDirX() * this->size.x;
+  Vector yDir = this->getAbsDirZ() * this->size.y;
+  Vector zDir = this->getAbsDirY();
+
+  for (unsigned int i = 0; i < count; i++)
+  {
+    Vector randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
+    randDir.normalize();
+    randDir = (Quaternion(angle + randomAngle *((float)rand()/RAND_MAX -.5), randDir)).apply(zDir);
+    Vector velocityV = randDir.getNormalized()*this->velocity + inheritVelocity;
+
+    Vector plane = this->getAbsCoor() +
+        xDir * ((float)rand()/RAND_MAX -.5) +
+        yDir * ((float)rand()/RAND_MAX -.5);
+
+    // ROTATIONAL CALCULATION (this must not be done for all types of particles.)
+    randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
+    randDir.normalize();
+    Quaternion orient = Quaternion(M_PI, randDir);
+    Quaternion moment = Quaternion(this->momentum + this->momentumRandom, randDir);
+
+    this->getSystem()->addParticle(plane, velocityV, orient, moment);
+
+  }
+}
Index: branches/heathaze/src/world_entities/particles/plane_emitter.h
===================================================================
--- branches/heathaze/src/world_entities/particles/plane_emitter.h	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/plane_emitter.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file plane_emitter.h
+ * Definition of a PlaneEmitter
+ */
+
+#ifndef _PLANE_EMITTER_H
+#define _PLANE_EMITTER_H
+
+#include "particle_emitter.h"
+
+#include "vector2D.h"
+
+#define PLANE_EMITTER_DEFAULT_SIZE Vector2D(1.0f, 1.0f)
+
+//! A class to handle a Plane Emitter.
+/**
+ * A Plane Emitter is a special kind of emitter, that has the (underlying) PNode
+ * at its center, and from there on is a Plane in the Direction of the PNode
+ * out around size in the corresponding directions in x and z
+ */
+class PlaneEmitter : public ParticleEmitter
+{
+  ObjectListDeclaration(PlaneEmitter);
+
+  friend class ParticleSystem;
+public:
+  PlaneEmitter(const Vector2D& size = PLANE_EMITTER_DEFAULT_SIZE,
+               float emissionRate = PARTICLE_EMITTER_DEFAULT_EMISSION_RATE,
+               float velocity = PARTICLE_EMITTER_DEFAULT_VELOCITY,
+               float angle = PARTICLE_EMITTER_DEFAULT_SPREAD);
+  PlaneEmitter(const TiXmlElement* root);
+  virtual ~PlaneEmitter();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setSize(float x, float y);
+  void setSize(const Vector2D& size) { this->setSize(size.x, size.y); };
+
+protected:
+  virtual void emitParticles(unsigned int count) const;
+
+private:
+  void init();
+
+private:
+  Vector2D      size;
+};
+
+#endif /* _PLANE_EMITTER_H */
Index: branches/heathaze/src/world_entities/particles/quick_animation.cc
===================================================================
--- branches/heathaze/src/world_entities/particles/quick_animation.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/quick_animation.cc	(revision 9940)
@@ -0,0 +1,316 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "quick_animation.h"
+
+#include <algorithm>
+
+
+
+/**
+ * @brief standard constructor
+ * @param resolution the Resolution of the LookupTable
+ */
+QuickAnimation::QuickAnimation (unsigned int resolution)
+{
+  this->lookupValues.resize(resolution, 0.0f);
+}
+
+/**
+ * @brief deletes all the deconstructor stuff
+ */
+QuickAnimation::~QuickAnimation ()
+{ }
+
+/**
+ * @brief adds a new entry to the list of keyframes
+ * @param position the position to add the key to
+ * @param value the Value to set for the position
+ * @returns false if the key existed already for a given position
+ */
+bool QuickAnimation::addKey(float position, float value)
+{
+  if (position > 1.0f || position < 0.0f)
+  {
+    printf("QuickAnimation::Position MUST BE between 0.0f and 1.0f\n");
+    return false;
+  }
+  if(std::find(this->keyFrames.begin(), this->keyFrames.end(), position) != this->keyFrames.end())
+  {
+    printf("QuickAnimation:: key at position %f already added. Use changeValue instead\n", position);
+    return false;
+  }
+  this->keyFrames.push_back(QuickKeyFrame(position, value));
+
+  this->rebuild();
+  return true;
+}
+
+
+/**
+ * @brief changes an entry in the region of position
+ * @param position the Position of an existing keyframe
+ * @param region a deviation of the existing keyframe (like a delta in witch to search for)
+ * @param value the new Value
+ */
+bool QuickAnimation::changeValueKey(unsigned int keyFrameNumber, float newValue)
+{
+  if (keyFrameNumber < this->keyFrames.size())
+  {
+    this->keyFrames[keyFrameNumber].value = newValue;
+    this->rebuild();
+    return true;
+  }
+  else
+    return false;
+}
+
+/**
+ * @brief changes an entry in the region of position
+ * @param position the Position of an existing keyframe
+ * @param region a deviation of the existing keyframe (like a delta in witch to search for)
+ * @param value the new Value
+ *
+ * This Function adds a new KeyFrame at position with newValue, if none was found in region of position.
+ */
+bool QuickAnimation::changeValue(float position, float newValue, float region)
+{
+  int keyFrame = this->getKeyAt(position, region);
+  if (keyFrame == -1)
+    return this->addKey(position, newValue);
+  else
+    return this->changeValueKey(keyFrame, newValue);
+}
+
+
+/**
+ * @brief removes the keyFrameNumber'th entry.
+ * @param keyFrameNumber the n'th Keyframe to remove.
+ * @returns true on success, false if keyFrameNumber did not exist.
+ */
+bool QuickAnimation::removeKey(unsigned int keyFrameNumber)
+{
+  if (keyFrameNumber < this->keyFrames.size())
+  {
+    this->keyFrames.erase(this->keyFrames.begin() + keyFrameNumber);
+    this->rebuild();
+    return true;
+  }
+  else
+    return false;
+}
+
+
+/**
+ * @brief removes a KeyFrame from the List.
+ * @param position the Keyframe at position position will be erased.
+ * @param region a deviation of the existing keyframe (like a delta in witch to search for)
+ * @returns true on success, false if no KeyFrame was found.
+ */
+bool QuickAnimation::remove(float position, float region)
+{
+  int keyFrame = this->getKeyAt(position, region);
+  if (keyFrame == -1)
+    return false;
+  else
+    return this->removeKey(keyFrame);
+}
+
+/**
+ * @brief moves the keyFrame keyFrameNumber to newPosition/newValue.
+ * @param keyFrameNumber the n'th KeyFrame to move.
+ * @param newPosition the new Position for the KeyFrame.
+ * @param newValue the new Value for the KeyFrame.
+ * @returns true on success, false if the KeyFrame did not exist.
+ */
+bool QuickAnimation::moveKey(unsigned int keyFrameNumber, float newPosition, float newValue)
+{
+  if (keyFrameNumber < this->keyFrames.size())
+  {
+    this->keyFrames[keyFrameNumber].position = newPosition;
+    this->keyFrames[keyFrameNumber].value = newValue;
+    this->rebuild();
+    return true;
+  }
+  else
+    return false;
+}
+
+/**
+ * @brief moves the keyFrame keyFrameNumber to newPosition/value.
+ * @param keyFrameNumber the n'th KeyFrame to move.
+ * @param newPosition the new Position for the KeyFrame.
+ * @returns true on success, false if the KeyFrame did not exist.
+ */
+bool QuickAnimation::moveKey(unsigned int keyFrameNumber, float newPosition)
+{
+  if (keyFrameNumber < this->keyFrames.size())
+  {
+    this->keyFrames[keyFrameNumber].position = newPosition;
+    this->rebuild();
+    return true;
+  }
+  else
+    return false;
+}
+
+/**
+ * @brief moves the keyFrame in the region of oldPosition to newPosition/newValue.
+ * @param oldPosition the old Position for the KeyFrame.
+ * @param newPosition the new Position for the KeyFrame.
+ * @param newValue the new Value for the KeyFrame.
+ * @param region the region around oldPosition to search for the KeyFrame.
+ * @returns true on success, false if the KeyFrame was not found within the region of oldPosition.
+ */
+bool QuickAnimation::move(float oldPosition, float newPosition, float newValue, float region)
+{
+  int keyFrame = this->getKeyAt(oldPosition, region);
+  if (keyFrame == -1)
+    return false;
+  else
+    return this->moveKey(keyFrame, newPosition, newValue);
+}
+
+/**
+ * @brief moves the keyFrame in the region of oldPosition to newPosition/Value.
+ * @param oldPosition the old Position for the KeyFrame.
+ * @param newPosition the new Position for the KeyFrame.
+ * @param region the region around oldPosition to search for the KeyFrame.
+ * @returns true on success, false if the KeyFrame was not found within the region of oldPosition.
+ */
+bool QuickAnimation::move(float oldPosition, float newPosition, float region)
+{
+  int keyFrame = this->getKeyAt(oldPosition, region);
+  if (keyFrame == -1)
+    return false;
+  else
+    return this->moveKey(keyFrame, newPosition);
+}
+
+
+/**
+ * @brief searches for a Keyframe in the region of position
+ * @param position the Keyframe at position position will searched for.
+ * @param region a deviation of the existing keyframe (like a delta in witch to search for)
+ * @returns the keyFrame on success, -1 on fault.
+ */
+int QuickAnimation::getKeyAt(float position, float region)
+{
+  for (unsigned int i = 0; i < this->keyFrames.size(); i++)
+  {
+    if (this->keyFrames[i].position + region/2.0 > position && this->keyFrames[i].position - region/2.0 < position)
+      return i;
+  }
+  return -1;
+}
+
+
+/**
+ * @brief rebuilds the QuickAnimation.
+ */
+void QuickAnimation::rebuild()
+{
+  // if we do not have any KeyFrames
+  if (this->keyFrames.empty())
+  {
+    for (unsigned int i = 0; i < this->lookupValues.size(); i++)
+      this->lookupValues[i] = 0.0f;
+    return;
+  }
+
+  // Sort the List.
+  std::sort(this->keyFrames.begin(), this->keyFrames.end(), QuickKeyFrame::sortPositionPredicate);
+
+  // rebuild the lookup-table
+  float sliceSize = 1.0f / this->lookupValues.size();
+  unsigned int key = 0;
+  float preVal = this->keyFrames[0].value;
+  float prePos = this->keyFrames[0].position;
+
+  float postVal = preVal;
+  float postPos = 1.0;
+
+  if (this->keyFrames.size() > 1)
+  {
+    postVal = this->keyFrames[1].value;
+    postPos = this->keyFrames[1].position;
+  }
+
+
+  for (unsigned int i = 0; i < this->lookupValues.size(); i++)
+  {
+    float position = (float)i * sliceSize;
+
+    // if we reach the Next KeyFrame
+    if (position > postPos)
+    {
+      // if we have more KeyFrames.
+      if (this->keyFrames.size() > ++key + 1)
+      {
+        preVal = this->keyFrames[key].value;
+        prePos = this->keyFrames[key].position;
+        postVal = this->keyFrames[key+1].value;
+        postPos = this->keyFrames[key+1].position;
+      }
+      // otherwise we reached the last KeyFrame
+      else
+      {
+        preVal = postVal;
+        prePos = postPos;
+        postPos = 1.0;
+      }
+    }
+    this->lookupValues[i] = preVal + ( postVal - preVal) / (postPos - prePos) * (position - prePos);
+  }
+}
+
+/**
+ * @brief outputs some nice information about this class
+ */
+void QuickAnimation::debug() const
+{
+  printf("QuickAnim(KeyFrames:%d, Resolution:%d)::(position, value) ", this->keyFrames.size(), this->lookupValues.size());
+
+  for (unsigned int i = 0; i < this->keyFrames.size(); i++)
+    printf("(%0.2f, %0.2f)->", this->keyFrames[i].position, this->keyFrames[i].value);
+  printf("\n");
+}
+
+
+
+/**
+ * @brief compares two QuickKeyFrames with their positions.
+ * @param key1 the first keyframe
+ * @param key2 the second keyframe
+ * @returns true, if the key1.position < key2.position.
+ */
+bool QuickAnimation::QuickKeyFrame::sortPositionPredicate(const QuickKeyFrame& key1, const QuickKeyFrame& key2)
+{
+  return (key1.position < key2.position);
+}
+
+/**
+ * @brief compares two QuickKeyFrames with their values.
+ * @param key1 the first keyframe
+ * @param key2 the second keyframe
+ * @returns true, if the key1.value < key2.value.
+ */
+bool QuickAnimation::QuickKeyFrame::sortValuePredicate(const QuickKeyFrame& key1, const QuickKeyFrame& key2)
+{
+  return (key1.value < key2.value);
+}
+
Index: branches/heathaze/src/world_entities/particles/quick_animation.h
===================================================================
--- branches/heathaze/src/world_entities/particles/quick_animation.h	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/quick_animation.h	(revision 9940)
@@ -0,0 +1,83 @@
+/*!
+ * @file quick_animation.h
+ * Definition of the QuickAnimation-class
+*/
+
+#ifndef _QUICK_ANIMATION_H
+#define _QUICK_ANIMATION_H
+
+#include <vector>
+// FORWARD DECLARATION
+
+//! A class for that linearely interpolates between multiple values.
+/**
+ * QuickAnimation is a Class that creates a LookupTable with
+ * position between [0.0f - 1.0f] so that one can resolve the
+ * given Value.
+ */
+class QuickAnimation
+{
+public:
+  QuickAnimation(unsigned int resolution = 100);
+  virtual ~QuickAnimation();
+
+  bool addKey(float position, float value);
+
+  bool changeValueKey(unsigned int keyFrameNumber, float newValue);
+  bool changeValue(float position, float newValue, float region = 0.04f);
+
+  bool removeKey(unsigned int keyFrameNumber);
+  bool remove(float position, float region = 0.04f);
+
+  bool moveKey(unsigned int keyFrameNumber, float newPosition, float newValue);
+  bool moveKey(unsigned int keyFrameNumber, float newPosition);
+  bool move(float oldPosition, float newPosition, float newValue, float region = 0.04f);
+  bool move(float oldPosition, float newPosition, float region = 0.04f);
+
+  int getKeyAt(float position, float region = 0.04f);
+
+  /**
+   * @brief returns the value of the animation at a certain position
+   * @param value returns the calculated value.
+   * @param position The position to get the Value from.
+   */
+  void getValue(float& value, float position) const
+  {
+    value = this->lookupValues[int(position*this->lookupValues.size())];
+  }
+
+  /**
+   * @brief returns the value of the animation at a certain position
+   * @param position the position to get the value from :)
+   * @returns the calculated Value.
+   */
+  float getValue(float position) const
+  {
+    return this->lookupValues[int(position*this->lookupValues.size())];
+  }
+
+  void debug() const;
+
+private:
+  void rebuild();
+
+private:
+  //! a simple struct that stores keyframes for the QuickAnimation-Class.
+  struct QuickKeyFrame
+  {
+    //! Creates a new QuickKeyFrame with @param position position @param value value */
+    QuickKeyFrame(float position, float value) :  position(position), value(value) {};
+    //! compares this->position with position @param position pos to compare, @returns true on match.
+    bool operator==(float position) { return this->position == position; };
+    float            position;          //!< The position of thies KeyFrame
+    float            value;             //!< The value of this KeyFrame
+
+    static bool sortPositionPredicate(const QuickKeyFrame& key1, const QuickKeyFrame& key2);
+    static bool sortValuePredicate(const QuickKeyFrame& key1, const QuickKeyFrame& key2);
+  };
+
+  std::vector<QuickKeyFrame>    keyFrames;              //!< An Array of KeyFrames.
+  std::vector<float>            lookupValues;           //!< The lookup-table where the values are stored.
+};
+
+#endif /* _QUICK_ANIMATION_H */
Index: branches/heathaze/src/world_entities/particles/spark_particles.cc
===================================================================
--- branches/heathaze/src/world_entities/particles/spark_particles.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/spark_particles.cc	(revision 9940)
@@ -0,0 +1,116 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "spark_particles.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "material.h"
+#include "state.h"
+#include "shell_command.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(SparkParticles, CL_SPARK_PARTICLES);
+CREATE_FACTORY(SparkParticles);
+
+/**
+ *  standard constructor
+ * @param maxCount the Count of particles in the System
+ * @param type The Type of the SparkParticles
+*/
+SparkParticles::SparkParticles (unsigned int maxCount)
+    : ParticleSystem(maxCount)
+{
+  this->init();
+}
+
+/**
+ * @brief creates a Particle System out of a XML-element
+ * @param root: the XML-element to load from
+ */
+SparkParticles::SparkParticles(const TiXmlElement* root)
+{
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+SparkParticles::~SparkParticles()
+{ }
+
+/**
+ * @brief initializes the SparkParticles with default values
+*/
+void SparkParticles::init()
+{
+  this->registerObject(this, SparkParticles::_objectList);
+}
+
+
+/**
+ * loads Parameters from a TiXmlElement
+ * @param root the XML-element to load from.
+ */
+void SparkParticles::loadParams(const TiXmlElement* root)
+{
+  ParticleSystem::loadParams(root);
+}
+
+/**
+ * @brief draws all the Particles of this System
+ *
+ * The Cases in this Function all do the same:
+ * Drawing all the particles with the appropriate Type.
+ * This is just the fastest Way to do this, but will most likely be changed in the future.
+ */
+void SparkParticles::draw() const
+{
+
+  Particle* drawPart = particles;
+
+  glDepthMask(GL_FALSE);
+  glPushAttrib(GL_ENABLE_BIT);
+
+  glDisable(GL_LIGHTING);
+  glDisable(GL_TEXTURE_2D);
+
+  glEnable(GL_LINE_SMOOTH);
+  glEnable(GL_BLEND);
+  glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
+
+  glLineWidth(2.0);
+  glBegin(GL_LINES);
+  while (likely(drawPart != NULL))
+  {
+  //    printf("%f %f %f %f\n", drawPart->color[0], drawPart->color[1], drawPart->color[2], drawPart->color[3]);
+    glColor4fv(drawPart->color);
+    glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z);
+    glVertex3f(drawPart->position.x - drawPart->velocity.x * drawPart->radius,
+               drawPart->position.y - drawPart->velocity.y * drawPart->radius,
+               drawPart->position.z - drawPart->velocity.z * drawPart->radius);
+    drawPart = drawPart->next;
+  }
+  glEnd();
+
+  glDepthMask(GL_TRUE);
+  glPopAttrib();
+}
Index: branches/heathaze/src/world_entities/particles/spark_particles.h
===================================================================
--- branches/heathaze/src/world_entities/particles/spark_particles.h	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/spark_particles.h	(revision 9940)
@@ -0,0 +1,33 @@
+/*!
+ * @file spark_particles.h
+
+*/
+
+#ifndef _SPARK_PARTICLE_SYSTEM_H
+#define _SPARK_PARTICLE_SYSTEM_H
+
+#include "particle_system.h"
+#include "material.h"
+
+//! A class to handle ParticleSystems
+class SparkParticles : public ParticleSystem
+{
+  ObjectListDeclaration(SparkParticles);
+
+public:
+  SparkParticles(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT);
+  SparkParticles(const TiXmlElement* root);
+  virtual ~SparkParticles();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void draw() const;
+
+private:
+  void init();
+
+private:
+  Material          material;            //!< A Material for all the Particles.
+};
+
+#endif /* _SPARK_PARTICLE_SYSTEM_H */
Index: branches/heathaze/src/world_entities/particles/sprite_particles.cc
===================================================================
--- branches/heathaze/src/world_entities/particles/sprite_particles.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/sprite_particles.cc	(revision 9940)
@@ -0,0 +1,173 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "sprite_particles.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "material.h"
+#include "state.h"
+#include "shell_command.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(SpriteParticles, CL_SPRITE_PARTICLES);
+CREATE_FACTORY(SpriteParticles);
+
+SHELL_COMMAND(texture, SpriteParticles, setMaterialTexture)
+    ->defaultValues("maps/evil-flower.png");
+
+
+
+/**
+ *  standard constructor
+ * @param maxCount the Count of particles in the System
+ * @param type The Type of the SpriteParticles
+*/
+SpriteParticles::SpriteParticles (unsigned int maxCount)
+  : ParticleSystem(maxCount)
+{
+  this->init();
+}
+
+/**
+ * @brief creates a Particle System out of a XML-element
+ * @param root: the XML-element to load from
+ */
+SpriteParticles::SpriteParticles(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+SpriteParticles::~SpriteParticles()
+{ }
+
+/**
+ * @brief initializes the SpriteParticles with default values
+*/
+void SpriteParticles::init()
+{
+  this->registerObject(this, SpriteParticles::_objectList);
+
+  this->material.setDiffuseMap("maps/radial-trans-noise.png");
+}
+
+
+/**
+ * loads Parameters from a TiXmlElement
+ * @param root the XML-element to load from.
+ */
+void SpriteParticles::loadParams(const TiXmlElement* root)
+{
+  ParticleSystem::loadParams(root);
+
+  LoadParam(root, "texture", this, SpriteParticles, setMaterialTexture);
+}
+
+/**
+ * @brief sets the Texutre that is placed onto the particles
+ * @param textureFile the Texture to load onto these SpriteParticles
+ */
+void SpriteParticles::setMaterialTexture(const std::string& textureFile)
+{
+  this->material.setDiffuseMap(textureFile);
+}
+
+/**
+ * @brief draws all the Particles of this System
+ *
+ * The Cases in this Function all do the same:
+ * Drawing all the particles with the appropriate Type.
+ * This is just the fastest Way to do this, but will most likely be changed in the future.
+ */
+void SpriteParticles::draw() const
+{
+
+  Particle* drawPart = particles;
+  this->material.select();
+
+  GLboolean checkLight = false;
+  glGetBooleanv(GL_LIGHTING, &checkLight);
+  glPushAttrib(GL_LIGHTING_BIT);
+  if (checkLight == GL_TRUE)
+    glDisable(GL_LIGHTING);
+
+  glDepthMask(GL_FALSE);
+  /*
+  glClearDepth(1.0);
+  glDepthFunc(GL_LEQUAL);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  glEnable(GL_BLEND);
+  glAlphaFunc(GL_GREATER,0.1);
+  glEnable(GL_ALPHA_TEST);
+  glEnable(GL_TEXTURE_2D);
+  glEnable(GL_CULL_FACE);
+  */
+  //glDepthMask(GL_FALSE);
+//glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
+
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+
+  while (likely(drawPart != NULL))
+  {
+    glColor4fv(drawPart->color);
+    //! @todo implement a faster code for the look-at Camera algorithm.
+
+    const PNode* camera = State::getCameraNode();  //!< @todo MUST be different
+    Vector cameraPos = camera->getAbsCoor();
+    Vector cameraTargetPos = State::getCameraTargetNode()->getAbsCoor();
+    Vector view = cameraTargetPos - cameraPos;
+    Vector up = Vector(0, 1, 0);
+    up = camera->getAbsDir().apply(up);
+    Vector h = up.cross(view);
+    Vector v = h.cross(view);
+    h.normalize();
+    v.normalize();
+    v *= .5 * drawPart->radius;
+    h *= .5 * drawPart->radius;
+
+    glBegin(GL_TRIANGLE_STRIP);
+    glTexCoord2i(1, 1);
+    glVertex3f(drawPart->position.x - h.x - v.x,
+               drawPart->position.y - h.y - v.y,
+               drawPart->position.z - h.z - v.z);
+    glTexCoord2i(0, 1);
+    glVertex3f(drawPart->position.x - h.x + v.x,
+               drawPart->position.y - h.y + v.y,
+               drawPart->position.z - h.z + v.z);
+    glTexCoord2i(1, 0);
+    glVertex3f(drawPart->position.x + h.x - v.x,
+               drawPart->position.y + h.y - v.y,
+               drawPart->position.z + h.z - v.z);
+    glTexCoord2i(0, 0);
+    glVertex3f(drawPart->position.x + h.x + v.x,
+               drawPart->position.y + h.y + v.y,
+               drawPart->position.z + h.z + v.z);
+
+    glEnd();
+
+    drawPart = drawPart->next;
+  }
+  glDepthMask(GL_TRUE);
+  glPopAttrib();
+}
Index: branches/heathaze/src/world_entities/particles/sprite_particles.h
===================================================================
--- branches/heathaze/src/world_entities/particles/sprite_particles.h	(revision 9940)
+++ branches/heathaze/src/world_entities/particles/sprite_particles.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file sprite_particles.h
+
+*/
+
+#ifndef _SPRITE_PARTICLE_SYSTEM_H
+#define _SPRITE_PARTICLE_SYSTEM_H
+
+#include "particle_system.h"
+#include "material.h"
+
+//! A class to handle ParticleSystems
+class SpriteParticles : public ParticleSystem
+{
+  ObjectListDeclaration(SpriteParticles);
+
+public:
+  SpriteParticles(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT);
+  SpriteParticles(const TiXmlElement* root);
+  virtual ~SpriteParticles();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setMaterialTexture(const std::string& textureFile);
+
+  /** @returns the Material that lies on this particles */
+  inline const Material* getMaterial() const { return &this->material; };
+
+  virtual void draw() const;
+
+private:
+  void init();
+
+private:
+  Material          material;            //!< A Material for all the Particles.
+};
+
+#endif /* _SPRITE_PARTICLE_SYSTEM_H */
Index: branches/heathaze/src/world_entities/planet.cc
===================================================================
--- branches/heathaze/src/world_entities/planet.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/planet.cc	(revision 9940)
@@ -0,0 +1,117 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "planet.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "static_model.h"
+
+#include "material.h"
+#include "texture.h"
+
+#include "network_game_manager.h"
+#include "converter.h"
+#include "vertex_array_model.h"
+#include "primitive_model.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Planet, CL_PLANET);
+CREATE_FACTORY(Planet);
+
+
+/**
+ *  initializes a skybox from a XmlElement
+*/
+Planet::Planet(const TiXmlElement* root)
+{
+  this->registerObject(this, Planet::_objectList);
+  this->toList(OM_GROUP_01);
+
+  //this->material->setIllum(20);
+  //this->material->setAmbient(0.1, 0.1, 0.1);
+
+
+
+      //st float radius, const unsigned int loops, const unsigned int segmentsPerLoop
+
+  this->loadParams(root);
+
+//   VertexArrayModel* model = new VertexArrayModel();
+//   model->spiralSphere(this->size, 10, 10);
+//   this->setModel(model);
+//   model->debug();
+//
+  PrimitiveModel* model = new PrimitiveModel(PRIM_SPHERE, this->size, 50);
+  this->setModel(model);
+}
+
+
+/**
+ *  default destructor
+*/
+Planet::~Planet()
+{
+  PRINTF(5)("Deleting Planet\n");
+}
+
+
+void Planet::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "texture", this, Planet, setTexture)
+      .describe("Sets the material on the Planet. The string must be the path relative to the data-dir, and without a trailing .jpg");
+
+  LoadParam(root, "size", this, Planet, setSize)
+      .describe("Sets the Size of the Planet (normally this should be 90% of the maximal viewing Distance).");
+}
+
+
+/**
+ *  Defines which textures should be loaded onto the Planet.
+ * @param textureName the top texture.
+*/
+void Planet::setTexture(const std::string& textureName)
+{
+  this->material.setDiffuseMap(textureName);
+}
+
+
+/**
+ * @param size The new size of the Planet
+
+ * do not forget to rebuild the Planet after this.
+*/
+void Planet::setSize(float size)
+{
+  this->size = size;
+}
+
+
+
+void Planet::draw() const
+{
+  this->material.select();
+
+  WorldEntity::draw();
+}
+
+
+
Index: branches/heathaze/src/world_entities/planet.h
===================================================================
--- branches/heathaze/src/world_entities/planet.h	(revision 9940)
+++ branches/heathaze/src/world_entities/planet.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file planet.h
+ *  Definition of the Planet, that handles the Display of an atmosphere for orxonox.
+ */
+
+#ifndef _PLANET_H
+#define _PLANET_H
+
+/* INCLUDES */
+#include "world_entity.h"
+#include "material.h"
+/* FORWARD DECLARATION */
+class Texture;
+
+//! A Class to handle a Planet
+class Planet : public WorldEntity
+{
+  ObjectListDeclaration(Planet);
+
+ public:
+  Planet(const TiXmlElement* root);
+
+  virtual ~Planet();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setSize(float size);
+  /** assumes jpg as input-format */
+  void setTexture(const std::string& textureName);
+
+
+  virtual void draw() const;
+
+
+
+ private:
+  Material        material;        //!< Materials for the Planet. sorted by number (0-5) top, bottom, left, right, front, back
+  Texture*        texture;         //!< Textures for the CubeMap.
+
+  float           size;            //!< Size of the Planet. This should match the frustum maximum range.
+  float           textureSize;     //!< this is the length of a texture (assumes a square texture)
+  char*           textureName;     //!< Name of the Texture
+
+};
+
+#endif  /* _PLANET_H */
+
+
+
Index: branches/heathaze/src/world_entities/playable.cc
===================================================================
--- branches/heathaze/src/world_entities/playable.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/playable.cc	(revision 9940)
@@ -0,0 +1,546 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Silvan Nellen
+   co-programmer: Benjamin Knecht
+*/
+
+
+#include "playable.h"
+
+#include "key_mapper.h"
+
+#include "player.h"
+#include "state.h"
+#include "camera.h"
+
+#include "util/loading/load_param.h"
+
+#include "power_ups/weapon_power_up.h"
+#include "power_ups/param_power_up.h"
+
+#include "game_rules.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include "shared_network_data.h"
+
+#include "effects/explosion.h"
+#include "kill.cc"
+
+#include "shell_command.h"
+SHELL_COMMAND_STATIC(orxoWeapon, Playable, Playable::addSomeWeapons_CHEAT)
+  ->setAlias("orxoWeapon");
+ObjectListDefinition(Playable);
+
+Playable::Playable()
+    : weaponMan(this),
+    supportedPlaymodes(Playable::Full3D),
+    playmode(Playable::Full3D)
+{
+  this->registerObject(this, Playable::_objectList);
+  PRINTF(4)("PLAYABLE INIT\n");
+
+  this->toList(OM_GROUP_01);
+
+  // the reference to the Current Player is NULL, because we dont have one at the beginning.
+  this->currentPlayer = NULL;
+
+  this->bFire = false;
+  this->oldFlags = 0;
+
+  this->setSynchronized(true);
+
+  this->score = 0;
+  this->collider = NULL;
+  this->enterRadius = 10.0f;
+
+  this->bDead = false;
+
+
+  this->teamChangeHandler = registerVarId( new SynchronizeableInt( &this->teamId, &this->teamId, "team-id", PERMISSION_MASTER_SERVER ) );
+
+  registerVar( new SynchronizeableInt( &score, &score, "score", PERMISSION_MASTER_SERVER ) );
+  registerVar( new SynchronizeableBool( &bFire, &bFire, "bFire", PERMISSION_OWNER));
+}
+
+
+/**
+ * @brief destroys the Playable
+ */
+Playable::~Playable()
+{
+  // THE DERIVED CLASS MUST UNSUBSCRIBE THE PLAYER THROUGH
+  // this->setPlayer(NULL);
+  // IN ITS DESTRUCTOR.
+
+  assert(this->currentPlayer == NULL);
+}
+
+/**
+ * @brief loads Playable parameters onto the Playable
+ * @param root the XML-root to load from
+ */
+void Playable::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "abs-dir", this, Playable, setPlayDirection);
+  LoadParam(root, "enter-radius", this, Playable, setEnterRadius)
+      .describe("The Distance one can enter the ship from.");
+}
+
+/**
+ * @brief picks up a powerup
+ * @param powerUp the PowerUp that should be picked.
+ * @returns true on success (pickup was picked, false otherwise)
+ *
+ * This function also checks if the Pickup can be picked up by this Playable
+ */
+bool Playable::pickup(PowerUp* powerUp)
+{
+  /// FIXME TOTALLY
+  if(powerUp->isA(WeaponPowerUp::staticClassID()))
+  {
+    return static_cast<WeaponPowerUp*>(powerUp)->process(&this->getWeaponManager());
+  }
+  else if(powerUp->isA(ParamPowerUp::staticClassID()))
+  {
+    ParamPowerUp* ppu = static_cast<ParamPowerUp*>(powerUp);
+    switch(ppu->getType())
+    {
+      case POWERUP_PARAM_HEALTH:
+        this->increaseHealth(ppu->getValue());
+        return true;
+      case POWERUP_PARAM_MAX_HEALTH:
+        this->increaseHealthMax(ppu->getValue());
+        return true;
+      default:
+        /// EVERYTHING THAT IS NOT HANDLED
+        /// FIXME
+        return false;
+    }
+  }
+  return false;
+}
+
+/**
+ * @brief adds a Weapon to the Playable.
+ * @param weapon the Weapon to add.
+ * @param configID the Configuration ID to add this weapon to.
+ * @param slotID the slotID to add the Weapon to.
+ */
+bool Playable::addWeapon(Weapon* weapon, int configID, int slotID)
+{
+  weapon->setOwner(this->getOwner());
+
+
+  if(this->weaponMan.addWeapon(weapon, configID, slotID))
+  {
+    this->weaponConfigChanged();
+    return true;
+  }
+  else
+  {
+    if (weapon != NULL)
+      PRINTF(2)("Unable to add Weapon (%s::%s) to %s::%s\n",
+                weapon->getClassCName(), weapon->getCName(), this->getClassCName(), this->getCName());
+    else
+      PRINTF(2)("No weapon defined\n");
+    return false;
+
+  }
+}
+
+/**
+ * @brief removes a Weapon.
+ * @param weapon the Weapon to remove.
+ */
+void Playable::removeWeapon(Weapon* weapon)
+{
+  this->weaponMan.removeWeapon(weapon);
+
+  this->weaponConfigChanged();
+}
+
+/**
+ * @brief jumps to the next WeaponConfiguration
+ */
+void Playable::nextWeaponConfig()
+{
+  this->weaponMan.nextWeaponConfig();
+  this->weaponConfigChanged();
+}
+
+/**
+ * @brief moves to the last WeaponConfiguration
+ */
+void Playable::previousWeaponConfig()
+{
+  this->weaponMan.previousWeaponConfig();
+  this->weaponConfigChanged();
+}
+
+/**
+ * @brief tells the Player, that the Weapon-Configuration has changed.
+ *
+ * TODO remove this
+ * This function is needed, so that the WeponManager of this Playable can easily update the HUD
+ */
+void Playable::weaponConfigChanged()
+{
+  if (this->currentPlayer != NULL)
+    this->currentPlayer->weaponConfigChanged();
+}
+
+/**
+ * @brief a Cheat that gives us some Weapons
+ */
+void Playable::addSomeWeapons_CHEAT()
+{
+  if (State::getPlayer() != NULL)
+  {
+    Playable* playable = State::getPlayer()->getPlayable();
+    if (playable != NULL)
+    {
+      PRINTF(2)("ADDING WEAPONS - you cheater\n");
+      playable->addWeapon(Weapon::createWeapon("Hyperblaster"));
+      playable->addWeapon(Weapon::createWeapon("Turret"));
+      playable->addWeapon(Weapon::createWeapon("AimingTurret"));
+      playable->addWeapon(Weapon::createWeapon("Cannon"));
+      playable->addWeapon(Weapon::createWeapon("TargetingTurret"));
+      PRINTF(2)("ADDING WEAPONS FINISHED\n");
+    }
+  }
+}
+
+/**
+ * @brief subscribe to all events the controllable needs
+ * @param player the player that shall controll this Playable
+ * @returns false on error true otherwise.
+ */
+bool Playable::setPlayer(Player* player)
+{
+  // if we already have a Player inside do nothing
+  if (this->currentPlayer != NULL && player != NULL)
+  {
+    return false;
+  }
+
+  // eject the Player if player == NULL
+  if (this->currentPlayer != NULL && player == NULL)
+  {
+    PRINTF(4)("Player gets ejected\n");
+
+    // unsubscibe all events.
+    std::vector<int>::iterator ev;
+    for (ev = this->events.begin(); ev != events.end(); ev++)
+      player->unsubscribeEvent(ES_GAME, (*ev));
+
+    // leave the entity
+    this->leave();
+
+    // eject the current Player.
+    Player* ejectPlayer = this->currentPlayer;
+    this->currentPlayer = NULL;
+    // eject the Player.
+    ejectPlayer->setPlayable(NULL);
+
+    return true;
+  }
+
+  // get the new Player inside
+  if (this->currentPlayer == NULL && player != NULL)
+  {
+    PRINTF(4)("New Player gets inside\n");
+    this->currentPlayer = player;
+    if (this->currentPlayer->getPlayable() != this)
+      this->currentPlayer->setPlayable(this);
+
+    /*EventHandler*/
+    std::vector<int>::iterator ev;
+    for (ev = this->events.begin(); ev != events.end(); ev++)
+      player->subscribeEvent(ES_GAME, (*ev));
+
+    this->enter();
+    return true;
+  }
+
+  return false;
+}
+
+
+/**
+ * @brief sets the TeamID and all the properties needed to be visible on the Playable
+ * @param teamID: the new TeamID of the Entity
+ */
+void Playable::setTeam(int teamID)
+{
+  /// Derive this function to make it look different with differen groups.
+  PRINTF(4)("No special team specific function implemented for %s::%s in Team %d\n", this->getClassCName(), this->getCName(), teamID);
+}
+
+
+/**
+ * @brief attaches the current Camera to this Playable
+ *
+ * this function can be derived, so that any Playable can make the attachment differently.
+ */
+void Playable::attachCamera()
+{
+  State::getCameraNode()->setParentSoft(this);
+  State::getCameraTargetNode()->setParentSoft(this);
+
+}
+
+/**
+ * @brief detaches the Camera
+ * @see void Playable::attachCamera()
+ */
+void  Playable::detachCamera()
+{
+}
+
+
+/**
+ * @brief sets the CameraMode.
+ * @param cameraMode: the Mode to switch to.
+ */
+void Playable::setCameraMode(unsigned int cameraMode)
+{
+  State::getCamera()->setViewMode((Camera::ViewMode)cameraMode);
+}
+
+
+/**
+ * @brief sets the Playmode
+ * @param playmode the Playmode
+ * @returns true on success, false otherwise
+ */
+bool Playable::setPlaymode(Playable::Playmode playmode)
+{
+  if (!this->playmodeSupported(playmode))
+    return false;
+  else
+  {
+    this->enterPlaymode(playmode);
+    this->playmode = playmode;
+    return true;
+  }
+}
+
+/**
+ * @brief This function look, that the Playable rotates to the given rotation.
+ * @param angle the Angle around
+ * @param dirX directionX
+ * @param dirY directionY
+ * @param dirZ directionZ
+ * @param speed how fast to turn there.
+ */
+void Playable::setPlayDirection(float angle, float dirX, float dirY, float dirZ, float speed)
+{
+  this->setPlayDirection(Quaternion(angle, Vector(dirX, dirY, dirZ)), speed);
+}
+
+/**
+ * @brief all Playable will enter the Playmode Differently, say here how to do it.
+ * @param playmode the Playmode to enter.
+ *
+ * In this function all the actions that are required to enter the Playmode are described.
+ * e.g: camera, rotation, wait cycle and so on...
+ *
+ * on enter of this function the playmode is still the old playmode.
+ */
+void Playable::enterPlaymode(Playable::Playmode playmode)
+{
+  switch(playmode)
+  {
+    default:
+      this->attachCamera();
+      break;
+    case Playable::Horizontal:
+      this->setCameraMode(Camera::ViewTop);
+      break;
+    case Playable::Vertical:
+      this->setCameraMode(Camera::ViewLeft);
+      break;
+    case Playable::FromBehind:
+      this->setCameraMode(Camera::ViewBehind);
+      break;
+  }
+}
+
+
+void Playable::respawn()
+{
+  PRINTF(0)("Playable respawn\n");
+  // only if this is the spaceship of the player
+  if( State::getGameRules() && State::getPlayer() && this == State::getPlayer()->getPlayable())
+    State::getGameRules()->onPlayerSpawn();
+
+  this->reset();
+  this->bDead = false;
+}
+
+
+
+
+void Playable::destroy(WorldEntity* killer)
+{
+  if( !this->bDead)
+  {
+    PRINTF(0)("Playable dies\n");
+    // only if this is the spaceship of the player
+    if (State::isOnline())
+    {
+      if( this == State::getPlayer()->getPlayable())
+        State::getGameRules()->onPlayerDeath();
+    }
+    this->bDead = true;
+
+    if( State::getGameRules() != NULL)
+      State::getGameRules()->registerKill(Kill(killer, this));
+  }
+}
+
+
+
+
+
+/**
+ * @brief add an event to the event list of events this Playable can capture
+ * @param eventType the Type of event to add
+ */
+void Playable::registerEvent(int eventType)
+{
+  this->events.push_back(eventType);
+
+  if (this->currentPlayer != NULL)
+    this->currentPlayer->subscribeEvent(ES_GAME, eventType);
+}
+
+/**
+ * @brief remove an event to the event list this Playable can capture.
+ * @param event the event to unregister.
+ */
+void Playable::unregisterEvent(int eventType)
+{
+  std::vector<int>::iterator rmEvent = std::find(this->events.begin(), this->events.end(), eventType);
+  this->events.erase(rmEvent);
+
+  if (this->currentPlayer != NULL)
+    this->currentPlayer->unsubscribeEvent(ES_GAME, eventType);
+}
+
+/**
+ * @brief ticks a Playable
+ * @param dt: the passed time since the last Tick
+ */
+void Playable::tick(float dt)
+{
+  this->weaponMan.tick(dt);
+  if (this->bFire)
+    weaponMan.fire();
+}
+
+
+/**
+ * @brief processes Playable events.
+ * @param event the Captured Event.
+ */
+void Playable::process(const Event &event)
+{
+  if( event.type == KeyMapper::PEV_FIRE1)
+    this->bFire = event.bPressed;
+  else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed)
+  {
+    this->nextWeaponConfig();
+  }
+  else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed)
+    this->previousWeaponConfig();
+}
+
+
+
+/**
+ * @brief converts a string into a Playable::Playmode.
+ * @param playmode the string naming the Playable::Playmode to convert.
+ * @returns the Playable::Playmode converted from playmode.
+ */
+Playable::Playmode Playable::stringToPlaymode(const std::string& playmode)
+{
+  if (playmode == Playable::playmodeNames[0])
+    return Playable::Vertical;
+  if (playmode == Playable::playmodeNames[1])
+    return Playable::Horizontal;
+  if (playmode == Playable::playmodeNames[2])
+    return Playable::FromBehind;
+  if (playmode == Playable::playmodeNames[3])
+    return Playable::Full3D;
+  if (playmode == Playable::playmodeNames[4])
+    return Playable::FirstPerson;
+
+  return Playable::Full3D;
+}
+
+
+/**
+ * @brief converts a playmode into a string.
+ * @param playmode the Playable::Playmode to convert.
+ * @returns the String.
+ */
+const std::string& Playable::playmodeToString(Playable::Playmode playmode)
+{
+  switch(playmode)
+  {
+    case Playable::Vertical:
+      return Playable::playmodeNames[0];
+    case Playable::Horizontal:
+      return Playable::playmodeNames[1];
+    case Playable::FromBehind:
+      return Playable::playmodeNames[2];
+    case Playable::Full3D:
+      return Playable::playmodeNames[3];
+    case Playable::FirstPerson:
+      return Playable::playmodeNames[4];
+
+    default:
+      return Playable::playmodeNames[3];
+  }
+}
+
+/**
+ * @brief PlaymodeNames
+ */
+const std::string Playable::playmodeNames[] =
+{
+  "Vertical",
+  "Horizontal",
+  "FromBehind",
+  "Full3D",
+  "FirstPerson"
+};
+
+
+/**
+ * handler for changes on registred vars
+ * @param id id's which changed
+ */
+void Playable::varChangeHandler( std::list< int > & id )
+{
+  if ( std::find( id.begin(), id.end(), this->teamChangeHandler) != id.end() )
+  {
+    this->setTeam(this->teamId);
+  }
+
+  WorldEntity::varChangeHandler(id);
+}
Index: branches/heathaze/src/world_entities/playable.h
===================================================================
--- branches/heathaze/src/world_entities/playable.h	(revision 9940)
+++ branches/heathaze/src/world_entities/playable.h	(revision 9940)
@@ -0,0 +1,141 @@
+
+/*!
+ * @file playable.h
+ * Interface for a basic controllable WorldEntity
+ */
+#ifndef _PLAYABLE_H
+#define _PLAYABLE_H
+
+#include "world_entity.h"
+#include "extendable.h"
+#include "event.h"
+#include <vector>
+#include <list>
+
+#include "world_entities/weapons/weapon_manager.h"
+
+class Weapon;
+class DotEmitter;
+class Player;
+class SpriteParticles;
+class Explosion;
+
+//! Basic controllable WorldEntity
+/**
+ *
+ */
+class Playable : public WorldEntity, public Extendable
+{
+  ObjectListDeclaration(Playable);
+public:
+  //! Defines the Playmode of an Entity.
+  typedef enum {
+    Vertical         =  1,       //!< Vertical (seen from left or right/move in x-z)
+    Horizontal       =  2,       //!< Horizontal (seet from the top/move in x-y)
+    FromBehind       =  4,       //!< Seen from behind (move in z-y)
+    Full3D           =  8,       //!< Full featured 3D-mode. (move in all directions x-y-z)
+    FirstPerson      = 16,
+
+    PlaymodeCount    =  5,
+  } Playmode;
+
+
+public:
+  virtual ~Playable();
+
+  virtual void loadParams(const TiXmlElement* root);
+  void varChangeHandler( std::list< int > & id );
+
+  // Weapon and Pickups
+  virtual bool pickup(PowerUp* powerUp);
+  bool addWeapon(Weapon* weapon, int configID = -1, int slotID = -1);
+  void removeWeapon(Weapon* weapon);
+  void nextWeaponConfig();
+  void previousWeaponConfig();
+  inline WeaponManager& getWeaponManager() { return this->weaponMan; };
+  void weaponConfigChanged();
+  static void addSomeWeapons_CHEAT();
+
+
+  // Player Settup
+  bool hasPlayer(){return !(this->currentPlayer == NULL);}
+  bool setPlayer(Player* player);
+  Player* getCurrentPlayer() const { return this->currentPlayer; };
+  /** @return a List of Events in PEV_* sytle */
+  inline const std::vector<int>& getEventList() { return this->events; };
+
+
+  // Camera and Playmode
+  void attachCamera();
+  void detachCamera();
+  void setCameraMode(unsigned int cameraMode = 0);
+  bool playmodeSupported(Playable::Playmode playmode) const { return this->supportedPlaymodes & playmode; };
+  bool setPlaymode(Playable::Playmode playmode);
+  Playable::Playmode getPlaymode() const { return this->playmode; };
+  virtual void setPlayDirection(const Quaternion& rot, float speed = 0.0f) = 0;
+  void setPlayDirection(float angle, float dirX, float dirY, float dirZ, float speed = 0.0f);
+
+  // Networking interface
+  inline void setScore( int score ) { this->score = score; }
+  inline int  getScore() { return this->score; }
+  inline void setTeamId( int teamId) { this->teamId = teamId;}
+  inline int getTeamId() const { return this->teamId; }
+  virtual void setTeam(int teamID);
+
+
+  void setEnterRadius(float radius) { this->enterRadius = radius; };
+  /** @returns the EnterRadius (how far away a Player must be to enter this entity) */
+  inline float getEnterRadius() const { return this->enterRadius; };
+
+  // WorldEntity Extensions
+  virtual void destroy(WorldEntity* killer);
+  virtual void respawn();
+  virtual void process(const Event &event);
+  virtual void tick(float dt);
+
+
+  inline bool beFire() const { return this->bFire; }
+  inline void fire(bool bF) { this->bFire = bF;}
+
+  // Transformations:
+  static Playable::Playmode stringToPlaymode(const std::string& playmode);
+  static const std::string& playmodeToString(Playable::Playmode playmode);
+  static const std::string playmodeNames[];
+
+protected:
+  Playable();
+
+  // Player Setup
+  virtual void enter() = 0;
+  virtual void leave() = 0;
+  // Playmode
+  void setSupportedPlaymodes(short playmodes) { this->supportedPlaymodes = playmodes; };
+  virtual void enterPlaymode(Playable::Playmode playmode);
+
+  // Events.
+  void registerEvent(int eventType);
+  void unregisterEvent(int eventType);
+
+private:
+  WeaponManager         weaponMan;          //!< the weapon manager: managing a list of weapon to wepaon-slot mapping
+  std::vector<int>      events;             //!< A list of Events, that are captured for this playable
+
+  Player*               currentPlayer;      //!< The Player currently connected to this Playable (the one that has controll) otherwise NULL
+
+  bool                  bFire;              //!< If the Ship is firing.
+  int                   oldFlags;           //!< Used for synchronisation
+
+  int                   score;              //!< players score
+  int                   teamChangeHandler;  //!< handler id for team changes network sync
+  int                   teamId;             //!< id of the current team
+
+  bool                  bDead;
+  short                 supportedPlaymodes; //!< What Playmodes are Supported in this Playable.
+  Playable::Playmode    playmode;           //!< The current playmode.
+
+  float                 enterRadius;        //!< How far one can be away from the Playable to enter it.
+
+  WorldEntity*          collider;
+};
+
+#endif /* _PLAYABLE_H */
Index: branches/heathaze/src/world_entities/player.cc
===================================================================
--- branches/heathaze/src/world_entities/player.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/player.cc	(revision 9940)
@@ -0,0 +1,129 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Silvan Nellen
+   co-programmer: Benjamin Knecht
+*/
+
+#include "player.h"
+#include "playable.h"
+
+#include "event_handler.h"
+
+#include "state.h"
+#include "util/hud.h"
+
+#include "debug.h"
+
+ObjectListDefinition(Player);
+/**
+ * creates a new Player
+*/
+Player::Player()
+{
+  //  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->registerObject(this, Player::_objectList);
+
+  PRINTF(4)("PLAYER INIT\n");
+
+  this->playable = NULL;
+  this->_hud.setVisibility(true);
+
+  this->subscribeEvent(ES_GAME, KeyMapper::PEV_CHANGE_SHIP);
+}
+
+
+/**
+ *  destructs the player, deletes alocated memory
+ */
+Player::~Player ()
+{
+  this->setPlayable(NULL);
+}
+
+
+bool Player::setPlayable(Playable* playable)
+{
+  if (this->playable == playable)
+    return false;
+
+  // get out of the current Playable
+  if (this->playable != NULL)
+  {
+    PRINTF(4)("Player gets ejected from Playable\n");
+    this->_hud.setEnergyWidget(NULL);
+    this->_hud.setWeaponManager(NULL);
+
+    Playable* ejectedPlayable = this->playable;
+
+    this->playable = NULL;
+    ejectedPlayable->setPlayer(NULL);
+  }
+
+  if (playable != NULL)
+  {
+    PRINTF(4)("Enter new Playable\n");
+    this->playable = playable;
+    this->_hud.setEnergyWidget(this->playable->getHealthWidget());
+    this->_hud.setWeaponManager(&this->playable->getWeaponManager());
+
+    this->playable->setPlayer(this);
+    return true;
+  }
+
+  if ( playable == NULL )
+    this->playable = NULL;
+
+  return true;
+}
+
+bool Player::eject()
+{
+  return this->setPlayable(NULL);
+}
+
+
+void Player::weaponConfigChanged()
+{
+  this->_hud.updateWeaponManager();
+}
+
+
+void Player::enterNewPlayable()
+{
+  /// FIXME this should be in the ObjectManager
+  for (ObjectList<Playable>::const_iterator node = Playable::objectList().begin();
+       node != Playable::objectList().end();
+       ++node)
+  {
+    if (this->playable != (*node) &&
+        ((*node)->getAbsCoor() - this->playable->getAbsCoor()).len() < ((*node)->getEnterRadius()))
+    {
+
+      this->setPlayable(*(node));
+
+      break;
+    }
+  }
+}
+
+
+void Player::process(const Event &event)
+{
+  if (event.type == KeyMapper::PEV_CHANGE_SHIP && event.bPressed)
+  {
+    this->enterNewPlayable();
+  }
+
+  if (likely(this->playable != NULL))
+    this->playable->process(event);
+}
+
Index: branches/heathaze/src/world_entities/player.h
===================================================================
--- branches/heathaze/src/world_entities/player.h	(revision 9940)
+++ branches/heathaze/src/world_entities/player.h	(revision 9940)
@@ -0,0 +1,51 @@
+/*!
+ * @file player.h
+ * Implements a basic playable WorldEntity
+ */
+
+#ifndef _PLAYER_H
+#define _PLAYER_H
+
+#include "event_listener.h"
+
+#include "util/hud.h"
+
+/* Forward Declaration */
+class Playable;
+
+
+//! Basic playable WorldEntity
+/**
+  *  this is the debug player - actualy we would have to make a new
+     class derivated from Player for each player. for now, we just use
+     the player.cc for debug also
+*/
+class Player : public EventListener
+{
+  ObjectListDeclaration(Player);
+
+  public:
+    Player();
+    virtual ~Player();
+
+    bool              setPlayable(Playable* controllalble);
+    bool              eject();
+    inline Playable*  getPlayable() const  { return this->playable; };
+
+
+     inline Hud& hud() { return this->_hud; };
+     inline const Hud& hud() const { return this->_hud; };
+
+
+    void              weaponConfigChanged();
+    void              enterNewPlayable();
+
+    // eventListener extension.
+    virtual void      process(const Event &event);
+
+  private:
+    Playable*         playable;                 //!< The one we controll or NULL if none
+    Hud               _hud;                      //!< The HUD to be displayed for this Player.
+};
+
+#endif /* _PLAYER_H */
Index: branches/heathaze/src/world_entities/power_ups/laser_power_up.cc
===================================================================
--- branches/heathaze/src/world_entities/power_ups/laser_power_up.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/power_ups/laser_power_up.cc	(revision 9940)
@@ -0,0 +1,123 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "laser_power_up.h"
+#include "util/loading/factory.h"
+#include "state.h"
+#include "network_game_manager.h"
+
+#include "primitive_model.h"
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(LaserPowerUp, CL_LASER_POWER_UP);
+CREATE_FACTORY(LaserPowerUp);
+
+LaserPowerUp::LaserPowerUp () : PowerUp(0.0, 1.0, 0.0)
+{
+  this->init();
+}
+
+LaserPowerUp::LaserPowerUp(const TiXmlElement* root) : PowerUp(0.0, 1.0, 0.0)
+{
+  this->init();
+
+  this->loadParams(root);
+}
+
+
+LaserPowerUp::~LaserPowerUp ()
+{
+  delete this->sphereModel;
+  delete this->sphereMaterial;
+}
+
+
+void LaserPowerUp::init()
+{
+  this->registerObject(this, LaserPowerUp::_objectList);
+  this->loadModel("models/guns/test_gun.obj", 2.0);
+
+  this->sphereModel = new PrimitiveModel(PRIM_SPHERE, 7, 5);
+  this->sphereMaterial = new Material;
+  this->sphereMaterial->setTransparency(.1);
+  this->sphereMaterial->setDiffuse(.7, .7, .1);
+
+  this->rotation = Vector(0,1,0);
+  this->cycle    = (float)rand()/RAND_MAX*M_2_PI;
+  this->shiftDir(Quaternion((float)rand()/RAND_MAX*M_2_PI, this->rotation));
+}
+
+
+void LaserPowerUp::loadParams(const TiXmlElement* root)
+{
+  PowerUp::loadParams(root);
+
+}
+
+
+/**
+ * this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void LaserPowerUp::collidesWith(WorldEntity* entity, const Vector& location)
+{
+ // PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassCName(), entity->getClassCName(), location.x, location.y, location.z);
+ if (entity->isA(CL_PLAYABLE))
+  this->toList(OM_DEAD);
+}
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+ *
+ * Handle all stuff that should update with time inside this method (movement, animation, etc.)
+*/
+void LaserPowerUp::tick(float dt)
+{
+  this->shiftDir(Quaternion(dt, this->rotation));
+  this->cycle+=dt;
+
+}
+
+/**
+ *  the entity is drawn onto the screen with this function
+ *
+ * This is a central function of an entity: call it to let the entity painted to the screen.
+ * Just override this function with whatever you want to be drawn.
+*/
+void LaserPowerUp::draw() const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y + cos(this->cycle*3.0)*2.0,
+                this->getAbsCoor ().z);
+  /* rotate */
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  this->getModel()->draw();
+
+  this->sphereMaterial->select();
+  this->sphereModel->draw();
+  glPopMatrix();
+}
+
+
Index: branches/heathaze/src/world_entities/power_ups/laser_power_up.h
===================================================================
--- branches/heathaze/src/world_entities/power_ups/laser_power_up.h	(revision 9940)
+++ branches/heathaze/src/world_entities/power_ups/laser_power_up.h	(revision 9940)
@@ -0,0 +1,40 @@
+/*!
+ * @file laser_power_up.h
+ * @brief A class representing a PowerUp in the world.
+*/
+
+#ifndef _LASER_POWER_UP_H
+#define _LASER_POWER_UP_H
+
+#include "power_up.h"
+
+/* FORWARD DEFINITION */
+class Material;
+
+class LaserPowerUp : public PowerUp {
+  ObjectListDeclaration(LaserPowerUp);
+
+ public:
+  LaserPowerUp();
+  LaserPowerUp(const TiXmlElement* root);
+  virtual ~LaserPowerUp ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+
+  virtual void collidesWith(WorldEntity* entity, const Vector& location);
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+  private:
+   void init();
+
+  private:
+   Vector              rotation;
+   float               cycle;
+
+   Model*              sphereModel;
+   Material*           sphereMaterial;
+};
+
+#endif /* _LASER_POWER_UP_H */
Index: branches/heathaze/src/world_entities/power_ups/param_power_up.cc
===================================================================
--- branches/heathaze/src/world_entities/power_ups/param_power_up.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/power_ups/param_power_up.cc	(revision 9940)
@@ -0,0 +1,126 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "param_power_up.h"
+#include "util/loading/factory.h"
+#include "state.h"
+
+#include "primitive_model.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+#include "network_game_manager.h"
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(ParamPowerUp, CL_PARAM_POWER_UP);
+CREATE_FACTORY(ParamPowerUp);
+
+const char* ParamPowerUp::paramTypes[] = {
+  "shield",
+  "max-shield",
+  "health",
+  "max-health",
+};
+
+ParamPowerUp::ParamPowerUp(const TiXmlElement* root) : PowerUp(0.0, 1.0, 0.0)
+{
+  this->init();
+  this->loadPickupSound("sound/powerups/power_up_6.wav");
+  if( root != NULL)
+    this->loadParams(root);
+
+  registerVar( new SynchronizeableInt( (int*)&type, (int*)&type, "type", PERMISSION_MASTER_SERVER ) );
+  registerVar( new SynchronizeableFloat( &value, &value, "value", PERMISSION_MASTER_SERVER ) );
+  registerVar( new SynchronizeableFloat( &max_value, &max_value, "max_value", PERMISSION_MASTER_SERVER ) );
+  registerVar( new SynchronizeableFloat( &min_value, &min_value, "min_value", PERMISSION_MASTER_SERVER ) );
+}
+
+
+ParamPowerUp::~ParamPowerUp ()
+{
+}
+
+
+void ParamPowerUp::init()
+{
+  this->registerObject(this, ParamPowerUp::_objectList);
+  this->value = 0;
+  this->max_value = 0;
+  this->min_value = 0;
+}
+
+
+void ParamPowerUp::loadParams(const TiXmlElement* root)
+{
+  PowerUp::loadParams(root);
+  LoadParam(root, "type", this, ParamPowerUp, setType);
+
+  if( root != NULL && root->FirstChildElement("value") != NULL) {
+
+    LoadParam(root, "value", this, ParamPowerUp, setValue);
+  }
+  else {
+    LoadParam(root, "max-value", this, ParamPowerUp, setMaxValue);
+    LoadParam(root, "min-value", this, ParamPowerUp, setMinValue);
+    respawn();
+  }
+}
+
+void ParamPowerUp::setValue(float value)
+{
+  this->value = value;
+}
+
+void ParamPowerUp::setType(const std::string& type)
+{
+  for(int i = 0; i < POWERUP_PARAM_size; ++i) {
+    if(type == paramTypes[i]) {
+      this->type = (EnumParamPowerUpType)i;
+      break;
+    }
+  }
+}
+
+void ParamPowerUp::setMaxValue(float value)
+{
+  this->max_value = value;
+}
+
+void ParamPowerUp::setMinValue(float value)
+{
+  this->min_value = value;
+}
+
+float ParamPowerUp::getValue()
+{
+  return this->value;
+}
+
+EnumParamPowerUpType ParamPowerUp::getType()
+{
+  return this->type;
+}
+
+void ParamPowerUp::respawn()
+{
+  if(this->min_value != this->max_value)
+  {
+    this->value = this->min_value + rand() * (this->max_value - this->min_value);
+  }
+}
+
Index: branches/heathaze/src/world_entities/power_ups/param_power_up.h
===================================================================
--- branches/heathaze/src/world_entities/power_ups/param_power_up.h	(revision 9940)
+++ branches/heathaze/src/world_entities/power_ups/param_power_up.h	(revision 9940)
@@ -0,0 +1,52 @@
+/*!
+ * @file weapon_power_up.h
+ * @brief A class representing a PowerUp modifying parameters.
+*/
+
+#ifndef _PARAM_POWER_UP_H
+#define _PARAM_POWER_UP_H
+
+#include "power_up.h"
+
+/* FORWARD DEFINITION */
+
+typedef enum EnumParamPowerUpType {
+  POWERUP_PARAM_SHIELD,
+  POWERUP_PARAM_MAX_SHIELD,
+  POWERUP_PARAM_HEALTH,
+  POWERUP_PARAM_MAX_HEALTH,
+  POWERUP_PARAM_size
+} EnumParamPowerUpType;
+
+class ParamPowerUp : public PowerUp {
+  ObjectListDeclaration(ParamPowerUp);
+
+public:
+  ParamPowerUp(const TiXmlElement* root = NULL);
+  virtual ~ParamPowerUp ();
+
+  void setValue(float value);
+  void setMaxValue(float value);
+  void setMinValue(float value);
+  void setType(const std::string& type);
+  EnumParamPowerUpType getType();
+  float getValue();
+
+protected:
+  virtual void respawn();
+
+private:
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+private:
+  EnumParamPowerUpType    type;
+  float                   value;
+  float                   max_value;
+  float                   min_value;
+
+  static const char*      paramTypes[];
+
+};
+
+#endif /* _PARAM_POWER_UP_H */
Index: branches/heathaze/src/world_entities/power_ups/power_up.cc
===================================================================
--- branches/heathaze/src/world_entities/power_ups/power_up.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/power_ups/power_up.cc	(revision 9940)
@@ -0,0 +1,175 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Manuel Leuenberger
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "power_up.h"
+#include "extendable.h"
+#include "primitive_model.h"
+
+#include "sound/resource_sound_buffer.h"
+#include "util/loading/load_param.h"
+
+#include "debug.h"
+
+ObjectListDefinition(PowerUp);
+
+PowerUp::PowerUp(float r, float g, float b)
+{
+  this->registerObject(this, PowerUp::_objectList);
+
+  this->respawnType = RESPAWN_TIME;
+  this->respawnStart = 10;
+  this->model = NULL;
+  /*  if(!PowerUp::sphereModel) {*/
+
+  Model* sphereModel = new PrimitiveModel(PRIM_SPHERE, 7, 5);
+
+  this->setModel(sphereModel);
+  this->buildObbTree( 4);
+  this->sphereMaterial = new Material;
+  this->sphereMaterial->setTransparency(.8);
+  this->sphereMaterial->setDiffuse(r, g, b);
+  this->toList(OM_COMMON);
+
+  this->soundSource.setSourceNode(this);
+
+  this->collider = NULL;
+}
+
+PowerUp::~PowerUp ()
+{
+  delete this->sphereMaterial;
+}
+
+
+void PowerUp::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "respawnType", this, PowerUp, setRespawnType);
+
+  LoadParam(root, "respawnTime", this, PowerUp, setRespawnTime);
+
+  LoadParam(root, "pickup-sound", this, PowerUp, loadPickupSound);
+
+  LoadParam(root, "respawn-sound", this, PowerUp, loadRespawnSound);
+}
+
+
+void PowerUp::loadPickupSound(const std::string& pickupSound)
+{
+  if (!pickupSound.empty())
+    this->pickupBuffer = OrxSound::ResourceSoundBuffer(pickupSound);
+  else
+    this->pickupBuffer = OrxSound::SoundBuffer();
+}
+
+void PowerUp::loadRespawnSound(const std::string& respawnSound)
+{
+  if (!respawnSound.empty())
+    this->respawnBuffer = OrxSound::ResourceSoundBuffer(respawnSound);
+  else
+    this->respawnBuffer = OrxSound::SoundBuffer();
+}
+
+
+void PowerUp::collidesWith (WorldEntity* entity, const Vector& location)
+{
+  if(this->collider != entity && entity->isA(Extendable::staticClassID()))
+  {
+    this->collider = entity;
+    if(dynamic_cast<Extendable*>(entity)->pickup(this))
+    {
+      if(pickupBuffer.loaded())
+        this->soundSource.play(this->pickupBuffer);
+
+      switch(respawnType)
+      {
+      case RESPAWN_NONE:
+        this->toList(OM_DEAD);
+        break;
+      case RESPAWN_TIME:
+        this->toList(OM_DEAD_TICK);
+        this->respawnTime = this->respawnStart;
+        break;
+        default:
+          /* NOT HANDLED */
+          break;
+      }
+    }
+  }
+}
+
+void PowerUp::tick(float dt)
+{
+  if(this->getOMListNumber() != OM_COMMON)
+  {
+    this->respawnTime -= dt;
+    if(this->respawnTime <= 0)
+    {
+      this->toList(OM_COMMON);
+      this->collider = NULL;
+      if (likely(this->respawnBuffer.loaded()))
+        this->soundSource.play(this->respawnBuffer);
+
+    }
+  }
+}
+
+void PowerUp::draw() const
+{
+  if(this->model != NULL)
+  {
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glTranslatef (this->getAbsCoor ().x,
+                  this->getAbsCoor ().y,
+                  this->getAbsCoor ().z);
+    Vector tmpRot = this->getAbsDir().getSpacialAxis();
+    glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+    this->model->draw();
+    glPopMatrix();
+  }
+  this->sphereMaterial->select();
+  WorldEntity::draw();
+}
+
+const char* PowerUp::respawnTypes[] =
+  {
+    "none",
+    "time"
+  };
+
+
+void PowerUp::setRespawnType(const std::string& type)
+{
+  for(int i = 0; i < RESPAWN_size; ++i)
+  {
+    if(type == respawnTypes[i])
+    {
+      this->respawnType = (PowerUpRespawn)i;
+      break;
+    }
+  }
+}
+
+void PowerUp::setRespawnTime(const float respawnTime)
+{
+  this->respawnStart = respawnTime;
+}
+
+
Index: branches/heathaze/src/world_entities/power_ups/power_up.h
===================================================================
--- branches/heathaze/src/world_entities/power_ups/power_up.h	(revision 9940)
+++ branches/heathaze/src/world_entities/power_ups/power_up.h	(revision 9940)
@@ -0,0 +1,57 @@
+/*!
+ * @file power_up.h
+ * @brief A class representing a PowerUp in the world.
+*/
+
+#ifndef _POWER_UP_H
+#define _POWER_UP_H
+
+#include "world_entity.h"
+
+#include "sound_buffer.h"
+#include "sound_source.h"
+
+class Material;
+
+typedef enum PowerUpRespawn {
+  RESPAWN_NONE,
+  RESPAWN_TIME,
+  RESPAWN_size
+} PowerUpRespawn;
+
+class PowerUp : public WorldEntity {
+  ObjectListDeclaration(PowerUp);
+
+public:
+  virtual void loadParams(const TiXmlElement* root);
+  void collidesWith (WorldEntity* entity, const Vector& location);
+
+  void loadPickupSound(const std::string& pickupSound);
+  void loadRespawnSound(const std::string& respawnSound);
+
+  virtual void draw () const;
+  virtual void tick(float dt);
+  void setRespawnType(const std::string& type);
+  void setRespawnTime(const float respawn);
+
+protected:
+  PowerUp(float r, float g, float b);
+  virtual ~PowerUp ();
+
+protected:
+  Model* model;
+
+private:
+  OrxSound::SoundSource  soundSource;
+  OrxSound::SoundBuffer  pickupBuffer;
+  OrxSound::SoundBuffer  respawnBuffer;
+  Material*              sphereMaterial;
+  PowerUpRespawn         respawnType;
+  float                  respawnTime;
+  float                  respawnStart;
+  static const char*     respawnTypes[];
+
+  WorldEntity*           collider;
+};
+
+#endif /* _POWER_UP_H */
Index: branches/heathaze/src/world_entities/power_ups/turret_power_up.cc
===================================================================
--- branches/heathaze/src/world_entities/power_ups/turret_power_up.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/power_ups/turret_power_up.cc	(revision 9940)
@@ -0,0 +1,117 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "turret_power_up.h"
+#include "util/loading/factory.h"
+#include "network_game_manager.h"
+#include "state.h"
+
+#include "primitive_model.h"
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(TurretPowerUp, CL_TURRET_POWER_UP);
+CREATE_FACTORY(TurretPowerUp);
+
+TurretPowerUp::TurretPowerUp(const TiXmlElement* root) : PowerUp(0.0, 1.0, 0.0)
+{
+  this->init();
+
+  if( root != NULL)
+    this->loadParams(root);
+}
+
+
+TurretPowerUp::~TurretPowerUp ()
+{
+  delete this->sphereModel;
+  delete this->sphereMaterial;
+}
+
+
+void TurretPowerUp::init()
+{
+  this->registerObject(this, TurretPowerUp::_objectList);
+  this->loadModel("models/guns/turret1.obj", 2.0);
+
+  this->sphereModel = new PrimitiveModel(PRIM_SPHERE, 7, 5);
+  this->sphereMaterial = new Material;
+  this->sphereMaterial->setTransparency(.1);
+  this->sphereMaterial->setDiffuse(.1, .1, .8);
+
+  this->rotation = Vector(0,1,0);
+  this->cycle    = (float)rand()/RAND_MAX*M_2_PI;
+  this->shiftDir(Quaternion((float)rand()/RAND_MAX*M_2_PI, this->rotation));
+}
+
+
+void TurretPowerUp::loadParams(const TiXmlElement* root)
+{
+  PowerUp::loadParams(root);
+
+}
+
+
+/**
+ * this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void TurretPowerUp::collidesWith(WorldEntity* entity, const Vector& location)
+{
+ // PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassCName(), entity->getClassCName(), location.x, location.y, location.z);
+ if (entity->isA(CL_PLAYABLE))
+   this->toList(OM_DEAD);
+}
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+ *
+ * Handle all stuff that should update with time inside this method (movement, animation, etc.)
+*/
+void TurretPowerUp::tick(float dt)
+{
+  this->shiftDir(Quaternion(dt, this->rotation));
+  this->cycle+=dt;
+
+}
+
+/**
+ *  the entity is drawn onto the screen with this function
+ *
+ * This is a central function of an entity: call it to let the entity painted to the screen.
+ * Just override this function with whatever you want to be drawn.
+*/
+void TurretPowerUp::draw() const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y + cos(this->cycle*3.0)*2.0,
+                this->getAbsCoor ().z);
+  /* rotate */
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  this->getModel()->draw();
+
+  this->sphereMaterial->select();
+  this->sphereModel->draw();
+  glPopMatrix();
+}
Index: branches/heathaze/src/world_entities/power_ups/turret_power_up.h
===================================================================
--- branches/heathaze/src/world_entities/power_ups/turret_power_up.h	(revision 9940)
+++ branches/heathaze/src/world_entities/power_ups/turret_power_up.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file turret_power_up.h
+ * @brief A class representing a PowerUp in the world.
+*/
+
+#ifndef _TURRET_POWER_UP_H
+#define _TURRET_POWER_UP_H
+
+#include "power_up.h"
+
+/* FORWARD DEFINITION */
+class Material;
+
+class TurretPowerUp : public PowerUp {
+  ObjectListDeclaration(TurretPowerUp);
+
+ public:
+  TurretPowerUp(const TiXmlElement* root = NULL);
+  virtual ~TurretPowerUp ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void collidesWith(WorldEntity* entity, const Vector& location);
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+  private:
+   void init();
+
+  private:
+   Vector              rotation;
+   float               cycle;
+
+   Model*              sphereModel;
+   Material*           sphereMaterial;
+};
+
+#endif /* _TURRET_POWER_UP_H */
Index: branches/heathaze/src/world_entities/power_ups/weapon_power_up.cc
===================================================================
--- branches/heathaze/src/world_entities/power_ups/weapon_power_up.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/power_ups/weapon_power_up.cc	(revision 9940)
@@ -0,0 +1,105 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "weapon_power_up.h"
+#include "util/loading/factory.h"
+#include "state.h"
+#include "network_game_manager.h"
+
+#include "primitive_model.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(WeaponPowerUp, CL_WEAPON_POWER_UP);
+CREATE_FACTORY(WeaponPowerUp);
+
+WeaponPowerUp::WeaponPowerUp(const TiXmlElement* root) : PowerUp(1.0, 1.0, 0.0)
+{
+  this->init();
+  if( root != NULL)
+    this->loadParams(root);
+}
+
+
+WeaponPowerUp::~WeaponPowerUp ()
+{
+}
+
+
+void WeaponPowerUp::init()
+{
+  this->registerObject(this, WeaponPowerUp::_objectList);
+  this->loadPickupSound("sound/powerups/whats this2.wav");
+
+  this->weaponXML = NULL;
+  this->weapon = NULL;
+}
+
+
+void WeaponPowerUp::loadParams(const TiXmlElement* root)
+{
+  PowerUp::loadParams(root);
+  const TiXmlElement* elem = root->FirstChildElement("weapon");
+  if(elem != NULL && (elem = elem->FirstChildElement()) != NULL)
+  {
+    this->weaponXML = elem;
+    newWeapon();
+  }
+  else
+  {
+    LoadParam(root, "weaponID", this, WeaponPowerUp, setWeaponClass);
+  }
+}
+
+Weapon* WeaponPowerUp::getWeapon()
+{
+  return this->weapon;
+}
+
+bool WeaponPowerUp::process(WeaponManager* manager)
+{
+  if(manager->addWeapon(this->weapon)) {
+    newWeapon();
+  }
+  else {
+    manager->increaseAmmunition(this->weapon->getProjectileType(), this->weapon->getEnergy());
+  }
+  return true;
+}
+
+void WeaponPowerUp::newWeapon()
+{
+  this->weapon = dynamic_cast<Weapon*>((weaponXML == NULL)
+      ? Factory::fabricate((this->weapon->getClassID()))
+      : Factory::fabricate((const TiXmlElement*)this->getXmlElem()->FirstChildElement("weapon")));
+  this->model = this->weapon->getModel(0);
+}
+
+void WeaponPowerUp::setWeaponClass(const std::string& name)
+{
+  this->weapon = dynamic_cast<Weapon*>(Factory::fabricate(name));
+  if (this->weapon == NULL)
+  {
+    PRINTF(1)("Unable to load Weapon. %s\n", name.c_str());
+    this->weapon = dynamic_cast<Weapon*>(Factory::fabricate("Turret"));
+  }
+  this->model = this->weapon->getModel(0);
+}
+
Index: branches/heathaze/src/world_entities/power_ups/weapon_power_up.h
===================================================================
--- branches/heathaze/src/world_entities/power_ups/weapon_power_up.h	(revision 9940)
+++ branches/heathaze/src/world_entities/power_ups/weapon_power_up.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file weapon_power_up.h
+ * @brief A class representing a PowerUp containing a weapon.
+*/
+
+#ifndef _WEAPON_POWER_UP_H
+#define _WEAPON_POWER_UP_H
+
+#include "power_up.h"
+#include "weapons/weapon.h"
+#include "weapons/weapon_manager.h"
+
+/* FORWARD DEFINITION */
+
+class WeaponPowerUp : public PowerUp {
+ObjectListDeclaration(WeaponPowerUp);
+public:
+  WeaponPowerUp(const TiXmlElement* root = NULL);
+  virtual ~WeaponPowerUp ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  Weapon* getWeapon();
+  void setWeaponClass(const std::string& name);
+
+  bool process(WeaponManager* manager);
+
+private:
+  void init();
+  void newWeapon();
+private:
+  Weapon* weapon;
+  const TiXmlElement* weaponXML;
+
+  void createWeapon();
+};
+
+#endif /* _WEAPON_POWER_UP_H */
Index: branches/heathaze/src/world_entities/projectiles/bomb.cc
===================================================================
--- branches/heathaze/src/world_entities/projectiles/bomb.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/bomb.cc	(revision 9940)
@@ -0,0 +1,195 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Stefan Lienhard
+   co-programmer: ...
+*/
+
+#include "bomb.h"
+#include "glincl.h"
+#include "state.h"
+#include "model.h"
+#include "primitive_model.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/particle_system.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Bomb, CL_BOMB);
+CREATE_FAST_FACTORY_STATIC(Bomb);
+
+/**
+ * constructs and loads a Bomb from a XML-element
+ * @param root the XML-element to load from
+ */
+Bomb::Bomb(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+  this->loadModel("models/projectiles/RadioActiveBomb.obj", 1.0);
+
+  this->setMinEnergy(1);
+  this->setHealthMax(10);
+
+  this->lifeSpan = 15;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+}
+
+
+/**
+ * standard deconstructor
+ */
+Bomb::~Bomb ()
+{
+  delete this->detonationSphere;
+  delete this->detonationMaterial;
+
+}
+
+
+/**
+ * initializes the Bomb
+ * @todo change this to what you wish
+ */
+void Bomb::init()
+{
+  this->registerObject(this, Bomb::_objectList);
+
+
+  this->detonationSphere = new PrimitiveModel(PRIM_SPHERE);
+  this->detonationMaterial = new Material();
+  this->detonationMaterial->setDiffuse(1, 0, 0);
+
+  this->loadExplosionSound("sound/explosions/explosion_7_far.wav");
+  //   this->detonationMaterial->setTransparency(.1);
+  /**
+   * @todo: Write CL_PROTO_WORLD_ENTITY INTO THE src/defs/class_id.h (your own definition)
+   */
+
+}
+
+
+/**
+ * loads a Bomb from a XML-element
+ * @param root the XML-element to load from
+ * @todo make the class Loadable
+ */
+void Bomb::loadParams(const TiXmlElement* root)
+{
+  // all the clases this Entity is directly derived from must be called in this way, to load all settings.
+  Projectile::loadParams(root);
+
+
+  /**
+   * @todo: make the class Loadable
+   */
+}
+
+
+/**
+ * advances the Bomb about time seconds
+ * @param time the Time to step
+ */
+void Bomb::tick(float time)
+{
+  this->lifeCycle += time/this->lifeSpan;
+  if( this->lifeCycle >= 1.0)
+    {
+      PRINTF(5)("FINALIZE==========================\n");
+      PRINTF(5)("current life cycle is: %f\n", this->lifeCycle);
+      PRINTF(5)("FINALIZE===========================\n");
+
+      this->deactivate();
+    }
+  else if (this->lifeCycle > 0.9f)
+    this->detonate ((this->lifeCycle-.89) *1000.0);
+  else
+  {
+    Vector v = this->velocity * (time);
+    this->shiftCoor(v);
+  }
+}
+
+/**
+ * draws this worldEntity
+ */
+void Bomb::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  float matrix[4][4];
+
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  /* rotate */
+  this->getAbsDir().matrix(matrix);
+  glMultMatrixf((float*)matrix);
+
+  if (this->lifeCycle < .9)
+  {
+    if (this->getModel() != NULL)
+      this->getModel()->draw();
+  }
+  else
+  {
+    glScalef((this->lifeCycle-.89) *1000.0,
+              (this->lifeCycle-.89) *1000.0,
+              (this->lifeCycle-.89) *1000.0);
+    this->detonationMaterial->select();
+    this->detonationSphere->draw();
+  }
+  glPopMatrix();
+}
+
+
+/**
+ *
+ *
+ */
+void Bomb::collidesWith (WorldEntity* entity, const Vector& location)
+{
+  if (this->lifeCycle < .9f && entity->isA(CL_NPC))
+    this->lifeCycle = 0.9f;
+}
+
+void Bomb::activate()
+{
+
+}
+
+
+void Bomb::deactivate()
+{
+  this->toList(OM_DEAD);
+  this->lifeCycle = 0.0f;
+  Bomb::fastFactory->kill(this);
+}
+
+void Bomb::detonate(float size)
+{
+  /// FIXME
+/*  ObjectManager::EntityList detonationList;
+  ObjectManager::distanceFromObject(detonationList, *this, size, NPC::objectList());
+    while( !detonationList.empty() )
+    {
+      detonationList.front()->collidesWith(this, Vector(0,0,0));
+      detonationList.pop_front();
+    }*/
+}
Index: branches/heathaze/src/world_entities/projectiles/bomb.h
===================================================================
--- branches/heathaze/src/world_entities/projectiles/bomb.h	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/bomb.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file bomb.h
+ * @brief description
+*/
+
+#ifndef _BOMB_H
+#define _BOMB_H
+
+#include "projectile.h"
+
+class FastFactory;
+class SpriteParticles;
+class ParticleEmitter;
+class Material;
+
+//! A Class to ...
+class Bomb : public Projectile
+{
+  ObjectListDeclaration(Bomb);
+ public:
+  Bomb(const TiXmlElement* root = NULL);
+  virtual ~Bomb();
+
+  virtual void loadParams(const TiXmlElement* root);
+  void init();
+
+//  virtual void postSpawn ();
+//  virtual void leftWorld ();
+
+
+  virtual void draw() const;
+  virtual void tick(float time);
+  virtual void collidesWith (WorldEntity* entity, const Vector& location);
+  virtual void activate();
+  virtual void deactivate();
+
+  void detonate(float size);
+
+ private:
+  static FastFactory*               fastFactory;
+  static SpriteParticles*           trailParticles;
+  static SpriteParticles*           explosionParticles;
+
+  ParticleEmitter*                  emitter;
+  Model*                            detonationSphere;
+  Material*                         detonationMaterial;
+};
+
+#endif /* BOMB */
Index: branches/heathaze/src/world_entities/projectiles/boomerang_projectile.cc
===================================================================
--- branches/heathaze/src/world_entities/projectiles/boomerang_projectile.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/boomerang_projectile.cc	(revision 9940)
@@ -0,0 +1,216 @@
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Silvan Nellen
+   co-programmer:
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "boomerang_projectile.h"
+
+#include "state.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(BoomerangProjectile, CL_BOOMERANG_PROJECTILE);
+CREATE_FAST_FACTORY_STATIC(BoomerangProjectile);
+
+/**
+ *  standard constructor
+*/
+BoomerangProjectile::BoomerangProjectile () : Projectile()
+{
+  this->registerObject(this, BoomerangProjectile::_objectList);
+
+  this->loadModel("models/projectiles/orx-rocket.obj", 2.0);
+  this->loadExplosionSound("sound/explosions/explosion_4.wav");
+
+
+  this->setMinEnergy(1);
+  this->setHealthMax(10);
+  this->lifeSpan = 2.0;
+  this->agility = 3.5;
+  this->maxVelocity = 150;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+BoomerangProjectile::~BoomerangProjectile ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (BoomerangProjectile::trailParticles != NULL && BoomerangProjectile::objectList().size() <= 1)
+  {
+    if (ParticleSystem::objectList().exists(BoomerangProjectile::trailParticles))
+      delete BoomerangProjectile::trailParticles;
+    BoomerangProjectile::trailParticles = NULL;
+  }
+  if (BoomerangProjectile::explosionParticles != NULL && BoomerangProjectile::objectList().size() <= 1)
+  {
+    if (ParticleSystem::objectList().exists(BoomerangProjectile::explosionParticles))
+      delete BoomerangProjectile::explosionParticles;
+    BoomerangProjectile::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* BoomerangProjectile::trailParticles = NULL;
+SpriteParticles* BoomerangProjectile::explosionParticles = NULL;
+
+
+
+void BoomerangProjectile::activate()
+{
+  if (unlikely(BoomerangProjectile::trailParticles == NULL))
+  {
+    BoomerangProjectile::trailParticles = new SpriteParticles(2000);
+    BoomerangProjectile::trailParticles->setName("BoomerangProjectileTrailParticles");
+    BoomerangProjectile::trailParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    BoomerangProjectile::trailParticles->setLifeSpan(1.0, .3);
+    BoomerangProjectile::trailParticles->setRadius(0.0, .5);
+    BoomerangProjectile::trailParticles->setRadius(0.2, 4.0);
+    BoomerangProjectile::trailParticles->setRadius(.5, 1.5);
+    BoomerangProjectile::trailParticles->setRadius(1.0, 1.5);
+    BoomerangProjectile::trailParticles->setColor(0.0, 1,0,0,.7);
+    BoomerangProjectile::trailParticles->setColor(0.2, .8,.8,0,.5);
+    BoomerangProjectile::trailParticles->setColor(0.5, .8,.8,.8,.8);
+    BoomerangProjectile::trailParticles->setColor(1.0, .8,.8,.8,.0);
+  }
+  if (unlikely(BoomerangProjectile::explosionParticles == NULL))
+  {
+    BoomerangProjectile::explosionParticles = new SpriteParticles(200);
+    BoomerangProjectile::explosionParticles->setName("BoomerangProjectileExplosionParticles");
+    BoomerangProjectile::explosionParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    BoomerangProjectile::explosionParticles->setLifeSpan(.5, .3);
+    BoomerangProjectile::explosionParticles->setRadius(0.0, 10);
+    BoomerangProjectile::explosionParticles->setRadius(.5, 15.0);
+    BoomerangProjectile::explosionParticles->setRadius(1.0, 10.0);
+    BoomerangProjectile::explosionParticles->setColor(0.0, 0,1,0,1);
+    BoomerangProjectile::explosionParticles->setColor(0.5, .8,.8,0,.8);
+    BoomerangProjectile::explosionParticles->setColor(0.8, .8,.8,.3,.8);
+    BoomerangProjectile::explosionParticles->setColor(1.0, 1,1,1,.0);
+  }
+
+  this->emitter->setSystem(BoomerangProjectile::trailParticles);
+
+  this->updateNode(0);
+  this->emitter->setEmissionRate(45.0);
+  this->emitter->setEmissionVelocity(0.0);
+
+  this->setHealth(10.0* (float)rand()/(float)RAND_MAX);
+}
+
+
+void BoomerangProjectile::deactivate()
+{
+  this->emitter->setSystem(NULL);
+  this->lifeCycle = 0.0;
+
+  this->toList(OM_DEAD);
+  this->removeNode();
+  BoomerangProjectile::fastFactory->kill(this);
+}
+
+
+void BoomerangProjectile::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (this->hitEntity != entity)
+    this->destroy( entity );
+  this->hitEntity = entity;
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param time since last tick
+*/
+void BoomerangProjectile::tick (float time)
+{
+
+  Vector targetFarFarAway = this->getAbsCoor() + Vector(100000, 0, 0);
+
+  {
+    speed = velocity.len();
+    diffVector = ((targetFarFarAway - this->getAbsCoor()).getNormalized());
+
+    if(velocity.dot(diffVector) != 0)
+    {
+      correctionVector = (( ( diffVector *  (speed * speed/( velocity.dot(diffVector ) ) )) - velocity).getNormalized()) * agility;
+
+      if( (diffVector *  (speed * speed/( velocity.dot(diffVector ) ) ) -velocity).len() < agility )
+        velocity = ((diffVector *  (speed * speed/( velocity.dot(diffVector ) ) )).getNormalized())*agility;
+      else if(velocity.dot(diffVector) > 0)
+        velocity += correctionVector;
+      else if (velocity.dot(diffVector) < 0)
+        velocity -= correctionVector;
+    }
+    else
+      velocity += diffVector * agility;
+
+    this->setAbsDir(Quaternion(velocity, Vector(0,1,0)) * Quaternion ( -M_PI_2, Vector(0,1,0)));
+  }
+
+  velocity *= maxVelocity/velocity.len();
+  Vector v = this->velocity * (time);
+  this->shiftCoor(v);
+
+  if(this->tickLifeCycle(time))
+    this->deactivate();
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+ */
+void BoomerangProjectile::destroy (WorldEntity* killer)
+{
+
+  printf("THIS SHOULD WORLk\n");
+
+  Projectile::destroy( killer );
+  PRINTF(5)("DESTROY BoomerangProjectile\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+  this->emitter->setSystem(BoomerangProjectile::explosionParticles);
+
+  this->emitter->setEmissionRate(1000.0);
+  this->emitter->setEmissionVelocity(50.0);
+  //  this->deactivate();
+
+}
+
+
+void BoomerangProjectile::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  glScalef(2.0, 2.0, 2.0);
+  this->getModel()->draw();
+
+  glPopMatrix();
+
+}
+
Index: branches/heathaze/src/world_entities/projectiles/boomerang_projectile.h
===================================================================
--- branches/heathaze/src/world_entities/projectiles/boomerang_projectile.h	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/boomerang_projectile.h	(revision 9940)
@@ -0,0 +1,51 @@
+/*!
+ * @file boomerang_projectile.h
+ * @brief a BoomerangProjectile Projectile
+*/
+
+#ifndef _BOOMERANG_PROJECTILE_H
+#define _BOOMERANG_PROJECTILE_H
+
+#include "projectile.h"
+
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+class Aim;
+
+class BoomerangProjectile : public Projectile
+{
+  ObjectListDeclaration(BoomerangProjectile);
+  public:
+    BoomerangProjectile ();
+    virtual ~BoomerangProjectile ();
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float time);
+    virtual void draw () const;
+
+
+  private:
+    static FastFactory*               fastFactory;
+    static SpriteParticles*           trailParticles;
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+    float                             agility;
+    float                             maxVelocity;
+    float                             speed;
+    Vector                            diffVector ;
+    Vector                            correctionVector;
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+
+};
+
+#endif /* _BOOMERANG_PROJECTILE_H */
Index: branches/heathaze/src/world_entities/projectiles/guided_missile.cc
===================================================================
--- branches/heathaze/src/world_entities/projectiles/guided_missile.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/guided_missile.cc	(revision 9940)
@@ -0,0 +1,215 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Silvan Nellen
+   co-programmer:
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "guided_missile.h"
+
+#include "state.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(GuidedMissile, CL_GUIDED_MISSILE);
+CREATE_FAST_FACTORY_STATIC(GuidedMissile);
+
+/**
+ *  standard constructor
+*/
+GuidedMissile::GuidedMissile () : Projectile()
+{
+  this->registerObject(this, GuidedMissile::_objectList);
+
+  this->loadModel("models/projectiles/orx-rocket.obj", 2.0);
+  this->loadExplosionSound("sound/explosions/explosion_4.wav");
+
+
+  this->setMinEnergy(1);
+  this->setHealthMax(10);
+  this->lifeSpan = 4.0;
+  this->agility = 3.5;
+  this->maxVelocity = 100;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+GuidedMissile::~GuidedMissile ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (GuidedMissile::trailParticles != NULL && GuidedMissile::objectList().size() <= 1)
+  {
+    if (ParticleSystem::objectList().exists(GuidedMissile::trailParticles))
+      delete GuidedMissile::trailParticles;
+    GuidedMissile::trailParticles = NULL;
+  }
+  if (GuidedMissile::explosionParticles != NULL && GuidedMissile::objectList().size() <= 1)
+  {
+    if (ParticleSystem::objectList().exists(GuidedMissile::explosionParticles))
+      delete GuidedMissile::explosionParticles;
+    GuidedMissile::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* GuidedMissile::trailParticles = NULL;
+SpriteParticles* GuidedMissile::explosionParticles = NULL;
+
+
+
+void GuidedMissile::activate()
+{
+  if (unlikely(GuidedMissile::trailParticles == NULL))
+  {
+    GuidedMissile::trailParticles = new SpriteParticles(2000);
+    GuidedMissile::trailParticles->setName("GuidedMissileTrailParticles");
+    GuidedMissile::trailParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    GuidedMissile::trailParticles->setLifeSpan(1.0, .3);
+    GuidedMissile::trailParticles->setRadius(0.0, .5);
+    GuidedMissile::trailParticles->setRadius(0.2, 4.0);
+    GuidedMissile::trailParticles->setRadius(.5, 1.5);
+    GuidedMissile::trailParticles->setRadius(1.0, 1.5);
+    GuidedMissile::trailParticles->setColor(0.0, 1,0,0,.7);
+    GuidedMissile::trailParticles->setColor(0.2, .8,.8,0,.5);
+    GuidedMissile::trailParticles->setColor(0.5, .8,.8,.8,.8);
+    GuidedMissile::trailParticles->setColor(1.0, .8,.8,.8,.0);
+  }
+  if (unlikely(GuidedMissile::explosionParticles == NULL))
+  {
+    GuidedMissile::explosionParticles = new SpriteParticles(200);
+    GuidedMissile::explosionParticles->setName("GuidedMissileExplosionParticles");
+    GuidedMissile::explosionParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    GuidedMissile::explosionParticles->setLifeSpan(.5, .3);
+    GuidedMissile::explosionParticles->setRadius(0.0, 10);
+    GuidedMissile::explosionParticles->setRadius(.5, 15.0);
+    GuidedMissile::explosionParticles->setRadius(1.0, 10.0);
+    GuidedMissile::explosionParticles->setColor(0.0, 0,1,0,1);
+    GuidedMissile::explosionParticles->setColor(0.5, .8,.8,0,.8);
+    GuidedMissile::explosionParticles->setColor(0.8, .8,.8,.3,.8);
+    GuidedMissile::explosionParticles->setColor(1.0, 1,1,1,.0);
+  }
+
+  this->emitter->setSystem(GuidedMissile::trailParticles);
+
+  this->updateNode(0);
+  this->emitter->setEmissionRate(45.0);
+  this->emitter->setEmissionVelocity(0.0);
+
+  this->setHealth(10.0* (float)rand()/(float)RAND_MAX);
+}
+
+
+void GuidedMissile::deactivate()
+{
+  this->emitter->setSystem(NULL);
+  this->lifeCycle = 0.0;
+
+  this->toList(OM_DEAD);
+  this->removeNode();
+  GuidedMissile::fastFactory->kill(this);
+}
+
+
+void GuidedMissile::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (this->hitEntity != entity)
+    this->destroy( entity );
+  this->hitEntity = entity;
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param time since last tick
+*/
+void GuidedMissile::tick (float time)
+{
+
+
+if (this->target != NULL && this->target->getParent() != PNode::getNullParent())
+   {
+    speed = velocity.len();
+    diffVector = ((target->getAbsCoor() - this->getAbsCoor()).getNormalized());
+
+    if(velocity.dot(diffVector) != 0)
+     {
+     correctionVector = (( ( diffVector *  (speed * speed/( velocity.dot(diffVector ) ) )) - velocity).getNormalized()) * agility;
+
+      if( (diffVector *  (speed * speed/( velocity.dot(diffVector ) ) ) -velocity).len() < agility )
+       velocity = ((diffVector *  (speed * speed/( velocity.dot(diffVector ) ) )).getNormalized())*agility;
+      else if(velocity.dot(diffVector) > 0)
+        velocity += correctionVector;
+      else if (velocity.dot(diffVector) < 0)
+        velocity -= correctionVector;
+     }
+    else
+      velocity += diffVector * agility;
+
+     this->setAbsDir(Quaternion(velocity, Vector(0,1,0)) * Quaternion ( -M_PI_2, Vector(0,1,0)));
+   }
+
+  velocity *= maxVelocity/velocity.len();
+  Vector v = this->velocity * (time);
+  this->shiftCoor(v);
+
+  if(this->tickLifeCycle(time))
+    this->deactivate();
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+ */
+void GuidedMissile::destroy (WorldEntity* killer)
+{
+
+  printf("THIS SHOULD WORLk\n");
+
+  Projectile::destroy( killer );
+  PRINTF(5)("DESTROY GuidedMissile\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+  this->emitter->setSystem(GuidedMissile::explosionParticles);
+
+  this->emitter->setEmissionRate(1000.0);
+  this->emitter->setEmissionVelocity(50.0);
+//  this->deactivate();
+
+}
+
+
+void GuidedMissile::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  glScalef(2.0, 2.0, 2.0);
+  this->getModel()->draw();
+
+  glPopMatrix();
+
+}
+
Index: branches/heathaze/src/world_entities/projectiles/guided_missile.h
===================================================================
--- branches/heathaze/src/world_entities/projectiles/guided_missile.h	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/guided_missile.h	(revision 9940)
@@ -0,0 +1,50 @@
+/*!
+ * @file guided_missile.h
+ * @brief a GuidedMissile Projectile
+*/
+
+#ifndef _GUIDED_MISSILE_H
+#define _GUIDED_MISSILE_H
+
+#include "projectile.h"
+
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class GuidedMissile : public Projectile
+{
+  ObjectListDeclaration(GuidedMissile);
+  public:
+    GuidedMissile ();
+    virtual ~GuidedMissile ();
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float time);
+    virtual void draw () const;
+
+
+  private:
+    static FastFactory*               fastFactory;
+    static SpriteParticles*           trailParticles;
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+    float                             agility;
+    float                             maxVelocity;
+    float                             speed;
+    Vector                            diffVector ;
+    Vector                            correctionVector;
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+
+};
+
+#endif /* _GUIDED_MISSILE_H */
Index: branches/heathaze/src/world_entities/projectiles/hyperblast.cc
===================================================================
--- branches/heathaze/src/world_entities/projectiles/hyperblast.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/hyperblast.cc	(revision 9940)
@@ -0,0 +1,159 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "hyperblast.h"
+
+#include "state.h"
+
+#include "particles/box_emitter.h"
+#include "particles/spark_particles.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Hyperblast, CL_HYPERBLAST);
+CREATE_FAST_FACTORY_STATIC(Hyperblast);
+
+
+/**
+ *  standard constructor
+*/
+Hyperblast::Hyperblast () : Projectile()
+{
+  this->registerObject(this, Hyperblast::_objectList);
+
+  this->loadModel("models/projectiles/hyperblast.obj", 5);
+
+  this->setMinEnergy(50);
+  this->setHealthMax(1000);
+  this->lifeSpan = 1;
+  this->size = 4.0;
+
+  this->emitter = new BoxEmitter(Vector(400, 2, 2), 100, 5, M_2_PI);
+  this->emitter->setRelCoor(200,0,0);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+Hyperblast::~Hyperblast ()
+{
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (Hyperblast::explosionParticles != NULL && Hyperblast::objectList().size() <= 1)
+  {
+    Hyperblast::explosionParticles = NULL;
+  }
+
+}
+
+SparkParticles* Hyperblast::explosionParticles = NULL;
+
+void Hyperblast::activate()
+{
+  if (unlikely(Hyperblast::explosionParticles == NULL))
+  {
+    Hyperblast::explosionParticles = new SparkParticles(2000);
+    Hyperblast::explosionParticles->setName("HyperblastExplosionParticles");
+    Hyperblast::explosionParticles->setLifeSpan(2, .3);
+    Hyperblast::explosionParticles->setRadius(0.1, .1);
+    Hyperblast::explosionParticles->setRadius(0.2, .2);
+    Hyperblast::explosionParticles->setRadius(1.0, .1);
+    Hyperblast::explosionParticles->setColor(0.0, 1.0, .6, 0 ,1);
+    Hyperblast::explosionParticles->setColor(0.5, .8,.1,0,.6);
+    Hyperblast::explosionParticles->setColor(0.8, .8,.2,.3,.3);
+    Hyperblast::explosionParticles->setColor(1.0, 1,1,1,.0);
+  }
+
+  this->emitter->setSystem(Hyperblast::explosionParticles);
+  this->size = 4.0;
+
+  Hyperblast::explosionParticles->debug();
+  this->updateNode(0);
+  this->emitter->setEmissionRate(5000.0);
+  this->emitter->setEmissionVelocity(50.0);
+
+  this->setHealth(200);
+}
+
+
+void Hyperblast::deactivate()
+{
+  this->emitter->setSystem(NULL);
+  this->lifeCycle = 0.0;
+  this->toList(OM_NULL);
+
+//  GarbageCollector::getInstance()->collect(this);
+  this->toList(OM_DEAD);
+  Hyperblast::fastFactory->kill(this);
+}
+
+
+void Hyperblast::collidesWith(WorldEntity* entity, const Vector& location)
+{
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param time since last tick
+*/
+void Hyperblast::tick (float dt)
+{
+  if(this->tickLifeCycle(dt))
+    this->deactivate();
+
+  this->size *=(1 - (5.0*dt));
+
+  if (this->lifeCycle > .1 && this->emitter->getEmissionRate() > 10.0)
+    this->emitter->setEmissionRate(0.0);
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void Hyperblast::destroy (WorldEntity* killer)
+{
+  Projectile::destroy( killer );
+
+  PRINTF(5)("DESTROY Hyperblast\n");
+
+
+}
+
+
+void Hyperblast::draw () const
+{
+  if (this->lifeCycle < .1)
+  {
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+//  glScalef(2.0, this->size, this->size);
+  this->getModel()->draw();
+
+  glPopMatrix();
+  }
+}
+
Index: branches/heathaze/src/world_entities/projectiles/hyperblast.h
===================================================================
--- branches/heathaze/src/world_entities/projectiles/hyperblast.h	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/hyperblast.h	(revision 9940)
@@ -0,0 +1,46 @@
+/*!
+ * @file hyperblast.h
+ * @brief a Hyperblast Projectile
+*/
+
+#ifndef _HYPERBLAST_H
+#define _HYPERBLAST_H
+
+#include "projectile.h"
+
+class Vector;
+class Weapon;
+class SparkParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class Hyperblast : public Projectile
+{
+  ObjectListDeclaration(Hyperblast);
+  public:
+    Hyperblast ();
+    virtual ~Hyperblast ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float time);
+    virtual void draw () const;
+
+
+  private:
+    static FastFactory*               fastFactory;
+    static SparkParticles*            explosionParticles;
+
+    ParticleEmitter*                  emitter;
+    float                             size;
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+};
+
+#endif /* _HYPERBLAST_H */
Index: branches/heathaze/src/world_entities/projectiles/laser.cc
===================================================================
--- branches/heathaze/src/world_entities/projectiles/laser.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/laser.cc	(revision 9940)
@@ -0,0 +1,160 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "laser.h"
+
+#include "state.h"
+#include "model.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include <cassert>
+#include "debug.h"
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinition(Laser);
+CREATE_FAST_FACTORY_STATIC(Laser);
+
+/**
+ *  standard constructor
+*/
+Laser::Laser () : Projectile()
+{
+  this->registerObject(this, Laser::_objectList);
+
+  this->loadModel("models/projectiles/laser.obj");
+
+  this->setMinEnergy(10);
+  this->setHealthMax(0);
+  this->lifeSpan = 5.0;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+  this->emitter->setEmissionRate(300.0);
+  this->emitter->setEmissionVelocity(50.0);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+Laser::~Laser ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (Laser::explosionParticles != NULL && Laser::objectList().size() <= 1)
+  {
+    //if (ClassList::exists(Laser::explosionParticles, CL_PARTICLE_SYSTEM))
+    //  delete Laser::explosionParticles;
+    PRINTF(1)("Deleting Laser Particles\n");
+    Laser::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* Laser::explosionParticles = NULL;
+
+void Laser::activate()
+{
+  if (unlikely(Laser::explosionParticles == NULL))
+  {
+    Laser::explosionParticles = new SpriteParticles(1000);
+    Laser::explosionParticles->setName("LaserExplosionParticles");
+    Laser::explosionParticles->setLifeSpan(.5, .3);
+    Laser::explosionParticles->setRadius(0.0, 10.0);
+    Laser::explosionParticles->setRadius(.5, 6.0);
+    Laser::explosionParticles->setRadius(1.0, 3.0);
+    Laser::explosionParticles->setColor(0.0, 1,1,0,.9);
+    Laser::explosionParticles->setColor(0.5, .8,.8,0,.5);
+    Laser::explosionParticles->setColor(1.0, .8,.8,.7,.0);
+  }
+
+  this->setDamage(20);
+  this->setHealth(0);
+}
+
+
+void Laser::deactivate()
+{
+  assert (Laser::explosionParticles != NULL);
+  Laser::explosionParticles->removeEmitter(this->emitter);
+  this->lifeCycle = 0.0;
+
+  this->toList(OM_NULL);
+  this->removeNode();
+  Laser::fastFactory->kill(this);
+}
+
+
+void Laser::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (this->hitEntity != entity && entity->isA(CL_NPC))
+    this->destroy( entity );
+  this->hitEntity = entity;
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param dt time since last tick
+*/
+void Laser::tick (float dt)
+{
+  //Vector v = *this->flightDirection * ( this->speed * time * 1000 + 0.1);
+  Vector v = this->velocity * dt;
+  this->shiftCoor(v);
+
+  if (this->tickLifeCycle(dt))
+    this->deactivate();
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void Laser::destroy (WorldEntity* killer)
+{
+  Projectile::destroy( killer );
+  PRINTF(5)("DESTROY Laser\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+
+  this->emitter->setSystem(Laser::explosionParticles);
+}
+
+
+void Laser::draw () const
+{
+  glPushAttrib(GL_ENABLE_BIT);
+  glDisable(GL_LIGHTING);
+
+  WorldEntity::draw();
+/*  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  glScalef(2.0, 2.0, 2.0);
+  this->getModel()->draw();
+  glPopMatrix();*/
+
+  glPopAttrib();
+}
+
Index: branches/heathaze/src/world_entities/projectiles/laser.h
===================================================================
--- branches/heathaze/src/world_entities/projectiles/laser.h	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/laser.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file laser.h
+ * @brief a projectile, that is been shooted by a weapon
+*/
+
+#ifndef _LASER_H
+#define _LASER_H
+
+#include "projectile.h"
+
+class Vector;
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class Laser : public Projectile
+{
+  ObjectListDeclaration(Laser);
+  public:
+    Laser ();
+    virtual ~Laser ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float dt);
+    virtual void draw () const;
+
+
+  private:
+    static FastFactory*               fastFactory;
+
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+};
+
+#endif /* _LASER_H */
Index: branches/heathaze/src/world_entities/projectiles/projectile.cc
===================================================================
--- branches/heathaze/src/world_entities/projectiles/projectile.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/projectile.cc	(revision 9940)
@@ -0,0 +1,146 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "projectile.h"
+
+#include "world_entity.h"
+#include "world_entities/weapons/weapon.h"
+#include "model.h"
+#include "sound/resource_sound_buffer.h"
+
+#include "debug.h"
+
+ObjectListDefinition(Projectile);
+
+/**
+ *  standard constructor
+*/
+Projectile::Projectile () : WorldEntity()
+{
+  this->registerObject(this, Projectile::_objectList);
+
+  this->lifeCycle = 0.0;
+  this->lifeSpan = 1.0f; /* sec */
+  this->target = NULL;
+  this->removeNode();
+
+  /* character attributes */
+  this->setHealth(1.0f);
+  this->setDamage(1.0f); // default damage of a projectile set to 100.0 damage points
+
+  //this->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+Projectile::~Projectile ()
+{
+  /*
+     do not delete the test projectModel, since it is pnode
+     and will be cleaned out by world
+  */
+  //delete this->projectileModel;
+}
+
+
+void Projectile::loadExplosionSound(const std::string& explosionSound)
+{
+  if (!explosionSound.empty())
+    this->explosionBuffer = OrxSound::ResourceSoundBuffer(explosionSound);
+  else
+    this->explosionBuffer = OrxSound::SoundBuffer();
+}
+
+
+void Projectile::loadEngineSound(const std::string& engineSound)
+{
+  if (!engineSound.empty())
+    this->engineBuffer = OrxSound::ResourceSoundBuffer(engineSound);
+  else
+    this->engineBuffer = OrxSound::SoundBuffer();
+}
+
+
+void Projectile::setMinEnergy(float energyMin)
+{
+  this->energyMin = energyMin;
+}
+
+
+/**
+ *  this sets the flight direction of the projectile
+ * @param directin in which to flight
+
+   this function will calculate a vector out of this to be used in the
+   tick function
+*/
+void Projectile::setFlightDirection(const Quaternion& flightDirection)
+{
+  Vector v(1, 0, 0);
+  this->flightDirection = flightDirection.apply(v);
+  this->flightDirection.normalize();
+}
+
+/**
+ *  sets the velocity vector to a spec speed
+ * @param velocity: vector of the velocity
+*/
+void Projectile::setVelocity(const Vector &velocity)
+{
+  //Vector offsetVel =
+  this->velocity = velocity;
+  // offsetVel.normalize();
+  //this->velocity += (offsetVel * 50.0);
+}
+
+
+
+void Projectile::setTarget(PNode* target)
+{
+  if (this->target == NULL)
+    this->target = new PNode(target, PNODE_REPARENT_ON_PARENTS_REMOVE | PNODE_REPARENT_TO_NULL | PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  else
+    this->target->setParent(target);
+}
+
+
+/**
+ * signal tick, time dependent things will be handled here
+ * @param dt since last tick
+*/
+void Projectile::tick (float dt)
+{
+  Vector v = this->velocity * (dt);
+  this->shiftCoor(v);
+
+  if (this->tickLifeCycle(dt))
+    this->destroy( NULL );
+}
+
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void Projectile::destroy (WorldEntity* killer)
+{
+  if (this->explosionBuffer.loaded())
+    this->soundSource.play(this->explosionBuffer);
+}
+
Index: branches/heathaze/src/world_entities/projectiles/projectile.h
===================================================================
--- branches/heathaze/src/world_entities/projectiles/projectile.h	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/projectile.h	(revision 9940)
@@ -0,0 +1,73 @@
+/*!
+ * @file projectile.h
+ * a projectile, that is been shooted by a weapon
+ *
+ * You can use this class to make some Projectiles/Bullets/Lasers/Rockets/etc.
+ *
+ */
+
+#ifndef _PROJECTILE_H
+#define _PROJECTILE_H
+
+#include "world_entity.h"
+#include "loading/fast_factory.h"
+
+#include "sound_source.h"
+#include "sound_buffer.h"
+
+class Projectile : public WorldEntity
+{
+  ObjectListDeclaration(Projectile);
+  public:
+    Projectile ();
+    virtual ~Projectile ();
+
+    void setFlightDirection(const Quaternion& flightDirection);
+    void setVelocity(const Vector &velocity);
+    void setLifeSpan(float lifeSpan);
+
+    void loadExplosionSound(const std::string& explosionSound);
+    void loadEngineSound(const std::string& engineSound);
+    void setMinEnergy(float energyMin);
+    /** @returns the minimal charched energy */
+    inline float getMinEnergy() { return this->energyMin; };
+    /** @returns if the Projectile can be charged */
+    inline bool isChageable() { return this->bChargeable; };
+
+    void setTarget(PNode* target);
+
+    /** @brief This is called, when the Projectile is Emitted */
+    virtual void activate() = 0;
+    /** @brief This is called, when the Projectile is being destroyed, or deleted */
+    virtual void deactivate() = 0;
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float dt);
+    /** @brief convenience function
+     * @param dt the Time passed
+     * @returns true if the Projectile is past its lifeTime, false if it shall still live */
+    inline bool tickLifeCycle(float dt ) { this->lifeCycle += dt/this->lifeSpan;  return(unlikely(this->lifeCycle >= 1)); }
+
+
+  protected:
+    // energy
+    float                  energyMin;                 //!< The minimal Energy a Projectile needs to be emitted.
+    bool                   bChargeable;               //!< if the Projectile is Charegeable
+
+    float                  lifeCycle;                 //!< The percentage of the Lifetime done [0-1]
+    float                  lifeSpan;                  //!< The entire lifespan of the Shoot. in seconds
+
+    Vector                 flightDirection;           //!< DOF direction in which the shoot flighs
+
+    Vector                 velocity;                  //!< velocity of the projectile.
+
+    PNode*                 target;                    //!< A target for guided Weapons.
+
+    OrxSound::SoundSource  soundSource;
+  private:
+    OrxSound::SoundBuffer  explosionBuffer;
+    OrxSound::SoundBuffer  engineBuffer;
+};
+
+#endif /* _PROJECTILE_H */
Index: branches/heathaze/src/world_entities/projectiles/rail_projectile.cc
===================================================================
--- branches/heathaze/src/world_entities/projectiles/rail_projectile.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/rail_projectile.cc	(revision 9940)
@@ -0,0 +1,159 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "rail_projectile.h"
+
+#include "state.h"
+#include "model.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include <cassert>
+#include "debug.h"
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(RailProjectile, CL_RAIL_PROJECTILE);
+CREATE_FAST_FACTORY_STATIC(RailProjectile);
+
+/**
+ *  standard constructor
+*/
+RailProjectile::RailProjectile () : Projectile()
+{
+  this->registerObject(this, RailProjectile::_objectList);
+
+  this->loadModel("models/projectiles/laser.obj", 1);
+
+  this->setMinEnergy(10);
+  this->setHealthMax(10);
+  this->lifeSpan = .5f;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+  this->emitter->setEmissionRate(300.0);
+  this->emitter->setEmissionVelocity(50.0);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+RailProjectile::~RailProjectile ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (RailProjectile::explosionParticles != NULL && RailProjectile::objectList().size() <= 1)
+  {
+    //if (ClassList::exists(RailProjectile::explosionParticles, CL_PARTICLE_SYSTEM))
+    //  delete RailProjectile::explosionParticles;
+    PRINTF(1)("Deleting RailProjectile Particles\n");
+    RailProjectile::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* RailProjectile::explosionParticles = NULL;
+
+void RailProjectile::activate()
+{
+  if (unlikely(RailProjectile::explosionParticles == NULL))
+  {
+    RailProjectile::explosionParticles = new SpriteParticles(1000);
+    RailProjectile::explosionParticles->setName("RailProjectileExplosionParticles");
+    RailProjectile::explosionParticles->setLifeSpan(.5, .3);
+    RailProjectile::explosionParticles->setRadius(0.0, 10.0);
+    RailProjectile::explosionParticles->setRadius(.5, 6.0);
+    RailProjectile::explosionParticles->setRadius(1.0, 3.0);
+    RailProjectile::explosionParticles->setColor(0.0, 1,1,0,.9);
+    RailProjectile::explosionParticles->setColor(0.5, .8,.8,0,.5);
+    RailProjectile::explosionParticles->setColor(1.0, .8,.8,.7,.0);
+  }
+
+  this->setHealth(10);
+}
+
+
+void RailProjectile::deactivate()
+{
+  assert (RailProjectile::explosionParticles != NULL);
+  RailProjectile::explosionParticles->removeEmitter(this->emitter);
+  this->lifeCycle = 0.0;
+
+  this->toList(OM_NULL);
+  this->removeNode();
+  RailProjectile::fastFactory->kill(this);
+}
+
+
+void RailProjectile::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (this->hitEntity != entity && entity->isA(CL_NPC))
+    this->destroy( entity );
+  this->hitEntity = entity;
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param dt time since last tick
+*/
+void RailProjectile::tick (float dt)
+{
+  //Vector v = *this->flightDirection * ( this->speed * time * 1000 + 0.1);
+  Vector v = this->velocity * dt;
+  this->shiftCoor(v);
+
+  if (this->tickLifeCycle(dt))
+    this->deactivate();
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void RailProjectile::destroy (WorldEntity* killer)
+{
+  Projectile::destroy( killer );
+  PRINTF(5)("DESTROY RailProjectile\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+
+  this->emitter->setSystem(RailProjectile::explosionParticles);
+}
+
+
+void RailProjectile::draw () const
+{
+  glPushAttrib(GL_ENABLE_BIT);
+  glDisable(GL_LIGHTING);
+
+  WorldEntity::draw();
+/*  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  glScalef(2.0, 2.0, 2.0);
+  this->getModel()->draw();
+  glPopMatrix();*/
+
+  glPopAttrib();
+}
+
Index: branches/heathaze/src/world_entities/projectiles/rail_projectile.h
===================================================================
--- branches/heathaze/src/world_entities/projectiles/rail_projectile.h	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/rail_projectile.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file rail_projectile.h
+ * @brief a projectile, that is been shooted by a weapon
+*/
+
+#ifndef _RAIL_PROJECTILE_H
+#define _RAIL_PROJECTILE_H
+
+#include "projectile.h"
+
+class Vector;
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class RailProjectile : public Projectile
+{
+  ObjectListDeclaration(RailProjectile);
+  public:
+    RailProjectile ();
+    virtual ~RailProjectile ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float dt);
+    virtual void draw () const;
+
+
+  private:
+    static FastFactory*               fastFactory;
+
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+};
+
+#endif /* _RAIL_PROJECTILE_H */
Index: branches/heathaze/src/world_entities/projectiles/rocket.cc
===================================================================
--- branches/heathaze/src/world_entities/projectiles/rocket.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/rocket.cc	(revision 9940)
@@ -0,0 +1,181 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "rocket.h"
+
+#include "state.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Rocket, CL_ROCKET);
+CREATE_FAST_FACTORY_STATIC(Rocket);
+
+/**
+ *  standard constructor
+*/
+Rocket::Rocket () : Projectile()
+{
+  this->registerObject(this, Rocket::_objectList);
+
+  this->loadModel("models/projectiles/orx-rocket.obj", .3);
+
+  this->setMinEnergy(1);
+  this->setHealthMax(10);
+  this->lifeSpan = 5;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+Rocket::~Rocket ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (Rocket::trailParticles != NULL && Rocket::objectList().size() <= 1)
+  {
+/*    if (ClassList::exists(Rocket::trailParticles, CL_PARTICLE_SYSTEM))
+      delete Rocket::trailParticles;*/
+    Rocket::trailParticles = NULL;
+  }
+  if (Rocket::explosionParticles != NULL && Rocket::objectList().size() <= 1)
+  {
+/*    if (ClassList::exists(Rocket::explosionParticles, CL_PARTICLE_SYSTEM))
+      delete Rocket::explosionParticles;*/
+    Rocket::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* Rocket::trailParticles = NULL;
+SpriteParticles* Rocket::explosionParticles = NULL;
+
+void Rocket::activate()
+{
+  if (unlikely(Rocket::trailParticles == NULL))
+  {
+    Rocket::trailParticles = new SpriteParticles(2000);
+    Rocket::trailParticles->setName("RocketTrailParticles");
+    Rocket::trailParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    Rocket::trailParticles->setLifeSpan(1.0, .3);
+    Rocket::trailParticles->setRadius(0.0, .5);
+    Rocket::trailParticles->setRadius(0.2, 2.0);
+    Rocket::trailParticles->setRadius(.5, .8);
+    Rocket::trailParticles->setRadius(1.0, .8);
+    Rocket::trailParticles->setColor(0.0, 1,0,0,.7);
+    Rocket::trailParticles->setColor(0.2, .8,.8,0,.5);
+    Rocket::trailParticles->setColor(0.5, .8,.8,.8,.8);
+    Rocket::trailParticles->setColor(1.0, .8,.8,.8,.0);
+  }
+  if (unlikely(Rocket::explosionParticles == NULL))
+  {
+    Rocket::explosionParticles = new SpriteParticles(200);
+    Rocket::explosionParticles->setName("RocketExplosionParticles");
+    Rocket::explosionParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    Rocket::explosionParticles->setLifeSpan(.5, .3);
+    Rocket::explosionParticles->setRadius(0.0, 10);
+    Rocket::explosionParticles->setRadius(.5, 15.0);
+    Rocket::explosionParticles->setRadius(1.0, 10.0);
+    Rocket::explosionParticles->setColor(0.0, 0,1,0,1);
+    Rocket::explosionParticles->setColor(0.5, .8,.8,0,.8);
+    Rocket::explosionParticles->setColor(0.8, .8,.8,.3,.8);
+    Rocket::explosionParticles->setColor(1.0, 1,1,1,.0);
+  }
+
+  this->emitter->setSystem(Rocket::trailParticles);
+
+  this->updateNode(0);
+  this->emitter->setEmissionRate(45.0);
+  this->emitter->setEmissionVelocity(0.0);
+}
+
+
+void Rocket::deactivate()
+{
+  this->emitter->setSystem(NULL);
+  this->lifeCycle = 0.0;
+  this->toList(OM_NULL);
+
+//  GarbageCollector::getInstance()->collect(this);
+  this->toList(OM_DEAD);
+  Rocket::fastFactory->kill(this);
+}
+
+
+void Rocket::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (this->hitEntity != entity)
+    this->destroy( entity );
+  this->hitEntity = entity;
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param time since last tick
+*/
+void Rocket::tick (float dt)
+{
+  //Vector v = *this->flightDirection * ( this->speed * time * 1000 + 0.1);
+  Vector v = this->velocity * (dt);
+  this->shiftCoor(v);
+
+  if(this->tickLifeCycle(dt))
+    this->deactivate();
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void Rocket::destroy (WorldEntity* killer)
+{
+  Projectile::destroy( killer );
+
+  PRINTF(5)("DESTROY Rocket\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+  this->emitter->setSystem(Rocket::explosionParticles);
+
+  this->emitter->setEmissionRate(1000.0);
+  this->emitter->setEmissionVelocity(50.0);
+//  this->deactivate();
+
+}
+
+
+void Rocket::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  glScalef(2.0, 2.0, 2.0);
+  this->getModel()->draw();
+
+  glPopMatrix();
+}
+
Index: branches/heathaze/src/world_entities/projectiles/rocket.h
===================================================================
--- branches/heathaze/src/world_entities/projectiles/rocket.h	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/rocket.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file rocket.h
+ * @brief a Rocket Projectile
+*/
+
+#ifndef _ROCKET_H
+#define _ROCKET_H
+
+#include "projectile.h"
+
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class Rocket : public Projectile
+{
+  ObjectListDeclaration(Rocket);
+
+public:
+  Rocket ();
+  virtual ~Rocket ();
+
+
+  virtual void activate();
+  virtual void deactivate();
+
+  virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+  virtual void destroy (WorldEntity* killer);
+
+  virtual void tick (float time);
+  virtual void draw () const;
+
+
+private:
+  static FastFactory*               fastFactory;
+  static SpriteParticles*           trailParticles;
+  static SpriteParticles*           explosionParticles;
+
+  ParticleEmitter*                  emitter;
+
+
+  WorldEntity* hitEntity; // FIXME TEMPORARY
+
+};
+
+#endif /* _ROCKET_H */
Index: branches/heathaze/src/world_entities/projectiles/test_bullet.cc
===================================================================
--- branches/heathaze/src/world_entities/projectiles/test_bullet.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/test_bullet.cc	(revision 9940)
@@ -0,0 +1,177 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "test_bullet.h"
+
+#include "state.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(TestBullet, CL_TEST_BULLET);
+CREATE_FAST_FACTORY_STATIC(TestBullet);
+
+/**
+ *  standard constructor
+*/
+TestBullet::TestBullet () : Projectile()
+{
+  this->registerObject(this, TestBullet::_objectList);
+
+  this->loadModel("models/projectiles/orx-rocket.obj", .3);
+
+  this->setMinEnergy(1);
+  this->setHealthMax(10);
+  this->lifeSpan = 2;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+TestBullet::~TestBullet ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (TestBullet::trailParticles != NULL && TestBullet::objectList().size() <= 1)
+  {
+    if (ParticleSystem::objectList().exists(TestBullet::trailParticles))
+      delete TestBullet::trailParticles;
+    TestBullet::trailParticles = NULL;
+  }
+  if (TestBullet::explosionParticles != NULL && TestBullet::objectList().size() <= 1)
+  {
+    if (ParticleSystem::objectList().exists(TestBullet::explosionParticles))
+      delete TestBullet::explosionParticles;
+    TestBullet::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* TestBullet::trailParticles = NULL;
+SpriteParticles* TestBullet::explosionParticles = NULL;
+
+void TestBullet::activate()
+{
+  if (unlikely(TestBullet::trailParticles == NULL))
+  {
+    TestBullet::trailParticles = new SpriteParticles(1000);
+    TestBullet::trailParticles->setName("TestBulletTrailParticles");
+    TestBullet::trailParticles->setLifeSpan(.5, .3);
+    TestBullet::trailParticles->setRadius(0.0, .5);
+    TestBullet::trailParticles->setRadius(0.5, 2.0);
+    TestBullet::trailParticles->setRadius(1.0, 5.0);
+    TestBullet::trailParticles->setColor(0.0, 1,0,0,.7);
+    TestBullet::trailParticles->setColor(0.5, .8,.8,0,.5);
+    TestBullet::trailParticles->setColor(1.0, .7,.7,.7,.0);
+  }
+  if (unlikely(TestBullet::explosionParticles == NULL))
+  {
+    TestBullet::explosionParticles = new SpriteParticles(1000);
+    TestBullet::explosionParticles->setName("TestBulletExplosionParticles");
+    TestBullet::explosionParticles->setLifeSpan(.5, .3);
+    TestBullet::explosionParticles->setRadius(0.0, 10);
+    TestBullet::explosionParticles->setRadius(.5, 20.0);
+    TestBullet::explosionParticles->setRadius(1.0, 3.0);
+    TestBullet::explosionParticles->setColor(0.0, 0,1,0,.9);
+    TestBullet::explosionParticles->setColor(0.5, .8,.8,0,.5);
+    TestBullet::explosionParticles->setColor(1.0, 1,1,1,.0);
+  }
+
+  this->emitter->setSystem(TestBullet::trailParticles);
+
+  this->emitter->setEmissionRate(20.0);
+  this->emitter->setEmissionVelocity(3.0);
+}
+
+
+void TestBullet::deactivate()
+{
+  this->emitter->setSystem(NULL);
+  this->lifeCycle = 0.0;
+  this->toList(OM_NULL);
+
+  TestBullet::fastFactory->kill(this);
+}
+
+
+void TestBullet::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (this->hitEntity != entity && entity->isA(CL_NPC))
+    this->destroy( entity );
+  this->hitEntity = entity;
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param time since last tick
+*/
+void TestBullet::tick (float time)
+{
+  //Vector v = *this->flightDirection * ( this->speed * time * 1000 + 0.1);
+  Vector v = this->velocity * (time);
+  this->shiftCoor(v);
+
+  this->lifeCycle += time/this->lifeSpan;
+  if( this->lifeCycle >= 1.0)
+    {
+      PRINTF(5)("FINALIZE==========================\n");
+      PRINTF(5)("current life cycle is: %f\n", this->lifeCycle);
+      PRINTF(5)("FINALIZE===========================\n");
+
+      this->deactivate();
+    }
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void TestBullet::destroy (WorldEntity* killer)
+{
+  PRINTF(5)("DESTROY TestBullet\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+  this->emitter->setSystem(TestBullet::explosionParticles);
+
+  this->emitter->setEmissionRate(30.0);
+  this->emitter->setEmissionVelocity(50.0);
+//  this->deactivate();
+
+}
+
+
+void TestBullet::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  glScalef(2.0, 2.0, 2.0);
+  this->getModel()->draw();
+
+  glPopMatrix();
+}
+
Index: branches/heathaze/src/world_entities/projectiles/test_bullet.h
===================================================================
--- branches/heathaze/src/world_entities/projectiles/test_bullet.h	(revision 9940)
+++ branches/heathaze/src/world_entities/projectiles/test_bullet.h	(revision 9940)
@@ -0,0 +1,48 @@
+/*!
+    \projectile.h
+  *  a projectile, that is been shooted by a weapon
+*/
+
+#ifndef _TEST_BULLET_H
+#define _TEST_BULLET_H
+
+#include "projectile.h"
+
+class Vector;
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class TestBullet : public Projectile
+{
+  ObjectListDeclaration(TestBullet);
+
+  public:
+    TestBullet ();
+    virtual ~TestBullet ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float time);
+    virtual void draw () const;
+
+  private:
+    static FastFactory*               fastFactory;
+    static SpriteParticles*           trailParticles;
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+
+};
+
+#endif /* _TEST_BULLET_H */
Index: branches/heathaze/src/world_entities/recorder.cc
===================================================================
--- branches/heathaze/src/world_entities/recorder.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/recorder.cc	(revision 9940)
@@ -0,0 +1,370 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: David Hasenfratz
+   co-programmer:
+*/
+
+#include "recorder.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "state.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Recorder, CL_RECORDER);
+CREATE_FACTORY(Recorder);
+
+
+Recorder::Recorder (const TiXmlElement* root)
+{
+  this->registerObject(this, Recorder::_objectList);
+
+  // initialize libavcodec, and register all codecs and formats
+  av_register_all();
+
+  // Default values
+  stream_duration = 10;
+  stream_frame_rate = 20;
+
+  this->loadParams(root);
+
+  this->toList(OM_COMMON);
+}
+
+
+Recorder::~Recorder ()
+{
+
+}
+
+
+void Recorder::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "duration", this, Recorder, setStreamDuration);
+
+  LoadParam(root, "fps", this, Recorder, setFPS);
+
+  LoadParam(root, "name", this, Recorder, initVideo);
+}
+
+
+void Recorder::setStreamDuration(float duration)
+{
+  this->stream_duration = duration;
+}
+
+
+void Recorder::setFPS(float fps)
+{
+  this->stream_frame_rate = fps;
+}
+
+
+void Recorder::initVideo(const std::string& filename)
+{
+  frame_count = 0;
+  time = 0;
+  stream_nb_frames = (int)(stream_duration * stream_frame_rate);
+
+  // auto detect the output format from the name, default is mpeg
+  output_format = guess_format(NULL, filename.c_str(), NULL);
+  if (!output_format)
+  {
+      PRINTF(0)("Could not deduce output format from file extension: using MPEG.\n");
+      output_format = guess_format("mpeg", NULL, NULL);
+  }
+  if (!output_format)
+    PRINTF(1)("Could not find suitable output format\n");
+
+  // allocate the output media context
+  format_context = av_alloc_format_context();
+  if (!format_context)
+    PRINTF(1)("Memory error\n");
+
+  format_context->oformat = output_format;
+  snprintf(format_context->filename, sizeof(format_context->filename), "%s", filename.c_str());
+
+  // add video stream using the default format codec and initialize the codec
+  if (output_format->video_codec != CODEC_ID_NONE)
+      this->addVideoStream();
+
+  // set the output parameters (must be done even if no parameters)
+  if (av_set_parameters(format_context, NULL) < 0)
+    PRINTF(1)("Invalid output format parameters\n");
+
+  // print some information
+  dump_format(format_context, 0, filename.c_str(), 1);
+
+  // now that all the parameters are set, we can open the
+  // video codec and allocate the necessary encode buffer
+  if(video_stream)
+    this->openVideo();
+
+  // open the output file, if needed
+  if(!(output_format->flags & AVFMT_NOFILE))
+  {
+    if(url_fopen(&format_context->pb, filename.c_str(), URL_WRONLY) < 0)
+      PRINTF(1)("Could not open %s\n", filename.c_str());
+  }
+
+  // write the stream header, if any
+  av_write_header(format_context);
+}
+
+void Recorder::closeVideo()
+{
+  avcodec_close(video_stream->codec);
+  av_free(picture->data[0]);
+  av_free(picture);
+  av_free(buffer);
+
+  // write the trailer, if any
+  av_write_trailer(format_context);
+
+  // free the streams
+  for(int i = 0; i < format_context->nb_streams; i++)
+    av_freep(&format_context->streams[i]);
+
+  // close the output file
+  if (!(output_format->flags & AVFMT_NOFILE))
+    url_fclose(&format_context->pb);
+
+  // free the stream
+  av_free(format_context);
+}
+
+
+void Recorder::openVideo()
+{
+  codec_context = video_stream->codec;
+
+  // find the video encoder
+  codec = avcodec_find_encoder(codec_context->codec_id);
+  if(!codec)
+    PRINTF(1)("codec not found\n");
+
+  // open the codec
+  if(avcodec_open(codec_context, codec) < 0)
+    PRINTF(1)("could not open codec\n");
+
+  buffer = NULL;
+  if(!(format_context->oformat->flags & AVFMT_RAWPICTURE))
+  {
+      // allocate output buffer
+      // XXX: API change will be done
+      buffer_size = 200000;
+      buffer = new uint8_t[buffer_size];
+  }
+
+  // allocate the encoded raw picture
+  this->allocPicture();
+  if(!picture)
+    PRINTF(0)("Could not allocate picture\n");
+}
+
+
+void Recorder::allocPicture()
+{
+  picture = avcodec_alloc_frame();
+  if(!picture)
+  {
+    picture = NULL;
+    return;
+  }
+  size = avpicture_get_size(codec_context->pix_fmt, width, height);
+  picture_buf = new uint8_t[size];
+  if(!picture_buf)
+  {
+      av_free(picture);
+      return;
+  }
+  avpicture_fill((AVPicture *)picture, picture_buf,
+                  codec_context->pix_fmt, width, height);
+
+
+
+  RGB_frame = avcodec_alloc_frame();
+
+  // Determine required buffer size and allocate buffer
+  size = avpicture_get_size(PIX_FMT_RGB24, width, height);
+  picture_buf = new uint8_t[size];
+
+  // Assign appropriate parts of buffer to image planes in RGB_frame
+  avpicture_fill((AVPicture *)RGB_frame, picture_buf, PIX_FMT_RGB24, width, height);
+}
+
+
+// add a video output stream
+void Recorder::addVideoStream()
+{
+  video_stream = av_new_stream(format_context, 0);
+  if (!video_stream)
+    PRINTF(1)("Could not alloc stream\n");
+
+  codec_context = video_stream->codec;
+  codec_context->codec_id = output_format->video_codec;
+  codec_context->codec_type = CODEC_TYPE_VIDEO;
+
+  // put sample parameters
+  codec_context->bit_rate = 400000;
+  // resolution must be a multiple of two
+  codec_context->width = State::getResX();
+  codec_context->height = State::getResY();
+
+  this->width = codec_context->width;
+  this->height = codec_context->height;
+
+  // time base: this is the fundamental unit of time (in seconds) in terms
+  // of which frame timestamps are represented. for fixed-fps content,
+  // timebase should be 1/framerate and timestamp increments should be
+  // identically 1
+  codec_context->time_base.den = (int)stream_frame_rate;
+  codec_context->time_base.num = 1;
+  codec_context->gop_size = 12;  // emit one intra frame every twelve frames at most
+  codec_context->pix_fmt = PIX_FMT_YUV420P;
+
+  if (codec_context->codec_id == CODEC_ID_MPEG1VIDEO)
+      // needed to avoid using macroblocks in which some coeffs overflow
+      // this doesnt happen with normal video, it just happens here as the
+      // motion of the chroma plane doesnt match the luma plane
+      codec_context->mb_decision=2;
+
+  // some formats want stream headers to be seperate
+  if(!strcmp(format_context->oformat->name, "mp4") ||
+     !strcmp(format_context->oformat->name, "mov") ||
+     !strcmp(format_context->oformat->name, "3gp"))
+    format_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
+}
+
+
+void Recorder::tick(float dt)
+{
+  time += dt;
+  if(time < 1/stream_frame_rate)
+    return;
+  else
+    time = 0;
+
+  // compute current video time
+  if (video_stream)
+      video_pts = (double)video_stream->pts.val * video_stream->time_base.num / video_stream->time_base.den;
+  else
+      video_pts = 0.0;
+
+  if (!video_stream || video_pts >= stream_duration)
+  {
+    this->toList(OM_DEAD);
+    this->closeVideo();
+  }
+  else
+    // write video frame
+    this->writeVideoFrame();
+}
+
+void Recorder::writeVideoFrame()
+{
+  int out_size, err;
+
+  codec_context = video_stream->codec;
+
+  if(frame_count >= stream_nb_frames)
+  {
+    /* no more frame to compress. The codec has a latency of a few
+        frames if using B frames, so we get the last frames by
+        passing the same picture again */
+  }
+  else
+    this->fillYuvImage();
+
+
+  if(format_context->oformat->flags & AVFMT_RAWPICTURE)
+  {
+    // raw video case. The API will change slightly in the near
+    // futur for that
+    av_init_packet(&packet);
+
+    packet.flags |= PKT_FLAG_KEY;
+    packet.stream_index= video_stream->index;
+    packet.data= (uint8_t *)picture;
+    packet.size= sizeof(AVPicture);
+
+    err = av_write_frame(format_context, &packet);
+  }
+  else
+  {
+    // encode the image
+    out_size = avcodec_encode_video(codec_context, buffer, buffer_size, picture);
+    // if zero size, it means the image was buffered
+    if (out_size > 0)
+    {
+      av_init_packet(&packet);
+
+      packet.pts= av_rescale_q(codec_context->coded_frame->pts, codec_context->time_base, video_stream->time_base);
+      if(codec_context->coded_frame->key_frame)
+        packet.flags |= PKT_FLAG_KEY;
+      packet.stream_index = video_stream->index;
+      packet.data= buffer;
+      packet.size= out_size;
+
+      // write the compressed frame in the media file
+      err = av_write_frame(format_context, &packet);
+    }
+    else
+      err = 0;
+  }
+
+  if(err != 0)
+    PRINTF(1)("Error while writing video frame\n");
+
+  frame_count++;
+}
+
+
+void Recorder::fillYuvImage()
+{
+  unsigned char *outputImage = 0;
+
+  // Allocate the neccessary memory.
+  outputImage = (unsigned char*)malloc(width * height * 3);
+
+  // Clear the variable.
+  memset(outputImage, 0, width * height * 3);
+
+  // You use the glReadPixels() to read every pixel on the screen
+  // that you specify.  You must use one less than each size.
+  glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, outputImage);
+
+  int i = 0;
+  for(int y=height-1;y>=0;y--)
+  {
+    for(int x=0;x<width*3;x++)
+    {
+      RGB_frame->data[0][y*width*3+x] = outputImage[i];
+      i++;
+    }
+  }
+
+
+  img_convert((AVPicture*)picture, PIX_FMT_YUV420P, (AVPicture*)RGB_frame,
+              PIX_FMT_RGB24, width, height);
+
+  // Clear the allocated memory.
+  free(outputImage);
+}
+
+
+void Recorder::draw() const
+{
+}
Index: branches/heathaze/src/world_entities/recorder.h
===================================================================
--- branches/heathaze/src/world_entities/recorder.h	(revision 9940)
+++ branches/heathaze/src/world_entities/recorder.h	(revision 9940)
@@ -0,0 +1,73 @@
+/*!
+ * @file recorder.h
+ *
+ */
+
+#ifndef _RECORDER_H
+#define _RECORDER_H
+
+#include "sdlincl.h"
+
+#ifdef HAVE_AVFORMAT_H
+  #include <avformat.h>
+#else
+  #include <ffmpeg/avformat.h>
+#endif
+
+#include "glincl.h"
+#include "world_entity.h"
+
+class Recorder : public WorldEntity
+{
+  ObjectListDeclaration(Recorder);
+  public:
+    Recorder (const TiXmlElement* root = NULL);
+    virtual ~Recorder ();
+
+    virtual void draw () const;
+    virtual void tick (float dt);
+
+    virtual void loadParams(const TiXmlElement* root);
+
+  private:
+    void initVideo(const std::string& filename);
+    void addVideoStream();
+    void openVideo();
+    void closeVideo();
+    void allocPicture();
+    void writeVideoFrame();
+    void fillYuvImage();
+
+    void setStreamDuration(float duration);
+    void setFPS(float fps);
+
+
+  private:
+    AVFrame*            picture;
+    uint8_t*            buffer;
+    int                 frame_count;
+    int                 buffer_size;
+
+    AVOutputFormat*     output_format;
+    AVFormatContext*    format_context;
+    AVCodecContext*     codec_context;
+    AVCodec*            codec;
+    AVStream*           video_stream;
+    AVPacket            packet;
+    double              video_pts;
+
+    uint8_t*            picture_buf;
+    int                 size;
+
+    int                 height;
+    int                 width;
+    float               time;
+
+    float               stream_duration;
+    float               stream_frame_rate;
+    int                 stream_nb_frames;
+
+    AVFrame*            RGB_frame;
+};
+
+#endif /* _RECORDER_H */
Index: branches/heathaze/src/world_entities/satellite.cc
===================================================================
--- branches/heathaze/src/world_entities/satellite.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/satellite.cc	(revision 9940)
@@ -0,0 +1,65 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "satellite.h"
+
+#include "objModel.h"
+
+
+
+
+ObjectListDefinition(Satellite);
+
+/**
+ *  standard constructor
+*/
+Satellite::Satellite (Vector axis, float speed)
+{
+  this->registerObject(this, Satellite::_objectList);
+
+  this->loadModel("cube");
+  this->speed = speed;
+  this->axis = new Vector();
+  *this->axis = axis;
+}
+
+/**
+ *  standard destructor
+*/
+Satellite::~Satellite ()
+{
+}
+
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+
+   Handle all stuff that should update with time inside this method (movement, animation, etc.)
+*/
+void Satellite::tick(float time)
+{
+  float w = this->speed * M_PI;
+
+  Quaternion rotation(w * time, *this->axis);
+  Quaternion v = this->getRelDir();
+
+  this->setRelDir(v * rotation);
+}
+
Index: branches/heathaze/src/world_entities/satellite.h
===================================================================
--- branches/heathaze/src/world_entities/satellite.h	(revision 9940)
+++ branches/heathaze/src/world_entities/satellite.h	(revision 9940)
@@ -0,0 +1,34 @@
+/*!
+ * @file world_entity.h
+  *  Definition of the basic WorldEntity
+*/
+
+#ifndef _SATELLITE_H
+#define _SATELLITE_H
+
+#include "world_entity.h"
+#include "comincl.h"
+
+class CharacterAttributes;
+class Model;
+
+
+//! Basic class from which all interactive stuff in the world is derived from
+class Satellite : public WorldEntity
+{
+  ObjectListDeclaration(Satellite);
+
+ public:
+  Satellite (Vector axis, float speed);
+  virtual ~Satellite ();
+
+  virtual void tick (float time);
+
+ private:
+  Vector*       axis;
+  float         speed;
+
+
+};
+
+#endif /* _SATELLITE_H */
Index: branches/heathaze/src/world_entities/script_trigger.cc
===================================================================
--- branches/heathaze/src/world_entities/script_trigger.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/script_trigger.cc	(revision 9940)
@@ -0,0 +1,285 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Silvan Nellen
+   co-programmer: ...
+*/
+
+
+#include "script_trigger.h"
+#include "script.h"
+
+#include "state.h"
+#include "debug.h"
+ObjectListDefinition(ScriptTrigger);
+
+CREATE_SCRIPTABLE_CLASS(ScriptTrigger,
+            // Coordinates
+			addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
+			    ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
+			    ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
+			    ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
+            //Properties
+			    ->addMethod("setName", Executor1<BaseObject, lua_State*, const std::string&>(&BaseObject::setName))
+			    ->addMethod("setTarget", Executor1<ScriptTrigger, lua_State*, const std::string&>(&ScriptTrigger::setTarget))
+			    ->addMethod("setTriggerParent", Executor1<ScriptTrigger, lua_State*, const std::string&>(&ScriptTrigger::setTriggerParent))
+			    ->addMethod("setTriggerRemains", Executor1<ScriptTrigger, lua_State*, bool>(&ScriptTrigger::setTriggerRemains))
+			    ->addMethod("setActiveOnCreation", Executor1<ScriptTrigger, lua_State*, bool>(&ScriptTrigger::setActiveOnCreation))
+			    ->addMethod("setInvert", Executor1<ScriptTrigger, lua_State*, bool>(&ScriptTrigger::setInvert))
+			    ->addMethod("setRadius", Executor1<ScriptTrigger, lua_State*, float>(&ScriptTrigger::setRadius))
+			    ->addMethod("setScript", Executor1<ScriptTrigger, lua_State*, const std::string&>(&ScriptTrigger::setScript))
+			    ->addMethod("setFunction", Executor1<ScriptTrigger, lua_State*, const std::string&>(&ScriptTrigger::setFunction))
+			    ->addMethod("setDebugDraw", Executor1<ScriptTrigger, lua_State*, bool>(&ScriptTrigger::setDebugDraw))
+			    ->addMethod("setAddToScript", Executor1<ScriptTrigger, lua_State*, bool>(&ScriptTrigger::setAddToScript))
+             );
+
+
+/**
+ * Constructs a new ScriptTrigger.
+ * @param root the xml element to load the parameters from.
+ *
+ */
+ScriptTrigger::ScriptTrigger(const TiXmlElement* root)
+{
+  this->registerObject(this, ScriptTrigger::_objectList);
+  this->toList(OM_COMMON);
+
+  radius = 10;
+  returnCount = 1;
+  scriptFinished = false;
+  doDebugDraw = false;
+  invert = false;
+  scriptCalled = false;
+  scriptIsOk = false;
+  triggerRemains = true;
+  addToScript = false;
+  this->activeOnCreation = false;
+
+  if(root != NULL)
+  {
+
+    loadParams(root);
+
+    if(addToScript && scriptIsOk)
+    {
+      script->addObject( "ScriptTrigger", this->getName());
+    }
+
+  }
+
+}
+
+/**
+ * Deletes the ScriptTrigger.
+ *
+ */
+ScriptTrigger::~ScriptTrigger()
+{
+
+}
+
+/**
+ * Reads the values from the tml element and sets them.
+ * @param root the xml element to load the parameters from.
+ *
+ */
+void ScriptTrigger::loadParams(const TiXmlElement* root)
+{
+
+  WorldEntity ::loadParams(root);
+
+  LoadParam(root, "file", this, ScriptTrigger, setScript)
+      .describe("the fileName of the script, that should be triggered by this script trigger")
+      .defaultValues("");
+  LoadParam(root, "function", this, ScriptTrigger, setFunction)
+      .describe("the function of the script, that should be triggered by this script trigger")
+      .defaultValues("");
+  LoadParam(root, "abs-coor", this, ScriptTrigger, setAbsCoor)
+      .describe("where this script trigger should be located")
+      .defaultValues("");
+  LoadParam(root, "radius", this, ScriptTrigger, setRadius)
+      .describe("the fileName of the script, that should be triggered by this script trigger")
+      .defaultValues(0);
+  LoadParam(root, "delay", this, ScriptTrigger, setDelay)
+      .describe("the delay after which the funtion sould be triggered")
+      .defaultValues(0);
+  LoadParam(root, "worldentity", this, ScriptTrigger, setTarget)
+      .describe("The name of the target as it is in the *.oxw file")
+      .defaultValues("");
+  LoadParam(root, "triggerparent", this, ScriptTrigger, setTriggerParent)
+      .describe("The name of the parent as it is in the *.oxw file")
+      .defaultValues("");
+  LoadParam(root, "invert", this, ScriptTrigger, setInvert)
+      .describe("")
+      .defaultValues(false);
+  LoadParam(root, "triggerRemains", this, ScriptTrigger, setTriggerRemains)
+      .describe("")
+      .defaultValues(true);
+  LoadParam(root, "debugdraw", this, ScriptTrigger, setDebugDraw)
+      .describe("")
+      .defaultValues(false);
+  LoadParam(root, "addtoscript", this, ScriptTrigger, setAddToScript)
+      .describe("True if this scripttrigger should be aviable in the script")
+      .defaultValues(false);
+}
+
+
+/**
+ * Sets the target(a world entity) of the ScriptTrigger. If the distance between the target and this trigger is smaller than the radius, the script gets triggered.
+ * @param target The worldentity that the script supervises.
+ */
+void ScriptTrigger::setTarget(const std::string& target)
+{
+
+  WorldEntity* targetEntity = WorldEntity::objectList().getObject(target);
+  if (targetEntity != NULL)
+  {
+    this->setTarget(targetEntity);
+  }
+  else
+  {
+    PRINTF(2)("Target %s for %s::%s does not Exist\n", target.c_str(), this->getClassCName(), this->getCName());
+  }
+}
+
+/**
+ * Sets the parent of the trigger.
+ * @param parent The parrent.
+ */
+void ScriptTrigger::setTriggerParent(const std::string& parent)
+{
+  WorldEntity* parentEntity = WorldEntity::objectList().getObject(parent);
+
+  if (parentEntity != NULL)
+  {
+    this->setParent(parentEntity);
+    this->setParentMode(PNODE_MOVEMENT);
+  }
+  else
+  {
+    PRINTF(2)("Parent %s for %s::%s does not Exist\n", parent.c_str(), this->getClassCName(), this->getCName());
+  }
+}
+
+void ScriptTrigger::tick(float timestep)
+{
+  if(scriptFinished) return;
+
+  if(activeOnCreation)
+   {
+     executeAction(timestep);
+     return;
+   }
+
+  if(triggerRemains && scriptCalled)
+  {
+    executeAction(timestep);
+    return;
+  }
+
+  if( !invert && this->distance(target) < radius)
+  {
+    executeAction(timestep);
+    scriptCalled = true;
+    return;
+
+  }
+  else if( invert && this->distance(target) > radius)
+  {
+    executeAction(timestep);
+    scriptCalled = true;
+    return;
+  }
+ //else
+   //printf("SCRIPTTRIGGER: target out of range\n");
+
+}
+
+
+void ScriptTrigger::executeAction(float timestep)
+{
+
+  if(scriptIsOk)
+  {
+       //testScriptingFramework();
+    if(!(script->selectFunction(this->functionName,returnCount)) )
+      PRINT(1)("Error ScriptTrigger: Selection of %s in %s failed.\n",functionName.c_str(), script->getFileName().c_str());
+
+    script->pushParam( timestep, this->functionName);
+
+    if( !(script->executeFunction()) )
+      PRINT(1)("Error ScriptTrigger: Execution of %s in %s failed.\n",functionName.c_str(), script->getFileName().c_str());
+
+    scriptFinished = script->getReturnedBool();
+  }
+
+
+}
+
+
+void ScriptTrigger::setScript(const std::string& file)
+{
+  ScriptManager* scriptManager = State::getScriptManager();
+  if (scriptManager != NULL)
+  {
+
+    script = scriptManager->getScriptByFile(file);
+    if(script != NULL)
+    {
+      scriptIsOk = true;
+    }
+  }
+}
+
+/*
+ void ScriptTrigger::testScriptingFramework()
+{
+   std::string file("lunartest2.lua");
+   //get script
+   Script* script = State::getScriptManager()->getScriptByFile(file);
+   printf("-------------------------- top of the stack:%i\n",lua_gettop(script->getLuaState()));
+
+      //execute a function
+   printf("----------- main -----------\n");
+   std::string main("main");
+   if( script->selectFunction(main,3))
+     printf("function %s selected\n",main.c_str());
+
+   script->pushParam(3.14159,main);
+   printf("-------------------------- top of the stack:%i\n",lua_gettop(script->getLuaState()));
+   script->executeFunction();
+
+   int ret = script->getReturnedInt();
+   printf("main returned %i\n",ret);
+
+   if(script->getReturnedBool())
+     printf("main returned true\n");
+   else
+     printf("main returned false\n");
+
+   float retf = script->getReturnedFloat();
+   printf("main returned %f\n",retf);
+
+
+   printf("-------------------------- top of the stack:%i\n",lua_gettop(script->getLuaState()));
+      //execute a 2nd function
+   printf("----------- test -----------\n");
+   std::string test("test");
+   if( script->selectFunction(test,0))
+     printf("function %s selected\n",test.c_str());
+
+   script->executeFunction();
+
+
+      //if(argc>1) lua_dofile(script.getLuaState(), argv[1]);
+   printf("-------------------------- top of the stack:%i\n",lua_gettop(script->getLuaState()));
+
+}*/
Index: branches/heathaze/src/world_entities/script_trigger.h
===================================================================
--- branches/heathaze/src/world_entities/script_trigger.h	(revision 9940)
+++ branches/heathaze/src/world_entities/script_trigger.h	(revision 9940)
@@ -0,0 +1,72 @@
+/*!
+ * @file scrip_trigger.h
+ *  triggeres a script
+ */
+
+#ifndef _SCRIPT_TRIGGER_H
+#define _SCRIPT_TRIGGER_H
+
+#include <string>
+
+#include "world_entity.h"
+#include "loading/load_param.h"
+#include "vector.h"
+#include "script_manager.h"
+#include "script.h"
+#include "script_class.h"
+
+class ScriptTrigger : public WorldEntity
+{
+  ObjectListDeclaration(ScriptTrigger);
+  public:
+    ScriptTrigger(const TiXmlElement* root = NULL);
+    ~ScriptTrigger();
+
+    ///LOADING
+    virtual void loadParams(const TiXmlElement* root);
+
+
+    /// DO WORK
+    virtual void tick(float timestep);
+    virtual void executeAction(float timestep);
+    void testScriptingFramework();
+
+    /// SET MEMBER
+    void setTarget(const std::string& targetName);
+    void setTarget(WorldEntity* target) { if(target!=NULL) this->target=target; }
+    void setTriggerParent(const std::string& name);
+    void setTriggerRemains(const bool lasts) { this->triggerRemains = lasts; }
+    void setActiveOnCreation(const bool avtive) { this->activeOnCreation = avtive; }
+    void setInvert(const bool inv) { this->invert = invert; }
+    void setDelay(float delay) { this->delay = delay; };
+    void setRadius(const float radius) { if(radius>0) this->radius = radius; }
+    void setScript(const std::string& file);
+    void setFunction(const std::string& function){ this->functionName = function;}
+    void setDebugDraw(const bool draw) { this->doDebugDraw = draw; }
+    void setAddToScript(const bool add) { this->addToScript = add; }
+
+    ///DRAWING
+    void draw()const{if(doDebugDraw)this->debugDraw();};
+
+  private:
+
+    WorldEntity* target;
+    bool         triggerRemains;
+    bool         activeOnCreation;
+    bool         invert;
+    float        radius;
+    float        delay;
+    Script*      script;
+    std::string  functionName;
+    bool         doDebugDraw;
+    bool         addToScript;
+    //for internal use
+    bool         scriptCalled;
+    bool         scriptIsOk;
+    bool         scriptFinished;
+    int          returnCount;        //TODO: set return count correctly
+
+};
+
+
+#endif
Index: branches/heathaze/src/world_entities/skybox.cc
===================================================================
--- branches/heathaze/src/world_entities/skybox.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/skybox.cc	(revision 9940)
@@ -0,0 +1,313 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "skybox.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "static_model.h"
+
+#include "material.h"
+#include "texture.h"
+
+#include "network_game_manager.h"
+#include "converter.h"
+#include "resource_texture.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(SkyBox, CL_SKYBOX);
+CREATE_FACTORY(SkyBox);
+
+/**
+ * Constructs a SkyBox and takes fileName as a map.
+ * @param fileName the file to take as input for the SkyBox
+*/
+SkyBox::SkyBox(const std::string& fileName)
+{
+  this->preInit();
+  if (!fileName.empty())
+    this->setTextureAndType(fileName, ".jpg");
+  this->postInit();
+}
+
+/**
+ *  initializes a skybox from a XmlElement
+*/
+SkyBox::SkyBox(const TiXmlElement* root)
+{
+  this->preInit();
+
+  if( root != NULL)
+    this->loadParams(root);
+
+  this->postInit();
+}
+
+void SkyBox::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "Materialset", this, SkyBox, setTexture)
+      .describe("Sets the material on the SkyBox. The string must be the path relative to the data-dir, and without a trailing .jpg");
+
+  LoadParam(root, "Size", this, SkyBox, setSize)
+      .describe("Sets the Size of the SkyBox (normally this should be 90% of the maximal viewing Distance).");
+}
+
+void SkyBox::preInit()
+{
+  this->registerObject(this, SkyBox::_objectList);
+  this->toList(OM_BACKGROUND);
+  this->toReflectionList();
+  //this->size = 100.0;
+  this->textureSize = 1024.0f;
+
+  for (int i = 0; i < 6; i++)
+    {
+      this->material[i] = new Material();
+      this->material[i]->setIllum(3);
+      this->material[i]->setDiffuse(0.0,0.0,0.0);
+      this->material[i]->setSpecular(0.0,0.0,0.0);
+      this->material[i]->setAmbient(2.0, 2.0, 2.0);
+
+      this->cubeTexture[i] = NULL;
+    }
+  this->setParentMode(PNODE_MOVEMENT);
+
+  this->textureName = "";
+}
+
+void SkyBox::postInit()
+{
+  this->rebuild();
+
+  textureName_handle = registerVarId( new SynchronizeableString( &textureName, &textureName, "textureName", PERMISSION_MASTER_SERVER) );
+  size_handle = registerVarId( new SynchronizeableFloat( &size, &size, "size", PERMISSION_MASTER_SERVER ) );
+}
+
+
+/**
+ *  default destructor
+*/
+SkyBox::~SkyBox()
+{
+  PRINTF(5)("Deleting SkyBox\n");
+  for (int i = 0; i < 6; i++)
+  {
+    if (this->material[i])
+      delete this->material[i];
+  }
+}
+
+void SkyBox::setTexture(const std::string& name)
+{
+  this->textureName = name;
+  this->setTextureAndType (name, "jpg");
+};
+
+
+/**
+ * @brief sets A set of textures when just giving a Name and an extension:
+ * @param name the prefix of the Name
+ * @param extension the file extension (jpg by default)
+ * usage: give this function an argument like
+ * setTexture("skybox", "jpg");
+ * and it will convert this to
+ * setTextures("skybox_negx.jpg", "skybox_posx.jpg", "skybox_negy.jpg",
+ *             "skybox_posy.jpg", "skybox_negz.jpg", "skybox_posz.jpg");
+ */
+void SkyBox::setTextureAndType(const std::string& name, const std::string& extension)
+{
+  std::string negX = name + "_negx." + extension;
+  std::string posX = name + "_posx." + extension;
+
+  std::string negY = name + "_negy." + extension;
+  std::string posY = name + "_posy." + extension;
+
+  std::string negZ = name + "_negz." + extension;
+  std::string posZ = name + "_posz." + extension;
+
+  this->setTextures(negX, posX, negY, posY, negZ, posZ);
+}
+
+/**
+ * @brief Defines which textures should be loaded onto the SkyBox.
+ * @param negX the top texture.
+ * @param posX the bottom texture.
+ * @param negY the left texture.
+ * @param posY the right texture.
+ * @param negZ the front texture.
+ * @param posZ the back texture.
+*/
+void SkyBox::setTextures(const std::string& negX, const std::string& posX,
+                         const std::string& negY, const std::string& posY,
+                         const std::string& negZ, const std::string& posZ)
+{
+  this->material[0]->setDiffuseMap(negX);
+  this->material[1]->setDiffuseMap(posX);
+  this->material[2]->setDiffuseMap(negY);
+  this->material[3]->setDiffuseMap(posY);
+  this->material[4]->setDiffuseMap(negZ);
+  this->material[5]->setDiffuseMap(posZ);
+  if (GLEW_EXT_texture_cube_map)
+    this->loadCubeMapTextures(negX, posX, negY, posY, negZ, posZ);
+}
+
+void SkyBox::loadCubeMapTextures(const std::string& posY, const std::string& negY, const std::string& negZ,
+                                  const std::string& posZ, const std::string& posX, const std::string& negX)
+{
+  this->cubeTexture[0] = ResourceTexture(negX, GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT);
+  this->cubeTexture[1] = ResourceTexture(posX, GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT);
+
+  this->cubeTexture[2] = ResourceTexture(negY, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT);
+  this->cubeTexture[3] = ResourceTexture(posY, GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT);
+
+  this->cubeTexture[4] = ResourceTexture(negZ, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT);
+  this->cubeTexture[5] = ResourceTexture(posZ, GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT);
+}
+
+void SkyBox::enableCubeMap()
+{
+  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+  glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+  glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
+
+  glEnable(GL_TEXTURE_CUBE_MAP_EXT);
+
+  glEnable(GL_TEXTURE_GEN_S);
+  glEnable(GL_TEXTURE_GEN_T);
+  glEnable(GL_TEXTURE_GEN_R);
+
+}
+
+void SkyBox::disableCubeMap()
+{
+  glDisable(GL_TEXTURE_CUBE_MAP);
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_TEXTURE_GEN_S);
+  glDisable(GL_TEXTURE_GEN_T);
+  glDisable(GL_TEXTURE_GEN_R);
+
+  glDisable(GL_TEXTURE_GEN_S);
+  glDisable(GL_TEXTURE_GEN_T);
+  glDisable(GL_TEXTURE_GEN_R);
+}
+
+
+
+/**
+ * @param size The new size of the SkyBox
+
+ * do not forget to rebuild the SkyBox after this.
+*/
+void SkyBox::setSize(float size)
+{
+  this->size = size;
+}
+
+
+
+void SkyBox::draw()
+{
+  glPushAttrib(GL_ENABLE_BIT);
+//   glPushAttrib(GL_LIGHTING_BIT);
+  glDisable(GL_LIGHTING);
+
+  glDisable(GL_FOG);
+
+  WorldEntity::draw();
+
+  glPopAttrib();
+
+}
+
+
+/**
+ *  rebuilds the SkyBox
+
+   this must be done, when changing the Size of the Skybox (runtime-efficency)
+*/
+void SkyBox::rebuild()
+{
+  StaticModel* model = new StaticModel();
+
+  model->addVertex (-0.5*size, -0.5*size, 0.5*size);
+  model->addVertex (0.5*size, -0.5*size, 0.5*size);
+  model->addVertex (-0.5*size, 0.5*size, 0.5*size);
+  model->addVertex (0.5*size, 0.5*size, 0.5*size);
+  model->addVertex (-0.5*size, 0.5*size, -0.5*size);
+  model->addVertex (0.5*size, 0.5*size, -0.5*size);
+  model->addVertex (-0.5*size, -0.5*size, -0.5*size);
+  model->addVertex (0.5*size, -0.5*size, -0.5*size);
+
+//   model->addVertexTexture (0.0, 1.0);
+//   model->addVertexTexture (1.0, 1.0);
+//   model->addVertexTexture (1.0, 0.0);
+//   model->addVertexTexture (0.0, 0.0);
+
+  model->addVertexTexture (1.0/this->textureSize, (this->textureSize - 1.0)/this->textureSize);
+  model->addVertexTexture ((this->textureSize - 1.0)/this->textureSize, (this->textureSize - 1.0)/this->textureSize);
+  model->addVertexTexture ((this->textureSize - 1.0)/this->textureSize, 1.0/this->textureSize);
+  model->addVertexTexture (1.0/this->textureSize, 1.0/this->textureSize);
+
+
+  model->addVertexNormal (0.0, 0.0, 1.0);
+  model->addVertexNormal (0.0, 1.0, 0.0);
+  model->addVertexNormal (0.0, 0.0, -1.0);
+  model->addVertexNormal (0.0, -1.0, 0.0);
+  model->addVertexNormal (1.0, 0.0, 0.0);
+  model->addVertexNormal (-1.0, 0.0, 0.0);
+
+  model->setMaterial(material[0]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,0,4, 0,1,4, 2,2,4, 4,3,4); // back
+  model->setMaterial(material[1]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,0,5, 7,1,5, 5,2,5, 3,3,5); // front
+  model->setMaterial(material[2]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,0,1, 7,1,1, 1,2,1, 0,3,1); // bottom
+  model->setMaterial(material[3]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,0,3, 3,1,3, 5,2,3, 4,3,3); // top
+  model->setMaterial(material[4]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 4,2,2, 5,3,2, 7,0,2, 6,1,2); // left
+  model->setMaterial(material[5]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 0,0,0, 1,1,0, 3,2,0, 2,3,0); // right
+
+  model->finalize();
+
+  this->setModel(model);
+}
+
+void SkyBox::varChangeHandler( std::list< int > & id )
+{
+  bool somethinChanged = false;
+
+  if ( std::find( id.begin(), id.end(), textureName_handle ) != id.end() )
+  {
+    somethinChanged = true;
+    setTexture( textureName );
+  }
+
+  if ( std::find( id.begin(), id.end(), size_handle ) != id.end() )
+  {
+    somethinChanged = true;
+  }
+
+  rebuild();
+
+  WorldEntity::varChangeHandler( id );
+}
Index: branches/heathaze/src/world_entities/skybox.h
===================================================================
--- branches/heathaze/src/world_entities/skybox.h	(revision 9940)
+++ branches/heathaze/src/world_entities/skybox.h	(revision 9940)
@@ -0,0 +1,81 @@
+/*!
+ * @file skybox.h
+ *  Definition of the SkyBox, that handles the Display of an atmosphere for orxonox.
+ *
+ * A SkyBox is always centered at the current working Camera, and will only obey the cameras
+ * movment but not its rotation.
+*/
+
+#ifndef _SKYBOX_H
+#define _SKYBOX_H
+
+/* INCLUDES */
+#include "world_entity.h"
+#include "material.h"
+
+enum SKY_SIDE
+{
+  SKY_BACK = 0,
+  SKY_FRONT,
+  SKY_BOTTOM,
+  SKY_TOP,
+  SKY_LEFT,
+  SKY_RIGHT,
+};
+
+//! A Class to handle a SkyBox
+class SkyBox : public WorldEntity
+{
+  ObjectListDeclaration(SkyBox);
+public:
+  SkyBox(const std::string& fileName = "");
+  SkyBox(const TiXmlElement* root);
+
+  virtual ~SkyBox();
+
+  void init();
+  void preInit();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void postInit();
+
+  virtual void draw();
+
+  void setSize(float size);
+  /** assumes jpg as input-format */
+  void setTexture(const std::string& name);
+
+  void setTextureAndType(const std::string& name, const std::string& extension);
+  void setTextures(const std::string& negX, const std::string& posX, const std::string& negY,
+                   const std::string& posY, const std::string& negZ, const std::string& posZ);
+
+  void loadCubeMapTextures(const std::string& negX, const std::string& posX, const std::string& negY,
+                           const std::string& posY, const std::string& negZ, const std::string& posZ);
+
+  GLuint getTexture(SKY_SIDE side) const { return (this->material[side]) ? this->material[side]->diffuseTextureID(): 0; };
+
+  static void enableCubeMap();
+  static void disableCubeMap();
+
+  virtual void varChangeHandler( std::list<int> & id );
+
+ private:
+  void rebuild();
+
+  Material*       material[6];     //!< Materials for the SkyBox. sorted by number (0-5) top, bottom, left, right, front, back
+  Texture         cubeTexture[6];  //!< Textures for the CubeMap.
+
+  float           size;            //!< Size of the SkyBox. This should match the frustum maximum range.
+  float           textureSize;     //!< this is the length of a texture (assumes a square texture)
+  std::string     textureName;     //!< Name of the Texture
+
+  int textureName_handle;          //!< used to notify about changes of textureName
+  int size_handle;                 //!< used to notify about changes of size
+
+};
+
+#endif  /* _SKYBOX_H */
+
+
+
Index: branches/heathaze/src/world_entities/skydome.cc
===================================================================
--- branches/heathaze/src/world_entities/skydome.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/skydome.cc	(revision 9940)
@@ -0,0 +1,227 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: hdavid, amaechler
+   co-programmer: ...
+*/
+
+#include "skydome.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "static_model.h"
+#include "shader.h"
+
+#include "network_game_manager.h"
+#include "converter.h"
+
+#include "debug.h"
+
+#define DTOR (PI/180.0f)
+#define SQR(x) (x*x)
+
+
+
+ObjectListDefinition(Skydome);
+
+/**
+ *  initializes a skybox from a XmlElement
+ */
+Skydome::Skydome()
+{
+  this->init();
+}
+
+
+void Skydome::init()
+{
+  PRINTF(4)("Skydome init\n");
+
+  this->registerObject(this, Skydome::_objectList);
+  this->toList(OM_BACKGROUND);
+  this->toReflectionList();
+  this->indices = NULL;
+  this->vertices = NULL;
+  this->planeVertices = NULL;
+  this->shader = NULL;
+  activateDome = false;
+
+}
+
+
+/**
+ *  default destructor
+ */
+Skydome::~Skydome()
+{
+  PRINTF(4)("Deleting Skydome\n");
+
+  if (glIsTexture(texture))
+    glDeleteTextures(1, &texture);
+}
+
+
+void Skydome::setShader(Shader* shader)
+{
+  this->shader = shader;
+}
+
+void Skydome::setTexture(GLuint texture)
+{
+  this->texture = texture;
+}
+
+
+void Skydome::activate()
+{
+  this->activateDome = true;
+}
+
+void Skydome::deactivate()
+{
+  this->activateDome = false;
+}
+
+
+void Skydome::draw() const
+{
+  if(!activateDome)
+    return;
+
+  glPushAttrib(GL_ENABLE_BIT);
+
+  glDisable(GL_LIGHTING);
+  glDisable(GL_BLEND);
+  glDisable(GL_FOG);
+
+  glEnable(GL_TEXTURE_3D);
+  glBindTexture(GL_TEXTURE_3D, texture);
+
+  this->shader->activateShader();
+
+  glPushMatrix();
+  glTranslatef(0.0f,pRadius,0.0f);
+
+  glBegin(GL_TRIANGLES);
+  for (int i=0; i < numIndices; i++)
+  {
+    glColor3f(1.0f, 1.0f, 1.0f);
+
+    glTexCoord2f(planeVertices[indices[i]].u, planeVertices[indices[i]].v);
+    glVertex3f(planeVertices[indices[i]].x, planeVertices[indices[i]].y, planeVertices[indices[i]].z);
+  }
+  glEnd();
+
+  WorldEntity::draw();
+
+  glPopMatrix();
+
+  this->shader->deactivateShader();
+
+  glPopAttrib();
+}
+
+
+void Skydome::generateSkyPlane(int divisions, float planetRadius, float atmosphereRadius, float hTile, float vTile)
+{
+  PRINTF(0)("Generating a sky plane\n");
+
+  // Make sure our vertex array is clear
+  if (planeVertices)
+  {
+    delete planeVertices;
+    planeVertices = NULL;
+  }
+
+  // Make sure our index array is clear
+  if (indices)
+  {
+    delete indices;
+    indices = NULL;
+  }
+
+  // Set the number of divisions into a valid range
+  int divs = divisions;
+  if (divisions < 1)
+    divs = 1;
+
+  if (divisions > 256)
+    divs = 256;
+
+  pRadius = planetRadius;
+
+  // Initialize the Vertex and indices arrays
+  numPlaneVertices = (divs + 1) * (divs + 1);   // 1 division would give 4 verts
+  numIndices  = divs * divs * 2 * 3;       // 1 division would give 6 indices for 2 tris
+
+  planeVertices = new VertexInfo[numPlaneVertices];
+  memset(planeVertices, 0, sizeof(VertexInfo));
+
+  indices = new int[numIndices];
+  memset(indices, 0, sizeof(int)*numIndices);
+
+  // Calculate some values we will need
+  float plane_size = 2.0f * (float)sqrt((SQR(atmosphereRadius)-SQR(planetRadius)));
+  float delta = plane_size/(float)divs;
+  float tex_delta = 2.0f/(float)divs;
+
+  // Variables we'll use during the dome's generation
+  float x_dist   = 0.0f;
+  float z_dist   = 0.0f;
+  float x_height = 0.0f;
+  float z_height = 0.0f;
+  float height = 0.0f;
+
+  VertexInfo SV; // temporary vertex
+
+  for (int i=0;i <= divs;i++)
+  {
+    for (int j=0; j <= divs; j++)
+    {
+      x_dist = (-0.5f * plane_size) + ((float)j*delta);
+      z_dist = (-0.5f * plane_size) + ((float)i*delta);
+
+      x_height = (x_dist*x_dist) / atmosphereRadius;
+      z_height = (z_dist*z_dist) / atmosphereRadius;
+      height = x_height + z_height;
+
+      SV.x = x_dist;
+      SV.y = 0.0f - height;
+      SV.z = z_dist;
+
+      // Calculate the texture coordinates
+      SV.u = hTile*((float)j * tex_delta*0.5f);
+      SV.v = vTile*(1.0f - (float)i * tex_delta*0.5f);
+
+      planeVertices[i*(divs+1)+j] = SV;
+    }
+  }
+
+  // Calculate the indices
+  int index = 0;
+  for (int i=0; i < divs;i++)
+  {
+    for (int j=0; j < divs; j++)
+    {
+      int startvert = (i*(divs+1) + j);
+
+      // tri 1
+      indices[index++] = startvert;
+      indices[index++] = startvert+1;
+      indices[index++] = startvert+divs+1;
+
+      // tri 2
+      indices[index++] = startvert+1;
+      indices[index++] = startvert+divs+2;
+      indices[index++] = startvert+divs+1;
+    }
+  }
+}
Index: branches/heathaze/src/world_entities/skydome.h
===================================================================
--- branches/heathaze/src/world_entities/skydome.h	(revision 9940)
+++ branches/heathaze/src/world_entities/skydome.h	(revision 9940)
@@ -0,0 +1,67 @@
+/*!
+ * @file skydome.h
+ */
+
+#ifndef _SKYDOME_H
+#define _SKYDOME_H
+
+/* INCLUDES */
+#include "world_entity.h"
+#include "shader.h"
+
+//   typedef struct VERTEX
+// {
+//   float x,y,z;
+//   unsigned int color;
+//   float u, v;
+// }  ;
+
+
+//! A Class to handle a SkyDome
+class Skydome : public WorldEntity
+{
+  ObjectListDeclaration(Skydome);
+public:
+  Skydome();
+
+  virtual ~Skydome();
+
+  void init();
+  virtual void draw() const;
+
+  void generateSkyPlane(int divisions, float planetRadius, float atmosphereRadius,
+                        float hTile, float vTile);
+
+  void setShader(Shader* shader);
+  void setTexture(GLuint texture);
+
+  void activate();
+  void deactivate();
+
+private:
+
+  typedef struct VertexInfo
+  {
+    float x,y,z;
+    unsigned int color;
+    float u, v;
+  };
+
+  bool activateDome;
+
+  VertexInfo *planeVertices;
+  int numPlaneVertices;
+
+  int *indices;
+  int numIndices;
+
+  float pRadius;
+
+  VertexInfo *vertices;
+  int numVertices;
+
+  GLuint texture;
+  Shader* shader;
+};
+
+#endif  /* _SKYDOME_H */
Index: branches/heathaze/src/world_entities/skysphere.cc
===================================================================
--- branches/heathaze/src/world_entities/skysphere.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/skysphere.cc	(revision 9940)
@@ -0,0 +1,121 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: David Gruetter
+   co-programmer: Benjamin Grauer
+
+   Created by Dave: this file is actually quite similar to player.cc and so is
+   skybox.h similar to player.h
+   With that said, things should be clear:)
+
+   Edited:
+   Bensch: more constructors, changeability, comments...
+   Patrick: giving it the common orxonox style, not much to do... good work Dave!
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "skysphere.h"
+
+#include "material.h"
+#include "debug.h"
+
+
+ObjectListDefinition(Skysphere);
+
+/**
+ *  Constructs a SkySphere and takes fileName as a map.
+ * @param fileName the file to take as input for the skysphere
+*/
+Skysphere::Skysphere(char* fileName)
+{
+  this->registerObject(this, Skysphere::_objectList);
+  this->toList(OM_BACKGROUND);
+  if (fileName == NULL)
+    this->initialize("pictures/sky-replace.jpg");
+  else
+    this->initialize(fileName);
+}
+
+
+/**
+ *  default destructor
+*/
+Skysphere::~Skysphere()
+{
+  PRINTF(3)("Deleting the SkySphere\n");
+  delete this->skyMaterial;
+  gluDeleteQuadric(this->sphereObj);
+}
+
+/**
+ *  initializes the Skysphere.
+ * @param fileName the file to take as input for the skysphere
+*/
+void Skysphere::initialize(char* fileName)
+{
+  PRINTF(1)("initializing the Skysphere with Material %s.\n", fileName);
+  this->sphereObj = gluNewQuadric();
+  this->setParentMode(PNODE_MOVEMENT);
+
+  gluQuadricTexture(this->sphereObj, GL_TRUE);
+  this->setRadius(1900.0);
+
+  this->skyMaterial = new Material("Sky");
+  this->setTexture(fileName);
+  this->skyMaterial->setIllum(3);
+  this->skyMaterial->setAmbient(1.0, 1.0, 1.0);
+}
+
+
+/**
+ *  Defines which texture should be loaded onto the skysphere.
+ * @param fileName The filename of the Texture
+*/
+void Skysphere::setTexture(char* fileName)
+{
+  this->skyMaterial->setDiffuseMap(fileName);
+}
+
+
+/**
+ *  draws the Skysphere
+
+   This part is normally precessed in the "Painting Phase".
+*/
+void Skysphere::draw() const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  Vector r = this->getAbsCoor();
+  glTranslatef(r.x, r.y, r.z);
+
+  //glRotatef(-30, 1, 0, 0);
+  //glRotatef(95.0f, 0.0f, 0.0f, 1.0f);
+  //glRotatef(-250.0f, 0.0, 1.0f, 0.0f);
+
+  skyMaterial->select();
+  gluSphere(this->sphereObj, this->sphereRadius, 20, 20);
+  glPopMatrix();
+}
+
+
+/**
+ *  sets the Radius of the Sphere.
+ * @param radius The Radius of The Sphere
+*/
+void Skysphere::setRadius(float radius)
+{
+  this->sphereRadius = radius;
+}
Index: branches/heathaze/src/world_entities/skysphere.h
===================================================================
--- branches/heathaze/src/world_entities/skysphere.h	(revision 9940)
+++ branches/heathaze/src/world_entities/skysphere.h	(revision 9940)
@@ -0,0 +1,49 @@
+/*!
+ * @file skysphere.h
+  *  Definition of the Skysphere, that handles the Display of an atmosphere of orxonox.
+
+    A SkySphere is always centered at the current working Camera, and will only obey the cameras
+    movment but not its rotation.
+
+    @todo self-rotation
+    @todo handle reference to parent-object
+*/
+
+#ifndef _SKYSPHERE_H
+#define _SKYSPHERE_H
+
+/* INCLUDES */
+#include "world_entity.h"
+#include "glincl.h"
+
+/* FORWARD DECLARATION */
+class Material;
+class Vector;
+
+//! A Class to handle a SkySphere
+class Skysphere : public WorldEntity
+{
+  ObjectListDeclaration(Skysphere);
+
+ public:
+  Skysphere(char* fileName = NULL);
+  virtual ~Skysphere();
+
+  void setRadius(float radius);
+  void setTexture(char* fileName);
+
+  virtual void draw() const;
+
+  private:
+    void initialize(char* fileName);
+
+ private:
+  GLUquadricObj*    sphereObj;           //!< A Placeholder for the SkySphere.
+  Material*         skyMaterial;         //!< A Material for the SkySphere.
+  float             sphereRadius;        //!< Radius of the SkySphere. This should match the frustum maximum range.
+};
+
+#endif  /* _SKYSPHERE_H */
+
+
+
Index: branches/heathaze/src/world_entities/space_ships/collision_probe.cc
===================================================================
--- branches/heathaze/src/world_entities/space_ships/collision_probe.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/collision_probe.cc	(revision 9940)
@@ -0,0 +1,117 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "collision_probe.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+#include "md2/md2Model.h"
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(CollisionProbe, CL_COLLISION_PROBE);
+
+CREATE_FACTORY(CollisionProbe);
+
+
+/**
+ *  destructs the spaceship, deletes alocated memory
+ */
+CollisionProbe::~CollisionProbe ()
+{}
+
+
+/**
+ *  creates a new Spaceship from Xml Data
+ * @param root the xml element containing spaceship data
+
+   @todo add more parameters to load
+*/
+CollisionProbe::CollisionProbe(const TiXmlElement* root)
+{
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * initializes a Spaceship
+ */
+void CollisionProbe::init()
+{
+  this->registerObject(this, CollisionProbe::_objectList);
+
+  bUp = bDown = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = false;
+
+  this->setHealthMax(100);
+  this->setHealth(80);
+
+  this->toList(OM_GROUP_00);
+  this->loadMD2Texture("maps/dr_freak.pcx");
+  this->loadModel("models/dr_freak.md2");
+
+  this->localVelocity = Vector(0,0,0);
+}
+
+
+/**
+ * loads the Settings of a CollisionProbe from an XML-element.
+ * @param root the XML-element to load the Spaceship's properties from
+ */
+void CollisionProbe::loadParams(const TiXmlElement* root)
+{
+  Playable::loadParams(root);
+}
+
+
+
+/**
+ *  draws the spaceship after transforming it.
+*/
+void CollisionProbe::draw () const
+{
+  WorldEntity::draw();
+}
+
+
+/**
+ *  the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+ */
+void CollisionProbe::tick (float time)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((MD2Model*)this->getModel(0))->tick(time);
+
+  this->shiftCoor(this->localVelocity * time);
+}
+
+
+/**
+ * @todo switch statement ??
+ */
+void CollisionProbe::process(const Event &event)
+{
+
+}
+
+
+
+
Index: branches/heathaze/src/world_entities/space_ships/collision_probe.h
===================================================================
--- branches/heathaze/src/world_entities/space_ships/collision_probe.h	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/collision_probe.h	(revision 9940)
@@ -0,0 +1,58 @@
+/*!
+ * @file space_ship.h
+ * Implements the Control of a Spaceship
+ */
+
+#ifndef _COLLISION_PROBE_H
+#define _COLLISION_PROBE_H
+
+#include "playable.h"
+
+#include "vector.h"
+
+class CollisionProbe : public Playable
+{
+  ObjectListDeclaration(CollisionProbe);
+
+  public:
+    CollisionProbe(const std::string& fileName);
+    CollisionProbe(const TiXmlElement* root = NULL);
+    virtual ~CollisionProbe();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void tick(float time);
+    virtual void draw() const;
+
+    virtual void process(const Event &event);
+
+    virtual void enter() {}
+    virtual void leave() {}
+    virtual void setPlayDirection(const Quaternion& rot, float speed = 0.0f) {}
+
+  private:
+    void init();
+
+
+    bool                  bUp;                //!< up button pressed.
+    bool                  bDown;              //!< down button pressed.
+    bool                  bLeft;              //!< left button pressed.
+    bool                  bRight;             //!< right button pressed.
+    bool                  bAscend;            //!< ascend button pressed.
+    bool                  bDescend;           //!< descend button presses.
+//    bool                  bFire;              //!< fire button pressed.(moved to playable)
+    bool                  bRollL;             //!< rolling button pressed (left)
+    bool                  bRollR;             //!< rolling button pressed (right)
+
+    float                 xMouse;             //!< mouse moved in x-Direction
+    float                 yMouse;             //!< mouse moved in y-Direction
+    float                 mouseSensitivity;   //!< the mouse sensitivity
+    int                   yInvert;
+    int                   controlVelocityX;
+    int                   controlVelocityY;
+
+    Vector                localVelocity;      //!< velocity this entity flights with
+
+};
+
+#endif /* _SPACE_SHIPS_H */
Index: branches/heathaze/src/world_entities/space_ships/cruizer.cc
===================================================================
--- branches/heathaze/src/world_entities/space_ships/cruizer.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/cruizer.cc	(revision 9940)
@@ -0,0 +1,374 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "cruizer.h"
+
+#include "weapons/weapon_manager.h"
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+
+#include "util/loading/factory.h"
+#include "key_mapper.h"
+#include "state.h"
+
+#include "graphics_engine.h"
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Cruizer, CL_CRUIZER);
+CREATE_FACTORY(Cruizer);
+
+/**
+ *  destructs the cruizer, deletes alocated memory
+ */
+Cruizer::~Cruizer ()
+{
+  this->setPlayer(NULL);
+}
+
+/**
+ * @brief loads a Cruizer information from a specified file.
+ * @param fileName the name of the File to load the cruizer from (absolute path)
+ */
+Cruizer::Cruizer(const std::string& fileName)
+{
+  this->init();
+  TiXmlDocument doc(fileName);
+
+  if(!doc.LoadFile())
+  {
+    PRINTF(2)("Loading file %s failed for Cruizer.\n", fileName.c_str());
+    return;
+  }
+
+  this->loadParams(doc.RootElement());
+}
+
+/**
+ * @brief creates a new Spaceship from Xml Data
+ * @param root the xml element containing spaceship data
+
+   @todo add more parameters to load
+*/
+Cruizer::Cruizer(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+
+  this->getWeaponManager().changeWeaponConfig(1);
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+ // this->loadModel("models/ships/human_cruizer.obj", 0.05);
+
+}
+
+
+/**
+ * @brief initializes a Cruizer
+ */
+void Cruizer::init()
+{
+  //  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->registerObject(this, Cruizer::_objectList);
+
+  this->setSupportedPlaymodes(Playable::Full3D);
+
+  bForward = bBackward = bLeft = bRight = bAscend = bDescend = false;
+  mouseSensitivity = 0.005;
+
+  this->rotorSpeed = 1000.0f;
+  this->rotorCycle = 0.0f;
+  this->cameraLook = 0.0f;
+  this->rotation = 0.0f;
+  this->acceleration = 10.0f;
+  this->airFriction = 2.0f;
+
+  this->setHealthMax(100);
+  this->setHealth(100);
+
+
+  // camera - issue
+  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
+  //this->cameraNode.setParentMode(PNODE_ROTATE_MOVEMENT);
+  //this->cameraNode.setParent(this);
+
+
+  // PARTICLES
+  this->burstEmitter = new DotEmitter(200, 5.0, .01);
+  this->burstEmitter->setParent(this);
+  this->burstEmitter->setRelCoor(0, -0.7, 0);
+  this->burstEmitter->setRelDir(Quaternion(-M_PI_2, Vector(0,0,1)));
+  this->burstEmitter->setName("Cruizer_Burst_emitter_Left");
+
+
+  this->burstSystem = new SpriteParticles(1000);
+  this->burstSystem->addEmitter(this->burstEmitter);
+  this->burstSystem->setName("SpaceShip_Burst_System");
+  ((SpriteParticles*)this->burstSystem)->setMaterialTexture("maps/radial-trans-noise.png");
+  this->burstSystem->setLifeSpan(1.0, .3);
+  this->burstSystem->setRadius(0.0, 1.5);
+  this->burstSystem->setRadius(0.05, 1.8);
+  this->burstSystem->setRadius(.5, .8);
+  this->burstSystem->setRadius(1.0, 0);
+  this->burstSystem->setColor(0.0, .7,.7,1,.5);
+  this->burstSystem->setColor(0.2, 0,0,0.8,.5);
+  this->burstSystem->setColor(0.5, .5,.5,.8,.3);
+  this->burstSystem->setColor(1.0, .8,.8,.8,.0);
+
+
+  //add events to the eventlist of the Playable
+  this->registerEvent(KeyMapper::PEV_FORWARD);
+  this->registerEvent(KeyMapper::PEV_BACKWARD);
+  this->registerEvent(KeyMapper::PEV_LEFT);
+  this->registerEvent(KeyMapper::PEV_RIGHT);
+  this->registerEvent(KeyMapper::PEV_UP);
+  this->registerEvent(KeyMapper::PEV_DOWN);
+  this->registerEvent(KeyMapper::PEV_FIRE1);
+  this->registerEvent(KeyMapper::PEV_NEXT_WEAPON);
+  this->registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
+  this->registerEvent(EV_MOUSE_MOTION);
+
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+  // WEAPON_MANAGER configuration
+  this->getWeaponManager().setSlotCount(5);
+
+  this->getWeaponManager().setSlotPosition(2, Vector(-1.63, .809, -.003));
+  this->getWeaponManager().setSlotCapability(2, WTYPE_HEAVY);
+
+  /// TODO: THESE ARE TOO MUCH
+  this->getWeaponManager().setSlotPosition(3, Vector(-1.63, .678, -.652));
+  this->getWeaponManager().setSlotDirection(3, Quaternion(-24/180 * M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(4, Vector(-1.63, .678, .652));
+  this->getWeaponManager().setSlotDirection(4, Quaternion(24/180 * M_PI, Vector(1,0,0)));
+
+  this->cameraNode.setRelCoor(1,5,0);
+  this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
+  this->getWeaponManager().getFixedTarget()->setRelCoor(1000,0,0);
+
+  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bAscend, &bAscend, "bAscend", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bDescend, &bDescend, "bDescend", PERMISSION_OWNER ) );
+  //registerVar( new SynchronizeableQuaternion( &direction, &direction, "direction", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableFloat( &cameraLook, &cameraLook, "cameraLook", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableFloat( &rotation, &rotation, "rotation", PERMISSION_OWNER ) );
+}
+
+/**
+ * @brief loads the Settings of a Cruizer from an XML-element.
+ * @param root the XML-element to load the Spaceship's properties from
+ */
+void Cruizer::loadParams(const TiXmlElement* root)
+{
+  Playable::loadParams(root);
+}
+
+void Cruizer::setPlayDirection(const Quaternion& rot, float speed)
+{
+  this->direction = Quaternion (rot.getHeading(), Vector(0,1,0));
+}
+
+void Cruizer::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( true);
+
+  if (State::getCameraNode != NULL)
+  {
+    State::getCameraNode()->setParentSoft(&this->cameraNode);
+    State::getCameraNode()->setRelCoorSoft(-10, 0,0);
+    State::getCameraTargetNode()->setParentSoft(&this->cameraNode);
+  }
+}
+
+void Cruizer::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+  this->detachCamera();
+
+}
+
+
+/**
+ * @brief effect that occurs after the Cruizer is spawned
+*/
+void Cruizer::postSpawn ()
+{
+  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
+}
+
+/**
+ * @brief the action occuring if the cruizer left the game
+*/
+void Cruizer::leftWorld ()
+{}
+
+/**
+ * @brief this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void Cruizer::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  Playable::collidesWith(entity, location);
+}
+
+
+
+/**
+ * @brief the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+*/
+void Cruizer::tick (float dt)
+{
+  //  this->debugNode(1);
+  Playable::tick(dt);
+
+  // spaceship controlled movement
+  this->movement(dt);
+  this->rotorCycle += this->rotorSpeed * dt;
+
+  // TRYING TO FIX PNode.
+  this->cameraNode.setAbsCoorSoft(this->getAbsCoor() + Vector(0.0f, 5.0f, 0.0f), 30.0f);
+  this->cameraNode.setRelDirSoft(this->getAbsDir(), 30.0f);
+}
+
+/**
+ * @brief calculate the velocity
+ * @param time the timeslice since the last frame
+*/
+void Cruizer::movement (float dt)
+{
+  Vector accel(0.0, 0.0, 0.0);
+
+  if( this->bForward )
+  {
+    accel += Vector(this->acceleration, 0, 0);
+  }
+
+  if( this->bBackward )
+  {
+    accel -= Vector(this->acceleration, 0, 0);
+  }
+  if( this->bLeft)
+  {
+    accel -= Vector(0, 0, this->acceleration);
+  }
+
+  if( this->bRight)
+  {
+    accel += Vector(0, 0, this->acceleration);
+  }
+
+  if (this->bAscend )
+  {
+    accel += Vector(0, this->acceleration, 0);
+  }
+  if (this->bDescend )
+  {
+    accel -= Vector(0, this->acceleration, 0);
+  }
+
+  switch(this->getPlaymode())
+  {
+    case Playable::Full3D:
+      {
+        Vector accelerationDir = this->getAbsDir().apply(accel * this->acceleration);
+
+        // this is the air friction (necessary for a smooth control)
+        Vector damping = (this->velocity * this->airFriction);
+
+
+        this->velocity += (accelerationDir - damping)* dt;
+        this->shiftCoor (this->velocity * dt);
+
+        // limit the maximum rotation speed.
+        if (this->rotation != 0.0f)
+        {
+          float maxRot = 10.0 * dt;
+          if (unlikely(this->rotation > maxRot)) this->rotation = maxRot;
+          if (unlikely(this->rotation < -maxRot)) this->rotation = -maxRot;
+          this->direction *= Quaternion(-M_PI/4.0*this->rotation, Vector(0,1,0));
+
+          this->rotation = 0.0f;
+        }
+
+        this->setRelDirSoft(this->direction * Quaternion(-cameraLook, Vector(0,0,1)), 5);
+     }
+      break;
+
+    default:
+      PRINTF(2)("Playmode %s Not Implemented\n", Playable::playmodeToString(this->getPlaymode()).c_str());
+  }
+}
+
+
+void Cruizer::draw() const
+{
+  Vector tmpRot;
+  WorldEntity::draw();
+}
+
+/**
+ * @todo switch statement ??
+ */
+void Cruizer::process(const Event &event)
+{
+  Playable::process(event);
+
+  if( event.type == KeyMapper::PEV_LEFT)
+    this->bLeft = event.bPressed;
+  else if( event.type == KeyMapper::PEV_RIGHT)
+    this->bRight = event.bPressed;
+  else if( event.type == KeyMapper::PEV_UP)
+    this->bAscend = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == KeyMapper::PEV_DOWN)
+    this->bDescend = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == KeyMapper::PEV_FORWARD)
+    this->bForward = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == KeyMapper::PEV_BACKWARD)
+    this->bBackward = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+    float xMouse, yMouse;
+    xMouse = event.xRel*mouseSensitivity;
+    yMouse = event.yRel*mouseSensitivity;
+
+    // rotate the Player around the y-axis
+    this->rotation += xMouse;
+
+    this->cameraLook += yMouse;
+    // rotate the Camera around the z-axis
+    if (cameraLook > M_PI_4)
+      cameraLook = M_PI_4;
+    else if (cameraLook < -M_PI_4)
+      cameraLook = -M_PI_4;
+    //this->cameraNode.setRelDirSoft(this->direction,10);
+  }
+}
Index: branches/heathaze/src/world_entities/space_ships/cruizer.h
===================================================================
--- branches/heathaze/src/world_entities/space_ships/cruizer.h	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/cruizer.h	(revision 9940)
@@ -0,0 +1,72 @@
+
+/*!
+ * @file cruizer.h
+ * Implements the Control of a Cruizer
+ */
+
+#ifndef _CRUIZER_H
+#define _CRUIZER_H
+
+#include "playable.h"
+
+// Forward Declaration
+class ParticleEmitter;
+class ParticleSystem;
+
+class Cruizer : public Playable
+{
+  ObjectListDeclaration(Cruizer);
+  public:
+    Cruizer(const std::string& fileName);
+    Cruizer(const TiXmlElement* root = NULL);
+    virtual ~Cruizer();
+
+    virtual void loadParams(const TiXmlElement* root);
+    virtual void setPlayDirection(const Quaternion& rot, float speed = 0.0f);
+    virtual void enter();
+    virtual void leave();
+
+    virtual void postSpawn();
+    virtual void leftWorld();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+    virtual void process(const Event &event);
+
+  private:
+    void init();
+    void movement(float dt);
+
+  private:
+    bool                  bForward;           //!< forward button pressed.
+    bool                  bBackward;          //!< backward button pressed.
+    bool                  bLeft;              //!< left button pressed.
+    bool                  bRight;             //!< right button pressed.
+    bool                  bAscend;            //!< ascend button pressed.
+    bool                  bDescend;           //!< descend button presses.
+
+    int                   yInvert;
+    float                 mouseSensitivity;   //!< the mouse sensitivity
+
+    PNode                 cameraNode;
+    float                 cameraLook;
+    float                 rotation;
+
+   // Vector                velocity;           //!< the velocity of the Cruizer.
+    Quaternion            direction;          //!< the direction of the Cruizer.
+    float                 travelSpeed;        //!< the current speed of the Hove (to make soft movement)
+    float                 acceleration;       //!< the acceleration of the Cruizer.
+    float                 airFriction;        //!< AirFriction.
+
+    float                 rotorSpeed;         //!< the speed of the rotor.
+    float                 rotorCycle;         //!< The Cycle the rotor is in.
+
+    float                 airViscosity;
+
+    ParticleEmitter*      burstEmitter;
+    ParticleSystem*       burstSystem;
+};
+
+#endif /* _CRUIZERS_H */
Index: branches/heathaze/src/world_entities/space_ships/helicopter.cc
===================================================================
--- branches/heathaze/src/world_entities/space_ships/helicopter.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/helicopter.cc	(revision 9940)
@@ -0,0 +1,460 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Knecht
+   co-programmer: ...
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "helicopter.h"
+
+#include "weapons/weapon_manager.h"
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+
+#include "util/loading/factory.h"
+#include "sound/resource_sound_buffer.h"
+
+#include "key_mapper.h"
+#include "state.h"
+
+#include "graphics_engine.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Helicopter, CL_HELICOPTER);
+CREATE_FACTORY(Helicopter);
+#include "script_class.h"
+CREATE_SCRIPTABLE_CLASS(Helicopter,
+			addMethod("moveUp", Executor1<Helicopter, lua_State*,bool>(&Helicopter::moveUp))
+			    ->addMethod("moveDown", Executor1<Helicopter, lua_State*,bool>(&Helicopter::moveDown))
+			    ->addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
+			    ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
+			    ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
+			    ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
+
+                       );
+
+
+/**
+ *  creates the controlable Helicopter
+ */
+Helicopter::Helicopter()
+{
+  this->init();
+}
+
+/**
+ *  destructs the helicopter, deletes alocated memory
+ */
+Helicopter::~Helicopter ()
+{
+  this->setPlayer(NULL);
+}
+
+/**
+ * loads a Helicopter information from a specified file.
+ * @param fileName the name of the File to load the helicopter from (absolute path)
+ */
+Helicopter::Helicopter(const std::string& fileName)
+{
+  this->init();
+  TiXmlDocument doc(fileName);
+
+  if(!doc.LoadFile())
+  {
+    PRINTF(2)("Loading file %s failed for Helicopter.\n", fileName.c_str());
+    return;
+  }
+
+  this->loadParams(doc.RootElement());
+}
+
+/**
+ *  creates a new Spaceship from Xml Data
+ * @param root the xml element containing spaceship data
+
+   @todo add more parameters to load
+*/
+Helicopter::Helicopter(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+  //weapons:
+  Weapon* wpRight = new TestGun(0);
+  wpRight->setName("testGun Right");
+  Weapon* wpLeft = new TestGun(1);
+  wpLeft->setName("testGun Left");
+  Weapon* cannon = dynamic_cast<Weapon*>(Factory::fabricate("Cannon"));
+
+  cannon->setName("BFG");
+
+  this->addWeapon(wpLeft, 1, 0);
+  this->addWeapon(wpRight,1 ,1);
+  this->addWeapon(cannon, 0, 6);
+
+  this->getWeaponManager().changeWeaponConfig(1);
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+  //load sound
+  this->chopperBuffer = OrxSound::ResourceSoundBuffer("sound/engine/chopper.wav");
+
+}
+
+
+/**
+ * initializes a Helicopter
+ */
+void Helicopter::init()
+{
+  this->registerObject(this, Helicopter::_objectList);
+  PRINTF(4)("HELICOPTER INIT\n");
+
+  this->loadModel("models/ships/helicopter_#.obj", 1.0);
+
+  //EventHandler::getInstance()->grabEvents(true);
+
+  bUp = bDown = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = false;
+  bFire = false;
+  xMouse = yMouse = 0;
+  mouseSensitivity = 0.05;
+  controlVelocityX = 100;
+  controlVelocityY = 100;
+
+
+  // initialization of cameraNode
+  this->cameraNode.setParent(this);
+  this->cameraNode.setParentMode(PNODE_ALL);
+  this->cameraNode.setRelCoor(Vector(0,1,0));
+
+  // rotors
+  this->topRotor.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->tailRotor.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+
+  this->topRotor.setParent(this);
+  this->tailRotor.setParent(this);
+
+  this->topRotor.setRelCoor(Vector(-0.877,0.627,0));
+  this->tailRotor.setRelCoor(Vector(-4.43,0.297,0.068));
+  this->tailRotor.setAbsDir(Quaternion(M_PI_2,Vector(1,0,0)));
+
+  this->loadModel("models/ships/rotor.obj",1.0,3);
+  this->loadModel("models/ships/rotor.obj",0.2,4);
+
+
+  this->velocity = Vector(0.0,0.0,0.0);
+  this->velocityDir = Vector(1.0,0.0,0.0);
+
+  // very, very old stuff
+  //  GLGuiButton* button = new GLGuiPushButton();
+  //  button->show();
+  //  button->setLabel("orxonox");
+  //  button->setBindNode(this);
+
+  //add events to the eventlist
+  registerEvent(KeyMapper::PEV_FORWARD);
+  registerEvent(KeyMapper::PEV_BACKWARD);
+  registerEvent(KeyMapper::PEV_LEFT);
+  registerEvent(KeyMapper::PEV_RIGHT);
+  registerEvent(SDLK_e);
+  registerEvent(SDLK_c);
+  registerEvent(KeyMapper::PEV_FIRE1);
+  registerEvent(KeyMapper::PEV_NEXT_WEAPON);
+  registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
+  registerEvent(EV_MOUSE_MOTION);
+
+  this->getWeaponManager().setSlotCount(7);
+
+  this->getWeaponManager().setSlotPosition(0, Vector(0.0, .1, -1.0));
+  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(1, Vector(0.0, .1, 1.0));
+  this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(2, Vector(-1.5, .5, -.5));
+  this->getWeaponManager().setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(3, Vector(-1.5, .5, .5));
+  this->getWeaponManager().setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(4, Vector(-1.5, -.5, .5));
+  this->getWeaponManager().setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(5, Vector(-1.5, -.5, -.5));
+  this->getWeaponManager().setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(6, Vector(-1, 0.0, 0));
+  this->getWeaponManager().setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().getFixedTarget()->setParent(&(this->cameraNode));
+  this->getWeaponManager().getFixedTarget()->setRelCoor(0,0,0);
+
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+}
+
+/**
+ * loads the Settings of a Helicopter from an XML-element.
+ * @param root the XML-element to load the Spaceship's properties from
+ */
+void Helicopter::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+void Helicopter::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( true);
+  State::getCameraNode()->setParentSoft(this->getWeaponManager().getFixedTarget());
+  State::getCameraTargetNode()->setParentSoft(this->getWeaponManager().getFixedTarget());
+
+  this->soundSource.play(this->chopperBuffer, 0.7f, true);
+}
+
+void Helicopter::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+  this->detachCamera();
+  this->soundSource.stop();
+}
+
+
+/**
+ *  effect that occurs after the Helicopter is spawned
+*/
+void Helicopter::postSpawn ()
+{
+  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
+}
+
+/**
+ *  the action occuring if the helicopter left the game
+*/
+void Helicopter::leftWorld ()
+{}
+
+/**
+ *  this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void Helicopter::collidesWith(WorldEntity* entity, const Vector& location)
+{
+}
+
+
+
+/**
+ *  the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+*/
+void Helicopter::tick (float time)
+{
+  Playable::tick(time);
+
+  if( xMouse != 0 || yMouse != 0)
+   {
+    if (xMouse > controlVelocityX) xMouse = controlVelocityX;
+    else if (xMouse < -controlVelocityX) xMouse = -controlVelocityX;
+    if (yMouse > controlVelocityY) yMouse = controlVelocityY;
+    else if (yMouse < -controlVelocityY) yMouse = -controlVelocityY;
+  }
+
+  // rotorrotation
+  this->topRotor.shiftDir(Quaternion(time*10, Vector(0,1,0)));
+  this->tailRotor.shiftDir(Quaternion(time*10, Vector(0,1,0)));
+
+  // spaceship controlled movement
+  this->calculateVelocity(time);
+
+  Vector move = (velocity)*time;
+
+  // this is the air friction (necessary for a smooth control)
+  if(velocity.len() != 0) velocity -= velocity*0.1;
+
+
+  //readjust
+  // if (this->getAbsDirZ().y > 0.1) this->shiftDir(Quaternion(time*0.3, Vector(1,0,0)));
+  // else if (this->getAbsDirZ().y < -0.1) this->shiftDir(Quaternion(-time*0.3, Vector(1,0,0)));
+
+
+  this->shiftCoor (move);
+}
+
+/**
+ *  calculate the velocity
+ * @param time the timeslice since the last frame
+*/
+void Helicopter::calculateVelocity (float time)
+{
+  Vector accel(0.0, 0.0, 0.0);
+  float rotValX = 0.0;
+  float rotValZ = 0.0;
+  /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */
+  /* calculate the direction in which the craft is heading  */
+
+  if( this->bUp )
+   {
+     //this->shiftCoor(this->getAbsDirX());
+     //accel -= this->getAbsDirY();
+
+     accel += Vector((this->getAbsDirX()).x,0,(this->getAbsDirX()).z) * 3;
+     if((this->getAbsDirX()).y >= -0.1) rotValZ -= time;
+   }
+   else
+   {
+       if(this->getAbsDirX().y < -.02) this->shiftDir(Quaternion(time, Vector(0,0,1))) ;
+   }
+
+  if( this->bDown )
+   {
+     //this->shiftCoor((this->getAbsDirX())*-1);
+     //accel -= this->getAbsDirY();
+
+     accel -= Vector((this->getAbsDirX()).x,0,(this->getAbsDirX()).z)*3;
+     rotValZ += time;
+   }
+   else
+   {
+         if(this->getAbsDirX().y > 0.02) this->shiftDir(Quaternion(-time, Vector(0,0,1)));
+   }
+
+  if( this->bLeft )
+  {
+    //this->shiftDir(Quaternion(time, Vector(0,1,0)));
+    //accel -= this->getAbsDirY();
+    //velocityDir.normalize();
+
+    accel -= Vector((this->getAbsDirZ()).x,0,(this->getAbsDirZ()).z);
+    rotValX -= time;
+  }
+  else
+   {
+         if(this->getAbsDirZ().y > 0.02) this->shiftDir(Quaternion(time, Vector(1,0,0)));
+   }
+
+  if( this->bRight )
+  {
+    //this->shiftDir(Quaternion(-time, Vector(0,1,0)));
+    //accel += this->getAbsDirY();
+    //velocityDir.normalize();
+
+    accel += Vector((this->getAbsDirZ()).x,0,(this->getAbsDirZ()).z);
+    rotValX += time;
+  }
+  else
+   {
+         if(this->getAbsDirZ().y < -0.02) this->shiftDir(Quaternion(-time, Vector(1,0,0)));
+   }
+
+  if( this->bRollL )
+  {
+    this->shiftDir(Quaternion(-time, Vector(1,0,0)));
+  }
+  if( this->bRollR )
+  {
+    this->shiftDir(Quaternion(time, Vector(1,0,0)));
+  }
+  if (this->bAscend )
+  {
+    accel += this->getAbsDirY();
+  }
+
+  if (this->bDescend )
+  {
+    accel -= this->getAbsDirY();
+  }
+
+  velocity += accel*3;
+  if((this->getAbsDirX()).y <= 0.3 && (this->getAbsDirX()).y >= -0.3) this->shiftDir(Quaternion(rotValZ, Vector(0,0,1)));
+  if((this->getAbsDirZ()).y <= 0.3 && (this->getAbsDirZ()).y >= -0.3) this->shiftDir(Quaternion(rotValX, Vector(1,0,0)));
+}
+
+
+void Helicopter::draw() const
+{
+  WorldEntity::draw();
+
+  glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+
+    /* translate */
+    glTranslatef (this->topRotor.getAbsCoor ().x,
+                  this->topRotor.getAbsCoor ().y,
+                  this->topRotor.getAbsCoor ().z);
+    Vector tmpRot = this->topRotor.getAbsDir().getSpacialAxis();
+    glRotatef (this->topRotor.getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+    this->getModel(3)->draw();
+
+    glPopMatrix ();
+    glPushMatrix();
+
+    /* translate */
+    glTranslatef (this->tailRotor.getAbsCoor ().x,
+                  this->tailRotor.getAbsCoor ().y,
+                  this->tailRotor.getAbsCoor ().z);
+    tmpRot = this->tailRotor.getAbsDir().getSpacialAxis();
+    glRotatef (this->tailRotor.getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+    this->getModel(4)->draw();
+
+    glPopMatrix ();
+}
+
+/**
+ * @todo switch statement ??
+ */
+void Helicopter::process(const Event &event)
+{
+  Playable::process(event);
+
+  if( event.type == KeyMapper::PEV_LEFT)
+      this->bLeft = event.bPressed;
+  else if( event.type == KeyMapper::PEV_RIGHT)
+      this->bRight = event.bPressed;
+  else if( event.type == SDLK_e)
+    this->bAscend = event.bPressed;
+  else if( event.type == SDLK_c)
+    this->bDescend = event.bPressed;
+  else if( event.type == KeyMapper::PEV_FORWARD)
+    this->bUp = event.bPressed;
+  else if( event.type == KeyMapper::PEV_BACKWARD)
+    this->bDown = event.bPressed;
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+    this->xMouse = event.xRel*mouseSensitivity;
+    this->yMouse = event.yRel*mouseSensitivity;
+
+    this->shiftDir(Quaternion(-M_PI/4*xMouse*mouseSensitivity, Vector(0,1,0)));
+
+    Quaternion yDir = Quaternion(-M_PI/4*yMouse*mouseSensitivity, Vector(0,0,1));
+
+
+    if ((this->cameraNode.getAbsDirY()).y < 0.5)
+    {
+     if((this->cameraNode.getAbsDirX()).y > 0)
+     {
+        if(yMouse > 0) this->cameraNode.shiftDir(yDir);
+     }
+     else
+     {
+         if(yMouse < 0) this->cameraNode.shiftDir(yDir);
+     }
+    }
+    else this->cameraNode.shiftDir(yDir);;
+    }
+}
Index: branches/heathaze/src/world_entities/space_ships/helicopter.h
===================================================================
--- branches/heathaze/src/world_entities/space_ships/helicopter.h	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/helicopter.h	(revision 9940)
@@ -0,0 +1,86 @@
+
+/*!
+ * @file helicopter.h
+ * Implements the Control of a Helicopter
+ */
+
+#ifndef _HELICOPTER_H
+#define _HELICOPTER_H
+
+#include "playable.h"
+
+#include "sound_buffer.h"
+#include "sound_source.h"
+
+#include "script_class.h"
+
+class Helicopter : public Playable
+{
+  ObjectListDeclaration(Helicopter);
+
+  public:
+
+    Helicopter();
+    Helicopter(const std::string& fileName);
+    Helicopter(const TiXmlElement* root);
+    virtual ~Helicopter();
+
+    virtual void loadParams(const TiXmlElement* root);
+    virtual void setPlayDirection(const Quaternion& rot, float speed = 0.0f) {/* FIXME */};
+
+    virtual void enter();
+    virtual void leave();
+
+    virtual void postSpawn();
+    virtual void leftWorld();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+    virtual void tick(float time);
+    virtual void draw() const;
+
+    virtual void process(const Event &event);
+
+    virtual void moveUp(bool move){bAscend = move;};
+    virtual void moveDown(bool move){bDescend = move;};
+
+
+
+  private:
+    void init();
+    void calculateVelocity(float time);
+
+    bool                  bUp;                //!< up button pressed.
+    bool                  bDown;              //!< down button pressed.
+    bool                  bLeft;              //!< left button pressed.
+    bool                  bRight;             //!< right button pressed.
+    bool                  bAscend;            //!< ascend button pressed.
+    bool                  bDescend;           //!< descend button presses.
+    bool                  bFire;              //!< fire button pressed.
+    bool                  bRollL;             //!< rolling button pressed (left)
+    bool                  bRollR;             //!< rolling button pressed (right)
+
+    float                 xMouse;             //!< mouse moved in x-Direction
+    float                 yMouse;             //!< mouse moved in y-Direction
+    int                   yInvert;
+    float                 mouseSensitivity;   //!< the mouse sensitivity
+    int                   controlVelocityX;   //!< defines max velocity of Xaxis of mousecontrol
+    int                   controlVelocityY;   //!< defines max velocity of Yaxis of mousecontrol
+
+    PNode                 topRotor;           //!< the position of the toprotor
+    PNode                 tailRotor;          //!< the position of the tailrotor
+
+    PNode                 cameraNode;         //!< the position the camera is locked at (used to look up and down without turning the helicopter)
+
+    Vector                velocity;           //!< the velocity of the player.
+    Vector                velocityDir;        //!< the direction of the velocity of the spaceship
+    float                 travelSpeed;        //!< the current speed of the player (to make soft movement)
+    float                 acceleration;       //!< the acceleration of the player.
+
+    float                 airViscosity;
+
+    OrxSound::SoundSource  soundSource;
+    OrxSound::SoundBuffer  chopperBuffer;
+
+};
+
+#endif /* _HELICOPTERS_H */
Index: branches/heathaze/src/world_entities/space_ships/hover.cc
===================================================================
--- branches/heathaze/src/world_entities/space_ships/hover.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/hover.cc	(revision 9940)
@@ -0,0 +1,442 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "hover.h"
+
+#include "weapons/weapon_manager.h"
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+
+#include "util/loading/factory.h"
+//#include "util/loading/resource_manager.h"
+
+#include "key_mapper.h"
+#include "state.h"
+
+#include "graphics_engine.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Hover, CL_HOVER);
+CREATE_FACTORY(Hover);
+
+#include "script_class.h"
+CREATE_SCRIPTABLE_CLASS(Hover,
+			addMethod("hasPlayer", Executor0ret<Playable, lua_State*,bool>(&Playable::hasPlayer))
+                        //Coordinates
+			    ->addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
+			    ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
+			    ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
+			    ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
+                       );
+
+/**
+ *  destructs the hover, deletes alocated memory
+ */
+Hover::~Hover ()
+{
+  this->setPlayer(NULL);
+
+  //if (this->hoverBuffer != NULL)
+  //  ResourceManager::getInstance()->unload(this->hoverBuffer);
+}
+
+/**
+ * loads a Hover information from a specified file.
+ * @param fileName the name of the File to load the hover from (absolute path)
+ */
+Hover::Hover(const std::string& fileName)
+{
+  this->init();
+  TiXmlDocument doc(fileName);
+
+  if(!doc.LoadFile())
+  {
+    PRINTF(2)("Loading file %s failed for Hover.\n", fileName.c_str());
+    return;
+  }
+
+  this->loadParams(doc.RootElement());
+
+  //load sound
+  //if (this->hoverBuffer != NULL)
+  //  ResourceManager::getInstance()->unload(this->hoverBuffer);
+  //this->hoverBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/engine/hover.wav", WAV);
+
+}
+
+/**
+ *  creates a new Spaceship from Xml Data
+ * @param root the xml element containing spaceship data
+
+   @todo add more parameters to load
+*/
+Hover::Hover(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+  //weapons:
+  Weapon* wpRight = new TestGun(0);
+  wpRight->setName("testGun Right");
+  Weapon* wpLeft = new TestGun(1);
+  wpLeft->setName("testGun Left");
+  Weapon* cannon = dynamic_cast<Weapon*>(Factory::fabricate("Hyperblaster"));
+
+  cannon->setName("BFG");
+
+  this->addWeapon(wpLeft, 1, 0);
+  this->addWeapon(wpRight,1 ,1);
+  this->addWeapon(cannon, 0, 2);
+
+  this->getWeaponManager().changeWeaponConfig(1);
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+  this->loadModel("models/ships/hoverglider_mainbody.obj");
+}
+
+
+/**
+ * initializes a Hover
+ */
+void Hover::init()
+{
+
+  //this->hitEntity = NULL;
+  //this->hoverBuffer = NULL;
+
+  //  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->registerObject(this, Hover::_objectList);
+  this->toReflectionList();
+
+  this->loadModel("models/ships/hoverglider_wing.obj", 1.0f, 3);
+  this->loadModel("models/ships/hoverglider_rotor.obj", 1.0f, 4);
+  this->loadModel("models/ships/rotor.obj", .45f, 5);
+
+  bForward = bBackward = bLeft = bRight = bAscend = bDescend = false;
+  mouseSensitivity = 0.005;
+
+  this->rotorSpeed = 1000.0f;
+  this->rotorCycle = 0.0f;
+  this->cameraLook = 0.0f;
+  this->rotation = 0.0f;
+  this->acceleration = 15.0f;
+  this->airFriction = 3.0f;
+
+  // camera - issue
+  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
+  //this->cameraNode.setParentMode(PNODE_ROTATE_MOVEMENT);
+  this->cameraNode.setParent(this);
+
+  // rotors
+  this->wingNodeLeft.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT );
+  this->wingNodeLeft.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
+  this->wingNodeLeft.setParent(this);
+  this->wingNodeLeft.setRelCoor(-1.5, -.3, -1.0);
+  this->rotorNodeLeft.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->rotorNodeLeft.setParent(&this->wingNodeLeft);
+  this->rotorNodeLeft.setRelCoor(0, 1.0, -2.3);
+
+  this->wingNodeRight.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->wingNodeRight.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
+  this->wingNodeRight.setParent(this);
+  this->wingNodeRight.setRelCoor(-1.5, -0.3, 1.0);
+  this->rotorNodeRight.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->rotorNodeRight.setParent(&this->wingNodeRight);
+  this->rotorNodeRight.setRelCoor(0, 1.0, 2.3);
+
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+
+  //add events to the eventlist
+  registerEvent(KeyMapper::PEV_FORWARD);
+  registerEvent(KeyMapper::PEV_BACKWARD);
+  registerEvent(KeyMapper::PEV_LEFT);
+  registerEvent(KeyMapper::PEV_RIGHT);
+  registerEvent(KeyMapper::PEV_UP);
+  registerEvent(KeyMapper::PEV_DOWN);
+  registerEvent(KeyMapper::PEV_FIRE1);
+  registerEvent(KeyMapper::PEV_NEXT_WEAPON);
+  registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
+  registerEvent(EV_MOUSE_MOTION);
+
+
+  // WEAPON_MANAGER configuration
+  this->getWeaponManager().setSlotCount(5);
+
+  this->getWeaponManager().setSlotPosition(0, Vector(-0.28, 1.186, -2.750), &this->wingNodeLeft);
+  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(1, Vector(-0.28, 1.186, 2.750), &this->wingNodeRight);
+  this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(2, Vector(-1.63, .809, -.003));
+  this->getWeaponManager().setSlotCapability(2, WTYPE_HEAVY);
+
+  /// TODO: THESE ARE TOO MUCH
+  this->getWeaponManager().setSlotPosition(3, Vector(-1.63, .678, -.652));
+  this->getWeaponManager().setSlotDirection(3, Quaternion(-24/180 * M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(4, Vector(-1.63, .678, .652));
+  this->getWeaponManager().setSlotDirection(4, Quaternion(24/180 * M_PI, Vector(1,0,0)));
+
+  this->cameraNode.setRelCoor(1,5,0);
+  this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
+  this->getWeaponManager().getFixedTarget()->setRelCoor(1000,0,0);
+
+  // NETWORK THINGS
+
+  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bAscend, &bAscend, "bAscend", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bDescend, &bDescend, "bDescend", PERMISSION_OWNER ) );
+
+  registerVar( new SynchronizeableFloat( &rotation, &rotation, "rotation", PERMISSION_OWNER ) );
+}
+
+/**
+ * loads the Settings of a Hover from an XML-element.
+ * @param root the XML-element to load the Spaceship's properties from
+ */
+void Hover::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+
+void Hover::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( true);
+
+  State::getCameraNode()->setParentSoft(&this->cameraNode);
+  State::getCameraNode()->setRelCoorSoft(-10, 0,0);
+  State::getCameraTargetNode()->setParentSoft(&this->cameraNode);
+
+  //this->soundSource.play(this->hoverBuffer, 0.3f, true);
+
+}
+
+void Hover::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+  this->detachCamera();
+
+}
+
+
+/**
+ *  effect that occurs after the Hover is spawned
+*/
+void Hover::postSpawn ()
+{
+  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
+}
+
+/**
+ *  the action occuring if the hover left the game
+*/
+void Hover::leftWorld ()
+{}
+
+/**
+ *  this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void Hover::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  Playable::collidesWith(entity, location);
+}
+
+
+
+/**
+ *  the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+*/
+void Hover::tick (float dt)
+{
+  Playable::tick(dt);
+
+  // spaceship controlled movement
+  this->movement(dt);
+  this->rotorCycle += this->rotorSpeed * dt;
+}
+
+/**
+ *  calculate the velocity
+ * @param time the timeslice since the last frame
+*/
+void Hover::movement (float dt)
+{
+  Vector accel(0.0, 0.0, 0.0);
+
+  if( this->bForward )
+  {
+    accel += Vector(this->acceleration, 0, 0);
+  }
+
+  if( this->bBackward )
+  {
+    accel -= Vector(this->acceleration, 0, 0);
+  }
+  if( this->bLeft)
+  {
+    accel -= Vector(0, 0, this->acceleration);
+  }
+
+  if( this->bRight)
+  {
+    accel += Vector(0, 0, this->acceleration);
+  }
+
+  if (this->bAscend )
+  {
+    accel += Vector(0, this->acceleration, 0);
+  }
+  if (this->bDescend )
+  {
+    accel -= Vector(0, this->acceleration, 0);
+  }
+
+  Vector accelerationDir = this->getAbsDir().apply(accel * this->acceleration);
+
+  // this is the air friction (necessary for a smooth control)
+  Vector damping = (this->velocity * this->airFriction);
+
+
+  this->velocity += (accelerationDir - damping)* dt;
+
+  this->shiftCoor (this->velocity * dt);
+
+  // limit the maximum rotation speed.
+  if (this->rotation != 0.0f)
+  {
+    float maxRot = 10.0 * dt;
+    if (unlikely(this->rotation > maxRot)) this->rotation = maxRot;
+    if (unlikely(this->rotation < -maxRot)) this->rotation = -maxRot;
+    this->direction *= Quaternion(-M_PI/4.0*this->rotation, Vector(0,1,0));
+    this->rotation = 0.0f;
+  }
+
+  this->setRelDirSoft(this->direction * Quaternion(-cameraLook, Vector(0,0,1)), 5);
+
+  this->wingNodeLeft.setRelDirSoft(Quaternion(accel.z * .03 +this->rotation, Vector(1,0,0)), 5);
+  this->rotorNodeLeft.setRelDirSoft(Quaternion(-accel.x * .05+this->rotation + cameraLook, Vector(0,0,1)), 5);
+
+  this->wingNodeRight.setRelDirSoft(Quaternion(accel.z * .03 +this->rotation, Vector(1,0,0)), 5);
+  this->rotorNodeRight.setRelDirSoft(Quaternion(-accel.x*.05 -this->rotation + cameraLook, Vector(0,0,1)), 5);
+}
+
+
+void Hover::draw() const
+{
+  Vector tmpRot;
+  WorldEntity::draw();
+
+  glPushMatrix();
+  /// LEFT SIDE
+  glTranslatef (this->wingNodeLeft.getAbsCoor ().x,
+                this->wingNodeLeft.getAbsCoor ().y,
+                this->wingNodeLeft.getAbsCoor ().z);
+  tmpRot = this->wingNodeLeft.getAbsDir().getSpacialAxis();
+  glRotatef (this->wingNodeLeft.getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  this->getModel(3)->draw();
+  glPopMatrix ();
+
+  glPushMatrix();
+  glTranslatef (this->rotorNodeLeft.getAbsCoor ().x,
+                this->rotorNodeLeft.getAbsCoor ().y,
+                this->rotorNodeLeft.getAbsCoor ().z);
+  tmpRot = this->rotorNodeLeft.getAbsDir().getSpacialAxis();
+  glRotatef (this->rotorNodeLeft.getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  this->getModel(4)->draw();
+  glTranslatef(0,-1,0);
+  glRotatef(this->rotorCycle, 0,1,0);
+  this->getModel(5)->draw();
+  glPopMatrix ();
+
+  /// RIGHT SIDE
+  glPushMatrix();
+  glTranslatef (this->wingNodeRight.getAbsCoor ().x,
+                this->wingNodeRight.getAbsCoor ().y,
+                this->wingNodeRight.getAbsCoor ().z);
+  tmpRot = this->wingNodeRight.getAbsDir().getSpacialAxis();
+  glRotatef (this->wingNodeRight.getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  glScalef(1,1,-1);
+  this->getModel(3)->draw();
+  glPopMatrix ();
+
+  glPushMatrix();
+  glTranslatef (this->rotorNodeRight.getAbsCoor ().x,
+                this->rotorNodeRight.getAbsCoor ().y,
+                this->rotorNodeRight.getAbsCoor ().z);
+  tmpRot = this->rotorNodeRight.getAbsDir().getSpacialAxis();
+  glRotatef (this->rotorNodeRight.getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  glScalef(1,1,-1);
+  this->getModel(4)->draw();
+  glTranslatef(0,-1,0);
+  glRotatef(this->rotorCycle, 0,1,0);
+  this->getModel(5)->draw();
+  glPopMatrix ();
+}
+
+/**
+ * @todo switch statement ??
+ */
+void Hover::process(const Event &event)
+{
+  Playable::process(event);
+
+  if( event.type == KeyMapper::PEV_LEFT)
+    this->bLeft = event.bPressed;
+  else if( event.type == KeyMapper::PEV_RIGHT)
+    this->bRight = event.bPressed;
+  else if( event.type == KeyMapper::PEV_UP)
+    this->bAscend = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == KeyMapper::PEV_DOWN)
+    this->bDescend = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == KeyMapper::PEV_FORWARD)
+    this->bForward = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == KeyMapper::PEV_BACKWARD)
+    this->bBackward = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+    float xMouse, yMouse;
+    xMouse = event.xRel*mouseSensitivity;
+    yMouse = event.yRel*mouseSensitivity;
+
+    // rotate the Player around the y-axis
+    this->rotation += xMouse;
+
+    this->cameraLook += yMouse;
+    // rotate the Camera around the z-axis
+    if (cameraLook > M_PI_4)
+      cameraLook = M_PI_4;
+    else if (cameraLook < -M_PI_4)
+      cameraLook = -M_PI_4;
+    //this->cameraNode.setRelDirSoft(this->direction,10);
+  }
+}
Index: branches/heathaze/src/world_entities/space_ships/hover.h
===================================================================
--- branches/heathaze/src/world_entities/space_ships/hover.h	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/hover.h	(revision 9940)
@@ -0,0 +1,80 @@
+
+/*!
+ * @file hover.h
+ * Implements the Control of a Hover
+ */
+
+#ifndef _HOVER_H
+#define _HOVER_H
+
+//#include "sound_buffer.h"
+//#include "sound_source.h"
+
+#include "playable.h"
+
+class Hover : public Playable
+{
+  ObjectListDeclaration(Hover);
+  public:
+
+    Hover(const std::string& fileName);
+    Hover(const TiXmlElement* root = NULL);
+    virtual ~Hover();
+
+    virtual void loadParams(const TiXmlElement* root);
+    virtual void setPlayDirection(const Quaternion& rot, float speed = 0.0f) {/* FIXME */};
+
+    virtual void enter();
+    virtual void leave();
+
+    virtual void postSpawn();
+    virtual void leftWorld();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+    virtual void process(const Event &event);
+
+  private:
+    void init();
+    void movement(float dt);
+
+  private:
+    bool                  bForward;           //!< forward button pressed.
+    bool                  bBackward;          //!< backward button pressed.
+    bool                  bLeft;              //!< left button pressed.
+    bool                  bRight;             //!< right button pressed.
+    bool                  bAscend;            //!< ascend button pressed.
+    bool                  bDescend;           //!< descend button presses.
+
+    int                   yInvert;
+    float                 mouseSensitivity;   //!< the mouse sensitivity
+
+    PNode                 wingNodeLeft;
+    PNode                 wingNodeRight;
+    PNode                 rotorNodeLeft;
+    PNode                 rotorNodeRight;
+
+    PNode                 cameraNode;
+    float                 cameraLook;
+    float                 rotation;
+
+    Vector                velocity;           //!< the velocity of the Hover.
+    Quaternion            direction;          //!< the direction of the Hover.
+    float                 travelSpeed;        //!< the current speed of the Hove (to make soft movement)
+    float                 acceleration;       //!< the acceleration of the Hover.
+    float                 airFriction;        //!< AirFriction.
+
+    float                 rotorSpeed;         //!< the speed of the rotor.
+    float                 rotorCycle;         //!< The Cycle the rotor is in.
+
+    float                 airViscosity;
+
+    WorldEntity*          hitEntity;
+
+    //OrxSound::SoundSource  soundSource;
+    //OrxSound::SoundBuffer* hoverBuffer;
+};
+
+#endif /* _HOVERS_H */
Index: branches/heathaze/src/world_entities/space_ships/space_ship.cc
===================================================================
--- branches/heathaze/src/world_entities/space_ships/space_ship.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/space_ship.cc	(revision 9940)
@@ -0,0 +1,524 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Knecht
+   co-programmer: Silvan Nellen
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "executor/executor.h"
+#include "space_ship.h"
+
+#include "util/loading/resource_manager.h"
+
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include "util/loading/factory.h"
+#include "key_mapper.h"
+
+#include "network_game_manager.h"
+#include "shared_network_data.h"
+
+#include "power_ups/weapon_power_up.h"
+#include "power_ups/param_power_up.h"
+
+#include "graphics_engine.h"
+
+#include "plane.h"
+
+#include "state.h"
+#include "player.h"
+
+#include "util/loading/load_param.h"
+
+
+// #include "lib/gui/gl_gui/glgui_bar.h"
+// #include "lib/gui/gl_gui/glgui_pushbutton.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(SpaceShip, CL_SPACE_SHIP);
+CREATE_FACTORY(SpaceShip);
+
+#include "script_class.h"
+CREATE_SCRIPTABLE_CLASS(SpaceShip,
+                        addMethod("hasPlayer", Executor0ret<Playable, lua_State*,bool>(&Playable::hasPlayer))
+                        ->addMethod("fire", Executor1<Playable, lua_State*, bool>(&Playable::fire))
+                        ->addMethod("loadModel", Executor2<WorldEntity, lua_State*,const std::string& ,float>(&WorldEntity::loadModel2))
+                        ->addMethod("setName", Executor1<BaseObject, lua_State*,const std::string&>(&BaseObject::setName))
+                        ->addMethod("hide", Executor0<WorldEntity, lua_State*>(&WorldEntity::hide))
+                        ->addMethod("unhide", Executor0<WorldEntity, lua_State*>(&WorldEntity::unhide))
+                        //Coordinates
+                        ->addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
+                        ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
+                        ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
+                        ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
+                       );
+
+/**
+ *  destructs the spaceship, deletes alocated memory
+ */
+SpaceShip::~SpaceShip ()
+{
+  this->setPlayer(NULL);
+}
+
+/**
+ * loads a Spaceships information from a specified file.
+ * @param fileName the name of the File to load the spaceship from (absolute path)
+ */
+SpaceShip::SpaceShip(const std::string& fileName)
+{
+  this->init();
+  TiXmlDocument doc(fileName);
+
+  if(!doc.LoadFile())
+  {
+    PRINTF(2)("Loading file %s failed for spaceship.\n", fileName.c_str());
+    return;
+  }
+
+  this->loadParams(doc.RootElement());
+}
+
+/**
+ *  creates a new Spaceship from Xml Data
+ * @param root the xml element containing spaceship data
+
+   @todo add more parameters to load
+*/
+SpaceShip::SpaceShip(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+}
+
+
+/**
+ * initializes a Spaceship
+ */
+void SpaceShip::init()
+{
+  //  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->registerObject(this, SpaceShip::_objectList);
+
+  PRINTF(4)("SPACESHIP INIT\n");
+
+  //weapons:
+  Weapon* wpRight = new TestGun(0);
+  wpRight->setName("testGun Right");
+  Weapon* wpLeft = new TestGun(1);
+  wpLeft->setName("testGun Left");
+  //Weapon* cannon = dynamic_cast<Weapon*>(Factory::fabricate(CL_CANNON));
+
+  //cannon->setName("BFG");
+
+  this->addWeapon(wpLeft, 1, 0);
+  this->addWeapon(wpRight,1 ,1);
+  //this->addWeapon(cannon, 0, 6);
+
+  this->getWeaponManager().changeWeaponConfig(1);
+
+  bUp = bDown = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = false;
+
+  xMouse = yMouse = 0;
+  yInvert = 1;
+  mouseSensitivity = 0.001;
+  airViscosity = 0.9;
+  controlVelocityX = 25;
+  controlVelocityY = 150;
+  shipInertia = 1.5;
+  //  cycle = 0.0;
+
+  this->setHealthMax(100);
+  this->setHealth(80);
+
+  travelSpeed = 0.0;
+  acceleration = 3;
+  this->velocity = this->getAbsDirX()*travelSpeed;
+  this->mouseDir = this->getAbsDir();
+  this->pitchDir = this->getAbsDir();
+
+  //   GLGuiButton* button = new GLGuiPushButton();
+  //    button->show();
+  //    button->setLabel("orxonox");
+  //    button->setBindNode(this);
+  //     GLGuiBar* bar = new GLGuiBar();
+  //     bar->show();
+  //     bar->setValue(7.0);
+  //     bar->setMaximum(10);
+  //     bar->setSize2D( 20, 100);
+  //     bar->setAbsCoor2D( 10, 200);
+
+  //add events to the eventlist
+  registerEvent(KeyMapper::PEV_FORWARD);
+  registerEvent(KeyMapper::PEV_BACKWARD);
+  registerEvent(KeyMapper::PEV_LEFT);
+  registerEvent(KeyMapper::PEV_RIGHT);
+  //registerEvent(SDLK_q);
+  //registerEvent(SDLK_e);
+  registerEvent(KeyMapper::PEV_FIRE1);
+  registerEvent(KeyMapper::PEV_NEXT_WEAPON);
+  registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
+  //registerEvent(SDLK_PAGEUP);
+  //registerEvent(SDLK_PAGEDOWN);
+  registerEvent(EV_MOUSE_MOTION);
+
+  this->getWeaponManager().setSlotCount(7);
+
+  this->getWeaponManager().setSlotPosition(0, Vector(-2.6, .1, -3.0));
+  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(1, Vector(-2.6, .1, 3.0));
+  this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(2, Vector(-1.5, .5, -.5));
+  this->getWeaponManager().setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(3, Vector(-1.5, .5, .5));
+  this->getWeaponManager().setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(4, Vector(-1.5, -.5, .5));
+  this->getWeaponManager().setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(5, Vector(-1.5, -.5, -.5));
+  this->getWeaponManager().setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
+  //
+  this->getWeaponManager().setSlotPosition(6, Vector(-1, 0.0, 0));
+  this->getWeaponManager().setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+  //
+  //   this->getWeaponManager().setSlotPosition(8, Vector(-2.5, -0.3, -2.0));
+  //   this->getWeaponManager().setSlotDirection(8, Quaternion(-M_PI, Vector(1,0,0)));
+  //
+  //   this->getWeaponManager().setSlotPosition(9, Vector(-2.5, -0.3, 2.0));
+  //   this->getWeaponManager().setSlotDirection(9, Quaternion(+M_PI, Vector(1,0,0)));:
+
+  this->getWeaponManager().getFixedTarget()->setParent(this);
+  this->getWeaponManager().getFixedTarget()->setRelCoor(100000,0,0);
+
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+  this->burstEmitter = new DotEmitter(200, 0.0, .01);
+  this->burstEmitter->setParent(this);
+  this->burstEmitter->setRelCoor(-1, .5, 0);
+  this->burstEmitter->setName("SpaceShip_Burst_emitter");
+
+  this->burstSystem = new SpriteParticles(1000);
+  this->burstSystem->addEmitter(this->burstEmitter);
+  this->burstSystem->setName("SpaceShip_Burst_System");
+  ((SpriteParticles*)this->burstSystem)->setMaterialTexture("maps/radial-trans-noise.png");
+  this->burstSystem->setLifeSpan(1.0, .3);
+  this->burstSystem->setRadius(0.0, 1.0);
+  this->burstSystem->setRadius(0.05, 1.0);
+  this->burstSystem->setRadius(.5, .8);
+  this->burstSystem->setRadius(1.0, 0);
+  this->burstSystem->setColor(0.0, .7,.7,1,.7);
+  this->burstSystem->setColor(0.2, 0,0,0.8,.5);
+  this->burstSystem->setColor(0.5, .5,.5,.8,.8);
+  this->burstSystem->setColor(1.0, .8,.8,.8,.0);
+
+  registerVar( new SynchronizeableVector( &velocity, &velocity, "velocity", PERMISSION_MASTER_SERVER ) );
+  registerVar( new SynchronizeableQuaternion( &mouseDir, &mouseDir, "mousedir", PERMISSION_OWNER ) );
+
+  registerVar( new SynchronizeableBool( &bUp, &bUp, "bUp", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bDown, &bDown, "bDown", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bAscend, &bAscend, "bAscend", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bDescend, &bDescend, "bDescend", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRollL, &bRollL, "bRollL", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRollR, &bRollR, "bRollR", PERMISSION_OWNER ) );
+}
+
+
+/**
+ * loads the Settings of a SpaceShip from an XML-element.
+ * @param root the XML-element to load the Spaceship's properties from
+ */
+void SpaceShip::loadParams(const TiXmlElement* root)
+{
+  Playable::loadParams(root);
+}
+
+void SpaceShip::setPlayDirection(const Quaternion& quat, float speed)
+{
+  this->mouseDir = quat;
+}
+
+
+void SpaceShip::reset()
+{
+  bUp = bDown = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = false;
+
+  xMouse = yMouse = 0;
+
+  this->setHealth(80);
+  this->velocity = Vector(0.0, 0.0, 0.0);
+}
+
+
+void SpaceShip::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( true);
+  this->attachCamera();
+}
+
+void SpaceShip::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+  this->detachCamera();
+}
+
+
+/**
+ *  effect that occurs after the SpaceShip is spawned
+*/
+void SpaceShip::postSpawn ()
+{
+  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
+}
+
+/**
+ *  the action occuring if the spaceship left the game
+*/
+void SpaceShip::leftWorld ()
+{}
+
+WorldEntity* ref = NULL;
+/**
+ *  this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void SpaceShip::collidesWith(WorldEntity* entity, const Vector& location)
+{
+}
+
+/**
+ *  draws the spaceship after transforming it.
+*/
+void SpaceShip::draw () const
+{
+  WorldEntity::draw();
+
+  //this->debug(0);
+}
+
+/**
+ *  the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+*/
+void SpaceShip::tick (float time)
+{
+  Playable::tick(time);
+
+  if( ( xMouse != 0 || yMouse != 0 ) && this->getOwner() == SharedNetworkData::getInstance()->getHostID() )
+  {
+    if (xMouse > controlVelocityX) xMouse = controlVelocityX;
+    else if (xMouse < -controlVelocityX) xMouse = -controlVelocityX;
+    if (yMouse > controlVelocityY) yMouse = controlVelocityY;
+    else if (yMouse < -controlVelocityY) yMouse = -controlVelocityY;
+
+    pitchDir = (Quaternion(xMouse*mouseSensitivity*0.5, Vector(1,0,0)));
+
+    mouseDir *= (Quaternion(-M_PI/4*xMouse*mouseSensitivity, Vector(0,1,0))*Quaternion(-M_PI/4*yMouse*mouseSensitivity*yInvert, Vector(0,0,1))*pitchDir);
+    xMouse = yMouse = 0;
+  }
+
+
+  //   if( this != State::getPlayer()->getControllable())
+  //     return;
+
+  // spaceship controlled movement fire(bool bF){ this->bFire = bF;}
+  //if (this->getOwner() == this->getHostID())
+  this->calculateVelocity(time);
+
+
+  Vector move = velocity*time;
+
+  //orient the velocity in the direction of the spaceship.
+  travelSpeed = velocity.len();
+  velocity += ((this->getAbsDirX())*travelSpeed-velocity)*airViscosity;
+  velocity = (velocity.getNormalized())*travelSpeed;
+  this->burstEmitter->setEmissionRate(travelSpeed);
+  this->burstEmitter->setEmissionVelocity(travelSpeed*.5, travelSpeed *.1);
+
+  //orient the spaceship in direction of the mouse
+  rotQuat = Quaternion::quatSlerp( this->getAbsDir(), mouseDir, 0.5);//fabsf(time)*shipInertia);
+  if (this->getAbsDir().distance(rotQuat) > 0.00000000000001)
+    this->setAbsDir( rotQuat);
+  //this->setAbsDirSoft(mouseDir,5);
+
+  // this is the air friction (necessary for a smooth control)
+  if(travelSpeed >= 120) velocity -= velocity.getNormalized()*travelSpeed*travelSpeed*0.0001;
+  else if (travelSpeed <= 80) velocity -= velocity.getNormalized()*travelSpeed*0.001;
+
+  //other physics (gravity)
+  //if(travelSpeed < 120)
+  //move += Vector(0,-1,0)*60*time + Vector(0,1,0)*travelSpeed/2*time;
+
+  //hoover effect
+  //cycle += time;
+  //this->shiftCoor(Vector(0,1,0)*cos(this->cycle*2.0)*0.02);
+
+  //readjust
+  //if (this->getAbsDirZ().y > 0.1) this->shiftDir(Quaternion(time*0.3, Vector(1,0,0)));
+  //else if (this->getAbsDirZ().y < -0.1) this->shiftDir(Quaternion(-time*0.3, Vector(1,0,0)));
+
+  //SDL_WarpMouse(GraphicsEngine::getInstance()->getResolutionX()/2, GraphicsEngine::getInstance()->getResolutionY()/2);
+
+  this->shiftCoor(move);
+
+  //   PRINTF(0)("id of %s is: %i\n", this->getName(), this->getOMListNumber());
+
+}
+
+/**
+ *  calculate the velocity
+ * @param time the timeslice since the last frame
+*/
+void SpaceShip::calculateVelocity (float time)
+{
+  Vector accel(0.0, 0.0, 0.0);
+  /*
+  Vector rot(0.0, 0.0, 0.0); // wird ben�igt fr Helicopter
+  */
+  //float rotVal = 0.0;
+  /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */
+  /* calculate the direction in which the craft is heading  */
+
+  //Plane plane(Vector(0,1,0), Vector(0,0,0));
+
+  if( this->bUp )
+  {
+    //this->shiftCoor(this->getAbsDirX());
+    //accel += (this->getAbsDirX())*2;
+    accel += (this->getAbsDirX())*acceleration;
+
+  }
+
+  if( this->bDown )
+  {
+    //this->shiftCoor((this->getAbsDirX())*-1);
+    //accel -= (this->getAbsDirX())*2;
+    //if(velocity.len() > 50)
+    accel -= (this->getAbsDirX())*0.5*acceleration;
+
+
+
+  }
+
+  if( this->bLeft/* > -this->getRelCoor().z*2*/)
+  {
+    this->shiftDir(Quaternion(time, Vector(0,1,0)));
+    //    accel -= rightDirection;
+    //velocityDir.normalize();
+    //rot +=Vector(1,0,0);
+    //rotVal -= .4;
+  }
+  if( this->bRight /* > this->getRelCoor().z*2*/)
+  {
+    this->shiftDir(Quaternion(-time, Vector(0,1,0)));
+
+    //    accel += rightDirection;
+    //velocityDir.normalize();
+    //rot += Vector(1,0,0);
+    //rotVal += .4;
+  }
+
+
+  if( this->bRollL /* > -this->getRelCoor().z*2*/)
+  {
+    mouseDir *= Quaternion(-time*2, Vector(1,0,0));
+    //    accel -= rightDirection;
+    //velocityDir.normalize();
+    //rot +=Vector(1,0,0);
+    //rotVal -= .4;
+  }
+  if( this->bRollR /* > this->getRelCoor().z*2*/)
+  {
+    mouseDir *= Quaternion(time*2, Vector(1,0,0));
+
+    //    accel += rightDirection;
+    //velocityDir.normalize();
+    //rot += Vector(1,0,0);
+    //rotVal += .4;
+  }
+  if (this->bAscend )
+  {
+    this->shiftDir(Quaternion(time, Vector(0,0,1)));
+
+    //    accel += upDirection;
+    //velocityDir.normalize();
+    //rot += Vector(0,0,1);
+    //rotVal += .4;
+  }
+  if (this->bDescend )
+  {
+    this->shiftDir(Quaternion(-time, Vector(0,0,1)));
+
+    //    accel -= upDirection;
+    //velocityDir.normalize();
+    //rot += Vector(0,0,1);
+    //rotVal -= .4;
+  }
+
+  velocity += accel*time*10;
+  //rot.normalize();
+  //this->setRelDirSoft(Quaternion(rotVal, rot), 5);
+}
+
+/**
+ * @todo switch statement ??
+ */
+void SpaceShip::process(const Event &event)
+{
+  Playable::process(event);
+
+  if( event.type == KeyMapper::PEV_LEFT)
+    this->bRollL = event.bPressed;
+  else if( event.type == KeyMapper::PEV_RIGHT)
+    this->bRollR = event.bPressed;
+  else if( event.type == KeyMapper::PEV_FORWARD)
+    this->bUp = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == KeyMapper::PEV_BACKWARD)
+    this->bDown = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+    this->xMouse += event.xRel;
+    this->yMouse += event.yRel;
+  }
+}
+
+void SpaceShip::destroy( WorldEntity* killer )
+{
+  PRINTF(0)("spaceship destroy\n");
+}
+
+void SpaceShip::respawn( )
+{
+  toList( OM_PLAYERS );
+}
+
+
+
+
Index: branches/heathaze/src/world_entities/space_ships/space_ship.h
===================================================================
--- branches/heathaze/src/world_entities/space_ships/space_ship.h	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/space_ship.h	(revision 9940)
@@ -0,0 +1,90 @@
+/*!
+ * @file space_ship.h
+ * Implements the Control of a Spaceship
+ */
+
+#ifndef _SPACE_SHIP_H
+#define _SPACE_SHIP_H
+
+#include "playable.h"
+#include "extendable.h"
+
+// Forward Declaration
+template<class T> class tList;
+class Vector;
+class Event;
+class ParticleEmitter;
+class ParticleSystem;
+
+class SpaceShip : public Playable
+{
+  ObjectListDeclaration(SpaceShip);
+
+  public:
+    SpaceShip(const std::string& fileName);
+    SpaceShip(const TiXmlElement* root = NULL);
+    virtual ~SpaceShip();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void setPlayDirection(const Quaternion& rot, float speed = 0.0f);
+
+    virtual void enter();
+    virtual void leave();
+
+    virtual void reset();
+
+    virtual void postSpawn();
+    virtual void leftWorld();
+
+    virtual void destroy(WorldEntity* killer);
+    virtual void respawn();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+    virtual void tick(float time);
+    virtual void draw() const;
+
+    virtual void process(const Event &event);
+
+  private:
+    void init();
+
+    void calculateVelocity(float time);
+
+    bool                  bUp;                //!< up button pressed.
+    bool                  bDown;              //!< down button pressed.
+    bool                  bLeft;              //!< left button pressed.
+    bool                  bRight;             //!< right button pressed.
+    bool                  bAscend;            //!< ascend button pressed.
+    bool                  bDescend;           //!< descend button presses.
+//    bool                  bFire;              //!< fire button pressed.(moved to playable)
+    bool                  bRollL;             //!< rolling button pressed (left)
+    bool                  bRollR;             //!< rolling button pressed (right)
+
+    float                 xMouse;             //!< mouse moved in x-Direction
+    float                 yMouse;             //!< mouse moved in y-Direction
+    float                 mouseSensitivity;   //!< the mouse sensitivity
+    int                   yInvert;
+    int                   controlVelocityX;
+    int                   controlVelocityY;
+//    float                 cycle;              //!< hovercycle
+
+    Vector                velocity;           //!< the velocity of the player.
+    Vector                oldVelocity;        //!< the velocity the player had last synced
+    Quaternion            mouseDir;           //!< the direction where the player wants to fly
+    Quaternion            oldMouseDir;        //!< the direction where the player wanted to fly
+    float                 shipInertia;        //!< the inertia of the ship(how fast the ship reacts to a mouse input)
+    Quaternion            rotQuat;
+    Quaternion            pitchDir;
+    float                 travelSpeed;        //!< the current speed of the player (to make soft movement)
+    float                 acceleration;       //!< the acceleration of the player.
+
+    float                 airViscosity;
+
+    byte                  oldMask;            //!< used for synchronisation
+
+    ParticleEmitter*      burstEmitter;
+    ParticleSystem*       burstSystem;
+};
+
+#endif /* _SPACE_SHIPS_H */
Index: branches/heathaze/src/world_entities/space_ships/spacecraft_2d.cc
===================================================================
--- branches/heathaze/src/world_entities/space_ships/spacecraft_2d.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/spacecraft_2d.cc	(revision 9940)
@@ -0,0 +1,525 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "spacecraft_2d.h"
+
+#include "weapons/weapon_manager.h"
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+#include "key_mapper.h"
+#include "state.h"
+
+#include "graphics_engine.h"
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include "debug.h"
+
+#include "script_class.h"
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Spacecraft2D, CL_SPACECRAFT_2D);
+CREATE_FACTORY(Spacecraft2D);
+
+CREATE_SCRIPTABLE_CLASS(Spacecraft2D,
+			addMethod("hasPlayer", Executor0ret<Playable, lua_State*,bool>(&Playable::hasPlayer))
+                        //Coordinates
+			    ->addMethod("setAbsCoor", Executor3<PNode, lua_State*,float,float,float>(&PNode::setAbsCoor))
+			    ->addMethod("getAbsCoorX", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorX))
+			    ->addMethod("getAbsCoorY", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorY))
+			    ->addMethod("getAbsCoorZ", Executor0ret<PNode, lua_State*, float>(&PNode::getAbsCoorZ))
+			    ->addMethod("setAirFriction", Executor1<Spacecraft2D, lua_State*, float>(&Spacecraft2D::setAirFriction))
+                       );
+
+
+
+/**
+ * @brief loads a Spacecraft2D information from a specified file.
+ * @param fileName the name of the File to load the spacecraft_2d from (absolute path)
+ */
+Spacecraft2D::Spacecraft2D(const std::string& fileName)
+{
+  this->init();
+  TiXmlDocument doc(fileName);
+
+  if(!doc.LoadFile())
+  {
+    PRINTF(2)("Loading file %s failed for Spacecraft2D.\n", fileName.c_str());
+    return;
+  }
+
+  this->loadParams(doc.RootElement());
+}
+
+/**
+ * @brief creates a new Spaceship from Xml Data
+ * @param root the xml element containing spaceship data
+
+   @todo add more parameters to load
+*/
+Spacecraft2D::Spacecraft2D(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+
+
+  //weapons:
+  Weapon* wpRight = dynamic_cast<Weapon*>(Factory::fabricate("LaserCannon"));
+  wpRight->setName("Cannon_Right");
+  Weapon* wpLeft = dynamic_cast<Weapon*>(Factory::fabricate("LaserCannon"));
+  wpLeft->setName("Cannon_Left");
+
+  Weapon* turretLeft = dynamic_cast<Weapon*>(Factory::fabricate("BoomerangGun"));
+  wpRight->setName("Turret_Left");
+  Weapon* turretRight = dynamic_cast<Weapon*>(Factory::fabricate("BoomerangGun"));
+  wpLeft->setName("Turret_Right");
+
+  //  cannon->setName("BFG");
+
+  this->addWeapon(wpLeft, 1, 0);
+  this->addWeapon(wpRight,1 ,1);
+  this->addWeapon(turretLeft, 1, 2);
+  this->addWeapon(turretRight, 1, 3);
+
+  //this->addWeapon(cannon, 0, 2);
+
+  this->getWeaponManager().changeWeaponConfig(1);
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+}
+
+
+/**
+ * @brief destructs the spacecraft_2d, deletes alocated memory
+ */
+Spacecraft2D::~Spacecraft2D ()
+{
+  this->setPlayer(NULL);
+  delete this->toTravelHeight;
+}
+
+
+/**
+ * @brief initializes a Spacecraft2D
+ */
+void Spacecraft2D::init()
+{
+  //  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->registerObject(this, Spacecraft2D::_objectList);
+
+  this->setSupportedPlaymodes(Playable::Full3D | Playable::Horizontal );
+
+  bForward = bBackward = bLeft = bRight = false;
+  mouseSensitivity = 0.005;
+
+  this->cameraLook = 0.0f;
+  this->rotation = 0.0f;
+  this->acceleration = 20.0f;
+  this->airFriction = 0.0f;
+
+
+  this->setHealthMax(1000);
+  this->setHealth(1000);
+  this->setDamage(100.0f);
+
+
+
+  /// 2D-MODE
+  this->toTravelHeight = NULL;
+  this->travelSpeed = 0.0f;
+  this->travelNode = new PNode();
+
+  this->loadModel("models/ships/mantawing.obj", 5.0f);
+
+  // camera - issue
+  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
+  //this->cameraNode.setParentMode(PNODE_ROTATE_MOVEMENT);
+  //this->cameraNode.setParent(this);
+
+  // PARTICLES
+  this->burstEmitter = new DotEmitter(200, 5.0, .01);
+  this->burstEmitter->setParent(this);
+  this->burstEmitter->setRelCoor(0, -0.7, 0);
+  this->burstEmitter->setRelDir(Quaternion(-M_PI, Vector(0,0,1)));
+  this->burstEmitter->setName("Spacecraft2D_Burst_emitter_Left");
+
+  this->burstSystem = new SpriteParticles(1000);
+  this->burstSystem->addEmitter(this->burstEmitter);
+  this->burstSystem->setName("SpaceShip_Burst_System");
+  ((SpriteParticles*)this->burstSystem)->setMaterialTexture("maps/radial-trans-noise.png");
+  this->burstSystem->setLifeSpan(1.0, .3);
+  this->burstSystem->setRadius(0.0, 1.5);
+  this->burstSystem->setRadius(0.05, 1.8);
+  this->burstSystem->setRadius(.5, .8);
+  this->burstSystem->setRadius(1.0, 0);
+  this->burstSystem->setColor(0.0, .7,.7,1,.5);
+  this->burstSystem->setColor(0.2, 0,0,0.8,.5);
+  this->burstSystem->setColor(0.5, .5,.5,.8,.3);
+  this->burstSystem->setColor(1.0, .8,.8,.8,.0);
+
+
+  //add events to the eventlist of the Playable
+  this->registerEvent(KeyMapper::PEV_FORWARD);
+  this->registerEvent(KeyMapper::PEV_BACKWARD);
+  this->registerEvent(KeyMapper::PEV_LEFT);
+  this->registerEvent(KeyMapper::PEV_RIGHT);
+  this->registerEvent(KeyMapper::PEV_FIRE1);
+  this->registerEvent(KeyMapper::PEV_NEXT_WEAPON);
+  this->registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
+  this->registerEvent(EV_MOUSE_MOTION);
+
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+  // WEAPON_MANAGER configuration
+  this->getWeaponManager().setSlotCount(5);
+
+  this->getWeaponManager().setSlotPosition(0, Vector(1.843, -0.335, 2.029) * 5.0);
+  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(1, Vector(1.843, -0.335, -2.029) * 5.0);
+  this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  /// TODO: THESE ARE TOO MUCH
+  this->getWeaponManager().setSlotPosition(2, Vector(-0.351, -.238, 1.406) * 5.0);
+  this->getWeaponManager().setSlotDirection(2, Quaternion(-1.7, Vector(0,1,0)));
+
+  this->getWeaponManager().setSlotPosition(3, Vector(-0.351, -.238, -1.406) * 5.0);
+  this->getWeaponManager().setSlotDirection(3, Quaternion(1.7, Vector(0,1,0)));
+
+  this->cameraNode.setRelCoor(1,5,0);
+  this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
+  this->getWeaponManager().getFixedTarget()->setRelCoor(1000,0,0);
+
+  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
+  //registerVar( new SynchronizeableQuaternion( &direction, &direction, "direction", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableFloat( &cameraLook, &cameraLook, "cameraLook", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableFloat( &rotation, &rotation, "rotation", PERMISSION_OWNER ) );
+
+
+
+}
+
+/**
+ * @brief loads the Settings of a Spacecraft2D from an XML-element.
+ * @param root the XML-element to load the Spaceship's properties from
+ */
+void Spacecraft2D::loadParams(const TiXmlElement* root)
+{
+  Playable::loadParams(root);
+
+  LoadParam(root, "travel-speed", this, Spacecraft2D, setTravelSpeed);
+  LoadParam(root, "travel-height", this, Spacecraft2D, setTravelHeight);
+  LoadParam(root, "travel-distance", this, Spacecraft2D, setTravelDistance);
+}
+
+void Spacecraft2D::setPlayDirection(const Quaternion& rot, float speed)
+{
+  this->direction = Quaternion (rot.getHeading(), Vector(0,1,0));
+}
+
+void Spacecraft2D::setTravelSpeed(float travelSpeed)
+{
+  this->travelSpeed = travelSpeed;
+}
+
+
+void Spacecraft2D::setTravelHeight(float travelHeight)
+{
+  if (this->toTravelHeight == NULL)
+    this->toTravelHeight = new float;
+  *this->toTravelHeight = travelHeight;
+}
+
+
+void Spacecraft2D::setTravelDistance(const Vector2D& distance)
+{
+  this->travelDistance = distance;
+}
+
+void Spacecraft2D::setTravelDistance(float x, float y)
+{
+  this->setTravelDistance(Vector2D(x, y));
+}
+
+
+
+void Spacecraft2D::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( true);
+  this->setPlaymode(this->getPlaymode());
+}
+
+void Spacecraft2D::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+  this->detachCamera();
+
+}
+
+
+void Spacecraft2D::enterPlaymode(Playable::Playmode playmode)
+{
+  switch(playmode)
+  {
+    case Playable::Full3D:
+      if (State::getCameraNode != NULL)
+      {
+        Vector absCoor = this->getAbsCoor();
+        this->setParent(PNode::getNullParent());
+        this->setAbsCoor(absCoor);
+        State::getCameraNode()->setParentSoft(&this->cameraNode);
+        State::getCameraNode()->setRelCoorSoft(-10, 0,0);
+        State::getCameraTargetNode()->setParentSoft(&this->cameraNode);
+        State::getCameraTargetNode()->setRelCoorSoft(100, 0,0);
+
+      }
+      break;
+
+
+    case Playable::Horizontal:
+      if (State::getCameraNode != NULL)
+      {
+        this->debugNode(1);
+        this->travelNode->debugNode(1);
+
+        this->travelNode->setAbsCoor(this->getAbsCoor());
+        this->travelNode->updateNode(0.01f);
+
+        this->setParent(this->travelNode);
+        this->setRelCoor(0,0,0);
+
+        State::getCameraNode()->setParentSoft(this->travelNode);
+        State::getCameraNode()->setRelCoorSoft(-3, 100,0);
+        State::getCameraTargetNode()->setParentSoft(this->travelNode);
+        State::getCameraTargetNode()->setRelCoorSoft(5,0,1);
+
+
+        this->debugNode(1);
+        this->travelNode->debugNode(1);
+      }
+      break;
+
+    default:
+      PRINTF(2)("Playmode %s Not Implemented in %s\n", Playable::playmodeToString(this->getPlaymode()).c_str(), this->getClassCName());
+  }
+}
+
+
+
+/**
+ * @brief effect that occurs after the Spacecraft2D is spawned
+*/
+void Spacecraft2D::postSpawn ()
+{
+  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
+}
+
+/**
+ * @brief the action occuring if the spacecraft_2d left the game
+*/
+void Spacecraft2D::leftWorld ()
+{}
+
+/**
+ * @brief this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void Spacecraft2D::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  Playable::collidesWith(entity, location);
+}
+
+
+
+/**
+ * @brief the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+*/
+void Spacecraft2D::tick (float dt)
+{
+  //  this->debugNode(1);
+  Playable::tick(dt);
+
+  // spaceship controlled movement
+  this->movement(dt);
+
+  // TRYING TO FIX PNode.
+  this->cameraNode.setAbsCoorSoft(this->getAbsCoor() + Vector(0.0f, 5.0f, 0.0f), 30.0f);
+  this->cameraNode.setRelDirSoft(this->getAbsDir(), 30.0f);
+}
+
+/**
+ * @brief calculate the velocity
+ * @param time the timeslice since the last frame
+*/
+void Spacecraft2D::movement (float dt)
+{
+  Vector accel(0.0, 0.0, 0.0);
+
+  if( this->bForward )
+  {
+    accel += Vector(this->acceleration, 0, 0);
+  }
+
+  if( this->bBackward )
+  {
+    accel -= Vector(this->acceleration, 0, 0);
+  }
+  if( this->bLeft)
+  {
+    accel -= Vector(0, 0, this->acceleration);
+  }
+
+  if( this->bRight)
+  {
+    accel += Vector(0, 0, this->acceleration);
+  }
+
+  switch(this->getPlaymode())
+  {
+    case Playable::Full3D:
+      {
+        Vector accelerationDir = this->getAbsDir().apply(accel * this->acceleration);
+
+        // this is the air friction (necessary for a smooth control)
+        Vector damping = (this->velocity * this->airFriction);
+
+
+        this->velocity += (accelerationDir - damping)* dt;
+        this->shiftCoor (this->velocity * dt);
+
+        // limit the maximum rotation speed.
+        if (this->rotation != 0.0f)
+        {
+          float maxRot = 10.0 * dt;
+          if (unlikely(this->rotation > maxRot)) this->rotation = maxRot;
+          if (unlikely(this->rotation < -maxRot)) this->rotation = -maxRot;
+          this->direction *= Quaternion(-M_PI/4.0*this->rotation, Vector(0,1,0));
+
+          this->rotation = 0.0f;
+        }
+
+        this->setRelDirSoft(this->direction * Quaternion(-cameraLook, Vector(0,0,1)), 5);
+      }
+      break;
+
+    case Playable::Horizontal:
+      {
+
+        if (this->toTravelHeight != NULL)
+        {
+          this->travelNode->shiftCoor(Vector(0, (*toTravelHeight - this->travelNode->getAbsCoor().y) * dt * 10.0, 0));
+          if (fabsf(this->travelNode->getAbsCoor().y - *this->toTravelHeight) < .1)
+          {
+            delete this->toTravelHeight;
+            this->toTravelHeight = NULL;
+          }
+        }
+        this->travelNode->shiftCoor(Vector(this->travelSpeed * dt, 0, 0));
+
+        accel.y = 0.0;
+
+        Vector accelerationDir = this->getAbsDir().apply(accel * this->acceleration);
+        accelerationDir.y = 0.0;
+
+        // this is the air friction (necessary for a smooth control)
+        Vector damping = (this->velocity * this->airFriction);
+
+
+        this->velocity += (accelerationDir - damping)* dt;
+
+        if (this->getRelCoor().z > this->travelDistance.y && velocity.z > 0.0)
+          this->velocity.z = 0.0f;
+        if (this->getRelCoor().z < -this->travelDistance.y && velocity.z < 0.0)
+          this->velocity.z = 0.0f;
+
+        if (this->getRelCoor().x > this->travelDistance.x && velocity.x > 0.0)
+          this->velocity.x = 0.0f;
+        if (this->getRelCoor().x < -this->travelDistance.x && velocity.x < 0.0)
+          this->velocity.x = 0.0f;
+
+
+        this->shiftCoor (this->velocity * dt);
+        if (accel.z == 0)
+          this->setRelDirSoft(Quaternion(0, Vector(0,0,0)), 5.0f);
+        else
+          this->setRelDirSoft(Quaternion(this->velocity.z * .004, Vector(1,0,0)), 4.5f);
+      }
+      break;
+
+    default:
+      PRINTF(2)("Playmode %s Not Implemented in %s\n", Playable::playmodeToString(this->getPlaymode()).c_str(), this->getClassCName());
+  }
+}
+
+
+void Spacecraft2D::draw() const
+{
+  WorldEntity::draw();
+}
+
+/**
+ * @todo switch statement ??
+ */
+void Spacecraft2D::process(const Event &event)
+{
+  Playable::process(event);
+
+  if( event.type == KeyMapper::PEV_LEFT)
+    this->bLeft = event.bPressed;
+  else if( event.type == KeyMapper::PEV_RIGHT)
+    this->bRight = event.bPressed;
+  else if( event.type == KeyMapper::PEV_FORWARD)
+    this->bForward = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == KeyMapper::PEV_BACKWARD)
+  {this->bBackward = event.bPressed; printf(" %f, %f, %f \n",getAbsCoorX(),getAbsCoorY(),getAbsCoorZ());} //this->shiftCoor(0,-.1,0);
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+
+
+
+    if (this->getPlaymode() == Playable::Full3D)
+    {
+      float xMouse, yMouse;
+      xMouse = event.xRel*mouseSensitivity;
+      yMouse = event.yRel*mouseSensitivity;
+
+      // rotate the Player around the y-axis
+      this->rotation += xMouse;
+
+      this->cameraLook += yMouse;
+      // rotate the Camera around the z-axis
+      if (cameraLook > M_PI_4)
+        cameraLook = M_PI_4;
+      else if (cameraLook < -M_PI_4)
+        cameraLook = -M_PI_4;
+    }
+  }
+}
Index: branches/heathaze/src/world_entities/space_ships/spacecraft_2d.h
===================================================================
--- branches/heathaze/src/world_entities/space_ships/spacecraft_2d.h	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/spacecraft_2d.h	(revision 9940)
@@ -0,0 +1,89 @@
+
+/*!
+ * @file spacecraft_2d.h
+ * Implements the Control of a Spacecraft2D
+ */
+
+#ifndef _SPACECRAFT_2D_H
+#define _SPACECRAFT_2D_H
+
+#include "playable.h"
+
+// Forward Declaration
+class ParticleEmitter;
+class ParticleSystem;
+
+class Spacecraft2D : public Playable
+{
+  ObjectListDeclaration(Spacecraft2D);
+  public:
+    Spacecraft2D(const std::string& fileName);
+    Spacecraft2D(const TiXmlElement* root = NULL);
+    virtual ~Spacecraft2D();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    void setTravelSpeed(float travelSpeed);
+    void setTravelHeight(float travelHeight);
+    void setTravelDistance(const Vector2D& distance);
+    void setTravelDistance(float x, float y);
+
+    void setAirFriction(float friction) { this->airFriction = friction; };
+
+
+    virtual void setPlayDirection(const Quaternion& rot, float speed = 0.0f);
+    virtual void enter();
+    virtual void leave();
+
+
+    virtual void postSpawn();
+    virtual void leftWorld();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+    virtual void process(const Event &event);
+
+  protected:
+    virtual void enterPlaymode(Playable::Playmode playmode);
+
+  private:
+    void init();
+    void movement(float dt);
+
+  private:
+    bool                  bForward;           //!< forward button pressed.
+    bool                  bBackward;          //!< backward button pressed.
+    bool                  bLeft;              //!< left button pressed.
+    bool                  bRight;             //!< right button pressed.
+
+    int                   yInvert;
+    float                 mouseSensitivity;   //!< the mouse sensitivity
+
+    /// Normal Movement.
+    Quaternion            direction;          //!< the direction of the Spacecraft2D.
+    float                 acceleration;       //!< the acceleration of the Spacecraft2D.
+    float                 airFriction;        //!< AirFriction.
+
+    float                 airViscosity;
+
+
+    /// 2D-traveling
+    PNode*                travelNode;
+    float*                toTravelHeight;
+    float                 travelSpeed;        //!< the current speed of the Hove (to make soft movement)
+
+    Vector2D              travelDistance;     //!< Travel-Distance away from the TravelNode.
+
+    /// Camera
+    PNode                 cameraNode;
+    float                 cameraLook;
+    float                 rotation;
+
+
+    ParticleEmitter*      burstEmitter;
+    ParticleSystem*       burstSystem;
+};
+
+#endif /* _SPACECRAFT_2DS_H */
Index: branches/heathaze/src/world_entities/space_ships/turbine_hover.cc
===================================================================
--- branches/heathaze/src/world_entities/space_ships/turbine_hover.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/turbine_hover.cc	(revision 9940)
@@ -0,0 +1,587 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "turbine_hover.h"
+
+#include "weapons/weapon_manager.h"
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+
+#include "util/loading/factory.h"
+#include "key_mapper.h"
+#include "state.h"
+
+#include "graphics_engine.h"
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(TurbineHover, CL_TURBINE_HOVER);
+CREATE_FACTORY(TurbineHover);
+
+/**
+ *  destructs the turbine_hover, deletes alocated memory
+ */
+TurbineHover::~TurbineHover ()
+{
+  this->setPlayer(NULL);
+}
+
+/**
+ * @brief loads a TurbineHover information from a specified file.
+ * @param fileName the name of the File to load the turbine_hover from (absolute path)
+ */
+TurbineHover::TurbineHover(const std::string& fileName)
+{
+  this->init();
+  TiXmlDocument doc(fileName);
+
+  if(!doc.LoadFile())
+  {
+    PRINTF(2)("Loading file %s failed for TurbineHover.\n", fileName.c_str());
+    return;
+  }
+
+  this->loadParams(doc.RootElement());
+}
+
+/**
+ * @brief creates a new Spaceship from Xml Data
+ * @param root the xml element containing spaceship data
+
+   @todo add more parameters to load
+*/
+TurbineHover::TurbineHover(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+  //weapons:
+  Weapon* wpRight = new TestGun(0);
+  wpRight->setName("testGun Right");
+  Weapon* wpLeft = new TestGun(1);
+  wpLeft->setName("testGun Left");
+  //Weapon* cannon = dynamic_cast<Weapon*>(Factory::fabricate(CL_HYPERBLASTER));
+
+  //  cannon->setName("BFG");
+
+  this->addWeapon(wpLeft, 1, 0);
+  this->addWeapon(wpRight,1 ,1);
+  //this->addWeapon(cannon, 0, 2);
+
+  this->getWeaponManager().changeWeaponConfig(1);
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+  this->loadModel("models/ships/hoverglider_mainbody.obj");
+
+}
+
+
+/**
+ * @brief initializes a TurbineHover
+ */
+void TurbineHover::init()
+{
+  //  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->registerObject(this, TurbineHover::_objectList);
+
+  this->setSupportedPlaymodes(Playable::Full3D | Playable::Horizontal | Playable::Vertical);
+
+  this->loadModel("models/ships/hoverglider_wing.obj", 1.0f, 3);
+  this->loadModel("models/ships/hoverglider_turbine.obj", 1.0f, 4);
+  this->loadModel("models/ships/hoverglider_turbine_rotors.obj", 1.0f, 5);
+
+  bForward = bBackward = bLeft = bRight = bAscend = bDescend = false;
+  mouseSensitivity = 0.005;
+
+  this->rotorSpeed = 1000.0f;
+  this->rotorCycle = 0.0f;
+  this->cameraLook = 0.0f;
+  this->rotation = 0.0f;
+  this->acceleration = 10.0f;
+  this->airFriction = 2.0f;
+
+  this->setHealthMax(100);
+  this->setHealth(100);
+
+
+  // camera - issue
+  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->cameraNode.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
+  //this->cameraNode.setParentMode(PNODE_ROTATE_MOVEMENT);
+  this->cameraNode.setParent(this);
+  this->cameraNode.setRelCoor(0,5,0);
+
+  // rotors
+  this->wingNodeLeft.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT );
+  this->wingNodeLeft.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
+  this->wingNodeLeft.setParent(this);
+  this->wingNodeLeft.setRelCoor(-1.5, -.3, -1.0);
+  this->rotorNodeLeft.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->rotorNodeLeft.setParent(&this->wingNodeLeft);
+  this->rotorNodeLeft.setRelCoor(0, 1.0, -2.3);
+
+  this->wingNodeRight.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->wingNodeRight.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE);
+  this->wingNodeRight.setParent(this);
+  this->wingNodeRight.setRelCoor(-1.5, -0.3, 1.0);
+  this->rotorNodeRight.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->rotorNodeRight.setParent(&this->wingNodeRight);
+  this->rotorNodeRight.setRelCoor(0, 1.0, 2.3);
+
+  // PARTICLES
+  this->burstEmitter[0] = new DotEmitter(200, 5.0, .01);
+  this->burstEmitter[0]->setParent(&this->rotorNodeLeft);
+  this->burstEmitter[0]->setRelCoor(0, -0.7, 0);
+  this->burstEmitter[0]->setRelDir(Quaternion(-M_PI_2, Vector(0,0,1)));
+  this->burstEmitter[0]->setName("TurbineHover_Burst_emitter_Left");
+
+  this->burstEmitter[1] = new DotEmitter(200, 5.0, .01);
+  this->burstEmitter[1]->setParent(&this->rotorNodeRight);
+  this->burstEmitter[1]->setRelCoor(0, -0.7, 0);
+  this->burstEmitter[1]->setRelDir(Quaternion(-M_PI_2, Vector(0,0,1)));
+  this->burstEmitter[1]->setName("TurbineHover_Burst_emitter_Right");
+
+
+  this->burstSystem = new SpriteParticles(1000);
+  this->burstSystem->addEmitter(this->burstEmitter[0]);
+  this->burstSystem->addEmitter(this->burstEmitter[1]);
+  this->burstSystem->setName("SpaceShip_Burst_System");
+  ((SpriteParticles*)this->burstSystem)->setMaterialTexture("maps/radial-trans-noise.png");
+  this->burstSystem->setLifeSpan(1.0, .3);
+  this->burstSystem->setRadius(0.0, 1.5);
+  this->burstSystem->setRadius(0.05, 1.8);
+  this->burstSystem->setRadius(.5, .8);
+  this->burstSystem->setRadius(1.0, 0);
+  this->burstSystem->setColor(0.0, .7,.7,1,.5);
+  this->burstSystem->setColor(0.2, 0,0,0.8,.5);
+  this->burstSystem->setColor(0.5, .5,.5,.8,.3);
+  this->burstSystem->setColor(1.0, .8,.8,.8,.0);
+
+
+  //add events to the eventlist of the Playable
+  this->registerEvent(KeyMapper::PEV_FORWARD);
+  this->registerEvent(KeyMapper::PEV_BACKWARD);
+  this->registerEvent(KeyMapper::PEV_LEFT);
+  this->registerEvent(KeyMapper::PEV_RIGHT);
+  this->registerEvent(KeyMapper::PEV_UP);
+  this->registerEvent(KeyMapper::PEV_DOWN);
+  this->registerEvent(KeyMapper::PEV_FIRE1);
+  this->registerEvent(KeyMapper::PEV_NEXT_WEAPON);
+  this->registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
+  this->registerEvent(EV_MOUSE_MOTION);
+
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+  // WEAPON_MANAGER configuration
+  this->getWeaponManager().setSlotCount(5);
+
+  this->getWeaponManager().setSlotPosition(0, Vector(-0.28, 1.186, -2.750), &this->wingNodeLeft);
+  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(1, Vector(-0.28, 1.186, 2.750), &this->wingNodeRight);
+  this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(2, Vector(-1.63, .809, -.003));
+  this->getWeaponManager().setSlotCapability(2, WTYPE_HEAVY);
+
+  /// TODO: THESE ARE TOO MUCH
+  this->getWeaponManager().setSlotPosition(3, Vector(-1.63, .678, -.652));
+  this->getWeaponManager().setSlotDirection(3, Quaternion(-24/180 * M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(4, Vector(-1.63, .678, .652));
+  this->getWeaponManager().setSlotDirection(4, Quaternion(24/180 * M_PI, Vector(1,0,0)));
+
+  this->cameraNode.setRelCoor(1,5,0);
+  this->getWeaponManager().getFixedTarget()->setParent(&this->cameraNode);
+  this->getWeaponManager().getFixedTarget()->setRelCoor(1000,0,0);
+
+  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bAscend, &bAscend, "bAscend", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bDescend, &bDescend, "bDescend", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableQuaternion( &direction, &direction, "direction", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableFloat( &cameraLook, &cameraLook, "cameraLook", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableFloat( &rotation, &rotation, "rotation", PERMISSION_OWNER ) );
+
+  if( State::isOnline())
+    toList( OM_PLAYERS );
+}
+
+/**
+ * @brief loads the Settings of a TurbineHover from an XML-element.
+ * @param root the XML-element to load the Spaceship's properties from
+ */
+void TurbineHover::loadParams(const TiXmlElement* root)
+{
+  Playable::loadParams(root);
+}
+
+
+void TurbineHover::setBoostColor(const Color& color)
+{
+  this->burstSystem->setColor(0.0, color);
+  this->burstSystem->setColor(0.2, color * 0.6);
+  this->burstSystem->setColor(0.5, color * .3 + Color(0.5, 0.5, 0.8, 0.3));
+  this->burstSystem->setColor(1.0, 0.8, 0.8, 0.8, 0.0);
+
+  printf(":::::::::::::::::::::::\n");
+  this->burstSystem->debug();
+}
+
+void TurbineHover::setPlayDirection(const Quaternion& rot, float speed)
+{
+  this->direction = Quaternion (rot.getHeading(), Vector(0,1,0));
+}
+
+void TurbineHover::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( true);
+
+  if (State::getCameraNode != NULL)
+  {
+    State::getCameraNode()->setParentSoft(&this->cameraNode);
+    State::getCameraNode()->setRelCoorSoft(-10, 0,0);
+    State::getCameraTargetNode()->setParentSoft(&this->cameraNode);
+  }
+}
+
+void TurbineHover::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+  this->detachCamera();
+
+}
+
+void TurbineHover::setTeam(int teamID)
+{
+  printf("::::::::::::::::: TEAM ::: %d\n", teamID);
+  if (teamID == 0)
+  {
+    this->setBoostColor(Color::blue);
+  }
+  else if (teamID == 1)
+  {
+    this->setBoostColor(Color::red);
+  }
+
+  ///HACK this is very much hard coded.set the owner of the weapons
+  this->getWeaponManager().getWeapon(0)->setOwner(this->getOwner());
+  this->getWeaponManager().getWeapon(1)->setOwner(this->getOwner());
+
+  //choose collision list
+  if( State::isOnline())
+  {
+    if( teamID == 0)
+      toList( OM_GROUP_00 );
+    else if(teamID == 1)
+      toList( OM_GROUP_01);
+  }
+
+
+  // set the local team id, very important
+  this->setTeamId(teamID);
+}
+
+
+
+/**
+ * @brief effect that occurs after the TurbineHover is spawned
+*/
+void TurbineHover::postSpawn ()
+{
+  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
+}
+
+/**
+ * @brief the action occuring if the turbine_hover left the game
+*/
+void TurbineHover::leftWorld ()
+{}
+
+/**
+ * @brief this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void TurbineHover::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  Playable::collidesWith(entity, location);
+}
+
+
+
+/**
+ * @brief the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+*/
+void TurbineHover::tick (float dt)
+{
+  //  this->debugNode(1);
+  Playable::tick(dt);
+
+  // spaceship controlled movement
+
+  // TRYING TO FIX PNode.
+  //this->cameraNode.setRelCoor(Vector(0.0f, 5.0f, 0.0f));//, 30.0f);
+  //this->cameraNode.setRelDir(Quaternion(this->smoothRotator  *10.0, Vector(0,1,0)));
+
+  this->movement(dt);
+  this->rotorCycle += this->rotorSpeed * dt;
+}
+
+
+#include "shared_network_data.h"
+
+/**
+ * @brief calculate the velocity
+ * @param time the timeslice since the last frame
+*/
+void TurbineHover::movement (float dt)
+{
+  Vector accel(0.0, 0.0, 0.0);
+
+  if( this->bForward )
+  {
+    accel += Vector(this->acceleration, 0, 0);
+  }
+
+  if( this->bBackward )
+  {
+    accel -= Vector(this->acceleration, 0, 0);
+  }
+  if( this->bLeft)
+  {
+    accel -= Vector(0, 0, this->acceleration);
+  }
+
+  if( this->bRight)
+  {
+    accel += Vector(0, 0, this->acceleration);
+  }
+
+  if (this->bAscend )
+  {
+    accel += Vector(0, this->acceleration, 0);
+  }
+  if (this->bDescend )
+  {
+    accel -= Vector(0, this->acceleration, 0);
+  }
+
+  switch(this->getPlaymode())
+  {
+    case Playable::Full3D:
+      {
+        Vector accelerationDir = this->getAbsDir().apply(accel * this->acceleration);
+
+        // this is the air friction (necessary for a smooth control)
+        Vector damping = (this->velocity * this->airFriction);
+
+
+        this->velocity += (accelerationDir - damping)* dt;
+        //if (this->getOwner() != SharedNetworkData::getInstance()->getHostID())
+          this->shiftCoor (this->velocity * dt);
+
+        // limit the maximum rotation speed.
+        if (this->rotation != 0.0f)
+        {
+          float maxRot = 10.0 * dt;
+          if (unlikely(this->rotation > maxRot)) this->rotation = maxRot;
+          if (unlikely(this->rotation < -maxRot)) this->rotation = -maxRot;
+          this->direction *= Quaternion(-M_PI/4.0*this->rotation, Vector(0,1,0));
+
+          this->rotation = 0.0f;
+        }
+
+        //if (this->getOwner() != SharedNetworkData::getInstance()->getHostID())
+          this->setRelDirSoft(this->direction * Quaternion(-cameraLook, Vector(0,0,1)), 5);
+
+        this->wingNodeLeft.setRelDirSoft(Quaternion(accel.z * .05 +this->rotation, Vector(1,0,0)), 5);
+        this->rotorNodeLeft.setRelDirSoft(Quaternion(-accel.x * .07+this->rotation + cameraLook, Vector(0,0,1)), 5);
+
+        this->wingNodeRight.setRelDirSoft(Quaternion(accel.z * .05 +this->rotation, Vector(1,0,0)), 5);
+        this->rotorNodeRight.setRelDirSoft(Quaternion(-accel.x*.07 -this->rotation + cameraLook, Vector(0,0,1)), 5);
+      }
+      break;
+
+    case Playable::Horizontal:
+      {
+        accel.y = 0.0;
+        Vector accelerationDir = this->getAbsDir().apply(accel * this->acceleration);
+        accelerationDir.y = 0.0;
+
+        // this is the air friction (necessary for a smooth control)
+        Vector damping = (this->velocity * this->airFriction);
+
+
+        this->velocity += (accelerationDir - damping)* dt;
+        this->shiftCoor (this->velocity * dt);
+
+        // limit the maximum rotation speed.
+        if (this->rotation != 0.0f)
+        {
+          float maxRot = 10.0 * dt;
+          if (unlikely(this->rotation > maxRot)) this->rotation = maxRot;
+          if (unlikely(this->rotation < -maxRot)) this->rotation = -maxRot;
+          this->direction *= Quaternion(-M_PI/4.0*this->rotation, Vector(0,1,0));
+
+          this->rotation = 0.0f;
+        }
+
+        this->setRelDirSoft(this->direction, 5);
+
+        this->wingNodeLeft.setRelDirSoft(Quaternion(accel.z * .05 +this->rotation, Vector(1,0,0)), 5);
+        this->rotorNodeLeft.setRelDirSoft(Quaternion(-accel.x * .07+this->rotation, Vector(0,0,1)), 5);
+
+        this->wingNodeRight.setRelDirSoft(Quaternion(accel.z * .05 +this->rotation, Vector(1,0,0)), 5);
+        this->rotorNodeRight.setRelDirSoft(Quaternion(-accel.x*.07 -this->rotation, Vector(0,0,1)), 5);
+      }
+      break;
+
+    case Playable::Vertical:
+      {
+        accel.z = 0;
+        Vector accelerationDir = this->getAbsDir().apply(accel * this->acceleration);
+        accelerationDir.z=0;
+
+        // this is the air friction (necessary for a smooth control)
+        Vector damping = (this->velocity * this->airFriction);
+
+        this->velocity += (accelerationDir - damping)* dt;
+        this->shiftCoor (this->velocity * dt);
+
+        this->setRelDirSoft(this->direction * Quaternion(-cameraLook, Vector(0,0,1)), 5);
+
+        this->wingNodeLeft.setRelDirSoft(Quaternion(accel.z * .05 +this->rotation, Vector(1,0,0)), 5);
+        this->rotorNodeLeft.setRelDirSoft(Quaternion(-accel.x * .07+this->rotation + cameraLook, Vector(0,0,1)), 5);
+
+        this->wingNodeRight.setRelDirSoft(Quaternion(accel.z * .05 +this->rotation, Vector(1,0,0)), 5);
+        this->rotorNodeRight.setRelDirSoft(Quaternion(-accel.x*.07 -this->rotation + cameraLook, Vector(0,0,1)), 5);
+      }
+      break;
+    default:
+      PRINTF(2)("Playmode %s Not Implemented\n", Playable::playmodeToString(this->getPlaymode()).c_str());
+  }
+}
+
+
+void TurbineHover::draw() const
+{
+  Vector tmpRot;
+  WorldEntity::draw();
+
+  glPushMatrix();
+  /// LEFT SIDE
+  glTranslatef (this->wingNodeLeft.getAbsCoor ().x,
+                this->wingNodeLeft.getAbsCoor ().y,
+                this->wingNodeLeft.getAbsCoor ().z);
+  tmpRot = this->wingNodeLeft.getAbsDir().getSpacialAxis();
+  glRotatef (this->wingNodeLeft.getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  this->getModel(3)->draw();
+  glPopMatrix ();
+
+  glPushMatrix();
+  glTranslatef (this->rotorNodeLeft.getAbsCoor ().x,
+                this->rotorNodeLeft.getAbsCoor ().y,
+                this->rotorNodeLeft.getAbsCoor ().z);
+  tmpRot = this->rotorNodeLeft.getAbsDir().getSpacialAxis();
+  glRotatef (this->rotorNodeLeft.getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  this->getModel(4)->draw();
+  glRotatef(this->rotorCycle, 0,1,0);
+  this->getModel(5)->draw();
+  glPopMatrix ();
+
+  /// RIGHT SIDE
+  glPushMatrix();
+  glTranslatef (this->wingNodeRight.getAbsCoor ().x,
+                this->wingNodeRight.getAbsCoor ().y,
+                this->wingNodeRight.getAbsCoor ().z);
+  tmpRot = this->wingNodeRight.getAbsDir().getSpacialAxis();
+  glRotatef (this->wingNodeRight.getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  glScalef(1,1,-1);
+  this->getModel(3)->draw();
+  glPopMatrix ();
+
+  glPushMatrix();
+  glTranslatef (this->rotorNodeRight.getAbsCoor ().x,
+                this->rotorNodeRight.getAbsCoor ().y,
+                this->rotorNodeRight.getAbsCoor ().z);
+  tmpRot = this->rotorNodeRight.getAbsDir().getSpacialAxis();
+  glRotatef (this->rotorNodeRight.getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  glScalef(1,1,-1);
+  this->getModel(4)->draw();
+  glRotatef(this->rotorCycle, 0,1,0);
+  this->getModel(5)->draw();
+  glPopMatrix ();
+}
+
+/**
+ * @todo switch statement ??
+ */
+void TurbineHover::process(const Event &event)
+{
+  Playable::process(event);
+
+  if( event.type == KeyMapper::PEV_LEFT)
+    this->bLeft = event.bPressed;
+  else if( event.type == KeyMapper::PEV_RIGHT)
+    this->bRight = event.bPressed;
+  else if( event.type == KeyMapper::PEV_UP)
+    this->bAscend = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == KeyMapper::PEV_DOWN)
+    this->bDescend = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == KeyMapper::PEV_FORWARD)
+    this->bForward = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == KeyMapper::PEV_BACKWARD)
+    this->bBackward = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+    float xMouse, yMouse;
+    xMouse = event.xRel*mouseSensitivity;
+    yMouse = event.yRel*mouseSensitivity;
+
+    // rotate the Player around the y-axis
+    this->rotation += xMouse;
+
+    this->cameraLook += yMouse;
+    // rotate the Camera around the z-axis
+    if (cameraLook > M_PI_4)
+      cameraLook = M_PI_4;
+    else if (cameraLook < -M_PI_4)
+      cameraLook = -M_PI_4;
+    //this->cameraNode.setRelDirSoft(this->direction,10);
+  }
+}
+
+
+/**
+ *  respawning function called by the GameRules
+ */
+void TurbineHover::respawn( )
+{
+
+  Playable::respawn();
+}
Index: branches/heathaze/src/world_entities/space_ships/turbine_hover.h
===================================================================
--- branches/heathaze/src/world_entities/space_ships/turbine_hover.h	(revision 9940)
+++ branches/heathaze/src/world_entities/space_ships/turbine_hover.h	(revision 9940)
@@ -0,0 +1,84 @@
+
+/*!
+ * @file turbine_hover.h
+ * Implements the Control of a TurbineHover
+ */
+
+#ifndef _TURBINE_HOVER_H
+#define _TURBINE_HOVER_H
+
+#include "playable.h"
+
+#include "color.h"
+
+// Forward Declaration
+class ParticleEmitter;
+class ParticleSystem;
+
+class TurbineHover : public Playable
+{
+  ObjectListDeclaration(TurbineHover);
+public:
+  TurbineHover(const std::string& fileName);
+  TurbineHover(const TiXmlElement* root = NULL);
+  virtual ~TurbineHover();
+
+  void setBoostColor(const Color& color);
+
+  virtual void loadParams(const TiXmlElement* root);
+  virtual void setPlayDirection(const Quaternion& rot, float speed = 0.0f);
+  virtual void enter();
+  virtual void leave();
+
+  virtual void setTeam(int teamID);
+
+  virtual void postSpawn();
+  virtual void leftWorld();
+  virtual void respawn();
+
+  virtual void collidesWith(WorldEntity* entity, const Vector& location);
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+  virtual void process(const Event &event);
+
+private:
+  void init();
+  void movement(float dt);
+
+private:
+  bool                  bForward;           //!< forward button pressed.
+  bool                  bBackward;          //!< backward button pressed.
+  bool                  bLeft;              //!< left button pressed.
+  bool                  bRight;             //!< right button pressed.
+  bool                  bAscend;            //!< ascend button pressed.
+  bool                  bDescend;           //!< descend button presses.
+
+  int                   yInvert;
+  float                 mouseSensitivity;   //!< the mouse sensitivity
+
+  PNode                 wingNodeLeft;
+  PNode                 wingNodeRight;
+  PNode                 rotorNodeLeft;
+  PNode                 rotorNodeRight;
+
+  PNode                 cameraNode;
+  float                 cameraLook;
+  float                 rotation;
+
+  // Vector                velocity;           //!< the velocity of the TurbineHover.
+  Quaternion            direction;          //!< the direction of the TurbineHover.
+  float                 travelSpeed;        //!< the current speed of the Hove (to make soft movement)
+  float                 acceleration;       //!< the acceleration of the TurbineHover.
+  float                 airFriction;        //!< AirFriction.
+
+  float                 rotorSpeed;         //!< the speed of the rotor.
+  float                 rotorCycle;         //!< The Cycle the rotor is in.
+
+  float                 airViscosity;
+
+  ParticleEmitter*      burstEmitter[2];
+  ParticleSystem*       burstSystem;
+};
+
+#endif /* _TURBINE_HOVERS_H */
Index: branches/heathaze/src/world_entities/spawning_point.cc
===================================================================
--- branches/heathaze/src/world_entities/spawning_point.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/spawning_point.cc	(revision 9940)
@@ -0,0 +1,276 @@
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+
+#include "spawning_point.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "world_entity.h"
+
+#include "compiler.h"
+
+#include "state.h"
+#include "game_rules.h"
+
+#include "shared_network_data.h"
+
+
+/// TODO REMOVE converter.h
+#include "converter.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(SpawningPoint, CL_SPAWNING_POINT);
+CREATE_FACTORY( SpawningPoint);
+/**
+ *  constructor
+ */
+SpawningPoint::SpawningPoint( const TiXmlElement * root )
+{
+  this->setAbsCoor( 0, 0, 0 );
+
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+void SpawningPoint::init()
+{
+  this->registerObject(this, SpawningPoint::_objectList);
+  PRINTF(0)("Created SpawningPoint\n");
+
+  this->teamId = -1;
+  this->localTimer = 0.0f;
+
+  this->toList( OM_DEAD_TICK );
+
+  MessageManager::getInstance()->registerMessageHandler( MSGID_RESPAWN, respawnMessageHandler, NULL );
+
+  this->setSynchronized( true );
+}
+
+
+/**
+ *  deconstructor
+ */
+SpawningPoint::~SpawningPoint ()
+{}
+
+
+/**
+ * loads the WorldEntity Specific Parameters.
+ * @param root: the XML-Element to load the Data From
+ */
+void SpawningPoint::loadParams(const TiXmlElement* root)
+{
+  /* let the world entity its stuff first */
+  WorldEntity::loadParams(root);
+
+  /* load teamId */
+  LoadParam(root, "teamId", this, SpawningPoint, setTeamId)
+  .describe("sets teamId");
+}
+
+
+
+/**
+ * pushes a world entity to the spawning queue
+ *  @param entity WorldEntity to be added
+ */
+void SpawningPoint::pushEntity(Playable* entity, float delay)
+{
+  QueueEntry qe;
+  qe.entity = entity;
+  qe.respawnTime = this->localTimer + delay;
+
+  queue.push_back( qe );
+}
+
+
+/**
+ *  spawn the entity
+ */
+void SpawningPoint::spawn(Playable* entity)
+{
+  bool found = false;
+
+  for (ObjectList<Playable>::const_iterator it = Playable::objectList().begin();
+       it != Playable::objectList().end();
+       ++it)
+  {
+    if ( *it == entity )
+    {
+      found = true;
+      break;
+    }
+  }
+
+  if ( !found )
+    return;
+
+  PRINTF(0)("Spawningpoint spawns Entity (%s)\n", entity->getClassCName());
+
+
+  entity->setAbsCoor( this->getAbsCoor() );
+  entity->setAbsDir( this->getAbsDir() );
+
+  //TODO set camera (not smooth)
+
+  if ( State::getGameRules() )
+  {
+    (State::getGameRules())->registerSpawn( entity );
+  }
+
+  entity->respawn();
+}
+
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+ *
+ * Handle all stuff that should update with time inside this method (movement, animation, etc.)
+ */
+void SpawningPoint::tick(float dt)
+{
+  this->localTimer += dt;
+  std::list<QueueEntry>::iterator it = this->queue.begin();
+  for( ; it != this->queue.end(); )
+  {
+    //PRINTF(0)("%f <= %f\n", it->respawnTime, this->localTimer);
+    if( it->respawnTime <= this->localTimer)
+    {
+      //spawn the player
+      this->spawn(it->entity);
+
+      bool found = false;
+
+      for (ObjectList<Playable>::const_iterator it2 = Playable::objectList().begin();
+           it2 != Playable::objectList().end();
+           ++it2)
+      {
+        if ( *it2 == it->entity )
+        {
+          found = true;
+          break;
+        }
+      }
+
+      if ( found && SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
+        this->sendRespawnMessage( it->entity->getUniqueID() );
+
+      std::list<QueueEntry>::iterator delit = it;
+      it++;
+
+      queue.erase( delit );
+
+      continue;
+    }
+
+    it++;
+  }
+
+}
+
+
+/**
+ *  the entity is drawn onto the screen with this function
+ *
+ * This is a central function of an entity: call it to let the entity painted to the screen.
+ * Just override this function with whatever you want to be drawn.
+ */
+void SpawningPoint::draw() const
+{}
+
+void SpawningPoint::sendRespawnMessage( int uniqueId )
+{
+  byte buf[2*INTSIZE];
+
+  assert( Converter::intToByteArray( this->getUniqueID(), buf, INTSIZE ) == INTSIZE );
+  assert( Converter::intToByteArray( uniqueId, buf + INTSIZE, INTSIZE ) == INTSIZE );
+
+  MessageManager::getInstance()->sendMessage( MSGID_RESPAWN, buf, 2*INTSIZE, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
+}
+
+/**
+ * message handler for respawn message
+ */
+bool SpawningPoint::respawnMessageHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
+{
+  if ( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
+  {
+    PRINTF(2)("server received spawn message!\n");
+    return true;
+  }
+
+  int spUniqueId;
+  int uniqueId;
+
+  if ( dataLength != 2*INTSIZE )
+  {
+    PRINTF(2)("spawn message has wrong size: %d\n", dataLength );
+    return true;
+  }
+
+  assert( Converter::byteArrayToInt( data, &spUniqueId ) == INTSIZE );
+  assert( Converter::byteArrayToInt( data+INTSIZE, &uniqueId ) == INTSIZE );
+
+  PRINTF(0)("SPAWNMESSAGE %d\n", uniqueId);
+
+  SpawningPoint * sp = NULL;
+  Playable      * playable = NULL;
+
+  for (ObjectList<SpawningPoint>::const_iterator it = SpawningPoint::objectList().begin();
+       it != SpawningPoint::objectList().end();
+       ++it)
+  {
+    PRINTF(0)("%d:%d\n", (*it)->getUniqueID(), spUniqueId);
+    if ( (*it)->getUniqueID() == spUniqueId )
+    {
+      sp = (*it);
+      break;
+    }
+  }
+
+  if ( !sp )
+  {
+    PRINTF(0)("could not find spawning point\n");
+    return false;
+  }
+
+  for (ObjectList<Playable>::const_iterator it = Playable::objectList().begin();
+       it != Playable::objectList().end();
+       ++it)
+  {
+    if ( (*it)->getUniqueID() == uniqueId )
+    {
+      playable = (*it);
+      break;
+    }
+  }
+
+  if ( !playable )
+  {
+    PRINTF(0)("could not find playable\n");
+    return false;
+  }
+
+  sp->spawn( playable );
+
+  return true;
+}
+
Index: branches/heathaze/src/world_entities/spawning_point.h
===================================================================
--- branches/heathaze/src/world_entities/spawning_point.h	(revision 9940)
+++ branches/heathaze/src/world_entities/spawning_point.h	(revision 9940)
@@ -0,0 +1,82 @@
+/*!
+ * @file spawning_point.h
+ *  Definition of a spawning point within the game, used for network game
+ */
+
+
+#ifndef _SPAWNING_POINT
+#define _SPAWNING_POINT
+
+#include "playable.h"
+
+#include "message_manager.h"
+
+#include <list>
+
+class World;
+class TiXmlElement;
+
+struct QueueEntry
+{
+  float respawnTime;
+  Playable * entity;
+};
+
+//!< used to indicate what type of objects are spawned by this spawning point
+typedef enum SpawningPointMode
+{
+  SPT_ALL_AT_ONCE = 0,                               //!< at this spawning points there will be players spawned (typicaly in MP games)
+  SPT_ONE_AFTER_OTHER,                               //!< at this spawning points there will be NPS spawnded
+
+  SPT_NUMBER
+};
+
+
+/**
+ * The spawning point for WorldEntities (and only WorldEntities)
+ *
+ * There are commonly two different spawning modes:
+ *
+ *  1) Just spawn whatever is in the queue with a given frequency (if delay = 0 => immediate spawn)
+ *  2) Spawn everything in the queue together with the given frequency
+ */
+class SpawningPoint : public WorldEntity {
+  ObjectListDeclaration(SpawningPoint);
+  public:
+    SpawningPoint(const TiXmlElement* root = NULL);
+    virtual ~SpawningPoint ();
+    void init();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    inline int getTeamId() const { return this->teamId; }
+    inline void setTeamId( int teamId ) { this->teamId = teamId; }
+
+    void pushEntity(Playable* entity, float delay = 0);
+
+    /** activates the spawning point */
+    inline void activate() { this->bSpawning = true; }
+    /** deactivates the spawning point */
+    inline void deactivate() { this->bSpawning = false; }
+    inline bool isActive() const { return this->bSpawning; }
+
+
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+
+  private:
+    void spawn(Playable* entity);
+
+    void sendRespawnMessage( int uniqueId );
+    static bool respawnMessageHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  );
+
+
+  private:
+    float                           localTimer;                     //!< the local timer
+    int                             teamId;                         //!< only spawn players of this team
+    std::list<QueueEntry>           queue;                          //!< queue of waiting WorldEntities to be spawned
+    bool                            bSpawning;                      //!< flag to indicate if this spawning point is active or not
+};
+
+#endif /* _SPAWNING_POINT */
Index: branches/heathaze/src/world_entities/spectator.cc
===================================================================
--- branches/heathaze/src/world_entities/spectator.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/spectator.cc	(revision 9940)
@@ -0,0 +1,235 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer: ...
+
+*/
+
+#include "spectator.h"
+
+#include "src/lib/util/loading/factory.h"
+#include "key_mapper.h"
+
+#include "shared_network_data.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Spectator, CL_SPECTATOR);
+CREATE_FACTORY(Spectator);
+
+
+/**
+ *  destructs the Spectator, deletes alocated memory
+ */
+Spectator::~Spectator ()
+{
+  this->setPlayer(NULL);
+}
+
+
+/**
+ *  creates a new Spectator from Xml Data
+ * @param root the xml element containing Spectator data
+
+   @todo add more parameters to load
+ */
+Spectator::Spectator(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+}
+
+
+/**
+ * initializes a Spectator
+ */
+void Spectator::init()
+{
+//  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->registerObject(this, Spectator::_objectList);
+
+  this->getWeaponManager().changeWeaponConfig(1);
+
+  this->bLeft = false;
+  this->bRight = false;
+  this->bForward = false;
+  this->bBackward = false;
+  this->xMouse = 0.0f;
+  this->yMouse = 0.0f;
+
+  this->setHealthMax(100);
+  this->setHealth(80);
+
+  this->mouseDir = this->getAbsDir();
+
+  //add events to the eventlist
+  registerEvent(KeyMapper::PEV_FORWARD);
+  registerEvent(KeyMapper::PEV_BACKWARD);
+  registerEvent(KeyMapper::PEV_LEFT);
+  registerEvent(KeyMapper::PEV_RIGHT);
+  registerEvent(KeyMapper::PEV_FIRE1);
+  registerEvent(EV_MOUSE_MOTION);
+
+  this->getWeaponManager().setSlotCount(0);
+
+  this->getWeaponManager().getFixedTarget()->setParent(this);
+  this->getWeaponManager().getFixedTarget()->setRelCoor(100000,0,0);
+
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+
+
+  registerVar( new SynchronizeableBool( &bLeft, &bLeft, "bLeft", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bRight, &bRight, "bRight", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableBool( &bBackward, &bBackward, "bBackward", PERMISSION_OWNER ) );
+  registerVar( new SynchronizeableQuaternion( &mouseDir, &mouseDir, "mouseDir", PERMISSION_OWNER ) );
+}
+
+
+/**
+ * loads the Settings of a Spectator from an XML-element.
+ * @param root the XML-element to load the Spaceship's properties from
+ */
+void Spectator::loadParams(const TiXmlElement* root)
+{
+  Playable::loadParams(root);
+}
+
+void Spectator::setPlayDirection(const Quaternion& quat, float speed)
+{
+  this->mouseDir = quat;
+  this->angleY = quat.getHeading();
+  this->angleX = quat.getAttitude();
+}
+
+
+void Spectator::reset()
+{
+  this->bLeft = false;
+  this->bRight = false;
+  this->bForward = false;
+  this->bBackward = false;
+  this->xMouse = 0.0f;
+  this->yMouse = 0.0f;
+
+  this->setHealth(80);
+}
+
+
+void Spectator::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false );
+  this->attachCamera();
+}
+
+void Spectator::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false);
+  this->detachCamera();
+}
+
+
+/**
+ *  this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ * @todo dont let Spectator fly through walls
+ */
+void Spectator::collidesWith(WorldEntity* entity, const Vector& location)
+{
+}
+
+
+
+/**
+ *  the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+ */
+void Spectator::tick (float time)
+{
+  Playable::tick( time );
+
+  if( ( xMouse != 0 || yMouse != 0 ) && this->getOwner() == SharedNetworkData::getInstance()->getHostID() )
+  {
+    xMouse *= time / 10;
+    yMouse *= time / 10;
+
+    angleX -= xMouse;
+    angleY -= yMouse;
+
+    if ( angleY > 2.05 )
+      angleY = 2.05;
+
+    if ( angleY < -1.15 )
+      angleY = -1.15;
+
+    this->mouseDir = Quaternion( angleX, Vector( 0, 1, 0 ) ) * Quaternion( angleY, Vector( 0, 0, 1 ) );
+
+    xMouse = yMouse = 0;
+  }
+
+  this->setAbsDir( this->mouseDir );
+
+  Vector velocity;
+
+  if ( this->bForward )
+  {
+    velocity += this->getAbsDirX();
+  }
+
+  if ( this->bBackward )
+  {
+    velocity -= this->getAbsDirX();
+  }
+
+  if ( this->bRight )
+  {
+    velocity += this->getAbsDirZ();
+  }
+
+  if ( this->bLeft )
+  {
+    velocity -= this->getAbsDirZ();
+  }
+
+  velocity *= 100;
+
+  this->shiftCoor( velocity*time );
+}
+
+/**
+ * @todo switch statement ??
+ */
+void Spectator::process(const Event &event)
+{
+  Playable::process(event);
+
+  if( event.type == KeyMapper::PEV_LEFT)
+    this->bLeft = event.bPressed;
+  else if( event.type == KeyMapper::PEV_RIGHT)
+    this->bRight = event.bPressed;
+  else if( event.type == KeyMapper::PEV_FORWARD)
+    this->bForward = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == KeyMapper::PEV_BACKWARD)
+    this->bBackward = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+    this->xMouse += event.xRel;
+    this->yMouse += event.yRel;
+  }
+}
+
+
+
+
Index: branches/heathaze/src/world_entities/spectator.h
===================================================================
--- branches/heathaze/src/world_entities/spectator.h	(revision 9940)
+++ branches/heathaze/src/world_entities/spectator.h	(revision 9940)
@@ -0,0 +1,50 @@
+/*!
+ * @file cpectator.h
+ * Implements a playable for lazy people
+ */
+
+#ifndef _SPECTATOR_H
+#define _SPECTATOR_H
+
+#include "playable.h"
+
+class Spectator : public Playable
+{
+  ObjectListDeclaration(Spectator);
+
+  public:
+    Spectator(const TiXmlElement* root = NULL);
+    virtual ~Spectator();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void setPlayDirection(const Quaternion& rot, float speed = 0.0f);
+
+    virtual void enter();
+    virtual void leave();
+
+    virtual void reset();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+    virtual void tick(float time);
+
+    virtual void process(const Event &event);
+
+  private:
+    void init();
+
+    bool                  bLeft;
+    bool                  bRight;
+    bool                  bForward;
+    bool                  bBackward;
+
+    float                 xMouse;             //!< mouse moved in x-Direction
+    float                 yMouse;             //!< mouse moved in y-Direction
+    Quaternion            mouseDir;           //!< the direction where the player wants to fly
+
+    float                 angleX;
+    float                 angleY;
+
+};
+
+#endif
Index: branches/heathaze/src/world_entities/terrain.cc
===================================================================
--- branches/heathaze/src/world_entities/terrain.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/terrain.cc	(revision 9940)
@@ -0,0 +1,429 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "terrain.h"
+
+#include "util/loading/resource_manager.h"
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "spatial_separation.h"
+
+#include "model.h"
+#include "network_game_manager.h"
+
+#include "height_map.h"
+#include "material.h"
+
+#include "glincl.h"
+
+#include "state.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Terrain, CL_TERRAIN);
+CREATE_FACTORY(Terrain);
+
+/**
+ *  standard constructor
+ */
+Terrain::Terrain (const TiXmlElement* root)
+{
+  this->init();
+
+
+  if( root != NULL)
+    this->loadParams(root);
+
+  //  if (this->model != NULL)
+  //this->ssp = new SpatialSeparation((Model*)this->model, 10.0f);
+}
+
+
+/**
+ *  Constructor for loading a Terrain out of a file
+ * @param fileName The file to load data from.
+
+   this either loads out of an OBJ-file, or loads a heightmap if no .obj-extension is found.
+*/
+Terrain::Terrain(const std::string& fileName)
+{
+  this->init();
+
+  if (fileName.rfind(".obj" ) != std::string::npos || fileName.rfind(".OBJ") != std::string::npos )
+  {
+    this->loadModel(fileName);
+  }
+  else
+  {
+    // load the hightMap here.
+  }
+}
+
+/**
+ *  a Constructor for the Debug-Worlds
+ */
+Terrain::Terrain(DebugTerrain debugTerrain)
+{
+  this->init();
+  this->buildDebugTerrain(debugTerrain);
+}
+
+/**
+ *  standard deconstructor
+
+*/
+Terrain::~Terrain ()
+{
+  if (modelList)
+    glDeleteLists(this->modelList, 1);
+  if( this->ssp)
+    delete ssp;
+
+  if(this->heightMap)
+    delete heightMap;
+}
+
+
+void Terrain::init()
+{
+  this->registerObject(this, Terrain::_objectList);
+  this->toList(OM_ENVIRON_NOTICK);
+  this->toReflectionList();
+
+  this->modelList = 0;
+  this->ssp = NULL;
+  this->vegetation = NULL;
+
+  this->heightMap = NULL;
+
+  this->heightMapMaterial = new Material();
+}
+
+
+void Terrain::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "scale", this, Terrain, setScale)
+  .describe("The scale in x,y,z direction");
+
+  LoadParam(root, "texture", this, Terrain, loadTexture)
+  .describe("The name of the Texture for this heightMap");
+
+  LoadParam(root, "vegetation", this, Terrain, loadVegetation)
+  .describe("the fileName of the vegetation, that should be loaded onto this terrain. (must be relative to the data-dir)") ;
+
+  LoadParam(root, "height-map", this, Terrain, loadHeightMap)
+  .describe("The HeightMap, splitted into two strings seperated by ','. 1: HeighMap, 2: ColorMap");
+
+}
+
+void Terrain::setScale(float x, float y, float z)
+{
+  this->terrainScale = Vector(x, y, z);
+}
+
+void Terrain::loadHeightMap(const std::string& heightMapFile, const std::string& colorMap)
+{
+  if (this->heightMap != NULL)
+    delete this->heightMap;
+  this->heightMap = NULL;
+
+  std::string hmName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(heightMapFile);
+  std::string hmColorName = Resources::ResourceManager::getInstance()->prependAbsoluteMainPath(colorMap);
+
+
+  this->heightMap = new HeightMap(hmName, hmColorName);
+  //   heightMap->scale(Vector(43.0f,4.7f,43.0f));
+  heightMap->scale(this->terrainScale);
+  heightMap->setAbsCoor(this->getAbsCoor());
+  heightMap->load();
+}
+
+
+void Terrain::loadTexture(const std::string& textureName)
+{
+  PRINTF(4)("Load texture: %s\n", textureName.c_str());
+
+  heightMapMaterial->setDiffuse(1.0,1.0,1.0);
+  heightMapMaterial->setAmbient(1.0,1.0,1.0 );
+  heightMapMaterial->setSpecular(1.0,1.0,1.0);
+  heightMapMaterial->setShininess(.5);
+  heightMapMaterial->setTransparency(1.0);
+
+  heightMapMaterial->setDiffuseMap(textureName);
+  //   heightMapMaterial->setAmbientMap(textureName);
+  //   heightMapMaterial->setSpecularMap(textureName);
+}
+
+
+
+void Terrain::loadVegetation(const std::string& vegetationFile)
+{
+  PRINTF(4)("loadVegetation: %s\n", vegetationFile.c_str());
+  if (this->vegetation)
+    this->vegetation = 0;
+  if (!vegetationFile.empty())
+  {
+    PRINTF(4)("fetching %s\n", vegetationFile.c_str());
+    this->loadModel(vegetationFile, 1.0, 2);
+    this->vegetation = this->getModel(2);
+  }
+  else
+    this->vegetation = NULL;
+}
+
+
+
+
+
+void Terrain::draw () const
+{
+  glPushMatrix();
+
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  /* rotate */
+  // Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  //glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  if (this->modelList)
+    glCallList(this->modelList);
+  else if (this->getModel())
+    this->getModel()->draw();
+
+  if (this->vegetation)
+    this->vegetation->draw();
+
+  if( this->heightMap)
+  {
+    this->heightMapMaterial->select();
+
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    this->heightMap->draw();
+  }
+  glPopMatrix();
+
+
+  /*
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glLoadIdentity();
+    Vector camera =   State::getCameraNode()->getAbsCoor(); // Go on here ..........!!!
+
+    float height =    heightMap->getHeight(camera.x, camera.z);
+
+    glEnable (GL_COLOR_MATERIAL) ;
+    glBegin(GL_QUADS);            // Draw The Cube Using quads
+    glColor3f(0.0f,1.0f,0.0f);  // Color Blue
+    glVertex3f(camera.x + 63.0f,Terrain->getHeight(camera.x+63.0f, camera.z-10.0f)+13.0f,camera.z-10.0f);      // Top Right Of The Quad (Top)
+    glVertex3f(camera.x-63.0f, getHeight(camera.x+63.0f, camera.z-10.0f)+13.0f,camera.z-10.0f);      // Top Left Of The Quad (Top)
+    glVertex3f(camera.x-63.0f, getHeight(camera.x+63.0f, camera.z+10.0f)+13.0f, camera.z+10.0f);      // Bottom Left Of The Quad (Top)
+    glVertex3f(camera.x+ 63.0f, getHeight(camera.x+63.0f, camera.z+10.0f)+13.0f, camera.z+10.0f);      // Bottom Right Of The Quad (Top)
+    glEnd();                      // End Drawing The Plan
+
+    glPopMatrix();*/
+
+
+  /* THIS IS ONLY FOR DEBUGGING INFORMATION */
+  //  if (this->ssp != NULL)
+  //    this->ssp->drawQuadtree();
+}
+
+
+void Terrain::buildDebugTerrain(DebugTerrain debugTerrain)
+{
+  // if the terrain is the Terrain of Dave
+  if (debugTerrain == TERRAIN_DAVE)
+  {
+    modelList = glGenLists(1);
+    glNewList (modelList, GL_COMPILE);
+
+    glColor3f(1.0,0,0);
+
+    int sizeX = 100;
+    int sizeZ = 80;
+    float length = 1000;
+    float width = 200;
+    float widthX = float (length /sizeX);
+    float widthZ = float (width /sizeZ);
+
+    float height [sizeX][sizeZ];
+    Vector normal_vectors[sizeX][sizeZ];
+
+
+    for ( int i = 0; i<sizeX-1; i+=1)
+      for (int j = 0; j<sizeZ-1;j+=1)
+        //height[i][j] = rand()/20046 + (j-25)*(j-25)/30;
+#ifdef __WIN32__
+        height[i][j]=(sin((float)j/3)*rand()*i/182400)*.5;
+#else
+        height[i][j]=(sin((float)j/3)*rand()*(long)i/6282450500.0)*.5;
+#endif
+
+    //Die Huegel ein wenig glaetten
+    for (int h=1; h<2;h++)
+      for (int i=1;i<sizeX-2 ;i+=1 )
+        for(int j=1;j<sizeZ-2;j+=1)
+          height[i][j]=(height[i+1][j]+height[i][j+1]+height[i-1][j]+height[i][j-1])/4;
+
+    //Berechnung von normalen Vektoren
+    for(int i=1;i<sizeX-2;i+=1)
+      for(int j=1;j<sizeZ-2 ;j+=1)
+      {
+        Vector v1 = Vector (widthX*(1),      height[i][j],      widthZ*(j) );
+        Vector v2 = Vector (widthX*(i-1),    height[i-1][j],    widthZ*(j));
+        Vector v3 = Vector (widthX*(i),      height[i][j+1],    widthZ*(j+1));
+        Vector v4 = Vector (widthX*(i+1),    height[i+1][j],    widthZ*(j));
+        Vector v5 = Vector (widthX*(i),      height[i][j-1],    widthZ*(j-1));
+
+        Vector c1 = v2 - v1;
+        Vector c2 = v3 - v1;
+        Vector c3=  v4 - v1;
+        Vector c4 = v5 - v1;
+        Vector zero = Vector (0,0,0);
+        normal_vectors[i][j]=c1.cross(v3-v5)+c2.cross(v4-v2)+c3.cross(v5-v3)+c4.cross(v2-v4);
+        normal_vectors[i][j].normalize();
+      }
+
+    glBegin(GL_QUADS);
+    int snowheight=3;
+    for ( int i = 0; i<sizeX; i+=1)
+      for (int j = 0; j<sizeZ;j+=1)
+      {
+        Vector v1 = Vector (widthX*(i),      height[i][j]-20,       widthZ*(j)  -width/2);
+        Vector v2 = Vector (widthX*(i+1),    height[i+1][j]-20,     widthZ*(j)  -width/2);
+        Vector v3 = Vector (widthX*(i+1),    height[i+1][j+1]-20,   widthZ*(j+1)-width/2);
+        Vector v4 = Vector (widthX*(i),      height[i][j+1]-20,     widthZ*(j+1)-width/2);
+        float a[3];
+        if(height[i][j]<snowheight)
+        {
+          a[0]=0;
+          a[1]=1.0-height[i][j]/10-.3;
+          a[2]=0;
+          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+        }
+        else
+        {
+          a[0]=1.0;
+          a[1]=1.0;
+          a[2]=1.0;
+          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+
+        }
+        glNormal3f(normal_vectors[i][j].x, normal_vectors[i][j].y, normal_vectors[i][j].z);
+        glVertex3f(v1.x, v1.y, v1.z);
+        if(height[i+1][j]<snowheight)
+        {
+          a[0]=0;
+          a[1] =1.0-height[i+1][j]/10-.3;
+          a[2]=0;
+          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+        }
+        else
+        {
+          a[0]=1.0;
+          a[1]=1.0;
+          a[2]=1.0;
+          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+
+        }
+        glNormal3f(normal_vectors[i+1][j].x, normal_vectors[i+1][j].y, normal_vectors[i+1][j].z);
+        glVertex3f(v2.x, v2.y, v2.z);
+        if(height[i+1][j+1]<snowheight)
+        {
+          a[0]=0;
+          a[1] =1.0-height[i+1][j+1]/10-.3;
+          a[2]=0;
+          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+        }
+        else
+        {
+          a[0]=1.0;
+          a[1]=1.0;
+          a[2]=1.0;
+          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+
+
+        }
+        glNormal3f(normal_vectors[i+1][j+1].x, normal_vectors[i+1][j+1].y, normal_vectors[i+1][j+1].z);
+        glVertex3f(v3.x, v3.y, v3.z);
+        if(height[i][j+1]<snowheight)
+        {
+          a[0]=0;
+          a[1] =1.0-height[i+1][j+1]/10-.3;
+          a[2]=0;
+          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+        }
+        else
+        {
+          a[0]=1.0;
+          a[1]=1.0;
+          a[2]=1.0;
+          glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+        }
+        glNormal3f(normal_vectors[i][j+1].x, normal_vectors[i][j+1].y, normal_vectors[i][j+1].z);
+        glVertex3f(v4.x, v4.y, v4.z);
+
+      }
+    glEnd();
+    glEndList();
+  }
+
+  if (debugTerrain == TERRAIN_BENSCH)
+  {
+    /*
+      this->model = (OBJModel*) new Model();
+    this->model->setName("CUBE");
+    this->model->addVertex (-0.5, -0.5, 0.5);
+    this->model->addVertex (0.5, -0.5, 0.5);
+    this->model->addVertex (-0.5, 0.5, 0.5);
+    this->model->addVertex (0.5, 0.5, 0.5);
+    this->model->addVertex (-0.5, 0.5, -0.5);
+    this->model->addVertex (0.5, 0.5, -0.5);
+    this->model->addVertex (-0.5, -0.5, -0.5);
+    this->model->addVertex (0.5, -0.5, -0.5);
+
+    this->model->addVertexTexture (0.0, 0.0);
+    this->model->addVertexTexture (1.0, 0.0);
+    this->model->addVertexTexture (0.0, 1.0);
+    this->model->addVertexTexture (1.0, 1.0);
+    this->model->addVertexTexture (0.0, 2.0);
+    this->model->addVertexTexture (1.0, 2.0);
+    this->model->addVertexTexture (0.0, 3.0);
+    this->model->addVertexTexture (1.0, 3.0);
+    this->model->addVertexTexture (0.0, 4.0);
+    this->model->addVertexTexture (1.0, 4.0);
+    this->model->addVertexTexture (2.0, 0.0);
+    this->model->addVertexTexture (2.0, 1.0);
+    this->model->addVertexTexture (-1.0, 0.0);
+    this->model->addVertexTexture (-1.0, 1.0);
+
+    this->model->finalize();
+    */
+  }
+}
+
+float Terrain::getHeight(float x, float y)
+{
+  if(this->heightMap != NULL)
+    return (this->heightMap->getHeight(x, y));
+  return 0;
+}
Index: branches/heathaze/src/world_entities/terrain.h
===================================================================
--- branches/heathaze/src/world_entities/terrain.h	(revision 9940)
+++ branches/heathaze/src/world_entities/terrain.h	(revision 9940)
@@ -0,0 +1,61 @@
+/*!
+ * @file terrain.h
+  *  Defines and handles the terrain of the World
+
+    @todo implement it
+
+    The terrain should either be build from a Model a OBJModel or from a HeightMap.
+*/
+
+#ifndef _TERRAIN_H
+#define _TERRAIN_H
+
+#include "world_entity.h"
+
+// FORWARD DECLARATION
+class SpatialSeparation;
+class HeightMap;
+class Material;
+
+//! A simple method to call a desired debug world.
+enum DebugTerrain {TERRAIN_DAVE, TERRAIN_BENSCH};
+
+
+//! A Class to handle Terrain of orxonox
+class Terrain : public WorldEntity
+{
+  ObjectListDeclaration(Terrain);
+
+ public:
+  Terrain(const TiXmlElement* root = NULL);
+  Terrain(const std::string& fileName);
+  Terrain(DebugTerrain debugTerrain);
+  virtual ~Terrain();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  void loadVegetation(const std::string& vegetationFile);
+
+  void loadHeightMap(const std::string& heightMapFile, const std::string& colorMap);
+  void loadTexture(const std::string& textureName);
+  void setScale(float x, float y, float z);
+
+  void buildDebugTerrain(DebugTerrain debugTerrain);
+
+  float getHeight(float x, float y);
+  virtual void draw() const;
+
+  public:
+    SpatialSeparation* ssp;
+
+ private:
+   Model*              vegetation;
+   int                 modelList;
+
+   HeightMap*          heightMap;
+   Material*           heightMapMaterial;
+   Vector              terrainScale;
+};
+
+#endif /* _TERRAIN_H */
Index: branches/heathaze/src/world_entities/test_entity.cc
===================================================================
--- branches/heathaze/src/world_entities/test_entity.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/test_entity.cc	(revision 9940)
@@ -0,0 +1,110 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer:
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "executor/executor.h"
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+
+
+#include "test_entity.h"
+#include "debug.h"
+
+
+
+
+#include "state.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinition(TestEntity);
+CREATE_FACTORY(TestEntity);
+
+
+
+/**
+ *
+ */
+TestEntity::TestEntity ()
+{
+  this->init();
+}
+
+
+/**
+ *
+ */
+TestEntity::TestEntity(const TiXmlElement* root)
+{
+  this->init();
+
+  if( root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ *
+ */
+TestEntity::~TestEntity ()
+{}
+
+
+/**
+ *
+ */
+void TestEntity::init()
+{
+  this->registerObject(this, TestEntity::_objectList);
+  this->toList(OM_GROUP_00);
+}
+
+
+/**
+ * loads the Settings of a MD2Creature from an XML-element.
+ * @param root the XML-element to load the MD2Creature's properties from
+ */
+void TestEntity::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+
+
+/**
+ *
+ */
+void TestEntity::tick (float time)
+{
+
+
+}
+
+
+/**
+ *
+ */
+void TestEntity::draw() const
+{
+
+}
+
+
+
+
Index: branches/heathaze/src/world_entities/test_entity.h
===================================================================
--- branches/heathaze/src/world_entities/test_entity.h	(revision 9940)
+++ branches/heathaze/src/world_entities/test_entity.h	(revision 9940)
@@ -0,0 +1,27 @@
+#ifndef _TEST_ENTITY_H
+#define _TEST_ENTITY_H
+
+#include "world_entity.h"
+
+class TiXmlElement;
+
+
+class TestEntity : public WorldEntity
+{
+    ObjectListDeclaration(TestEntity);
+
+  public:
+    TestEntity ();
+    TestEntity(const TiXmlElement* root);
+    virtual ~TestEntity ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+
+    virtual void tick (float time);
+    virtual void draw() const;
+
+};
+
+#endif /* _TEST_ENTITY_H */
Index: branches/heathaze/src/world_entities/weapons/aim.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/aim.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/aim.cc	(revision 9940)
@@ -0,0 +1,234 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "aim.h"
+
+#include "util/loading/load_param.h"
+#include "graphics_engine.h"
+#include "state.h"
+#include "material.h"
+#include "t_animation.h"
+#include "text.h"
+
+#include "world_entity.h"
+
+
+
+ObjectListDefinition(Aim);
+
+/**
+ * standart constructor
+ */
+Aim::Aim (PNode* source, const TiXmlElement* root)
+{
+  this->init();
+
+  this->source = source;
+
+  if (root)
+    this->loadParams(root);
+  else
+    this->setTexture("maps/aim.png");
+}
+
+/**
+ * destroys a Aim
+*/
+Aim::~Aim ()
+{
+  /*  if (this->text != NULL)
+      delete this->text;*/
+}
+
+/**
+ * initializes the Aim
+ */
+void Aim::init()
+{
+  this->registerObject(this, Aim::_objectList);
+  this->setName("Aim");
+
+  this->setLayer(E2D_LAYER_TOP);
+  this->setRotationSpeed(30.0* (float)rand()/RAND_MAX + 10.0);
+  this->setSize(GraphicsEngine::getInstance()->getResolutionX()/10.0);
+
+  this->setBindNode(this);
+  this->source = NULL;
+
+  this->range = 1000;
+  this->angle = M_PI_4;
+  this->targetGroup = OM_GROUP_01;
+  this->anim = new tAnimation<Aim>(this, &Aim::setSize);
+  this->anim->setInfinity(ANIM_INF_CONSTANT);
+  this->anim->addKeyFrame(500, .3, ANIM_LINEAR);
+  this->anim->addKeyFrame(100, .2, ANIM_LINEAR);
+  this->anim->addKeyFrame(50, .01, ANIM_LINEAR);
+
+
+  /*  this->text = new Text();
+    this->text->setLayer(this->getLayer());
+    this->text->setParent2D(this);
+    this->text->setRelCoor2D(10, -50);
+    this->text->setParentMode2D(E2D_PARENT_MOVEMENT);
+    this->text->setText("Testing");*/
+}
+
+void Aim::loadParams(const TiXmlElement* root)
+{
+  PNode::loadParams(root);
+
+  LoadParam(root, "texture", this, Aim, setTexture)
+  .describe("the texture-file to load onto the Aim");
+
+  LoadParam(root, "size", this, Aim, setSize)
+  .describe("the size of the Aim in Pixels");
+
+  LoadParam(root, "rotation-speed", this, Aim, setRotationSpeed)
+  .describe("the Speed with which the Aim should rotate");
+
+  LoadParam(root, "target-group", this, Aim, setTargetGroupS);
+}
+
+void Aim::searchTarget()
+{
+  ObjectManager::EntityList::iterator entity;
+  //printf("%d\n", this->targetGroup);
+  for (entity = State::getObjectManager()->getEntityList(this->targetGroup).begin();
+       entity != State::getObjectManager()->getEntityList(this->targetGroup).end();
+       entity ++)
+  {
+    diffVec = ( (*entity)->getAbsCoor() - this->source->getAbsCoor() );
+
+    if ( diffVec.len() < range )//&&  acos( (this->source->getAbsDirX()).dot(diffVec)/(diffVec.len() * (this->source->getAbsDirX()).len() ) )  < angle)
+    {
+      //if (this->getParent() != (*entity))
+      {
+        //        printf("found target::: %d %s::%s\n", (*entity)->getOMListNumber(), (*entity)->getClassCName(), (*entity)->getCName());
+        this->anim->replay();
+        this->setParentSoft(*entity, 5);
+        return;
+      }
+    }
+  }
+
+  //if no target found:
+  this->setParent(PNode::getNullParent());
+}
+
+void Aim::setTargetGroupS(const std::string& groupName)
+{
+  OM_LIST id = ObjectManager::StringToOMList(groupName);
+  if (id != OM_NULL)
+    this->setTargetGroup(id);
+  else
+    PRINTF(2)("List %s not found for targetting\n", groupName.c_str());
+}
+
+/**
+ * @brief sets the size of the Aim.
+ * @param size the size in pixels
+ */
+void Aim::setSize(float size)
+{
+  this->setSize2D(size/2, size/2);
+}
+
+/**
+ * sets the material to load
+ * @param textureFile The texture-file to load onto the crosshair
+ */
+void Aim::setTexture(const std::string& textureFile)
+{
+  this->material.setDiffuseMap(textureFile);
+}
+
+/**
+ * ticks the Aim
+ * @param dt the time to ticks
+ */
+void Aim::tick(float dt)
+{
+  // let the crosshair rotate
+  this->shiftDir2D(dt * rotationSpeed);
+
+  //   char outputText[100];
+  //   sprintf(outputText, "%s - distance: %f\n", this->getParent()->getName(), (this->source->getAbsCoor() - this->getAbsCoor()).len());
+  //   this->text->setText(outputText);
+
+
+  //  if (this->source->getAbsCoor().x > this->getAbsCoor().x )
+  diffVec = ( this->getAbsCoor() - this->source->getAbsCoor() );
+  //only look for target if the aim hasn`t locked a target yet or if the actual target is out of range
+  if(this->getParent() == PNode::getNullParent() ||
+      diffVec.len() > range )// ||
+    //( acos( (this->source->getAbsDirX()).dot(diffVec)/(diffVec.len() * (this->source->getAbsDirX()).len() ) ) > angle))
+  {
+    this->setParentSoft(PNode::getNullParent(),5);
+    this->searchTarget();
+  }
+
+  //   float z = 0.0f;
+  //   glReadPixels ((int)this->getAbsCoor2D().x,
+  //                  GraphicsEngine::getInstance()->getResolutionY()-(int)this->getAbsCoor2D().y-1,
+  //                  1,
+  //                  1,
+  //                  GL_DEPTH_COMPONENT,
+  //                  GL_FLOAT,
+  //                  &z);
+  //
+  //
+  //   GLdouble objX=.0, objY=.0, objZ=.0;
+  //   gluUnProject(this->getAbsCoor2D().x,
+  //                GraphicsEngine::getInstance()->getResolutionY()-this->getAbsCoor2D().y-1,
+  //                .99,  // z
+  //                GraphicsEngine::modMat,
+  //                GraphicsEngine::projMat,
+  //                GraphicsEngine::viewPort,
+  //                &objX,
+  //                &objY,
+  //                &objZ );
+  //aa
+  //   this->setAbsCoor(objX, objY, objZ);
+}
+
+/**
+ * draws the crosshair
+ */
+void Aim::draw() const
+{
+
+  if( this->getParent() != PNode::getNullParent() )
+  {
+    glPushMatrix();
+    glTranslatef(this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
+
+    glRotatef(this->getAbsDir2D(), 0,0,1);
+    this->material.select();
+    glBegin(GL_TRIANGLE_STRIP);
+    glTexCoord2f(0, 0);
+    glVertex2f(-this->getSizeX2D(), -this->getSizeY2D());
+    glTexCoord2f(1, 0);
+    glVertex2f(this->getSizeX2D(), -this->getSizeY2D());
+    glTexCoord2f(0, 1);
+    glVertex2f(-this->getSizeX2D(), this->getSizeY2D());
+    glTexCoord2f(1, 1);
+    glVertex2f(this->getSizeX2D(), this->getSizeY2D());
+    glEnd();
+    glPopMatrix();
+  }
+
+}
Index: branches/heathaze/src/world_entities/weapons/aim.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/aim.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/aim.h	(revision 9940)
@@ -0,0 +1,78 @@
+/*!
+ * @file aim.h
+ *  Definition of
+ */
+
+#ifndef _AIM_H
+#define _AIM_H
+
+#include "p_node.h"
+#include "element_2d.h"
+#include "object_manager.h"
+
+#include "material.h"
+
+// FORWARD DECLARATION
+class Model;
+class Text;
+class TiXmlElement;
+template<class T> class tAnimation;
+
+
+//! An Aim for zooming in on Targets.
+/**
+ * An Aim is a PNode, that is connected, to the Target, it has aquired
+ * The target becomes, if selected its Parent.
+ *
+ * Also the Aim is a Element2D, as it draws a cross onto the Target.
+ */
+class Aim : public PNode, public Element2D
+{
+  ObjectListDeclaration(Aim);
+
+public:
+  Aim(PNode* source, const TiXmlElement* root = NULL);
+  virtual ~Aim();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  inline void setSource(PNode* source) { this->source = source; };
+
+  inline void selectTarget(PNode* target) { this->setParent(target); };
+  inline PNode* getTarget(PNode* target) const { return this->getParent(); };
+
+  void searchTarget();
+
+  void setRange(float range) {this->range = range;};
+  void setAngle(float angle) {this->angle = angle;};
+  void setTargetGroup(OM_LIST group) { this->targetGroup = group; };
+  void setTargetGroupS(const std::string& grounName);
+
+  void setSize(float size);
+  void setTexture(const std::string& textureFile);
+  /** @param rotationSpeed the speed at what the crosshair should rotate */
+  inline void setRotationSpeed(float rotationSpeed) { this->rotationSpeed = rotationSpeed; };
+
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+private:
+  void init();
+
+
+private:
+  Material         material;             //!< a material for the Aim.
+  float            rotationSpeed;        //!< Speed of the Rotation.
+  tAnimation<Aim>* anim;
+
+  float            range;                //!<
+  float            angle;                //!<
+  Vector           diffVec;
+  OM_LIST          targetGroup;
+
+  PNode*           source;               //!< Where this Shot has come from.
+
+  //   Text             text;                 //!< A Text to display onto this Node. (distance to Target)
+};
+
+#endif /* _AIM_H */
Index: branches/heathaze/src/world_entities/weapons/aiming_system.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/aiming_system.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/aiming_system.cc	(revision 9940)
@@ -0,0 +1,155 @@
+  /*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "aiming_system.h"
+
+#include "util/loading/load_param.h"
+
+#include "state.h"
+#include "debug.h"
+
+#include "aabb.h"
+#include "obb_tree.h"
+
+
+
+ObjectListDefinition(AimingSystem);
+
+/**
+ * standart constructor
+ */
+AimingSystem::AimingSystem (WorldEntity* entity)
+  : WorldEntity()
+{
+  this->owner = entity;
+
+  this->init();
+}
+
+
+/**
+ * destroys a AimingSystem
+*/
+AimingSystem::~AimingSystem ()
+{}
+
+
+/**
+ * initializes the AimingSystem
+ */
+void AimingSystem::init()
+{
+  this->registerObject(this, AimingSystem::_objectList);
+  this->setName("AimingSystem");
+
+  //this->loadModel("models/guns/targeting_system_body2.obj");
+//   this->loadModel("models/ships/fighter.obj");
+
+  // registering default reactions:
+  this->unsubscribeReaction(CREngine::CR_OBJECT_DAMAGE);
+  this->subscribeReaction(CREngine::CR_OBJECT_DAMAGE, WorldEntity::staticClassID());
+
+  this->range = 1000.0f;
+  this->sideLength = 2.0f;
+
+  // new obb tree
+  this->obbTree = new OBBTree();
+  this->obbTree->createBox(Vector(0.0f, 0.0f, 0.0f), Vector(this->range, this->sideLength, this->sideLength));
+  this->setOBBTree(this->obbTree);
+}
+
+
+
+/**
+ * get back the nearest target
+ * @returns the nerest target
+ */
+WorldEntity* AimingSystem::getNearestTarget()
+{
+  if( this->selectionList.size() == 0)
+    return NULL;
+
+
+  WorldEntity* nearestEntity     = NULL;
+  float        distance          = 0.0f;
+  float        smalestDistance   = this->range * 5.0f;
+
+
+  for(unsigned int i = 0; i < this->selectionList.size(); i++)
+  {
+    distance = fabs((this->getAbsCoor() - this->selectionList[i]->getAbsCoor()).len());
+    if( distance < smalestDistance)
+    {
+      nearestEntity = this->selectionList[i];
+      smalestDistance = distance;
+    }
+  }
+
+  PRINTF(0)("entity: %s\n", nearestEntity->getClassCName());
+    return nearestEntity;
+}
+
+
+/**
+ * called when an object is "selected"
+ *  @param damage damage to be dealt
+ *  @param killer the entity
+ */
+void AimingSystem::hit(float damage, WorldEntity* killer)
+{
+  if( this->owner != killer)
+  {
+    //PRINTF(0)("real hit: %s\n", killer->getClassCName());
+    this->selectionList.push_back(killer);
+  }
+}
+
+
+
+/**
+ * ticks the AimingSystem
+ * @param dt the time to ticks
+ */
+void AimingSystem::tick(float dt)
+{
+
+
+}
+
+
+/**
+ * draws the crosshair
+ */
+void AimingSystem::draw() const
+{
+  WorldEntity::draw();
+
+//   glMatrixMode(GL_MODELVIEW);
+//   glPushMatrix();
+//
+//   /* translate */
+//   glTranslatef (this->getAbsCoor ().x,
+//                 this->getAbsCoor ().y,
+//                 this->getAbsCoor ().z);
+//   Vector tmpRot = this->getAbsDir().getSpacialAxis();
+//   glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+//
+//   this->obbTree->drawBV(0, 1);
+//
+//   glPopMatrix();
+
+}
Index: branches/heathaze/src/world_entities/weapons/aiming_system.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/aiming_system.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/aiming_system.h	(revision 9940)
@@ -0,0 +1,54 @@
+/*!
+ * @file aiming_system.h
+ *  Definition of
+ */
+
+#ifndef _AIMING_SYSTEM_H
+#define _AIMING_SYSTEM_H
+
+
+#include "world_entity.h"
+
+
+
+// FORWARD DECLARATION
+class TiXmlElement;
+class BVTree;
+class Model;
+class OBBTree;
+
+
+class AimingSystem : public WorldEntity
+{
+  ObjectListDeclaration(AimingSystem);
+
+ public:
+  AimingSystem(WorldEntity* owner = NULL);
+  virtual ~AimingSystem();
+
+  void init();
+
+  WorldEntity* getNearestTarget();
+  void flushList() { this->selectionList.clear(); }
+
+  void setRange(float range){this->range = range;};
+
+  virtual void hit(float damage, WorldEntity* killer);
+  virtual void destroy(WorldEntity* entity) {}
+
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+
+ private:
+   float                       range;                //!<
+   float                       sideLength;
+   std::vector<WorldEntity*>   selectionList;        //!< the selections
+
+   WorldEntity*                owner;                //!< the owner of the targeting system
+
+   OBBTree*                    obbTree;
+
+};
+
+#endif /* _AIMING_SYSTEM_H */
Index: branches/heathaze/src/world_entities/weapons/aiming_turret.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/aiming_turret.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/aiming_turret.cc	(revision 9940)
@@ -0,0 +1,177 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Benjamin Grauer
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "aiming_turret.h"
+
+#include "weapon_manager.h"
+#include "aim.h"
+#include "world_entities/projectiles/projectile.h"
+
+#include "model.h"
+
+#include "animation3d.h"
+
+#include "util/loading/factory.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(AimingTurret, CL_AIMING_TURRET);
+CREATE_FACTORY(AimingTurret);
+
+
+
+/**
+ *  standard constructor
+
+   creates a new weapon
+*/
+AimingTurret::AimingTurret ()
+    : Weapon(), target(this)
+{
+  this->init();
+  this->loadModel("models/guns/turret2.obj");
+}
+
+
+AimingTurret::AimingTurret(const TiXmlElement* root)
+    : target(this)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+AimingTurret::~AimingTurret ()
+{
+  // model will be deleted from WorldEntity-destructor
+  //  delete this->target;
+}
+
+void AimingTurret::init()
+{
+  this->registerObject(this, AimingTurret::_objectList);
+
+  Animation3D* animation1 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation2 = this->getAnimation(WS_DEACTIVATING, this);
+
+  animation1->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+
+  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+
+  this->setStateDuration(WS_SHOOTING, .9);
+  this->setStateDuration(WS_RELOADING, .1);
+  this->setStateDuration(WS_ACTIVATING, .4);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setEnergyMax(10000);
+  this->increaseEnergy(100000);
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_TURRET);
+  this->setProjectileTypeC("GuidedMissile");
+
+
+  this->setEmissionPoint(1.684, 0.472, 0);
+  //this->getProjectileFactory()->prepare(100);
+
+  this->target.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT | PNODE_PROHIBIT_CHILD_DELETE);
+  this->target.setVisibility(false);
+  this->target.setRange(400);
+  this->target.setAngle(M_PI_2);
+
+  this->setActionSound(WA_SHOOT, "sound/explosions/explosion_3.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/voices/rockets.wav");
+  this->setActionSound(WA_RELOAD, "sound/vocals/reload.wav");
+
+}
+
+void AimingTurret::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+
+}
+
+void AimingTurret::activate()
+{
+  this->target.setVisibility(true);
+}
+
+void AimingTurret::deactivate()
+{
+  this->target.setVisibility(false);
+}
+
+void AimingTurret::tick(float dt)
+{
+  if (!Weapon::tickW(dt))
+    return;
+  Quaternion quat;
+  Vector direction = this->target.getAbsCoor() - this->getAbsCoor();
+
+  direction.normalize();
+
+  if (likely (this->getParent() != NULL))
+    //quat = Quaternion(direction, this->getParent()->getAbsDirY()) * Quaternion ( -M_PI_2, Vector(0,1,0)) ;
+    quat = Quaternion ( M_PI_2, this->getParent()->getAbsDirY()) * Quaternion::lookAt(this->getAbsCoor(), this->target.getAbsCoor(), this->getParent()->getAbsDirY());
+  else
+    //quat = Quaternion(direction, Vector(0,1,0)) * Quaternion ( -M_PI_2, Vector(0,1,0)) ;
+    quat = Quaternion ( M_PI_2, Vector(0,1,0)) * Quaternion::lookAt(this->getAbsCoor(), this->target.getAbsCoor(), Vector(0,1,0));
+
+  this->setAbsDirSoft(quat, 5);
+
+  this->target.tick(dt);
+}
+
+void AimingTurret::fire()
+{
+  Projectile* pj = this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  pj->setVelocity(/*this->getVelocity()+*/(this->getAbsDirX()*250.0 + VECTOR_RAND(4)
+                                          /*target.getAbsCoor() - this->getAbsCoor()*/)*.5);//this->getVelocity());
+
+  pj->setParent(PNode::getNullParent());
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
+
+
+/**
+ * draws the AimingTurret
+*/
+void AimingTurret::draw () const
+{
+  /* draw gun body */
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  if (this->getModel())
+    this->getModel()->draw();
+  glPopMatrix();
+}
+
Index: branches/heathaze/src/world_entities/weapons/aiming_turret.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/aiming_turret.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/aiming_turret.h	(revision 9940)
@@ -0,0 +1,42 @@
+/*!
+ * @file aiming_turret.h
+*/
+
+
+#ifndef _AIMING_TURRET_H
+#define _AIMING_TURRET_H
+
+#include "weapon.h"
+#include "aim.h"
+/* FORWARD DECLARATION */
+
+class AimingTurret : public Weapon
+{
+  ObjectListDeclaration(AimingTurret);
+
+public:
+  AimingTurret ();
+  AimingTurret(const TiXmlElement* root);
+  virtual ~AimingTurret ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setTargetGroup(OM_LIST targetGroup) { this->target.setTargetGroup(targetGroup); };
+
+  virtual void activate();
+  virtual void deactivate();
+
+  virtual void tick(float dt);
+  virtual void fire();
+
+
+  virtual void draw() const;
+
+private:
+  void init();
+
+private:
+  Aim           target;
+};
+
+#endif /* _AIMING_TURRET_H */
Index: branches/heathaze/src/world_entities/weapons/ammo_container.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/ammo_container.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/ammo_container.cc	(revision 9940)
@@ -0,0 +1,95 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "ammo_container.h"
+
+#include "weapon.h"
+
+#include <assert.h>
+
+
+ObjectListDefinition(AmmoContainer);
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+AmmoContainer::AmmoContainer (const ClassID& projectileType, float maxEnergy)
+{
+  this->registerObject(this, AmmoContainer::_objectList);
+
+  this->projectileType = projectileType;
+  this->maxEnergy = maxEnergy;
+
+  this->energy = 0.0;
+}
+
+
+/**
+ * standard deconstructor
+*/
+AmmoContainer::~AmmoContainer ()
+{
+  // delete what has to be deleted here
+}
+
+
+
+float AmmoContainer::increaseEnergy(float energy)
+{
+  this->energy += energy;
+
+  if (unlikely(this->energy > this->maxEnergy))
+  {
+    float retEnergy = this->energy - this->maxEnergy;
+    this->energy = this->maxEnergy;
+    return retEnergy;
+  }
+  else
+    return 0.0f;
+}
+
+
+float AmmoContainer::decreaseEnergy(float energy)
+{
+  this->energy -= energy;
+
+  if (unlikely(this->energy < 0))
+  {
+    float retEnergy = 0 - this->energy;
+    this->energy = 0;
+    return retEnergy;
+  }
+  else
+    return 0.0f;
+}
+
+bool AmmoContainer::weaponValid(const Weapon* weapon)
+{
+  return (weapon->isA(this->projectileType));
+}
+
+
+void AmmoContainer::fillWeapon(Weapon* weapon)
+{
+  assert (weapon != NULL);
+  assert (this->weaponValid(weapon));
+
+  float fillEnergy = weapon->getEnergyMax();
+
+  float restEnergy = weapon->increaseEnergy(fillEnergy);
+  this->decreaseEnergy(fillEnergy - restEnergy);
+}
Index: branches/heathaze/src/world_entities/weapons/ammo_container.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/ammo_container.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/ammo_container.h	(revision 9940)
@@ -0,0 +1,47 @@
+/*!
+ * @file proto_class.h
+ * @brief Definition of ...
+*/
+
+#ifndef _AMMO_CONTAINER_H
+#define _AMMO_CONTAINER_H
+
+#include "base_object.h"
+
+
+// FORWARD DECLARATION
+class Weapon;
+
+#define DEFAULT_MAX_ENERGY 100
+
+//! A class for Storing energy of Projectiles.
+class AmmoContainer : public BaseObject {
+  ObjectListDeclaration(AmmoContainer);
+
+ public:
+  AmmoContainer(const ClassID& id, float maxEnergy = DEFAULT_MAX_ENERGY);
+  virtual ~AmmoContainer();
+
+  bool operator=(int projectileType) const { return (this->projectileType == projectileType); };
+  ClassID getProjectileType() const { return this->projectileType; };
+
+  float increaseEnergy(float energy);
+  float decreaseEnergy(float energy);
+
+  float getStoredEnergy() const { return this->energy; };
+  float getMaxEnergy() const { return this->maxEnergy; };
+
+  void increaseMaxEnergy(float increase);
+
+  bool weaponValid(const Weapon* weapon);
+  void fillWeapon(Weapon* weapon);
+
+
+ private:
+   float  energy;
+   float  maxEnergy;
+
+   ClassID projectileType;
+};
+
+#endif /* _AMMO_CONTAINER_H */
Index: branches/heathaze/src/world_entities/weapons/boomerang_gun.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/boomerang_gun.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/boomerang_gun.cc	(revision 9940)
@@ -0,0 +1,151 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Benjamin Grauer
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "boomerang_gun.h"
+
+#include "weapon_manager.h"
+#include "world_entities/projectiles/projectile.h"
+
+#include "model.h"
+
+#include "state.h"
+#include "animation3d.h"
+
+#include "util/loading/factory.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(BoomerangGun, CL_BOOMERANG_GUN);
+CREATE_FACTORY(BoomerangGun);
+
+
+/**
+ *  standard constructor
+ *
+ * creates a new BoomerangGun
+ */
+BoomerangGun::BoomerangGun ()
+  : Weapon()
+{
+  this->init();
+}
+
+/**
+ * creates a new BoomerangGun from a TiXmlElement
+ */
+BoomerangGun::BoomerangGun(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+BoomerangGun::~BoomerangGun ()
+{
+  // model will be deleted from WorldEntity-destructor
+}
+
+void BoomerangGun::init()
+{
+  this->registerObject(this, BoomerangGun::_objectList);
+
+
+  Animation3D* animation1 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation2 = this->getAnimation(WS_DEACTIVATING, this);
+
+  animation1->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+
+  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+
+  this->setStateDuration(WS_SHOOTING, .6);
+  this->setStateDuration(WS_RELOADING, 1.0f);
+  this->setStateDuration(WS_ACTIVATING, .4);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setEnergyMax(100);
+  this->increaseEnergy(100);
+  //this->minCharge = 2;
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_TURRET);
+  this->setProjectileTypeC("BoomerangProjectile");
+
+  this->loadModel("models/guns/turret1.obj", 5.0);
+
+  this->setEmissionPoint(1.684, 0.472, 0);
+  //this->getProjectileFactory()->prepare(100);
+
+  this->setActionSound(WA_SHOOT, "sound/explosions/explosion_3.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/vocals/missiles.wav");
+  this->setActionSound(WA_RELOAD, "sound/vocals/reload.wav");
+
+}
+
+void BoomerangGun::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+}
+
+void BoomerangGun::activate()
+{
+}
+
+void BoomerangGun::deactivate()
+{
+}
+
+void BoomerangGun::tick(float dt)
+{
+  if (!Weapon::tickW(dt))
+    return;
+
+  Quaternion quat;
+  Vector direction;
+  if (this->getDefaultTarget() == NULL)
+    direction = this->getAbsCoor();
+  else
+    direction = this->getDefaultTarget()->getAbsCoor() - this->getAbsCoor();
+
+  direction.normalize();
+
+  if (likely (this->getParent() != NULL))
+    quat = Quaternion(direction, this->getParent()->getAbsDir().apply(Vector(0,1,0))) * Quaternion ( -M_PI_2, Vector(0,1,0)) ;
+  else
+    quat = Quaternion(direction, Vector(0,1,0)) * Quaternion ( -M_PI_2, Vector(0,1,0)) ;
+
+  this->setAbsDirSoft(quat, 5);
+}
+
+void BoomerangGun::fire()
+{
+  Projectile* pj = this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  pj->setVelocity(this->getVelocity()+(this->getAbsDir().apply(Vector(1,0,0))*100.0 /*+ VECTOR_RAND(13) */
+            /*target->getAbsCoor() - this->getAbsCoor()*/)*.5);//this->getVelocity());
+
+
+  pj->setParent(PNode::getNullParent());
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
Index: branches/heathaze/src/world_entities/weapons/boomerang_gun.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/boomerang_gun.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/boomerang_gun.h	(revision 9940)
@@ -0,0 +1,32 @@
+/*!
+ * @file turret.h
+*/
+
+
+#ifndef _BOOMERANG_GUN_H
+#define _BOOMERANG_GUN_H
+
+#include "weapon.h"
+
+class BoomerangGun : public Weapon
+  {
+    ObjectListDeclaration(BoomerangGun);
+  public:
+    BoomerangGun ();
+    BoomerangGun(const TiXmlElement* root);
+    virtual ~BoomerangGun ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void tick(float dt);
+    virtual void fire();
+
+
+  private:
+  };
+
+#endif /* _BOOMERANG_GUN_H */
Index: branches/heathaze/src/world_entities/weapons/cannon.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/cannon.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/cannon.cc	(revision 9940)
@@ -0,0 +1,201 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+
+
+   @todo: direction in which the projectile flights
+   @todo: a target to set/hit
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "cannon.h"
+
+#include "world_entity.h"
+#include "model.h"
+#include "world_entities/projectiles/projectile.h"
+#include "weapon_manager.h"
+#include "util/loading/factory.h"
+
+#include "vector.h"
+#include "animation3d.h"
+
+#include "loading/fast_factory.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Cannon, CL_CANNON);
+CREATE_FACTORY(Cannon);
+
+/**
+ *  standard constructor
+
+   creates a new weapon
+*/
+Cannon::Cannon ()
+  : Weapon()
+{
+  this->init();
+}
+
+
+Cannon::Cannon(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+Cannon::~Cannon ()
+{
+  // model will be deleted from WorldEntity-destructor
+}
+
+
+void Cannon::init()
+{
+  this->registerObject(this, Cannon::_objectList);
+
+//  this->model = (Model*)ResourceManager::getInstance()->load("models/guns/test_gun.obj", OBJ, RP_CAMPAIGN);
+
+  this->loadModel("models/guns/cannon.obj", 1.0);
+
+  this->setStateDuration(WS_SHOOTING, 2.0);
+  this->setStateDuration(WS_RELOADING, .1);
+  this->setStateDuration(WS_ACTIVATING, .1);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setEnergyMax(100);
+  this->increaseEnergy(100);
+  //this->minCharge = 2;
+
+  this->setActionSound(WA_SHOOT, "sound/explo.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/voices/cannon.wav");
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_DIRECTIONAL | WTYPE_HEAVY);
+  this->setProjectileTypeC("Bomb");
+  this->prepareProjectiles(5);
+
+//  this->objectComponent1 = new PNode();
+//  Animation3D* animation1 = this->getAnimation(WS_SHOOTING, this->objectComponent1);
+  Animation3D* animation2 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation3 = this->getAnimation(WS_DEACTIVATING, this);
+  //parent->addChild(this->objectComponent1, PNODE_ALL);
+//  this->addChild(this->objectComponent1);
+
+//  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+  animation3->setInfinity(ANIM_INF_CONSTANT);
+
+  this->setEmissionPoint(3.8, 1.2, 0);
+
+//     animation1->addKeyFrame(Vector(0, -1.5, 0), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+//     animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+//     animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.0, ANIM_LINEAR, ANIM_NULL);
+
+  animation2->addKeyFrame(Vector(0.0, -1.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+  animation2->addKeyFrame(Vector(0.0, 0.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+
+  animation3->addKeyFrame(Vector(0.0, 0.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+  animation3->addKeyFrame(Vector(0.0, -1.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+}
+
+
+void Cannon::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+}
+
+
+/**
+ *  this activates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void Cannon::activate()
+{
+}
+
+
+/**
+ *  this deactivates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void Cannon::deactivate()
+{
+}
+
+
+/**
+ *  fires the weapon
+
+   this is called from the player.cc, when fire-button is been pushed
+   @todo: the ObjectManager deliveres Projectiles not TestBullets! this should be diffrent
+*/
+void Cannon::fire()
+{
+  Projectile* pj =  this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  pj->setParent(PNode::getNullParent());
+
+  pj->setVelocity(this->getVelocity() + this->getAbsDir().apply(Vector(1,0,0))*15+VECTOR_RAND(5));
+
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
+
+
+/**
+ *  this will draw the weapon
+*/
+void Cannon::draw () const
+{
+  /* draw gun body */
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  this->getModel()->draw();
+  glPopMatrix();
+
+  /* draw objectComponent1: gun coil - animated stuff */
+/*  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->objectComponent1->getAbsCoor ().x,
+                this->objectComponent1->getAbsCoor ().y,
+                this->objectComponent1->getAbsCoor ().z);
+  tmpRot = this->objectComponent1->getAbsDir().getSpacialAxis();
+  glRotatef (this->objectComponent1->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  this->model->draw(0);
+
+  glPopMatrix();*/
+}
+
Index: branches/heathaze/src/world_entities/weapons/cannon.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/cannon.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/cannon.h	(revision 9940)
@@ -0,0 +1,33 @@
+/*!
+ * @file cannon.h
+ * a weapon that is fix on top of the player to fire heavy weaponary.
+*/
+
+
+#ifndef _CANNON_H
+#define _CANNON_H
+
+#include "weapon.h"
+
+class Cannon : public Weapon
+  {
+    ObjectListDeclaration(Cannon);
+  public:
+    Cannon ();
+    Cannon (const TiXmlElement* root);
+    virtual ~Cannon ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void fire();
+
+    virtual void draw() const;
+
+  private:
+//     PNode* objectComponent1;         //<! the gun is made of multiple parts, these PNodes represent their location and orientation
+  };
+#endif /* _CANNON_H */
Index: branches/heathaze/src/world_entities/weapons/crosshair.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/crosshair.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/crosshair.cc	(revision 9940)
@@ -0,0 +1,176 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "crosshair.h"
+
+#include "util/loading/load_param.h"
+#include "graphics_engine.h"
+#include "glincl.h"
+#include "state.h"
+#include "material.h"
+
+
+
+ObjectListDefinition(Crosshair);
+/**
+ * standart constructor
+ */
+Crosshair::Crosshair (const TiXmlElement* root)
+{
+  this->init();
+
+  if (root)
+    this->loadParams(root);
+  else
+    this->setTexture("maps/aim.png");
+}
+
+/**
+ * destroys a Crosshair
+*/
+Crosshair::~Crosshair ()
+{
+  if (this->material)
+  delete this->material;
+}
+
+/**
+ * initializes the Crosshair
+ */
+void Crosshair::init()
+{
+  this->registerObject(this, Crosshair::_objectList);
+  this->setName("Crosshair");
+
+  this->setLayer(E2D_LAYER_TOP);
+  this->setRotationSpeed(5);
+  this->setSize(GraphicsEngine::getInstance()->getResolutionX()/10.0);
+
+  this->setBindNode(this);
+  this->material = new Material;
+
+  //this->subscribeEvent(ES_GAME, EV_MOUSE_MOTION);
+
+  // center the mouse on the screen, and also hide the cursors
+  /*  SDL_WarpMouse(GraphicsEngine::getInstance()->getResolutionX()/2, GraphicsEngine::getInstance()->getResolutionY()/2);
+  GraphicsEngine::showMouse(false);
+  SDL_WarpMouse(GraphicsEngine::getInstance()->getResolutionX()/2, GraphicsEngine::getInstance()->getResolutionY()/2);*/
+}
+
+
+void Crosshair::loadParams(const TiXmlElement* root)
+{
+  PNode::loadParams(root);
+  EventListener::loadParams(root);
+
+  LoadParam(root, "texture", this->material, Material, setDiffuseMap)
+      .describe("the texture-file to load onto the Crosshair");
+
+  LoadParam(root, "size", this, Crosshair, setSize)
+      .describe("the size of the Crosshair in Pixels");
+
+  LoadParam(root, "rotation-speed", this, Crosshair, setRotationSpeed)
+      .describe("the Speed with which the Crosshair should rotate");
+}
+
+
+/**
+ * sets the size of the Crosshair.
+ * @param size the size in pixels
+ */
+void Crosshair::setSize(float size)
+{
+  this->setSize2D(size/2, size/2);
+}
+
+/**
+ * sets the material to load
+ * @param textureFile The texture-file to load onto the crosshair
+ */
+void Crosshair::setTexture(const std::string& textureFile)
+{
+  this->material->setDiffuseMap(textureFile);
+}
+
+/**
+ * processes the input
+ * @param event the Event coming as input
+ */
+void Crosshair::process(const Event &event)
+{
+  if  (event.type == EV_MOUSE_MOTION)
+  {
+    //this->setAbsCoor2D(event.x, event.y);
+  }
+}
+
+/**
+ * ticks the Crosshair
+ * @param dt the time to ticks
+ */
+void Crosshair::tick(float dt)
+{
+  // let the crosshair rotate
+  this->shiftDir2D(dt * rotationSpeed);
+
+/*
+  float z = 0.0f;
+  glReadPixels ((int)this->getAbsCoor2D().x,
+                 GraphicsEngine::getInstance()->getResolutionY()-(int)this->getAbsCoor2D().y-1,
+                 1,
+                 1,
+                 GL_DEPTH_COMPONENT,
+                 GL_FLOAT,
+                 &z);
+
+
+  GLdouble objX=.0, objY=.0, objZ=.0;
+  gluUnProject(this->getAbsCoor2D().x,
+               GraphicsEngine::getInstance()->getResolutionY()-this->getAbsCoor2D().y-1,
+               .99,  // z
+               GraphicsEngine::modMat,
+               GraphicsEngine::projMat,
+               GraphicsEngine::viewPort,
+               &objX,
+               &objY,
+               &objZ );*/
+
+  //this->setAbsCoor(objX, objY, objZ);
+}
+
+/**
+ * draws the crosshair
+ */
+void Crosshair::draw() const
+{
+  glPushMatrix();
+  glTranslatef(this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
+
+  glRotatef(this->getAbsDir2D(), 0,0,1);
+  this->material->select();
+  glBegin(GL_TRIANGLE_STRIP);
+  glTexCoord2f(0, 0);
+  glVertex2f(-this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(1, 0);
+  glVertex2f(this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(0, 1);
+  glVertex2f(-this->getSizeX2D(), this->getSizeY2D());
+  glTexCoord2f(1, 1);
+  glVertex2f(this->getSizeX2D(), this->getSizeY2D());
+  glEnd();
+  glPopMatrix();
+}
Index: branches/heathaze/src/world_entities/weapons/crosshair.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/crosshair.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/crosshair.h	(revision 9940)
@@ -0,0 +1,46 @@
+/*!
+ * @file crosshair.h
+  *  Definition of ...
+
+*/
+
+#ifndef _CROSSHAIR_H
+#define _CROSSHAIR_H
+
+#include "p_node.h"
+#include "element_2d.h"
+#include "event_listener.h"
+
+#include "vector.h"
+
+
+// FORWARD DECLARATION
+class Model;
+class Material;
+class TiXmlElement;
+
+//! A class that enables the
+class Crosshair : public PNode, public Element2D, public EventListener {
+  ObjectListDeclaration(Crosshair);
+ public:
+  Crosshair(const TiXmlElement* root = NULL);
+  virtual ~Crosshair();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setSize(float size);
+  void setTexture(const std::string& textureFile);
+  /** @param rotationSpeed the speed at what the crosshair should rotate */
+  void setRotationSpeed(float rotationSpeed) { this->rotationSpeed = rotationSpeed; };
+
+  virtual void process(const Event &event);
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+ private:
+   Material*        material;             //!< a material for the Aim.
+   float            rotationSpeed;        //!< Speed of the Rotation.
+};
+
+#endif /* _CROSSHAIR_H */
Index: branches/heathaze/src/world_entities/weapons/fps_sniper_rifle.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/fps_sniper_rifle.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/fps_sniper_rifle.cc	(revision 9940)
@@ -0,0 +1,193 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+
+
+   @todo: direction in which the projectile flights
+   @todo: a target to set/hit
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "world_entities/projectiles/projectile.h"
+
+#include "world_entity.h"
+#include "static_model.h"
+#include "weapon_manager.h"
+#include "util/loading/factory.h"
+
+
+#include "loading/fast_factory.h"
+
+#include "fps_sniper_rifle.h"
+
+
+#include "effects/explosion.h"
+
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(FPSSniperRifle, CL_FPS_SNIPER_RIFLE);
+CREATE_FACTORY(FPSSniperRifle);
+
+/**
+ *  standard constructor
+
+   creates a new weapon
+*/
+FPSSniperRifle::FPSSniperRifle ( int leftRight)
+  : Weapon()
+{
+  this->init();
+
+  this->leftRight = leftRight;
+}
+
+
+FPSSniperRifle::FPSSniperRifle(const TiXmlElement* root)
+{
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+FPSSniperRifle::~FPSSniperRifle ()
+{
+  // model will be deleted from WorldEntity-destructor
+  if( this->material != NULL)
+    delete this->material;
+}
+
+
+void FPSSniperRifle::init()
+{
+  this->registerObject(this, FPSSniperRifle::_objectList);
+
+  this->loadModel("models/guns/fps_sniper_rifle.obj", 0.2);
+  this->material = new Material();
+  this->material->setIllum(3);
+  this->material->setAmbient(1.0, 1.0, 1.0);
+  this->material->setDiffuseMap("maps/rifle01tex.jpg");
+
+  this->setStateDuration(WS_SHOOTING, .1);
+  this->setStateDuration(WS_RELOADING, .1);
+  this->setStateDuration(WS_ACTIVATING, .4);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setEnergyMax(100000);
+  this->increaseEnergy(100000);
+  //this->minCharge = 2;
+
+  this->setActionSound(WA_SHOOT, "sound/laser.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/voices/lasers.wav");
+
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+  this->setProjectileTypeC("Laser");
+  this->prepareProjectiles(20);
+
+}
+
+
+void FPSSniperRifle::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+
+}
+
+
+/**
+ *  this activates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void FPSSniperRifle::activate()
+{
+}
+
+
+/**
+ *  this deactivates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void FPSSniperRifle::deactivate()
+{
+}
+
+
+/**
+ *  fires the weapon
+
+   this is called from the player.cc, when fire-button is been pushed
+   @todo: the ObjectManager deliveres Projectiles not TestBullets! this should be diffrent
+*/
+void FPSSniperRifle::fire()
+{
+  Projectile* pj =  this->getProjectile();
+  if (pj == NULL)
+    return;
+
+//   Explosion::explode(this, Vector(0.1,0.1,0.1));
+
+  pj->setParent(this);
+  pj->setParentMode(PNODE_ROTATE_AND_MOVE);
+
+  pj->setVelocity(this->getAbsDir().apply(Vector(1,0,0))*550 + VECTOR_RAND(5) );
+
+  pj->setAbsCoor(this->getEmissionPoint() + this->getAbsDirX() * 25.0f);
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
+
+
+
+
+/**
+ *  this will draw the weapon
+ */
+void FPSSniperRifle::draw () const
+{
+  /* draw gun body */
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  if( this->leftRight == W_RIGHT)
+    glScalef(1.0, 1.0, -1.0);
+
+  this->material->select();
+  this->getModel()->draw();
+  //static_cast<StaticModel*>(this->getModel())->draw();
+
+  glPopMatrix();
+
+}
+
+
+
Index: branches/heathaze/src/world_entities/weapons/fps_sniper_rifle.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/fps_sniper_rifle.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/fps_sniper_rifle.h	(revision 9940)
@@ -0,0 +1,65 @@
+/*!
+    @file weapon.h
+  *  a weapon that a player can use
+
+    A Player has a list of weapons, that can be choosen to shoot projectiles
+    (projectiles.{cc,h}) at enemies. These weapons can be shooted sequentially
+    or (if able) combined. Therefore you can choose the weapon mode = choose
+    a weapon.
+
+    A weapon is characterized by:
+     o firing-rate: the initial firing rate of a weapon (1/s = Herz)
+     o slowdown-factor: this is a factor d: exp(-d*x), d is element of all positive R. it determines how fast the firing-rate will slow down. if no slowdown: d=0, the bigger d is, the faster the weapon will slow down!
+     o energy-consumption: this determines the energy that has to be used to produce this projectile = costs per projectile
+
+    Furthermore there are some other attributes, that will help to represent a firing
+    weapon in this world:
+     o sound file/ressource: this is a pointer to the sound-file/ressource. however it may be represented
+     o shooting animation
+
+*/
+
+
+#ifndef _FPS_SNIPER_RIFLE_H
+#define _FPS_SNIPER_RIFLE_H
+
+#include "weapon.h"
+
+
+//! a weapon can be left or right sided
+/**
+ * @todo this will be reset with mirror X/Y/Z
+ */
+#define    W_LEFT        0
+#define    W_RIGHT       1
+
+
+class Material;
+
+class FPSSniperRifle : public Weapon
+  {
+    ObjectListDeclaration(FPSSniperRifle);
+
+  public:
+    FPSSniperRifle (int leftRight);
+    FPSSniperRifle (const TiXmlElement* root);
+    virtual ~FPSSniperRifle ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void fire();
+
+    virtual void draw() const;
+
+
+
+  private:
+    int              leftRight;   //!< this will become an enum
+    Material*        material;    //!< material
+
+  };
+#endif /* _FPS_SNIPER_RIFLE_H */
Index: branches/heathaze/src/world_entities/weapons/hyperblaster.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/hyperblaster.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/hyperblaster.cc	(revision 9940)
@@ -0,0 +1,158 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Benjamin Grauer
+   co-programmer:
+
+
+   @todo: direction in which the projectile flights
+   @todo: a target to set/hit
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "hyperblaster.h"
+
+#include "world_entity.h"
+#include "model.h"
+#include "world_entities/projectiles/projectile.h"
+#include "weapon_manager.h"
+#include "util/loading/factory.h"
+
+#include "animation3d.h"
+
+#include "loading/fast_factory.h"
+
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Hyperblaster, CL_HYPERBLASTER);
+CREATE_FACTORY(Hyperblaster);
+
+Hyperblaster::Hyperblaster(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+Hyperblaster::~Hyperblaster ()
+{
+  // model will be deleted from WorldEntity-destructor
+}
+
+
+void Hyperblaster::init()
+{
+  this->registerObject(this, Hyperblaster::_objectList);
+
+//  this->model = (Model*)ResourceManager::getInstance()->load("models/guns/test_gun.obj", OBJ, RP_CAMPAIGN);
+
+  this->loadModel("models/guns/plasmadriver_#.obj", 2.0);
+
+  this->setStateDuration(WS_SHOOTING, 2.0);
+  this->setStateDuration(WS_RELOADING, 5.0);
+  this->setStateDuration(WS_ACTIVATING, .8);
+  this->setStateDuration(WS_DEACTIVATING, .8);
+
+  this->setEnergyMax(5000);
+  this->increaseEnergy(5000);
+  //this->minCharge = 2;
+
+  this->setActionSound(WA_SHOOT, "sound/explosions/explosion_4.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/powerups/whats this2.wav");
+  this->setActionSound(WA_RELOAD, "sound/spawn/alien_generator.wav");
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_DIRECTIONAL | WTYPE_HEAVY);
+  this->setProjectileTypeC("Hyperblast");
+  this->prepareProjectiles(2);
+
+//  this->objectComponent1 = new PNode();
+//  Animation3D* animation1 = this->getAnimation(WS_SHOOTING, this->objectComponent1);
+  Animation3D* animation2 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation3 = this->getAnimation(WS_DEACTIVATING, this);
+  //parent->addChild(this->objectComponent1, PNODE_ALL);
+//  this->addChild(this->objectComponent1);
+
+//  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+  animation3->setInfinity(ANIM_INF_CONSTANT);
+
+  this->setEmissionPoint(3.8, 1.2, 0);
+
+//     animation1->addKeyFrame(Vector(0, -1.5, 0), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+//     animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+//     animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.0, ANIM_LINEAR, ANIM_NULL);
+
+  animation2->addKeyFrame(Vector(0.0, -1.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+  animation2->addKeyFrame(Vector(0.0, 0.0, 0.0), Quaternion(), 0.5, ANIM_LINEAR, ANIM_NULL);
+
+  animation3->addKeyFrame(Vector(0.0, 0.0, 0.0), Quaternion(), 0.5, ANIM_LINEAR, ANIM_NULL);
+  animation3->addKeyFrame(Vector(0.0, -1.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+}
+
+
+void Hyperblaster::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+}
+
+
+/**
+ *  this activates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void Hyperblaster::activate()
+{
+}
+
+
+/**
+ *  this deactivates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void Hyperblaster::deactivate()
+{
+}
+
+
+/**
+ *  fires the weapon
+
+   this is called from the player.cc, when fire-button is been pushed
+   @todo: the ObjectManager deliveres Projectiles not TestBullets! this should be diffrent
+*/
+void Hyperblaster::fire()
+{
+  Projectile* pj =  this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  pj->setParent(PNode::getNullParent());
+
+  pj->setVelocity(this->getVelocity() + this->getAbsDir().apply(Vector(1,0,0))*15+VECTOR_RAND(5));
+
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
+
+
Index: branches/heathaze/src/world_entities/weapons/hyperblaster.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/hyperblaster.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/hyperblaster.h	(revision 9940)
@@ -0,0 +1,30 @@
+/*!
+ * @file hyperblaster.h
+ * a weapon that to fire heavy weaponary Hyperblasts.
+*/
+
+
+#ifndef _HYPERBLASTER_H
+#define _HYPERBLASTER_H
+
+#include "weapon.h"
+
+class Hyperblaster : public Weapon
+  {
+    ObjectListDeclaration(Hyperblaster);
+    public:
+    Hyperblaster (const TiXmlElement* root = NULL);
+    virtual ~Hyperblaster ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void fire();
+
+  private:
+//     PNode* objectComponent1;         //<! the gun is made of multiple parts, these PNodes represent their location and orientation
+  };
+#endif /* _HYPERBLASTER_H */
Index: branches/heathaze/src/world_entities/weapons/laser_cannon.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/laser_cannon.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/laser_cannon.cc	(revision 9940)
@@ -0,0 +1,134 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+
+
+   @todo: direction in which the projectile flights
+   @todo: a target to set/hit
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "laser_cannon.h"
+#include "world_entities/projectiles/projectile.h"
+
+#include "world_entity.h"
+#include "static_model.h"
+#include "weapon_manager.h"
+#include "util/loading/factory.h"
+
+#include "animation3d.h"
+
+#include "loading/fast_factory.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(LaserCannon, CL_LASER_CANNON);
+CREATE_FACTORY(LaserCannon);
+
+LaserCannon::LaserCannon(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+LaserCannon::~LaserCannon ()
+{
+  // model will be deleted from WorldEntity-destructor
+}
+
+
+void LaserCannon::init()
+{
+  this->registerObject(this, LaserCannon::_objectList);
+
+//  this->model = (Model*)ResourceManager::getInstance()->load("models/guns/laser_cannon.obj", OBJ, RP_CAMPAIGN);
+
+  this->loadModel("models/guns/lasercannon.obj", 5.0f);
+
+  this->setStateDuration(WS_SHOOTING, .1);
+  this->setStateDuration(WS_RELOADING, .1);
+  this->setStateDuration(WS_ACTIVATING, .4);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setEnergyMax(10000);
+  this->increaseEnergy(10000);
+  //this->minCharge = 2;
+
+  this->setActionSound(WA_SHOOT, "sound/laser.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/voices/lasers.wav");
+
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+  this->setProjectileTypeC("RailProjectile");
+  this->prepareProjectiles(100);
+  this->setEmissionPoint(Vector(2.8,0,0) * 5.0);
+}
+
+
+void LaserCannon::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+
+}
+
+
+/**
+ *  this activates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void LaserCannon::activate()
+{
+}
+
+
+/**
+ *  this deactivates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void LaserCannon::deactivate()
+{
+}
+
+
+/**
+ *  fires the weapon
+
+   this is called from the player.cc, when fire-button is been pushed
+   @todo: the ObjectManager deliveres Projectiles not TestBullets! this should be diffrent
+*/
+void LaserCannon::fire()
+{
+  Projectile* pj =  this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  // make this to let the onKill(...) fuction get the stuff
+  pj->setOwner(this->getOwner());
+
+  pj->setParent(PNode::getNullParent());
+
+  pj->setVelocity(this->getAbsDir().apply(Vector(1,0,0))*250 + VECTOR_RAND(5));
+
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
Index: branches/heathaze/src/world_entities/weapons/laser_cannon.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/laser_cannon.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/laser_cannon.h	(revision 9940)
@@ -0,0 +1,48 @@
+/*!
+    @file weapon.h
+  *  a weapon that a player can use
+
+    A Player has a list of weapons, that can be choosen to shoot projectiles
+    (projectiles.{cc,h}) at enemies. These weapons can be shooted sequentially
+    or (if able) combined. Therefore you can choose the weapon mode = choose
+    a weapon.
+
+    A weapon is characterized by:
+     o firing-rate: the initial firing rate of a weapon (1/s = Herz)
+     o slowdown-factor: this is a factor d: exp(-d*x), d is element of all positive R. it determines how fast the firing-rate will slow down. if no slowdown: d=0, the bigger d is, the faster the weapon will slow down!
+     o energy-consumption: this determines the energy that has to be used to produce this projectile = costs per projectile
+
+    Furthermore there are some other attributes, that will help to represent a firing
+    weapon in this world:
+     o sound file/ressource: this is a pointer to the sound-file/ressource. however it may be represented
+     o shooting animation
+
+*/
+
+
+#ifndef _LASER_CANNON_H
+#define _LASER_CANNON_H
+
+#include "weapon.h"
+
+
+class LaserCannon : public Weapon
+  {
+    ObjectListDeclaration(LaserCannon);
+    public:
+    LaserCannon (const TiXmlElement* root = NULL);
+    virtual ~LaserCannon ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void fire();
+
+  private:
+    PNode* objectComponent1;         //<! the gun is made of multiple parts, these PNodes represent their location and orientation
+  };
+
+#endif /* _LASER_CANNON_H */
Index: branches/heathaze/src/world_entities/weapons/targeting_turret.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/targeting_turret.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/targeting_turret.cc	(revision 9940)
@@ -0,0 +1,172 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Benjamin Grauer
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "targeting_turret.h"
+
+#include "projectiles/projectile.h"
+
+#include "model.h"
+
+#include "animation3d.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(TargetingTurret, CL_TARGETING_TURRET);
+CREATE_FACTORY(TargetingTurret);
+
+
+TargetingTurret::TargetingTurret(const TiXmlElement* root)
+{
+  this->init();
+  if( root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+TargetingTurret::~TargetingTurret ()
+{
+  if(Aim::objectList().exists(target))
+    delete target;
+  // model will be deleted from WorldEntity-destructor
+//  delete this->target;
+}
+
+void TargetingTurret::init()
+{
+  this->registerObject(this, TargetingTurret::_objectList);
+  this->target = new Aim(this);
+
+  Animation3D* animation1 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation2 = this->getAnimation(WS_DEACTIVATING, this);
+
+  animation1->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+
+  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+
+  this->setStateDuration(WS_SHOOTING, .5);
+  this->setStateDuration(WS_RELOADING, 1.0);
+  this->setStateDuration(WS_ACTIVATING, .4);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setEnergyMax(100);
+  this->increaseEnergy(100);
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_TURRET);
+  this->setProjectileTypeC("GuidedMissile");
+
+
+  this->setEmissionPoint(1.684, 0.472, 0);
+  //this->getProjectileFactory()->prepare(100);
+
+  this->target->setVisibility(false);
+  this->target->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT | PNODE_PROHIBIT_CHILD_DELETE);
+  this->target->setRange(1000);
+  this->target->setAngle(M_PI_4);
+  this->lockedTarget = this->target;
+
+  this->lockedTime = 0;
+  this->neededLockTime = 2;
+  this->lockedTarget->setParent(PNode::getNullParent());
+  this->loadModel("models/guns/turret2.obj");
+
+
+  this->setActionSound(WA_SHOOT, "sound/explosions/explosion_3.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/voices/rockets.wav");
+  this->setActionSound(WA_RELOAD, "sound/vocals/reload.wav");
+}
+
+void TargetingTurret::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+
+  LoadParam(root, "target-group", target, Aim, setTargetGroupS);
+
+}
+
+void TargetingTurret::activate()
+{
+  // TODO move this back in
+  //this->target->setVisibility(true);
+}
+
+void TargetingTurret::deactivate()
+{
+  this->target->setVisibility(false);
+}
+
+void TargetingTurret::tick(float dt)
+{
+  if (!Weapon::tickW(dt))
+    return;
+
+  this->target->tick(dt);
+
+  if( lockedTime >= neededLockTime )
+   {
+    lockedTarget = this->target->getParent();
+    lockedTime = 0;
+   }
+
+
+  if(this->target->getParent() == PNode::getNullParent())
+   lockedTime = 0;
+  else
+   lockedTime += dt;
+
+}
+
+void TargetingTurret::fire()
+{
+  Projectile* pj = this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  pj->setVelocity(this->getVelocity() + /*this->getVelocity()+*/(this->getAbsDir().apply(Vector(1,0,0))*250.0 + VECTOR_RAND(13)
+            /*target->getAbsCoor() - this->getAbsCoor()*/)*.5);//this->getVelocity());
+
+  pj->setTarget(lockedTarget);
+  pj->setParent(PNode::getNullParent());
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
+
+/**
+ * draws the TargetingTurret
+*/
+void TargetingTurret::draw () const
+{
+  /* draw gun body */
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  if (this->getModel() != NULL)
+    this->getModel()->draw();
+  glPopMatrix();
+}
+
Index: branches/heathaze/src/world_entities/weapons/targeting_turret.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/targeting_turret.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/targeting_turret.h	(revision 9940)
@@ -0,0 +1,42 @@
+/*!
+ * @file aiming_turret.h
+*/
+
+
+#ifndef _TARGETING_TURRET_H
+#define _TARGETING_TURRET_H
+
+#include "weapon.h"
+#include "aim.h"
+
+class TargetingTurret : public Weapon
+{
+  ObjectListDeclaration(TargetingTurret);
+public:
+  TargetingTurret(const TiXmlElement* root = NULL);
+  virtual ~TargetingTurret ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void activate();
+  virtual void deactivate();
+
+  virtual void tick(float dt);
+  virtual void fire();
+
+  virtual void draw() const;
+
+  void setTargetGroup(OM_LIST targetGroup) { this->target->setTargetGroup(targetGroup); };
+  const PNode* getLockedTarget() const { return lockedTarget; };
+
+private:
+  void init();
+
+private:
+  Aim*           target;
+  PNode*         lockedTarget;
+  float          lockedTime;
+  float          neededLockTime;
+};
+
+#endif /* _TARGETING_TURRET_H */
Index: branches/heathaze/src/world_entities/weapons/test_gun.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/test_gun.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/test_gun.cc	(revision 9940)
@@ -0,0 +1,224 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+
+
+   @todo: direction in which the projectile flights
+   @todo: a target to set/hit
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "test_gun.h"
+#include "world_entities/projectiles/projectile.h"
+
+#include "world_entity.h"
+#include "static_model.h"
+#include "weapon_manager.h"
+#include "util/loading/factory.h"
+
+#include "animation3d.h"
+
+#include "loading/fast_factory.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(TestGun, CL_TEST_GUN);
+CREATE_FACTORY(TestGun);
+/**
+ *  standard constructor
+
+   creates a new weapon
+*/
+TestGun::TestGun ( int leftRight)
+  : Weapon()
+{
+  this->init();
+
+
+  this->leftRight = leftRight;
+
+  this->objectComponent1 = new PNode();
+  Animation3D* animation1 = this->getAnimation(WS_SHOOTING, this->objectComponent1);
+  Animation3D* animation2 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation3 = this->getAnimation(WS_DEACTIVATING, this);
+  //parent->addChild(this->objectComponent1, PNODE_ALL);
+  this->addChild(this->objectComponent1);
+
+  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+  animation3->setInfinity(ANIM_INF_CONSTANT);
+
+  if( this->leftRight == W_LEFT)
+  {
+    this->setEmissionPoint(1.0, -0.6, -0.2);
+
+    animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+    animation1->addKeyFrame(Vector(-0.4, 0, 0), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+    animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.0, ANIM_LINEAR, ANIM_NULL);
+
+    animation2->addKeyFrame(Vector(0.0, 0.0, -1.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+    animation2->addKeyFrame(Vector(0.0, 0.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+
+    animation3->addKeyFrame(Vector(0.0, 0.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+    animation3->addKeyFrame(Vector(0.0, 0.0, -1.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+  }
+  else if( this->leftRight == W_RIGHT)
+  {
+    this->setEmissionPoint(1.0, -0.6, 0.3);
+
+    this->objectComponent1->setRelCoor(Vector(0,0,0.35));
+    animation1->addKeyFrame(Vector(0, 0, .5), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+    animation1->addKeyFrame(Vector(-0.4, 0, .5), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+    animation1->addKeyFrame(Vector(0, 0, .5), Quaternion(), 0.0, ANIM_LINEAR, ANIM_NULL);
+
+    animation2->addKeyFrame(Vector(.0, .0, 1.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+    animation2->addKeyFrame(Vector(.0, .0, .0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+
+    animation3->addKeyFrame(Vector(.0, .0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+    animation3->addKeyFrame(Vector(.0, .0, 1.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+  }
+}
+
+
+TestGun::TestGun(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+TestGun::~TestGun ()
+{
+  // model will be deleted from WorldEntity-destructor
+}
+
+
+void TestGun::init()
+{
+  this->registerObject(this, TestGun::_objectList);
+//  this->model = (Model*)ResourceManager::getInstance()->load("models/guns/test_gun.obj", OBJ, RP_CAMPAIGN);
+
+  this->loadModel("models/guns/test_gun.obj");
+
+  this->setStateDuration(WS_SHOOTING, .1);
+  this->setStateDuration(WS_RELOADING, .1);
+  this->setStateDuration(WS_ACTIVATING, .4);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setEnergyMax(10000);
+  this->increaseEnergy(10000);
+  //this->minCharge = 2;
+
+  this->setActionSound(WA_SHOOT, "sound/laser.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/voices/lasers.wav");
+
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+  this->setProjectileTypeC("Laser");
+  this->prepareProjectiles(100);
+
+}
+
+
+void TestGun::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+
+}
+
+
+/**
+ *  this activates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void TestGun::activate()
+{
+}
+
+
+/**
+ *  this deactivates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void TestGun::deactivate()
+{
+}
+
+
+/**
+ *  fires the weapon
+
+   this is called from the player.cc, when fire-button is been pushed
+   @todo: the ObjectManager deliveres Projectiles not TestBullets! this should be diffrent
+*/
+void TestGun::fire()
+{
+  Projectile* pj =  this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  // set the owner
+  pj->setOwner(this->getOwner());
+
+  pj->setParent(PNode::getNullParent());
+
+  pj->setVelocity(this->getAbsDir().apply(Vector(1,0,0))*250 + VECTOR_RAND(5));
+
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
+
+
+
+/**
+ *  this will draw the weapon
+*/
+void TestGun::draw () const
+{
+  /* draw gun body */
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  if( this->leftRight == W_RIGHT)
+    glScalef(1.0, 1.0, -1.0);
+  static_cast<StaticModel*>(this->getModel())->draw(1);
+  glPopMatrix();
+
+  /* draw objectComponent1: gun coil - animated stuff */
+  glPushMatrix();
+  glTranslatef (this->objectComponent1->getAbsCoor ().x,
+                this->objectComponent1->getAbsCoor ().y,
+                this->objectComponent1->getAbsCoor ().z);
+  tmpRot = this->objectComponent1->getAbsDir().getSpacialAxis();
+  glRotatef (this->objectComponent1->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  static_cast<StaticModel*>(this->getModel())->draw(0);
+  glPopMatrix();
+}
+
Index: branches/heathaze/src/world_entities/weapons/test_gun.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/test_gun.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/test_gun.h	(revision 9940)
@@ -0,0 +1,60 @@
+/*!
+    @file weapon.h
+  *  a weapon that a player can use
+
+    A Player has a list of weapons, that can be choosen to shoot projectiles
+    (projectiles.{cc,h}) at enemies. These weapons can be shooted sequentially
+    or (if able) combined. Therefore you can choose the weapon mode = choose
+    a weapon.
+
+    A weapon is characterized by:
+     o firing-rate: the initial firing rate of a weapon (1/s = Herz)
+     o slowdown-factor: this is a factor d: exp(-d*x), d is element of all positive R. it determines how fast the firing-rate will slow down. if no slowdown: d=0, the bigger d is, the faster the weapon will slow down!
+     o energy-consumption: this determines the energy that has to be used to produce this projectile = costs per projectile
+
+    Furthermore there are some other attributes, that will help to represent a firing
+    weapon in this world:
+     o sound file/ressource: this is a pointer to the sound-file/ressource. however it may be represented
+     o shooting animation
+
+*/
+
+
+#ifndef _TEST_GUN_H
+#define _TEST_GUN_H
+
+#include "weapon.h"
+
+
+//! a weapon can be left or right sided
+/**
+ * @todo this will be reset with mirror X/Y/Z
+ */
+#define    W_LEFT        0
+#define    W_RIGHT       1
+
+
+class TestGun : public Weapon
+  {
+    ObjectListDeclaration(TestGun);
+  public:
+    TestGun (int leftRight);
+    TestGun (const TiXmlElement* root);
+    virtual ~TestGun ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void fire();
+
+    virtual void draw() const;
+
+  private:
+    PNode* objectComponent1;         //<! the gun is made of multiple parts, these PNodes represent their location and orientation
+
+    int leftRight;   // this will become an enum
+  };
+#endif /* _TEST_GUN_H */
Index: branches/heathaze/src/world_entities/weapons/turret.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/turret.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/turret.cc	(revision 9940)
@@ -0,0 +1,150 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Benjamin Grauer
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "turret.h"
+
+#include "weapon_manager.h"
+#include "world_entities/projectiles/projectile.h"
+
+#include "model.h"
+
+#include "state.h"
+#include "animation3d.h"
+
+#include "util/loading/factory.h"
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(Turret, CL_TURRET);
+CREATE_FACTORY(Turret);
+
+/**
+ *  standard constructor
+ *
+ * creates a new Turret
+ */
+Turret::Turret ()
+  : Weapon()
+{
+  this->init();
+}
+
+/**
+ * creates a new Turret from a TiXmlElement
+ */
+Turret::Turret(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+Turret::~Turret ()
+{
+  // model will be deleted from WorldEntity-destructor
+}
+
+void Turret::init()
+{
+  this->registerObject(this, Turret::_objectList);
+
+
+  Animation3D* animation1 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation2 = this->getAnimation(WS_DEACTIVATING, this);
+
+  animation1->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+
+  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+
+  this->setStateDuration(WS_SHOOTING, .6);
+  this->setStateDuration(WS_RELOADING, 1.0f);
+  this->setStateDuration(WS_ACTIVATING, .4);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setEnergyMax(100);
+  this->increaseEnergy(100);
+  //this->minCharge = 2;
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_TURRET);
+  this->setProjectileTypeC("Rocket");
+
+  this->loadModel("models/guns/turret1.obj");
+
+  this->setEmissionPoint(1.684, 0.472, 0);
+  //this->getProjectileFactory()->prepare(100);
+
+  this->setActionSound(WA_SHOOT, "sound/explosions/explosion_3.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/vocals/missiles.wav");
+  this->setActionSound(WA_RELOAD, "sound/vocals/reload.wav");
+
+}
+
+void Turret::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+}
+
+void Turret::activate()
+{
+}
+
+void Turret::deactivate()
+{
+}
+
+void Turret::tick(float dt)
+{
+  if (!Weapon::tickW(dt))
+    return;
+
+  Quaternion quat;
+  Vector direction;
+  if (this->getDefaultTarget() == NULL)
+    direction = this->getAbsCoor();
+  else
+    direction = this->getDefaultTarget()->getAbsCoor() - this->getAbsCoor();
+
+  direction.normalize();
+
+  if (likely (this->getParent() != NULL))
+    quat = Quaternion(direction, this->getParent()->getAbsDir().apply(Vector(0,1,0))) * Quaternion ( -M_PI_2, Vector(0,1,0)) ;
+  else
+    quat = Quaternion(direction, Vector(0,1,0)) * Quaternion ( -M_PI_2, Vector(0,1,0)) ;
+
+  this->setAbsDirSoft(quat, 5);
+}
+
+void Turret::fire()
+{
+  Projectile* pj = this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  pj->setVelocity(this->getVelocity()+(this->getAbsDir().apply(Vector(1,0,0))*100.0 /*+ VECTOR_RAND(13) */
+            /*target->getAbsCoor() - this->getAbsCoor()*/)*.5);//this->getVelocity());
+
+
+  pj->setParent(PNode::getNullParent());
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
Index: branches/heathaze/src/world_entities/weapons/turret.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/turret.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/turret.h	(revision 9940)
@@ -0,0 +1,32 @@
+/*!
+ * @file turret.h
+*/
+
+
+#ifndef _TURRET_H
+#define _TURRET_H
+
+#include "weapon.h"
+
+class Turret : public Weapon
+  {
+    ObjectListDeclaration(Turret);
+  public:
+    Turret ();
+    Turret(const TiXmlElement* root);
+    virtual ~Turret ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void tick(float dt);
+    virtual void fire();
+
+
+  private:
+  };
+
+#endif /* _TURRET_H */
Index: branches/heathaze/src/world_entities/weapons/weapon.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/weapon.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/weapon.cc	(revision 9940)
@@ -0,0 +1,776 @@
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+   2005-07-15: Benjamin Grauer: restructurating the entire Class
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "weapon.h"
+
+#include "loading/fast_factory.h"
+#include "world_entities/projectiles/projectile.h"
+
+#include "util/loading/factory.h"
+#include "util/loading/load_param.h"
+#include "state.h"
+#include "animation3d.h"
+
+#include "sound_source.h"
+#include "sound_buffer.h"
+#include "resource_sound_buffer.h"
+
+#include "elements/glgui_energywidget.h"
+
+ObjectListDefinition(Weapon);
+
+////////////////////
+// INITAILISATION //
+// SETTING VALUES //
+////////////////////
+/**
+ * standard constructor
+ *
+ * creates a new weapon
+*/
+Weapon::Weapon ()
+{
+  this->init();
+}
+
+/**
+ * standard deconstructor
+*/
+Weapon::~Weapon ()
+{
+  for (int i = 0; i < WS_STATE_COUNT; i++)
+    if (this->animation[i] && Animation::objectList().exists(animation[i]))  //!< @todo this should check animation3D
+      delete this->animation[i];
+
+  if (OrxSound::SoundSource::objectList().exists(this->soundSource))
+    delete this->soundSource;
+}
+
+/**
+ * @brief creates a new Weapon of type weaponID and returns it.
+ * @param weaponID the WeaponID type to create.
+ * @returns the newly created Weapon.
+ */
+Weapon* Weapon::createWeapon(const ClassID& weaponID)
+{
+  BaseObject* createdObject = Factory::fabricate(weaponID);
+  if (createdObject != NULL)
+  {
+    if (createdObject->isA(Weapon::staticClassID()))
+      return dynamic_cast<Weapon*>(createdObject);
+    else
+    {
+      delete createdObject;
+      return NULL;
+    }
+  }
+  return NULL;
+}
+
+Weapon* Weapon::createWeapon(const std::string& weaponName)
+{
+  BaseObject* createdObject = Factory::fabricate(weaponName);
+  if (createdObject != NULL)
+  {
+    if (createdObject->isA(Weapon::staticClassID()))
+      return dynamic_cast<Weapon*>(createdObject);
+    else
+    {
+      delete createdObject;
+      return NULL;
+    }
+  }
+  return NULL;
+}
+
+
+/**
+ * initializes the Weapon with ALL default values
+ *
+ * This Sets the default values of the Weapon
+ */
+void Weapon::init()
+{
+  this->registerObject(this, Weapon::_objectList);
+  this->currentState     = WS_INACTIVE;            //< Normaly the Weapon is Inactive
+  this->requestedAction  = WA_NONE;                //< No action is requested by default
+  this->stateDuration    = 0.0;                    //< All the States have zero duration
+  for (int i = 0; i < WS_STATE_COUNT; i++)         //< Every State has:
+  {
+    this->times[i] = 0.0;                        //< An infinitesimal duration
+    this->animation[i] = NULL;                   //< No animation
+  }
+
+  this->soundSource = new OrxSound::SoundSource(this);       //< Every Weapon has exacty one SoundSource.
+  this->emissionPoint.setParent(this);             //< One EmissionPoint, that is a PNode connected to the weapon. You can set this to the exitting point of the Projectiles
+  this->emissionPoint.setName("EmissionPoint");
+  this->emissionPoint.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+
+  this->defaultTarget = NULL;                      //< Nothing is Targeted by default.
+
+  this->projectile = NullClass::staticClassID();         //< No Projectile Class is Connected to this weapon
+  this->projectileFactory = NULL;                  //< No Factory generating Projectiles is selected.
+
+  this->hideInactive = true;                       //< The Weapon will be hidden if it is inactive (by default)
+
+  this->minCharge = 1.0;                           //< The minimum charge the Weapon can hold is 1 unit.
+  this->maxCharge = 1.0;                           //< The maximum charge is also one unit.
+
+  this->energy = 10;                               //< The secondary Buffer (before we have to reload)
+  this->energyMax = 10.0;                          //< How much energy can be carried
+  this->capability = WTYPE_ALL;                    //< The Weapon has all capabilities @see W_Capability.
+
+  this->energyWidget = NULL;
+
+  // set this object to be synchronized over network
+  //this->setSynchronized(true);
+}
+
+/**
+ * loads the Parameters of a Weapon
+ * @param root the XML-Element to load the Weapons settings from
+ */
+void Weapon::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "projectile", this, Weapon, setProjectileTypeC)
+  .describe("Sets the name of the Projectile to load onto the Entity");
+
+  LoadParam(root, "emission-point", this, Weapon, setEmissionPoint)
+  .describe("Sets the Point of emission of this weapon");
+
+  LoadParam(root, "state-duration", this, Weapon, setStateDuration)
+  .describe("Sets the duration of a given state (1: state-Name; 2: duration in seconds)");
+
+  LoadParam(root, "action-sound", this, Weapon, setActionSound)
+  .describe("Sets a given sound to an action (1: action-Name; 2: name of the sound (relative to the Data-Path))");
+}
+
+
+/**
+ * sets the Projectile to use for this weapon.
+ * @param projectile The ID of the Projectile to use
+ * @returns true, if it was sucessfull, false on error
+ *
+ * be aware, that this function does not create Factories, as this is job of Projecitle/Bullet-classes.
+ * What it does, is telling the Weapon what Projectiles it can Emit.
+ */
+void Weapon::setProjectileType(const ClassID& projectile)
+{
+  this->projectile = projectile;
+  this->projectileFactory = FastFactory::searchFastFactory(projectile);
+  if (this->projectileFactory == NULL)
+  {
+    PRINTF(1)("unable to find FastFactory for the Projectile.\n");
+    return;
+  }
+  else
+  {
+    // grabbing Parameters from the Projectile to have them at hand here.
+    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
+    this->minCharge = pj->getMinEnergy();
+    this->maxCharge = pj->getHealthMax();
+    this->chargeable = pj->isChageable();
+    this->projectileFactory->kill(pj);
+  }
+}
+
+
+/**
+ * @see bool Weapon::setProjectile(ClassID projectile)
+ * @param projectile the Name of the Projectile.
+ */
+void Weapon::setProjectileTypeC(const std::string& projectile)
+{
+  FastFactory* tmpFac = FastFactory::searchFastFactory(projectile);
+  if (tmpFac != NULL)
+  {
+    this->setProjectileType(tmpFac->getStoredID());
+  }
+  else
+  {
+    PRINTF(1)("Projectile %s does not exist for weapon %s\n", projectile.c_str(), this->getCName());
+  }
+}
+
+
+/**
+ * prepares Projectiles of the Weapon
+ * @param count how many Projectiles to create (they will be stored in the ProjectileFactory)
+ */
+void Weapon::prepareProjectiles(unsigned int count)
+{
+  if (likely(this->projectileFactory != NULL))
+    projectileFactory->prepare(count);
+  else
+    PRINTF(2)("unable to create %d projectile for Weapon %s::%s\n", count, this->getClassCName(), this->getCName());
+}
+
+
+/**
+ * resurects and returns a Projectile
+ * @returns a Projectile on success, NULL on error
+ *
+ * errors: 1. (ProjectileFastFactory not Found)
+ *         2. No more Projectiles availiable.
+ */
+Projectile* Weapon::getProjectile()
+{
+  if (likely (this->projectileFactory != NULL))
+  {
+    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
+    pj->toList((OM_LIST)(this->getOMListNumber()+1));
+    return pj;
+  }
+  else
+  {
+    PRINTF(2)("No projectile defined for Weapon %s(%s) can't return any\n", this->getCName(), this->getClassCName());
+    return NULL;
+  }
+}
+
+
+/**
+ * sets the emissionPoint's relative position from the Weapon
+ * @param point the Point relative to the mass-point of the Weapon
+ */
+void Weapon::setEmissionPoint(const Vector& point)
+{
+  this->emissionPoint.setRelCoor(point);
+}
+
+
+/**
+ * assigns a Sound-file to an action
+ * @param action the action the sound should be assigned too
+ * @param soundFile the soundFile's relative position to the data-directory (will be looked for by the ResourceManager)
+ */
+void Weapon::setActionSound(WeaponAction action, const std::string& soundFile)
+{
+  if (action >= WA_ACTION_COUNT)
+    return;
+
+  else if (!soundFile.empty())
+  {
+    this->soundBuffers[action] = OrxSound::ResourceSoundBuffer(soundFile);
+    if (this->soundBuffers[action].loaded())
+    {
+      PRINTF(4)("Loaded sound %s to action %s.\n", soundFile.c_str(), actionToChar(action));
+    }
+    else
+    {
+      PRINTF(2)("Failed to load sound %s to %s.\n.", soundFile.c_str(), actionToChar(action));
+    }
+  }
+  else
+    this->soundBuffers[action] = OrxSound::SoundBuffer();
+}
+
+
+/**
+ * creates/returns an Animation3D for a certain State.
+ * @param state what State should the Animation be created/returned for
+ * @param node the node this Animation should apply to. (NULL is fine if the animation was already created)
+ * @returns The created animation.Animation(), NULL on error (or if the animation does not yet exist).
+ *
+ * This function does only generate the Animation Object, and if set it will
+ * automatically be executed, when a certain State is reached.
+ * What this does not do, is set keyframes, you have to operate on the returned animation.
+ */
+Animation3D* Weapon::getAnimation(WeaponState state, PNode* node)
+{
+  if (state >= WS_STATE_COUNT) // if the state is not known
+    return NULL;
+
+  if (unlikely(this->animation[state] == NULL)) // if the animation does not exist yet create it.
+  {
+    if (likely(node != NULL))
+      return this->animation[state] = new Animation3D(node);
+    else
+    {
+      PRINTF(2)("Node not defined for the Creation of the 3D-animation of state %s\n", stateToChar(state));
+      return NULL;
+    }
+  }
+  else
+    return this->animation[state];
+}
+
+OrxGui::GLGuiWidget* Weapon::getEnergyWidget()
+{
+  if (this->energyWidget == NULL)
+  {
+    this->energyWidget = new OrxGui::GLGuiEnergyWidget();
+    this->energyWidget->setDisplayedName(this->getClassCName());
+    this->energyWidget->setSize2D( 20, 100);
+    this->energyWidget->setMaximum(this->getEnergyMax());
+    this->energyWidget->setValue(this->getEnergy());
+  }
+  return this->energyWidget;
+}
+
+void Weapon::updateWidgets()
+{
+  if (this->energyWidget != NULL)
+  {
+    this->energyWidget->setMaximum(this->energyMax);
+    this->energyWidget->setValue(this->energy);
+  }
+}
+
+/////////////////
+//  EXECUTION  //
+// GAME ACTION //
+/////////////////
+/**
+ * request an action that should be executed,
+ * @param action the next action to take
+ *
+ * This function must be called instead of the actions (like fire/reload...)
+ * to make all the checks needed to have a usefull WeaponSystem.
+ */
+void Weapon::requestAction(WeaponAction action)
+{
+  if (likely(this->isActive()))
+  {
+    if (this->requestedAction != WA_NONE)
+      return;
+    PRINTF(5)("next action will be %s in %f seconds\n", actionToChar(action), this->stateDuration);
+    this->requestedAction = action;
+  }
+  //else
+  else if (unlikely(action == WA_ACTIVATE))
+  {
+    this->currentState = WS_ACTIVATING;
+    this->requestedAction = WA_ACTIVATE;
+  }
+}
+
+
+/**
+ * adds energy to the Weapon
+ * @param energyToAdd The amount of energy
+ * @returns the amount of energy we did not pick up, because the weapon is already full
+ */
+float Weapon::increaseEnergy(float energyToAdd)
+{
+  float maxAddEnergy = this->energyMax - this->energy;
+
+  if (maxAddEnergy >= energyToAdd)
+  {
+    this->energy += energyToAdd;
+    return 0.0;
+  }
+  else
+  {
+    this->energy += maxAddEnergy;
+    return energyToAdd - maxAddEnergy;
+  }
+}
+
+
+////////////////////////////////////////////////////////////
+// WEAPON INTERNALS                                       //
+// These are functions, that no other Weapon should over- //
+// write. No class has direct Access to them, as it is    //
+// quite a complicated process, handling a Weapon from    //
+// the outside                                            //
+////////////////////////////////////////////////////////////
+/**
+ * executes an action, and with it starts a new State.
+ * @return true, if it worked, false otherwise
+ *
+ * This function checks, wheter the possibility of executing an action is valid,
+ * and does all the necessary stuff, to execute them. If an action does not succeed,
+ * it tries to go around it. (ex. shoot->noAmo->reload()->wait until shoot comes again)
+ */
+bool Weapon::execute()
+{
+#if DEBUG_LEVEL > 4
+  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
+  this->debug();
+#endif
+
+  WeaponAction action = this->requestedAction;
+  this->requestedAction = WA_NONE;
+
+  switch (action)
+  {
+    case WA_SHOOT:
+    return this->fireW();
+    break;
+    case WA_CHARGE:
+    return this->chargeW();
+    break;
+    case WA_RELOAD:
+    return this->reloadW();
+    break;
+    case WA_DEACTIVATE:
+    return this->deactivateW();
+    break;
+    case WA_ACTIVATE:
+    return this->activateW();
+    break;
+    default:
+    PRINTF(2)("Action %s Not Implemented yet \n", Weapon::actionToChar(action));
+    return false;
+  }
+}
+
+/**
+ * checks and activates the Weapon.
+ * @return true on success.
+ */
+bool Weapon::activateW()
+{
+  //  if (this->currentState == WS_INACTIVE)
+  {
+    // play Sound
+    if (likely(this->soundBuffers[WA_ACTIVATE].loaded()))
+      this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
+    this->updateWidgets();
+    // activate
+    PRINTF(4)("Activating the Weapon %s\n", this->getCName());
+    this->activate();
+    // setting up for next action
+    this->enterState(WS_ACTIVATING);
+  }
+  return true;
+}
+
+/**
+ * checks and deactivates the Weapon
+ * @return true on success.
+ */
+bool Weapon::deactivateW()
+{
+  //  if (this->currentState != WS_INACTIVE)
+  {
+    PRINTF(4)("Deactivating the Weapon %s\n", this->getCName());
+    // play Sound
+    if (this->soundBuffers[WA_DEACTIVATE].loaded())
+      this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
+    // deactivate
+    this->deactivate();
+    this->enterState(WS_DEACTIVATING);
+  }
+
+  return true;
+}
+
+/**
+ * checks and charges the Weapon
+ * @return true on success.
+ */
+bool Weapon::chargeW()
+{
+  if ( this->currentState != WS_INACTIVE && this->energy >= this->minCharge)
+  {
+    // playing Sound
+    if (this->soundBuffers[WA_CHARGE].loaded())
+      this->soundSource->play(this->soundBuffers[WA_CHARGE]);
+
+    // charge
+    this->charge();
+    // setting up for the next state
+    this->enterState(WS_CHARGING);
+  }
+  else // deactivate the Weapon if we do not have enough energy
+  {
+    this->requestAction(WA_RELOAD);
+  }
+  return true;
+}
+
+/**
+ * checks and fires the Weapon
+ * @return true on success.
+ */
+bool Weapon::fireW()
+{
+  //if (likely(this->currentState != WS_INACTIVE))
+  if (this->minCharge <= this->energy)
+  {
+    // playing Sound
+    if (this->soundBuffers[WA_SHOOT].loaded())
+      this->soundSource->play(this->soundBuffers[WA_SHOOT]);
+    this->updateWidgets();
+    // fire
+    this->energy -= this->minCharge;
+    this->fire();
+    // setting up for the next state
+    this->enterState(WS_SHOOTING);
+  }
+  else  // reload if we still have the charge
+  {
+    this->requestAction(WA_RELOAD);
+    this->execute();
+  }
+  return true;
+}
+
+/**
+ * checks and Reloads the Weapon
+ * @return true on success.
+ */
+bool Weapon::reloadW()
+{
+  PRINTF(4)("Reloading Weapon %s\n", this->getCName());
+  if (!this->ammoContainer.isNull() &&
+      unlikely(this->energy + this->ammoContainer->getStoredEnergy() < this->minCharge))
+  {
+    this->requestAction(WA_DEACTIVATE);
+    this->execute();
+    return false;
+  }
+
+
+  if (this->soundBuffers[WA_RELOAD].loaded())
+    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
+
+  if (!this->ammoContainer.isNull())
+    this->ammoContainer->fillWeapon(this);
+  else
+  {
+    this->energy = this->energyMax;
+  }
+  this->updateWidgets();
+  this->reload();
+  this->enterState(WS_RELOADING);
+
+  return true;
+}
+
+/**
+ * enters the requested State, plays back animations updates the timing.
+ * @param state the state to enter.
+ */
+inline void Weapon::enterState(WeaponState state)
+{
+  PRINTF(4)("ENTERING STATE %s\n", stateToChar(state));
+  // playing animation if availiable
+  if (likely(this->animation[state] != NULL))
+    this->animation[state]->replay();
+
+  this->stateDuration += this->times[state];
+  this->currentState = state;
+}
+
+///////////////////
+//  WORLD-ENTITY //
+// FUNCTIONALITY //
+///////////////////
+/**
+ * tick signal for time dependent/driven stuff
+*/
+bool Weapon::tickW(float dt)
+{
+  //printf("%s ", stateToChar(this->currentState));
+
+  // setting up the timing properties
+  this->stateDuration -= dt;
+
+  if (this->stateDuration <= 0.0)
+  {
+    if (unlikely (this->currentState == WS_DEACTIVATING))
+    {
+      this->currentState = WS_INACTIVE;
+      return false;
+    }
+    else
+      this->currentState = WS_IDLE;
+
+    if (this->requestedAction != WA_NONE)
+    {
+      this->stateDuration = -dt;
+      this->execute();
+    }
+  }
+  return true;
+}
+
+
+
+
+//////////////////////
+// HELPER FUNCTIONS //
+//////////////////////
+/**
+ * checks wether all the Weapons functions are valid, and if it is possible to go to action with it.
+ * @todo IMPLEMENT the Weapons Check
+ */
+bool Weapon::check() const
+{
+  bool retVal = true;
+
+  //  if (this->projectile == NULL)
+  {
+    PRINTF(1)("There was no projectile assigned to the Weapon.\n");
+    retVal = false;
+  }
+
+
+
+
+  return retVal;
+}
+
+/**
+ * some nice debugging information about this Weapon
+ */
+void Weapon::debug() const
+{
+  PRINT(0)("Weapon-Debug %s, state: %s (duration: %fs), nextAction: %s\n", this->getCName(), Weapon::stateToChar(this->currentState), this->stateDuration, Weapon::actionToChar(requestedAction));
+  PRINT(0)("Energy: max: %f; current: %f; chargeMin: %f, chargeMax %f\n",
+           this->energyMax, this->energy, this->minCharge, this->maxCharge);
+
+
+}
+
+////////////////////////////////////////////////////////
+// static Definitions (transormators for readability) //
+////////////////////////////////////////////////////////
+/**
+ * Converts a String into an Action.
+ * @param action the String input holding the Action.
+ * @return The Action if known, WA_NONE otherwise.
+ */
+WeaponAction Weapon::charToAction(const std::string& action)
+{
+  if (action == "none")
+    return WA_NONE;
+  else if (action == "shoot")
+    return WA_SHOOT;
+  else if (action == "charge")
+    return WA_CHARGE;
+  else if (action == "reload")
+    return WA_RELOAD;
+  else if (action == "acitvate")
+    return WA_ACTIVATE;
+  else if (action == "deactivate")
+    return WA_DEACTIVATE;
+  else if (action == "special1")
+    return WA_SPECIAL1;
+  else
+  {
+    PRINTF(2)("action %s could not be identified.\n", action.c_str());
+    return WA_NONE;
+  }
+}
+
+/**
+ * converts an action into a String
+ * @param action the action to convert
+ * @return a String matching the name of the action
+ */
+const char* Weapon::actionToChar(WeaponAction action)
+{
+  switch (action)
+  {
+    case WA_SHOOT:
+    return "shoot";
+    break;
+    case WA_CHARGE:
+    return "charge";
+    break;
+    case WA_RELOAD:
+    return "reload";
+    break;
+    case WA_ACTIVATE:
+    return "activate";
+    break;
+    case WA_DEACTIVATE:
+    return "deactivate";
+    break;
+    case WA_SPECIAL1:
+    return "special1";
+    break;
+    default:
+    return "none";
+    break;
+  }
+}
+
+/**
+ * Converts a String into a State.
+ * @param state the String input holding the State.
+ * @return The State if known, WS_NONE otherwise.
+ */
+WeaponState Weapon::charToState(const std::string& state)
+{
+  if (state == "none")
+    return WS_NONE;
+  else if (state == "shooting")
+    return WS_SHOOTING;
+  else if (state == "charging")
+    return WS_CHARGING;
+  else if (state == "reloading")
+    return WS_RELOADING;
+  else if (state == "activating")
+    return WS_ACTIVATING;
+  else if (state == "deactivating")
+    return WS_DEACTIVATING;
+  else if (state == "inactive")
+    return WS_INACTIVE;
+  else if (state == "idle")
+    return WS_IDLE;
+  else
+  {
+    PRINTF(2)("state %s could not be identified.\n", state.c_str());
+    return WS_NONE;
+  }
+}
+
+/**
+ * converts a State into a String
+ * @param state the state to convert
+ * @return a String matching the name of the state
+ */
+const char* Weapon::stateToChar(WeaponState state)
+{
+  switch (state)
+  {
+    case WS_SHOOTING:
+    return "shooting";
+    break;
+    case WS_CHARGING:
+    return "charging";
+    break;
+    case WS_RELOADING:
+    return "reloading";
+    break;
+    case WS_ACTIVATING:
+    return "activating";
+    break;
+    case WS_DEACTIVATING:
+    return "deactivating";
+    break;
+    case WS_IDLE:
+    return "idle";
+    break;
+    case WS_INACTIVE:
+    return "inactive";
+    break;
+    default:
+    return "none";
+    break;
+  }
+}
Index: branches/heathaze/src/world_entities/weapons/weapon.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/weapon.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/weapon.h	(revision 9940)
@@ -0,0 +1,241 @@
+/*!
+ * @file weapon.h
+ *
+ * Weapon is the mayor baseclass for all weapons. it is quite extensive, and expensive in use,
+ * because each weapon will know virutal functions for the WorldEntity's part, and also virtuals
+ * for Fireing/Reloading/...,
+ * quickly said: Weapon is a wrapper for weapons, that makes it easy to very quickly implement
+ * new Weapons, and with them make this game better, than any game before it, because still
+ * Weapons (GUNS) are the most important thing in life :?... no to be serious
+ * @see Weapon
+ */
+
+
+#ifndef _WEAPON_H
+#define _WEAPON_H
+
+#include "world_entity.h"
+#include "count_pointer.h"
+#include "ammo_container.h"
+
+#include "sound_buffer.h"
+
+// FORWARD DECLARATION
+class Projectile;
+class WeaponManager;
+class Animation3D;
+class TiXmlElement;
+class FastFactory;
+template<class T> class tFastFactory;
+
+//! An enumerator defining Actions a Weapon can take
+typedef enum {
+  WA_NONE          =    0,    //!< No Action taken
+  WA_SHOOT         =    1,    //!< emitting Shot
+  WA_CHARGE        =    2,    //!< charge action (one click before the shot)
+  WA_RELOAD        =    3,    //!< reload right after shoot is finished
+  WA_ACTIVATE      =    4,    //!< activate the GUN
+  WA_DEACTIVATE    =    5,    //!< deactivate the GUN
+  WA_SPECIAL1      =    6,    //!< Special Action taken
+
+  WA_ACTION_COUNT  =    7     //!< This must match the count of enumerations-members.
+} WeaponAction;
+
+//! An enumerator defining the States of a Weapon
+typedef enum {
+  WS_NONE          =    0,    //!< No State at all (if set, there is something wrong, or the weapon is not yet availiable)
+  WS_SHOOTING      =    1,    //!< The State of the Shooting
+  WS_CHARGING      =    2,    //!< The state of charging th weapon
+  WS_RELOADING     =    3,    //!< The State of the Reloading
+  WS_ACTIVATING    =    4,    //!< The State in which the weapon gets activated
+  WS_DEACTIVATING  =    5,    //!< The State in which the weapon gets deactivated
+  WS_INACTIVE      =    6,    //!< The State where the weapon is inactive (unable to shoot)
+  WS_IDLE          =    7,    //!< The State where the weapon is idle
+
+  WS_STATE_COUNT  =     8     //!< This must match the count of enumerations-members.
+} WeaponState;
+
+//! an enumerator defining capabilities of a WeaponSlot
+typedef enum
+{
+  WTYPE_DIRECTIONAL   = 0x00000001,           //!< Weapon is directional/Slot is able to carry directional weapons
+  WTYPE_TURRET        = 0x00000002,           //!< Weapon is a turret/slot is able to carry turrets
+  WTYPE_LIGHT         = 0x00000004,           //!< For light Armament.
+  WTYPE_HEAVY         = 0x00000008,           //!< The heavy Armament (Cannons).
+  WTYPE_ALLKINDS      = 0x0000000f,           //!< Weapon is all types/Slot is able to carry all kinds of weapons
+
+  WTYPE_FORWARD       = 0x00000010,           //!< Weapon fires forwards/Slot is able to carry weapons firing forwards
+  WTYPE_BACKWARD      = 0x00000020,           //!< Weapon fires backwards/Slot is able to carry weapons firing backwards
+  WTYPE_LEFT          = 0x00000040,           //!< Weapon fires to the left/Slot is able to carry weapons firing to the left
+  WTYPE_RIGHT         = 0x00000080,           //!< Weapon fires to the right/Slot is able to carry weapons firing to the right
+  WTYPE_ALLDIRS       = 0x000000f0,           //!< Weapon has no specific firing direction/Slot can fire into all directions
+
+  WTYPE_ALL           = 0x000000ff,           //!< Weapon has no limitations/Slot can handle all kinds of Weapon.
+} W_Capability;
+
+//! An abstract class, that describes weapons
+/**
+ * This is used as a container for all the different kinds of weapons that may exist
+ *
+ * Weapons have certain states, and actions, that can inflict them.
+ * ex. Action WA_SHOOT leeds to State WS_SHOOTING.
+ * each action has a sound connected to it,
+ * each state a time and an animation.
+ */
+class Weapon : public WorldEntity
+{
+  ObjectListDeclaration(Weapon);
+
+  public:
+    // INITIALISATION //
+    Weapon ();
+    virtual ~Weapon ();
+    static Weapon* createWeapon(const ClassID& weaponID);
+    static Weapon* createWeapon(const std::string& weaponName);
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+    ////////////////////
+
+    // INTERACTIVITY //
+    void requestAction(WeaponAction action);
+    float increaseEnergy(float energyToAdd);
+    ///////////////////
+
+    /** @returns true if the Weapon is Active  (this is used to check if the weapon must be drawn)*/
+    inline bool isActive() const { return (this->currentState == WS_INACTIVE)? false : true; };
+    /** @returns true if the weapon must be drawn */
+    inline bool isVisible() const { return (this->currentState != WS_INACTIVE || !this->hideInactive) ? true : false; };
+    /** @returns true if the Weapon is chargeable */
+    inline bool isChargeable() const { return this->chargeable; };
+
+    // FUNCTIONS TO SET THE WEAPONS PROPERTIES.
+    /** sets the Weapons Capabilities */
+    inline void setCapability(long capabilities) { this->capability = capabilities; };
+    /** @returns the Capabilities of this Weapon */
+    inline long getCapability() const { return this->capability; };
+    void setProjectileType(const ClassID& projectile);
+    void setProjectileTypeC(const std::string& projectile);
+    /** @returns The projectile's classID */
+    inline ClassID getProjectileType() { return this->projectile; };
+    /** @returns the FastFactory, that creates Projectiles of type getProjectile */
+    inline FastFactory* getProjectileFactory() { return this->projectileFactory; };
+    void prepareProjectiles(unsigned int count);
+    Projectile* getProjectile();
+
+
+    // EMISSION
+    void setEmissionPoint(const Vector& point);
+    /** @see void setEmissionPoint(const Vector& point); */
+    inline void setEmissionPoint(float x, float y, float z) { this->setEmissionPoint(Vector(x, y, z)); };
+    /** @returns the absolute Position of the EmissionPoint */
+    inline const Vector& getEmissionPoint() const { return this->emissionPoint.getAbsCoor(); };
+
+    inline void setDefaultTarget(PNode* defaultTarget) { this->defaultTarget = defaultTarget; };
+    inline PNode* getDefaultTarget() const { return this->defaultTarget; };
+
+    // STATE CHANGES //
+    /** @param state the State to time @param duration the duration of the State */
+    inline void setStateDuration(const std::string& state, float duration) { setStateDuration(charToState(state), duration); };
+    /** @param state the State to time @param duration the duration of the State */
+    inline void setStateDuration(WeaponState state, float duration) { /*(state < WS_STATE_COUNT)?*/this->times[state] = duration; };
+    /** @param state The state to query @returns the Time the queried State takes to complete */
+    inline float getStateDuration(WeaponState state) const { return (state < WS_STATE_COUNT)? this->times[state] : 0.0; };
+    /** @returns true if the time of the currentState is elapsed, false otherwise */
+    inline bool stateTimeElapsed() const { return (this->stateDuration > this->times[currentState])? true : false; };
+    /** @returns the current State of the Weapon */
+    inline WeaponState getCurrentState() const { return this->currentState; };
+
+    /** @param energyMax the maximum energy the Weapon can have */
+    inline void setEnergyMax(float energyMax) { this->energyMax = energyMax; };
+    inline float getEnergy() const { return this->energy; };
+    inline float getEnergyMax() const { return this->energyMax; };
+    inline void setAmmoContainer(const CountPointer<AmmoContainer>& ammoContainer) { this->ammoContainer = ammoContainer;}
+
+    void setActionSound(WeaponAction action, const std::string& soundFile);
+    /** @see void setActionSound(WeaponAction action, const std::string& soundFile); */
+    void setActionSound(const std::string& action, const std::string& soundFile) { this->setActionSound(charToAction(action), soundFile); };
+
+    Animation3D* getAnimation(WeaponState state, PNode* node = NULL);
+    Animation3D* copyAnimation(WeaponState from, WeaponState to);
+
+    OrxGui::GLGuiWidget* getEnergyWidget();
+
+    // FLOW
+    bool tickW(float dt); //!< this is a function that must be called by the weaponManager, or any other weaponHandler, all other functions are handled from within
+
+    virtual void tick(float dt) { tickW(dt); };
+
+    bool check() const;
+    void debug() const;
+
+  protected:
+    //! ACTION: these functions are handled by the Weapon itself, and must be called by requestAction(WeaponAction);
+    virtual void activate() {};
+    virtual void deactivate() {};
+    virtual void charge() {};
+    virtual void fire() {};
+    virtual void reload() {};
+
+
+    // utility:
+    static WeaponAction  charToAction(const std::string& action);
+    static const char*   actionToChar(WeaponAction action);
+    static WeaponState   charToState(const std::string& state);
+    static const char*   stateToChar(WeaponState state);
+
+  private:
+    /** executive functions, that handle timing with actions.
+     * This is for the action-functions in derived functions to be easy
+     * The main function is execute, that calls all the other functions
+     * for being fast, the Functions are private and as such will be inlined
+     * into the execute function. (this is work of the compiler)
+     */
+    bool execute();
+    bool activateW();
+    bool deactivateW();
+    bool chargeW();
+    bool fireW();
+    bool reloadW();
+    inline void enterState(WeaponState state);
+
+    void updateWidgets();
+
+  private:
+    // type of Weapon
+    long                 capability;                       //!< what capabilities the Weapon has @see W_Capability
+
+    // it is all about energy
+    float                energy;                           //!< The energy stored in the weapons buffers
+    float                energyMax;                        //!< The maximal energy that can be stored in the secondary buffers (reserveMax)
+    CountPointer<AmmoContainer> ammoContainer;             //!< Pointer to the AmmoContainer this weapon grabs Energy from.
+    //! @todo move this to projectile
+    float                minCharge;                        //!< The minimal energy to be loaded onto one projectile if chargeable otherwise the power consumed by one projectile
+    float                maxCharge;                        //!< The maximal energy to be loaded onto one projectile (this is only availible if chargeable is enabled)
+
+    OrxGui::GLGuiEnergyWidget* energyWidget;
+
+    PNode*               defaultTarget;                    //!< A target for targeting Weapons.
+
+    ////////////
+    // PHASES //
+    ////////////
+    OrxSound::SoundSource* soundSource;                     //!< A SoundSource to play sound from (this is connected to the PNode of the Weapon)
+
+    WeaponState            currentState;                    //!< The State the weapon is in.
+    WeaponAction           requestedAction;                 //!< An action to try to Engage after the currentState ends.
+    float                  stateDuration;                   //!< how long the state has taken until now.
+    float                  times[WS_STATE_COUNT];           //!< Times to stay in the different States @see WeaponState.
+    Animation3D*           animation[WS_STATE_COUNT];       //!< Animations for all the States (you can say yourself on what part of the gun this animation acts).
+    OrxSound::SoundBuffer  soundBuffers[WA_ACTION_COUNT];   //!< SoundBuffers for all actions @see WeaponAction.
+
+    PNode                  emissionPoint;                   //!< The point, where the projectiles are emitted. (this is coppled with the Weapon by default)
+
+    bool                   hideInactive;                    //!< Hides the Weapon if it is inactive
+    bool                   chargeable;                      //!< if the Weapon is charcheable (if true, the weapon will charge before it fires.)
+
+    ClassID                projectile;                      //!< the projectile used for this weapon (since they should be generated via macro and the FastFactory, only the ClassID must be known.)
+    FastFactory*           projectileFactory;               //!< A factory, that produces and handles the projectiles.
+  };
+
+#endif /* _WEAPON_H */
Index: branches/heathaze/src/world_entities/weapons/weapon_manager.cc
===================================================================
--- branches/heathaze/src/world_entities/weapons/weapon_manager.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/weapon_manager.cc	(revision 9940)
@@ -0,0 +1,560 @@
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+   2005-07-24: Benjamin Grauer: restructurate, so it can handle the new Weapons.
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "weapon_manager.h"
+#include "weapon.h"
+#include "crosshair.h"
+
+#include "playable.h"
+
+#include "util/loading/load_param_xml.h"
+#include "util/loading/factory.h"
+
+#include "t_animation.h"
+
+
+ObjectListDefinition(WeaponManager);
+/**
+ * @brief this initializes the weaponManager for a given nnumber of weapon slots
+ * @param number of weapon slots of the model/ship <= 8 (limitied)
+ */
+WeaponManager::WeaponManager(WorldEntity* parent)
+{
+  this->init();
+  this->setParentEntity(parent);
+
+  assert (parent != NULL);
+}
+
+WeaponManager::WeaponManager(const TiXmlElement* root)
+{
+  this->init();
+  this->loadParams(root);
+}
+
+/**
+ * @brief Destroys a WeaponManager
+ */
+WeaponManager::~WeaponManager()
+{
+  // crosshair being a PNode it must not be deleted (this is because PNodes delete themselves.)
+  // rennerc: crosshair seems not to delete itselve
+  //if (Crosshair::objectList().exists(this->crosshair))
+  //  delete this->crosshair;
+}
+
+/**
+ * @brief initializes the WeaponManager
+ */
+void WeaponManager::init()
+{
+  this->registerObject(this, WeaponManager::_objectList);
+
+  this->parentNode = NULL;
+  this->parentEntity = NULL;
+
+  for (int i = 0; i < WM_MAX_CONFIGS; i++)
+    for (int j = 0; j < WM_MAX_SLOTS; j++)
+      this->configs[i][j] = NULL;
+
+  for (int i = 0; i < WM_MAX_SLOTS; i++)
+  {
+    this->currentSlotConfig[i].capability = WTYPE_ALL;
+    this->currentSlotConfig[i].currentWeapon = NULL;
+    this->currentSlotConfig[i].nextWeapon = NULL;
+
+    // NAMING
+    char* tmpName;
+    if (!this->getName().empty())
+    {
+      tmpName = new char[this->getName().size() + 10];
+      sprintf(tmpName, "%s_slot%d", this->getCName(), i);
+    }
+    else
+    {
+      tmpName = new char[30];
+      sprintf(tmpName, "WeaponMan_slot%d", i);
+    }
+    this->currentSlotConfig[i].position.setName(tmpName);
+    this->currentSlotConfig[i].position.deactivateNode();
+    delete[] tmpName;
+  }
+
+  for (int i = 0; i < WM_MAX_LOADED_WEAPONS; i++)
+    this->availiableWeapons[i] = NULL;
+
+
+  this->currentConfigID = 0;
+  this->slotCount = 2;
+  //this->weaponChange;
+
+  // CROSSHAIR INITIALISATION
+  this->crosshair = new Crosshair();
+  //this->crosshair->setRelCoor(1000,0,0);
+  this->crossHairSizeAnim = new tAnimation<Crosshair>(this->crosshair, &Crosshair::setSize);
+  this->crossHairSizeAnim->setInfinity(ANIM_INF_REWIND);
+  this->crossHairSizeAnim->addKeyFrame(50, .1, ANIM_LINEAR);
+  this->crossHairSizeAnim->addKeyFrame(100, .05, ANIM_LINEAR);
+  this->crossHairSizeAnim->addKeyFrame(50, .01, ANIM_LINEAR);
+}
+
+/**
+ * @brief loads the settings of the WeaponManager
+ * @param root the XML-element to load from
+ */
+void WeaponManager::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+
+  LoadParam(root, "slot-count", this, WeaponManager, setSlotCount)
+  .describe("how many slots(cannons) the WeaponManager can handle");
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    // CHECK IF THIS WORKS....
+    LoadParamXML_CYCLE(element, "weapons", this, WeaponManager, loadWeapons)
+    .describe("loads Weapons");
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ * @brief loads a Weapon onto the WeaponManager
+ * @param root the XML-element to load the Weapons from
+ */
+void WeaponManager::loadWeapons(const TiXmlElement* root)
+{
+  LOAD_PARAM_START_CYCLE(root, element);
+
+  BaseObject* object = Factory::fabricate(element);
+  if (object != NULL)
+  {
+    Weapon* newWeapon = dynamic_cast<Weapon*>(object);
+    if (newWeapon == NULL)
+      delete object;
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ * @brief sets the Parent of the WeaponManager.
+ * @param parent the parent of the WeaponManager
+ *
+ * this is used, to identify to which ship/man/whatever this WeaponManager is connected.
+ * also all the Slots will be subconnected to this parent.
+ *
+ * The reason this function exists is that the WeaponManager is neither a WorldEntity nor
+ * a PNode.
+ */
+void WeaponManager::setParentEntity(WorldEntity* parent)
+{
+  this->parentEntity = parent;
+  if (this->parentNode == NULL)
+    this->setParentNode(parent);
+}
+
+
+void WeaponManager::setParentNode(PNode* parent)
+{
+  this->parentNode = parent;
+  assert(parent != NULL);
+
+  if (this->parentNode != NULL)
+  {
+    for (int i = 0; i < WM_MAX_SLOTS; i++)
+      this->parentNode->addChild(&this->currentSlotConfig[i].position);
+  }
+
+}
+
+
+/**
+ * @brief sets the number of Slots the WeaponManager has
+ * @param slotCount the number of slots
+ */
+void WeaponManager::setSlotCount(unsigned int slotCount)
+{
+  if (slotCount <= WM_MAX_SLOTS)
+    this->slotCount = slotCount;
+  else
+    this->slotCount = WM_MAX_SLOTS;
+}
+
+
+/**
+ * @brief sets the position of the Slot relative to the parent
+ * @param slot the slot to set-up
+ * @param position the position of the given slot
+ */
+void WeaponManager::setSlotPosition(int slot, const Vector& position, PNode* parent)
+{
+  if (slot < this->slotCount)
+  {
+    this->currentSlotConfig[slot].position.setRelCoor(position);
+
+    if (parent != NULL)
+      this->currentSlotConfig[slot].position.setParent(parent);
+  }
+}
+
+
+/**
+ * @brief sets the relative rotation of the slot to its parent
+ * @param slot the slot to set-up
+ * @param rotation the relative rotation of the given slot
+ */
+void WeaponManager::setSlotDirection(int slot, const Quaternion& rotation)
+{
+  if (slot < this->slotCount)
+    this->currentSlotConfig[slot].position.setRelDir(rotation);
+}
+
+
+/**
+ * @brief adds a weapon to the selected weaponconfiguration into the selected slot
+ * @param weapon the weapon to add
+ * @param configID an identifier for the slot: number between 0..7 if not specified: slotID=next free slot
+ * @param slotID an identifier for the weapon configuration, number between 0..3
+ *
+ * if you add explicitly a weapon at config:n, slot:m, the weapon placed at this location will be
+ * replaced by the weapon specified. if you use the WM_FREE_SLOT, the manager will look for a free
+ * slot in this weaponconfiguration. if there is non, the weapon won't be added and there will be
+ * a error message.
+ */
+bool WeaponManager::addWeapon(Weapon* weapon, int configID, int slotID)
+{
+  if ( weapon == NULL )
+    return false;
+
+  if (unlikely(configID >= WM_MAX_CONFIGS || slotID >= (int)this->slotCount))
+  {
+    PRINTF(2)("Slot %d of config %d is not availiabe (max: %d) searching for suitable slot\n", slotID, configID, this->slotCount);
+    if (configID >= WM_MAX_CONFIGS)
+      configID = -1;
+    if (slotID >= (int)this->slotCount)
+      slotID = -1;
+  }
+  // if no ConfigID is supplied set to Current Config.
+  if (configID <= -1)
+    configID = this->currentConfigID;
+  //
+  if (configID > -1 && slotID == -1)
+  {
+    slotID = this->getNextFreeSlot(configID, weapon->getCapability());
+    if (slotID == -1)
+      configID = -1;
+  }
+
+  if (configID > 0 && slotID > 0 && this->configs[configID][slotID] != NULL)
+  {
+    PRINTF(3)("Weapon-slot %d/%d of %s already poulated, remove weapon (%s::%s) first\n", configID, slotID, this->getCName(), weapon->getClassCName(), weapon->getCName());
+    return false;
+  }
+
+  if (slotID <= -1) // WM_FREE_SLOT
+  {
+    slotID = this->getNextFreeSlot(configID, weapon->getCapability());
+    if( slotID < 0 || slotID >= this->slotCount)
+    {
+      PRINTF(1)("There is no free slot in this WeaponConfig to dock this weapon at! Aborting\n");
+      return false;
+    }
+  }
+
+  if (!(this->currentSlotConfig[slotID].capability & weapon->getCapability() & WTYPE_ALLKINDS) &&
+      this->currentSlotConfig[slotID].capability & weapon->getCapability() & WTYPE_ALLDIRS)
+  {
+    PRINTF(2)("Unable to add Weapon with wrong capatibility to Slot %d (W:%d M:%d)\n",
+              slotID, weapon->getCapability(), this->currentSlotConfig[slotID].capability);
+    return false;
+  }
+
+  //! @todo check if the weapon is already assigned to another config in another slot
+  if (this->configs[configID][slotID] != NULL)
+    return false;
+
+  this->configs[configID][slotID] = weapon;
+  weapon->setAmmoContainer(this->getAmmoContainer(weapon->getProjectileType()));
+  if(configID == this->currentConfigID)
+    this->currentSlotConfig[slotID].nextWeapon = weapon;
+  //if (this->parent != NULL)
+  {
+    this->parentNode->addChild(weapon);
+    if (this->parentEntity->isA(Playable::staticClassID()))
+      dynamic_cast<Playable*>(this->parentEntity)->weaponConfigChanged();
+    weapon->setDefaultTarget(this->crosshair);
+  }
+  PRINTF(4)("Added a new Weapon (%s::%s) to the WeaponManager: config %i/ slot %i\n", weapon->getClassCName(), weapon->getCName(), configID, slotID);
+  return true;
+}
+
+/**
+ * @brief increases the Energy of the WeaponContainer of type (projectileType)
+ * @param projectileType the type of weapon to increase Energy from
+ * @param ammo the ammo to increase
+ */
+float WeaponManager::increaseAmmunition(const ClassID& projectileType, float ammo)
+{
+  return this->getAmmoContainer(projectileType)->increaseEnergy(ammo);
+}
+
+/**
+ * @brief does the same as the funtion inclreaseAmmunition, added four your convenience
+ * @param weapon, the Weapon to read the ammo-info about.
+ * @param ammo how much ammo to add.
+ */
+float WeaponManager::inclreaseAmmunition(const Weapon* weapon, float ammo)
+{
+  assert (weapon != NULL);
+  return this->increaseAmmunition(weapon->getClassID(), ammo);
+
+}
+
+
+/**
+ * sets the capabilities of a Slot
+ * @param slot the slot to set the capability
+ * @param slotCapability the capability @see WM_SlotCapability
+ */
+void WeaponManager::setSlotCapability(int slot, long slotCapability)
+{
+  if (slot > slotCount)
+    return;
+  this->currentSlotConfig[slot].capability = slotCapability;
+}
+
+
+/**
+ * removes a Weapon from the WeaponManager
+ *
+ * !! The weapon must be inactive before you can delete it,    !!
+ * !! because it will still be deactivated (if it is selected) !!
+ */
+void WeaponManager::removeWeapon(Weapon* weapon, int configID)
+{
+  if (weapon == NULL)
+    return;
+  if (configID < 0)
+  {
+    for (int j = 0; j < WM_MAX_SLOTS; j++)
+    {
+      for (int i = 0; i < WM_MAX_CONFIGS; i++)
+      {
+        if (this->configs[i][j] == weapon)
+          this->configs[i][j] = NULL;
+      }
+      if (this->currentSlotConfig[j].currentWeapon == weapon)
+      {
+        this->currentSlotConfig[j].nextWeapon = NULL;
+      }
+    }
+  }
+}
+
+
+/**
+ * changes to the next weapon configuration
+ */
+void WeaponManager::nextWeaponConfig()
+{
+  ++this->currentConfigID;
+  if (this->currentConfigID >= WM_MAX_CONFIGS)
+    this->currentConfigID = 0;
+  this->changeWeaponConfig(this->currentConfigID);
+}
+
+/**
+ * changes to the previous configuration
+ */
+void WeaponManager::previousWeaponConfig()
+{
+  --this->currentConfigID;
+  if (this->currentConfigID < 0)
+    this->currentConfigID = WM_MAX_CONFIGS -1;
+  this->changeWeaponConfig(this->currentConfigID);
+}
+
+/**
+ * change to a desired configuration
+ * @param weaponConfig the configuration to jump to.
+ */
+void WeaponManager::changeWeaponConfig(int weaponConfig)
+{
+  this->currentConfigID = weaponConfig;
+  PRINTF(4)("Changing weapon configuration: to %i\n", this->currentConfigID);
+  for (int i = 0; i < WM_MAX_SLOTS; i++)
+    this->currentSlotConfig[i].nextWeapon = this->configs[currentConfigID][i];
+}
+
+
+/**
+ * triggers fire of all weapons in the current weaponconfig
+ */
+void WeaponManager::fire()
+{
+  Weapon* firingWeapon;
+  for(int i = 0; i < this->slotCount; i++)
+  {
+    firingWeapon = this->currentSlotConfig[i].currentWeapon;
+    if( firingWeapon != NULL) firingWeapon->requestAction(WA_SHOOT);
+  }
+  this->crosshair->setRotationSpeed(500);
+  this->crossHairSizeAnim->replay();
+}
+
+
+/**
+ * triggers tick of all weapons in the current weaponconfig
+ * @param second passed since last tick
+ */
+void WeaponManager::tick(float dt)
+{
+  Weapon* tickWeapon;
+
+  for(int i = 0; i < this->slotCount; i++)
+  {
+/*
+    NICE LITTLE DEBUG FUNCTION
+       if (this->currentSlotConfig[i].currentWeapon != NULL || this->currentSlotConfig[i].nextWeapon != NULL)
+      printf("%p %p\n", this->currentSlotConfig[i].currentWeapon, this->currentSlotConfig[i].nextWeapon);*/
+
+    // current Weapon in Slot i
+    tickWeapon = this->currentSlotConfig[i].currentWeapon;
+    // On A change (current != next)
+    if (tickWeapon != this->currentSlotConfig[i].nextWeapon)
+    {
+      // if a Weapon is Active in slot i, deactivate it.
+      if (tickWeapon != NULL )
+      {
+        if (tickWeapon->isActive())
+        {
+          tickWeapon->requestAction(WA_DEACTIVATE);
+          continue;
+        }
+        else
+        {
+          tickWeapon->toList(OM_NULL);
+          this->currentSlotConfig[i].currentWeapon = NULL;
+        }
+      }
+
+      // switching to next Weapon
+      tickWeapon = this->currentSlotConfig[i].currentWeapon = this->currentSlotConfig[i].nextWeapon;
+      if (tickWeapon != NULL)
+      {
+           //        if (this->parent != NULL)
+          tickWeapon->toList(this->parentEntity->getOMListNumber());
+        tickWeapon->requestAction(WA_ACTIVATE);
+        this->currentSlotConfig[i].position.activateNode();
+        tickWeapon->setParent(&this->currentSlotConfig[i].position);
+      }
+      else
+        this->currentSlotConfig[i].position.deactivateNode();
+      if (this->parentEntity != NULL && this->parentEntity->isA(Playable::staticClassID()))
+        dynamic_cast<Playable*>(this->parentEntity)->weaponConfigChanged();
+    }
+    else if (unlikely(tickWeapon != NULL && tickWeapon->getCurrentState() == WS_DEACTIVATING))
+      this->currentSlotConfig[i].nextWeapon = NULL;
+  }
+}
+
+
+/**
+ * triggers draw of all weapons in the current weaponconfig
+ */
+void WeaponManager::draw() const
+{
+  assert(false || "must not be called");
+  Weapon* drawWeapon;
+  for (int i = 0; i < this->slotCount; i++)
+  {
+    drawWeapon = this->currentSlotConfig[i].currentWeapon;
+    if( drawWeapon != NULL && drawWeapon->isVisible())
+      drawWeapon->draw();
+  }
+}
+
+
+/**
+ * private gets the next free slot in a certain weaponconfig
+ * @param the selected weaponconfig -1 if none found
+ */
+int WeaponManager::getNextFreeSlot(int configID, long capability)
+{
+  if (configID == -1)
+  {
+    for (configID = 0; configID < WM_MAX_CONFIGS; configID++)
+      for( int i = 0; i < this->slotCount; ++i)
+      {
+        if( this->configs[configID][i] == NULL &&
+            (this->currentSlotConfig[i].capability & capability & WTYPE_ALLKINDS) &&
+            (this->currentSlotConfig[i].capability & capability & WTYPE_ALLDIRS))
+          return i;
+      }
+  }
+  else
+  {
+    for( int i = 0; i < this->slotCount; ++i)
+    {
+      if( this->configs[configID][i] == NULL &&
+          (this->currentSlotConfig[i].capability & capability & WTYPE_ALLKINDS) &&
+          (this->currentSlotConfig[i].capability & capability & WTYPE_ALLDIRS))
+        return i;
+    }
+  }
+  return -1;
+}
+
+CountPointer<AmmoContainer>& WeaponManager::getAmmoContainer(const ClassID& projectileType)
+{
+  for (unsigned int i = 0; i < this->ammo.size(); i++)
+  {
+    if (this->ammo[i]->getProjectileType() == projectileType)
+      return this->ammo[i];
+  }
+  this->ammo.push_back(CountPointer<AmmoContainer>(new AmmoContainer(projectileType)));
+  return this->ammo.back();
+}
+
+CountPointer<AmmoContainer>& WeaponManager::getAmmoContainer(const Weapon* weapon)
+{
+  assert (weapon != NULL);
+  return (this->getAmmoContainer(weapon->getClassID()));
+}
+
+
+/**
+ * outputs some nice debug information about the WeaponManager
+ */
+void WeaponManager::debug() const
+{
+  PRINT(3)("WeaponManager Debug Information\n");
+  PRINT(3)("-------------------------------\n");
+  PRINT(3)("current Config is %d\n", this->currentConfigID);
+  for (int i = 0; i < WM_MAX_CONFIGS; i++)
+  {
+    PRINT(3)("Listing Weapons in Configuration %d\n", i);
+    for (int j = 0; j < WM_MAX_SLOTS; j++)
+    {
+      if (this->configs[i][j] != NULL)
+        PRINT(3)("Slot %d loaded a %s\n", j, this->configs[i][j]->getClassCName());
+    }
+  }
+}
Index: branches/heathaze/src/world_entities/weapons/weapon_manager.h
===================================================================
--- branches/heathaze/src/world_entities/weapons/weapon_manager.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weapons/weapon_manager.h	(revision 9940)
@@ -0,0 +1,132 @@
+/*!
+ * @file weapon_manager.h
+ * every big WorldEntity has the ability to carry many different Weapons.
+ * for this to be easy there is the WeaponManager, that handels these weapons,
+ * and changes between them.
+ *
+ *
+ *
+ * @TODO 1. WeaponManager should also handle a List of availiableWeapons.
+ */
+
+#ifndef _WEAPON_MANAGER_H
+#define _WEAPON_MANAGER_H
+
+#include "base_object.h"
+
+#include "crosshair.h"
+#include "weapon.h"
+
+#include "count_pointer.h"
+#include "ammo_container.h"
+
+// FORWARD DECLARATION
+template <class T> class tAnimation;
+
+#define    WM_MAX_SLOTS            10             //!< How many slots the WeaponManager has at its max
+#define    WM_MAX_CONFIGS          4              //!< The maximum number of predefined Configurations
+#define    WM_MAX_LOADED_WEAPONS   20             //!< The
+
+//! This is a special class, that can handle many different Weapons of a ship/man/whatever.
+/**
+ * this class is designed to interactively changeing multiple weapons (or just one),
+ * and to allow the Weapon itself to enable/disable itself.
+ *
+ * How to configure
+ * 1. set the default values.
+ * 2. define weapons. connect them to the WeaponManager's configurations (have a look at "player.cc", to see how it works)
+ * 3. go on and run :)....
+ */
+class WeaponManager : public BaseObject {
+  ObjectListDeclaration(WeaponManager);
+
+  //! an enumerator defining a Slot, where a Weapon can be stored inside.
+  typedef struct
+  {
+    PNode         position;               //!< the relative Position to the position of the carrying entity. (const PNode* parent; of WeaponManager)
+    long          capability;             //!< the capabilities of the Slot @see WM_SlotCapability.
+
+    Weapon*       currentWeapon;          //!< The current weapon this slot is carrying.
+    Weapon*       nextWeapon;             //!< either NULL or the next weapon that will be set (require currentWeapon to deactivate)
+  } WM_Slot;
+
+  public:
+    WeaponManager(WorldEntity* parent);
+    WeaponManager(const TiXmlElement* root);
+    virtual ~WeaponManager();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+    void loadWeapons(const TiXmlElement* root);
+
+    void setSlotCount(unsigned int slotCount);
+    unsigned int getSlotCount() const { return this->slotCount; };
+    // setting up the WeaponManager with the following functions
+    void setSlotPosition(int slot, const Vector& position, PNode* parent = NULL);
+    void setSlotDirection(int slot, const Quaternion& rotation);
+    /** @param slot the slot to get the relative position from @returns the relative position of the Carrier to the Slot */
+    const Vector& getSlotPosition(int slot) const { return this->currentSlotConfig[slot].position.getRelCoor(); };
+    void setSlotCapability(int slot, long slotCapability);
+    /** @param slot the slot to get the capabilities from @returns the capabilies */
+    long getSlotCapability(int slot) const { return this->currentSlotConfig[slot].capability; };
+
+    void setParentEntity(WorldEntity* parent);
+    WorldEntity* getParentEntity() const { return this->parentEntity; };
+
+    void setParentNode(PNode* node);
+    /** @returns the Parent (carrier) of this WeaponManager */
+    PNode* getParentNode() const { return this->parentNode; };
+
+    bool addWeapon(Weapon* weapon, int configID = -1, int slotID = -1);
+    void removeWeapon(Weapon* weapon, int configID = -1);
+
+    Weapon* getWeapon(int slotID) const { return (slotID >= 0 && slotID < this->slotCount)? this->currentSlotConfig[slotID].nextWeapon: NULL; };
+
+    // FIXME ::
+//    bool hasFreeSlot(int configID, long capability = WTYPE_ALL) { return ( getNextFreeSlot(configID, capability ) != -1)? true : false; };
+
+    void nextWeaponConfig();
+    void previousWeaponConfig();
+    void changeWeaponConfig(int weaponConfig);
+
+    float increaseAmmunition(const ClassID& projectileType, float ammo);
+    float inclreaseAmmunition(const Weapon* weapon, float ammo);
+
+    /** @returns a fixed target namely the Crosshair's 3D position */
+    inline PNode* getFixedTarget() const { return this->crosshair; };
+
+    void fire();
+    //! @TODO: implement this function (maybe also in Weapon itself)
+    void releaseFire();
+
+    void tick(float dt);
+    void draw() const;
+
+    void debug() const;
+
+ // private:
+    int getNextFreeSlot(int configID, long capability = WTYPE_ALL);
+    CountPointer<AmmoContainer>& getAmmoContainer(const ClassID& projectileType);
+    CountPointer<AmmoContainer>& getAmmoContainer(const Weapon* weapon);
+
+  private:
+    WorldEntity*            parentEntity;                             //!< The parent, this WeaponManager is connected to.
+    PNode*                  parentNode;                               //!< The parented Node the WeaponManager is connected to. (by default == parentEntity).
+
+    int                     slotCount;                                //!< number of weapon slots the ship has.
+    int                     currentConfigID;                          //!< the currently selected config.
+    Weapon*                 configs[WM_MAX_CONFIGS][WM_MAX_SLOTS];    //!< An array of predefined configurations and assigned weapon.
+    WM_Slot                 currentSlotConfig[WM_MAX_SLOTS];          //!< The currentConfigureation.
+
+    Weapon*                 availiableWeapons[WM_MAX_LOADED_WEAPONS]; //!< The availiable Weapons of this WeaponManager
+
+    bool                    weaponChange;
+
+    Crosshair*              crosshair;                                //!< an aim.
+    tAnimation<Crosshair>*  crossHairSizeAnim;                        //!< An animation for the crosshair (scaling)
+
+    std::vector<CountPointer<AmmoContainer> > ammo;                   //!< Containers
+};
+
+
+#endif /* _WEAPON_MANAGER_H */
Index: branches/heathaze/src/world_entities/weather_effects/atmospheric_engine.cc
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/atmospheric_engine.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/atmospheric_engine.cc	(revision 9940)
@@ -0,0 +1,112 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Andreas Maechler, David Hasenfratz
+   co-programmer: ...
+*/
+
+#include "atmospheric_engine.h"
+
+#include "weather_effects/fog_effect.h"
+
+#include "util/loading/load_param_xml.h"
+#include "util/loading/factory.h"
+
+ObjectListDefinition(AtmosphericEngine);
+
+/**
+ * @param root The XML-element to load the AtmosphericEngine from
+ */
+AtmosphericEngine::AtmosphericEngine()
+{
+  this->registerObject(this, AtmosphericEngine::_objectList);
+}
+
+/**
+ *  The Pointer to this AtmosphericEngine
+*/
+AtmosphericEngine* AtmosphericEngine::singletonRef = NULL;
+
+
+/**
+ *  destroys a AtmosphericEngine
+ */
+AtmosphericEngine::~AtmosphericEngine()
+{
+  AtmosphericEngine::singletonRef = NULL;
+
+  while(!WeatherEffect::objectList().empty())
+    delete WeatherEffect::objectList().front();
+}
+
+/**
+ * @param root The XML-element to load the AtmosphericEngine from
+ */
+void AtmosphericEngine::loadParams(const TiXmlElement* root)
+{
+  LoadParamXML(root, "WeatherEffect", this, AtmosphericEngine, loadWeatherEffect);
+  LoadParamXML(root, "SunEffect", this, AtmosphericEngine, loadSunEffect);
+}
+
+/**
+ * @param root The XML-element to load WeatherEffects from
+ */
+void AtmosphericEngine::loadWeatherEffect(const TiXmlElement* root)
+{
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    PRINTF(4)("element is: %s\n", element->Value());
+    // Factory::fabricate(element);
+
+    BaseObject* bo = Factory::fabricate(element);
+    if( bo == NULL)
+      PRINTF(0)(" Could not create Element %s\n", element->Value());
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ * @param root The XML-element to load SunEffects from
+ */
+void AtmosphericEngine::loadSunEffect(const TiXmlElement* root)
+{
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    PRINTF(4)("element is: %s\n", element->Value());
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+
+/**
+ * draws the effect, if needed
+ */
+void AtmosphericEngine::draw() const
+{
+  for (ObjectList<WeatherEffect>::const_iterator it = WeatherEffect::objectList().begin();
+       it != WeatherEffect::objectList().end();
+       ++it)
+    (*it)->draw();
+}
+
+
+
+/**
+ * ticks the effect if there is any time dependancy
+ */
+void AtmosphericEngine::tick(float dt)
+{
+
+  for (ObjectList<WeatherEffect>::const_iterator it = WeatherEffect::objectList().begin();
+       it != WeatherEffect::objectList().end();
+       ++it)
+    (*it)->tick(dt);
+}
Index: branches/heathaze/src/world_entities/weather_effects/atmospheric_engine.h
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/atmospheric_engine.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/atmospheric_engine.h	(revision 9940)
@@ -0,0 +1,43 @@
+/*!
+ * @file atmospheric_engine.h
+ *
+ */
+
+#ifndef _ATMOSPHERIC_ENGINE_H
+#define _ATMOSPHERIC_ENGINE_H
+
+#include "base_object.h"
+
+
+class TiXmlElement;
+
+class AtmosphericEngine : public BaseObject
+{
+  ObjectListDeclaration(AtmosphericEngine);
+  public:
+    ~AtmosphericEngine();
+
+    /** @returns a Pointer to the only object of this Class */
+    inline static AtmosphericEngine* getInstance() { if (!AtmosphericEngine::singletonRef) AtmosphericEngine::singletonRef = new AtmosphericEngine();  return AtmosphericEngine::singletonRef; };
+
+    void loadParams(const TiXmlElement* root);
+
+    void init();
+
+    void draw() const;
+    void tick(float dt);
+
+    // inline bool isActivated() const { return this->bActivated; }
+
+    void loadWeatherEffect(const TiXmlElement* root);
+    void loadSunEffect(const TiXmlElement* root);
+
+  private:
+
+    AtmosphericEngine();
+
+    static AtmosphericEngine*     singletonRef;       //!< Pointer to the only instance of this Class
+};
+
+
+#endif /* _ATMOSPHERIC_ENGINE */
Index: branches/heathaze/src/world_entities/weather_effects/cloud_effect.cc
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/cloud_effect.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/cloud_effect.cc	(revision 9940)
@@ -0,0 +1,451 @@
+/*
+  orxonox - the future of 3D-vertical-scrollers
+
+  Copyright (C) 2004 orx
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+### File Specific:
+  main-programmer: hdavid, amaechler
+
+  INSPIRED BY http://www.codesampler.com/usersrc/usersrc_6.htm#oglu_sky_dome_shader
+*/
+
+#include "cloud_effect.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "material.h"
+#include "state.h"
+#include "p_node.h"
+#include "shader.h"
+#include "shell_command.h"
+#include "t_animation.h"
+#include "script_class.h"
+
+#include "resource_shader.h"
+
+#include "class_id_DEPRECATED.h"
+
+Vector    CloudEffect::cloudColor;
+Vector    CloudEffect::skyColor;
+Vector    CloudEffect::newCloudColor;
+Vector    CloudEffect::newSkyColor;
+
+bool      CloudEffect::fadeSky;
+bool      CloudEffect::fadeCloud;
+float     CloudEffect::fadeTime;
+
+ObjectListDefinitionID(CloudEffect, CL_CLOUD_EFFECT);
+
+
+SHELL_COMMAND(activate, CloudEffect, activateCloud);
+SHELL_COMMAND(deactivate, CloudEffect, deactivateCloud);
+SHELL_COMMAND(skyColor, CloudEffect, shellSkyColor);
+SHELL_COMMAND(cloudColor, CloudEffect, shellCloudColor);
+
+
+CREATE_SCRIPTABLE_CLASS(CloudEffect,
+                        addMethod("skyColor", Executor4<CloudEffect, lua_State*,float,float,float,float>(&CloudEffect::shellSkyColor))
+                        ->addMethod("cloudColor", Executor4<CloudEffect, lua_State*,float,float,float,float>(&CloudEffect::shellCloudColor))
+                        ->addMethod("activate", Executor0<CloudEffect, lua_State*>(&CloudEffect::activate))
+                        ->addMethod("deactivate", Executor0<CloudEffect, lua_State*>(&CloudEffect::deactivate))
+                       );
+
+
+CREATE_FACTORY(CloudEffect);
+
+CloudEffect::CloudEffect(const TiXmlElement* root) {
+  this->registerObject(this, CloudEffect::_objectList);
+
+    this->init();
+
+    if (root != NULL)
+        this->loadParams(root);
+
+    if(cloudActivate)
+        this->activate();
+}
+
+CloudEffect::~CloudEffect() {
+    this->deactivate();
+
+    if (glIsTexture(noise3DTexName))
+        glDeleteTextures(1, &noise3DTexName);
+}
+
+
+void CloudEffect::init() {
+    PRINTF(4)("Initializing CloudEffect\n");
+
+    // default values
+    this->offsetZ = 0;
+    this->animationSpeed = 2;
+    this->scale = 0.0004f;
+    this->atmosphericRadius = 4000;
+    this->planetRadius = 1500;
+    this->divs = 15;
+    this->cloudActivate = false;
+    fadeSky = false;
+    fadeCloud = false;
+
+
+    skyColor = Vector(0.0f, 0.0f, 0.8f);
+    cloudColor = Vector(0.8f, 0.8f, 0.8f);
+    newSkyColor = skyColor;
+    newCloudColor = cloudColor;
+
+    this->noise3DTexSize = 128;
+    this->noise3DTexName = 0;
+
+    this->make3DNoiseTexture();
+
+    glGenTextures(1, &noise3DTexName);
+    glBindTexture(GL_TEXTURE_3D, noise3DTexName);
+
+    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
+    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA,
+                 noise3DTexSize, noise3DTexSize, noise3DTexSize,
+                 0, GL_RGBA, GL_UNSIGNED_BYTE, noise3DTexPtr);
+
+    this->skydome = new Skydome();
+    this->skydome->setTexture(noise3DTexName);
+
+    this->shader = ResourceShader("/shaders/cloud.vert", "/shaders/cloud.frag");
+
+    this->shader.activateShader();
+
+    Shader::Uniform(shader, "Noise").set(0);
+
+    this->offset = new Shader::Uniform(shader, "Offset");
+    this->skycolor = new Shader::Uniform(shader, "SkyColor");
+    this->cloudcolor = new Shader::Uniform(shader, "CloudColor");
+
+    this->shader.deactivateShader();
+
+    this->skydome->setShader(&shader);
+}
+
+
+void CloudEffect::loadParams(const TiXmlElement* root) {
+    WeatherEffect::loadParams(root);
+
+    LoadParam(root, "speed", this, CloudEffect, setAnimationSpeed);
+    LoadParam(root, "scale", this, CloudEffect, setCloudScale);
+    LoadParam(root, "cloudcolor", this, CloudEffect, setCloudColor);
+    LoadParam(root, "skycolor", this, CloudEffect, setSkyColor);
+
+    LoadParam(root, "planetRadius", this, CloudEffect, setPlanetRadius);
+    LoadParam(root, "atmosphericRadius", this, CloudEffect, setAtmosphericRadius);
+    LoadParam(root, "divisions", this, CloudEffect, setDivisions);
+
+    LOAD_PARAM_START_CYCLE(root, element);
+    {
+        LoadParam_CYCLE(element, "option", this, CloudEffect, setCloudOption);
+    }
+    LOAD_PARAM_END_CYCLE(element);
+}
+
+
+void CloudEffect::activate() {
+    PRINTF(0)( "Activating\n");
+
+    // Can only be set after the loadParams call
+    this->shader.activateShader();
+    Shader::Uniform(shader, "Scale").set(this->scale);
+    this->skycolor->set
+    (skyColor.x, skyColor.y, skyColor.z);
+    this->cloudcolor->set
+    (cloudColor.x, cloudColor.y, cloudColor.z);
+    this->shader.deactivateShader();
+
+    this->skydome->generateSkyPlane(this->divs, this->planetRadius, this->atmosphericRadius, 1, 1);
+    this->skydome->activate();
+
+    this->cloudActivate = true;
+}
+
+void CloudEffect::deactivate() {
+    PRINTF(4)("Deactivating CloudEffect\n");
+
+    this->skydome->deactivate();
+    this->cloudActivate = false;
+}
+
+void CloudEffect::draw() const {}
+
+void CloudEffect::tick (float dt) {
+
+    if (this->cloudActivate) {
+
+        this->offsetZ += 0.05 * dt * this->animationSpeed;
+
+        this->shader.activateShader();
+        this->offset->set
+        (0.0f, 0.0f, offsetZ);
+
+        if(cloudColor != newCloudColor) {
+
+            if(fadeCloud) {
+
+                this->cloudColorFadeX = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudX);
+                this->cloudColorFadeX->setInfinity(ANIM_INF_CONSTANT);
+                this->cloudColorFadeY = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudY);
+                this->cloudColorFadeY->setInfinity(ANIM_INF_CONSTANT);
+                this->cloudColorFadeZ = new tAnimation<CloudEffect>(this, &CloudEffect::setColorCloudZ);
+                this->cloudColorFadeZ->setInfinity(ANIM_INF_CONSTANT);
+
+                this->cloudColorFadeX->addKeyFrame(cloudColor.x, fadeTime, ANIM_LINEAR);
+                this->cloudColorFadeX->addKeyFrame(newCloudColor.x, 0, ANIM_LINEAR);
+
+                this->cloudColorFadeY->addKeyFrame(cloudColor.y, fadeTime, ANIM_LINEAR);
+                this->cloudColorFadeY->addKeyFrame(newCloudColor.y, 0, ANIM_LINEAR);
+
+                this->cloudColorFadeZ->addKeyFrame(cloudColor.z, fadeTime, ANIM_LINEAR);
+                this->cloudColorFadeZ->addKeyFrame(newCloudColor.z, 0, ANIM_LINEAR);
+
+                fadeCloud = false;
+
+                this->cloudColorFadeX->replay();
+                this->cloudColorFadeY->replay();
+                this->cloudColorFadeZ->replay();
+            }
+
+            this->cloudcolor->set
+            (this->cloudColor.x, this->cloudColor.y, this->cloudColor.z);
+        }
+
+        if(skyColor != newSkyColor) {
+
+            if(fadeSky) {
+
+                this->skyColorFadeX = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyX);
+                this->skyColorFadeX->setInfinity(ANIM_INF_CONSTANT);
+                this->skyColorFadeY = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyY);
+                this->skyColorFadeY->setInfinity(ANIM_INF_CONSTANT);
+                this->skyColorFadeZ = new tAnimation<CloudEffect>(this, &CloudEffect::setColorSkyZ);
+                this->skyColorFadeZ->setInfinity(ANIM_INF_CONSTANT);
+
+                this->skyColorFadeX->addKeyFrame(skyColor.x, fadeTime, ANIM_LINEAR);
+                this->skyColorFadeX->addKeyFrame(newSkyColor.x, 0, ANIM_LINEAR);
+
+                this->skyColorFadeY->addKeyFrame(skyColor.y, fadeTime, ANIM_LINEAR);
+                this->skyColorFadeY->addKeyFrame(newSkyColor.y, 0, ANIM_LINEAR);
+
+                this->skyColorFadeZ->addKeyFrame(skyColor.z, fadeTime, ANIM_LINEAR);
+                this->skyColorFadeZ->addKeyFrame(newSkyColor.z, 0, ANIM_LINEAR);
+
+                fadeSky = false;
+
+                this->skyColorFadeX->replay();
+                this->skyColorFadeY->replay();
+                this->skyColorFadeZ->replay();
+            }
+
+            this->skycolor->set
+            (this->skyColor.x, this->skyColor.y, this->skyColor.z);
+        }
+
+        this->shader.deactivateShader();
+    }
+}
+
+
+void CloudEffect::setColorSkyX(float color) {
+    skyColor.x = color;
+}
+void CloudEffect::setColorSkyY(float color) {
+    skyColor.y = color;
+}
+void CloudEffect::setColorSkyZ(float color) {
+    skyColor.z = color;
+}
+void CloudEffect::setColorCloudX(float color) {
+    cloudColor.x = color;
+}
+void CloudEffect::setColorCloudY(float color) {
+    cloudColor.y = color;
+}
+void CloudEffect::setColorCloudZ(float color) {
+    cloudColor.z = color;
+}
+
+void CloudEffect::changeSkyColor(Vector color, float time) {
+    newSkyColor = color;
+    fadeSky = true;
+    fadeTime = time;
+}
+
+
+void CloudEffect::changeCloudColor(Vector color, float time) {
+    newCloudColor = color;
+    fadeCloud = true;
+    fadeTime = time;
+}
+
+void CloudEffect::shellSkyColor(float colorX, float colorY, float colorZ, float time) {
+    changeSkyColor( Vector(colorX, colorY, colorZ), time);
+}
+
+void CloudEffect::shellCloudColor(float colorX, float colorY, float colorZ, float time) {
+    changeCloudColor( Vector(colorX, colorY, colorZ), time);
+}
+
+
+
+void CloudEffect::make3DNoiseTexture() {
+    int f, i, j, k, inc;
+    int startFrequency = 4;
+    int numOctaves = 4;
+    double ni[3];
+    double inci, incj, inck;
+    int frequency = startFrequency;
+    GLubyte *ptr;
+    double amp = 0.5;
+
+    if ((noise3DTexPtr = (GLubyte *) malloc(noise3DTexSize *
+                                            noise3DTexSize *
+                                            noise3DTexSize * 4)) == NULL)
+        PRINTF(0)("ERROR: Could not allocate 3D noise texture\n");
+
+    for (f=0, inc=0; f < numOctaves;
+            ++f, frequency *= 2, ++inc, amp *= 0.5) {
+        SetNoiseFrequency(frequency);
+        ptr = noise3DTexPtr;
+        ni[0] = ni[1] = ni[2] = 0;
+
+        inci = 1.0 / (noise3DTexSize / frequency);
+        for (i=0; i<noise3DTexSize; ++i, ni[0] += inci) {
+            incj = 1.0 / (noise3DTexSize / frequency);
+            for (j=0; j<noise3DTexSize; ++j, ni[1] += incj) {
+                inck = 1.0 / (noise3DTexSize / frequency);
+                for (k=0; k<noise3DTexSize; ++k, ni[2] += inck, ptr+= 4) {
+                    *(ptr+inc) = (GLubyte) (((noise3(ni)+1.0) * amp)*128.0);
+                }
+            }
+        }
+    }
+}
+
+void CloudEffect::initNoise() {
+    int i, j, k;
+
+    srand(30757);
+    for (i = 0 ; i < B ; i++) {
+        p[i] = i;
+        g1[i] = (double)((rand() % (B + B)) - B) / B;
+
+        for (j = 0 ; j < 2 ; j++)
+            g2[i][j] = (double)((rand() % (B + B)) - B) / B;
+        normalize2(g2[i]);
+
+        for (j = 0 ; j < 3 ; j++)
+            g3[i][j] = (double)((rand() % (B + B)) - B) / B;
+        normalize3(g3[i]);
+    }
+
+    while (--i) {
+        k = p[i];
+        p[i] = p[j = rand() % B];
+        p[j] = k;
+    }
+
+    for (i = 0 ; i < B + 2 ; i++) {
+        p[B + i] = p[i];
+        g1[B + i] = g1[i];
+        for (j = 0 ; j < 2 ; j++)
+            g2[B + i][j] = g2[i][j];
+        for (j = 0 ; j < 3 ; j++)
+            g3[B + i][j] = g3[i][j];
+    }
+}
+
+void CloudEffect::SetNoiseFrequency( int frequency) {
+    start = 1;
+    B = frequency;
+    BM = B-1;
+}
+
+double CloudEffect::noise3( double vec[3]) {
+    int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
+    double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
+    int i, j;
+
+    if (start) {
+        start = 0;
+        initNoise();
+    }
+
+    setup(0, bx0,bx1, rx0,rx1);
+    setup(1, by0,by1, ry0,ry1);
+    setup(2, bz0,bz1, rz0,rz1);
+
+    i = p[ bx0 ];
+    j = p[ bx1 ];
+
+    b00 = p[ i + by0 ];
+    b10 = p[ j + by0 ];
+    b01 = p[ i + by1 ];
+    b11 = p[ j + by1 ];
+
+    t  = s_curve(rx0);
+    sy = s_curve(ry0);
+    sz = s_curve(rz0);
+
+    q = g3[ b00 + bz0 ] ;
+    u = at3(rx0,ry0,rz0);
+    q = g3[ b10 + bz0 ] ;
+    v = at3(rx1,ry0,rz0);
+    a = lerp(t, u, v);
+
+    q = g3[ b01 + bz0 ] ;
+    u = at3(rx0,ry1,rz0);
+    q = g3[ b11 + bz0 ] ;
+    v = at3(rx1,ry1,rz0);
+    b = lerp(t, u, v);
+
+    c = lerp(sy, a, b);
+
+    q = g3[ b00 + bz1 ] ;
+    u = at3(rx0,ry0,rz1);
+    q = g3[ b10 + bz1 ] ;
+    v = at3(rx1,ry0,rz1);
+    a = lerp(t, u, v);
+
+    q = g3[ b01 + bz1 ] ;
+    u = at3(rx0,ry1,rz1);
+    q = g3[ b11 + bz1 ] ;
+    v = at3(rx1,ry1,rz1);
+    b = lerp(t, u, v);
+
+    d = lerp(sy, a, b);
+
+    return lerp(sz, c, d);
+}
+
+void CloudEffect::normalize2( double v[2]) {
+    double s;
+
+    s = sqrt(v[0] * v[0] + v[1] * v[1]);
+    v[0] = v[0] / s;
+    v[1] = v[1] / s;
+}
+
+void CloudEffect::normalize3( double v[3]) {
+    double s;
+
+    s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+    v[0] = v[0] / s;
+    v[1] = v[1] / s;
+    v[2] = v[2] / s;
+}
+
Index: branches/heathaze/src/world_entities/weather_effects/cloud_effect.h
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/cloud_effect.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/cloud_effect.h	(revision 9940)
@@ -0,0 +1,172 @@
+/**
+ * @file cloud_effect.h
+ * Create clouds
+*/
+
+#ifndef _CLOUD_EFFECT
+#define _CLOUD_EFFECT
+
+#include "weather_effect.h"
+
+#include "sound_buffer.h"
+#include "sound_source.h"
+
+#include "skydome.h"
+#include "material.h"
+#include "shader.h"
+
+#define MAXB 0x100
+#define N 0x1000
+#define NP 12   /* 2^N */
+#define NM 0xfff
+
+#define s_curve(t) ( t * t * (3. - 2. * t) )
+#define lerp(t, a, b) ( a + t * (b - a) )
+#define setup(i,b0,b1,r0,r1)\
+        t = vec[i] + N;\
+        b0 = ((int)t) & BM;\
+        b1 = (b0+1) & BM;\
+        r0 = t - (int)t;\
+        r1 = r0 - 1.;
+#define at2(rx,ry) ( rx * q[0] + ry * q[1] )
+#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
+
+// FORWARD DECLARATION
+template <class T>
+class tAnimation;
+
+class CloudEffect : public WeatherEffect {
+  ObjectListDeclaration(CloudEffect);
+
+public:
+
+    CloudEffect(const TiXmlElement* root = NULL);
+    virtual ~CloudEffect();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void init();
+
+    virtual void activate();
+    virtual void deactivate();
+
+    void activateCloud() {
+        this->activate();
+    }
+    void deactivateCloud() {
+        this->deactivate();
+    }
+
+    void setCloudOption(const std::string& option) {
+        if (option == "activate")
+            this->cloudActivate = true;
+    }
+
+    void setAnimationSpeed(float speed) {
+        this->animationSpeed = speed;
+    }
+
+    void setCloudScale(float scale) {
+        this->scale = scale;
+    }
+
+    void setCloudColor(float colorX, float colorY, float colorZ) {
+        this->cloudColor = Vector(colorX, colorY, colorZ);
+    }
+
+    void setSkyColor(float colorX, float colorY, float colorZ) {
+        this->skyColor = Vector(colorX, colorY, colorZ);
+    }
+
+    void setPlanetRadius(float planetRadius) {
+        this->planetRadius = planetRadius;
+    }
+
+    void setAtmosphericRadius(float atmosphericRadius) {
+        this->atmosphericRadius = atmosphericRadius;
+    }
+
+    void setDivisions(int divs) {
+        this->divs = divs;
+    }
+
+    virtual void draw() const;
+    virtual void tick(float dt);
+
+    static void changeSkyColor(Vector color, float time);
+    static void changeCloudColor(Vector color, float time);
+
+    void setColorSkyX(float color);
+    void setColorSkyY(float color);
+    void setColorSkyZ(float color);
+    void setColorCloudX(float color);
+    void setColorCloudY(float color);
+    void setColorCloudZ(float color);
+
+    static Vector cloudColor;
+    static Vector skyColor;
+
+    void make3DNoiseTexture();
+    void initNoise();
+    void SetNoiseFrequency(int frequency);
+    double noise3(double vec[3]);
+    void normalize2(double v[2]);
+    void normalize3(double v[3]);
+
+    void generateSkyPlane(int divisions, float planetRadius, float atmosphereRadius,
+                          float hTile, float vTile);
+
+    void shellSkyColor(float colorX, float colorY, float colorZ, float time);
+    void shellCloudColor(float colorX, float colorY, float colorZ, float time);
+
+
+private:
+
+    bool                    cloudActivate;
+    float                   animationSpeed;
+
+    static Vector           newSkyColor;
+    static Vector           newCloudColor;
+
+    // Material             cloudMaterial;
+    Skydome*                 skydome;
+
+    tAnimation<CloudEffect>*  skyColorFadeX;
+    tAnimation<CloudEffect>*  skyColorFadeY;
+    tAnimation<CloudEffect>*  skyColorFadeZ;
+    tAnimation<CloudEffect>*  cloudColorFadeX;
+    tAnimation<CloudEffect>*  cloudColorFadeY;
+    tAnimation<CloudEffect>*  cloudColorFadeZ;
+    static bool fadeSky;
+    static bool fadeCloud;
+    static float fadeTime;
+
+    // SHADER STUFF
+    Shader           shader;
+    Shader::Uniform* offset;
+    Shader::Uniform* skycolor;
+    Shader::Uniform* cloudcolor;
+    float            offsetZ;
+    float            scale;
+    float            planetRadius;
+    float            atmosphericRadius;
+    int              divs;
+
+    // NOISE STUFF
+    int              noise3DTexSize;
+    GLuint           noise3DTexName;
+    GLubyte          *noise3DTexPtr;
+
+    int              p[MAXB + MAXB + 2];
+    double           g3[MAXB + MAXB + 2][3];
+    double           g2[MAXB + MAXB + 2][2];
+    double           g1[MAXB + MAXB + 2];
+
+    int              start;
+    int              B;
+    int              BM;
+
+
+};
+
+#endif  /* _CLOUD_EFFECT */
Index: branches/heathaze/src/world_entities/weather_effects/fog_effect.cc
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/fog_effect.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/fog_effect.cc	(revision 9940)
@@ -0,0 +1,263 @@
+/*
+  orxonox - the future of 3D-vertical-scrollers
+
+  Copyright (C) 2004 orx
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+### File Specific:
+  main-programmer: hdavid, amaechler
+*/
+
+#include "fog_effect.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "shell_command.h"
+#include "script_class.h"
+#include "cloud_effect.h"
+#include "debug.h"
+
+ObjectListDefinition(FogEffect);
+// Define shell commands
+//SHELL_COMMAND(activate, FogEffect, activateFog);
+//SHELL_COMMAND(deactivate, FogEffect, deactivateFog);
+SHELL_COMMAND(fadein, FogEffect, fadeInFog);
+SHELL_COMMAND(fadeout, FogEffect, fadeOutFog);
+
+#include "class_id_DEPRECATED.h"
+
+CREATE_SCRIPTABLE_CLASS(FogEffect,
+                        addMethod("fadeIn", Executor0<FogEffect, lua_State*>(&FogEffect::fadeInFog))
+                            ->addMethod("fadeOut", Executor0<FogEffect, lua_State*>(&FogEffect::fadeOutFog))
+                            ->addMethod("activate", Executor0<FogEffect, lua_State*>(&FogEffect::activate))
+                            ->addMethod("deactivate", Executor0<FogEffect, lua_State*>(&FogEffect::deactivate))
+                       );
+
+CREATE_FACTORY(FogEffect);
+
+/**
+ * @brief standard constructor
+ */
+FogEffect::FogEffect(const TiXmlElement* root) {
+  this->registerObject(this, FogEffect::_objectList);
+    // Initialize values
+    this->init();
+
+    // Load XML params
+    if (root != NULL)
+        this->loadParams(root);
+
+    // Activate fog, if chosen to be activated by default
+    if (this->fogActivate)
+        this->activate();
+}
+
+/**
+ * @brief standard destructor
+ */
+FogEffect::~FogEffect() {
+    this->deactivate();
+}
+
+/**
+ * @brief initalizes the fog effect with default values
+ */
+void FogEffect::init() {
+    // default values
+  this->fogMode = GL_LINEAR;
+  this->fogDensity = 0.005;
+  this->fogStart = 0;
+  this->fogEnd = 300;
+  this->colorVector = Vector(0.6, 0.0, 0.0);
+
+    // init variables
+  this->fogFadeInDuration = 0;
+  this->fogFadeOutDuration = 0;
+  this->fogFadeDensity = 0;
+  this->fogFadeEnd = 0;
+
+  this->localTimer = 0;
+  this->fogActivate = false;
+  this->fogFadeInActivate = false;
+  this->fogFadeOutActivate = false;
+
+  this->cloudColor = Vector(0.2f, 0.3f, 0.3f);
+  this->skyColor = Vector(0.2f, 0.3f, 0.3f);
+}
+
+/**
+ * @brief loads the fog effect parameters.
+ * @param root: the XML-Element to load the data from
+ */
+void FogEffect::loadParams(const TiXmlElement* root) {
+    WeatherEffect::loadParams(root);
+
+    LoadParam(root, "mode", this, FogEffect, setFogMode).describe("fog mode (linear, exponential)");
+    LoadParam(root, "density", this, FogEffect, setFogDensity).describe("fog density if exp. fog");
+    LoadParam(root, "range", this, FogEffect, setFogRange).describe("fog range: start, end");
+    LoadParam(root, "color", this, FogEffect, setFogColor).describe("fog color: r,g,b");
+    LoadParam(root, "fadeinduration", this, FogEffect, setFogFadeIn).describe("duration of the fade in");
+    LoadParam(root, "fadeoutduration", this, FogEffect, setFogFadeOut).describe("duration of the fade out");
+    LoadParam(root, "cloudcolor", this, FogEffect, setCloudColor);
+    LoadParam(root, "skycolor", this, FogEffect, setSkyColor);
+
+    LOAD_PARAM_START_CYCLE(root, element);
+    {
+      LoadParam_CYCLE(element, "option", this, FogEffect, setFogOption).describe("sets a fog option: activate");
+    }
+    LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ * @brief activates the fog effect
+ */
+void FogEffect::activate() {
+    PRINTF(3)( "Activating FogEffect\n");
+
+    // init fogGL
+    GLfloat fogColor[4] = { colorVector.x, colorVector.y, colorVector.z, 1.0};
+    glFogi(GL_FOG_MODE, this->fogMode);
+    glFogfv(GL_FOG_COLOR, fogColor);
+    glHint(GL_FOG_HINT, GL_DONT_CARE);
+    glFogf(GL_FOG_DENSITY, this->fogDensity);
+    glFogf(GL_FOG_START, this->fogStart);
+    glFogf(GL_FOG_END, this->fogEnd);
+
+    this->fogActivate = true;
+
+    glEnable(GL_FOG);
+
+    // Store cloud- and sky color before the snow
+    this->oldCloudColor = CloudEffect::cloudColor;
+    this->oldSkyColor   = CloudEffect::skyColor;
+
+    // Change the colors
+    CloudEffect::changeCloudColor(this->cloudColor, this->fogFadeInDuration);
+    CloudEffect::changeSkyColor(this->skyColor, this->fogFadeInDuration);
+}
+
+/**
+ * @brief deactivates the fog effect
+ */
+void FogEffect::deactivate() {
+    PRINTF(3)("Deactivating FogEffect\n");
+
+    this->fogFadeInActivate = false;
+    this->fogFadeOutActivate = false;
+    this->fogActivate = false;
+
+    glDisable(GL_FOG);
+}
+
+/**
+ * @brief draws the fog effect
+ */
+void FogEffect::draw() const {
+
+    if (!this->fogActivate)
+        return;
+
+    // If fog is fading
+    if ( this->fogFadeInActivate || this->fogFadeOutActivate ) {
+        if ( this->fogMode == GL_LINEAR)
+            glFogf(GL_FOG_END, this->fogFadeEnd);
+        else
+            glFogf(GL_FOG_DENSITY, this->fogFadeDensity);
+    }
+}
+
+/**
+ * @brief ticks the fog effect
+ * @param dt: tick float
+ */
+void FogEffect::tick(float dt) {
+
+    if (!this->fogActivate)
+        return;
+
+    // If fog is fading in
+    if ( this->fogFadeInActivate ) {
+        this->localTimer += dt;
+
+        if ( this->fogMode == GL_LINEAR)
+          this->fogFadeEnd = 2000 * (1 - ( this->localTimer / this->fogFadeInDuration )) + this->fogEnd;
+        else
+            this->fogFadeDensity = ( this->localTimer / this->fogFadeInDuration ) * this->fogDensity;
+
+        if ( this->localTimer >= this->fogFadeInDuration )
+            this->fogFadeInActivate = false;
+    }
+
+    // If fog is fading out
+    if ( this->fogFadeOutActivate ) {
+        this->localTimer += dt;
+
+        if ( this->fogMode == GL_LINEAR)
+          this->fogFadeEnd = 2000 * ( this->localTimer / this->fogFadeOutDuration ) + this->fogEnd;
+        else
+            this->fogFadeDensity = 1 - (( this->localTimer / this->fogFadeOutDuration ) * this->fogDensity);
+
+        if ( this->localTimer >= this->fogFadeOutDuration )
+            this->deactivate();
+    }
+}
+
+/**
+ * @brief fades the fog in
+ */
+void FogEffect::fadeInFog() {
+
+    // If Fog is already fading out, stop it
+    this->fogFadeOutActivate = false;
+
+    // If Fog is already on, turn it off first
+    if (this->fogActivate)
+        this->deactivate();
+
+    // If no manual FadeIn value was set, set a default value
+    if (!this->fogFadeInDuration > 0)
+        this->fogFadeInDuration = 10;
+
+    // Reset local timer
+    this->localTimer = 0;
+
+    // Activate Fog
+    this->activate();
+
+    // set FogFadeIn activate
+    this->fogFadeInActivate = true;
+}
+
+/**
+ * @brief fades the fog out
+ */
+void FogEffect::fadeOutFog() {
+
+    // If Fog is already fading in, stop it
+    this->fogFadeInActivate = false;
+
+
+    // If Fog is off, turn it on first
+    if (!this->fogActivate)
+        this->activate();
+
+    // If no manual FadeOut value was set, set a default value
+    if (!this->fogFadeOutDuration > 0)
+        this->fogFadeOutDuration = 10;
+
+    // set FogFadeOut activate
+    this->fogFadeOutActivate = true;
+
+    // Reset local timer
+    this->localTimer = 0;
+
+    // Restore the old cloud- and sky color
+    CloudEffect::changeCloudColor(this->oldCloudColor, this->fogFadeOutDuration);
+    CloudEffect::changeSkyColor(this->oldSkyColor, this->fogFadeOutDuration);
+}
+
Index: branches/heathaze/src/world_entities/weather_effects/fog_effect.h
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/fog_effect.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/fog_effect.h	(revision 9940)
@@ -0,0 +1,130 @@
+/**
+ * @file fog_effect.h
+ * Generates simple openGL fog
+*/
+
+#ifndef _FOG_EFFECT
+#define _FOG_EFFECT
+
+#include "weather_effect.h"
+#include "glincl.h"
+#include "vector.h"
+
+class CloudEffect;
+
+class FogEffect : public WeatherEffect
+{
+  ObjectListDeclaration(FogEffect);
+public:
+  FogEffect(const TiXmlElement* root = NULL);
+  virtual ~FogEffect();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void init();
+
+  virtual void activate();
+  virtual void deactivate();
+
+  void activateFog()
+  {
+    this->activate();
+  }
+
+  void deactivateFog()
+  {
+    this->deactivate();
+  }
+
+  virtual void draw() const;
+  virtual void tick(float dt);
+
+  inline void setFogMode(const std::string& mode)
+  {
+    this->fogMode = this->stringToFogMode(mode);
+  }
+
+  inline void setFogDensity(float density)
+  {
+    this->fogDensity = density;
+  }
+
+  inline void setFogRange(float start, float end)
+  {
+    this->fogStart = start;
+    this->fogEnd = end;
+  }
+
+  inline void setFogColor(float r, float g, float b)
+  {
+    this->colorVector = Vector(r, g, b);
+  }
+
+  inline void setFogFadeIn(float fadein)
+  {
+    this->fogFadeInDuration = fadein;
+  }
+
+  inline void setFogFadeOut(float fadeout)
+  {
+    this->fogFadeOutDuration = fadeout;
+  }
+
+  inline void setFogOption(const std::string& option)
+  {
+    if (option == "activate")
+      this->fogActivate = true;
+  }
+
+  inline void setCloudColor(float colorX, float colorY, float colorZ)
+  {
+    this->cloudColor = Vector(colorX, colorY, colorZ);
+  }
+  inline void setSkyColor(float colorX, float colorY, float colorZ)
+  {
+    this->skyColor = Vector(colorX, colorY, colorZ);
+  }
+
+  void fadeInFog();
+  void fadeOutFog();
+
+
+private:
+  inline GLint stringToFogMode(const std::string& mode)
+  {
+    if(mode == "GL_LINEAR")
+      return GL_LINEAR;
+    else if(mode == "GL_EXP")
+      return GL_EXP;
+    else if(mode == "GL_EXP2" )
+      return GL_EXP2;
+    else
+      return -1;
+  }
+
+  bool          fogActivate;
+
+  bool          fogFadeInActivate;
+  bool          fogFadeOutActivate;
+
+  GLfloat       fogFadeInDuration;
+  GLfloat       fogFadeOutDuration;
+
+  GLint         fogMode;
+  GLfloat       fogDensity;
+  GLfloat       fogFadeDensity;
+
+  GLfloat       fogStart;
+  GLfloat       fogEnd;
+  GLfloat       fogFadeEnd;
+
+  Vector        colorVector;
+  float         localTimer;
+
+  Vector oldSkyColor;
+  Vector oldCloudColor;
+  Vector skyColor;
+  Vector cloudColor;
+};
+
+#endif  /* _FOG_EFFECT */
Index: branches/heathaze/src/world_entities/weather_effects/lense_flare.cc
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/lense_flare.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/lense_flare.cc	(revision 9940)
@@ -0,0 +1,230 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "lense_flare.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "glincl.h"
+#include "texture.h"
+
+#include "light.h"
+#include "state.h"
+#include "debug.h"
+
+#include "render2D/image_plane.h"
+
+#include "light.h"
+#include "camera.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(LenseFlare, CL_LENSE_FLARE);
+CREATE_FACTORY(LenseFlare);
+
+/**
+ * @brief default constructor
+ * @param root The XML-element to load the LenseFlare from
+ */
+LenseFlare::LenseFlare(const TiXmlElement* root) {
+  this->registerObject(this, LenseFlare::_objectList);
+
+    /*          length                      image scale */
+    this->flareMatrix[0] = 1.0f;
+    this->flareMatrix[1] = 1.0f;
+    this->flareMatrix[2] = 0.5f;
+    this->flareMatrix[3] = 0.5f;
+    this->flareMatrix[4] = 0.33f;
+    this->flareMatrix[5] = 0.25f;
+    this->flareMatrix[6] = 0.125f;
+    this->flareMatrix[7] = 1.0f;
+    this->flareMatrix[8] = -0.5f;
+    this->flareMatrix[9] = 0.5f;
+    this->flareMatrix[10] = -0.25f;
+    this->flareMatrix[11] = 0.15f;
+    this->flareMatrix[12] = -1.82f;
+    this->flareMatrix[13] = 0.25f;
+
+    this->lightSource = (LightManager::getInstance())->getLight(0);
+    PRINTF(4)("light is: %p\n", this->lightSource);
+
+    if (root != NULL) {
+        this->loadParams(root);
+        this->activate();
+    }
+
+    this->bVisible = true;
+    this->setSourceVisibility(false);
+
+}
+
+
+/**
+ *  destroys a LenseFlare
+ */
+LenseFlare::~LenseFlare() {
+    std::vector<ImagePlane*>::iterator it;
+    for( it = flares.begin(); it != flares.end(); it++)
+        delete (*it);
+}
+
+
+/**
+ * @param root The XML-element to load the LenseFlare from
+ */
+void LenseFlare::loadParams(const TiXmlElement* root) {
+    GraphicsEffect::loadParams(root);
+
+    LOAD_PARAM_START_CYCLE(root, element);
+    {
+        LoadParam_CYCLE(element, "add-flare-texture", this, LenseFlare, addFlare)
+        .describe("adds a lensflare texture to the engine");
+    }
+    LOAD_PARAM_END_CYCLE(element);
+}
+
+
+/**
+ * initializes the fog effect
+ */
+void LenseFlare::init() {}
+
+
+/**
+ * activates the fog effect
+ */
+void LenseFlare::activate() {
+    this->bActivated = true;
+}
+
+
+/**
+ * deactivates the fog effect
+ */
+void LenseFlare::deactivate() {
+    this->bActivated = false;
+}
+
+
+/**
+ * @brief converts a gl mode char to a GLint
+ * @param mode the mode character
+ */
+GLint LenseFlare::stringToFogMode(const std::string& mode) {
+    return 0;
+}
+
+
+/**
+ * @brief adds a texture flare
+ * @param textureName the name of the flare texture
+ *
+ *  1st: Texture of the Sun/Light source itself
+ *  2nd: Texture of the fist halo
+ *  3rd: Texture of small burst
+ *  4th: Texture of the second halo
+ *  5th: Texutre of the second burst
+ *  6th: Texture of the third halo
+ *  7th: Texture of the third burst
+ */
+void LenseFlare::addFlare(const std::string& textureName) {
+    if( this->flares.size() > LF_MAX_FLARES) {
+        PRINTF(2)("You tried to add more than %i lense flares, ignoring\n", LF_MAX_FLARES);
+        return;
+    }
+
+    ImagePlane* bb = new ImagePlane(NULL);
+    if (this->flares.empty())
+        bb->setLayer(E2D_LAYER_BELOW_ALL);
+    bb->setTexture(textureName);
+    bb->setSize(50, 50);
+    this->flares.push_back(bb);
+    bb->setVisibility(true);
+
+    PRINTF(4)("Added a Lenseflare ImagePlane with texture %s\n", textureName.c_str());
+
+    // the first flare belongs to the light source
+    if( this->flares.size() == 1 && this->lightSource != NULL) {
+        bb->setBindNode(static_cast<PNode*>(this->lightSource));
+    }
+
+    PRINTF(4)("Finished adding\n");
+}
+
+
+void LenseFlare::setSourceVisibility(bool visibility) {
+    if (this->bVisible == visibility)
+        return;
+
+    std::vector<ImagePlane*>::const_iterator it;
+    for(it = ++flares.begin(); it != flares.end(); it++)
+        (*it)->setVisibility(visibility);
+    this->bVisible = visibility;
+}
+
+
+/**
+ * tick the effect
+ */
+void LenseFlare::tick(float dt) {
+    if( unlikely(!this->bActivated || this->flares.size() == 0))
+        return;
+
+    // refetch light source information if needed
+    if( unlikely( this->lightSource == NULL)) {
+        this->lightSource = (LightManager::getInstance())->getLight(0);
+        if( this->flares.size() > 0)
+            this->flares[0]->setBindNode(static_cast<PNode*>(this->lightSource));
+    }
+
+    //set the frustum plane
+    if (!flares.empty())
+        this->setSourceVisibility(this->flares[0]->isVisible());
+
+
+    // always update the screen center, it could be, that the window is resized
+    this->screenCenter = Vector2D(State::getResX()/2.0f, State::getResY()/2.0f);
+
+    // flare vector is the direction from the center to the light source
+    this->flareVector = this->flares[0]->getAbsCoor2D() - this->screenCenter;
+    this->distance = this->flareVector.len();
+    this->flareVector.normalize();
+
+    // now calculate the new coordinates of the billboards
+    std::vector<ImagePlane*>::iterator it;
+    int i;
+    for( it = flares.begin(), i = 0; it != flares.end(); it++, i++) {
+        // set the new position
+        if( i == 0)
+            continue;
+
+        (*it)->setAbsCoor2D( this->screenCenter + this->flareVector * this->flareMatrix[i * 2] * this->distance);
+        (*it)->setSize2D(50.0f * this->flareMatrix[i * 2 + 1], 50.0f * this->flareMatrix[i * 2 + 1]);
+        PRINTF(5)("Tick flare %i @ (%f, %f)\n", i, (*it)->getAbsCoor2D().x, (*it)->getAbsCoor2D().y);
+    }
+}
+
+
+/**
+ * draws the LenseFlares
+ */
+void LenseFlare::draw() const {
+    if( !this->bActivated)
+        return;
+}
Index: branches/heathaze/src/world_entities/weather_effects/lense_flare.h
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/lense_flare.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/lense_flare.h	(revision 9940)
@@ -0,0 +1,65 @@
+/**
+ * @file lense_flare.h
+ *  lense flare effect
+ */
+
+#ifndef _LENSE_FLARE
+#define _LENSE_FLARE
+
+#include "graphics_effect.h"
+
+#include <vector>
+
+#include "vector2D.h"
+#include "plane.h"
+#include "glincl.h"
+
+
+#define LF_MAX_FLARES 7
+
+
+class TiXmlElement;
+class Light;
+class ImagePlane;
+
+//! A class that handles LenseFlares. The LenseFlareManager operates on this.
+class LenseFlare : public GraphicsEffect
+{
+  ObjectListDeclaration(LenseFlare);
+  public:
+    LenseFlare(const TiXmlElement* root = NULL);
+    virtual ~LenseFlare();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void init();
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void draw() const;
+    virtual void tick(float dt);
+
+    void addFlare(const std::string& textureName);
+
+
+  private:
+    GLint stringToFogMode(const std::string& mode);
+    void setSourceVisibility(bool visibility) ;
+
+
+  private:
+    bool                     bVisible;          //!< Checks visibility
+    Light*                   lightSource;        //!< reference to the sun (or primary light source)
+    std::vector<ImagePlane*> flares;             //!< the flares array
+
+    Vector2D                 flareVector;        //!< the axis to draw the flares on
+    float                    distance;           //!< distance from center to source
+    Vector2D                 screenCenter;       //!< the vector marking the center of the screen
+
+    float                    flareMatrix[14];
+    Plane                    frustumPlane;       //!< plane that marks the view frustum
+};
+
+
+#endif /* _LENSE_FLARE */
Index: branches/heathaze/src/world_entities/weather_effects/lightning_effect.cc
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/lightning_effect.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/lightning_effect.cc	(revision 9940)
@@ -0,0 +1,288 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: hdavid, amaechler
+*/
+
+#include "lightning_effect.h"
+
+#include "state.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "sound/resource_sound_buffer.h"
+
+#include "effects/billboard.h"
+
+#include "shell_command.h"
+#include "light.h"
+#include "cloud_effect.h"
+#include "script_class.h"
+#include "debug.h"
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(LightningEffect, CL_LIGHTNING_EFFECT);
+
+SHELL_COMMAND(activate, LightningEffect, activateLightning);
+SHELL_COMMAND(deactivate, LightningEffect, deactivateLightning);
+
+CREATE_SCRIPTABLE_CLASS(LightningEffect,
+                        addMethod("activate", Executor0<LightningEffect, lua_State*>(&LightningEffect::activate))
+                            ->addMethod("deactivate", Executor0<LightningEffect, lua_State*>(&LightningEffect::deactivate))
+                       );
+
+CREATE_FACTORY(LightningEffect);
+
+LightningEffect::LightningEffect(const TiXmlElement* root) {
+  this->registerObject(this, LightningEffect::_objectList);
+    this->init();
+
+    if (root != NULL)
+        this->loadParams(root);
+
+    if(this->lightningActivate)
+        this->activate();
+}
+
+LightningEffect::~LightningEffect() {
+    this->deactivate();
+}
+
+void LightningEffect::loadParams(const TiXmlElement* root) {
+    WeatherEffect::loadParams(root);
+
+    LoadParam(root, "coord", this, LightningEffect, coord);
+    LoadParam(root, "frequency", this, LightningEffect, setFlashFrequency);
+    LoadParam(root, "const-time", this, LightningEffect, setFlashConstTime);
+    LoadParam(root, "rising-time", this, LightningEffect, setFlashRisingTime);
+    LoadParam(root, "size", this, LightningEffect, setFlashSize);
+    LoadParam(root, "seed", this, LightningEffect, setFlashSeed);
+
+    LOAD_PARAM_START_CYCLE(root, element);
+    {
+        LoadParam_CYCLE(element, "option", this, LightningEffect, setLightningOption);
+    }
+    LOAD_PARAM_END_CYCLE(element);
+}
+
+
+void LightningEffect::init() {
+    //default values
+    this->lightningActivate = false;
+
+    this->flashFrequency = 4.0f;
+    this->flashFrequencyBase = 4.0f;
+    this->flashFrequencySeed = 2.0f;
+
+    this->flashHoldTime = 0.1f;
+    this->flashRisingTime = 0.03f;
+
+    this->seedX = 500.f;
+    this->seedZ = 1000.0f;
+
+    this->width = 640.0f;
+    this->height = 400.0f;
+    this->seedWidth = 100.0f;
+    this->seedHeight = 100.0f;
+
+    this->lightningMove = false;
+
+    this->mainPosX = 0;
+    this->mainPosY = 100;
+    this->mainPosZ = 5;
+
+    this->time = 0.0;
+
+    // initialize thunder billboard
+    int i;
+    for (i = 0; i < 4; i++) {
+        this->thunderBolt[i] = new Billboard(NULL);
+        this->thunderBolt[i]->setSize(this->width, this->height);
+        this->thunderBolt[i]->setVisibiliy(false);
+    }
+
+    //should load both texture
+    this->thunderTextureA = true;
+    this->setTexture();
+    this->switchTexture();
+
+    if (this->lightningMove) {
+        this->cameraCoor = State::getCameraNode()->getAbsCoor();
+        for (i = 0; i < 4; i++)
+          this->thunderBolt[i]->setAbsCoor(this->cameraCoor.x + this->mainPosX, this->mainPosY, this->cameraCoor.z + this->mainPosZ);
+    } else
+        for (i = 0; i < 4; i++)
+          this->thunderBolt[i]->setAbsCoor(this->mainPosX, this->mainPosY, this->mainPosZ);
+
+    this->flashLight = new Light();
+    this->flashLight->setDiffuseColor(0,0,0);
+    this->flashLight->setSpecularColor(0,0,0);
+
+    //load sound
+    this->thunderBuffer = OrxSound::ResourceSoundBuffer("sound/atmosphere/thunder.wav");
+
+}
+
+void LightningEffect::coord(float x, float y, float z) {
+    int i;
+
+    if (this->lightningMove) {
+        this->cameraCoor = State::getCameraNode()->getAbsCoor();
+        for (i = 0; i < 4; i++)
+            this->thunderBolt[i]->setAbsCoor(this->cameraCoor.x+x, y, this->cameraCoor.z+z);
+    } else
+        for (i = 0; i < 4; i++)
+            this->thunderBolt[i]->setAbsCoor(x, y, z);
+
+    this->mainPosX = x;
+    this->mainPosY = y;
+    this->mainPosZ = z;
+}
+
+
+void LightningEffect::setFlashSize(float width, float height, float seedWidth, float seedHeight) {
+    this->width = width;
+    this->height = height;
+    this->seedWidth = seedWidth;
+    this->seedHeight = seedHeight;
+
+    int i;
+    for (i = 0; i < 4; i++)
+        this->thunderBolt[i]->setSize(this->width, this->height);
+
+}
+
+
+void LightningEffect::activate() {
+    PRINTF(3)( "Activating LightningEffect\n" );
+    this->lightningActivate = true;
+
+    this->time = 0;
+}
+
+
+void LightningEffect::deactivate() {
+    PRINTF(3)("Deactivating LightningEffect\n");
+    this->lightningActivate = false;
+
+    int i;
+    for (i = 0; i < 4; i++)
+        this->thunderBolt[i]->setVisibiliy(false);
+
+}
+
+void LightningEffect::tick (float dt) {
+    if(!lightningActivate)
+        return;
+
+    this->time += dt;
+
+    float x;
+    x = (float)rand()/(float)RAND_MAX;
+
+    if( this->time > this->flashFrequency) {
+        // Reset timer
+        this->time = 0.0f;
+
+        // Move thunderBolt to start position
+        this->flashLight->setAbsCoor(this->thunderBolt[0]->getAbsCoor().x, this->thunderBolt[0]->getAbsCoor().y, this->thunderBolt[0]->getAbsCoor().z);
+
+        // Start a flash & lightning cycle
+        this->thunderBolt[0]->setVisibiliy(true);
+
+        // Lighten up environment
+        this->flashLight->setDiffuseColor(1,1,1);
+        this->flashLight->setSpecularColor(1,1,1);
+
+
+        // Play thunder sound
+        this->soundSource.play(this->thunderBuffer);
+    }
+
+    if( this->thunderBolt[0]->isVisible() && this->time > this->flashRisingTime*1/3 ) {
+        this->thunderBolt[0]->setVisibiliy(false);
+        this->thunderBolt[1]->setVisibiliy(true);
+    } else if( this->thunderBolt[1]->isVisible() && this->time > this->flashRisingTime*2/3 ) {
+        this->thunderBolt[1]->setVisibiliy(false);
+        this->thunderBolt[2]->setVisibiliy(true);
+
+    } else if( this->thunderBolt[2]->isVisible() && this->time > this->flashRisingTime) {
+        this->thunderBolt[2]->setVisibiliy(false);
+        this->thunderBolt[3]->setVisibiliy(true);
+    }
+
+    if( this->thunderBolt[3]->isVisible() && this->time > this->flashHoldTime) {
+        this->thunderBolt[3]->setVisibiliy(false);
+
+        this->time = 0.0f;
+        this->flashLight->setDiffuseColor(0,0,0);
+        this->flashLight->setSpecularColor(0,0,0);
+
+        this->newCoordinates();
+    }
+}
+
+void LightningEffect::newCoordinates() {
+
+    float posX, posZ;
+
+    if(this->lightningMove) {
+        this->cameraCoor = State::getCameraNode()->getAbsCoor();
+        posX = this->mainPosX - this->seedX * (float)rand()/(float)RAND_MAX + this->cameraCoor.x;
+        posZ = this->mainPosZ + this->seedZ * (float)rand()/(float)RAND_MAX + this->cameraCoor.z;
+    } else {
+        posX = this->mainPosX - this->seedX * (float)rand()/(float)RAND_MAX;
+        posZ = this->mainPosZ + this->seedZ * (float)rand()/(float)RAND_MAX;
+    }
+
+    this->switchTexture();
+
+    int i;
+    for (i = 0; i < 4; i++)
+        this->thunderBolt[i]->setAbsCoor(posX, this->mainPosY, posZ);
+
+    this->flashFrequency = this->flashFrequencyBase + this->flashFrequencySeed * (float)rand()/(float)RAND_MAX;
+
+    float w = this->width + this->seedWidth * (float)rand()/(float)RAND_MAX;
+    float h = this->height + this->seedHeight * (float)rand()/(float)RAND_MAX;
+
+    for (i = 0; i < 4; i++)
+        this->thunderBolt[i]->setSize(w, h);
+
+}
+
+void LightningEffect::setTexture() {
+
+  if (this->thunderTextureA) {
+    this->thunderBolt[0]->setTexture("maps/thunderbA1.png");
+    this->thunderBolt[1]->setTexture("maps/thunderbA2.png");
+    this->thunderBolt[2]->setTexture("maps/thunderbA3.png");
+    this->thunderBolt[3]->setTexture("maps/thunderbA4.png");
+  }
+  else {
+    this->thunderBolt[0]->setTexture("maps/thunderbB1.png");
+    this->thunderBolt[1]->setTexture("maps/thunderbB2.png");
+    this->thunderBolt[2]->setTexture("maps/thunderbB3.png");
+    this->thunderBolt[3]->setTexture("maps/thunderbB4.png");
+  }
+
+}
+
+void LightningEffect::switchTexture() {
+
+  if (this->thunderTextureA)
+    this->thunderTextureA = false;
+  else
+    this->thunderTextureA = true;
+
+  this->setTexture();
+
+}
Index: branches/heathaze/src/world_entities/weather_effects/lightning_effect.h
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/lightning_effect.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/lightning_effect.h	(revision 9940)
@@ -0,0 +1,124 @@
+/**
+* @file lightning_effect.h
+*/
+
+#ifndef _LIGHTNING_EFFECT
+#define _LIGHTNING_EFFECT
+
+#include "vector.h"
+#include "vector2D.h"
+
+#include "weather_effect.h"
+
+#include "sound_buffer.h"
+#include "sound_source.h"
+
+class Billboard;
+class Light;
+
+class LightningEffect : public WeatherEffect
+{
+  ObjectListDeclaration(LightningEffect);
+public:
+  LightningEffect(const TiXmlElement* root = NULL);
+  virtual ~LightningEffect();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void init();
+
+  virtual void activate();
+  virtual void deactivate();
+
+  inline  void activateLightning()
+  {
+    this->activate();
+  }
+  inline  void deactivateLightning()
+  {
+    this->deactivate();
+  }
+
+  virtual void tick(float dt);
+
+  void coord(float x, float y, float z);
+  void setFlashSize(float width, float height, float seedWidth, float seedHeight);
+
+  inline void setLightningOption(const std::string& option)
+  {
+    if (option == "activate")
+      this->lightningActivate = true;
+    if (option == "movelightning")
+      this->lightningMove = true;
+  }
+
+  inline void setFlashFrequency(float baseFrequency, float seedTime)
+  {
+    this->flashFrequencyBase = baseFrequency;
+    this->flashFrequency = baseFrequency;
+    this->flashFrequencySeed = seedTime;
+  }
+
+  inline void setFlashConstTime(float holdTime)
+  {
+    this->flashHoldTime = holdTime;
+  }
+
+  inline void setFlashRisingTime(float flashRisingTime)
+  {
+    if(flashRisingTime > this->flashHoldTime)
+      this->flashRisingTime = this->flashHoldTime * 0.5;
+    else
+      this->flashRisingTime = flashRisingTime;
+  }
+
+  inline void setFlashSeed(float seedX, float seedZ)
+  {
+    this->seedX = seedX;
+    this->seedZ = seedZ;
+  }
+
+
+private:
+
+  void newCoordinates();
+  void setTexture();
+  void switchTexture();
+
+  Billboard* thunderBolt[4];
+  bool thunderTextureA;
+
+  bool lightningActivate;
+  bool lightningMove;
+
+  float flashFrequency;
+  float flashFrequencyBase;
+  float flashHoldTime;
+  float flashRisingTime;
+
+  float time;
+
+  float width;
+  float height;
+  float seedWidth;
+  float seedHeight;
+
+  float seedX;
+  float seedZ;
+  float flashFrequencySeed;
+
+  float mainPosX;
+  float mainPosY;
+  float mainPosZ;
+
+  Vector origSkyColor;
+  Vector cameraCoor;
+
+  Light* flashLight;
+
+  OrxSound::SoundSource    soundSource;
+  OrxSound::SoundBuffer    thunderBuffer;
+
+};
+
+#endif  /* _LIGHTNING_EFFECT */
Index: branches/heathaze/src/world_entities/weather_effects/rain_effect.cc
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/rain_effect.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/rain_effect.cc	(revision 9940)
@@ -0,0 +1,333 @@
+/*
+  orxonox - the future of 3D-vertical-scrollers
+
+  Copyright (C) 2004 orx
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+### File Specific:
+  main-programmer: hdavid, amaechler
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "rain_effect.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "sound/resource_sound_buffer.h"
+
+#include "glincl.h"
+#include "p_node.h"
+#include "state.h"
+#include "particles/spark_particles.h"
+#include "particles/plane_emitter.h"
+#include "shell_command.h"
+#include "light.h"
+#include "cloud_effect.h"
+#include "script_class.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(RainEffect, CL_RAIN_EFFECT);
+
+// Define shell commands
+//SHELL_COMMAND(activate, RainEffect, activateRain);
+//SHELL_COMMAND(deactivate, RainEffect, deactivateRain);
+SHELL_COMMAND(startraining, RainEffect, startRaining);
+SHELL_COMMAND(stopraining, RainEffect, stopRaining);
+
+
+
+CREATE_SCRIPTABLE_CLASS(RainEffect,
+                        addMethod("startRaining", Executor0<RainEffect, lua_State*>(&RainEffect::startRaining))
+                            ->addMethod("stopRaining", Executor0<RainEffect, lua_State*>(&RainEffect::stopRaining))
+                            ->addMethod("activate", Executor0<RainEffect, lua_State*>(&RainEffect::activate))
+                            ->addMethod("deactivate", Executor0<RainEffect, lua_State*>(&RainEffect::deactivate))
+                       );
+
+CREATE_FACTORY(RainEffect);
+
+/**
+ * @brief standard constructor
+ */
+RainEffect::RainEffect(const TiXmlElement* root) {
+  this->registerObject(this, RainEffect::_objectList);
+    this->init();
+
+    if (root != NULL)
+        this->loadParams(root);
+
+    //load rain sound
+    this->rainBuffer = OrxSound::ResourceSoundBuffer("sound/atmosphere/rain.wav");
+
+    //load wind sound
+    if (this->rainWindForce != 0) {
+      this->windBuffer = OrxSound::ResourceSoundBuffer("sound/atmosphere/wind.wav");
+    }
+
+    if(rainActivate) {
+        this->activate();
+        RainEffect::rainParticles->precache((int)this->rainLife * 2);
+    }
+}
+
+/**
+ * @brief standard deconstructor
+ */
+RainEffect::~RainEffect() {
+    this->deactivate();
+}
+
+/**
+ * @brief initalizes the rain effect with default values
+ */
+void RainEffect::init() {
+
+    this->rainParticles = NULL;
+    this->emitter = NULL;
+    this->lightMan = NULL;
+
+    //Default values
+    this->rainActivate = false;
+    this->rainFadeInActivate = false;
+    this->rainFadeOutActivate = false;
+
+    this->rainMove = false;
+    this->rainCoord = Vector(500, 500, 500);
+    this->rainSize = Vector2D(1000, 1000);
+    this->rainRate = 4000;
+    this->rainVelocity = -300;
+    this->rainLife = 4;
+    this->rainWindForce  = 0;
+    this->rainFadeInDuration = 10;
+    this->rainFadeOutDuration = 10;
+
+    this->cloudColor = Vector(0.6f, 0.6f, 0.6f);
+    this->skyColor = Vector(0.0f, 0.0f, 0.0f);
+
+    this->rainMaxParticles = this->rainRate * this->rainLife;
+    this->localTimer = 0;
+    this->soundRainVolume = 0.3f;
+    this->emitter = new PlaneEmitter(this->rainSize);
+
+    lightMan = LightManager::getInstance();
+}
+
+/**
+ * @brief loads the rain effect parameters.
+ * @param root: the XML-Element to load the data from
+ */
+void RainEffect::loadParams(const TiXmlElement* root) {
+    WeatherEffect::loadParams(root);
+
+    LoadParam(root, "coord", this, RainEffect, setRainCoord);
+    LoadParam(root, "size", this, RainEffect, setRainSize);
+    LoadParam(root, "rate", this, RainEffect, setRainRate);
+    LoadParam(root, "velocity", this, RainEffect, setRainVelocity);
+    LoadParam(root, "life", this, RainEffect, setRainLife);
+    LoadParam(root, "wind", this, RainEffect, setRainWind);
+    LoadParam(root, "fadeinduration", this, RainEffect, setRainFadeIn);
+    LoadParam(root, "fadeoutduration", this, RainEffect, setRainFadeOut);
+    LoadParam(root, "cloudcolor", this, RainEffect, setCloudColor);
+    LoadParam(root, "skycolor", this, RainEffect, setSkyColor);
+
+    LOAD_PARAM_START_CYCLE(root, element);
+    {
+        LoadParam_CYCLE(element, "option", this, RainEffect, setRainOption);
+    }
+    LOAD_PARAM_END_CYCLE(element);
+}
+
+SparkParticles* RainEffect::rainParticles = NULL;
+
+/**
+ * @brief activates the rain effect
+ */
+void RainEffect::activate() {
+    PRINTF(3)( "Activating RainEffect, coord: %f, %f, %f, size: %f, %f, rate: %f, velocity: %f, moveRain: %s\n", this->rainCoord.x, this->rainCoord.y, this->rainCoord.z, this->rainSize.x, this-> rainSize.y, this->rainRate, this->rainVelocity, this->rainMove ? "true" : "false" );
+
+    this->rainActivate = true;
+
+    if (unlikely(RainEffect::rainParticles == NULL)) {
+        RainEffect::rainParticles = new SparkParticles((int) this->rainMaxParticles);
+        RainEffect::rainParticles->setName("RainParticles");
+        RainEffect::rainParticles->setLifeSpan(this->rainLife, 2);
+        RainEffect::rainParticles->setRadius(0, 0.03);
+        RainEffect::rainParticles->setRadius(0.2, 0.02);
+        RainEffect::rainParticles->setRadius(1, 0.01);
+        RainEffect::rainParticles->setColor(0, 0.3, 0.3, 0.5, 0.2);   // grey blue 1
+        RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2); // grey blue 2
+        RainEffect::rainParticles->setColor(1, 0.7, 0.7, 0.7, 0.2);   // light grey
+    }
+
+    this->emitter->setSystem(RainEffect::rainParticles);
+    this->emitter->setRelCoor(this->rainCoord);
+    this->emitter->setEmissionRate(this->rainRate);
+    this->emitter->setEmissionVelocity(this->rainVelocity);
+    this->emitter->setSpread(this->rainWindForce / 50, 0.2);
+
+    // play rain sound and loop it
+    this->soundSource.play(this->rainBuffer, this->soundRainVolume, true);
+
+    // if there's wind, play wind sound
+    if (this->rainWindForce > 0)
+        this->soundSource.play(this->windBuffer, 0.1f * this->rainWindForce, true);
+
+    // Store cloud- and sky color before the rain;
+    this->oldCloudColor = CloudEffect::cloudColor;
+    this->oldSkyColor   = CloudEffect::skyColor;
+
+    // If we're not fading, change color immediately
+    if (!this->rainFadeInActivate || !this->rainFadeOutActivate) {
+        CloudEffect::changeCloudColor(this->cloudColor, 0.2);
+        CloudEffect::changeSkyColor(this->skyColor, 0.2);
+    }
+
+    //lightMan->setAmbientColor(.1,.1,.1);
+}
+
+/**
+ * @brief deactivates the rain effect
+ */
+void RainEffect::deactivate() {
+    PRINTF(3)("Deactivating RainEffect\n");
+
+    this->rainActivate = false;
+    this->rainFadeInActivate = false;
+    this->rainFadeOutActivate = false;
+
+    //if(this->emitter)
+    //  this->emitter->setSystem(NULL);
+    //this->hideRain();
+
+    // Stop Sound
+    this->soundSource.stop();
+
+    // Restore the old cloud- and sky color
+    CloudEffect::changeCloudColor(this->oldCloudColor, 0.2);
+    CloudEffect::changeSkyColor(this->oldSkyColor, 0.2);
+}
+
+/**
+ * @brief ticks the rain effect
+ * @param dt: tick float
+ */
+void RainEffect::tick (float dt) {
+    if (!this->rainActivate)
+        return;
+
+    if (this->rainMove) {
+        this->rainCoord = State::getCameraNode()->getAbsCoor();
+        this->emitter->setRelCoor(this->rainCoord.x , this->rainCoord.y+800, this->rainCoord.z);
+    }
+
+    if (this->rainFadeInActivate) {
+        PRINTF(4)("tick fading IN RainEffect\n");
+
+        this->localTimer += dt;
+        float progress = this->localTimer / this->rainFadeInDuration;
+
+        // use alpha in color to fade in rain
+        RainEffect::rainParticles->setColor(0,   0.3, 0.3, 0.5, 0.2 * progress); // grey blue 1
+        RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2 * progress); // grey blue 2
+        RainEffect::rainParticles->setColor(1,   0.7, 0.7, 0.7, 0.2 * progress); // light grey
+
+        // increase radius for more "heavy" rain
+        RainEffect::rainParticles->setRadius(0, 0.03 * progress);
+        RainEffect::rainParticles->setRadius(0.2, 0.02 * progress);
+        RainEffect::rainParticles->setRadius(1, 0.01 * progress);
+
+        // increase sound volume
+        if (progress > 0.5) {
+          if (!this->soundSource.isPlaying())
+            this->soundSource.play(this->rainBuffer, this->soundRainVolume, true);
+          this->soundSource.gain(this->rainBuffer, this->soundRainVolume * progress * 2 - 0.5);
+        }
+
+        if (progress >= 1)
+            this->rainFadeInActivate = false;
+
+        lightMan->setAmbientColor(1-progress, 1-progress, 1-progress);
+    }
+
+    if (this->rainFadeOutActivate) {
+        PRINTF(4)("tick fading OUT RainEffect\n");
+
+        this->localTimer += dt;
+        float progress = 1 - (this->localTimer / this->rainFadeOutDuration);
+
+        // use alpha in color to fade out
+        RainEffect::rainParticles->setColor(0,   0.3, 0.3, 0.5, 0.2 * progress); // grey blue 1
+        RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2 * progress); // grey blue 2
+        RainEffect::rainParticles->setColor(1,   0.7, 0.7, 0.7, 0.2 * progress); // light grey
+
+        // decrease radius
+        RainEffect::rainParticles->setRadius(0, 0.03 * progress);
+        RainEffect::rainParticles->setRadius(0.2, 0.02 * progress);
+        RainEffect::rainParticles->setRadius(1, 0.01 * progress);
+
+        // decrease sound volume
+        if (!this->soundSource.isPlaying())
+            this->soundSource.play(this->rainBuffer, this->soundRainVolume, true);
+        this->soundSource.gain(this->rainBuffer, this->soundRainVolume * progress);
+
+        if (progress <= 0) {
+            PRINTF(4)("tick fading OUT RainEffect COMPLETED! Deactivating...\n");
+            this->rainFadeOutActivate = false;
+            this->deactivate();
+        }
+        lightMan->setAmbientColor(1-progress, 1-progress, 1-progress);
+    }
+}
+
+/**
+ * @brief starts raining slowly
+*/
+void RainEffect::startRaining() {
+    PRINTF(4)("startRaining function;\n");
+
+    // If it is already raining, do nothing
+    if (this->rainActivate)
+        return;
+
+    this->localTimer = 0;
+    this->rainFadeInActivate = true;
+
+    PRINTF(4)("startRaining function complete; fadedur: %f\n", this->rainFadeInDuration);
+    this->activate();
+
+    CloudEffect::changeCloudColor(this->cloudColor, this->rainFadeInDuration);
+    CloudEffect::changeSkyColor(this->skyColor, this->rainFadeInDuration);
+}
+
+/**
+ * @brief stops raining slowly
+ */
+void RainEffect::stopRaining() {
+    PRINTF(4)("stopRaining function;\n");
+
+    // If it is not raining, do nothing
+    if (!this->rainActivate)
+        return;
+
+    this->localTimer = 0;
+    this->rainFadeOutActivate = true;
+
+    PRINTF(4)("stopRaining function completed; fadedur: %f\n", this->rainFadeOutDuration);
+
+    CloudEffect::changeCloudColor(this->oldCloudColor, this->rainFadeOutDuration);
+    CloudEffect::changeSkyColor(this->oldSkyColor, this->rainFadeOutDuration);
+}
+
+/**
+ * @brief hides the rain
+ */
+void RainEffect::hideRain() {
+    RainEffect::rainParticles->setColor(0, 0,0,0, 0);
+    RainEffect::rainParticles->setColor(0, 0,0,0, 0);
+}
Index: branches/heathaze/src/world_entities/weather_effects/rain_effect.h
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/rain_effect.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/rain_effect.h	(revision 9940)
@@ -0,0 +1,144 @@
+/**
+ * @file rain_effect.h
+ * Generates rain using the particle engine
+*/
+
+#ifndef _RAIN_EFFECT
+#define _RAIN_EFFECT
+
+#include "weather_effect.h"
+
+#include "vector.h"
+#include "vector2D.h"
+#include <string>
+
+#include "particles/particle_system.h"
+
+class SparkParticles;
+class PlainEmitter;
+class LightManager;
+class CloudEffect;
+
+#include "sound_buffer.h"
+#include "sound_source.h"
+
+class RainEffect : public WeatherEffect
+{
+  ObjectListDeclaration(RainEffect);
+public:
+  RainEffect(const TiXmlElement* root = NULL);
+  virtual ~RainEffect();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void init();
+
+  virtual void activate();
+  virtual void deactivate();
+
+  inline void activateRain()
+  {
+    this->activate();
+  }
+
+  inline void deactivateRain()
+  {
+    this->deactivate();
+  }
+
+  virtual void tick(float dt);
+
+  void startRaining();
+  void stopRaining();
+
+  void hideRain();
+
+  inline void setRainCoord(float x, float y, float z)
+  {
+    this->rainCoord = Vector(x, y, z);
+  }
+  inline void setRainSize(float x, float y)
+  {
+    this->rainSize = Vector2D(x, y);
+  }
+  inline void setRainRate(float rate)
+  {
+    this->rainRate = rate;
+  }
+  inline void setRainVelocity(float velocity)
+  {
+    this->rainVelocity = -velocity;
+  }
+  inline void setRainLife(float life)
+  {
+    this->rainLife = life;
+  }
+  inline void setRainWind(int force)
+  {
+    this->rainWindForce = force;
+  }
+
+  inline void setRainFadeIn(float fadein)
+  {
+    this->rainFadeInDuration = fadein;
+  }
+  inline void setRainFadeOut(float fadeout)
+  {
+    this->rainFadeOutDuration = fadeout;
+  }
+
+  inline void setCloudColor(float colorX, float colorY, float colorZ)
+  {
+    this->cloudColor = Vector(colorX, colorY, colorZ);
+  }
+  inline void setSkyColor(float colorX, float colorY, float colorZ)
+  {
+    this->skyColor = Vector(colorX, colorY, colorZ);
+  }
+
+  inline void setRainOption(const std::string& option)
+  {
+    if (option == "moverain")
+      this->rainMove = true;
+    if (option == "activate")
+      this->rainActivate = true;
+  }
+
+
+private:
+  static SparkParticles*      rainParticles;
+  ParticleEmitter*            emitter;
+
+  float                       localTimer;
+
+  GLfloat                     rainFadeInDuration;
+  GLfloat                     rainFadeOutDuration;
+  bool                        rainFadeInActivate;
+  bool                        rainFadeOutActivate;
+
+  Vector                      rainCoord;
+  Vector2D                    rainSize;
+  GLfloat                     rainRate;
+  GLfloat                     rainVelocity;
+  GLfloat                     rainLife;
+  GLfloat                     rainMaxParticles;
+  int                         rainWindForce;
+  bool                        rainMove;
+  bool                        rainActivate;
+
+  OrxSound::SoundSource       soundSource;
+  OrxSound::SoundBuffer       rainBuffer;
+  OrxSound::SoundBuffer       windBuffer;
+
+  float                       soundRainVolume;
+
+  Vector                      oldSkyColor;
+  Vector                      oldCloudColor;
+  Vector                      skyColor;
+  Vector                      cloudColor;
+
+  LightManager*               lightMan;
+
+};
+
+#endif  /* _RAIN_EFFECT */
Index: branches/heathaze/src/world_entities/weather_effects/snow_effect.cc
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/snow_effect.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/snow_effect.cc	(revision 9940)
@@ -0,0 +1,233 @@
+/*
+        orxonox - the future of 3D-vertical-scrollers
+
+        Copyright (C) 2004 orx
+
+        This program is free software; you can redistribute it and/or modify
+        it under the terms of the GNU General Public License as published by
+        the Free Software Foundation; either version 2, or (at your option)
+        any later version.
+
+### File Specific:
+        main-programmer: hdavid, amaechler
+*/
+
+#include "snow_effect.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+#include "sound/resource_sound_buffer.h"
+
+#include "glincl.h"
+#include "debug.h"
+
+#include "p_node.h"
+#include "state.h"
+#include "particles/sprite_particles.h"
+#include "particles/plane_emitter.h"
+#include "shell_command.h"
+#include "script_class.h"
+#include "cloud_effect.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinitionID(SnowEffect, CL_SNOW_EFFECT);
+SHELL_COMMAND(activate, SnowEffect, activateSnow);
+SHELL_COMMAND(deactivate, SnowEffect, deactivateSnow);
+
+
+CREATE_SCRIPTABLE_CLASS(SnowEffect,
+                        addMethod("activate", Executor0<SnowEffect, lua_State*>(&SnowEffect::activate))
+                        ->addMethod("deactivate", Executor0<SnowEffect, lua_State*>(&SnowEffect::deactivate))
+                       );
+
+CREATE_FACTORY(SnowEffect);
+
+SnowEffect::SnowEffect(const TiXmlElement* root)
+{
+  this->registerObject(this, SnowEffect::_objectList);
+
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+
+  //load wind sound
+  if (this->snowWindForce >= 1)
+  {
+    this->windBuffer = OrxSound::ResourceSoundBuffer("sound/atmosphere/wind.wav");
+  }
+
+  if(snowActivate)
+  {
+    this->activate();
+    SnowEffect::snowParticles->precache((int) this->snowLife);
+  }
+}
+
+
+SnowEffect::~SnowEffect()
+{
+  this->deactivate();
+}
+
+SpriteParticles* SnowEffect::snowParticles = NULL;
+
+void SnowEffect::loadParams(const TiXmlElement* root)
+{
+  WeatherEffect::loadParams(root);
+
+  LoadParam(root, "numParticles", this, SnowEffect, numParticles);
+  LoadParam(root, "materialTexture", this, SnowEffect, materialTexture);
+  LoadParam(root, "lifeSpans", this, SnowEffect, lifeSpan);
+  LoadParam(root, "radius", this, SnowEffect, radius);
+  LoadParam(root, "mass", this, SnowEffect, mass);
+  LoadParam(root, "emissionRate", this, SnowEffect, emissionRate);
+  LoadParam(root, "emissionVelocity", this, SnowEffect, emissionVelocity);
+  LoadParam(root, "wind", this, SnowEffect, wind);
+  LoadParam(root, "size", this, SnowEffect, size);
+  LoadParam(root, "coord", this, SnowEffect, coord);
+  LoadParam(root, "cloudcolor", this, SnowEffect, setCloudColor);
+  LoadParam(root, "skycolor", this, SnowEffect, setSkyColor);
+  LoadParam(root, "fadetime", this, SnowEffect, setFadeTime);
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    LoadParam_CYCLE(element, "option", this, SnowEffect, setSnowOption);
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+void SnowEffect::init()
+{
+  this->emitter = new PlaneEmitter();
+
+  // Default values
+  this->snowActivate = false;
+  this->snowMove = false;
+  this->particles = 12000;
+  this->texture = "maps/snow_flake_01_32x32.png";
+  this->snowLife = 8;
+  this->randomLife = 2;
+  this->snowRadius = 3.5;
+  this->randomRadius = 1;
+  this->snowMass = 1.0;
+  this->randomMass = 0.3;
+  this->rate = 900;
+  this->velocity = -100;
+  this->randomVelocity = 5;
+  this->angle = 0.5;
+  this->randomAngle = 0.2;
+  this->alpha = 0.5;
+  this->snowSize = Vector2D(2500, 2500);
+  this->snowCoord = Vector(100,450,400);
+  this->snowWindForce = 1;
+
+  this->fadeTime = 10;
+  this->cloudColor = Vector(0.2f, 0.2f, 0.2f);
+  this->skyColor = Vector(0.0f, 0.0f, 0.0f);
+}
+
+void SnowEffect::activate()
+{
+  PRINTF(3)("Activating SnowEffect\n");
+
+  this->snowActivate = true;
+
+  SnowEffect::snowParticles = new SpriteParticles(particles);
+  SnowEffect::snowParticles->setName("SnowEffectTrailParticles");
+  SnowEffect::snowParticles->setMaterialTexture(texture);
+  SnowEffect::snowParticles->setLifeSpan(snowLife, randomLife);
+  SnowEffect::snowParticles->setRadius(0.0, snowRadius, randomRadius);
+  SnowEffect::snowParticles->setRadius(0.2, snowRadius, randomRadius*0.8);
+  SnowEffect::snowParticles->setRadius(1.0, snowRadius, randomRadius*0.5);
+  SnowEffect::snowParticles->setMass(0, snowMass, randomMass);
+  SnowEffect::snowParticles->setColor(0,1, 1, 1, alpha);
+  SnowEffect::snowParticles->setColor(.5, .6, .6, .6, alpha/2);
+  SnowEffect::snowParticles->setColor(1, .0, .0, .0, .0);
+
+  this->emitter->setSystem(SnowEffect::snowParticles);
+
+  this->emitter->setRelCoor(snowCoord);
+  this->emitter->setEmissionRate(rate);
+  this->emitter->setEmissionVelocity(velocity, randomVelocity);
+  this->emitter->setSpread(angle * this->snowWindForce , randomAngle * this->snowWindForce);
+  this->emitter->setSize(snowSize);
+
+  if (this->snowWindForce != 0)
+    this->soundSource.play(this->windBuffer, 0.1f * this->snowWindForce, true);
+
+  // Store cloud- and sky color before the snow
+  this->oldCloudColor = CloudEffect::cloudColor;
+  this->oldSkyColor   = CloudEffect::skyColor;
+
+  // Change the colors
+  CloudEffect::changeCloudColor(this->cloudColor, this->fadeTime);
+  CloudEffect::changeSkyColor(this->skyColor, this->fadeTime);
+
+}
+
+
+void SnowEffect::deactivate()
+{
+  PRINTF(3)("Deactivating SnowEffect\n");
+
+  this->snowActivate = false;
+  this->emitter->setSystem(NULL);
+
+  // Restore the old cloud- and sky color
+  CloudEffect::changeCloudColor(this->oldCloudColor, this->fadeTime);
+  CloudEffect::changeSkyColor(this->oldSkyColor, this->fadeTime);
+}
+
+void SnowEffect::draw() const
+{
+  if (!this->snowActivate)
+    return;
+}
+
+void SnowEffect::tick(float dt)
+{
+  if (!this->snowActivate)
+    return;
+
+  /*
+  float distance = (State::getCameraNode()->getAbsCoor() - Vector(snowCoord.x, State::getCameraNode()->getAbsCoor().y, snowCoord.z)).len();
+
+  if(activated)
+  {
+  if(distance > 0.3*snowSize.x || distance > 0.3*snowSize.y)
+                  this->deactivate();
+  else if(distance > 0.25*snowSize.x || distance > 0.25*snowSize.y)
+  this->alpha = 0.15;
+  else if(distance > 0.2*snowSize.x || distance > 0.2*snowSize.y)
+  this->alpha = 0.25;
+  else if(distance > 0.1*snowSize.x || distance > 0.1*snowSize.y)
+  this->alpha = 0.4;
+
+  SnowEffect::snowParticles->setColor(0,1, 1, 1, alpha);
+  SnowEffect::snowParticles->setColor(.5, .6, .6, .6, alpha/2);
+  SnowEffect::snowParticles->setColor(1, .0, .0, .0, .0);
+  }
+  else
+  {
+  if(distance < 0.3*snowSize.x || distance < 0.3*snowSize.y )
+  this->activate();
+  if( distance < 0.25*snowSize.x || distance < 0.25*snowSize.y )
+  this->alpha = 0.25;
+  else if( distance < 0.2*snowSize.x || distance < 0.2*snowSize.y )
+  this->alpha = 0.4;
+  else if( distance < 0.1*snowSize.x || distance < 0.1*snowSize.y )
+  this->alpha = 0.5;
+
+  SnowEffect::snowParticles->setColor(0,1, 1, 1, alpha);
+  SnowEffect::snowParticles->setColor(.5, .6, .6, .6, alpha/2);
+  SnowEffect::snowParticles->setColor(1, .0, .0, .0, .0);
+  }*/
+
+  if (this->snowMove)
+  {
+    this->snowCoord = State::getCameraNode()->getAbsCoor();
+    this->emitter->setRelCoor(this->snowCoord.x , this->snowCoord.y+300, this->snowCoord.z);
+  }
+}
Index: branches/heathaze/src/world_entities/weather_effects/snow_effect.h
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/snow_effect.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/snow_effect.h	(revision 9940)
@@ -0,0 +1,148 @@
+/**
+* @file snow_effect.h
+*/
+
+#ifndef _SNOW_EFFECT
+#define _SNOW_EFFECT
+
+#include "vector.h"
+#include "particles/particle_system.h"
+#include "material.h"
+#include "vector2D.h"
+
+#include "weather_effect.h"
+
+class SpriteParticles;
+class PlaneEmitter;
+class PNode;
+class CloudEffect;
+
+#include "sound_source.h"
+#include "sound_buffer.h"
+
+class SnowEffect : public WeatherEffect
+{
+  ObjectListDeclaration(SnowEffect);
+public:
+  SnowEffect(const TiXmlElement* root = NULL);
+  virtual ~SnowEffect();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void init();
+
+  virtual void activate();
+  virtual void deactivate();
+
+  inline void activateSnow()
+  {
+    this->activate();
+  }
+  inline void deactivateSnow()
+  {
+    this->deactivate();
+  }
+
+  virtual void draw() const;
+  virtual void tick(float dt);
+
+
+  inline void numParticles(int n)
+  {
+    this->particles = n;
+  }
+  inline void materialTexture(const std::string& texture)
+  {
+    this->texture = texture;
+  }
+  inline void lifeSpan(float lifeSpan, float randomLifeSpan)
+  {
+    this->snowLife = lifeSpan;
+    this->randomLife = randomLifeSpan;
+  }
+  inline void radius(float radius, float randomRadius)
+  {
+    this->snowRadius = radius;
+    this->randomRadius = randomRadius;
+  }
+  inline void mass(float mass, float randomMass)
+  {
+    this->snowMass = mass;
+    this->randomMass = randomMass;
+  }
+  inline void emissionRate(float emissionRate)
+  {
+    this->rate = emissionRate;
+  }
+  inline void emissionVelocity(float velocity, float randomVelocity)
+  {
+    this->velocity = velocity;
+    this->randomVelocity = randomVelocity;
+  }
+  inline void size(float sizeX, float sizeY)
+  {
+    this->snowSize = Vector2D(sizeX, sizeY);
+  }
+  inline void coord(float x, float y, float z)
+  {
+    this->snowCoord = Vector(x, y, z);
+  }
+  inline void wind(int force)
+  {
+    this->snowWindForce = force;
+  }
+  inline void setCloudColor(float colorX, float colorY, float colorZ)
+  {
+    this->cloudColor = Vector(colorX, colorY, colorZ);
+  }
+  inline void setSkyColor(float colorX, float colorY, float colorZ)
+  {
+    this->skyColor = Vector(colorX, colorY, colorZ);
+  }
+  inline void setFadeTime(float time)
+  {
+    this->fadeTime = time;
+  }
+
+  inline void setSnowOption(const std::string& option)
+  {
+    /*if (option == "fade") this->snowFade = true;*/
+    if (option == "movesnow")
+      this->snowMove = true;
+    if (option == "activate")
+      this->snowActivate = true;
+  }
+
+
+private:
+  int               particles;
+  std::string       texture;
+  float             snowLife, randomLife;
+  float             snowRadius, randomRadius;
+  float             snowMass, randomMass;
+  float             rate;
+  float             velocity, randomVelocity;
+  float             angle, randomAngle;
+  float             alpha;
+  float             fadeTime;
+  Vector            snowCoord;
+  Vector2D          snowSize;
+  int               snowWindForce;
+
+  bool              snowMove;
+  bool              snowActivate;
+
+  PlaneEmitter*     emitter;
+
+  static SpriteParticles*   snowParticles;
+  OrxSound::SoundSource     soundSource;
+  OrxSound::SoundBuffer     windBuffer;
+
+  Vector            oldSkyColor;
+  Vector            oldCloudColor;
+  Vector            skyColor;
+  Vector            cloudColor;
+};
+
+
+#endif  /* _SNOW_EFFECT */
Index: branches/heathaze/src/world_entities/weather_effects/sun_effect.cc
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/sun_effect.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/sun_effect.cc	(revision 9940)
@@ -0,0 +1,76 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: hdavid, amaechler
+*/
+
+
+#include "sun_effect.h"
+
+#include "util/loading/load_param.h"
+
+
+
+
+
+
+/**
+ * @param root The XML-element to load the SunEffect from
+ */
+SunEffect::SunEffect(const TiXmlElement* root)
+{
+//  this->setClassID(CL_SUN_EFFECT, "SunEffect");
+  this->bActivated = false;
+}
+
+
+/**
+ *  destroys a SunEffect
+ */
+SunEffect::~SunEffect()
+{
+
+}
+
+
+/**
+ * @param root The XML-element to load the SunEffect from
+ */
+void SunEffect::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+}
+
+
+/**
+ *  initializes the graphics effect
+ */
+void SunEffect::init()
+{}
+
+
+
+/**
+ * draws the effect, if needed
+ */
+void SunEffect::draw() const
+{}
+
+
+
+/**
+ * ticks the effect if there is any time dependancy
+ */
+void SunEffect::tick(float dt)
+{}
+
Index: branches/heathaze/src/world_entities/weather_effects/sun_effect.h
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/sun_effect.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/sun_effect.h	(revision 9940)
@@ -0,0 +1,37 @@
+/*!
+ * @file sun_effect.h
+ *
+ */
+
+#ifndef _SUN_EFFECT_H
+#define _SUN_EFFECT_H
+
+#include "base_object.h"
+
+
+class TiXmlElement;
+
+class SunEffect : public BaseObject
+{
+  public:
+    SunEffect(const TiXmlElement* root = NULL);
+    virtual ~SunEffect();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void init();
+
+    virtual void activate() = 0;
+    virtual void deactivate() = 0;
+
+    virtual void draw() const;
+    virtual void tick(float dt);
+
+    inline bool isActivated() const { return this->bActivated; }
+
+  protected:
+    bool              bActivated;
+};
+
+
+#endif /* _SUN_EFFECT */
Index: branches/heathaze/src/world_entities/weather_effects/volfog_effect.cc
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/volfog_effect.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/volfog_effect.cc	(revision 9940)
@@ -0,0 +1,198 @@
+/*
+  orxonox - the future of 3D-vertical-scrollers
+
+  Copyright (C) 2004 orx
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2, or (at your option)
+  any later version.
+
+### File Specific:
+  main-programmer: hdavid, amaechler
+*/
+
+#include "volfog_effect.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "p_node.h"
+#include "state.h"
+
+#include "glincl.h"
+//#include "shell_command.h"
+#include "debug.h"
+
+
+#define GLX_GLXEXT_PROTOTYPES
+//#include <GL/glx.h>
+// #include <GL/glut.h>
+
+//#include <GL/glext.h> //OpenGL Extensions
+//#include <GL/glxext.h> // GLX Extensions
+
+#ifndef GL_EXT_fog_coord
+#define GL_EXT_fog_coord 1
+typedef void (APIENTRY * PFNGLFOGCOORDFEXTPROC) (GLfloat coord);
+typedef void (APIENTRY * PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord);
+typedef void (APIENTRY * PFNGLFOGCOORDDEXTPROC) (GLdouble coord);
+typedef void (APIENTRY * PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord);
+typedef void (APIENTRY * PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+PFNGLFOGCOORDFEXTPROC glFogCoordfEXT = 0;
+PFNGLFOGCOORDFVEXTPROC glFogCoordfvEXT = 0;
+PFNGLFOGCOORDDEXTPROC glFogCoorddEXT = 0;
+PFNGLFOGCOORDDVEXTPROC glFogCoorddvEXT = 0;
+PFNGLFOGCOORDPOINTEREXTPROC glFogCoordPointerEXT = 0;
+
+
+#include "class_id_DEPRECATED.h"
+ObjectListDefinitionID(VolFogEffect, CL_VOLFOG_EFFECT);
+CREATE_FACTORY(VolFogEffect);
+
+VolFogEffect::VolFogEffect(const TiXmlElement* root) {
+  this->registerObject(this, VolFogEffect::_objectList);
+
+    if (root != NULL)
+        this->loadParams(root);
+
+    // Initialize Effect
+    this->init();
+
+    // Activate Effect
+    this->activate();
+}
+
+
+VolFogEffect::~VolFogEffect() {
+    this->deactivate();
+}
+
+void VolFogEffect::loadParams(const TiXmlElement* root) {
+    WeatherEffect::loadParams(root);
+}
+
+void VolFogEffect::init() {
+    PRINTF(3)("Initalize VolFogEffect\n");
+
+    // set fog mode
+    GLenum fogMode  = GL_EXP;
+
+    // set fog density
+    float  fogDensity  = 0.001f;
+
+    // set fog near & far distance
+    float fogStart = 0.0f;
+    float fogEnd   = 1000.0f;
+
+    // Set fog color
+    float fogColor[4] = {0.6f,0.58f,0.79f,0.0f};
+
+
+    /*    glFogCoordfEXT       = (PFNGLFOGCOORDFEXTPROC)glXGetProcAddressARB((const GLubyte*)"glFogCoordfEXT");
+    glFogCoordfvEXT      = (PFNGLFOGCOORDFVEXTPROC)glXGetProcAddressARB((const GLubyte*)"glFogCoordfvEXT");
+    glFogCoorddEXT       = (PFNGLFOGCOORDDEXTPROC)glXGetProcAddressARB((const GLubyte*)"glFogCoorddEXT");
+    glFogCoorddvEXT      = (PFNGLFOGCOORDDVEXTPROC)glXGetProcAddressARB((const GLubyte*)"glFogCoorddvEXT");
+    glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC)glXGetProcAddressARB((const GLubyte*)"glFogCoordPointerEXT");
+    */
+    // set the fog attributes
+    glFogf (GL_FOG_START,  fogStart);
+    glFogf (GL_FOG_END,    fogEnd);
+    glFogfv(GL_FOG_COLOR,  fogColor);
+    glFogi (GL_FOG_MODE,   fogMode);
+    glFogf (GL_FOG_DENSITY,fogDensity);
+    glFogi (GL_FOG_COORDINATE_SOURCE_EXT,GL_FOG_COORDINATE_EXT);
+
+    // enable the fog
+    glEnable(GL_FOG);
+
+    if (glewInit() == GLEW_OK)
+        PRINTF(4)("glewInit OK\n");
+    else
+        PRINTF(4)("glewInit failed\n");
+
+    if (glewGetExtension("GL_EXT_fog_coord"))
+        PRINTF(4)("GL_EXT_fog_coord extension found\n");
+}
+
+
+void VolFogEffect::activate() {
+    PRINTF(3)("Activating VolFogEffect\n");
+}
+
+void VolFogEffect::deactivate() {
+    PRINTF(3)("Deactivating VolFogEffect\n");
+
+    glDisable(GL_FOG);
+}
+
+
+/**
+* draws the effect, if needed
+*/
+void VolFogEffect::draw() const {
+    glPushAttrib(GL_ENABLE_BIT);
+    glClearColor(fogColor[0],fogColor[1],fogColor[2],0.0f);
+    glShadeModel(GL_SMOOTH);
+    glEnable(GL_DEPTH_TEST);
+    glEnable(GL_CULL_FACE);
+    glCullFace(GL_BACK);
+
+    /* clear all pixels in colour buffer */
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    /* Enable blending */
+    //glEnable(GL_BLEND);
+    //glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
+
+    int i;
+    glLoadIdentity();
+
+
+    glBegin( GL_LINES );
+    glNormal3f(0,1,0);
+    for(i=-20;i<=20;i+=2) {
+        float fog_c;
+        float diff[3];
+
+        diff[0] = State::getCameraNode()->getAbsCoor().x - i;
+        diff[2] = State::getCameraNode()->getAbsCoor().z + 20;
+        diff[1] = State::getCameraNode()->getAbsCoor().y;
+        fog_c = 1.3f*sqrt(diff[0]*diff[0]+diff[1]*diff[1]+diff[2]*diff[2]);
+        glFogCoordfEXT(fog_c*2);
+        glVertex3f(i,0,-20);
+
+        diff[0] = State::getCameraNode()->getAbsCoor().x - i;
+        diff[2] = State::getCameraNode()->getAbsCoor().z + 20;
+        diff[1] = State::getCameraNode()->getAbsCoor().y;
+        fog_c = 1.3f*sqrt(diff[0]*diff[0]+diff[1]*diff[1]+diff[2]*diff[2]);
+        glFogCoordfEXT(fog_c*2);
+        glVertex3f(i,0,20);
+
+        diff[0] = State::getCameraNode()->getAbsCoor().x - i;
+        diff[2] = State::getCameraNode()->getAbsCoor().z + 20;
+        diff[1] = State::getCameraNode()->getAbsCoor().y;
+        fog_c = 1.3f*sqrt(diff[0]*diff[0]+diff[1]*diff[1]+diff[2]*diff[2]);
+        glFogCoordfEXT(fog_c*2);
+        glVertex3f(-20,0,i);
+
+        diff[0] = State::getCameraNode()->getAbsCoor().x - i;
+        diff[2] = State::getCameraNode()->getAbsCoor().z + 20;
+        diff[1] = State::getCameraNode()->getAbsCoor().y;
+        fog_c = 1.3f*sqrt(diff[0]*diff[0]+diff[1]*diff[1]+diff[2]*diff[2]);
+        glFogCoordfEXT(fog_c*2);
+        glVertex3f(20,0,i);
+    }
+    glEnd();
+
+    glPopAttrib();
+
+}
+
+
+/**
+* ticks the effect if there is any time dependancy
+*/
+void VolFogEffect::tick(float dt) {}
Index: branches/heathaze/src/world_entities/weather_effects/volfog_effect.h
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/volfog_effect.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/volfog_effect.h	(revision 9940)
@@ -0,0 +1,35 @@
+/**
+* @file volfog_effect.h
+*/
+
+#ifndef _VOLFOG_EFFECT
+#define _VOLFOG_EFFECT
+
+#include "vector.h"
+
+#include "weather_effect.h"
+#include "glincl.h"
+
+class VolFogEffect : public WeatherEffect
+{
+  ObjectListDeclaration(VolFogEffect);
+public:
+  VolFogEffect(const TiXmlElement* root = NULL);
+  virtual ~VolFogEffect();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void init();
+
+  virtual void activate();
+  virtual void deactivate();
+
+  virtual void draw() const;
+  virtual void tick(float dt);
+
+private:
+  GLfloat fogColor[4];
+
+};
+
+#endif  /* _VOLFOG_EFFECT */
Index: branches/heathaze/src/world_entities/weather_effects/weather_effect.cc
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/weather_effect.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/weather_effect.cc	(revision 9940)
@@ -0,0 +1,74 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: hdavid, amaechler
+*/
+
+// TODO: descriptions to loadparams, movealong unified, start activation
+
+#include "weather_effect.h"
+#include "util/loading/load_param.h"
+
+ObjectListDefinition(WeatherEffect);
+
+/**
+ * @param root The XML-element to load the WeatherEffect from
+ */
+WeatherEffect::WeatherEffect(const TiXmlElement* root)
+{
+  this->registerObject(this, WeatherEffect::_objectList);
+  this->bActivated = false;
+}
+
+
+/**
+ *  destroys a WeatherEffects
+ */
+WeatherEffect::~WeatherEffect()
+{
+
+}
+
+
+/**
+ * @param root The XML-element to load the WeatherEffects from
+ */
+void WeatherEffect::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+}
+
+
+/**
+ *  initializes the graphics effect
+ */
+void WeatherEffect::init()
+{
+}
+
+
+
+/**
+ * draws the effect, if needed
+ */
+void WeatherEffect::draw() const
+{}
+
+
+
+/**
+ * ticks the effect if there is any time dependancy
+ */
+void WeatherEffect::tick(float dt)
+{}
+
Index: branches/heathaze/src/world_entities/weather_effects/weather_effect.h
===================================================================
--- branches/heathaze/src/world_entities/weather_effects/weather_effect.h	(revision 9940)
+++ branches/heathaze/src/world_entities/weather_effects/weather_effect.h	(revision 9940)
@@ -0,0 +1,38 @@
+/*!
+ * @file weather_effect.h
+ *
+ */
+
+#ifndef _WEATHER_EFFECT_H
+#define _WEATHER_EFFECT_H
+
+#include "base_object.h"
+
+
+class WeatherEffect : public BaseObject
+{
+  ObjectListDeclaration(WeatherEffect);
+
+  public:
+    WeatherEffect(const TiXmlElement* root = NULL);
+    virtual ~WeatherEffect();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void init();
+
+    virtual void activate() = 0;
+    virtual void deactivate() = 0;
+
+    virtual void draw() const;
+    virtual void tick(float dt);
+
+    inline  bool isActivated() const { return this->bActivated; }
+
+
+  protected:
+    bool              bActivated;
+};
+
+
+#endif /* _WEATHER_EFFECT */
Index: branches/heathaze/src/world_entities/world_entity.cc
===================================================================
--- branches/heathaze/src/world_entities/world_entity.cc	(revision 9940)
+++ branches/heathaze/src/world_entities/world_entity.cc	(revision 9940)
@@ -0,0 +1,879 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Christian Meyer
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "world_entity.h"
+#include "shell_command.h"
+
+#include "util/loading/resource_manager.h"
+#include "resource_obj.h"
+#include "md2/md2Model.h"
+#include "md3/md3_model.h"
+
+#include "aabb_tree_node.h"
+
+#include "util/loading/load_param.h"
+#include "obb_tree.h"
+
+#include "elements/glgui_energywidget.h"
+
+#include "state.h"
+#include "camera.h"
+
+#include "collision_handle.h"
+#include "collision_event.h"
+#include "game_rules.h"
+#include "kill.h"
+#include "debug.h"
+
+#include "projectiles/projectile.h"
+
+SHELL_COMMAND(model, WorldEntity, loadModel)
+->describe("sets the Model of the WorldEntity")
+->defaultValues("models/ships/fighter.obj", 1.0f);
+
+SHELL_COMMAND(debugEntity, WorldEntity, debugWE);
+
+
+ObjectListDefinition(WorldEntity);
+/**
+ *  Loads the WordEntity-specific Part of any derived Class
+ *
+ * @param root: Normally NULL, as the Derived Entities define a loadParams Function themeselves,
+ *              that can calls WorldEntities loadParams for itself.
+ */
+WorldEntity::WorldEntity()
+    : Synchronizeable()
+{
+  this->registerObject(this, WorldEntity::_objectList);
+
+  this->obbTree = NULL;
+  this->aabbNode = NULL;
+  this->healthWidget = NULL;
+  this->healthMax = 1.0f;
+  this->health = 1.0f;
+  this->damage = 0.0f; // no damage dealt by a default entity
+  this->scaling = 1.0f;
+
+  /* OSOLETE */
+  this->bVisible = true;
+  this->bCollide = true;
+
+  this->objectListNumber = OM_INIT;
+  this->lastObjectListNumber = OM_INIT;
+
+  // reset all collision handles to NULL == unsubscribed state
+  for(int i = 0; i < CREngine::CR_NUMBER; ++i)
+    this->collisionHandles[i] = NULL;
+  this->bReactive = false;
+  this->bOnGround = false;
+
+  // registering default reactions:
+  this->subscribeReaction(CREngine::CR_OBJECT_DAMAGE, /* WorldEntity::staticClassID(), */ Projectile::staticClassID());
+
+  this->toList(OM_NULL);
+
+  registerVar( new SynchronizeableString( &this->md2TextureFileName, &this->md2TextureFileName, "md2TextureFileName", PERMISSION_MASTER_SERVER ) );
+  modelFileName_handle = registerVarId( new SynchronizeableString( &modelFileName, &modelFileName, "modelFileName", PERMISSION_MASTER_SERVER ) );
+  scaling_handle = registerVarId( new SynchronizeableFloat( &scaling, &scaling, "scaling", PERMISSION_MASTER_SERVER ) );
+  list_handle = registerVarId( new SynchronizeableInt( (int*)&objectListNumber, &list_write, "list", PERMISSION_MASTER_SERVER ) );
+
+  health_handle = registerVarId( new SynchronizeableFloat( &this->health, &this->health_write, "health", PERMISSION_MASTER_SERVER ) );
+  healthMax_handle = registerVarId( new SynchronizeableFloat( &this->healthMax, &this->healthMax_write, "maxHealth", PERMISSION_MASTER_SERVER ) );
+}
+
+/**
+ *  standard destructor
+*/
+WorldEntity::~WorldEntity ()
+{
+  State::getObjectManager()->toList(this, OM_INIT);
+
+  // Delete the model (unregister it with the ResourceManager)
+  for (unsigned int i = 0; i < this->models.size(); i++)
+    this->setModel(NULL, i);
+
+  // Delete the obbTree
+  if( this->obbTree != NULL)
+    delete this->obbTree;
+
+  if (this->healthWidget != NULL)
+    delete this->healthWidget;
+
+  this->unsubscribeReaction();
+}
+
+/**
+ * loads the WorldEntity Specific Parameters.
+ * @param root: the XML-Element to load the Data From
+ */
+void WorldEntity::loadParams(const TiXmlElement* root)
+{
+  // Do the PNode loading stuff
+  PNode::loadParams(root);
+
+  LoadParam(root, "md2texture", this, WorldEntity, loadMD2Texture)
+  .describe("the fileName of the texture, that should be loaded onto this world-entity. (must be relative to the data-dir)")
+  .defaultValues("");
+
+  // Model Loading
+  LoadParam(root, "model", this, WorldEntity, loadModel)
+  .describe("the fileName of the model, that should be loaded onto this world-entity. (must be relative to the data-dir)")
+  .defaultValues("", 1.0f, 0);
+
+  LoadParam(root, "maxHealth", this, WorldEntity, setHealthMax)
+  .describe("The Maximum health that can be loaded onto this entity")
+  .defaultValues(1.0f);
+
+  LoadParam(root, "health", this, WorldEntity, setHealth)
+  .describe("The Health the WorldEntity has at this moment")
+  .defaultValues(1.0f);
+
+  LoadParam(root, "list", this, WorldEntity, toListS);
+}
+
+
+/**
+ * loads a Model onto a WorldEntity
+ * @param fileName the name of the model to load
+ * @param scaling the Scaling of the model
+ *
+ * FIXME
+ * @todo: separate the obb tree generation from the model
+ */
+void WorldEntity::loadModel(const std::string& fileName, float scaling, unsigned int modelNumber, unsigned int obbTreeDepth)
+{
+  this->modelLODName = fileName;
+  this->scaling = scaling;
+
+  std::string name = fileName;
+
+  if (  name.find( Resources::ResourceManager::getInstance()->mainGlobalPath().name() ) == 0 )
+  {
+    name.erase(Resources::ResourceManager::getInstance()->mainGlobalPath().name().size());
+  }
+
+  this->modelFileName = name;
+
+  if (!fileName.empty())
+  {
+    // search for the special character # in the LoadParam
+    if (fileName.find('#') != std::string::npos)
+    {
+      PRINTF(4)("Found # in %s... searching for LOD's\n", fileName.c_str());
+      std::string lodFile = fileName;
+      unsigned int offset = lodFile.find('#');
+      for (unsigned int i = 0; i < 3; i++)
+      {
+        lodFile[offset] = 48+(int)i;
+        if (Resources::ResourceManager::getInstance()->checkFileInMainPath( lodFile))
+          this->loadModel(lodFile, scaling, i);
+      }
+      return;
+    }
+    if (this->scaling <= 0.0)
+    {
+      PRINTF(1)("YOU GAVE ME A CRAPY SCALE resetting to 1.0\n");
+      this->scaling = 1.0;
+    }
+    /// LOADING AN OBJ FILE
+    if(fileName.find(".obj") != std::string::npos)
+    {
+      PRINTF(4)("fetching OBJ file: %s\n", fileName.c_str());
+      StaticModel* model = new StaticModel();
+      *model = ResourceOBJ(fileName, this->scaling);
+      if (model->getVertexCount() > 0)
+      {
+        this->setModel(model, modelNumber);
+	if( modelNumber == 0 /* FIXME && !this->isA(CL_WEAPON) */)
+	  this->buildObbTree(obbTreeDepth);
+      }
+      else
+        delete model;
+    }
+    /// LOADING AN MD2-model
+    else if(fileName.find(".md2") != std::string::npos)
+    {
+      PRINTF(4)("fetching MD2 file: %s\n", fileName.c_str());
+      Model* m = new MD2Model(fileName, this->md2TextureFileName, this->scaling);
+      //this->setModel((Model*)ResourceManager::getInstance()->load(fileName, MD2, RP_CAMPAIGN), 0);
+      this->setModel(m, 0);
+
+      if( m != NULL)
+        this->buildObbTree(obbTreeDepth);
+    }
+    /// LOADING AN MD3-MODEL.
+    else if(fileName.find(".md3") != std::string::npos)
+    {
+      PRINTF(4)("fetching MD3 file: %s\n", fileName.c_str());
+//      Model* m = new md3::MD3Model(fileName, this->scaling);
+//      this->setModel(m, 0);
+
+      //       if( m != NULL)
+      //         this->buildObbTree(obbTreeDepth);
+    }
+  }
+  else
+  {
+    this->setModel(NULL);
+  }
+}
+
+/**
+ * sets a specific Model for the Object.
+ * @param model The Model to set
+ * @param modelNumber the n'th model in the List to get.
+ */
+void WorldEntity::setModel(Model* model, unsigned int modelNumber)
+{
+  if (this->models.size() <= modelNumber)
+    this->models.resize(modelNumber+1, NULL);
+
+  if (this->models[modelNumber] != NULL)
+  {
+    delete this->models[modelNumber];
+  }
+
+  this->models[modelNumber] = model;
+}
+
+
+/**
+ * builds the obb-tree
+ * @param depth the depth to calculate
+ */
+bool WorldEntity::buildObbTree(int depth)
+{
+  if( this->obbTree != NULL)
+  {
+    delete this->obbTree;
+    this->obbTree = NULL;
+  }
+
+  if (this->models[0] != NULL)
+    this->obbTree = new OBBTree(depth, models[0]->getModelInfo(), this);
+  else
+  {
+    PRINTF(1)("could not create obb-tree, because no model was loaded yet\n");
+    this->obbTree = NULL;
+    return false;
+  }
+
+
+  // create the axis aligned bounding box
+  if( this->aabbNode != NULL)
+  {
+    delete this->aabbNode;
+    this->aabbNode = NULL;
+  }
+
+  if( this->models[0] != NULL)
+  {
+    this->aabbNode = new AABBTreeNode();
+    this->aabbNode->spawnBVTree(this->models[0]);
+  }
+  else
+  {
+    PRINTF(1)("could not create aabb bounding box, because no model was loaded yet\n");
+    this->aabbNode = NULL;
+    return false;
+  }
+  return true;
+}
+
+
+/**
+ * subscribes this world entity to a collision reaction
+ *  @param type the type of reaction to subscribe to
+ *  @param target1 a filter target (classID)
+ */
+void WorldEntity::subscribeReaction(CREngine::CRType type, const ClassID& target1)
+{
+  this->subscribeReaction(type);
+
+  // add the target filter
+  this->collisionHandles[type]->addTarget(target1);
+}
+
+
+/**
+ * subscribes this world entity to a collision reaction
+ *  @param type the type of reaction to subscribe to
+ *  @param target1 a filter target (classID)
+ */
+void WorldEntity::subscribeReaction(CREngine::CRType type, const ClassID& target1, const ClassID& target2)
+{
+  this->subscribeReaction(type);
+
+  // add the target filter
+  this->collisionHandles[type]->addTarget(target1);
+  this->collisionHandles[type]->addTarget(target2);
+}
+
+
+/**
+ * subscribes this world entity to a collision reaction
+ *  @param type the type of reaction to subscribe to
+ *  @param target1 a filter target (classID)
+ */
+void WorldEntity::subscribeReaction(CREngine::CRType type, const ClassID& target1, const ClassID& target2, const ClassID& target3)
+{
+  this->subscribeReaction(type);
+
+  // add the target filter
+  this->collisionHandles[type]->addTarget(target1);
+  this->collisionHandles[type]->addTarget(target2);
+  this->collisionHandles[type]->addTarget(target3);
+}
+
+
+/**
+ * subscribes this world entity to a collision reaction
+ *  @param type the type of reaction to subscribe to
+ *  @param target1 a filter target (classID)
+ */
+void WorldEntity::subscribeReaction(CREngine::CRType type, const ClassID& target1, const ClassID& target2, const ClassID& target3, const ClassID& target4)
+{
+  this->subscribeReaction(type);
+
+  // add the target filter
+  this->collisionHandles[type]->addTarget(target1);
+  this->collisionHandles[type]->addTarget(target2);
+  this->collisionHandles[type]->addTarget(target3);
+  this->collisionHandles[type]->addTarget(target4);
+}
+
+
+/**
+ * subscribes this world entity to a collision reaction
+ *  @param type the type of reaction to subscribe to
+ *  @param nrOfTargets number of target filters
+ *  @param ... the targets as classIDs
+ */
+void WorldEntity::subscribeReaction(CREngine::CRType type)
+{
+  if( this->collisionHandles[type] != NULL)
+  {
+    PRINTF(2)("Registering for a CollisionReaction already subscribed to! Skipping\n");
+    return;
+  }
+
+  this->collisionHandles[type] = CREngine::getInstance()->subscribeReaction(this, type);
+
+  // now there is at least one collision reaction subscribed
+  this->bReactive = true;
+}
+
+
+/**
+ * unsubscribes a specific reaction from the worldentity
+ *  @param type the reaction to unsubscribe
+ */
+void WorldEntity::unsubscribeReaction(CREngine::CRType type)
+{
+  if( this->collisionHandles[type] == NULL)
+    return;
+
+  CREngine::getInstance()->unsubscribeReaction(this->collisionHandles[type]);
+  this->collisionHandles[type] = NULL;
+
+  // check if there is still any handler registered
+  for(int i = 0; i < CREngine::CR_NUMBER; ++i)
+  {
+    if( this->collisionHandles[i] != NULL)
+    {
+      this->bReactive = true;
+      return;
+    }
+  }
+  this->bReactive = false;
+}
+
+
+/**
+ * unsubscribes all collision reactions
+ */
+void WorldEntity::unsubscribeReaction()
+{
+  for( int i = 0; i < CREngine::CR_NUMBER; i++)
+    this->unsubscribeReaction((CREngine::CRType)i);
+
+  // there are no reactions subscribed from now on
+  this->bReactive = false;
+}
+
+
+/**
+ * registers a new collision event to this world entity
+ *  @param entityA entity of the collision
+ *  @param entityB entity of the collision
+ *  @param bvA colliding bounding volume of entityA
+ *  @param bvB colliding bounding volume of entityA
+ */
+bool WorldEntity::registerCollision(WorldEntity* entityA, WorldEntity* entityB, BoundingVolume* bvA, BoundingVolume* bvB)
+{
+  PRINTF(5)("registering collision of type: %s vs %s\n", entityA->getClassCName(), entityB->getClassCName());
+  // is there any handler listening?
+  if( !this->bReactive)
+    return false;
+
+  // get a collision event
+  CollisionEvent* c = CREngine::getInstance()->popCollisionEventObject();
+  assert(c != NULL); // if this should fail: we got not enough precached CollisionEvents: alter value in cr_defs.h
+  c->collide(COLLISION_TYPE_OBB, entityA, entityB, bvA, bvB);
+
+  for( int i = 0; i < CREngine::CR_NUMBER; ++i)
+    if( this->collisionHandles[i] != NULL)
+      this->collisionHandles[i]->registerCollisionEvent(c);
+  return true;
+}
+
+
+/**
+ * registers a new collision event to this woeld entity
+ *  @param entity the entity that collides
+ *  @param plane it stands on
+ *  @param position it collides on the plane
+ */
+bool WorldEntity::registerCollision(int type, WorldEntity* entity, WorldEntity* groundEntity, Vector normal, Vector position, bool bInWall)
+{
+  // is there any handler listening?
+  if( !this->bReactive)
+    return false;
+
+  // get a collision event
+  CollisionEvent* c = CREngine::getInstance()->popCollisionEventObject();
+  assert(c != NULL); // if this should fail: we got not enough precached CollisionEvents: alter value in cr_defs.h
+  c->collide(type, entity, groundEntity, normal, position, bInWall);
+
+  for( int i = 0; i < CREngine::CR_NUMBER; ++i)
+    if( this->collisionHandles[i] != NULL)
+      this->collisionHandles[i]->registerCollisionEvent(c);
+  return true;
+}
+
+
+/**
+ * @brief moves this entity to the List OM_List
+ * @param list the list to set this Entity to.
+ *
+ * this is the same as a call to State::getObjectManager()->toList(entity , list);
+ * directly, but with an easier interface.
+ *
+ * @todo inline this (peut etre)
+ */
+void WorldEntity::toList(OM_LIST list)
+{
+  State::getObjectManager()->toList(this, list);
+}
+
+void WorldEntity::toListS(const std::string& listName)
+{
+  OM_LIST id = ObjectManager::StringToOMList(listName);
+  if (id != OM_NULL)
+    this->toList(id);
+  else
+    PRINTF(2)("List %s not found\n", listName.c_str());
+}
+
+
+void WorldEntity::toReflectionList()
+{
+  State::getObjectManager()->toReflectionList( this );
+}
+
+void removeFromReflectionList()
+{
+  /// TODO
+  ///  State::getObject
+}
+
+/**
+ * sets the character attributes of a worldentity
+ * @param character attributes
+ *
+ * these attributes don't have to be set, only use them, if you need them
+*/
+//void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr)
+//{}
+
+
+/**
+ *  this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void WorldEntity::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  /**
+   * THIS IS A DEFAULT COLLISION-Effect.
+   * IF YOU WANT TO CREATE A SPECIFIC COLLISION ON EACH OBJECT
+   * USE::
+   * if (entity->isA(CL_WHAT_YOU_ARE_LOOKING_FOR)) { printf "dothings"; };
+   *
+   * You can always define a default Action.... don't be affraid just test it :)
+   */
+  //  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassCName(), entity->getClassCName(), location.x, location.y, location.z);
+}
+
+
+/**
+ *  this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void WorldEntity::collidesWithGround(const Vector& location)
+{
+  PRINTF(0)("BSP_GROUND: %s collides \n", this->getClassCName() );
+}
+
+void WorldEntity::collidesWithGround(const Vector& feet, const Vector& ray_1, const Vector& ray_2)
+{
+
+  // PRINTF(0)("BSP_GROUND: Player collides \n", this->getClassCName() );
+
+  Vector v = this->getAbsDirX();
+  v.x *= 10.1;
+  v.y *= 10.1;
+  v.z *= 10.1;
+  Vector u = Vector(0.0,-20.0,0.0);
+
+
+  if(!(this->getAbsCoor().x == ray_2.x && this->getAbsCoor().y == ray_2.y && this->getAbsCoor().z == ray_2.z) )
+  {
+
+    this->setAbsCoor(ray_2 - v);
+
+  }
+  else
+  {
+    if(ray_1.x == this->getAbsCoor().x + v.x && ray_1.y == this->getAbsCoor().y + v.y + 0.1 && ray_1.z ==this->getAbsCoor().z + v.z)
+    {
+      this->setAbsCoor(feet -u );
+    }
+
+    this->setAbsCoor(ray_2 - v);
+
+  }
+
+
+}
+
+/**
+ *  this is called immediately after the Entity has been constructed, initialized and then Spawned into the World
+ *
+ */
+void WorldEntity::postSpawn ()
+{}
+
+
+/**
+ *  this method is called by the world if the WorldEntity leaves the game
+ */
+void WorldEntity::leaveWorld ()
+{}
+
+
+/**
+ * resets the WorldEntity to its initial values. eg. used for multiplayer games: respawning
+ */
+void WorldEntity::reset()
+{
+  this->setHealth( this->getHealthMax() );
+}
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+ *
+ * Handle all stuff that should update with time inside this method (movement, animation, etc.)
+*/
+void WorldEntity::tick(float time)
+{}
+
+
+/**
+ *  the entity is drawn onto the screen with this function
+ *
+ * This is a central function of an entity: call it to let the entity painted to the screen.
+ * Just override this function with whatever you want to be drawn.
+*/
+void WorldEntity::draw() const
+{
+  //PRINTF(0)("(%s::%s)\n", this->getClassCName(), this->getName());
+  //  assert(!unlikely(this->models.empty()));
+  {
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+
+    /* translate */
+    glTranslatef (this->getAbsCoor ().x,
+                  this->getAbsCoor ().y,
+                  this->getAbsCoor ().z);
+    Vector tmpRot = this->getAbsDir().getSpacialAxis();
+    glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+
+    // This Draws the LOD's
+    float cameraDistance = State::getCamera()->distance(this);
+    if (cameraDistance > 30 && this->models.size() >= 3 && this->models[2] != NULL)
+    {
+      this->models[2]->draw();
+    }
+    else if (cameraDistance > 10 && this->models.size() >= 2 && this->models[1] != NULL)
+    {
+      this->models[1]->draw();
+    }
+    else if (this->models.size() >= 1 && this->models[0] != NULL)
+    {
+      this->models[0]->draw();
+    }
+
+    //     if( this->aabbNode != NULL)
+    //       this->aabbNode->drawBV(0, DRAW_BV_POLYGON, Vector(1, 0.6, 0.2), true);
+
+    glPopMatrix();
+  }
+}
+
+/**
+ * @param health the Health to add.
+ * @returns the health left (this->healthMax - health+this->health)
+ */
+float WorldEntity::increaseHealth(float health)
+{
+  this->health += health;
+  if (this->health > this->healthMax)
+  {
+    float retHealth = this->healthMax - this->health;
+    this->health = this->healthMax;
+    this->updateHealthWidget();
+    return retHealth;
+  }
+  this->updateHealthWidget();
+  return 0.0;
+}
+
+/**
+ * @param health the Health to be removed
+ * @returns 0.0 or the rest, that was not substracted (bellow 0.0)
+ */
+float WorldEntity::decreaseHealth(float health)
+{
+  this->health -= health;
+
+  if (this->health < 0)
+  {
+    float retHealth = -this->health;
+    this->health = 0.0f;
+    this->updateHealthWidget();
+    return retHealth;
+  }
+  this->updateHealthWidget();
+  return 0.0;
+
+}
+
+/**
+ * @param maxHealth the maximal health that can be loaded onto the entity.
+ */
+void WorldEntity::setHealthMax(float healthMax)
+{
+  this->healthMax = healthMax;
+  if (this->health > this->healthMax)
+  {
+    PRINTF(3)("new maxHealth is bigger as the old health. Did you really intend to do this for (%s::%s)\n", this->getClassCName(), this->getCName());
+    this->health = this->healthMax;
+  }
+  this->updateHealthWidget();
+}
+
+/**
+ * @brief creates the HealthWidget
+ *
+ * since not all entities need an HealthWidget, it is only created on request.
+ */
+void WorldEntity::createHealthWidget()
+{
+  if (this->healthWidget == NULL)
+  {
+    this->healthWidget = new OrxGui::GLGuiEnergyWidget();
+    this->healthWidget->setDisplayedName(std::string(this->getClassName()) + " Energy:");
+    this->healthWidget->setSize2D(30,400);
+    this->healthWidget->setAbsCoor2D(10,100);
+
+    this->updateHealthWidget();
+  }
+  else
+    PRINTF(3)("Allready created the HealthWidget for %s::%s\n", this->getClassCName(), this->getCName());
+}
+
+void WorldEntity::increaseHealthMax(float increaseHealth)
+{
+  this->healthMax += increaseHealth;
+  this->updateHealthWidget();
+}
+
+
+OrxGui::GLGuiWidget* WorldEntity::getHealthWidget()
+{
+  this->createHealthWidget();
+  return this->healthWidget;
+}
+
+/**
+ * @param visibility shows or hides the health-bar
+ * (creates the widget if needed)
+ */
+void WorldEntity::setHealthWidgetVisibilit(bool visibility)
+{
+  if (visibility)
+  {
+    if (this->healthWidget != NULL)
+      this->healthWidget->show();
+    else
+    {
+      this->createHealthWidget();
+      this->updateHealthWidget();
+      this->healthWidget->show();
+    }
+  }
+  else if (this->healthWidget != NULL)
+    this->healthWidget->hide();
+}
+
+
+/**
+ * hit the world entity with
+ *  @param damage damage to be dealt
+ */
+void WorldEntity::hit(float damage, WorldEntity* killer)
+{
+  this->decreaseHealth(damage);
+
+  PRINTF(5)("Hit me: %s::%s now only %f/%f health\n", this->getClassCName(), this->getCName(), this->getHealth(), this->getHealthMax());
+
+  if( this->getHealth() > 0)
+  {
+    // any small explosion animaitions
+  }
+  else
+  {
+    this->destroy( killer );
+  }
+}
+
+
+/**
+ * destoys the world entity
+ */
+void WorldEntity::destroy(WorldEntity* killer)
+{
+  this->toList(OM_DEAD);
+}
+
+
+/**
+ * @brief updates the HealthWidget
+ */
+void WorldEntity::updateHealthWidget()
+{
+  if (this->healthWidget != NULL)
+  {
+    this->healthWidget->setMaximum(this->healthMax);
+    this->healthWidget->setValue(this->health);
+  }
+}
+
+
+/**
+ * DEBUG-DRAW OF THE BV-Tree.
+ * @param depth What depth to draw
+ * @param drawMode the mode to draw this entity under
+ */
+void WorldEntity::drawBVTree(int depth, int drawMode) const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  /* rotate */
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+
+  if (this->obbTree)
+    this->obbTree->drawBV(depth, drawMode);
+
+
+  glPopMatrix();
+}
+
+
+/**
+ * Debug the WorldEntity
+ */
+void WorldEntity::debugEntity() const
+{
+  PRINT(0)("WorldEntity %s::%s  (DEBUG)\n", this->getClassCName(), this->getCName());
+  this->debugNode();
+  PRINT(0)("List: %s ; ModelCount %d - ", ObjectManager::OMListToString(this->objectListNumber).c_str(), this->models.size());
+  for (unsigned int i = 0; i < this->models.size(); i++)
+  {
+    if (models[i] != NULL)
+      PRINT(0)(" : %d:%s", i, this->models[i]->getCName());
+  }
+  PRINT(0)("\n");
+
+}
+
+
+/**
+ * handler for changes on registred vars
+ * @param id id's which changed
+ */
+void WorldEntity::varChangeHandler( std::list< int > & id )
+{
+  if ( std::find( id.begin(), id.end(), modelFileName_handle ) != id.end() ||
+       std::find( id.begin(), id.end(), scaling_handle ) != id.end()
+     )
+  {
+    loadModel( modelFileName, scaling );
+  }
+
+  if ( std::find( id.begin(), id.end(), list_handle ) != id.end() )
+  {
+    this->toList( (OM_LIST)list_write );
+  }
+
+  if ( std::find( id.begin(), id.end(), health_handle ) != id.end() )
+  {
+    this->setHealth( health_write );
+  }
+
+  if ( std::find( id.begin(), id.end(), healthMax_handle ) != id.end() )
+  {
+    this->setHealthMax( healthMax_write );
+  }
+
+  PNode::varChangeHandler( id );
+}
+
Index: branches/heathaze/src/world_entities/world_entity.h
===================================================================
--- branches/heathaze/src/world_entities/world_entity.h	(revision 9940)
+++ branches/heathaze/src/world_entities/world_entity.h	(revision 9940)
@@ -0,0 +1,225 @@
+/*!
+ * @file world_entity.h
+ * Definition of the basic WorldEntity
+ */
+
+#ifndef _WORLD_ENTITY_H
+#define _WORLD_ENTITY_H
+
+#include "p_node.h"
+#include "synchronizeable.h"
+#include "model.h"
+
+#include "cr_engine.h"
+#include "object_manager.h"
+#include "glincl.h"
+#include <vector>
+
+#include "aabb_tree_node.h"
+
+#include "physics_interface.h"
+
+
+
+// FORWARD DECLARATION
+namespace OrxSound { class SoundBuffer; class SoundSource; }
+namespace OrxGui { class GLGuiWidget; class GLGuiBar; class GLGuiEnergyWidget; };
+
+class BVTree;
+class BoundingVolume;
+class AABBTreeNode;
+class Model;
+class CollisionHandle;
+class Collision;
+
+
+//class CharacterAttributes;
+
+
+
+//! Basis-class all interactive stuff in the world is derived from
+class WorldEntity : public PNode
+{
+  ObjectListDeclaration(WorldEntity);
+public:
+  WorldEntity();
+  virtual ~WorldEntity ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void loadModel(const std::string& fileName, float scaling = 1.0f, unsigned int modelNumber = 0, unsigned int obbTreeDepth = 4);
+  void loadModel2(const std::string& fileN, float scal = 1.0f){this->loadModel(fileN,scal,0,4);}
+  void setModel(Model* model, unsigned int modelNumber = 0);
+Model* getModel(unsigned int modelNumber = 0) const { return (this->models.size() > modelNumber)? this->models[modelNumber] : NULL; };
+
+  inline void loadMD2Texture(const std::string& fileName) { this->md2TextureFileName = fileName; }
+
+  /** @param visibility if the Entity should be visible (been draw) */
+  void setVisibiliy (bool visibility) { this->bVisible = visibility; };
+  /** @returns true if the entity is visible, false otherwise */
+  inline bool isVisible() const { return this->bVisible; };
+
+  virtual void reset();
+
+  virtual void postSpawn ();
+  virtual void leaveWorld ();
+
+  virtual void tick (float time);
+  virtual void draw () const;
+
+  /* --- Collision Detection Block  --- */
+  bool buildObbTree(int depth);
+  virtual void collidesWith (WorldEntity* entity, const Vector& location);
+  virtual void collidesWithGround(const Vector& location);
+  virtual void collidesWithGround(const Vector& feet, const Vector& ray_1, const Vector& ray_2);
+
+
+  /** @returns a reference to the obb tree of this worldentity */
+  inline BVTree* getOBBTree() const { return this->obbTree; };
+  inline void setOBBTree(OBBTree* tree) { /*if( this->obbTree != NULL) delete this->obbTree;*/ this->obbTree = (BVTree*)tree; }
+  void drawBVTree(int depth, int drawMode) const;
+  inline AABB* getModelAABB() const { return (this->aabbNode)?this->aabbNode->getAABB():NULL;}
+
+  /* --- Collision Reaction Block --- */
+  void subscribeReaction(CREngine::CRType type);
+  void subscribeReaction(CREngine::CRType type, const ClassID& target1);
+  void subscribeReaction(CREngine::CRType type, const ClassID& target1, const ClassID& target2);
+  void subscribeReaction(CREngine::CRType type, const ClassID& target1, const ClassID& target2, const ClassID& target3);
+  void subscribeReaction(CREngine::CRType type, const ClassID& target1, const ClassID& target2, const ClassID& target3, const ClassID& target4);
+
+  void unsubscribeReaction(CREngine::CRType type);
+  void unsubscribeReaction();
+
+  bool registerCollision(WorldEntity* entityA, WorldEntity* entityB, BoundingVolume* bvA, BoundingVolume* bvB);
+  bool registerCollision(int type, WorldEntity* entity, WorldEntity* groundEntity, Vector normal, Vector position, bool bInWall = false);
+  /** @return true if there is at least on collision reaction subscribed */
+  inline bool isReactive() const { return this->bReactive; }
+
+  CollisionHandle* getCollisionHandle(CREngine::CRType type) const { return this->collisionHandles[type]; }
+
+  /** @returns true if this entity is standing on ground (BSP model) */
+  bool isOnGround() const { return this->bOnGround; }
+  /** @param flag: marks if this entity is standing on ground */
+  void setOnGround(bool flag) { this->bOnGround = flag; }
+
+  virtual void hit(float damage, WorldEntity* killer);
+
+  virtual void destroy( WorldEntity* killer );
+
+
+  /* @returns the Count of Faces on this WorldEntity */
+  //unsigned int getFaceCount () const { return (this->model != NULL)?this->model->getFaceCount():0; };
+  //  void addAbility(Ability* ability);
+  //  void removeAbility(Ability* ability);
+  //  void setCharacterAttributes(CharacterAttributes* charAttr);
+  //  CharacterAttributes* getCharacterAttributes();
+
+  /* --- Object Manager Block --- */
+  void toList(OM_LIST list);
+  void toListS(const std::string& listName);
+
+  void toReflectionList();
+  void removeFromReflectionList();
+
+  /** @returns a Reference to the objectListNumber to set. */
+  OM_LIST& getOMListNumber() { return this->objectListNumber; }
+  /** @returns a Reference to the Iterator */
+  ObjectManager::EntityList::iterator& getEntityIterator() { return this->objectListIterator; }
+
+  void hide() { if( this->objectListNumber != OM_DEAD) this->lastObjectListNumber = this->objectListNumber; this->toList(OM_DEAD); }
+void unhide() { if( this->objectListNumber != this->lastObjectListNumber) this->toList(this->lastObjectListNumber); }
+
+
+  /* --- Character Attribute Block --- */
+  /** @returns the scaling of the model */
+float getScaling(){return this->scaling;}
+  /** @returns the damage dealt by this world entity */
+  float getDamage() const { return this->damage; }
+  /** sets the damage dealt to @param damage damage per second */
+  void setDamage(float damage) { this->damage = damage; }
+  /** @returns the Energy of the entity */
+  float getHealth() const { return this->health; };
+  /** @returns the Maximum energy this entity can be charged with */
+  float getHealthMax() const { return this->healthMax; }
+  float increaseHealth(float health);
+  float decreaseHealth(float health);
+  void increaseHealthMax(float increaseHealth);
+  OrxGui::GLGuiWidget* getHealthWidget();
+  bool hasHealthWidget() const { return this->healthWidget; };
+
+  virtual void varChangeHandler( std::list<int> & id );
+
+
+  //FIXME: the PhysicsInterface and the whole PEngine should probably be reviewed. Here its just used to store the vars
+  /* --- Physics Interface --- */
+  inline PhysicsInterface getPhysicsInterface() const { return this->physicsInterface; }
+  inline float getMass() const { return this->physicsInterface.getMass(); }
+  inline float getTotalMass() const { return this->physicsInterface.getTotalMass(); }
+  inline void setVelocity(const Vector& vel) { this->velocity = vel; }
+
+
+  /* --- Misc Stuff Block --- */
+  void debugWE() { this->debugEntity(); }
+  ;  ///FIXME
+  void debugEntity() const;
+
+
+protected:
+  void setHealth(float health) { this->health = health; this->updateHealthWidget();};
+  void setHealthWidgetVisibilit(bool visibility);
+  void setHealthMax(float healthMax);
+  void createHealthWidget();
+
+  //  CharacterAttributes*    charAttr;         //!< the character attributes of a world_entity
+private:
+  void updateHealthWidget();
+
+private:
+  /// TODO maybe we will move the following three entries and the corresponding functions to Playable AND NPC
+  float                   damage;             //!< the damage dealt to other objects by colliding.
+  float                   health;             //!< The Energy of this Entity, if the Entity has any energy at all.
+  float                   healthMax;          //!< The Maximal energy this entity can take.
+  OrxGui::GLGuiEnergyWidget* healthWidget;    //!< The Slider (if wanted).
+
+  std::vector<Model*>     models;             //!< The model that should be loaded for this entity.
+  std::string             md2TextureFileName; //!< the file name of the md2 model texture, only if this
+  std::string             modelLODName;       //!< the name of the model lod file
+  BVTree*                 obbTree;            //!< this is the obb tree reference needed for collision detection
+  AABBTreeNode*           aabbNode;           //!< the tree node of the first level of a axis aligned bounding boxes tree: model dimension
+
+  bool                    bCollide;           //!< If it should be considered for the collisiontest.
+  bool                    bVisible;           //!< If it should be visible.
+
+  OM_LIST                 objectListNumber;                //!< The ObjectList from ObjectManager this Entity is in.
+  ObjectManager::EntityList::iterator objectListIterator;  //!< The iterator position of this Entity in the given list of the ObjectManager.
+  OM_LIST                 lastObjectListNumber;            //!< the last ObjectList from the ObjectManager this Entity was is in
+
+
+
+  float                   scaling;                         //!< model's scaling factor
+  int                     scaling_handle;                  //!< handle for syncing var
+
+  std::string             modelFileName;                   //!< model's file name
+  int                     modelFileName_handle;            //!< handle for syncing var
+
+  int                     list_write;                      //!< entity's list
+  int                     list_handle;                     //!< handle for list changes
+
+  float                   health_write;
+  int                     health_handle;
+
+  float                   healthMax_write;
+  int                     healthMax_handle;
+
+  CollisionHandle*        collisionHandles[CREngine::CR_NUMBER];  //!< the list of the collision reactions
+  bool                    bReactive;                              //!< true if there is at least one collision reaction subscibed
+
+  PhysicsInterface        physicsInterface;                //!< the physics object of the WorldEntity
+  bool                    bOnGround;                       //!< true if this entity is standing on the ground
+
+protected:
+  Vector                  velocity;                        //!< speed of the entity
+
+};
+
+#endif /* _WORLD_ENTITY_H */
