godot-plateformer/_player/states/grapping.gd

103 lines
2.5 KiB
GDScript3
Raw Normal View History

2025-12-31 16:24:11 +08:00
extends LimboState
2026-01-05 15:28:43 +08:00
@onready var root: Normal = %Normal
2025-12-31 16:24:11 +08:00
@export_category("Hook Pull Release")
@export var release_distance: float = 12.0
@export var release_dot_threshold: float = 0.0
2026-01-05 15:28:43 +08:00
@export var min_pull_timer: float = 0.08
2025-12-31 16:24:11 +08:00
2026-01-05 15:28:43 +08:00
var _pull_timer := 0.0
2025-12-31 16:24:11 +08:00
var _anchor
2026-01-05 17:38:43 +08:00
var _tween: Tween
2026-01-05 15:28:43 +08:00
func _setup() -> void:
self.add_event_handler(&"trigger_jump",_handle_trigger_jump)
2025-12-31 16:24:11 +08:00
func _enter() -> void:
2026-01-05 17:38:43 +08:00
var tween := get_tree().create_tween()
tween.set_ignore_time_scale(true)
2026-01-06 23:18:36 +08:00
tween.tween_property(Engine, "time_scale", .25, .03)
tween.tween_interval(.1)
tween.tween_property(Engine, "time_scale", 1.0, .05)
2026-01-05 17:38:43 +08:00
2026-01-06 23:18:36 +08:00
var hook_inst: Hook = agent.spawn_hook_comp.get_current_hook_inst()
if hook_inst:
var i = hook_inst.get_direction_id()
2026-01-08 22:39:39 +08:00
#if i >= 0:
#if i == 0 or i == 4:
#CameraSystem.get_cached_camera().emit_hook_touch_shock(0)
#elif i == 1 or i == 5:
#CameraSystem.get_cached_camera().emit_hook_touch_shock(1)
#elif i == 2 or i == 6:
#CameraSystem.get_cached_camera().emit_hook_touch_shock(2)
#elif i == 3 or i == 7:
#CameraSystem.get_cached_camera().emit_hook_touch_shock(3)
2026-01-06 11:58:41 +08:00
2026-01-05 15:28:43 +08:00
if root.grap_hook_state._jump_grace_timer > 0:
_hook_to_jump()
_pull_timer = 0.0
2025-12-31 16:24:11 +08:00
_anchor = agent.spawn_hook_comp.get_current_hook_anchor()
if _anchor and is_instance_valid(_anchor):
agent.locomotion_comp._custom_move_to(_anchor)
func _update(delta: float) -> void:
2026-01-05 15:28:43 +08:00
_pull_timer += delta
2025-12-31 16:24:11 +08:00
2026-01-05 15:28:43 +08:00
if _pull_timer < min_pull_timer:
2025-12-31 16:24:11 +08:00
return
if not _anchor or not is_instance_valid(_anchor):
_force_release()
return
var character : CharacterBody2D = agent
var pos: Vector2 = character.global_position
var target_pos: Vector2 = _anchor.global_position
var to_target := target_pos - pos
var distance := to_target.length()
if distance <= release_distance:
_force_release()
return
if distance > 0.001:
var dir := to_target / distance
if character.velocity.dot(dir) <= release_dot_threshold:
_force_release()
return
func _exit() -> void:
agent.locomotion_comp.stop_custom_move(false)
_anchor = null
2026-01-05 15:28:43 +08:00
agent.spawn_hook_comp.release_cached_hook()
func _handle_trigger_jump() -> bool:
_hook_to_jump()
return false
func _hook_to_jump() -> void:
get_root().blackboard.set_var(&"want_to_jump",true)
self.dispatch(&"hook_to_jump")
2025-12-31 16:24:11 +08:00
func _force_release() -> void:
agent.locomotion_comp.stop_custom_move(false)
if agent.spawn_hook_comp.has_method("release_hook"):
agent.spawn_hook_comp.release_hook()
##解除hook
if agent.is_on_floor():
self.dispatch(&"exit_on_ground")
else:
self.dispatch(&"exit_on_air")
return