class_name PlayableBoundsRule extends RefCounted const PlayableBoundsStatus = preload( "res://game/application/sites/playable_bounds_status.gd" ) var _bounds_m: Rect2 var _warning_margin_m: float func _init(bounds_m: Rect2, warning_margin_m: float = 40.0) -> void: _bounds_m = bounds_m _warning_margin_m = maxf(warning_margin_m, 0.0) func evaluate(position_m: Vector3) -> PlayableBoundsStatus: var point := Vector2(position_m.x, position_m.z) var to_west := point.x - _bounds_m.position.x var to_east := _bounds_m.end.x - point.x var to_north := point.y - _bounds_m.position.y var to_south := _bounds_m.end.y - point.y var distance := minf(minf(to_west, to_east), minf(to_north, to_south)) var state := PlayableBoundsStatus.State.INSIDE if distance < 0.0: state = PlayableBoundsStatus.State.OUTSIDE elif distance < _warning_margin_m: state = PlayableBoundsStatus.State.NEAR_EDGE var direction := Vector3.ZERO if state != PlayableBoundsStatus.State.INSIDE: var centre := _bounds_m.get_center() var toward: Vector2 if distance == to_west or distance == to_east: toward = Vector2(signf(centre.x - point.x), 0.0) else: toward = Vector2(0.0, signf(centre.y - point.y)) direction = Vector3(toward.x, 0.0, toward.y) return PlayableBoundsStatus.new(state, distance, direction)