Index: /branches/playability/src/world_entities/Makefile.am
===================================================================
--- /branches/playability/src/world_entities/Makefile.am	(revision 10080)
+++ /branches/playability/src/world_entities/Makefile.am	(revision 10081)
@@ -11,5 +11,5 @@
 					extendable.cc 		power_ups/power_up.cc 		power_ups/param_power_up.cc \
 			power_ups/weapon_power_up.cc 				spawning_point.cc 						effects/explosion.cc 		effects/billboard.cc \
-							elements/glgui_energywidget.cc
+			effects/trail.cc				elements/glgui_energywidget.cc
 
 
@@ -18,5 +18,5 @@
 			weapons/weapon.h 		weapons/ammo_container.h 		projectiles/projectile.h \
 					power_ups/power_up.h 		power_ups/param_power_up.h 		power_ups/weapon_power_up.h \
-					spawning_point.h 						effects/explosion.h 		effects/billboard.h \
+					spawning_point.h 						effects/explosion.h 		effects/billboard.h		effects/trail.h \
 									elements/glgui_energywidget.h 					
 
Index: /branches/playability/src/world_entities/effects/trail.cc
===================================================================
--- /branches/playability/src/world_entities/effects/trail.cc	(revision 10081)
+++ /branches/playability/src/world_entities/effects/trail.cc	(revision 10081)
@@ -0,0 +1,402 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+
+   Trail system for engine output trails.
+   uses a catmull rom spline to interpolate the curve which is subdivided
+   into sections parts.
+   main-programmer: Marc Schaerer
+*/
+
+#include "trail.h"
+
+#include "util/loading/load_param.h"
+#include "util/loading/factory.h"
+
+#include "quaternion.h"
+#include "vector.h"
+
+#include "graphics_engine.h"
+#include "material.h"
+#include "glincl.h"
+#include "state.h"
+#include "debug.h"
+
+#include "class_id_DEPRECATED.h"
+
+ObjectListDefinition(Trail);
+CREATE_FACTORY(Trail);
+
+/**
+ * standart constructor
+ * @param maxLength maximum length of the trail. You will later need to set the actual length used.
+ * @param sections number of sections into which the trail polygon shall be splited. Higher number for more smooth curves
+ * @param radius radius of the trail cross.
+ * 
+ */
+Trail::Trail (float maxLength, int sections, float radius)
+{
+  this->maxLength = maxLength;
+  this->length    = 1.0;
+  this->sections  = sections;
+  this->radius    = radius;
+
+  this->nodeList  = new Vector[sections];
+
+
+  this->init();
+}
+
+Trail::Trail (const TiXmlElement* root)
+{
+  this->init();
+
+  if( root)
+    this->loadParams(root);
+}
+
+/**
+ * destroys a Trail
+ */
+Trail::~Trail ()
+{
+  if (this->material)
+    delete this->material;
+  delete this->nodeList;
+}
+
+
+/**
+ * initializes the Trail
+ */
+void Trail::init()
+{
+  this->registerObject(this, Trail::_objectList);
+  this->setName("Trail");
+
+  this->material = new Material();
+  this->material->setIllum(3);
+  this->material->setDiffuse(1.0,1.0,1.0);
+  this->material->setSpecular(0.0,0.0,0.0);
+  this->material->setAmbient(1.0, 1.0, 1.0);
+
+  this->setAbsCoor(0, 0, 0);
+  this->setVisibiliy(true);
+
+  this->nodeList[0] = (this->getAbsCoor());
+  //PRINTF(0)("Trail data: N%i (%f,%f,%f)",0,this->getAbsCoor().x,this->getAbsCoor().y,this->getAbsCoor().z);
+  for( int i = 1; i < sections; i++)
+  {
+    this->nodeList[i] = (this->getAbsCoor() - ((Vector(1,0,0) * (i * this->maxLength / sections))));
+    //PRINTF(0)(" N%i (%f,%f,%f)",i,this->nodeList[i].x,this->nodeList[i].y,this->nodeList[i].z);
+  }
+  //PRINTF(0)("\n");
+}
+
+
+/**
+ *  load params
+ * @param root TiXmlElement object
+ */
+void Trail::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams( root);
+}
+
+/**
+ * sets the material to load
+ * @param textureFile The texture-file to load
+ */
+void Trail::setTexture(const std::string& textureFile)
+{
+  this->material->setDiffuseMap(textureFile);
+}
+
+
+/**
+ * ticks the Trail
+ * @param dt the time to ticks
+ */
+void Trail::tick(float dt)
+{
+  // Update node positions
+  float secLen  = this->maxLength / this->sections;
+  this->nodeList[0] = (this->getAbsCoor());
+  for(int i = 1; i < this->sections; i++)
+  {
+    this->nodeList[i] = this->nodeList[i-1] - (this->nodeList[i-1] - this->nodeList[i]).getNormalized()*secLen;
+  }
+  /*
+  this->length  = this->maxLength / (this->getAbsCoor() - this->nodeList[this->sections-1]).len();
+  if (!likely(this->length == 1.0))
+    for(int i = 1; i < this->sections; i++)
+      this->nodeList[i] = this->getAbsCoor()- (this->getAbsCoor() - this->nodeList[i])*this->length;
+  */
+  /*PRINTF(0)("TRAIL POS ");
+  for( int i=0; i < this->sections; i++)
+  {
+    PRINTF(0)("N%i (%f,%f,%f)",i,this->nodeList[i].x,this->nodeList[i].y,this->nodeList[i].z);
+  }
+  PRINTF(0)("\n");*/
+}
+
+
+/**
+ * draws the trail
+ * the trail has a cone shape
+ */
+void Trail::draw() const
+{
+  if(!this->isVisible())
+    return;
+
+  Vector* Q = new Vector[4];
+  Vector targ;
+  Vector now, later;
+  float fact  = 1.0/this->sections;
+  float rad0, rad1;
+
+  //glPushAttrib(GL_ENABLE_BIT);
+  
+  glPushMatrix();
+  //glMatrixMode(GL_MODELVIEW);
+  //glLoadIdentity();
+  glTranslatef(-this->getAbsCoor().x,-this->getAbsCoor().y,-this->getAbsCoor().z);
+  glScalef(1,1,1);
+  this->material->select();
+  /*
+  glBegin(GL_TRIANGLESTRIP);
+  for( int i = 0; i < this->sections-1; i++)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i+1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i+1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // vertical polygon
+    Q[0]  = now + Vector(0,rad1,0) ;
+    Q[1]  = later + Vector(0,rad0,0) ;
+    Q[2]  = later + Vector(0,-rad0,0) ;
+    Q[3]  = now + Vector(0,-rad1,0) ;
+    //PRINTF(0)("Debug output: Q0 (%f,%f,%f) :: Q1 (%f,%f,%f) :: Q2 (%f,%f,%f) :: Q3 (%f,%f,%f)\n",Q[0].x,Q[0].y,Q[0].z,Q[1].x,Q[1].y,Q[1].z,Q[2].x,Q[2].y,Q[2].z,Q[3].x,Q[3].y,Q[3].z);
+
+      glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+      glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+      glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+      glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+    
+  }
+  glEnd();
+  glBegin(GL_TRIANGLESTRIP);
+  for( int i = 0; i < this->sections-1; i++)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i+1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i+1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // vertical polygon
+    Q[0]  = now + Vector(0,rad1,0) ;
+    Q[1]  = later + Vector(0,rad0,0) ;
+    Q[2]  = later + Vector(0,-rad0,0) ;
+    Q[3]  = now + Vector(0,-rad1,0) ;
+    //PRINTF(0)("Debug output: Q0 (%f,%f,%f) :: Q1 (%f,%f,%f) :: Q2 (%f,%f,%f) :: Q3 (%f,%f,%f)\n",Q[0].x,Q[0].y,Q[0].z,Q[1].x,Q[1].y,Q[1].z,Q[2].x,Q[2].y,Q[2].z,Q[3].x,Q[3].y,Q[3].z);
+
+      glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+      glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+      glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+      glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+    
+  }
+  glEnd();*/
+  glBegin(GL_TRIANGLE_STRIP);
+  for( int i = 1; i < this->sections-1; i++)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i+1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i+1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // horizontal polygon
+    Q[0]  = now + Vector(0,rad1,0) ;
+    Q[3]  = now + Vector(0,-rad1,0) ;
+    
+    glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+	glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+
+    if( i == this->sections - 1)
+    {
+      
+      Q[1]  = later + Vector(0,rad0,0) ;
+      Q[2]  = later + Vector(0,-rad0,0) ;
+      glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+      glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+    }
+
+
+  }
+  glEnd();
+  glBegin(GL_TRIANGLE_STRIP);
+  for( int i = this->sections-1; i > 0; i--)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i-1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i-1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // horizontal polygon
+    Q[0]  = now + Vector(0,rad1,0) ;
+    Q[3]  = now + Vector(0,-rad1,0) ;
+
+	glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+	glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+
+    if( i == 1)
+    {
+        Q[1]  = later + Vector(0,rad0,0) ;
+        Q[2]  = later + Vector(0,-rad0,0) ;
+		glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+		glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+	}
+
+  }
+  glEnd();
+
+
+  glBegin(GL_TRIANGLE_STRIP);
+  for( int i = 1; i < this->sections-1; i++)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i+1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i+1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // horizontal polygon
+    Q[0]  = now + targ.cross(Vector(0,rad1,0)) ;
+    Q[3]  = now + targ.cross(Vector(0,-rad1,0)) ;
+    
+	glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+	glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+
+    if( i == this->sections-1)
+    {
+      Q[1]  = later + targ.cross(Vector(0,rad0,0)) ;
+      Q[2]  = later + targ.cross(Vector(0,-rad0,0)) ;
+      glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+      glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+    }
+
+
+  }
+  glEnd();
+  glBegin(GL_TRIANGLE_STRIP);
+  for( int i = this->sections-1; i > 0; i--)
+  {
+    rad1  = this->radius * (1.0-i*fact);
+    rad0  = this->radius * (1.0-(i-1)*fact);
+
+    now   =  this->nodeList[i];
+    later =  this->nodeList[i-1];
+    if( i == 0)
+      targ  = this->getAbsDir().apply(Vector(1,0,0)).getNormalized();
+    else
+      targ  = (this->getAbsCoor() - now).getNormalized();
+
+    // horizontal polygon
+    Q[0]  = now + targ.cross(Vector(0,rad1,0)) ;
+    Q[3]  = now + targ.cross(Vector(0,-rad1,0)) ;
+
+	glTexCoord2f(0.0f, 0.0f); glVertex3f(Q[0].x,Q[0].y,Q[0].z);
+	glTexCoord2f(1.0f, 0.0f); glVertex3f(Q[3].x,Q[3].y,Q[3].z);
+
+    if( i == 1)
+    {
+        Q[1]  = later + targ.cross(Vector(0,rad0,0)) ;
+        Q[2]  = later + targ.cross(Vector(0,-rad0,0)) ;
+		glTexCoord2f(0.0f, 1.0f); glVertex3f(Q[1].x,Q[1].y,Q[1].z);
+		glTexCoord2f(1.0f, 1.0f); glVertex3f(Q[2].x,Q[2].y,Q[2].z);
+	}
+
+  }
+  glEnd();
+  this->material->unselect();
+
+  glPopMatrix();
+  //glPopAttrib();
+/*
+  //glTranslatef(this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z);
+  //glTranslatef(0,0,0);
+
+  const PNode* camera = State::getCameraNode();  //!< @todo MUST be different
+  Vector cameraPos = camera->getAbsCoor();
+  Vector cameraTargetPos = State::getCameraTargetNode()->getAbsCoor();
+  Vector view = cameraTargetPos - cameraPos;
+  Vector up = Vector(0, 1, 0);
+  up = camera->getAbsDir().apply(up);
+  Vector h = up.cross(view);
+  Vector v = h.cross(view);
+  h.normalize();
+  v.normalize();
+
+  v *= sizeX;
+  h *= sizeY;
+
+//v += this->getAbsCoor();
+    //PRINTF(0)("sizeX: %f sizeY: %f\n", sizeX, sizeY);
+  glBegin(GL_QUADS);
+  glTexCoord2f(0.0f, 0.0f);
+  glVertex3f(this->getAbsCoor().x - h.x - v.x,
+             this->getAbsCoor().y - h.y - v.y,
+             this->getAbsCoor().z - h.z - v.z);
+  glTexCoord2f(1.0f, 0.0f);
+  glVertex3f( this->getAbsCoor().x + h.x - v.x,
+              this->getAbsCoor().y + h.y - v.y,
+              this->getAbsCoor().z + h.z - v.z);
+  glTexCoord2f(1.0f, 1.0f);
+  glVertex3f(this->getAbsCoor().x + h.x + v.x,
+             this->getAbsCoor().y + h.y + v.y,
+             this->getAbsCoor().z + h.z + v.z);
+  glTexCoord2f(0.0f, 1.0f);
+  glVertex3f(this->getAbsCoor().x - h.x + v.x,
+             this->getAbsCoor().y - h.y + v.y,
+             this->getAbsCoor().z - h.z + v.z);
+  glEnd();
+
+
+  glPopMatrix();
+
+  glPopAttrib();*/
+}
Index: /branches/playability/src/world_entities/effects/trail.h
===================================================================
--- /branches/playability/src/world_entities/effects/trail.h	(revision 10081)
+++ /branches/playability/src/world_entities/effects/trail.h	(revision 10081)
@@ -0,0 +1,62 @@
+/*!
+ * @file trail.h
+ */
+
+#ifndef _TRAIL_H_
+#define _TRAIL_H_
+
+#include "world_entity.h"
+
+class Material;
+
+
+
+class Trail : public WorldEntity
+{
+  ObjectListDeclaration(Trail);
+  public:
+    Trail(float maxLength, int sections, float radius);
+    Trail(const TiXmlElement* root = NULL);
+    virtual ~Trail();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    void setTexture(const std::string& textureFile);
+
+    virtual void tick(float dt);
+    virtual void draw() const;
+
+    /**
+     *  length of the trail.
+     */
+    inline void setLength(float length) { this->length = length;};
+    inline float getLength() { return this->length;};
+
+    /**
+     *  Amount of sections (parts) of the trail. The more, the rounder it will look
+     */
+    inline void setSections(int sections) { this->sections = sections;};
+    inline int getSections() { return this->sections;};
+
+    /**
+     *  Radius of the trail object
+     */
+    inline void setRadius(float radius) { this->radius = radius;};
+    inline float getRadius() { return this->radius;};
+
+  private:
+    void init();
+    inline Vector catmull(Vector P0, Vector P1, Vector P2, Vector P3, float t) const {return (P1*2 + (P2 - P0)*t + (P0*2 - P1*5- P2*4 - P3)*t*t + (P1*3 -P0 - P2*3 + P3)*t*t*t); };
+
+
+    Material*              material;
+
+    float maxLength;
+    float length;
+    float radius;
+    int   sections;
+
+    Vector*  nodeList;
+};
+
+#endif /* _TRAIL_H_ */
Index: /branches/playability/src/world_entities/projectiles/hbolt.cc
===================================================================
--- /branches/playability/src/world_entities/projectiles/hbolt.cc	(revision 10080)
+++ /branches/playability/src/world_entities/projectiles/hbolt.cc	(revision 10081)
@@ -122,6 +122,6 @@
     this->destroy( entity );
   this->hitEntity = entity;
-  dynamic_cast<SpaceShip*>(entity)->damage(this->getPhysDamage(),0);
-//   this->deactivate();
+  dynamic_cast<SpaceShip*>(entity)->damage( this->getPhysDamage(), this->getElecDamage());
+  this->deactivate();
 }
 
Index: /branches/playability/src/world_entities/projectiles/mbolt.cc
===================================================================
--- /branches/playability/src/world_entities/projectiles/mbolt.cc	(revision 10080)
+++ /branches/playability/src/world_entities/projectiles/mbolt.cc	(revision 10081)
@@ -34,4 +34,6 @@
 #include "static_model.h"
 
+#include "effects/trail.h"
+
 
 #include "class_id_DEPRECATED.h"
@@ -46,4 +48,5 @@
   this->registerObject(this, MBolt::_objectList);
   this->loadModel("models/projectiles/mbolt.obj");
+
   
   //this->loadModel("models/projectiles/laser.obj");
@@ -72,4 +75,9 @@
   dynamic_cast<StaticModel*>(this->getModel())->addMaterial(this->mat);
   dynamic_cast<StaticModel*>(this->getModel())->finalize();
+
+  
+  this->trail = new Trail(6,1,.4);
+  this->trail->setParent( this);
+  this->trail->setTexture( "maps/laser.png");
 }
 
