diff options
author | Lucas Fryzek <lucas.fryzek@fryzekconcepts.com> | 2025-03-20 22:52:01 +0000 |
---|---|---|
committer | Lucas Fryzek <lucas.fryzek@fryzekconcepts.com> | 2025-03-20 22:52:01 +0000 |
commit | f741a652f283c4533723a03eca7cf315a487ce92 (patch) | |
tree | 3485572823fb828ce791e61b1ef63c88ff3cff20 | |
parent | ecdc16c7f050b1d0bd63412b4ba3ac5cef758488 (diff) |
Make validate functions reusable
-rw-r--r-- | world.rhm | 115 |
1 files changed, 54 insertions, 61 deletions
@@ -57,72 +57,65 @@ class Chunk(width :: Int, tiles[y * width + x] := tile class Entity(id:: Int, mutable x :: Int, mutable y :: Int, mutable current_chunk :: Chunk): + method validate_dist(x :: Int, y :: Int, max_dist :: Int): + let diff_x = math.abs(this.x - x) + let diff_y = math.abs(this.y - y) + // Diagonal case is moving in the same direction (same x & y) and that amount + // is less than or equal to max distance + let diagonal = diff_x == diff_y && diff_x <= max_dist + let x_axis = diff_x <= max_dist && diff_y == 0 + let y_axis = diff_y <= max_dist && diff_x == 0 + let no_movement = diff_x == 0 && diff_y == 0 + !no_movement && (diagonal || x_axis || y_axis) + + method validate_chunk(x :: Int, y :: Int) :: maybe(Chunk): + let current_chunk = this.current_chunk + let local_x = x - current_chunk.offset_x * current_chunk.width + let local_y = y - current_chunk.offset_y * current_chunk.height + let less_x = local_x < 0 + let less_y = local_y < 0 + let more_x = local_x >= current_chunk.width + let more_y = local_y >= current_chunk.height + let inside_x = !(less_x || more_x) + let inside_y = !(less_y || more_y) + let next_chunk :: maybe(Chunk) = cond + | inside_x && less_y: current_chunk.neighbours.get(#'north, #false) + | more_x && less_y: current_chunk.neighbours.get(#'north_east, #false) + | more_x && inside_y: current_chunk.neighbours.get(#'east, #false) + | more_x && more_y: current_chunk.neighbours.get(#'south_east, #false) + | inside_x && more_y: current_chunk.neighbours.get(#'south, #false) + | less_x && more_y: current_chunk.neighbours.get(#'south_west, #false) + | less_x && inside_y: current_chunk.neighbours.get(#'west, #false) + | less_x && less_y: current_chunk.neighbours.get(#'north_west, #false) + | ~else: current_chunk + + next_chunk + + method validate_move(x :: Int, y :: Int, max_dist :: Int, target_chunk :: Chunk): + let current_tile = this.current_chunk.get_tile(this.x, this.y) + let target_tile = target_chunk.get_tile(x, y) + let diff_x = x - this.x + let diff_y = y - this.y + let direction = cond + | diff_x == 0 && diff_y < 0: #'north + | diff_x > 0 && diff_y < 0: #'north_east + | diff_x > 0 && diff_y == 0: #'east + | diff_x > 0 && diff_y > 0: #'south_east + | diff_x == 0 && diff_y > 0: #'south + | diff_x < 0 && diff_y > 0: #'south_west + | diff_x < 0 && diff_y == 0: #'west + | diff_x < 0 && diff_y < 0: #'north_west + let current_block = current_tile.get_block() + let target_block = flip_block(target_tile.get_block()) + !(direction == current_block || direction == target_block) + method | move(x :: Int, y :: Int): move(x, y, 1) | move(x :: Int, y :: Int, max_dist :: Int) :: Boolean: - let mutable target_chunk :: Chunk = current_chunk - let mutable target_tile = Tile(#'empty) - let validate_dist = fun (entity :: Entity) :: Boolean: - let diff_x = math.abs(entity.x - x) - let diff_y = math.abs(entity.y - y) - // Diagonal case is moving in the same direction (same x & y) and that amount - // is less than or equal to max distance - let diagonal = diff_x == diff_y && diff_x <= max_dist - let x_axis = diff_x <= max_dist && diff_y == 0 - let y_axis = diff_y <= max_dist && diff_x == 0 - let no_movement = diff_x == 0 && diff_y == 0 - !no_movement && (diagonal || x_axis || y_axis) - - let validate_chunk = fun (entity :: Entity) :: Boolean: - let current_chunk = entity.current_chunk - let local_x = x - current_chunk.offset_x * current_chunk.width - let local_y = y - current_chunk.offset_y * current_chunk.height - let less_x = local_x < 0 - let less_y = local_y < 0 - let more_x = local_x >= current_chunk.width - let more_y = local_y >= current_chunk.height - let inside_x = !(less_x || more_x) - let inside_y = !(less_y || more_y) - let next_chunk :: maybe(Chunk) = cond - | inside_x && less_y: current_chunk.neighbours.get(#'north, #false) - | more_x && less_y: current_chunk.neighbours.get(#'north_east, #false) - | more_x && inside_y: current_chunk.neighbours.get(#'east, #false) - | more_x && more_y: current_chunk.neighbours.get(#'south_east, #false) - | inside_x && more_y: current_chunk.neighbours.get(#'south, #false) - | less_x && more_y: current_chunk.neighbours.get(#'south_west, #false) - | less_x && inside_y: current_chunk.neighbours.get(#'west, #false) - | less_x && less_y: current_chunk.neighbours.get(#'north_west, #false) - | ~else: current_chunk - - cond - | !next_chunk: #false - | ~else: - target_chunk := next_chunk!! - let local_x = x - current_chunk.offset_x * current_chunk.width - let local_y = y - current_chunk.offset_y * current_chunk.height - target_tile := entity.current_chunk.get_tile(local_x, local_y) - #true - - let validate_move = fun (entity :: Entity) :: Boolean: - let current_tile = entity.current_chunk.get_tile(entity.x, entity.y) - let target_tile = target_chunk.get_tile(x, y) - let diff_x = x - this.x - let diff_y = y - this.y - let direction = cond - | diff_x == 0 && diff_y < 0: #'north - | diff_x > 0 && diff_y < 0: #'north_east - | diff_x > 0 && diff_y == 0: #'east - | diff_x > 0 && diff_y > 0: #'south_east - | diff_x == 0 && diff_y > 0: #'south - | diff_x < 0 && diff_y > 0: #'south_west - | diff_x < 0 && diff_y == 0: #'west - | diff_x < 0 && diff_y < 0: #'north_west - let current_block = current_tile.get_block() - let target_block = flip_block(target_tile.get_block()) - !(direction == current_block || direction == target_block) + let target_chunk = validate_chunk(x, y) cond - | validate_dist(this) && validate_chunk(this) && validate_move(this): + | validate_dist(x, y, max_dist) && target_chunk != #false && validate_move(x, y, max_dist, target_chunk!!): this.current_chunk := target_chunk this.x := x this.y := y |