Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/SuperOrxoBros_HS18/src/modules/superorxobros/SOBFigure.cc @ 12177

Last change on this file since 12177 was 12177, checked in by siramesh, 5 years ago

Super Orxo Bros Final (Sidharth Ramesh, Nisa Balta, Jeff Ren)

File size: 17.3 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Julien Kindle
24 *   Co-authors:
25 *      Noah Zarro
26 *      Theo von Arx
27 *     
28 *
29 */
30
31/**
32    @file SOBFigure.cc
33    @brief This class represents your figure when you play the minigame. Here the movement of the figure, activating items, ... are handled.
34*/
35
36#include "SOBFigure.h"
37
38#include "core/CoreIncludes.h"
39#include "core/XMLPort.h"
40#include "graphics/Model.h"
41#include "graphics/Camera.h"
42#include "graphics/ParticleSpawner.h"
43#include <OgreMath.h>
44
45#include "SOBTube.h"
46#include "SOBMushroom.h"
47#include "SOBGumba.h"
48#include "SOBCactus.h"
49#include "SOBGumbaBoss.h"
50#include "SOBFireball.h"
51#include "SOB.h"
52#include "SOBFlagstone.h"
53#include "SOBCastlestone.h"
54#include "Highscore.h"
55#include <BulletCollision/NarrowPhaseCollision/btManifoldPoint.h>
56
57namespace orxonox
58{
59    RegisterClass(SOBFigure);
60
61    SOBFigure::SOBFigure(Context* context) : ControllableEntity(context)
62    {
63        RegisterObject(SOBFigure);
64
65        // initialize variables
66        gravityAcceleration_ = 350.0;
67
68        //Vars for movement of player
69        moveUpPressed_      = false;
70        moveDownPressed_    = false;
71        moveLeftPressed_    = false;
72        moveRightPressed_    = false;
73        firePressed_        = false;
74        collDisZ_           = 0;
75        tube                = NULL;
76
77        //Variables for Action in Tube
78        tcol_               = false;
79        tubing              = false; 
80        kkk                 = 0;
81       
82        //Times and turning
83        timeSinceLastFire_  = 0.0;
84        lastSpeed_z         = 0.0;
85        timeCounter_        = 0;
86
87        //Properties of player
88
89        isColliding_        = true;
90        particlespawner_    = NULL;
91
92        //Properties of players life
93        predead_            = false;
94        dead_               = false;
95        lvlEnded_           = false;
96        reachedLvlEndState_ = 0;
97
98        positiontube_=10000;
99        // Properties concerning PowerUps and items
100       
101        PowerUpCounter_     = 0;
102        maxPowerUp_         = 2;
103        FireballPower       = 2;
104        //Properties of fireing Fireballs, NOTE! fireballs are fired with the moveUP Key, not with the fire key
105        fireallowed_        = true;
106        firecooldown_       = 0;
107
108       
109        setAngularFactor(0.0); //Means player doesn't turn on collision, so he doesn't fall over while walking over the ground
110        this->enableCollisionCallback(); // Turns on that on every collision function collidesAgainst is executed
111    }
112
113
114
115    bool SOBFigure::collidesAgainst(WorldEntity* otherObject, const btCollisionShape* ownCollisionShape, btManifoldPoint& contactPoint) {
116
117        //Inform tick fct that player is colliding and tell him how far away the collision point is from player middle point in z dir
118        isColliding_ = true;
119        collDisZ_ = getPosition().z - contactPoint.getPositionWorldOnB().getZ();
120
121
122        //Orxocast returns object with casted type if otherObject has that class, and if not a nullptr
123        //SOBTube* test;
124       
125        SOBMushroom*    mush        = orxonox_cast<SOBMushroom*>    (otherObject);
126        tube                        = orxonox_cast<SOBTube*>        (otherObject);
127        SOBGumba*       gumba       = orxonox_cast<SOBGumba*>       (otherObject);
128        SOBCactus*      cactus      = orxonox_cast<SOBCactus*>      (otherObject);
129        SOBGumbaBoss*   gumbaBoss   = orxonox_cast<SOBGumbaBoss*>   (otherObject);
130        SOBFlagstone*   flagstone   = orxonox_cast<SOBFlagstone*>   (otherObject);
131        SOBCastlestone* castlestone = orxonox_cast<SOBCastlestone*> (otherObject);
132        SOBFireball*    fireball    = orxonox_cast<SOBFireball*>    (otherObject);
133        SOB* SOBGame                = orxonox_cast<SOB*>            (getGametype()); 
134
135
136
137        //Check if otherObject is a powerup-mushroom
138        if (mush != nullptr && !(mush->hasCollided_)) {
139            otherObject->destroyLater();
140
141            PowerUpCounter_++;
142            if(PowerUpCounter_ > maxPowerUp_)   PowerUpCounter_ = maxPowerUp_; // you had already the max
143            else                                this->changeClothes();
144
145            SOBGame->addMushroom(); // Tell the gametype to increase points
146            mush->hasCollided_ = true; // needed because of destroyLater takes some time and player should receive points only once
147           
148           
149        }else if(tube != nullptr && !(tube->hasCollided_)){ //Check if other Object is a tube and set position wher tube is in positiontube_
150            tube->hasCollided_=true;positiontube_=getPosition().x;tcol_=true; //tcol_ used for movedown function in SOBfigure.cc
151               
152
153
154        }else if (gumba != nullptr && gumbaBoss == nullptr && !(gumba->hasCollided_)) {
155            //Check if otherObject is a Gumba (that walking enemies)
156
157            //If player jumps on its head, kill the Gumba, else, kill the player
158            if (getVelocity().z >= -20) {
159                // If player hasn't a power up, he dies. Else he shrinks and the gumba dies.
160                if(PowerUpCounter_ == 0){
161                    this->die();
162                } 
163                else{
164                    PowerUpCounter_--;
165                    this->changeClothes();
166
167                    gumba->destroyLater();
168                    gumba->hasCollided_ = true;
169                }
170
171          } else {
172            gumba->destroyLater();
173            gumba->hasCollided_ = true;
174            SOBGame->addGumba();
175
176
177            }
178        }
179        else if (cactus != nullptr && !(cactus ->hasCollided_))
180        {
181            if(PowerUpCounter_ == 0){
182                    this->die();
183                } 
184                else {
185                    PowerUpCounter_--;
186                    this->changeClothes();
187                }
188
189        }
190        else if (gumbaBoss != nullptr && !(gumbaBoss->hasCollided_)) {
191            if (getVelocity().z >= -20) {
192                // If player hasn't a power up, he dies. Else he dies directly.
193                this->die(); 
194            }
195
196            else {
197                gumbaBoss->destroyLater();
198                gumbaBoss->hasCollided_ = true;
199                SOBGame->addGumbaBoss();
200                }
201        }
202        else if (fireball != nullptr && !(fireball->hasCollided_)){
203            if(PowerUpCounter_ == 0){
204                    this->die();
205                } 
206            PowerUpCounter_--;
207            this->changeClothes();
208            fireball->destroyLater();
209        }
210
211    //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
212    if (reachedLvlEndState_ == 0 && flagstone != nullptr && !(flagstone->hasCollided_)) {
213        flagstone->hasCollided_ = true;
214        reachedLvlEndState_ = 1;
215
216        SOBGame->setDone(true);
217        SOBGame->addPoints(flagstone->getPoints());
218       
219
220    }
221    if (castlestone != nullptr && !(castlestone->hasCollided_)) {
222        castlestone->hasCollided_ = true;
223        reachedLvlEndState_++;
224
225    }
226
227    return true;
228}
229
230
231//Self implemented sign function that returns either 1 or -1 (and never 0)
232int SOBFigure::sgn(float x) {
233    if (x < 0.0) return -1;
234    return 1;
235}
236/*bool SOBFigure::tubeAction(){
237return true;
238}*/
239//Function to spawn the Fireball
240void SOBFigure::spawnFireball() {
241        SOBCenterpoint* center_ = ((SOB*)getGametype())->center_;
242
243         SOBFireball* ball = new SOBFireball(center_->getContext());
244         Vector3 spawnpos = this->getWorldPosition();
245         spawnpos.z += 0;
246
247        if (ball != nullptr && center_ != nullptr)
248        {
249            ball->addTemplate("fireball");
250            bool direction = ((this->getWorldOrientation().getRoll().valueRadians())>-1.6&&(this->getWorldOrientation().getRoll().valueRadians()<1.6));
251            ball->setDirection(direction);
252            if(direction)
253            {
254                spawnpos.x+=10;
255            }
256            else
257            {
258                spawnpos.x-=10;
259            }
260            ball->setPosition(spawnpos);
261
262        }
263     }
264
265//For those of you who don't have an idea: the tick function is called about 50 times/sec
266void SOBFigure::tick(float dt)
267{
268    SUPER(SOBFigure, tick, dt);
269   
270
271    bool inputAllowed = true;
272   
273
274    //the particle spawner that generates the fire from the backpack when pressed
275    if (particlespawner_ == NULL) {
276        for (WorldEntity* object : this->getAttachedObjects())
277        {
278           if (object->isA(Class(ParticleSpawner)))
279            particlespawner_ = object;
280        }
281
282    }
283   
284
285
286    //Behavior on level end - this is like described above for the movement from the player when hit the flag. He moves then into the castle
287    if (reachedLvlEndState_ != 0) {
288        timeCounter_+= dt;
289        inputAllowed = false;
290    }
291    if (reachedLvlEndState_ == 1 && timeCounter_ >= 1.5) {
292        timeCounter_ = 0;
293        reachedLvlEndState_ = 2;
294    }
295
296
297    //if input blocked, then cancel every movement operation
298    if (!inputAllowed) {
299        moveUpPressed_      = false;
300        moveDownPressed_    = false;
301        moveLeftPressed_    = false;
302        moveRightPressed_   = false;
303    }
304
305    //set the gravityto standard 350
306    if (firePressed_ == false) {
307        gravityAcceleration_ = 350.0;
308
309    }
310
311    if (hasLocalController())
312    {
313        SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
314        Vector3 velocity = getVelocity();
315        Vector3 position = getPosition();
316
317        if (!predead_)
318            velocity.y = 0;
319        //If player falls in a hole
320        if (position.z < -250) {
321            dead_ = true;
322            SOBGame->setDone(true);
323        }
324
325
326        if (dead_) {
327            velocity.x = 0;
328            velocity.z = 0;
329            setVelocity(velocity);
330           
331            if (firePressed_)
332                SOBGame->restart();
333            return;
334        }
335
336
337        int maxvelocity_x = 100;
338        int speedAddedPerTick = 5;
339        int camMaxOffset = 25;
340        int camMaxOffsetz = 25;
341
342        timeSinceLastFire_ += dt;
343        lastSpeed_z = velocity.z;
344
345
346
347        //Handle the rocket fire from the jetpack
348        if (velocity.z > 40)
349            particlespawner_->setVisible(true); 
350        else
351            particlespawner_->setVisible(false); 
352       
353
354        //If player hits space and collides against an object under him then jump
355        if (inputAllowed && firePressed_ && isColliding_ && (collDisZ_ >= 0 && collDisZ_ <+ 10)) {
356            gravityAcceleration_ = 350;
357            velocity.z = 175; 
358        }
359
360
361        //Left-right movement with acceleration and rotation
362        float rot = getOrientation().getRoll().valueDegrees();
363        if (moveRightPressed_) {
364            if (!(rot < 5.0 && -5.0 < rot))
365                setOrientation(Vector3::UNIT_Z, getOrientation().getRoll() - sgn(rot)*dt*Radian(6));
366
367            if (std::abs(velocity.x) < maxvelocity_x) {
368                velocity.x += speedAddedPerTick;
369
370            }
371        } else if (moveLeftPressed_) {
372            if (!(abs(rot) > 175.0 ))
373                setOrientation(Vector3::UNIT_Z, getOrientation().getRoll() + sgn(rot)*dt*Radian(6));
374
375
376
377            if (std::abs(velocity.x) < maxvelocity_x) {
378                velocity.x -= speedAddedPerTick;
379            }
380        } else {
381            velocity.x /= 1.1;
382        }
383
384        //If moveUp pressed, fire a fireball
385        if(moveUpPressed_ && inputAllowed) //if pressed up jump through tube if you are underground
386        {
387            Vector3 position1 = getPosition();
388
389             
390               
391               
392                if(position1.z>=-100 && position1.z<=-40){
393                    position1.z=40;
394                    if(460<=position1.x && position1.x<480){setPosition(position1);}  //little hack works without this but first tube must be touched     //position where second tube is
395                    if(positiontube_-10<=position1.x && position1.x<positiontube_+10){      //function for jumping through any SOBtube`s
396                    setPosition(position1);}}
397
398
399            if((PowerUpCounter_ >= FireballPower) && fireallowed_){
400            spawnFireball();
401
402            fireallowed_  = false;
403            firecooldown_ = 0;}
404        }
405       
406         if(moveDownPressed_ && inputAllowed ){ //if movedownpressed change collisiontype of tube and slip through tube
407               
408             
409                Vector3 position1 = getPosition();
410             
411
412               
413           
414               if(tube != nullptr && !(tube->movedown)){ //Check if other Object is a tube
415               
416                if(positiontube_-10<position1.x && position1.x<positiontube_+10){
417                tube->movedown=true;}
418                }
419   
420        }
421
422        //Increase the firecooldown
423        if(firecooldown_> 0.5)
424        {
425            fireallowed_ = true;
426        }
427        if(!fireallowed_)
428        {
429            firecooldown_ += dt;
430        }
431
432        //Again another EndOfLevel behavior
433        if (reachedLvlEndState_ == 1)
434            velocity.x = -2;
435        if (reachedLvlEndState_ == 2)
436            velocity.x = 30;
437        if (reachedLvlEndState_ == 3) {
438            velocity.x = 0;
439            velocity.y = 20;
440            setOrientation(Vector3::UNIT_Z, Degree(90));
441        }
442        if (reachedLvlEndState_ == 4) {
443            //Highscore
444            if (Highscore::exists())
445            {
446                int score = SOBGame->getPoints();
447                bool isHighScore = Highscore::getInstance().storeScore("Super Orxo Bros.", score, this->getPlayer());
448                SOBGame->newHighscore = isHighScore;
449            }
450            lvlEnded_ = true;
451            dead_ = true;
452        }
453
454        //velocity = acc. * time
455        velocity.z -= gravityAcceleration_*dt;
456        setVelocity(velocity);
457
458        //Vector3 pos = this->getPosition();
459       
460        // pos.y = 0;
461        // this->setPosition(pos);
462
463
464        //Camera operation - the camera should always follow the player in a specific region
465        Camera* cam = getCamera();
466        Vector3 campos = cam->getPosition();
467
468        if (campos.x + camMaxOffset < position.x) {
469            campos.x = position.x - camMaxOffset;
470            cam->setPosition(campos);
471        }
472        if (campos.x - camMaxOffset > position.x) {
473            campos.x = position.x + camMaxOffset;
474            cam->setPosition(campos);
475        }
476
477        if(campos.y + camMaxOffsetz < position.z) {
478            campos.y = position.z - camMaxOffset;
479            cam -> setPosition(campos);
480        }
481
482        if(campos.y - camMaxOffsetz > position.z) {
483            campos.y = position.z + camMaxOffset;
484            cam ->setPosition(campos);
485        }
486
487    }
488
489    // Reset key variables
490    moveUpPressed_      = false;
491    moveDownPressed_    = false;
492    moveLeftPressed_    = false;
493    moveRightPressed_   = false;
494   
495
496    isColliding_ = false;
497    collDisZ_ = 0;
498
499}
500
501
502
503
504
505//The following functions read the input of the player and then set the bools for the movement
506void SOBFigure::moveFrontBack(const Vector2& value)
507{
508    if (value.x > 0)
509    {
510        moveUpPressed_ = true;
511        moveDownPressed_ = false;
512    }
513    else
514    {
515        moveUpPressed_ = false;
516        moveDownPressed_ = true;
517    }
518}
519
520void SOBFigure::moveRightLeft(const Vector2& value)
521{
522    if (value.x > 0)
523    {
524        moveLeftPressed_ = false;
525        moveRightPressed_ = true;
526    }
527    else
528    {
529        moveLeftPressed_ = true;
530        moveRightPressed_ = false;
531    }
532}
533
534void SOBFigure::boost(bool boost)
535{
536    firePressed_ = boost;
537}
538
539
540
541// PRE: name is an existing name of a material. Example orxo_material for orxo_material.material in data_extern/materials
542//      !!! PowerUpCounter_ has to be modified before changing the clothes!!!
543// POST: clothes of body of player are changed to name
544void SOBFigure::changeClothes(){
545            // clothes: white (basic), red (one PowerUp), orange (Fireball enabled)
546            std::string clothes[] = {"orxo_material", "orxo_material_gross", "orxo_material_fire"};
547
548            std::set<WorldEntity*> attachedObjects = this->getAttachedObjects();
549            std::set<WorldEntity*>::iterator it;
550            for (it = attachedObjects.begin(); it != attachedObjects.end(); ++it)
551            {
552                Model* FiguresModel = orxonox_cast<Model*>(*it);
553                if (FiguresModel != nullptr)
554                {
555                    FiguresModel->setSubMaterial(clothes[PowerUpCounter_] , 4); // 4 is the body
556                }
557            }   
558}
559// PRE:
560// POST: Player jumps out of the game, game is finished and can be restarted.
561void SOBFigure::die(){
562    Vector3 vel = getVelocity();
563    vel.y = -80;
564    vel.z = 200;
565    setVelocity(vel);
566    predead_= true; 
567    SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
568    SOBGame->setDone(true);
569}
570
571}
Note: See TracBrowser for help on using the repository browser.