@tool extends Node signal stage_updated(event_name: StringName, stage: int) func _ready() -> void: if Engine.is_editor_hint(): return # 0demo 1release set_stage("release_stage", GlobalConfig.RELEASE_STAGE) func get_chapter_stage() -> int: return get_stage("current_chapter_stage") 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.") return 0 var val = ArchiveManager.archive.event_stage.get(event_name, 0) return val # 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.") return ArchiveManager.archive.event_stage[event_name] = stage # print before emit print("[EventManager] Stage updated: %s, stage: %s" % [event_name, stage]) stage_updated.emit(event_name, stage) # 如果是 handnote_ 事件,玩家进行记笔记动作 if ( SceneManager.is_node_ready() and SceneManager.get_player() and SceneManager.get_player().character.begins_with("吕萍") ): if event_name == &"current_chapter_stage": # 章节更新 pass elif 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") # 仅在设置的 stage > 当前 stage 时更新,相等或小于时不更新 func set_stage_if_greater(event_name: StringName, stage := 1) -> bool: var current_stage = get_stage(event_name) if stage > current_stage: set_stage(event_name, stage) return true return false # stage 最大 99999 func next_staged(event_name: StringName, stage_max := 99999) -> void: var current_stage = get_stage(event_name) if current_stage < stage_max: set_stage(event_name, current_stage + 1) ##### 其他事件 ##### 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 #c03_invite_xchan_supper: 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