Index: code/trunk/src/orxonox/objects/BillboardProjectile.cc
===================================================================
--- code/trunk/src/orxonox/objects/BillboardProjectile.cc	(revision 1552)
+++ code/trunk/src/orxonox/objects/BillboardProjectile.cc	(revision 1552)
@@ -0,0 +1,62 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "BillboardProjectile.h"
+
+#include <OgreBillboard.h>
+
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(BillboardProjectile);
+
+    BillboardProjectile::BillboardProjectile(SpaceShip* owner) : Projectile(owner)
+    {
+        RegisterObject(BillboardProjectile);
+
+        if (this->owner_)
+        {
+            this->billboard_.setBillboardSet("Examples/Flare", ColourValue(1.0, 1.0, 0.5), 1);
+            this->attachObject(this->billboard_.getBillboardSet());
+            this->scale(0.5);
+        }
+    }
+
+    BillboardProjectile::~BillboardProjectile()
+    {
+        if (this->owner_)
+            this->detachObject(this->billboard_.getBillboardSet());
+    }
+
+    void BillboardProjectile::setColour(const ColourValue& colour)
+    {
+        this->billboard_.getBillboardSet()->getBillboard(0)->setColour(colour);
+    }
+}
Index: code/trunk/src/orxonox/objects/BillboardProjectile.h
===================================================================
--- code/trunk/src/orxonox/objects/BillboardProjectile.h	(revision 1552)
+++ code/trunk/src/orxonox/objects/BillboardProjectile.h	(revision 1552)
@@ -0,0 +1,52 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _BillboardProjectile_H__
+#define _BillboardProjectile_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "Projectile.h"
+#include "tools/BillboardSet.h"
+#include "util/Math.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport BillboardProjectile : public Projectile
+    {
+        public:
+            BillboardProjectile(SpaceShip* owner = 0);
+            virtual ~BillboardProjectile();
+            virtual void setColour(const ColourValue& colour);
+
+        private:
+            BillboardSet billboard_;
+    };
+}
+
+#endif /* _BillboardProjectile_H__ */
Index: code/trunk/src/orxonox/objects/Explosion.cc
===================================================================
--- code/trunk/src/orxonox/objects/Explosion.cc	(revision 1535)
+++ 	(revision )
@@ -1,92 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Fabian 'x3n' Landau
- *   Co-authors:
- *      ...
- *
- */
-
-#include "OrxonoxStableHeaders.h"
-#include "Explosion.h"
-
-#include <OgreParticleSystem.h>
-#include <OgreSceneManager.h>
-#include <OgreSceneNode.h>
-
-#include "core/CoreIncludes.h"
-#include "core/Executor.h"
-
-#include "util/Math.h"
-#include "GraphicsEngine.h"
-#include "particle/ParticleInterface.h"
-
-namespace orxonox
-{
-    CreateFactory(Explosion);
-
-    Explosion::Explosion(WorldEntity* owner) :
-      lifetime_(0.4),
-      particle_(0)
-    {
-        RegisterObject(Explosion);
-
-        if (owner)
-        {
-            this->destroyTimer_.setTimer(this->lifetime_, false, this, createExecutor(createFunctor(&Explosion::destroyObject)));
-
-            Vector3 position = owner->getNode()->getWorldPosition();
-
-            this->particle_ = new ParticleInterface(GraphicsEngine::getSingleton().getSceneManager(), "explosion" + this->getName(), "Orxonox/treibwerk");
-            this->particle_->getParticleSystem()->setParameter("local_space", "true");
-            this->particle_->newEmitter();
-            this->particle_->setPositionOfEmitter(0, Vector3::ZERO);
-            this->particle_->setPositionOfEmitter(1, Vector3::ZERO);
-            this->particle_->setColour(ColourValue(1.0, 0.8, 0.2));
-
-            this->setPosition(position);
-            this->scale(2);
-
-            this->particle_->addToSceneNode(this->getNode());
-        }
-    }
-
-    Explosion::~Explosion()
-    {
-        if (this->particle_)
-        {
-            this->particle_->detachFromSceneNode();
-            delete this->particle_;
-        }
-    };
-    
-    /*bool Explosion::create(){
-      if(!WorldEntity::create())
-        return false;
-      classID=this->getIdentifier()->getNetworkID();
-    }*/
-
-    void Explosion::destroyObject()
-    {
-        delete this;
-    }
-}
Index: code/trunk/src/orxonox/objects/Explosion.h
===================================================================
--- code/trunk/src/orxonox/objects/Explosion.h	(revision 1535)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- *   ORXONOX - the hottest 3D action shooter ever to exist
- *                    > www.orxonox.net <
- *
- *
- *   License notice:
- *
- *   This program is free software; you can redistribute it and/or
- *   modify it under the terms of the GNU General Public License
- *   as published by the Free Software Foundation; either version 2
- *   of the License, or (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- *   Author:
- *      Fabian 'x3n' Landau
- *   Co-authors:
- *      ...
- *
- */
-
-#ifndef _Explosion_H__
-#define _Explosion_H__
-
-#include "OrxonoxPrereqs.h"
-
-#include "WorldEntity.h"
-#include "../tools/Timer.h"
-
-namespace orxonox
-{
-    class _OrxonoxExport Explosion : public WorldEntity
-    {
-        public:
-            Explosion(WorldEntity* owner = 0);
-            virtual ~Explosion();
-            void destroyObject();
-            virtual bool create(){return WorldEntity::create();}
-
-        private:
-            Timer<Explosion> destroyTimer_;
-            float lifetime_;
-            ParticleInterface* particle_;
-    };
-}
-
-#endif /* _Explosion_H__ */
Index: code/trunk/src/orxonox/objects/Model.cc
===================================================================
--- code/trunk/src/orxonox/objects/Model.cc	(revision 1535)
+++ code/trunk/src/orxonox/objects/Model.cc	(revision 1552)
@@ -45,5 +45,5 @@
     CreateFactory(Model);
 
-    Model::Model()
+    Model::Model() : meshSrc_("")
     {
         RegisterObject(Model);
@@ -53,4 +53,6 @@
     Model::~Model()
     {
+        if ((this->meshSrc_ != "") && (this->meshSrc_.size() > 0))
+            this->detachObject(this->mesh_.getEntity());
     }
 
Index: code/trunk/src/orxonox/objects/ParticleProjectile.cc
===================================================================
--- code/trunk/src/orxonox/objects/ParticleProjectile.cc	(revision 1552)
+++ code/trunk/src/orxonox/objects/ParticleProjectile.cc	(revision 1552)
@@ -0,0 +1,57 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "ParticleProjectile.h"
+
+#include "SpaceShip.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(ParticleProjectile);
+
+    ParticleProjectile::ParticleProjectile(SpaceShip* owner) : BillboardProjectile(owner), particles_(0)
+    {
+        RegisterObject(ParticleProjectile);
+
+        if (this->owner_)
+        {
+            this->particles_ = new ParticleInterface("Orxonox/shot2");
+            this->particles_->addToSceneNode(this->getNode());
+            this->particles_->getAllEmitters()->setDirection(-this->owner_->getInitialDir());
+            this->particles_->setKeepParticlesInLocalSpace(true);
+        }
+    }
+
+    ParticleProjectile::~ParticleProjectile()
+    {
+        if (this->particles_)
+            delete this->particles_;
+    }
+}
Index: code/trunk/src/orxonox/objects/ParticleProjectile.h
===================================================================
--- code/trunk/src/orxonox/objects/ParticleProjectile.h	(revision 1552)
+++ code/trunk/src/orxonox/objects/ParticleProjectile.h	(revision 1552)
@@ -0,0 +1,51 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ParticleProjectile_H__
+#define _ParticleProjectile_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "BillboardProjectile.h"
+#include "particle/ParticleInterface.h"
+#include "util/Math.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport ParticleProjectile : public BillboardProjectile
+    {
+        public:
+            ParticleProjectile(SpaceShip* owner = 0);
+            virtual ~ParticleProjectile();
+
+        private:
+            ParticleInterface* particles_;
+    };
+}
+
+#endif /* _ParticleProjectile_H__ */
Index: code/trunk/src/orxonox/objects/ParticleSpawner.cc
===================================================================
--- code/trunk/src/orxonox/objects/ParticleSpawner.cc	(revision 1552)
+++ code/trunk/src/orxonox/objects/ParticleSpawner.cc	(revision 1552)
@@ -0,0 +1,80 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OrxonoxStableHeaders.h"
+#include "ParticleSpawner.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+#include "particle/ParticleInterface.h"
+
+namespace orxonox
+{
+    CreateFactory(ParticleSpawner);
+
+    ParticleSpawner::ParticleSpawner() : particle_(0)
+    {
+        RegisterObject(ParticleSpawner);
+    }
+
+    ParticleSpawner::ParticleSpawner(const std::string& templateName, float lifetime, float delay, const Vector3& direction) : particle_(0)
+    {
+        RegisterObject(ParticleSpawner);
+
+        ExecutorMember<ParticleSpawner>* executor = createExecutor(createFunctor(&ParticleSpawner::createParticleSpawner));
+        executor->setDefaultValues(lifetime);
+        this->timer_.setTimer(delay, false, this, executor);
+        this->particle_ = new ParticleInterface(templateName);
+        this->particle_->addToSceneNode(this->getNode());
+        this->particle_->setEnabled(false);
+        if (direction != Vector3::ZERO)
+        {
+            this->particle_->getAllEmitters()->setDirection(direction);
+        }
+    }
+
+    ParticleSpawner::~ParticleSpawner()
+    {
+        if (this->particle_)
+        {
+            this->particle_->detachFromSceneNode();
+            delete this->particle_;
+        }
+    };
+
+    void ParticleSpawner::createParticleSpawner(float lifetime)
+    {
+        this->timer_.setTimer(lifetime, false, this, createExecutor(createFunctor(&ParticleSpawner::destroyParticleSpawner)));
+        this->particle_->setEnabled(true);
+    }
+
+    void ParticleSpawner::destroyParticleSpawner()
+    {
+        delete this;
+    }
+}
Index: code/trunk/src/orxonox/objects/ParticleSpawner.h
===================================================================
--- code/trunk/src/orxonox/objects/ParticleSpawner.h	(revision 1552)
+++ code/trunk/src/orxonox/objects/ParticleSpawner.h	(revision 1552)
@@ -0,0 +1,57 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ParticleSpawner_H__
+#define _ParticleSpawner_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "WorldEntity.h"
+#include "../tools/Timer.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport ParticleSpawner : public WorldEntity
+    {
+        public:
+            ParticleSpawner();
+            ParticleSpawner(const std::string& templateName, float lifetime, float delay = 0, const Vector3& direction = Vector3::ZERO);
+            virtual ~ParticleSpawner();
+            inline ParticleInterface* getParticleInterface() const
+                { return this->particle_; }
+
+        private:
+            void createParticleSpawner(float lifetime);
+            void destroyParticleSpawner();
+
+            Timer<ParticleSpawner> timer_;
+            ParticleInterface* particle_;
+    };
+}
+
+#endif /* _ParticleSpawner_H__ */
Index: code/trunk/src/orxonox/objects/Projectile.cc
===================================================================
--- code/trunk/src/orxonox/objects/Projectile.cc	(revision 1535)
+++ code/trunk/src/orxonox/objects/Projectile.cc	(revision 1552)
@@ -35,25 +35,21 @@
 #include "core/Executor.h"
 #include "core/ConfigValueIncludes.h"
