39 lines
1.3 KiB
GDScript
39 lines
1.3 KiB
GDScript
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(centre.x - point.x, centre.y - point.y)
|
|
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)
|