From 7a5517571dee225462586fadad2165d990d68221 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Fri, 24 Jan 2025 22:51:20 +0000 Subject: [PATCH] add functionality for enemy to walk to appropriate position if next platform is below current one, but only partially overlapping with current platform so enemy will not reach it if they drop down from current position --- fcore/enemy-behaviour.sml | 81 ++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/fcore/enemy-behaviour.sml b/fcore/enemy-behaviour.sml index 2a37280..8b64718 100644 --- a/fcore/enemy-behaviour.sml +++ b/fcore/enemy-behaviour.sml @@ -88,10 +88,10 @@ struct if hasWallAhead then EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc - else (* invert direction if moving further left - * will result in falling down *) if - canWalkAhead (searchStartX, y, wallTree, platformTree) - then acc + else if canWalkAhead (searchStartX, y, wallTree, platformTree) then + (* invert direction if moving further left + * will result in falling down *) + acc else EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc end | MOVE_RIGHT => @@ -122,10 +122,10 @@ struct if hasWallAhead then EnemyPatch.W_X_AXIS MOVE_LEFT :: acc - else (* invert direction if moving further right - * will result in falling down *) if - canWalkAhead (searchStartX, y, wallTree, platformTree) - then acc + else if canWalkAhead (searchStartX, y, wallTree, platformTree) then + (* invert direction if moving further right + * will result in falling down *) + acc else EnemyPatch.W_X_AXIS MOVE_LEFT :: acc end | STAY_STILL => acc @@ -190,7 +190,7 @@ struct val nPlatFinishX = nPlatX + nPlatW in (isBetween (nPlatX, pPlatX, nPlatFinishX) - orelse isBetween (nPlatX, pPlatFinishX, nPlatFinishX)) + orelse isBetween (nPlatX, pPlatFinishX, nPlatFinishX)) andalso pPlatY > nPlatY end @@ -206,33 +206,65 @@ struct val standingOnPlat = standingOnArea (enemy, platformTree) in if ey >= platY andalso standingOnPlat then - if isBetween (platX, ecx, platFinishX) then + if + isBetween (platX, ecx, platFinishX) + then (* can jump from same position enemy is at *) case eyAxis of ON_GROUND => EnemyPatch.W_Y_AXIS (JUMPING 0) :: acc | FALLING => EnemyPatch.W_Y_AXIS (JUMPING 0) :: acc | _ => acc - else + else (* have to travel either left or right before jumping *) if ecx < platX then EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc else EnemyPatch.W_X_AXIS MOVE_LEFT :: acc - else - acc + else + acc end - fun canDrop (nextPlatform, platformTree, enemy) = + fun canDrop (prevPlatform, nextPlatform) = let - val {x = platX, y = platY, width = platW, ...} = nextPlatform - val platFinishX = platX + platW + val {x = pPlatX, y = pPlatY, width = pPlatW, ...} = prevPlatform + val pPlatFinishX = pPlatX + pPlatW - val {x = eX, y = ey, yAxis = eyAxis, ...} = enemy + val {x = nPlatX, y = nPlatY, width = nPlatW, ...} = nextPlatform + val nPlatFinishX = nPlatX + nPlatW + in + (isBetween (nPlatX, pPlatX, nPlatFinishX) + orelse isBetween (nPlatX, pPlatFinishX, nPlatFinishX)) + andalso pPlatY < nPlatY + end + + fun getDropPatches (nextPlatform, platformTree, enemy, acc) = + let + val {x = platX, y = platY, width = platWidth, ...} = nextPlatform + val platFinishX = platX + platWidth + + val {x = eX, y = ey, yAxis = eyAxis, xAxis = exAxis, ...} = enemy + val ecx = eX + (Constants.enemySize div 2) + val ey = ey + Constants.enemySize val standingOnPlat = standingOnArea (enemy, platformTree) in - isBetween (platX, eX, platFinishX) andalso standingOnPlat - andalso ey < platY + if ey <= platY andalso standingOnPlat then + if + isBetween (platX, ecx, platFinishX) + then + (* can jump from same position enemy is at *) + case eyAxis of + ON_GROUND => EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM :: acc + | FALLING => EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM :: acc + | _ => acc + else + (* have to travel either left or right before jumping *) + if ecx < platX then + EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc + else + EnemyPatch.W_X_AXIS MOVE_LEFT :: acc + else + acc end (* get patches to help enemy move to nextPlatformID *) @@ -245,11 +277,14 @@ struct val {x = eX, y = ey, yAxis = eyAxis, ...} = enemy val canJump = canJump (currentPlatform, nextPlatform) - val canDrop = canDrop (nextPlatform, platformTree, enemy) + val canDrop = canDrop (currentPlatform, nextPlatform) in - if canJump then getJumpPatches (nextPlatform, platformTree, enemy, acc) - else if canDrop then EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM :: acc - else acc + if canJump then + getJumpPatches (nextPlatform, platformTree, enemy, acc) + else if canDrop then + getDropPatches (nextPlatform, platformTree, enemy, acc) + else + acc end fun canJumpOnPlatform (player, platforms, enemy: enemy, platformTree, acc) =