diff --git a/addons/escoria-core/game/core-scripts/behaviors/esc_movable.gd b/addons/escoria-core/game/core-scripts/behaviors/esc_movable.gd index 5fbcd0a0..14b8a085 100644 --- a/addons/escoria-core/game/core-scripts/behaviors/esc_movable.gd +++ b/addons/escoria-core/game/core-scripts/behaviors/esc_movable.gd @@ -327,7 +327,7 @@ func _get_dir_deg(deg: int, animations: ESCAnimationResource) -> int: var i = 0 for direction_angle in animations.dir_angles: - if is_angle_in_interval(deg, direction_angle): + if _is_angle_in_interval(deg, direction_angle): dir = i break else: @@ -353,7 +353,7 @@ func _get_dir_deg(deg: int, animations: ESCAnimationResource) -> int: # - direction_angle: ESCDirectionAngle resource, containing the starting angle, # and the size of interval # eg: angle_start=90, angle_size=40 corresponds to angle between 90° and 130° -func is_angle_in_interval( +func _is_angle_in_interval( angle: float, direction_angle: ESCDirectionAngle ) -> bool: @@ -364,19 +364,47 @@ func is_angle_in_interval( var angle_area = direction_angle.angle_size var end_angle = wrapi(direction_angle.angle_start + angle_area, 0, 360) - if ((angle >= 270 and angle <= 360) \ - or (angle >= 0 and angle <= 90)) \ - and wrapi(angle + 180, 0, 360) > wrapi(direction_angle.angle_start - + 180, 0, 360) \ - and wrapi(angle + 180, 0, 360) <= wrapi( - direction_angle.angle_start + angle_area + 180, 0, 360 - ): - return true - elif wrapi(angle, 0, 360) > start_angle \ - and wrapi(angle, 0, 360) <= end_angle: - return true + # First we want to test if angle is in upper part of the clock. + # If it is, we add 180 to all angles so that we test in lower part of the + # clock, so we avoid messing with calculations wrapping around 360° and 0°. + if _angle_is_between_270_to_90(angle): + return _angle_is_between( + angle + 180, + start_angle + 180, + start_angle + angle_area + 180 + ) + else: + return _angle_is_between(angle, start_angle, end_angle) - return false + +# Returns true if angle is in upper part of trigonometric circle +# ie. between 0 and PI +# ie. between 270° and 90° +# ie. between 9 o'clock and 3 o'clock +# +# #### Parameters +# +# - angle: the angle in degrees +func _angle_is_between_270_to_90(angle: float) -> bool: + return (angle >= 270 and angle <= 360) or (angle >= 0 and angle <= 90) + + +# Returns true if angle is between start angle and end angle. All angle values +# will clamped between 0 and 360 degrees. +# +# #### Parameters +# +# - angle: the angle in degrees +# - start_angle: the start value of the angle interval +# - end_angle: the end value of the angle interval +func _angle_is_between( + angle: float, + start_angle: float, + end_angle: float +) -> bool: + return wrapi(angle, 0, 360) >= wrapi(start_angle, 0, 360) \ + and wrapi(angle, 0, 360) <= wrapi(end_angle, 0, 360) + # Sets character's angle and plays according animation. # diff --git a/docs/api/ESCMovable.md b/docs/api/ESCMovable.md index 34298b63..b6e9aea2 100644 --- a/docs/api/ESCMovable.md +++ b/docs/api/ESCMovable.md @@ -175,12 +175,6 @@ Update the sprite scale and lighting - on_event_finished_name: Used if this function is called from an ESC event -### is\_angle\_in\_interval - -```gdscript -func is_angle_in_interval(angle: float, direction_angle: ESCDirectionAngle) -> bool -``` - ### set\_angle ```gdscript