Fix up the spatialmap to have an occupied_by method which checks if a square is occupied and returns what is there.

This commit is contained in:
Zed A. Shaw 2025-09-02 12:46:05 -04:00
parent 759f93cae0
commit a11e7de14e
7 changed files with 24 additions and 43 deletions

View file

@ -303,11 +303,10 @@ bool Autowalker::found_enemy() {
for(matrix::compass it{level.map->$walls, player.location.x, player.location.y}; it.next();) {
Point aim{it.x, it.y};
if(aim != player.aiming_at ||
!level.collision->occupied(player.aiming_at)) continue;
auto aimed_ent = level.collision->occupied_by(player.aiming_at);
if(aim != player.aiming_at || aimed_ent == DinkyECS::NONE) continue;
auto ent = level.collision->get(player.aiming_at);
if(level.world->has<components::Combat>(ent)) return true;
if(level.world->has<components::Combat>(aimed_ent)) return true;
}
return false;

View file

@ -102,9 +102,7 @@ namespace gui {
void MainUI::render_mind_reading() {
auto level = GameDB::current_level();
if(level.collision->occupied($rayview->aiming_at)) {
auto entity = level.collision->get($rayview->aiming_at);
if(auto entity = level.collision->occupied_by($rayview->aiming_at)) {
if(auto enemy_ai = level.world->get_if<ai::EntityAI>(entity)) {
$overlay_ui.show_text("left", fmt::format(L"AI: {}",
guecs::to_wstring(enemy_ai->to_string())));

View file

@ -32,15 +32,19 @@ void SpatialMap::move(Point from, Point to, Entity ent) {
insert(to, ent, data.collision);
}
bool SpatialMap::occupied(Point at) const {
Entity SpatialMap::occupied_by(Point at) const {
auto [begin, end] = $collision.equal_range(at);
for(auto it = begin; it != end; ++it) {
if(it->second.collision) {
return true;
return it->second.entity;
}
}
return false;
return DinkyECS::NONE;
}
bool SpatialMap::occupied(Point at) const {
return occupied_by(at) != DinkyECS::NONE;
}
bool SpatialMap::something_there(Point at) const {

View file

@ -35,6 +35,7 @@ class SpatialMap {
void move(Point from, Point to, DinkyECS::Entity ent);
// return value is whether the removed thing has collision
CollisionData remove(Point pos, DinkyECS::Entity entity);
DinkyECS::Entity occupied_by(Point pos) const;
bool occupied(Point pos) const;
bool something_there(Point at) const;
DinkyECS::Entity get(Point at) const;

View file

@ -38,9 +38,5 @@ TEST_CASE("lighting a map works", "[lighting]") {
lr.clear_light_target(light2);
Matrix &lighting = lr.lighting();
matrix::dump("WALLS=====", map.walls(), light1.x, light1.y);
matrix::dump("PATHS=====", lr.paths(), light1.x, light1.y);
matrix::dump("LIGHTING 1", lighting, light1.x, light1.y);
matrix::dump("LIGHTING 2", lighting, light2.x, light2.y);
(void)lighting;
}

View file

@ -27,11 +27,12 @@ TEST_CASE("SpatialMap::insert", "[spatialmap]") {
REQUIRE(!map.occupied(at));
map.insert(at, player, true);
REQUIRE(map.occupied(at));
REQUIRE(map.occupied_by(at) == player);
REQUIRE_THROWS(map.insert(at, enemy, true));
map.insert(enemy_at, enemy, true);
REQUIRE(map.occupied_by(enemy_at) == player);
REQUIRE(map.occupied(enemy_at));
}
@ -47,6 +48,7 @@ TEST_CASE("SpatialMap::remove", "[spatialmap]") {
map.insert(at, player, true);
map.insert(at, item, false);
REQUIRE(map.occupied(at));
REQUIRE(map.occupied_by(at) == player);
auto data = map.remove(at, player);
REQUIRE(!map.occupied(at));
@ -74,6 +76,7 @@ TEST_CASE("SpatialMap::move", "[spatialmap]") {
map.insert(enemy_at, enemy, true);
map.insert(enemy_at, potion, false);
REQUIRE(map.occupied(enemy_at));
REQUIRE(map.occupied_by(enemy_at) == enemy);
Point target{at.x + 1, at.y};
@ -89,6 +92,7 @@ TEST_CASE("SpatialMap::move", "[spatialmap]") {
map.move(at, target, player);
REQUIRE(map.occupied(target));
REQUIRE(map.occupied_by(target) == player);
auto data = map.remove(target, player);
REQUIRE(data.entity == player);
REQUIRE(data.collision == true);
@ -116,12 +120,14 @@ TEST_CASE("SpatialMap::occupied/something_there", "[spatialmap]") {
map.insert(at, player, true);
REQUIRE(map.something_there(at));
REQUIRE(map.occupied(at));
REQUIRE(map.occupied_by(at) == player);
// then remove the item and still have collision
map.remove(at, item);
REQUIRE(map.something_there(at));
REQUIRE(map.occupied(at));
REQUIRE(map.occupied_by(at) == player);
// remove player and back to no collision
map.remove(at, player);
@ -133,6 +139,7 @@ TEST_CASE("SpatialMap::occupied/something_there", "[spatialmap]") {
map.insert(target, player, true);
REQUIRE(map.something_there(target));
REQUIRE(map.occupied(target));
REQUIRE(map.occupied_by(target) == player);
}
@ -147,6 +154,7 @@ TEST_CASE("SpatialMap::get", "[spatialmap]") {
// finally with collision and an item there
map.insert(at, player, true);
REQUIRE(map.occupied(at));
REQUIRE(map.occupied_by(at) == player);
auto entity = map.get(at);
REQUIRE(player == entity);

View file

@ -4,19 +4,6 @@
#include <cmath>
#include <numbers>
/*
face_x := rand.Float64() * 100
face_y := rand.Float64() * 100
target_x := rand.Float64() * 100
target_y := rand.Float64() * 100
rad_angle1 := atan2(target_y, target_x)
rad_angle2 := atan2(face_y, face_x)
diff := rad_angle1 - rad_angle2
if diff < 0 { fmt.Printf("\nTurn Right") }
else { fmt.Printf("\nTurn Left") }
*/
TEST_CASE("figure out best rotation direction", "[systems-rotate]") {
Matrix map = matrix::make(3, 3);
@ -34,26 +21,14 @@ TEST_CASE("figure out best rotation direction", "[systems-rotate]") {
float aiming_dx = float(player_at.x) - float(aiming_at.x);
float aiming_dy = float(player_at.y) - float(aiming_at.y);
fmt::println("target_d={},{}; aiming_d={},{}",
target_dx, target_dy, aiming_dx, aiming_dy);
float target_angle = atan2(-target_dy, target_dx) * (180.0 / std::numbers::pi);
float aiming_angle = atan2(-aiming_dy, aiming_dx) * (180.0 / std::numbers::pi);
float diff = target_angle - aiming_angle;
double normalized = fmod(diff + 360.0, 360.0);
fmt::println("\n\n>>>>>>>>> BEGIN");
if(normalized != diff) fmt::println("YOU NEED NORMALIZED");
fmt::println("aming_angle={}, target_angle={}, delta={}, norm={}",
aiming_angle, target_angle, diff, normalized);
fmt::println("TURN {}", normalized < 180.0 ? "LEFT" : "RIGHT");
matrix::dump("< is target, a is aim", map, target.x, target.y);
fmt::println("-----------------END");
REQUIRE(normalized >= 0);
REQUIRE(normalized <= 360);
map[aiming_at.y][aiming_at.x] = 0;
}