Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/questsystem5/src/orxonox/objects/worldentities/ControllableEntity.cc @ 2908

Last change on this file since 2908 was 2908, checked in by dafrick, 15 years ago

Reverted to revision 2906 (because I'm too stupid to merge correctly, 2nd try will follow shortly. ;))

  • Property svn:eol-style set to native
File size: 18.5 KB
RevLine 
[2072]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:
[2662]25 *      Reto Grieder
[2072]26 *
27 */
28
29#include "OrxonoxStableHeaders.h"
30#include "ControllableEntity.h"
31
[2662]32#include <OgreSceneManager.h>
33
[2072]34#include "core/CoreIncludes.h"
[2662]35#include "core/ConfigValueIncludes.h"
[2908]36#include "core/Core.h"
[2072]37#include "core/XMLPort.h"
38#include "core/Template.h"
39
[2662]40#include "objects/Scene.h"
[2072]41#include "objects/infos/PlayerInfo.h"
42#include "objects/worldentities/Camera.h"
43#include "objects/worldentities/CameraPosition.h"
[2662]44#include "objects/gametypes/Gametype.h"
[2072]45#include "overlays/OverlayGroup.h"
46
47namespace orxonox
48{
49    CreateFactory(ControllableEntity);
50
[2662]51    ControllableEntity::ControllableEntity(BaseObject* creator) : MobileEntity(creator)
[2072]52    {
53        RegisterObject(ControllableEntity);
54
[2662]55        this->bHasLocalController_ = false;
56        this->bHasHumanController_ = false;
57
[2072]58        this->server_overwrite_ = 0;
59        this->client_overwrite_ = 0;
60        this->player_ = 0;
[2171]61        this->playerID_ = OBJECTID_UNKNOWN;
[2072]62        this->hud_ = 0;
63        this->camera_ = 0;
64        this->bDestroyWhenPlayerLeft_ = false;
[2662]65        this->cameraPositionRootNode_ = this->node_->createChildSceneNode();
66        this->bMouseLook_ = false;
67        this->mouseLookSpeed_ = 200;
[2072]68
[2662]69        this->gtinfo_ = 0;
70        this->gtinfoID_ = OBJECTID_UNKNOWN;
71        this->changedGametype();
[2072]72
[2662]73        this->server_position_         = Vector3::ZERO;
74        this->client_position_         = Vector3::ZERO;
75        this->server_linear_velocity_  = Vector3::ZERO;
76        this->client_linear_velocity_  = Vector3::ZERO;
77        this->server_orientation_      = Quaternion::IDENTITY;
78        this->client_orientation_      = Quaternion::IDENTITY;
79        this->server_angular_velocity_ = Vector3::ZERO;
80        this->client_angular_velocity_ = Vector3::ZERO;
[2072]81
[2662]82
83        this->setConfigValues();
84        this->setPriority( priority::very_high );
[2072]85        this->registerVariables();
86    }
87
88    ControllableEntity::~ControllableEntity()
89    {
90        if (this->isInitialized())
91        {
[2662]92            this->bDestroyWhenPlayerLeft_ = false;
[2072]93
[2662]94            if (this->bHasLocalController_ && this->bHasHumanController_)
95                this->stopLocalHumanControl();
96
97            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
98                this->getPlayer()->stopControl(this, false);
99
[2072]100            if (this->hud_)
101                delete this->hud_;
102
103            if (this->camera_)
104                delete this->camera_;
105
[2662]106            for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
107                delete (*it);
108
109            if (this->getScene()->getSceneManager())
110                this->getScene()->getSceneManager()->destroySceneNode(this->cameraPositionRootNode_->getName());
[2072]111        }
112    }
113
114    void ControllableEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
115    {
116        SUPER(ControllableEntity, XMLPort, xmlelement, mode);
117
118        XMLPortParam(ControllableEntity, "hudtemplate", setHudTemplate, getHudTemplate, xmlelement, mode);
119        XMLPortParam(ControllableEntity, "camerapositiontemplate", setCameraPositionTemplate, getCameraPositionTemkplate, xmlelement, mode);
120
121        XMLPortObject(ControllableEntity, CameraPosition, "camerapositions", addCameraPosition, getCameraPosition, xmlelement, mode);
122    }
123
[2662]124    void ControllableEntity::setConfigValues()
125    {
126        SetConfigValue(mouseLookSpeed_, 3.0f);
127    }
128
129    void ControllableEntity::changedGametype()
130    {
131        //SUPER(ControllableEntity, changedGametype);
132        WorldEntity::changedGametype();
133
134        this->gtinfo_ = 0;
135        this->gtinfoID_ = OBJECTID_UNKNOWN;
136
137        if (this->getGametype() && this->getGametype()->getGametypeInfo())
138        {
139            this->gtinfo_ = this->getGametype()->getGametypeInfo();
140            this->gtinfoID_ = this->gtinfo_->getObjectID();
141        }
142    }
143
[2072]144    void ControllableEntity::addCameraPosition(CameraPosition* position)
145    {
[2908]146        if (position->getAllowMouseLook())
147            position->attachToNode(this->cameraPositionRootNode_);
[2662]148        else
[2908]149            this->attach(position);
[2072]150        this->cameraPositions_.push_back(position);
151    }
152
153    CameraPosition* ControllableEntity::getCameraPosition(unsigned int index) const
154    {
155        unsigned int i = 0;
156        for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
157        {
158            if (i == index)
159                return (*it);
160            ++i;
161        }
162        return 0;
163    }
164
165    void ControllableEntity::switchCamera()
166    {
167        if (this->camera_)
168        {
169            if (this->camera_->getParent() == this && this->cameraPositions_.size() > 0)
170            {
171                this->cameraPositions_.front()->attachCamera(this->camera_);
172            }
173            else if (this->cameraPositions_.size() > 0)
174            {
175                for (std::list<CameraPosition*>::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
176                {
177                    if ((*it) == this->camera_->getParent())
178                    {
179                        ++it;
180                        if (it != this->cameraPositions_.end())
181                            (*it)->attachCamera(this->camera_);
182                        else
183                            (*this->cameraPositions_.begin())->attachCamera(this->camera_);
184                        break;
185                    }
186                }
187            }
188            else
189            {
[2662]190                this->camera_->attachToNode(this->cameraPositionRootNode_);
[2072]191            }
192        }
193    }
194
[2662]195    void ControllableEntity::mouseLook()
196    {
197        this->bMouseLook_ = !this->bMouseLook_;
198
199        if (!this->bMouseLook_)
200            this->cameraPositionRootNode_->setOrientation(Quaternion::IDENTITY);
201    }
202
203    void ControllableEntity::rotateYaw(const Vector2& value)
204    {
205        if (this->bMouseLook_)
206            this->cameraPositionRootNode_->yaw(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
207    }
208
209    void ControllableEntity::rotatePitch(const Vector2& value)
210    {
211        if (this->bMouseLook_)
212            this->cameraPositionRootNode_->pitch(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
213    }
214
215    void ControllableEntity::rotateRoll(const Vector2& value)
216    {
217        if (this->bMouseLook_)
218            this->cameraPositionRootNode_->roll(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
219    }
220
[2072]221    void ControllableEntity::setPlayer(PlayerInfo* player)
222    {
223        if (!player)
224        {
225            this->removePlayer();
226            return;
227        }
228
229        this->player_ = player;
230        this->playerID_ = player->getObjectID();
[2662]231        this->bHasLocalController_ = player->isLocalPlayer();
232        this->bHasHumanController_ = player->isHumanPlayer();
233
234        if (this->bHasLocalController_ && this->bHasHumanController_)
[2072]235        {
[2662]236            this->startLocalHumanControl();
[2072]237
[2908]238            if (!Core::isMaster())
[2072]239            {
240                this->client_overwrite_ = this->server_overwrite_;
[2662]241                this->setObjectMode(objectDirection::bidirectional);
[2072]242            }
243        }
244    }
245
246    void ControllableEntity::removePlayer()
247    {
[2662]248        if (this->bHasLocalController_ && this->bHasHumanController_)
249            this->stopLocalHumanControl();
[2072]250
251        this->player_ = 0;
[2171]252        this->playerID_ = OBJECTID_UNKNOWN;
[2662]253        this->bHasLocalController_ = false;
254        this->bHasHumanController_ = false;
255        this->setObjectMode(objectDirection::toclient);
[2072]256
257        if (this->bDestroyWhenPlayerLeft_)
258            delete this;
259    }
260
261    void ControllableEntity::networkcallback_changedplayerID()
262    {
263        // just do this in case the entity wasn't yet synchronized when the corresponding PlayerInfo got our objectID
[2171]264        if (this->playerID_ != OBJECTID_UNKNOWN)
[2072]265        {
[2171]266            this->player_ = dynamic_cast<PlayerInfo*>(Synchronisable::getSynchronisable(this->playerID_));
[2072]267            if (this->player_ && (this->player_->getControllableEntity() != this))
268                this->player_->startControl(this);
269        }
270    }
271
[2662]272    void ControllableEntity::networkcallback_changedgtinfoID()
[2072]273    {
[2662]274        if (this->gtinfoID_ != OBJECTID_UNKNOWN)
275        {
276            this->gtinfo_ = dynamic_cast<GametypeInfo*>(Synchronisable::getSynchronisable(this->gtinfoID_));
[2072]277
[2662]278            if (!this->gtinfo_)
279                this->gtinfoID_ = OBJECTID_UNKNOWN;
280        }
281    }
282
283    void ControllableEntity::startLocalHumanControl()
284    {
285        if (!this->camera_)
[2072]286        {
[2662]287            this->camera_ = new Camera(this);
288            this->camera_->requestFocus();
289            if (this->cameraPositionTemplate_ != "")
290                this->addTemplate(this->cameraPositionTemplate_);
291            if (this->cameraPositions_.size() > 0)
292                this->cameraPositions_.front()->attachCamera(this->camera_);
293            else
294                this->camera_->attachToNode(this->cameraPositionRootNode_);
[2072]295        }
[2662]296
297        if (!this->hud_)
298        {
299            if (this->hudtemplate_ != "")
300            {
301                this->hud_ = new OverlayGroup(this);
302                this->hud_->addTemplate(this->hudtemplate_);
303                this->hud_->setOwner(this);
304            }
305        }
[2072]306    }
307
[2662]308    void ControllableEntity::stopLocalHumanControl()
[2072]309    {
[2662]310        if (this->camera_)
311        {
312            this->camera_->detachFromParent();
313            delete this->camera_;
314            this->camera_ = 0;
315        }
[2072]316
[2662]317        if (this->hud_)
318        {
319            delete this->hud_;
320            this->hud_ = 0;
321        }
[2072]322    }
323
324    void ControllableEntity::tick(float dt)
325    {
[2662]326        MobileEntity::tick(dt);
327
[2072]328        if (this->isActive())
329        {
[2662]330            // Check whether Bullet doesn't do the physics for us
331            if (!this->isDynamic())
[2072]332            {
[2908]333                if (Core::isMaster())
[2662]334                {
335                    this->server_position_ = this->getPosition();
336                    this->server_orientation_ = this->getOrientation();
337                    this->server_linear_velocity_ = this->getVelocity();
338                    this->server_angular_velocity_ = this->getAngularVelocity();
339                }
340                else if (this->bHasLocalController_)
341                {
342                    this->client_position_ = this->getPosition();
343                    this->client_orientation_ = this->getOrientation();
344                    this->client_linear_velocity_ = this->getVelocity();
345                    this->client_angular_velocity_ = this->getAngularVelocity();
346                }
[2072]347            }
348        }
349    }
350
351    void ControllableEntity::registerVariables()
352    {
[2662]353        registerVariable(this->cameraPositionTemplate_,  variableDirection::toclient);
354        registerVariable(this->hudtemplate_,             variableDirection::toclient);
[2072]355
[2662]356        registerVariable(this->server_position_,         variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
357        registerVariable(this->server_linear_velocity_,  variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerLinearVelocity));
358        registerVariable(this->server_orientation_,      variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
359        registerVariable(this->server_angular_velocity_, variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerAngularVelocity));
[2072]360
[2662]361        registerVariable(this->server_overwrite_,        variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
362        registerVariable(this->client_overwrite_,        variableDirection::toserver);
[2072]363
[2662]364        registerVariable(this->client_position_,         variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
365        registerVariable(this->client_linear_velocity_,  variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientLinearVelocity));
366        registerVariable(this->client_orientation_,      variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
367        registerVariable(this->client_angular_velocity_, variableDirection::toserver, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientAngularVelocity));
[2072]368
[2662]369        registerVariable(this->playerID_,                variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID));
370        registerVariable(this->gtinfoID_,                variableDirection::toclient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedgtinfoID));
[2072]371    }
372
373    void ControllableEntity::processServerPosition()
374    {
[2662]375        if (!this->bHasLocalController_)
376            MobileEntity::setPosition(this->server_position_);
[2072]377    }
378
[2662]379    void ControllableEntity::processServerLinearVelocity()
[2072]380    {
[2662]381        if (!this->bHasLocalController_)
382            MobileEntity::setVelocity(this->server_linear_velocity_);
[2072]383    }
384
385    void ControllableEntity::processServerOrientation()
386    {
[2662]387        if (!this->bHasLocalController_)
388            MobileEntity::setOrientation(this->server_orientation_);
[2072]389    }
390
[2662]391    void ControllableEntity::processServerAngularVelocity()
392    {
393        if (!this->bHasLocalController_)
394            MobileEntity::setAngularVelocity(this->server_angular_velocity_);
395    }
396
[2072]397    void ControllableEntity::processOverwrite()
398    {
[2662]399        if (this->bHasLocalController_)
[2072]400        {
401            this->setPosition(this->server_position_);
402            this->setOrientation(this->server_orientation_);
[2662]403            this->setVelocity(this->server_linear_velocity_);
404            this->setAngularVelocity(this->server_angular_velocity_);
[2072]405
406            this->client_overwrite_ = this->server_overwrite_;
407        }
408    }
409
410    void ControllableEntity::processClientPosition()
411    {
412        if (this->server_overwrite_ == this->client_overwrite_)
413        {
[2662]414            MobileEntity::setPosition(this->client_position_);
415            this->server_position_ = this->getPosition();
[2072]416        }
417    }
418
[2662]419    void ControllableEntity::processClientLinearVelocity()
[2072]420    {
421        if (this->server_overwrite_ == this->client_overwrite_)
422        {
[2662]423            MobileEntity::setVelocity(this->client_linear_velocity_);
424            this->server_linear_velocity_ = this->getVelocity();
[2072]425        }
426    }
427
428    void ControllableEntity::processClientOrientation()
429    {
430        if (this->server_overwrite_ == this->client_overwrite_)
431        {
[2662]432            MobileEntity::setOrientation(this->client_orientation_);
433            this->server_orientation_ = this->getOrientation();
[2072]434        }
435    }
436
[2662]437    void ControllableEntity::processClientAngularVelocity()
[2072]438    {
[2662]439        if (this->server_overwrite_ == this->client_overwrite_)
[2072]440        {
[2662]441            MobileEntity::setAngularVelocity(this->client_angular_velocity_);
442            this->server_angular_velocity_ = this->getAngularVelocity();
[2072]443        }
444    }
445
[2662]446    void ControllableEntity::setPosition(const Vector3& position)
[2072]447    {
[2908]448        if (Core::isMaster())
[2072]449        {
[2662]450            MobileEntity::setPosition(position);
451            this->server_position_ = this->getPosition();
[2072]452            ++this->server_overwrite_;
453        }
[2662]454        else if (this->bHasLocalController_)
[2072]455        {
[2662]456            MobileEntity::setPosition(position);
457            this->client_position_ = this->getPosition();
[2072]458        }
459    }
460
461    void ControllableEntity::setOrientation(const Quaternion& orientation)
462    {
[2908]463        if (Core::isMaster())
[2072]464        {
[2662]465            MobileEntity::setOrientation(orientation);
466            this->server_orientation_ = this->getOrientation();
[2072]467            ++this->server_overwrite_;
468        }
[2662]469        else if (this->bHasLocalController_)
[2072]470        {
[2662]471            MobileEntity::setOrientation(orientation);
472            this->client_orientation_ = this->getOrientation();
[2072]473        }
474    }
475
[2662]476    void ControllableEntity::setVelocity(const Vector3& velocity)
[2072]477    {
[2908]478        if (Core::isMaster())
[2072]479        {
[2662]480            MobileEntity::setVelocity(velocity);
481            this->server_linear_velocity_ = this->getVelocity();
[2072]482            ++this->server_overwrite_;
483        }
[2662]484        else if (this->bHasLocalController_)
[2072]485        {
[2662]486            MobileEntity::setVelocity(velocity);
487            this->client_linear_velocity_ = this->getVelocity();
[2072]488        }
489    }
490
[2662]491    void ControllableEntity::setAngularVelocity(const Vector3& velocity)
[2072]492    {
[2908]493        if (Core::isMaster())
[2072]494        {
[2662]495            MobileEntity::setAngularVelocity(velocity);
496            this->server_angular_velocity_ = this->getAngularVelocity();
[2072]497            ++this->server_overwrite_;
498        }
[2662]499        else if (this->bHasLocalController_)
[2072]500        {
[2662]501            MobileEntity::setAngularVelocity(velocity);
502            this->client_angular_velocity_ = this->getAngularVelocity();
[2072]503        }
504    }
505
[2662]506    void ControllableEntity::setWorldTransform(const btTransform& worldTrans)
[2072]507    {
[2662]508        MobileEntity::setWorldTransform(worldTrans);
[2908]509        if (Core::isMaster())
[2072]510        {
[2662]511            this->server_position_ = this->getPosition();
512            this->server_orientation_ = this->getOrientation();
513            this->server_linear_velocity_ = this->getVelocity();
514            this->server_angular_velocity_ = this->getAngularVelocity();
[2072]515        }
[2662]516        else if (this->bHasLocalController_)
[2072]517        {
[2662]518            this->client_position_ = this->getPosition();
519            this->client_orientation_ = this->getOrientation();
520            this->client_linear_velocity_ = this->getVelocity();
521            this->client_angular_velocity_ = this->getAngularVelocity();
[2072]522        }
523    }
524}
Note: See TracBrowser for help on using the repository browser.