@@ -83,10 +91,4 @@
   // delete this->emitter;
 
-  if (MBolt::trailParticles != NULL && MBolt::objectList().size() <= 1)
-  {
-    if (ParticleSystem::objectList().exists(MBolt::trailParticles))
-      delete MBolt::trailParticles;
-    MBolt::trailParticles = NULL;
-  }
   if (MBolt::explosionParticles != NULL && MBolt::objectList().size() <= 1)
   {
@@ -94,25 +96,13 @@
       delete MBolt::explosionParticles;
     MBolt::explosionParticles = NULL;
+    PRINTF(1)("Deleting MBolt Explosion Particles\n");
   }
-}
-
-SpriteParticles* MBolt::trailParticles = NULL;
+  
+}
+
 SpriteParticles* MBolt::explosionParticles = NULL;
 
 void MBolt::activate()
 {
-  if (unlikely(MBolt::trailParticles == NULL))
-  {
-    MBolt::trailParticles = new SpriteParticles(1000);
-    MBolt::trailParticles->setName("BoomerangProjectileTrailParticles");
-    MBolt::trailParticles->setMaterialTexture("maps/radial-trans-noise.png");
-    MBolt::trailParticles->setLifeSpan(0.3, 0);
-    MBolt::trailParticles->setRadius(0.0, .8);
-    MBolt::trailParticles->setRadius(1.0, .2);
-    MBolt::trailParticles->setColor(0.0, 1,0,0,.9);
-    MBolt::trailParticles->setColor(0.2, .8,.2,0,.9);
-    MBolt::trailParticles->setColor(0.5, .8,.4,.4,.8);
-    MBolt::trailParticles->setColor(1.0, .8,.8,.8,.7);
-  }
   if (unlikely(MBolt::explosionParticles == NULL))
   {
@@ -128,8 +118,8 @@
   }
 
-  this->setDamage(10);
+  this->setPhysDamage(10);
+  this->setElecDamage(0);
   this->setHealth(0);
 
-  this->emitter->setSystem(MBolt::trailParticles);
 
   this->emitter->setSpread(0);
@@ -142,7 +132,4 @@
 void MBolt::deactivate()
 {
-  assert (MBolt::trailParticles != NULL);
-  MBolt::trailParticles->removeEmitter(this->emitter);
-
   assert (MBolt::explosionParticles != NULL);
   MBolt::explosionParticles->removeEmitter(this->emitter);
@@ -157,8 +144,12 @@
 void MBolt::collidesWith(WorldEntity* entity, const Vector& location)
 {
-  if (this->hitEntity != entity && entity->isA(CL_NPC))
-    this->destroy( entity );
-  this->hitEntity = entity;
-  dynamic_cast<SpaceShip*>(entity)->damage(this->getDamage(),0);
+  PRINTF(0)("MBolt collides pretest\n");
+  if( entity == NULL || dynamic_cast<SpaceShip*>(entity) == NULL)
+    return;
+
+  PRINTF(0)("MBolt collides\n");
+  dynamic_cast<SpaceShip*>(entity)->damage( this->getPhysDamage(), this->getElecDamage());
+  entity->destroy(this);
+  this->deactivate();
 }
 
@@ -177,4 +168,5 @@
 
   this->angle += MBolt::rotationSpeed * dt;
+  this->trail->tick(dt);
 }
 
@@ -209,4 +201,7 @@
   dynamic_cast<StaticModel*>(this->getModel())->draw();
   this->mat->unselect();
+  glScalef(1/.75,4/.7,4/.7);
+  glTranslatef(-4,0,0);
+  this->trail->draw();
   glPopMatrix();
   glPopAttrib();
Index: /branches/playability/src/world_entities/projectiles/mbolt.h
===================================================================
--- /branches/playability/src/world_entities/projectiles/mbolt.h	(revision 10080)
+++ /branches/playability/src/world_entities/projectiles/mbolt.h	(revision 10081)
@@ -15,4 +15,5 @@
 class ParticleEmitter;
 class FastFactory;
+class Trail;
 
 class MBolt : public Projectile
@@ -37,6 +38,7 @@
   private:
     static FastFactory*               fastFactory;
-    static SpriteParticles*           trailParticles;
     static SpriteParticles*           explosionParticles;
+
+    Trail*                            trail;
 
     float                             angle;
Index: /branches/playability/src/world_entities/projectiles/swarm_projectile.cc
===================================================================
--- /branches/playability/src/world_entities/projectiles/swarm_projectile.cc	(revision 10080)
+++ /branches/playability/src/world_entities/projectiles/swarm_projectile.cc	(revision 10081)
@@ -24,4 +24,5 @@
 #include "particles/sprite_particles.h"
 #include "space_ships/space_ship.h"
+#include "effects/trail.h"
 
 #include "debug.h"
@@ -57,4 +58,8 @@
 
   this->physDamage = 200;
+
+  this->trail = new Trail(2.5,4,.2);
+  this->trail->setParent( this);
+  this->trail->setTexture( "maps/laser.png");
 }
 