+#include "particle/ParticleInterface.h"
 
-#include "SpaceShip.h"
-#include "Explosion.h"
+#include "SpaceShipAI.h"
+#include "ParticleSpawner.h"
 #include "Model.h"
 
 namespace orxonox
 {
-    CreateFactory(Projectile);
+    float Projectile::speed_ = 2000;
 
-    float Projectile::speed_ = 0;
-
-    Projectile::Projectile(SpaceShip* owner) :
-      owner_(owner)
+    Projectile::Projectile(SpaceShip* owner) : owner_(owner)
     {
         RegisterObject(Projectile);
 
         this->setConfigValues();
-
-        this->billboard_.setBillboardSet("Examples/Flare", ColourValue(1.0, 1.0, 0.5), 1);
-        this->attachObject(this->billboard_.getBillboardSet());
-        this->scale(0.5);
+        this->explosionTemplateName_ = "Orxonox/explosion1";
+        this->smokeTemplateName_ = "Orxonox/smoke3";
 
         if (this->owner_)
@@ -63,9 +59,8 @@
             this->setPosition(this->owner_->getPosition());
             this->translate(Vector3(55, 0, 0), Ogre::Node::TS_LOCAL);
-            this->setVelocity(Vector3(1, 0, 0) * this->speed_);
+            this->setVelocity(this->owner_->getInitialDir() * this->speed_);
         }
 
         this->destroyTimer_.setTimer(this->lifetime_, false, this, createExecutor(createFunctor(&Projectile::destroyObject)));
-//        COUT(3) << this->classID << std::endl;
     }
 
@@ -76,8 +71,9 @@
     void Projectile::setConfigValues()
     {
-        SetConfigValue(lifetime_, 10.0).description("The time in seconds a projectile stays alive");
+        SetConfigValue(damage_, 15.0).description("The damage caused by the projectile");
+        SetConfigValue(lifetime_, 5.0).description("The time in seconds a projectile stays alive");
         SetConfigValue(speed_, 2000.0).description("The speed of a projectile in units per second");
 
-        this->setVelocity(Vector3(1, 0, 0) * this->speed_);
+        this->setVelocity(this->owner_->getInitialDir() * this->speed_);
     }
 
@@ -95,6 +91,14 @@
                 if (this->getPosition().squaredDistance(it->getPosition()) <= (radius*radius))
                 {
-                    Explosion *exp = new Explosion(this);
-                    exp->create();
+                    // hit
+                    if (it->isA(Class(SpaceShipAI)))
+                        ((SpaceShipAI*)(*it))->damage(this->damage_);
+                    ParticleSpawner* explosion = new ParticleSpawner(this->explosionTemplateName_, 2.0);
+                    explosion->setPosition(this->getPosition());
+                    explosion->create();
+                    ParticleSpawner* smoke = new ParticleSpawner(this->smokeTemplateName_, 6.0, 0.0);
+                    smoke->setPosition(this->getPosition());
+                    smoke->getParticleInterface()->setSpeedFactor(3.0);
+                    smoke->create();
                     delete this;
                     return;
@@ -108,8 +112,3 @@
         delete this;
     }
-
-    void Projectile::setColour(const ColourValue& colour)
-    {
-        this->billboard_.getBillboardSet()->getBillboard(0)->setColour(colour);
-    }
 }
