Refactored the FSM so that it uses a generic registry of systems to do what it needs.
This commit is contained in:
parent
cbff127b40
commit
e742b8772d
7 changed files with 150 additions and 118 deletions
82
src/game/registry.hpp
Normal file
82
src/game/registry.hpp
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include "game/components.hpp"
|
||||
|
||||
namespace System {
|
||||
using MovingFunc = std::function<void(components::Position& move_to)>;
|
||||
using CombatFunc = std::function<void(int attack_id)>;
|
||||
using RenderFunc = std::function<void()>;
|
||||
using UpdateFunc = std::function<void()>;
|
||||
using UseItemFunc = std::function<void(const std::string& slot_name)>;
|
||||
using PickupFunc = std::function<void()>;
|
||||
|
||||
struct Registry {
|
||||
std::vector<MovingFunc> $moving;
|
||||
std::vector<CombatFunc> $combat;
|
||||
std::vector<RenderFunc> $render;
|
||||
std::vector<UpdateFunc> $update;
|
||||
std::vector<UseItemFunc> $use_item;
|
||||
std::vector<PickupFunc> $pickup;
|
||||
|
||||
void addMoving(MovingFunc action) {
|
||||
$moving.emplace_back(action);
|
||||
}
|
||||
|
||||
void addCombat(CombatFunc action) {
|
||||
$combat.emplace_back(action);
|
||||
}
|
||||
|
||||
void addRender(RenderFunc action) {
|
||||
$render.emplace_back(action);
|
||||
}
|
||||
|
||||
void addUpdate(UpdateFunc action) {
|
||||
$update.emplace_back(action);
|
||||
}
|
||||
|
||||
void addUseItem(UseItemFunc action) {
|
||||
$use_item.emplace_back(action);
|
||||
}
|
||||
|
||||
void addPickup(PickupFunc action) {
|
||||
$pickup.emplace_back(action);
|
||||
}
|
||||
|
||||
void runMoving(components::Position move_to) {
|
||||
for(auto func : $moving) {
|
||||
func(move_to);
|
||||
}
|
||||
}
|
||||
|
||||
void runCombat(int attack_id) {
|
||||
for(auto func : $combat) {
|
||||
func(attack_id);
|
||||
}
|
||||
}
|
||||
|
||||
void runRender() {
|
||||
for(auto func : $render) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
void runUpdate() {
|
||||
for(auto func : $update) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
void runUseItem(const std::string& slot_name) {
|
||||
for(auto func : $use_item) {
|
||||
func(slot_name);
|
||||
}
|
||||
}
|
||||
|
||||
void runPickup() {
|
||||
for(auto func : $pickup) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -474,14 +474,14 @@ bool System::inventory_occupied(Entity container_id, const std::string& name) {
|
|||
return inventory.has(name);
|
||||
}
|
||||
|
||||
bool System::use_item(const string& slot_name) {
|
||||
void System::use_item(const string& slot_name) {
|
||||
auto& level = GameDB::current_level();
|
||||
auto& world = *level.world;
|
||||
auto& inventory = world.get<inventory::Model>(level.player);
|
||||
auto& player_combat = world.get<Combat>(level.player);
|
||||
|
||||
if(player_combat.hp >= player_combat.max_hp) return false;
|
||||
if(!inventory.has(slot_name)) return false;
|
||||
if(player_combat.hp >= player_combat.max_hp) return;
|
||||
if(!inventory.has(slot_name)) return;
|
||||
|
||||
auto what = inventory.get(slot_name);
|
||||
|
||||
|
|
@ -498,10 +498,8 @@ bool System::use_item(const string& slot_name) {
|
|||
player_combat.hp));
|
||||
|
||||
world.remove<Curative>(what);
|
||||
return true;
|
||||
} else {
|
||||
dbc::log($F("no usable item at {}", what));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -541,3 +539,19 @@ void System::clear_attack() {
|
|||
|
||||
void System::spawn_attack(World& world, int attack_id, DinkyECS::Entity enemy) {
|
||||
}
|
||||
|
||||
|
||||
void System::init(Registry& reg) {
|
||||
reg.addRender(System::clear_attack);
|
||||
reg.addUseItem(System::use_item);
|
||||
reg.addMoving(System::move_player);
|
||||
reg.addCombat(System::combat);
|
||||
reg.addPickup(System::pickup);
|
||||
reg.addUpdate(System::generate_paths);
|
||||
reg.addUpdate(System::enemy_ai_initialize);
|
||||
reg.addUpdate(System::enemy_pathing);
|
||||
reg.addUpdate(System::motion);
|
||||
reg.addUpdate(System::collision);
|
||||
reg.addUpdate(System::lighting);
|
||||
reg.addUpdate(System::death);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@
|
|||
#include "algos/spatialmap.hpp"
|
||||
#include "game/level.hpp"
|
||||
#include "events.hpp"
|
||||
#include "game/registry.hpp"
|
||||
|
||||
namespace System {
|
||||
|
||||
using namespace components;
|
||||
using namespace DinkyECS;
|
||||
using std::string, matrix::Matrix;
|
||||
|
|
@ -32,15 +34,15 @@ namespace System {
|
|||
|
||||
void pickup();
|
||||
|
||||
// BUG: these might need to go somewhere else....
|
||||
bool place_in_container(Entity cont_id, const string& name, Entity world_entity);
|
||||
|
||||
void remove_from_container(Entity cont_id, const std::string& name);
|
||||
void remove_from_world(Entity entity);
|
||||
void inventory_swap(Entity container_id, const std::string& a_name, const std::string &b_name);
|
||||
bool inventory_occupied(Entity container_id, const std::string& name);
|
||||
|
||||
void set_position(DinkyECS::World& world, SpatialMap& collision, Entity entity, Position pos);
|
||||
bool use_item(const std::string& slot_name);
|
||||
void use_item(const std::string& slot_name);
|
||||
|
||||
game::Event shortest_rotate(Point player_at, Point aiming_at, Point turning_to);
|
||||
|
||||
|
|
@ -67,4 +69,6 @@ namespace System {
|
|||
|
||||
void clear_attack();
|
||||
void spawn_attack(World& world, int attack_id, DinkyECS::Entity enemy);
|
||||
|
||||
void init(Registry& reg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ namespace gui {
|
|||
void FSM::MOVING(Event ) {
|
||||
// this should be an optional that returns a point
|
||||
if(auto move_to = $main_ui.play_move()) {
|
||||
System::move_player(*move_to);
|
||||
$systems.runMoving(*move_to);
|
||||
run_systems();
|
||||
$main_ui.dirty();
|
||||
state(State::IDLE);
|
||||
|
|
@ -70,7 +70,7 @@ namespace gui {
|
|||
switch(ev) {
|
||||
case TICK: {
|
||||
dbc::log("!!!!!! FIX System::combat(0) doesn't use any weapons, only first");
|
||||
System::combat(0);
|
||||
$systems.runCombat(0);
|
||||
run_systems();
|
||||
state(State::IN_COMBAT);
|
||||
} break;
|
||||
|
|
@ -79,7 +79,7 @@ namespace gui {
|
|||
break;
|
||||
case ATTACK: {
|
||||
int attack_id = std::any_cast<int>(data);
|
||||
System::combat(attack_id);
|
||||
$systems.runCombat(attack_id);
|
||||
run_systems();
|
||||
} break;
|
||||
default:
|
||||
|
|
@ -174,10 +174,8 @@ namespace gui {
|
|||
case USE_ITEM: {
|
||||
auto gui_id = std::any_cast<guecs::Entity>(data);
|
||||
auto& slot_name = $status_ui.$gui.name_for(gui_id);
|
||||
|
||||
if(System::use_item(slot_name)) {
|
||||
$systems.runUseItem(slot_name);
|
||||
$status_ui.update();
|
||||
}
|
||||
} break;
|
||||
case MOUSE_CLICK:
|
||||
mouse_action(guecs::NO_MODS);
|
||||
|
|
@ -186,7 +184,7 @@ namespace gui {
|
|||
mouse_action({1 << guecs::ModBit::hover});
|
||||
} break;
|
||||
case AIM_CLICK:
|
||||
System::pickup();
|
||||
$systems.runPickup();
|
||||
break;
|
||||
default:
|
||||
break; // ignore everything else
|
||||
|
|
@ -312,9 +310,6 @@ namespace gui {
|
|||
$debug_ui.debug();
|
||||
shaders::reload();
|
||||
break;
|
||||
case KEY::O:
|
||||
autowalking = true;
|
||||
break;
|
||||
case KEY::L:
|
||||
// This will go away as soon as containers work
|
||||
$loot_ui.set_target($loot_ui.$temp_loot);
|
||||
|
|
@ -360,10 +355,8 @@ namespace gui {
|
|||
}
|
||||
|
||||
void FSM::render() {
|
||||
$window.clear();
|
||||
|
||||
// this clears any attack animations, like fire
|
||||
System::clear_attack();
|
||||
$systems.runRender();
|
||||
// BUG: this is the render for this class, and where I add an update
|
||||
draw_gui();
|
||||
|
||||
|
|
@ -371,13 +364,7 @@ namespace gui {
|
|||
}
|
||||
|
||||
void FSM::run_systems() {
|
||||
System::generate_paths();
|
||||
System::enemy_ai_initialize();
|
||||
System::enemy_pathing();
|
||||
System::motion();
|
||||
System::collision();
|
||||
System::lighting();
|
||||
System::death();
|
||||
$systems.runUpdate();
|
||||
}
|
||||
|
||||
bool FSM::active() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "constants.hpp"
|
||||
#include "game/registry.hpp"
|
||||
#include "algos/simplefsm.hpp"
|
||||
#include "gui/debug_ui.hpp"
|
||||
#include "gui/main_ui.hpp"
|
||||
|
|
@ -35,12 +36,11 @@ namespace gui {
|
|||
LootUI $loot_ui;
|
||||
gui::routing::Router $router;
|
||||
DNDLoot $dnd_loot;
|
||||
System::Registry $systems;
|
||||
|
||||
FSM();
|
||||
|
||||
void event(game::Event ev, std::any data={});
|
||||
void autowalk();
|
||||
void start_autowalk(double rot_speed);
|
||||
|
||||
void START(game::Event ev);
|
||||
void MOVING(game::Event ev);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "gui/backend.hpp"
|
||||
#include "game/level.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "game/systems.hpp"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
try {
|
||||
|
|
@ -21,6 +22,7 @@ int main(int argc, char* argv[]) {
|
|||
sound::mute(true);
|
||||
|
||||
gui::FSM main;
|
||||
System::init(main.$systems);
|
||||
main.event(game::Event::START);
|
||||
|
||||
sound::play("ambient_1", true);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
#include "game/systems.hpp"
|
||||
#include <cmath>
|
||||
#include <numbers>
|
||||
#include "game/registry.hpp"
|
||||
|
||||
using components::Position;
|
||||
|
||||
TEST_CASE("figure out best rotation direction", "[systems-rotate]") {
|
||||
Matrix map = matrix::make(3, 3);
|
||||
|
|
@ -35,104 +37,45 @@ TEST_CASE("figure out best rotation direction", "[systems-rotate]") {
|
|||
}
|
||||
}
|
||||
|
||||
using MovingFunc = std::function<void()>;
|
||||
using CombatFunc = std::function<void(bool)>;
|
||||
using RenderFunc = std::function<void()>;
|
||||
using UpdateFunc = std::function<void()>;
|
||||
using UseFunc = std::function<void()>;
|
||||
using PickupFunc = std::function<void()>;
|
||||
|
||||
struct Engine {
|
||||
std::vector<MovingFunc> $moving;
|
||||
std::vector<CombatFunc> $combat;
|
||||
std::vector<RenderFunc> $render;
|
||||
std::vector<UpdateFunc> $update;
|
||||
std::vector<UseFunc> $use;
|
||||
std::vector<PickupFunc> $pickup;
|
||||
|
||||
void addMoving(MovingFunc action) {
|
||||
$moving.emplace_back(action);
|
||||
}
|
||||
|
||||
void addCombat(CombatFunc action) {
|
||||
$combat.emplace_back(action);
|
||||
}
|
||||
|
||||
void addRender(RenderFunc action) {
|
||||
$render.emplace_back(action);
|
||||
}
|
||||
|
||||
void addUpdate(UpdateFunc action) {
|
||||
$update.emplace_back(action);
|
||||
}
|
||||
|
||||
void addUse(UseFunc action) {
|
||||
$use.emplace_back(action);
|
||||
}
|
||||
|
||||
void addPickup(PickupFunc action) {
|
||||
$pickup.emplace_back(action);
|
||||
}
|
||||
|
||||
void runMoving() {
|
||||
for(auto func : $moving) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
void runCombat(bool attr) {
|
||||
for(auto func : $combat) {
|
||||
func(attr);
|
||||
}
|
||||
}
|
||||
|
||||
void runRender() {
|
||||
for(auto func : $render) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
void runUpdate() {
|
||||
for(auto func : $update) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
void runUse() {
|
||||
for(auto func : $use) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
void runPickup() {
|
||||
for(auto func : $pickup) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void test_system_1() {
|
||||
fmt::println("TEST 1");
|
||||
void test_moving(Position& move_to) {
|
||||
fmt::println("MOVING: {},{}", move_to.location.x, move_to.location.y);
|
||||
}
|
||||
|
||||
void test_combat(bool what) {
|
||||
fmt::println("TEST 2: {}", what);
|
||||
void test_combat(int attack_id) {
|
||||
fmt::println("ATTACK: {}", attack_id);
|
||||
}
|
||||
|
||||
void test_render() {
|
||||
fmt::println("RENDER");
|
||||
}
|
||||
|
||||
void test_update() {
|
||||
fmt::println("UPDATE");
|
||||
}
|
||||
|
||||
void test_use_item(const std::string& slot_name) {
|
||||
fmt::println("USE ITEM {}", slot_name);
|
||||
}
|
||||
|
||||
void test_pickup() {
|
||||
fmt::println("PICKUP");
|
||||
}
|
||||
|
||||
TEST_CASE("new system running engine thing", "[systems-engine]") {
|
||||
Engine systems;
|
||||
System::Registry systems;
|
||||
|
||||
systems.addMoving(test_system_1);
|
||||
systems.addMoving(test_moving);
|
||||
systems.addCombat(test_combat);
|
||||
systems.addRender(test_system_1);
|
||||
systems.addUpdate(test_system_1);
|
||||
systems.addUse(test_system_1);
|
||||
systems.addPickup(test_system_1);
|
||||
systems.addRender(test_render);
|
||||
systems.addUpdate(test_update);
|
||||
systems.addUseItem(test_use_item);
|
||||
systems.addPickup(test_pickup);
|
||||
|
||||
systems.runCombat(false);
|
||||
systems.runMoving();
|
||||
systems.runCombat(1);
|
||||
systems.runMoving({1,1});
|
||||
systems.runRender();
|
||||
systems.runUpdate();
|
||||
systems.runUse();
|
||||
systems.runUseItem("hand_l");
|
||||
systems.runPickup();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue