diff options
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 |