49 lines
1.5 KiB
C++
49 lines
1.5 KiB
C++
#include "enemies.h"
|
|
#include "core/roguedefs.h"
|
|
#include "core/world.h"
|
|
#include <functional>
|
|
|
|
namespace rogue {
|
|
Tile CritteLogic::move() {
|
|
Tile location{this->character->location};
|
|
Character *player{this->character->world->get_player()};
|
|
if(this->is_aware_of_player) {
|
|
// cache query_tile call for repeated use
|
|
std::function<TileData(Tile)> query_tile{std::bind(&World::query_tile, this->character->world, std::placeholders::_1)};
|
|
Tile difference{
|
|
player->location.x - location.x,
|
|
player->location.y - location.y
|
|
};
|
|
Tile abs{std::abs(difference.x), std::abs(difference.y)};
|
|
Tile direction{
|
|
difference.x == 0 ? 0 : difference.x / std::abs(difference.x),
|
|
difference.y == 0 ? 0 : difference.y / std::abs(difference.y)
|
|
};
|
|
Tile x_motion{location.x + direction.x, location.y};
|
|
Tile y_motion{location.x, location.y + direction.y};
|
|
if(abs.x > abs.y) {
|
|
if(!query_tile(x_motion).is_wall)
|
|
return x_motion;
|
|
else if(!query_tile(y_motion).is_wall) {
|
|
return y_motion;
|
|
}
|
|
} else {
|
|
if(!query_tile(y_motion).is_wall) {
|
|
return y_motion;
|
|
} else if(!query_tile(x_motion).is_wall) {
|
|
return x_motion;
|
|
}
|
|
}
|
|
} else {
|
|
// cache get_chunk call for easier reading
|
|
std::function<Chunk(Tile)> get_chunk{std::bind(&World::get_chunk, this->character->world, std::placeholders::_1)};
|
|
this->is_aware_of_player |= get_chunk(player->location) != get_chunk(location);
|
|
}
|
|
// fallback return value, for if there is no desirable tile to move to
|
|
return {
|
|
.x = location.x,
|
|
.y = location.y
|
|
};
|
|
}
|
|
}
|