Index: trunk/src/world_entities/projectiles/acid_splash.cc
===================================================================
--- trunk/src/world_entities/projectiles/acid_splash.cc	(revision 10368)
+++ trunk/src/world_entities/projectiles/acid_splash.cc	(revision 10368)
@@ -0,0 +1,183 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004-2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Marc Schaerrer
+   co-programmer: Benjamin Grauer
+
+*/
+
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "acid_splash.h"
+
+#include "state.h"
+
+//#include "space_ships/space_ship.h"
+
+#include <cassert>
+#include "debug.h"
+
+//#include "static_model.h"
+
+#include "effects/wobblegrid.h"
+
+
+
+ObjectListDefinition(AcidSplash);
+CREATE_FAST_FACTORY_STATIC(AcidSplash);
+
+/**
+ *  standard constructor
+*/
+AcidSplash::AcidSplash () : Projectile()
+{
+  this->registerObject(this, AcidSplash::_objectList);
+
+  srand(time(0));   //initialize Random Nomber Generator
+
+  //this->loadModel("models/projectiles/laser.obj");
+
+  this->setMinEnergy(1);
+  this->setHealthMax(0);
+  this->lifeSpan = 3.0;
+  this->angle     = 0;
+
+  this->grid = new Wobblegrid( 5);
+  this->grid->setParent( this);
+
+
+  int rnd = int(rand() % 3);
+
+  switch (rnd){
+    case 0:
+      this->grid->setTexture( "maps/acid2.png");
+      break;
+    case 1:
+      this->grid->setTexture( "maps/acid3.png");
+      break;
+    case 2:
+      this->grid->setTexture( "maps/blub.png");
+      break;
+    default:
+      this->grid->setTexture( "maps/acid2.png");
+  }
+//   if (rand()/2 == 0) //!<Randomized Textrures
+//     this->grid->setTexture( "maps/acid3.png");
+//   else
+//     this->grid->setTexture( "maps/blub.png");
+
+  this->grid->toList(OM_ENVIRON); 
+}
+
+
+/**
+ *  standard deconstructor
+ *
+ */
+AcidSplash::~AcidSplash ()
+{
+  // delete this->emitter;
+  //delete this->grid;
+  this->grid->toList(OM_DEAD);
+  
+}
+
+
+void AcidSplash::activate()
+{
+  this->origList = this->getOMListNumber();
+  this->toList(OM_ENVIRON);
+ // this->unhide();
+  this->grid->setVisibiliy(true);
+
+  this->setPhysDamage(10);
+  this->setElecDamage(0);
+  this->setHealth(0);
+}
+
+
+void AcidSplash::deactivate()
+{
+  this->lifeCycle = 0.0;
+
+ // this->hide();
+  this->grid->setVisibiliy(false);
+  this->lifeCycle = 0.0;
+  this->toList(OM_NULL);
+  //this->toList(OM_DEAD);
+  this->removeNode();
+  
+  AcidSplash::fastFactory->kill(this);
+}
+
+/*
+void AcidSplash::collidesWith(WorldEntity* entity, const Vector& location)
+{
+
+  if (this->hitEntity != entity)
+    this->destroy( entity );
+  this->hitEntity = entity;
+  //dynamic_cast<SpaceShip*>(entity)->damage(this->getPhysDamage(),this->getElecDamage());
+  //this->destroy(this);
+  this->deactivate();
+  
+//   return;
+
+  //dynamic_cast<SpaceShip*>(entity)->damage( this->getPhysDamage(), this->getElecDamage());
+  //entity->destroy(this);
+  //this->deactivate();
+}
+*/
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param dt time since last tick
+*/
+void AcidSplash::tick (float dt)
+{
+  //Vector v = *this->flightDirection * ( this->speed * time * 1000 + 0.1);
+  Vector v = this->velocity * dt;
+  this->shiftCoor(v);
+
+  if (this->tickLifeCycle(dt))
+    this->deactivate();
+
+  this->angle += this->rotationSpeed * dt;
+
+  this->grid->tick(dt);
+
+  for( ObjectList<Playable>::const_iterator eIterator = Playable::objectList().begin(); eIterator !=Playable::objectList().end(); eIterator++)
+  {
+    if( ((*eIterator)->getOMListNumber() != (this->origList -1))  && ((*eIterator)->getAbsCoor() - this->getAbsCoor()).len() <= 8)
+    {
+      (*eIterator)->hit (this->getDamage(),this);
+      this->deactivate();
+    }
+  }
+
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void AcidSplash::destroy (WorldEntity* killer)
+{
+  this->deactivate();
+  Projectile::destroy( killer );
+  PRINTF(5)("DESTROY AcidSplash\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+}
+
+
+void AcidSplash::draw () const
+{
+  this->grid->draw();
+}
Index: trunk/src/world_entities/projectiles/acid_splash.h
===================================================================
--- trunk/src/world_entities/projectiles/acid_splash.h	(revision 10368)
+++ trunk/src/world_entities/projectiles/acid_splash.h	(revision 10368)
@@ -0,0 +1,45 @@
+/*!
+ * @file acid_splash.h
+ * @brief acid splash projectile
+*/
+
+#ifndef _ACIDSPLASH_H
+#define _ACIDSPLASH_H
+
+#include "projectile.h"
+
+class Vector;
+class Weapon;
+class FastFactory;
+class Wobblegrid;
+
+class AcidSplash : public Projectile
+{
+  ObjectListDeclaration(AcidSplash);
+  public:
+    AcidSplash ();
+    virtual ~AcidSplash ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+ //   virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float dt);
+    virtual void draw () const;
+
+  private:
+    static FastFactory*               fastFactory;
+    Wobblegrid*                       grid;
+
+    float                             angle;
+    static const float                rotationSpeed = 1080;
+
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+};
+
+#endif /* _ACIDSPLASH_H */
Index: trunk/src/world_entities/projectiles/hbolt.cc
===================================================================
--- trunk/src/world_entities/projectiles/hbolt.cc	(revision 10368)
+++ trunk/src/world_entities/projectiles/hbolt.cc	(revision 10368)
@@ -0,0 +1,196 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004-2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Nicolas Schlumberger, Marc Schaerrer
+   co-programmer: Benjamin Grauer
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "hbolt.h"
+
+#include "state.h"
+#include "model.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include <cassert>
+#include "debug.h"
+
+// #include "effects/billboard.h"
+#include "space_ships/space_ship.h"
+#include "npcs/npc.h"
+
+ObjectListDefinition(HBolt);
+CREATE_FAST_FACTORY_STATIC(HBolt);
+
+/**
+ *  standard constructor
+*/
+HBolt::HBolt () : Projectile()
+{
+  this->registerObject(this, HBolt::_objectList);
+
+  this->loadModel("models/projectiles/hbolt.obj",1.1);
+
+  this->setMinEnergy(10);
+  this->setHealthMax(0);
+  this->lifeSpan = 2.0;
+
+  this->angle = 0;
+  this->rotationSpeed = 600;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+  this->emitter->setEmissionRate(300.0);
+  this->emitter->setEmissionVelocity(50.0);
+
+  this->halo = new Billboard();
+  this->halo->setSize(.65, .65);
+  this->halo->setTexture("hbolt_halo2.png");
+
+}
+
+
+/**
+ *  standard deconstructor
+*/
+HBolt::~HBolt ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (HBolt::explosionParticles != NULL && HBolt::objectList().size() <= 1)
+  {
+    //if (ClassList::exists(HBolt::explosionParticles, CL_PARTICLE_SYSTEM))
+    //  delete HBolt::explosionParticles;
+    PRINTF(1)("Deleting HBolt Particles\n");
+    HBolt::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* HBolt::explosionParticles = NULL;
+
+void HBolt::activate()
+{
+  this->origList = this->getOMListNumber();
+  this->toList(OM_ENVIRON);
+  if (unlikely(HBolt::explosionParticles == NULL))
+  {
+    HBolt::explosionParticles = new SpriteParticles(1000);
+    HBolt::explosionParticles->setName("HBoltExplosionParticles");
+    HBolt::explosionParticles->setLifeSpan(.5, .3);
+    HBolt::explosionParticles->setRadius(0.0, 10.0);
+    HBolt::explosionParticles->setRadius(.5, 6.0);
+    HBolt::explosionParticles->setRadius(1.0, 3.0);
+    HBolt::explosionParticles->setColor(0.0, 1,1,0,.9);
+    HBolt::explosionParticles->setColor(0.5, .8,.8,0,.5);
+    HBolt::explosionParticles->setColor(1.0, .8,.8,.7,.0);
+  }
+
+  this->setPhysDamage(100);
+  this->setHealth(0);
+}
+
+
+void HBolt::deactivate()
+{
+  assert (HBolt::explosionParticles != NULL);
+  HBolt::explosionParticles->removeEmitter(this->emitter);
+  this->lifeCycle = 0.0;
+
+  this->toList(OM_DEAD);
+  this->removeNode();
+  HBolt::fastFactory->kill(this);
+
+}
+
+
+void HBolt::hit (float damage, WorldEntity* entity )
+{
+  printf("Collision with HBolt\n");
+  if (this->hitEntity != entity && entity->isA(NPC::staticClassID()) || entity == this->target)
+    this->destroy( entity );
+  this->hitEntity = entity;
+ // dynamic_cast<SpaceShip*>(entity)->damage( this->getPhysDamage(), this->getElecDamage());
+  this->deactivate();
+}
+
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param dt time since last tick
+*/
+void HBolt::tick (float dt)
+{
+  //Vector v = *this->flightDirection * ( this->speed * time * 1000 + 0.1);
+  Vector v = this->velocity * dt;
+  this->shiftCoor(v);
+
+  if (this->tickLifeCycle(dt))
+    this->deactivate();
+
+  this->angle += this->rotationSpeed * dt;
+
+  for( ObjectList<Playable>::const_iterator eIterator = Playable::objectList().begin(); eIterator !=Playable::objectList().end(); eIterator++)
+  {
+    if( ((*eIterator)->getOMListNumber() != (this->origList -1))   && ((*eIterator)->getAbsCoor() - this->getAbsCoor()).len() <= 8)
+    {
+      (*eIterator)->hit (this->getDamage(),this);
+      this->deactivate();
+  PRINTF(0)("HBolt destroyed\n");
+    }
+  }
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void HBolt::destroy (WorldEntity* killer)
+{
+  Projectile::destroy( killer );
+  PRINTF(5)("DESTROY HBolt\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+
+  this->emitter->setSystem(HBolt::explosionParticles);
+}
+
+
+void HBolt::draw () const
+{
+
+  glPushAttrib(GL_ENABLE_BIT);
+  glDisable(GL_LIGHTING);
+  glDisable(GL_FOG);
+
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+
+  glTranslatef (this->getAbsCoor ().x,
+                  this->getAbsCoor ().y,
+                  this->getAbsCoor ().z);
+
+  this->halo->draw();
+
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  glRotatef(this->angle, 0.0, 0.0, 1.0);
+
+  this->getModel()->draw();
+
+  glPopMatrix();
+  glPopAttrib();
+
+}
Index: trunk/src/world_entities/projectiles/hbolt.h
===================================================================
--- trunk/src/world_entities/projectiles/hbolt.h	(revision 10368)
+++ trunk/src/world_entities/projectiles/hbolt.h	(revision 10368)
@@ -0,0 +1,51 @@
+/*!
+ * @file hhbolt.h
+ * @brief heavy blaster hbolt
+*/
+
+#ifndef _HBOLT_H
+#define _HBOLT_H
+
+#include "projectile.h"
+#include "effects/billboard.h"
+
+class Vector;
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class HBolt : public Projectile
+{
+  ObjectListDeclaration(HBolt);
+  public:
+    HBolt ();
+    virtual ~HBolt ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void hit (float damage, WorldEntity* entity);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float dt);
+    virtual void draw () const;
+
+  private:
+    static FastFactory*               fastFactory;
+
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+
+    float                             angle;
+    float                             rotationSpeed;
+
+    Billboard*                        halo;
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+};
+
+#endif /* _HBOLT_H */
Index: trunk/src/world_entities/projectiles/lbolt.cc
===================================================================
--- trunk/src/world_entities/projectiles/lbolt.cc	(revision 10368)
+++ trunk/src/world_entities/projectiles/lbolt.cc	(revision 10368)
@@ -0,0 +1,193 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004-2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Nicolas Schlumberger, Marc Schaerrer
+   co-programmer: Benjamin Grauer
+
+*/
+
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "lbolt.h"
+
+#include "state.h"
+#include "model.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+#include "npcs/npc.h"
+
+#include <cassert>
+#include "debug.h"
+
+#include "space_ships/space_ship.h"
+
+
+
+ObjectListDefinition(LBolt);
+CREATE_FAST_FACTORY_STATIC(LBolt);
+
+/**
+ *  standard constructor
+*/
+LBolt::LBolt () : Projectile()
+{
+  this->registerObject(this, LBolt::_objectList);
+
+  this->loadModel("models/projectiles/lbolt.obj");
+
+  this->setMinEnergy(1);
+  this->setHealthMax(0);
+  this->lifeSpan = 1.0;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+  this->emitter->setEmissionRate(300.0);
+  this->emitter->setEmissionVelocity(50.0);
+
+  this->angle = 0;
+  this->rotationSpeed = 130;
+
+  this->halo = new Billboard();
+  this->halo->setSize(.35, .35);
+  this->halo->setTexture("hbolt_halo.png");
+
+
+}
+
+
+/**
+ *  standard deconstructor
+*/
+LBolt::~LBolt ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (LBolt::explosionParticles != NULL && LBolt::objectList().size() <= 1)
+  {
+    //if (ClassList::exists(LBolt::explosionParticles, CL_PARTICLE_SYSTEM))
+    //  delete LBolt::explosionParticles;
+    PRINTF(1)("Deleting LBolt Particles\n");
+    LBolt::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* LBolt::explosionParticles = NULL;
+
+void LBolt::activate()
+{
+  this->origList = this->getOMListNumber();
+  this->toList(OM_ENVIRON);
+  if (unlikely(LBolt::explosionParticles == NULL))
+  {
+    LBolt::explosionParticles = new SpriteParticles(1000);
+    LBolt::explosionParticles->setName("BoltExplosionParticles");
+    LBolt::explosionParticles->setLifeSpan(.5, .3);
+    LBolt::explosionParticles->setRadius(0.0, 10.0);
+    LBolt::explosionParticles->setRadius(.5, 6.0);
+    LBolt::explosionParticles->setRadius(1.0, 3.0);
+    LBolt::explosionParticles->setColor(0.0, 1,1,0,.9);
+    LBolt::explosionParticles->setColor(0.5, .8,.8,0,.5);
+    LBolt::explosionParticles->setColor(1.0, .8,.8,.7,.0);
+  }
+
+  this->setDamage(5);
+  this->setHealth(0);
+}
+
+
+void LBolt::deactivate()
+{
+  assert (LBolt::explosionParticles != NULL);
+  LBolt::explosionParticles->removeEmitter(this->emitter);
+  this->lifeCycle = 0.0;
+
+  this->toList(OM_DEAD);
+  this->removeNode();
+  LBolt::fastFactory->kill(this);
+}
+
+
+void LBolt::hit (float damage, WorldEntity* entity )
+{
+  PRINTF(0)("Collision with LBolt\n");
+  if (this->hitEntity != entity && entity->isA(NPC::staticClassID()))
+    this->destroy( entity );
+  this->hitEntity = entity;
+  this->deactivate();
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param dt time since last tick
+*/
+void LBolt::tick (float dt)
+{
+  //Vector v = *this->flightDirection * ( this->speed * time * 1000 + 0.1);
+  Vector v = this->velocity * dt;
+  this->shiftCoor(v);
+
+  if (this->tickLifeCycle(dt))
+    this->deactivate();
+
+  angle += rotationSpeed * dt;
+
+  for( ObjectList<Playable>::const_iterator eIterator = Playable::objectList().begin(); eIterator !=Playable::objectList().end(); eIterator++)
+  {
+    if( ((*eIterator)->getOMListNumber() != (this->origList -1))   && ((*eIterator)->getAbsCoor() - this->getAbsCoor()).len() <= 8)
+    {
+      (*eIterator)->hit (this->getDamage(),this);
+      this->deactivate();
+  PRINTF(0)("LBolt destroyed\n");
+    }
+  }
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void LBolt::destroy (WorldEntity* killer)
+{
+  Projectile::destroy( killer );
+  PRINTF(5)("DESTROY LBolt\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+
+  this->emitter->setSystem(LBolt::explosionParticles);
+}
+
+
+void LBolt::draw () const
+{
+  glPushAttrib(GL_ENABLE_BIT);
+  //glDisable(GL_LIGHTING);
+
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+
+  glRotatef(angle, 1.0, 0.0, 0.0);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  this->getModel()->draw();
+
+  this->halo->draw();
+
+  glPopMatrix();
+
+  glPopAttrib();
+}
+
Index: trunk/src/world_entities/projectiles/lbolt.h
===================================================================
--- trunk/src/world_entities/projectiles/lbolt.h	(revision 10368)
+++ trunk/src/world_entities/projectiles/lbolt.h	(revision 10368)
@@ -0,0 +1,52 @@
+/*!
+ * @file lbolt.h
+ * @brief light blaster lbolt
+*/
+
+#ifndef _LBOLT_H
+#define _LBOLT_H
+
+#include "projectile.h"
+#include "effects/billboard.h"
+
+class Vector;
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class LBolt : public Projectile
+{
+  ObjectListDeclaration(LBolt);
+  public:
+    LBolt ();
+    virtual ~LBolt ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void hit (float damage, WorldEntity* entity);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float dt);
+    virtual void draw () const;
+
+
+  private:
+    static FastFactory*               fastFactory;
+
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+
+    float                             angle;
+    float                             rotationSpeed;
+
+    Billboard*                        halo;
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+};
+
+#endif /* _LBOLT_H */
Index: trunk/src/world_entities/projectiles/mbolt.cc
===================================================================
--- trunk/src/world_entities/projectiles/mbolt.cc	(revision 10368)
+++ trunk/src/world_entities/projectiles/mbolt.cc	(revision 10368)
@@ -0,0 +1,226 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004-2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Marc Schaerrer
+   co-programmer: Benjamin Grauer
+
+*/
+
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "mbolt.h"
+
+#include "state.h"
+#include "model.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include "space_ships/space_ship.h"
+
+#include <cassert>
+#include "debug.h"
+
+#include "static_model.h"
+
+#include "effects/trail.h"
+
+
+
+ObjectListDefinition(MBolt);
+CREATE_FAST_FACTORY_STATIC(MBolt);
+
+/**
+ *  standard constructor
+*/
+MBolt::MBolt () : Projectile()
+{
+  this->registerObject(this, MBolt::_objectList);
+  this->loadModel("models/projectiles/mbolt.obj",4);
+
+
+  //this->loadModel("models/projectiles/laser.obj");
+
+  this->setMinEnergy(4);
+  this->setHealthMax(0);
+  this->lifeSpan = 1.5;
+  this->angle     = 0;
+
+  //this->emitter = new DotEmitter(1000, 0, 0);
+  this->emitter = new DotEmitter(50, 0, 0);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI,M_PI);
+  this->emitter->setInheritSpeed(this->velocity.len());
+  this->emitter->setEmissionRate(500.0);
+  this->emitter->setEmissionVelocity(this->velocity.len());
+
+  this->mat = new Material("mBolt");
+  //this->mat->setBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+  this->mat->setBlendFunc(GL_SRC_ALPHA,GL_ONE);
+  this->mat->setDiffuse(1,1,1);
+  this->mat->setDiffuseMap("laser_add.png");
+  this->mat->setDiffuseMap("laser.png",1);
+
+  dynamic_cast<StaticModel*>(this->getModel())->addMaterial(*this->mat);
+  dynamic_cast<StaticModel*>(this->getModel())->finalize();
+
+  dynamic_cast<StaticModel*>(this->getModel())->rebuild();
+  //this->buildObbTree(4);
+
+  this->trail = new Trail(6, 4, .1, this);
+  //this->trail->setParent( this);
+  this->trail->setTexture( "maps/laser.png");
+  this->trail->setAbsCoor(this->getAbsCoor() - Vector(.7,0,0));
+
+}
+
+
+/**
+ *  standard deconstructor
+ *
+ */
+MBolt::~MBolt ()
+{
+
+  if (MBolt::explosionParticles != NULL && MBolt::objectList().size() <= 1)
+  {
+    if (ParticleSystem::objectList().exists(MBolt::explosionParticles))
+      delete MBolt::explosionParticles;
+    MBolt::explosionParticles = NULL;
+    PRINTF(1)("Deleting MBolt Explosion Particles\n");
+  }
+
+  delete this->emitter;
+  delete this->trail;
+}
+
+SpriteParticles* MBolt::explosionParticles = NULL;
+
+void MBolt::activate()
+{
+  this->origList = this->getOMListNumber();
+  this->toList(OM_ENVIRON);
+  if (unlikely(MBolt::explosionParticles == NULL))
+  {
+    MBolt::explosionParticles = new SpriteParticles(1000);
+    MBolt::explosionParticles->setName("MBoltExplosionParticles");
+    MBolt::explosionParticles->setLifeSpan(.2, .1);
+    MBolt::explosionParticles->setRadius(0.0, 10.0);
+    MBolt::explosionParticles->setRadius(.5, 6.0);
+    MBolt::explosionParticles->setRadius(1.0, 3.0);
+    MBolt::explosionParticles->setColor(0.0, 1,1,0,.9);
+    MBolt::explosionParticles->setColor(0.5, .8,.8,0,.5);
+    MBolt::explosionParticles->setColor(1.0, .8,.8,.7,.0);
+  }
+
+  this->setPhysDamage(10);
+  this->setElecDamage(0);
+  this->setHealth(0);
+
+  this->emitter->setSpread(0);
+  this->emitter->setEmissionRate(10.0);
+  this->emitter->setEmissionVelocity(50);
+}
+
+
+void MBolt::deactivate()
+{
+  assert (MBolt::explosionParticles != NULL);
+  MBolt::explosionParticles->removeEmitter(this->emitter);
+  this->lifeCycle = 0.0;
+
+  this->lifeCycle = 0.0;
+  this->toList(OM_NULL);
+  //this->toList(OM_DEAD);
+  this->removeNode();
+  MBolt::fastFactory->kill(this);
+}
+
+void MBolt::hit (float damage, WorldEntity* entity )
+{
+
+  if (this->hitEntity != entity)
+    this->destroy( entity );
+  this->hitEntity = entity;
+ // dynamic_cast<SpaceShip*>(entity)->damage(this->getPhysDamage(),this->getElecDamage());
+  //this->destroy(this);
+  this->deactivate();
+
+  return;
+
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param dt time since last tick
+*/
+void MBolt::tick (float dt)
+{
+  //Vector v = *this->flightDirection * ( this->speed * time * 1000 + 0.1);
+  Vector v = this->velocity * dt;
+  this->shiftCoor(v);
+
+  if (this->tickLifeCycle(dt))
+    this->deactivate();
+
+  this->angle += MBolt::rotationSpeed * dt;
+  this->trail->tick(dt);
+
+  for( ObjectList<Playable>::const_iterator eIterator = Playable::objectList().begin(); eIterator !=Playable::objectList().end(); eIterator++)
+  {
+    if( ((*eIterator)->getOMListNumber() != (this->origList -1))  && ((*eIterator)->getAbsCoor() - this->getAbsCoor()).len() <= 8)
+    {
+      (*eIterator)->hit (this->getDamage(),this);
+      this->deactivate();
+      PRINTF(0)("MBolt destroyed\n");
+    }
+  }
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void MBolt::destroy (WorldEntity* killer)
+{
+  //this->deactivate();
+  Projectile::destroy( killer );
+  PRINTF(5)("DESTROY MBolt\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+
+  this->emitter->setSystem(MBolt::explosionParticles);
+}
+
+
+void MBolt::draw () const
+{
+  glPushAttrib(GL_ENABLE_BIT);
+  glDisable(GL_LIGHTING);
+
+  glPushMatrix();
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  glRotatef(this->angle, 1.0f, 0.0f, 0.0f); //spinning missile
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+
+  glScalef(0.75/4, 0.7/16, 0.7/16);  // no double rescale
+
+  this->mat->select();
+  dynamic_cast<StaticModel*>(this->getModel())->draw();
+  this->mat->unselect();
+  glScalef(4/.75,16/.7,16/.7);
+  glTranslatef(-3,0,0);
+  this->trail->draw();
+  glPopMatrix();
+  glPopAttrib();
+
+}
Index: trunk/src/world_entities/projectiles/mbolt.h
===================================================================
--- trunk/src/world_entities/projectiles/mbolt.h	(revision 10368)
+++ trunk/src/world_entities/projectiles/mbolt.h	(revision 10368)
@@ -0,0 +1,54 @@
+/*!
+ * @file mbolt.h
+ * @brief medium blaster bolt
+*/
+
+#ifndef _MBOLT_H
+#define _MBOLT_H
+
+#include "projectile.h"
+#include "material.h"
+
+class Vector;
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+class Trail;
+
+class MBolt : public Projectile
+{
+  ObjectListDeclaration(MBolt);
+  public:
+    MBolt ();
+    virtual ~MBolt ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void hit (float damage, WorldEntity* entity);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float dt);
+    virtual void draw () const;
+
+  private:
+    static FastFactory*               fastFactory;
+    static SpriteParticles*           explosionParticles;
+
+    Trail*                            trail;
+
+    float                             angle;
+    static const float                rotationSpeed = 1080;
+
+    ParticleEmitter*                  emitter;
+
+    Material*                         mat;
+
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+};
+
+#endif /* _MBOLT_H */
Index: trunk/src/world_entities/projectiles/projectile.cc
===================================================================
--- trunk/src/world_entities/projectiles/projectile.cc	(revision 10317)
+++ trunk/src/world_entities/projectiles/projectile.cc	(revision 10368)
@@ -25,4 +25,6 @@
 #include "playable.h"
 
+#include <cmath>
+
 #include "debug.h"
 
@@ -46,4 +48,6 @@
   this->subscribeReaction( CoRe::CREngine::CR_PHYSICS_FULL_WALK, Playable::staticClassID());
 
+  this->physDamage = 0.0f;
+  this->elecDamage = 0.0f;
   //this->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
 }
@@ -60,4 +64,31 @@
   */
   //delete this->projectileModel;
+}
+
+Projectile::Projectile (float pDamage, float eDamage, PNode* target) : WorldEntity()
+{
+  this->registerObject(this, Projectile::_objectList);
+
+  this->lifeCycle = 0.0;
+  this->lifeSpan = 1.0f; /* sec */
+  this->removeNode();
+
+  /* character attributes */
+  this->setHealth(1.0f);
+  this->setDamage(1.0f); // default damage of a projectile set to 100.0 damage points
+
+  this->physDamage = pDamage;
+  this->elecDamage = eDamage;
+  this->target = target;
+
+  //this->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+}
+
+void Projectile::initialize(float pDamage, float eDamage, PNode* target)
+{
+  /* character attributes*/
+  this->physDamage = pDamage;
+  this->elecDamage = eDamage;
+  this->target = target;
 }
 
@@ -124,4 +155,13 @@
 
 
+void Projectile::collidesWith (WorldEntity* target, const Vector& location)
+{
+  dynamic_cast<SpaceShip*>(target)->damage(this->getPhysDamage(),this->getElecDamage());
+//   this->destroy(NULL);
+  this->destroy(target);
+}
+
+
+
 /**
  * signal tick, time dependent things will be handled here
@@ -130,7 +170,4 @@
 void Projectile::tick (float dt)
 {
-  Vector v = this->velocity * (dt);
-  this->shiftCoor(v);
-
   if (this->tickLifeCycle(dt))
     this->destroy( NULL );
Index: trunk/src/world_entities/projectiles/projectile.h
===================================================================
--- trunk/src/world_entities/projectiles/projectile.h	(revision 10317)
+++ trunk/src/world_entities/projectiles/projectile.h	(revision 10368)
@@ -12,4 +12,5 @@
 #include "world_entity.h"
 #include "loading/fast_factory.h"
+#include "space_ships/space_ship.h"
 
 #include "sound_source.h"
@@ -22,4 +23,9 @@
     Projectile ();
     virtual ~Projectile ();
+
+    /** @brief Constructor with variable passing*/
+    Projectile (float pDamage, float eDamage, PNode* target);
+    /** @brief for void construction; setting values later - needed for FastFactory*/
+    virtual void initialize(float pDamage, float eDamage, PNode* target);
 
     void setFlightDirection(const Quaternion& flightDirection);
@@ -44,4 +50,7 @@
     virtual void destroy (WorldEntity* killer);
 
+    virtual void collidesWith (WorldEntity* target, const Vector& location);  //!< collision handler; used against SpaceShip as most target will be
+
+
     virtual void tick (float dt);
     /** @brief convenience function
@@ -50,18 +59,28 @@
     inline bool tickLifeCycle(float dt ) { this->lifeCycle += dt/this->lifeSpan;  return(unlikely(this->lifeCycle >= 1)); }
 
+    inline float getPhysDamage() { return this->physDamage; };
+    inline float getElecDamage() { return this->elecDamage; };
+
+    inline void setPhysDamage( float dmg) {this->physDamage = dmg; };
+    inline void setElecDamage( float dmg) {this->elecDamage = dmg; };
 
   protected:
     // energy
-    float                  energyMin;                 //!< The minimal Energy a Projectile needs to be emitted.
-    bool                   bChargeable;               //!< if the Projectile is Charegeable
+    int		       origList;			//!< FIXME currently a fix around the collision seg fault
+    float                   energyMin;                //!< The minimal Energy a Projectile needs to be emitted.
+    bool                    bChargeable;              //!< if the Projectile is Charegeable
 
-    float                  lifeCycle;                 //!< The percentage of the Lifetime done [0-1]
-    float                  lifeSpan;                  //!< The entire lifespan of the Shoot. in seconds
+    float                   lifeCycle;                //!< The percentage of the Lifetime done [0-1]
+    float                   lifeSpan;                 //!< The entire lifespan of the Shoot. in seconds
 
-    Vector                 flightDirection;           //!< DOF direction in which the shoot flighs
+    float                   physDamage;               //!< damage to shield and armor
+    float                   elecDamage;               //!< damage to elctronic
+    float                   turningSpeed;             //!< degrees per tick
 
-    Vector                 velocity;                  //!< velocity of the projectile.
+    Vector                  flightDirection;          //!< DOF direction in which the shoot flighs
 
-    PNode*                 target;                    //!< A target for guided Weapons.
+    Vector                  velocity;                 //!< velocity of the projectile.
+
+    PNode*                  target;                   //!< A target for guided Weapons.
 
     OrxSound::SoundSource  soundSource;
Index: trunk/src/world_entities/projectiles/projectile_weapon.cc
===================================================================
--- trunk/src/world_entities/projectiles/projectile_weapon.cc	(revision 10368)
+++ trunk/src/world_entities/projectiles/projectile_weapon.cc	(revision 10368)
@@ -0,0 +1,182 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Nicolas Schlumberger
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "projectile_weapon.h"
+
+#include "world_entity.h"
+#include "world_entities/weapons/weapon.h"
+#include "model.h"
+#include "sound/resource_sound_buffer.h"
+
+#include <cmath>
+
+#include "debug.h"
+
+ObjectListDefinition(ProjectileWeapon);
+
+/**
+ *  standard constructor
+*/
+ProjectileWeapon::ProjectileWeapon () : Projectile()
+{
+  this->registerObject(this, ProjectileWeapon::_objectList);
+
+  this->lifeCycle = 0.0;
+  this->lifeSpan = 1.0f; /* sec */
+  this->target = NULL;
+  this->removeNode();
+
+  /* character attributes */
+  this->setHealth(1.0f);
+  this->setDamage(1.0f); // default damage of a projectile_weapon set to 100.0 damage points
+
+  this->physDamage = 0.0f;
+  this->elecDamage = 0.0f;
+  //this->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+ProjectileWeapon::~ProjectileWeapon ()
+{
+}
+
+ProjectileWeapon::ProjectileWeapon (float pDamage, float eDamage, PNode* target) : Projectile()
+{
+  this->registerObject(this, ProjectileWeapon::_objectList);
+
+  this->lifeCycle = 0.0;
+  this->lifeSpan = 1.0f; /* sec */
+  this->removeNode();
+
+  /* character attributes */
+  this->setHealth(1.0f);
+  this->setDamage(1.0f); // default damage of a projectile_weapon set to 100.0 damage points
+
+  this->physDamage = pDamage;
+  this->elecDamage = eDamage;
+  this->target = target;
+
+  //this->addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+}
+
+void ProjectileWeapon::initialize(float pDamage, float eDamage, PNode* target)
+{
+  /* character attributes*/
+  this->physDamage = pDamage;
+  this->elecDamage = eDamage;
+  this->target = target;
+}
+
+
+void ProjectileWeapon::loadExplosionSound(const std::string& explosionSound)
+{
+  if (!explosionSound.empty())
+    this->explosionBuffer = OrxSound::ResourceSoundBuffer(explosionSound);
+  else
+    this->explosionBuffer = OrxSound::SoundBuffer();
+}
+
+
+void ProjectileWeapon::loadEngineSound(const std::string& engineSound)
+{
+  if (!engineSound.empty())
+    this->engineBuffer = OrxSound::ResourceSoundBuffer(engineSound);
+  else
+    this->engineBuffer = OrxSound::SoundBuffer();
+}
+
+
+void ProjectileWeapon::setMinEnergy(float energyMin)
+{
+  this->energyMin = energyMin;
+}
+
+
+/**
+ *  this sets the flight direction of the projectile_weapon
+ * @param directin in which to flight
+
+   this function will calculate a vector out of this to be used in the
+   tick function
+*/
+void ProjectileWeapon::setFlightDirection(const Quaternion& flightDirection)
+{
+  Vector v(1, 0, 0);
+  this->flightDirection = flightDirection.apply(v);
+  this->flightDirection.normalize();
+}
+
+/**
+ *  sets the velocity vector to a spec speed
+ * @param velocity: vector of the velocity
+*/
+void ProjectileWeapon::setVelocity(const Vector &velocity)
+{
+  //Vector offsetVel =
+  this->velocity = velocity;
+  // offsetVel.normalize();
+  //this->velocity += (offsetVel * 50.0);
+}
+
+
+
+void ProjectileWeapon::setTarget(PNode* target)
+{
+  if (this->target == NULL)
+    this->target = new PNode(target, PNODE_REPARENT_ON_PARENTS_REMOVE | PNODE_REPARENT_TO_NULL | PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  else
+    this->target->setParent(target);
+}
+
+
+void ProjectileWeapon::collidesWith (WorldEntity* target, const Vector& location)
+{
+  dynamic_cast<SpaceShip*>(target)->damage(this->getPhysDamage(),this->getElecDamage());
+//   this->destroy(NULL);
+  this->destroy(target);
+}
+
+
+
+/**
+ * signal tick, time dependent things will be handled here
+ * @param dt since last tick
+*/
+void ProjectileWeapon::tick (float dt)
+{
+  if (this->tickLifeCycle(dt))
+    this->destroy( NULL );
+}
+
+
+/**
+ *  the function gets called, when the projectile_weapon is destroyed
+*/
+void ProjectileWeapon::destroy (WorldEntity* killer)
+{
+  if (this->explosionBuffer.loaded())
+    this->soundSource.play(this->explosionBuffer);
+}
+
+void ProjectileWeapon::blow()
+{
+}
+
Index: trunk/src/world_entities/projectiles/projectile_weapon.h
===================================================================
--- trunk/src/world_entities/projectiles/projectile_weapon.h	(revision 10368)
+++ trunk/src/world_entities/projectiles/projectile_weapon.h	(revision 10368)
@@ -0,0 +1,126 @@
+/*!
+ * @file projectile_weapon.h
+ * a projectile_weapon, that is been shooted by a weapon
+ *
+ * You can use this class to make some ProjectileWeapons/Bullets/Lasers/Rockets/etc.
+ *
+ */
+
+#ifndef _PROJECTILE_WEAPON_H
+#define _PROJECTILE_WEAPON_H
+
+#include "world_entity.h"
+#include "loading/fast_factory.h"
+#include "space_ships/space_ship.h"
+
+#include "loading/fast_factory.h"
+#include "world_entities/projectiles/projectile.h"
+#include "weapons/weapon.h"
+
+
+#include "sound_source.h"
+#include "sound_buffer.h"
+
+class FastFactory;
+
+
+class ProjectileWeapon : public Projectile
+{
+  ObjectListDeclaration(ProjectileWeapon);
+  public:
+    ProjectileWeapon ();
+    virtual ~ProjectileWeapon ();
+
+    /** @brief Constructor with variable passing*/
+    ProjectileWeapon (float pDamage, float eDamage, PNode* target);
+    /** @brief for void construction; setting values later - needed for FastFactory*/
+    virtual void initialize(float pDamage, float eDamage, PNode* target);
+
+    void setFlightDirection(const Quaternion& flightDirection);
+    void setVelocity(const Vector &velocity);
+    void setLifeSpan(float lifeSpan);
+
+    void loadExplosionSound(const std::string& explosionSound);
+    void loadEngineSound(const std::string& engineSound);
+    void setMinEnergy(float energyMin);
+    /** @returns the minimal charched energy */
+    inline float getMinEnergy() { return this->energyMin; };
+    /** @returns if the ProjectileWeapon can be charged */
+    inline bool isChageable() { return this->bChargeable; };
+
+    void setTarget(PNode* target);
+
+    /** @brief This is called, when the ProjectileWeapon is Emitted */
+    virtual void activate() = 0;
+    /** @brief This is called, when the ProjectileWeapon is being destroyed, or deleted */
+    virtual void deactivate() = 0;
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void collidesWith (WorldEntity* target, const Vector& location);  //!< collision handler; used against SpaceShip as most target will be
+
+
+    virtual void tick (float dt);
+    /** @brief convenience function
+     * @param dt the Time passed
+     * @returns true if the ProjectileWeapon is past its lifeTime, false if it shall still live */
+    inline bool tickLifeCycle(float dt ) { this->lifeCycle += dt/this->lifeSpan;  return(unlikely(this->lifeCycle >= 1)); }
+
+    inline float getPhysDamage() { return this->physDamage; };
+    inline float getElecDamage() { return this->elecDamage; };
+
+    inline void setPhysDamage( float dmg) {this->physDamage = dmg; };
+    inline void setElecDamage( float dmg) {this->elecDamage = dmg; };
+
+    inline void setRotationAxis ( Vector axis ) { this->rotationAxis = axis; };
+    inline void setRotationSpeed ( float speed ) { this->rotationSpeed = speed; };
+    inline const Vector & getRotationAxis () const { return this->rotationAxis; };
+    inline float getRotationSpeed () { return this->rotationSpeed; };     //!< Added for completeness
+
+    inline void setAngle () { this->angle = 0; };
+    inline void setAngle ( float angle ) { this->angle = angle; };
+    inline float getAngle () { return this->angle; };
+
+    inline void updateAngle ( float dt ) { this->angle += this->rotationSpeed * dt; };
+
+    inline void setFragments( int frag ) { this->fragments = frag; };
+    inline int getFragments () { return this->fragments; };
+
+//     virtual void blow ();
+
+  protected:
+    // energy
+    float                   energyMin;                //!< The minimal Energy a ProjectileWeapon needs to be emitted.
+    bool                    bChargeable;              //!< if the ProjectileWeapon is Charegeable
+
+    float                   lifeCycle;                //!< The percentage of the Lifetime done [0-1]
+    float                   lifeSpan;                 //!< The entire lifespan of the Shoot. in seconds
+
+    float                   physDamage;               //!< damage to shield and armor
+    float                   elecDamage;               //!< damage to elctronic
+    float                   turningSpeed;             //!< degrees per tick
+
+    Vector                  flightDirection;          //!< DOF direction in which the shoot flighs
+
+    float                   angle;                    //!< Spinning Projectile, needed to ajust dispersal pattern
+    float                   rotationSpeed;            //!< rotation speed
+    Vector                  rotationAxis;           //!< rotation axis
+
+    int                     fragments;                //!< Number of fragements created by the blow
+
+    Vector                  velocity;                 //!< velocity of the projectile_weapon.
+
+    PNode*                  target;                   //!< A target for guided Weapons.
+
+    virtual void            blow();
+
+//     FastFactory             ff;
+//     static FastFactory*               fastFactory;
+
+    OrxSound::SoundSource  soundSource;
+  private:
+    OrxSound::SoundBuffer  explosionBuffer;
+    OrxSound::SoundBuffer  engineBuffer;
+};
+
+#endif /* _PROJECTILE_WEAPON_H */
Index: trunk/src/world_entities/projectiles/spike.cc
===================================================================
--- trunk/src/world_entities/projectiles/spike.cc	(revision 10368)
+++ trunk/src/world_entities/projectiles/spike.cc	(revision 10368)
@@ -0,0 +1,175 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004-2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Nicolas Schlumberger, Marc Schaerrer
+   co-programmer: Benjamin Grauer
+
+*/
+
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "spike.h"
+
+#include "state.h"
+#include "model.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include <cassert>
+#include "debug.h"
+
+#include "space_ships/space_ship.h"
+
+
+
+ObjectListDefinition(Spike);
+CREATE_FAST_FACTORY_STATIC(Spike);
+
+/**
+ *  standard constructor
+*/
+Spike::Spike () : Projectile()
+{
+  this->registerObject(this, Spike::_objectList);
+
+  this->loadModel("models/projectiles/spike.obj", 2);
+
+  this->setMinEnergy(1);
+  this->setHealthMax(0);
+  this->lifeSpan = 2.0;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+  this->emitter->setEmissionRate(300.0);
+  this->emitter->setEmissionVelocity(50.0);
+
+  this->angle = 0;
+  this->rotationSpeed = 130;
+}
+
+
+/**
+ *  standard deconstructor
+*/
+Spike::~Spike ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (Spike::explosionParticles != NULL && Spike::objectList().size() <= 1)
+  {
+    //if (ClassList::exists(Spike::explosionParticles, CL_PARTICLE_SYSTEM))
+    //  delete Spike::explosionParticles;
+    PRINTF(1)("Deleting Spike Particles\n");
+/*
+  if (Spike::objectList().exists(Spike::explosionParticles))
+      delete Spike::explosionParticles; */
+    Spike::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* Spike::explosionParticles = NULL;
+
+void Spike::activate()
+{
+  if (unlikely(Spike::explosionParticles == NULL))
+  {
+    Spike::explosionParticles = new SpriteParticles(1000);
+    Spike::explosionParticles->setName("SpikeExplosionParticles");
+    Spike::explosionParticles->setLifeSpan(.5, .3);
+    Spike::explosionParticles->setRadius(0.0, 10.0);
+    Spike::explosionParticles->setRadius(.5, 6.0);
+    Spike::explosionParticles->setRadius(1.0, 3.0);
+    Spike::explosionParticles->setColor(0.0, 1,1,0,.9);
+    Spike::explosionParticles->setColor(0.5, .8,.8,0,.5);
+    Spike::explosionParticles->setColor(1.0, .8,.8,.7,.0);
+  }
+
+  this->setDamage(5);
+  this->setHealth(0);
+}
+
+
+void Spike::deactivate()
+{
+  assert (Spike::explosionParticles != NULL);
+  //Spike::explosionParticles->removeEmitter(this->emitter);
+  this->emitter->setSystem(NULL);
+  this->lifeCycle = 0.0;
+
+  this->toList(OM_NULL);
+  this->removeNode();
+  Spike::fastFactory->kill(this);
+}
+
+/*
+void Spike::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  PRINTF(0)("Collision with Spike\n");
+  if (this->hitEntity != entity && entity->isA(CL_NPC))
+    this->destroy( entity );
+  this->hitEntity = entity;
+  dynamic_cast<SpaceShip*>(entity)->damage(this->getDamage(),0);
+//   this->deactivate();
+}*/
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param dt time since last tick
+*/
+void Spike::tick (float dt)
+{
+  Vector v = this->velocity * dt;
+  this->shiftCoor(v);
+
+  if (this->tickLifeCycle(dt))
+    this->deactivate();
+
+  angle += rotationSpeed * dt;
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void Spike::destroy (WorldEntity* killer)
+{
+  Projectile::destroy( killer );
+  PRINTF(5)("DESTROY Spike\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+
+  this->emitter->setSystem(Spike::explosionParticles);
+}
+
+
+void Spike::draw () const
+{
+  glPushAttrib(GL_ENABLE_BIT);
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  glRotatef(angle, 1.0, 0.0, 0.0);
+
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  this->getModel()->draw();
+
+  glPopMatrix();
+  glPopAttrib();
+}
+
Index: trunk/src/world_entities/projectiles/spike.h
===================================================================
--- trunk/src/world_entities/projectiles/spike.h	(revision 10368)
+++ trunk/src/world_entities/projectiles/spike.h	(revision 10368)
@@ -0,0 +1,52 @@
+/*!
+ * @file spike.h
+ * @brief light blaster spike
+*/
+
+#ifndef _SPIKE_H
+#define _SPIKE_H
+
+#include "projectile.h"
+#include "effects/billboard.h"
+
+class Vector;
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class Spike : public Projectile
+{
+  ObjectListDeclaration(Spike);
+  public:
+    Spike ();
+    virtual ~Spike ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+   //virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float dt);
+    virtual void draw () const;
+
+    inline void setVelocity(Vector velocity) {this->velocity = velocity;}
+  private:
+    static FastFactory*               fastFactory;
+
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+
+    float                             angle;
+    float                             rotationSpeed;
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+
+    Vector                            velocity;
+};
+
+#endif /* _SPIKE_H */
Index: trunk/src/world_entities/projectiles/spike_ball.cc
===================================================================
--- trunk/src/world_entities/projectiles/spike_ball.cc	(revision 10368)
+++ trunk/src/world_entities/projectiles/spike_ball.cc	(revision 10368)
@@ -0,0 +1,277 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004-2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Nicolas Schlumberger, Marc Schaerrer
+   co-programmer: Benjamin Grauer
+
+*/
+
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "spike_ball.h"
+
+#include "state.h"
+#include "model.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+
+#include <cassert>
+#include "debug.h"
+
+#include "space_ships/space_ship.h"
+
+
+
+ObjectListDefinition(SpikeBall);
+CREATE_FAST_FACTORY_STATIC(SpikeBall);
+
+/**
+ *  standard constructor
+*/
+SpikeBall::SpikeBall () : ProjectileWeapon()
+{
+  this->registerObject(this, SpikeBall::_objectList);
+
+  this->loadModel("models/projectiles/spike_ball.obj", .25);
+
+  this->setMinEnergy(1);
+  this->setHealthMax(1);
+  this->lifeSpan = 1.0;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+  this->emitter->setEmissionRate(300.0);
+  this->emitter->setEmissionVelocity(50.0);
+
+  this->setRotationSpeed(130);
+
+  this->halo = new Billboard();
+  this->halo->setSize(2, 2);
+  this->halo->setTexture("hbolt_halo.png");
+
+  this->setFragments(26);
+
+  this->size = 4;
+
+  this->launcher = new Vector [this->getFragments()];
+}
+
+
+/**
+ *  standard deconstructor
+*/
+SpikeBall::~SpikeBall ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (SpikeBall::explosionParticles != NULL && SpikeBall::objectList().size() <= 1)
+  {
+    //if (ClassList::exists(SpikeBall::explosionParticles, CL_PARTICLE_SYSTEM))
+    //  delete SpikeBall::explosionParticles;
+    PRINTF(1)("Deleting SpikeBall Particles\n");
+//    if (SpikeBall::objectList().exists(SpikeBall::explosionParticles))
+//      delete SpikeBall::explosionParticles;
+    SpikeBall::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* SpikeBall::explosionParticles = NULL;
+
+void SpikeBall::activate()
+{
+  if (unlikely(SpikeBall::explosionParticles == NULL))
+  {
+    SpikeBall::explosionParticles = new SpriteParticles(1000);
+    SpikeBall::explosionParticles->setName("SpikeBallExplosionParticles");
+    SpikeBall::explosionParticles->setLifeSpan(.5, .3);
+    SpikeBall::explosionParticles->setRadius(0.0, 10.0);
+    SpikeBall::explosionParticles->setRadius(.5, 6.0);
+    SpikeBall::explosionParticles->setRadius(1.0, 3.0);
+    SpikeBall::explosionParticles->setColor(0.0, 1,1,0,.9);
+    SpikeBall::explosionParticles->setColor(0.5, .8,.8,0,.5);
+    SpikeBall::explosionParticles->setColor(1.0, .8,.8,.7,.0);
+  }
+  this->setDamage(5);
+  this->setHealth(10);
+  this->setRotationAxis(VECTOR_RAND(1));
+  this->setAngle();
+
+  this->launcher[0] = Vector(1.0, 0.0, 0.0);
+  this->launcher[1] = Vector(0.0, 1.0, 0.0);
+  this->launcher[2] = Vector(0.0, 0.0, 1.0);
+
+  this->launcher[3] = Vector(1.0, 1.0, 0.0);
+  this->launcher[4] = Vector(0.0, 1.0, 1.0);
+  this->launcher[5] = Vector(1.0, 0.0, 1.0);
+  this->launcher[6] = Vector(1.0, -1.0, 0.0);
+  this->launcher[7] = Vector(0.0, 1.0, -1.0);
+  this->launcher[8] = Vector(-1.0, 0.0, 1.0);
+
+  this->launcher[9] = Vector(-1.0, 1.0, 1.0);
+  this->launcher[10] = Vector(1.0, 1.0, 1.0);
+  this->launcher[11] = Vector(1.0, -1.0, 1.0);
+  this->launcher[12] = Vector(-1.0, -1.0, 1.0);
+
+  int tmp = this->getFragments() / 2;
+  for (int i = 0; i < tmp; i++)
+  {
+    this->launcher[i].normalize();
+    this->launcher[tmp + i] =  this->launcher[i] * (-1);
+  }
+
+  this->freeMode = false;
+}
+
+
+void SpikeBall::deactivate()
+{
+  assert (SpikeBall::explosionParticles != NULL);
+  //SpikeBall::explosionParticles->removeEmitter(this->emitter);
+  this->emitter->setSystem(NULL);
+  this->lifeCycle = 0.0;
+
+  this->toList(OM_NULL);
+  this->removeNode();
+  SpikeBall::fastFactory->kill(this);
+}
+
+/*
+void SpikeBall::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  PRINTF(0)("Collision with SpikeBall\n");
+  if (this->hitEntity != entity && entity->isA(CL_NPC))
+    this->destroy( entity );
+  this->hitEntity = entity;
+  dynamic_cast<SpaceShip*>(entity)->damage(this->getDamage(),0);
+}*/
+
+
+void SpikeBall::blow()
+{
+  if ( this->freeMode )
+    updateFireDir();
+
+  Spike* pj = NULL;
+  for ( int i = 0; i < this->getFragments(); i++)
+  {
+    pj  = new Spike();
+    assert( pj );
+    pj->setParent(PNode::getNullParent());
+
+    pj->setVelocity(this->launcher[i].getNormalized() * 250.0);
+
+    pj->setParent(PNode::getNullParent());
+    pj->setAbsCoor(this->getAbsCoor() + this->launcher[i] * this->size);
+//     Quaternion q;
+    pj->setAbsDir(Quaternion(this->launcher[i], 0));
+
+    pj->toList(this->getOMListNumber());
+
+    pj->activate();
+  }
+}
+
+
+void SpikeBall::updateFireDir(){
+
+  float** m = new float* [3];
+  for( int i = 0; i < 3 ; i++)
+    m[i] = new float;
+
+  float nx, ny, nz, ca, sa;
+
+  nx = this->getRotationAxis().x;
+  ny = this->getRotationAxis().y;
+  nz = this->getRotationAxis().z;
+
+  ca = cos (this->getAngle());
+  sa = sin (this->getAngle());
+
+  m[0][0] = nx * nx * (1 - ca) + ca;
+  m[0][1] = nx * ny * (1 - ca) + nz * sa;
+  m[0][2] = nx * nz * (1 - ca) - ny * sa;
+  m[1][0] = nx * nz * (1 - ca) - nz * sa;
+  m[1][1] = ny * ny * (1 - ca) + ca;
+  m[1][2] = ny * nz * (1 - ca) + nx * sa;
+  m[2][0] = nx * nz * (1 - ca) + ny * sa;
+  m[2][1] = ny * nz * (1 - ca) - nx * sa;
+  m[2][2] = nz * nz * (1 - ca) + ca;
+
+  float x, y, z;
+  for (int i = 0; i < this->getFragments(); i++){
+    x = m[0][0] * this->launcher[i].x + m[0][1] * this->launcher[i].y + m[0][2] * this->launcher[i].z;
+    y = m[1][0] * this->launcher[i].x + m[1][1] * this->launcher[i].y + m[1][2] * this->launcher[i].z;
+    z = m[2][0] * this->launcher[i].x + m[2][1] * this->launcher[i].y + m[2][2] * this->launcher[i].z;
+
+    this->launcher[i] = Vector (x, y, z);
+  }
+
+  for( int i = 0; i < 3 ; i++)
+    delete m[i];
+  delete m;
+}
+
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param dt time since last tick
+*/
+void SpikeBall::tick (float dt)
+{
+  Vector v = this->velocity * dt;
+  this->shiftCoor(v);
+
+  if (this->tickLifeCycle(dt)){
+    this->blow();
+    this->deactivate();
+  }
+
+  this->updateAngle( dt );
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void SpikeBall::destroy (WorldEntity* killer)
+{
+  ProjectileWeapon::destroy( killer );
+  PRINTF(5)("DESTROY SpikeBall\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+
+  this->emitter->setSystem(SpikeBall::explosionParticles);
+}
+
+
+void SpikeBall::draw () const
+{
+  glPushAttrib(GL_ENABLE_BIT);
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  this->halo->draw();
+
+  glRotatef(angle, this->getRotationAxis().x, this->getRotationAxis().y, this->getRotationAxis().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  this->getModel()->draw();
+
+
+  glPopMatrix();
+  glPopAttrib();
+}
+
Index: trunk/src/world_entities/projectiles/spike_ball.h
===================================================================
--- trunk/src/world_entities/projectiles/spike_ball.h	(revision 10368)
+++ trunk/src/world_entities/projectiles/spike_ball.h	(revision 10368)
@@ -0,0 +1,67 @@
+/*!
+ * @file spike_ball.h
+ * @brief Noxonian SpikeBall Projectile; 2 stage weapon, splits into spikes
+*/
+
+#ifndef _SPIKE_BALL_H
+#define _SPIKE_BALL_H
+
+#include "projectile_weapon.h"
+#include "spike.h"
+#include "effects/billboard.h"
+
+
+#include "extendable.h"
+
+class Vector;
+class ProjectileWeapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+
+class SpikeBall : public ProjectileWeapon
+{
+  ObjectListDeclaration(SpikeBall);
+  public:
+    SpikeBall ();
+    virtual ~SpikeBall ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+   // virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float dt);
+    virtual void draw () const;
+
+    inline void setVelocity(Vector velocity) { this->velocity = velocity; }
+
+
+  private:
+    static FastFactory*               fastFactory;
+
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+
+    Vector                            velocity;
+
+    Billboard*                        halo;
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+
+    void updateFireDir();
+    virtual void blow();
+
+    Vector*       launcher;
+    float         size;
+
+    bool          freeMode;
+
+};
+
+#endif /* _SPIKE_BALL_H */
Index: trunk/src/world_entities/projectiles/swarm_projectile.cc
===================================================================
--- trunk/src/world_entities/projectiles/swarm_projectile.cc	(revision 10368)
+++ trunk/src/world_entities/projectiles/swarm_projectile.cc	(revision 10368)
@@ -0,0 +1,273 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004-2006 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Marc Schaerrer, Nicolas Schlumberger
+   co-programmer:
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "swarm_projectile.h"
+
+#include "state.h"
+
+#include "particles/dot_emitter.h"
+#include "particles/sprite_particles.h"
+#include "space_ships/space_ship.h"
+#include "effects/trail.h"
+
+#include "debug.h"
+
+
+
+#include "math/vector.h"
+
+ObjectListDefinition(SwarmProjectile);
+CREATE_FAST_FACTORY_STATIC(SwarmProjectile);
+
+/**
+ *  standard constructor
+*/
+SwarmProjectile::SwarmProjectile () : Projectile()
+{
+
+/*  this->loadModel("models/projectiles/orx-rocket.obj", 0.5);*/
+  this->loadModel("models/projectiles/swarm_projectile.obj"); // no double rescale (see draw())
+  this->loadExplosionSound("sound/explosions/explosion_4.wav");
+
+
+  this->setMinEnergy(1);
+  this->setHealthMax(10);
+  this->lifeSpan = 4.0;
+  this->agility = 3.5;
+
+  this->emitter = new DotEmitter(100, 5, M_2_PI);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+
+  this->turningSpeed = 10;
+
+  this->physDamage = 200;
+  this->elecDamage = 0;
+
+  this->trail = new Trail(2.5,4,.2, this);
+  //this->trail->setParent( this);
+  this->trail->setTexture( "maps/laser.png");
+
+
+  this->origList = this->getOMListNumber();
+  this->toList(OM_ENVIRON);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+SwarmProjectile::~SwarmProjectile ()
+{
+
+  if (SwarmProjectile::explosionParticles != NULL && SwarmProjectile::objectList().size() <= 1)
+  {
+    if (ParticleSystem::objectList().exists(SwarmProjectile::explosionParticles))
+      delete SwarmProjectile::explosionParticles;
+    SwarmProjectile::explosionParticles = NULL;
+  }
+  // delete this->emitter;
+  delete this->trail;
+}
+
+SpriteParticles* SwarmProjectile::explosionParticles = NULL;
+
+
+
+void SwarmProjectile::activate()
+{
+  this->toList(OM_ENVIRON);
+  if (unlikely(SwarmProjectile::explosionParticles == NULL))
+  {
+    SwarmProjectile::explosionParticles = new SpriteParticles(200);
+    SwarmProjectile::explosionParticles->setName("SwarmProjectileExplosionParticles");
+    SwarmProjectile::explosionParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    SwarmProjectile::explosionParticles->setLifeSpan(.5, .3);
+    SwarmProjectile::explosionParticles->setRadius(0.0, 10);
+    SwarmProjectile::explosionParticles->setRadius(.5, 15.0);
+    SwarmProjectile::explosionParticles->setRadius(1.0, 10.0);
+    SwarmProjectile::explosionParticles->setColor(0.0, 0,1,0,1);
+    SwarmProjectile::explosionParticles->setColor(0.5, .8,.8,0,.8);
+    SwarmProjectile::explosionParticles->setColor(0.8, .8,.8,.3,.8);
+    SwarmProjectile::explosionParticles->setColor(1.0, 1,1,1,.0);
+  }
+
+  this->emitter->setEmissionRate(50.0);
+  this->emitter->setEmissionVelocity(0.0);
+  this->emitter->setInheritSpeed(0);
+
+  this->setHealth(10.0* (float)rand()/(float)RAND_MAX);
+
+  this->maxVelocity = 300;
+
+  this->rotationSpeed = 360;
+  this->angle = 0;
+
+  this->curDir = this->lastDir = this->velocity;
+}
+
+
+void SwarmProjectile::deactivate()
+{
+  this->emitter->setSystem(NULL);
+  this->lifeCycle = 0.0;
+
+  this->toList(OM_DEAD);
+  this->removeNode();
+  SwarmProjectile::fastFactory->kill(this);
+}
+
+
+void SwarmProjectile::hit (WorldEntity* entity, float damage)
+{
+  if (this->hitEntity != entity)
+    this->destroy( entity );
+  this->hitEntity = entity;
+  //dynamic_cast<SpaceShip*>(entity)->damage(this->getPhysDamage(),this->getElecDamage());
+ // this->destroy(this);
+  this->deactivate();
+}
+
+
+void SwarmProjectile::setTarget(PNode* target)
+{
+    this->target = target;
+}
+
+
+
+/**
+ *  this function gets called by tick to calculate the new flight direction
+ *  @param curDirection direction vector
+ *  @param estTargetDir target vector, pointing to where the target will be on hit
+ *  @param angle = tick * turningSpeed
+ *  @return (new) direction vector
+*/
+Vector SwarmProjectile::newDirection(Vector curDirection, Vector estTargetDir, float angle)
+{
+  if (unlikely(curDirection.len() == 0))
+    return curDirection;
+  //printf("recalculating direction\n");
+  float tmp = angleRad ( curDirection, estTargetDir);
+  if ( unlikely(tmp == 0) ) { return curDirection * maxVelocity / curDirection.len(); }
+//   printf("turning angle: %f\ntemp: %f\n", angle, tmp);
+
+  if( fabsf(angle) >  fabsf(tmp) )
+    angle = tmp;
+  else
+    angle *= tmp/fabsf(tmp);
+
+  Vector d = curDirection.cross(estTargetDir).cross(curDirection);
+  d.normalize();
+  if( unlikely( fabsf(angle) == 90)) { return d; } //avoid complication
+
+  Vector newDir = curDirection + d *  curDirection.len() * tan (angle);
+  newDir.normalize();
+  newDir *= curDirection.len();
+  return newDir;
+}
+
+
+
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param time since last tick
+*/
+void SwarmProjectile::tick (float time)
+{
+  if(unlikely(this->target == NULL)) /** Check whether the target still exists*/
+    this->deactivate();
+
+
+
+/** old  guiding function*/
+
+  float projectileVelocity = this->getVelocity().len();
+  if (target != NULL){
+    Vector estTargetDir = (this->target->getAbsCoor() - this->getAbsCoor()).getNormalized();
+    this->velocity = this->newDirection(this->velocity, estTargetDir, this->turningSpeed * time );
+  }
+  else
+    if (likely(projectileVelocity != 0 || projectileVelocity != this->maxVelocity) )
+      this->velocity *= (this->maxVelocity / projectileVelocity); // set speed to max
+/*
+  printf("position: %f, %f, %f\n", this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z);
+  printf("target position: %f, %f, %f\n", this->target->getAbsCoor().x, this->target->getAbsCoor().y, this->target->getAbsCoor().z);*/
+
+  this->shiftCoor(this->velocity * time);
+
+  if(this->tickLifeCycle(time))
+    this->deactivate();
+
+  this->trail->tick(time);
+
+  this->angle += this->rotationSpeed * time;
+  while (this->angle > 360)
+    this->angle -= 360;
+
+  this->lastDir = this->curDir;
+  this->curDir = this->velocity;
+
+  if( this->target != NULL && (this->getAbsCoor() - this->target->getAbsCoor()).len() < 3)   // FIXME  Temp fake workaround for collision :)
+  {
+    dynamic_cast<WorldEntity*>(target)->hit(this->getDamage(), this);
+    this->deactivate();
+  }
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+ */
+void SwarmProjectile::destroy (WorldEntity* killer)
+{
+
+//   printf("THIS SHOULD WORK!\n");
+
+  Projectile::destroy( killer );
+  PRINTF(5)("DESTROY SwarmProjectile\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+  this->emitter->setSystem(SwarmProjectile::explosionParticles);
+
+  this->emitter->setEmissionRate(1000.0);
+  this->emitter->setEmissionVelocity(50.0);
+  this->deactivate();
+
+}
+
+
+void SwarmProjectile::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  Vector tmpDir = this->curDir; // *.7 + this->lastDir * .3;
+  tmpDir.slerpTo(this->lastDir, .4);
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  Vector tmpRot = this->getAbsCoor().cross(tmpDir);
+  glRotatef (angleRad ( this->getAbsCoor(), tmpDir), tmpRot.x, tmpRot.y, tmpRot.z );
+  glRotatef(this->angle, 1.0f, 0.0f, 0.0f); //spinning missile
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  //glScalef(2.0, 2.0, 2.0);  // no double rescale
+  this->getModel()->draw();
+  glTranslatef(-.9,0,0);
+  this->trail->draw();
+  glPopMatrix();
+}
Index: trunk/src/world_entities/projectiles/swarm_projectile.h
===================================================================
--- trunk/src/world_entities/projectiles/swarm_projectile.h	(revision 10368)
+++ trunk/src/world_entities/projectiles/swarm_projectile.h	(revision 10368)
@@ -0,0 +1,63 @@
+/*!
+ * @file swarm_projectile.h
+ * @brief a SwarmProjectile Projectile
+*/
+
+#ifndef _SWARM_PROJECTILE_H
+#define _SWARM_PROJECTILE_H
+
+#include "projectile.h"
+
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+class Aim;
+class Trail;
+
+class SwarmProjectile : public Projectile
+{
+  ObjectListDeclaration(SwarmProjectile);
+  public:
+    SwarmProjectile ();
+    virtual ~SwarmProjectile ();
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void hit (WorldEntity* entity, float damage);
+
+    virtual void destroy (WorldEntity* killer);
+
+    virtual void tick (float time);
+    virtual void draw () const;
+
+    void setTarget(PNode* target);
+
+  private:
+    static FastFactory*               fastFactory;
+    static SpriteParticles*           explosionParticles;
+
+    Trail*                            trail;
+
+    ParticleEmitter*                  emitter;
+    float                             agility;
+    float                             maxVelocity;
+    float                             speed;
+    Vector                            diffVector ;
+    Vector                            correctionVector;
+
+    Vector                            curDir;
+    Vector                            lastDir;
+    Vector                            oldPos;
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+
+    Vector newDirection(Vector curDirection, Vector estTargetDir, float angle);
+
+    // spinning missle
+    float                             rotationSpeed;
+    float                             angle;
+};
+
+#endif /* _SWARM_PROJECTILE_H */
