ULTIMA8: Check x & y flat rules before z flat rules.

This commit is contained in:
Matthew Jimenez 2023-10-04 14:58:45 -05:00
parent a6bde075f1
commit 4c1f8dfc59
2 changed files with 64 additions and 37 deletions

View File

@ -107,6 +107,40 @@ bool SortItem::below(const SortItem &si2) const {
return false;
}
// Check with a tolerance based on footpad calculations
if (si1._zTop - 8 <= si2._z && si1._z < si2._zTop - 8)
return true;
if (si1._z >= si2._zTop - 8 && si1._zTop - 8 > si2._z)
return false;
// Y-flat vs non-flat handling
if (yFlat1 != yFlat2) {
// Check with a precision loss based on footpad calculations
if (si1._y / 32 <= si2._yFar / 32)
return true;
if (si1._yFar / 32 >= si2._y / 32)
return false;
int32 yCenter1 = (si1._yFar / 32 + si1._y / 32) / 2;
int32 yCenter2 = (si2._yFar / 32 + si2._y / 32) / 2;
if (yCenter1 != yCenter2)
return yCenter1 < yCenter2;
}
// X-flat vs non-flat handling
if (xFlat1 != xFlat2) {
// Check with a precision loss based on footpad calculations
if (si1._x / 32 <= si2._xLeft / 32)
return true;
if (si1._xLeft / 32 >= si2._x / 32)
return false;
int32 xCenter1 = (si1._xLeft / 32 + si1._x / 32) / 2;
int32 xCenter2 = (si2._xLeft / 32 + si2._x / 32) / 2;
if (xCenter1 != xCenter2)
return xCenter1 < xCenter2;
}
// Specialist z flat handling
if (si1._flat || si2._flat) {
// Lower z-bottom drawn before
@ -146,40 +180,6 @@ bool SortItem::below(const SortItem &si2) const {
return si1._fbigsq > si2._fbigsq;
}
// Check with a tolerance based on footpad calculations
if (si1._zTop - 8 <= si2._z && si1._z < si2._zTop - 8)
return true;
if (si1._z >= si2._zTop - 8 && si1._zTop - 8 > si2._z)
return false;
// Y-flat vs non-flat handling
if (yFlat1 != yFlat2) {
// Check with a precision loss based on footpad calculations
if (si1._y / 32 <= si2._yFar / 32)
return true;
if (si1._yFar / 32 >= si2._y / 32)
return false;
int32 yCenter1 = (si1._yFar / 32 + si1._y / 32) / 2;
int32 yCenter2 = (si2._yFar / 32 + si2._y / 32) / 2;
if (yCenter1 != yCenter2)
return yCenter1 < yCenter2;
}
// X-flat vs non-flat handling
if (xFlat1 != xFlat2) {
// Check with a precision loss based on footpad calculations
if (si1._x / 32 <= si2._xLeft / 32)
return true;
if (si1._xLeft / 32 >= si2._x / 32)
return false;
int32 xCenter1 = (si1._xLeft / 32 + si1._x / 32) / 2;
int32 xCenter2 = (si2._xLeft / 32 + si2._x / 32) / 2;
if (xCenter1 != xCenter2)
return xCenter1 < xCenter2;
}
// Specialist handling for same location
if (si1._x == si2._x && si1._y == si2._y) {
// Trans always gets drawn after

View File

@ -402,7 +402,7 @@ class U8SortItemTestSuite : public CxxTest::TestSuite {
Ultima::Ultima8::Box b2(17408, 17888, 96, 0, 96, 40);
si2.setBoxBounds(b2, 0, 0);
si1._fixed = true;
si2._fixed = true;
TS_ASSERT(si1.overlap(si2));
TS_ASSERT(si2.overlap(si1));
@ -425,7 +425,7 @@ class U8SortItemTestSuite : public CxxTest::TestSuite {
Ultima::Ultima8::Box b2(2111, 1055, 48, 96, 0, 40);
si2.setBoxBounds(b2, 0, 0);
si1._fixed = true;
si2._fixed = true;
TS_ASSERT(si1.overlap(si2));
TS_ASSERT(si2.overlap(si1));
@ -449,7 +449,7 @@ class U8SortItemTestSuite : public CxxTest::TestSuite {
Ultima::Ultima8::Box b2(2175, 1055, 48, 96, 0, 40);
si2.setBoxBounds(b2, 0, 0);
si1._fixed = true;
si2._fixed = true;
// These share a one pixel edge, but we need to ignore that currently to prevent paint dependency cycles
TS_ASSERT(!si1.overlap(si2));
@ -512,6 +512,33 @@ class U8SortItemTestSuite : public CxxTest::TestSuite {
TS_ASSERT(!si2.below(si1));
}
/**
* Overlapping y-flat vs z-flat floor where z order not clear
* Test case for rendering issue at MainActor::teleport 37 22546 18656 56
* Vines should draw after floor
*/
void test_y_flat_z_tolerance_sort() {
Ultima::Ultima8::SortItem si1;
Ultima::Ultima8::SortItem si2;
Ultima::Ultima8::Box b1(22271, 18431, 56, 128, 128, 0);
si1.setBoxBounds(b1, 0, 0);
si1._solid = true;
si1._occl = true;
si1._land = true;
si1._fixed = true;
Ultima::Ultima8::Box b2(22367, 18399, 48, 128, 0, 40);
si2.setBoxBounds(b2, 0, 0);
si2._fixed = true;
TS_ASSERT(si1.overlap(si2));
TS_ASSERT(si2.overlap(si1));
TS_ASSERT(si1.below(si2));
TS_ASSERT(!si2.below(si1));
}
/**
* Overlapping fixed y-flat vs non-fixed non-flat items where the flat should draw first
* Test case for rendering issue at MainActor::teleport 3 12355 5467 8