Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2040 was 2040, checked in by rgrieder, 16 years ago

reverted those svn:eol-style "native" properties: Tomorrow then.

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