Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2/src/orxonox/worldentities/ControllableEntity.cc @ 6112

Last change on this file since 6112 was 6112, checked in by scheusso, 14 years ago

first attempts to have synchronised fire direction and target
however client cannot select targets yet (probably because of classtreemask hack)

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