diff options
author | Steph Enders <smenders@gmail.com> | 2022-06-17 11:19:51 -0400 |
---|---|---|
committer | Steph Enders <smenders@gmail.com> | 2022-06-17 11:19:51 -0400 |
commit | 87a53f2a09a204ca9bcdde9c73db414c79075326 (patch) | |
tree | 5dbb78e554d01a8f9dd1e3cdf11d4077f0d15676 /src | |
parent | 49bb775d4cf9935b0f0d54daa358423ac786c9be (diff) |
Add scene controls and win/loss scenarios
Setup ability to check collisions and transition game scene
Diffstat (limited to 'src')
-rw-r--r-- | src/CApi.h (renamed from src/Api.h) | 115 | ||||
-rw-r--r-- | src/LuaApi.h | 89 | ||||
-rw-r--r-- | src/Scene.h | 5 | ||||
-rw-r--r-- | src/main.cpp | 80 |
4 files changed, 231 insertions, 58 deletions
@@ -1,12 +1,17 @@ -#ifndef DNG_API_H -#define DNG_API_H +#ifndef DNG_CAPI_H +#define DNG_CAPI_H #include "Level.h" +#include "Scene.h" #include <lua.hpp> #include <memory> extern std::shared_ptr<Level> lvl; +extern Scene scene; +/* + * c_get_player_position(int x, int y) + */ static int c_get_player_position(lua_State *L) { lua_createtable(L, 0, 2); lua_pushnumber(L, lvl->player.y + 1); @@ -17,24 +22,31 @@ static int c_get_player_position(lua_State *L) { return 1; } +/* + * c_move_player(int dx, int dy) + */ 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->playerCanStep(dx, dy)) { lvl->player.x += dx; lvl->player.y += dy; - res = true; } - lua_pushboolean(L, res); + 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; } +/* + * c_move_enemy(int id, int dx, int dy) + */ static int c_move_enemy(lua_State *L) { // stack ordering int dy = static_cast<int>(lua_tonumber(L, -1)); @@ -44,22 +56,27 @@ static int c_move_enemy(lua_State *L) { 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; } - - lua_pushboolean(L, res); + lua_createtable(L, 0, 3); + lua_pushnumber(L, lvl->enemyPositions[i].y + 1); + lua_setfield(L, -2, "y"); + lua_pushnumber(L, lvl->enemyPositions[i].x + 1); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, lvl->enemyPositions[i].id); + lua_setfield(L, -2, "id"); return 1; } +/* + * c_get_enemies() + */ static int c_get_enemies(lua_State *L) { lua_createtable(L, int(lvl->enemyPositions.size()), 0); @@ -80,10 +97,19 @@ static int c_get_enemies(lua_State *L) { return 1; } +/* + * c_spawn_enemy(int x, int y) + */ static int c_spawn_enemy(lua_State *L) { return 1; } +/* + * c_destroy_enemy(int id) + */ static int c_destroy_enemy(lua_State *L) { return 1; } +/* + * c_get_map() + */ static int c_get_map(lua_State *L) { lua_createtable(L, int(lvl->map.size()), 0); int idx = 0; @@ -101,7 +127,64 @@ static int c_get_map(lua_State *L) { return 1; } -static void init_c_api(lua_State *L) { +/* + * c_trigger_level_start() + */ +static int c_trigger_level_start(lua_State *L) { + scene = Scene::LEVEL; + lua_pushboolean(L, true); + return 1; +} +/* + * c_trigger_win() + */ +static int c_trigger_win(lua_State *L) { + scene = Scene::WIN; + lua_pushboolean(L, true); + return 1; +} + +/* + * c_trigger_loss() + */ +static int c_trigger_loss(lua_State *L) { + scene = Scene::LOSS; + lua_pushboolean(L, true); + return 1; +} + +static int c_get_scene(lua_State *L) { + lua_pushnumber(L, scene); + return 1; +} + +static int c_get_treasures(lua_State *L) { + lua_createtable(L, static_cast<int>(lvl->treasurePositions.size()), 0); + int idx = 0; + for (auto &t : lvl->treasurePositions) { + lua_pushnumber(L, ++idx); + lua_createtable(L, 0, 3); + lua_pushnumber(L, t.y + 1); + lua_setfield(L, -2, "y"); + lua_pushnumber(L, t.x + 1); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, t.id); + lua_setfield(L, -2, "id"); + lua_settable(L, -3); + } + return 1; +} + +static int c_score_treasure(lua_State *L) { + int id = static_cast<int>(lua_tonumber(L, -1)); + + erase_if(lvl->treasurePositions, [id](Pos t) { return t.id == id; }); + + return 1; +} + +// not for lua use +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); @@ -109,6 +192,12 @@ static void init_c_api(lua_State *L) { 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); + lua_register(L, "c_trigger_level_start", c_trigger_level_start); + lua_register(L, "c_trigger_win", c_trigger_win); + lua_register(L, "c_trigger_loss", c_trigger_loss); + lua_register(L, "c_get_scene", c_get_scene); + lua_register(L, "c_score_treasure", c_score_treasure); + lua_register(L, "c_get_treasures", c_get_treasures); } -#endif // DNG_API_H
\ No newline at end of file +#endif // DNG_CAPI_H
\ No newline at end of file diff --git a/src/LuaApi.h b/src/LuaApi.h new file mode 100644 index 0000000..cb68e36 --- /dev/null +++ b/src/LuaApi.h @@ -0,0 +1,89 @@ +#ifndef DNG_LUA_API_H +#define DNG_LUA_API_H + +#include <iostream> +#include <lua.hpp> + +struct LState { + lua_State *onkeypress; + lua_State *onupdate; + lua_State *onintro; + lua_State *onwin; + lua_State *onloss; +} typedef LState; + +const char *ON_KEYPRESS = "onKeypress"; +const char *ON_UPDATE = "onUpdate"; +const char *ON_INTRO = "onIntro"; +const char *ON_WIN = "onWin"; +const char *ON_LOSS = "onLoss"; + +LState *init_default(lua_State *L) { + auto *state = static_cast<LState *>(malloc(sizeof(LState))); + + state->onkeypress = L; + state->onupdate = L; + state->onintro = L; + state->onwin = L; + state->onloss = L; + + return state; +} + +bool check_fn(lua_State *L, const char *fn) { + lua_getglobal(L, fn); + return lua_isfunction(L, -1); +} + +void override_file_fns(lua_State *L, LState *state) { + if (check_fn(L, ON_KEYPRESS)) { + state->onkeypress = L; + } + if (check_fn(L, ON_UPDATE)) { + state->onupdate = L; + } + if (check_fn(L, ON_INTRO)) { + state->onintro = L; + } + if (check_fn(L, ON_WIN)) { + state->onwin = L; + } + if (check_fn(L, ON_LOSS)) { + state->onloss = L; + } +} + +bool lua_dofn(lua_State *L, const char *fn) { + lua_getglobal(L, fn); + if (!lua_isfunction(L, -1)) { + std::cout << "[C] Error " << fn << " not function | not found" << std::endl; + return false; + } + lua_pcall(L, 0, 1, 0); + return true; +} + +bool lua_dofn_with_key(lua_State *L, const char *fn, char pressedKey) { + lua_getglobal(L, fn); + if (!lua_isfunction(L, -1)) { + std::cout << "[C] Error " << fn << " not function | not found" << std::endl; + return false; + } + lua_pushinteger(L, pressedKey); + lua_pcall(L, 1, 1, 0); + return true; +} + +bool lua_onkeypress(lua_State *L, char pressedKey) { + return lua_dofn_with_key(L, "onKeyPress", pressedKey); +} + +bool lua_onupdate(lua_State *L) { return lua_dofn(L, "onUpdate"); } + +bool lua_onintro(lua_State *L) { return lua_dofn(L, "onIntro"); } + +bool lua_onwin(lua_State *L) { return lua_dofn(L, "onWin"); } + +bool lua_onloss(lua_State *L) { return lua_dofn(L, "onLoss"); } + +#endif // DNG_LUA_API_H
\ No newline at end of file diff --git a/src/Scene.h b/src/Scene.h new file mode 100644 index 0000000..dab51c5 --- /dev/null +++ b/src/Scene.h @@ -0,0 +1,5 @@ +#ifndef DNG_SCENE_H +#define DNG_SCENE_H +/* sync with constants.lua */ +enum Scene { INTRO, LEVEL, WIN, LOSS }; +#endif // DNG_SCENE_H diff --git a/src/main.cpp b/src/main.cpp index eef9777..a9b5d3b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,20 +1,16 @@ -#include "Api.h" +#include "CApi.h" #include "Level.h" +#include "LuaApi.h" #include <SFML/Graphics.hpp> #include <filesystem> #include <iostream> #include <lua.hpp> const char *DEFAULT_PROC = "include/defaults.lua"; -std::shared_ptr<Level> lvl; -struct LState { - lua_State *onkeypress; - lua_State *onupdate; -} typedef LState; +std::shared_ptr<Level> lvl; -bool call_onkeypress(lua_State *L, char pressedKey); -bool call_onupdate(lua_State *L); +Scene scene; int main(int argc, char **argv) { @@ -28,6 +24,7 @@ int main(int argc, char **argv) { std::filesystem::path luaFile{lvl_pfx + "/proc.lua"}; lvl = std::make_shared<Level>(); + scene = Scene::INTRO; lvl->loadLevelFromFile(mapFile.c_str()); @@ -47,20 +44,11 @@ int main(int argc, char **argv) { } // Initialize to default - LState l_state = {.onkeypress = L_default, .onupdate = L_default}; + LState *l_state = init_default(L_default); if (std::filesystem::exists(luaFile) && 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; - } + override_file_fns(L_lvl, l_state); } 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)); @@ -72,12 +60,35 @@ int main(int argc, char **argv) { char in; do { - lvl->print(); - std::cin >> in; - if (!call_onkeypress(l_state.onkeypress, in)) { + if (scene == Scene::INTRO) { + if (!lua_onintro(l_state->onintro)) { + quit = true; + } + std::cin >> in; + if (!lua_onkeypress(l_state->onkeypress, in)) { + quit = true; + } + } else if (scene == Scene::LEVEL) { + lvl->print(); + + std::cin >> in; + if (!lua_onkeypress(l_state->onkeypress, in)) { + quit = true; + } + if (!lua_onupdate(l_state->onupdate)) { + quit = true; + } + } else if (scene == Scene::WIN) { + lvl->player.x = -1; // hide + lvl->player.y = -1; // hide + lvl->print(); + lua_onwin(l_state->onwin); quit = true; - } - if (!call_onupdate(l_state.onupdate)) { + } else if (scene == Scene::LOSS) { + lvl->player.x = -1; // hide + lvl->player.y = -1; // hide + lvl->print(); + lua_onloss(l_state->onloss); quit = true; } if (!quit && in == 'q') { @@ -89,24 +100,3 @@ int main(int argc, char **argv) { return EXIT_SUCCESS; } - -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; - return false; - } - 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 |