@@ -66,12 +71,4 @@
 {
 
-
-  /* this is normaly done by World.cc by deleting the ParticleEngine */
-  if (SwarmProjectile::trailParticles != NULL && SwarmProjectile::objectList().size() <= 1)
-  {
-    if (ParticleSystem::objectList().exists(SwarmProjectile::trailParticles))
-      delete SwarmProjectile::trailParticles;
-    SwarmProjectile::trailParticles = NULL;
-  }
   if (SwarmProjectile::explosionParticles != NULL && SwarmProjectile::objectList().size() <= 1)
   {
@@ -80,8 +77,8 @@
     SwarmProjectile::explosionParticles = NULL;
   }
-   delete this->emitter;
-}
-
-SpriteParticles* SwarmProjectile::trailParticles = NULL;
+  // delete this->emitter;
+  delete this->trail;
+}
+
 SpriteParticles* SwarmProjectile::explosionParticles = NULL;
 
@@ -90,19 +87,4 @@
 void SwarmProjectile::activate()
 {
-  if (unlikely(SwarmProjectile::trailParticles == NULL))
-  {
-    SwarmProjectile::trailParticles = new SpriteParticles(2000);
-    SwarmProjectile::trailParticles->setName("SwarmProjectileTrailParticles");
-    SwarmProjectile::trailParticles->setMaterialTexture("maps/radial-trans-noise.png");
-    SwarmProjectile::trailParticles->setLifeSpan(.3, 0);
-    SwarmProjectile::trailParticles->setRadius(0.0, .7);
-    SwarmProjectile::trailParticles->setRadius(0.2, 1.3);
-    SwarmProjectile::trailParticles->setRadius(.5, .8);
-    SwarmProjectile::trailParticles->setRadius(1.0, 0.3);
-    SwarmProjectile::trailParticles->setColor(0.0, 1,0,0,.7);
-    SwarmProjectile::trailParticles->setColor(0.2, .8,.8,0,.5);
-    SwarmProjectile::trailParticles->setColor(0.5, .8,.8,.8,.8);
-    SwarmProjectile::trailParticles->setColor(1.0, .8,.8,.8,.0);
-  }
   if (unlikely(SwarmProjectile::explosionParticles == NULL))
   {
@@ -120,5 +102,4 @@
   }
 
-  this->emitter->setSystem(SwarmProjectile::trailParticles);
 
   this->updateNode(0);
@@ -253,4 +234,6 @@
 
   this->updateAngle(time);
+
+  this->trail->tick(time);
 }
 