Index: code/trunk/src/orxonox/objects/Projectile.h
===================================================================
--- code/trunk/src/orxonox/objects/Projectile.h	(revision 1535)
+++ code/trunk/src/orxonox/objects/Projectile.h	(revision 1552)
@@ -33,7 +33,5 @@
 
 #include "WorldEntity.h"
-#include "../tools/BillboardSet.h"
-#include "../tools/Timer.h"
-#include "util/Math.h"
+#include "tools/Timer.h"
 
 namespace orxonox
@@ -42,11 +40,8 @@
     {
         public:
-            Projectile(SpaceShip* owner = 0);
             virtual ~Projectile();
             void setConfigValues();
             void destroyObject();
             virtual void tick(float dt);
-            virtual bool create(){return WorldEntity::create();}
-            void setColour(const ColourValue& colour);
 
             static float getSpeed()
@@ -54,10 +49,13 @@
 
         protected:
+            Projectile(SpaceShip* owner = 0);
             SpaceShip* owner_;
 
         private:
-            BillboardSet billboard_;
+            std::string explosionTemplateName_;
+            std::string smokeTemplateName_;
             static float speed_;
             float lifetime_;
+            float damage_;
             Timer<Projectile> destroyTimer_;
     };
Index: code/trunk/src/orxonox/objects/RotatingProjectile.cc
===================================================================
--- code/trunk/src/orxonox/objects/RotatingProjectile.cc	(revision 1535)
+++ code/trunk/src/orxonox/objects/RotatingProjectile.cc	(revision 1552)
@@ -37,5 +37,5 @@
     CreateFactory(RotatingProjectile);
 
