2025-01-29 19:12:24 +00:00
|
|
|
structure TraceJump =
|
|
|
|
|
struct
|
2025-01-29 23:04:28 +00:00
|
|
|
structure Trace =
|
|
|
|
|
MakeQuadTreeFold
|
|
|
|
|
(struct
|
|
|
|
|
type env = int
|
|
|
|
|
type state = bool
|
2025-01-29 19:12:24 +00:00
|
|
|
|
2025-01-29 23:04:28 +00:00
|
|
|
fun fold (foldPlatID, nextPlatID, hasFoundNextPlatID) =
|
|
|
|
|
hasFoundNextPlatID orelse foldPlatID = nextPlatID
|
|
|
|
|
end)
|
2025-01-29 19:12:24 +00:00
|
|
|
|
2025-01-29 23:04:28 +00:00
|
|
|
fun traceRightDescent (x, y, nextPlatID, platTree) =
|
2025-01-29 19:12:24 +00:00
|
|
|
if x >= Constants.worldWidth orelse y >= Constants.worldHeight then
|
|
|
|
|
(* we hit bounds of screen and saw that there was
|
|
|
|
|
* no way to jump to next nextPlatID *)
|
|
|
|
|
false
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val width = Constants.moveEnemyBy
|
|
|
|
|
val height = Constants.worldHeight - y
|
2025-01-29 23:04:28 +00:00
|
|
|
val shouldJumpRight = Trace.foldRegion
|
|
|
|
|
(x, y, width, height, nextPlatID, false, platTree)
|
2025-01-29 19:12:24 +00:00
|
|
|
|
|
|
|
|
val nextX = x + Constants.moveEnemyBy
|
|
|
|
|
val nextY = y + Constants.moveEnemyBy
|
|
|
|
|
in
|
2025-01-29 23:04:28 +00:00
|
|
|
shouldJumpRight
|
|
|
|
|
orelse traceRightDescent (nextX, nextY, nextPlatID, platTree)
|
2025-01-29 19:12:24 +00:00
|
|
|
end
|
|
|
|
|
|
2025-01-29 23:04:28 +00:00
|
|
|
fun traceRightDrop (enemy: GameType.enemy, nextPlatID, platTree) =
|
2025-01-29 19:35:40 +00:00
|
|
|
let
|
2025-01-29 23:04:28 +00:00
|
|
|
val {x, y, ...} = enemy
|
2025-01-29 19:35:40 +00:00
|
|
|
val x = x - Constants.enemySize
|
|
|
|
|
in
|
2025-01-29 23:04:28 +00:00
|
|
|
traceRightDescent (x, y, nextPlatID, platTree)
|
2025-01-29 19:35:40 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun traceRightJumpAscent (x, y, remainingJump, nextPlatID, platTree) =
|
2025-01-29 23:51:02 +00:00
|
|
|
(* because value of y parameter is at the top,
|
|
|
|
|
* we subtract the jump limit by the enemy's size,
|
|
|
|
|
* so we only check for places enemy can jump to. *)
|
|
|
|
|
if remainingJump >= Constants.jumpLimit - Constants.enemySize then
|
2025-01-29 23:04:28 +00:00
|
|
|
traceRightDescent (x, y, nextPlatID, platTree)
|
2025-01-29 19:12:24 +00:00
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val width = Constants.moveEnemyBy
|
|
|
|
|
val height = Constants.worldHeight - y
|
2025-01-29 23:04:28 +00:00
|
|
|
val shouldJumpRight = Trace.foldRegion
|
|
|
|
|
(x, y, width, height, nextPlatID, false, platTree)
|
2025-01-29 19:12:24 +00:00
|
|
|
|
|
|
|
|
val nextX = x + Constants.moveEnemyBy
|
|
|
|
|
val nextY = y - Constants.moveEnemyBy
|
|
|
|
|
val nextJump = remainingJump + Constants.moveEnemyBy
|
|
|
|
|
in
|
2025-01-29 23:04:28 +00:00
|
|
|
shouldJumpRight
|
|
|
|
|
orelse
|
2025-01-29 19:35:40 +00:00
|
|
|
traceRightJumpAscent (nextX, nextY, nextJump, nextPlatID, platTree)
|
2025-01-29 19:12:24 +00:00
|
|
|
end
|
|
|
|
|
|
2025-01-29 23:04:28 +00:00
|
|
|
fun traceRightJump (enemy: GameType.enemy, nextPlatID, platTree) =
|
2025-01-29 19:12:24 +00:00
|
|
|
let
|
2025-01-29 23:04:28 +00:00
|
|
|
val {x, y, ...} = enemy
|
2025-01-29 19:35:40 +00:00
|
|
|
val x = x - Constants.enemySize
|
2025-01-29 23:04:28 +00:00
|
|
|
|
|
|
|
|
open GameType
|
2025-01-29 19:12:24 +00:00
|
|
|
in
|
|
|
|
|
if EnemyPhysics.standingOnArea (x, y, platTree) then
|
2025-01-29 19:35:40 +00:00
|
|
|
traceRightJumpAscent (x, y, 0, nextPlatID, platTree)
|
2025-01-29 19:12:24 +00:00
|
|
|
else
|
|
|
|
|
case #yAxis enemy of
|
2025-01-29 23:04:28 +00:00
|
|
|
JUMPING amt => traceRightJumpAscent (x, y, amt, nextPlatID, platTree)
|
|
|
|
|
| ON_GROUND => traceRightJumpAscent (x, y, 0, nextPlatID, platTree)
|
|
|
|
|
| FALLING => traceRightDescent (x, y, nextPlatID, platTree)
|
|
|
|
|
| DROP_BELOW_PLATFORM => traceRightDescent (x, y, nextPlatID, platTree)
|
|
|
|
|
| FLOATING _ => traceRightDescent (x, y, nextPlatID, platTree)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun traceLeftDescent (x, y, nextPlatID, platTree) =
|
|
|
|
|
if x <= 0 orelse y >= Constants.worldHeight then
|
|
|
|
|
false
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val width = Constants.moveEnemyBy
|
|
|
|
|
val height = Constants.worldHeight - y
|
|
|
|
|
val shouldJumpLeft = Trace.foldRegion
|
|
|
|
|
(x, y, width, height, nextPlatID, false, platTree)
|
|
|
|
|
|
|
|
|
|
val nextX = x - Constants.moveEnemyBy
|
|
|
|
|
val nextY = y + Constants.moveEnemyBy
|
|
|
|
|
in
|
|
|
|
|
shouldJumpLeft
|
2025-01-31 00:35:36 +00:00
|
|
|
orelse traceLeftDescent (nextX, nextY, nextPlatID, platTree)
|
2025-01-29 23:04:28 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun traceLeftDrop (enemy: GameType.enemy, nextPlatID, platTree) =
|
|
|
|
|
let
|
|
|
|
|
val {x, y, ...} = enemy
|
|
|
|
|
val x = x + Constants.enemySize
|
|
|
|
|
in
|
|
|
|
|
traceLeftDescent (x, y, nextPlatID, platTree)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun traceLeftJumpAscent (x, y, remainingJump, nextPlatID, platTree) =
|
2025-01-29 23:51:02 +00:00
|
|
|
if remainingJump >= Constants.jumpLimit - Constants.enemySize then
|
2025-01-29 23:04:28 +00:00
|
|
|
traceLeftDescent (x, y, nextPlatID, platTree)
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val width = Constants.moveEnemyBy
|
|
|
|
|
val height = Constants.worldHeight - y
|
|
|
|
|
val shouldJumpLeft = Trace.foldRegion
|
|
|
|
|
(x, y, width, height, nextPlatID, false, platTree)
|
|
|
|
|
|
|
|
|
|
val nextX = x - Constants.moveEnemyBy
|
|
|
|
|
val nextY = y - Constants.moveEnemyBy
|
|
|
|
|
val nextJump = remainingJump + Constants.moveEnemyBy
|
|
|
|
|
in
|
|
|
|
|
shouldJumpLeft
|
|
|
|
|
orelse
|
|
|
|
|
traceLeftJumpAscent (nextX, nextY, nextJump, nextPlatID, platTree)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun traceLeftJump (enemy: GameType.enemy, nextPlatID, platTree) =
|
|
|
|
|
let
|
|
|
|
|
val {x, y, ...} = enemy
|
|
|
|
|
|
|
|
|
|
open GameType
|
|
|
|
|
in
|
|
|
|
|
if EnemyPhysics.standingOnArea (x, y, platTree) then
|
|
|
|
|
traceLeftJumpAscent (x, y, 0, nextPlatID, platTree)
|
|
|
|
|
else
|
|
|
|
|
case #yAxis enemy of
|
|
|
|
|
JUMPING amt => traceLeftJumpAscent (x, y, amt, nextPlatID, platTree)
|
|
|
|
|
| ON_GROUND => traceLeftJumpAscent (x, y, 0, nextPlatID, platTree)
|
|
|
|
|
| FALLING => traceLeftDescent (x, y, nextPlatID, platTree)
|
|
|
|
|
| DROP_BELOW_PLATFORM => traceLeftDescent (x, y, nextPlatID, platTree)
|
|
|
|
|
| FLOATING _ => traceLeftDescent (x, y, nextPlatID, platTree)
|
2025-01-29 19:12:24 +00:00
|
|
|
end
|
|
|
|
|
end
|