diff --git a/assets/config.json b/assets/config.json index 7961f8b..4fff41e 100644 --- a/assets/config.json +++ b/assets/config.json @@ -27,6 +27,11 @@ "frame_width": 256, "frame_height": 256 }, + "open_vent": + {"path": "assets/sprites/open_vent.png", + "frame_width": 256, + "frame_height": 256 + }, "dead_body": {"path": "assets/sprites/dead_body.png", "frame_width": 256, diff --git a/assets/devices.json b/assets/devices.json index 70abeb3..e3bb67b 100644 --- a/assets/devices.json +++ b/assets/devices.json @@ -17,6 +17,24 @@ {"_type": "Sprite", "name": "ladder_down", "width": 256, "height": 256, "scale": 1.0} ] }, + "OPEN_VENT": { + "id": "OPEN_VENT", + "name": "Open Vent", + "placement": "fixed", + "description": "Your Goal.", + "inventory_count": 0, + "randomized": false, + "components": [ + {"_type": "Tile", "display": 6106, + "foreground": "devices/fg:stairs_down", + "background": "devices/bg:stairs_down" + }, + {"_type": "Device", + "config": {}, + "events": ["STAIRS_DOWN"]}, + {"_type": "Sprite", "name": "open_vent", "width": 256, "height": 256, "scale": 1.0} + ] + }, "DEAD_BODY_LOOTABLE": { "id": "DEAD_BODY_LOOTABLE", "name": "Grave Stone", diff --git a/assets/enemies.json b/assets/enemies.json index b874da5..dd3c0e0 100644 --- a/assets/enemies.json +++ b/assets/enemies.json @@ -6,7 +6,7 @@ "foreground": "enemies/fg:player", "background": "color:transparent" }, - {"_type": "Combat", "max_hp": 200, "max_ap": 12, "ap_delta": 6, "damage": 20, "dead": false, + {"_type": "Combat", "max_hp": 200, "max_ap": 12, "ap_delta": 6, "damage": 200, "body_parts": { "head": 200, "chest": 200, @@ -30,7 +30,7 @@ "foreground": "enemies/fg:rat_giant", "background": "color:transparent" }, - {"_type": "Combat", "max_hp": 50, "max_ap": 12, "ap_delta": 6,"damage": 30, "dead": false, + {"_type": "Combat", "max_hp": 50, "max_ap": 12, "ap_delta": 6,"damage": 30, "body_parts": { "head": 50, "chest": 50, diff --git a/assets/sprites/open_vent.png b/assets/sprites/open_vent.png new file mode 100644 index 0000000..830490d Binary files /dev/null and b/assets/sprites/open_vent.png differ diff --git a/src/combat/combat.cpp b/src/combat/combat.cpp index 6f93dd0..9ba9217 100644 --- a/src/combat/combat.cpp +++ b/src/combat/combat.cpp @@ -25,10 +25,7 @@ namespace components { dbc::check(hp >= 0, "HP went negative"); // don't hit dead parts - if(hp == 0) { - dbc::log("IT's zero."); - return; - } + if(hp == 0) return; // don't go below 0 body_parts[name] = std::max(0, hp - my_dmg); @@ -36,7 +33,9 @@ namespace components { } bool Combat::less_than(int level) { - return body_parts["head"] <= level || body_parts["stomach"] <= level || body_parts["chest"] <= level; + return body_parts["head"] <= level + || body_parts["stomach"] <= level + || body_parts["chest"] <= level; } bool Combat::is_dead() { diff --git a/src/game/components.hpp b/src/game/components.hpp index fcd9d95..bfc5ade 100644 --- a/src/game/components.hpp +++ b/src/game/components.hpp @@ -131,7 +131,7 @@ namespace components { int ap = 0; /* NOTE: This is used to _mark_ entities as dead, to detect ones that have just died. Don't make attack automatically set it.*/ - bool dead = false; + bool has_died = false; bool less_than(int level); int attack(Combat &target); diff --git a/src/game/systems.cpp b/src/game/systems.cpp index 5642b08..65d1c3e 100644 --- a/src/game/systems.cpp +++ b/src/game/systems.cpp @@ -195,13 +195,14 @@ void System::death() { world.query([&](auto ent, auto &combat) { // bring out yer dead - if(combat.is_dead() && !combat.dead) { - combat.dead = true; + if(!combat.has_died && combat.is_dead()) { + combat.has_died = true; if(ent != player.entity) { // we won't change out the player's components later dead_things.push_back(ent); } // we need to send this event for everything that dies + dbc::log("SENT DEATH!"); world.send(game::Event::DEATH, ent, {}); } else if(combat.almost_dead()) { // if enemies are below 50% health they are marked with bad health @@ -304,7 +305,7 @@ void System::collision() { for(auto entity : nearby) { if(world.has(entity)) { auto combat = world.get(entity); - if(!combat.dead) { + if(!combat.has_died) { combat_count++; world.send(game::Event::COMBAT_START, entity, entity); } diff --git a/src/gui/body_ui.cpp b/src/gui/body_ui.cpp index 43f6f0c..ffea011 100644 --- a/src/gui/body_ui.cpp +++ b/src/gui/body_ui.cpp @@ -29,7 +29,6 @@ namespace gui { auto gui_id = $gui.entity(name); $gui.set(gui_id, {guecs::to_wstring(name)}); - $gui.set(gui_id, {1, THEME.TRANSPARENT}); $gui.set(gui_id, {1.0f, THEME.DARK_MID, {}}); } diff --git a/src/gui/fsm.cpp b/src/gui/fsm.cpp index 38cf346..640630b 100644 --- a/src/gui/fsm.cpp +++ b/src/gui/fsm.cpp @@ -31,7 +31,10 @@ namespace gui { void FSM::event(Event ev, std::any data) { switch($state) { FSM_STATE(State, START, ev); - FSM_STATE(State, START_SCREEN, ev); + FSM_STATE(State, START_SCENE, ev); + FSM_STATE(State, DEATH_SCENE, ev); + FSM_STATE(State, WIN_SCENE, ev); + FSM_STATE(State, NEXT_LEVEL_SCENE, ev); FSM_STATE(State, MOVING, ev); FSM_STATE(State, ATTACKING, ev, data); FSM_STATE(State, ROTATING, ev); @@ -56,19 +59,16 @@ namespace gui { $status_ui.init(); run_systems(); - $cur_scene = $scenes["STARTING"]; - dbc::check($cur_scene != nullptr, "No STARTING scene?!"); - - state(State::START_SCREEN); + show_scene("STARTING"); + state(State::START_SCENE); } - void FSM::START_SCREEN(Event ev) { + void FSM::START_SCENE(Event ev) { using enum Event; switch(ev) { case MOUSE_CLICK: - dbc::log("CLICK!"); - $cur_scene = nullptr; + close_scene(); state(State::IDLE); break; case MOUSE_MOVE: { @@ -81,6 +81,46 @@ namespace gui { } } + void FSM::DEATH_SCENE(Event ev) { + using enum Event; + + switch(ev) { + case MOUSE_CLICK: + show_scene("STARTING"); + state(State::START_SCENE); + break; + default: + break; + } + } + + void FSM::WIN_SCENE(Event ev) { + using enum Event; + + switch(ev) { + case MOUSE_CLICK: + show_scene("STARTING"); + state(State::START_SCENE); + break; + default: + break; + } + } + + void FSM::NEXT_LEVEL_SCENE(Event ev) { + using enum Event; + + switch(ev) { + case MOUSE_CLICK: + next_level(); + close_scene(); + state(State::IDLE); + break; + default: + break; + } + } + void FSM::MOVING(Event ) { // this should be an optional that returns a point if(auto move_to = $main_ui.play_move()) { @@ -417,15 +457,17 @@ namespace gui { event(Event::ATTACK, data); break; case eGUI::STAIRS_DOWN: - next_level(); - state(State::IDLE); + show_scene("NEXT_LEVEL"); + state(State::NEXT_LEVEL_SCENE); break; case eGUI::DEATH: { $status_ui.update(); + if(entity != player.entity) { $main_ui.dead_entity(entity); } else { - dbc::log("NEED TO HANDLE PLAYER DYING."); + show_scene("DEATH"); + state(State::DEATH_SCENE); } } break; case eGUI::NOOP: { @@ -459,4 +501,13 @@ namespace gui { run_systems(); } + + void FSM::show_scene(const std::string& name) { + dbc::check($scenes.contains(name), $F("$scenes does not contain {}", name)); + $cur_scene = $scenes[name]; + } + + void FSM::close_scene() { + $cur_scene = nullptr; + } } diff --git a/src/gui/fsm.hpp b/src/gui/fsm.hpp index 3d6d6e4..d6b228f 100644 --- a/src/gui/fsm.hpp +++ b/src/gui/fsm.hpp @@ -16,7 +16,10 @@ namespace gui { enum class State { START=__LINE__, - START_SCREEN=__LINE__, + START_SCENE=__LINE__, + DEATH_SCENE=__LINE__, + WIN_SCENE=__LINE__, + NEXT_LEVEL_SCENE=__LINE__, MOVING=__LINE__, ATTACKING=__LINE__, ROTATING=__LINE__, @@ -50,7 +53,10 @@ namespace gui { void event(game::Event ev, std::any data={}); void START(game::Event ev); - void START_SCREEN(game::Event ev); + void START_SCENE(game::Event ev); + void WIN_SCENE(game::Event ev); + void DEATH_SCENE(game::Event ev); + void NEXT_LEVEL_SCENE(game::Event ev); void IDLE(game::Event ev, std::any data); void MOVING(game::Event ev); void ATTACKING(game::Event ev, std::any data); @@ -72,5 +78,7 @@ namespace gui { void next_level(); void debug_render(); void take_screenshot(); + void show_scene(const std::string& name); + void close_scene(); }; } diff --git a/src/main.cpp b/src/main.cpp index c5c41a1..88ece2e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,7 +33,10 @@ int main(int argc, char* argv[]) { // BUG: need to sort out how to deal with this in the FSM if(main.in_state(gui::State::IDLE) - || main.in_state(gui::State::START_SCREEN) + || main.in_state(gui::State::START_SCENE) + || main.in_state(gui::State::WIN_SCENE) + || main.in_state(gui::State::DEATH_SCENE) + || main.in_state(gui::State::NEXT_LEVEL_SCENE) || main.in_state(gui::State::LOOTING)) { main.handle_keyboard_mouse();