Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/dockingsystem/src/modules/pong/Pong.cc @ 8201

Last change on this file since 8201 was 8194, checked in by dafrick, 14 years ago

Merging trunk into dockingsystem branch to be able to use the recent bugfix in MultiTrigger.

  • Property svn:eol-style set to native
File size: 10.3 KB
RevLine 
[2825]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
[8194]29/**
30    @file Pong.cc
31    @brief Implementation of the Pong class.
32*/
33
[2825]34#include "Pong.h"
35
36#include "core/CoreIncludes.h"
[5929]37#include "core/EventIncludes.h"
[7284]38#include "core/command/Executor.h"
[8194]39
40#include "gamestates/GSLevel.h"
41
[5725]42#include "PongCenterpoint.h"
43#include "PongBall.h"
44#include "PongBat.h"
45#include "PongBot.h"
46#include "PongAI.h"
[2825]47
48namespace orxonox
49{
[8194]50    // Events to allow to react to scoring of a player, in the level-file.
[5929]51    CreateEventName(PongCenterpoint, right);
52    CreateEventName(PongCenterpoint, left);
[6417]53
[2825]54    CreateUnloadableFactory(Pong);
55
[8194]56    /**
57    @brief
58        Constructor. Registers and initializes the object.
59    */
[2825]60    Pong::Pong(BaseObject* creator) : Deathmatch(creator)
61    {
62        RegisterObject(Pong);
63
64        this->center_ = 0;
65        this->ball_ = 0;
66        this->bat_[0] = 0;
67        this->bat_[1] = 0;
68
[2890]69        this->setHUDTemplate("PongHUD");
70
[8194]71        // Pre-set the timer, but don't start it yet.
[5929]72        this->starttimer_.setTimer(1.0, false, createExecutor(createFunctor(&Pong::startBall, this)));
[2825]73        this->starttimer_.stopTimer();
[2839]74
[8194]75        // Set the type of Bots for this particular Gametype.
[2839]76        this->botclass_ = Class(PongBot);
[2825]77    }
78
[8194]79    /**
80    @brief
81        Destructor. Cleans up, if initialized.
82    */
[7911]83    Pong::~Pong()
84    {
85        if (this->isInitialized())
86            this->cleanup();
87    }
88
[8194]89    /**
90    @brief
91        Cleans up the Gametype by destroying the ball and the bats.
92    */
[7911]93    void Pong::cleanup()
94    {
[8194]95        if (this->ball_ != NULL) // Destroy the ball, if present.
[7911]96        {
97            this->ball_->destroy();
98            this->ball_ = 0;
99        }
100
[8194]101        // Destroy both bats, if present.
[7911]102        for (size_t i = 0; i < 2; ++i)
103        {
[8194]104            if (this->bat_[0] != NULL)
[7911]105            {
106                this->bat_[0]->destroy();
107                this->bat_[0] = 0;
108            }
109        }
110    }
111
[8194]112    /**
113    @brief
114        Starts the Pong minigame.
115    */
[2825]116    void Pong::start()
117    {
[8194]118        if (this->center_ != NULL) // There needs to be a PongCenterpoint, i.e. the area the game takes place.
[2825]119        {
[8194]120            if (this->ball_ == NULL) // If there is no ball, create a new ball.
[2825]121            {
122                this->ball_ = new PongBall(this->center_);
[8194]123                // Apply the template for the ball specified by the centerpoint.
[2825]124                this->ball_->addTemplate(this->center_->getBalltemplate());
125            }
126
[8194]127            // Attach the ball to the centerpoint and set the parameters as specified in the centerpoint, the ball is attached to.
[2825]128            this->center_->attach(this->ball_);
129            this->ball_->setPosition(0, 0, 0);
130            this->ball_->setFieldDimension(this->center_->getFieldDimension());
131            this->ball_->setSpeed(0);
[5929]132            this->ball_->setAccelerationFactor(this->center_->getBallAccelerationFactor());
[2825]133            this->ball_->setBatLength(this->center_->getBatLength());
134
[8194]135            // If one of the bats is missing, create it. Apply the template for the bats as specified in the centerpoint.
136            for (size_t i = 0; i < 2; ++i)
[2825]137            {
[8194]138                if (this->bat_[i] == NULL)
139                {
140                    this->bat_[i] = new PongBat(this->center_);
141                    this->bat_[i]->addTemplate(this->center_->getBattemplate());
142                }
[2825]143            }
144
[8194]145            // Attach the bats to the centerpoint and set the parameters as specified in the centerpoint, the bats are attached to.
[2825]146            this->center_->attach(this->bat_[0]);
147            this->center_->attach(this->bat_[1]);
148            this->bat_[0]->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
149            this->bat_[1]->setPosition( this->center_->getFieldDimension().x / 2, 0, 0);
150            this->bat_[0]->yaw(Degree(-90));
151            this->bat_[1]->yaw(Degree(90));
152            this->bat_[0]->setSpeed(this->center_->getBatSpeed());
153            this->bat_[1]->setSpeed(this->center_->getBatSpeed());
154            this->bat_[0]->setFieldHeight(this->center_->getFieldDimension().y);
155            this->bat_[1]->setFieldHeight(this->center_->getFieldDimension().y);
156            this->bat_[0]->setLength(this->center_->getBatLength());
157            this->bat_[1]->setLength(this->center_->getBatLength());
158
[8194]159            // Set the bats for the ball.
[2825]160            this->ball_->setBats(this->bat_);
161        }
[8194]162        else // If no centerpoint was specified, an error is thrown and the level is exited.
[2825]163        {
164            COUT(1) << "Error: No Centerpoint specified." << std::endl;
[8194]165            GSLevel::startMainMenu();
166            return;
[2825]167        }
168
[8194]169        // Start the timer. After it has expired the ball is started.
[2825]170        this->starttimer_.startTimer();
171
[8194]172        // Set variable to temporarily force the player to spawn.
[2885]173        bool temp = this->bForceSpawn_;
174        this->bForceSpawn_ = true;
175
[8194]176        // Call start for the parent class.
[2825]177        Deathmatch::start();
[2885]178
[8194]179        // Reset the variable.
[2885]180        this->bForceSpawn_ = temp;
[2825]181    }
182
[8194]183    /**
184    @brief
185        Ends the Pong minigame.
186    */
[2825]187    void Pong::end()
188    {
[7911]189        this->cleanup();
[2825]190
[8194]191        // Call end for the parent class.
[2825]192        Deathmatch::end();
193    }
194
[8194]195    /**
196    @brief
197        Spawns players, and fills the rest up with bots.
198    */
[7865]199    void Pong::spawnPlayersIfRequested()
200    {
201        // first spawn human players to assign always the left bat to the player in singleplayer
202        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
203            if (it->first->isHumanPlayer() && (it->first->isReadyToSpawn() || this->bForceSpawn_))
204                this->spawnPlayer(it->first);
205        // now spawn bots
206        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
207            if (!it->first->isHumanPlayer() && (it->first->isReadyToSpawn() || this->bForceSpawn_))
208                this->spawnPlayer(it->first);
209    }
210
[8194]211    /**
212    @brief
213        Spawns the input player.
214    @param player
215        The player to be spawned.
216    */
[2825]217    void Pong::spawnPlayer(PlayerInfo* player)
218    {
[8194]219        assert(player);
220
221        // If the first (left) bat has no player.
222        if (this->bat_[0]->getPlayer() == NULL)
[2825]223        {
224            player->startControl(this->bat_[0]);
225            this->players_[player].state_ = PlayerState::Alive;
226        }
[8194]227        // If the second (right) bat has no player.
228        else if (this->bat_[1]->getPlayer() == NULL)
[2825]229        {
230            player->startControl(this->bat_[1]);
231            this->players_[player].state_ = PlayerState::Alive;
232        }
[8194]233        // If both bats are taken.
[2839]234        else
235            return;
236
[8194]237        // If the player is an AI, it receives a pointer to the ball.
238        if (player->getController() != NULL && player->getController()->isA(Class(PongAI)))
[2839]239        {
[3325]240            PongAI* ai = orxonox_cast<PongAI*>(player->getController());
[2839]241            ai->setPongBall(this->ball_);
242        }
[2825]243    }
244
[8194]245    /**
246    @brief
247        Is called when the player scored.
248    */
[2825]249    void Pong::playerScored(PlayerInfo* player)
250    {
251        Deathmatch::playerScored(player);
252
[8194]253        if (this->center_ != NULL) // If there is a centerpoint.
[2872]254        {
[8194]255            // Fire an event for the player that has scored, to be able to react to it in the level, e.g. by displaying fireworks.
[5929]256            if (player == this->getRightPlayer())
257                this->center_->fireEvent(FireEventName(PongCenterpoint, right));
258            else if (player == this->getLeftPlayer())
259                this->center_->fireEvent(FireEventName(PongCenterpoint, left));
[6417]260
[8194]261            // Also announce, that the player has scored.
262            if (player != NULL)
[5929]263                this->gtinfo_->sendAnnounceMessage(player->getName() + " scored");
[2872]264        }
265
[8194]266        // If there is a ball present, reset its position, velocity and acceleration.
267        if (this->ball_ != NULL)
[2825]268        {
269            this->ball_->setPosition(Vector3::ZERO);
270            this->ball_->setVelocity(Vector3::ZERO);
[5929]271            this->ball_->setAcceleration(Vector3::ZERO);
[2825]272            this->ball_->setSpeed(0);
273        }
274
[8194]275        // If there are bats reset them to the middle position.
276        if (this->bat_[0] != NULL && this->bat_[1] != NULL)
[2825]277        {
278            this->bat_[0]->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
279            this->bat_[1]->setPosition( this->center_->getFieldDimension().x / 2, 0, 0);
280        }
281
[8194]282        // Restart the timer to start the ball.
[2825]283        this->starttimer_.startTimer();
284    }
285
[8194]286    /**
287    @brief
288        Starts the ball with some default speed.
289    */
[2825]290    void Pong::startBall()
291    {
[8194]292        if (this->ball_ != NULL && this->center_ != NULL)
[2825]293            this->ball_->setSpeed(this->center_->getBallSpeed());
294    }
[2890]295
[8194]296    /**
297    @brief
298        Get the left player.
299    @return
300        Returns a pointer to the player playing on the left. If there is no left player, NULL is returned.
301    */
[2890]302    PlayerInfo* Pong::getLeftPlayer() const
303    {
[8194]304        if (this->bat_ != NULL && this->bat_[0] != NULL)
[2890]305            return this->bat_[0]->getPlayer();
306        else
307            return 0;
308    }
309
[8194]310    /**
311    @brief
312        Get the right player.
313    @return
314        Returns a pointer to the player playing on the right. If there is no right player, NULL is returned.
315    */
[2890]316    PlayerInfo* Pong::getRightPlayer() const
317    {
[8194]318        if (this->bat_ != NULL && this->bat_[1] != NULL)
[2890]319            return this->bat_[1]->getPlayer();
320        else
321            return 0;
322    }
[2825]323}
Note: See TracBrowser for help on using the repository browser.