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 |