@@ -291,6 +274,6 @@
   //glScalef(2.0, 2.0, 2.0);  // no double rescale
   this->getModel()->draw();
-
+  glTranslatef(-.9,0,0);
+  this->trail->draw();
   glPopMatrix();
-
-}
+}
Index: /branches/playability/src/world_entities/projectiles/swarm_projectile.h
===================================================================
--- /branches/playability/src/world_entities/projectiles/swarm_projectile.h	(revision 10080)
+++ /branches/playability/src/world_entities/projectiles/swarm_projectile.h	(revision 10081)
@@ -14,4 +14,5 @@
 class FastFactory;
 class Aim;
+class Trail;
 
 class SwarmProjectile : public Projectile
@@ -36,6 +37,7 @@
   private:
     static FastFactory*               fastFactory;
-    static SpriteParticles*           trailParticles;
     static SpriteParticles*           explosionParticles;
+
+    Trail*                            trail;
 
     ParticleEmitter*                  emitter;
Index: /branches/playability/src/world_entities/space_ships/space_ship.cc
===================================================================
--- /branches/playability/src/world_entities/space_ships/space_ship.cc	(revision 10080)
+++ /branches/playability/src/world_entities/space_ships/space_ship.cc	(revision 10081)
@@ -34,4 +34,6 @@
 #include "particles/emitter_node.h"
 #include "particles/sprite_particles.h"
