diff --git a/asset/art/gif/c02_小手/c02_小手_frames.tres b/asset/art/gif/c02_小手/c02_小手_frames.tres index e463c14f..6250a88e 100644 --- a/asset/art/gif/c02_小手/c02_小手_frames.tres +++ b/asset/art/gif/c02_小手/c02_小手_frames.tres @@ -220,6 +220,26 @@ animations = [{ "speed": 30.0 }, { "frames": [{ +"duration": 6.0, +"texture": ExtResource("45_11vlt") +}, { +"duration": 6.0, +"texture": ExtResource("59_0fj2q") +}, { +"duration": 6.0, +"texture": ExtResource("58_rggru") +}, { +"duration": 6.0, +"texture": ExtResource("57_rhstw") +}, { +"duration": 6.0, +"texture": ExtResource("56_8wl6b") +}], +"loop": false, +"name": &"小手_纸杯_hide", +"speed": 30.0 +}, { +"frames": [{ "duration": 12.0, "texture": ExtResource("50_nwjv4") }, { diff --git a/asset/dialogue/item_description.csv b/asset/dialogue/item_description.csv index 5444ed8c..aff5b41a 100644 --- a/asset/dialogue/item_description.csv +++ b/asset/dialogue/item_description.csv @@ -165,9 +165,11 @@ c02_s03_掉鞋子,怎么天上掉了个小鞋子下来?,,,,, c02_s03_铁门,锁住了,,,,, c02_保卫科花名册os,芦昌公寓居民登记簿,黄国栋记。,,,,, c02_保卫科祭台os,祭台是专门供奉这只大老鼠的?,,,,, -c02_小手出现摔倒,?!,,,,, -c02_小手其他交易,...还有什么东西能跟它交换呢?,,,,, c02_保卫科老鼠精,鼠歌

天地小如喉,
红轮自吞吐。
多少世间人,
都被红轮误。,,,,, +c02_小手其他交易,...还有什么东西能跟它交换呢?,,,,, +c02_小手出现摔倒,?!,,,,, +这是什么鬼东西,它是在讨要什么 [ID:],这是什么鬼东西,它是在讨要什么 [ID:],,,,, +c02_小手再次出现,又来一个!,,,,, c02_一楼楼道被挡住,被挡住了,,,,, c02_一楼戏台,盖着布的木头架子...用来做什么的呢,,,,, c02_描述垃圾通道,桶是空的,飘着一股血气,又酸又腥。,,,,, diff --git a/asset/dialogue/item_description.dialogue b/asset/dialogue/item_description.dialogue index 6aed3b9c..aec1e46f 100644 --- a/asset/dialogue/item_description.dialogue +++ b/asset/dialogue/item_description.dialogue @@ -197,9 +197,12 @@ # c02 保卫科 芦昌公寓居民登记簿,黄国栋记。 [ID:c02_保卫科花名册os] 祭台是专门供奉这只大老鼠的? [ID:c02_保卫科祭台os] -?! [ID:c02_小手出现摔倒] -...还有什么东西能跟它交换呢? [ID:c02_小手其他交易] 鼠歌

天地小如喉,
红轮自吞吐。
多少世间人,
都被红轮误。 [ID:c02_保卫科老鼠精] +# c02 小手 +...还有什么东西能跟它交换呢? [ID:c02_小手其他交易] +?! [ID:c02_小手出现摔倒] +这是什么鬼东西,它是在讨要什么 [ID:] +又来一个! [ID:c02_小手再次出现] # c02 内侧楼道 被挡住了 [ID:c02_一楼楼道被挡住] 盖着布的木头架子...用来做什么的呢 [ID:c02_一楼戏台] diff --git a/manager/scene/scene_manager.gd b/manager/scene/scene_manager.gd index 8e51161e..825ce7c0 100644 --- a/manager/scene/scene_manager.gd +++ b/manager/scene/scene_manager.gd @@ -103,7 +103,7 @@ func unhold_player(): # lock_time: the time to lock the player action. 0 means lock forever, thus the player will be locked until release_player is called. -func freeze_player(lock_time: float, action := 3, auto_quit := false) -> void: +func freeze_player(lock_time := 0.0, action := 3, auto_quit := false) -> void: # 先 freeze 再 action,否则会重置 action get_lock().freeze(lock_time) player_action(action, auto_quit) @@ -229,12 +229,12 @@ func disable_prop_item(prop_key: String) -> void: printerr("disable_prop_item PropHud node not found") -func pop_os_with_str(translation_key: String, auto_freeze := true, auto_release := true) -> void: +func pop_os_with_str(translation_key: String, auto_lock := true, auto_unlock := true) -> void: var player = get_player() as MainPlayer if player: var msg = tr(translation_key).replace("
", "\n") var lines = await DialogueUtil.generate_lines(msg) - player.pop_os(lines, auto_freeze, auto_release) + player.pop_os(lines, auto_lock, auto_unlock) else: printerr("Player node not found") diff --git a/scene/character/main_player.gd b/scene/character/main_player.gd index a2697b97..d311e5ab 100644 --- a/scene/character/main_player.gd +++ b/scene/character/main_player.gd @@ -382,7 +382,7 @@ var os_finished_not_emitted := false var os_pausing_timer: SceneTreeTimer -func pop_os(lines := [], auto_freeze := true, auto_release := true) -> void: +func pop_os(lines := [], auto_lock := true, auto_unlock := true) -> void: if os_tween: os_tween.kill() os_finish_emit_lock.lock() @@ -390,8 +390,13 @@ func pop_os(lines := [], auto_freeze := true, auto_release := true) -> void: os_finished.emit() os_finished_not_emitted = true os_finish_emit_lock.unlock() - if auto_freeze: - freeze_player(0, 3, false) + if auto_lock: + SceneManager.lock_player() + if auto_unlock: + # os_finished 必然发送,防止 tween 被 kill,保证一定 unlock + if os_finished.is_connected(release_player): + SceneManager.unlock_player() + os_finished.connect(SceneManager.unlock_player, CONNECT_ONE_SHOT) os_tween = create_tween() os_label.text = "" os_tween.tween_property(os_contaner, "modulate:a", 1.0, 0.2) @@ -401,14 +406,15 @@ func pop_os(lines := [], auto_freeze := true, auto_release := true) -> void: os_tween.tween_callback(_os_load_line.bind(line, duration)) os_tween.tween_interval(0.1) os_tween.tween_property(os_contaner, "modulate:a", 0.0, 0.2) - if auto_release: - os_tween.tween_callback(release_player) os_tween.tween_callback(func(): - os_finished.emit() os_finish_emit_lock.lock() - os_finished_not_emitted = false + if os_finished_not_emitted: + os_finished_not_emitted = false + os_finished.emit() os_finish_emit_lock.unlock() ) + # os 结束 + await os_finished func _os_load_line(line, duration): @@ -488,6 +494,8 @@ func walk_to(global_pos: Vector2) -> Tween: var time_cost = absf(global_pos.distance_to(global_position) / 50.0) # 忽略过小的位移 if time_cost >= 0.05: + if GlobalConfig.DEBUG: + print("walk_to start. lock player. time_cost:", time_cost) SceneManager.lock_player(0, 3, false) var direction = facing_direction if global_pos.x < global_position.x: @@ -504,4 +512,6 @@ func walk_to(global_pos: Vector2) -> Tween: func _after_walk_to() -> void: current_status = PlayerAnimationConfig.MOVEMENT_IDLE _play_animation() + if GlobalConfig.DEBUG: + print("walk_to end. unlock player") SceneManager.unlock_player() diff --git a/scene/character/reenter_lock.gd b/scene/character/reenter_lock.gd index 9802eb52..19b33dc1 100644 --- a/scene/character/reenter_lock.gd +++ b/scene/character/reenter_lock.gd @@ -22,10 +22,11 @@ signal hold_changed(count: int, is_add: bool) var _freeze_requests: int = 0 var _hold_requests: int = 0 + func _ready() -> void: process_mode = Node.PROCESS_MODE_PAUSABLE - - + + func _exit_tree() -> void: if _freeze_requests > 0: if GlobalConfig.DEBUG: @@ -57,15 +58,16 @@ func freeze(duration := 0.0) -> void: func release() -> void: - if _freeze_requests <= 0: - push_warning( + _freeze_requests -= 1 + if _freeze_requests < 0: + printerr( ( "[Lock] Attempting to release more times than frozen! Current local count: %d" % _freeze_requests - ) + ), + " Reset to 0." ) - return - _freeze_requests -= 1 + _freeze_requests = 0 if GlobalConfig.DEBUG: print("[Lock] Release applied: ", _freeze_requests) freeze_changed.emit(_freeze_requests, false) @@ -82,15 +84,16 @@ func hold(duration := 0.0) -> void: func unhold() -> void: - if _hold_requests <= 0: - push_warning( + _hold_requests -= 1 + if _hold_requests < 0: + printerr( ( "[Lock] Attempting to unhold more times than held! Current local count: %d" % _hold_requests - ) + ), + " Reset to 0." ) - return - _hold_requests -= 1 + _hold_requests = 0 if GlobalConfig.DEBUG: print("[Lock] Unhold applied: ", _hold_requests) hold_changed.emit(_hold_requests, false) @@ -126,8 +129,30 @@ func lock_all(duration := 0.0) -> void: func unlock_all() -> void: - release() - unhold() + _freeze_requests -= 1 + _hold_requests -= 1 + if _freeze_requests < 0: + printerr( + ( + "[Lock] Attempting to unlock more times than frozen! Current local count: %d" + % _freeze_requests + ), + " Reset to 0." + ) + _freeze_requests = 0 + if _hold_requests < 0: + printerr( + ( + "[Lock] Attempting to unhold more times than held! Current local count: %d" + % _hold_requests + ), + " Reset to 0." + ) + _hold_requests = 0 + freeze_changed.emit(_freeze_requests, false) + hold_changed.emit(_hold_requests, false) + if GlobalConfig.DEBUG: + prints("[Lock] UnlockAll applied (hold, freeze): ", _hold_requests, _freeze_requests) func _to_string() -> String: diff --git a/scene/entity/closeup.gd b/scene/entity/closeup.gd index 35e64238..e540839b 100644 --- a/scene/entity/closeup.gd +++ b/scene/entity/closeup.gd @@ -21,10 +21,10 @@ func _ready() -> void: # 可以直接调用 func display() -> void: if current_child: - # 先退出 - _exit() + return if packed_scene: - printraw("[" + name + "] call ") + if GlobalConfig.DEBUG: + print("[" + name + "] call lock") SceneManager.lock_player(0, action_key) # 展示时,禁用 sign_mark 的输入 sign_mark.pass_unhandled_input = true @@ -38,9 +38,14 @@ func display() -> void: func _exit(arg = null): if current_child: - printraw("[" + name + "] call ") + if GlobalConfig.DEBUG: + print("[" + name + "] call lock") SceneManager.unlock_player() - current_child.queue_free() + if current_child: + remove_child(current_child) + current_child.queue_free() + current_child = null + print("quit [", name, "] arg=", arg) exit.emit(arg) # 退出时,恢复 sign_mark 的输入 sign_mark.pass_unhandled_input = false diff --git a/scene/entity/inspectable.gd b/scene/entity/inspectable.gd index cda5023b..4e2558e3 100644 --- a/scene/entity/inspectable.gd +++ b/scene/entity/inspectable.gd @@ -65,11 +65,11 @@ var blinking_tween: Tween var ground_archive: GroundArchive # 尝试互动的次数 -var tried_times: int: +var icount: int: set(val): - tried_times = val - ground_archive.set_pair(name, "tried_times", val) - if tried_times >= 1 and sign_mark: + icount = val + ground_archive.set_pair(name, "icount", val) + if icount >= 1 and sign_mark: sign_mark.sprite2d.texture = note_sign_texture @@ -88,8 +88,7 @@ func _ready() -> void: sign_mark.enabled = enabled # setup default value ground_archive = ArchiveManager.archive.ground_archive() - tried_times = ground_archive.get_value(name, "tried_times", 0) - + icount = ground_archive.get_value(name, "icount", 0) if content_centered: content_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER # sign_mark.interacted.connect(_on_interacted) @@ -115,7 +114,7 @@ func _get_tr_content(): func _on_interacted() -> void: if STATUS_TRANSITIONING == status: return - if tried_times == 0 and first_interact_os_key: + if icount == 0 and first_interact_os_key: sign_mark.display_sign = false SceneManager.pop_os_with_str(first_interact_os_key) await SceneManager.get_player().os_finished @@ -125,10 +124,12 @@ func _on_interacted() -> void: func _do_action() -> void: if status == STATUS_NORAML: - # 不使用 lock, 因为需要用 sign 进行继续交互 + # 不使用 lock player, 因为需要用 sign 进行继续交互 + if GlobalConfig.DEBUG: + print("[" + name + "] call lock") SceneManager.freeze_player(0, action_key) status = STATUS_TRANSITIONING - tried_times += 1 + icount += 1 sfx.play() SceneManager.focus_node(self) SceneManager.get_camera_marker().tween_zoom(2.0) @@ -189,6 +190,8 @@ func _on_cancel(_body = null): tween.tween_callback(func(): status = STATUS_NORAML) tween.tween_callback(func(): content_label.modulate.a = 0.0) SceneManager.focus_player_and_reset_zoom() + if GlobalConfig.DEBUG: + print("[" + name + "] call lock") SceneManager.release_player() sign_mark.display_sign = true # 改变信号源 diff --git a/scene/entity/interactable.gd b/scene/entity/interactable.gd index 08a134c1..13aafbf5 100644 --- a/scene/entity/interactable.gd +++ b/scene/entity/interactable.gd @@ -52,10 +52,10 @@ var prop_key3 := "" var ground_archive: GroundArchive # 尝试互动的次数 -var tried_times: int: +var icount: int: set(val): - tried_times = val - ground_archive.set_pair(name, "tried_times", val) + icount = val + ground_archive.set_pair(name, "icount", val) # 成功互动的次数 var interacted_times: int: set(val): @@ -80,10 +80,9 @@ func _ready() -> void: sign_snapper.enabled = false sign_mark.interacted.connect(_pre_interacted) sign_mark.cancel.connect(_on_cancel) - sign_mark.enabled = enabled # setup default value ground_archive = ArchiveManager.archive.ground_archive() - tried_times = ground_archive.get_value(name, "tried_times", 0) + icount = ground_archive.get_value(name, "icount", 0) interacted_times = ground_archive.get_value(name, "interacted_times", 0) if interacted_times and interacted_texture: texture = interacted_texture @@ -108,7 +107,7 @@ func _reset_sign_testure_to_prop(): # 根据当前 prop,调整 sign 所显示的 texture func _set_sign_texture_to_prop(_key): - if tried_times == 0: + if icount == 0: # 首次交互前 unrevealed sign_mark.sprite2d.texture = unrevealed_sign_texture return @@ -144,7 +143,7 @@ func is_key_matched(key) -> bool: func _pre_interacted() -> void: SceneManager.player_action(action_key) - if tried_times == 0 and first_interact_os_key: + if icount == 0 and first_interact_os_key: sign_mark.display_sign = false SceneManager.pop_os_with_str(first_interact_os_key) await SceneManager.get_player().os_finished @@ -154,7 +153,7 @@ func _pre_interacted() -> void: func _on_interacted() -> void: interact_mutex.lock() - tried_times += 1 + icount += 1 if one_shot and interacted_times >= one_shot_max_times: interact_mutex.unlock() return diff --git a/scene/entity/note.gd b/scene/entity/note.gd index 29ac0bfd..8c05a14c 100644 --- a/scene/entity/note.gd +++ b/scene/entity/note.gd @@ -68,11 +68,11 @@ var mutex = Mutex.new() var ground_archive: GroundArchive # 尝试互动的次数 -var tried_times: int: +var icount: int: set(val): - tried_times = val - ground_archive.set_pair(name, "tried_times", val) - if tried_times >= 1 and sign_mark: + icount = val + ground_archive.set_pair(name, "icount", val) + if icount >= 1 and sign_mark: sign_mark.sprite2d.texture = note_sign_texture @@ -91,7 +91,7 @@ func _ready() -> void: # setup default value ground_archive = ArchiveManager.archive.ground_archive() - tried_times = ground_archive.get_value(name, "tried_times", 0) + icount = ground_archive.get_value(name, "icount", 0) func _on_interacted() -> void: @@ -100,7 +100,7 @@ func _on_interacted() -> void: if not note_key: printerr("Note key is not set") return - tried_times += 1 + icount += 1 %Sfx.play() match mode: "os": @@ -132,18 +132,16 @@ func _show_os(): func _show_balloon(res, title): # SceneManager.focus_node(self) DialogueManager.show_dialogue_balloon(res, title) - # TODO note viewing animation + # note viewing animation + if GlobalConfig.DEBUG: + print("[" + name + "] call lock") SceneManager.freeze_player(0, action) interacting = true - DialogueManager.dialogue_ended.connect(_on_ballon_ended, CONNECT_ONE_SHOT) - # var player = SceneManager.get_player() - # DialogueManager.show_dialogue_balloon_scene(player, dialogue_res, note_key) - - -func _on_ballon_ended(_res): - interacting = false + await DialogueManager.dialogue_ended + if GlobalConfig.DEBUG: + print("[" + name + "] call lock") SceneManager.release_player() - # SceneManager.focus_player_and_reset_zoom() + interacting = false func _set(property: StringName, value: Variant) -> bool: diff --git a/scene/entity/npc.gd b/scene/entity/npc.gd index bac700c8..b3a09e25 100644 --- a/scene/entity/npc.gd +++ b/scene/entity/npc.gd @@ -105,19 +105,20 @@ func _on_interacted() -> void: interacted.emit() DialogueManager.show_dialogue_balloon(dialogue_res, dialogue_title) speaking = true - SceneManager.freeze_player(0, action_key) - DialogueManager.dialogue_ended.connect(_dialog_end, CONNECT_ONE_SHOT) + if GlobalConfig.DEBUG: + print("[" + name + "] call lock") + SceneManager.lock_player(0, action_key) var tween = create_tween() tween.tween_property(speaking_sign, "modulate", Color.WHITE, 0.5) tween.parallel().tween_property(speaking_sign, "scale", base_scale * 1.3, 0.3) - - -func _dialog_end(_res): - speaking = false - SceneManager.release_player() - var tween = create_tween() - tween.tween_property(speaking_sign, "modulate", base_mod, 0.5) - tween.parallel().tween_property(speaking_sign, "scale", base_scale, 0.3) + await DialogueManager.dialogue_ended + tween = create_tween() + tween.tween_property(speaking_sign, "modulate", base_mod, 0.5) + tween.parallel().tween_property(speaking_sign, "scale", base_scale, 0.3) + if GlobalConfig.DEBUG: + print("[" + name + "] call lock") + SceneManager.unlock_player() + speaking = false func _play_speaking() -> void: diff --git a/scene/entity/pickable.gd b/scene/entity/pickable.gd index 8ba6b829..26837f63 100644 --- a/scene/entity/pickable.gd +++ b/scene/entity/pickable.gd @@ -14,7 +14,7 @@ signal sign_mark_offset_updated set(val): enabled = val if is_node_ready(): - sign_mark.enabled = enabled + _check_display() @export var action_key := 4 # 除了 picked 必然隐藏,其他情况下跟随 enabled 状态 @export var visible_follow_enabled := true diff --git a/scene/entity/portal.gd b/scene/entity/portal.gd index 22ee3a7a..a52de1f8 100644 --- a/scene/entity/portal.gd +++ b/scene/entity/portal.gd @@ -76,10 +76,10 @@ var items: PackedStringArray var ground_archive: GroundArchive # 尝试互动的次数 -var tried_times: int: +var icount: int: set(val): - tried_times = val - ground_archive.set_pair(name, "tried_times", val) + icount = val + ground_archive.set_pair(name, "icount", val) # Called when the node enters the scene tree for the first time. func _ready() -> void: @@ -92,7 +92,7 @@ func _ready() -> void: _reload_items() return ground_archive = ArchiveManager.archive.ground_archive() - tried_times = ground_archive.get_value(name, "tried_times", 0) + icount = ground_archive.get_value(name, "icount", 0) status = ground_archive.get_value(name, "status", status) if GlobalConfig.DEBUG: print("Portal read status [", name, "] status=", status) @@ -131,7 +131,7 @@ func _check_sign_mark_and_texture(): else: sign_snapper.action_on_arrived = 4 # holding 状态下,同样显示 unrevealed_sign_texture - if tried_times == 0 or holding: + if icount == 0 or holding: sign_mark.sprite2d.texture = unrevealed_sign_texture else: match status: @@ -150,7 +150,7 @@ var interact_mutex = Mutex.new() func _on_interacted() -> void: - tried_times += 1 + icount += 1 if holding: if holding_reason_key: SceneManager.pop_os_with_str(holding_reason_key) @@ -222,7 +222,7 @@ func _set_sign_texture_to_prop(_key): # if not prop_key or prop_key == key: # sign_mark.sprite2d.texture = matched_sign_texture # else: - if tried_times: + if icount: sign_mark.sprite2d.texture = locked_sign_texture else: sign_mark.sprite2d.texture = unrevealed_sign_texture diff --git a/scene/entity/ux/sign.gd b/scene/entity/ux/sign.gd index ca8b614d..b79b2314 100644 --- a/scene/entity/ux/sign.gd +++ b/scene/entity/ux/sign.gd @@ -13,9 +13,9 @@ signal toggle_active(activated: bool) # @export var lock_on_player_freezed := false @export var enabled := true: set(val): - if enabled == val: - return - _align_activation() + if enabled != val: + enabled = val + align_activation() @export var display_sign := true: set(val): if display_sign != val: @@ -34,8 +34,9 @@ var pass_unhandled_input = false # 同时只能有一个物品被激活交互态,其他物品进入等待队列 static var occupied: NodePath -static var _pending_activate_sign: Array[NodePath] = [] -# 使用互斥锁保证线程安全。在操作 occupied 或 _pending_activate_sign 时需要先锁定,操作完成后解锁 +# touching 状态改变时就要擦除 +static var _touching_sign_arr: Array[NodePath] = [] +# 使用互斥锁保证线程安全。在操作 occupied 或 _touching_sign_arr 时需要先锁定,操作完成后解锁 static var mutex = Mutex.new() var tween: Tween @@ -43,7 +44,12 @@ var player_touching := false: set(val): if player_touching != val: player_touching = val - _align_activation() + var path = get_path() + if player_touching and not _touching_sign_arr.has(path): + _touching_sign_arr.append(path) + if not player_touching: + _touching_sign_arr.erase(path) + align_activation() var activated = false: set(val): if activated != val: @@ -82,11 +88,11 @@ func is_hold() -> bool: func _on_lock_hold_changed(count: int, is_add: bool): if count == 0 or (count == 1 and is_add): - _align_activation() + align_activation() func _on_visibility_changed() -> void: - _align_activation() + align_activation() # activition/display mode 变化时 _check_sign_display @@ -113,7 +119,7 @@ func _on_body_exited(_body: Node2D) -> void: # 四种参数变化时调用 align: 1 enable 2 hold 3 visibility 4 touching -func _align_activation() -> bool: +func align_activation() -> bool: if Engine.is_editor_hint(): return activated var ideal_status := enabled and player_touching and not is_hold() and is_visible_in_tree() @@ -134,8 +140,8 @@ func _align_activation() -> bool: "[/color]", " occupied:[color=khaki]", _get_name_from_path(occupied), - "[/color] pending:[color=coral]", - _get_name_from_paths(_pending_activate_sign), + "[/color] touching:[color=coral]", + _get_name_from_paths(_touching_sign_arr), "[/color]" ) return activated @@ -147,14 +153,14 @@ func _try_disactivate() -> void: activated = false occupied = NodePath(&"") # 转移 active 状态给下一个节点 - while _pending_activate_sign.size() > 0: - var path = _pending_activate_sign.pop_front() - var _sign = get_node_or_null(path) as Sign - if _sign and _sign._align_activation(): + var self_path = get_path() + for p in _touching_sign_arr: + # skip self + if p == self_path: + continue + var s = get_node_or_null(p) as Sign + if s and s.align_activation(): break - else: - # make sure the sign is not in the pending list - _pending_activate_sign.erase(get_path()) mutex.unlock() # point_light.energy = 0.0 if tween and tween.is_valid(): @@ -169,10 +175,7 @@ func _try_activate() -> bool: var path := get_path() mutex.lock() # 若 lock 为 hold 状态则直接跳过 - if occupied and occupied != path: - if not _pending_activate_sign.has(path): - _pending_activate_sign.append(path) - else: + if not occupied or occupied == path: occupied = path activated = true mutex.unlock() diff --git a/scene/ground/scene/c01/s06_孤儿院长廊围墙.gd b/scene/ground/scene/c01/s06_孤儿院长廊围墙.gd index 172302f5..d3a44f05 100644 --- a/scene/ground/scene/c01/s06_孤儿院长廊围墙.gd +++ b/scene/ground/scene/c01/s06_孤儿院长廊围墙.gd @@ -78,7 +78,7 @@ func _dean_flip_book() -> void: # 在游戏开始前,更早的对话 func pre_game_intro(): - SceneManager.freeze_player(0) + SceneManager.lock_player() var camera = SceneManager.get_camera_marker() as CameraFocusMarker camera.tween_zoom(1.5, 3.0) var p = $"../DeployLayer/四小孩画鬼差的对话ambush/FocusPoint" @@ -89,7 +89,8 @@ func pre_game_intro(): # 重置镜头 SceneManager.focus_player_and_reset_zoom(2.5) await get_tree().create_timer(1.5).timeout - SceneManager.pop_os_with_str("c01_s06_熟悉的墙画", false, true) + await SceneManager.pop_os_with_str("c01_s06_熟悉的墙画") + SceneManager.unlock_player() func game_intro() -> void: @@ -159,9 +160,10 @@ func _on_talked(): if talk_count == 3: # 三个小孩都对话完毕 await DialogueManager.dialogue_ended - SceneManager.freeze_player(0) + SceneManager.lock_player() await get_tree().create_timer(1.0).timeout - SceneManager.pop_os_with_str("c01_s06_四小孩对话结束", false, true) + await SceneManager.pop_os_with_str("c01_s06_四小孩对话结束") + SceneManager.unlock_player() var kid_run_tween diff --git a/scene/ground/scene/c02/s02_过道.gd b/scene/ground/scene/c02/s02_过道.gd index 89d1910a..ca1caeb1 100644 --- a/scene/ground/scene/c02/s02_过道.gd +++ b/scene/ground/scene/c02/s02_过道.gd @@ -53,22 +53,20 @@ func _on_ground_ready() -> void: func _oneshot_wind(): var player = %MainPlayer as MainPlayer - SceneManager.freeze_player(0) + SceneManager.lock_player() player.hide_sprite = true player.set_facing_direction(Vector2.RIGHT) player.global_position.x = 53.0 + $"冷飕飕Sfx".play() wind_blows.visible = true wind_blows.play() - wind_blows.animation_finished.connect(_on_wind_finished, CONNECT_ONE_SHOT) - $"冷飕飕Sfx".play() - - -func _on_wind_finished(): + await wind_blows.animation_finished set_data("first_enter", true) %MainPlayer.hide_sprite = false wind_blows.visible = false # 使用气泡文字 - SceneManager.pop_os_with_str("c02_冷飕飕的", false, true) + await SceneManager.pop_os_with_str("c02_冷飕飕的") + SceneManager.unlock_player() func xiaochan_disappear(): @@ -78,7 +76,7 @@ func xiaochan_disappear(): func _on_flyer_exit(arg): - if arg: + if arg == true: $"../DeployLayer/青岛啤酒".enabled = true set_data("flyer_shaven", true) flyer.enabled = false diff --git a/scene/ground/scene/c02/s03_院子.gd b/scene/ground/scene/c02/s03_院子.gd index 1f449dc7..9d482f93 100644 --- a/scene/ground/scene/c02/s03_院子.gd +++ b/scene/ground/scene/c02/s03_院子.gd @@ -98,7 +98,7 @@ func _on_ground_ready() -> void: await tween.finished # 落地音效 $"Sfx小鞋落地".play() - SceneManager.pop_os_with_str("c02_s03_掉鞋子", false, false) + SceneManager.pop_os_with_str("c02_s03_掉鞋子") tween = create_tween() tween.tween_property(fg, "modulate:a", 0.0, 1.5) await tween.finished diff --git a/scene/ground/scene/c02/s04_保卫科.gd b/scene/ground/scene/c02/s04_保卫科.gd index 2e0fa984..aac9a6fc 100644 --- a/scene/ground/scene/c02/s04_保卫科.gd +++ b/scene/ground/scene/c02/s04_保卫科.gd @@ -22,24 +22,6 @@ func _on_ground_ready() -> void: if not ArchiveManager.get_global_value(&"c02_tin_coin_taken"): closeup_tin_coin.exit.connect(_on_closeup_tin_coin_exited) - little_hand = $"../DeployLayer/小手讨东西" - if little_hand.tried_times == 0: - little_hand.interacted.connect( - _on_little_hand_first_interacted.call_deferred, CONNECT_ONE_SHOT - ) - - -func _on_little_hand_first_interacted() -> void: - # 9 小手交互,吓摔倒 - little_hand.enabled = false - var duration = 3.0 - SceneManager.freeze_player(duration, 9) - SceneManager.pop_os_with_str(tr("c02_小手出现摔倒"), false, false) - get_tree().create_timer(1.5).timeout.connect($"Sfx摔倒".play) - await get_tree().create_timer(duration).timeout - SceneManager.release_player() - little_hand.enabled = true - func _on_closeup_tin_coin_exited(arg = null): if arg == true: diff --git a/scene/ground/scene/c02/s04_保卫科.tscn b/scene/ground/scene/c02/s04_保卫科.tscn index cb98ca15..5bc1bf67 100644 --- a/scene/ground/scene/c02/s04_保卫科.tscn +++ b/scene/ground/scene/c02/s04_保卫科.tscn @@ -1,13 +1,11 @@ -[gd_scene load_steps=24 format=3 uid="uid://bivc5cdap370p"] +[gd_scene load_steps=22 format=3 uid="uid://bivc5cdap370p"] [ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_2jej0"] [ext_resource type="Script" uid="uid://dmhh4g47bdxxy" path="res://scene/ground/scene/c02/s04_保卫科.gd" id="2_jyere"] [ext_resource type="Texture2D" uid="uid://7jvg2flkapj3" path="res://asset/art/scene/c02/s04_保卫科/bg_保卫科.png" id="3_66gue"] -[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="4_ffvrp"] [ext_resource type="SpriteFrames" uid="uid://c2sjavnptjn" path="res://asset/art/gif/c02_保卫科/c02_保卫科_frames.tres" id="4_svuj3"] [ext_resource type="Texture2D" uid="uid://bnyf8m63ltgh0" path="res://asset/art/scene/c02/s04_保卫科/l_香.png" id="5_cy26p"] [ext_resource type="Script" uid="uid://cpejxlfni6n52" path="res://manager/audio_manager/vibe_sfx.gd" id="5_g8amr"] -[ext_resource type="AudioStream" uid="uid://c26x8f18w6is0" path="res://asset/audio/sfx/旧版/c02/撞到柜子.mp3" id="5_xy3nq"] [ext_resource type="PackedScene" uid="uid://dqkxiqbq83cmq" path="res://scene/entity/closeup.tscn" id="6_66gue"] [ext_resource type="PackedScene" uid="uid://b8i6tqwdvvddy" path="res://scene/ground/script/c02/花名册.tscn" id="6_fvlg0"] [ext_resource type="Texture2D" uid="uid://cs14llkvr3fg8" path="res://asset/art/scene/c02/s04_保卫科/弹珠墙面涂鸦提示.png" id="6_gk1h4"] @@ -42,14 +40,7 @@ data = { } oneshot_animation = "" -[node name="Sfx摔倒" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"] -process_mode = 1 -stream = ExtResource("5_xy3nq") -bus = &"game_sfx" -script = ExtResource("4_ffvrp") -metadata/_custom_type_script = "uid://rq6w1vuhuq1m" - -[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="1"] +[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"] script = ExtResource("5_g8amr") autoplay_group = &"c02_房间里1" metadata/_custom_type_script = "uid://cpejxlfni6n52" @@ -106,12 +97,6 @@ hide_texture = true gaslight_texture = ExtResource("9_a43aq") ground_light_texture = ExtResource("10_svuj3") -[node name="SfxInvalid" parent="Ground/DeployLayer/煤油灯" index="0"] -process_mode = 1 - -[node name="SfxSuccess" parent="Ground/DeployLayer/煤油灯" index="1"] -process_mode = 1 - [node name="CollisionShape2D" parent="Ground/DeployLayer/煤油灯/Area2D" index="0"] shape = SubResource("RectangleShape2D_gk1h4") diff --git a/scene/ground/scene/c02/s05_一楼内侧楼道.gd b/scene/ground/scene/c02/s05_一楼内侧楼道.gd index a431ca3d..d0d9f25f 100644 --- a/scene/ground/scene/c02/s05_一楼内侧楼道.gd +++ b/scene/ground/scene/c02/s05_一楼内侧楼道.gd @@ -66,7 +66,7 @@ func _on_madman_interacted() -> void: return await DialogueManager.dialogue_ended EventManager.set_stage("c02_madman_interacted", 1) - SceneManager.pop_os_with_str(tr("c02_一楼疯子互动后")) + SceneManager.pop_os_with_str("c02_一楼疯子互动后") func xiaochan_disappear(): diff --git a/scene/ground/scene/c02/s06_二楼.gd b/scene/ground/scene/c02/s06_二楼.gd index 54f5eebc..911839ad 100644 --- a/scene/ground/scene/c02/s06_二楼.gd +++ b/scene/ground/scene/c02/s06_二楼.gd @@ -45,7 +45,7 @@ func _on_ground_ready() -> void: gas_light_upon_hole.lighted.connect(func(): mice_hole.enabled = true get_tree().create_timer(1.5).timeout.connect( - SceneManager.pop_os_with_str.bind(tr("c02_二楼血脚印")) + SceneManager.pop_os_with_str.bind("c02_二楼血脚印") ) ) diff --git a/scene/ground/scene/c02/s06_二楼.tscn b/scene/ground/scene/c02/s06_二楼.tscn index 41c3d6ef..defc2a97 100644 --- a/scene/ground/scene/c02/s06_二楼.tscn +++ b/scene/ground/scene/c02/s06_二楼.tscn @@ -942,12 +942,6 @@ position = Vector2(616, -14) ground_light_texture = ExtResource("8_7x2h6") ground_height_offset = 15.0 -[node name="SfxInvalid" parent="Ground/DeployLayer/煤油灯" index="0"] -process_mode = 1 - -[node name="SfxSuccess" parent="Ground/DeployLayer/煤油灯" index="1"] -process_mode = 1 - [node name="CollisionShape2D" parent="Ground/DeployLayer/煤油灯/Area2D" index="0"] shape = SubResource("RectangleShape2D_lh55k") diff --git a/scene/ground/scene/c02/s07_二楼内侧楼道.gd b/scene/ground/scene/c02/s07_二楼内侧楼道.gd index 2f5b7f87..d5fae4ba 100644 --- a/scene/ground/scene/c02/s07_二楼内侧楼道.gd +++ b/scene/ground/scene/c02/s07_二楼内侧楼道.gd @@ -43,7 +43,12 @@ func take_off_flyer(immediatelly = false): flyer.visible = false var hand = $"../DeployLayer/小手讨东西" hand.enabled = true - if hand.tried_times == 0: - await get_tree().create_timer(1.0).timeout - hand.do_first_interact(immediatelly) - hand.tried_times += 1 + # if hand.icount == 0: + # await get_tree().create_timer(1.0).timeout + # hand.icount += 1 + # SceneManager.lock_player() + # await hand.do_first_interact(immediatelly) + # SceneManager.unlock_player() + + + diff --git a/scene/ground/scene/c02/s10_空房间.gd b/scene/ground/scene/c02/s10_空房间.gd index 73b208ea..b74aa99a 100644 --- a/scene/ground/scene/c02/s10_空房间.gd +++ b/scene/ground/scene/c02/s10_空房间.gd @@ -190,7 +190,7 @@ func _on_pick_catty_head() -> void: sprite.visible = false SceneManager.enable_prop_item("prop_小猫玩具完整") await SceneManager.get_inspector().quit_and_hidden - SceneManager.pop_os_with_str(tr("c02_获得小猫玩具")) + SceneManager.pop_os_with_str("c02_获得小猫玩具") # 进过瞎子卧室后,通道关闭 if not ArchiveManager.get_global_value(&"c02_the_blind_room_unlocked"): portal_note.enabled = true diff --git a/scene/ground/script/c02/s00_煤油灯.gd b/scene/ground/script/c02/s00_煤油灯.gd index 48bcc29c..ca7ae739 100644 --- a/scene/ground/script/c02/s00_煤油灯.gd +++ b/scene/ground/script/c02/s00_煤油灯.gd @@ -75,7 +75,7 @@ func _on_mismatch(): ArchiveManager.set_global_entry(&"c02_gaslight_first_failed", true) var scene = ArchiveManager.archive.current_scene if scene == "c02_s02" or scene == "c02_s03": - SceneManager.pop_os_with_str(tr("c02_陈旧的煤油灯")) + SceneManager.pop_os_with_str("c02_陈旧的煤油灯") # 如果有道具,则提示玩家可以使用道具 elif SceneManager.get_current_prop(false): SceneManager.pop_center_notification(tr("ui_switch_prop")) @@ -145,4 +145,4 @@ func _gaslight_interacted(): var scene = ArchiveManager.archive.current_scene if scene == "c02_s02" or scene == "c02_s03": await get_tree().create_timer(1.0).timeout - SceneManager.pop_os_with_str(tr("c02_使用煤油灯")) + SceneManager.pop_os_with_str("c02_使用煤油灯") diff --git a/scene/ground/script/c02/s00_煤油灯.tscn b/scene/ground/script/c02/s00_煤油灯.tscn index cbfcb67b..db02f644 100644 --- a/scene/ground/script/c02/s00_煤油灯.tscn +++ b/scene/ground/script/c02/s00_煤油灯.tscn @@ -43,11 +43,13 @@ prop_key2 = "" prop_key3 = "" [node name="SfxInvalid" type="AudioStreamPlayer" parent="."] +process_mode = 1 stream = ExtResource("9_l338h") bus = &"game_sfx" script = ExtResource("8_abb1f") [node name="SfxSuccess" type="AudioStreamPlayer" parent="."] +process_mode = 1 stream = ExtResource("9_abb1f") bus = &"game_sfx" script = ExtResource("8_abb1f") diff --git a/scene/ground/script/c02/小手讨东西.gd b/scene/ground/script/c02/小手讨东西.gd index d650e99e..76708492 100644 --- a/scene/ground/script/c02/小手讨东西.gd +++ b/scene/ground/script/c02/小手讨东西.gd @@ -1,7 +1,7 @@ @tool extends Sprite2D -signal interacted +signal interact_start # 0保卫科 1二楼内侧 @export_enum("保卫科", "二楼内侧") var id := 0 @@ -48,10 +48,31 @@ var tin_coin_drop = false: if tin_coin_drop: coin.reset() # 尝试互动的次数 -var tried_times: int: +var icount: int: set(val): - tried_times = val - ground_archive.set_pair(name, "tried_times", 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_小手出现摔倒") + get_tree().create_timer(1.5).timeout.connect($"Sfx摔倒".play) + await SceneManager.get_player().animation_finished + SceneManager.unlock_player() + elif stage == 1: + # 第二次交互小手 + EventManager.set_stage(&"c02_little_hand", 2) + SceneManager.pop_os_with_str("c02_小手再次出现") var coin: Pickable2D @@ -59,18 +80,16 @@ var coin: Pickable2D func _ready() -> void: if Engine.is_editor_hint(): return - area2d.body_entered.connect(_reset) - area2d.body_exited.connect(_on_exit) # sign_mark.interacted.connect(_on_interacted) sign_snapper.arrived.connect(_on_interacted) sign_mark.cancel.connect(_on_cancel) - sign_mark.enabled = enabled + _check_sign_mark_display() # setup default value 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", "") - tried_times = ground_archive.get_value(name, "tried_times", 0) + icount = ground_archive.get_value(name, "icount", 0) if holding_prop == "prop_弹珠": animated_sprite.play("小手_弹珠_idle") @@ -78,7 +97,7 @@ func _ready() -> void: animated_sprite.play("小手_老虎钳_idle") elif is_holding_cup: animated_sprite.play("小手_纸杯_idle") - elif tried_times > 0: + elif icount > 0: animated_sprite.play("小手_show") coin = get_node("Pickable元宝") @@ -90,42 +109,13 @@ func _check_sign_mark_display(): sign_mark.enabled = enabled and not interacting -func _reset(_body = null) -> void: - _reset_sign_testure_to_prop() - var prop_hud = SceneManager.get_prop_hud() as PropHud - if not prop_hud.current_item_changed.is_connected(_set_sign_texture_to_prop): - prop_hud.current_item_changed.connect(_set_sign_texture_to_prop) - - # 在场景中调用该方法,可以跳过小手初次交互的伸出过程 func do_first_interact(immediatelly := false): if immediatelly: animated_sprite.play("小手_idle") else: animated_sprite.play("小手_show") - _reset_sign_testure_to_prop() - - -func _reset_sign_testure_to_prop(): - var key = SceneManager.get_current_prop(false) - _set_sign_texture_to_prop(key) - - -# 根据当前 prop,调整 sign 所显示的 texture -func _set_sign_texture_to_prop(_key): - _check_sign_mark_display() - if tried_times == 0: - # 首次交互前 unrevealed - sign_mark.sprite2d.texture = unrevealed_sign_texture - return - sign_mark.sprite2d.texture = matched_sign_texture - - -func _on_exit(_body = null) -> void: - # disconnect signal - var prop_hud = SceneManager.get_prop_hud() as PropHud - if prop_hud and prop_hud.current_item_changed.is_connected(_set_sign_texture_to_prop): - prop_hud.current_item_changed.disconnect(_set_sign_texture_to_prop) + await animated_sprite.animation_changed func _on_cancel(_body = null) -> void: @@ -153,36 +143,31 @@ var interacting := false: var communicating = false - func _on_interacted() -> void: if interacting: print("小手 interacting 锁定中") - SceneManager.release_player() + # SceneManager.release_player() return interacting = true - interacted.emit() - tried_times += 1 - if tried_times == 1: - do_first_interact(false) - interacting = false - SceneManager.release_player() - return - if holding_prop != "": + interact_start.emit() + icount += 1 + if icount == 1: + await do_first_interact(false) + elif holding_prop != "": # 手持物品时,交互直接给玩家物品 SceneManager.enable_prop_item(holding_prop) holding_prop = "" animated_sprite.play("小手_show") - interacting = false - SceneManager.release_player() - return - - if is_holding_cup: + await animated_sprite.animation_changed + elif is_holding_cup: # 对话 if not communicating: communicating = true - animated_sprite.visible = false + # animated_sprite.visible = false # 7 拿起纸杯 8 监听纸杯 SceneManager.freeze_player(0, 7) + # 小手收回 play backwards + animated_sprite.play("小手_纸杯_hide") await SceneManager.get_player().animation_finished SceneManager.player_action(8) SceneManager.pop_debug_dialog_info("音效", "纸杯电话童谣") @@ -191,71 +176,70 @@ func _on_interacted() -> void: sfx_bgm.finished.connect(_quit_communicating, CONNECT_ONE_SHOT) else: _quit_communicating() - interacting = false - return - - var key = SceneManager.get_current_prop(false) - var interacted_success = false - SceneManager.freeze_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") - await get_tree().create_timer(2).timeout - # 稍等片刻再给小鞋子 - 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 - await get_tree().create_timer(1.5).timeout - coin.visible = 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") - await get_tree().create_timer(1.5).timeout - 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") - await get_tree().create_timer(1.5).timeout - holding_prop = "prop_老虎钳" - - if interacted_success: - EventManager.prop_interacted(name, key, 1) - _reset_sign_testure_to_prop() else: - sfx_invalid.play() - sign_mark.invalid_shake(matched_sign_texture, unmatched_sign_texture) + 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" + ) + await get_tree().create_timer(2).timeout + # 稍等片刻再给小鞋子 + 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 + await get_tree().create_timer(1.5).timeout + coin.visible = true + if not ArchiveManager.get_global_value(&"c02_little_hand_dropped_tin"): + SceneManager.pop_os_with_str("c02_小手要东西") + ArchiveManager.set_global_entry(&"c02_little_hand_dropped_tin", true) - SceneManager.release_player() + # 是否允许老虎钳换弹珠 + 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") + await get_tree().create_timer(1.5).timeout + 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") + await get_tree().create_timer(1.5).timeout + 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 diff --git a/scene/ground/script/c02/小手讨东西.tscn b/scene/ground/script/c02/小手讨东西.tscn index 9892f0fe..f6528861 100644 --- a/scene/ground/script/c02/小手讨东西.tscn +++ b/scene/ground/script/c02/小手讨东西.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=17 format=3 uid="uid://xovlfee503a4"] +[gd_scene load_steps=18 format=3 uid="uid://xovlfee503a4"] [ext_resource type="Texture2D" uid="uid://cawpq7rnho5px" path="res://asset/art/gif/c02_小手/洞.png" id="1_47cqy"] [ext_resource type="Script" uid="uid://my5xqi3bkka6" path="res://scene/ground/script/c02/小手讨东西.gd" id="1_n7thl"] @@ -12,6 +12,7 @@ [ext_resource type="AudioStream" uid="uid://44slgncnt6sj" path="res://asset/audio/sfx/交互/第一章/sfx_手交互成功.wav" id="8_7dftu"] [ext_resource type="AudioStream" uid="uid://c5d6i2wp8xkay" path="res://asset/audio/sfx/bgm/第一章/童谣合并_FX.wav" id="9_7dftu"] [ext_resource type="SpriteFrames" uid="uid://b6nvwset1hwbv" path="res://asset/art/gif/c02_小手/c02_小手_frames.tres" id="9_yatcw"] +[ext_resource type="AudioStream" uid="uid://c26x8f18w6is0" path="res://asset/audio/sfx/旧版/c02/撞到柜子.mp3" id="10_0tuif"] [ext_resource type="Texture2D" uid="uid://2mjipesnigcr" path="res://asset/art/prop/c02/锡箔元宝.png" id="10_47cqy"] [ext_resource type="PackedScene" uid="uid://dsa6frlw6e6gg" path="res://scene/entity/pickable.tscn" id="12_6lwlv"] [ext_resource type="Script" uid="uid://cnt01hiw52bmn" path="res://scene/entity/ux/sign_snapper.gd" id="15_lr23o"] @@ -48,6 +49,13 @@ bus = &"game_sfx" script = ExtResource("7_7dftu") metadata/_custom_type_script = "uid://rq6w1vuhuq1m" +[node name="Sfx摔倒" type="AudioStreamPlayer" parent="."] +process_mode = 1 +stream = ExtResource("10_0tuif") +bus = &"game_sfx" +script = ExtResource("7_7dftu") +metadata/_custom_type_script = "uid://rq6w1vuhuq1m" + [node name="Area2D" type="Area2D" parent="."] unique_name_in_owner = true collision_layer = 0 diff --git a/scene/little_game/八音盒/八音盒.gd b/scene/little_game/八音盒/八音盒.gd index 4e78e6ee..e5762e67 100644 --- a/scene/little_game/八音盒/八音盒.gd +++ b/scene/little_game/八音盒/八音盒.gd @@ -346,4 +346,4 @@ func _on_pick_catty(): SceneManager.enable_prop_item("prop_小猫玩具完整") # 八音盒中看不到 os # await inspector.quit_and_hidden - # SceneManager.pop_os_with_str(tr("c02_获得小猫玩具")) \ No newline at end of file + # SceneManager.pop_os_with_str("c02_获得小猫玩具") \ No newline at end of file diff --git a/scene/little_game/八音盒/八音盒.tscn b/scene/little_game/八音盒/八音盒.tscn index 57285ce7..9bbc582b 100644 --- a/scene/little_game/八音盒/八音盒.tscn +++ b/scene/little_game/八音盒/八音盒.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=54 format=3 uid="uid://beleib3mmu0af"] +[gd_scene load_steps=46 format=3 uid="uid://beleib3mmu0af"] [ext_resource type="Texture2D" uid="uid://2xbl572hv2qf" path="res://asset/art/little_game/八音盒/背景.png" id="1_j0wst"] [ext_resource type="Script" uid="uid://bian8ga7cet8k" path="res://scene/little_game/八音盒/八音盒.gd" id="2_opptd"] @@ -115,43 +115,12 @@ animations = [{ "speed": 5.0 }] -[sub_resource type="RectangleShape2D" id="RectangleShape2D_b3w8p"] -size = Vector2(310, 170) - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_28n4a"] -resource_local_to_scene = true -size = Vector2(20, 95) - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_5r85q"] -resource_local_to_scene = true -size = Vector2(20, 90) - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_ytjup"] -resource_local_to_scene = true -size = Vector2(20, 60) - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_7s35x"] -resource_local_to_scene = true -size = Vector2(20, 60) - [sub_resource type="RectangleShape2D" id="RectangleShape2D_cbhp3"] resource_local_to_scene = true size = Vector2(290, 60) -[sub_resource type="RectangleShape2D" id="RectangleShape2D_04cdl"] -resource_local_to_scene = true -size = Vector2(50, 70) - [sub_resource type="CircleShape2D" id="CircleShape2D_wq2wm"] -radius = 20.0 - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_sg8mt"] -resource_local_to_scene = true -size = Vector2(50, 30) - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_0kog4"] -resource_local_to_scene = true -size = Vector2(30, 70) +radius = 18.0 [node name="八音盒" type="CanvasLayer"] layer = 5 @@ -216,7 +185,6 @@ sprite_frames = SubResource("SpriteFrames_t7gu7") centered = false [node name="ClosedBox" parent="All" instance=ExtResource("16_h88gi")] -visible = false position = Vector2(277, 194.5) act_as_button = true item_name = "照片" @@ -224,11 +192,12 @@ sprite_offset = Vector2(3, -35) texture = ExtResource("22_rdaqv") limit_rect = Rect2(150, 150, 220, 70) -[node name="CollisionShape2D" type="CollisionShape2D" parent="All/ClosedBox"] -position = Vector2(15, 2.5) -shape = SubResource("RectangleShape2D_b3w8p") +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="All/ClosedBox"] +position = Vector2(2.99999, -33.5) +polygon = PackedVector2Array(123, -48, -102, -48, -102, -45.8, -104.8, -43, -106.3, -43, -147.3, 42, -149.3, 42, -139, 110.3, -139, 112.5, -135, 119.4, -135, 120, 155.1, 120, 157.4, 114, 158.7, 114, 167.7, 55, 169, 55, 169, 43.5, 123, -45.6) [node name="OpenedBox" type="Sprite2D" parent="All"] +visible = false position = Vector2(-48, 38) texture = ExtResource("16_dtoml") centered = false @@ -246,9 +215,9 @@ sprite_offset = Vector2(3, -35) texture = ExtResource("17_gm7pw") limit_rect = Rect2(150, 150, 220, 70) -[node name="CollisionShape2D" type="CollisionShape2D" parent="All/OpenedBox/Panel/Draggable2D1"] -position = Vector2(-1, -36) -shape = SubResource("RectangleShape2D_28n4a") +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="All/OpenedBox/Panel/Draggable2D1"] +position = Vector2(3.20175, -33.5559) +polygon = PackedVector2Array(2.5, -45.5, -8.5, -45.5, -9.3, -44.5, -11.9, -44.5, -9.5, -31.1, -9.5, -30.4, -15.2, -25.5, -17.1, -25.5, -18.5, -19.2, -18.5, -3.9, -14.5, -0.700001, -13.5, 33.3, -14.5, 34.8, -14.5, 41.7, -7.7, 45.5, 4.3, 45.5, 6.3, 43.5, 8.1, 43.5, 9.5, 37.7, 9.5, 35.7, 5.8, 32, 6.3, 31.5, 8.7, 31.5, 7.5, 16.5, 7.5, -5.5, 13.8, -5.5, 18.5, -15.9, 18.5, -26.8, 16.2, -27.8, 9.5, -22.5, 9.5, -20.5, 8.6, -20.5, 3.1, -28.8, 6.5, -38.1, 6.5, -42.5) [node name="Draggable2D2" parent="All/OpenedBox/Panel" instance=ExtResource("16_h88gi")] position = Vector2(286.5, 197) @@ -258,9 +227,9 @@ sprite_offset = Vector2(1, -34) texture = ExtResource("18_8vbnc") limit_rect = Rect2(150, 150, 220, 70) -[node name="CollisionShape2D" type="CollisionShape2D" parent="All/OpenedBox/Panel/Draggable2D2"] -position = Vector2(0, -34) -shape = SubResource("RectangleShape2D_5r85q") +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="All/OpenedBox/Panel/Draggable2D2"] +position = Vector2(1.42264, -34.029) +polygon = PackedVector2Array(11.5, -41.9, 2, -45.5, -5.5, -45.5, -9.4, -40.5, -12.1, -40.5, -10.5, -34.5, -10.5, -31.5, -6, -27.9, -10.3, -23.5, -12.3, -23.5, -12.5, -21.9, -12.5, -7.8, -10.9, -3.5, -12.5, 9.4, -12.5, 29.3, -9.5, 32.3, -12.5, 34.4, -12.5, 41.7, -5.7, 45.5, 6.3, 45.5, 8.3, 43.5, 10.1, 43.5, 11.5, 37.7, 11.5, 35.7, 8, 32.2, 10.2, 30.5, 12.5, 30.5, 12.5, 28.1, 8.5, -2.5, 8.5, -3.6, 12.2, -6.5, 12.5, -19.6, 5.4, -29.3, 11.5, -37.9) [node name="Draggable2D3" parent="All/OpenedBox/Panel" instance=ExtResource("16_h88gi")] position = Vector2(354, 169) @@ -270,9 +239,9 @@ sprite_offset = Vector2(1, -23) texture = ExtResource("19_858bj") limit_rect = Rect2(150, 150, 220, 70) -[node name="CollisionShape2D" type="CollisionShape2D" parent="All/OpenedBox/Panel/Draggable2D3"] -position = Vector2(-1, -23) -shape = SubResource("RectangleShape2D_ytjup") +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="All/OpenedBox/Panel/Draggable2D3"] +position = Vector2(1.18075, -22.9097) +polygon = PackedVector2Array(9.5, -23.1, 4.6, -26.3, 2.5, -25.2, 2.5, -24, -6.6, -24, -8.6, -21, -10.5, -21, -10.5, -18.8, -9.5, -15, -9.5, -8.9, -6.5, -6.9, -10.5, -2.8, -10.5, 16, -7.4, 18.3, -10, 20, -10.5, 29.5, -8.5, 31, -8.5, 32, 6.3, 32, 8.3, 30, 10.5, 30, 10.5, 27.6, 7, 17.3, 8.6, 15, 10.5, 15, 10.5, 13, 7.2, -9, 9.5, -20.8) [node name="Draggable2D4" parent="All/OpenedBox/Panel" instance=ExtResource("16_h88gi")] position = Vector2(310, 173) @@ -281,9 +250,9 @@ item_name = "蝉" sprite_offset = Vector2(-4, -23) limit_rect = Rect2(150, 150, 220, 70) -[node name="CollisionShape2D" type="CollisionShape2D" parent="All/OpenedBox/Panel/Draggable2D4"] -position = Vector2(1, -22) -shape = SubResource("RectangleShape2D_7s35x") +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="All/OpenedBox/Panel/Draggable2D4"] +position = Vector2(-4.7032, -24.7816) +polygon = PackedVector2Array(12, -29.6, -2.9, -33, -5, -33, -5, -31.3, -7, -30.2, -7, -25.3, -1.3, -17.7, -15, -5.9, -15, -3.2, -11.8, 0, -7.3, 0, -3.9, -2.8, -5, 1.8, -5, 6.7, -1, 12, -1, 17.9, -5.7, 21, -8, 21, -8, 29, -4, 32, -4, 33, 10.8, 33, 12.8, 31, 14.6, 31, 16, 25.2, 16, 22.8, 9, 18.8, 9, 15.8, 9.8, 15, 11.8, 15, 12.8, 7, 14.9, 7, 11, -3.5, 11, -8.4, 16, -17.5, 16, -27.3, 15.5, -29, 12, -29) [node name="Marker2D1" type="Marker2D" parent="All/OpenedBox/Panel"] position = Vector2(198, 178) @@ -298,7 +267,6 @@ position = Vector2(294, 177) position = Vector2(340, 178) [node name="BrokenBox" type="Sprite2D" parent="All"] -visible = false position = Vector2(-48, 38) texture = ExtResource("24_rriyt") centered = false @@ -320,10 +288,9 @@ item_name = "prop_撕下的照片上" texture = ExtResource("19_cbhp3") limit_rect = Rect2(150, 150, 220, 70) -[node name="CollisionShape2D" type="CollisionShape2D" parent="All/Draggable照片"] -position = Vector2(7, -2) -rotation = -0.234631 -shape = SubResource("RectangleShape2D_04cdl") +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="All/Draggable照片"] +position = Vector2(6.4373e-06, -9.53674e-07) +polygon = PackedVector2Array(31.5, -37.5, 29.7, -38, 18.4, -38, -19.7, -28.9, -26, -32, -30.7, -32, -32.5, -28.4, -32.5, -23.2, -24.5, -15.2, -24.5, -9.6, -20.5, -8.3, -20.5, 4.5, -17.7, 10, -14.5, 30.3, -14.5, 32, -10.5, 35, -10.5, 37, 3.3, 37, 4.5, 26.1, 6.2, 25, 9.3, 25, 7.5, 19.6, 10.6, 14, 13.1, 14, 10.5, 4, 10.5, 3.2, 21, -2, 23.6, -2, 31.6, -14, 32.5, -14, 32.5, -22.4, 31.5, -28.3) [node name="Drawer" type="Node2D" parent="All"] position = Vector2(20.5, 0) @@ -341,7 +308,7 @@ texture = ExtResource("30_tgpfj") limit_rect = Rect2(150, 150, 220, 70) [node name="CollisionShape2D" type="CollisionShape2D" parent="All/Drawer/Draggable1"] -position = Vector2(-1.15028, -1.11837) +position = Vector2(1, 7.62939e-06) shape = SubResource("CircleShape2D_wq2wm") [node name="Draggable2" parent="All/Drawer" instance=ExtResource("16_h88gi")] @@ -352,10 +319,9 @@ item_name = "prop_无头小猫玩具" texture = ExtResource("31_wq2wm") limit_rect = Rect2(150, 150, 220, 70) -[node name="CollisionShape2D" type="CollisionShape2D" parent="All/Drawer/Draggable2"] -position = Vector2(-2.01144, 7.74298) -scale = Vector2(3.06142, 3.16563) -shape = SubResource("RectangleShape2D_sg8mt") +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="All/Drawer/Draggable2"] +position = Vector2(-1.99999, 0.999999) +polygon = PackedVector2Array(46.8, -40.3, 44, -39.5, 44, -38.3, 42, -37.2, 42, -30, 31.2, -30, 30, -32.5, 30, -34.3, 27.5, -35.4, 26.2, -34, 22.8, -34, 20, -36.8, 20, -38.3, 17.5, -39.4, 15.2, -37, 13.8, -37, 12.7, -35, 15.7, -30, 13.5, -30, 12, -35, 12, -37.3, 9.5, -38.4, 5, -33.8, -4, -31.6, -4, -30, -15.9, -30, -17, -31.7, -17, -33.6, -26.8, -36, -28.8, -36, -33.8, -31, -35.6, -31, -43, 4.8, -43, 10.4, -45.4, 9, -46.9, 9, -50.9, 3, -51, -12.3, -50.3, -12, -46.9, -12, -44.9, -15, -42.7, -15, -44, -25, -44, -28.9, -51, -34.9, -51, -37.2, -62.2, -36, -64.9, -36, -72.9, -27, -74.6, -27, -78.5, -11, -80.1, -11, -79, 14.1, -79, 20.6, -73, 30.5, -73, 33, -63, 40.9, -63, 42.4, -58.3, 44, -42.4, 44, -40, 50.4, -40, 53.1, -35, 56.1, -35, 57.8, -25.1, 59, 12.8, 59, 16, 55.8, 16, 48.4, 23.2, 46, 25.2, 48, 33.8, 48, 38.8, 58, 61, 58, 64, 54, 68, 54, 77, 41.7, 77, 28.4, 73.1, 22, 72, 13, 72, 3.2, 69, 0.199997, 69, -20.7, 56, -36.9, 56, -38.5, 53.1, -39.3, 50.4, -35) [node name="Draggable3" parent="All/Drawer" instance=ExtResource("16_h88gi")] position = Vector2(368.5, 175) @@ -365,10 +331,9 @@ item_name = "prop_木头人偶" texture = ExtResource("32_sg8mt") limit_rect = Rect2(150, 150, 220, 70) -[node name="CollisionShape2D" type="CollisionShape2D" parent="All/Drawer/Draggable3"] -position = Vector2(-0.621627, 1.27025) -scale = Vector2(1.22064, 1.29461) -shape = SubResource("RectangleShape2D_0kog4") +[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="All/Drawer/Draggable3"] +position = Vector2(-1.99999, 0.999999) +polygon = PackedVector2Array(-11, -44.2, -11, -42.1, -14, -40.1, -14, -34.4, -9, -26.4, -9, -23.8, -5.6, -22.1, -12, -14.8, -12, -14.2, -27.6, -4, -29.2, -4, -30.3, -1.9, -27.1, 3, -20.5, 3, -8.7, -3.4, -11, 6.8, -11, 11.7, -5, 18.8, -5, 29, -12.7, 35, -15, 35, -15, 43.8, -11, 47.8, -11, 49.3, -2.4, 53, 6.8, 53, 15.7, 45, 18, 45, 18, 36, 13, 32, 13, 30, 8, 30, 8, 25.6, 10, 23, 11.7, 23, 13.7, 12, 15.6, 12, 11.5, -3, 12, -9.9, 12, -15.4, 19, -25, 21, -25, 21, -34.8, 16.8, -39, 13.8, -39, 12, -35.7, 12, -41.8) [node name="BoxAnimation" type="AnimatedSprite2D" parent="All"] visible = false