Index: code/trunk/src/modules/superorxobros/SOBFigure.cc
===================================================================
--- code/trunk/src/modules/superorxobros/SOBFigure.cc	(revision 11449)
+++ code/trunk/src/modules/superorxobros/SOBFigure.cc	(revision 11783)
@@ -23,4 +23,6 @@
  *      Julien Kindle
  *   Co-authors:
+ *      Noah Zarro
+ *      Theo von Arx
  *      
  *
@@ -39,10 +41,15 @@
 #include "graphics/Camera.h"
 #include "graphics/ParticleSpawner.h"
+#include <OgreMath.h>
 
 #include "SOBMushroom.h"
 #include "SOBGumba.h"
+#include "SOBGumbaBoss.h"
+#include "SOBFireball.h"
 #include "SOB.h"
 #include "SOBFlagstone.h"
 #include "SOBCastlestone.h"
+#include "SOBFireball.h"
+#include "Highscore.h"
 #include <BulletCollision/NarrowPhaseCollision/btManifoldPoint.h>
 
@@ -59,26 +66,34 @@
 
         //Vars for movement of player
-        moveUpPressed_ = false;
-        moveDownPressed_ = false;
-        moveLeftPressed_ = false;
-        moveDownPressed_ = false;
-        firePressed_ = false;
-        collDisZ_ = 0;
+        moveUpPressed_      = false;
+        moveDownPressed_    = false;
+        moveLeftPressed_    = false;
+        moveRightPressed_    = false;
+        firePressed_        = false;
+        collDisZ_           = 0;
+
         //Times and turning
-        timeSinceLastFire_ = 0.0;
-        lastSpeed_z = 0.0;
-        pitch_ = 0.0;
-        timeCounter_ = 0;
+        timeSinceLastFire_  = 0.0;
+        lastSpeed_z         = 0.0;
+        timeCounter_        = 0;
 
         //Properties of player
-        gotPowerUp_ = false;
-        isColliding_ = true;
-        particlespawner_ = NULL;
+
+        isColliding_        = true;
+        particlespawner_    = NULL;
 
         //Properties of players life
-        predead_ = false;
-        dead_ = false;
-        lvlEnded_ = false;
+        predead_            = false;
+        dead_               = false;
+        lvlEnded_           = false;
         reachedLvlEndState_ = 0;
+
+        // Properties concerning PowerUps and items
+        PowerUpCounter_     = 0;
+        maxPowerUp_         = 2;
+        FireballPower       = 2;
+        //Properties of fireing Fireballs, NOTE! fireballs are fired with the moveUP Key, not with the fire key
+        fireallowed_        = true;
+        firecooldown_       = 0;
 
         
@@ -97,39 +112,75 @@
 
         //Orxocast returns object with casted type if otherObject has that class, and if not a nullptr
-        SOBMushroom* mush = orxonox_cast<SOBMushroom*>(otherObject);
-        SOBGumba* gumba = orxonox_cast<SOBGumba*>(otherObject);
-        SOBFlagstone* flagstone = orxonox_cast<SOBFlagstone*>(otherObject);
-        SOBCastlestone* castlestone = orxonox_cast<SOBCastlestone*>(otherObject);
-
-        //Check if otherObject is a powerup
+        SOBMushroom*    mush        = orxonox_cast<SOBMushroom*>    (otherObject);
+        SOBGumba*       gumba       = orxonox_cast<SOBGumba*>       (otherObject);
+        SOBGumbaBoss*   gumbaBoss   = orxonox_cast<SOBGumbaBoss*>   (otherObject);
+        SOBFlagstone*   flagstone   = orxonox_cast<SOBFlagstone*>   (otherObject);
+        SOBCastlestone* castlestone = orxonox_cast<SOBCastlestone*> (otherObject);
+        SOBFireball*    fireball    = orxonox_cast<SOBFireball*>    (otherObject);
+        SOB* SOBGame                = orxonox_cast<SOB*>            (getGametype()); 
+
+
+        //Check if otherObject is a powerup-mushroom
         if (mush != nullptr && !(mush->hasCollided_)) {
             otherObject->destroyLater();
-            gotPowerUp_ = true;
-            SOB* SOBGame = orxonox_cast<SOB*>(getGametype()); //Get the Gametype
+
+            PowerUpCounter_++;
+            if(PowerUpCounter_ > maxPowerUp_)   PowerUpCounter_ = maxPowerUp_; // you had already the max
+            else                                this->changeClothes();
+
             SOBGame->addMushroom(); // Tell the gametype to increase points
             mush->hasCollided_ = true; // needed because of destroyLater takes some time and player should receive points only once
+            
+            
+        }
+
+        
 
         //Check if otherObject is a Gumba (that walking enemies)
