Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc @ 11662

Last change on this file since 11662 was 11662, checked in by kohlia, 6 years ago

Crashes when killing the player

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