About Social Code
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2025-03-20 22:52:01 +0000
committerLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2025-03-20 22:52:01 +0000
commitf741a652f283c4533723a03eca7cf315a487ce92 (patch)
tree3485572823fb828ce791e61b1ef63c88ff3cff20
parentecdc16c7f050b1d0bd63412b4ba3ac5cef758488 (diff)
Make validate functions reusable
-rw-r--r--world.rhm115
1 files changed, 54 insertions, 61 deletions
diff --git a/world.rhm b/world.rhm
index 9f606f6..dbedf15 100644
--- a/world.rhm
+++ b/world.rhm
@@ -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