[Orxonox-commit 7043] r11662 - in code/branches/ScriptableController_HS17/src/orxonox: infos scriptablecontroller

kohlia at orxonox.net kohlia at orxonox.net
Mon Dec 11 16:35:38 CET 2017


Author: kohlia
Date: 2017-12-11 16:35:38 +0100 (Mon, 11 Dec 2017)
New Revision: 11662

Modified:
   code/branches/ScriptableController_HS17/src/orxonox/infos/GametypeInfo.cc
   code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc
   code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc
   code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.h
Log:
Crashes when killing the player



Modified: code/branches/ScriptableController_HS17/src/orxonox/infos/GametypeInfo.cc
===================================================================
--- code/branches/ScriptableController_HS17/src/orxonox/infos/GametypeInfo.cc	2017-12-11 15:06:56 UTC (rev 11661)
+++ code/branches/ScriptableController_HS17/src/orxonox/infos/GametypeInfo.cc	2017-12-11 15:35:38 UTC (rev 11662)
@@ -317,8 +317,11 @@
         if(player->isHumanPlayer() && player->isLocalPlayer())
         {
             this->getLevel()->getScriptableController()->setPlayer(player);
-            // TODO Fix for relative paths
-            this->getLevel()->getScriptableController()->runScript(this->getLevel()->getFilename() + "/" + this->getLevel()->getScript());
+
+            std::string script = this->getLevel()->getScript();
+            if(script.at(0) != '/')
+                script = "../levels/" + script; // Not very dynamic
+            this->getLevel()->getScriptableController()->runScript(script);
         }
     }
 

Modified: code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc
===================================================================
--- code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc	2017-12-11 15:06:56 UTC (rev 11661)
+++ code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc	2017-12-11 15:35:38 UTC (rev 11662)
@@ -34,6 +34,7 @@
     // Load the program; this supports both source code and bytecode files.
     if((ret = luaL_loadfile(lua, file_path.c_str())) != 0)
     {
+        orxout(user_error) << "Failed to load level script " + file_path << std::endl;
         this->printLuaError(lua);
         delete api;
         return ret;
@@ -42,6 +43,7 @@
     // Execute the script
     if((ret = lua_pcall(lua, 0, LUA_MULTRET, 0)) != 0)
     {
+        orxout(user_error) << "Level script returned an error" << std::endl;
         this->printLuaError(lua);
         delete api;
         return ret;
@@ -85,7 +87,7 @@
     }
 
     for(auto &api : this->apis_)
-        api->pawnKilled(pawn_id_iter->second);
+        api->pawnKilled(pawn_id_iter->second, pawn);
 
     this->pawns_.erase(pawn_id_iter->second);
     this->pawnsReverse_.erase(pawn_id_iter);
@@ -109,14 +111,14 @@
 
 void ScriptableController::killPawn(std::string id)
 {
-    auto pawn = this->pawns_.find(id);
-    if(pawn == this->pawns_.end())
+    auto pawn = this->getPawnByID(id);
+    if(pawn == nullptr)
     {
         orxout(user_warning) << "Tried to destroy unknown pawn " << id << std::endl;
         return;
     }
 
-    pawn->second->kill();
+    pawn->kill();
 }
 
 WorldEntity *ScriptableController::getWorldEntityByID(std::string id) const
@@ -140,6 +142,9 @@
 
 Pawn *ScriptableController::getPawnByID(std::string id) const
 {
+    if(id == "player" || id == "Player" || id == "PLAYER")
+        return orxonox_cast<Pawn*>(this->player_->getControllableEntity());
+
     auto pawn = this->pawns_.find(id);
     return pawn != this->pawns_.end() ? pawn->second : nullptr;
 }
@@ -150,7 +155,7 @@
     // Fetch it, print it and then pop it off the stack.
     // Yes, this is 'const char*' and not 'std::string' because that's what lua gives us.
     const char* message = lua_tostring(lua, -1);
-    std::cout << message << std::endl;
+    orxout(user_error) << message << std::endl;
     lua_pop(lua, 1);
 }
 

Modified: code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc
===================================================================
--- code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc	2017-12-11 15:06:56 UTC (rev 11661)
+++ code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc	2017-12-11 15:35:38 UTC (rev 11662)
@@ -3,6 +3,9 @@
 #include "luatb.h"
 #include "scriptable_controller.h"
 #include "tools/Timer.h"
+#include "worldentities/pawns/Pawn.h"
+#include "infos/Bot.h"
+#include "worldentities/pawns/ModularSpaceShip.h"
 
 namespace orxonox
 {
@@ -31,6 +34,7 @@
     LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::setAngularVelocity)>::registerFunction<&ScriptableControllerAPI::setAngularVelocity>(this, lua, "setAngularVelocity");
 
     LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::killPawn)>::registerFunction<&ScriptableControllerAPI::killPawn>(this, lua, "killPawn");
+    LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::spawn)>::registerFunction<&ScriptableControllerAPI::spawn>(this, lua, "spawn");
 
     this->periodicTimer.setTimer(ScriptableControllerAPI::periodic_interval, true, createExecutor(createFunctor(&ScriptableControllerAPI::periodic, this)), false);
 }
