Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy/src/orxonox/objects/worldentities/ControllableEntity.cc @ 1993

Last change on this file since 1993 was 1993, checked in by landauf, 16 years ago

added several new classes

File size: 13.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#include "ControllableEntity.h"
30
31#include "core/CoreIncludes.h"
32#include "core/Core.h"
33#include "core/XMLPort.h"
34#include "core/Template.h"
35
36#include "objects/infos/PlayerInfo.h"
37#include "objects/Camera.h"
38#include "overlays/OverlayGroup.h"
39
40namespace orxonox
41{
42    CreateFactory(ControllableEntity);
43
44    ControllableEntity::ControllableEntity()
45    {
46        RegisterObject(ControllableEntity);
47
48        this->bControlled_ = false;
49        this->server_overwrite_ = 0;
50        this->client_overwrite_ = 0;
51        this->player_ = 0;
52        this->playerID_ = network::OBJECTID_UNKNOWN;
53        this->hud_ = 0;
54        this->camera_ = 0;
55        this->bDestroyWhenPlayerLeft_ = false;
56
57        this->velocity_ = Vector3::ZERO;
58        this->acceleration_ = Vector3::ZERO;
59
60        this->server_position_ = Vector3::ZERO;
61        this->client_position_ = Vector3::ZERO;
62        this->server_velocity_ = Vector3::ZERO;
63        this->client_velocity_ = Vector3::ZERO;
64        this->server_orientation_ = Quaternion::IDENTITY;
65        this->client_orientation_ = Quaternion::IDENTITY;
66
67        this->registerVariables();
68    }
69
70    ControllableEntity::~ControllableEntity()
71    {
72        if (this->isInitialized() && this->bControlled_)
73            this->stopLocalControl();
74    }
75
76    void ControllableEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
77    {
78        SUPER(ControllableEntity, XMLPort, xmlelement, mode);
79
80        XMLPortParam(ControllableEntity, "hudtemplate", setHudTemplate, getHudTemplate, xmlelement, mode);
81    }
82
83    void ControllableEntity::setPlayer(PlayerInfo* player)
84    {
85        if (!player)
86        {
87            this->removePlayer();
88            return;
89        }
90
91        this->player_ = player;
92        this->playerID_ = player->getObjectID();
93        this->bControlled_ = player->isLocalPlayer();
94
95        if (this->bControlled_)
96        {
97            this->startLocalControl();
98            this->setObjectMode(network::direction::bidirectional);
99        }
100    }
101
102    void ControllableEntity::removePlayer()
103    {
104        if (this->bControlled_)
105            this->stopLocalControl();
106
107        this->player_ = 0;
108        this->playerID_ = network::OBJECTID_UNKNOWN;
109        this->bControlled_ = false;
110        this->setObjectMode(network::direction::toclient);
111
112        if (this->bDestroyWhenPlayerLeft_)
113            delete this;
114    }
115
116    void ControllableEntity::updatePlayer()
117    {
118        if (this->playerID_ != network::OBJECTID_UNKNOWN)
119        {
120            this->player_ = dynamic_cast<PlayerInfo*>(network::Synchronisable::getSynchronisable(this->playerID_));
121            if (this->player_ && (this->player_->getPawn() != this))
122                this->player_->startControl(this);
123        }
124    }
125
126    void ControllableEntity::startLocalControl()
127    {
128        std::cout << "###### start local control" << std::endl;
129        this->camera_ = new Camera();
130        this->camera_->requestFocus();
131        this->attach(this->camera_);
132
133        if (this->hudtemplate_ != "")
134        {
135            this->hud_ = new OverlayGroup();
136            this->hud_->addTemplate(this->hudtemplate_);
137        }
138    }
139
140    void ControllableEntity::stopLocalControl()
141    {
142        std::cout << "###### stop local control" << std::endl;
143        this->detach(this->camera_);
144        delete this->camera_;
145        this->camera_ = 0;
146
147        delete this->hud_;
148        this->hud_ = 0;
149    }
150
151    void ControllableEntity::tick(float dt)
152    {
153        if (this->isActive())
154        {
155            this->velocity_ += (dt * this->acceleration_);
156            this->node_->translate(dt * this->velocity_, Ogre::Node::TS_PARENT);
157
158            if (Core::isMaster())
159            {
160                this->server_velocity_ = this->velocity_;
161                this->server_position_ = this->node_->getPosition();
162            }
163            else if (this->bControlled_)
164            {
165                this->client_velocity_ = this->velocity_;
166                this->client_position_ = this->node_->getPosition();
167            }
168        }
169    }
170
171    void ControllableEntity::registerVariables()
172    {
173        REGISTERDATA(this->server_position_,    network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
174        REGISTERDATA(this->server_velocity_,    network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerVelocity));
175        REGISTERDATA(this->server_orientation_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
176
177        REGISTERDATA(this->server_overwrite_,   network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
178
179        REGISTERDATA(this->client_position_,    network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
180        REGISTERDATA(this->client_velocity_,    network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientVelocity));
181        REGISTERDATA(this->client_orientation_, network::direction::toserver, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
182
183        REGISTERDATA(this->client_overwrite_,   network::direction::toserver);
184
185        REGISTERDATA(this->playerID_, network::direction::toclient, new network::NetworkCallback<ControllableEntity>(this, &ControllableEntity::updatePlayer));
186    }
187
188    void ControllableEntity::processServerPosition()
189    {
190        if (!this->bControlled_)
191            this->node_->setPosition(this->server_position_);
192    }
193
194    void ControllableEntity::processServerVelocity()
195    {
196        if (!this->bControlled_)
197            this->velocity_ = this->server_velocity_;
198    }
199
200    void ControllableEntity::processServerOrientation()
201    {
202        if (!this->bControlled_)
203            this->node_->setOrientation(this->server_orientation_);
204    }
205
206    void ControllableEntity::processOverwrite()
207    {
208        if (this->bControlled_)
209        {
210            this->setPosition(this->server_position_);
211            this->setVelocity(this->server_velocity_);
212            this->setOrientation(this->server_orientation_);
213
214            this->client_overwrite_ = this->server_overwrite_;
215        }
216    }
217
218    void ControllableEntity::processClientPosition()
219    {
220        if (this->server_overwrite_ == this->client_overwrite_)
221        {
222            this->node_->setPosition(this->client_position_);
223            this->server_position_ = this->client_position_;
224        }
225    }
226
227    void ControllableEntity::processClientVelocity()
228    {
229        if (this->server_overwrite_ == this->client_overwrite_)
230        {
231            this->velocity_ = this->client_velocity_;
232            this->server_velocity_ = this->client_velocity_;
233        }
234    }
235
236    void ControllableEntity::processClientOrientation()
237    {
238        if (this->server_overwrite_ == this->client_overwrite_)
239        {
240            this->node_->setOrientation(this->client_orientation_);
241            this->server_orientation_ = this->client_orientation_;
242        }
243    }
244
245
246    void ControllableEntity::setPosition(const Vector3& position)
247    {
248        if (Core::isMaster())
249        {
250            this->node_->setPosition(position);
251            this->server_position_ = position;
252            ++this->server_overwrite_;
253        }
254        else if (this->bControlled_)
255        {
256            this->node_->setPosition(position);
257            this->client_position_ = position;
258        }
259    }
260
261    void ControllableEntity::setVelocity(const Vector3& velocity)
262    {
263        if (Core::isMaster())
264        {
265            this->velocity_ = velocity;
266            this->server_velocity_ = velocity;
267            ++this->server_overwrite_;
268        }
269        else if (this->bControlled_)
270        {
271            this->velocity_ = velocity;
272            this->client_velocity_ = velocity;
273        }
274    }
275
276    void ControllableEntity::translate(const Vector3& distance, Ogre::Node::TransformSpace relativeTo)
277    {
278        if (Core::isMaster())
279        {
280            this->node_->translate(distance, relativeTo);
281            this->server_position_ = this->node_->getPosition();
282            ++this->server_overwrite_;
283        }
284        else if (this->bControlled_)
285        {
286            this->node_->translate(distance, relativeTo);
287            this->client_position_ = this->node_->getPosition();
288        }
289    }
290
291    void ControllableEntity::setOrientation(const Quaternion& orientation)
292    {
293        if (Core::isMaster())
294        {
295            this->node_->setOrientation(orientation);
296            this->server_orientation_ = orientation;
297            ++this->server_overwrite_;
298        }
299        else if (this->bControlled_)
300        {
301            this->node_->setOrientation(orientation);
302            this->client_orientation_ = orientation;
303        }
304    }
305
306    void ControllableEntity::rotate(const Quaternion& rotation, Ogre::Node::TransformSpace relativeTo)
307    {
308        if (Core::isMaster())
309        {
310            this->node_->rotate(rotation, relativeTo);
311            this->server_orientation_ = this->node_->getOrientation();
312            ++this->server_overwrite_;
313        }
314        else if (this->bControlled_)
315        {
316            this->node_->rotate(rotation, relativeTo);
317            this->client_orientation_ = this->node_->getOrientation();
318        }
319    }
320
321    void ControllableEntity::yaw(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
322    {
323        if (Core::isMaster())
324        {
325            this->node_->yaw(angle, relativeTo);
326            this->server_orientation_ = this->node_->getOrientation();
327            ++this->server_overwrite_;
328        }
329        else if (this->bControlled_)
330        {
331            this->node_->yaw(angle, relativeTo);
332            this->client_orientation_ = this->node_->getOrientation();
333        }
334    }
335
336    void ControllableEntity::pitch(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
337    {
338        if (Core::isMaster())
339        {
340            this->node_->pitch(angle, relativeTo);
341            this->server_orientation_ = this->node_->getOrientation();
342            ++this->server_overwrite_;
343        }
344        else if (this->bControlled_)
345        {
346            this->node_->pitch(angle, relativeTo);
347            this->client_orientation_ = this->node_->getOrientation();
348        }
349    }
350
351    void ControllableEntity::roll(const Degree& angle, Ogre::Node::TransformSpace relativeTo)
352    {
353        if (Core::isMaster())
354        {
355            this->node_->roll(angle, relativeTo);
356            this->server_orientation_ = this->node_->getOrientation();
357            ++this->server_overwrite_;
358        }
359        else if (this->bControlled_)
360        {
361            this->node_->roll(angle, relativeTo);
362            this->client_orientation_ = this->node_->getOrientation();
363        }
364    }
365
366    void ControllableEntity::lookAt(const Vector3& target, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
367    {
368        if (Core::isMaster())
369        {
370            this->node_->lookAt(target, relativeTo, localDirectionVector);
371            this->server_orientation_ = this->node_->getOrientation();
372            ++this->server_overwrite_;
373        }
374        else if (this->bControlled_)
375        {
376            this->node_->lookAt(target, relativeTo, localDirectionVector);
377            this->client_orientation_ = this->node_->getOrientation();
378        }
379    }
380
381    void ControllableEntity::setDirection(const Vector3& direction, Ogre::Node::TransformSpace relativeTo, const Vector3& localDirectionVector)
382    {
383        if (Core::isMaster())
384        {
385            this->node_->setDirection(direction, relativeTo, localDirectionVector);
386            this->server_orientation_ = this->node_->getOrientation();
387            ++this->server_overwrite_;
388        }
389        else if (this->bControlled_)
390        {
391            this->node_->setDirection(direction, relativeTo, localDirectionVector);
392            this->client_orientation_ = this->node_->getOrientation();
393        }
394    }
395}
Note: See TracBrowser for help on using the repository browser.