diff options
| author | Steph Enders <smenders@gmail.com> | 2022-06-16 16:14:18 -0400 | 
|---|---|---|
| committer | Steph Enders <smenders@gmail.com> | 2022-06-16 16:16:34 -0400 | 
| commit | c57ae8c42c1f2f2ed576719c00cff5cf613fe650 (patch) | |
| tree | 0e0c6533b099edbe2c283a8961b1b240d29ad904 /src | |
| parent | 750b308d70cf1c903812316deeb0a8c4befa37ce (diff) | |
Added onUpdate logic to move the enemies etc
Created some algorithm logic for enemy movement
Allowed for default overrides
Diffstat (limited to 'src')
| -rw-r--r-- | src/Api.h | 93 | ||||
| -rw-r--r-- | src/Level.cpp | 55 | ||||
| -rw-r--r-- | src/Level.h | 16 | ||||
| -rw-r--r-- | src/main.cpp | 58 | 
4 files changed, 148 insertions, 74 deletions
| @@ -7,16 +7,24 @@  extern std::shared_ptr<Level> lvl; -static int -c_update_player_pos(lua_State* L) -{ +static int c_get_player_position(lua_State *L) { +  lua_createtable(L, 0, 2); +  lua_pushnumber(L, lvl->player.y + 1); +  lua_setfield(L, -2, "y"); +  lua_pushnumber(L, lvl->player.x + 1); +  lua_setfield(L, -2, "x"); + +  return 1; +} + +static int c_move_player(lua_State *L) {    // stack ordering    int dy = static_cast<int>(lua_tonumber(L, -1));    int dx = static_cast<int>(lua_tonumber(L, -2));    bool res = false; -  if (lvl->canStep(dx, dy)) { +  if (lvl->playerCanStep(dx, dy)) {      lvl->player.x += dx;      lvl->player.y += dy;      res = true; @@ -27,45 +35,80 @@ c_update_player_pos(lua_State* L)    return 1;  } -static int -c_player_can_move(lua_State* L) -{ +static int c_move_enemy(lua_State *L) {    // stack ordering    int dy = static_cast<int>(lua_tonumber(L, -1));    int dx = static_cast<int>(lua_tonumber(L, -2)); +  int id = static_cast<int>(lua_tonumber(L, -3)); + +  int i = lvl->getEnemyIndex(id); +  // guard against enemy not found +  if (i == -1) { +    lua_pushboolean(L, false); +    return 1; +  } + +  bool res = false; +  if (lvl->enemyCanStep(lvl->enemyPositions[i], dx, dy)) { +    lvl->enemyPositions[i].x += dx; +    lvl->enemyPositions[i].y += dy; +    res = true; +  } -  bool res = lvl->canStep(dx, dy);    lua_pushboolean(L, res);    return 1;  } -static int -c_enemy_can_move(lua_State* L) -{ -  return 1; -} +static int c_get_enemies(lua_State *L) { +  lua_createtable(L, int(lvl->enemyPositions.size()), 0); + +  int idx = 0; + +  for (auto &pos : lvl->enemyPositions) { +    lua_pushnumber(L, ++idx); +    lua_createtable(L, 0, 3); +    lua_pushnumber(L, pos.id); +    lua_setfield(L, -2, "id"); +    lua_pushnumber(L, pos.x + 1); +    lua_setfield(L, -2, "x"); +    lua_pushnumber(L, pos.y + 1); +    lua_setfield(L, -2, "y"); +    lua_settable(L, -3); +  } -static int -c_spawn_enemy(lua_State* L) -{    return 1;  } -static int -c_destroy_enemy(lua_State* L) -{ +static int c_spawn_enemy(lua_State *L) { return 1; } + +static int c_destroy_enemy(lua_State *L) { return 1; } + +static int c_get_map(lua_State *L) { +  lua_createtable(L, int(lvl->map.size()), 0); +  int idx = 0; +  for (auto &vec : lvl->map) { +    lua_pushnumber(L, ++idx); +    lua_createtable(L, int(vec.size()), 0); +    int inner_idx = 0; +    for (auto &c : vec) { +      lua_pushnumber(L, ++inner_idx); +      lua_pushnumber(L, c == WALL_SPACE ? 1 : 0); +      lua_rawset(L, -3); +    } +    lua_rawset(L, -3); +  }    return 1;  } -static void -init_c_api(lua_State* L) -{ -  lua_register(L, "c_update_player_pos", c_update_player_pos); -  lua_register(L, "c_player_can_move", c_player_can_move); -  lua_register(L, "c_enemy_can_move", c_enemy_can_move); +static void init_c_api(lua_State *L) { +  lua_register(L, "c_move_player", c_move_player); +  lua_register(L, "c_move_enemy", c_move_enemy);    lua_register(L, "c_spawn_enemy", c_spawn_enemy);    lua_register(L, "c_destroy_enemy", c_destroy_enemy); +  lua_register(L, "c_get_enemies", c_get_enemies); +  lua_register(L, "c_get_player_position", c_get_player_position); +  lua_register(L, "c_get_map", c_get_map);  }  #endif // DNG_API_H
\ No newline at end of file diff --git a/src/Level.cpp b/src/Level.cpp index 013c2a1..5f06def 100644 --- a/src/Level.cpp +++ b/src/Level.cpp @@ -3,9 +3,11 @@  #include <iostream>  #include <string> -void -Level::loadLevelFromFile(const char* filePath) -{ +bool canStep(Pos pos, int dx, int dy, std::vector<std::vector<char>> map) { +  return map[pos.y + dy][pos.x + dx] != WALL_SPACE; +} + +void Level::loadLevelFromFile(const char *filePath) {    std::ifstream mapFile(filePath);    if (mapFile.is_open()) { @@ -15,7 +17,6 @@ Level::loadLevelFromFile(const char* filePath)      // from 1 -> N each enemy and treasure has its  own unique ID      // IDs are unique entirely, not just per enemy or treasure -      std::string line;      int y = 0;      while (std::getline(mapFile, line)) { @@ -28,14 +29,14 @@ Level::loadLevelFromFile(const char* filePath)            this->map[y].push_back(BLANK_SPACE);          } else if (c == ENEMY_TKN) {            this->enemyPositions.push_back( -            { .id = this->nextId(), .x = x, .y = y }); +              {.id = this->nextId(), .x = x, .y = y});            this->map[y].push_back(BLANK_SPACE);          } else if (c == PLAYER_TKN) { -          this->player = { .id = playerId, .x = x, .y = y }; +          this->player = {.id = playerId, .x = x, .y = y};            this->map[y].push_back(BLANK_SPACE);          } else if (c == TREASURE_TKN) {            this->treasurePositions.push_back( -            { .id = this->nextId(), .x = x, .y = y }); +              {.id = this->nextId(), .x = x, .y = y});            this->map[y].push_back(BLANK_SPACE);          } else {            continue; @@ -48,26 +49,17 @@ Level::loadLevelFromFile(const char* filePath)    mapFile.close();  } -bool -Level::isEmpty(int x, int y) -{ -  return map[y][x] == BLANK_SPACE; -} +bool Level::isEmpty(int x, int y) { return map[y][x] == BLANK_SPACE; } -bool -Level::canStep(int dx, int dy) -{ -  bool res = map[player.y + dy][player.x + dx] != WALL_SPACE; -  return res; +bool Level::playerCanStep(int dx, int dy) { +  return canStep(player, dx, dy, map);  } -void -Level::print() -{ +void Level::print() {    int x = 0;    int y = 0; -  for (auto& row : map) { -    for (auto& tile : row) { +  for (auto &row : map) { +    for (auto &tile : row) {        bool printed = false;        if (player.x == x && player.y == y) {          std::cout << "p"; @@ -101,8 +93,17 @@ Level::print()    }  } -int -Level::nextId() -{ -  return idCounter++; -}
\ No newline at end of file +int Level::nextId() { return idCounter++; } + +int Level::getEnemyIndex(int id) { +  for (int i = 0; i < enemyPositions.size(); i++) { +    if (enemyPositions[i].id == id) { +      return i; +    } +  } + +  return -1; +} +bool Level::enemyCanStep(Pos pos, int dx, int dy) { +  return canStep(pos, dx, dy, map); +} diff --git a/src/Level.h b/src/Level.h index 1607f0c..7791ab6 100644 --- a/src/Level.h +++ b/src/Level.h @@ -12,30 +12,32 @@ static const char WALL_SPACE = '#';  #include <memory>  #include <vector> -struct Pos -{ +struct Pos {    int id;    int x;    int y;  } typedef Coord; -class Level -{ +class Level {  public: -  void loadLevelFromFile(const char* filePath); +  void loadLevelFromFile(const char *filePath);    bool isEmpty(int x, int y); -  bool canStep(int dx, int dy); +  bool playerCanStep(int dx, int dy); + +  int getEnemyIndex(int id); + +  bool enemyCanStep(Pos pos, int dx, int dy);    void print();    int nextId(); -    std::vector<std::vector<char>> map;    Pos player;    std::vector<Pos> enemyPositions; +    std::vector<Pos> treasurePositions;  private: diff --git a/src/main.cpp b/src/main.cpp index 6f649cd..eef9777 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,15 +5,18 @@  #include <iostream>  #include <lua.hpp> -const char* DEFAULT_PROC = "include/default_proc.lua"; +const char *DEFAULT_PROC = "include/defaults.lua";  std::shared_ptr<Level> lvl; -bool -call_onkeypress(lua_State* L, char pressedKey); +struct LState { +  lua_State *onkeypress; +  lua_State *onupdate; +} typedef LState; -int -main(int argc, char** argv) -{ +bool call_onkeypress(lua_State *L, char pressedKey); +bool call_onupdate(lua_State *L); + +int main(int argc, char **argv) {    if (argc <= 1) {      return -1; @@ -21,18 +24,18 @@ main(int argc, char** argv)    std::string lvl_pfx = argv[1]; -  std::filesystem::path mapFile{ lvl_pfx + "/dng.map" }; -  std::filesystem::path luaFile{ lvl_pfx + "/proc.lua" }; +  std::filesystem::path mapFile{lvl_pfx + "/dng.map"}; +  std::filesystem::path luaFile{lvl_pfx + "/proc.lua"};    lvl = std::make_shared<Level>();    lvl->loadLevelFromFile(mapFile.c_str()); -  lua_State* L_lvl = luaL_newstate(); +  lua_State *L_lvl = luaL_newstate();    luaL_openlibs(L_lvl);    init_c_api(L_lvl); -  lua_State* L_default = luaL_newstate(); +  lua_State *L_default = luaL_newstate();    luaL_openlibs(L_default);    init_c_api(L_default); @@ -43,8 +46,22 @@ main(int argc, char** argv)      return EXIT_FAILURE;    } +  // Initialize to default +  LState l_state = {.onkeypress = L_default, .onupdate = L_default}; +    if (std::filesystem::exists(luaFile) && -      luaL_dofile(L_lvl, luaFile.c_str()) != LUA_OK) { +      luaL_dofile(L_lvl, luaFile.c_str()) == LUA_OK) { + +    // overwrite defaults +    lua_getglobal(L_lvl, "onKeyPress"); +    if (lua_isfunction(L_lvl, -1)) { +      l_state.onkeypress = L_lvl; +    } +    lua_getglobal(L_lvl, "onUpdate"); +    if (lua_isfunction(L_lvl, -1)) { +      l_state.onupdate = L_lvl; +    } +  } else if (std::filesystem::exists(luaFile)) {      std::cout << "[C] No Good" << std::endl;      luaL_error(L_lvl, "Error: %s\n", lua_tostring(L_lvl, -1));      return EXIT_FAILURE; @@ -57,7 +74,10 @@ main(int argc, char** argv)    do {      lvl->print();      std::cin >> in; -    if (!call_onkeypress(L_default, in)) { +    if (!call_onkeypress(l_state.onkeypress, in)) { +      quit = true; +    } +    if (!call_onupdate(l_state.onupdate)) {        quit = true;      }      if (!quit && in == 'q') { @@ -70,9 +90,7 @@ main(int argc, char** argv)    return EXIT_SUCCESS;  } -bool -call_onkeypress(lua_State* L, char pressedKey) -{ +bool call_onkeypress(lua_State *L, char pressedKey) {    lua_getglobal(L, "onKeyPress");    if (!lua_isfunction(L, -1)) {      std::cout << "[C] Error onKeyPress not function | not found" << std::endl; @@ -81,4 +99,14 @@ call_onkeypress(lua_State* L, char pressedKey)    lua_pushinteger(L, pressedKey);    lua_pcall(L, 1, 1, 0);    return true; +} + +bool call_onupdate(lua_State *L) { +  lua_getglobal(L, "onUpdate"); +  if (!lua_isfunction(L, -1)) { +    std::cout << "[C] Error onUpdate not function | not found" << std::endl; +    return false; +  } +  lua_pcall(L, 0, 1, 0); +  return true;  }
\ No newline at end of file |