Boss fight now reuses the combat_ui.cpp to do the combat panel, so next is making it work with the mechanics I want but no art.
This commit is contained in:
parent
6ec43026b6
commit
8a828fbd31
11 changed files with 107 additions and 91 deletions
|
|
@ -101,7 +101,7 @@ void Autowalker::path_fail(const std::string& msg, Matrix& bad_paths, Point pos)
|
|||
status(L"PATH FAIL");
|
||||
matrix::dump("MOVE FAIL PATHS", bad_paths, pos.x, pos.y);
|
||||
log(L"Autowalk failed to find a path.");
|
||||
send_event(gui::Event::STAIRS_DOWN);
|
||||
send_event(gui::Event::BOSS_START);
|
||||
}
|
||||
|
||||
bool Autowalker::path_player(Pathing& paths, Point& target_out) {
|
||||
|
|
@ -176,9 +176,9 @@ void Autowalker::update_state(ai::EntityAI& player_ai) {
|
|||
|
||||
void Autowalker::handle_boss_fight() {
|
||||
// skip the boss fight for now
|
||||
if(fsm.in_state(gui::State::NEXT_LEVEL)) {
|
||||
if(fsm.in_state(gui::State::BOSS_FIGHT)) {
|
||||
// eventually we'll have AI handle this too
|
||||
send_event(gui::Event::STAIRS_DOWN);
|
||||
send_event(gui::Event::BOSS_END);
|
||||
face_enemy();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
30
boss/ui.cpp
30
boss/ui.cpp
|
|
@ -7,6 +7,7 @@ namespace boss {
|
|||
UI::UI(shared_ptr<World> world, Entity boss_id) :
|
||||
$world(world),
|
||||
$boss_id(boss_id),
|
||||
$combat_ui(true),
|
||||
$boss_sprite(textures::get_sprite("test_boss")),
|
||||
$player_sprite(textures::get_sprite("test_player")),
|
||||
$floor_sprite(textures::get_sprite("test_floor"))
|
||||
|
|
@ -30,33 +31,27 @@ namespace boss {
|
|||
|
||||
position_sprite($boss_sprite, "boss2", 0.7, true);
|
||||
position_sprite($player_sprite, "player1", 0.5, true);
|
||||
position_sprite($floor_sprite, "floor2", 1.0, false);
|
||||
position_sprite($floor_sprite, "floor1", 1.0, false);
|
||||
|
||||
$arena.init();
|
||||
|
||||
$actions.position(0,0, SCREEN_WIDTH-BOSS_VIEW_WIDTH, SCREEN_HEIGHT);
|
||||
$actions.layout(
|
||||
"[action1|action2]"
|
||||
"[action3|action4]"
|
||||
"[action5|action6]"
|
||||
"[*(200)dodge]"
|
||||
"[*(200,400)combat|_]"
|
||||
"[_|_]"
|
||||
"[_|_]"
|
||||
"[_|_]"
|
||||
"[*(200,300)stats]"
|
||||
"[_]"
|
||||
"[_]");
|
||||
|
||||
for(auto& [name, cell] : $actions.cells()) {
|
||||
auto id = $actions.entity(name);
|
||||
$actions.set<Rectangle>(id, {});
|
||||
$actions.set<Text>(id, {guecs::to_wstring(name)});
|
||||
|
||||
if(name != "stats") {
|
||||
$actions.set<Clickable>(id, {
|
||||
[name](auto){ fmt::println("clicked {}", name); }
|
||||
});
|
||||
}
|
||||
}
|
||||
auto stats = $actions.entity("stats");
|
||||
$actions.set<Rectangle>(stats, {});
|
||||
$actions.set<Text>(stats, {L"stats"});
|
||||
|
||||
$actions.init();
|
||||
|
||||
auto& cell = $actions.cell_for("combat");
|
||||
$combat_ui.init(cell.x, cell.y, cell.w, cell.h);
|
||||
}
|
||||
|
||||
void UI::position_sprite(textures::SpriteTexture& st, const std::string& name, float scale, bool at_mid) {
|
||||
|
|
@ -71,6 +66,7 @@ namespace boss {
|
|||
void UI::render(sf::RenderWindow& window) {
|
||||
$arena.render(window);
|
||||
$actions.render(window);
|
||||
$combat_ui.render(window);
|
||||
window.draw(*$floor_sprite.sprite);
|
||||
window.draw(*$boss_sprite.sprite);
|
||||
window.draw(*$player_sprite.sprite);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <SFML/Graphics/RenderWindow.hpp>
|
||||
#include <guecs/ui.hpp>
|
||||
#include "textures.hpp"
|
||||
#include "gui/combat_ui.hpp"
|
||||
|
||||
namespace boss {
|
||||
using std::shared_ptr;
|
||||
|
|
@ -13,6 +14,7 @@ namespace boss {
|
|||
struct UI {
|
||||
shared_ptr<World> $world = nullptr;
|
||||
Entity $boss_id = NONE;
|
||||
gui::CombatUI $combat_ui;
|
||||
SpriteTexture $boss_sprite;
|
||||
SpriteTexture $player_sprite;
|
||||
SpriteTexture $floor_sprite;
|
||||
|
|
|
|||
|
|
@ -1,32 +1,27 @@
|
|||
#include "gui/combat_ui.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "rituals.hpp"
|
||||
#include <fmt/xchar.h>
|
||||
#include "gui/guecstra.hpp"
|
||||
#include "inventory.hpp"
|
||||
#include "game_level.hpp"
|
||||
#include "gui/combat_ui.hpp"
|
||||
|
||||
namespace gui {
|
||||
using guecs::THEME;
|
||||
using namespace guecs;
|
||||
|
||||
CombatUI::CombatUI()
|
||||
CombatUI::CombatUI(bool boss_style) :
|
||||
$boss_style(boss_style)
|
||||
{
|
||||
$gui.position(COMBAT_UI_X, COMBAT_UI_Y, COMBAT_UI_WIDTH, COMBAT_UI_HEIGHT);
|
||||
$gui.layout(
|
||||
"[button_0 | button_1 | button_2 | button_3"
|
||||
"|button_4 | button_5 | button_6 | =healing_button | =hp_gauge ]"
|
||||
);
|
||||
}
|
||||
|
||||
guecs::Entity CombatUI::make_button(
|
||||
std::string name,
|
||||
guecs::Entity button,
|
||||
Events::GUI event,
|
||||
int action,
|
||||
const std::string &icon_name,
|
||||
const std::string &sound,
|
||||
const std::string &effect_name)
|
||||
{
|
||||
auto button = $gui.entity(name);
|
||||
$gui.set<Sprite>(button, {icon_name});
|
||||
$gui.set<Sound>(button, {sound});
|
||||
$gui.set<Effect>(button, {.duration=0.5f, .name=effect_name});
|
||||
|
|
@ -36,49 +31,68 @@ namespace gui {
|
|||
return button;
|
||||
}
|
||||
|
||||
void CombatUI::init() {
|
||||
void CombatUI::init(int x, int y, int w, int h) {
|
||||
$gui.position(x, y, w, h);
|
||||
|
||||
if($boss_style) {
|
||||
$gui.layout(
|
||||
"[action0|action1]"
|
||||
"[action2|action3]"
|
||||
"[action4|action5]"
|
||||
"[action6|action7]");
|
||||
} else {
|
||||
$gui.layout(
|
||||
"[action0 | action1 | action2 | action3"
|
||||
"|action4 | action5 | action6 | action7 | =hp_gauge ]");
|
||||
}
|
||||
|
||||
auto world = GameDB::current_world();
|
||||
using guecs::THEME;
|
||||
$gui.set<Background>($gui.MAIN, {$gui.$parser, THEME.DARK_MID});
|
||||
auto& the_belt = world->get_the<ritual::Belt>();
|
||||
|
||||
for(int slot = 0; slot < the_belt.max_slots; slot++) {
|
||||
fmt::println("combat ui belt slot {}", slot);
|
||||
if(the_belt.has(slot)) {
|
||||
std::string name = fmt::format("button_{}", slot);
|
||||
auto button = $gui.entity("action", slot);
|
||||
fmt::println("combat ui has belt slot {} with id {}", slot, button);
|
||||
|
||||
auto& ritual = the_belt.get(slot);
|
||||
|
||||
using enum ritual::Element;
|
||||
|
||||
switch(ritual.element) {
|
||||
case FIRE:
|
||||
make_button(name, Events::GUI::ATTACK,
|
||||
make_button(button, Events::GUI::ATTACK,
|
||||
slot, "broken_yoyo", "fireball_01", "flame");
|
||||
break;
|
||||
case LIGHTNING:
|
||||
make_button(name, Events::GUI::ATTACK,
|
||||
make_button(button, Events::GUI::ATTACK,
|
||||
slot, "pocket_watch", "electric_shock_01", "lightning");
|
||||
break;
|
||||
default:
|
||||
make_button(name, Events::GUI::ATTACK,
|
||||
make_button(button, Events::GUI::ATTACK,
|
||||
slot, "severed_finger", "punch_cartoony", "ui_shader");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto hp_gauge = $gui.entity("hp_gauge");
|
||||
$gui.set<Sprite>(hp_gauge, {"stone_doll_cursed"});
|
||||
$gui.set<Clickable>(hp_gauge,
|
||||
guecs::make_action(hp_gauge, Events::GUI::HP_STATUS, {}));
|
||||
if(!$boss_style) {
|
||||
auto hp_gauge = $gui.entity("hp_gauge");
|
||||
$gui.set<Sprite>(hp_gauge, {"stone_doll_cursed"});
|
||||
$gui.set<Clickable>(hp_gauge,
|
||||
guecs::make_action(hp_gauge, Events::GUI::HP_STATUS, {}));
|
||||
}
|
||||
|
||||
$gui.init();
|
||||
}
|
||||
|
||||
void CombatUI::render(sf::RenderWindow& window) {
|
||||
$gui.render(window);
|
||||
// $gui.debug_layout(window);
|
||||
}
|
||||
|
||||
void CombatUI::update_level() {
|
||||
init();
|
||||
init(COMBAT_UI_X, COMBAT_UI_Y, COMBAT_UI_WIDTH, COMBAT_UI_HEIGHT);
|
||||
}
|
||||
|
||||
bool CombatUI::mouse(float x, float y, guecs::Modifiers mods) {
|
||||
|
|
|
|||
|
|
@ -7,15 +7,16 @@
|
|||
namespace gui {
|
||||
class CombatUI {
|
||||
public:
|
||||
bool $boss_style;
|
||||
guecs::UI $gui;
|
||||
|
||||
CombatUI();
|
||||
CombatUI(bool boss_style);
|
||||
|
||||
void init();
|
||||
void init(int x, int y, int w, int h);
|
||||
void render(sf::RenderWindow& window);
|
||||
void update_level();
|
||||
bool mouse(float x, float y, guecs::Modifiers mods);
|
||||
guecs::Entity make_button(std::string name, Events::GUI event,
|
||||
guecs::Entity make_button(guecs::Entity button, Events::GUI event,
|
||||
int action, const std::string &icon_name,
|
||||
const std::string &sound, const std::string &effect_name);
|
||||
};
|
||||
|
|
|
|||
57
gui/fsm.cpp
57
gui/fsm.cpp
|
|
@ -20,6 +20,7 @@ namespace gui {
|
|||
FSM::FSM() :
|
||||
$window(sf::VideoMode({SCREEN_WIDTH, SCREEN_HEIGHT}), "Zed's Raycaster Thing"),
|
||||
$main_ui($window),
|
||||
$combat_ui(false),
|
||||
$font{FONT_FILE_NAME},
|
||||
$dnd_loot($status_ui, $loot_ui, $window, $router)
|
||||
{
|
||||
|
|
@ -35,7 +36,7 @@ namespace gui {
|
|||
FSM_STATE(State, IDLE, ev, data);
|
||||
FSM_STATE(State, IN_COMBAT, ev);
|
||||
FSM_STATE(State, COMBAT_ROTATE, ev);
|
||||
FSM_STATE(State, NEXT_LEVEL, ev);
|
||||
FSM_STATE(State, BOSS_FIGHT, ev);
|
||||
FSM_STATE(State, END, ev);
|
||||
FSM_STATE(State, LOOTING, ev, data);
|
||||
}
|
||||
|
|
@ -50,12 +51,8 @@ namespace gui {
|
|||
auto cell = $main_ui.overlay_cell("left");
|
||||
$debug_ui.init(cell);
|
||||
|
||||
$combat_ui.init();
|
||||
$combat_ui.init(COMBAT_UI_X, COMBAT_UI_Y, COMBAT_UI_WIDTH, COMBAT_UI_HEIGHT);
|
||||
$status_ui.init();
|
||||
|
||||
$boss_fight_ui = GameDB::create_bossfight();
|
||||
$boss_fight_ui->init();
|
||||
|
||||
$map_ui.init();
|
||||
$map_ui.log(L"Welcome to the game!");
|
||||
|
||||
|
|
@ -169,9 +166,10 @@ namespace gui {
|
|||
case CLOSE:
|
||||
dbc::log("Nothing to close.");
|
||||
break;
|
||||
case STAIRS_DOWN:
|
||||
case BOSS_START:
|
||||
sound::stop("ambient");
|
||||
state(State::NEXT_LEVEL);
|
||||
next_level(true);
|
||||
state(State::BOSS_FIGHT);
|
||||
break;
|
||||
case LOOT_ITEM:
|
||||
$dnd_loot.event(Event::LOOT_ITEM);
|
||||
|
|
@ -207,13 +205,16 @@ namespace gui {
|
|||
}
|
||||
}
|
||||
|
||||
void FSM::NEXT_LEVEL(Event ev) {
|
||||
void FSM::BOSS_FIGHT(Event ev) {
|
||||
dbc::check($boss_fight_ui != nullptr, "$boss_fight_ui not initialized");
|
||||
using enum Event;
|
||||
|
||||
switch(ev) {
|
||||
case STAIRS_DOWN:
|
||||
// this is only if using the debug X key to skip it
|
||||
case BOSS_START:
|
||||
case BOSS_END:
|
||||
sound::play("ambient");
|
||||
next_level();
|
||||
next_level(false);
|
||||
state(State::IDLE);
|
||||
break;
|
||||
case MOUSE_CLICK: {
|
||||
|
|
@ -221,7 +222,7 @@ namespace gui {
|
|||
$boss_fight_ui->mouse(pos.x, pos.y, guecs::NO_MODS);
|
||||
|
||||
if($boss_fight_ui->boss_dead()) {
|
||||
event(Event::STAIRS_DOWN);
|
||||
event(Event::BOSS_END);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
|
|
@ -362,7 +363,7 @@ namespace gui {
|
|||
$main_ui.toggle_mind_reading();
|
||||
break;
|
||||
case KEY::X:
|
||||
event(Event::STAIRS_DOWN);
|
||||
event(Event::BOSS_START);
|
||||
break;
|
||||
case KEY::F5:
|
||||
take_screenshot();
|
||||
|
|
@ -384,7 +385,7 @@ namespace gui {
|
|||
}
|
||||
|
||||
void FSM::draw_gui() {
|
||||
if(in_state(State::NEXT_LEVEL)) {
|
||||
if(in_state(State::BOSS_FIGHT)) {
|
||||
$boss_fight_ui->render($window);
|
||||
} else {
|
||||
if($debug_ui.active) {
|
||||
|
|
@ -406,7 +407,7 @@ namespace gui {
|
|||
}
|
||||
|
||||
void FSM::render() {
|
||||
if(in_state(State::NEXT_LEVEL)) {
|
||||
if(in_state(State::BOSS_FIGHT)) {
|
||||
$window.clear();
|
||||
$boss_fight_ui->render($window);
|
||||
} else {
|
||||
|
|
@ -502,14 +503,14 @@ namespace gui {
|
|||
System::player_status();
|
||||
break;
|
||||
case eGUI::NEW_RITUAL:
|
||||
$combat_ui.init();
|
||||
$combat_ui.init(COMBAT_UI_X, COMBAT_UI_Y, COMBAT_UI_WIDTH, COMBAT_UI_HEIGHT);
|
||||
break;
|
||||
case eGUI::ATTACK:
|
||||
$temp_attack_id = std::any_cast<int>(data);
|
||||
event(Event::ATTACK);
|
||||
break;
|
||||
case eGUI::STAIRS_DOWN:
|
||||
event(Event::STAIRS_DOWN);
|
||||
event(Event::BOSS_START);
|
||||
break;
|
||||
case eGUI::DEATH: {
|
||||
$status_ui.update();
|
||||
|
|
@ -541,17 +542,17 @@ namespace gui {
|
|||
dbc::check(worked, "Failed to write screenshot.png");
|
||||
}
|
||||
|
||||
void FSM::next_level() {
|
||||
dbc::log("current_level: Yep, next is called...");
|
||||
GameDB::create_level();
|
||||
|
||||
$status_ui.update_level();
|
||||
$combat_ui.update_level();
|
||||
$main_ui.update_level();
|
||||
$loot_ui.update_level();
|
||||
|
||||
$boss_fight_ui = GameDB::create_bossfight();
|
||||
$boss_fight_ui->init();
|
||||
void FSM::next_level(bool bossfight) {
|
||||
if(bossfight) {
|
||||
$boss_fight_ui = GameDB::create_bossfight();
|
||||
$boss_fight_ui->init();
|
||||
} else {
|
||||
GameDB::create_level();
|
||||
$status_ui.update_level();
|
||||
$combat_ui.update_level();
|
||||
$main_ui.update_level();
|
||||
$loot_ui.update_level();
|
||||
}
|
||||
|
||||
run_systems();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ namespace gui {
|
|||
COMBAT_ROTATE=3,
|
||||
ATTACKING=4,
|
||||
ROTATING=5,
|
||||
NEXT_LEVEL=6,
|
||||
BOSS_FIGHT=6,
|
||||
LOOTING=7,
|
||||
IDLE=8,
|
||||
END=9
|
||||
|
|
@ -59,7 +59,7 @@ namespace gui {
|
|||
void IDLE(Event ev, std::any data);
|
||||
void IN_COMBAT(Event ev);
|
||||
void COMBAT_ROTATE(Event ev);
|
||||
void NEXT_LEVEL(Event ev);
|
||||
void BOSS_FIGHT(Event ev);
|
||||
void LOOTING(Event ev, std::any data);
|
||||
void END(Event ev);
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ namespace gui {
|
|||
bool active();
|
||||
void run_systems();
|
||||
void handle_world_events();
|
||||
void next_level();
|
||||
void next_level(bool bossfight);
|
||||
void debug_render();
|
||||
void take_screenshot();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,19 +15,20 @@ namespace gui {
|
|||
ATTACK = 10,
|
||||
START_COMBAT = 11,
|
||||
STOP_COMBAT = 12,
|
||||
STAIRS_DOWN = 13,
|
||||
LOOT_OPEN=14,
|
||||
LOOT_ITEM=15,
|
||||
LOOT_SELECT=16,
|
||||
INV_SELECT=17,
|
||||
USE_ITEM=18,
|
||||
QUIT = 19,
|
||||
MOUSE_CLICK=20,
|
||||
MOUSE_MOVE=21,
|
||||
MOUSE_DRAG=22,
|
||||
MOUSE_DRAG_START=23,
|
||||
MOUSE_DROP=24,
|
||||
KEY_PRESS=25,
|
||||
AIM_CLICK=26
|
||||
BOSS_START = 13,
|
||||
BOSS_END = 14,
|
||||
LOOT_OPEN=15,
|
||||
LOOT_ITEM=16,
|
||||
LOOT_SELECT=17,
|
||||
INV_SELECT=18,
|
||||
USE_ITEM=19,
|
||||
QUIT = 20,
|
||||
MOUSE_CLICK=21,
|
||||
MOUSE_MOVE=22,
|
||||
MOUSE_DRAG=23,
|
||||
MOUSE_DRAG_START=24,
|
||||
MOUSE_DROP=25,
|
||||
KEY_PRESS=26,
|
||||
AIM_CLICK=27
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#include "dinkyecs.hpp"
|
||||
#include <unordered_map>
|
||||
|
||||
|
|
|
|||
2
main.cpp
2
main.cpp
|
|
@ -35,7 +35,7 @@ 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::NEXT_LEVEL)
|
||||
|| main.in_state(gui::State::BOSS_FIGHT)
|
||||
|| main.in_state(gui::State::LOOTING)
|
||||
|| main.in_state(gui::State::IN_COMBAT))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ namespace ritual {
|
|||
|
||||
struct Belt {
|
||||
int next_slot = 0;
|
||||
int max_slots = 6;
|
||||
int max_slots = 8;
|
||||
std::unordered_map<int, Action> equipped;
|
||||
|
||||
Action& get(int index);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue