Index: orxonox/trunk/src/Makefile.am
===================================================================
--- orxonox/trunk/src/Makefile.am	(revision 2811)
+++ orxonox/trunk/src/Makefile.am	(revision 2816)
@@ -6,7 +6,8 @@
 
 bin_PROGRAMS=orxonox
-orxonox_SOURCES=orxonox.cc world.cc player.cc data_tank.cc world_entity.cc vector.cc camera.cc collision.cc command_node.cc ini_parser.cc keynames.cc track.cc base_entity.cc game_loader.cc campaign.cc story_entity.cc object.cc array.cc material.cc
 
-noinst_HEADERS=ability.h data_tank.h npc.h stdincl.h ai.h environment.h orxonox.h synchronisable.h base_entity.h error.h player.h track.h camera.h ini_parser.h power_up.h vector.h collision.h keynames.h proto_class.h world.h command_node.h list.h shoot_laser.h world_entity.h coordinates.h message_structures.h shoot_rocket.h object.h array.h material.h
+orxonox_SOURCES=orxonox.cc world.cc player.cc data_tank.cc world_entity.cc vector.cc camera.cc collision.cc command_node.cc ini_parser.cc keynames.cc track.cc base_entity.cc game_loader.cc campaign.cc story_entity.cc object.cc environment.cc array.cc material.cc list.cc
+noinst_HEADERS=ability.h data_tank.h npc.h stdincl.h ai.h environment.h orxonox.h synchronisable.h base_entity.h error.h player.h track.h camera.h ini_parser.h power_up.h vector.h collision.h keynames.h proto_class.h world.h command_node.h list.h shoot_laser.h world_entity.h coordinates.h message_structures.h shoot_rocket.h object.h array.h material.h list_template.h
+
 
 
Index: orxonox/trunk/src/Makefile.in
===================================================================
--- orxonox/trunk/src/Makefile.in	(revision 2811)
+++ orxonox/trunk/src/Makefile.in	(revision 2816)
@@ -58,5 +58,6 @@
 	track.$(OBJEXT) base_entity.$(OBJEXT) game_loader.$(OBJEXT) \
 	campaign.$(OBJEXT) story_entity.$(OBJEXT) object.$(OBJEXT) \
-	array.$(OBJEXT) material.$(OBJEXT)
+	environment.$(OBJEXT) array.$(OBJEXT) material.$(OBJEXT) \
+	list.$(OBJEXT)
 orxonox_OBJECTS = $(am_orxonox_OBJECTS)
 orxonox_LDADD = $(LDADD)
@@ -69,11 +70,12 @@
 @AMDEP_TRUE@	./$(DEPDIR)/command_node.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/data_tank.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/environment.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/game_loader.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/ini_parser.Po ./$(DEPDIR)/keynames.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/material.Po ./$(DEPDIR)/object.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/orxonox.Po ./$(DEPDIR)/player.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/story_entity.Po ./$(DEPDIR)/track.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/vector.Po ./$(DEPDIR)/world.Po \
-@AMDEP_TRUE@	./$(DEPDIR)/world_entity.Po
+@AMDEP_TRUE@	./$(DEPDIR)/list.Po ./$(DEPDIR)/material.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/object.Po ./$(DEPDIR)/orxonox.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/player.Po ./$(DEPDIR)/story_entity.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/track.Po ./$(DEPDIR)/vector.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/world.Po ./$(DEPDIR)/world_entity.Po
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -165,6 +167,6 @@
 AM_CXXFLAGS = "-I/usr/X11R6/include"
 AM_LDFLAGS = "-L/usr/Mesa-6.0.1/lib  -L/usr/X11R6/lib -lXt -lX11" $(MWINDOWS)
-orxonox_SOURCES = orxonox.cc world.cc player.cc data_tank.cc world_entity.cc vector.cc camera.cc collision.cc command_node.cc ini_parser.cc keynames.cc track.cc base_entity.cc game_loader.cc campaign.cc story_entity.cc object.cc array.cc material.cc
-noinst_HEADERS = ability.h data_tank.h npc.h stdincl.h ai.h environment.h orxonox.h synchronisable.h base_entity.h error.h player.h track.h camera.h ini_parser.h power_up.h vector.h collision.h keynames.h proto_class.h world.h command_node.h list.h shoot_laser.h world_entity.h coordinates.h message_structures.h shoot_rocket.h object.h array.h material.h
+orxonox_SOURCES = orxonox.cc world.cc player.cc data_tank.cc world_entity.cc vector.cc camera.cc collision.cc command_node.cc ini_parser.cc keynames.cc track.cc base_entity.cc game_loader.cc campaign.cc story_entity.cc object.cc environment.cc array.cc material.cc list.cc
+noinst_HEADERS = ability.h data_tank.h npc.h stdincl.h ai.h environment.h orxonox.h synchronisable.h base_entity.h error.h player.h track.h camera.h ini_parser.h power_up.h vector.h collision.h keynames.h proto_class.h world.h command_node.h list.h shoot_laser.h world_entity.h coordinates.h message_structures.h shoot_rocket.h object.h array.h material.h list_template.h
 all: all-am
 
@@ -240,7 +242,9 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command_node.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data_tank.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/environment.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/game_loader.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ini_parser.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keynames.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/material.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Po@am__quote@
Index: orxonox/trunk/src/campaign.cc
===================================================================
--- orxonox/trunk/src/campaign.cc	(revision 2811)
+++ orxonox/trunk/src/campaign.cc	(revision 2816)
@@ -27,5 +27,5 @@
 Campaign::Campaign () 
 {
-  this->entities = new List<StoryEntity>();
+  this->entities = new ListTemplate<StoryEntity>();
   this->isInit = false;
 }
@@ -144,5 +144,5 @@
 StoryEntity* Campaign::getStoryEntity(Uint32 storyID)
 {
-  List<StoryEntity>* l;
+  ListTemplate<StoryEntity>* l;
   StoryEntity* entity;
   l = this->entities->get_next();  
Index: orxonox/trunk/src/campaign.h
===================================================================
--- orxonox/trunk/src/campaign.h	(revision 2811)
+++ orxonox/trunk/src/campaign.h	(revision 2816)
@@ -33,5 +33,5 @@
 
  private:
-  List<StoryEntity>* entities;
+  ListTemplate<StoryEntity>* entities;
   bool running;
 
Index: orxonox/trunk/src/command_node.cc
===================================================================
--- orxonox/trunk/src/command_node.cc	(revision 2811)
+++ orxonox/trunk/src/command_node.cc	(revision 2816)
@@ -11,5 +11,5 @@
    ### File Specific:
    main-programmer: Christian Meyer
-   co-programmer: ...
+   co-programmer: Patrick Boenzli
 */
 
@@ -33,5 +33,5 @@
 CommandNode::CommandNode (int ID)
 {
-  bound = new List<WorldEntity>();
+  bound = new List();
   aliases = NULL;
   netID = ID;
@@ -48,5 +48,5 @@
   bLocalInput = true;
   netID = 0;
-  bound = new List<WorldEntity>();
+  bound = new List();
   load_bindings (filename);
 }
@@ -59,4 +59,10 @@
   if( aliases != NULL) free (aliases);
   if( bound != NULL) delete bound;
+}
+
+
+void CommandNode::reset()
+{
+  this->bound->clear();
 }
 
@@ -123,5 +129,5 @@
 void CommandNode::bind (WorldEntity* entity)
 {
-  bound->add (entity, LIST_ADD_NEXT, true);
+  bound->add (entity);
 }
 
@@ -132,5 +138,5 @@
 void CommandNode::unbind (WorldEntity* entity)
 {
-  bound->remove (entity, LIST_FIND_FW);
+  bound->remove (entity);
 }
 
@@ -214,4 +220,5 @@
 }
 
+
 void CommandNode::process_network ()
 {
@@ -219,8 +226,7 @@
 }
 
+
 void CommandNode::relay (Command* cmd)
 {
-  //printf("CommandNode|relay()\n");
-  List<WorldEntity>* plist = bound;
   
   Orxonox *orx = Orxonox::getInstance();
@@ -231,9 +237,12 @@
   if( bLocalInput) send_over_network (cmd);
   
-  while( (plist = plist->get_next()) != NULL)
-    {
-      plist->get_object()->command (cmd);
-    }
-}
+  WorldEntity* entity = bound->enumerate();
+  while(  entity != NULL)
+    {
+      entity->command (cmd);
+      entity = bound->nextElement();
+    }
+}
+
 
 /**
Index: orxonox/trunk/src/command_node.h
===================================================================
--- orxonox/trunk/src/command_node.h	(revision 2811)
+++ orxonox/trunk/src/command_node.h	(revision 2816)
@@ -19,40 +19,42 @@
 //! Key aliasing structure
 /**
-	This structure contains the key aliasing information, e.g. the command strings that
-	have been bound to the keys.
+   This structure contains the key aliasing information, e.g. the command strings that
+   have been bound to the keys.
 */
 typedef struct
 {
-	char keys[N_STD_KEYS][CMD_LENGHT];
-	char buttons[N_BUTTONS][CMD_LENGHT];
+  char keys[N_STD_KEYS][CMD_LENGHT];
+  char buttons[N_BUTTONS][CMD_LENGHT];
 } KeyBindings;
 
 //! Command Node
 /**
-	This class gathers all incoming SDL_Events and processes them. Keyboard, mouse and joystick input is
-	captured and translated into command messages which are passed down to the bound WorldEntities (via WorldEntity::command()).
-	Other SDL_Events are passed to Orxonox::event_handler() to deal with them. If the CommandNode has been created
-	with bLocalInput set to false, it will query the network class for incoming commands that match his netID and pass
-	them on to it's WorldEntities.
+   This class gathers all incoming SDL_Events and processes them. Keyboard, mouse and joystick input is
+   captured and translated into command messages which are passed down to the bound WorldEntities (via WorldEntity::command()).
+   Other SDL_Events are passed to Orxonox::event_handler() to deal with them. If the CommandNode has been created
+   with bLocalInput set to false, it will query the network class for incoming commands that match his netID and pass
+   them on to it's WorldEntities.
 */
 class CommandNode {
  private:
- 	bool bLocalInput;	//!< Identifies the CommandNode that processes local input
- 	int netID;	//!< Unique identifier that is used to determine between remote CommandNodes
-	KeyBindings* aliases;
-	List<WorldEntity>* bound;	//!< List of WorldEntites that recieve commands from this CommandNode
-	Sint32 coord[2];
-	
-	void relay (Command* cmd);
-	int* name_to_index (char* name);
-	void process_local ();
-	void process_network ();
-	void send_over_network (Command* cmd);
-	
+  bool bLocalInput;	//!< Identifies the CommandNode that processes local input
+  int netID;	//!< Unique identifier that is used to determine between remote CommandNodes
+  KeyBindings* aliases;
+  List* bound;	//!< List of WorldEntites that recieve commands from this CommandNode
+  Sint32 coord[2];
+  
+
+  void relay (Command* cmd);
+  int* name_to_index (char* name);
+  void process_local ();
+  void process_network ();
+  void send_over_network (Command* cmd);
+  
  public:
   CommandNode (int ID);
   CommandNode (char* filename);
   ~CommandNode ();
-  
+
+  void reset();  
   void load_bindings (char* filename);
   void bind (WorldEntity* entity);
Index: orxonox/trunk/src/environment.cc
===================================================================
--- orxonox/trunk/src/environment.cc	(revision 2811)
+++ orxonox/trunk/src/environment.cc	(revision 2816)
@@ -16,11 +16,9 @@
 */
 
-#include <iostream>
-#include <GL/glut.h>
-#include <stdlib.h>
-
-#include "data_tank.h"
 
 #include "environment.h"
+#include "stdincl.h"
+#include "world_entity.h"
+#include "vector.h"
 
 using namespace std;
@@ -30,6 +28,5 @@
 #define LEVEL_LENGTH 500
 
-Environment::Environment () 
-  : WorldEntity()
+Environment::Environment () : WorldEntity()
 {
 
@@ -60,8 +57,48 @@
 Environment::~Environment () {}
 
+void Environment::tick (float time) {}
 
+void Environment::hit (WorldEntity* weapon, Vector loc) {}
+
+void Environment::destroy () {}
+
+void Environment::collide (WorldEntity* other,  Uint32 ownhitflags, Uint32 otherhitflags) {}
+
+void Environment::draw () 
+{
+  printf("Environment::draw()");
+
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  float matrix[4][4];
+  
+  glTranslatef(get_placement()->r.x,get_placement()->r.y,get_placement()->r.z);
+  get_placement()->w.matrix (matrix);
+  glMultMatrixf ((float*)matrix);
+
+  glBegin(GL_TRIANGLES);
+  glColor3f(1,1,1);
+  glVertex3f(0,0,0.5);
+  glVertex3f(-0.5,0,-1);
+  glVertex3f(0.5,0,-1);
+  
+  glVertex3f(0,0,0.5);
+  glVertex3f(0,0.5,-1);
+  glVertex3f(0,-0.5,-1);
+  glEnd();
+    
+  glBegin(GL_QUADS);
+  glColor3f(0,0,1);
+  glVertex3f(0.5,0.5,-1);
+  glVertex3f(0.5,-0.5,-1);
+  glVertex3f(-0.5,-0.5,-1);
+  glVertex3f(-0.5,0.5,-1);
+  glEnd();
+}
+
+/*
 void Environment::paint()
 {
-  /*
+  
   glPushMatrix();
   //glScalef(0.5, 0.5, 1.0);
@@ -95,5 +132,5 @@
   
   glPopMatrix();
-  */
+  
 }
 
@@ -103,2 +140,3 @@
 }
 
