mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Compare commits
4 commits
c64c6763a5
...
2abb7337fd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2abb7337fd | ||
|
|
5f63f9e497 | ||
|
|
402de88f25 | ||
|
|
626c91e02b |
2 changed files with 86 additions and 19 deletions
|
|
@ -313,12 +313,12 @@ TS_ASSERT(cmpTurretHolder.OccupiesTurretPoint(spawned));
|
|||
TS_ASSERT_EQUALS(cmpHolderPassable.GetClosestApproachDistanceToTurretPoint("center"), 0);
|
||||
|
||||
// No obstruction component at all
|
||||
const cmpHolderNoObst = ConstructComponent(++entityID, "TurretHolder", {
|
||||
++entityID;
|
||||
const cmpHolderNoObst = ConstructComponent(entityID, "TurretHolder", {
|
||||
"TurretPoints": {
|
||||
"center": { "X": "0", "Y": "5.0", "Z": "0" }
|
||||
}
|
||||
});
|
||||
const result = cmpHolderNoObst.GetClosestApproachDistanceToTurretPoint("center");
|
||||
TS_ASSERT_EQUALS(result, 0);
|
||||
TS_ASSERT_EQUALS(cmpHolderNoObst.GetClosestApproachDistanceToTurretPoint("center"), 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void test_queries()
|
||||
void test_range_queries_distance_only()
|
||||
{
|
||||
ComponentTestHelper test(*g_ScriptContext);
|
||||
|
||||
|
|
@ -242,8 +242,9 @@ public:
|
|||
{ CMessageCreate msg(100); rangeManager->HandleMessage(msg, false); }
|
||||
{ CMessageCreate msg(101); rangeManager->HandleMessage(msg, false); }
|
||||
|
||||
{ CMessageOwnershipChanged msg(100, -1, 1); rangeManager->HandleMessage(msg, false); }
|
||||
{ CMessageOwnershipChanged msg(101, -1, 1); rangeManager->HandleMessage(msg, false); }
|
||||
// Don't set ownership for either entity - leave both as INVALID_PLAYER.
|
||||
// This bypasses the visibility check in TestEntityQuery, allowing us to test
|
||||
// the core distance calculation logic independently of the LOS system.
|
||||
|
||||
auto move = [&rangeManager](entity_id_t ent, MockPositionRgm& pos, fixed x, fixed z) {
|
||||
pos.m_Pos = CFixedVector3D(x, fixed::Zero(), z);
|
||||
|
|
@ -253,45 +254,111 @@ public:
|
|||
move(100, position, fixed::FromInt(10), fixed::FromInt(10));
|
||||
move(101, position2, fixed::FromInt(10), fixed::FromInt(20));
|
||||
|
||||
std::vector<entity_id_t> nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0, true);
|
||||
// Query for owner -1 (INVALID_PLAYER) since both entities have no owner
|
||||
std::vector<entity_id_t> nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{});
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{101});
|
||||
|
||||
move(101, position2, fixed::FromInt(10), fixed::FromInt(10));
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{101});
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{});
|
||||
|
||||
move(101, position2, fixed::FromInt(10), fixed::FromInt(13));
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{101});
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(4), fixed::FromInt(50), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{});
|
||||
|
||||
move(101, position2, fixed::FromInt(10), fixed::FromInt(15));
|
||||
// In range thanks to self obstruction size.
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(4), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{101});
|
||||
// In range thanks to target obstruction size.
|
||||
nearby = rangeManager->ExecuteQuery(101, fixed::FromInt(0), fixed::FromInt(4), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(101, fixed::FromInt(0), fixed::FromInt(4), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{100});
|
||||
|
||||
// Trickier: min-range is closest-to-closest, but rotation may change the real distance.
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(2), fixed::FromInt(50), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(2), fixed::FromInt(50), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{101});
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(5), fixed::FromInt(50), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(5), fixed::FromInt(50), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{101});
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(6), fixed::FromInt(50), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(6), fixed::FromInt(50), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{});
|
||||
nearby = rangeManager->ExecuteQuery(101, fixed::FromInt(5), fixed::FromInt(50), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(101, fixed::FromInt(5), fixed::FromInt(50), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{100});
|
||||
nearby = rangeManager->ExecuteQuery(101, fixed::FromInt(6), fixed::FromInt(50), {1}, 0, true);
|
||||
nearby = rangeManager->ExecuteQuery(101, fixed::FromInt(6), fixed::FromInt(50), {-1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{});
|
||||
|
||||
}
|
||||
|
||||
void test_range_queries_visibility_filtering()
|
||||
{
|
||||
ComponentTestHelper test(*g_ScriptContext);
|
||||
|
||||
ICmpRangeManager* rangeManager = test.Add<ICmpRangeManager>(CID_RangeManager, "", SYSTEM_ENTITY);
|
||||
|
||||
MockVisionRgm vision, vision2;
|
||||
MockPositionRgm position, position2;
|
||||
MockObstructionRgm obs(fixed::FromInt(2)), obs2(fixed::Zero());
|
||||
test.AddMock(100, IID_Vision, vision);
|
||||
test.AddMock(100, IID_Position, position);
|
||||
test.AddMock(100, IID_Obstruction, obs);
|
||||
|
||||
test.AddMock(101, IID_Vision, vision2);
|
||||
test.AddMock(101, IID_Position, position2);
|
||||
test.AddMock(101, IID_Obstruction, obs2);
|
||||
|
||||
rangeManager->SetBounds(entity_pos_t::FromInt(0), entity_pos_t::FromInt(0), entity_pos_t::FromInt(512), entity_pos_t::FromInt(512));
|
||||
rangeManager->Verify();
|
||||
{ CMessageCreate msg(100); rangeManager->HandleMessage(msg, false); }
|
||||
{ CMessageCreate msg(101); rangeManager->HandleMessage(msg, false); }
|
||||
|
||||
// Set ownership for both entities so they have proper owners
|
||||
{ CMessageOwnershipChanged msg(100, -1, 1); rangeManager->HandleMessage(msg, false); }
|
||||
{ CMessageOwnershipChanged msg(101, -1, 1); rangeManager->HandleMessage(msg, false); }
|
||||
|
||||
auto move = [&rangeManager](entity_id_t ent, MockPositionRgm& pos, fixed x, fixed z) {
|
||||
pos.m_Pos = CFixedVector3D(x, fixed::Zero(), z);
|
||||
{ CMessagePositionChanged msg(ent, true, x, z, entity_angle_t::Zero()); rangeManager->HandleMessage(msg, false); }
|
||||
};
|
||||
|
||||
move(100, position, fixed::FromInt(10), fixed::FromInt(10));
|
||||
move(101, position2, fixed::FromInt(10), fixed::FromInt(15));
|
||||
|
||||
// Note: Full LOS testing (vision range, terrain, fog) requires a full game world
|
||||
// with terrain, water, and proper pathfinding. That's beyond the scope of this
|
||||
// unit test. The visibility test here verifies that ExecuteQuery respects the
|
||||
// reveal whole map flag, which exercises the visibility check path in TestEntityQuery.
|
||||
|
||||
// Enable "reveal whole map" to force all entities to be visible
|
||||
rangeManager->SetLosRevealWholeMap(1, true);
|
||||
|
||||
// Process an update
|
||||
{ CMessageUpdate msg(fixed::FromInt(1)); rangeManager->HandleMessage(msg, false); }
|
||||
|
||||
// Entity 101 should be visible (due to reveal map) and in range
|
||||
std::vector<entity_id_t> nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(50), {1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{101});
|
||||
|
||||
// Disable "reveal whole map" to test hidden entities
|
||||
rangeManager->SetLosRevealWholeMap(1, false);
|
||||
{ CMessageUpdate msg(fixed::FromInt(1)); rangeManager->HandleMessage(msg, false); }
|
||||
|
||||
// Entity 101 should now be hidden because LOS isn't properly set up
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(50), {1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{});
|
||||
|
||||
// Re-enable reveal map to show it works again
|
||||
rangeManager->SetLosRevealWholeMap(1, true);
|
||||
{ CMessageUpdate msg(fixed::FromInt(1)); rangeManager->HandleMessage(msg, false); }
|
||||
|
||||
nearby = rangeManager->ExecuteQuery(100, fixed::FromInt(0), fixed::FromInt(50), {1}, 0, true);
|
||||
TS_ASSERT_EQUALS(nearby, std::vector<entity_id_t>{101});
|
||||
}
|
||||
|
||||
void test_ParabolicRangeBasic()
|
||||
{
|
||||
ComponentTestHelper test(*g_ScriptContext);
|
||||
|
|
|
|||
Loading…
Reference in a new issue