Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ScriptableController_FS18/src/orxonox/scriptablecontroller/scriptable_controller.cc @ 12206

Last change on this file since 12206 was 11974, checked in by adamc, 6 years ago

can

File size: 4.7 KB
RevLine 
[11519]1
2#include "scriptable_controller.h"
3#include "luatb.h"
[11562]4#include "infos/PlayerInfo.h"
[11583]5#include "core/command/Executor.h"
[11606]6#include "worldentities/pawns/Pawn.h"
[11519]7
8namespace orxonox
9{
10
11// Used https://csl.name/post/lua-and-cpp/ as a reference
12int ScriptableController::runScript(const std::string &file_path)
13{
14    int ret;
15
[11861]16    // Not having a script specified at all is not an error.
17    if(file_path.empty()){
18        orxout(internal_warning) << "No script specified!" << std::endl;
[11583]19        return 0;
[11861]20    }
[11583]21
[11519]22    // Create a lua object
23    lua_State *lua = luaL_newstate();
24    if(lua == nullptr)
25    {
[11854]26        orxout(internal_warning) << "ScriptableController: Failed to load script " << file_path << std::endl;
[11519]27        return LUA_ERRMEM;
28    }
29
[11861]30    // Make standard libraries available in the Lua object.
[11519]31    luaL_openlibs(lua);
32
33    // Register the API
34    ScriptableControllerAPI *api = new ScriptableControllerAPI(lua, this);
35
36    // Load the program; this supports both source code and bytecode files.
37    if((ret = luaL_loadfile(lua, file_path.c_str())) != 0)
38    {
[11662]39        orxout(user_error) << "Failed to load level script " + file_path << std::endl;
[11519]40        this->printLuaError(lua);
41        delete api;
42        return ret;
43    }
44
45    // Execute the script
46    if((ret = lua_pcall(lua, 0, LUA_MULTRET, 0)) != 0)
47    {
[11662]48        orxout(user_error) << "Level script returned an error" << std::endl;
[11519]49        this->printLuaError(lua);
50        delete api;
51        return ret;
52    }
53
[11673]54    // Remember the api
[11519]55    this->apis_.push_back(std::unique_ptr<ScriptableControllerAPI>(api));
56
57    return 0;
58}
59
[11562]60void ScriptableController::setPlayer(PlayerInfo *player)
61{
62    this->player_ = player;
63}
64
[11583]65void ScriptableController::registerWorldEntity(std::string id, WorldEntity *entity)
[11519]66{
[11583]67    this->worldEntities_[id] = entity;
[11519]68}
69
[11638]70void ScriptableController::registerMobileEntity(std::string id, MobileEntity *entity)
71{
72    this->mobileEntities_[id] = entity;
73}
74
[11606]75void ScriptableController::registerPawn(std::string id, Pawn *pawn)
[11519]76{
[11606]77    this->pawns_[id] = pawn;
78    this->pawnsReverse_[pawn] = id;
[11519]79}
80
[11606]81void ScriptableController::pawnKilled(Pawn *pawn)
82{
83    auto pawn_id_iter = this->pawnsReverse_.find(pawn);
84    if(pawn_id_iter == this->pawnsReverse_.end())
85    {
86        orxout(internal_warning) << "Unregistered pawn reported that it's destroyed" << std::endl;
87        return;
88    }
89
[11673]90    // The ID of the pawn should already be invalid when we call the callback
91    std::string id = pawn_id_iter->second;
[11606]92    this->pawns_.erase(pawn_id_iter->second);
93    this->pawnsReverse_.erase(pawn_id_iter);
[11673]94
95    for(auto &api : this->apis_)
96        api->pawnKilled(id, pawn);
[11606]97}
98
99void ScriptableController::pawnHit(Pawn *target, Pawn *source, double new_health, double new_shield)
100{
101    auto target_id_iter = this->pawnsReverse_.find(target);
102    auto source_id_iter = this->pawnsReverse_.find(source);
103
104    if(target_id_iter == this->pawnsReverse_.end() ||
105       source_id_iter == this->pawnsReverse_.end() )
106    {
107        orxout(internal_warning) << "Unregistered pawn reported that it's hit" << std::endl;
108        return;
109    }
110
111    for(auto &api : this->apis_)
112        api->pawnHit(target_id_iter->second, source_id_iter->second, new_health, new_shield);
113}
114
[11583]115WorldEntity *ScriptableController::getWorldEntityByID(std::string id) const
[11519]116{
[11583]117    if(id == "player" || id == "Player" || id == "PLAYER")
[11562]118        return this->player_->getControllableEntity();
119
[11583]120    auto entity = this->worldEntities_.find(id);
121    return entity != this->worldEntities_.end() ? entity->second : nullptr;
[11519]122}
123
[11638]124MobileEntity *ScriptableController::getMobileEntityByID(std::string id) const
125{
126    if(id == "player" || id == "Player" || id == "PLAYER")
127        return this->player_->getControllableEntity();
128
129    auto entity = this->mobileEntities_.find(id);
130    return entity != this->mobileEntities_.end() ? entity->second : nullptr;
131}
132
[11606]133Pawn *ScriptableController::getPawnByID(std::string id) const
[11519]134{
[11974]135    if(id == "player" || id == "Player" || id == "PLAYER") {
[11662]136        return orxonox_cast<Pawn*>(this->player_->getControllableEntity());
[11974]137        orxout(user_status) << "Pawn is player!?" << std::endl;
138    }
[11662]139
[11974]140
[11606]141    auto pawn = this->pawns_.find(id);
[11974]142
143    if(pawn != this->pawns_.end()) {
144        orxout(user_status) << "Requested Pawn is available!" << std::endl;
145    }
146
[11606]147    return pawn != this->pawns_.end() ? pawn->second : nullptr;
[11519]148}
149
150void ScriptableController::printLuaError(lua_State *lua)
151{
152    // The error message is on top of the stack.
153    // Fetch it, print it and then pop it off the stack.
154    // Yes, this is 'const char*' and not 'std::string' because that's what lua gives us.
155    const char* message = lua_tostring(lua, -1);
[11662]156    orxout(user_error) << message << std::endl;
[11519]157    lua_pop(lua, 1);
158}
159
160}
Note: See TracBrowser for help on using the repository browser.