Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ai/src/orxonox/worldentities/ControllableEntity.cc @ 8874

Last change on this file since 8874 was 8701, checked in by jo, 13 years ago

First successful attempt, to make bots shoot rockets. Unfortunately they're shooting the wrong ones.

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