Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 27, 2017, 4:38:50 PM (7 years ago)
Author:
kohlia
Message:

Pawn killing works too now

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  
    44#include "infos/PlayerInfo.h"
    55#include "core/command/Executor.h"
     6#include "worldentities/pawns/Pawn.h"
    67
    78namespace orxonox
     
    6364}
    6465
    65 void ScriptableController::registerControllableEntity(std::string id, ControllableEntity *entity)
     66void ScriptableController::registerPawn(std::string id, Pawn *pawn)
    6667{
    67     this->worldEntities_[id] = entity;
     68    this->worldEntities_[id] = pawn;
     69    this->pawns_[id] = pawn;
     70    this->pawnsReverse_[pawn] = id;
     71}
     72
     73void 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
     89void 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
     105void 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();
    68115}
    69116
     
    77124}
    78125
    79 ControllableEntity *ScriptableController::getControllableEntityByID(std::string id) const
     126Pawn *ScriptableController::getPawnByID(std::string id) const
    80127{
    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;
    86130}
    87131
  • code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.h

    r11583 r11606  
    1818{
    1919
     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 */
    2030class ScriptableController
    2131{
    2232public:
     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     */
    2340    int runScript(const std::string &file_path);
    2441
     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     */
    2548    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     */
    2658    void registerWorldEntity(std::string id, WorldEntity *entity);
    27     void registerControllableEntity(std::string id, ControllableEntity *entity);
    2859
     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     */
    29100    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;
    31108
    32109private:
     
    34111    PlayerInfo *player_;
    35112    std::map<std::string, WorldEntity*> worldEntities_;
     113    std::map<std::string, Pawn*> pawns_;
     114    std::map<Pawn*, std::string> pawnsReverse_;
    36115    std::map<std::string, ControllableEntity*> controllabelEntities_;
    37116
     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     */
    38121    void printLuaError(lua_State *lua);
    39122};
  • code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc

    r11583 r11606  
    88{
    99
     10const double ScriptableControllerAPI::periodic_interval = 0.5;
     11
    1012ScriptableControllerAPI::ScriptableControllerAPI(lua_State *lua, ScriptableController *controller)
    1113{
     
    1517    // Haven't found a shorter way yet to write that...
    1618    LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::orxPrint)>::registerFunction<&ScriptableControllerAPI::orxPrint>(this, lua, "orxPrint");
     19
    1720    LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAfterTimeout)>::registerFunction<&ScriptableControllerAPI::registerAfterTimeout>(this, lua, "registerAfterTimeout");
    1821    LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtNearObject)>::registerFunction<&ScriptableControllerAPI::registerAtNearObject>(this, lua, "registerAtNearObject");
     
    2023    LuaTB<ScriptableControllerAPI, decltype(&ScriptableControllerAPI::registerAtAreaEnter)>::registerFunction<&ScriptableControllerAPI::registerAtAreaEnter>(this, lua, "registerAtAreaEnter");
    2124    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");
    2427
    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);
    2731}
    2832
     
    7680}
    7781
    78 void ScriptableControllerAPI::checkAreas()
     82void ScriptableControllerAPI::registerAtPawnKilled(std::function<void (std::string)> callback, std::string id)
     83{
     84    this->pawnDestroyedHandlers_[id].push_back(callback);
     85}
     86
     87void 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
     92void 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
     100void ScriptableControllerAPI::pawnKilled(std::string id)
     101{
     102    for(auto callback : this->pawnDestroyedHandlers_[id])
     103        callback(id);
     104
     105    this->pawnDestroyedHandlers_.erase(id);
     106}
     107
     108void 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
     114void ScriptableControllerAPI::periodic()
    79115{
    80116    // Near object
     
    138174        }
    139175    }
     176
     177    // Pawns to kill
     178    for(auto &pawn : this->pawnsToKill_)
     179        this->controller_->killPawn(pawn);
     180
     181    this->pawnsToKill_.clear();
    140182}
    141183
  • code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.h

    r11583 r11606  
    1515class WorldEntity;
    1616
     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 */
    1724class ScriptableControllerAPI
    1825{
    1926public:
     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     */
    2034    ScriptableControllerAPI(lua_State *lua, ScriptableController *controller);
     35
     36    /**
     37     * @brief Destructs the API and closes the lua state.
     38     */
    2139    ~ScriptableControllerAPI();
    2240
    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     */
    2550    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     */
    2657    void registerAfterTimeout(std::function<void (void)> callback, double timeout);
    2758
     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     */
    2869    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     */
    2983    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);
    39159
    40160private:
     161    /**
     162     * @brief Groups everything together that is needed to handle a near-object event
     163     */
    41164    struct NearObjectHandler
    42165    {
     
    51174    };
    52175
     176    /**
     177     * @brief Groups everything together that is needed to handle a near-poinb event
     178     */
    53179    struct NearPointHandler
    54180    {
     
    64190    };
    65191
     192    /**
     193     * @brief Groups everything together that is needed to handle an area enter/leave event
     194     */
    66195    struct AreaHandler
    67196    {
     
    83212    std::list<NearPointHandler> nearPointHandlers_;
    84213    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);
    88228};
    89229
Note: See TracChangeset for help on using the changeset viewer.