From d95d26ff5fb00030c4d8a06ea95f7b040e2f2bc2 Mon Sep 17 00:00:00 2001 From: Duncan Brown Date: Thu, 27 Oct 2022 15:37:48 -0400 Subject: [PATCH] fix: updates camera limit checking in commands to respect viewport limits (i.e. taking into account camera centre and half-screen limits); also updates warning message and no longer fails on limit violation. --- .../core-scripts/esc/commands/camera_push.gd | 6 ++--- .../esc/commands/camera_set_pos.gd | 6 ++--- .../core-scripts/esc/commands/camera_shift.gd | 7 ++---- .../game/scenes/camera_player/esc_camera.gd | 24 ++++++++++++++++++- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/addons/escoria-core/game/core-scripts/esc/commands/camera_push.gd b/addons/escoria-core/game/core-scripts/esc/commands/camera_push.gd index 4b89b690..38a3b803 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/camera_push.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/camera_push.gd @@ -57,14 +57,12 @@ func validate(arguments: Array): var target_pos = (escoria.object_manager.get_object(arguments[0]).node as ESCItem).global_position + Vector2.ONE var camera: ESCCamera = escoria.object_manager.get_object(escoria.object_manager.CAMERA).node as ESCCamera - # has_point() is exclusive of right-/bottom-edge - var camera_limit_to_test: Rect2 = Rect2(camera.limit_left, camera.limit_top, camera.limit_right - camera.limit_left + 1, camera.limit_bottom - camera.limit_top + 1) var camera_limit: Rect2 = Rect2(camera.limit_left, camera.limit_top, camera.limit_right - camera.limit_left, camera.limit_bottom - camera.limit_top) - if not camera_limit_to_test.has_point(target_pos): + if not camera.check_point_is_inside_viewport_limits(target_pos): escoria.logger.warn( self, - "[%s]: invalid camera position. Camera cannot be moved to %s at position %s as this is outside the current camera limit %s." + "[%s]: Invalid camera position. Moving camera by %s to %s will result in viewport being clamped to the current camera limit %s but its actual position not reflecting this." % [ get_command_name(), arguments[0], diff --git a/addons/escoria-core/game/core-scripts/esc/commands/camera_set_pos.gd b/addons/escoria-core/game/core-scripts/esc/commands/camera_set_pos.gd index 0ba5c741..8ac1b7c5 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/camera_set_pos.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/camera_set_pos.gd @@ -31,14 +31,12 @@ func validate(arguments: Array): var new_pos: Vector2 = Vector2(arguments[1], arguments[2]) var camera: ESCCamera = escoria.object_manager.get_object(escoria.object_manager.CAMERA).node as ESCCamera - # has_point() is exclusive of right-/bottom-edge - var camera_limit_to_test: Rect2 = Rect2(camera.limit_left, camera.limit_top, camera.limit_right - camera.limit_left + 1, camera.limit_bottom - camera.limit_top + 1) var camera_limit: Rect2 = Rect2(camera.limit_left, camera.limit_top, camera.limit_right - camera.limit_left, camera.limit_bottom - camera.limit_top) - if not camera_limit_to_test.has_point(new_pos): + if not camera.check_point_is_inside_viewport_limits(new_pos): escoria.logger.warn( self, - "[%s]: invalid camera position. Camera cannot be moved to %s as this is outside the current camera limit %s." + "[%s]: Invalid camera position. Moving camera by %s to %s will result in viewport being clamped to the current camera limit %s but its actual position not reflecting this." % [ get_command_name(), new_pos, diff --git a/addons/escoria-core/game/core-scripts/esc/commands/camera_shift.gd b/addons/escoria-core/game/core-scripts/esc/commands/camera_shift.gd index 797d972c..d8e8d107 100644 --- a/addons/escoria-core/game/core-scripts/esc/commands/camera_shift.gd +++ b/addons/escoria-core/game/core-scripts/esc/commands/camera_shift.gd @@ -76,16 +76,14 @@ func validate(arguments: Array): return false var camera: ESCCamera = escoria.object_manager.get_object(escoria.object_manager.CAMERA).node as ESCCamera - # has_point() is exclusive of right-/bottom-edge - var camera_limit_to_test: Rect2 = Rect2(camera.limit_left, camera.limit_top, camera.limit_right - camera.limit_left + 1, camera.limit_bottom - camera.limit_top + 1) var camera_limit: Rect2 = Rect2(camera.limit_left, camera.limit_top, camera.limit_right - camera.limit_left, camera.limit_bottom - camera.limit_top) var shift_by: Vector2 = Vector2(arguments[0], arguments[1]) var new_pos: Vector2 = Vector2(camera.position.x + shift_by.x, camera.position.y + shift_by.y) - if not camera_limit_to_test.has_point(new_pos): + if not camera.check_point_is_inside_viewport_limits(new_pos): escoria.logger.warn( self, - "[%s]: invalid camera position. Camera cannot be moved by %s to %s as this is outside the current camera limit %s." + "[%s]: Invalid camera position. Moving camera by %s to %s will result in viewport being clamped to the current camera limit %s but its actual position not reflecting this." % [ get_command_name(), shift_by, @@ -93,7 +91,6 @@ func validate(arguments: Array): camera_limit ] ) - return false return true diff --git a/addons/escoria-core/game/scenes/camera_player/esc_camera.gd b/addons/escoria-core/game/scenes/camera_player/esc_camera.gd index e194cac5..8130af58 100644 --- a/addons/escoria-core/game/scenes/camera_player/esc_camera.gd +++ b/addons/escoria-core/game/scenes/camera_player/esc_camera.gd @@ -305,6 +305,28 @@ func shift(p_target: Vector2, p_time: float, p_type: int): _tween.start() +# Checks whether the given point is contained within the viewport's limits. +# Note that this is different from the camera's limits when using anchor mode +# DRAG_CENTER. +# +# #### Parameters +# - point: Point to be tested against viewport limits. +# +# **Returns** true iff point is inside the calculated viewport's limits (inclusive) +func check_point_is_inside_viewport_limits(point: Vector2) -> bool: + var viewport_rect: Rect2 = get_viewport_rect() + var screen_half_size: Vector2 = viewport_rect.size * 0.5 + + var limits_to_test: Rect2 = Rect2( + limit_left + screen_half_size.x, + limit_top + screen_half_size.y, + limit_right - limit_left - viewport_rect.size.x + 1, + limit_bottom - limit_top - viewport_rect.size.y + 1 + ) + + return limits_to_test.has_point(point) + + func _target_reached(): _tween.stop_all() set_drag_margin_enabled(true, true) @@ -350,5 +372,5 @@ func _convert_current_global_pos_for_disabled_drag_margin() -> void: ret_position.y = ret_position.y - (viewport_rect.size.y * 0.5 * zoom.y * drag_margin_bottom) elif cur_camera_pos.y > ret_position.y: ret_position.y = ret_position.y + (viewport_rect.size.y * 0.5 * zoom.y * drag_margin_top) - + self.global_position = ret_position