feat: adapt fishing visuals to character scale
This commit is contained in:
parent
038b628061
commit
0bbd449c55
4 changed files with 63 additions and 13 deletions
|
|
@ -59,6 +59,7 @@ var _cast_arrival_position: Vector3
|
||||||
var _cast_tracks_water_surface: bool = false
|
var _cast_tracks_water_surface: bool = false
|
||||||
var _bobber_surface_position: Vector3
|
var _bobber_surface_position: Vector3
|
||||||
var _bobber_idle_elapsed: float = 0.0
|
var _bobber_idle_elapsed: float = 0.0
|
||||||
|
var _bobber_base_scale: Vector3 = Vector3.ONE
|
||||||
var _active_tween: Tween
|
var _active_tween: Tween
|
||||||
var _rod_tween: Tween
|
var _rod_tween: Tween
|
||||||
var _bite_tween: Tween
|
var _bite_tween: Tween
|
||||||
|
|
@ -94,11 +95,13 @@ func begin_aim(
|
||||||
minimum_target: Vector3,
|
minimum_target: Vector3,
|
||||||
target_normal: Vector3,
|
target_normal: Vector3,
|
||||||
target_is_fishable: bool,
|
target_is_fishable: bool,
|
||||||
|
character_scale: float = 1.0,
|
||||||
) -> void:
|
) -> void:
|
||||||
cleanup()
|
cleanup()
|
||||||
if rod_tip == null or rod == null:
|
if rod_tip == null or rod == null:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
_bobber_base_scale = Vector3.ONE * maxf(character_scale, 0.01)
|
||||||
_mode = VisualMode.AIMING
|
_mode = VisualMode.AIMING
|
||||||
_rod = rod
|
_rod = rod
|
||||||
_rod_tip = rod_tip
|
_rod_tip = rod_tip
|
||||||
|
|
@ -158,7 +161,7 @@ func begin_cast(
|
||||||
_mode = VisualMode.CASTING
|
_mode = VisualMode.CASTING
|
||||||
_target_marker.visible = false
|
_target_marker.visible = false
|
||||||
_bobber.visible = true
|
_bobber.visible = true
|
||||||
_bobber.scale = Vector3.ONE
|
_bobber.scale = _bobber_base_scale
|
||||||
_cast_arrival_position = (
|
_cast_arrival_position = (
|
||||||
blocked_landing_position if cast_is_blocked else target
|
blocked_landing_position if cast_is_blocked else target
|
||||||
)
|
)
|
||||||
|
|
@ -188,26 +191,26 @@ func show_bite() -> void:
|
||||||
return
|
return
|
||||||
|
|
||||||
_kill_bite_tween()
|
_kill_bite_tween()
|
||||||
_bobber.scale = Vector3.ONE
|
_bobber.scale = _bobber_base_scale
|
||||||
_bite_tween = create_tween()
|
_bite_tween = create_tween()
|
||||||
_bite_tween.set_trans(Tween.TRANS_QUAD)
|
_bite_tween.set_trans(Tween.TRANS_QUAD)
|
||||||
_bite_tween.set_ease(Tween.EASE_IN_OUT)
|
_bite_tween.set_ease(Tween.EASE_IN_OUT)
|
||||||
_bite_tween.tween_property(
|
_bite_tween.tween_property(
|
||||||
_bobber,
|
_bobber,
|
||||||
"scale",
|
"scale",
|
||||||
Vector3.ONE * 0.68,
|
_bobber_base_scale * 0.68,
|
||||||
0.08
|
0.08
|
||||||
)
|
)
|
||||||
_bite_tween.tween_property(
|
_bite_tween.tween_property(
|
||||||
_bobber,
|
_bobber,
|
||||||
"scale",
|
"scale",
|
||||||
Vector3.ONE * 1.2,
|
_bobber_base_scale * 1.2,
|
||||||
0.1
|
0.1
|
||||||
)
|
)
|
||||||
_bite_tween.tween_property(
|
_bite_tween.tween_property(
|
||||||
_bobber,
|
_bobber,
|
||||||
"scale",
|
"scale",
|
||||||
Vector3.ONE,
|
_bobber_base_scale,
|
||||||
0.1
|
0.1
|
||||||
)
|
)
|
||||||
_bite_tween.finished.connect(_on_bite_tween_finished)
|
_bite_tween.finished.connect(_on_bite_tween_finished)
|
||||||
|
|
@ -247,7 +250,7 @@ func play_outcome(outcome: StringName) -> void:
|
||||||
# Withdrawal is a visible return, not an instant cancellation. Keep the
|
# Withdrawal is a visible return, not an instant cancellation. Keep the
|
||||||
# bobber present even if the preceding reel update hid or reset it.
|
# bobber present even if the preceding reel update hid or reset it.
|
||||||
_bobber.visible = true
|
_bobber.visible = true
|
||||||
_bobber.scale = Vector3.ONE
|
_bobber.scale = _bobber_base_scale
|
||||||
_active_tween = create_tween()
|
_active_tween = create_tween()
|
||||||
_active_tween.set_trans(Tween.TRANS_QUAD)
|
_active_tween.set_trans(Tween.TRANS_QUAD)
|
||||||
_active_tween.set_ease(Tween.EASE_IN)
|
_active_tween.set_ease(Tween.EASE_IN)
|
||||||
|
|
@ -296,6 +299,7 @@ func cleanup() -> void:
|
||||||
_invalid_target_marker.visible = false
|
_invalid_target_marker.visible = false
|
||||||
_bobber.visible = false
|
_bobber.visible = false
|
||||||
_bobber.scale = Vector3.ONE
|
_bobber.scale = Vector3.ONE
|
||||||
|
_bobber_base_scale = Vector3.ONE
|
||||||
_bobber.rotation = Vector3.ZERO
|
_bobber.rotation = Vector3.ZERO
|
||||||
_cast_arrival_position = Vector3.ZERO
|
_cast_arrival_position = Vector3.ZERO
|
||||||
_cast_tracks_water_surface = false
|
_cast_tracks_water_surface = false
|
||||||
|
|
@ -475,7 +479,7 @@ func _kill_bite_tween() -> void:
|
||||||
_bite_tween.kill()
|
_bite_tween.kill()
|
||||||
_bite_tween = null
|
_bite_tween = null
|
||||||
if is_instance_valid(_bobber):
|
if is_instance_valid(_bobber):
|
||||||
_bobber.scale = Vector3.ONE
|
_bobber.scale = _bobber_base_scale
|
||||||
|
|
||||||
|
|
||||||
func _on_bite_tween_finished() -> void:
|
func _on_bite_tween_finished() -> void:
|
||||||
|
|
|
||||||
|
|
@ -609,7 +609,8 @@ func _begin_aiming(player: PlayerType) -> void:
|
||||||
_active_player.get_fishing_rod(),
|
_active_player.get_fishing_rod(),
|
||||||
preview_position,
|
preview_position,
|
||||||
_aim_surface_sample.normal,
|
_aim_surface_sample.normal,
|
||||||
target_is_fishable
|
target_is_fishable,
|
||||||
|
_active_player.get_character_visual_scale(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -952,6 +953,7 @@ func _activate_bite() -> void:
|
||||||
return
|
return
|
||||||
|
|
||||||
state = FishingState.FIGHTING
|
state = FishingState.FIGHTING
|
||||||
|
_active_player.set_fighting_visual(true)
|
||||||
_state_time_remaining = 0.0
|
_state_time_remaining = 0.0
|
||||||
_withdrawal_input_held = false
|
_withdrawal_input_held = false
|
||||||
_pending_catch = _fish_selector.create_catch(_selected_fish)
|
_pending_catch = _fish_selector.create_catch(_selected_fish)
|
||||||
|
|
@ -1040,6 +1042,7 @@ func _on_catch_completed() -> void:
|
||||||
_cancel_attempt()
|
_cancel_attempt()
|
||||||
return
|
return
|
||||||
_stop_fight_audio()
|
_stop_fight_audio()
|
||||||
|
_active_player.set_fighting_visual(false)
|
||||||
state = FishingState.SHOWING_CATCH
|
state = FishingState.SHOWING_CATCH
|
||||||
_showcase_ready = false
|
_showcase_ready = false
|
||||||
_showcase_outcome_completed = false
|
_showcase_outcome_completed = false
|
||||||
|
|
@ -1162,6 +1165,8 @@ func _cleanup_attempt(
|
||||||
) -> void:
|
) -> void:
|
||||||
_stop_fight_audio()
|
_stop_fight_audio()
|
||||||
_stop_reeling_audio()
|
_stop_reeling_audio()
|
||||||
|
if _active_player != null:
|
||||||
|
_active_player.set_fighting_visual(false)
|
||||||
if not visual_outcome.is_empty():
|
if not visual_outcome.is_empty():
|
||||||
if state == FishingState.RETURNING:
|
if state == FishingState.RETURNING:
|
||||||
return
|
return
|
||||||
|
|
@ -1190,6 +1195,7 @@ func _cleanup_attempt(
|
||||||
func _finalize_attempt_cleanup(cooldown_message: String) -> void:
|
func _finalize_attempt_cleanup(cooldown_message: String) -> void:
|
||||||
_showcase_restore_generation += 1
|
_showcase_restore_generation += 1
|
||||||
if _active_player != null:
|
if _active_player != null:
|
||||||
|
_active_player.set_fighting_visual(false)
|
||||||
_active_player.end_catch_showcase()
|
_active_player.end_catch_showcase()
|
||||||
_active_player.set_movement_enabled(true)
|
_active_player.set_movement_enabled(true)
|
||||||
_active_player = null
|
_active_player = null
|
||||||
|
|
@ -1477,6 +1483,8 @@ func _on_network_bite_started(_attempt_id: String) -> void:
|
||||||
return
|
return
|
||||||
_stop_reeling_audio()
|
_stop_reeling_audio()
|
||||||
state = FishingState.FIGHTING
|
state = FishingState.FIGHTING
|
||||||
|
if _active_player != null:
|
||||||
|
_active_player.set_fighting_visual(true)
|
||||||
_withdrawal_input_held = false
|
_withdrawal_input_held = false
|
||||||
_network_primary_input_held = Input.is_action_pressed("fish_primary")
|
_network_primary_input_held = Input.is_action_pressed("fish_primary")
|
||||||
_network_input_resend_elapsed = 0.0
|
_network_input_resend_elapsed = 0.0
|
||||||
|
|
@ -1567,6 +1575,8 @@ func _on_network_catch_received(fish_catch: FishCatchType) -> void:
|
||||||
return
|
return
|
||||||
_stop_fight_audio()
|
_stop_fight_audio()
|
||||||
_pending_catch = fish_catch
|
_pending_catch = fish_catch
|
||||||
|
if _active_player != null:
|
||||||
|
_active_player.set_fighting_visual(false)
|
||||||
state = FishingState.SHOWING_CATCH
|
state = FishingState.SHOWING_CATCH
|
||||||
_showcase_ready = false
|
_showcase_ready = false
|
||||||
_showcase_outcome_completed = false
|
_showcase_outcome_completed = false
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ var _return_tween: Tween
|
||||||
var _showcase_tween: Tween
|
var _showcase_tween: Tween
|
||||||
var _return_showcase_catch: FishCatch
|
var _return_showcase_catch: FishCatch
|
||||||
var _bobber_idle_elapsed: float = 0.0
|
var _bobber_idle_elapsed: float = 0.0
|
||||||
|
var _bobber_base_scale: Vector3 = Vector3.ONE
|
||||||
|
|
||||||
|
|
||||||
func setup(owning_player: Player) -> void:
|
func setup(owning_player: Player) -> void:
|
||||||
|
|
@ -52,11 +53,12 @@ func show_cast(origin: Vector3, target: Vector3) -> void:
|
||||||
return
|
return
|
||||||
_kill_cast_tween()
|
_kill_cast_tween()
|
||||||
_active = true
|
_active = true
|
||||||
|
_bobber_base_scale = Vector3.ONE * _owner.get_character_visual_scale()
|
||||||
_target = origin
|
_target = origin
|
||||||
_pending_target = target
|
_pending_target = target
|
||||||
_bobber_idle_elapsed = 0.0
|
_bobber_idle_elapsed = 0.0
|
||||||
_bobber.global_position = origin
|
_bobber.global_position = origin
|
||||||
_bobber.scale = Vector3.ONE
|
_bobber.scale = _bobber_base_scale
|
||||||
_bobber.visible = true
|
_bobber.visible = true
|
||||||
_line.visible = true
|
_line.visible = true
|
||||||
_owner.set_active_item_is_rod(true)
|
_owner.set_active_item_is_rod(true)
|
||||||
|
|
@ -87,12 +89,16 @@ func update_bobber(world_position: Vector3) -> void:
|
||||||
func show_bite() -> void:
|
func show_bite() -> void:
|
||||||
if not _active:
|
if not _active:
|
||||||
return
|
return
|
||||||
|
if _owner != null and is_instance_valid(_owner):
|
||||||
|
_owner.set_fighting_visual(true)
|
||||||
var tween: Tween = create_tween()
|
var tween: Tween = create_tween()
|
||||||
tween.tween_property(_bobber, "scale", Vector3.ONE * 0.7, 0.08)
|
tween.tween_property(_bobber, "scale", _bobber_base_scale * 0.7, 0.08)
|
||||||
tween.tween_property(_bobber, "scale", Vector3.ONE, 0.12)
|
tween.tween_property(_bobber, "scale", _bobber_base_scale, 0.12)
|
||||||
|
|
||||||
|
|
||||||
func play_return(showcase_catch: FishCatch = null) -> void:
|
func play_return(showcase_catch: FishCatch = null) -> void:
|
||||||
|
if _owner != null and is_instance_valid(_owner):
|
||||||
|
_owner.set_fighting_visual(false)
|
||||||
if not _active or _bobber == null:
|
if not _active or _bobber == null:
|
||||||
cleanup()
|
cleanup()
|
||||||
return_completed.emit()
|
return_completed.emit()
|
||||||
|
|
@ -128,10 +134,12 @@ func cleanup() -> void:
|
||||||
_return_showcase_catch = null
|
_return_showcase_catch = null
|
||||||
_bobber_idle_elapsed = 0.0
|
_bobber_idle_elapsed = 0.0
|
||||||
if _owner != null and is_instance_valid(_owner):
|
if _owner != null and is_instance_valid(_owner):
|
||||||
|
_owner.set_fighting_visual(false)
|
||||||
_owner.end_catch_showcase(Callable(), true)
|
_owner.end_catch_showcase(Callable(), true)
|
||||||
if _bobber != null:
|
if _bobber != null:
|
||||||
_bobber.visible = false
|
_bobber.visible = false
|
||||||
_bobber.scale = Vector3.ONE
|
_bobber.scale = Vector3.ONE
|
||||||
|
_bobber_base_scale = Vector3.ONE
|
||||||
if _line != null:
|
if _line != null:
|
||||||
_line.visible = false
|
_line.visible = false
|
||||||
_line_mesh.clear_surfaces()
|
_line_mesh.clear_surfaces()
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ const CHARACTER_IDLE_SIT_ANIMATION: StringName = &"idle_sit"
|
||||||
const CHARACTER_IDLE_SIT_SHOW_ANIMATION: StringName = &"idle_sit_show"
|
const CHARACTER_IDLE_SIT_SHOW_ANIMATION: StringName = &"idle_sit_show"
|
||||||
const CHARACTER_WALKING_ANIMATION: StringName = &"walking"
|
const CHARACTER_WALKING_ANIMATION: StringName = &"walking"
|
||||||
const CHARACTER_WALKING_SHOW_ANIMATION: StringName = &"walking_show"
|
const CHARACTER_WALKING_SHOW_ANIMATION: StringName = &"walking_show"
|
||||||
|
const FIGHTING_EYES_ID: String = "alligator_eyes"
|
||||||
const BASE_REEL_SPEED: float = 0.16
|
const BASE_REEL_SPEED: float = 0.16
|
||||||
# The target Android handheld exposes its physical right trigger through
|
# The target Android handheld exposes its physical right trigger through
|
||||||
# Godot's left-trigger axis. Keep the role named here so the platform mapping
|
# Godot's left-trigger axis. Keep the role named here so the platform mapping
|
||||||
|
|
@ -75,7 +76,33 @@ func unequip_bait() -> void:
|
||||||
func apply_appearance_snapshot(snapshot: Dictionary) -> void:
|
func apply_appearance_snapshot(snapshot: Dictionary) -> void:
|
||||||
if CharacterCustomizationCatalog.validate_snapshot(snapshot):
|
if CharacterCustomizationCatalog.validate_snapshot(snapshot):
|
||||||
appearance_snapshot = snapshot.duplicate(true)
|
appearance_snapshot = snapshot.duplicate(true)
|
||||||
PlayerVisualPresenter.apply_appearance(_visuals, appearance_snapshot)
|
_apply_presented_appearance()
|
||||||
|
|
||||||
|
|
||||||
|
func get_character_visual_scale() -> float:
|
||||||
|
return CharacterCustomizationCatalog.character_scale(
|
||||||
|
appearance_snapshot.get(
|
||||||
|
CharacterCustomizationCatalog.SCALE_CATEGORY_ID,
|
||||||
|
CharacterCustomizationCatalog.DEFAULT_CHARACTER_SCALE,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func set_fighting_visual(active: bool) -> void:
|
||||||
|
if _fighting_visual_active == active:
|
||||||
|
return
|
||||||
|
_fighting_visual_active = active
|
||||||
|
_apply_presented_appearance()
|
||||||
|
|
||||||
|
|
||||||
|
func _apply_presented_appearance() -> void:
|
||||||
|
if not is_node_ready() or _visuals == null:
|
||||||
|
return
|
||||||
|
var presented_appearance := appearance_snapshot
|
||||||
|
if _fighting_visual_active:
|
||||||
|
presented_appearance = appearance_snapshot.duplicate(true)
|
||||||
|
presented_appearance["eyes"] = FIGHTING_EYES_ID
|
||||||
|
PlayerVisualPresenter.apply_appearance(_visuals, presented_appearance)
|
||||||
|
|
||||||
|
|
||||||
func apply_animalese_voice_id(voice_id: String) -> void:
|
func apply_animalese_voice_id(voice_id: String) -> void:
|
||||||
|
|
@ -218,6 +245,7 @@ var _sitting_intent_pending: bool = false
|
||||||
var _sitting_intent_sequence: int = -1
|
var _sitting_intent_sequence: int = -1
|
||||||
var _held_fish_visible: bool = false
|
var _held_fish_visible: bool = false
|
||||||
var _showcase_animation_active: bool = false
|
var _showcase_animation_active: bool = false
|
||||||
|
var _fighting_visual_active: bool = false
|
||||||
var _fishing_rod: Node3D
|
var _fishing_rod: Node3D
|
||||||
var _fishing_rod_tip: Marker3D
|
var _fishing_rod_tip: Marker3D
|
||||||
var _controller_mapping_manager: ControllerMappingManagerType
|
var _controller_mapping_manager: ControllerMappingManagerType
|
||||||
|
|
@ -226,7 +254,7 @@ var _controller_mapping_manager: ControllerMappingManagerType
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
if not bag.contents_changed.is_connected(_on_bag_contents_changed):
|
if not bag.contents_changed.is_connected(_on_bag_contents_changed):
|
||||||
bag.contents_changed.connect(_on_bag_contents_changed)
|
bag.contents_changed.connect(_on_bag_contents_changed)
|
||||||
PlayerVisualPresenter.apply_appearance(_visuals, appearance_snapshot)
|
_apply_presented_appearance()
|
||||||
_initialize_fishing_rod()
|
_initialize_fishing_rod()
|
||||||
_target_zoom = clampf(_spring_arm.spring_length, minimum_zoom, maximum_zoom)
|
_target_zoom = clampf(_spring_arm.spring_length, minimum_zoom, maximum_zoom)
|
||||||
_spring_arm.spring_length = _target_zoom
|
_spring_arm.spring_length = _target_zoom
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue