mirror of
https://github.com/bryanthaboi/gen1recomp
synced 2026-09-29 15:08:50 -04:00
Merge pull request #2392 from bryanthaboi/dev
This commit is contained in:
+70
-117
@@ -19,9 +19,6 @@ FieldView._loggedPal = false
|
||||
FieldView._nativeBatch = nil
|
||||
FieldView._nativeBatches = nil
|
||||
FieldView._nativeOverBatches = nil
|
||||
FieldView._nativeOverByRow = nil
|
||||
FieldView._nativeRows = nil
|
||||
FieldView._nativeCy0 = nil
|
||||
FieldView._nativeBx = nil
|
||||
FieldView._nativeBy = nil
|
||||
FieldView._nativePair = nil
|
||||
@@ -430,23 +427,34 @@ local function pushBillboard(x, y, camX, camY)
|
||||
return true
|
||||
end
|
||||
|
||||
local function isPlayerAboveBg2(playerXOff, playerYOff)
|
||||
if (playerXOff and playerXOff ~= 0) or (playerYOff and playerYOff ~= 0) then
|
||||
return true
|
||||
-- pokefirered/src/event_object_movement.c:8368 sElevationToPriority
|
||||
local ELEVATION_TO_PRIORITY = {
|
||||
[0] = 2, [1] = 2, [2] = 2, [3] = 2,
|
||||
[4] = 1, [5] = 2, [6] = 1, [7] = 2,
|
||||
[8] = 1, [9] = 2, [10] = 1, [11] = 2,
|
||||
[12] = 1, [13] = 0, [14] = 0, [15] = 2,
|
||||
}
|
||||
|
||||
local function actorPriority(a)
|
||||
if a.kind == "player" then
|
||||
local PlayerMod = package.loaded["src.core.game3.player"]
|
||||
if PlayerMod and (PlayerMod.jumping or PlayerMod.surfHopping) then
|
||||
return 1
|
||||
end
|
||||
local WarpMod = package.loaded["src.core.game3.warp"]
|
||||
if WarpMod and WarpMod.isEscalatorActive and WarpMod.isEscalatorActive() then
|
||||
return 1
|
||||
end
|
||||
local SpecialAnim = package.loaded["src.core.game3.special_field_anim"]
|
||||
if SpecialAnim and SpecialAnim.isActive and SpecialAnim.isActive() then
|
||||
return 1
|
||||
end
|
||||
local elev = a.elevation or (PlayerMod and PlayerMod.elevation) or 3
|
||||
return ELEVATION_TO_PRIORITY[elev] or 2
|
||||
else
|
||||
local elev = a.elevation or (a.obj and (a.obj.elevation or (a.obj.def and a.obj.def.elevation))) or 3
|
||||
return ELEVATION_TO_PRIORITY[elev] or 2
|
||||
end
|
||||
local PlayerMod = package.loaded["src.core.game3.player"]
|
||||
if PlayerMod and (PlayerMod.jumping or PlayerMod.surfHopping) then
|
||||
return true
|
||||
end
|
||||
local WarpMod = package.loaded["src.core.game3.warp"]
|
||||
if WarpMod and WarpMod.isEscalatorActive and WarpMod.isEscalatorActive() then
|
||||
return true
|
||||
end
|
||||
local SpecialAnim = package.loaded["src.core.game3.special_field_anim"]
|
||||
if SpecialAnim and SpecialAnim.isActive and SpecialAnim.isActive() then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function drawSingleActor(game, mapDef, a, camX, camY)
|
||||
@@ -501,6 +509,7 @@ local function collectGame3Actors(game, mapDef, camX, camY, px, py, facing, walk
|
||||
kind = "npc",
|
||||
i = eo.localId,
|
||||
obj = eo.def,
|
||||
elevation = eo.elevation or (eo.def and eo.def.elevation) or 0,
|
||||
x = (eo.px or (eo.cellX * CELL)) + (eo.raiseX or 0),
|
||||
y = (eo.py or (eo.cellY * CELL)) + (eo.raiseY or 0),
|
||||
sortY = sortY,
|
||||
@@ -532,6 +541,7 @@ local function collectGame3Actors(game, mapDef, camX, camY, px, py, facing, walk
|
||||
kind = "npc",
|
||||
i = i,
|
||||
obj = npc.def,
|
||||
elevation = npc.elevation or (npc.def and npc.def.elevation) or 0,
|
||||
x = npc.px or ((npc.cellX or 0) * CELL),
|
||||
y = npc.py or ((npc.cellY or 0) * CELL),
|
||||
sortY = npc.py or ((npc.cellY or 0) * CELL),
|
||||
@@ -547,6 +557,7 @@ local function collectGame3Actors(game, mapDef, camX, camY, px, py, facing, walk
|
||||
kind = "npc",
|
||||
i = i,
|
||||
obj = obj,
|
||||
elevation = obj.elevation or 0,
|
||||
x = (tonumber(obj.x) or 0) * CELL,
|
||||
y = (tonumber(obj.y) or 0) * CELL,
|
||||
sortY = (tonumber(obj.y) or 0) * CELL,
|
||||
@@ -559,15 +570,15 @@ local function collectGame3Actors(game, mapDef, camX, camY, px, py, facing, walk
|
||||
end
|
||||
end
|
||||
|
||||
local aboveBg2 = isPlayerAboveBg2(playerXOff, playerYOff)
|
||||
local PlayerMod = package.loaded["src.core.game3.player"]
|
||||
if not aboveBg2 and (not PlayerMod or (PlayerMod.isVisible and PlayerMod.isVisible())) then
|
||||
if not PlayerMod or (PlayerMod.isVisible and PlayerMod.isVisible()) then
|
||||
local playerSortY = py
|
||||
if PlayerMod and PlayerMod.moving and PlayerMod.targetY and PlayerMod.targetY > (PlayerMod.cellY or 0) then
|
||||
playerSortY = math.max(playerSortY, PlayerMod.targetY * CELL)
|
||||
end
|
||||
actors[#actors + 1] = {
|
||||
kind = "player",
|
||||
elevation = PlayerMod and PlayerMod.elevation or 3,
|
||||
x = px + (playerXOff or 0),
|
||||
y = py + (playerYOff or 0),
|
||||
sortY = playerSortY,
|
||||
@@ -580,60 +591,27 @@ local function collectGame3Actors(game, mapDef, camX, camY, px, py, facing, walk
|
||||
}
|
||||
end
|
||||
|
||||
table.sort(actors, function(a, b)
|
||||
local underActors = {}
|
||||
local overActors = {}
|
||||
for _, a in ipairs(actors) do
|
||||
a.priority = actorPriority(a)
|
||||
if (a.priority or 2) < 2 then
|
||||
overActors[#overActors + 1] = a
|
||||
else
|
||||
underActors[#underActors + 1] = a
|
||||
end
|
||||
end
|
||||
|
||||
local function sortActors(a, b)
|
||||
local ay = a.sortY or a.y
|
||||
local by = b.sortY or b.y
|
||||
if ay == by then return (a.i or 0) < (b.i or 0) end
|
||||
return ay < by
|
||||
end)
|
||||
|
||||
return actors
|
||||
end
|
||||
|
||||
local function drawInterleaved(game, mapDef, camX, camY, actors, rows, cy0)
|
||||
local actorIdx = 1
|
||||
local nActors = #actors
|
||||
local ox = FieldView._nativeOverOx or 0
|
||||
local oy = FieldView._nativeOverOy or 0
|
||||
local overByRow = FieldView._nativeOverByRow
|
||||
|
||||
if not overByRow or not rows or rows <= 0 then
|
||||
for _, a in ipairs(actors) do
|
||||
drawSingleActor(game, mapDef, a, camX, camY)
|
||||
end
|
||||
return
|
||||
end
|
||||
table.sort(underActors, sortActors)
|
||||
table.sort(overActors, sortActors)
|
||||
|
||||
local topWy = (cy0 or 0) * CELL
|
||||
while actorIdx <= nActors and (actors[actorIdx].sortY or actors[actorIdx].y) < topWy do
|
||||
drawSingleActor(game, mapDef, actors[actorIdx], camX, camY)
|
||||
actorIdx = actorIdx + 1
|
||||
end
|
||||
|
||||
for r = 0, rows - 1 do
|
||||
local rowWy = ((cy0 or 0) + r) * CELL
|
||||
|
||||
local rowOver = overByRow[r]
|
||||
if rowOver and #rowOver > 0 then
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
for _, item in ipairs(rowOver) do
|
||||
if item.image and item.quad then
|
||||
love.graphics.draw(item.image, item.quad, ox + item.x, oy + item.y)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local nextRowWy = rowWy + CELL
|
||||
while actorIdx <= nActors and (actors[actorIdx].sortY or actors[actorIdx].y) < nextRowWy do
|
||||
drawSingleActor(game, mapDef, actors[actorIdx], camX, camY)
|
||||
actorIdx = actorIdx + 1
|
||||
end
|
||||
end
|
||||
|
||||
while actorIdx <= nActors do
|
||||
drawSingleActor(game, mapDef, actors[actorIdx], camX, camY)
|
||||
actorIdx = actorIdx + 1
|
||||
end
|
||||
return underActors, overActors
|
||||
end
|
||||
|
||||
--- Collect visible tile draws grouped by palette slot for batched GbcPalette.with.
|
||||
@@ -817,7 +795,7 @@ local function drawNativeTiles(mapDef, camX, camY, canvasW, canvasH)
|
||||
list = {}
|
||||
cellsByPair[srcPair] = list
|
||||
end
|
||||
list[#list + 1] = { mid = mid, x = col * CELL, y = row * CELL, row = row }
|
||||
list[#list + 1] = { mid = mid, x = col * CELL, y = row * CELL }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -840,15 +818,6 @@ local function drawNativeTiles(mapDef, camX, camY, canvasW, canvasH)
|
||||
local oq = NativeTileset.overQuad(ts, slot)
|
||||
if oq then
|
||||
overBatch:add(oq, cell.x, cell.y)
|
||||
local rList = FieldView._nativeOverByRow[cell.row]
|
||||
if rList then
|
||||
rList[#rList + 1] = {
|
||||
image = ts.overImage,
|
||||
quad = oq,
|
||||
x = cell.x,
|
||||
y = cell.y,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -867,8 +836,6 @@ local function drawNativeTiles(mapDef, camX, camY, canvasW, canvasH)
|
||||
FieldView._nativeOverOx = ox
|
||||
FieldView._nativeOverOy = oy
|
||||
FieldView._nativeOverPair = pair
|
||||
FieldView._nativeRows = rows
|
||||
FieldView._nativeCy0 = cy0
|
||||
if FieldView._nativeBatches[pair] then
|
||||
love.graphics.draw(FieldView._nativeBatches[pair], ox, oy)
|
||||
end
|
||||
@@ -1215,12 +1182,30 @@ function FieldView.draw(game, canvasW, canvasH, opts)
|
||||
end
|
||||
end
|
||||
|
||||
-- Draw Game3 actors and native overhead tiles interleaved by Y-row.
|
||||
-- Collect Game3 actors partitioned by OAM priority.
|
||||
local underActors, overActors = nil, nil
|
||||
if not opts.skipActors then
|
||||
local actors = collectGame3Actors(
|
||||
underActors, overActors = collectGame3Actors(
|
||||
game, mapDef, camX, camY, px, py, facing, walkPhase, stepFlip, playerYOff, playerXOff)
|
||||
drawInterleaved(
|
||||
game, mapDef, camX, camY, actors, FieldView._nativeRows, FieldView._nativeCy0)
|
||||
end
|
||||
|
||||
-- Draw Game3 actors with normal priority (under BG1 / overhead layer).
|
||||
if underActors then
|
||||
for _, a in ipairs(underActors) do
|
||||
drawSingleActor(game, mapDef, a, camX, camY)
|
||||
end
|
||||
end
|
||||
|
||||
-- pret BG1: metatile top layer covers normal OW sprites (roofs, desk counters, trees).
|
||||
if usedNative and not opts.actorsOnly then
|
||||
drawNativeOverTiles()
|
||||
end
|
||||
|
||||
-- Draw Game3 actors with elevated priority (over BG1 / overhead layer, e.g. bridges/cliffs/jumping/escalators).
|
||||
if overActors then
|
||||
for _, a in ipairs(overActors) do
|
||||
drawSingleActor(game, mapDef, a, camX, camY)
|
||||
end
|
||||
end
|
||||
|
||||
-- Tall grass over feet (pret subpriority above avatar).
|
||||
@@ -1243,35 +1228,6 @@ function FieldView.draw(game, canvasW, canvasH, opts)
|
||||
end
|
||||
end
|
||||
|
||||
-- pret BG2: metatile top layer covers OW sprites if actors were skipped or non-interleaved.
|
||||
if usedNative and not opts.actorsOnly and (opts.skipActors or not FieldView._nativeOverByRow) then
|
||||
drawNativeOverTiles()
|
||||
end
|
||||
|
||||
-- When riding escalator or flagged above BG2, player sprite is in front of BG2 handrail
|
||||
if not opts.skipActors and isPlayerAboveBg2(playerXOff, playerYOff) then
|
||||
local PlayerMod = package.loaded["src.core.game3.player"]
|
||||
if not PlayerMod or (PlayerMod.isVisible and PlayerMod.isVisible()) then
|
||||
local daytime = daytimeFor(game, mapDef)
|
||||
local okOw, OwSprites = pcall(require, "src.core.game3.ow_sprites")
|
||||
local useOw = okOw and OwSprites and OwSprites.ready and OwSprites.ready()
|
||||
local gid = useOw and OwSprites.playerGraphicsId(game) or nil
|
||||
local drew = false
|
||||
if useOw and gid ~= nil then
|
||||
drew = OwSprites.draw(
|
||||
gid, px + playerXOff, py + playerYOff, camX, camY, facing,
|
||||
(walkPhase == 1 or walkPhase == true) and 1 or 0, stepFlip and true or false)
|
||||
end
|
||||
if not drew then
|
||||
local sr = getSpriteRenderer(game, playerSpriteName(game), "player:p", nil, daytime)
|
||||
if sr then
|
||||
sr:draw(px + playerXOff, py + playerYOff, camX, camY, facing,
|
||||
(walkPhase == 1 or walkPhase == true) and 1 or 0, stepFlip and true or false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Pokemon Center heal machine (screen-space OAM, pret FLDEFF_POKECENTER_HEAL).
|
||||
if not opts.actorsOnly then
|
||||
local okFx, FieldEffects = pcall(require, "src.core.game3.field_effects")
|
||||
@@ -1301,9 +1257,6 @@ function FieldView.invalidate()
|
||||
FieldView._nativeBatch = nil
|
||||
FieldView._nativeBatches = nil
|
||||
FieldView._nativeOverBatches = nil
|
||||
FieldView._nativeOverByRow = nil
|
||||
FieldView._nativeRows = nil
|
||||
FieldView._nativeCy0 = nil
|
||||
FieldView._nativeBx = nil
|
||||
FieldView._nativeBy = nil
|
||||
FieldView._nativePair = nil
|
||||
|
||||
@@ -93,111 +93,110 @@ do
|
||||
assert_eq("EventObject elevation at (5,6) is updated to 4", eo.elevation, 4)
|
||||
end
|
||||
|
||||
print("[test] 3. Interleaved row-by-row overhead and actor draw order")
|
||||
print("[test] 3. GBA OAM Priority vs Overhead Layer partitioning")
|
||||
do
|
||||
local drawLog = {}
|
||||
_G.love = _G.love or {}
|
||||
_G.love.graphics = _G.love.graphics or {}
|
||||
love.graphics.draw = function(drawable, ...)
|
||||
local args = { ... }
|
||||
if type(drawable) == "string" then
|
||||
drawLog[#drawLog + 1] = drawable
|
||||
elseif type(drawable) == "table" and drawable.tag then
|
||||
drawLog[#drawLog + 1] = drawable.tag
|
||||
local ELEVATION_TO_PRIORITY = {
|
||||
[0] = 2, [1] = 2, [2] = 2, [3] = 2,
|
||||
[4] = 1, [5] = 2, [6] = 1, [7] = 2,
|
||||
[8] = 1, [9] = 2, [10] = 1, [11] = 2,
|
||||
[12] = 1, [13] = 0, [14] = 0, [15] = 2,
|
||||
}
|
||||
|
||||
local actorPriority = function(a)
|
||||
if a.kind == "player" then
|
||||
if a.jumping or a.surfHopping or a.escalatorActive or a.specialAnimActive then
|
||||
return 1
|
||||
end
|
||||
local elev = a.elevation or 3
|
||||
return ELEVATION_TO_PRIORITY[elev] or 2
|
||||
else
|
||||
drawLog[#drawLog + 1] = "quad"
|
||||
local elev = a.elevation or (a.obj and a.obj.elevation) or 3
|
||||
return ELEVATION_TO_PRIORITY[elev] or 2
|
||||
end
|
||||
end
|
||||
love.graphics.setColor = function() end
|
||||
love.graphics.push = function() end
|
||||
love.graphics.pop = function() end
|
||||
love.graphics.translate = function() end
|
||||
|
||||
-- Setup overhead rows:
|
||||
-- Row 5: Counter overhead tile (wy = 5 * 16 = 80)
|
||||
-- Row 17: Cliff upper edge overhead tile (wy = 17 * 16 = 272)
|
||||
FieldView._nativeOverByRow = {
|
||||
[0] = {},
|
||||
[1] = {},
|
||||
[2] = {},
|
||||
[3] = {},
|
||||
[4] = {},
|
||||
[5] = { { image = { tag = "OVERHEAD_ROW_5_COUNTER" }, quad = {} } },
|
||||
[6] = {},
|
||||
[16] = {},
|
||||
[17] = { { image = { tag = "OVERHEAD_ROW_17_CLIFF" }, quad = {} } },
|
||||
[18] = {},
|
||||
}
|
||||
FieldView._nativeOverOx = 0
|
||||
FieldView._nativeOverOy = 0
|
||||
|
||||
-- Setup actors:
|
||||
-- Actor A: NPC behind counter at row 4 (sortY = 4 * 16 = 64)
|
||||
-- Actor B: Player in front of counter at row 6 (sortY = 6 * 16 = 96)
|
||||
-- Actor C: NPC standing behind cliff in water at row 16 (sortY = 16 * 16 = 256)
|
||||
-- Actor D: Player standing ON cliff upper edge at row 17 (sortY = 17 * 16 = 272)
|
||||
local actors = {
|
||||
{ tag = "ACTOR_NPC_BEHIND_COUNTER", sortY = 64, x = 0, y = 64 },
|
||||
{ tag = "ACTOR_PLAYER_IN_FRONT_OF_COUNTER", sortY = 96, x = 0, y = 96 },
|
||||
{ tag = "ACTOR_NPC_IN_WATER", sortY = 256, x = 0, y = 256 },
|
||||
{ tag = "ACTOR_PLAYER_ON_CLIFF_EDGE", sortY = 272, x = 0, y = 272 },
|
||||
}
|
||||
|
||||
table.sort(actors, function(a, b) return a.sortY < b.sortY end)
|
||||
|
||||
drawLog = {}
|
||||
|
||||
local actorIdx = 1
|
||||
local nActors = #actors
|
||||
local cy0 = 0
|
||||
local rows = 20
|
||||
local overByRow = FieldView._nativeOverByRow
|
||||
|
||||
for r = 0, rows - 1 do
|
||||
local rowWy = (cy0 + r) * CELL
|
||||
|
||||
local rowOver = overByRow[r]
|
||||
if rowOver and #rowOver > 0 then
|
||||
for _, item in ipairs(rowOver) do
|
||||
love.graphics.draw(item.image, item.quad, item.x or 0, item.y or 0)
|
||||
local drawLog = {}
|
||||
local function simulateDraw(actors)
|
||||
local underActors = {}
|
||||
local overActors = {}
|
||||
for _, a in ipairs(actors) do
|
||||
a.priority = actorPriority(a)
|
||||
if a.priority < 2 then
|
||||
overActors[#overActors + 1] = a
|
||||
else
|
||||
underActors[#underActors + 1] = a
|
||||
end
|
||||
end
|
||||
|
||||
local nextRowWy = rowWy + CELL
|
||||
while actorIdx <= nActors and actors[actorIdx].sortY < nextRowWy do
|
||||
love.graphics.draw(actors[actorIdx].tag)
|
||||
actorIdx = actorIdx + 1
|
||||
local function sortActors(a, b)
|
||||
local ay = a.sortY or a.y
|
||||
local by = b.sortY or b.y
|
||||
if ay == by then return (a.i or 0) < (b.i or 0) end
|
||||
return ay < by
|
||||
end
|
||||
table.sort(underActors, sortActors)
|
||||
table.sort(overActors, sortActors)
|
||||
|
||||
drawLog = {}
|
||||
-- 1. Draw underActors (OAM Priority >= 2)
|
||||
for _, a in ipairs(underActors) do
|
||||
drawLog[#drawLog + 1] = a.tag
|
||||
end
|
||||
-- 2. Draw Overhead layer (BG1, Priority 1)
|
||||
drawLog[#drawLog + 1] = "OVERHEAD_BG1_LAYER"
|
||||
-- 3. Draw overActors (OAM Priority < 2, e.g. elevation 4 cliff/bridge, jumping, escalator)
|
||||
for _, a in ipairs(overActors) do
|
||||
drawLog[#drawLog + 1] = a.tag
|
||||
end
|
||||
end
|
||||
|
||||
-- Scenario A: Nurse Joy behind desk (row 5) and Player on ground (row 6)
|
||||
-- Both have ground elevation 3 -> Priority 2. Both drawn BEFORE overhead BG1 layer.
|
||||
-- The overhead desk covers Nurse Joy; the overhead roof covers player legs.
|
||||
local testActors = {
|
||||
{ tag = "NURSE_JOY_ROW_5", elevation = 3, y = 80, sortY = 80, kind = "npc" },
|
||||
{ tag = "PLAYER_ON_GROUND_ROW_6", elevation = 3, y = 96, sortY = 96, kind = "player" },
|
||||
{ tag = "PLAYER_ON_CLIFF_ELEV_4", elevation = 4, y = 272, sortY = 272, kind = "player" },
|
||||
{ tag = "NPC_IN_WATER_ELEV_1", elevation = 1, y = 256, sortY = 256, kind = "npc" },
|
||||
}
|
||||
|
||||
simulateDraw(testActors)
|
||||
|
||||
print("Draw order result:")
|
||||
for idx, entry in ipairs(drawLog) do
|
||||
print(string.format(" [%d] %s", idx, entry))
|
||||
end
|
||||
|
||||
assert_eq("Draw step 1 is NPC behind counter", drawLog[1], "ACTOR_NPC_BEHIND_COUNTER")
|
||||
assert_eq("Draw step 2 is Counter overhead (drawn after NPC behind counter)", drawLog[2], "OVERHEAD_ROW_5_COUNTER")
|
||||
assert_eq("Draw step 3 is Player in front of counter (drawn after counter)", drawLog[3], "ACTOR_PLAYER_IN_FRONT_OF_COUNTER")
|
||||
assert_eq("Draw step 4 is NPC in water", drawLog[4], "ACTOR_NPC_IN_WATER")
|
||||
assert_eq("Draw step 5 is Cliff overhead (drawn after NPC in water, covering them)", drawLog[5], "OVERHEAD_ROW_17_CLIFF")
|
||||
assert_eq("Draw step 6 is Player on cliff edge (drawn AFTER cliff overhead, on top of edge!)", drawLog[6], "ACTOR_PLAYER_ON_CLIFF_EDGE")
|
||||
assert_eq("Under-actor 1 is Nurse Joy (behind desk)", drawLog[1], "NURSE_JOY_ROW_5")
|
||||
assert_eq("Under-actor 2 is Player on ground (behind roof)", drawLog[2], "PLAYER_ON_GROUND_ROW_6")
|
||||
assert_eq("Under-actor 3 is NPC in water", drawLog[3], "NPC_IN_WATER_ELEV_1")
|
||||
assert_eq("Step 4 is Overhead BG1 layer (covers Nurse Joy and player on ground)", drawLog[4], "OVERHEAD_BG1_LAYER")
|
||||
assert_eq("Step 5 is Player on cliff (elevation 4, drawn ON TOP of overhead layer)", drawLog[5], "PLAYER_ON_CLIFF_ELEV_4")
|
||||
end
|
||||
|
||||
print("[test] 4. isPlayerAboveBg2 special states")
|
||||
print("[test] 4. Player priority override states (jumping, escalator, surf hopping)")
|
||||
do
|
||||
local isPlayerAboveBg2_test = function(playerXOff, playerYOff, isJumping, isEscalator)
|
||||
if (playerXOff and playerXOff ~= 0) or (playerYOff and playerYOff ~= 0) then
|
||||
return true
|
||||
local ELEVATION_TO_PRIORITY = {
|
||||
[0] = 2, [1] = 2, [2] = 2, [3] = 2,
|
||||
[4] = 1, [5] = 2, [6] = 1, [7] = 2,
|
||||
[8] = 1, [9] = 2, [10] = 1, [11] = 2,
|
||||
[12] = 1, [13] = 0, [14] = 0, [15] = 2,
|
||||
}
|
||||
|
||||
local computePlayerPriority = function(opts)
|
||||
if opts.jumping or opts.surfHopping or opts.escalatorActive or opts.specialAnimActive then
|
||||
return 1
|
||||
end
|
||||
if isJumping then return true end
|
||||
if isEscalator then return true end
|
||||
return false
|
||||
local elev = opts.elevation or 3
|
||||
return ELEVATION_TO_PRIORITY[elev] or 2
|
||||
end
|
||||
|
||||
assert_true("Jumping player is flagged above BG2", isPlayerAboveBg2_test(0, 0, true, false))
|
||||
assert_true("Escalator player is flagged above BG2", isPlayerAboveBg2_test(0, 0, false, true))
|
||||
assert_true("Subpixel Y offset player is flagged above BG2", isPlayerAboveBg2_test(0, -8, false, false))
|
||||
assert_eq("Normal walking player is not forced above BG2", isPlayerAboveBg2_test(0, 0, false, false), false)
|
||||
assert_eq("Jumping player has Priority 1 (above BG1)", computePlayerPriority({ jumping = true, elevation = 3 }), 1)
|
||||
assert_eq("Escalator player has Priority 1 (above BG1)", computePlayerPriority({ escalatorActive = true, elevation = 3 }), 1)
|
||||
assert_eq("Surf hopping player has Priority 1 (above BG1)", computePlayerPriority({ surfHopping = true, elevation = 1 }), 1)
|
||||
assert_eq("Bridge player has Priority 1 (above BG1)", computePlayerPriority({ elevation = 4 }), 1)
|
||||
assert_eq("Normal walking player with animation offsets has Priority 2 (under BG1)", computePlayerPriority({ elevation = 3, spriteYOffset = -8 }), 2)
|
||||
assert_eq("Water surfing player has Priority 2 (under BG1)", computePlayerPriority({ elevation = 1 }), 2)
|
||||
end
|
||||
|
||||
print("[test] ALL ELEVATION AND OAM CONDITIONAL PRIORITY TESTS PASSED!")
|
||||
|
||||
Reference in New Issue
Block a user