+#include "effects/explosion.h"
+#include "effects/trail.h"
 
 #include "util/loading/factory.h"
@@ -120,4 +122,5 @@
 {
   this->init();
+  //this->setParentMode(PNODE_REPARENT_DELETE_CHILDREN);
   if (root != NULL)
     this->loadParams(root);
@@ -139,8 +142,6 @@
   PRINTF(4)("SPACESHIP INIT\n");
 
-  secWeaponMan.showCrosshair();
-
   //weapons:
-
+  /*
   Weapon* wpRight1 = new LightBlaster ();
   wpRight1->setName( "LightBlaster");
@@ -148,5 +149,5 @@
   Weapon* wpLeft1 = new LightBlaster ();
   wpLeft1->setName( "LightBlaster");
-  wpLeft1->setParent( this);
+  wpLeft1->setParent( this);*/
 
   Weapon* wpRight2 = new MediumBlaster ();
@@ -156,5 +157,5 @@
   wpLeft2->setName( "MediumBlaster");
   wpLeft2->setParent( this);
-
+  /*
   Weapon* wpRight3 = new HeavyBlaster ();
   wpRight3->setName( "HeavyBlaster");
@@ -162,5 +163,5 @@
   Weapon* wpLeft3 = new HeavyBlaster ();
   wpLeft3->setName( "HeavyBlaster");
-  wpLeft3->setParent( this);
+  wpLeft3->setParent( this);*/
 
   Weapon* cannon = new SwarmLauncher();
@@ -169,10 +170,10 @@
 
 
-  this->weaponMan.addWeapon( wpLeft1, 0, 0);
-  this->weaponMan.addWeapon( wpRight1, 0, 1);
+  //this->weaponMan.addWeapon( wpLeft1, 0, 0);
+  //this->weaponMan.addWeapon( wpRight1, 0, 1);
   this->weaponMan.addWeapon( wpLeft2, 0, 2);
   this->weaponMan.addWeapon( wpRight2, 0, 3);
-  this->weaponMan.addWeapon( wpLeft3, 0, 4);
-  this->weaponMan.addWeapon( wpRight3, 0, 5);
+  //this->weaponMan.addWeapon( wpLeft3, 0, 4);
+  //this->weaponMan.addWeapon( wpRight3, 0, 5);
 
   this->secWeaponMan.addWeapon( cannon, 1, 0);
@@ -181,10 +182,10 @@
   this->secWeaponMan.changeWeaponConfig(1);
 
-  wpRight1->requestAction(WA_ACTIVATE);
-  wpLeft1->requestAction(WA_ACTIVATE);
+  //wpRight1->requestAction(WA_ACTIVATE);
+  //wpLeft1->requestAction(WA_ACTIVATE);
   wpRight2->requestAction(WA_ACTIVATE);
   wpLeft2->requestAction(WA_ACTIVATE);
-  wpRight3->requestAction(WA_ACTIVATE);
-  wpLeft3->requestAction(WA_ACTIVATE);
+  //wpRight3->requestAction(WA_ACTIVATE);
+  //wpLeft3->requestAction(WA_ACTIVATE);
 
   cannon->requestAction(WA_ACTIVATE);
@@ -301,23 +302,4 @@
   dynamic_cast<Element2D*>(this->weaponMan.getFixedTarget())->setVisibility( false);
 
-  this->burstEmitter = new DotEmitter(800, 0.0, .01);
-  this->burstEmitter->setParent(this);
-  this->burstEmitter->setRelCoor(-1, .5, 0);
-  this->burstEmitter->setName("SpaceShip_Burst_emitter");
-  this->burstEmitter->setEmissionRate(800);
-
-  this->burstSystem = new SpriteParticles(400);
-  this->burstSystem->addEmitter(this->burstEmitter);
-  this->burstSystem->setName("SpaceShip_Burst_System");
-  ((SpriteParticles*)this->burstSystem)->setMaterialTexture("maps/radial-trans-noise.png");
-  this->burstSystem->setLifeSpan(0.3, .3);
-  this->burstSystem->setRadius(0.0, 1.0);
-  this->burstSystem->setRadius(0.05, 1.0);
-  this->burstSystem->setRadius(.5, .6);
-  this->burstSystem->setRadius(1.0, 0);
-  this->burstSystem->setColor(0.0, .7,.7,1,.5);
-  this->burstSystem->setColor(0.2, 0,0,0.8,.7);
-  this->burstSystem->setColor(0.5, .5,.5,.8,.8);
-  this->burstSystem->setColor(1.0, .8,.8,.8,.0);
 
   registerVar( new SynchronizeableBool( &bForward, &bForward, "bForward", PERMISSION_OWNER ) );
@@ -342,4 +324,17 @@
 
   this->setSupportedPlaymodes(Playable::Horizontal | Playable::Vertical);
+
+  
+  this->trail = new Trail( 15, 10, .2);
+  this->trail->setParent( this);
+  this->trail->setTexture( "maps/engine.png");
+
+  this->trailL = new Trail( 15, 10, .2);
+  this->trailL->setParent( this);
+  this->trailL->setTexture( "maps/engine.png");
+
+  this->trailR = new Trail( 15, 10, .2);
+  this->trailR->setParent( this);
+  this->trailR->setTexture( "maps/engine.png");
 }
 
