Index: /trunk/src/defs/class_id.h
===================================================================
--- /trunk/src/defs/class_id.h	(revision 8189)
+++ /trunk/src/defs/class_id.h	(revision 8190)
@@ -1,2 +1,3 @@
+
 /*
    orxonox - the future of 3D-vertical-scrollers
@@ -253,8 +254,18 @@
   CL_COLLISION                  =    0x00000711,
   CL_COLLISION_HANDLE           =    0x00000712,
+  CL_COLLISION_REACTION         =    0X00000713,
+  CL_CR_PHYSICS_MOMENTUM        =    0X00000714,
+  CL_CR_PHYSICS_GROUND          =    0X00000715,
+  CL_CR_PHYSICS_GROUND_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                   =    0x00000714,
-  CL_OBB_TREE_NODE              =    0x00000715,
+  CL_OBB_TREE                   =    0x00000721,
+  CL_OBB_TREE_NODE              =    0x00000722,
   CL_BOUNDING_VOLUME            =    0x00710000,
   CL_OBB                        =    0x00720000,
Index: /trunk/src/lib/BuildLibs.am
===================================================================
--- /trunk/src/lib/BuildLibs.am	(revision 8189)
+++ /trunk/src/lib/BuildLibs.am	(revision 8190)
@@ -13,4 +13,5 @@
                 $(LIB_PREFIX)/particles/libORXparticles.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 \
Index: /trunk/src/lib/collision_detection/Makefile.am
===================================================================
--- /trunk/src/lib/collision_detection/Makefile.am	(revision 8189)
+++ /trunk/src/lib/collision_detection/Makefile.am	(revision 8190)
@@ -5,5 +5,4 @@
 
 libORXcd_a_SOURCES = cd_engine.cc \
-                     collision.cc \
                      obb.cc \
                      obb_tree.cc \
@@ -17,5 +16,4 @@
 noinst_HEADERS =     cd_engine.h \
                      collision_defs.h \
-                     collision.h \
                      obb.h \
                      obb_tree.h \
Index: unk/src/lib/collision_detection/collision.cc
===================================================================
--- /trunk/src/lib/collision_detection/collision.cc	(revision 8189)
+++ 	(revision )
@@ -1,40 +1,0 @@
-/*
-   orxonox - the future of 3D-vertical-scrollers
-
-   Copyright (C) 2004 orx
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU 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 "collision.h"
-
-using namespace std;
-
-
-/**
- *  standard constructor
-*/
-Collision::Collision ()
-{
-   this->setClassID(CL_COLLISION, "Collision");
-
-}
-
-
-/**
- *  standard deconstructor
-
-*/
-Collision::~Collision ()
-{
-  // delete what has to be deleted here
-}
Index: unk/src/lib/collision_detection/collision.h
===================================================================
--- /trunk/src/lib/collision_detection/collision.h	(revision 8189)
+++ 	(revision )
@@ -1,30 +1,0 @@
-/*! 
- * @file collision.h
-  *  Definition of a collision event
-
-*/
-
-#ifndef _COLLISION_H
-#define _COLLISION_H
-
-#include "base_object.h"
-#include "vector.h"
-
-
-class WorldEntity;
-class BoundingVolume;
-
-//! A class representing a simple collision
-class Collision : public BaseObject {
-
- public:
-  Collision();
-  virtual ~Collision();
-
- public:
-  Vector            pointOfImpact;              //!< point of impact, approximated via bounding volumes
-  WorldEntity*      body;                       //!< the collision body
-  BoundingVolume*   boundingVolume;             //!< reference to the bounding volume that fired the collision
-};
-
-#endif /* _COLLISION_H */
Index: /trunk/src/lib/collision_detection/obb_tree_node.cc
===================================================================
--- /trunk/src/lib/collision_detection/obb_tree_node.cc	(revision 8189)
+++ /trunk/src/lib/collision_detection/obb_tree_node.cc	(revision 8190)
@@ -481,31 +481,45 @@
     PRINTF(5)("collision @ lvl %i, object %s vs. %s, (%p, %p)\n", this->depth, nodeA->getClassName(), nodeB->getClassName(), this->nodeLeft, this->nodeRight);
 
