xiandie/manager/event_manager/event_manager.gd

144 lines
4.5 KiB
GDScript3
Raw Normal View History

@tool
2024-12-23 01:29:31 +00:00
extends Node
## 当任何事件的状态stage发生变化时发出此信号。
## 其他系统如UI、角色状态机等可以监听此信号来做出反应。
2025-06-27 14:52:46 +00:00
signal stage_updated(event_name: StringName, stage: int)
# 节点初始化时,异步加载并解析事件规则。
func _ready() -> void:
stage_updated.connect(_on_stage_updated_for_handnote)
# --- 公共 API ---
func get_chapter_stage() -> int:
return get_stage(&"current_chapter_stage")
2025-06-27 14:52:46 +00:00
func get_stage(event_name: StringName) -> int:
if not ArchiveManager.archive or ArchiveManager.archive.event_stage == null:
printerr("[EventManager] Archive or event_stage is null. Cannot get stage for '", event_name, "'.")
2025-06-27 14:52:46 +00:00
return 0
return ArchiveManager.archive.event_stage.get(event_name, 0)
2025-06-27 14:52:46 +00:00
# 核心的 stage 设置函数
2025-06-27 14:52:46 +00:00
# default 为 0首次更新为 1
func set_stage(event_name: StringName, stage := 1) -> void:
if not ArchiveManager.archive or ArchiveManager.archive.event_stage == null:
printerr("[EventManager] Archive or event_stage is null. Cannot set stage for '", event_name, "'.")
2025-06-27 14:52:46 +00:00
return
ArchiveManager.archive.event_stage[event_name] = stage
print("[EventManager] Stage updated: %s -> %s" % [event_name, stage])
2025-06-27 14:52:46 +00:00
stage_updated.emit(event_name, stage)
# 仅当设置的 stage > 当前 stage 时更新
func set_stage_if_greater(event_name: StringName, stage: int) -> bool:
if stage > get_stage(event_name):
2025-06-27 14:52:46 +00:00
set_stage(event_name, stage)
2025-07-02 18:29:39 +00:00
return true
return false
2025-06-27 14:52:46 +00:00
# stage 最大 99999
func next_stage(event_name: StringName, stage_max := 99999) -> int:
2025-06-27 14:52:46 +00:00
var current_stage = get_stage(event_name)
if current_stage < stage_max:
var new_stage = current_stage + 1
set_stage(event_name, new_stage)
return new_stage
return stage_max
2025-06-27 14:52:46 +00:00
# --- 游戏特定逻辑 ---
func _on_stage_updated_for_handnote(event_name: StringName, stage: int) -> void:
# 检查条件是否满足
if not (
SceneManager.is_node_ready()
and SceneManager.get_player()
and SceneManager.get_player().character.begins_with("吕萍")
):
return
if event_name.begins_with("handnote_"):
# 笔记条目更新
# 0 初始化隐藏1 开始显示2 划掉3 结束隐藏
if stage == 1:
SceneManager.lock_player(3.0, 16, true)
SceneManager.pop_notification("ui_notify_note_update")
2025-06-27 14:52:46 +00:00
2025-06-27 14:52:46 +00:00
##### 其他事件 #####
2025-01-13 08:09:57 +00:00
2025-06-17 05:01:19 +00:00
func prop_interacted(e_name, prop_key, interacted_times) -> void:
print("Event: %s interacted with %s. total times: %s" % [e_name, prop_key, interacted_times])
##### TOOL 方法
# event_name -> {stages:PackedStringArray, update_time:int}
var _debug_event_stage_dict := {}
# return: stages
func get_event_stage_map_array(event_name: StringName) -> PackedStringArray:
if not Engine.is_editor_hint():
return PackedStringArray()
var current_dict = _debug_event_stage_dict.get(event_name)
var time_msec = Time.get_ticks_msec()
# 3秒更新
if current_dict and time_msec - current_dict["update_time"] < 3000:
return current_dict["stages"]
# 文件: res://asset/dialogue/event_stage.dialogue
var event_stage_resource = load("uid://dohpsb4jttuv1") as DialogueResource
for title in event_stage_resource.get_titles():
var lines = await Util.get_lines(event_stage_resource, title)
for line in lines:
var line_text = line.text.strip_edges()
var e_name = line.character
if line_text.begins_with("#"):
continue
#xxxx: 0:未开始 1:已偷听,需邀请 2:已完成邀请
var parts = line_text.split(" ")
var stages = PackedStringArray()
for id in range(0, len(parts)):
var tuple = parts[id].split(":")
if len(tuple) == 2:
var event_stage = int(tuple[0])
if stages.size() < event_stage + 1:
stages.resize(event_stage + 1)
stages[event_stage] = tuple[1]
for id in len(stages):
if stages[id] == "":
stages[id] = str(id)
_debug_event_stage_dict[e_name] = {
"stages": stages,
"update_time": time_msec,
}
if _debug_event_stage_dict.has(event_name):
prints("reload", event_name, "stages:", _debug_event_stage_dict[event_name]["stages"])
return _debug_event_stage_dict[event_name]["stages"]
return PackedStringArray()
# map stage_id->name, 必定保持相同长度的数组
func map_event_stages(
event_name: StringName, stages: Array, including_id := true
) -> PackedStringArray:
var result = PackedStringArray()
result.resize(stages.size())
var dict = await get_event_stage_map_array(event_name)
for id in range(stages.size()):
var stage = stages[id]
if dict.size() > stage:
if including_id:
result[id] = str(stage) + ":" + dict[stage]
else:
result[id] = str(stage)
return result