2024-12-27 13:32:12 +00:00
|
|
|
@tool
|
2024-12-27 07:56:45 +00:00
|
|
|
class_name GroundLoader extends Node2D
|
2024-12-26 13:58:37 +00:00
|
|
|
|
2024-12-30 13:19:10 +00:00
|
|
|
@export var ignore_archive := false
|
2024-12-27 13:32:12 +00:00
|
|
|
@export var current_scene := "c02_s01"
|
|
|
|
@export var entrance_portal := "left"
|
2024-12-26 13:58:37 +00:00
|
|
|
|
2024-12-27 13:32:12 +00:00
|
|
|
var ground: Node2D
|
2024-12-26 13:58:37 +00:00
|
|
|
|
|
|
|
var scenes_dir = "res://scene/ground/scene/"
|
|
|
|
|
|
|
|
var ground_dict = {}
|
|
|
|
|
|
|
|
|
|
|
|
func _ready() -> void:
|
2024-12-30 13:19:10 +00:00
|
|
|
if not ignore_archive:
|
|
|
|
_load_save()
|
2024-12-26 13:58:37 +00:00
|
|
|
_read_grounds()
|
2025-01-02 11:01:44 +00:00
|
|
|
ground = get_node_or_null("Ground")
|
|
|
|
if current_scene and entrance_portal:
|
2024-12-27 13:32:12 +00:00
|
|
|
transition_to_scene(current_scene, entrance_portal, true)
|
2025-01-02 11:01:44 +00:00
|
|
|
elif ground:
|
|
|
|
ground.queue_free()
|
|
|
|
ground = null
|
2024-12-26 13:58:37 +00:00
|
|
|
|
2024-12-30 13:19:10 +00:00
|
|
|
|
2024-12-27 13:32:12 +00:00
|
|
|
func _load_save():
|
2025-01-02 11:01:44 +00:00
|
|
|
if not Engine.is_editor_hint() and ArchiveManager.archive:
|
2024-12-27 13:32:12 +00:00
|
|
|
if ArchiveManager.archive.current_scene:
|
|
|
|
current_scene = ArchiveManager.archive.current_scene
|
|
|
|
if ArchiveManager.archive.entrance_portal:
|
|
|
|
entrance_portal = ArchiveManager.archive.entrance_portal
|
2024-12-26 13:58:37 +00:00
|
|
|
|
2024-12-30 13:19:10 +00:00
|
|
|
|
2024-12-26 13:58:37 +00:00
|
|
|
func _read_grounds():
|
|
|
|
var dir = DirAccess.open(scenes_dir)
|
|
|
|
for c_dir in dir.get_directories():
|
|
|
|
var c_path = scenes_dir + c_dir + "/"
|
|
|
|
for s_file in DirAccess.open(c_path).get_files():
|
|
|
|
if s_file.ends_with(".tscn"):
|
|
|
|
var s_path = c_path + s_file
|
2024-12-27 13:32:12 +00:00
|
|
|
ground_dict[c_dir.substr(0, 3) + "_" + s_file.substr(0, 3)] = s_path
|
2024-12-26 13:58:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
func play_footstep_sound() -> void:
|
2024-12-27 13:32:12 +00:00
|
|
|
if ground and ground.is_visible_in_tree():
|
|
|
|
ground.play_footstep_sound()
|
2024-12-26 13:58:37 +00:00
|
|
|
|
|
|
|
|
2024-12-27 13:32:12 +00:00
|
|
|
func transition_to_scene(key: String, portal: String, load_save := false) -> void:
|
|
|
|
var scene_path = ground_dict[key]
|
2024-12-26 13:58:37 +00:00
|
|
|
if scene_path:
|
2024-12-27 13:52:11 +00:00
|
|
|
var scene = load(scene_path).instantiate()
|
2024-12-27 13:32:12 +00:00
|
|
|
current_scene = key
|
|
|
|
entrance_portal = portal
|
|
|
|
if load_save:
|
2024-12-27 13:52:11 +00:00
|
|
|
_do_transition(scene)
|
2024-12-27 13:32:12 +00:00
|
|
|
# 更新玩家位置
|
|
|
|
_update_player_position()
|
|
|
|
else:
|
2024-12-30 13:19:10 +00:00
|
|
|
var tween = create_tween() as Tween
|
2024-12-27 13:32:12 +00:00
|
|
|
var player = SceneManager.get_player() as MainPlayer
|
|
|
|
if player:
|
|
|
|
player.action_locked = true
|
|
|
|
#TODO 转场效果
|
|
|
|
#
|
2024-12-27 13:52:11 +00:00
|
|
|
tween.tween_interval(0.2)
|
|
|
|
tween.tween_callback(_do_transition.bind(scene))
|
2024-12-27 13:32:12 +00:00
|
|
|
tween.tween_callback(func(): player.action_locked = false)
|
2024-12-26 13:58:37 +00:00
|
|
|
else:
|
2024-12-27 13:32:12 +00:00
|
|
|
print("Scene not found: " + key)
|
|
|
|
|
2024-12-30 13:19:10 +00:00
|
|
|
|
2024-12-27 13:32:12 +00:00
|
|
|
func _update_player_position():
|
2025-01-02 11:01:44 +00:00
|
|
|
if ignore_archive or Engine.is_editor_hint():
|
2024-12-30 13:19:10 +00:00
|
|
|
return
|
2024-12-27 13:32:12 +00:00
|
|
|
var player = SceneManager.get_player() as MainPlayer
|
|
|
|
if player and ArchiveManager.archive:
|
|
|
|
# if GlobalConfig.DEBUG:
|
|
|
|
# print("update player position", ArchiveManager.archive.player_global_position)
|
|
|
|
player.global_position = ArchiveManager.archive.player_global_position
|
|
|
|
player.set_facing_direction(ArchiveManager.archive.player_direction)
|
|
|
|
|
2024-12-30 13:19:10 +00:00
|
|
|
|
2024-12-27 13:52:11 +00:00
|
|
|
func _do_transition(scene: Node2D):
|
2024-12-27 13:32:12 +00:00
|
|
|
if ground:
|
|
|
|
ground.queue_free()
|
|
|
|
# 提前移除,防止命名冲突
|
|
|
|
remove_child(ground)
|
|
|
|
ground = scene.get_child(0)
|
|
|
|
scene.remove_child(ground)
|
|
|
|
scene.queue_free()
|
2024-12-30 13:19:10 +00:00
|
|
|
ground.owner = null
|
2024-12-27 13:32:12 +00:00
|
|
|
add_child(ground)
|
2024-12-30 13:19:10 +00:00
|
|
|
ground.owner = self
|
2024-12-27 13:32:12 +00:00
|
|
|
ground.name = "Ground"
|
|
|
|
_set_camera_and_player_boundary()
|
|
|
|
_update_archive()
|
2025-01-02 11:01:44 +00:00
|
|
|
var portal_node = ground.get_node_or_null("DeployLayer/portal_" + entrance_portal) as Node2D
|
|
|
|
if portal_node and not Engine.is_editor_hint():
|
2024-12-27 13:32:12 +00:00
|
|
|
var player = SceneManager.get_player()
|
|
|
|
if player:
|
|
|
|
player.global_position.x = portal_node.global_position.x
|
2025-01-02 11:01:44 +00:00
|
|
|
print("move player to portal:", entrance_portal, portal_node.global_position)
|
|
|
|
if GlobalConfig.DEBUG and not Engine.is_editor_hint():
|
2024-12-30 13:19:10 +00:00
|
|
|
_watch_scene_update()
|
2024-12-27 13:32:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
func _set_camera_and_player_boundary():
|
|
|
|
var bg = ground.get_node("BGSprite2D")
|
2025-01-02 11:01:44 +00:00
|
|
|
if bg.texture and not Engine.is_editor_hint():
|
2024-12-27 13:32:12 +00:00
|
|
|
SceneManager.set_camera_boundary(bg.texture.get_size())
|
|
|
|
SceneManager.set_player_boundary(bg.texture.get_size())
|
|
|
|
|
|
|
|
|
|
|
|
func _update_archive():
|
2025-01-02 11:01:44 +00:00
|
|
|
if not Engine.is_editor_hint() and ArchiveManager.archive:
|
2024-12-30 13:19:10 +00:00
|
|
|
ArchiveManager.archive.current_scene = current_scene
|
|
|
|
ArchiveManager.archive.entrance_portal = entrance_portal
|
|
|
|
|
|
|
|
|
|
|
|
var update_watcher: Timer
|
|
|
|
var last_modify = 0
|
|
|
|
|
2025-01-02 11:01:44 +00:00
|
|
|
|
2024-12-30 13:19:10 +00:00
|
|
|
func _watch_scene_update():
|
|
|
|
var scene_path = ground_dict[current_scene]
|
|
|
|
if scene_path:
|
|
|
|
last_modify = FileAccess.get_modified_time(scene_path)
|
|
|
|
if not update_watcher:
|
|
|
|
update_watcher = Timer.new()
|
|
|
|
update_watcher.wait_time = 1
|
|
|
|
update_watcher.one_shot = false
|
|
|
|
add_child(update_watcher)
|
|
|
|
update_watcher.start()
|
|
|
|
else:
|
|
|
|
# remove all connections
|
|
|
|
for c in update_watcher.timeout.get_connections():
|
|
|
|
update_watcher.timeout.disconnect(c.callable)
|
|
|
|
update_watcher.timeout.connect(_check_scene_update.bind(scene_path))
|
|
|
|
|
|
|
|
|
|
|
|
func _check_scene_update(scene_path):
|
|
|
|
var modify = FileAccess.get_modified_time(scene_path)
|
|
|
|
if modify != last_modify:
|
|
|
|
last_modify = modify
|
|
|
|
_on_resources_reload(scene_path)
|
|
|
|
|
|
|
|
|
|
|
|
func _on_resources_reload(res):
|
|
|
|
print("resources_reload processing:", res)
|
2025-01-02 11:01:44 +00:00
|
|
|
if not Engine.is_editor_hint() and res.ends_with(".tscn"):
|
2024-12-30 13:19:10 +00:00
|
|
|
ArchiveManager.save_all()
|
|
|
|
transition_to_scene(current_scene, entrance_portal, true)
|