-    /* check if left node overlaps */
+
+    // left node
     if( this->nodeLeft != NULL )
     {
-      PRINTF(5)("Checking OBB %i vs %i: ", this->nodeLeft->getIndex(), treeNode->getIndex());
       if( this->overlapTest(this->nodeLeft->bvElement, treeNode->bvElement, nodeA, nodeB))
       {
-        this->nodeLeft->collideWith(treeNode->nodeLeft, nodeA, nodeB);
-        this->nodeLeft->collideWith(treeNode->nodeRight, nodeA, nodeB);
+        if( treeNode->nodeLeft != NULL)
+          this->nodeLeft->collideWith(treeNode->nodeLeft, nodeA, nodeB);
+        if( treeNode->nodeRight != NULL)
+          this->nodeLeft->collideWith(treeNode->nodeRight, nodeA, nodeB);
       }
     }
-    /* check if right node overlaps */
-    if( likely( this->nodeRight != NULL))
-    {
-      PRINTF(5)("Checking OBB %i vs %i: ", this->nodeRight->getIndex(), treeNode->getIndex());
-      if(this->overlapTest(this->nodeRight->bvElement, treeNode->bvElement, nodeA, nodeB))
+
+    // right node
+    if( this->nodeRight != NULL )
+    {
+      if( this->overlapTest(this->nodeRight->bvElement, treeNode->bvElement, nodeA, nodeB))
       {
-        this->nodeRight->collideWith(treeNode->nodeLeft, nodeA, nodeB);
-        this->nodeRight->collideWith(treeNode->nodeRight, nodeA, nodeB);
+        if( treeNode->nodeLeft != NULL)
+          this->nodeRight->collideWith(treeNode->nodeLeft, nodeA, nodeB);
+        if( treeNode->nodeRight != NULL)
+          this->nodeRight->collideWith(treeNode->nodeRight, nodeA, nodeB);
       }
     }
 
-    /* so there is a collision and this is the last box in the tree (i.e. leaf) */
-    if( unlikely((this->nodeRight == NULL || this->nodeLeft == NULL) ||
-                 (treeNode->nodeRight == NULL || treeNode->nodeLeft == NULL)) )
-    {
-      nodeA->collidesWith(nodeB, treeNode->bvElement->center);
-      nodeB->collidesWith(nodeA, this->bvElement->center);
+
+    // 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);
     }
 
Index: /trunk/src/lib/collision_reaction/Makefile.am
===================================================================
--- /trunk/src/lib/collision_reaction/Makefile.am	(revision 8189)
+++ /trunk/src/lib/collision_reaction/Makefile.am	(revision 8190)
@@ -5,9 +5,18 @@
 
 libORXcr_a_SOURCES = cr_engine.cc \
-                     collision_handle.cc
+                     collision.cc \
+                     collision_event.cc \
+                     collision_handle.cc \
+                     collision_reaction.cc \
+                     cr_object_damage.cc
 
 
 
 noinst_HEADERS =     cr_engine.h \
- 										 collision_handle.h
+                     collision.h \
+                     collision_event.h \
+                     collision_handle.h \
+                     cr_defs.h \
+                     collision_reaction.h \
+                     cr_object_damage.h
 
Index: /trunk/src/lib/collision_reaction/collision.cc
===================================================================
--- /trunk/src/lib/collision_reaction/collision.cc	(revision 8190)
+++ /trunk/src/lib/collision_reaction/collision.cc	(revision 8190)
@@ -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: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
+
+#include "collision.h"
+#include "debug.h"
+
+using namespace std;
+
+
+/**
+ *  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: /trunk/src/lib/collision_reaction/collision.h
===================================================================
--- /trunk/src/lib/collision_reaction/collision.h	(revision 8190)
+++ /trunk/src/lib/collision_reaction/collision.h	(revision 8190)
@@ -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; }
+
+
+    /** @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: /trunk/src/lib/collision_reaction/collision_event.cc
===================================================================
--- /trunk/src/lib/collision_reaction/collision_event.cc	(revision 8190)
+++ /trunk/src/lib/collision_reaction/collision_event.cc	(revision 8190)
@@ -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: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION_REACTION
+
+#include "collision_event.h"
+#include "debug.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+ */
+CollisionEvent::CollisionEvent ()
+{
+  this->entityA = NULL;
+  this->entityB = NULL;
+  this->bvA = NULL;
+  this->bvB = NULL;
+}
+
+
+/**
+ *  standard deconstructor
+ */
+CollisionEvent::~CollisionEvent ()
+{
+}
+
+
+
Index: /trunk/src/lib/collision_reaction/collision_event.h
===================================================================
--- /trunk/src/lib/collision_reaction/collision_event.h	(revision 8190)
+++ /trunk/src/lib/collision_reaction/collision_event.h	(revision 8190)
@@ -0,0 +1,56 @@
+/*!
+ * @file collision_event.h
+ *  Definition of a collision event
+ */
+
+#ifndef _COLLISION_EVENT_H
+#define _COLLISION_EVENT_H
+
+#include "vector.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(WorldEntity* entityA, WorldEntity* entityB, BoundingVolume* bvA, BoundingVolume* bvB)
+  { 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(WorldEntity* entity, Plane* ground, Vector position)
+  { this->entityA = entity; this->ground = ground; this->position = position; }
+
+
+  /** @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; }
+
+
+  inline void operator()(WorldEntity* entityA, WorldEntity* entityB, BoundingVolume* bvA, BoundingVolume* bvB) { this->collide(entityA, entityB, bvA, bvB); }
+  inline void operator()(WorldEntity* entity, Plane* ground, Vector position) { this->collide(entity, ground, position); }
+
+
+ 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
+
+  Plane*            ground;                        //!< the ground plane with which it collides (only for bsp-model collisions
+  Vector            position;                      //!< position of the collision on the ground plane
+};
+
+#endif /* _COLLISION_EVENT_H */
Index: /trunk/src/lib/collision_reaction/collision_handle.cc
===================================================================
--- /trunk/src/lib/collision_reaction/collision_handle.cc	(revision 8189)
+++ /trunk/src/lib/collision_reaction/collision_handle.cc	(revision 8190)
@@ -17,4 +17,12 @@
 #include "collision_handle.h"
 
+#include "world_entity.h"
+
+#include "collision.h"
+#include "collision_event.h"
+#include "collision_reaction.h"
+
+#include "cr_object_damage.h"
+
 using namespace std;
 
@@ -31,4 +39,25 @@
   this->type = type;
 
+  this->bCollided = false;
+  this->bDispatched = false;
+
+  if( this->type == CREngine::CR_PHYSICS_STEP_BACK)
+    this->bContinuousPoll = false;
+  else
+    this->bContinuousPoll = true;
+
+  if( this->type == CREngine::CR_OBJECT_DAMAGE)
+    this->bStopOnFirstCollision = true;
+  else
+   this->bStopOnFirstCollision = false;
+
+  switch( type)
+  {
+    case CREngine::CR_OBJECT_DAMAGE:
+      this->collisionReaction = new CRObjectDamage();
+      break;
+    default:
+      break;
+  };
 }
 
@@ -41,2 +70,181 @@
   // delete what has to be deleted here
 }
