|
|
|
#include "collider.hpp"
|
|
|
|
|
|
|
|
using DinkyECS::Entity;
|
|
|
|
|
|
|
|
void SpatialHashTable::insert(Point pos, Entity ent) {
|
|
|
|
table[pos] = ent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SpatialHashTable::remove(Point pos) {
|
|
|
|
table.erase(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SpatialHashTable::move(Point from, Point to, Entity ent) {
|
|
|
|
remove(from);
|
|
|
|
insert(to, ent);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SpatialHashTable::occupied(Point at) const {
|
|
|
|
return table.contains(at);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void find_neighbor(const PointEntityMap &table, FoundList &result, Point at) {
|
|
|
|
auto it = table.find(at);
|
|
|
|
if (it != table.end()) {
|
|
|
|
result.insert(result.end(), it->second);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::tuple<bool, FoundList> SpatialHashTable::neighbors(Point cell, bool diag) const {
|
|
|
|
FoundList result;
|
|
|
|
|
|
|
|
// 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.x, cell.y+1}); // north
|
|
|
|
find_neighbor(table, result, {cell.x, cell.y-1}); // south
|
|
|
|
find_neighbor(table, result, {cell.x+1, cell.y}); // east
|
|
|
|
find_neighbor(table, result, {cell.x-1, cell.y}); // west
|
|
|
|
find_neighbor(table, result, {cell.x+1, cell.y-1}); // south east
|
|
|
|
|
|
|
|
if(diag) {
|
|
|
|
find_neighbor(table, result, {cell.x-1, cell.y-1}); // south west
|
|
|
|
find_neighbor(table, result, {cell.x+1, cell.y+1}); // north east
|
|
|
|
find_neighbor(table, result, {cell.x-1, cell.y+1}); // north west
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::tuple(!result.empty(), result);
|
|
|
|
}
|