Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/tetris/src/modules/pong/Pong.cc @ 8666

Last change on this file since 8666 was 8106, checked in by dafrick, 14 years ago

And even more documentation.
Also moved some of the documentation out of Groups.dox into seperate files located in the new groups folder.

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