+*/
Index: orxonox/trunk/src/environment.h
===================================================================
--- orxonox/trunk/src/environment.h	(revision 2811)
+++ orxonox/trunk/src/environment.h	(revision 2816)
@@ -1,12 +1,11 @@
-
-
-
 #ifndef ENVIRONEMENT_H
 #define ENVIRONEMENT_H
 
-
 #include "world_entity.h"
 
-class Environment : public WorldEntity {
+
+class Environment : public WorldEntity 
+{
+  friend class World;
 
  private:
@@ -21,8 +20,10 @@
   ~Environment ();
 
-  void paint(void);
-  void drawEnvironment(void);
-  void setEnvPosition(void);
-  void getEnvPosition(void);
+  
+  virtual void tick (float time);
+  virtual void hit (WorldEntity* weapon, Vector loc);
+  virtual void destroy ();
+  virtual void collide (WorldEntity* other,  Uint32 ownhitflags, Uint32 otherhitflags);
+  virtual void draw ();
 
 };
Index: orxonox/trunk/src/list.cc
===================================================================
--- orxonox/trunk/src/list.cc	(revision 2816)
+++ orxonox/trunk/src/list.cc	(revision 2816)
@@ -0,0 +1,147 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU 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 "list.h"
+
+
+using namespace std;
+
+
+
+List::List () 
+{
+  this->first = NULL;
+  this->last = NULL;
+  this->size = 0;
+}
+
+List::~List () 
+{}
+
+
+void List::add(WorldEntity* entity)
+{
+  printf("List::add() \n");
+  listElement* el = new listElement;
+  el->prev = this->last;
+  el->curr = entity;
+  el->next = NULL;
+
+  this->last = el;
+
+  if(this->size == 0) this->first = el;
+  else el->prev->next = el;
+  this->size++;
+}
+
+
+void List::remove(WorldEntity* entity)
+{
+  this->currentEl = this->first;
+  listElement* te;
+  while( this->currentEl != NULL)
+    {
+      if( this->currentEl->curr == entity)
+	{
+	  printf("List::remove() - object found\n");
+	  
+	  if( this->currentEl->prev  == NULL ) this->first = this->currentEl->next;
+	  else this->currentEl->prev->next = this->currentEl->next;
+
+	  if( this->currentEl->next == NULL) this->last = this->currentEl->prev;
+	  else this->currentEl->next->prev = this->currentEl->prev;
+
+	  te = this->currentEl->next;
+	  delete this->currentEl;
+	  this->currentEl = te;
+	  return;
+	}
+      this->currentEl = this->currentEl->next;
+    }
+}
+
+
+void List::clear()
+{
+  printf("List::clear() - clearing all world objects, releasing mem\n");
+  this->currentEl = this->first;
+  while(this->currentEl != NULL)
+    {
+      listElement* le = this->currentEl->next;
+      delete this->currentEl->curr;
+      delete this->currentEl;
+      this->currentEl = le;
+    }
+  this->first = NULL;
+  this->last = NULL;
+  this->size = 0;
+}
+
+
+WorldEntity* List::firstElement()
+{
+  return this->first->curr;
+}
+
+
+bool List::isEmpty()
+{
+  return (this->size==0)?true:false;
+}
+
+
+int List::getSize()
+{
+  return this->size;
+}
+
+
+WorldEntity* List::enumerate()
+{
+  if(this->size == 0) return NULL;
+  this->currentEl = this->first;
+  return this->currentEl->curr;
+}
+
+
+WorldEntity* List::nextElement()
+{
+  if(this->size == 0) return NULL;
+  this->currentEl = this->currentEl->next;
+  if(this->currentEl == NULL) return NULL;
+  return this->currentEl->curr;
+}
+
+
+WorldEntity* List::toArray()
+{}
+
+
+void List::debug()
+{
+  int counter = 1;
+  this->currentEl = this->first;
+  printf("List:debug() =====================\n");
+  while(this->currentEl != NULL)
+    {
+      printf("element: nr %d/%d\n", counter, size);
+      this->currentEl = this->currentEl->next;
+      counter++;
+    }
+  printf("List:debug()END =====================\n");
+}
Index: orxonox/trunk/src/list.h
===================================================================
--- orxonox/trunk/src/list.h	(revision 2811)
+++ orxonox/trunk/src/list.h	(revision 2816)
@@ -1,300 +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: Christian Meyer
-
-   ADDONS/FIXES:
-  
-   Patrick Boenzli     :          Implemented getSize() function
-*/
-
-
-/*!
-  \file list.h
-  \brief Contains a template for a doubly linked list
-*/
 
 #ifndef LIST_H
 #define LIST_H
 
-#include "stdlib.h"
+#include "stdincl.h"
 
 //! An enum to list all the modes available when adding an object to a List
-enum ADDMODE {LIST_ADD_NEXT, LIST_ADD_PREV, LIST_ADD_FIRST, LIST_ADD_LAST};
+//enum ADDMODE {LIST_ADD_FIRST, LIST_ADD_LAST};
 //! An enum to list the two searching directions available when removing an object from a List
-enum FINDMODE {LIST_FIND_BW, LIST_FIND_FW};
+//enum FINDMODE {LIST_FIND_BW, LIST_FIND_FW};
 
-//! A generic doubly linked list
-template<class T> class List 
-{
-  T* object;
-  List<T>* next;
-  List<T>* prev;
-  bool bReference;
-  int size;
-  
+
+
+class WorldEntity;
+
+class List {
+
  public:
-  List (T* obj, List<T>* n, List<T>* p, bool bRef);
+  List ();
   ~List ();
-  
-  int add (T* obj, ADDMODE mode, bool bRef);
-  T* get_object();
-  List<T>* get_next ();
-  List<T>* get_previous ();
-  List<T>* get_last ();
-  List<T>* get_first ();
-  void set_next (List<T>* ptr);
-  void set_prev (List<T>* ptr);
-  int remove (T* obj, FINDMODE mode);
+
+  void add(WorldEntity* entity);
+  void remove(WorldEntity* entity);
+  void clear();
+  WorldEntity* firstElement();
+  bool isEmpty();
   int getSize();
+  WorldEntity* enumerate();
+  WorldEntity* nextElement();
+  WorldEntity* toArray();
+  void debug();
+
+ private:
+  struct listElement
+  {
+    listElement* prev;
+    WorldEntity* curr;
+    listElement* next;
+  };
+  Uint32 size;
+  listElement* first;
+  listElement* last;
+  listElement* currentEl;
+
+
 };
 
+class Iterator
+{
 
-/**
-  \brief Standard constructor
-  
-  Call this without any parameters to generate a new List which can be filled with content.
-  DO NOT create a List element that contains an object on your own, you'll lose the data
-  contained in that object and will have trouble removing the list from your memory.
-*/
-template<class T>
-List<T>::List (T* obj = NULL, List<T>* n = NULL, List<T>* p = NULL, bool bRef = false)
-{
-  object = obj;
-  next = n;
-  prev = p;
-  bReference = bRef;
-  if(obj != NULL)
-    ++size;
-}
+ public:
+  bool hasNext();
+  WorldEntity* next();
 
-/**
-  \brief Standard destructor
-  
-  Call this on the initially generated base List element to remove the whole List from the memory.
-  You can safely do this to any List element you want without messing up the rest of the List, but keep in mind
-  that the contained object will be deleted as well when bRef had been set to false.
-*/
-template<class T>
-List<T>::~List ()
-{
-  if (object == NULL) // deleted foot node => disband the list
-  {
-    while( next != NULL)
-    {
-      delete next;
-    }
-    while( prev != NULL)
-    {
-      delete prev;
-    }
-  }
-  else
-  {
-    if (prev != NULL) prev->set_next (next);
-    if (next != NULL) next->set_prev (prev);
-    if (!bReference) delete object;
-  }
-}
- 
-/**
-  \brief Add an object to the List
-  \param obj: A pointer to an allocated object
-  \param mode: A Value of ADDMODE (default: LIST_ADD_NEXT)
-  \param bRef: Sets whether the element is serving as a storage point or a simple listing (default: false)
-  \return 0 if the operation succeded, -1 if the element could not be added
-  
-  This adds a new List element to the chain. The mode parameter can be used to specify
-  the location where the element should be added. LIST_ADD_NEXT will add the new element directly
-  after the base element. LIST_ADD_PREV will add the new element directly before the base element.
-  LIST_ADD_FIRST will add the element at the beginning of the List whereas LIST_ADD_LAST will add
-  it to the end of the chain. If the bRef parameter is set to true, the object pointer will not be deleted
-  when the element containing that object is deleted, thus the List can be used for temporary listings as
-  well as permanent data storage.
-*/
-template<class T> 
-int List<T>::add (T* obj, ADDMODE mode = LIST_ADD_NEXT, bool bRef = false)
-{
-  List<T>* p;
-  if( obj == NULL) return -1;
-  switch (mode)
-  {
-    case LIST_ADD_NEXT:
-      p = new List<T>( obj, next, this, bRef);
-      if( next != NULL) next->set_prev (p);
-      next = p;
-      break;
-    case LIST_ADD_PREV:
-      p = new List<T>( obj, this, prev, bRef);
-      if( prev != NULL) prev->set_next (p);
-      prev = p;
-      break;
-    case LIST_ADD_FIRST:
-      if (prev == NULL) prev = new List<T> (obj, this, NULL, bRef);
-      else return prev->add (obj, mode, bRef);
-      break;
-    case LIST_ADD_LAST:
-      if (next == NULL) next = new List<T> (obj, NULL, this, bRef);
-      else return next->add (obj, mode, bRef);
-      break;
-    default:
-        return -1;
-      break;
-  }
-  ++size;
-  return 0;
-}
+ private:
 
-/**
-  \brief Get the next element of the List
-  \return The List element after the current List element
-*/
-template<class T>
-List<T>* List<T>::get_next ()
-{
-  return next;
-}
- 
-/**
-  \brief Get the previous element of the List
-  \return The List element before the current List element
-*/
-template<class T>
-List<T>* List<T>::get_previous ()
-{
-  return prev;
-}
-
-/**
-  \brief Get the last element of the List
-  \return The last List element
-*/
-template<class T>
-List<T>* List<T>::get_last ()
-{
-  if (next == NULL) return this;
-  else return next->get_last();
-}
-
-/**
-  \brief Get the first element of the List
-  \return The first List element
-*/
-template<class T>
-List<T>* List<T>::get_first ()
-{
-  if (prev == NULL) return this;
-  else return prev->get_first();
-}
-
-/**
-  \brief Removes a certain element from the List
-  \param obj: A pointer to the object that should be removed
-  \param mode: A value of FINDMODE
-  \return 0 if the element was found and removed, -1 if the element was not found
-  
-  This searches the part of the List specified with mode for the object in question.
-  When the object is found it is deleted and the List element is removed from the chain.
-  If mode is LIST_FIND_FW all elements AFTER the base element are searched, if mode is
-  LIST_FIND_BW all elements BEFORE the base element are searched. Note that the object
-  contained within the List element is NOT deleted when bRef was set to true.
-*/
-template<class T>
-int List<T>::remove (T* obj, FINDMODE mode = LIST_FIND_FW)
-{
-  if (obj == NULL) return -1;
-  else
-  {
-    switch (mode)
-    {
-      case LIST_FIND_BW:
-        if (prev == NULL) return -1;
-        else
-        {
-          if( prev->get_object() == obj)
-          {
-            delete prev;
-          }
-          else
-          {
-            return prev->remove( obj, mode);
-          }
-        }
-        break;
-      case LIST_FIND_FW:
-        if (next == NULL) return -1;
-        else
-        {
-          if( next->get_object() == obj)
-          {
-            delete next;
-          }
-          else
-          {
-            return next->remove( obj, mode);
-          }
-        }
-        break;
-      default:
-        return -1;
-    }
-  }
-  --size;
-  return 0;
-}
-
-/**
-  \brief Set the next element of a List element
-  \param ptr: A pointer to the new next element
-    
-  Sets the next element of a List element... Better not touch this, it can really mess up a List.
-*/
-template<class T>
-void List<T>::set_next (List<T>* ptr)
-{
-  next = ptr;
-}
-
-/**
-  \brief Set the prev element of a List element
-  \param ptr: A pointer to the new previous element
-    
-  Sets the previous element of a List element... Better not touch this, it can really mess up a List.
-*/
-template<class T>
-void List<T>::set_prev (List<T>* ptr)
-{
-  prev = ptr;
-}
-
-/**
-  \brief Get the pointer to the object the element is containing
-  \return The contained object (will be NULL if called on the base element).
-*/
-template<class T>
-T* List<T>::get_object()
-{
-  return object;
-}
-
-
-/**
-  \brief Returns the current size of the List
-  \return Size of List
-*/
-template<class T>
-int List<T>::getSize()
-{
-  return this->size;
-}
+};
 
 #endif
-
Index: orxonox/trunk/src/list_template.h
===================================================================
--- orxonox/trunk/src/list_template.h	(revision 2816)
+++ orxonox/trunk/src/list_template.h	(revision 2816)
@@ -0,0 +1,300 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU 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
+
+   ADDONS/FIXES:
+  
+   Patrick Boenzli     :          Implemented getSize() function
+*/
+
+
+/*!
+  \file list.h
+  \brief Contains a template for a doubly linked list
+*/
+
+#ifndef LIST_TEMPLATE_H
+#define LIST_TEMPLATE_H
+
+#include "stdincl.h"
+
+//! An enum to list all the modes available when adding an object to a List
+enum ADDMODE {LIST_ADD_NEXT, LIST_ADD_PREV, LIST_ADD_FIRST, LIST_ADD_LAST};
+//! An enum to list the two searching directions available when removing an object from a List
+enum FINDMODE {LIST_FIND_BW, LIST_FIND_FW};
+
+//! A generic doubly linked list
+template<class T> class ListTemplate 
+{
+  T* object;
+  ListTemplate<T>* next;
+  ListTemplate<T>* prev;
+  bool bReference;
+  int size;
+  
+ public:
+  ListTemplate (T* obj, ListTemplate<T>* n, ListTemplate<T>* p, bool bRef);
+  ~ListTemplate ();
+  
+  int add (T* obj, ADDMODE mode, bool bRef);
+  T* get_object();
+  ListTemplate<T>* get_next ();
+  ListTemplate<T>* get_previous ();
+  ListTemplate<T>* get_last ();
+  ListTemplate<T>* get_first ();
+  void set_next (ListTemplate<T>* ptr);
+  void set_prev (ListTemplate<T>* ptr);
+  int remove (T* obj, FINDMODE mode);
+  int getSize();
+};
+
+
+/**
+  \brief Standard constructor
+  
+  Call this without any parameters to generate a new ListTemplate which can be filled with content.
+  DO NOT create a ListTemplate element that contains an object on your own, you'll lose the data
+  contained in that object and will have trouble removing the list from your memory.
+*/
+template<class T>
+ListTemplate<T>::ListTemplate (T* obj = NULL, ListTemplate<T>* n = NULL, ListTemplate<T>* p = NULL, bool bRef = false)
+{
+  object = obj;
+  next = n;
+  prev = p;
+  bReference = bRef;
+  if(obj != NULL)
+    ++size;
+}
+
+/**
+  \brief Standard destructor
+  
+  Call this on the initially generated base ListTemplate element to remove the whole ListTemplate from the memory.
+  You can safely do this to any ListTemplate element you want without messing up the rest of the ListTemplate, but keep in mind
+  that the contained object will be deleted as well when bRef had been set to false.
+*/
+template<class T>
+ListTemplate<T>::~ListTemplate ()
+{
+  if (object == NULL) // deleted foot node => disband the list
+  {
+    while( next != NULL)
+    {
+      delete next;
+    }
+    while( prev != NULL)
+    {
+      delete prev;
+    }
+  }
+  else
+  {
+    if (prev != NULL) prev->set_next (next);
+    if (next != NULL) next->set_prev (prev);
+    if (!bReference) delete object;
+  }
+}
+ 
+/**
+  \brief Add an object to the ListTemplate
+  \param obj: A pointer to an allocated object
+  \param mode: A Value of ADDMODE (default: LIST_ADD_NEXT)
+  \param bRef: Sets whether the element is serving as a storage point or a simple listing (default: false)
+  \return 0 if the operation succeded, -1 if the element could not be added
+  
+  This adds a new ListTemplate element to the chain. The mode parameter can be used to specify
+  the location where the element should be added. LIST_ADD_NEXT will add the new element directly
+  after the base element. LIST_ADD_PREV will add the new element directly before the base element.
+  LIST_ADD_FIRST will add the element at the beginning of the ListTemplate whereas LIST_ADD_LAST will add
+  it to the end of the chain. If the bRef parameter is set to true, the object pointer will not be deleted
+  when the element containing that object is deleted, thus the ListTemplate can be used for temporary listings as
+  well as permanent data storage.
+*/
+template<class T> 
+int ListTemplate<T>::add (T* obj, ADDMODE mode = LIST_ADD_NEXT, bool bRef = false)
+{
+  ListTemplate<T>* p;
+  if( obj == NULL) return -1;
+  switch (mode)
+  {
+    case LIST_ADD_NEXT:
+      p = new ListTemplate<T>( obj, next, this, bRef);
+      if( next != NULL) next->set_prev (p);
+      next = p;
+      break;
+    case LIST_ADD_PREV:
+      p = new ListTemplate<T>( obj, this, prev, bRef);
+      if( prev != NULL) prev->set_next (p);
+      prev = p;
+      break;
+    case LIST_ADD_FIRST:
+      if (prev == NULL) prev = new ListTemplate<T> (obj, this, NULL, bRef);
+      else return prev->add (obj, mode, bRef);
+      break;
+    case LIST_ADD_LAST:
+      if (next == NULL) next = new ListTemplate<T> (obj, NULL, this, bRef);
+      else return next->add (obj, mode, bRef);
+      break;
+    default:
+        return -1;
+      break;
+  }
+  ++size;
+  return 0;
+}
+
+/**
+  \brief Get the next element of the ListTemplate
+  \return The ListTemplate element after the current ListTemplate element
+*/
+template<class T>
+ListTemplate<T>* ListTemplate<T>::get_next ()
+{
+  return next;
+}
+ 
+/**
+  \brief Get the previous element of the ListTemplate
+  \return The ListTemplate element before the current ListTemplate element
+*/
+template<class T>
+ListTemplate<T>* ListTemplate<T>::get_previous ()
+{
+  return prev;
+}
+
+/**
+  \brief Get the last element of the ListTemplate
+  \return The last ListTemplate element
+*/
+template<class T>
+ListTemplate<T>* ListTemplate<T>::get_last ()
+{
+  if (next == NULL) return this;
+  else return next->get_last();
+}
+
+/**
+  \brief Get the first element of the ListTemplate
+  \return The first ListTemplate element
+*/
+template<class T>
+ListTemplate<T>* ListTemplate<T>::get_first ()
+{
+  if (prev == NULL) return this;
+  else return prev->get_first();
+}
+
+/**
+  \brief Removes a certain element from the ListTemplate
+  \param obj: A pointer to the object that should be removed
+  \param mode: A value of FINDMODE
+  \return 0 if the element was found and removed, -1 if the element was not found
+  
+  This searches the part of the ListTemplate specified with mode for the object in question.
+  When the object is found it is deleted and the ListTemplate element is removed from the chain.
+  If mode is LIST_FIND_FW all elements AFTER the base element are searched, if mode is
+  LIST_FIND_BW all elements BEFORE the base element are searched. Note that the object
+  contained within the ListTemplate element is NOT deleted when bRef was set to true.
+*/
+template<class T>
+int ListTemplate<T>::remove (T* obj, FINDMODE mode = LIST_FIND_FW)
+{
+  if (obj == NULL) return -1;
+  else
+  {
+    switch (mode)
+    {
+      case LIST_FIND_BW:
+        if (prev == NULL) return -1;
+        else
+        {
+          if( prev->get_object() == obj)
+          {
+            delete prev;
+          }
+          else
+          {
+            return prev->remove( obj, mode);
+          }
+        }
+        break;
+      case LIST_FIND_FW:
+        if (next == NULL) return -1;
+        else
+        {
+          if( next->get_object() == obj)
+          {
+            delete next;
+          }
+          else
+          {
+            return next->remove( obj, mode);
+          }
+        }
+        break;
+      default:
+        return -1;
+    }
+  }
+  --size;
+  return 0;
+}
+
+/**
+  \brief Set the next element of a ListTemplate element
+  \param ptr: A pointer to the new next element
+    
+  Sets the next element of a ListTemplate element... Better not touch this, it can really mess up a ListTemplate.
+*/
+template<class T>
+void ListTemplate<T>::set_next (ListTemplate<T>* ptr)
+{
+  next = ptr;
+}
+
+/**
+  \brief Set the prev element of a ListTemplate element
+  \param ptr: A pointer to the new previous element
+    
+  Sets the previous element of a ListTemplate element... Better not touch this, it can really mess up a ListTemplate.
+*/
+template<class T>
+void ListTemplate<T>::set_prev (ListTemplate<T>* ptr)
+{
+  prev = ptr;
+}
+
+/**
+  \brief Get the pointer to the object the element is containing
+  \return The contained object (will be NULL if called on the base element).
+*/
+template<class T>
+T* ListTemplate<T>::get_object()
+{
+  return object;
+}
+
+
+/**
+  \brief Returns the current size of the ListTemplate
+  \return Size of ListTemplate
+*/
+template<class T>
+int ListTemplate<T>::getSize()
+{
+  return this->size;
+}
+
+#endif
+
Index: orxonox/trunk/src/player.cc
===================================================================
--- orxonox/trunk/src/player.cc	(revision 2811)
+++ orxonox/trunk/src/player.cc	(revision 2816)
@@ -61,10 +61,10 @@
 void Player::post_spawn ()
 {
-	travel_speed = 15.0;
-	velocity = Vector();
-	bUp = bDown = bLeft = bRight = bAscend = bDescend = false;
-	bFire = false;
-	acceleration = 10.0;
-	set_collision (new CollisionCluster (1.0, Vector(0,0,0)));
+  travel_speed = 15.0;
+  velocity = Vector();
+  bUp = bDown = bLeft = bRight = bAscend = bDescend = false;
+  bFire = false;
+  acceleration = 10.0;
+  set_collision (new CollisionCluster (1.0, Vector(0,0,0)));
 }
 
@@ -112,4 +112,5 @@
   //  glCallList (objectList);
 
+  
   
   //printf("Player@%f/%f/%f\n", get_placement()->r.x, get_placement()->r.y, get_placement()->r.z);
Index: orxonox/trunk/src/stdincl.h
===================================================================
--- orxonox/trunk/src/stdincl.h	(revision 2811)
+++ orxonox/trunk/src/stdincl.h	(revision 2816)
@@ -15,4 +15,5 @@
 #include "coordinates.h"
 #include "list.h"
+#include "list_template.h"
 #include "error.h"
 #include "message_structures.h"
Index: orxonox/trunk/src/vector.cc
===================================================================
--- orxonox/trunk/src/vector.cc	(revision 2811)
+++ orxonox/trunk/src/vector.cc	(revision 2816)
@@ -33,5 +33,5 @@
 {
   Vector r;
-  
+
   r.x = x + v.x;
   r.y = y + v.y;
Index: orxonox/trunk/src/world.cc
===================================================================
--- orxonox/trunk/src/world.cc	(revision 2811)
+++ orxonox/trunk/src/world.cc	(revision 2816)
@@ -22,4 +22,5 @@
 #include "command_node.h"
 #include "camera.h"
+#include "environment.h"
 
 using namespace std;
@@ -35,5 +36,5 @@
   this->worldName = name;
   this->debugWorldNr = -1;
-  this->entities = new List<WorldEntity>();
+  this->entities = new List();
 }
 
@@ -42,5 +43,5 @@
   this->debugWorldNr = worldID;
   this->worldName = NULL;
-  this->entities = new List<WorldEntity>();
+  this->entities = new List();
 }
 
@@ -74,4 +75,6 @@
   this->bQuitCurrentGame = true;
   this->localCamera->setWorld(NULL);
+  this->entities->clear();
+  Orxonox::getInstance()->get_localinput()->reset();
   this->~World();
 }
