- Timestamp:
- Nov 27, 2017, 4:38:50 PM (7 years ago)
- Location:
- code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc
r11583 r11606 4 4 #include "infos/PlayerInfo.h" 5 5 #include "core/command/Executor.h" 6 #include "worldentities/pawns/Pawn.h" 6 7 7 8 namespace orxonox … … 63 64 } 64 65 65 void ScriptableController::register ControllableEntity(std::string id, ControllableEntity *entity)66 void ScriptableController::registerPawn(std::string id, Pawn *pawn) 66 67 { 67 this->worldEntities_[id] = entity; 68 this->worldEntities_[id] = pawn; 69 this->pawns_[id] = pawn; 70 this->pawnsReverse_[pawn] = id; 71 } 72 73 void ScriptableController::pawnKilled(Pawn *pawn) 74 { 75 auto pawn_id_iter = this->pawnsReverse_.find(pawn); 76 if(pawn_id_iter == this->pawnsReverse_.end()) 77 { 78 orxout(internal_warning) << "Unregistered pawn reported that it's destroyed" << std::endl; 79 return; 80 } 81 82 for(auto &api : this->apis_) 83 api->pawnKilled(pawn_id_iter->second); 84 85 this->pawns_.erase(pawn_id_iter->second); 86 this->pawnsReverse_.erase(pawn_id_iter); 87 } 88 89 void ScriptableController::pawnHit(Pawn *target, Pawn *source, double new_health, double new_shield) 90 { 91 auto target_id_iter = this->pawnsReverse_.find(target); 92 auto source_id_iter = this->pawnsReverse_.find(source); 93 94 if(target_id_iter == this->pawnsReverse_.end() || 95 source_id_iter == this->pawnsReverse_.end() ) 96 { 97 orxout(internal_warning) << "Unregistered pawn reported that it's hit" << std::endl; 98 return; 99 } 100 101 for(auto &api : this->apis_) 102 api->pawnHit(target_id_iter->second, source_id_iter->second, new_health, new_shield); 103 } 104 105 void ScriptableController::killPawn(std::string id) 106 { 107 auto pawn = this->pawns_.find(id); 108 if(pawn == this->pawns_.end()) 109 { 110 orxout(user_warning) << "Tried to destroy unknown pawn " << id << std::endl; 111 return; 112 } 113 114 pawn->second->kill(); 68 115 } 69 116 … … 77 124 } 78 125 79 ControllableEntity *ScriptableController::getControllableEntityByID(std::string id) const126 Pawn *ScriptableController::getPawnByID(std::string id) const 80 127 { 81 if(id == "player" || id == "Player" || id == "PLAYER") 82 return this->player_->getControllableEntity(); 83 84 auto entity = this->controllabelEntities_.find(id); 85 return entity != this->controllabelEntities_.end() ? entity->second : nullptr; 128 auto pawn = this->pawns_.find(id); 129 return pawn != this->pawns_.end() ? pawn->second : nullptr; 86 130 } 87 131 -
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.h
r11583 r11606 18 18 { 19 19 20 /** 21 * @brief Runs a scripts on a per-level basis and handles the connection to orxonox 22 * 23 * The script is an attribute of the <Level> element with the name 'script' and should be 24 * the path to a lua script. The script will be run as soon as the player spawns. It can 25 * then register on various events and react to them. See ScriptableControllerAPI for 26 * the complete API. 27 * 28 * \sa ScriptableControllerAPI 29 */ 20 30 class ScriptableController 21 31 { 22 32 public: 33 /** 34 * @brief Run a lua script 35 * @param file_path Path to the script 36 * @return A lua error code (0 for success) 37 * 38 * Constructs an API for the script and runs it. 39 */ 23 40 int runScript(const std::string &file_path); 24 41 42 /** 43 * @brief Set the player object of the current game 44 * @param player The player 45 * 46 * The player is a special object and can perfom special actions. 47 */ 25 48 void setPlayer(PlayerInfo *player); 49 50 /** 51 * @brief Register a WorldEntity to the ScriptableController 52 * @param id The ID of the WorldEntity 53 * @param entity The WorldEntity 54 * 55 * The ScriptableController needs a list of all WorldEntity's so it can 56 * convert an ID to a WorldEntity. 57 */ 26 58 void registerWorldEntity(std::string id, WorldEntity *entity); 27 void registerControllableEntity(std::string id, ControllableEntity *entity);28 59 60 /** 61 * @brief Register a Pawn to the ScriptableController 62 * @param id The ID of the Pawn 63 * @param pawn The Pawn 64 * 65 * The ScriptableController needs a list of all Pawn's in addition to 66 * the WorldEntity's, because they have additional actions available. 67 */ 68 void registerPawn(std::string id, Pawn *pawn); 69 70 /** 71 * @brief Called when a Pawn is killed 72 * @param pawn The Pawn 73 * 74 * Called by the Pawn itself as soon as it's killed. 75 */ 76 void pawnKilled(Pawn *pawn); 77 78 /** 79 * @brief Called when a Pawn is hit 80 * @param target The hit Pawn 81 * @param source The shooting Pawn 82 * @param new_health The new health of the hit Pawn 83 * @param new_shield The new shield health of the hit Pawn 84 * 85 * Called by the Pawn itself as soon as it's hit. 86 */ 87 void pawnHit(Pawn *target, Pawn *source, double new_health, double new_shield); 88 89 /** 90 * @brief Kill a Pawn 91 * @param id The Pawn to kill 92 */ 93 void killPawn(std::string id); 94 95 /** 96 * @brief Convert an ID to a WorldEntity pointer 97 * @param id The ID of the WorldEntity 98 * @return A pointer to the WorldEntity, nullptr if it's not found 99 */ 29 100 WorldEntity *getWorldEntityByID(std::string id) const; 30 ControllableEntity *getControllableEntityByID(std::string id) const; 101 102 /** 103 * @brief Convert an ID to a Pawt pointer 104 * @param id The ID of the Pawn 105 * @return A pointer to the Pawn, nullptr if it's not found 106 */ 107 Pawn *getPawnByID(std::string id) const; 31 108 32 109 private: … … 34 111 PlayerInfo *player_; 35 112 std::map<std::string, WorldEntity*> worldEntities_; 113 std::map<std::string, Pawn*> pawns_; 114 std::map<Pawn*, std::string> pawnsReverse_; 36 115 std::map<std::string, ControllableEntity*> controllabelEntities_; 37 116 117 /** 118 * @brief Prints a human readable error message if a lua error occurs 119 * @param lua The lua state where the error occured 120 */ 38 121 void printLuaError(lua_State *lua); 39 122 }; -
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc
r11583 r11606 8 8 { 9 9 10 const double ScriptableControllerAPI::periodic_interval = 0.5; 11 10 12 ScriptableControllerAPI::ScriptableControllerAPI(lua_State *lua, ScriptableController *controller) 11 13 { … … 15 17 // Haven't found a shorter way yet to write that... 16 18 LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::orxPrint)>::registerFunction<&ScriptableControllerAPI::orxPrint>(this, lua, "orxPrint"); 19 17 20 LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAfterTimeout)>::registerFunction<&ScriptableControllerAPI::registerAfterTimeout>(this, lua, "registerAfterTimeout"); 18 21 LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtNearObject)>::registerFunction<&ScriptableControllerAPI::registerAtNearObject>(this, lua, "registerAtNearObject"); … … 20 23 LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtAreaEnter)>::registerFunction<&ScriptableControllerAPI::registerAtAreaEnter>(this, lua, "registerAtAreaEnter"); 21 24 LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtAreaLeave)>::registerFunction<&ScriptableControllerAPI::registerAtAreaLeave>(this, lua, "registerAtAreaLeave"); 22 // LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtObjectDestroyed)>::registerFunction<&ScriptableControllerAPI::registerAtObjectDestroyed>(this, lua, "registerAtObjectDestroyed");23 // LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtPickup)>::registerFunction<&ScriptableControllerAPI::registerAtPickup>(this, lua, "registerAtPickup");25 LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtPawnKilled)>::registerFunction<&ScriptableControllerAPI::registerAtPawnKilled>(this, lua, "registerAtPawnKilled"); 26 LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtPawnHit)>::registerFunction<&ScriptableControllerAPI::registerAtPawnHit>(this, lua, "registerAtPawnHit"); 24 27 25 // Checks for area enter, area leave and near object events 26 this->areaCheckTimer.setTimer(0.5, true, createExecutor(createFunctor(&ScriptableControllerAPI::checkAreas, this)), false); 28 LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::killPawn)>::registerFunction<&ScriptableControllerAPI::killPawn>(this, lua, "killPawn"); 29 30 this->periodicTimer.setTimer(ScriptableControllerAPI::periodic_interval, true, createExecutor(createFunctor(&ScriptableControllerAPI::periodic, this)), false); 27 31 } 28 32 … … 76 80 } 77 81 78 void ScriptableControllerAPI::checkAreas() 82 void ScriptableControllerAPI::registerAtPawnKilled(std::function<void (std::string)> callback, std::string id) 83 { 84 this->pawnDestroyedHandlers_[id].push_back(callback); 85 } 86 87 void ScriptableControllerAPI::registerAtPawnHit(std::function<void (std::string, std::string, double, double)> callback, std::string id) 88 { 89 this->pawnHitHandlers_[id].push_back(callback); 90 } 91 92 void ScriptableControllerAPI::killPawn(std::string id) 93 { 94 // We don't kill the pawn here directly, because this function is called from LUA and thus 95 // runs in a different thread. So we schedule the kill for later in the main thread 96 // (in 'periodic'). 97 this->pawnsToKill_.push_back(id); 98 } 99 100 void ScriptableControllerAPI::pawnKilled(std::string id) 101 { 102 for(auto callback : this->pawnDestroyedHandlers_[id]) 103 callback(id); 104 105 this->pawnDestroyedHandlers_.erase(id); 106 } 107 108 void ScriptableControllerAPI::pawnHit(std::string target_id, std::string source_id, double new_health, double new_shield) 109 { 110 for(auto callback : this->pawnHitHandlers_[target_id]) 111 callback(target_id, source_id, new_health, new_shield); 112 } 113 114 void ScriptableControllerAPI::periodic() 79 115 { 80 116 // Near object … … 138 174 } 139 175 } 176 177 // Pawns to kill 178 for(auto &pawn : this->pawnsToKill_) 179 this->controller_->killPawn(pawn); 180 181 this->pawnsToKill_.clear(); 140 182 } 141 183 -
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.h
r11583 r11606 15 15 class WorldEntity; 16 16 17 /** 18 * @brief API for ScriptableController's lua-scripts 19 * 20 * Defines the interface that lua can use in the scripts to communicate with orxonox. 21 * 22 * \sa ScriptableController 23 */ 17 24 class ScriptableControllerAPI 18 25 { 19 26 public: 27 /** 28 * @brief Constructs the API with the given lua state 29 * @param lua The lua state 30 * @param controller The parent controller 31 * 32 * This will not run any scripts, it'll just make the API visible to lua. 33 */ 20 34 ScriptableControllerAPI(lua_State *lua, ScriptableController *controller); 35 36 /** 37 * @brief Destructs the API and closes the lua state. 38 */ 21 39 ~ScriptableControllerAPI(); 22 40 23 void testOutput(std::function<void(std::string)> callback); 24 41 // --- API ---------------------------------- 42 43 /** 44 * @brief Print a message 45 * @param msg The message 46 * 47 * Use this function instead of printing from lua directly, because that will mess up the 48 * output as it is not synchronized. 49 */ 25 50 void orxPrint(std::string msg); 51 52 /** 53 * @brief Register a function that will be called after a timeout 54 * @param callback The function to call after the timeout expired 55 * @param timeout The timeout in seconds 56 */ 26 57 void registerAfterTimeout(std::function<void (void)> callback, double timeout); 27 58 59 /** 60 * @brief Register a function that will be called when two object are close to eachother 61 * @param callback The function to call when the objects are close enough 62 * @param id1 The first object 63 * @param id2 The second object 64 * @param distance If the distance between the two objects is smaller than this value, 65 * the function is called 66 * 67 * Note: Distances are only checked every 0.5s! 68 */ 28 69 void registerAtNearObject(std::function<void(std::string, std::string)> callback, std::string id1, std::string id2, double distance); 70 71 /** 72 * @brief Register a function that will be called when an object is close to a certain point 73 * @param callback The function to call when the object is close enough 74 * @param id The object 75 * @param x X-coordinate of the point 76 * @param y Y-coordinate of the point 77 * @param z Z-coordinate of the point 78 * @param distance If the distance between the object and the point is smaller than this value, the 79 * function is called. 80 * 81 * Note: Distances are only checked every 0.5s! 82 */ 29 83 void registerAtNearPoint(std::function<void (std::string)> callback, std::string id, double x, double y, double z, double distance); 30 void registerAtAreaEnter(std::function<void (std::string)> callback, std::string obj, int x, int y, int z, int dx, int dy, int dz); 31 void registerAtAreaLeave(std::function<void (std::string)> callback, std::string obj, int x, int y, int z, int dx, int dy, int dz); 32 33 void registerAtObjectDestroyed(std::function<void (std::string)> callback, std::string obj); 34 void registerAtPickup(std::function<void (int)> callback, int pickup_id); 35 36 void destroyObject(std::string obj); 37 void removeObject(std::string obj); 38 void setObjectPosition(std::string obj, double x, double y, double z); 84 85 /** 86 * @brief Register a function that will be called when an object enters a cubic area 87 * @param callback The function to call when the object entered the area 88 * @param id The object 89 * @param x X-coordinate of the top-left corner 90 * @param y Y-coordinate of the top-left corner 91 * @param z Z-coordinate of the top-left corner 92 * @param dx Size in X-direction of the cube 93 * @param dy Size in Y-direction of the cube 94 * @param dz Size in Z-direction of the cube 95 * 96 * Note: Distances are only checked every 0.5s! 97 */ 98 void registerAtAreaEnter(std::function<void (std::string)> callback, std::string id, int x, int y, int z, int dx, int dy, int dz); 99 100 /** 101 * @brief Register a function that will be called when an object leaves a cubic area 102 * @param callback The function to call when the object left the area 103 * @param id The object 104 * @param x X-coordinate of the top-left corner 105 * @param y Y-coordinate of the top-left corner 106 * @param z Z-coordinate of the top-left corner 107 * @param dx Size in X-direction of the cube 108 * @param dy Size in Y-direction of the cube 109 * @param dz Size in Z-direction of the cube 110 * 111 * Note: Distances are only checked every 0.5s! 112 */ 113 void registerAtAreaLeave(std::function<void (std::string)> callback, std::string id, int x, int y, int z, int dx, int dy, int dz); 114 115 /** 116 * @brief Register a function that will be called when a Pawn is killed 117 * @param callback The function to call as soon as the Pawn is dead 118 * @param id The Pawn 119 * 120 * Note: Once a Pawn is dead, the callback is removed, even if the pawn got magically revived. 121 */ 122 void registerAtPawnKilled(std::function<void (std::string)> callback, std::string id); 123 124 /** 125 * @brief Register a function that will be called when a Pawn is hit 126 * @param callback The function to call as soon as the Pawn is hit 127 * @param id The Pawn 128 * 129 * Note: Once a Pawn is dead, the all hit-callbacks are removed, even if the pawn got magically revived. 130 */ 131 void registerAtPawnHit(std::function<void (std::string, std::string, double, double)> callback, std::string id); 132 133 /** 134 * @brief Kill a pawn 135 * @param id The pawn to kill 136 * 137 * Note: It might up to 0.5s until the pawn is actually killed. 138 */ 139 void killPawn(std::string id); 140 141 // ------------------------------------------ 142 143 /** 144 * @brief Called by ScriptableController when a pawn is killed 145 * @param id The dead pawn 146 * 147 * Calls the lua callbacks associated with this event. 148 */ 149 void pawnKilled(std::string id); 150 151 /** 152 * @brief Called by ScriptableController when a Pawn is hit 153 * @param target_id The hit Pawn 154 * @param source_id The shooting Pawn 155 * @param new_health The new health of the hit Pawn 156 * @param new_shield The new shield health of the hit Pawn 157 */ 158 void pawnHit(std::string target_id, std::string source_id, double new_health, double new_shield); 39 159 40 160 private: 161 /** 162 * @brief Groups everything together that is needed to handle a near-object event 163 */ 41 164 struct NearObjectHandler 42 165 { … … 51 174 }; 52 175 176 /** 177 * @brief Groups everything together that is needed to handle a near-poinb event 178 */ 53 179 struct NearPointHandler 54 180 { … … 64 190 }; 65 191 192 /** 193 * @brief Groups everything together that is needed to handle an area enter/leave event 194 */ 66 195 struct AreaHandler 67 196 { … … 83 212 std::list<NearPointHandler> nearPointHandlers_; 84 213 std::list<AreaHandler> areaHandlers_; 85 Timer areaCheckTimer; 86 87 void checkAreas(void); 214 std::list<std::string> pawnsToKill_; 215 std::map<std::string, std::list<std::function<void (std::string)> > > pawnDestroyedHandlers_; 216 std::map<std::string, std::list<std::function<void (std::string, std::string, double, double)> > > pawnHitHandlers_; 217 Timer periodicTimer; 218 static const double periodic_interval; 219 220 /** 221 * @brief Called every 0.5s 222 * 223 * This handles things that have to be checked periodically (like area events) and 224 * things that are done by lua that have to synchronize with the main thread (like 225 * killing a pawn). Doing this in every tick would be an overkill. 226 */ 227 void periodic(void); 88 228 }; 89 229
Note: See TracChangeset
for help on using the changeset viewer.