Enemies and now using the GOAP AI to decide when to attack the player, but it's very rough right now. I need to sort out how to store the AI states and use them in the System.

This commit is contained in:
Zed A. Shaw 2025-03-14 11:14:25 -04:00
parent 77f2e94515
commit ad71631809
13 changed files with 61 additions and 30 deletions

View file

@ -9,6 +9,8 @@
#include "inventory.hpp"
#include "events.hpp"
#include "sound.hpp"
#include "ai.hpp"
#include "ai_debug.hpp"
using std::string;
using namespace fmt;
@ -35,10 +37,26 @@ void System::lighting(GameLevel &level) {
}
void System::enemy_ai(GameLevel &level) {
(void)level;
// AI: look up Enemy::actions in ai.json
// AI: setup the state
// AI: process it and keep the next action in the world
auto &world = *level.world;
auto &map = *level.map;
auto player = world.get_the<Player>();
const auto &player_position = world.get<Position>(player.entity);
map.set_target(player_position.location);
map.make_paths();
world.query<Position, EnemyConfig>([&](const auto ent, auto& pos, auto& config) {
config.ai_start = ai::load_state(config.ai_start_name);
config.ai_goal = ai::load_state(config.ai_goal_name);
ai::set(config.ai_start, "detect_enemy",
map.distance(pos.location) < config.hearing_distance);
auto a_plan = ai::plan(config.ai_script, config.ai_start, config.ai_goal);
ai::dump_script("\n\n\n-----ENEMY SCRIPT", config.ai_start, a_plan.script);
auto action = a_plan.script.front();
world.set<ai::Action>(ent, action);
});
}
void System::enemy_pathing(GameLevel &level) {
@ -52,15 +70,9 @@ void System::enemy_pathing(GameLevel &level) {
world.query<Position, Motion>([&](auto ent, auto &position, auto &motion) {
if(ent != player.entity) {
// AI: EnemyConfig can be replaced with an AI thing
// AI: after the enemy_ai systems are run we can then look at what
// AI: their next actions is, and if it's pathing do that
dbc::check(world.has<EnemyConfig>(ent), "enemy is missing config");
const auto &config = world.get<EnemyConfig>(ent);
Point out = position.location; // copy
if(map.distance(out) < config.hearing_distance) {
auto action = world.get_if<ai::Action>(ent);
if(action && (*action).name == "find_enemy") {
Point out = position.location; // copy
map.neighbors(out, motion.random);
motion = { int(out.x - position.location.x), int(out.y - position.location.y)};
}