From a11e7de14eb79c7e8734351e5fb79ca2052c4059 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Tue, 2 Sep 2025 12:46:05 -0400 Subject: [PATCH] Fix up the spatialmap to have an occupied_by method which checks if a square is occupied and returns what is there. --- autowalker.cpp | 7 +++---- gui/main_ui.cpp | 4 +--- spatialmap.cpp | 10 +++++++--- spatialmap.hpp | 1 + tests/lighting.cpp | 6 +----- tests/spatialmap.cpp | 10 +++++++++- tests/systems.cpp | 29 ++--------------------------- 7 files changed, 24 insertions(+), 43 deletions(-) diff --git a/autowalker.cpp b/autowalker.cpp index 4a0adc4..b2df92f 100644 --- a/autowalker.cpp +++ b/autowalker.cpp @@ -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(ent)) return true; + if(level.world->has(aimed_ent)) return true; } return false; diff --git a/gui/main_ui.cpp b/gui/main_ui.cpp index 57e7c76..018df0f 100644 --- a/gui/main_ui.cpp +++ b/gui/main_ui.cpp @@ -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(entity)) { $overlay_ui.show_text("left", fmt::format(L"AI: {}", guecs::to_wstring(enemy_ai->to_string()))); diff --git a/spatialmap.cpp b/spatialmap.cpp index 5a26306..8b34998 100644 --- a/spatialmap.cpp +++ b/spatialmap.cpp @@ -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 { diff --git a/spatialmap.hpp b/spatialmap.hpp index 363c0a1..efa33c7 100644 --- a/spatialmap.hpp +++ b/spatialmap.hpp @@ -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; diff --git a/tests/lighting.cpp b/tests/lighting.cpp index 54617c8..3f7d7df 100644 --- a/tests/lighting.cpp +++ b/tests/lighting.cpp @@ -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; } diff --git a/tests/spatialmap.cpp b/tests/spatialmap.cpp index c4168ec..7b953e7 100644 --- a/tests/spatialmap.cpp +++ b/tests/spatialmap.cpp @@ -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); diff --git a/tests/systems.cpp b/tests/systems.cpp index b22c7db..1d42126 100644 --- a/tests/systems.cpp +++ b/tests/systems.cpp @@ -4,19 +4,6 @@ #include #include -/* - 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; }