@@ -105,6 +108,6 @@
 	    
 	    // create the tracks
-	    this->tracklen = 6;
-	    this->track = new Track[6];
+	    this->tracklen = 2;
+	    this->track = new Track[2];
 	    for( int i = 0; i < this->tracklen; i++)
 	      {
@@ -113,5 +116,4 @@
 	    
 	    // create a player
-	    //WorldEntity* myPlayer = (WorldEntity*) this->spawn<Player>();
 	    WorldEntity* myPlayer = new Player();
 	    this->spawn(myPlayer);
@@ -125,4 +127,12 @@
 	    this->localCamera = new Camera(this);
 	    this->getCamera()->bind (myPlayer);	
+
+	    Placement* plc = new Placement;
+	    plc->r = Vector(100, 10, 10);
+	    plc->w = Quaternion();
+	    WorldEntity* env = new Environment();
+	    this->spawn(env, plc);
+
+	    this->entities->debug();
 	    break;
 	  }
@@ -260,18 +270,19 @@
 void World::collide ()
 {
-  List<WorldEntity> *a, *b;
+  /*
+  List *a, *b;
   WorldEntity *aobj, *bobj;
-  
-  a = entities->get_next();
+   
+  a = entities;
   
   while( a != NULL)
     {
-      aobj = a->get_object();
+      aobj = a->nextElement();
       if( aobj->bCollide && aobj->collisioncluster != NULL)
 	{
-	  b = a->get_next();
+	  b = a->nextElement();
 	  while( b != NULL )
 	    {
-	      bobj = b->get_object();
+	      bobj = b->nextElement();
 	      if( bobj->bCollide && bobj->collisioncluster != NULL )
 		{
@@ -285,9 +296,10 @@
 		  }
 		}
-	      b = b->get_next();
+	      b = b->nextElement();
 	    }
 	}
-      a = a->get_next();
-    }
+      a = a->enumerate();
+    }
+  */
 }
 
