Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 11577 was 11577, checked in by zarron, 7 years ago

first atempt to set dir of fireballs correctly

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