From 29e6d45dc65c0b7dfb2d4feb535a6df6b15fc997 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Mon, 24 Feb 2025 23:26:50 -0500 Subject: [PATCH] Level traversal works, but it's very immediate. Next is a little 'confirm level' modal and a transition screen. --- combat_ui.cpp | 5 +++++ combat_ui.hpp | 2 +- gui_fsm.cpp | 38 ++++++++++++++++++++++++++++++++++---- gui_fsm.hpp | 4 ++++ inventory.cpp | 1 + levelmanager.hpp | 8 ++++---- main_ui.cpp | 19 ++++++++++--------- main_ui.hpp | 4 ++-- raycaster.cpp | 11 +++++------ raycaster.hpp | 5 +++-- status_ui.cpp | 21 ++++++++++++++------- status_ui.hpp | 2 +- systems.cpp | 9 +++++++-- worldbuilder.cpp | 12 +++++++----- 14 files changed, 98 insertions(+), 43 deletions(-) diff --git a/combat_ui.cpp b/combat_ui.cpp index 13a493a..1371ede 100644 --- a/combat_ui.cpp +++ b/combat_ui.cpp @@ -50,4 +50,9 @@ namespace gui { auto& meter = $gui.world().get($meter); meter.percent = percent; } + + void CombatUI::update_level(GameLevel &level) { + $level = level; + render(); + } } diff --git a/combat_ui.hpp b/combat_ui.hpp index e8d3cd4..ccddabe 100644 --- a/combat_ui.hpp +++ b/combat_ui.hpp @@ -15,7 +15,7 @@ namespace gui { void render(); void draw(sf::RenderWindow& window); - void update_level(GameLevel &level) { $level = level; } + void update_level(GameLevel &level); void set_damage(float percent); }; } diff --git a/gui_fsm.cpp b/gui_fsm.cpp index 01b4b73..76ecc6f 100644 --- a/gui_fsm.cpp +++ b/gui_fsm.cpp @@ -14,7 +14,7 @@ namespace gui { FSM::FSM() : $window(sf::VideoMode({SCREEN_WIDTH, SCREEN_HEIGHT}), "Zed's Raycaster Thing"), - $main_ui($window, $levels.current()), + $main_ui($window), $renderer($window), $level($levels.current()), $map_ui($level), @@ -34,12 +34,13 @@ namespace gui { FSM_STATE(State, IDLE, ev); FSM_STATE(State, IN_COMBAT, ev); FSM_STATE(State, COMBAT_ROTATE, ev); + FSM_STATE(State, NEXT_LEVEL, ev); FSM_STATE(State, END, ev); } } void FSM::START(Event ) { - $main_ui.generate_map(); + $main_ui.update_level($level); $level.world->set_the({}); $main_ui.init(); @@ -160,6 +161,9 @@ namespace gui { case CLOSE: dbc::log("Nothing to close."); break; + case STAIRS_DOWN: + state(State::NEXT_LEVEL); + break; case STOP_COMBAT: case TICK: // do nothing @@ -169,6 +173,18 @@ namespace gui { } } + void FSM::NEXT_LEVEL(Event ev) { + using enum Event; + + switch(ev) { + case TICK: + next_level(); + state(State::IDLE); + default: + break; // do nothing for now + } + } + void FSM::IN_COMBAT(Event ev) { using enum Event; @@ -342,11 +358,13 @@ namespace gui { // std::string(item.data["name"]))); $status_ui.log("You picked up an item."); $status_ui.update(); - } - break; + } break; case eGUI::ATTACK: event(Event::ATTACK); break; + case eGUI::STAIRS_DOWN: + event(Event::STAIRS_DOWN); + break; case eGUI::DEATH: { $status_ui.update(); if(entity != player.entity) { @@ -366,4 +384,16 @@ namespace gui { } } } + + void FSM::next_level() { + $levels.create_level($level.world); + $level = $levels.next(); + + $status_ui.update_level($level); + $combat_ui.update_level($level); + $map_ui.update_level($level); + $main_ui.update_level($level); + + run_systems(); + } } diff --git a/gui_fsm.hpp b/gui_fsm.hpp index d78e6ad..beda75d 100644 --- a/gui_fsm.hpp +++ b/gui_fsm.hpp @@ -19,6 +19,7 @@ namespace gui { ATTACKING, MAPPING, ROTATING, + NEXT_LEVEL, IDLE, END }; @@ -37,6 +38,7 @@ namespace gui { ATTACK, START_COMBAT, STOP_COMBAT, + STAIRS_DOWN, QUIT }; @@ -65,6 +67,7 @@ namespace gui { void IDLE(Event ev); void IN_COMBAT(Event ev); void COMBAT_ROTATE(Event ev); + void NEXT_LEVEL(Event ev); void END(Event ev); void try_move(int dir, bool strafe); @@ -74,5 +77,6 @@ namespace gui { bool active(); void run_systems(); void handle_world_events(); + void next_level(); }; } diff --git a/inventory.cpp b/inventory.cpp index a541893..60d4dad 100644 --- a/inventory.cpp +++ b/inventory.cpp @@ -15,6 +15,7 @@ namespace components { } bool Inventory::has_item(size_t at) { + fmt::println(">>> INVENTORY: requesting item at {}, have {} items in stock", at, items.size()); return at < items.size(); } diff --git a/levelmanager.hpp b/levelmanager.hpp index b96582f..4a95f8d 100644 --- a/levelmanager.hpp +++ b/levelmanager.hpp @@ -13,10 +13,10 @@ using std::shared_ptr; struct GameLevel { size_t index; DinkyECS::Entity player; - shared_ptr map; - shared_ptr world; - shared_ptr lights; - shared_ptr collision; + shared_ptr map = nullptr; + shared_ptr world = nullptr; + shared_ptr lights = nullptr; + shared_ptr collision = nullptr; }; struct LevelScaling { diff --git a/main_ui.cpp b/main_ui.cpp index 3b973ef..60b52fe 100644 --- a/main_ui.cpp +++ b/main_ui.cpp @@ -4,9 +4,8 @@ namespace gui { using namespace components; - MainUI::MainUI(sf::RenderWindow& window, GameLevel level) : + MainUI::MainUI(sf::RenderWindow& window) : $window(window), - $level(level), $overlay_ui($level), $rayview(RAY_VIEW_WIDTH, RAY_VIEW_HEIGHT) { @@ -121,18 +120,20 @@ namespace gui { $camera.abort_plan($rayview); } - void MainUI::generate_map() { - auto& player = $level.world->get_the(); - auto& player_position = $level.world->get(player.entity); - $player = player_position.location; - $rayview.set_level($level); - } - void MainUI::dead_entity(DinkyECS::Entity entity) { auto &sprite = $level.world->get(entity); $rayview.update_sprite(entity, sprite); } + void MainUI::update_level(GameLevel level) { + $level = level; + auto& player_position = $level.world->get($level.player); + $player = player_position.location; + $rayview.update_level($level); + $rayview.position_camera($player.x + 0.5, $player.y + 0.5); + dirty(); + } + void MainUI::mouse(int x, int y) { $overlay_ui.$gui.mouse(x, y); } diff --git a/main_ui.hpp b/main_ui.hpp index 712fbe3..ff1e806 100644 --- a/main_ui.hpp +++ b/main_ui.hpp @@ -20,7 +20,7 @@ namespace gui { Raycaster $rayview; CameraLOL $camera; - MainUI(sf::RenderWindow& window, GameLevel level); + MainUI(sf::RenderWindow& window); void mouse(int x, int y); void debug(); @@ -32,12 +32,12 @@ namespace gui { std::optional play_move(); Point plan_move(int dir, bool strafe); void abort_plan(); + void update_level(GameLevel level); void init(); void draw(); void dirty(); - void generate_map(); void dead_entity(DinkyECS::Entity entity); }; } diff --git a/raycaster.cpp b/raycaster.cpp index 33eaedd..e2e3db4 100644 --- a/raycaster.cpp +++ b/raycaster.cpp @@ -368,19 +368,18 @@ void Raycaster::update_sprite(DinkyECS::Entity ent, components::Sprite& sprite) $sprites.insert_or_assign(ent, sprite_txt); } -void Raycaster::set_level(GameLevel level) { +void Raycaster::update_level(GameLevel level) { $level = level; + auto& tiles = $level.map->tiles(); - auto world = $level.world; - auto& player = world->get_the(); $map = textures::convert_char_to_texture(tiles.$tile_ids); - world->query([&](const auto ent, auto& sprite) { + $level.world->query([&](const auto ent, auto& sprite) { // player doesn't need a sprite - if(player.entity == ent) return; + if($level.player == ent) return; fmt::println("entity {} will have sprite named {}", ent, sprite.name); auto sprite_txt = textures::get(sprite.name); - $sprites.try_emplace(ent, sprite_txt); + $sprites.insert_or_assign(ent, sprite_txt); }); } diff --git a/raycaster.hpp b/raycaster.hpp index 304e815..8341fd3 100644 --- a/raycaster.hpp +++ b/raycaster.hpp @@ -34,9 +34,10 @@ struct Raycaster { int $height; int $screen_pos_x = RAY_VIEW_X; int $screen_pos_y = RAY_VIEW_Y; + std::unordered_map $sprites; + GameLevel $level; Matrix $map; - std::unordered_map $sprites; std::vector $zbuffer; // width Raycaster(int width, int height); @@ -57,7 +58,7 @@ struct Raycaster { return ((y) * $width) + (x); } - void set_level(GameLevel level); + void update_level(GameLevel level); void update_sprite(DinkyECS::Entity ent, components::Sprite& sprite); void init_shaders(); }; diff --git a/status_ui.cpp b/status_ui.cpp index f79343f..c09331a 100644 --- a/status_ui.cpp +++ b/status_ui.cpp @@ -59,15 +59,17 @@ namespace gui { auto& inventory = world->get($level.player); size_t inv_id = $slots[any_cast(slot_name)]; - auto [used, name] = inventory.use($level, inv_id); + if(inventory.has_item(inv_id)) { + auto [used, name] = inventory.use($level, inv_id); - if(used) { - log(fmt::format("Used item: {}", name)); - } else { - log(fmt::format("You are out of {}.", name)); - } + if(used) { + log(fmt::format("Used item: {}", name)); + } else { + log(fmt::format("You are out of {}.", name)); + } - update(); + update(); + } } } @@ -118,4 +120,9 @@ namespace gui { $messages.pop_back(); } } + + void StatusUI::update_level(GameLevel &level) { + $level = level; + render(); + } } diff --git a/status_ui.hpp b/status_ui.hpp index 9cf8bd8..41bb915 100644 --- a/status_ui.hpp +++ b/status_ui.hpp @@ -16,7 +16,7 @@ namespace gui { StatusUI(GameLevel level); void select_slot(DinkyECS::Entity ent, std::any data); - void update_level(GameLevel &level) { $level = level; } + void update_level(GameLevel &level); void log(std::string msg); void render(); void draw(sf::RenderWindow &window); diff --git a/systems.cpp b/systems.cpp index 30bff27..464b37e 100644 --- a/systems.cpp +++ b/systems.cpp @@ -254,8 +254,13 @@ void System::device(DinkyECS::World &world, DinkyECS::Entity actor, DinkyECS::En auto& device = world.get(item); for(auto event : device.events) { - // world.send((Events::GUI)event, actor, device); - fmt::println("BROKEN can't sent device event {}", event); + fmt::println("Device event received {}", event); + + if(event == "Events::GUI::STAIRS_DOWN") { + world.send(Events::GUI::STAIRS_DOWN, actor, device); + } else { + dbc::log(fmt::format("EVENT IGNORED {}", event)); + } } println("entity {} INTERACTED WITH DEVICE {}", actor, item); diff --git a/worldbuilder.cpp b/worldbuilder.cpp index e7f36a3..369180b 100644 --- a/worldbuilder.cpp +++ b/worldbuilder.cpp @@ -244,11 +244,13 @@ void WorldBuilder::randomize_entities(DinkyECS::World &world, GameConfig &config } void WorldBuilder::place_stairs(DinkyECS::World& world, GameConfig& config) { - auto& device_config = config.devices.json(); - auto entity_data = device_config["STAIRS_DOWN"]; - int last_room = $map.room_count() - 1; - auto entity = configure_entity_in_map(world, entity_data, last_room); - check_player(world, entity); + for(size_t i = 1; i < $map.room_count() - 1; i++) { + auto& device_config = config.devices.json(); + auto entity_data = device_config["STAIRS_DOWN"]; + int last_room = i; + auto entity = configure_entity_in_map(world, entity_data, last_room); + check_player(world, entity); + } } void WorldBuilder::place_entities(DinkyECS::World &world) {