@@ -300,13 +312,13 @@
   
   // draw entities
-  List<WorldEntity> *l;
+  List *l;
   WorldEntity* entity;
   
-  l = entities->get_next();  
-  while( l != NULL ) 
+  l = entities; 
+  entity = l->enumerate();
+  while( entity != NULL ) 
     { 
-      entity = l->get_object();
       if( entity->bDraw ) entity->draw();
-      l = l->get_next();
+      entity = l->nextElement();
     }
   
@@ -328,5 +340,5 @@
 void World::update ()
 {
-  List<WorldEntity> *l;
+  //List<WorldEntity> *l;
   WorldEntity* entity;
   Location* loc;
@@ -334,8 +346,9 @@
   Uint32 t;
   
-  l = entities->get_next();  
-  while( l != NULL ) 
+  //  l = entities->enumerate(); 
+  entity = this->entities->enumerate();
+  while( entity != NULL ) 
     { 
-      entity = l->get_object();
+
       
       if( !entity->isFree() )
@@ -375,5 +388,5 @@
 	}
       
-      l = l->get_next();
+      entity = entities->nextElement();
     }
   
@@ -386,5 +399,5 @@
 void World::time_slice (Uint32 deltaT)
 {
-  List<WorldEntity> *l;
+  //List<WorldEntity> *l;
   WorldEntity* entity;
   float seconds = deltaT;
@@ -392,12 +405,11 @@
   seconds /= 1000;
   
-  l = entities->get_next();  
-  while( l != NULL) 
+  entity = entities->enumerate(); 
+  while( entity != NULL) 
     { 
-      entity = l->get_object();
       entity->tick (seconds);
-      l = l->get_next();
-    }
-  
+      entity = entities->nextElement();
+    }
+
   for( int i = 0; i < tracklen; i++) track[i].tick (seconds);
 }
