Compare commits

...

14 Commits

34 changed files with 786 additions and 247 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://jnw2yk6ls0fj"
path="res://.godot/imported/键位提示.png-64709bcd377e39f225bc60843c2472b7.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://asset/art/ui/键位提示.png"
dest_files=["res://.godot/imported/键位提示.png-64709bcd377e39f225bc60843c2472b7.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bb3khctfdyap8"
path="res://.godot/imported/键位提示_带背景.jpeg-07d430663777eab7f02ee130e18c9ded.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://asset/art/ui/键位提示_带背景.jpeg"
dest_files=["res://.godot/imported/键位提示_带背景.jpeg-07d430663777eab7f02ee130e18c9ded.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@ -27,8 +27,9 @@ c03_li_paperwoman: 0:初始化隐藏 1:显示纸人 2:纸舌头完成 3:给药
c03_drug_game: 0:初始化 1:获得药方 2:获得药包
# 囚室海报
c03_prison_flyer: 0:初始化 1:刮开
# 囚室门锁
c03_prison_lock: 0:初始化 1:打开
# 棺材房
c03_coffin: 0:初始化 1:拿走刀 2:拿走纸条_棺材怪演出 3:演出完成
# 绞肉机
c03_meat_grinder: 0:初始化 1:已装转盘 2:绞肉机演出 3:演出结束
# 结尾井边演出

View File

@ -59,13 +59,23 @@ ui_center_notify_c03药车不能再取药材,同种药材只能取出一份,,,,,
ui_center_notify_c03放到碗中或原处,药材只能放到碗中或原处,,,,,
ui_center_notify_c03碗口放入药材,从碗口处放入药材,,,,,
ui_center_notify_c03准备研磨,已准备好研磨,,,,,
ui_center_notify_c03粘刀把,需要粘上刀把,,,,,
ui_center_notify_c03绞肉机缺少转轮,缺少转轮,按 E 使用道具,,,,,
ui_获得道具,获得道具,,,,,Item Obtained
ui_获得重要物品,重要物品,,,,,
ui_退出,退出,,,,,Exit
ui_阅读,阅读,,,,,Read
ui_检阅,检阅,,,,,Examine
ui_收起,收起,,,,,Put away
ui_key_z,上个道具,,,,,Previous
ui_key_c,下个道具,,,,,Next
ui_key_a,向左走,,,,,Left
ui_key_d,向右走,,,,,Right
ui_key_q,取消,,,,,Cancel
ui_key_e,交互,,,,,Interact
ui_key_esc,退出,,,,,Exit
ui_key_b,重要物品,,,,,Bag
ui_key_n,笔记,,,,,Note
ui_key_m,回忆,,,,,Memory
ui_夜行船1,百岁光阴一梦蝶。,,,,,"A hundred years of life, like a butterfly's dream."
ui_夜行船2,重回首往事堪嗟。,,,,,"Looking back, past events are cause for lament."
ui_夜行船4,今日春来,明朝花谢。,,,,,"Spring comes today, tomorrow the flowers will wither."
@ -273,3 +283,4 @@ c03_s08_囚室绳子,绑得很死,直接解不开绳子。,,,,,
c03_s08_囚室醒过来,?这里是,,,,,
c03_s08_囚室看到脚印,?又是脚印,,,,,
c03_s08_囚室符纸,妖物者,本自造化而生,具灵识,知求生,与万类本无别。人言有异,是以别之。,,,,,
c03_s09_胖子干尸,?胖子干尸,,,,,

1 keys zh_CN _character _notes _tags zh_SH en
59 ui_center_notify_c03放到碗中或原处 药材只能放到碗中或原处
60 ui_center_notify_c03碗口放入药材 从碗口处放入药材
61 ui_center_notify_c03准备研磨 已准备好研磨
62 ui_center_notify_c03粘刀把 需要粘上刀把
63 ui_center_notify_c03绞肉机缺少转轮 缺少转轮,按 E 使用道具
64 ui_获得道具 获得道具 Item Obtained
ui_获得重要物品 重要物品
65 ui_退出 退出 Exit
66 ui_阅读 阅读 Read
67 ui_检阅 检阅 Examine
68 ui_收起 收起 Put away
69 ui_key_z 上个道具 Previous
70 ui_key_c 下个道具 Next
71 ui_key_a 向左走 Left
72 ui_key_d 向右走 Right
73 ui_key_q 取消 Cancel
74 ui_key_e 交互 Interact
75 ui_key_esc 退出 Exit
76 ui_key_b 重要物品 Bag
77 ui_key_n 笔记 Note
78 ui_key_m 回忆 Memory
79 ui_夜行船1 百岁光阴一梦蝶。 A hundred years of life, like a butterfly's dream.
80 ui_夜行船2 重回首往事堪嗟。 Looking back, past events are cause for lament.
81 ui_夜行船4 今日春来,明朝花谢。 Spring comes today, tomorrow the flowers will wither.
283 c03_s08_囚室醒过来 ?这里是
284 c03_s08_囚室看到脚印 ?又是脚印
285 c03_s08_囚室符纸 妖物者,本自造化而生,具灵识,知求生,与万类本无别。人言有异,是以别之。
286 c03_s09_胖子干尸 ?胖子干尸

View File

@ -67,16 +67,27 @@
药材只能放到碗中或原处 [ID:ui_center_notify_c03放到碗中或原处]
从碗口处放入药材 [ID:ui_center_notify_c03碗口放入药材]
已准备好研磨 [ID:ui_center_notify_c03准备研磨]
需要粘上刀把 [ID:ui_center_notify_c03粘刀把]
缺少转轮,按 E 使用道具 [ID:ui_center_notify_c03绞肉机缺少转轮]
获得道具 [ID:ui_获得道具]
重要物品 [ID:ui_获得重要物品]
退出 [ID:ui_退出]
阅读 [ID:ui_阅读]
检阅 [ID:ui_检阅]
收起 [ID:ui_收起]
上个道具 [ID:ui_key_z]
下个道具 [ID:ui_key_c]
向左走 [ID:ui_key_a]
向右走 [ID:ui_key_d]
取消 [ID:ui_key_q]
交互 [ID:ui_key_e]
退出 [ID:ui_key_esc]
重要物品 [ID:ui_key_b]
笔记 [ID:ui_key_n]
回忆 [ID:ui_key_m]
百岁光阴一梦蝶。 [ID:ui_夜行船1]
重回首往事堪嗟。 [ID:ui_夜行船2]
#今日春来 [ID:ui_夜行船3]
@ -360,6 +371,8 @@
?又是脚印 [ID:c03_s08_囚室看到脚印]
妖物者,本自造化而生,具灵识,知求生,与万类本无别。人言有异,是以别之。 [ID:c03_s08_囚室符纸]
# s09 棺材房
?胖子干尸 [ID:c03_s09_胖子干尸]
=> END
~ Notes_c04

View File

@ -7,3 +7,4 @@
[resource]
script = ExtResource("3_soveh")
audios = Array[AudioStream]([ExtResource("1_vboyp"), ExtResource("2_evogo")])
db = -7

View File

@ -22,10 +22,12 @@ var archive: AssembledArchive:
# emit signal
archive_loaded.emit()
GlobalConfigManager.print_global_info()
print("use archive ", archive.resource_path)
print("[Archive] use archive ", archive.resource_path)
archive.event_stage["release_stage"] = GlobalConfig.RELEASE_STAGE
print_rich("[color=brown] release_stage = %s[/color]" % GlobalConfig.RELEASE_STAGE)
else:
print("[Archive] unload archive")
var archives_dict: Dictionary[int, AssembledArchive] = {}
var archives_notes_dict: Dictionary[int, String] = {}

View File

@ -257,6 +257,26 @@ func disable_prop_item(prop_key: String) -> void:
printerr("disable_prop_item PropHud node not found")
# 临时禁用 prop, 延迟写入(真正 disable_prop_item 的时候写入)
func disable_prop_item_temp(prop_key: String) -> void:
var prop_hud = get_prop_hud()
if prop_hud:
print("[prop] disable_prop_item_temp prop:", prop_key)
prop_hud.disable_prop_item_temp(prop_key)
else:
printerr("disable_prop_item_temp PropHud node not found")
# 恢复临时禁用的 prop
func reset_temp_disabled_props() -> void:
var prop_hud = get_prop_hud()
if prop_hud:
print("[prop] reset_temp_disabled_props prop:")
prop_hud.reset_temp_disabled_props()
else:
printerr("reset_temp_disabled_props PropHud node not found")
func pop_os_with_str(translation_key: String) -> void:
var player = get_player() as MainPlayer
if player:
@ -338,6 +358,8 @@ func pop_chapter_notification(id: int) -> void:
func checkout_index_page(transition := true) -> void:
# 保存后,渐隐切换场景
ArchiveManager.save_all()
# 移除 archive
ArchiveManager.archive = null
if transition:
var ground_loader = get_ground_loader() as GroundLoader
if ground_loader:

View File

@ -76,9 +76,9 @@ func _unhandled_input(event: InputEvent) -> void:
if quit_closeup_on_cancel and not _holding_cancel_before_exit:
get_viewport().set_input_as_handled()
_exit()
# 在有特写界面时,阻塞 interact 输入
elif event.is_action_pressed("interact"):
get_viewport().set_input_as_handled()
# # 在有特写界面时,不能阻塞 interact 输入,因为可能 inspcet prop
# elif event.is_action_pressed("interact"):
# get_viewport().set_input_as_handled()
###### TOOL BUTTON

View File

@ -45,7 +45,6 @@ const GROUND_SCENE_PATH_DICT: Dictionary[String, Dictionary] = {
"c03_s10": {"path": "uid://clgwc3jcqarpe", "name": "胖子游戏1"},
"c03_s11": {"path": "uid://shgrg8qcr1cu", "name": "胖子游戏2"},
"c03_s12": {"path": "uid://cxabqg87g4vxc", "name": "胖子游戏3"},
"c03_s13": {"path": "uid://s6odh172gpbr", "name": "胖子游戏4"},
"c04_s01": {"path": "uid://drjnu33pga6i5", "name": "父母房间"},
}

View File

@ -24,6 +24,7 @@ func _setup_display_on_locale():
$"Intro/Content/水平排版".visible = not is_zh
$"Intro/Content/竖直排版".visible = is_zh
func _notification(what: int) -> void:
if what == NOTIFICATION_TRANSLATION_CHANGED:
_setup_display_on_locale()
@ -44,8 +45,10 @@ func play_intro_dialogue():
# 直接使用 sfx防止下方字幕与全屏文字重复
$intro_audio_player.play()
var tip: Node2D
func _on_ground_ready() -> void:
tip = $"../ParallaxForeground/FGParallaxLayer/键位提示"
ArchiveManager.set_chapter_if_greater(1)
ambush = $"../DeployLayer/ambush鸡毛掸子"
frame = $"../DeployLayer/画框"
@ -95,7 +98,9 @@ func _on_ground_ready() -> void:
func cant_read() -> void:
DialogueManager.show_dialogue_balloon(dialogue_c01, "c01_s05_院长房间_看不清了", [GlobalConfig.DIALOG_IGNORE_INPUT])
DialogueManager.show_dialogue_balloon(
dialogue_c01, "c01_s05_院长房间_看不清了", [GlobalConfig.DIALOG_IGNORE_INPUT]
)
func os_find_wig() -> void:
@ -178,8 +183,38 @@ func _on_piano_interacted():
SceneManager.pop_debug_dialog_info("音效", "钢琴声: " + str(piano_id))
var help_tween: Tween
var help_tween_paused := false
func show_interact_help():
tip.modulate.a = 0.0
tip.show()
SceneManager.lock_player()
help_tween = create_tween()
help_tween.tween_property(tip, "modulate:a", 1.0, 1.0)
help_tween.tween_callback(func ():
help_tween_paused = true
Util.timer(2.0, _breath_light)
help_tween.pause()
)
help_tween.tween_property(tip, "modulate:a", 0.0, 1.0)
await help_tween.finished
SceneManager.unlock_player()
await Util.wait(0.5)
SceneManager.pop_center_notification("ui_center_notify_a_d_to_move")
await Util.wait(5.0)
SceneManager.pop_center_notification("ui_center_notify_press_e_to_interact")
func _breath_light() -> void:
var light = tip.get_node("PointLight2D") as PointLight2D
var tween = create_tween()
tween.tween_property(light, "energy", 1.0, 1.0)
tween.tween_property(light, "energy", 0.0, 1.0)
tween.tween_callback(_breath_light)
func _unhandled_input(event: InputEvent) -> void:
if help_tween_paused and event.is_action_pressed("cancel"):
help_tween.play()

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=38 format=3 uid="uid://dlx5xxbg53rb8"]
[gd_scene load_steps=41 format=3 uid="uid://dlx5xxbg53rb8"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_ff4yb"]
[ext_resource type="Script" uid="uid://q2qgg85xa6ie" path="res://scene/ground/scene/c01/s05_院长房间.gd" id="2_j5oim"]
@ -20,6 +20,7 @@
[ext_resource type="PackedScene" uid="uid://jr1yd46wm5je" path="res://scene/entity/note.tscn" id="10_18v0g"]
[ext_resource type="Script" uid="uid://wapo47a1oddf" path="res://scene/entity/audio/sfx2d.gd" id="10_kyds0"]
[ext_resource type="Texture2D" uid="uid://choqjery7hf58" path="res://asset/art/scene/c01/s05_院长房间/e_画框.png" id="11_6gq1s"]
[ext_resource type="Texture2D" uid="uid://jnw2yk6ls0fj" path="res://asset/art/ui/键位提示.png" id="11_247wt"]
[ext_resource type="Texture2D" uid="uid://dae5yrbb5llia" path="res://asset/art/scene/c01/s05_院长房间/e_鸡毛掸子.png" id="12_jtglg"]
[ext_resource type="SpriteFrames" uid="uid://b7fhheih1hbvf" path="res://config/animation/entity_sprite_frames.tres" id="14_e1bmq"]
[ext_resource type="PackedScene" uid="uid://cw3q5pvciumil" path="res://scene/entity/interactable.tscn" id="14_lq1ou"]
@ -30,6 +31,8 @@
[ext_resource type="Texture2D" uid="uid://gui0ubwlwoi0" path="res://asset/art/ui/action_mark/UI手.png" id="22_00ufd"]
[ext_resource type="LabelSettings" uid="uid://dd6jhbqr6uh3x" path="res://config/序章夜行船_label_settings.tres" id="28_8gx6s"]
[ext_resource type="Script" uid="uid://dpocj5al0rvai" path="res://ui/text_helper.gd" id="29_247wt"]
[ext_resource type="Texture2D" uid="uid://b7gyapghy3tsy" path="res://asset/art/neutral_point_light.png" id="31_qf7jl"]
[ext_resource type="FontVariation" uid="uid://1ryw42kej6lv" path="res://config/font_ui.tres" id="31_w4f3l"]
[sub_resource type="Animation" id="Animation_c6mhi"]
length = 0.001
@ -865,6 +868,7 @@ position = Vector2(27, 3)
[node name="portal_right" parent="Ground/DeployLayer" index="1"]
position = Vector2(503, 11)
texture = ExtResource("4_gdhoy")
sign_mark_offset = Vector2(0, -46)
target_scene = "c01_s06"
target_portal = "left"
status = "opened"
@ -984,6 +988,257 @@ position = Vector2(21, 39)
texture = ExtResource("3_vmr0f")
offset = Vector2(0, 0)
[node name="键位提示" type="Node2D" parent="Ground/ParallaxForeground/FGParallaxLayer" index="1"]
visible = false
[node name="提示图" type="Sprite2D" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
light_mask = 3
position = Vector2(0, -158)
scale = Vector2(0.25, 0.25)
texture = ExtResource("11_247wt")
centered = false
[node name="PointLight2D" type="PointLight2D" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
position = Vector2(230, -14)
color = Color(0, 0.770832, 0.205171, 1)
energy = 0.0
range_layer_min = 1
range_layer_max = 10
range_item_cull_mask = 2
texture = ExtResource("31_qf7jl")
texture_scale = 0.3
[node name="z" type="Control" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
layout_mode = 3
anchors_preset = 0
offset_left = 100.0
offset_top = -83.0
offset_right = 100.0
offset_bottom = -83.0
mouse_filter = 2
[node name="Label" type="Label" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示/z"]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -21.5
offset_right = 21.5
offset_bottom = 14.0
grow_horizontal = 2
theme_override_fonts/font = ExtResource("31_w4f3l")
text = "ui_key_z"
horizontal_alignment = 1
vertical_alignment = 1
[node name="c" type="Control" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
layout_mode = 3
anchors_preset = 0
offset_left = 143.0
offset_top = -83.0
offset_right = 143.0
offset_bottom = -83.0
mouse_filter = 2
[node name="Label" type="Label" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示/c"]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -21.5
offset_right = 21.5
offset_bottom = 14.0
grow_horizontal = 2
theme_override_fonts/font = ExtResource("31_w4f3l")
text = "ui_key_c"
horizontal_alignment = 1
vertical_alignment = 1
[node name="a" type="Control" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
layout_mode = 3
anchors_preset = 0
offset_left = 71.0
offset_top = 21.0
offset_right = 71.0
offset_bottom = 21.0
mouse_filter = 2
[node name="Label" type="Label" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示/a"]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -21.5
offset_right = 21.5
offset_bottom = 14.0
grow_horizontal = 2
theme_override_fonts/font = ExtResource("31_w4f3l")
text = "ui_key_a"
horizontal_alignment = 1
vertical_alignment = 1
[node name="d" type="Control" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
layout_mode = 3
anchors_preset = 0
offset_left = 111.0
offset_top = 21.0
offset_right = 111.0
offset_bottom = 21.0
mouse_filter = 2
[node name="Label" type="Label" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示/d"]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -21.5
offset_right = 21.5
offset_bottom = 14.0
grow_horizontal = 2
theme_override_fonts/font = ExtResource("31_w4f3l")
text = "ui_key_d"
horizontal_alignment = 1
vertical_alignment = 1
[node name="q" type="Control" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
layout_mode = 3
anchors_preset = 0
offset_left = 229.0
offset_top = -3.0
offset_right = 229.0
offset_bottom = -3.0
mouse_filter = 2
[node name="Label" type="Label" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示/q"]
light_mask = 3
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -21.5
offset_right = 21.5
offset_bottom = 14.0
grow_horizontal = 2
theme_override_fonts/font = ExtResource("31_w4f3l")
text = "ui_key_q"
horizontal_alignment = 1
vertical_alignment = 1
[node name="e" type="Control" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
layout_mode = 3
anchors_preset = 0
offset_left = 326.0
offset_top = -2.0
offset_right = 326.0
offset_bottom = -2.0
mouse_filter = 2
[node name="Label" type="Label" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示/e"]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -21.5
offset_right = 21.5
offset_bottom = 14.0
grow_horizontal = 2
theme_override_fonts/font = ExtResource("31_w4f3l")
text = "ui_key_e"
horizontal_alignment = 1
vertical_alignment = 1
[node name="esc" type="Control" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
layout_mode = 3
anchors_preset = 0
offset_left = 306.0
offset_top = 80.0
offset_right = 306.0
offset_bottom = 80.0
mouse_filter = 2
[node name="Label" type="Label" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示/esc"]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -21.5
offset_right = 21.5
offset_bottom = 14.0
grow_horizontal = 2
theme_override_fonts/font = ExtResource("31_w4f3l")
text = "ui_key_esc"
horizontal_alignment = 1
vertical_alignment = 1
[node name="b" type="Control" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
layout_mode = 3
anchors_preset = 0
offset_left = 365.0
offset_top = 80.0
offset_right = 365.0
offset_bottom = 80.0
mouse_filter = 2
[node name="Label" type="Label" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示/b"]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -21.5
offset_right = 21.5
offset_bottom = 14.0
grow_horizontal = 2
theme_override_fonts/font = ExtResource("31_w4f3l")
text = "ui_key_b"
horizontal_alignment = 1
vertical_alignment = 1
[node name="n" type="Control" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
layout_mode = 3
anchors_preset = 0
offset_left = 427.0
offset_top = 80.0
offset_right = 427.0
offset_bottom = 80.0
mouse_filter = 2
[node name="Label" type="Label" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示/n"]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -21.5
offset_right = 21.5
offset_bottom = 14.0
grow_horizontal = 2
theme_override_fonts/font = ExtResource("31_w4f3l")
text = "ui_key_n"
horizontal_alignment = 1
vertical_alignment = 1
[node name="m" type="Control" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示"]
layout_mode = 3
anchors_preset = 0
offset_left = 486.0
offset_top = 80.0
offset_right = 486.0
offset_bottom = 80.0
mouse_filter = 2
[node name="Label" type="Label" parent="Ground/ParallaxForeground/FGParallaxLayer/键位提示/m"]
layout_mode = 1
anchors_preset = 5
anchor_left = 0.5
anchor_right = 0.5
offset_left = -21.5
offset_right = 21.5
offset_bottom = 14.0
grow_horizontal = 2
theme_override_fonts/font = ExtResource("31_w4f3l")
text = "ui_key_m"
horizontal_alignment = 1
vertical_alignment = 1
[node name="PlayerLine2D" parent="Ground/ParallaxForeground" index="2"]
points = PackedVector2Array(40, 149, 530, 150)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=30 format=3 uid="uid://c777lv8mjojcw"]
[gd_scene load_steps=28 format=3 uid="uid://c777lv8mjojcw"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_mrwu5"]
[ext_resource type="Script" uid="uid://c7rvvsuf18ykn" path="res://scene/ground/scene/c01/s09_公寓楼外.gd" id="2_u053j"]
@ -19,7 +19,6 @@
[ext_resource type="SpriteFrames" uid="uid://c2peyi2l65h47" path="res://asset/art/gif/c01_公寓外街道/c01_公寓外街道_frames.tres" id="10_0ohlv"]
[ext_resource type="Script" uid="uid://dxq5c05ab7uyu" path="res://scene/ground/script/c01/s00_ghost_footstep.gd" id="11_6w7lv"]
[ext_resource type="Texture2D" uid="uid://b7gyapghy3tsy" path="res://asset/art/neutral_point_light.png" id="12_828bq"]
[ext_resource type="Texture2D" uid="uid://r0n7qy4kr3w2" path="res://asset/art/ui/action_mark/UI场景切换.png" id="12_lrqbi"]
[ext_resource type="PackedScene" uid="uid://svvlohuicvhf" path="res://scene/entity/ambient/light.tscn" id="13_6w7lv"]
[ext_resource type="Script" uid="uid://wapo47a1oddf" path="res://scene/entity/audio/sfx2d.gd" id="19_jgofb"]
[ext_resource type="Script" uid="uid://baok7hk5jygpm" path="res://scene/ground/script/c01/s09_鬼影浮现.gd" id="20_nwvnr"]
@ -53,10 +52,6 @@ animations = [{
"speed": 5.0
}]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_j34rt"]
resource_local_to_scene = true
size = Vector2(30, 130)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4sgc5"]
size = Vector2(40, 80)
@ -118,28 +113,12 @@ frame = 0
[node name="portal_2" parent="Ground/DeployLayer" index="3" instance=ExtResource("3_4myxt")]
position = Vector2(2938, 18)
collision_width_and_x = Vector2(75.04, 0)
debug_note = "传送到公寓楼道"
portal_name = "2"
target_scene = "c01_s10"
target_portal = "left"
[node name="SfxEnter" parent="Ground/DeployLayer/portal_2" index="2"]
stream = null
[node name="Sign" parent="Ground/DeployLayer/portal_2" index="4"]
enabled = true
[node name="TextureContainer" parent="Ground/DeployLayer/portal_2/Sign" index="0"]
offset_top = -50.0
offset_bottom = -50.0
[node name="Sprite2D" parent="Ground/DeployLayer/portal_2/Sign/TextureContainer" index="0"]
texture = ExtResource("12_lrqbi")
[node name="CollisionShape2D" parent="Ground/DeployLayer/portal_2/Area2D" index="0"]
position = Vector2(5, 0)
shape = SubResource("RectangleShape2D_j34rt")
[node name="S01自动枯萎的花朵" parent="Ground/DeployLayer" index="4" node_paths=PackedStringArray("focus_node") instance=ExtResource("3_52pqy")]
position = Vector2(539, 79)
focus_node = NodePath("../Ghost")
@ -371,5 +350,3 @@ energy = 0.4
blend_mode = 1
[editable path="Ground"]
[editable path="Ground/DeployLayer/portal_2"]
[editable path="Ground/DeployLayer/portal_2/Sign"]

View File

@ -53,6 +53,7 @@ debug_note = "出来就不能回来了"
portal_name = "1"
target_scene = "c02_s12"
target_portal = "left"
status = "opened"
[node name="Ambush猫咪敲门互动2" parent="Ground/DeployLayer" index="3" instance=ExtResource("8_m6dyn")]
position = Vector2(106, 6)

View File

@ -41,6 +41,7 @@ func _on_ground_ready() -> void:
if interactable_body.icount > 0:
closeup符纸.show()
if interactable_body.interacted_times > 0:
pickable转轮.enabled = true
body_sprite.frame = 3
if ambush血脚印.played:
ambush血脚印.get_node("血脚印").frame = 8
@ -72,6 +73,8 @@ func _on_body_interacted(success: bool) -> void:
await Util.wait(1.0)
SceneManager.unlock_player()
if success:
SceneManager.disable_prop_item("prop_菜刀")
pickable转轮.enabled = true
SceneManager.lock_player()
body_sprite.play()
await body_sprite.animation_finished

View File

@ -4,7 +4,7 @@ extends AnimationRoot
# 覆盖该方法
func _default_data() -> Dictionary:
return {"monster_woken": false}
return {}
func _ready() -> void:
@ -27,24 +27,27 @@ func _setup_node_reference() -> void:
func _on_ground_ready() -> void:
closeup棺材特写.exit.connect(_on_coffin_exit)
if data["monster_woken"]:
closeup棺材特写.hide()
# c03_coffin: 0:初始化 1:拿走刀 2:拿走纸条_棺材怪演出 3:演出完成
var stage = EventManager.get_stage("c03_coffin")
if stage == 2:
_coffin_monster_climb_out()
elif stage == 3:
sfx_2d棺材呼吸声.stop()
func _on_coffin_exit(arg) -> void:
if arg:
set_data("monster_woken", true)
_coffin_monster_climb_out()
func _coffin_monster_climb_out() -> void:
await Util.wait(2.0)
SceneManager.lock_player()
play("monster_first_contact")
await Util.wait(1.0)
SceneManager.pop_debug_dialog_info("音效", "棺材怪对峙amb+爬行sfx")
await animation_finished
SceneManager.unlock_player()
EventManager.set_stage("c03_coffin", 3)
func monster_disappear_ambush() -> void:

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=22 format=3 uid="uid://dfln301xllqpn"]
[gd_scene load_steps=23 format=3 uid="uid://dfln301xllqpn"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_8vqn6"]
[ext_resource type="Script" uid="uid://dxt2u1jajrm1g" path="res://scene/ground/scene/c03/s09_棺材房.gd" id="2_8vqn6"]
@ -15,6 +15,7 @@
[ext_resource type="Script" uid="uid://cphfob11f7atx" path="res://addons/property-inspector/pro_animation_sprite2d/pro_animated_sprite.gd" id="10_t7o3d"]
[ext_resource type="AudioStream" uid="uid://cfsx6yqrw5gp4" path="res://asset/audio/sfx/交互/第二章/棺材怪呼吸.ogg" id="11_qr48f"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="13_alans"]
[ext_resource type="Script" uid="uid://0wjaho6qkg6s" path="res://manager/event_manager/event_binder.gd" id="13_fijc5"]
[ext_resource type="Texture2D" uid="uid://d3rl4pyal4bao" path="res://asset/art/scene/c03/s09_棺材房/角落胖子干尸.png" id="14_htuhx"]
[ext_resource type="AudioStream" uid="uid://b8gsppgtp8tdk" path="res://asset/audio/sfx/旧版/lvping/footstep_earth_left.ogg" id="15_qr48f"]
[ext_resource type="Texture2D" uid="uid://cylsq5cvhlp18" path="res://asset/art/tool/point_light.png" id="15_rcrkk"]
@ -36,7 +37,7 @@ tracks/0/keys = {
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("%Sfx2D棺材怪移动声:playing")
tracks/1/path = NodePath("DeployLayer/Pro棺材怪/Sfx2D棺材怪移动声:playing")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
@ -48,7 +49,7 @@ tracks/1/keys = {
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("%Sfx2D棺材呼吸声:position")
tracks/2/path = NodePath("DeployLayer/Sfx2D棺材呼吸声:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
@ -105,10 +106,22 @@ tracks/6/keys = {
"update": 1,
"values": [&"棺材怪走路"]
}
tracks/7/type = "value"
tracks/7/imported = false
tracks/7/enabled = true
tracks/7/path = NodePath("DeployLayer/Pro棺材怪2/Ambush棺材怪消失:enabled")
tracks/7/interp = 1
tracks/7/loop_wrap = true
tracks/7/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="Animation" id="Animation_alans"]
resource_name = "monster_first_contact"
length = 7.0
length = 10.0
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
@ -116,7 +129,7 @@ tracks/0/path = NodePath("DeployLayer/Pro棺材怪/呼吸声跟随1:remote_path"
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 3.5),
"times": PackedFloat32Array(0, 4.83334),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [NodePath("../../Sfx2D棺材呼吸声"), NodePath("")]
@ -128,7 +141,7 @@ tracks/1/path = NodePath("DeployLayer/Pro棺材怪:position")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 2.33333, 3.5),
"times": PackedFloat32Array(0, 3.66667, 4.83334),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector2(453, -100), Vector2(453, -100), Vector2(-100, -100)]
@ -140,7 +153,7 @@ tracks/2/path = NodePath("DeployLayer/Pro棺材怪2:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 3.93333, 5.53333),
"times": PackedFloat32Array(0, 5.83333, 7.26667),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector2(-88, 12), Vector2(-88, 12), Vector2(50, 12)]
@ -152,7 +165,7 @@ tracks/3/path = NodePath("DeployLayer/Pro棺材怪2/呼吸声跟随2:remote_path
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0, 3.56667),
"times": PackedFloat32Array(0, 5),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [NodePath(""), NodePath("../../Sfx2D棺材呼吸声")]
@ -160,14 +173,14 @@ tracks/3/keys = {
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("%Sfx2D棺材怪移动声:playing")
tracks/4/path = NodePath("DeployLayer/Pro棺材怪/Sfx2D棺材怪移动声:playing")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(2.37),
"transitions": PackedFloat32Array(1),
"times": PackedFloat32Array(3.70334, 5.66667),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [true]
"values": [true, false]
}
tracks/5/type = "method"
tracks/5/imported = false
@ -176,7 +189,7 @@ tracks/5/path = NodePath("MainPlayer")
tracks/5/interp = 1
tracks/5/loop_wrap = true
tracks/5/keys = {
"times": PackedFloat32Array(0, 2.7),
"times": PackedFloat32Array(0, 4.3),
"transitions": PackedFloat32Array(1, 1),
"values": [{
"args": [Vector2(1, 0)],
@ -193,11 +206,23 @@ tracks/6/path = NodePath("DeployLayer/Pro棺材怪2:animation")
tracks/6/interp = 1
tracks/6/loop_wrap = true
tracks/6/keys = {
"times": PackedFloat32Array(5.83333),
"times": PackedFloat32Array(7.7),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [&"棺材怪受惊"]
}
tracks/7/type = "value"
tracks/7/imported = false
tracks/7/enabled = true
tracks/7/path = NodePath("DeployLayer/Pro棺材怪2/Ambush棺材怪消失:enabled")
tracks/7/interp = 1
tracks/7/loop_wrap = true
tracks/7/keys = {
"times": PackedFloat32Array(9.4),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_k01ve"]
_data = {
@ -253,9 +278,10 @@ texture = ExtResource("14_htuhx")
position = Vector2(420, 56)
sign_mark_offset = Vector2(27.55, 0)
action = 3
title_filter = "c03"
note_key = "c03_s09_胖子干尸"
[node name="Sfx2D棺材呼吸声" type="AudioStreamPlayer2D" parent="Ground/DeployLayer" index="4"]
unique_name_in_owner = true
position = Vector2(341, 45)
stream = ExtResource("11_qr48f")
autoplay = true
@ -270,9 +296,18 @@ metadata/_custom_type_script = "uid://wapo47a1oddf"
position = Vector2(338, 54)
texture = ExtResource("7_kdfpp")
packed_scene = ExtResource("7_klnhf")
quit_closeup_on_cancel = false
sign_mark_offset = Vector2(0, -21.53)
collision_width_and_x = Vector2(100.52, 0)
[node name="EventBinder" type="Node" parent="Ground/DeployLayer/Closeup棺材特写"]
script = ExtResource("13_fijc5")
updater_event = &"c03_coffin"
updater_mode = "shower"
updater_ease_duration = 0.0
updater_stages = Array[int]([0, 1])
metadata/_custom_type_script = "uid://0wjaho6qkg6s"
[node name="Pro棺材怪" type="AnimatedSprite2D" parent="Ground/DeployLayer" index="6"]
light_mask = 3
position = Vector2(611, -65)
@ -283,7 +318,6 @@ script = ExtResource("10_t7o3d")
metadata/_custom_type_script = "uid://cphfob11f7atx"
[node name="Sfx2D棺材怪移动声" type="AudioStreamPlayer2D" parent="Ground/DeployLayer/Pro棺材怪"]
unique_name_in_owner = true
position = Vector2(15, -22)
stream = ExtResource("15_qr48f")
volume_db = 10.0
@ -296,6 +330,7 @@ metadata/_custom_type_script = "uid://wapo47a1oddf"
[node name="PointLight2D" type="PointLight2D" parent="Ground/DeployLayer/Pro棺材怪"]
position = Vector2(-19, -27)
energy = 0.35
range_item_cull_mask = 2
texture = ExtResource("15_rcrkk")
@ -315,9 +350,11 @@ metadata/_custom_type_script = "uid://cphfob11f7atx"
[node name="Ambush棺材怪消失" parent="Ground/DeployLayer/Pro棺材怪2" instance=ExtResource("13_alans")]
position = Vector2(155, 45)
enabled = false
hook_method = "monster_disappear_ambush"
[node name="PointLight2D" type="PointLight2D" parent="Ground/DeployLayer/Pro棺材怪2"]
position = Vector2(-20, 4)
energy = 0.35
range_item_cull_mask = 2
texture = ExtResource("15_rcrkk")

View File

@ -30,5 +30,6 @@ func _check_first_enter() -> void:
if not data["has_entered"]:
SceneManager.lock_player(0, 5, true)
set_data("has_entered", true)
await SceneManager.pause_and_hide_player_sprite(1.5)
SceneManager.pause_and_hide_player_sprite(1.5)
await SceneManager.get_player().animation_finished
SceneManager.unlock_player()

View File

@ -21,22 +21,20 @@ func _ready() -> void:
func _setup_node_reference() -> void:
pass
func _on_ground_ready() -> void:
pass
func eat_meat() -> void:
var light_pivot = $"../DeployLayer/LightPivot"
SceneManager.lock_player()
$"../DeployLayer/Ambush吃肉".enabled = false
await SceneManager.get_player().walk_to_x(850.0).finished
# 第一帧没有瘦子,后面才有
var player = SceneManager.get_player() as MainPlayer
var sprite = $"../DeployLayer/Pro吃肉" as ProAnimatedSprite2D
sprite.play()
sprite.frame = 1
player.hide_sprite = true
await sprite.animation_finished
player.reparent_light(light_pivot)
play("eat_meat")
await animation_finished
SceneManager.unlock_player()
# c03_meat_grinder: 0:初始化 1:已装转盘 2:绞肉机演出 3:演出结束
EventManager.set_stage_if_greater("c03_meat_grinder", 2)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=10 format=3 uid="uid://cxabqg87g4vxc"]
[gd_scene load_steps=12 format=3 uid="uid://cxabqg87g4vxc"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_ly8ge"]
[ext_resource type="Script" uid="uid://f4uampm47832" path="res://scene/ground/scene/c03/s12_胖子游戏3.gd" id="2_c01lu"]
@ -9,7 +9,91 @@
[ext_resource type="SpriteFrames" uid="uid://cb3b44a1jpybb" path="res://asset/art/gif/c03_胖子游戏/c03_胖子游戏第四段/c03_胖子游戏第四段_frames.tres" id="10_7x1vi"]
[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="11_sul0a"]
[sub_resource type="Animation" id="Animation_c01lu"]
resource_name = "eat_meat"
length = 10.0
capture_included = true
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("DeployLayer/LightPivot:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.42, 0.7, 3.31, 4.75, 5.79, 9.4, 9.68, 10),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Vector2(850, 95), Vector2(875, 75), Vector2(892, 47), Vector2(940, 20), Vector2(944, 21), Vector2(959, 11), Vector2(977, -13), Vector2(977, 13), Vector2(968, 176)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("DeployLayer/Pro吃肉:frame")
tracks/1/interp = 1
tracks/1/loop_wrap = false
tracks/1/keys = {
"times": PackedFloat32Array(0, 10),
"transitions": PackedFloat32Array(1, 1),
"update": 2,
"values": [1, 48]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("MainPlayer:hide_sprite")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0.0333333),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
[sub_resource type="Animation" id="Animation_ay855"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("DeployLayer/LightPivot:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(850, 95)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("DeployLayer/Pro吃肉:frame")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [0]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("MainPlayer:hide_sprite")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_k01ve"]
_data = {
&"RESET": SubResource("Animation_ay855"),
&"eat_meat": SubResource("Animation_c01lu")
}
[node name="S12" type="Node2D"]
metadata/_edit_horizontal_guides_ = [-627.0]
@ -63,6 +147,9 @@ trigger_mode = "interact"
one_shot = false
hook_method = "eat_meat"
[node name="LightPivot" type="Marker2D" parent="Ground/DeployLayer" index="4"]
position = Vector2(850, 95)
[node name="MainPlayer" parent="Ground" index="5"]
position = Vector2(69, 95)
character = "胖子游戏"

View File

@ -1,45 +0,0 @@
@tool
extends AnimationRoot
# 覆盖该方法
func _default_data() -> Dictionary:
return {}
func _ready() -> void:
super._ready()
if Engine.is_editor_hint():
return
#region node_reference
#endregion
# 读取设置变量名
func _setup_node_reference() -> void:
pass
func _on_ground_ready() -> void:
pass
func eat_meat() -> void:
SceneManager.lock_player()
$"../DeployLayer/Ambush吃肉".enabled = false
await SceneManager.get_player().walk_to_x(850.0).finished
# 第一帧没有瘦子,后面才有
var player = SceneManager.get_player() as MainPlayer
var sprite = $"../DeployLayer/Pro吃肉" as ProAnimatedSprite2D
sprite.play()
sprite.frame = 1
player.hide_sprite = true
await sprite.animation_finished
SceneManager.unlock_player()
# c03_meat_grinder: 0:初始化 1:已装转盘 2:绞肉机演出 3:演出结束
EventManager.set_stage_if_greater("c03_meat_grinder", 2)
SceneManager.get_ground_loader().transition_to_scene("c03_s07", "2")

View File

@ -1 +0,0 @@
uid://ddawqvg4fjxv6

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=10 format=3 uid="uid://s6odh172gpbr"]
[gd_scene load_steps=10 format=3 uid="uid://ban8firg4ti5x"]
[ext_resource type="PackedScene" uid="uid://dayyx4jerj7io" path="res://scene/ground/ground.tscn" id="1_via7g"]
[ext_resource type="Script" uid="uid://f4uampm47832" path="res://scene/ground/scene/c03/s12_胖子游戏3.gd" id="2_f2euj"]

View File

@ -10,10 +10,10 @@ extends Node2D
@export var trun_back_detect_x := 150
# 抓取范围,优先 catch_front 播放 猪头怪抓盒子猫
# 其次 catch_nearby 播放 猪头怪抓盒子猫后段
@export var catch_front_x_range := Vector2(55 - 3, 55 + 3)
@export var catch_nearby_x_range := Vector2(-10, 55)
var catch_front_x_range := Vector2(55 - 3, 55 + 3)
var catch_nearby_x_range := Vector2(-10, 55)
# 观测范围,在观测范围内进入盒子仍旧会被抓
@export var watching_x := 180
var watching_x := 80
# 允许被抓后重开游戏
var allow_restart_game := true
@ -50,6 +50,7 @@ func _on_ground_ready():
var archive = ArchiveManager.archive as AssembledArchive
var portal = archive.entrance_portal
var chasing_started = ArchiveManager.get_global_value(&"c02_boxcat_chasing_started", false)
# 盒子猫二楼 c02_s13
if archive.current_scene == "c02_s13":
# 开始追逐后,禁用二楼两只
if chasing_started and not transfer_mode:
@ -89,8 +90,8 @@ func _on_ground_ready():
global_position.x = portal_node.global_position.x
# 禁用传送过来的 portal 3s
_disable_portal_a_few_seconds(portal_node)
# 3 秒后传送
Util.timer(1.0, _do_transfer)
# 2.5 秒后传送
Util.timer(2.5, _do_transfer)
if GlobalConfig.DEBUG:
print("猪头怪 Transfer to: " + portal)
else:
@ -126,10 +127,10 @@ func toggle_footstep_sfx(play := true):
footstep_timer.stop()
# 禁用传送过来的 portal 3s
# 禁用传送过来的 portal 4s
func _disable_portal_a_few_seconds(portal_node: Portal2D):
portal_node.enabled = false
await create_tween().tween_interval(3.0).finished
await create_tween().tween_interval(4.0).finished
portal_node.enabled = true
@ -183,6 +184,8 @@ func do_catch(front: bool):
SceneManager.unlock_player()
# 等待动画播放后秒,再检查是否允许重开游戏
if allow_restart_game:
# 重置追击状态
ArchiveManager.set_global_entry(&"c02_boxcat_chasing_started", false)
SceneManager.get_ground_loader().transition_to_scene("c02_s12", "left")

View File

@ -76,5 +76,4 @@ func _unhandled_input(event: InputEvent) -> void:
return
if GlobalConfig.DEBUG:
print("无效的道具:%s" % prop)
$SfxInvalid.play()
prop_hud.on_toggle_invalid_prop()

View File

@ -13,7 +13,7 @@ signal exit(arg)
func _ready() -> void:
layer = GlobalConfig.CANVAS_LAYER_LITTLE_GAME
drag_wizardpaper.picked.connect(func(_a):
SceneManager.enable_important_item("prop_符纸", false)
SceneManager.enable_important_item("prop_符纸")
)
drag_newspaper.picked.connect(func(_a):
sfx_newspaper.play()

View File

@ -3,34 +3,71 @@ extends CanvasLayer
@warning_ignore("unused_signal")
signal exit(arg)
@onready var hover_knife = %"Hover刀" as HoverLightClickArea
@onready var hover_note = %"Hover纸条" as HoverLightClickArea
# c03_coffin: 0:初始化 1:拿走刀 2:拿走纸条_棺材怪演出 3:演出完成
var coffin_stage := 0
func _ready() -> void:
layer = GlobalConfig.CANVAS_LAYER_LITTLE_GAME
coffin_stage = EventManager.get_stage("c03_coffin")
hover_knife.interacted.connect(_on_knife_interacted)
hover_note.interacted.connect(_on_note_interacted)
if coffin_stage == 0:
SceneManager.pop_center_notification("ui_center_notify_c03粘刀把")
elif coffin_stage == 1:
hover_knife.hide()
hover_note.freezing = false
elif coffin_stage == 2:
hover_knife.hide()
hover_note.hide()
func _on_knife_interacted() -> void:
hover_knife.hide()
hover_note.freezing = false
EventManager.set_stage("c03_coffin", 1)
SceneManager.enable_prop_item("prop_菜刀")
SceneManager.disable_prop_item("prop_浆糊")
SceneManager.disable_prop_item("prop_刀把")
### TODO 读纸条时,开始准备横版的呼吸声(呼吸声与棺材怪爬墙活动分在两个音频文件)
# 退出阅读马上进入横版,出现棺材怪爬墙活动的声音
func _read() -> void:
SceneManager.pop_debug_dialog_info("音效", "棺材怪呼吸的声音A")
SceneManager.pop_debug_dialog_info("音效", "棺材怪爬墙活动的声音B")
func _on_note_interacted() -> void:
hover_note.hide()
EventManager.set_stage("c03_coffin", 2)
SceneManager.enable_important_item("prop_沾血的纸条")
await SceneManager.get_inspector().quit_and_hidden
exit.emit(true)
func _monster_show() -> void:
SceneManager.lock_player()
var player = SceneManager.get_player()
player.set_facing_direction(Vector2.RIGHT)
# 惊讶
await SceneManager.pop_os_with_str("")
await Util.wait(2.0)
# 棺材怪开始行动
player.set_facing_direction(Vector2.LEFT)
var displaying_bloody_note := false
# 0: 需要浆糊 1: 需要刀把 2: 已完成
var knife_state := 0
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("cancel") and displaying_bloody_note:
if event.is_action_pressed("cancel") and coffin_stage == 0:
get_viewport().set_input_as_handled()
displaying_bloody_note = false
%"沾血的纸条".hide()
SceneManager.reset_temp_disabled_props()
exit.emit(false)
if event.is_action_pressed("interact") and coffin_stage == 0:
var prop = SceneManager.get_current_prop()
if knife_state == 0:
get_viewport().set_input_as_handled()
if prop == "prop_浆糊":
knife_state = 1
$"Sfx使用浆糊".play()
%"胶水".show()
SceneManager.disable_prop_item_temp("prop_浆糊")
else:
SceneManager.get_prop_hud().on_toggle_invalid_prop()
elif knife_state == 1:
get_viewport().set_input_as_handled()
if prop == "prop_刀把":
knife_state = 2
%"刀有柄".show()
SceneManager.disable_prop_item_temp("prop_刀把")
hover_knife.freezing = false
else:
SceneManager.get_prop_hud().on_toggle_invalid_prop()

View File

@ -1,18 +1,17 @@
[gd_scene load_steps=14 format=3 uid="uid://btmen4wc4uhhj"]
[gd_scene load_steps=13 format=3 uid="uid://btmen4wc4uhhj"]
[ext_resource type="Script" uid="uid://cj22vg4dn44qk" path="res://scene/ground/script/c03/s09_closeup棺材特写.gd" id="1_6v1ol"]
[ext_resource type="Texture2D" uid="uid://d03ja5ujdmyce" path="res://asset/art/scene/c03/s09_棺材房/棺材互动/棺材特写.png" id="2_6xi18"]
[ext_resource type="AudioStream" uid="uid://c57eu0dnr821k" path="res://asset/audio/sfx/交互/sfx_检阅道具.ogg" id="2_bgvp8"]
[ext_resource type="Texture2D" uid="uid://cbql1i4hblmt1" path="res://asset/art/ui/遮罩/inspect特写通用遮罩.png" id="2_f6kiq"]
[ext_resource type="PackedScene" uid="uid://dmysq4sxx8iqh" path="res://scene/entity/ux/content_inspector.tscn" id="3_6xi18"]
[ext_resource type="Script" uid="uid://rq6w1vuhuq1m" path="res://scene/entity/audio/sfx.gd" id="3_mobd5"]
[ext_resource type="Texture2D" uid="uid://bihf4gpj0r1jj" path="res://asset/art/scene/c03/s09_棺材房/棺材互动/棺材纸条.png" id="4_bgvp8"]
[ext_resource type="Texture2D" uid="uid://f186lvt5y2ql" path="res://asset/art/ui/遮罩/inspect背景遮罩.png" id="5_mobd5"]
[ext_resource type="AudioStream" uid="uid://has5y3j2yyp7" path="res://asset/audio/sfx/UI/纸条包裹钥匙.ogg" id="4_7k28m"]
[ext_resource type="Texture2D" uid="uid://ush0d2g8uj08" path="res://asset/art/scene/c03/s09_棺材房/棺材互动/带血的纸条.png" id="6_ok7al"]
[ext_resource type="Script" uid="uid://dpocj5al0rvai" path="res://ui/text_helper.gd" id="6_t53mt"]
[ext_resource type="PackedScene" uid="uid://bkk1rxx36ghrl" path="res://scene/entity/ux/hover_light_click_area.tscn" id="10_t53mt"]
[ext_resource type="Texture2D" uid="uid://bkn0cytl435yw" path="res://asset/art/scene/c03/s09_棺材房/棺材互动/刀.png" id="11_ok7al"]
[ext_resource type="Texture2D" uid="uid://cd76oamv0msug" path="res://asset/art/scene/c03/s09_棺材房/棺材互动/胶水.png" id="13_i378g"]
[ext_resource type="Texture2D" uid="uid://dhdo8nxthe0et" path="res://asset/art/scene/c03/s09_棺材房/棺材互动/刀把.png" id="13_ld65o"]
[ext_resource type="Script" uid="uid://0wjaho6qkg6s" path="res://manager/event_manager/event_binder.gd" id="16_6hali"]
[node name="Closeup棺材特写" type="CanvasLayer"]
script = ExtResource("1_6v1ol")
@ -23,13 +22,18 @@ stream = ExtResource("2_bgvp8")
bus = &"game_sfx"
script = ExtResource("3_mobd5")
[node name="Sfx使用浆糊" type="AudioStreamPlayer" parent="."]
stream = ExtResource("4_7k28m")
bus = &"game_sfx"
script = ExtResource("3_mobd5")
metadata/_custom_type_script = "uid://rq6w1vuhuq1m"
[node name="BG" type="TextureRect" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 0
texture = ExtResource("2_6xi18")
[node name="遮罩" type="TextureRect" parent="."]
@ -38,54 +42,10 @@ anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
texture = ExtResource("2_f6kiq")
[node name="沾血的纸条" type="TextureRect" parent="."]
unique_name_in_owner = true
visible = false
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 0
texture = ExtResource("4_bgvp8")
[node name="ContentInspector" parent="沾血的纸条" instance=ExtResource("3_6xi18")]
layout_mode = 1
[node name="遮罩" type="TextureRect" parent="沾血的纸条/ContentInspector"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
texture = ExtResource("5_mobd5")
[node name="Label" type="Label" parent="沾血的纸条/ContentInspector/遮罩"]
custom_minimum_size = Vector2(180, 0)
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -60.0
offset_top = -15.5
offset_right = 60.0
offset_bottom = 15.5
grow_horizontal = 2
grow_vertical = 2
text = "文开,近日几条丘八又上门,娘仍未告诉他们你在何处,如今世道乱,苟活不耻,保命为上,盼望与儿早日重逢。"
vertical_alignment = 1
autowrap_mode = 3
script = ExtResource("6_t53mt")
translation_key = "prop_沾血的纸条_说明"
[node name="Hover纸条" parent="." instance=ExtResource("10_t53mt")]
unique_name_in_owner = true
position = Vector2(250, 139)
freezing = true
@ -102,18 +62,34 @@ range_layer_max = 10
range_item_cull_mask = 4
texture = ExtResource("6_ok7al")
[node name="EventBinder" type="Node" parent="Hover纸条"]
script = ExtResource("16_6hali")
updater_event = &"c03_coffin"
updater_mode = "unfreezer"
metadata/_custom_type_script = "uid://0wjaho6qkg6s"
[node name="Hover刀" parent="." instance=ExtResource("10_t53mt")]
unique_name_in_owner = true
position = Vector2(286, 112)
freezing = true
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Hover刀"]
visible = false
polygon = PackedVector2Array(52.5, -32, 34.8, -32, -57.2, 12, -59.5, 12, -59.5, 24.2, -57.5, 25, -57.5, 26.6, -19.7, 32, 4, 32, 33.8, 22, 37.5, 22, 43.5, 17.5, 43.5, 13.5, 21, -4.4, 52.3, -24, 54.4, -24, 56, -27.3)
[node name="刀无柄" type="Sprite2D" parent="Hover刀"]
light_mask = 4
texture = ExtResource("11_ok7al")
[node name="胶水" type="Sprite2D" parent="Hover刀"]
unique_name_in_owner = true
visible = false
light_mask = 4
position = Vector2(33, -18)
texture = ExtResource("13_i378g")
[node name="刀有柄" type="Sprite2D" parent="Hover刀"]
unique_name_in_owner = true
visible = false
light_mask = 4
position = Vector2(32, -23)
texture = ExtResource("13_ld65o")
@ -123,3 +99,10 @@ energy = 3.0
range_layer_max = 10
range_item_cull_mask = 4
texture = ExtResource("11_ok7al")
[node name="EventBinder" type="Node" parent="Hover刀"]
script = ExtResource("16_6hali")
updater_event = &"c03_coffin"
updater_mode = "shower"
updater_stages = Array[int]([0])
metadata/_custom_type_script = "uid://0wjaho6qkg6s"

View File

@ -51,12 +51,11 @@ func intro():
func intro_finished():
SceneManager.disable_prop_item("prop_弹珠")
# 老虎钳 - 弹珠交换功能结束
EventManager.set_stage_if_greater(&"handnote_c02_hand_exchange", 2)
SceneManager.disable_prop_item_temp("prop_弹珠")
# SceneManager.disable_prop_item("prop_弹珠")
# 0:默认 1:寻找弹珠(老虎钳可以换弹珠) 2:给出弹珠 3:游戏结束(小猫纸片) 4:游戏结束(小猫离开)
# 放入弹珠,开始游戏
EventManager.set_stage(&"c02_ball_game_stage", 2)
# EventManager.set_stage(&"c02_ball_game_stage", 2)
var ball = pivot.get_child(0) as RigidBody2D
ball.angular_velocity = 20
animation_player.play("give_ball")
@ -255,6 +254,8 @@ func game_win() -> void:
animation_player.stop()
# 0:默认 1:寻找弹珠(老虎钳可以换弹珠) 2:给出弹珠 3:游戏结束(小猫纸片) 4:游戏结束(小猫离开)
EventManager.set_stage(&"c02_ball_game_stage", 3)
# 老虎钳 - 弹珠交换功能结束
EventManager.set_stage_if_greater(&"handnote_c02_hand_exchange", 2)
$"Sfx结尾小孩跑_耳鸣".global_play()
Util.shake_layer(self, 2.0)
# 弹珠雨

View File

@ -54,7 +54,7 @@ const HUD_FADE_DURATION = 0.3
var prop_containers: Array[CenterContainer] = []
var items_dict := {}
# 从配置文件加载 prop items
var item_config_res = preload("uid://b1vwhxctfhl5d") #item_description.dialogue
var item_config_res = preload("uid://b1vwhxctfhl5d") #item_description.dialogue
var path_prefix = "res://asset/art/prop/"
var cached_inventory_textures := {}
@ -97,18 +97,15 @@ func _ready() -> void:
display_prop.gui_input.connect(_on_prop_gui_input.bind(-1))
_load_items_config_to_dict("ImportantPropItems")
_load_items_config_to_dict("PropItems")
_reload_cache_and_realign_display()
_reload_all()
# 存档更新时,从存档加载 prop
ArchiveManager.archive_loaded.connect(_reload_all)
selecting_bg.modulate.a = 0.0
prop_scroll.scroll_horizontal = PROP_CONTAINER_X
props_bag_scroll.scroll_horizontal = 0.0
props_bag_scroll.custom_minimum_size.x = 0.0
# 存档更新时,从存档加载 prop
ArchiveManager.archive_loaded.connect(_reload_cache_and_realign_display)
# tween timer
timer.wait_time = display_time
timer.one_shot = true
@ -128,9 +125,17 @@ func _ready() -> void:
func _notification(what: int) -> void:
if what == NOTIFICATION_TRANSLATION_CHANGED and is_node_ready():
_load_items_config_to_dict("ImportantPropItems")
_load_items_config_to_dict("PropItems")
_reload_cache_and_realign_display()
_reload_all()
func _reload_all() -> void:
inventory = ArchiveManager.archive.prop_inventory
if inventory:
# 刷新 inventory 的 virtual回到 index 再进游戏时inventory 的 virtual 应该刷新)
inventory.virtual_enabled_items(true, true)
_load_items_config_to_dict("ImportantPropItems")
_load_items_config_to_dict("PropItems")
_reload_cache_and_realign_display()
func _load_items_config_to_dict(title: String):
@ -218,22 +223,24 @@ func _load_texture_cache() -> void:
if not inventory:
return
var virtual_items = inventory.virtual_enabled_items()
# 移除无效纹理
var keys_to_remove = []
for k in cached_inventory_textures:
if not k in inventory.enabled_items:
if not k in virtual_items:
keys_to_remove.append(k)
for k in keys_to_remove:
cached_inventory_textures.erase(k)
# 加载新纹理
for key in inventory.enabled_items:
for key in virtual_items:
if cached_inventory_textures.has(key):
continue
if not items_dict.has(key):
inventory.disable_item(key)
inventory.disable_item_tmp(key)
virtual_items = inventory.virtual_enabled_items()
printerr(
"PropHud _load_texture_cache: key not found in items_dict:", key, ". remove item."
)
@ -251,18 +258,15 @@ func _load_texture_cache() -> void:
print("Cache load prop texture key=", key)
cached_inventory_textures[key] = texture
# wrap index
if inventory.enabled_items.size() > 0:
inventory.current_index = wrapi(inventory.current_index, 0, inventory.enabled_items.size())
func _update_prop_display_with_texture():
if not inventory:
return
var virtual_items = inventory.virtual_enabled_items()
var key = ""
# 在没有道具时,展示空手 placeholder
if inventory.enabled_items.is_empty():
if virtual_items.is_empty():
display_prop.texture_normal = placeholder_texture
display_prop.size = Vector2(PROP_CONTROL_X, PROP_CONTROL_X)
display_prop.scale = Vector2(1.0, 1.0)
@ -284,9 +288,9 @@ func _update_prop_display_with_texture():
_update_select_mark()
# bag更新
for i in range(inventory.enabled_items.size()):
var id = wrapi(i, 0, inventory.enabled_items.size())
var k = inventory.enabled_items[id]
for i in range(virtual_items.size()):
var id = wrapi(i, 0, virtual_items.size())
var k = virtual_items[id]
var container = prop_containers[i]
var button = container.get_child(0).get_child(0) as TextureButton
_display_texture_by_key(button, k)
@ -300,7 +304,7 @@ func _update_select_mark():
if not is_instance_valid(select_mark):
select_mark = TextureRect.new()
select_mark.custom_minimum_size = Vector2(PROP_CONTAINER_X, PROP_CONTAINER_X)
# select_mark
# res://asset/art/ui/hud/select_mark.png
select_mark.texture = preload("uid://c0gjes4a8ou3b")
else:
var parent = select_mark.get_parent()
@ -380,10 +384,10 @@ func _on_prop_gui_input(event: InputEvent, id: int) -> void:
func _on_prop_inspected(id := 0) -> void:
if locked:
return
var virtual_items = inventory.virtual_enabled_items()
var prop_key = ""
if id >= 0 and id < inventory.enabled_items.size():
prop_key = inventory.enabled_items[id]
if id >= 0 and id < virtual_items.size():
prop_key = virtual_items[id]
else:
prop_key = inventory.current_item_key()
@ -404,7 +408,8 @@ func _on_prop_pressed(id := 0) -> void:
focus_mode = FOCUS_ALL
grab_focus()
if id >= 0 and id < inventory.enabled_items.size():
var virtual_items = inventory.virtual_enabled_items()
if id >= 0 and id < virtual_items.size():
inventory.current_index = id
_update_prop_display_with_texture()
@ -589,13 +594,9 @@ func inspect_item(prop_key: String, display_obtained := true, as_important_item
if as_important_item:
var content = get_item_description(prop_key)
var wide = len(content) > 150
inspector.pop_standard_inspection(
texture, null, content, false, wide
)
inspector.pop_standard_inspection(texture, null, content, false, wide)
else:
inspector.pop_prop_inspection(
prop_key, texture, display_obtained
)
inspector.pop_prop_inspection(prop_key, texture, display_obtained)
func disable_prop_item(prop_key: String) -> void:
@ -605,16 +606,33 @@ func disable_prop_item(prop_key: String) -> void:
_reload_cache_and_realign_display()
# 临时禁用 prop, 延迟写入(真正 disable_prop_item 的时候写入)
func disable_prop_item_temp(prop_key: String) -> void:
if not inventory or not prop_key:
return
inventory.disable_item_temp(prop_key)
_reload_cache_and_realign_display()
# 恢复临时禁用的 prop
func reset_temp_disabled_props() -> void:
if not inventory:
return
inventory.virtual_enabled_items(true, true)
_reload_cache_and_realign_display()
func _align_container_size() -> void:
if not inventory:
return
var virtual_items = inventory.virtual_enabled_items()
# 添加新容器
while inventory.enabled_items.size() > prop_containers.size():
while virtual_items.size() > prop_containers.size():
append_prop_container()
# 删除多余容器
while inventory.enabled_items.size() < prop_containers.size():
while virtual_items.size() < prop_containers.size():
remove_prop_container()
if displaying:
@ -654,13 +672,15 @@ func remove_prop_container() -> void:
props_bag.remove_child(container)
container.queue_free()
var invalid_sfx = preload("uid://dph8v3v5mq1xl")
func on_toggle_invalid_prop():
func on_toggle_invalid_prop(play_sfx := true):
if not inventory or not inventory.current_item_key():
return
if GlobalConfig.DEBUG:
print("使用无效道具. invalid_prop shake. current prop:", inventory.current_item_key())
if play_sfx:
AudioManager.play_sfx(invalid_sfx)
if shake_tween and shake_tween.is_running():
shake_tween.kill()

View File

@ -120,6 +120,7 @@ func pop_standard_inspection(
content_label.text = inspection_note.replace("{br}", "\n").strip_edges()
var tween = create_tween()
tween.tween_property(full_texture, "modulate:a", 1.0, 0.15)
tween.parallel().tween_property(prop_bg, "modulate:a", 1.0, 0.15)
tip_label.text = tip_cover
_blink_label()

View File

@ -7,10 +7,11 @@ signal current_item_changed(prop_key: String)
@export var current_index := 0:
set(val):
if current_index != val:
val = wrapi(val, 0, enabled_items.size())
# virtual id
val = wrapi(val, 0, virtual_items.size())
current_index = val
if enabled_items.size() > 0:
current_item_changed.emit(enabled_items[current_index])
if virtual_items.size() > 0:
current_item_changed.emit(virtual_items[current_index])
else:
current_item_changed.emit("")
# 重要物品,不可丢弃,在背包可见
@ -22,8 +23,11 @@ signal current_item_changed(prop_key: String)
@export var xdie_enabled_items := [] as Array[String]
@export var xxdie_enabled_items := [] as Array[String]
@export var xxxdie_enabled_items := [] as Array[String]
var enabled_items := [] as Array[String]
var enabled_items: Array[String]
var virtual_items: Array[String]
# virtual
var disabled_tmp_props := [] as Array[String]
func checkout(character: String):
# @export_enum("吕萍", "吕萍爬行", "吕萍带小猫", "吕萍推柜子", "小小蝶", "盒子猫", "小小小蝶") var character := "吕萍":
@ -35,6 +39,7 @@ func checkout(character: String):
enabled_items = xdie_enabled_items
else:
enabled_items = default_enabled_items
virtual_items = virtual_enabled_items(true)
func enable_important_item(prop_key: String) -> void:
@ -44,34 +49,56 @@ func enable_important_item(prop_key: String) -> void:
func has_prop(prop_key: String) -> bool:
return enabled_items.has(prop_key)
if not virtual_items.has(prop_key):
return false
return not disabled_tmp_props.has(prop_key)
# return current virtual item key
func current_item_key() -> String:
if enabled_items.size() == 0:
if virtual_items.is_empty():
return ""
return enabled_items[current_index]
current_index = wrapi(current_index, 0, virtual_items.size())
return virtual_items[current_index]
func enable_item(prop_key: String, inspect := true) -> void:
# 重复 enable 无负面影响
if not enabled_items.has(prop_key):
enabled_items.append(prop_key)
# 消除临时禁用
disabled_tmp_props.erase(prop_key)
virtual_items = virtual_enabled_items(true)
# 如果 inspect, 则直接选中为当前条目
if inspect:
current_index = enabled_items.find(prop_key)
current_index = virtual_items.find(prop_key)
func disable_item(prop_key: String) -> void:
disabled_tmp_props.erase(prop_key)
# if enabled_items.has(prop_key):
enabled_items.erase(prop_key)
virtual_items = virtual_enabled_items(true)
# wrap index
current_index = clampi(current_index, 0, enabled_items.size())
current_index = clampi(current_index, 0, virtual_items.size())
func disable_item_temp(prop_key: String) -> void:
disabled_tmp_props.append(prop_key)
virtual_items = virtual_enabled_items(true)
# return true if the index changed
func index_wrap_add(delta: int) -> bool:
func index_wrap_add(delta: int) -> void:
# auto wrapped in setter
current_index += delta
return not enabled_items.is_empty()
current_index = wrapi(current_index + delta, 0, virtual_items.size())
func virtual_enabled_items(refresh := false, clear_tmps := false) -> Array[String]:
if clear_tmps:
disabled_tmp_props.clear()
if refresh:
virtual_items = enabled_items.duplicate()
for k in disabled_tmp_props:
virtual_items.erase(k)
return virtual_items