Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ScriptableController_FS18/src/orxonox/scriptablecontroller/scriptable_controller_api.cc @ 11902

Last change on this file since 11902 was 11902, checked in by adamc, 7 years ago

scriptablecontroller trying to move player with lua

File size: 15.7 KB
Line 
1
2#include "scriptable_controller_api.h"
3#include "luatb.h"
4#include "scriptable_controller.h"
5#include "tools/Timer.h"
6#include "worldentities/pawns/Pawn.h"
7#include "infos/Bot.h"
8#include "worldentities/pawns/ModularSpaceShip.h"
9
10namespace orxonox
11{
12
13    const double ScriptableControllerAPI::periodic_interval = 0.5;
14
15    ScriptableControllerAPI::ScriptableControllerAPI(lua_State *lua, ScriptableController *controller)
16    {
17        this->lua_ = lua;
18        this->controller_ = controller;
19
20        // Haven't found a shorter way yet to write that... We need C++17!
21        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::orxPrint)>::registerFunction<&ScriptableControllerAPI::orxPrint>(this, lua, "orxPrint");
22
23        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAfterTimeout)>::registerFunction<&ScriptableControllerAPI::registerAfterTimeout>(this, lua, "registerAfterTimeout");
24        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtNearObject)>::registerFunction<&ScriptableControllerAPI::registerAtNearObject>(this, lua, "registerAtNearObject");
25        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtNearPoint)>::registerFunction<&ScriptableControllerAPI::registerAtNearPoint>(this, lua, "registerAtNearPoint");
26        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtAreaEnter)>::registerFunction<&ScriptableControllerAPI::registerAtAreaEnter>(this, lua, "registerAtAreaEnter");
27        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtAreaLeave)>::registerFunction<&ScriptableControllerAPI::registerAtAreaLeave>(this, lua, "registerAtAreaLeave");
28        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtPawnKilled)>::registerFunction<&ScriptableControllerAPI::registerAtPawnKilled>(this, lua, "registerAtPawnKilled");
29        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtPawnHit)>::registerFunction<&ScriptableControllerAPI::registerAtPawnHit>(this, lua, "registerAtPawnHit");
30
31        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::setPosition)>::registerFunction<&ScriptableControllerAPI::setPosition>(this, lua, "setPosition");
32        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::setOrientation)>::registerFunction<&ScriptableControllerAPI::setOrientation>(this, lua, "setOrientation");
33        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::setVelocity)>::registerFunction<&ScriptableControllerAPI::setVelocity>(this, lua, "setVelocity");
34        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::setAngularVelocity)>::registerFunction<&ScriptableControllerAPI::setAngularVelocity>(this, lua, "setAngularVelocity");
35
36        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::killPawn)>::registerFunction<&ScriptableControllerAPI::killPawn>(this, lua, "killPawn");
37        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::spawn)>::registerFunction<&ScriptableControllerAPI::spawn>(this, lua, "spawn");
38
39
40
41        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::myTestFunction)>::registerFunction<&ScriptableControllerAPI::myTestFunction>(this, lua, "mytestfunction");
42        LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::moveControllableEntity)>::registerFunction<&ScriptableControllerAPI::moveControllableEntity>(this, lua, "moveControllableEntity");
43
44
45
46        this->periodicTimer.setTimer(ScriptableControllerAPI::periodic_interval, true, createExecutor(createFunctor(&ScriptableControllerAPI::periodic, this)), false);
47    }
48
49    ScriptableControllerAPI::~ScriptableControllerAPI()
50    {
51        lua_close(this->lua_);
52    }
53
54    void ScriptableControllerAPI::orxPrint(std::string msg)
55    {
56        orxout(user_info) << msg << std::endl;
57    }
58
59    void ScriptableControllerAPI::registerAfterTimeout(std::function<void (void)> callback, double timeout)
60    {
61        // Kills itself when the timer fires
62        new Timer(timeout, false, callback, true);
63    }
64
65    void ScriptableControllerAPI::registerAtNearObject(std::function<void (std::string, std::string)> callback, std::string id1, std::string id2, double distance)
66    {
67        WorldEntity *entity1 = this->controller_->getWorldEntityByID(id1);
68        WorldEntity *entity2 = this->controller_->getWorldEntityByID(id2);
69
70        if(entity1 != nullptr && entity2 != nullptr)
71            this->nearObjectHandlers_.push_front(NearObjectHandler(entity1, entity2, id1, id2, distance, callback));
72    }
73
74    void ScriptableControllerAPI::registerAtNearPoint(std::function<void (std::string)> callback, std::string id, double x, double y, double z, double distance)
75    {
76        WorldEntity *entity = this->controller_->getWorldEntityByID(id);
77
78        if(entity != nullptr)
79            this->nearPointHandlers_.push_front(NearPointHandler(entity, id, x, y, z, distance, callback));
80    }
81
82    void ScriptableControllerAPI::registerAtAreaEnter(std::function<void (std::string)> callback, std::string id, int x, int y, int z, int dx, int dy, int dz)
83    {
84        WorldEntity *entity = this->controller_->getWorldEntityByID(id);
85
86        if(entity != nullptr)
87            this->areaHandlers_.push_front(AreaHandler(entity, id, x, y, z, dx, dy, dz, true, callback));
88    }
89
90    void ScriptableControllerAPI::registerAtAreaLeave(std::function<void (std::string)> callback, std::string id, int x, int y, int z, int dx, int dy, int dz)
91    {
92        WorldEntity *entity = this->controller_->getWorldEntityByID(id);
93
94        if(entity != nullptr)
95            this->areaHandlers_.push_front(AreaHandler(entity, id, x, y, z, dx, dy, dz, false, callback));
96    }
97
98    void ScriptableControllerAPI::registerAtPawnKilled(std::function<void (std::string)> callback, std::string id)
99    {
100        this->pawnDestroyedHandlers_[id].push_back(callback);
101    }
102
103    void ScriptableControllerAPI::registerAtPawnHit(std::function<void (std::string, std::string, double, double)> callback, std::string id)
104    {
105        this->pawnHitHandlers_[id].push_back(callback);
106    }
107
108    void ScriptableControllerAPI::killPawn(std::string id)
109    {
110        Pawn *pawn = this->controller_->getPawnByID(id);
111        if(pawn == nullptr)
112            orxout(user_warning) << "Trying to kill an unknown pawn" << std::endl;
113        else
114            pawn->kill();
115    }
116
117    void ScriptableControllerAPI::spawn(std::string type, std::string id)
118    {
119        if(this->controller_->getWorldEntityByID(id) != nullptr)
120        {
121            orxout(user_warning) << "Script tried to spawn an object, but an object with the given ID exists already" << std::endl;
122            return;
123        }
124
125        Identifier *identifier = ClassByString(type);
126        if(!identifier)
127        {
128            orxout(user_error) << "Script tried to spawn unknown object" << std::endl;
129            return;
130        }
131
132        if(!identifier->isLoadable())
133        {
134            orxout(user_error) << "Script tried to spawn unloadable object" << std::endl;
135            return;
136        }
137
138        WorldEntity *entity;
139        Identifiable *obj = identifier->fabricate(this->controller_->getWorldEntityByID("Player")->getContext());
140
141        if(obj->isA(ClassIdentifier<WorldEntity>::getIdentifier()))
142        {
143            entity = orxonox_cast<WorldEntity*>(obj);
144        }
145        else if(obj->isA(ClassIdentifier<PlayerInfo>::getIdentifier()))
146        {
147            // TODO This does not work yet because somehow the controllable entity is not set
148            // yet at this stage.
149    //        entity = orxonox_cast<PlayerInfo*>(obj)->getControllableEntity();
150            return;
151        }
152        else
153        {
154            orxout(user_warning) << "Script tried to spawn an object that is neither a WorldEntity, nor a PlayerInfo" << std::endl;
155           
156            return;
157        }
158
159        if(entity->isA(ClassIdentifier<MobileEntity>::getIdentifier()))
160            this->controller_->registerMobileEntity(id, orxonox_cast<MobileEntity*>(entity));
161
162        if(entity->isA(ClassIdentifier<Pawn>::getIdentifier()))
163            this->controller_->registerPawn(id, orxonox_cast<Pawn*>(entity));
164
165        this->controller_->registerWorldEntity(id, orxonox_cast<WorldEntity*>(entity));
166    }
167
168    void ScriptableControllerAPI::setPosition(std::string id, double x, double y, double z)
169    {
170        WorldEntity *entity = this->controller_->getWorldEntityByID(id);
171        if(entity == nullptr)
172        {
173            orxout(user_warning) << "Trying to set position of an unknown object" << std::endl;
174            return;
175        }
176
177        const Vector3 &old = entity->getPosition();
178
179        // If one of the values is NaN, don't change that value
180        x = std::isnan(x) ? old.x : x;
181        y = std::isnan(y) ? old.y : y;
182        z = std::isnan(z) ? old.z : z;
183
184        entity->setPosition(x, y, z);
185    }
186
187    void ScriptableControllerAPI::setOrientation(std::string id, double x, double y, double z, double angle)
188    {
189        WorldEntity *entity = this->controller_->getWorldEntityByID(id);
190        if(entity == nullptr)
191        {
192            orxout(user_warning) << "Trying to set orientation of an unknown object" << std::endl;
193            return;
194        }
195
196        Vector3 old_axis;
197        Degree old_angle;
198
199        entity->getOrientation().ToAngleAxis(old_angle, old_axis);
200
201        // If one of the values is NaN, don't change that value
202        x = std::isnan(x) ? old_axis.x : x;
203        y = std::isnan(y) ? old_axis.y : y;
204        z = std::isnan(z) ? old_axis.z : z;
205        angle = std::isnan(x) ? old_angle.valueDegrees() : angle;
206
207
208        entity->setOrientation(Vector3(x, y, z), Degree(angle));
209    }
210
211    void ScriptableControllerAPI::setVelocity(std::string id, double x, double y, double z)
212    {
213        MobileEntity *entity = this->controller_->getMobileEntityByID(id);
214        if(entity == nullptr)
215        {
216            orxout(user_warning) << "Trying to set velocity of an unknown object" << std::endl;
217            return;
218        }
219
220        const Vector3 &old = entity->getVelocity();
221
222        // If one of the values is NaN, don't change that value
223        x = std::isnan(x) ? old.x : x;
224        y = std::isnan(y) ? old.y : y;
225        z = std::isnan(z) ? old.z : z;
226
227        entity->setVelocity(x, y, z);
228    }
229
230    void ScriptableControllerAPI::setAngularVelocity(std::string id, double x, double y, double z)
231    {
232        MobileEntity *entity = this->controller_->getMobileEntityByID(id);
233        if(entity == nullptr)
234        {
235            orxout(user_warning) << "Trying to set angular velocity of an unknown object" << std::endl;
236            return;
237        }
238
239        const Vector3 &old = entity->getAngularVelocity();
240
241        // If one of the values is NaN, don't change that value
242        x = std::isnan(x) ? old.x : x;
243        y = std::isnan(y) ? old.y : y;
244        z = std::isnan(z) ? old.z : z;
245
246        entity->setAngularVelocity(x, y, z);
247    }
248
249    void ScriptableControllerAPI::pawnKilled(std::string id, Pawn *pawn)
250    {
251        for(auto callback : this->pawnDestroyedHandlers_[id])
252            callback(id);
253
254        this->pawnDestroyedHandlers_.erase(id);
255
256        // We need to delete those handlers as well, they're no longer valid
257        auto near_obj_handler = this->nearObjectHandlers_.begin();
258        while(near_obj_handler != this->nearObjectHandlers_.end())
259        {
260            if(near_obj_handler->entity1_ == pawn || near_obj_handler->entity2_ == pawn)
261                near_obj_handler = this->nearObjectHandlers_.erase(near_obj_handler);
262            else
263                near_obj_handler++;
264        }
265
266        auto near_point_handler = this->nearPointHandlers_.begin();
267        while(near_point_handler != this->nearPointHandlers_.end())
268        {
269            if(near_point_handler->entity_ == pawn)
270                near_point_handler = this->nearPointHandlers_.erase(near_point_handler);
271            else
272                near_point_handler++;
273        }
274
275        auto area_handler = this->areaHandlers_.begin();
276        while(area_handler != this->areaHandlers_.end())
277        {
278            if(area_handler->entity_ == pawn)
279                area_handler = this->areaHandlers_.erase(area_handler);
280            else
281                area_handler++;
282        }
283    }
284
285    void ScriptableControllerAPI::pawnHit(std::string target_id, std::string source_id, double new_health, double new_shield)
286    {
287        for(auto callback : this->pawnHitHandlers_[target_id])
288            callback(target_id, source_id, new_health, new_shield);
289    }
290
291    void ScriptableControllerAPI::periodic()
292    {
293        // Near object
294        auto near_obj_handler = this->nearObjectHandlers_.begin();
295        while(near_obj_handler != this->nearObjectHandlers_.end())
296        {
297            if((near_obj_handler->entity1_->getPosition() - near_obj_handler->entity2_->getPosition()).length() < near_obj_handler->distance_)
298            {
299                near_obj_handler->callback_(near_obj_handler->id1_, near_obj_handler->id2_);
300                near_obj_handler = this->nearObjectHandlers_.erase(near_obj_handler);
301            }
302            else
303            {
304                near_obj_handler++;
305            }
306        }
307
308        // Near point
309        auto near_point_handler = this->nearPointHandlers_.begin();
310        while(near_point_handler != this->nearPointHandlers_.end())
311        {
312            if((near_point_handler->entity_->getPosition() - near_point_handler->point_).length() < near_point_handler->distance_)
313            {
314                near_point_handler->callback_(near_point_handler->id_);
315                near_point_handler = this->nearPointHandlers_.erase(near_point_handler);
316            }
317            else
318            {
319                near_point_handler++;
320            }
321        }
322
323        // Areas
324        auto area_handler = this->areaHandlers_.begin();
325        while(area_handler != this->areaHandlers_.end())
326        {
327            if(area_handler->entity_->getPosition() > area_handler->start_point_ &&
328               area_handler->entity_->getPosition() < area_handler->end_point_)
329            {
330                if(area_handler->atEnter_)
331                {
332                    area_handler->callback_(area_handler->id_);
333                    area_handler = this->areaHandlers_.erase(area_handler);
334                }
335                else
336                {
337                    area_handler++;
338                }
339            }
340            else
341            {
342                if(!area_handler->atEnter_)
343                {
344                    area_handler->callback_(area_handler->id_);
345                    area_handler = this->areaHandlers_.erase(area_handler);
346                }
347                else
348                {
349                    area_handler++;
350                }
351            }
352        }
353
354    }
355
356
357    //// TESTTESTTESTTESTTESTTEST
358    double ScriptableControllerAPI::myTestFunction(double x, double y)
359    {
360        double z = x + y;
361        orxout(user_info) << "Result = " << z << endl;
362        return z;
363    }
364
365    void ScriptableControllerAPI::moveControllableEntity(std::string id, double x, double y, double z)
366    {
367        MobileEntity *entity = this->controller_->getMobileEntityByID(id);
368        if(entity == nullptr)
369        {
370            orxout(user_warning) << "Trying to set velocity of an unknown object" << std::endl;
371            return;
372        }
373
374
375
376
377        Identifier *identifier = ClassByString("ControllableEntity");
378       
379        ControllableEntity *controllable_entity;
380       
381        if(identifier->isA(ClassIdentifier<ControllableEntity>::getIdentifier()))
382        {
383            controllable_entity = orxonox_cast<ControllableEntity*>(entity);
384
385            controllable_entity->moveFrontBack(x);
386            controllable_entity->moveRightLeft(y);
387            controllable_entity->moveUpDown(z);
388        }
389
390        return;
391       
392    }
393}
Note: See TracBrowser for help on using the repository browser.