Now have an autowalker class that allows me to drive the game from an external source.

master
Zed A. Shaw 10 months ago
parent 1aba26831b
commit d4355a608d
  1. 112
      autowalker.cpp
  2. 13
      autowalker.hpp
  3. 120
      gui_fsm.cpp
  4. 2
      gui_fsm.hpp
  5. 8
      main.cpp
  6. 1
      meson.build

@ -0,0 +1,112 @@
#include "autowalker.hpp"
void Autowalker::autowalk() {
fmt::println("I'M WALKIN' HEAR!");
fsm.$window.handleEvents(
[&](const sf::Event::KeyPressed &) {
fsm.autowalking = false;
fmt::println("ABORT AUTOWALK");
},
[&](const sf::Event::MouseButtonPressed &) {
fsm.autowalking = false;
fmt::println("ABORT AUTOWALK");
}
);
if(!fsm.autowalking) return;
while(fsm.in_state(gui::State::IN_COMBAT) || fsm.in_state(gui::State::ATTACKING)) {
if(fsm.in_state(gui::State::ATTACKING)) {
fsm.event(gui::Event::TICK);
} else {
fsm.event(gui::Event::ATTACK);
}
fsm.handle_world_events();
}
auto& player_position = fsm.$level.world->get<components::Position>(fsm.$level.player);
auto current = player_position.location;
Point target = current;
bool found = fsm.$level.map->neighbors(target, false, -1);
if(!found) {
dbc::log("no neighbor found, aborting autowalk");
fsm.autowalking = false;
return;
}
if(!fsm.$level.map->can_move(target)) {
dbc::log("neighbors is telling me to go to a bad spot.");
fsm.autowalking = false;
return;
}
int delta_x = int(target.x) - int(current.x);
int delta_y = int(target.y) - int(current.y);
int facing = fsm.$main_ui.$compass_dir;
int target_facing = 0;
if(delta_x == -1 && delta_y == 0) {
// west
fmt::println("WEST: {}, {}", target.x, target.y);
target_facing = 4;
} else if(delta_x == 1 && delta_y == 0) {
// east
fmt::println("EAST: {}, {}", target.x, target.y);
target_facing = 0;
} else if(delta_x == 0 && delta_y == 1) {
fmt::println("SOUTH: {}, {}", target.x, target.y);
// south
target_facing = 2;
} else if(delta_x == 0 && delta_y == -1) {
fmt::println("NORTH: {}, {}", target.x, target.y);
// north
target_facing = 6;
} else {
dbc::sentinel(
fmt::format("got more than 4 direction result: "
"current={},{} "
"target={},{} "
"delta={},{} ",
current.x, current.y,
target.x, target.y,
delta_x, delta_y));
}
auto dir = facing < target_facing ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT;
while(facing != target_facing) {
fsm.event(dir);
fsm.render();
fsm.handle_world_events();
facing = fsm.$main_ui.$compass_dir;
}
dbc::check(fsm.$main_ui.$compass_dir == target_facing,
"player isn't facing the correct direction");
if(!fsm.in_state(gui::State::IN_COMBAT)) {
if(fsm.in_state(gui::State::ATTACKING)) {
fsm.event(gui::Event::TICK);
} else {
fsm.event(gui::Event::MOVE_FORWARD);
}
fsm.handle_world_events();
do {
fmt::println("IN WHILE MOVING");
fsm.event(gui::Event::TICK);
fsm.event(gui::Event::ATTACK);
fsm.render();
fsm.handle_world_events();
} while(fsm.in_state(gui::State::MOVING));
}
}
void Autowalker::start_autowalk() {
fsm.autowalking = true;
}

@ -0,0 +1,13 @@
#pragma once
#include "gui_fsm.hpp"
struct Autowalker {
gui::FSM& fsm;
Autowalker(gui::FSM& fsm)
: fsm(fsm) {}
void autowalk();
void start_autowalk();
};