@@ -436,14 +448,14 @@
 void World::debug()
 {
-  List<WorldEntity> *l;
+  //List<WorldEntity> *l;
   WorldEntity* entity;
   
   printf("counting all entities\n");
-  l = entities->get_next();  
-  while( l != NULL ) 
+  printf("World::debug() - enumerate()\n");
+  entity = entities->enumerate();  
+  while( entity != NULL ) 
     { 
-      entity = l->get_object();
       if( entity->bDraw ) printf("got an entity\n");
-      l = l->get_next();
+      entity = entities->nextElement();
     }
 }
@@ -470,4 +482,7 @@
       // Draw
       display();
+  
+      for(int i = 0; i < 1000000; i++){}
+
     }
   printf("World|Exiting the main loop\n");
@@ -502,5 +517,5 @@
     {
       Uint32 dt = currentFrame - this->lastFrame;
-      /*
+      
       if(dt > 0)
 	{
@@ -510,7 +525,7 @@
       else
 	{
-	  printf("fps = 1000\n");
-	}
-      */
+	  printf("fps = 1000 but 0ms!\n");
+	}
+      
       this->time_slice (dt);
       this->update ();
@@ -570,14 +585,11 @@
   Location* loc = NULL;
   WorldEntity* owner;
-  //T* entity = new T();
-  entities->add (entity, LIST_ADD_NEXT);
-  //if( loc == NULL)
-  //{
-      zeroloc.dist = 0;
-      zeroloc.part = 0;
-      zeroloc.pos = Vector();
-      zeroloc.rot = Quaternion();
-      loc = &zeroloc;
-      //}
+
+  entities->add (entity);
+  zeroloc.dist = 0;
+  zeroloc.part = 0;
+  zeroloc.pos = Vector();
+  zeroloc.rot = Quaternion();
+  loc = &zeroloc;
   entity->init (loc, owner);
   if (entity->bFree)