-    RotatingProjectile::RotatingProjectile(SpaceShip* owner) : Projectile(owner)
+    RotatingProjectile::RotatingProjectile(SpaceShip* owner) : BillboardProjectile(owner)
     {
         RegisterObject(RotatingProjectile);
Index: code/trunk/src/orxonox/objects/RotatingProjectile.h
===================================================================
--- code/trunk/src/orxonox/objects/RotatingProjectile.h	(revision 1535)
+++ code/trunk/src/orxonox/objects/RotatingProjectile.h	(revision 1552)
@@ -2,11 +2,11 @@
 #define _RotatingProjectile_H__
 
-#include "../OrxonoxPrereqs.h"
+#include "OrxonoxPrereqs.h"
 #include "util/Math.h"
-#include "Projectile.h"
+#include "BillboardProjectile.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport RotatingProjectile : public Projectile/*, public network::Synchronisable*/
+    class _OrxonoxExport RotatingProjectile : public BillboardProjectile
     {
         public:
@@ -15,5 +15,4 @@
             void setConfigValues();
             virtual void tick(float dt);
-            virtual bool create(){return Projectile::create();}
 
         private:
Index: code/trunk/src/orxonox/objects/SpaceShip.cc
===================================================================
--- code/trunk/src/orxonox/objects/SpaceShip.cc	(revision 1535)
+++ code/trunk/src/orxonox/objects/SpaceShip.cc	(revision 1552)
@@ -44,6 +44,6 @@
 #include "core/input/InputManager.h"
 #include "particle/ParticleInterface.h"
-#include "Projectile.h"
 #include "RotatingProjectile.h"
+#include "ParticleProjectile.h"
 #include "core/XMLPort.h"
 #include "core/ConsoleCommand.h"
@@ -69,5 +69,5 @@
     SpaceShip* SpaceShip::instance_s;
 
-    
+
     SpaceShip *SpaceShip::getLocalShip(){
       Iterator<SpaceShip> it;
@@ -88,5 +88,6 @@
       cam_(0),
       camName_("CamNode"),
-      tt_(0),
+      tt1_(0),
+      tt2_(0),
       redNode_(0),
       greenNode_(0),
@@ -111,5 +112,4 @@
       mouseX_(0.0f),
       mouseY_(0.0f),
-      emitterRate_(0.0f),
       myShip_(false),
       teamNr_(0),
@@ -138,6 +138,8 @@
     SpaceShip::~SpaceShip()
     {
-        if (this->tt_)
-            delete this->tt_;
+        if (this->tt1_)
+            delete this->tt1_;
+        if (this->tt2_)
+            delete this->tt2_;
         if(setMouseEventCallback_)
           InputManager::removeMouseHandler("SpaceShip");
@@ -180,22 +182,26 @@
     {
         // START CREATING THRUSTER
-        this->tt_ = new ParticleInterface(GraphicsEngine::getSingleton().getSceneManager(),"twinthruster" + this->getName(),"Orxonox/engineglow");
-        this->tt_->getParticleSystem()->setParameter("local_space","true");
-        this->tt_->newEmitter();
-/*
-        this->tt_->setDirection(Vector3(0,0,1));
-        this->tt_->setPositionOfEmitter(0, Vector3(20,-1,-15));
-        this->tt_->setPositionOfEmitter(1, Vector3(-20,-1,-15));
-*/
-        this->tt_->setDirection(Vector3(-1,0,0));
-        this->tt_->setPositionOfEmitter(0, Vector3(-15,20,-1));
-        this->tt_->setPositionOfEmitter(1, Vector3(-15,-20,-1));
-        this->tt_->setVelocity(50);
-
-        emitterRate_ = tt_->getRate();
-
-        Ogre::SceneNode* node2 = this->getNode()->createChildSceneNode(this->getName() + "particle2");
-        node2->setInheritScale(false);
-        tt_->addToSceneNode(node2);
+        this->tt1_ = new ParticleInterface("Orxonox/thruster1");
+        this->tt1_->createNewEmitter();
+        this->tt1_->getAllEmitters()->setDirection(-this->getInitialDir());
+        this->tt1_->getEmitter(0)->setPosition(Vector3(-15, 20, -1));
+        this->tt1_->getEmitter(1)->setPosition(Vector3(-15, -20, -1));
+        this->tt1_->setSpeedFactor(3.0);
+
+        Ogre::SceneNode* node2a = this->getNode()->createChildSceneNode(this->getName() + "particle2a");
+        node2a->setInheritScale(false);
+        node2a->setScale(1, 1, 1);
+        tt1_->addToSceneNode(node2a);
+
+        this->tt2_ = new ParticleInterface("Orxonox/thruster2");
+        this->tt2_->createNewEmitter();
+        this->tt2_->getAllEmitters()->setDirection(Vector3(-1, 0, 0));
+        this->tt2_->getEmitter(0)->setPosition(Vector3(-30, 40, -2));
+        this->tt2_->getEmitter(1)->setPosition(Vector3(-30, -40, -2));
+
+        Ogre::SceneNode* node2b = this->getNode()->createChildSceneNode(this->getName() + "particle2b");
+        node2b->setInheritScale(false);
+        node2b->setScale(0.5, 0.5, 0.5);
+        tt2_->addToSceneNode(node2b);
         // END CREATING THRUSTER
 
@@ -266,5 +272,5 @@
       this->camNode_ = this->getNode()->createChildSceneNode(camName_);
       COUT(4) << "position: (this)" << this->getNode()->getPosition() << std::endl;
-      this->camNode_->setPosition(Vector3(-50,0,10));
+      this->camNode_->setPosition(Vector3(-25,0,5));
 //      Quaternion q1 = Quaternion(Radian(Degree(90)),Vector3(0,-1,0));
 //      Quaternion q2 = Quaternion(Radian(Degree(90)),Vector3(0,0,-1));
@@ -339,14 +345,4 @@
     }
 
-    Vector3 SpaceShip::getDir() {
-        return currentDir_;
-    }
-
-    Vector3 SpaceShip::getOrth(){
-        return currentOrth_;
-    }
-
-    float SpaceShip::getMaxSpeed() { return maxSpeed_; }
-
     void SpaceShip::tick(float dt)
     {
@@ -374,15 +370,13 @@
         {
 
-            Projectile *p;
-            if (this->isExactlyA(Class(SpaceShip)))
-                p = new RotatingProjectile(this);
-            else
-                p = new Projectile(this);
-            p->setColour(this->getProjectileColour());
-            p->create();
-            if(p->classID==0)
+            BillboardProjectile* projectile = new ParticleProjectile(this);
+            projectile->setColour(this->getProjectileColour());
+            projectile->create();
+            if (projectile->classID == 0)
+            {
               COUT(3) << "generated projectile with classid 0" <<  std::endl; // TODO: remove this output
-
-            p->setBacksync(true);
+            }
+
+            projectile->setBacksync(true);
             this->timeToReload_ = this->reloadTime_;
         }
@@ -464,7 +458,13 @@
 
         if (this->acceleration_.x > 0)
-            this->tt_->setRate(emitterRate_);
+        {
+            this->tt1_->setEnabled(true);
+            this->tt2_->setEnabled(true);
+        }
         else
-            this->tt_->setRate(0);
+        {
+            this->tt1_->setEnabled(false);
+            this->tt2_->setEnabled(false);
+        }
 
         if( myShip_ )
Index: code/trunk/src/orxonox/objects/SpaceShip.h
===================================================================
--- code/trunk/src/orxonox/objects/SpaceShip.h	(revision 1535)
+++ code/trunk/src/orxonox/objects/SpaceShip.h	(revision 1552)
@@ -43,6 +43,4 @@
     {
         public:
-          
-
             static SpaceShip *getLocalShip();
 
@@ -66,4 +64,19 @@
             void getFocus();
 
+            inline float getMaxSpeed() const
+                { return this->maxSpeed_; }
+            inline float getMaxSideAndBackSpeed() const
+                { return this->maxSideAndBackSpeed_; }
+            inline float getMaxRotation() const
+                { return this->maxRotation_; }
+            inline float getTransAcc() const
+                { return this->translationAcceleration_; }
+            inline float getRotAcc() const
+                { return this->rotationAcceleration_; }
+            inline float getTransDamp() const
+                { return this->translationDamping_; }
+            inline float getRotDamp() const
+                { return this->rotationDamping_; }
+
             static std::string whereAmI();
             static void setMaxSpeedTest(float value)
@@ -83,12 +96,18 @@
             void doFire();
 
-            float getMaxSpeed();
-            Vector3 getDir();
-            Vector3 getOrth();
+            inline const Vector3& getDir() const
+                { return this->currentDir_; }
+            inline const Vector3& getInitialDir() const
+                { return this->initialDir_; }
+            inline const Vector3& getOrth() const
+                { return this->currentOrth_; }
+            inline const Vector3& getInitialOrth() const
+                { return this->initialOrth_; }
+
             Camera* getCamera();
 
             int getTeamNr() const
                 { return this->teamNr_; }
-            int getHealth() const
+            float getHealth() const
                 { return this->health_; }
 
@@ -118,6 +137,6 @@
             std::string camName_;
 
-
-            ParticleInterface* tt_;
+            ParticleInterface* tt1_;
+            ParticleInterface* tt2_;
 
             BillboardSet redBillboard_;
@@ -153,11 +172,9 @@
             float mouseY_;
 
-            float emitterRate_;
-
         protected:
             bool myShip_;
 
             int teamNr_;
-            int health_;
+            float health_;
 
             static SpaceShip* instance_s;
Index: code/trunk/src/orxonox/objects/SpaceShipAI.cc
===================================================================
--- code/trunk/src/orxonox/objects/SpaceShipAI.cc	(revision 1535)
+++ code/trunk/src/orxonox/objects/SpaceShipAI.cc	(revision 1552)
@@ -32,4 +32,5 @@
 #include <OgreMath.h>
 #include "Projectile.h"
+#include "ParticleSpawner.h"
 #include "core/CoreIncludes.h"
 #include "core/Iterator.h"
@@ -37,4 +38,5 @@
 #include "core/ConsoleCommand.h"
 #include "core/XMLPort.h"
+#include "particle/ParticleInterface.h"
 
 #define ACTION_INTERVAL 1.0f
@@ -51,6 +53,4 @@
         RegisterObject(SpaceShipAI);
 
-        this->alive_ = true;
-        this->setPosition(Vector3(rnd(-1000, 1000), rnd(-1000, 1000), rnd(-1000, 0000)));
         this->target_ = 0;
         this->bShooting_ = 0;
@@ -70,9 +70,15 @@
     }
 
+    SpaceShipAI::~SpaceShipAI()
+    {
+        for (Iterator<SpaceShipAI> it = ObjectList<SpaceShipAI>::begin(); it; ++it)
+            it->shipDied(this);
+    }
+
     void SpaceShipAI::XMLPort(Element& xmlelement, XMLPort::Mode mode)
     {
         SpaceShip::XMLPort(xmlelement, mode);
-        myShip_=true;
-
+
+        this->myShip_=true;
         this->actionTimer_.setTimer(ACTION_INTERVAL, true, this, createExecutor(createFunctor(&SpaceShipAI::action)));
     }
@@ -85,4 +91,5 @@
             newenemy->setMesh("assff.mesh");
 //            newenemy->setPosition(0, 0, 0);
+            newenemy->setPosition(Vector3(rnd(-3000, 3000), rnd(-3000, 3000), rnd(-3000, 3000)));
             newenemy->setScale(10);
             newenemy->setMaxSpeed(500);
@@ -95,4 +102,8 @@
             Element xmlelement;
             newenemy->XMLPort(xmlelement, XMLPort::LoadObject);
+
+            ParticleSpawner* spawneffect = new ParticleSpawner("Orxonox/fairytwirl", 2.0, 0.0, newenemy->getOrth());
+            spawneffect->setPosition(newenemy->getPosition() - newenemy->getOrth() * 50);
+            spawneffect->create();
         }
     }
@@ -103,6 +114,5 @@
         for (Iterator<SpaceShipAI> it = ObjectList<SpaceShipAI>::begin(); it; )
         {
-            delete *(it++);
-            ++i;
+            (it++)->kill();
             if (num && i >= num)
                 break;
@@ -122,65 +132,76 @@
         // search enemy
         random = rnd(maxrand);
-//std::cout << "search enemy: " << random << std::endl;
         if (random < 20 && (!this->target_))
-        {
             this->searchNewTarget();
-        }
 
         // forget enemy
         random = rnd(maxrand);
-//std::cout << "forget enemy: " << random << std::endl;
         if (random < 5 && (this->target_))
-        {
             this->forgetTarget();
-        }
 
         // next enemy
         random = rnd(maxrand);
-//std::cout << "next enemy: " << random << std::endl;
         if (random < 10 && (this->target_))
-        {
             this->searchNewTarget();
-        }
 
         // fly somewhere
         random = rnd(maxrand);
-//std::cout << "fly somewhere: " << random << std::endl;
         if (random < 40 && (!this->bHasTargetPosition_ && !this->target_))
-        {
             this->searchNewTargetPosition();
-        }
 
         // stop flying
         random = rnd(maxrand);
-//std::cout << "stop flying: " << random << std::endl;
         if (random < 10 && (this->bHasTargetPosition_ && !this->target_))
-        {
             this->bHasTargetPosition_ = false;
-        }
 
         // fly somewhere else
         random = rnd(maxrand);
-//std::cout << "fly somewhere else: " << random << std::endl;
         if (random < 30 && (this->bHasTargetPosition_ && !this->target_))
-        {
             this->searchNewTargetPosition();
-        }
 
         // shoot
         random = rnd(maxrand);
-//std::cout << "shoot: " << random << std::endl;
         if (random < 75 && (this->target_ && !this->bShooting_))
-        {
             this->bShooting_ = true;
-        }
 
         // stop shooting
         random = rnd(maxrand);
-//std::cout << "stop shooting: " << random << std::endl;
         if (random < 25 && (this->bShooting_))
-        {
             this->bShooting_ = false;
-        }
+    }
+
+    void SpaceShipAI::damage(float damage)
+    {
+        this->health_ -= damage;
+        if (this->health_ <= 0)
+        {
+            this->kill();
+            SpaceShipAI::createEnemy(1);
+        }
+    }
+
+    void SpaceShipAI::kill()
+    {
+        ParticleSpawner* explosion = new ParticleSpawner("Orxonox/BigExplosion1part1", 3.0);
+        explosion->setPosition(this->getPosition());
+        explosion->getParticleInterface()->setKeepParticlesInLocalSpace(true);
+        explosion->setScale(4);
+        explosion->create();
+
+        explosion = new ParticleSpawner("Orxonox/BigExplosion1part2", 3.0);
+        explosion->setPosition(this->getPosition());
+        explosion->getParticleInterface()->setKeepParticlesInLocalSpace(true);
+        explosion->setScale(4);
+        explosion->create();
+
+        Vector3 ringdirection = Vector3(rnd(), rnd(), rnd());
+        ringdirection.normalise();
+        explosion = new ParticleSpawner("Orxonox/BigExplosion1part3", 3.0, 0.5, ringdirection);
+        explosion->setPosition(this->getPosition());
+        explosion->getParticleInterface()->setKeepParticlesInLocalSpace(true);
+        explosion->setScale(4);
+        explosion->create();
+
+        delete this;
     }
 
@@ -193,5 +214,5 @@
             this->moveToTargetPosition(dt);
 
-        if (this->bShooting_ && this->isCloseAtTarget(2000) && this->isLookingAtTarget(Ogre::Math::PI / 10.0f))
+        if (this->bShooting_ && this->isCloseAtTarget(2500) && this->isLookingAtTarget(Ogre::Math::PI / 10))
             this->doFire();
 
@@ -201,23 +222,21 @@
     void SpaceShipAI::moveToTargetPosition(float dt)
     {
-        static Radian RadianZERO(0);
-
-//        float dotprod = (this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(this->targetPosition_ - this->getPosition());
-        Quaternion rotation = (this->getOrientation() * Ogre::Vector3::UNIT_X).getRotationTo(this->targetPosition_ - this->getPosition());
-/*
-std::cout << "scalprod: " << dotprod << std::endl;
-std::cout << "dist: " << this->targetPosition_ - this->getPosition() << std::endl;
-std::cout << "yaw: " << rotation.getYaw().valueRadians() << std::endl;
-std::cout << "pitch: " << rotation.getPitch().valueRadians() << std::endl;
-std::cout << "roll: " << rotation.getRoll().valueRadians() << std::endl;
-*/
-        this->setMoveYaw(-rotation.getRoll().valueRadians());
-        this->setMovePitch(rotation.getYaw().valueRadians());
-
-        if ((this->targetPosition_ - this->getPosition()).length() > 100)
-        {
+        Vector3 proj = Ogre::Plane(this->getDir(), this->getPosition()).projectVector(this->targetPosition_ - this->getPosition());
+        float angle = acos((this->getOrth().dotProduct(proj)) / (this->getOrth().length()*proj.length()));
+
+        if ((this->getDir().crossProduct(this->getOrth())).dotProduct(this->targetPosition_ - this->getPosition()) > 0)
+            this->setMoveYaw(sgn(sin(angle)));
+        else
+            this->setMoveYaw(-sgn(sin(angle)));
+        this->setMovePitch(sgn(cos(angle)));
+
+        if ((this->targetPosition_ - this->getPosition()).length() > 300)
             this->setMoveLongitudinal(1);
-        }
-
+
+        if (this->isCloseAtTarget(300) && this->target_)
+        {
+            if (this->getVelocity().length() > this->target_->getVelocity().length())
+                this->setMoveLongitudinal(-1);
+        }
     }
 
@@ -241,5 +260,5 @@
                 Vector3 distanceNew = it->getPosition() - this->getPosition();
                 if (!this->target_ || it->getPosition().squaredDistance(this->getPosition()) * (1.5f + acos((this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(distanceNew) / speed / distanceNew.length()) / (2 * Ogre::Math::PI))
-                        < this->targetPosition_.squaredDistance(this->getPosition()) * (1.5f + acos((this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(distanceCurrent) / speed / distanceCurrent.length()) / (2 * Ogre::Math::PI)))
+                        < this->targetPosition_.squaredDistance(this->getPosition()) * (1.5f + acos((this->getOrientation() * Ogre::Vector3::UNIT_X).dotProduct(distanceCurrent) / speed / distanceCurrent.length()) / (2 * Ogre::Math::PI)) + rnd(-250, 250))
                 {
                     this->target_ = (*it);
@@ -248,5 +267,5 @@
             }
         }
-   }
+    }
 
     void SpaceShipAI::forgetTarget()
@@ -260,5 +279,5 @@
         if (!this->target_)
             return;
-/*
+
         Vector3 enemymovement = this->target_->getVelocity();
         Vector3 distance_normalised = this->target_->getPosition() - this->getPosition();
@@ -267,4 +286,5 @@
         float scalarprod = enemymovement.dotProduct(distance_normalised);
         float aimoffset = scalarprod*scalarprod + Projectile::getSpeed() * Projectile::getSpeed() - this->target_->getVelocity().squaredLength();
+
         if (aimoffset < 0)
         {
@@ -273,21 +293,26 @@
         }
         aimoffset = -scalarprod + sqrt(aimoffset);
-        this->targetPosition_ = enemymovement + distance_normalised * aimoffset;
+        this->targetPosition_ = this->getPosition() + enemymovement + distance_normalised * aimoffset;
         this->bHasTargetPosition_ = true;
-
-        std::cout << "targetpos: " << this->targetPosition_ << std::endl;
-*/
-        this->targetPosition_ = this->target_->getPosition();
-        this->bHasTargetPosition_ = true;
     }
 
     bool SpaceShipAI::isCloseAtTarget(float distance)
     {
-        return (this->getPosition().squaredDistance(this->targetPosition_) < distance*distance);
+        if (!this->target_)
+            return (this->getPosition().squaredDistance(this->targetPosition_) < distance*distance);
+        else
+            return (this->getPosition().squaredDistance(this->target_->getPosition()) < distance*distance);
     }
 
     bool SpaceShipAI::isLookingAtTarget(float angle)
     {
-        return (this->getOrientation() * Ogre::Vector3::UNIT_X).directionEquals(this->targetPosition_ - this->getPosition(), Radian(angle));
+        Vector3 dist = this->targetPosition_ - this->getPosition();
+        return (acos((this->getDir().dotProduct(dist)) / (dist.length() * this->getDir().length())) < angle);
+    }
+
+    void SpaceShipAI::shipDied(SpaceShipAI* ship)
+    {
+        this->forgetTarget();
+        this->searchNewTargetPosition();
     }
 }
Index: code/trunk/src/orxonox/objects/SpaceShipAI.h
===================================================================
--- code/trunk/src/orxonox/objects/SpaceShipAI.h	(revision 1535)
+++ code/trunk/src/orxonox/objects/SpaceShipAI.h	(revision 1552)
@@ -44,7 +44,12 @@
         public:
             SpaceShipAI();
+            virtual ~SpaceShipAI();
+
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
             static void createEnemy(int num);
             static void killEnemies(int num);
+            void shipDied(SpaceShipAI* ship);
+            void damage(float damage);
+            void kill();
 
         private:
@@ -64,5 +69,4 @@
             Timer<SpaceShipAI> actionTimer_;
 
-            bool alive_;
             bool bHasTargetPosition_;
             Vector3 targetPosition_;
Index: code/trunk/src/orxonox/objects/WorldEntity.cc
===================================================================
--- code/trunk/src/orxonox/objects/WorldEntity.cc	(revision 1535)
+++ code/trunk/src/orxonox/objects/WorldEntity.cc	(revision 1552)
@@ -66,11 +66,14 @@
         }
     }
-    
+
 
     WorldEntity::~WorldEntity()
     {
-      // just to make sure we clean out all scene nodes
-      if(this->getNode())
-        this->getNode()->removeAndDestroyAllChildren();
+        // just to make sure we clean out all scene nodes
+        if(this->getNode())
+        {
+            this->getNode()->removeAndDestroyAllChildren();
+            GraphicsEngine::getSingleton().getSceneManager()->destroySceneNode(this->getName());
+        }
     }
 
@@ -95,5 +98,5 @@
         create();
     }
-    
+
 
     void WorldEntity::setYawPitchRoll(const Degree& yaw, const Degree& pitch, const Degree& roll)
@@ -122,5 +125,5 @@
 
         XMLPortObject(WorldEntity, WorldEntity, "attached", attachWorldEntity, getAttachedWorldEntity, xmlelement, mode, false, true);
-        
+
         WorldEntity::create();
     }
