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  |