@@ -376,9 +371,10 @@
 {
   this->secWeaponMan.showCrosshair();
+  /*for(ObjectList<PNode>::const_iterator it = this->getNodesChildren().begin(); it != this->getNodesChildren().end(); it++)
+  {
+    if( likely( dynamic_cast<WorldEntity*>(*it) != NULL))
+      dynamic_cast<WorldEntity*>(*it)->toList( OM_GROUP_01);
+  }*/
   this->toList( OM_GROUP_01 );
-  /*for(ObjectList<WorldEntity>::const_iterator it = WorldEntity::objectList().begin(); it != WorldEntity::objectList().end(); it++)
-  {
-    (*it)->toList( OM_GROUP_01);
-  }*/
   //dynamic_cast<Element2D*>(this->secWeaponMan.getFixedTarget())->setVisibility( true);
   //this->attachCamera();
@@ -389,9 +385,10 @@
 {
   this->secWeaponMan.hideCrosshair();
+  /*for(ObjectList<PNode>::const_iterator it = this->getNodesChildren().begin(); it != this->getNodesChildren().end(); it++)
+  {
+    if( likely(dynamic_cast<WorldEntity*>(*it) != NULL))
+      dynamic_cast<WorldEntity*>(*it)->toList( OM_GROUP_00);
+  }*/
   this->toList( OM_GROUP_00);
-  /*for(ObjectList<WorldEntity>::const_iterator it = WorldEntity::objectList().begin(); it != WorldEntity::objectList().end(); it++)
-  {
-    (*it)->toList( OM_GROUP_00);
-  }*/
   //dynamic_cast<Element2D*>(this->secWeaponMan.getFixedTarget())->setVisibility( false);
   //this->detachCamera();
@@ -424,4 +421,5 @@
 void SpaceShip::collidesWith(WorldEntity* entity, const Vector& location)
 {
+  PRINTF(0)("SPACESHIP COLLIDED WITH %s\n",entity->getCName());
 }
 
@@ -433,4 +431,21 @@
   WorldEntity::draw();
 
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x-1, this->getAbsCoor ().y-.2, this->getAbsCoor ().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  //glScalef(2.0, 2.0, 2.0);  // no double rescale
+  
+  this->trail->draw();
+  
+  glTranslatef(0,0,-.5);
+  this->trailL->draw();
+
+  glTranslatef(0,0,1);
+  this->trailR->draw();
+  glPopMatrix();
   //this->debug(0);
 }
@@ -512,7 +527,7 @@
   this->cameraNode.setRelDirSoft(this->getAbsDir(), 30.0f);
 
-  this->burstEmitter->setEmissionRate(this->cameraSpeed + (velocity.z>0)*velocity.z);
-  this->burstEmitter->setEmissionVelocity(this->cameraSpeed + (velocity.z>0)*velocity.z, travelSpeed *.1);
-
+  this->trail->tick(time);
+  this->trailL->tick(time);
+  this->trailR->tick(time);
   //orient the spaceship in direction of the mouse
   /*
@@ -585,5 +600,5 @@
 {
   PRINTF(0)("spaceship destroy\n");
-
+  /*
   EmitterNode* node  = NULL;
   DotEmitter* emitter = NULL;
@@ -613,5 +628,9 @@
   node->setVelocity( this->getParent()->getVelocity());
   node->setAbsCoor( this->getAbsCoor());
-  node->start();
+  node->start();*/
+  PNode* node          = new PNode();
+  node->setAbsCoor(this->getAbsCoor());
+  Explosion* explosion = new Explosion();
+  explosion->explode( node, Vector(5,5,5));
 
   this->setAbsCoor(Vector(-10000,10000,10000));
@@ -619,7 +638,8 @@
 
   this->toList( OM_DEAD);
-  /*for(ObjectList<WorldEntity>::const_iterator it = WorldEntity::objectList().begin(); it != WorldEntity::objectList().end(); it++)
+  /*for(ObjectList<PNode>::const_iterator it = this->getNodesChildren().begin(); it != this->getNodesChildren().end(); it++)
   {
-    (*it)->toList( OM_DEAD);
+    if( dynamic_cast<WorldEntity*>(*it) != NULL)
+      dynamic_cast<WorldEntity*>(*it)->toList( OM_DEAD);
   }*/
     PRINTF(0)("spaceship destroy == ship translated \n");
@@ -628,12 +648,22 @@
 void SpaceShip::respawn( )
 {
-  //this->show();
-  //this->toList( OM_GROUP_00);
+  this->unhide();
+  /*for(ObjectList<PNode>::const_iterator it = this->getNodesChildren().begin(); it != this->getNodesChildren().end(); it++)
+  {
+    if( dynamic_cast<WorldEntity*>(*it) != NULL)
+      dynamic_cast<WorldEntity*>(*it)->toList( OM_GROUP_00);
+  }*/
+  /*if( this->hasPlayer())
+    this->toList( OM_GROUP_01);
+  else
+    this->toList( OM_GROUP_00);*/
+
 }
 
 
 void SpaceShip::damage(float pDamage, float eDamage){
-  PRINTF(0)("ship hit");
-  printf("Shit hit");
+  PRINTF(0)("ship hit for (%f,%f) \n",pDamage,eDamage);
+  PRINTF(0)("SHIP HIT - SHIP HIT - SHIP HIT\n");
+
   if( this->shieldActive) {
     if( this->shieldCur > pDamage) {
@@ -643,5 +673,5 @@
       this->shieldCur -=pDamage;
       this->shieldActive = false; //shield collapses
-      pDamage = pDamage - this->shieldCur;
+      pDamage += this->shieldCur;
       if( !this->shieldActive) {
         this->armorCur -= pDamage / 2; // remaining damages hits armor at half rate
Index: /branches/playability/src/world_entities/space_ships/space_ship.h
===================================================================
--- /branches/playability/src/world_entities/space_ships/space_ship.h	(revision 10080)
+++ /branches/playability/src/world_entities/space_ships/space_ship.h	(revision 10081)
@@ -19,4 +19,5 @@
 class ParticleEmitter;
 class ParticleSystem;
+class Trail;
 
 class SpaceShip : public Playable
@@ -177,6 +178,8 @@
     byte                  oldMask;            //!< used for synchronisation
 
-    ParticleEmitter*      burstEmitter;
-    ParticleSystem*       burstSystem;
+    Trail*                trail;              //!< Burst trail
+    Trail*                trailL;              //!< Burst trail
+    Trail*                trailR;              //!< Burst trail
+
 };
 
