Level traversal works, but it's very immediate. Next is a little 'confirm level' modal and a transition screen.
This commit is contained in:
parent
1886c99920
commit
29e6d45dc6
14 changed files with 98 additions and 43 deletions
|
@ -50,4 +50,9 @@ namespace gui {
|
||||||
auto& meter = $gui.world().get<Meter>($meter);
|
auto& meter = $gui.world().get<Meter>($meter);
|
||||||
meter.percent = percent;
|
meter.percent = percent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CombatUI::update_level(GameLevel &level) {
|
||||||
|
$level = level;
|
||||||
|
render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace gui {
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
void draw(sf::RenderWindow& window);
|
void draw(sf::RenderWindow& window);
|
||||||
void update_level(GameLevel &level) { $level = level; }
|
void update_level(GameLevel &level);
|
||||||
void set_damage(float percent);
|
void set_damage(float percent);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
38
gui_fsm.cpp
38
gui_fsm.cpp
|
@ -14,7 +14,7 @@ namespace gui {
|
||||||
|
|
||||||
FSM::FSM() :
|
FSM::FSM() :
|
||||||
$window(sf::VideoMode({SCREEN_WIDTH, SCREEN_HEIGHT}), "Zed's Raycaster Thing"),
|
$window(sf::VideoMode({SCREEN_WIDTH, SCREEN_HEIGHT}), "Zed's Raycaster Thing"),
|
||||||
$main_ui($window, $levels.current()),
|
$main_ui($window),
|
||||||
$renderer($window),
|
$renderer($window),
|
||||||
$level($levels.current()),
|
$level($levels.current()),
|
||||||
$map_ui($level),
|
$map_ui($level),
|
||||||
|
@ -34,12 +34,13 @@ namespace gui {
|
||||||
FSM_STATE(State, IDLE, ev);
|
FSM_STATE(State, IDLE, ev);
|
||||||
FSM_STATE(State, IN_COMBAT, ev);
|
FSM_STATE(State, IN_COMBAT, ev);
|
||||||
FSM_STATE(State, COMBAT_ROTATE, ev);
|
FSM_STATE(State, COMBAT_ROTATE, ev);
|
||||||
|
FSM_STATE(State, NEXT_LEVEL, ev);
|
||||||
FSM_STATE(State, END, ev);
|
FSM_STATE(State, END, ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSM::START(Event ) {
|
void FSM::START(Event ) {
|
||||||
$main_ui.generate_map();
|
$main_ui.update_level($level);
|
||||||
$level.world->set_the<Debug>({});
|
$level.world->set_the<Debug>({});
|
||||||
|
|
||||||
$main_ui.init();
|
$main_ui.init();
|
||||||
|
@ -160,6 +161,9 @@ namespace gui {
|
||||||
case CLOSE:
|
case CLOSE:
|
||||||
dbc::log("Nothing to close.");
|
dbc::log("Nothing to close.");
|
||||||
break;
|
break;
|
||||||
|
case STAIRS_DOWN:
|
||||||
|
state(State::NEXT_LEVEL);
|
||||||
|
break;
|
||||||
case STOP_COMBAT:
|
case STOP_COMBAT:
|
||||||
case TICK:
|
case TICK:
|
||||||
// do nothing
|
// 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) {
|
void FSM::IN_COMBAT(Event ev) {
|
||||||
using enum Event;
|
using enum Event;
|
||||||
|
|
||||||
|
@ -342,11 +358,13 @@ namespace gui {
|
||||||
// std::string(item.data["name"])));
|
// std::string(item.data["name"])));
|
||||||
$status_ui.log("You picked up an item.");
|
$status_ui.log("You picked up an item.");
|
||||||
$status_ui.update();
|
$status_ui.update();
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
case eGUI::ATTACK:
|
case eGUI::ATTACK:
|
||||||
event(Event::ATTACK);
|
event(Event::ATTACK);
|
||||||
break;
|
break;
|
||||||
|
case eGUI::STAIRS_DOWN:
|
||||||
|
event(Event::STAIRS_DOWN);
|
||||||
|
break;
|
||||||
case eGUI::DEATH: {
|
case eGUI::DEATH: {
|
||||||
$status_ui.update();
|
$status_ui.update();
|
||||||
if(entity != player.entity) {
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace gui {
|
||||||
ATTACKING,
|
ATTACKING,
|
||||||
MAPPING,
|
MAPPING,
|
||||||
ROTATING,
|
ROTATING,
|
||||||
|
NEXT_LEVEL,
|
||||||
IDLE,
|
IDLE,
|
||||||
END
|
END
|
||||||
};
|
};
|
||||||
|
@ -37,6 +38,7 @@ namespace gui {
|
||||||
ATTACK,
|
ATTACK,
|
||||||
START_COMBAT,
|
START_COMBAT,
|
||||||
STOP_COMBAT,
|
STOP_COMBAT,
|
||||||
|
STAIRS_DOWN,
|
||||||
QUIT
|
QUIT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,6 +67,7 @@ namespace gui {
|
||||||
void IDLE(Event ev);
|
void IDLE(Event ev);
|
||||||
void IN_COMBAT(Event ev);
|
void IN_COMBAT(Event ev);
|
||||||
void COMBAT_ROTATE(Event ev);
|
void COMBAT_ROTATE(Event ev);
|
||||||
|
void NEXT_LEVEL(Event ev);
|
||||||
void END(Event ev);
|
void END(Event ev);
|
||||||
|
|
||||||
void try_move(int dir, bool strafe);
|
void try_move(int dir, bool strafe);
|
||||||
|
@ -74,5 +77,6 @@ namespace gui {
|
||||||
bool active();
|
bool active();
|
||||||
void run_systems();
|
void run_systems();
|
||||||
void handle_world_events();
|
void handle_world_events();
|
||||||
|
void next_level();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace components {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Inventory::has_item(size_t at) {
|
bool Inventory::has_item(size_t at) {
|
||||||
|
fmt::println(">>> INVENTORY: requesting item at {}, have {} items in stock", at, items.size());
|
||||||
return at < items.size();
|
return at < items.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@ using std::shared_ptr;
|
||||||
struct GameLevel {
|
struct GameLevel {
|
||||||
size_t index;
|
size_t index;
|
||||||
DinkyECS::Entity player;
|
DinkyECS::Entity player;
|
||||||
shared_ptr<Map> map;
|
shared_ptr<Map> map = nullptr;
|
||||||
shared_ptr<DinkyECS::World> world;
|
shared_ptr<DinkyECS::World> world = nullptr;
|
||||||
shared_ptr<lighting::LightRender> lights;
|
shared_ptr<lighting::LightRender> lights = nullptr;
|
||||||
shared_ptr<SpatialMap> collision;
|
shared_ptr<SpatialMap> collision = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LevelScaling {
|
struct LevelScaling {
|
||||||
|
|
19
main_ui.cpp
19
main_ui.cpp
|
@ -4,9 +4,8 @@
|
||||||
namespace gui {
|
namespace gui {
|
||||||
using namespace components;
|
using namespace components;
|
||||||
|
|
||||||
MainUI::MainUI(sf::RenderWindow& window, GameLevel level) :
|
MainUI::MainUI(sf::RenderWindow& window) :
|
||||||
$window(window),
|
$window(window),
|
||||||
$level(level),
|
|
||||||
$overlay_ui($level),
|
$overlay_ui($level),
|
||||||
$rayview(RAY_VIEW_WIDTH, RAY_VIEW_HEIGHT)
|
$rayview(RAY_VIEW_WIDTH, RAY_VIEW_HEIGHT)
|
||||||
{
|
{
|
||||||
|
@ -121,18 +120,20 @@ namespace gui {
|
||||||
$camera.abort_plan($rayview);
|
$camera.abort_plan($rayview);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainUI::generate_map() {
|
|
||||||
auto& player = $level.world->get_the<Player>();
|
|
||||||
auto& player_position = $level.world->get<Position>(player.entity);
|
|
||||||
$player = player_position.location;
|
|
||||||
$rayview.set_level($level);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainUI::dead_entity(DinkyECS::Entity entity) {
|
void MainUI::dead_entity(DinkyECS::Entity entity) {
|
||||||
auto &sprite = $level.world->get<Sprite>(entity);
|
auto &sprite = $level.world->get<Sprite>(entity);
|
||||||
$rayview.update_sprite(entity, sprite);
|
$rayview.update_sprite(entity, sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainUI::update_level(GameLevel level) {
|
||||||
|
$level = level;
|
||||||
|
auto& player_position = $level.world->get<Position>($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) {
|
void MainUI::mouse(int x, int y) {
|
||||||
$overlay_ui.$gui.mouse(x, y);
|
$overlay_ui.$gui.mouse(x, y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace gui {
|
||||||
Raycaster $rayview;
|
Raycaster $rayview;
|
||||||
CameraLOL $camera;
|
CameraLOL $camera;
|
||||||
|
|
||||||
MainUI(sf::RenderWindow& window, GameLevel level);
|
MainUI(sf::RenderWindow& window);
|
||||||
|
|
||||||
void mouse(int x, int y);
|
void mouse(int x, int y);
|
||||||
void debug();
|
void debug();
|
||||||
|
@ -32,12 +32,12 @@ namespace gui {
|
||||||
std::optional<Point> play_move();
|
std::optional<Point> play_move();
|
||||||
Point plan_move(int dir, bool strafe);
|
Point plan_move(int dir, bool strafe);
|
||||||
void abort_plan();
|
void abort_plan();
|
||||||
|
void update_level(GameLevel level);
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void draw();
|
void draw();
|
||||||
void dirty();
|
void dirty();
|
||||||
|
|
||||||
void generate_map();
|
|
||||||
void dead_entity(DinkyECS::Entity entity);
|
void dead_entity(DinkyECS::Entity entity);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -368,19 +368,18 @@ void Raycaster::update_sprite(DinkyECS::Entity ent, components::Sprite& sprite)
|
||||||
$sprites.insert_or_assign(ent, sprite_txt);
|
$sprites.insert_or_assign(ent, sprite_txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Raycaster::set_level(GameLevel level) {
|
void Raycaster::update_level(GameLevel level) {
|
||||||
$level = level;
|
$level = level;
|
||||||
|
|
||||||
auto& tiles = $level.map->tiles();
|
auto& tiles = $level.map->tiles();
|
||||||
auto world = $level.world;
|
|
||||||
auto& player = world->get_the<components::Player>();
|
|
||||||
$map = textures::convert_char_to_texture(tiles.$tile_ids);
|
$map = textures::convert_char_to_texture(tiles.$tile_ids);
|
||||||
|
|
||||||
world->query<components::Sprite>([&](const auto ent, auto& sprite) {
|
$level.world->query<components::Sprite>([&](const auto ent, auto& sprite) {
|
||||||
// player doesn't need a 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);
|
fmt::println("entity {} will have sprite named {}", ent, sprite.name);
|
||||||
auto sprite_txt = textures::get(sprite.name);
|
auto sprite_txt = textures::get(sprite.name);
|
||||||
$sprites.try_emplace(ent, sprite_txt);
|
$sprites.insert_or_assign(ent, sprite_txt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,10 @@ struct Raycaster {
|
||||||
int $height;
|
int $height;
|
||||||
int $screen_pos_x = RAY_VIEW_X;
|
int $screen_pos_x = RAY_VIEW_X;
|
||||||
int $screen_pos_y = RAY_VIEW_Y;
|
int $screen_pos_y = RAY_VIEW_Y;
|
||||||
|
std::unordered_map<DinkyECS::Entity, textures::SpriteTexture> $sprites;
|
||||||
|
|
||||||
GameLevel $level;
|
GameLevel $level;
|
||||||
Matrix $map;
|
Matrix $map;
|
||||||
std::unordered_map<DinkyECS::Entity, textures::SpriteTexture> $sprites;
|
|
||||||
std::vector<double> $zbuffer; // width
|
std::vector<double> $zbuffer; // width
|
||||||
|
|
||||||
Raycaster(int width, int height);
|
Raycaster(int width, int height);
|
||||||
|
@ -57,7 +58,7 @@ struct Raycaster {
|
||||||
return ((y) * $width) + (x);
|
return ((y) * $width) + (x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_level(GameLevel level);
|
void update_level(GameLevel level);
|
||||||
void update_sprite(DinkyECS::Entity ent, components::Sprite& sprite);
|
void update_sprite(DinkyECS::Entity ent, components::Sprite& sprite);
|
||||||
void init_shaders();
|
void init_shaders();
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,6 +59,7 @@ namespace gui {
|
||||||
auto& inventory = world->get<components::Inventory>($level.player);
|
auto& inventory = world->get<components::Inventory>($level.player);
|
||||||
size_t inv_id = $slots[any_cast<string>(slot_name)];
|
size_t inv_id = $slots[any_cast<string>(slot_name)];
|
||||||
|
|
||||||
|
if(inventory.has_item(inv_id)) {
|
||||||
auto [used, name] = inventory.use($level, inv_id);
|
auto [used, name] = inventory.use($level, inv_id);
|
||||||
|
|
||||||
if(used) {
|
if(used) {
|
||||||
|
@ -70,6 +71,7 @@ namespace gui {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* WARNING: This is really not the greatest way to do this. */
|
/* WARNING: This is really not the greatest way to do this. */
|
||||||
void StatusUI::update() {
|
void StatusUI::update() {
|
||||||
|
@ -118,4 +120,9 @@ namespace gui {
|
||||||
$messages.pop_back();
|
$messages.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StatusUI::update_level(GameLevel &level) {
|
||||||
|
$level = level;
|
||||||
|
render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace gui {
|
||||||
|
|
||||||
StatusUI(GameLevel level);
|
StatusUI(GameLevel level);
|
||||||
void select_slot(DinkyECS::Entity ent, std::any data);
|
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 log(std::string msg);
|
||||||
void render();
|
void render();
|
||||||
void draw(sf::RenderWindow &window);
|
void draw(sf::RenderWindow &window);
|
||||||
|
|
|
@ -254,8 +254,13 @@ void System::device(DinkyECS::World &world, DinkyECS::Entity actor, DinkyECS::En
|
||||||
auto& device = world.get<Device>(item);
|
auto& device = world.get<Device>(item);
|
||||||
|
|
||||||
for(auto event : device.events) {
|
for(auto event : device.events) {
|
||||||
// world.send<Events::GUI>((Events::GUI)event, actor, device);
|
fmt::println("Device event received {}", event);
|
||||||
fmt::println("BROKEN can't sent device event {}", event);
|
|
||||||
|
if(event == "Events::GUI::STAIRS_DOWN") {
|
||||||
|
world.send<Events::GUI>(Events::GUI::STAIRS_DOWN, actor, device);
|
||||||
|
} else {
|
||||||
|
dbc::log(fmt::format("EVENT IGNORED {}", event));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println("entity {} INTERACTED WITH DEVICE {}", actor, item);
|
println("entity {} INTERACTED WITH DEVICE {}", actor, item);
|
||||||
|
|
|
@ -244,11 +244,13 @@ void WorldBuilder::randomize_entities(DinkyECS::World &world, GameConfig &config
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldBuilder::place_stairs(DinkyECS::World& world, GameConfig& config) {
|
void WorldBuilder::place_stairs(DinkyECS::World& world, GameConfig& config) {
|
||||||
|
for(size_t i = 1; i < $map.room_count() - 1; i++) {
|
||||||
auto& device_config = config.devices.json();
|
auto& device_config = config.devices.json();
|
||||||
auto entity_data = device_config["STAIRS_DOWN"];
|
auto entity_data = device_config["STAIRS_DOWN"];
|
||||||
int last_room = $map.room_count() - 1;
|
int last_room = i;
|
||||||
auto entity = configure_entity_in_map(world, entity_data, last_room);
|
auto entity = configure_entity_in_map(world, entity_data, last_room);
|
||||||
check_player(world, entity);
|
check_player(world, entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldBuilder::place_entities(DinkyECS::World &world) {
|
void WorldBuilder::place_entities(DinkyECS::World &world) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue