diff --git a/README.md b/README.md
index b816bb8d..dcd50d41 100644
--- a/README.md
+++ b/README.md
@@ -94,6 +94,41 @@ GroundLoader 加载/切换 Ground 时,分为上下两段转场:
3. 三种模式:default(通道);opened(打开的门);locked(锁定的门);对应不同图标与操作音效
4. 锁定的门可以配置启用钥匙(prop_key),可在使用后自动消耗该钥匙
+### AimationPlayer Tool Button 说明
+
+#### 存档 Tool Button
+
+
+
+- 全局 ArchiveManager 与 EventManager 的存档变量都在 Debug Global Data 中
+- 场景本地状态在 Debug Ground Data 中
+
+#### 自动生成变量名 Tool Button
+
+
+
+```py
+func _parse_node(ground_node, node:Node, existing_vars:Dictionary, code_lines:PackedStringArray, created_vars):
+ # 0. filter unique mark
+ # 1. create `var snake_case_variable_name = $"../xx/yy/NodeName"`
+ # 2. create `var snake_case_variable_name = $"../xx/yy/NodeName"`
+ if not node.unique_name_in_owner or ground_node.get_node_or_null("%"+node.name) == null:
+ # 只读取 unique 标记过的节点; node.unique_name_in_owner 参数不可靠,需要实际检查
+ return
+ var var_name = node.name.to_snake_case()
+ if existing_vars.has(var_name):
+ return
+ created_vars.append(var_name)
+ code_lines.insert(region_start_id + 1, "var " + var_name + ": "+ str(node.get_class()))
+ func_line_id += 1
+ code_lines.insert(func_line_id + 1, "\t" + var_name +" = %\"" + node.name +"\"")
+```
+
+- 只读取 unique 标记过的变量(%)
+
+## 线索笔记说明
+
+
## 存档结构
diff --git a/asset/art/scene/c03/引导纸人/指引纸人1.png b/asset/art/scene/c03/引导纸人/指引纸人1.png
new file mode 100644
index 00000000..1d9b3b92
Binary files /dev/null and b/asset/art/scene/c03/引导纸人/指引纸人1.png differ
diff --git a/asset/art/scene/c03/引导纸人/指引纸人1.png.import b/asset/art/scene/c03/引导纸人/指引纸人1.png.import
new file mode 100644
index 00000000..fe31aa59
--- /dev/null
+++ b/asset/art/scene/c03/引导纸人/指引纸人1.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bxernv6qyitdn"
+path="res://.godot/imported/指引纸人1.png-9c6724f5e420661923d6ce5fc0371d37.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://asset/art/scene/c03/引导纸人/指引纸人1.png"
+dest_files=["res://.godot/imported/指引纸人1.png-9c6724f5e420661923d6ce5fc0371d37.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
diff --git a/asset/art/scene/c03/引导纸人/指引纸人2.png b/asset/art/scene/c03/引导纸人/指引纸人2.png
new file mode 100644
index 00000000..f896689e
Binary files /dev/null and b/asset/art/scene/c03/引导纸人/指引纸人2.png differ
diff --git a/asset/art/scene/c03/引导纸人/指引纸人2.png.import b/asset/art/scene/c03/引导纸人/指引纸人2.png.import
new file mode 100644
index 00000000..165c2ac5
--- /dev/null
+++ b/asset/art/scene/c03/引导纸人/指引纸人2.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://ci0jxl74wek65"
+path="res://.godot/imported/指引纸人2.png-e76bee3e8ba30b0c12be6afd2445d22d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://asset/art/scene/c03/引导纸人/指引纸人2.png"
+dest_files=["res://.godot/imported/指引纸人2.png-e76bee3e8ba30b0c12be6afd2445d22d.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
diff --git a/asset/art/scene/c03/引导纸人/指引纸人3.png b/asset/art/scene/c03/引导纸人/指引纸人3.png
new file mode 100644
index 00000000..17390ae5
Binary files /dev/null and b/asset/art/scene/c03/引导纸人/指引纸人3.png differ
diff --git a/asset/art/scene/c03/引导纸人/指引纸人3.png.import b/asset/art/scene/c03/引导纸人/指引纸人3.png.import
new file mode 100644
index 00000000..ad3c1006
--- /dev/null
+++ b/asset/art/scene/c03/引导纸人/指引纸人3.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b7t2sfe5ugtsc"
+path="res://.godot/imported/指引纸人3.png-a2f79d004d8ba58ac69beea4f0ec1fc7.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://asset/art/scene/c03/引导纸人/指引纸人3.png"
+dest_files=["res://.godot/imported/指引纸人3.png-a2f79d004d8ba58ac69beea4f0ec1fc7.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
diff --git a/asset/art/scene/c03/引导纸人/指引纸人4.png b/asset/art/scene/c03/引导纸人/指引纸人4.png
new file mode 100644
index 00000000..03f33d59
Binary files /dev/null and b/asset/art/scene/c03/引导纸人/指引纸人4.png differ
diff --git a/asset/art/scene/c03/引导纸人/指引纸人4.png.import b/asset/art/scene/c03/引导纸人/指引纸人4.png.import
new file mode 100644
index 00000000..889fbbc5
--- /dev/null
+++ b/asset/art/scene/c03/引导纸人/指引纸人4.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bxmc7pas3b6wa"
+path="res://.godot/imported/指引纸人4.png-6f6d31a0e21878e6d47c3a492743b6a4.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://asset/art/scene/c03/引导纸人/指引纸人4.png"
+dest_files=["res://.godot/imported/指引纸人4.png-6f6d31a0e21878e6d47c3a492743b6a4.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
diff --git a/asset/art/ui/note/笔记线索_第一章.json b/asset/art/ui/note/笔记线索_第一章.json
new file mode 100644
index 00000000..b2324706
--- /dev/null
+++ b/asset/art/ui/note/笔记线索_第一章.json
@@ -0,0 +1,37 @@
+{ "frames": {
+ "笔记线索_第一章.png": {
+ "frame": { "x": 0, "y": 0, "w": 1790, "h": 1136 },
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": { "x": 0, "y": 0, "w": 1790, "h": 1136 },
+ "sourceSize": { "w": 1790, "h": 1136 },
+ "duration": 100
+ }
+ },
+ "meta": {
+ "app": "https://www.aseprite.org/",
+ "version": "1.3.8.1-arm64",
+ "format": "RGBA8888",
+ "size": { "w": 1790, "h": 1136 },
+ "scale": "1",
+ "slices": [
+ { "name": "c02_meat_knockDoor", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 226, "y": 253, "w": 101, "h": 53 } }] },
+ { "name": "c02_hand_exchange", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 49, "y": 184, "w": 163, "h": 116 } }] },
+ { "name": "c02_musicbox_needPuppet", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 86, "y": 317, "w": 102, "h": 58 } }] },
+ { "name": "c02_gate_chain", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 426, "y": 333, "w": 89, "h": 70 } }] },
+ { "name": "c02_split_illusionSpace", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 482, "y": 170, "w": 199, "h": 89 } }] },
+ { "name": "c02_meat_stopMouse", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 364, "y": 77, "w": 108, "h": 59 } }] },
+ { "name": "c02_map_1Left", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 872, "y": 88, "w": 517, "h": 383 } }] },
+ { "name": "c02_map_1Right", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 1440, "y": 278, "w": 283, "h": 195 } }] },
+ { "name": "c02_map_2", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 1324, "y": 714, "w": 437, "h": 371 } }] },
+ { "name": "c02_shoe_giveToMouce", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 1186, "y": 780, "w": 121, "h": 79 } }] },
+ { "name": "c02_hand_requireCoin", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 1185, "y": 867, "w": 112, "h": 75 } }] },
+ { "name": "c02_xchan_sheKnowsMe", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 882, "y": 571, "w": 462, "h": 93 } }] },
+ { "name": "c02_road_address", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 1381, "y": 563, "w": 391, "h": 97 } }] },
+ { "name": "c02_xchan_giveHerPuppet", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 1466, "y": 166, "w": 168, "h": 49 } }] },
+ { "name": "c02_list_namesAndGoal", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 55, "y": 548, "w": 615, "h": 283 } }] },
+ { "name": "c02_xchan_isSheGohst", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 93, "y": 916, "w": 200, "h": 127 } }] },
+ { "name": "c02_blotOut", "color": "#0000ffff", "keys": [{ "frame": 0, "bounds": {"x": 378, "y": 931, "w": 97, "h": 74 } }] }
+ ]
+ }
+}
diff --git a/asset/art/ui/note/笔记线索_第一章.png b/asset/art/ui/note/笔记线索_第一章.png
new file mode 100644
index 00000000..ece154e3
Binary files /dev/null and b/asset/art/ui/note/笔记线索_第一章.png differ
diff --git a/asset/art/ui/note/笔记线索_第一章.png.import b/asset/art/ui/note/笔记线索_第一章.png.import
new file mode 100644
index 00000000..4927eb86
--- /dev/null
+++ b/asset/art/ui/note/笔记线索_第一章.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://drijblepnhhsw"
+path="res://.godot/imported/笔记线索_第一章.png-5a92d0c0d981e032650977ec75646448.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://asset/art/ui/note/笔记线索_第一章.png"
+dest_files=["res://.godot/imported/笔记线索_第一章.png-5a92d0c0d981e032650977ec75646448.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
diff --git a/asset/dialogue/item_description.csv b/asset/dialogue/item_description.csv
index a3270a42..aa3c6360 100644
--- a/asset/dialogue/item_description.csv
+++ b/asset/dialogue/item_description.csv
@@ -142,6 +142,8 @@ c02_s03_掉鞋子,怎么天上掉了个小鞋子下来?,,,,,
c02_s03_铁门,被铁链锁住了,,,,,
c02_偷听李癞对话后,三快三慢?是和那个肉铺老板交流的暗号吗?,,,,,
c02_柜子可放置区域,这里之前放着的东西好像被人挪走了?,,,,,
+c02_保卫科看到小蝉,那是....一个小女孩吗?,,,,,
+c02_保卫科小蝉消失,诶?,,,,,
c02_保卫科花名册os,登记簿?
刚才那个小孩在上面写了些什么,,,,,
c02_保卫科花名册首次互动结束,3012?上面有我的名字,看来确实是这里...
先去三楼看看吧,,,,,
c02_保卫科祭台os,祭台是专门供奉这只大老鼠的?,,,,,
@@ -159,6 +161,7 @@ c02_一楼死老鼠,老鼠被粘住死掉了。,,,,,
c02_获得木头人偶,怎么回事...头...好痛,,,,,
c02_获得小猫玩具,我的头,又开始痛了,,,,,
c02_小蝉头套文字,吕萍阿姨,我不想死,求你...帮帮我,,,,,
+c02_互动小蝉头套,!!!,,,,,
c02_敲门_肉掉落,楼道有东西掉下来了?,,,,,
c02_敲门_老鼠叼肉,刚刚这里有块肉不见了?,,,,,
c02_锡箔换小鞋子,另一只小鞋子。,,,,,
diff --git a/asset/dialogue/item_description.dialogue b/asset/dialogue/item_description.dialogue
index 6024ba72..399627aa 100644
--- a/asset/dialogue/item_description.dialogue
+++ b/asset/dialogue/item_description.dialogue
@@ -201,6 +201,8 @@
三快三慢?是和那个肉铺老板交流的暗号吗? [ID:c02_偷听李癞对话后]
这里之前放着的东西好像被人挪走了? [ID:c02_柜子可放置区域]
#保卫科
+那是....一个小女孩吗? [ID:c02_保卫科看到小蝉]
+诶? [ID:c02_保卫科小蝉消失]
登记簿?
刚才那个小孩在上面写了些什么 [ID:c02_保卫科花名册os]
3012?上面有我的名字,看来确实是这里...
先去三楼看看吧[ID:c02_保卫科花名册首次互动结束]
祭台是专门供奉这只大老鼠的? [ID:c02_保卫科祭台os]
diff --git a/image-1.png b/image-1.png
new file mode 100644
index 00000000..e56b688b
Binary files /dev/null and b/image-1.png differ
diff --git a/image-1.png.import b/image-1.png.import
new file mode 100644
index 00000000..aa5e8a6d
--- /dev/null
+++ b/image-1.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://btdvb8jar6n4c"
+path="res://.godot/imported/image-1.png-dbab14dd40403047ee602a1bb16c5f26.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://image-1.png"
+dest_files=["res://.godot/imported/image-1.png-dbab14dd40403047ee602a1bb16c5f26.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
diff --git a/image.png b/image.png
new file mode 100644
index 00000000..6b7d7147
Binary files /dev/null and b/image.png differ
diff --git a/image.png.import b/image.png.import
new file mode 100644
index 00000000..ee0f22bc
--- /dev/null
+++ b/image.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b7qb1le0xqy10"
+path="res://.godot/imported/image.png-2de165adb17dfebcee8a7cd6c9833936.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://image.png"
+dest_files=["res://.godot/imported/image.png-2de165adb17dfebcee8a7cd6c9833936.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
diff --git a/scene/entity/ambush.gd b/scene/entity/ambush.gd
index cb4f5cee..79ddb5c6 100644
--- a/scene/entity/ambush.gd
+++ b/scene/entity/ambush.gd
@@ -33,7 +33,7 @@ signal sign_mark_offset_updated
@export var on_first_enter_tree := false
@export var cooldown_time := 0.5
@export var lock_player_on_playing_dialogue = true
-var hook_animation = ""
+@export var global_method := ""
@export var hook_os_key := ""
@export_enum("c01", "c02", "c03", "c04", "c05", "c06") var hook_dialogue_res = "c01":
set(val):
@@ -54,8 +54,8 @@ var hook_animation = ""
if is_node_ready() and Engine.is_editor_hint():
notify_property_list_changed()
var hook_dialogue_title := ""
+var hook_animation = ""
var hook_method := ""
-@export var global_method := ""
var dialogue_c01 = preload("res://asset/dialogue/c01.dialogue")
var dialogue_c02 = preload("res://asset/dialogue/c02.dialogue")
diff --git a/scene/entity/inspectable.gd b/scene/entity/inspectable.gd
index 4e2558e3..e8a142f5 100644
--- a/scene/entity/inspectable.gd
+++ b/scene/entity/inspectable.gd
@@ -1,5 +1,6 @@
@tool
-extends Sprite2D
+class_name Inspectable2D extends Sprite2D
+
signal start_inspecting
signal quit_inspecting
diff --git a/scene/ground/scene/animation_root.gd b/scene/ground/scene/animation_root.gd
index 232332e3..1597dd15 100644
--- a/scene/ground/scene/animation_root.gd
+++ b/scene/ground/scene/animation_root.gd
@@ -22,7 +22,7 @@ var dialogue_c06 := preload("res://asset/dialogue/c06.dialogue") as DialogueReso
@export var debug_ground_data: Dictionary[String, Variant] = {}
@export var auto_reset_on_debug_restarting := false
-
+@export_tool_button("auto reference") var auto_ref = _auto_setup_node_reference
var oneshot_animation := ""
var ground_archive: GroundArchive
var ground: Ground2D
@@ -59,12 +59,17 @@ func _ready() -> void:
data[key] = archive_data[key]
# 等待 DeployLayer 先加载完成
if not ground.is_node_ready():
+ ground.ready.connect(_setup_node_reference)
ground.ready.connect(_on_ground_ready)
else:
+ _setup_node_reference()
_on_ground_ready()
ready.connect(_on_ready)
+func _setup_node_reference() -> void:
+ pass
+
func _on_ground_ready() -> void:
pass
@@ -159,9 +164,9 @@ func _reset_archive() -> void:
var getter_regx = RegEx.create_from_string(r'get_global_value\(.?"(.+)"') as RegEx
var properties = {}
for setter_match in setter_regx.search_all(code):
- properties[(setter_match as RegExMatch).get_string(1)] = true
+ properties[setter_match.get_string(1)] = true
for getter_match in getter_regx.search_all(code):
- properties[(getter_match as RegExMatch).get_string(1)] = true
+ properties[getter_match.get_string(1)] = true
for p in properties.keys():
if debug_global_data.get(p) == null:
debug_global_data[p] = false
@@ -184,11 +189,11 @@ func _reset_archive() -> void:
)
var events = {}
for event_match in event_setter_regx.search_all(code):
- events[(event_match as RegExMatch).get_string(1)] = true
+ events[event_match.get_string(1)] = true
for event_match in event_set_greater_regx.search_all(code):
- events[(event_match as RegExMatch).get_string(1)] = true
+ events[event_match.get_string(1)] = true
for event_match in event_getter_regx.search_all(code):
- events[(event_match as RegExMatch).get_string(1)] = true
+ events[event_match.get_string(1)] = true
# 遍历 ".." 下所有节点,找到属于 Event2D 的节点
_find_event2d(events, ground)
for e in events.keys():
@@ -200,7 +205,7 @@ func _reset_archive() -> void:
notify_property_list_changed()
-func _setup_ground_data(g_data: Dictionary[String, Variant], node: Node):
+func _setup_ground_data(g_data: Dictionary, node: Node):
if not node:
return
for child in node.get_children():
@@ -225,3 +230,88 @@ func _find_event2d(events: Dictionary, node: Node) -> void:
if child.pre_event != &"":
events[child.pre_event] = true
_find_event2d(events, child)
+
+
+var func_line_id := -1
+var region_start_id := -1
+var region_end_id := -1
+# #region node_reference
+# #endregion
+# # 读取设置变量名
+# func _setup_node_reference() -> void:
+# pass
+func _auto_setup_node_reference():
+ var script = get_script() as GDScript
+ if not script:
+ printerr("script not found")
+ return
+ var code_lines := script.source_code.split("\n") as PackedStringArray
+ func_line_id = -1
+ region_start_id = -1
+ region_end_id = -1
+ for i in len(code_lines):
+ var line = code_lines[i]
+ if line.begins_with("func _setup_node_reference()"):
+ func_line_id = i
+ elif line.begins_with("#region node_reference"):
+ region_start_id = i
+ elif region_start_id != -1 and region_end_id == -1 and line.begins_with("#endregion"):
+ region_end_id = i
+ if func_line_id == -1:
+ printerr("func _setup_node_reference() not found")
+ return
+ if region_start_id == -1:
+ print("#region node_reference not found, creat region upon func_line..")
+ region_start_id = func_line_id - 2
+ func_line_id += 1
+ code_lines.insert(region_start_id, "#region node_reference")
+ if region_end_id == -1:
+ region_end_id = region_start_id + 1
+ code_lines.insert(region_end_id, "#endregion")
+ func_line_id += 1
+ print("auto reference start, region_start_id=", region_start_id, " region_end_id=", region_end_id)
+ var existing_vars = _read_existing_vars(code_lines)
+ var created_vars = []
+ _traverse_nodes(get_node(".."), get_node(".."), existing_vars, code_lines, created_vars)
+ script.source_code = "\n".join(code_lines)
+ ResourceSaver.save(script)
+ print("auto reference done.")
+ print("skipped existing_vars:", existing_vars.size(), existing_vars)
+ print("created_vars:", created_vars.size(), created_vars)
+
+
+func _read_existing_vars(code_lines: PackedStringArray) -> Dictionary:
+ var existing_vars = {}
+ for i in range(region_start_id + 1, region_end_id):
+ var line = code_lines[i]
+ if line.begins_with("var "):
+ var var_name = line.split(" ")[1].split(":")[0].strip_escapes()
+ if var_name:
+ existing_vars[var_name] = true
+ return existing_vars
+
+
+func _traverse_nodes(ground_node, node: Node, existing_vars: Dictionary, code_lines: PackedStringArray, created_vars):
+ if node:
+ _parse_node(ground_node, node, existing_vars, code_lines, created_vars)
+ for child in node.get_children():
+ _traverse_nodes(ground_node, child, existing_vars, code_lines, created_vars)
+
+
+func _parse_node(ground_node, node:Node, existing_vars:Dictionary, code_lines:PackedStringArray, created_vars):
+ # 0. filter unique mark
+ # 1. create `var snake_case_variable_name = $"../xx/yy/NodeName"`
+ # 2. create `var snake_case_variable_name = $"../xx/yy/NodeName"`
+ if not node.unique_name_in_owner or ground_node.get_node_or_null("%"+node.name) == null:
+ # 只读取 unique 标记过的节点; node.unique_name_in_owner 参数不可靠,需要实际检查
+ return
+ var var_name = node.name.to_snake_case()
+ if existing_vars.has(var_name):
+ return
+ created_vars.append(var_name)
+ code_lines.insert(region_start_id + 1, "var " + var_name + ": "+ str(node.get_class()))
+ func_line_id += 1
+ code_lines.insert(func_line_id + 1, "\t" + var_name +" = %\"" + node.name +"\"")
+
+
+
diff --git a/scene/ground/scene/c02/s02_过道.tscn b/scene/ground/scene/c02/s02_过道.tscn
index f40d7241..6974d6d3 100644
--- a/scene/ground/scene/c02/s02_过道.tscn
+++ b/scene/ground/scene/c02/s02_过道.tscn
@@ -110,6 +110,7 @@ debug_ground_data = Dictionary[String, Variant]({
"interacted_times": 0
}
})
+auto_ref_type = PackedStringArray("Ambush2D", "Inspectable2D", "Closeup2D", "Note2D", "Interactable2D", "Pickable2D", "Event2D", "Sprite2D", "ProAnimatedSprite2D", "AnimatedSprite2D", "Sfx", "Sfx2D", "VibeSfx", "PointLight2D", "Area2D", "MainPlayer", "CameraFocusMarker")
oneshot_animation = ""
[node name="冷飕飕Sfx" parent="Ground/AnimationPlayer" index="0" instance=ExtResource("3_fvldj")]
diff --git a/scene/ground/scene/c02/s03_院子.tscn b/scene/ground/scene/c02/s03_院子.tscn
index 81393353..d8ace5fa 100644
--- a/scene/ground/scene/c02/s03_院子.tscn
+++ b/scene/ground/scene/c02/s03_院子.tscn
@@ -355,6 +355,7 @@ debug_ground_data = Dictionary[String, Variant]({
"interacted_times": 0
}
})
+auto_ref_type = PackedStringArray("Ambush2D", "Inspectable2D", "Closeup2D", "Note2D", "Interactable2D", "Pickable2D", "Event2D", "Sprite2D", "ProAnimatedSprite2D", "AnimatedSprite2D", "Sfx", "Sfx2D", "VibeSfx", "PointLight2D", "Area2D", "MainPlayer", "CameraFocusMarker")
oneshot_animation = ""
[node name="Sfx闷雷" type="AudioStreamPlayer" parent="Ground/AnimationPlayer" index="0"]
diff --git a/scene/ground/scene/c02/s04_保卫科.gd b/scene/ground/scene/c02/s04_保卫科.gd
index f9ba39d8..50918584 100644
--- a/scene/ground/scene/c02/s04_保卫科.gd
+++ b/scene/ground/scene/c02/s04_保卫科.gd
@@ -12,19 +12,43 @@ func _ready() -> void:
if Engine.is_editor_hint():
return
-
-var closeup_tin_coin
-var little_hand
+#region node_reference
+var closeup花名册: Sprite2D
+var closeup折锡纸: Sprite2D
+var footstep_audio_player: AudioStreamPlayer
+var directional_light_2d: DirectionalLight2D
+var player_line_2d: Line2D
+var fg_sprite_2d: Sprite2D
+var parallax_foreground: ParallaxBackground
+var camera_focus_marker: Camera2D
+var main_player: CharacterBody2D
+var deploy_layer: Node2D
+var bg_sprite_2d: Sprite2D
+var player_reenter_lock: Node
+#endregion
-func _on_ground_ready() -> void:
- closeup_tin_coin = $"../DeployLayer/Closeup折锡纸" as Closeup2D
- if not ArchiveManager.get_global_value(&"c02_tin_coin_taken"):
- closeup_tin_coin.exit.connect(_on_closeup_tin_coin_exited)
-
- var closeup_book = $"../DeployLayer/Closeup花名册" as Closeup2D
- if closeup_book.icount == 0:
- closeup_book.exit.connect(_on_first_read, CONNECT_ONE_SHOT)
+func _setup_node_reference() -> void:
+ closeup花名册 = %"Closeup花名册"
+ closeup折锡纸 = %"Closeup折锡纸"
+ footstep_audio_player = %"FootstepAudioPlayer"
+ directional_light_2d = %"DirectionalLight2D"
+ player_line_2d = %"PlayerLine2D"
+ fg_sprite_2d = %"FGSprite2D"
+ parallax_foreground = %"ParallaxForeground"
+ camera_focus_marker = %"CameraFocusMarker"
+ main_player = %"MainPlayer"
+ deploy_layer = %"DeployLayer"
+ bg_sprite_2d = %"BGSprite2D"
+ player_reenter_lock = %"PlayerReenterLock"
+
+
+# func _on_ground_ready() -> void:
+# if not ArchiveManager.get_global_value(&"c02_tin_coin_taken"):
+# closeup折锡纸.exit.connect(_on_closeup_tin_coin_exited)
+
+# if closeup花名册.icount == 0:
+# closeup花名册.exit.connect(_on_first_read, CONNECT_ONE_SHOT)
func _on_closeup_tin_coin_exited(arg = null):
@@ -37,3 +61,8 @@ func _on_closeup_tin_coin_exited(arg = null):
func _on_first_read(_arg) -> void:
SceneManager.pop_os_with_str("c02_保卫科花名册首次互动结束")
+
+
+func xiaochan_disappear():
+ #TODO
+ SceneManager.pop_os_with_str("c02_保卫科小蝉消失")
diff --git a/scene/ground/scene/c02/s04_保卫科.tscn b/scene/ground/scene/c02/s04_保卫科.tscn
index 5c2fd132..da9547fd 100644
--- a/scene/ground/scene/c02/s04_保卫科.tscn
+++ b/scene/ground/scene/c02/s04_保卫科.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=22 format=3 uid="uid://bivc5cdap370p"]
+[gd_scene load_steps=23 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"]
@@ -11,19 +11,26 @@
[ext_resource type="Texture2D" uid="uid://cs14llkvr3fg8" path="res://asset/art/scene/c02/s04_保卫科/弹珠墙面涂鸦提示.png" id="6_gk1h4"]
[ext_resource type="Texture2D" uid="uid://baffg10ne8hu8" path="res://asset/art/scene/c02/s04_保卫科/fg_前景.png" id="6_tio43"]
[ext_resource type="PackedScene" uid="uid://b454ap241bshk" path="res://scene/ground/script/c02/折锡纸.tscn" id="7_fvlg0"]
+[ext_resource type="PackedScene" uid="uid://bnf3lkcbpx1ar" path="res://scene/entity/ambush.tscn" id="7_ypth3"]
[ext_resource type="PackedScene" uid="uid://cdf2qe8l7323i" path="res://scene/ground/script/c02/老鼠精画像.tscn" id="8_cm3g6"]
-[ext_resource type="PackedScene" uid="uid://cxw5rovg5mu1a" path="res://scene/ground/script/c02/s00_煤油灯.tscn" id="8_wpvss"]
[ext_resource type="Texture2D" uid="uid://ch6uf4qi1i0h2" path="res://asset/art/scene/c02/s03_公寓一楼院子/光晕/光晕3.png" id="9_a43aq"]
[ext_resource type="PackedScene" uid="uid://xovlfee503a4" path="res://scene/ground/script/c02/小手讨东西.tscn" id="10_a43aq"]
-[ext_resource type="Texture2D" uid="uid://dtmd13ktss5hk" path="res://asset/art/scene/c02/s03_公寓一楼院子/地面物品反光/地反光5.png" id="10_svuj3"]
[ext_resource type="Texture2D" uid="uid://v6q6ao6fiqm1" path="res://asset/art/scene/c02/s04_保卫科/e_老鼠画像横板.png" id="11_ffvrp"]
+[ext_resource type="SpriteFrames" uid="uid://3nas025c2c5u" path="res://asset/art/gif/c02_杂项/c02_杂项_frames.tres" id="13_xy3nq"]
[ext_resource type="PackedScene" uid="uid://ci5anaxsa1apl" path="res://scene/entity/inspectable.tscn" id="19_k74x7"]
[ext_resource type="Texture2D" uid="uid://day38kany2gmr" path="res://asset/art/scene/c02/小蝉寻人启事/e_寻人启事完整.png" id="20_g8amr"]
[ext_resource type="Texture2D" uid="uid://ce3d785v5lxg2" path="res://asset/art/scene/c02/小蝉寻人启事/ux_寻人启事完整.png" id="21_cq2m4"]
-[sub_resource type="RectangleShape2D" id="RectangleShape2D_gk1h4"]
-resource_local_to_scene = true
-size = Vector2(20, 70)
+[sub_resource type="Gradient" id="Gradient_l338h"]
+offsets = PackedFloat32Array(0, 0.67029, 1)
+colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_ivr1s"]
+gradient = SubResource("Gradient_l338h")
+width = 200
+height = 200
+fill = 1
+fill_from = Vector2(0.5, 0.5)
[node name="S04" type="Node2D"]
@@ -93,59 +100,59 @@ target_portal = "1"
[node name="portal_right" parent="Ground/DeployLayer" index="1"]
position = Vector2(551, 22)
-[node name="涂鸦提示" type="Sprite2D" parent="Ground/DeployLayer" index="2"]
+[node name="Ambush进门看到小蝉" parent="Ground/DeployLayer" index="2" instance=ExtResource("7_ypth3")]
+position = Vector2(72, 51)
+hook_os_key = "c02_保卫科看到小蝉"
+hook_method = "xiaochan_disappear"
+
+[node name="涂鸦提示" type="Sprite2D" parent="Ground/DeployLayer" index="3"]
position = Vector2(275, 13)
texture = ExtResource("6_gk1h4")
-[node name="Closeup折锡纸" parent="Ground/DeployLayer" index="3" instance=ExtResource("6_66gue")]
+[node name="Closeup折锡纸" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_66gue")]
+unique_name_in_owner = true
position = Vector2(189, 15)
packed_scene = ExtResource("7_fvlg0")
first_interact_os_key = "c02_保卫科祭台os"
-[node name="Closeup老鼠精" parent="Ground/DeployLayer" index="4" instance=ExtResource("6_66gue")]
+[node name="Closeup老鼠精" parent="Ground/DeployLayer" index="5" instance=ExtResource("6_66gue")]
light_mask = 5
position = Vector2(207.5, -40.5)
texture = ExtResource("11_ffvrp")
packed_scene = ExtResource("8_cm3g6")
-[node name="Closeup花名册" parent="Ground/DeployLayer" index="5" instance=ExtResource("6_66gue")]
+[node name="Closeup花名册" parent="Ground/DeployLayer" index="6" instance=ExtResource("6_66gue")]
+unique_name_in_owner = true
position = Vector2(351, 31)
packed_scene = ExtResource("6_fvlg0")
first_interact_os_key = "c02_保卫科花名册os"
-[node name="煤油灯" parent="Ground/DeployLayer" index="6" instance=ExtResource("8_wpvss")]
+[node name="Sprite2D" type="Sprite2D" parent="Ground/DeployLayer" index="7"]
position = Vector2(370, 39)
-animation_low_mode = true
-hide_texture = true
-gaslight_texture = ExtResource("9_a43aq")
-ground_light_texture = ExtResource("10_svuj3")
-[node name="SfxInvalid" parent="Ground/DeployLayer/煤油灯" index="0"]
-process_mode = 0
+[node name="灯光" type="AnimatedSprite2D" parent="Ground/DeployLayer/Sprite2D"]
+position = Vector2(0, -13)
+scale = Vector2(0.3, 0.3)
+sprite_frames = ExtResource("13_xy3nq")
+animation = &"火苗"
+autoplay = "火苗"
-[node name="SfxSuccess" parent="Ground/DeployLayer/煤油灯" index="1"]
-process_mode = 0
-
-[node name="CollisionShape2D" parent="Ground/DeployLayer/煤油灯/Area2D" index="0"]
-shape = SubResource("RectangleShape2D_gk1h4")
-
-[node name="PointLight2D" parent="Ground/DeployLayer/煤油灯" index="3"]
+[node name="PointLight2D" type="PointLight2D" parent="Ground/DeployLayer/Sprite2D"]
+position = Vector2(-5, 3)
+color = Color(1, 0.882353, 0.705882, 1)
+energy = 2.0
+blend_mode = 2
texture = ExtResource("9_a43aq")
-[node name="PointLightGround2D" parent="Ground/DeployLayer/煤油灯" index="4"]
-texture = ExtResource("10_svuj3")
-
-[node name="灯座" parent="Ground/DeployLayer/煤油灯" index="6"]
+[node name="PointLight2D范围" type="PointLight2D" parent="Ground/DeployLayer/Sprite2D/PointLight2D"]
visible = false
+energy = 0.7
+texture = SubResource("GradientTexture2D_ivr1s")
-[node name="Sign" parent="Ground/DeployLayer/煤油灯" index="7"]
-offset_top = -19.0
-offset_bottom = -19.0
-
-[node name="小手讨东西" parent="Ground/DeployLayer" index="7" instance=ExtResource("10_a43aq")]
+[node name="小手讨东西" parent="Ground/DeployLayer" index="8" instance=ExtResource("10_a43aq")]
position = Vector2(295, -6)
-[node name="Local寻人启事" parent="Ground/DeployLayer" index="8" instance=ExtResource("19_k74x7")]
+[node name="Local寻人启事" parent="Ground/DeployLayer" index="9" instance=ExtResource("19_k74x7")]
position = Vector2(116, -1)
texture = ExtResource("20_g8amr")
texture_cover = ExtResource("21_cq2m4")
@@ -164,9 +171,7 @@ texture = ExtResource("6_tio43")
points = PackedVector2Array(66, 150, 495, 150)
[node name="DirectionalLight2D" parent="Ground" index="8"]
-visible = false
energy = 0.9
blend_mode = 1
[editable path="Ground"]
-[editable path="Ground/DeployLayer/煤油灯"]
diff --git a/scene/ground/scene/c02/s05_一楼内侧楼道.tscn b/scene/ground/scene/c02/s05_一楼内侧楼道.tscn
index ee56c377..5c67c92b 100644
--- a/scene/ground/scene/c02/s05_一楼内侧楼道.tscn
+++ b/scene/ground/scene/c02/s05_一楼内侧楼道.tscn
@@ -151,6 +151,7 @@ debug_ground_data = Dictionary[String, Variant]({
"picked": false
}
})
+auto_ref_type = PackedStringArray("Ambush2D", "Inspectable2D", "Closeup2D", "Note2D", "Interactable2D", "Pickable2D", "Event2D", "Sprite2D", "ProAnimatedSprite2D", "AnimatedSprite2D", "Sfx", "Sfx2D", "VibeSfx", "PointLight2D", "Area2D", "MainPlayer", "CameraFocusMarker")
oneshot_animation = ""
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
diff --git a/scene/ground/scene/c02/s06_二楼.tscn b/scene/ground/scene/c02/s06_二楼.tscn
index 6554c1c6..7bc19d9e 100644
--- a/scene/ground/scene/c02/s06_二楼.tscn
+++ b/scene/ground/scene/c02/s06_二楼.tscn
@@ -893,6 +893,7 @@ debug_ground_data = Dictionary[String, Variant]({
"interacted_times": 0
}
})
+auto_ref_type = PackedStringArray("Ambush2D", "Inspectable2D", "Closeup2D", "Note2D", "Interactable2D", "Pickable2D", "Event2D", "Sprite2D", "ProAnimatedSprite2D", "AnimatedSprite2D", "Sfx", "Sfx2D", "VibeSfx", "PointLight2D", "Area2D", "MainPlayer", "CameraFocusMarker")
oneshot_animation = ""
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
diff --git a/scene/ground/scene/c02/s10_空房间.tscn b/scene/ground/scene/c02/s10_空房间.tscn
index 24743e27..f1d8cb2a 100644
--- a/scene/ground/scene/c02/s10_空房间.tscn
+++ b/scene/ground/scene/c02/s10_空房间.tscn
@@ -122,6 +122,7 @@ debug_ground_data = Dictionary[String, Variant]({
"interacted_times": 1
}
})
+auto_ref_type = PackedStringArray("Ambush2D", "Inspectable2D", "Closeup2D", "Note2D", "Interactable2D", "Pickable2D", "Event2D", "Sprite2D", "ProAnimatedSprite2D", "AnimatedSprite2D", "Sfx", "Sfx2D", "VibeSfx", "PointLight2D", "Area2D", "MainPlayer", "CameraFocusMarker")
oneshot_animation = ""
[node name="VibeSfx" type="Node" parent="Ground/AnimationPlayer" index="0"]
diff --git a/scene/ground/scene/template_animation.gd b/scene/ground/scene/template_animation.gd
index 68319f6f..21463fc3 100644
--- a/scene/ground/scene/template_animation.gd
+++ b/scene/ground/scene/template_animation.gd
@@ -13,5 +13,14 @@ func _ready() -> void:
return
+#region node_reference
+#endregion
+
+
+# 读取设置变量名
+func _setup_node_reference() -> void:
+ pass
+
+
func _on_ground_ready() -> void:
pass