roguelike/src/enemies.cpp

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
};
}
}