-        } else if (gumba != nullptr && !(gumba->hasCollided_)) {
-
-            //If player jumps on its head, kill it, else, kill the player
+
+         else if (gumba != nullptr && gumbaBoss == nullptr && !(gumba->hasCollided_)) {
+
+            //If player jumps on its head, kill the Gumba, else, kill the player
             if (getVelocity().z >= -20) {
-              Vector3 vel = getVelocity();
-              vel.y = -80;
-              vel.z = 200;
-              setVelocity(vel);
-              predead_=true; 
-              SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
-              SOBGame->setDone(true);
+                // If player hasn't a power up, he dies. Else he shrinks and the gumba dies.
+                if(PowerUpCounter_ == 0){
+                    this->die();
+                } 
+                else{
+                    PowerUpCounter_--;
+                    this->changeClothes();
+
+                    gumba->destroyLater();
+                    gumba->hasCollided_ = true;
+                }
 
           } else {
             gumba->destroyLater();
             gumba->hasCollided_ = true;
-            SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
             SOBGame->addGumba();
 
 
-        }
-    }
+            }
+        }
+        else if (gumbaBoss != nullptr && !(gumbaBoss->hasCollided_)) {
+            if (getVelocity().z >= -20) {
+                // If player hasn't a power up, he dies. Else he dies directly.
+                this->die(); 
+            }
+
+            else {
+                gumbaBoss->destroyLater();
+                gumbaBoss->hasCollided_ = true;
+                SOBGame->addGumbaBoss();
+                }
+        }
+        else if (fireball != nullptr && !(fireball->hasCollided_)){
+            if(PowerUpCounter_ == 0){
+                    this->die();
+                } 
+            PowerUpCounter_--;
+            this->changeClothes();
+            fireball->destroyLater();
+        }
 
     //Purpose is that if player hits the flag, he should walk into the castle at the end of the level. For that we use SOBCastlestone
@@ -137,5 +188,5 @@
         flagstone->hasCollided_ = true;
         reachedLvlEndState_ = 1;
-        SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
+
         SOBGame->setDone(true);
         SOBGame->addPoints(flagstone->getPoints());
@@ -159,4 +210,30 @@
 }
 
+//Function to spawn the Fireball
+void SOBFigure::spawnFireball() {
+        SOBCenterpoint* center_ = ((SOB*)getGametype())->center_;
+
+         SOBFireball* ball = new SOBFireball(center_->getContext());
+         Vector3 spawnpos = this->getWorldPosition();
+         spawnpos.z += 0;
+
+        if (ball != nullptr && center_ != nullptr)
+        {
+            ball->addTemplate("fireball");
+            bool direction = ((this->getWorldOrientation().getRoll().valueRadians())>-1.6&&(this->getWorldOrientation().getRoll().valueRadians()<1.6));
+            ball->setDirection(direction);
+            if(direction)
+            {
+                spawnpos.x+=10;
+            }
+            else
+            {
+                spawnpos.x-=10;
+            }
+            ball->setPosition(spawnpos);
+
+        }
+     }
+
 //For those of you who don't have an idea: the tick function is called about 50 times/sec
 void SOBFigure::tick(float dt)
@@ -166,4 +243,5 @@
 
     bool inputAllowed = true;
+    //SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
 
     //the particle spawner that generates the fire from the backpack when pressed
@@ -174,5 +252,7 @@
             particlespawner_ = object;
         }
-    }
+
+    }
+    
 
 
@@ -190,8 +270,8 @@
     //if input blocked, then cancel every movement operation
     if (!inputAllowed) {
-        moveUpPressed_ = false;
-        moveDownPressed_ = false;
-        moveLeftPressed_ = false;
-        moveRightPressed_ = false;
+        moveUpPressed_      = false;
+        moveDownPressed_    = false;
+        moveLeftPressed_    = false;
+        moveRightPressed_   = false;
     }
 
