Prep for fixing the spatialmap to allow for entities without collision to still be in the space.

master
Zed A. Shaw 7 days ago
parent d93bc1615c
commit fd53f92fe6
  1. 6
      levelmanager.cpp
  2. 34
      spatialmap.cpp
  3. 4
      spatialmap.hpp
  4. 18
      systems.cpp
  5. 1
      systems.hpp
  6. 12
      worldbuilder.cpp
  7. 5
      worldbuilder.hpp

@ -101,14 +101,10 @@ size_t LevelManager::create_level(shared_ptr<DinkyECS::World> prev_world) {
size_t index = $levels.size();
auto collider = make_shared<SpatialMap>();
// not sure if this is still needed
System::init_positions(*world, *collider);
auto player = world->get_the<Player>();
$levels.emplace_back(index, player.entity, map, world,
make_shared<LightRender>(map->tiles()), collider);
make_shared<LightRender>(map->tiles()), builder.$collision);
dbc::check(index == $levels.size() - 1, "Level index is not the same as $levels.size() - 1, off by one error");
return index;

@ -6,11 +6,11 @@ using namespace fmt;
using DinkyECS::Entity;
void SpatialMap::insert(Point pos, Entity ent) {
table[pos] = ent;
yes_collision.insert_or_assign(pos, ent);
}
void SpatialMap::remove(Point pos) {
table.erase(pos);
yes_collision.erase(pos);
}
void SpatialMap::move(Point from, Point to, Entity ent) {
@ -19,11 +19,11 @@ void SpatialMap::move(Point from, Point to, Entity ent) {
}
bool SpatialMap::occupied(Point at) const {
return table.contains(at);
return yes_collision.contains(at);
}
Entity SpatialMap::get(Point at) const {
return table.at(at);
return yes_collision.at(at);
}
/*
@ -50,24 +50,22 @@ FoundEntities SpatialMap::neighbors(Point cell, bool diag) const {
// just unroll the loop since we only check four directions
// this also solves the problem that it was detecting that the cell was automatically included as a "neighbor" but it's not
find_neighbor(table, result, cell, 0, 1); // north
find_neighbor(table, result, cell, 0, -1); // south
find_neighbor(table, result, cell, 1, 0); // east
find_neighbor(table, result, cell, -1, 0); // west
find_neighbor(yes_collision, result, cell, 0, 1); // north
find_neighbor(yes_collision, result, cell, 0, -1); // south
find_neighbor(yes_collision, result, cell, 1, 0); // east
find_neighbor(yes_collision, result, cell, -1, 0); // west
if(diag) {
find_neighbor(table, result, cell, 1, -1); // south east
find_neighbor(table, result, cell, -1, -1); // south west
find_neighbor(table, result, cell, 1, 1); // north east
find_neighbor(table, result, cell, -1, 1); // north west
find_neighbor(yes_collision, result, cell, 1, -1); // south east
find_neighbor(yes_collision, result, cell, -1, -1); // south west
find_neighbor(yes_collision, result, cell, 1, 1); // north east
find_neighbor(yes_collision, result, cell, -1, 1); // north west
}
return {!result.empty(), result};
}
SortedEntities SpatialMap::distance_sorted(Point from, int max_dist) {
SortedEntities sprite_distance;
inline void update_sorted(SortedEntities& sprite_distance, PointEntityMap& table, Point from, int max_dist) {
for(const auto &rec : table) {
Point sprite = rec.first;
int inside = (from.x - sprite.x) * (from.x - sprite.x) +
@ -77,6 +75,12 @@ SortedEntities SpatialMap::distance_sorted(Point from, int max_dist) {
sprite_distance.push_back({inside, rec.second});
}
}
}
SortedEntities SpatialMap::distance_sorted(Point from, int max_dist) {
SortedEntities sprite_distance;
update_sorted(sprite_distance, yes_collision, from, max_dist);
std::sort(sprite_distance.begin(), sprite_distance.end(), std::greater<>());

@ -19,7 +19,7 @@ struct FoundEntities {
class SpatialMap {
public:
SpatialMap() {}
PointEntityMap table;
PointEntityMap yes_collision;
void insert(Point pos, DinkyECS::Entity obj);
void move(Point from, Point to, DinkyECS::Entity ent);
@ -29,5 +29,5 @@ class SpatialMap {
FoundEntities neighbors(Point position, bool diag=false) const;
SortedEntities distance_sorted(Point from, int max_distance);
size_t size() { return table.size(); }
size_t size() { return yes_collision.size(); }
};

@ -106,24 +106,6 @@ void System::enemy_pathing(GameLevel &level) {
map.clear_target(player_position.location);
}
void System::init_positions(World &world, SpatialMap &collider) {
auto player = world.get_the<Player>();
auto& inv = world.get<inventory::Model>(player.entity);
world.query<Position>([&](auto ent, auto &pos) {
if(world.has<Combat>(ent)) {
const auto& combat = world.get<Combat>(ent);
if(!combat.dead) {
collider.insert(pos.location, ent);
}
} else {
dbc::check(!inv.has(ent),
fmt::format("!!! Entity {} is in player inventory and _also_ has a position in the world.", ent));
collider.insert(pos.location, ent);
}
});
}
inline void move_entity(SpatialMap &collider, Map &game_map, Position &position, Motion &motion, Entity ent) {
Point move_to = {

@ -16,7 +16,6 @@ namespace System {
void enemy_pathing(GameLevel &level);
void enemy_ai_initialize(GameLevel &level);
void init_positions(World &world, SpatialMap &collider);
void device(World &world, Entity actor, Entity item);
void plan_motion(World& world, Position move_to);
Entity spawn_item(World& world, const string& name);

@ -69,7 +69,7 @@ bool WorldBuilder::find_open_spot(Point& pos_out) {
for(matrix::rando_box it{$map.walls(), pos_out.x, pos_out.y, i}; it.next();) {
Point test{size_t(it.x), size_t(it.y)};
if($map.can_move(test) && !$collision.occupied(test)) {
if($map.can_move(test) && !$collision->occupied(test)) {
pos_out = test;
return true;
}
@ -99,7 +99,7 @@ DinkyECS::Entity WorldBuilder::configure_entity_in_map(DinkyECS::World &world, j
components::configure_entity(world, item, entity_data["components"]);
}
$collision.insert(pos, item);
$collision->insert(pos, item);
return item;
}
@ -224,14 +224,6 @@ void WorldBuilder::place_entities(DinkyECS::World &world) {
dbc::check(player_pos.location.x != 0 && player_pos.location.y != 0,
"failed to place the player correctly");
// make a dead zone around the player
auto& player = world.get_the<Player>();
for(matrix::box it{$map.walls(), player_pos.location.x, player_pos.location.y, 2};
it.next();)
{
$collision.insert({it.x, it.y}, player.entity);
}
randomize_entities(world, config);
place_stairs(world, config);
}

@ -8,10 +8,11 @@
class WorldBuilder {
public:
Map& $map;
SpatialMap $collision;
std::shared_ptr<SpatialMap> $collision;
WorldBuilder(Map &map) :
$map(map)
$map(map),
$collision(std::make_shared<SpatialMap>())
{ }
void generate_map();

Loading…
Cancel
Save