|
|
@ -107,6 +107,9 @@ void System::enemy_pathing() { |
|
|
|
map.random_walk(out, motion.random, PATHING_TOWARD); |
|
|
|
map.random_walk(out, motion.random, PATHING_TOWARD); |
|
|
|
} else if(enemy_ai.wants_to("run_away")) { |
|
|
|
} else if(enemy_ai.wants_to("run_away")) { |
|
|
|
map.random_walk(out, motion.random, PATHING_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)}; |
|
|
|
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) { |
|
|
|
void System::motion() { |
|
|
|
|
|
|
|
auto& level = GameDB::current_level(); |
|
|
|
|
|
|
|
auto world = level.world; |
|
|
|
|
|
|
|
auto map = level.map; |
|
|
|
|
|
|
|
auto collider = level.collision; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
world->query<Position, Motion>( |
|
|
|
|
|
|
|
[&](auto ent, auto &position, auto &motion) { |
|
|
|
|
|
|
|
// skip enemies that aren't moving
|
|
|
|
|
|
|
|
if(motion.dx == 0 && motion.dy == 0) return; |
|
|
|
|
|
|
|
|
|
|
|
Point move_to = { |
|
|
|
Point move_to = { |
|
|
|
position.location.x + motion.dx, |
|
|
|
position.location.x + motion.dx, |
|
|
|
position.location.y + motion.dy |
|
|
|
position.location.y + motion.dy |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
motion = {0,0}; // clear it after getting it
|
|
|
|
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<ai::EntityAI>(ent)) { |
|
|
|
|
|
|
|
enemy_ai->set_state("cant_move", cant_move); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// it's a wall, skip
|
|
|
|
// it's a wall, skip
|
|
|
|
if(!game_map.can_move(move_to)) return; |
|
|
|
if(cant_move) return; |
|
|
|
// there's collision skip
|
|
|
|
|
|
|
|
if(collider.occupied(move_to)) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// all good, do the move
|
|
|
|
// all good, do the move
|
|
|
|
collider.move(position.location, move_to, ent); |
|
|
|
collider->move(position.location, move_to, ent); |
|
|
|
position.location = move_to; |
|
|
|
position.location = move_to; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void System::motion() { |
|
|
|
|
|
|
|
auto& level = GameDB::current_level(); |
|
|
|
|
|
|
|
level.world->query<Position, Motion>( |
|
|
|
|
|
|
|
[&](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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|