Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pickupsFS14/src/modules/jump/Jump.cc @ 10041

Last change on this file since 10041 was 10041, checked in by fvultier, 10 years ago

Level wird zufaellig generiert, HUD funktionier(Punkte werden angezeigt), Diverse bugs behoben, Figur springt von allen Platformen korrekt ab.

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 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file Jump.cc
31    @brief Implementation of the Jump class.
32*/
33
34#include "Jump.h"
35
36#include "core/CoreIncludes.h"
37#include "core/EventIncludes.h"
38#include "core/command/Executor.h"
39#include "core/config/ConfigValueIncludes.h"
40
41#include "gamestates/GSLevel.h"
42#include "chat/ChatManager.h"
43
44#include "JumpCenterpoint.h"
45#include "JumpPlatform.h"
46#include "JumpPlatformStatic.h"
47#include "JumpPlatformHMove.h"
48#include "JumpPlatformVMove.h"
49#include "JumpFigure.h"
50
51#include "infos/PlayerInfo.h"
52
53namespace orxonox
54{
55    // Events to allow to react to scoring of a player, in the level-file.
56    CreateEventName(JumpCenterpoint, right);
57    CreateEventName(JumpCenterpoint, left);
58
59    RegisterUnloadableClass(Jump);
60
61    /**
62    @brief
63        Constructor. Registers and initializes the object.
64    */
65    Jump::Jump(Context* context) : Deathmatch(context)
66    {
67        RegisterObject(Jump);
68
69        this->center_ = 0;
70        this->figure_ = 0;
71        this->camera = 0;
72
73        platformList.clear();
74
75        this->setHUDTemplate("JumpHUD");
76
77        // Pre-set the timer, but don't start it yet.
78        this->starttimer_.setTimer(1.0, false, createExecutor(createFunctor(&Jump::startBall, this)));
79        this->starttimer_.stopTimer();
80
81
82        this->scoreLimit_ = 10;
83        this->setConfigValues();
84    }
85
86    /**
87    @brief
88        Destructor. Cleans up, if initialized.
89    */
90    Jump::~Jump()
91    {
92        if (this->isInitialized())
93        {
94            this->cleanup();
95        }
96    }
97
98    void Jump::tick(float dt)
99    {
100        SUPER(Jump, tick, dt);
101
102        if (figure_ != NULL)
103        {
104                Vector3 figurePosition = figure_->getPosition();
105                Vector3 figureVelocity = figure_->getVelocity();
106
107                if (figurePosition.z > totalScreenShift)
108                {
109                        screenShiftSinceLastUpdate += figurePosition.z - totalScreenShift;
110                        totalScreenShift = figurePosition.z;
111
112                // Falls noetig neue Platformen im neuen Bereich einfuegen
113                if (screenShiftSinceLastUpdate > sectionLength)
114                {
115                        screenShiftSinceLastUpdate -= sectionLength;
116                    addSection();
117                }
118                }
119
120                // Spiel verloren wegen Ansturz?
121                if (figurePosition.z < totalScreenShift - center_->getFieldDimension().y && figureVelocity.z < 0)
122                {
123                        end();
124                }
125
126
127                if (this->camera != NULL)
128                        {
129                                Vector3 cameraPosition = Vector3(0, totalScreenShift, 0);
130                                camera->setPosition(cameraPosition);
131                        }
132                        else
133                        {
134                                orxout() << "No camera found." << endl;
135                                //this->camera = this->figure_->getCamera();
136                        }
137        }
138        else
139        {
140                //orxout() << "No figure found." << endl;
141        }
142
143                // Platformen, die zu weit unten sind entfernen
144                Vector3 platformPosition;
145                for (std::list<JumpPlatform*>::iterator it = platformList.begin(); it != platformList.end(); it++)
146                {
147                        // IDEE: Statt durch alle platformen in der Liste, wie im Tutorial durch alle objekte im Spiel iterieren --> eigene liste unnoetig
148                        platformPosition = (**it).getPosition();
149                        if (platformPosition.z < totalScreenShift - center_->getFieldDimension().y)
150                        {
151                                // Entferne Platform
152                                orxout() << "position = " << (**it).getPosition().y << endl;
153                                center_->detach(*it);
154                                it = platformList.erase(it);
155                        }
156                }
157    }
158
159
160    void Jump::setConfigValues()
161    {
162        SetConfigValue(scoreLimit_, 10).description("The player first reaching those points wins.");
163    }
164
165    /**
166    @brief
167        Cleans up the Gametype by destroying the ball and the bats.
168    */
169    void Jump::cleanup()
170    {
171        /*if (this->ball_ != NULL) // Destroy the ball, if present.
172        {
173            this->ball_->destroy();
174            this->ball_ = 0;
175        }*/
176
177        // Destroy both bats, if present.
178                if (this->figure_ != NULL)
179                {
180                        this->figure_->destroy();
181                        this->figure_ = 0;
182                }
183                this->camera = 0;
184    }
185
186    /**
187    @brief
188        Starts the Jump minigame.
189    */
190    void Jump::start()
191    {
192        if (this->center_ != NULL) // There needs to be a JumpCenterpoint, i.e. the area the game takes place.
193        {
194
195
196            // Attach the ball to the centerpoint and set the parameters as specified in the centerpoint, the ball is attached to.
197            /*this->center_->attach(this->ball_);
198            this->ball_->setPosition(0, 0, 0);
199            this->ball_->setFieldDimension(this->center_->getFieldDimension());
200
201            // Set the bats for the ball.
202            this->ball_->setFigure(this->figure_);
203            */
204
205            // If one of the bats is missing, create it. Apply the template for the bats as specified in the centerpoint.
206                        if (this->figure_ == NULL)
207                        {
208                                this->figure_ = new JumpFigure(this->center_->getContext());
209                                this->figure_->addTemplate(this->center_->getBattemplate());
210                        }
211
212            // Attach the bats to the centerpoint and set the parameters as specified in the centerpoint, the bats are attached to.
213            this->center_->attach(this->figure_);
214            this->figure_->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
215            this->figure_->yaw(Degree(-90));
216            this->figure_->setSpeed(this->center_->getBatSpeed());
217            this->figure_->setFieldDimension(this->center_->getFieldDimension());
218            this->figure_->setLength(this->center_->getBatLength());
219
220
221        }
222        else // If no centerpoint was specified, an error is thrown and the level is exited.
223        {
224            orxout(internal_error) << "Jump: No Centerpoint specified." << endl;
225            GSLevel::startMainMenu();
226            return;
227        }
228
229        // Start the timer. After it has expired the ball is started.
230        this->starttimer_.startTimer();
231
232        // Set variable to temporarily force the player to spawn.
233        bool temp = this->bForceSpawn_;
234        this->bForceSpawn_ = true;
235
236        // Call start for the parent class.
237        Deathmatch::start();
238
239        // Reset the variable.
240        this->bForceSpawn_ = temp;
241
242        if (this->figure_ != NULL)
243        {
244                this->camera = this->figure_->getCamera();
245        }
246
247        totalScreenShift = 0.0;
248        screenShiftSinceLastUpdate = 0.0;
249        sectionNumber = 0;
250        sectionLength = 100.0;
251
252        addStartSection();
253        addSection();
254        addSection();
255    }
256
257    /**
258    @brief
259        Ends the Jump minigame.
260    */
261    void Jump::end()
262    {
263        this->cleanup();
264
265        // Call end for the parent class.
266        Deathmatch::end();
267    }
268
269    /**
270    @brief
271        Spawns players, and fills the rest up with bots.
272    */
273    void Jump::spawnPlayersIfRequested()
274    {
275
276        // first spawn human players to assign always the left bat to the player in singleplayer
277        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
278            if (it->first->isHumanPlayer() && (it->first->isReadyToSpawn() || this->bForceSpawn_))
279                this->spawnPlayer(it->first);
280        // now spawn bots
281        /*
282        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
283            if (!it->first->isHumanPlayer() && (it->first->isReadyToSpawn() || this->bForceSpawn_))
284                this->spawnPlayer(it->first);
285        */
286    }
287
288    /**
289    @brief
290        Spawns the input player.
291    @param player
292        The player to be spawned.
293    */
294    void Jump::spawnPlayer(PlayerInfo* player)
295    {
296        assert(player);
297
298        // If the first (left) bat has no player.
299        if (this->figure_->getPlayer() == NULL)
300        {
301            player->startControl(this->figure_);
302            this->players_[player].state_ = PlayerState::Alive;
303        }
304        // If both bats are taken.
305        else
306        {
307            return;
308        }
309
310    }
311
312    /**
313    @brief
314        Is called when the player scored.
315    */
316    void Jump::playerScored(PlayerInfo* player, int score)
317    {
318        /*
319        Deathmatch::playerScored(player, score);
320        if (this->center_ != NULL) // If there is a centerpoint.
321        {
322            // Fire an event for the player that has scored, to be able to react to it in the level, e.g. by displaying fireworks.
323            if (player == this->getRightPlayer())
324                this->center_->fireEvent(FireEventName(JumpCenterpoint, right));
325            else if (player == this->getLeftPlayer())
326                this->center_->fireEvent(FireEventName(JumpCenterpoint, left));
327
328            // Also announce, that the player has scored.
329            if (player != NULL)
330                this->gtinfo_->sendAnnounceMessage(player->getName() + " scored");
331        }
332
333        // If there is a ball present, reset its position, velocity and acceleration.
334        if (this->ball_ != NULL)
335        {
336            this->ball_->setPosition(Vector3::ZERO);
337            this->ball_->setVelocity(Vector3::ZERO);
338            this->ball_->setAcceleration(Vector3::ZERO);
339            this->ball_->setSpeed(0);
340        }
341
342        // If there are bats reset them to the middle position.
343        if (this->figure_[0] != NULL && this->figure_[1] != NULL)
344        {
345            this->figure_[0]->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
346            this->figure_[1]->setPosition( this->center_->getFieldDimension().x / 2, 0, 0);
347        }
348
349        // If a player gets enough points, he won the game -> end of game
350        PlayerInfo* winningPlayer = NULL;
351        if (this->getLeftPlayer() && this->getScore(this->getLeftPlayer()) >= scoreLimit_)
352            winningPlayer = this->getLeftPlayer();
353        else if (this->getRightPlayer() && this->getScore(this->getRightPlayer()) >= scoreLimit_)
354            winningPlayer = getLeftPlayerthis->getRightPlayer();
355
356        if (winningPlayer)
357        {
358             ChatManager::message(winningPlayer->getName() + " has won!");
359             this->end();
360        }
361
362        // Restart the timer to start the ball.
363        this->starttimer_.startTimer();
364
365        */
366    }
367
368    /**
369    @brief
370        Starts the ball with some default speed.
371    */
372    void Jump::startBall()
373    {
374
375    }
376
377    /**
378    @brief
379        Get the left player.
380    @return
381        Returns a pointer to the player playing on the left. If there is no left player, NULL is returned.
382    */
383    PlayerInfo* Jump::getPlayer() const
384    {
385        if (this->figure_ != NULL)
386        {
387            return this->figure_->getPlayer();
388        }
389        else
390        {
391            return 0;
392        }
393    }
394
395    void Jump::addPlatform(JumpPlatform* newPlatform, float xPosition, float zPosition)
396    {
397        if (newPlatform != NULL)
398                {
399                newPlatform->setPosition(Vector3(xPosition, 0.0, zPosition));
400                newPlatform->setFieldDimension(center_->getFieldDimension());
401                newPlatform->setFigure(this->figure_);
402                center_->attach(newPlatform);
403                platformList.push_front(newPlatform);
404                }
405    }
406
407    void Jump::addStartSection()
408    {
409                JumpPlatform* newPlatform;
410
411                for (float xPosition = -center_->getFieldDimension().x; xPosition <= center_->getFieldDimension().x; xPosition += 12.0)
412                {
413                        newPlatform = new JumpPlatformStatic(center_->getContext());
414                        addPlatform(newPlatform, xPosition, -0.05*sectionLength);
415                }
416    }
417
418    void Jump::addSection()
419    {
420        float fieldWidth = center_->getFieldDimension().x;
421        float fieldHeight = center_->getFieldDimension().y;
422
423        float sectionBegin = sectionNumber * sectionLength;
424        float sectionEnd = (1.0 + sectionNumber) * sectionLength;
425
426        JumpPlatformStatic* newPlatformStatic;
427        JumpPlatformHMove* newPlatformHMove;
428        JumpPlatformVMove* newPlatformVMove;
429
430                switch (rand()%3)
431                {
432                case 0:
433                        for (int i = 0; i < 10; ++i)
434                        {
435                                newPlatformStatic = new JumpPlatformStatic(center_->getContext());
436                                addPlatform(newPlatformStatic, randomXPosition(), sectionBegin + i*sectionLength/10);
437                        }
438                        break;
439                case 1:
440                        for (int i = 0; i < 10; ++i)
441                        {
442                                newPlatformHMove = new JumpPlatformHMove(center_->getContext());
443                                newPlatformHMove->setProperties(-fieldWidth, fieldWidth, 30.0);
444                                addPlatform(newPlatformHMove, randomXPosition(), sectionBegin + i*sectionLength/10);
445                        }
446
447                        break;
448                case 2:
449                        for (int i = 0; i < 10; ++i)
450                        {
451                                newPlatformVMove = new JumpPlatformVMove(center_->getContext());
452                                newPlatformVMove->setProperties(sectionBegin, sectionEnd, 20.0);
453                                addPlatform(newPlatformVMove, -fieldWidth + i*fieldWidth*2/10, randomYPosition(sectionBegin, sectionEnd));
454                        }
455                        break;
456                }
457                orxout() << "new section added with number "<< sectionNumber << endl;
458
459                ++ sectionNumber;
460    }
461
462    float Jump::randomXPosition()
463    {
464        return (float)(rand()%(2*(int)center_->getFieldDimension().x)) - center_->getFieldDimension().x;
465    }
466
467    float Jump::randomYPosition(float lowerBoundary, float upperBoundary)
468    {
469        return (float)(rand()%(int)(upperBoundary - lowerBoundary)) + lowerBoundary;
470    }
471
472    int Jump::getScore(PlayerInfo* player) const
473    {
474        return sectionNumber - 2;
475    }
476
477}
Note: See TracBrowser for help on using the repository browser.