Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ScriptableController/src/orxonox/controllers/ScriptController.cc @ 10065

Last change on this file since 10065 was 10065, checked in by smerkli, 11 years ago

Improved controller, "move and look" is now scriptable.

File size: 8.9 KB
RevLine 
[10014]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 "ScriptController.h"
[10047]30#include "infos/PlayerInfo.h"
[10014]31#include "core/CoreIncludes.h"
[10028]32#include "worldentities/ControllableEntity.h"
[10045]33#include "core/LuaState.h"
[10034]34#include <cmath>
[10014]35
36namespace orxonox
37{
38    RegisterClass(ScriptController);
39
[10028]40    ScriptController::ScriptController(Context* context) : ArtificialController(context)
[10014]41    {
42        RegisterObject(ScriptController);
[10065]43
44        /* By default, this controller has ID 0, which means it is not assigned
45         * to anything yet.
46         */
[10047]47        this->ctrlid_ = 0;
[10065]48
49
50        /* Set default values for all variables */
51        /* - pointers to zero */
52        this->player_ = NULL;
53        this->entity_ = NULL;
54
55        /* - times */
56        this->scTime = 0.0f;
57        this->timeToTarget = 0.0f;
58        this->eventTime = 0.0f;
59
60        /* - Points in space */
61        this->target = Vector3(0,0,0);
62        this->startpos = Vector3(0,0,0);
63        this->lookAtPosition = Vector3(0,0,0);
64
65        /* - Processing flag */
66        this->processing = false;
67
68        /* - Counters */
69        this->eventno = 0;
70
[10014]71    }
72
[10047]73    void ScriptController::takeControl(int ctrlid)
[10014]74    {
[10065]75        /* Output some debugging information */
[10047]76        orxout() << "ScriptController: Taking control" << endl;
77        orxout() << "This-pointer: " << this << endl;
[10065]78
79        /* Set the controller ID (the argument here should be nonzero) */
[10047]80        this->ctrlid_ = ctrlid;
[10065]81
82        /* Store the entity pointer in a private variable */
[10047]83        this->entity_ = this->player_->getControllableEntity();
84        assert(this->entity_);
[10065]85         
86        /* Add the controller here to this entity. Apparently this still leaves
87         * any preexisting human controllers in place.
88         */
[10047]89        this->entity_->setDestroyWhenPlayerLeft(false);
90        this->player_->pauseControl();
91        this->entity_->setController(this);
92        this->setControllableEntity(this->entity_);
[10065]93        this->entity_->mouseLook();
94        this->entity_->setVisible(false);
[10014]95    }
96
[10047]97    /* Yet to be implemented and tested */
98    //void ScriptController::yieldControl()
99    //{
100        //this->player_->startControl(this->entity_);
101        //this->setActive(false);
102        //this->controllableEntity_ = NULL;
103    //}
104
[10034]105    const Vector3& ScriptController::getPosition()
[10020]106    {
[10065]107      return this->entity_->getPosition();
[10028]108    }
[10014]109
[10045]110    ScriptController* ScriptController::getScriptController()
111    {
[10046]112      /* Output a message that confirms this function was called */
[10045]113      orxout() << "Great success!" << std::endl;
[10046]114
[10047]115      /* Debugging: print all the scriptcontroller object pointers */
[10045]116      for(ObjectList<ScriptController>::iterator it = 
117        ObjectList<ScriptController>::begin(); 
118        it != ObjectList<ScriptController>::end(); ++it)
[10047]119      { orxout() << "Have object in list: " << *it << endl; }
120
121      /* Find the first one with a nonzero ID */
122      for(ObjectList<ScriptController>::iterator it = 
123        ObjectList<ScriptController>::begin(); 
124        it != ObjectList<ScriptController>::end(); ++it)
[10045]125      { 
126        // TODO: do some selection here. Currently just returns the first one
[10047]127        if( (*it)->getID() > 0 )
[10065]128        { orxout() << "Controller to return: " << *it << endl;
[10047]129          return *it; 
[10065]130        }
[10045]131     
132      }
133      return NULL;
134    }
135
[10048]136    void ScriptController::execute(event ev)
137    {
[10065]138        orxout() << "Executing event " << ev.fctName
139          << " with parameters:\n " 
140          << ev.x1 << " " << ev.y1 << " " << ev.z1 << "\n"
141          << ev.x2 << " " << ev.y2 << " " << ev.z2 << "\n"
142          << ev.duration << endl;
[10057]143
[10065]144        this->eventTime = 0.0f;
145        this->startpos = this->entity_->getPosition();
146        this->processing = true;
147
148        if(ev.fctName == "mal")
149          moveAndLook(ev.x1, ev.y1, ev.z1, ev.x2, ev.y2, ev.z2, ev.duration);
[10048]150    }
151
152
[10047]153    void ScriptController::tick(float dt)
154    {
[10065]155        /* Call the tick function of the classes we derive from */
156        SUPER(ScriptController, tick, dt);
[10059]157
[10047]158        /* If this controller has no entity entry, do nothing */
159        if( !(this->entity_) )
160          return;
[10045]161
[10065]162        //orxout() << "Size 0: " << this->eventList.size() << endl;
[10045]163
[10065]164        /* See if time has come for the next event to be run */
165        if(this->eventList.size() > 0 && this->eventList[0].eventTime <= scTime)
[10048]166        {
[10065]167          /* Execute the next event on the list */
168          this->execute(this->eventList[0]);
169          this->eventList.erase(this->eventList.begin());
170          this->eventno -= 1;
171          //orxout() << "Size 1: " << this->eventList.size() << endl;
172          //orxout() << "Eventno is now: " << this->eventno << endl;
173        }
[10048]174
[10065]175        /* Update the local timers in this object */
176        scTime += dt;
177        eventTime += dt;
178
179        /* If we've arrived at the target, stop processing */
180        if( eventTime > timeToTarget && this->processing == true)
181        { this->processing = false;
182
183          //orxout() << "Size 4: " << this->eventList.size() << endl;
184          //orxout() << "Eventno: " << this->eventno << endl;
185         
186          if( this->eventno == 0 )
187          {
188            this->entity_->mouseLook();
189            this->entity_->setVisible(true);
190          }
[10048]191        }
192
[10065]193        /* Get a variable that specifies how far along the trajectory
194         * we are
195         */
196        float dl = eventTime / timeToTarget; 
[10048]197
[10065]198        /* Do some moving */
199        if( this->processing )
200        { 
201          /* Set the position to the correct place in the trajectory */
202          this->entity_->setPosition( (1-dl)*startpos + dl * target );
[10047]203
[10065]204          /* Look at the specified position */
205          this->entity_->lookAt(lookAtPosition);
[10047]206
[10065]207          /* Force mouse look */
208          if( this->entity_->isInMouseLook() == false )
209            this->entity_->mouseLook();
210        }
211    }
[10048]212
[10065]213    void ScriptController::moveAndLook(
214      float xm, float ym, float zm,
215      float xl, float yl, float zl,
216      float t )
[10034]217    {
[10065]218      orxout()<<"moveAndLook executed"<<endl;
[10059]219
[10065]220      /* Set the local variables required for this event */
221      this->target = Vector3(xm,ym,zm);
222      this->lookAtPosition = Vector3(xl,yl,zl);
223      this->timeToTarget = t;
[10034]224
[10059]225
[10065]226      orxout() << "Moving This-pointer: " << this << endl;
[10059]227
[10065]228      if(this->entity_ != NULL)
229        orxout()<<"not-NULL-entity"<<endl;
230      else 
231        return;
[10059]232
[10065]233      if(this->player_ != NULL)
234        orxout()<<"not-NULL-player"<<endl;
235      else 
236        return;
[10034]237    }
238
[10065]239    void ScriptController::eventScheduler(std::string instruction, 
240      float x1, float y1, float z1, 
241      float x2, float y2, float z2, 
242      float duration, float executionTime)
[10048]243    {
[10065]244      /* put data (from LUA) into time-sorted eventList*/ 
245      /* Nimmt den befehl und die argumente aus luascript und ertellt einen
246       * struct pro event, diese structs werden sortiert nach eventTime
247       */
248      struct event tmp;
[10057]249
[10065]250      /* Fill the structure with all the provided information */
251      tmp.fctName = instruction;
252      tmp.x1 = x1; tmp.y1 = y1; tmp.z1 = z1;
253      tmp.x2 = x2; tmp.y2 = y2; tmp.z2 = z2;
254      tmp.duration = duration;
255      tmp.eventTime = executionTime;
[10059]256
[10065]257      orxout() << tmp.fctName << endl;
[10047]258
[10065]259      /* Add the created event to the event list */
260      if(eventList.size()==0)
261      { /* The list is still empty, just add it */
262        orxout() << "eventList empty (01)" << endl;
263        eventList.insert(eventList.begin(), tmp);
264        this->eventno += 1;
265        return; /* Nothing more to do, the event was added */
266      }
[10059]267
[10065]268      /* Event was not added yet since the list was not empty. Walk through
269       * the list of events and add it so that the events are correctly in
270       * order.
271       */
272      for (std::vector<event>::iterator it=eventList.begin(); it<eventList.end(); it++)
273      { if(tmp.eventTime < it->eventTime)
274        { eventList.insert(it,tmp);
275          this->eventno += 1;
276          orxout()<<"new event added"<<endl;
277          return;
[10059]278        }
[10065]279      }
[10034]280
[10065]281      /* If the event was still not added here, it belongs in the end of the list */
282      eventList.insert(eventList.end(), tmp);
283      this->eventno += 1;
[10059]284
[10048]285    }
[10014]286}
Note: See TracBrowser for help on using the repository browser.