[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