Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/SOBv2_HS17/src/modules/superorxobros/SOBFigure.cc @ 11597

Last change on this file since 11597 was 11597, checked in by varxth, 6 years ago

Collisionshape of fireball

File size: 13.7 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 *     
26 *
27 */
28
29/**
30    @file SOBFigure.cc
31    @brief This class represents your figure when you play the minigame. Here the movement of the figure, activating items, ... are handled.
32*/
33
34#include "SOBFigure.h"
35
36#include "core/CoreIncludes.h"
37#include "core/XMLPort.h"
38#include "graphics/Model.h"
39#include "graphics/Camera.h"
40#include "graphics/ParticleSpawner.h"
41#include <OgreMath.h>
42
43#include "SOBMushroom.h"
44#include "SOBGumba.h"
45#include "SOBFireball.h"
46#include "SOB.h"
47#include "SOBFlagstone.h"
48#include "SOBCastlestone.h"
49#include "SOBFireball.h"
50#include <BulletCollision/NarrowPhaseCollision/btManifoldPoint.h>
51
52namespace orxonox
53{
54    RegisterClass(SOBFigure);
55
56    SOBFigure::SOBFigure(Context* context) : ControllableEntity(context)
57    {
58        RegisterObject(SOBFigure);
59
60        // initialize variables
61        gravityAcceleration_ = 350.0;
62
63        //Vars for movement of player
64        moveUpPressed_      = false;
65        moveDownPressed_    = false;
66        moveLeftPressed_    = false;
67        moveDownPressed_    = false;
68        firePressed_        = false;
69        collDisZ_           = 0;
70
71        //Times and turning
72        timeSinceLastFire_  = 0.0;
73        lastSpeed_z         = 0.0;
74        pitch_              = 0.0;
75        timeCounter_        = 0;
76
77        //Properties of player
78
79        isColliding_        = true;
80        particlespawner_    = NULL;
81
82        //Properties of players life
83        predead_            = false;
84        dead_               = false;
85        lvlEnded_           = false;
86        reachedLvlEndState_ = 0;
87
88        // Properties concerning PowerUps and items
89        PowerUpCounter_     = 0;
90        maxPowerUp_         = 2;
91        FireballPower       = 2;
92        //Properties of fireing Fireballs, NOTE! fireballs are fired with the moveUP Key, not with the fire key
93        fireallowed_        = true;
94        firecooldown_       = 0;
95
96       
97        setAngularFactor(0.0); //Means player doesn't turn on collision, so he doesn't fall over while walking over the ground
98        this->enableCollisionCallback(); // Turns on that on every collision function collidesAgainst is executed
99    }
100
101
102
103    bool SOBFigure::collidesAgainst(WorldEntity* otherObject, const btCollisionShape* ownCollisionShape, btManifoldPoint& contactPoint) {
104
105        //Inform tick fct that player is colliding and tell him how far away the collision point is from player middle point in z dir
106        isColliding_ = true;
107        collDisZ_ = getPosition().z - contactPoint.getPositionWorldOnB().getZ();
108
109
110        //Orxocast returns object with casted type if otherObject has that class, and if not a nullptr
111        SOBMushroom*    mush        = orxonox_cast<SOBMushroom*>    (otherObject);
112        SOBGumba*       gumba       = orxonox_cast<SOBGumba*>       (otherObject);
113        SOBFlagstone*   flagstone   = orxonox_cast<SOBFlagstone*>   (otherObject);
114        SOBCastlestone* castlestone = orxonox_cast<SOBCastlestone*> (otherObject);
115        SOBFireball* fireball       = orxonox_cast<SOBFireball*>    (otherObject);
116        SOB* SOBGame                = orxonox_cast<SOB*>            (getGametype()); 
117
118
119        //Check if otherObject is a powerup-mushroom
120        if (mush != nullptr && !(mush->hasCollided_)) {
121            otherObject->destroyLater();
122
123            PowerUpCounter_++;
124            if(PowerUpCounter_ > maxPowerUp_)   PowerUpCounter_ = maxPowerUp_; // you had already the max
125            else                                this->changeClothes();
126
127            SOBGame->addMushroom(); // Tell the gametype to increase points
128            mush->hasCollided_ = true; // needed because of destroyLater takes some time and player should receive points only once
129           
130           
131        }
132       
133
134        //Check if otherObject is a Gumba (that walking enemies)
135
136         else if (gumba != nullptr && !(gumba->hasCollided_)) {
137
138            //If player jumps on its head, kill the Gumba, else, kill the player
139            if (getVelocity().z >= -20) {
140                // If player hasn't a power up, he dies. Else he shrinks and the gumba dies.
141                if(PowerUpCounter_ == 0){
142                    this->die();
143                } 
144                else{
145                    PowerUpCounter_--;
146                    this->changeClothes();
147
148                    gumba->destroyLater();
149                    gumba->hasCollided_ = true;
150                }
151
152          } else {
153            gumba->destroyLater();
154            gumba->hasCollided_ = true;
155            SOBGame->addGumba();
156
157
158        }
159    }
160
161        else if (fireball != nullptr && !(fireball->hasCollided_)){
162            PowerUpCounter_--;
163            this->changeClothes();
164        }
165
166    //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
167    if (reachedLvlEndState_ == 0 && flagstone != nullptr && !(flagstone->hasCollided_)) {
168        flagstone->hasCollided_ = true;
169        reachedLvlEndState_ = 1;
170
171        SOBGame->setDone(true);
172        SOBGame->addPoints(flagstone->getPoints());
173       
174
175    }
176    if (castlestone != nullptr && !(castlestone->hasCollided_)) {
177        castlestone->hasCollided_ = true;
178        reachedLvlEndState_++;
179
180    }
181
182    return true;
183}
184
185
186//Self implemented sign function that returns either 1 or -1 (and never 0)
187int SOBFigure::sgn(float x) {
188    if (x < 0.0) return -1;
189    return 1;
190}
191
192//Function to spawn the Fireball
193void SOBFigure::spawnFireball() {
194        SOBCenterpoint* center_ = ((SOB*)getGametype())->center_;
195
196         SOBFireball* ball = new SOBFireball(center_->getContext());
197         Vector3 spawnpos = this->getWorldPosition();
198         spawnpos.z += 0;
199
200        if (ball != nullptr && center_ != nullptr)
201        {
202            ball->addTemplate("fireball");
203            bool direction = ((this->getWorldOrientation().getRoll().valueRadians())>-1.6&&(this->getWorldOrientation().getRoll().valueRadians()<1.6));
204            ball->setDirection(direction);
205            orxout() << "Rotation: " << this->getWorldOrientation().getRoll() << " direction: "<< direction <<endl;
206            if(direction)
207            {
208                spawnpos.x+=10;
209            }
210            else
211            {
212                spawnpos.x-=10;
213            }
214            ball->setPosition(spawnpos);
215
216        }
217     }
218
219//For those of you who don't have an idea: the tick function is called about 50 times/sec
220void SOBFigure::tick(float dt)
221{
222    SUPER(SOBFigure, tick, dt);
223
224
225    bool inputAllowed = true;
226
227    //the particle spawner that generates the fire from the backpack when pressed
228    if (particlespawner_ == NULL) {
229        for (WorldEntity* object : this->getAttachedObjects())
230        {
231           if (object->isA(Class(ParticleSpawner)))
232            particlespawner_ = object;
233        }
234    }
235
236
237    //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
238    if (reachedLvlEndState_ != 0) {
239        timeCounter_+= dt;
240        inputAllowed = false;
241    }
242    if (reachedLvlEndState_ == 1 && timeCounter_ >= 1.5) {
243        timeCounter_ = 0;
244        reachedLvlEndState_ = 2;
245    }
246
247
248    //if input blocked, then cancel every movement operation
249    if (!inputAllowed) {
250        moveUpPressed_      = false;
251        moveDownPressed_    = false;
252        moveLeftPressed_    = false;
253        moveRightPressed_   = false;
254    }
255
256    //set the gravityto standard 350
257    if (firePressed_ == false) {
258        gravityAcceleration_ = 350.0;
259
260    }
261
262    if (hasLocalController())
263    {
264        SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
265        Vector3 velocity = getVelocity();
266        Vector3 position = getPosition();
267
268        if (!predead_)
269            velocity.y = 0;
270        //If player falls in a hole
271        if (position.z < -100) {
272            dead_ = true;
273            SOBGame->setDone(true);
274        }
275
276
277        if (dead_) {
278            velocity.x = 0;
279            velocity.z = 0;
280            setVelocity(velocity);
281           
282            if (firePressed_)
283                SOBGame->restart();
284            return;
285        }
286
287
288        int maxvelocity_x = 100;
289        int speedAddedPerTick = 5;
290        int camMaxOffset = 25;
291
292        timeSinceLastFire_ += dt;
293        lastSpeed_z = velocity.z;
294
295
296
297        //Handle the rocket fire from the jetpack
298        if (velocity.z > 40)
299            particlespawner_->setVisible(true); 
300        else
301            particlespawner_->setVisible(false); 
302
303
304        //If player hits space and collides against an object under him then jump
305        if (inputAllowed && firePressed_ && isColliding_ && (collDisZ_ >= 0 && collDisZ_ <+ 10)) {
306            gravityAcceleration_ = 100.0;
307            velocity.z = 110; 
308        }
309
310
311        //Left-right movement with acceleration and rotation
312        float rot = getOrientation().getRoll().valueDegrees();
313        if (moveRightPressed_) {
314            if (!(rot < 5.0 && -5.0 < rot))
315                setOrientation(Vector3::UNIT_Z, getOrientation().getRoll() - sgn(rot)*dt*Radian(6));
316
317            if (std::abs(velocity.x) < maxvelocity_x) {
318                velocity.x += speedAddedPerTick;
319
320            }
321        } else if (moveLeftPressed_) {
322            if (!(abs(rot) > 175.0 ))
323                setOrientation(Vector3::UNIT_Z, getOrientation().getRoll() + sgn(rot)*dt*Radian(6));
324
325
326
327            if (std::abs(velocity.x) < maxvelocity_x) {
328                velocity.x -= speedAddedPerTick;
329            }
330        } else {
331            velocity.x /= 1.1;
332        }
333
334        //If moveUp pressed, fire a fireball
335        if(moveUpPressed_ && (PowerUpCounter_ >= FireballPower) && fireallowed_)
336        {
337            spawnFireball();
338            fireallowed_  = false;
339            firecooldown_ = 0;
340        }
341
342        //Increase the firecooldown
343        if(firecooldown_> 0.5)
344        {
345            fireallowed_ = true;
346        }
347        if(!fireallowed_)
348        {
349            firecooldown_ += dt;
350        }
351
352        //Again another EndOfLevel behavior
353        if (reachedLvlEndState_ == 1)
354            velocity.x = -2;
355        if (reachedLvlEndState_ == 2)
356            velocity.x = 30;
357        if (reachedLvlEndState_ == 3) {
358            velocity.x = 0;
359            velocity.y = 20;
360        }
361        if (reachedLvlEndState_ == 4) {
362            lvlEnded_ = true;
363            dead_ = true;
364        }
365
366        //velocity = acc. * time
367        velocity.z -= gravityAcceleration_*dt;
368        setVelocity(velocity);
369
370
371        //Camera operation - the camera should always follow the player in a specific region
372        Camera* cam = getCamera();
373        Vector3 campos = cam->getPosition();
374
375        if (campos.x + camMaxOffset < position.x) {
376            campos.x = position.x - camMaxOffset;
377            cam->setPosition(campos);
378        }
379        if (campos.x - camMaxOffset > position.x) {
380            campos.x = position.x + camMaxOffset;
381            cam->setPosition(campos);
382        }
383
384    }
385
386    // Reset key variables
387    moveUpPressed_      = false;
388    moveDownPressed_    = false;
389    moveLeftPressed_    = false;
390    moveRightPressed_   = false;
391
392    isColliding_ = false;
393    collDisZ_ = 0;
394
395}
396
397
398
399
400
401//The following functions read the input of the player and then set the bools for the movement
402void SOBFigure::moveFrontBack(const Vector2& value)
403{
404    if (value.x > 0)
405    {
406        moveUpPressed_ = true;
407        moveDownPressed_ = false;
408    }
409    else
410    {
411        moveUpPressed_ = false;
412        moveDownPressed_ = true;
413    }
414}
415
416void SOBFigure::moveRightLeft(const Vector2& value)
417{
418    if (value.x > 0)
419    {
420        moveLeftPressed_ = false;
421        moveRightPressed_ = true;
422    }
423    else
424    {
425        moveLeftPressed_ = true;
426        moveRightPressed_ = false;
427    }
428}
429
430void SOBFigure::boost(bool boost)
431{
432    firePressed_ = boost;
433}
434
435
436
437// PRE: name is an existing name of a material. Example orxo_material for orxo_material.material in data_extern/materials
438//      !!! PowerUpCounter_ has to be modified before changing the clothes!!!
439// POST: clothes of body of player are changed to name
440void SOBFigure::changeClothes(){
441            // clothes: white (basic), red (one PowerUp), orange (Fireball enabled)
442            std::string clothes[] = {"orxo_material", "orxo_material_gross", "orxo_material_fire"};
443
444            std::set<WorldEntity*> attachedObjects = this->getAttachedObjects();
445            std::set<WorldEntity*>::iterator it;
446            for (it = attachedObjects.begin(); it != attachedObjects.end(); ++it)
447            {
448                Model* FiguresModel = orxonox_cast<Model*>(*it);
449                if (FiguresModel != nullptr)
450                {
451                    FiguresModel->setSubMaterial(clothes[PowerUpCounter_] , 4); // 4 is the body
452                }
453            }   
454}
455// PRE:
456// POST: Player jumps out of the game, game is finished and can be restarted.
457void SOBFigure::die(){
458    Vector3 vel = getVelocity();
459    vel.y = -80;
460    vel.z = 200;
461    setVelocity(vel);
462    predead_= true; 
463    SOB* SOBGame = orxonox_cast<SOB*>(getGametype());
464    SOBGame->setDone(true);
465}
466
467}
Note: See TracBrowser for help on using the repository browser.