Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

merged Fireball and player

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