+
+/**
+ * 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(long target)
+{
+  // make sure there is no dublicate
+  std::vector<long>::iterator it = this->targetList.begin();
+  for( ; it < this->targetList.end(); it++)
+    if( (*it) == target)
+      return;
+
+  // add element
+   PRINTF(0)("addTarget: %i \n", target);
+   this->targetList.push_back(target);
+}
+
+
+/**
+ * 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);
+}
+
+
+/**
+ * flushes the collision list
+ */
+void CollisionHandle::flushCollisions()
+{
+  this->collisionList.clear();
+}
+
+
+/**
+ * handles the collisions and react according to algorithm
+ */
+void CollisionHandle::handleCollisions()
+{
+  // collision reaction calculations (for every collision there will be a reaction)
+  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)
+{
+  vector<long>::iterator it = this->targetList.begin();
+  for(; it < this->targetList.end(); it++)
+  {
+    if( collisionEvent->getEntityA() == this->owner) {
+      if( collisionEvent->getEntityA()->isA((ClassID)(*it)))
+        return true; }
+    else {
+      if( collisionEvent->getEntityB()->isA((ClassID)(*it)))
+        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)
+{
+  vector<long>::iterator it = this->targetList.begin();
+  for(; it < this->targetList.end(); it++)
+  {
+    if( collision->getEntityA() == this->owner) {
+      if( collision->getEntityA()->isA((ClassID)(*it)))
+        return true; }
+      else {
+        if( collision->getEntityB()->isA((ClassID)(*it)))
+          return true; }
+  }
+
+  return false;
+}
+
+
+
+
+
+
+
Index: /trunk/src/lib/collision_reaction/collision_handle.h
===================================================================
--- /trunk/src/lib/collision_reaction/collision_handle.h	(revision 8189)
+++ /trunk/src/lib/collision_reaction/collision_handle.h	(revision 8190)
@@ -11,36 +11,58 @@
 
 #include <vector>
+#include <list>
 
 
 class Collision;
 class WorldEntity;
+class CollisionReaction;
 
-// struct CRType;
 
 
 //! A class for defining collision reactions and storing events
-class CollisionHandle : public BaseObject {
+class CollisionHandle : public BaseObject
+{
 
- public:
-  CollisionHandle(WorldEntity* owner, CREngine::CRType type);
-  virtual ~CollisionHandle();
+  public:
+    CollisionHandle(WorldEntity* owner, CREngine::CRType type);
+    virtual ~CollisionHandle();
+
+    void reset();
+
+    void addTarget(long 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; }
+
+    void handleCollisions();
 
 
-  void addTarget();
-
-  void registerCollision(Collision* collision);
-
-  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                          bDispatched;             //!< true if this handle has already been dispatched
-   bool                          bStopOnFirstCollision;   //!< true if the cd of this object should be terminated after one match
+  private:
+    WorldEntity*                  owner;                   //!< the worldenity this reaction will be applied on
+    CREngine::CRType              type;                    //!< the reaction type
 
-   std::vector<Collision*>       collisionList;           //!< a list full of collisions
-   std::vector<long>             targetList;              //!< a list of target classes for filtering
+    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
+    std::vector<long>             targetList;              //!< a list of target classes for filtering
+
+    CollisionReaction*            collisionReaction;       //!< reference to the collision reaction object
 
 };
Index: /trunk/src/lib/collision_reaction/collision_reaction.cc
===================================================================
--- /trunk/src/lib/collision_reaction/collision_reaction.cc	(revision 8190)
+++ /trunk/src/lib/collision_reaction/collision_reaction.cc	(revision 8190)
@@ -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"
+
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+ */
+CollisionReaction::CollisionReaction ()
+  : BaseObject()
+{
+  this->setClassID(CL_COLLISION_REACTION, "CollisionReaction");
+}
+
+
+/**
+ *  standard deconstructor
+ */
+CollisionReaction::~CollisionReaction ()
+{
+}
+
Index: /trunk/src/lib/collision_reaction/collision_reaction.h
===================================================================
--- /trunk/src/lib/collision_reaction/collision_reaction.h	(revision 8190)
+++ /trunk/src/lib/collision_reaction/collision_reaction.h	(revision 8190)
@@ -0,0 +1,31 @@
+/*!
+ * @file collision_reaction.h
+ *  Definition of a generic collision reaction
+ */
+
+#ifndef _COLLISION_REACTION_H
+#define _COLLISION_REACTION_H
+
+#include "base_object.h"
+
+
+
+class Collision;
+
+//! A class representing a simple collision
+class CollisionReaction : public BaseObject
+{
+
+  public:
+    CollisionReaction();
+    virtual ~CollisionReaction();
+
+    virtual void reactToCollision(Collision* collision) = 0;
+
+    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: /trunk/src/lib/collision_reaction/cr_defs.h
===================================================================
--- /trunk/src/lib/collision_reaction/cr_defs.h	(revision 8190)
+++ /trunk/src/lib/collision_reaction/cr_defs.h	(revision 8190)
@@ -0,0 +1,31 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU 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
+
+
+
+#endif /* _NETWORK_MANAGER */
Index: /trunk/src/lib/collision_reaction/cr_engine.cc
===================================================================
--- /trunk/src/lib/collision_reaction/cr_engine.cc	(revision 8189)
+++ /trunk/src/lib/collision_reaction/cr_engine.cc	(revision 8190)
@@ -16,4 +16,11 @@
 #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"
 
@@ -25,8 +32,10 @@
  */
 CREngine::CREngine ()
+  : BaseObject()
 {
    this->setClassID(CL_CR_ENGINE, "CREngine");
    this->setName("CREngine");
 
+   this->init();
 }
 
@@ -42,20 +51,128 @@
 {
   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();
+
+  vector<Collision*>::iterator it1 = this->collisionsUnused.begin();
+  for(; it1 < this->collisionsUnused.end(); it1++)
+    delete *it1;
+  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
 
+  vector<CollisionHandle*>::iterator it = this->collisionHandles.begin();
+  for(; it < this->collisionHandles.end(); it++)
+  {
+    (*it)->reset();
+    delete *it;
+  }
 
-CollisionHandle* CREngine::subscribeReaction(WorldEntity* owner, CRType type, int nrOfTargets, ...)
-{
-
-  va_list itemlist;
-  va_start (itemlist, type);
-//  for (int i = 0; i < nrOfTargets; i++)
-  //  this->targetList.push_back(va_arg(itemlist, int));
-  va_end(itemlist);
+  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)->isCollided() || (*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()
+{
+  vector<Collision*>::iterator it1 = this->collisionsUsed.begin();
+  for(; it1 < this->collisionsUsed.end(); it1++)
+    this->collisionsUnused.push_back(*it1);
+
+  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: /trunk/src/lib/collision_reaction/cr_engine.h
===================================================================
--- /trunk/src/lib/collision_reaction/cr_engine.h	(revision 8189)
+++ /trunk/src/lib/collision_reaction/cr_engine.h	(revision 8190)
@@ -2,5 +2,10 @@
  * @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_
@@ -8,5 +13,5 @@
 
 #include "base_object.h"
-#include <stdarg.h>
+
 #include <vector>
 
@@ -14,4 +19,5 @@
 class CollisionHandle;
 class Collision;
+class CollisionEvent;
 class WorldEntity;
 
@@ -22,14 +28,16 @@
   public:
   typedef enum CRType {
-    CR_PHYSICS_MOMENTUM   = 0,
-    CR_PHYSICS_GROUND,
-    CR_PHYSICS_GROUND_WALK,
+    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,            //!< physical reaction: stand on the ground, no movement: simulating simple normal force away from the gravity force
+    CR_PHYSICS_GROUND_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,
-    CR_OBJECT_PICKUP,
+    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,
+    CR_VERTEX_TRAFO,              //!< vertex trafo: transforming the vertex according to the damage
 
-    CR_SPECIAL_CALLBACK,
+    CR_SPECIAL_CALLBACK,          //!< special: call a callback function
 
     CR_NUMBER
@@ -39,28 +47,44 @@
 
   /** @returns a Pointer to the only object of this Class */
-  inline static CREngine* getInstance(void) { if (!singletonRef) singletonRef = new CREngine();  return singletonRef; };
+  inline static CREngine* getInstance() { if (!singletonRef) singletonRef = new CREngine();  return singletonRef; };
+
+  void reset();
 
 
-  CollisionHandle* subscribeReaction(WorldEntity* worldEntity, CRType type, int nrOfTargets, ...);
+  CollisionHandle* subscribeReaction(WorldEntity* worldEntity, CRType type);
 
-  bool unsubscribeReaction(WorldEntity* worldEntity);
   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* getCollisionObject() { /* return the first element of the cache list*/ }
-  /** @param collision: returns the Collision object back to the cache list */
-  inline void putCollisionObject(Collision* collision) { this->cachedCollisions.push_back(collision); }
+  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);
+  CREngine();
+  void init();
+
+  void flushCollisions();
 
 
 private:
   std::vector<CollisionHandle*>       collisionHandles;         //!< list with the collision handles
-  std::vector<Collision*>             cachedCollisions;         //!< a list of unused, cached collision events
+
+  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)
Index: /trunk/src/lib/collision_reaction/cr_object_damage.cc
===================================================================
--- /trunk/src/lib/collision_reaction/cr_object_damage.cc	(revision 8190)
+++ /trunk/src/lib/collision_reaction/cr_object_damage.cc	(revision 8190)
@@ -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: 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"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+ */
+CRObjectDamage::CRObjectDamage ()
+  : CollisionReaction()
+{
+  this->setClassID(CL_CR_OBJECT_DAMAGE, "CRObjectDamage");
+
+}
+
+
+/**
+ *  standard deconstructor
+ */
+CRObjectDamage::~CRObjectDamage ()
+{
+}
+
+
+/**
+ * caluculates and applys the reaction to a specific collision
+ *  @param collision the collision
+ */
+void CRObjectDamage::reactToCollision(Collision* collision)
+{
+  float damage;
+
+  PRINTF(0)("Dealing damage - Handling collision: %s vs %s\n",
+            collision->getEntityA()->getClassName(),
+            collision->getEntityB()->getClassName());
+
+  // the collision damage been dealed by the entity
+  if( collision->isEntityACollide()) {
+    damage = collision->getEntityB()->getDamage();
+    collision->getEntityA()->decreaseHealth(damage);
+  }
+  PRINTF(0)("Dealing damage - %f damage to %s \n", damage, collision->getEntityA()->getClassName());
+
+  if( collision->isEntityBCollide()) {
+    damage = collision->getEntityA()->getDamage();
+    collision->getEntityB()->decreaseHealth(damage);
+  }
+  PRINTF(0)("Dealing damage - %f damage to %s \n", damage, collision->getEntityB()->getClassName());
+
+  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: /trunk/src/lib/collision_reaction/cr_object_damage.h
===================================================================
--- /trunk/src/lib/collision_reaction/cr_object_damage.h	(revision 8190)
+++ /trunk/src/lib/collision_reaction/cr_object_damage.h	(revision 8190)
@@ -0,0 +1,27 @@
+/*!
+ * @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
+{
+  public:
+    CRObjectDamage();
+    virtual ~CRObjectDamage();
+
+    virtual void reactToCollision(Collision* collision);
+
+  private:
+
+};
+
+#endif /* _CR_OBJECT_DAMAGE_H */
Index: /trunk/src/lib/graphics/effects/atmospheric_engine.cc
===================================================================
--- /trunk/src/lib/graphics/effects/atmospheric_engine.cc	(revision 8189)
+++ /trunk/src/lib/graphics/effects/atmospheric_engine.cc	(revision 8190)
@@ -127,5 +127,5 @@
     for (it = weatherEffects->begin(); it != weatherEffects->end(); it++)
     {
-      printf("%s::%s \n", (*it)->getClassName(), (*it)->getName());
+/*      printf("%s::%s \n", (*it)->getClassName(), (*it)->getName());*/
       dynamic_cast<WeatherEffect*>(*it)->tick(dt);
     }
Index: /trunk/src/lib/physics/physics_interface.h
===================================================================
--- /trunk/src/lib/physics/physics_interface.h	(revision 8189)
+++ /trunk/src/lib/physics/physics_interface.h	(revision 8190)
@@ -39,4 +39,9 @@
   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);
@@ -51,4 +56,7 @@
   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
Index: /trunk/src/story_entities/game_world.cc
===================================================================
--- /trunk/src/story_entities/game_world.cc	(revision 8189)
+++ /trunk/src/story_entities/game_world.cc	(revision 8190)
@@ -136,5 +136,5 @@
   AnimationPlayer::getInstance();
   PhysicsEngine::getInstance();
-
+  CREngine::getInstance();
 }
 
@@ -199,4 +199,5 @@
   delete AnimationPlayer::getInstance();
   delete PhysicsEngine::getInstance();
+  delete CREngine::getInstance();
 
   State::setCurrentStoryEntity(NULL);
@@ -278,6 +279,8 @@
     /* process time */
     this->tick ();
-    /* process collision */
-    this->collide ();
+    /* collision detection */
+    this->collisionDetection ();
+    /* collision reaction */
+    this->collisionReaction ();
     /* update the state */
     this->update ();
@@ -408,5 +411,5 @@
  * kicks the CDEngine to detect the collisions between the object groups in the world
  */
-void GameWorld::collide()
+void GameWorld::collisionDetection()
 {
   CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getObjectList(OM_GROUP_00),
@@ -422,4 +425,10 @@
       this->dataTank->objectManager->getObjectList(OM_COMMON));
 
+}
+
+
+void GameWorld::collisionReaction()
+{
+  CREngine::getInstance()->handleCollisions();
 }
 
Index: /trunk/src/story_entities/game_world.h
===================================================================
--- /trunk/src/story_entities/game_world.h	(revision 8189)
+++ /trunk/src/story_entities/game_world.h	(revision 8190)
@@ -68,5 +68,6 @@
     virtual void update();
     virtual void checkGameRules();
-    virtual void collide();
+    virtual void collisionDetection();
+    virtual void collisionReaction();
 
     void drawEntityList(const ObjectManager::EntityList& drawList ) const;
Index: /trunk/src/world_entities/projectiles/projectile.cc
===================================================================
--- /trunk/src/world_entities/projectiles/projectile.cc	(revision 8189)
+++ /trunk/src/world_entities/projectiles/projectile.cc	(revision 8190)
@@ -38,4 +38,8 @@
   this->target = NULL;
   this->removeNode();
+
+  /* character attributes */
+  this->setHealth(1.0f);
+  this->setDamage(100.0f); // default damage of a projectile set to 100.0 damage points
 
   this->explosionBuffer = NULL;
Index: /trunk/src/world_entities/world_entity.cc
===================================================================
--- /trunk/src/world_entities/world_entity.cc	(revision 8189)
+++ /trunk/src/world_entities/world_entity.cc	(revision 8190)
@@ -32,6 +32,8 @@
 #include "camera.h"
 
-#include "cr_engine.h"
 #include "collision_handle.h"
+#include "collision_event.h"
+
+#include <stdarg.h>
 
 
@@ -59,4 +61,5 @@
   this->healthMax = 1.0f;
   this->health = 1.0f;
+  this->damage = 0.0f; // no damage dealt by a default entity
   this->scaling = 1.0f;
 
@@ -68,4 +71,13 @@
   this->objectListIterator = NULL;
 
+  // reset all collision handles to NULL == unsubscribed state
+  for(int i = 0; i < CREngine::CR_NUMBER; ++i)
+    this->collisionHandles[i] = NULL;
+  this->bReactive = false;
+
+  // registering default reactions:
+  this->subscribeReaction(CREngine::CR_OBJECT_DAMAGE, CL_WORLD_ENTITY);
+  this->subscribeReaction(CREngine::CR_PHYSICS_GROUND, CL_TERRAIN);
+
   this->toList(OM_NULL);
 
@@ -91,4 +103,6 @@
   if (this->healthWidget != NULL)
     delete this->healthWidget;
+
+  this->unsubscribeReaction();
 }
 
@@ -249,9 +263,166 @@
  * 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, long 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, long target1, long 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, long target1, long target2, long 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, long target1, long target2, long target3, long 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, int nrOfTargets, ...)
-{}
+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)
+{
+  // 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(entityA, entityB, bvA, bvB);
+
+  for( int i = 0; i < CREngine::CR_NUMBER; ++i)
+    if( this->collisionHandles[i] != NULL)
+      this->collisionHandles[i]->registerCollisionEvent(c);
+}
+
+
+/**
+ * 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(WorldEntity* entity, Plane* plane, Vector position)
+{
+  // 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(entity, plane, position);
+
+  for( int i = 0; i < CREngine::CR_NUMBER; ++i)
+    if( this->collisionHandles[i] != NULL)
+      this->collisionHandles[i]->registerCollisionEvent(c);
+}
 
 
@@ -324,7 +495,7 @@
 void WorldEntity::collidesWithGround(const Vector& feet, const Vector& ray_1, const Vector& ray_2)
 {
-  
+
   // PRINTF(0)("BSP_GROUND: Player collides \n", this->getClassName() );
-  
+
   Vector v = this->getAbsDirX();
   v.x *= 10;
@@ -332,8 +503,8 @@
   v.z *= 10;
   Vector u = this->getAbsDirY();
-  
+
   if(feet.x == (u.x+this->getAbsCoor().x) &&  feet.y == u.y +this->getAbsCoor().y && feet.z == this->getAbsCoor().z)
   {
-    
+
   this->setAbsCoor(ray_2 - v);
   }
@@ -342,9 +513,9 @@
     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->setAbsCoor(feet -u );
+    }
+
+    this->setAbsCoor(ray_2 - v);
+
   }
 }
Index: /trunk/src/world_entities/world_entity.h
===================================================================
--- /trunk/src/world_entities/world_entity.h	(revision 8189)
+++ /trunk/src/world_entities/world_entity.h	(revision 8190)
@@ -15,5 +15,6 @@
 #include "glincl.h"
 #include <vector>
-#include <stdarg.h>
+
+#include "physics_interface.h"
 
 
@@ -24,6 +25,9 @@
 
 class BVTree;
+class BoundingVolume;
 class Model;
 class CollisionHandle;
+class Collision;
+class Plane;
 
 
@@ -72,5 +76,19 @@
 
   /* --- Collision Reaction Block --- */
-  void subscribeReaction(CREngine::CRType type, int nrOfTargets, ...);
+  void subscribeReaction(CREngine::CRType type);
+  void subscribeReaction(CREngine::CRType type, long target1);
+  void subscribeReaction(CREngine::CRType type, long target1, long target2);
+  void subscribeReaction(CREngine::CRType type, long target1, long target2, long target3);
+  void subscribeReaction(CREngine::CRType type, long target1, long target2, long target3, long target4);
+
+  void unsubscribeReaction(CREngine::CRType type);
+  void unsubscribeReaction();
+
+  bool registerCollision(WorldEntity* entityA, WorldEntity* entityB, BoundingVolume* bvA, BoundingVolume* bvB);
+  bool registerCollision(WorldEntity* entity, Plane* plane, Vector position);
+  /** @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]; }
 
 
@@ -98,4 +116,8 @@
 
   /* --- Character Attribute Block --- */
+  /** @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; };
@@ -107,6 +129,14 @@
   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(); }
+
 
   /* --- Misc Stuff Block --- */
@@ -128,4 +158,5 @@
 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.
@@ -140,17 +171,19 @@
   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                 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.
 
-  
-  //network stuff
-  
-  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
-  CollisionHandle**       collisionHandles;
 
+
+  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
+
+  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
 
 };
