diff --git a/assets/ai.json b/assets/ai.json index c58acb7..6679d2e 100644 --- a/assets/ai.json +++ b/assets/ai.json @@ -9,7 +9,8 @@ "have_item": 6, "have_healing": 7, "detect_enemy": 8, - "tough_personality": 9 + "tough_personality": 9, + "cant_move": 10 }, "actions": [ { @@ -32,7 +33,8 @@ "tough_personality": false, "in_combat": true, "have_healing": false, - "health_good": false + "health_good": false, + "cant_move": false }, "effects": { "in_combat": false diff --git a/gui/fsm.cpp b/gui/fsm.cpp index 179f9ee..2c57a72 100644 --- a/gui/fsm.cpp +++ b/gui/fsm.cpp @@ -418,8 +418,8 @@ namespace gui { System::generate_paths(); System::enemy_ai_initialize(); System::enemy_pathing(); - System::collision(); System::motion(); + System::collision(); System::lighting(); System::death(); } diff --git a/systems.cpp b/systems.cpp index 26997d1..c232fee 100644 --- a/systems.cpp +++ b/systems.cpp @@ -107,6 +107,9 @@ void System::enemy_pathing() { map.random_walk(out, motion.random, PATHING_TOWARD); } else if(enemy_ai.wants_to("run_away")) { map.random_walk(out, motion.random, PATHING_AWAY); + } else { + motion = {0,0}; + return; // enemy doesn't want to move } motion = { int(out.x - position.location.x), int(out.y - position.location.y)}; @@ -117,31 +120,38 @@ void System::enemy_pathing() { } -inline void move_entity(SpatialMap &collider, Map &game_map, Position &position, Motion &motion, Entity ent) { - Point move_to = { - position.location.x + motion.dx, - position.location.y + motion.dy - }; - motion = {0,0}; // clear it after getting it - - // it's a wall, skip - if(!game_map.can_move(move_to)) return; - // there's collision skip - if(collider.occupied(move_to)) return; - - // all good, do the move - collider.move(position.location, move_to, ent); - position.location = move_to; -} - void System::motion() { auto& level = GameDB::current_level(); - level.world->query( + auto world = level.world; + auto map = level.map; + auto collider = level.collision; + + world->query( [&](auto ent, auto &position, auto &motion) { - // don't process entities that don't move - if(motion.dx != 0 || motion.dy != 0) { - move_entity(*level.collision, *level.map, position, motion, ent); - } + // skip enemies that aren't moving + if(motion.dx == 0 && motion.dy == 0) return; + + Point move_to = { + position.location.x + motion.dx, + position.location.y + motion.dy + }; + + motion = {0,0}; // clear it after getting it + + dbc::check(map->can_move(move_to), "Enemy pathing failed, move_to is wall."); + + bool cant_move = collider->occupied(move_to); + + if(auto enemy_ai = world->get_if(ent)) { + enemy_ai->set_state("cant_move", cant_move); + } + + // it's a wall, skip + if(cant_move) return; + + // all good, do the move + collider->move(position.location, move_to, ent); + position.location = move_to; }); }