Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

bugs—
network++
endurance—
tiredness++

but it still doesn't work properly
(commit because oli is very impatient)

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