@@ -102,6 +106,56 @@
     this->pawnsToKill_.push_back(id);
 }
 
+void ScriptableControllerAPI::spawn(std::string type, std::string id)
+{
+    if(this->controller_->getWorldEntityByID(id) != nullptr)
+    {
+        orxout(user_warning) << "Script tried to spawn an object, but an object with the given ID exists already" << std::endl;
+        return;
+    }
+
+    Identifier *identifier = ClassByString(type);
+    if(!identifier)
+    {
+        orxout(user_error) << "Script tried to spawn unknown object" << std::endl;
+        return;
+    }
+
+    if(!identifier->isLoadable())
+    {
+        orxout(user_error) << "Script tried to spawn unloadable object" << std::endl;
+        return;
+    }
+
+    WorldEntity *entity;
+    Identifiable *obj = identifier->fabricate(this->controller_->getWorldEntityByID("Player")->getContext());
+
+    if(obj->isA(ClassIdentifier<WorldEntity>::getIdentifier()))
+    {
+        entity = orxonox_cast<WorldEntity*>(obj);
+    }
+    else if(obj->isA(ClassIdentifier<PlayerInfo>::getIdentifier()))
+    {
+        // TODO This does not work yet because somehow the controllable entity is not set
+        // yet at this stage.
+//        entity = orxonox_cast<PlayerInfo*>(obj)->getControllableEntity();
+        return;
+    }
+    else
+    {
+        orxout(user_warning) << "Script tried to spawn an object that is neither a WorldEntity, nor a PlayerInfo" << std::endl;
+        return;
+    }
+
+    if(entity->isA(ClassIdentifier<MobileEntity>::getIdentifier()))
+        this->controller_->registerMobileEntity(id, orxonox_cast<MobileEntity*>(entity));
+
+    if(entity->isA(ClassIdentifier<Pawn>::getIdentifier()))
+        this->controller_->registerPawn(id, orxonox_cast<Pawn*>(entity));
+
+    this->controller_->registerWorldEntity(id, orxonox_cast<WorldEntity*>(entity));
+}
+
 void ScriptableControllerAPI::setPosition(std::string id, double x, double y, double z)
 {
     WorldEntity *entity = this->controller_->getWorldEntityByID(id);
@@ -178,12 +232,22 @@
     entity->setAngularVelocity(x, y, z);
 }
 
-void ScriptableControllerAPI::pawnKilled(std::string id)
+void ScriptableControllerAPI::pawnKilled(std::string id, Pawn *pawn)
 {
     for(auto callback : this->pawnDestroyedHandlers_[id])
         callback(id);
 
     this->pawnDestroyedHandlers_.erase(id);
+
+    // We need to delete those handlers as well, they're no longer valid
+    auto near_obj_handler = this->nearObjectHandlers_.begin();
+    while(near_obj_handler != this->nearObjectHandlers_.end())
+    {
+        if(near_obj_handler->entity1_ == pawn || near_obj_handler->entity2_ == pawn)
+            near_obj_handler = this->nearObjectHandlers_.erase(near_obj_handler);
+        else
+            near_obj_handler++;
+    }
 }
 
 void ScriptableControllerAPI::pawnHit(std::string target_id, std::string source_id, double new_health, double new_shield)
@@ -256,6 +320,8 @@
     }
 
     // Pawns to kill
+    // TODO Possible race condidtion when the player destroys the pawn
+    // between the callback and the next periodic call.
     for(auto &pawn : this->pawnsToKill_)
         this->controller_->killPawn(pawn);
 

Modified: code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.h
===================================================================
--- code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.h	2017-12-11 15:06:56 UTC (rev 11661)
+++ code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.h	2017-12-11 15:35:38 UTC (rev 11662)
@@ -13,6 +13,7 @@
 
 class ScriptableController;
 class WorldEntity;
+class Pawn;
 
 /**
  * @brief API for ScriptableController's lua-scripts
@@ -23,6 +24,8 @@
  */
 class ScriptableControllerAPI
 {
+friend class ScriptableController;
+
 public:
     /**
      * @brief Constructs the API with the given lua state
@@ -139,6 +142,13 @@
     void killPawn(std::string id);
 
     /**
+     * @brief Spawn an object
+     * @param type Name of the class of the object you want to spawn
+     * @param id The newly created ID that can be used to access this object
+     */
+    void spawn(std::string type, std::string id);
+
+    /**
      * @brief Set the position of an object
      * @param id The ID of the object
      * @param x The position on the x-axis
@@ -184,6 +194,7 @@
 
 // ### API END ################################################################
 
+private:
     /**
      * @brief Called by ScriptableController when a pawn is killed
      * @param id The dead pawn
@@ -190,7 +201,7 @@
      *
      * Calls the lua callbacks associated with this event.
      */
-    void pawnKilled(std::string id);
+    void pawnKilled(std::string id, Pawn *pawn);
 
     /**
      * @brief Called by ScriptableController when a Pawn is hit
@@ -201,7 +212,6 @@
      */
     void pawnHit(std::string target_id, std::string source_id, double new_health, double new_shield);
 
-private:
     /**
      * @brief Groups everything together that is needed to handle a near-object event
      */



More information about the Orxonox-commit mailing list