diff --git a/Makefile b/Makefile index 14b9464..ece7c1d 100644 --- a/Makefile +++ b/Makefile @@ -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' diff --git a/assets/ai.json b/assets/ai.json index eb3e6bd..446231e 100644 --- a/assets/ai.json +++ b/assets/ai.json @@ -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"] diff --git a/autowalker.cpp b/autowalker.cpp index c84b45c..9f5ac9d 100644 --- a/autowalker.cpp +++ b/autowalker.cpp @@ -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(); int item_count = number_left(); - 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(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() { diff --git a/autowalker.hpp b/autowalker.hpp index daf8bc1..5a51016 100644 --- a/autowalker.hpp +++ b/autowalker.hpp @@ -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();