From 88656e757c4d14a684a4965f5e288c5a1882cb1d Mon Sep 17 00:00:00 2001 From: Matthew Jimenez Date: Wed, 27 Sep 2023 21:33:06 -0500 Subject: [PATCH] ULTIMA8: Adjust flat item rules based on more examples at map 37 --- engines/ultima/ultima8/world/sort_item.h | 36 ++++++++++++++----- test/engines/ultima/ultima8/world/sort_item.h | 26 ++++++++++++++ 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/engines/ultima/ultima8/world/sort_item.h b/engines/ultima/ultima8/world/sort_item.h index 9ec31c22d2a..b0335ed5a94 100644 --- a/engines/ultima/ultima8/world/sort_item.h +++ b/engines/ultima/ultima8/world/sort_item.h @@ -498,22 +498,42 @@ inline bool SortItem::below(const SortItem &si2) const { if (si1._roof != si2._roof) return si1._roof > si2._roof; - // X-Flat gets drawn after when past center point + // X-Flat gets drawn after under specific conditions bool xFlat1 = si1._xLeft == si1._x; bool xFlat2 = si2._xLeft == si2._x; if (xFlat1 != xFlat2 && si1._fixed == si2._fixed) { - int32 xCenter1 = (si1._xLeft + si1._x) / 2; - int32 xCenter2 = (si2._xLeft + si2._x) / 2; - return xFlat1 ? xCenter1 <= xCenter2 : xCenter1 < xCenter2; + if (xFlat1) { + if (si2._x - 32 > si2._xLeft) { + int32 xCenter2 = (si2._xLeft + si2._x) / 2; + return si1._x <= xCenter2; + } + return false; + } else { + if (si1._x - 32 > si1._xLeft) { + int32 xCenter1 = (si1._xLeft + si1._x) / 2; + return xCenter1 < si2._x; + } + return true; + } } - // Y-Flat gets drawn after when past center point + // Y-Flat gets drawn after under specific conditions bool yFlat1 = si1._yFar == si1._y; bool yFlat2 = si2._yFar == si2._y; if (yFlat1 != yFlat2 && si1._fixed == si2._fixed) { - int32 yCenter1 = (si1._yFar + si1._y) / 2; - int32 yCenter2 = (si2._yFar + si2._y) / 2; - return yFlat1 ? yCenter1 <= yCenter2 : yCenter1 < yCenter2; + if (yFlat1) { + if (si2._y - 32 > si2._yFar) { + int32 yCenter2 = (si2._yFar + si2._y) / 2; + return si1._y <= yCenter2; + } + return false; + } else { + if (si1._y - 32 > si1._yFar) { + int32 yCenter1 = (si1._yFar + si1._y) / 2; + return yCenter1 < si2._y; + } + return true; + } } // Partial in X + Y front diff --git a/test/engines/ultima/ultima8/world/sort_item.h b/test/engines/ultima/ultima8/world/sort_item.h index 9f3b370318d..b37c52f51d1 100644 --- a/test/engines/ultima/ultima8/world/sort_item.h +++ b/test/engines/ultima/ultima8/world/sort_item.h @@ -319,6 +319,30 @@ class U8SortItemTestSuite : public CxxTest::TestSuite { TS_ASSERT(!si2.below(si1)); } + /** + * Overlapping x-flat vs non-flat wall with x-flat far inside wall + * Test case for rendering issue at MainActor::teleport 37 17619 17767 104 + * Tapestry should draw after wall again + */ + void test_x_flat_vs_thin_wall_sort() { + Ultima::Ultima8::SortItem si1; + Ultima::Ultima8::SortItem si2; + + Ultima::Ultima8::Box b1(17439, 17535, 104, 32, 128, 40); + si1.setBoxBounds(b1, 0, 0); + si1._solid = true; + si1._occl = true; + si1._land = true; + si1._fixed = true; + + Ultima::Ultima8::Box b2(17410, 17502, 96, 0, 96, 40); + si2.setBoxBounds(b2, 0, 0); + si2._fixed = true; + + TS_ASSERT(si1.below(si2)); + TS_ASSERT(!si2.below(si1)); + } + /** * Overlapping x-flat vs non-flat items but the flat item was misplaced * Test case for rendering issue at MainActor::teleport 41 19411 15787 48 @@ -406,9 +430,11 @@ class U8SortItemTestSuite : public CxxTest::TestSuite { si1._trans = true; si1._solid = true; si1._land = true; + si1._fixed = true; Ultima::Ultima8::Box b2(20543, 9855, 48, 96, 0, 16); si2.setBoxBounds(b2, 0, 0); + si2._fixed = true; TS_ASSERT(si1.overlap(si2)); TS_ASSERT(si2.overlap(si1));