diff --git a/fcore/enemy/enemy-behaviour.sml b/fcore/enemy/enemy-behaviour.sml index 7c2d7af..64abf94 100644 --- a/fcore/enemy/enemy-behaviour.sml +++ b/fcore/enemy/enemy-behaviour.sml @@ -409,101 +409,46 @@ struct | _ => enemy fun updatePatrolState - ( player - , enemy - , walls - , wallTree - , platforms - , platformTree - , projectileTree - , enemyList - , fallingList - ) = + (player, enemy, walls, wallTree, platforms, platformTree) = let val {x, y, ...} = enemy val size = Constants.enemySize + val enemy = withDefaultYAxis enemy + + val patches = getPatrolPatches (enemy, wallTree, platformTree, []) + val enemy = EnemyPatch.withPatches (enemy, patches) + + val patches = EnemyPhysics.getPhysicsPatches enemy + val enemy = EnemyPatch.withPatches (enemy, patches) + + val patches = EnemyPhysics.getEnvironmentPatches + (enemy, walls, wallTree, platforms, platformTree) in - if QuadTree.hasCollisionAt (x, y, size, size, ~1, projectileTree) then - (* if projectile hits, filter out from this list, and add to list of - * fallingEnemies *) - let - val fallingList = - {x = x, y = y, variant = #variant enemy} :: fallingList - in - (enemyList, fallingList) - end - else if isCollidingWithPlayerAttack (player, enemy) then - (* filter out when any projectile hits *) - (enemyList, fallingList) - else - (* since we're not filtering out, update the enemy's state and cons enemy *) - let - val enemy = withDefaultYAxis enemy - - val patches = getPatrolPatches (enemy, wallTree, platformTree, []) - val enemy = EnemyPatch.withPatches (enemy, patches) - - val patches = EnemyPhysics.getPhysicsPatches enemy - val enemy = EnemyPatch.withPatches (enemy, patches) - - val patches = EnemyPhysics.getEnvironmentPatches - (enemy, walls, wallTree, platforms, platformTree) - val enemy = EnemyPatch.withPatches (enemy, patches) - in - (enemy :: enemyList, fallingList) - end + EnemyPatch.withPatches (enemy, patches) end fun updateFollowState - ( player - , enemy - , walls - , wallTree - , platforms - , platformTree - , projectileTree - , graph - , enemyList - , fallingList - ) = + (player, enemy, walls, wallTree, platforms, platformTree, graph) = let val {x, y, ...} = enemy val size = Constants.enemySize + + val enemy = withDefaultYAxis enemy + + val patches = getFollowPatches + (player, enemy, wallTree, platformTree, platforms, graph, []) + val enemy = EnemyPatch.withPatches (enemy, patches) + + val patches = EnemyPhysics.getPhysicsPatches enemy + val enemy = EnemyPatch.withPatches (enemy, patches) + + val patches = EnemyPhysics.getEnvironmentPatches + (enemy, walls, wallTree, platforms, platformTree) in - if QuadTree.hasCollisionAt (x, y, size, size, ~1, projectileTree) then - (* if projectile hits, filter out from this list, and add to list of - * fallingEnemies *) - let - val fallingList = - {x = x, y = y, variant = #variant enemy} :: fallingList - in - (enemyList, fallingList) - end - else if isCollidingWithPlayerAttack (player, enemy) then - (* filter out when any projectile hits *) - (enemyList, fallingList) - else - (* since we're not filtering out, update the enemy's state and cons enemy *) - let - val enemy = withDefaultYAxis enemy - - val patches = getFollowPatches - (player, enemy, wallTree, platformTree, platforms, graph, []) - val enemy = EnemyPatch.withPatches (enemy, patches) - - val patches = EnemyPhysics.getPhysicsPatches enemy - val enemy = EnemyPatch.withPatches (enemy, patches) - - val patches = EnemyPhysics.getEnvironmentPatches - (enemy, walls, wallTree, platforms, platformTree) - val enemy = EnemyPatch.withPatches (enemy, patches) - in - (enemy :: enemyList, fallingList) - end + EnemyPatch.withPatches (enemy, patches) end - fun updateStraightBat - (player, enemy, walls, wallTree, projectileTree, enemyList, fallingList) = + fun updateStraightBat (player, enemy, walls, wallTree) = let val {x, y, batRest, batDirY, batMinY, batMaxY, xAxis, ...} = enemy @@ -553,59 +498,18 @@ struct in EnemyPatch.W_BAT_REST 0 :: patches end - - val enemy = EnemyPatch.withPatches (enemy, patches) in - (enemy :: enemyList, fallingList) + EnemyPatch.withPatches (enemy, patches) end fun updateEnemyState - ( enemy - , projectiles - , projectileTree - , walls - , wallTree - , platforms - , platformTree - , player - , graph - , enemyList - , fallingList - ) = + (enemy, walls, wallTree, platforms, platformTree, player, graph) = case #variant enemy of PATROL_SLIME => updatePatrolState - ( player - , enemy - , walls - , wallTree - , platforms - , platformTree - , projectileTree - , enemyList - , fallingList - ) + (player, enemy, walls, wallTree, platforms, platformTree) | FOLLOW_SLIME => updateFollowState - ( player - , enemy - , walls - , wallTree - , platforms - , platformTree - , projectileTree - , graph - , enemyList - , fallingList - ) - | STRAIGHT_BAT => - updateStraightBat - ( player - , enemy - , walls - , wallTree - , projectileTree - , enemyList - , fallingList - ) + (player, enemy, walls, wallTree, platforms, platformTree, graph) + | STRAIGHT_BAT => updateStraightBat (player, enemy, walls, wallTree) end diff --git a/fcore/enemy/enemy.sml b/fcore/enemy/enemy.sml index 12ebd5a..98a6115 100644 --- a/fcore/enemy/enemy.sml +++ b/fcore/enemy/enemy.sml @@ -1,150 +1,4 @@ structure Enemy = struct - open EnemyType - (* returns a vector of enemies, with new state (like position, etc.). - * Also filters any enemies from list if defeated. - * Called once per frame. *) - fun updateEnemyList - ( pos - , enemies - , projectiles - , projectileTree - , walls - , wallTree - , platforms - , platformTree - , player - , graph - , enemyList - , fallingList - ) = - if pos < 0 then - (Vector.fromList enemyList, fallingList) - else - let - val enemy = Vector.sub (enemies, pos) - - (* call function to act on variant, either: - * 1. updating enemy and :: cons :: ing to enemyList, or - * 2. filtering enemy if projectile hit which enemy should not survive - * *) - val (enemyList, fallingList) = EnemyBehaviour.updateEnemyState - ( enemy - , projectiles - , projectileTree - , walls - , wallTree - , platforms - , platformTree - , player - , graph - , enemyList - , fallingList - ) - in - updateEnemyList - ( pos - 1 - , enemies - , projectiles - , projectileTree - , walls - , wallTree - , platforms - , platformTree - , player - , graph - , enemyList - , fallingList - ) - end - - fun helpGenerateTree (pos, enemyVec: enemy vector, acc) = - if pos = Vector.length enemyVec then - acc - else - let - val {id, x, y, ...} = Vector.sub (enemyVec, pos) - - val size = Constants.enemySize - - val acc = QuadTree.insert (x, y, size, size, id, acc) - in - helpGenerateTree (pos + 1, enemyVec, acc) - end - - fun generateTree enemyVec = - helpGenerateTree - ( 0 - , enemyVec - , QuadTree.create (Constants.worldWidth, Constants.worldHeight) - ) - - fun helpFind (findNum, vec: enemy vector, low, high) = - (* should only be called when we know enemy already exists in vec *) - let - val mid = low + ((high - low) div 2) - val enemy = Vector.sub (vec, mid) - val {id = curNum, ...} = enemy - in - if curNum = findNum then enemy - else if curNum < findNum then helpFind (findNum, vec, mid + 1, high) - else helpFind (findNum, vec, low, mid - 1) - end - - fun find (findNum, vec) = - helpFind (findNum, vec, 0, Vector.length vec - 1) - - fun helpGetDrawVec (enemy: enemy, width, height) = - let - val {x, y, ...} = enemy - val wratio = width / Constants.worldWidthReal - val hratio = height / Constants.worldHeightReal - in - if wratio < hratio then - let - val scale = Constants.worldHeightReal * wratio - val yOffset = - if height > scale then (height - scale) / 2.0 - else if height < scale then (scale - height) / 2.0 - else 0.0 - - val x = Real32.fromInt x * wratio - val y = Real32.fromInt y * wratio + yOffset - - val realSize = Constants.enemySizeReal * wratio - in - Block.lerp (x, y, realSize, realSize, width, height, 0.5, 0.5, 1.0) - end - else - let - val scale = Constants.worldWidthReal * hratio - val xOffset = - if width > scale then (width - scale) / 2.0 - else if width < scale then (scale - width) / 2.0 - else 0.0 - - val x = Real32.fromInt x * hratio + xOffset - val y = Real32.fromInt y * hratio - - val realSize = Constants.enemySizeReal * hratio - in - Block.lerp (x, y, realSize, realSize, width, height, 0.5, 0.5, 1.0) - end - end - - fun getDrawVecLoop (pos, enemies, width, height, acc) = - if pos = Vector.length enemies then - Vector.concat acc - else - let - val e = Vector.sub (enemies, pos) - val hd = helpGetDrawVec (e, width, height) - val acc = hd :: acc - in - getDrawVecLoop (pos + 1, enemies, width, height, acc) - end - - fun getDrawVec (enemies, width, height) = - getDrawVecLoop (0, enemies, width, height, []) end