@@ -586,4 +598,43 @@
     }
   entity->post_spawn ();
+}
+
+
+void World::spawn(WorldEntity* entity, Location* loc)
+{
+  Location zeroLoc;
+  WorldEntity* owner;
+  this->entities->add (entity);
+  if( loc == NULL)
+    {
+      zeroLoc.dist = 0;
+      zeroLoc.part = 0;
+      zeroLoc.pos = Vector();
+      zeroLoc.rot = Quaternion();
+      loc = &zeroLoc;
+    }
+  entity->init (loc, owner);
+  if (entity->bFree)
+    {
+      this->track[loc->part].map_coords( loc, entity->get_placement());
+    }
+  entity->post_spawn ();
   //return entity;
 }
+
+
+void World::spawn(WorldEntity* entity, Placement* plc)
+{
+  Placement zeroPlc;
+  WorldEntity* owner;
+  if( plc == NULL)
+    {
+      zeroPlc.r = Vector();
+      zeroPlc.w = Quaternion();
+      plc = &zeroPlc;
+    }
+  this->entities->add (entity);
+  entity->init (plc, owner);
+  entity->post_spawn ();
+  //return entity;
+}
Index: orxonox/trunk/src/world.h
===================================================================
--- orxonox/trunk/src/world.h	(revision 2811)
+++ orxonox/trunk/src/world.h	(revision 2816)
@@ -49,9 +49,10 @@
   bool system_command (Command* cmd);
   Camera* getCamera();
-  //private:
 
   void spawn(WorldEntity* entity);
+  void spawn(WorldEntity* entity, Location* loc);
+  void spawn(WorldEntity* entity, Placement* plc);
 
-  List<WorldEntity>* entities;
+  List* entities;
   
   // base level data
