Now using a simple collision map to track entities and then determine if they're near the player for attacking.
This commit is contained in:
parent
743f906bc7
commit
ec1ed23c52
6 changed files with 72 additions and 48 deletions
42
systems.cpp
42
systems.cpp
|
@ -3,6 +3,7 @@
|
|||
#include <string>
|
||||
#include <cmath>
|
||||
#include "rand.hpp"
|
||||
#include "collider.hpp"
|
||||
|
||||
using std::string;
|
||||
using namespace fmt;
|
||||
|
@ -24,8 +25,17 @@ void System::enemy_pathing(DinkyECS::World &world, Map &game_map, Player &player
|
|||
game_map.clear_target(player_position.location);
|
||||
}
|
||||
|
||||
void System::init_positions(DinkyECS::World &world) {
|
||||
auto &collider = world.get<SpatialHashTable>();
|
||||
|
||||
world.system<Position>([&](const auto &ent, auto &pos) {
|
||||
collider.insert(pos.location, ent);
|
||||
});
|
||||
}
|
||||
|
||||
void System::motion(DinkyECS::World &world, Map &game_map) {
|
||||
auto &collider = world.get<SpatialHashTable>();
|
||||
|
||||
world.system<Position, Motion>([&](const auto &ent, auto &position, auto &motion) {
|
||||
// don't process entities that don't move
|
||||
if(motion.dx != 0 || motion.dy != 0) {
|
||||
|
@ -36,8 +46,10 @@ void System::motion(DinkyECS::World &world, Map &game_map) {
|
|||
motion = {0,0}; // clear it after getting it
|
||||
|
||||
if(game_map.inmap(move_to.x, move_to.y) &&
|
||||
!game_map.iswall(move_to.x,move_to.y))
|
||||
!game_map.iswall(move_to.x, move_to.y) &&
|
||||
!collider.occupied(move_to))
|
||||
{
|
||||
collider.move(position.location, move_to, ent);
|
||||
position.location = move_to;
|
||||
}
|
||||
}
|
||||
|
@ -46,25 +58,27 @@ void System::motion(DinkyECS::World &world, Map &game_map) {
|
|||
|
||||
|
||||
void System::combat(DinkyECS::World &world, Player &player) {
|
||||
const auto& collider = world.get<SpatialHashTable>();
|
||||
const auto& player_position = world.component<Position>(player.entity);
|
||||
auto& player_combat = world.component<Combat>(player.entity);
|
||||
auto& log = world.get<ActionLog>();
|
||||
|
||||
world.system<Position, Combat>([&](const auto &ent, auto &pos, auto &combat) {
|
||||
if(ent != player.entity) {
|
||||
int dx = std::abs(int(pos.location.x) - int(player_position.location.x));
|
||||
int dy = std::abs(int(pos.location.y) - int(player_position.location.y));
|
||||
// this is guaranteed to not return the given position
|
||||
auto [found, nearby] = collider.neighbors(player_position.location);
|
||||
|
||||
if(dx <= 1 && dy <= 1) {
|
||||
if(player_combat.hp > -1) {
|
||||
int dmg = Random::uniform<int>(1, combat.damage);
|
||||
player_combat.hp -= dmg;
|
||||
|
||||
log.log(format("HIT! You took {} damage.", dmg));
|
||||
}
|
||||
}
|
||||
if(found) {
|
||||
for(auto entity : nearby) {
|
||||
int attack = Random::uniform<int>(0,1);
|
||||
if(attack) {
|
||||
const auto& enemy_dmg = world.component<Combat>(entity);
|
||||
int dmg = Random::uniform<int>(1, enemy_dmg.damage);
|
||||
player_combat.hp -= dmg;
|
||||
log.log(format("HIT! You took {} damage.", dmg));
|
||||
} else {
|
||||
log.log("You dodged! Run!");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void System::draw_entities(DinkyECS::World &world, Map &game_map, ftxui::Canvas &canvas, const Point &cam_orig, size_t view_x, size_t view_y) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue