xiandie/scene/ground/script/c02/小手讨东西.gd

247 lines
7.8 KiB
GDScript3
Raw Normal View History

@tool
extends Sprite2D
signal interact_start
2025-06-04 14:02:22 +00:00
2025-06-04 11:46:27 +00:00
# 0保卫科 1二楼内侧
@export_enum("保卫科", "二楼内侧") var id := 0
@export var enabled := true:
set(val):
enabled = val
if is_node_ready():
_check_sign_mark_display()
2025-06-04 11:46:27 +00:00
@export var unrevealed_sign_texture: Texture2D
@export var unmatched_sign_texture: Texture2D
@export var matched_sign_texture: Texture2D
@onready var sfx_invalid = $SfxInvalid as Sfx
@onready var sfx_success = $SfxSuccess as Sfx
2025-05-14 20:43:55 +00:00
@onready var sfx_bgm = $SfxBgm as AudioStreamPlayer
@onready var sign_mark = %Sign as Sign
@onready var sign_snapper = %SignSnapper as SignSnapper
@onready var area2d = %Area2D as Area2D
2025-05-14 20:43:55 +00:00
@onready var animated_sprite = $"小手" as AnimatedSprite2D
var ground_archive: GroundArchive
static var item_config_res = preload("res://asset/dialogue/item_description.dialogue")
# 当前小手手持的 prop
2025-05-14 20:43:55 +00:00
var holding_prop = "":
set(val):
holding_prop = val
ground_archive.set_pair(name, "holding_prop", val)
# 是否手持纸杯电话
var is_holding_cup = false:
set(val):
is_holding_cup = val
ground_archive.set_pair(name, "is_holding_cup", val)
# 锡纸是否在地上
var tin_coin_drop = false:
set(val):
tin_coin_drop = val
ground_archive.set_pair(name, "tin_coin_drop", tin_coin_drop)
if is_node_ready():
coin.enabled = val
if tin_coin_drop:
coin.reset()
2025-06-04 11:46:27 +00:00
# 尝试互动的次数
var icount: int:
2025-06-04 11:46:27 +00:00
set(val):
icount = val
ground_archive.set_pair(name, "icount", val)
# update sign texture
if icount == 0:
# 首次交互前 unrevealed
sign_mark.sprite2d.texture = unrevealed_sign_texture
else:
sign_mark.sprite2d.texture = matched_sign_texture
if icount == 1:
var stage = EventManager.get_stage(&"c02_little_hand")
if stage == 0:
# 首次交互小手
EventManager.set_stage(&"c02_little_hand", 1)
# 9 小手交互,吓摔倒
SceneManager.lock_player(0, 9, true)
SceneManager.pop_os_with_str("c02_小手出现摔倒")
2025-06-30 10:33:40 +00:00
Util.timer(1.5, $"Sfx摔倒".play)
await SceneManager.get_player().animation_finished
2025-07-01 11:40:30 +00:00
SceneManager.pop_os_with_str("c02_小手是什么鬼")
SceneManager.unlock_player()
elif stage == 1:
# 第二次交互小手
EventManager.set_stage(&"c02_little_hand", 2)
SceneManager.pop_os_with_str("c02_小手再次出现")
2025-05-14 20:43:55 +00:00
var coin: Pickable2D
func _ready() -> void:
if Engine.is_editor_hint():
return
# sign_mark.interacted.connect(_on_interacted)
sign_snapper.arrived.connect(_on_interacted)
sign_mark.cancel.connect(_on_cancel)
_check_sign_mark_display()
2025-05-14 20:43:55 +00:00
# setup default value
2025-05-14 20:43:55 +00:00
ground_archive = ArchiveManager.archive.ground_archive() as GroundArchive
is_holding_cup = ground_archive.get_value(name, "is_holding_cup", false)
holding_prop = ground_archive.get_value(name, "holding_prop", "")
icount = ground_archive.get_value(name, "icount", 0)
2025-05-14 20:43:55 +00:00
if holding_prop == "prop_弹珠":
animated_sprite.play("小手_弹珠_idle")
elif holding_prop == "prop_老虎钳":
animated_sprite.play("小手_老虎钳_idle")
elif is_holding_cup:
animated_sprite.play("小手_纸杯_idle")
elif icount > 0:
2025-06-04 14:02:22 +00:00
animated_sprite.play("小手_show")
2025-05-14 20:43:55 +00:00
coin = get_node("Pickable元宝")
tin_coin_drop = ground_archive.get_value(name, "tin_coin_drop", false)
coin.triggered.connect(func(): tin_coin_drop = false)
func _check_sign_mark_display():
sign_mark.enabled = enabled and not interacting
2025-06-04 11:46:27 +00:00
# 在场景中调用该方法,可以跳过小手初次交互的伸出过程
func do_first_interact(immediatelly := false):
if immediatelly:
animated_sprite.play("小手_idle")
else:
animated_sprite.play("小手_show")
await animated_sprite.animation_changed
2025-05-14 20:43:55 +00:00
func _on_cancel(_body = null) -> void:
if communicating:
_quit_communicating()
return
func _quit_communicating() -> void:
sfx_bgm.stop()
if sfx_bgm.finished.is_connected(_quit_communicating):
sfx_bgm.finished.disconnect(_quit_communicating)
communicating = false
SceneManager.release_player()
# 重置动画
SceneManager.get_player().set_facing_direction(Vector2.ONE)
animated_sprite.visible = true
2025-06-07 09:04:08 +00:00
animated_sprite.play("小手_纸杯_show")
2025-05-14 20:43:55 +00:00
var interacting := false:
set(val):
interacting = val
_check_sign_mark_display()
2025-05-14 20:43:55 +00:00
var communicating = false
func _on_interacted() -> void:
if interacting:
print("小手 interacting 锁定中")
# SceneManager.release_player()
return
interacting = true
interact_start.emit()
icount += 1
if icount == 1:
await do_first_interact(false)
elif holding_prop != "":
# 手持物品时,交互直接给玩家物品
SceneManager.enable_prop_item(holding_prop)
holding_prop = ""
2025-06-04 11:46:27 +00:00
animated_sprite.play("小手_show")
await animated_sprite.animation_changed
elif is_holding_cup:
2025-05-14 20:43:55 +00:00
# 对话
if not communicating:
communicating = true
# animated_sprite.visible = false
2025-05-14 20:43:55 +00:00
# 7 拿起纸杯 8 监听纸杯
SceneManager.freeze_player(0, 7)
# 小手收回 play backwards
animated_sprite.play("小手_纸杯_hide")
2025-06-14 08:46:32 +00:00
await SceneManager.get_player().animation_finished
SceneManager.player_action(8)
2025-05-14 20:43:55 +00:00
SceneManager.pop_debug_dialog_info("音效", "纸杯电话童谣")
sfx_bgm.play()
# 交互时,已经在对话中
sfx_bgm.finished.connect(_quit_communicating, CONNECT_ONE_SHOT)
else:
_quit_communicating()
else:
var key = SceneManager.get_current_prop(false)
var interacted_success = false
SceneManager.lock_player(0, 4)
# accept_tin_coin
if key == "prop_锡箔元宝":
interacted_success = true
sfx_success.play()
SceneManager.disable_prop_item("prop_锡箔元宝")
if id == 1:
SceneManager.enable_prop_item_silently("prop_小鞋子1")
ArchiveManager.set_global_entry(&"c02_mouse_follow_player", true)
# 叠成纸杯电话
animated_sprite.play("小手_锡箔_hide")
is_holding_cup = true
SceneManager.pop_debug_dialog_info(
"美术", "叠成纸杯: 小手_锡箔_hide + 小手_纸杯_show + 小手_纸杯_idle"
)
2025-06-30 10:33:40 +00:00
await Util.wait(2.0)
# 稍等片刻再给小鞋子
SceneManager.enable_prop_item("prop_小鞋子1")
await SceneManager.get_inspector().quit_and_hidden
SceneManager.pop_os_with_str("c02_锡箔换小鞋子")
var node = get_node("../自动跟随的老鼠") as Node2D
if node:
node.visible = true
else:
printerr("小手已接受锡箔;自动跟随的老鼠节点不存在")
else:
# 丢下元宝
animated_sprite.play("小手_锡箔_drop")
# 先设置允许 pickable然后再设置可见性等待动画播完再显示
tin_coin_drop = true
coin.visible = false
2025-06-30 10:33:40 +00:00
await Util.wait(1.5)
coin.visible = true
if not ArchiveManager.get_global_value(&"c02_little_hand_dropped_tin"):
2025-07-01 11:40:30 +00:00
SceneManager.pop_os_with_str("c02_小手还能换什么")
ArchiveManager.set_global_entry(&"c02_little_hand_dropped_tin", true)
# 是否允许老虎钳换弹珠
var pliers_to_ball = ArchiveManager.get_global_value(&"c02_pliers_to_ball", false)
if id == 0 and key == "prop_老虎钳" and pliers_to_ball:
interacted_success = true
sfx_success.play()
SceneManager.disable_prop_item("prop_老虎钳")
animated_sprite.play("小手_老虎钳_hide")
SceneManager.pop_debug_dialog_info("美术", "小手_老虎钳_hide + 小手_弹珠_show + 小手_弹珠_idle")
2025-06-30 10:33:40 +00:00
await Util.wait(1.5)
holding_prop = "prop_弹珠"
EventManager.set_stage_if_greater("handnote_stage", 4)
elif id == 0 and key == "prop_弹珠" and not pliers_to_ball:
interacted_success = true
sfx_success.play()
SceneManager.disable_prop_item("prop_弹珠")
animated_sprite.play("小手_弹珠_hide")
SceneManager.pop_debug_dialog_info("美术", "小手_弹珠_hide + 小手_老虎钳_show + 小手_老虎钳_idle")
2025-06-30 10:33:40 +00:00
await Util.wait(1.5)
holding_prop = "prop_老虎钳"
if interacted_success:
EventManager.prop_interacted(name, key, 1)
else:
sfx_invalid.play()
sign_mark.invalid_shake(matched_sign_texture, unmatched_sign_texture)
SceneManager.unlock_player()
interacting = false