From 37ac675399978514748700ad71c168d4a29898b2 Mon Sep 17 00:00:00 2001 From: Voyager Date: Mon, 17 Aug 2026 19:06:50 -0400 Subject: [PATCH] fix: hold successful net strikes before showcase --- player/player.gd | 53 +++++++++++++++++-- .../player_gathering_animation_validation.gd | 7 +++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/player/player.gd b/player/player.gd index 5514b57..487c2fa 100644 --- a/player/player.gd +++ b/player/player.gd @@ -355,6 +355,7 @@ class ShowcaseCameraSnapshot: @export_category("Gathering") @export_flags_3d_physics var net_impact_collision_mask: int = 1 @export_range(0.02, 0.5, 0.01) var net_impact_radius: float = 0.16 +@export_range(0.0, 1.0, 0.01) var net_success_contact_pause_duration: float = 0.45 @export_category("Camera") @export var mouse_sensitivity: float = 0.005 @@ -508,6 +509,7 @@ var _net_strike_previous_animation_position: float = 0.0 var _net_strike_contact_held: bool = false var _net_strike_result_known: bool = false var _net_strike_successful: bool = false +var _net_strike_showcase_pause_tween: Tween var _net_impact_shape := SphereShape3D.new() var _pending_net_showcase_catch: FishCatchType var _pending_net_showcase_remote: bool = false @@ -669,6 +671,7 @@ func cancel_net_action_visual() -> void: func _clear_net_strike_state() -> void: + _kill_net_strike_showcase_pause() _net_strike_collision_armed = false _net_strike_has_previous_sample = false _net_strike_contact_held = false @@ -678,6 +681,50 @@ func _clear_net_strike_state() -> void: _set_animation_action_paused(false) +func _kill_net_strike_showcase_pause() -> void: + if ( + _net_strike_showcase_pause_tween != null + and _net_strike_showcase_pause_tween.is_valid() + ): + _net_strike_showcase_pause_tween.kill() + _net_strike_showcase_pause_tween = null + + +func _hold_successful_net_strike_before_showcase() -> void: + _kill_net_strike_showcase_pause() + var strike_animation := _character_animation_player.get_animation( + CHARACTER_NET_STRIKE_ANIMATION + ) + if strike_animation != null: + _animation_action_elapsed = maxf( + strike_animation.length - 0.001, + 0.0, + ) + _net_strike_collision_armed = false + _net_strike_contact_held = false + _set_animation_action_paused(true) + if net_success_contact_pause_duration <= 0.0: + _finish_successful_net_strike_pause() + return + _net_strike_showcase_pause_tween = create_tween() + _net_strike_showcase_pause_tween.tween_interval( + net_success_contact_pause_duration + ) + _net_strike_showcase_pause_tween.finished.connect( + _finish_successful_net_strike_pause + ) + + +func _finish_successful_net_strike_pause() -> void: + _net_strike_showcase_pause_tween = null + if local_control_enabled: + if not _net_strike_result_known or not _net_strike_successful: + return + _clear_net_strike_state() + end_animation_action() + _begin_pending_net_showcase() + + func _set_animation_action_paused(paused: bool) -> void: if _animation_action_id.is_empty() or _animation_action_paused == paused: return @@ -1352,9 +1399,7 @@ func _on_character_animation_finished(animation_name: StringName) -> void: if animation_name == CHARACTER_NET_STRIKE_ANIMATION: if local_control_enabled: if _net_strike_result_known and _net_strike_successful: - _clear_net_strike_state() - end_animation_action() - _begin_pending_net_showcase() + _hold_successful_net_strike_before_showcase() else: var strike_animation := ( _character_animation_player.get_animation( @@ -1371,7 +1416,7 @@ func _on_character_animation_finished(animation_name: StringName) -> void: _set_animation_action_paused(true) return if _pending_net_showcase_remote: - _begin_pending_net_showcase() + _hold_successful_net_strike_before_showcase() return if ( local_control_enabled diff --git a/tests/player_gathering_animation_validation.gd b/tests/player_gathering_animation_validation.gd index c0f5576..40ca8f6 100644 --- a/tests/player_gathering_animation_validation.gd +++ b/tests/player_gathering_animation_validation.gd @@ -65,6 +65,7 @@ func _run() -> void: assert(player.play_net_strike_visual()) player.resolve_net_strike_visual(true) + player.net_success_contact_pause_duration = 0.05 var crab_catch := FishCatch.new() crab_catch.fish = CrabBrown crab_catch.fish_id = CrabBrown.id @@ -80,6 +81,12 @@ func _run() -> void: assert(not bool(player.get("_showcase_animation_active"))) assert(player.get("_pending_net_showcase_catch") == crab_catch) player.call("_on_character_animation_finished", &"strike") + assert(StringName(player.get("_animation_action_id")) == &"strike") + assert(bool(player.get("_animation_action_paused"))) + assert(not bool(player.get("_showcase_animation_active"))) + var contact_pause := player.get("_net_strike_showcase_pause_tween") as Tween + assert(contact_pause != null and contact_pause.is_valid()) + await contact_pause.finished assert(StringName(player.get("_animation_action_id")).is_empty()) assert(bool(player.get("_showcase_animation_active"))) var catch_display := player.get("_catch_display") as Node3D