Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/pong/PongBall.cc @ 7852

Last change on this file since 7852 was 7852, checked in by landauf, 13 years ago

fixed crash in Pong gametype if the game was ended right after the ball was set back to center after a score

  • Property svn:eol-style set to native
File size: 6.4 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#include "PongBall.h"
30
31#include "core/CoreIncludes.h"
32#include "core/GameMode.h"
33#include "gametypes/Gametype.h"
34#include "PongBat.h"
35
36namespace orxonox
37{
38    CreateFactory(PongBall);
39
40    const float PongBall::MAX_REL_Z_VELOCITY = 1.5;
41
42    PongBall::PongBall(BaseObject* creator)
43        : MovableEntity(creator)
44    {
45        RegisterObject(PongBall);
46
47        this->speed_ = 0;
48        this->accelerationFactor_ = 1.0f;
49        this->bat_ = 0;
50        this->batID_ = new unsigned int[2];
51        this->batID_[0] = OBJECTID_UNKNOWN;
52        this->batID_[1] = OBJECTID_UNKNOWN;
53        this->relMercyOffset_ = 0.05f;
54
55        this->registerVariables();
56    }
57
58    PongBall::~PongBall()
59    {
60    }
61
62    void PongBall::registerVariables()
63    {
64        registerVariable( this->fieldWidth_ );
65        registerVariable( this->fieldHeight_ );
66        registerVariable( this->batlength_ );
67        registerVariable( this->speed_ );
68        registerVariable( this->relMercyOffset_ );
69        registerVariable( this->batID_[0] );
70        registerVariable( this->batID_[1], VariableDirection::ToClient, new NetworkCallback<PongBall>( this, &PongBall::applyBats) );
71    }
72
73    void PongBall::tick(float dt)
74    {
75        SUPER(PongBall, tick, dt);
76
77        Vector3 position = this->getPosition();
78        Vector3 velocity = this->getVelocity();
79        Vector3 acceleration = this->getAcceleration();
80
81        if (position.z > this->fieldHeight_ / 2 || position.z < -this->fieldHeight_ / 2)
82        {
83            velocity.z = -velocity.z;
84            if (position.z > this->fieldHeight_ / 2)
85                position.z = this->fieldHeight_ / 2;
86            if (position.z < -this->fieldHeight_ / 2)
87                position.z = -this->fieldHeight_ / 2;
88
89            this->fireEvent();
90        }
91
92        if (position.x > this->fieldWidth_ / 2 || position.x < -this->fieldWidth_ / 2)
93        {
94            float distance = 0;
95
96            if (this->bat_)
97            {
98                if (position.x > this->fieldWidth_ / 2 && this->bat_[1])
99                {
100                    distance = (position.z - this->bat_[1]->getPosition().z) / (this->fieldHeight_ * (this->batlength_ * 1.10f) / 2);
101                    if (fabs(distance) <= 1)
102                    {
103                        position.x = this->fieldWidth_ / 2;
104                        velocity.x = -velocity.x;
105                        velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
106                        acceleration = this->bat_[1]->getVelocity() * this->accelerationFactor_ * -1;
107
108                        this->fireEvent();
109                    }
110                    else if (GameMode::isMaster() && position.x > this->fieldWidth_ / 2 * (1 + this->relMercyOffset_))
111                    {
112                        if (this->getGametype() && this->bat_[0])
113                        {
114                            this->getGametype()->playerScored(this->bat_[0]->getPlayer());
115                            return;
116                        }
117                    }
118                }
119                if (position.x < -this->fieldWidth_ / 2 && this->bat_[0])
120                {
121                    distance = (position.z - this->bat_[0]->getPosition().z) / (this->fieldHeight_ * (this->batlength_ * 1.10f) / 2);
122                    if (fabs(distance) <= 1)
123                    {
124                        position.x = -this->fieldWidth_ / 2;
125                        velocity.x = -velocity.x;
126                        velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
127                        acceleration = this->bat_[0]->getVelocity() * this->accelerationFactor_ * -1;
128
129                        this->fireEvent();
130                    }
131                    else if (GameMode::isMaster() && position.x < -this->fieldWidth_ / 2 * (1 + this->relMercyOffset_))
132                    {
133                        if (this->getGametype() && this->bat_[1])
134                        {
135                            this->getGametype()->playerScored(this->bat_[1]->getPlayer());
136                            return;
137                        }
138                    }
139                }
140            }
141        }
142
143        if (acceleration != this->getAcceleration())
144            this->setAcceleration(acceleration);
145        if (velocity != this->getVelocity())
146            this->setVelocity(velocity);
147        if (position != this->getPosition())
148            this->setPosition(position);
149    }
150
151    void PongBall::setSpeed(float speed)
152    {
153        if (speed != this->speed_)
154        {
155            this->speed_ = speed;
156
157            Vector3 velocity = this->getVelocity();
158            if (velocity.x != 0)
159                velocity.x = sgn(velocity.x) * this->speed_;
160            else
161                velocity.x = this->speed_ * sgn(rnd(-1,1));
162
163            this->setVelocity(velocity);
164        }
165    }
166
167    void PongBall::setBats(WeakPtr<PongBat>* bats)
168    {
169        this->bat_ = bats;
170        this->batID_[0] = this->bat_[0]->getObjectID();
171        this->batID_[1] = this->bat_[1]->getObjectID();
172    }
173
174    void PongBall::applyBats()
175    {
176        if (!this->bat_)
177            this->bat_ = new WeakPtr<PongBat>[2]; // TODO: delete this somewhere
178        if (this->batID_[0] != OBJECTID_UNKNOWN)
179            this->bat_[0] = orxonox_cast<PongBat*>(Synchronisable::getSynchronisable(this->batID_[0]));
180        if (this->batID_[1] != OBJECTID_UNKNOWN)
181            this->bat_[1] = orxonox_cast<PongBat*>(Synchronisable::getSynchronisable(this->batID_[1]));
182    }
183}
Note: See TracBrowser for help on using the repository browser.