@ -235,11 +235,6 @@ namespace gui {
}
void FSM::keyboard_mouse() {
if($autowalking) {
autowalk();
return;
}
while(const auto ev = $window.pollEvent()) {
if(ev->is<sf::Event::Closed>()) {
event(Event::QUIT);
@ -293,7 +288,8 @@ namespace gui {
$main_ui.debug();
break;
case KEY::O:
start_autowalk(0.06);
autowalking = true;
break;
default:
break; // ignored
}
@ -406,116 +402,4 @@ namespace gui {
run_systems();
}
void FSM::autowalk() {
fmt::println("I'M WALKIN' HEAR!");
$window.handleEvents(
[&](const sf::Event::KeyPressed &) {
$autowalking = false;
fmt::println("ABORT AUTOWALK");
},
[&](const sf::Event::MouseButtonPressed &) {
$autowalking = false;
fmt::println("ABORT AUTOWALK");
}
);
if(!$autowalking) return;
while(in_state(State::IN_COMBAT) || in_state(State::ATTACKING)) {
if(in_state(State::ATTACKING)) {
event(Event::TICK);
} else {
event(Event::ATTACK);
}
handle_world_events();
}
auto& player_position = $level.world->get<Position>($level.player);
auto current = player_position.location;
Point target = current;
bool found = $level.map->neighbors(target, false, -1);
if(!found) {
dbc::log("no neighbor found, aborting autowalk");
$autowalking = false;
return;
}
if(!$level.map->can_move(target)) {
dbc::log("neighbors is telling me to go to a bad spot.");
$autowalking = false;
return;
}
int delta_x = int(target.x) - int(current.x);
int delta_y = int(target.y) - int(current.y);
int facing = $main_ui.$compass_dir;
int target_facing = 0;
if(delta_x == -1 && delta_y == 0) {
// west
fmt::println("WEST: {}, {}", target.x, target.y);
target_facing = 4;
} else if(delta_x == 1 && delta_y == 0) {
// east
fmt::println("EAST: {}, {}", target.x, target.y);
target_facing = 0;
} else if(delta_x == 0 && delta_y == 1) {
fmt::println("SOUTH: {}, {}", target.x, target.y);
// south
target_facing = 2;
} else if(delta_x == 0 && delta_y == -1) {
fmt::println("NORTH: {}, {}", target.x, target.y);
// north
target_facing = 6;
} else {
dbc::sentinel(
fmt::format("got more than 4 direction result: "
"current={},{} "
"target={},{} "
"delta={},{} ",
current.x, current.y,
target.x, target.y,
delta_x, delta_y));
}
auto dir = facing < target_facing ? Event::ROTATE_LEFT : Event::ROTATE_RIGHT;
while(facing != target_facing) {
event(dir);
render();
handle_world_events();
facing = $main_ui.$compass_dir;
}
dbc::check($main_ui.$compass_dir == target_facing,
"player isn't facing the correct direction");
if(!in_state(State::IN_COMBAT)) {
if(in_state(State::ATTACKING)) {
event(Event::TICK);
} else {
event(Event::MOVE_FORWARD);
}
handle_world_events();
do {
fmt::println("IN WHILE MOVING");
event(Event::TICK);
event(Event::ATTACK);
render();
handle_world_events();
} while(in_state(State::MOVING));
}
}
void FSM::start_autowalk(double rot_speed) {
$autowalking = true;
$main_ui.$camera.rot_speed = rot_speed;
}
}

@ -46,7 +46,7 @@ namespace gui {
public:
sf::RenderWindow $window;
bool $draw_stats = false;
bool $autowalking = false;
bool autowalking = false;
LevelManager $levels;
MainUI $main_ui;
SFMLRender $renderer;

@ -1,6 +1,7 @@
#include "gui_fsm.hpp"
#include "textures.hpp"
#include "sound.hpp"
#include "autowalker.hpp"
int main(int argc, char* argv[]) {
textures::init();
@ -8,9 +9,10 @@ int main(int argc, char* argv[]) {
sound::mute(true);
gui::FSM main;
main.event(gui::Event::STARTED);
Autowalker walker(main);
if(argc > 1 && argv[1][0] == 't') {
main.start_autowalk(0.1);
walker.start_autowalk();
}
while(main.active()) {
@ -22,7 +24,11 @@ int main(int argc, char* argv[]) {
|| main.in_state(gui::State::MAPPING)
|| main.in_state(gui::State::IN_COMBAT))
{
if(main.autowalking) {
walker.autowalk();
} else {
main.keyboard_mouse();
}
} else{
main.event(gui::Event::TICK);
}

@ -53,6 +53,7 @@ endif
sources = [
'ansi_parser.cpp',
'autowalker.cpp',
'camera.cpp',
'combat.cpp',
'combat_ui.cpp',