@@ -204,4 +284,5 @@
     if (hasLocalController())
     {
+        SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
         Vector3 velocity = getVelocity();
         Vector3 position = getPosition();
@@ -212,5 +293,4 @@
         if (position.z < -100) {
             dead_ = true;
-            SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
             SOBGame->setDone(true);
         }
@@ -221,5 +301,5 @@
             velocity.z = 0;
             setVelocity(velocity);
-            SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
+           
             if (firePressed_)
                 SOBGame->restart();
@@ -242,10 +322,10 @@
         else
             particlespawner_->setVisible(false); 
-
+        
 
         //If player hits space and collides against an object under him then jump
-        if (inputAllowed && firePressed_ && isColliding_ && (collDisZ_ >= 7.75 && collDisZ_ <+ 8.25)) {
-            gravityAcceleration_ = 100.0;
-            velocity.z = 110; 
+        if (inputAllowed && firePressed_ && isColliding_ && (collDisZ_ >= 0 && collDisZ_ <+ 10)) {
+            gravityAcceleration_ = 350;
+            velocity.z = 175; 
         }
 
@@ -274,4 +354,21 @@
         }
 
+        //If moveUp pressed, fire a fireball
+        if(moveUpPressed_ && (PowerUpCounter_ >= FireballPower) && fireallowed_)
+        {
+            spawnFireball();
+            fireallowed_  = false;
+            firecooldown_ = 0;
+        }
+
+        //Increase the firecooldown
+        if(firecooldown_> 0.5)
+        {
+            fireallowed_ = true;
+        }
+        if(!fireallowed_)
+        {
+            firecooldown_ += dt;
+        }
 
         //Again another EndOfLevel behavior
@@ -283,6 +380,14 @@
             velocity.x = 0;
             velocity.y = 20;
+            setOrientation(Vector3::UNIT_Z, Degree(90));
         }
         if (reachedLvlEndState_ == 4) {
+            //Highscore
+            if (Highscore::exists())
+            {
+                int score = SOBGame->getPoints();
+                bool isHighScore = Highscore::getInstance().storeScore("Super Orxo Bros.", score, this->getPlayer());
+                SOBGame->newHighscore = isHighScore;
+            }
             lvlEnded_ = true;
             dead_ = true;
@@ -307,16 +412,11 @@
         }
 
-
-
-
-    }
-
-
+    }
 
     // Reset key variables
-    moveUpPressed_ = false;
-    moveDownPressed_ = false;
-    moveLeftPressed_ = false;
-    moveRightPressed_ = false;
+    moveUpPressed_      = false;
+    moveDownPressed_    = false;
+    moveLeftPressed_    = false;
+    moveRightPressed_   = false;
 
     isColliding_ = false;
@@ -364,3 +464,34 @@
 
 
-}
+
+// PRE: name is an existing name of a material. Example orxo_material for orxo_material.material in data_extern/materials
+//      !!! PowerUpCounter_ has to be modified before changing the clothes!!!
+// POST: clothes of body of player are changed to name
+void SOBFigure::changeClothes(){
+            // clothes: white (basic), red (one PowerUp), orange (Fireball enabled)
+            std::string clothes[] = {"orxo_material", "orxo_material_gross", "orxo_material_fire"};
+
+            std::set<WorldEntity*> attachedObjects = this->getAttachedObjects();
+            std::set<WorldEntity*>::iterator it;
+            for (it = attachedObjects.begin(); it != attachedObjects.end(); ++it)
+            {
+                Model* FiguresModel = orxonox_cast<Model*>(*it);
+                if (FiguresModel != nullptr)
+                {
+                    FiguresModel->setSubMaterial(clothes[PowerUpCounter_] , 4); // 4 is the body
+                }
+            }   
+}
+// PRE:
+// POST: Player jumps out of the game, game is finished and can be restarted.
+void SOBFigure::die(){
+    Vector3 vel = getVelocity();
+    vel.y = -80;
+    vel.z = 200;
+    setVelocity(vel);
+    predead_= true; 
+    SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
+    SOBGame->setDone(true);
+}
+
+}
