Improved the code so it uses ai::EntityAI and it now will find healing when it gets low. Has a bug where it stalls when finding healing and gets into combat.

This commit is contained in:
Zed A. Shaw 2025-09-07 23:56:24 -04:00
parent 7207d53885
commit 0afaa20c1d
4 changed files with 31 additions and 29 deletions

View file

@ -37,7 +37,7 @@ tracy_build:
meson compile -j 10 -C builddir
test:
./builddir/runtests -d yes "[systems-rotate]"
./builddir/runtests -d yes
run: build test
ifeq '$(OS)' 'Windows_NT'
@ -60,7 +60,7 @@ clean:
meson compile --clean -C builddir
debug_test: build
gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests -e "[systems-rotate]"
gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests -e
win_installer:
powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" scripts\win_installer.ifp'

View file

@ -23,6 +23,7 @@
"enemy_found": false
},
"effects": {
"in_combat": true,
"enemy_found": true
}
},
@ -67,7 +68,7 @@
},
{
"name": "find_healing",
"cost": 5,
"cost": 2,
"needs": {
"have_healing": false,
"in_combat": false,
@ -79,11 +80,10 @@
},
{
"name": "use_healing",
"cost": 0,
"cost": 1,
"needs": {
"have_item": true,
"have_healing": true,
"in_combat": false,
"health_good": false
},
"effects": {
@ -132,6 +132,7 @@
["find_enemy",
"kill_enemy",
"collect_items",
"find_healing",
"use_healing"],
"Enemy::actions":
["find_enemy", "run_away", "kill_enemy", "use_healing"]

View file

@ -153,27 +153,25 @@ void Autowalker::rotate_player(Point target) {
fsm.autowalking = player.aiming_at == target;
}
ai::State Autowalker::update_state(ai::State start) {
void Autowalker::update_state(ai::EntityAI& player_ai) {
int enemy_count = number_left<components::Combat>();
int item_count = number_left<components::InventoryItem>();
ai::set(start, "no_more_enemies", enemy_count == 0);
ai::set(start, "no_more_items", item_count == 0);
player_ai.set_state("no_more_enemies", enemy_count == 0);
player_ai.set_state("no_more_items", item_count == 0);
// BUG: so isn't this wrong? we "find" an enemy when we are aiming at one
ai::set(start, "enemy_found", found_enemy());
player_ai.set_state("enemy_found", found_enemy());
player_ai.set_state("health_good", player_health_good());
ai::set(start, "health_good", player_health_good());
ai::set(start, "in_combat",
player_ai.set_state("in_combat",
fsm.in_state(gui::State::IN_COMBAT) ||
fsm.in_state(gui::State::ATTACKING));
auto inv = player_item_count();
ai::set(start, "have_item", inv.other > 0 || inv.healing > 0);
ai::set(start, "have_healing", inv.healing > 0);
player_ai.set_state("have_item", inv.other > 0 || inv.healing > 0);
player_ai.set_state("have_healing", inv.healing > 0);
return start;
player_ai.update();
}
void Autowalker::handle_boss_fight() {
@ -186,20 +184,18 @@ void Autowalker::handle_boss_fight() {
}
void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) {
start = update_state(start);
auto a_plan = ai::plan("Host::actions", start, goal);
auto action = a_plan.script.front();
ai::EntityAI player_ai("Host::actions", start, goal);
update_state(player_ai);
auto level = GameDB::current_level();
// ai::dump_script("AUTOWALK", start, a_plan.script);
if(action.name == "find_enemy") {
if(player_ai.wants_to("find_enemy")) {
status(L"FINDING ENEMY");
auto paths = path_to_enemies();
process_move(paths, [&](auto target) -> bool {
return level.collision->occupied(target);
});
face_enemy();
} else if(action.name == "kill_enemy") {
} else if(player_ai.wants_to("kill_enemy")) {
status(L"KILLING ENEMY");
if(fsm.in_state(gui::State::IN_COMBAT)) {
@ -207,11 +203,13 @@ void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) {
process_combat();
}
}
} else if(action.name == "use_healing") {
} else if(player_ai.wants_to("use_healing")) {
status(L"USING HEALING");
player_use_healing();
} else if(action.name == "collect_items" || action.name == "find_healing") {
status(action.name == "collection_items" ? L"COLLECTING ITEMS" : L"FIND HEALING");
} else if(player_ai.wants_to("collect_items") || player_ai.wants_to("find_healing")) {
fmt::println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
status(player_ai.wants_to("collect_items") ? L"COLLECTING ITEMS" : L"FIND HEALING");
player_ai.dump();
auto paths = path_to_items();
@ -225,13 +223,14 @@ void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) {
});
if(found_it) pickup_item();
} else if(action == ai::FINAL_ACTION) {
fmt::println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
} else if(!player_ai.active()) {
close_status();
log(L"FINAL ACTION! Autowalk done.");
fsm.autowalking = false;
} else {
close_status();
dbc::log(fmt::format("Unknown action: {}", action.name));
dbc::log(fmt::format("Unknown action: {}", player_ai.to_string()));
}
}
@ -358,7 +357,9 @@ bool Autowalker::player_health_good() {
auto world = GameDB::current_world();
auto player = GameDB::the_player();
auto combat = world->get<components::Combat>(player);
return float(combat.hp) / float(combat.max_hp) > 0.5f;
float health = float(combat.hp) / float(combat.max_hp);
fmt::println("!!!!!!!!!! HEALTH: {}", health);
return health > 0.5f;
}
InventoryStats Autowalker::player_item_count() {

View file

@ -41,7 +41,7 @@ struct Autowalker {
bool player_health_good();
void player_use_healing();
InventoryStats player_item_count();
ai::State update_state(ai::State start);
void update_state(ai::EntityAI& player_ai);
DinkyECS::Entity camera_aim();
Pathing path_to_enemies();