From dd829f599b8f8ea4682b513c1b6d79a12807b89b Mon Sep 17 00:00:00 2001 From: jkboy Date: Fri, 9 May 2025 23:39:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0proposal=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E4=BD=86=E6=98=AF=E8=BF=98=E4=B8=8D=E8=83=BD=E6=AD=A3?= =?UTF-8?q?=E5=B8=B8=E5=B7=A5=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 6148 -> 0 bytes Autoload/InitialDataManager.gd | 25 +- Autoload/InitializationManager.gd | 52 +- Data/npc.json | 28 + Data/task_development.json | 782 +++++++++--------- System/TimeManager.gd | 1 - UI/Font/AlimamaFangYuanTiVF-Thin.ttf.import | 9 +- UI/popup/dialogue.gd | 7 +- UI/popup/dialogue.tscn | 2 +- .../task_development/key_output/proposal.gd | 257 ++++++ .../{proposal => key_output}/proposal.gd.uid | 0 .../{proposal => key_output}/proposal.tscn | 170 ++-- .../task_development/key_output/work_out.tscn | 481 +++++++++++ .../task_development/proposal/proposal.gd | 16 - UI/popup/task_development/task_development.gd | 53 +- .../task_development/task_development.tscn | 2 +- project.godot | 2 +- 17 files changed, 1338 insertions(+), 549 deletions(-) delete mode 100644 .DS_Store create mode 100644 Data/npc.json create mode 100644 UI/popup/task_development/key_output/proposal.gd rename UI/popup/task_development/{proposal => key_output}/proposal.gd.uid (100%) rename UI/popup/task_development/{proposal => key_output}/proposal.tscn (69%) create mode 100644 UI/popup/task_development/key_output/work_out.tscn delete mode 100644 UI/popup/task_development/proposal/proposal.gd diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 3df45961e886c6b54e542f68f4d90b8712a130bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%Wl&^6upy%)S;@#qDb8!Sz;T7lr*%6O$h0tTg+ntDA-LD42~y?okmp@DQox# zet|7N0{_Aa&Yc-5+W{f52oKGT?wom?>+zh-!$U-(I~yDj)riP}GnTI+`GIje`~V&$#qR$|(4r z_k$Z%%l;=;wcp&FpIg1C0iuH7ZQ+2BS+WunEY9H0z)=_&| zcNfRU2go-Mm&>Yi{pPKE5BqPTaV+1ek&?ikri?Yp+B+21bU62>aU|mr+BmLEJ*bnC zpVvp+KwDPNOWvQ><&br0x0Nn;Z#V1iVe8Is=yExpf*ut*!R$&YgkKaiVLh{&IAEQr z+1Q|j&S_NOe<|><75UUa&6p;5#+1^0bcz3=Y;U{ZO~HIkL-d*=c7zhIhGOKWLS%(J zy1*Nzh#cp8QS0V?X5EzNF`X7TyjHRt6gO&SemgrG?bUW>6|f5Y3kvZ5;KCU@23H!@ z)`3J_0f1#xD?^??131Pt*fF@$h!&X8p+Frf%oRiEaMZho*D<)#sKZH^%ZD&M3v)ve zs&_o!Rdf;^jW)FkSOxM5Z0TZ+&;OI3-~aPLwqzBs3j9|Jh;q;CbulD!wyq71&srD$ r63)iFl|~hU#2m*e!$ bool: # 依次加载所有 JSON 文件 var success = true - success = success and _load_json_data("Init_Base.json", "_settings_data", false) # Init_Base is a Dictionary - success = success and _load_json_data("task_development.json", "_task_development_data", false) # task_development is a Dictionary - #success = success and _load_json_data("genres.json", "_genre_data") - #success = success and _load_json_data("topics.json", "_topic_data") - #success = success and _load_json_data("platforms.json", "_platform_data") - #success = success and _load_json_data("staff_roles.json", "_staff_role_data") - #success = success and _load_json_data("development_phases.json", "_development_phase_data") - #success = success and _load_json_data("features.json", "_feature_data") + success = success and _load_json_data("Init_Base.json", "_settings_data", false) + success = success and _load_json_data("task_development.json", "_task_development_data", false) + success = success and _load_json_data("npc.json", "_npc_data", false) # MODIFIED: 新增加载npc.json if success: _is_data_loaded = true @@ -61,6 +57,14 @@ func get_task_development_data() -> Dictionary: # 返回副本以强调只读性 return _task_development_data.duplicate(true) +# NEW: 获取 npc.json 中的所有数据。 +# 返回的数据应视为只读,用于构建初始状态。 +func get_npc_initial_data() -> Dictionary: + if not _is_data_loaded: + printerr("InitialDataManager: Attempted to get NPC data before data was loaded!") + return {} + return _npc_data.duplicate(true) + # --- 内部辅助函数 --- @@ -92,7 +96,7 @@ func _load_json_data(filename: String, target_var_name: String, expect_array: bo printerr("InitialDataManager: Invalid data format in " + file_path + ". Expected Array, got " + str(typeof(parse_result))) return false if not expect_array and not typeof(parse_result) == TYPE_DICTIONARY: - printerr("InitialDataManager: Invalid data format in " + file_path + ". Expected Dictionary, got " + str(typeof(parse_result))) + printerr("InitialDataManager: Invalid data format in " + file_path + ". Expected Dictionary, got " + str(typeof(parse_result))) # 确保npc.json顶层是字典 return false # 使用 set() 通过变量名字符串来设置成员变量的值 @@ -115,4 +119,5 @@ func _find_item_by_id(data_array: Array, id: String): # Removed -> Dictionary func _clear_loaded_data() -> void: _settings_data = {} _task_development_data = {} + _npc_data = {} # MODIFIED: 清理NPC数据 _is_data_loaded = false diff --git a/Autoload/InitializationManager.gd b/Autoload/InitializationManager.gd index 2a9093f..cc13347 100644 --- a/Autoload/InitializationManager.gd +++ b/Autoload/InitializationManager.gd @@ -23,15 +23,22 @@ func start_new_game_process() -> bool: # 2. 获取初始蓝图数据 var settings_data = InitialDataManager.get_starting_settings() var task_dev_data = InitialDataManager.get_task_development_data() + var npc_initial_data = InitialDataManager.get_npc_initial_data() # MODIFIED: 获取NPC初始数据 - if settings_data.is_empty() or task_dev_data.is_empty(): - printerr("InitializationManager: Failed to retrieve initial settings or task development data. Aborting new game.") + # MODIFIED: 更新空值检查 + if settings_data.is_empty() or task_dev_data.is_empty() or npc_initial_data.is_empty(): + var error_msg = "InitializationManager: Failed to retrieve initial data. Aborting new game. Details:\n" + if settings_data.is_empty(): error_msg += " - Settings data is empty.\n" + if task_dev_data.is_empty(): error_msg += " - Task development data is empty.\n" + if npc_initial_data.is_empty(): error_msg += " - NPC initial data is empty (check npc.json or InitialDataManager logs).\n" + printerr(error_msg) return false # 3. 构建注入 GameState 的初始状态字典 - var initial_state = _build_initial_state(settings_data, task_dev_data) - if initial_state.is_empty(): # _build_initial_state 内部可能有错误检查 - printerr("InitializationManager: Failed to build initial game state. Aborting new game.") + # MODIFIED: 传递 npc_initial_data 给 _build_initial_state + var initial_state = _build_initial_state(settings_data, task_dev_data, npc_initial_data) + if initial_state.is_empty(): # _build_initial_state 内部可能有错误检查导致返回空 + printerr("InitializationManager: Failed to build initial game state (returned empty). Aborting new game.") return false # 4. 初始化 GameState @@ -65,8 +72,9 @@ func load_game_process(save_data: Dictionary) -> bool: # --- 内部辅助函数 --- +# MODIFIED: 函数签名增加了 npc_defs 参数 # 根据从 InitialDataManager 获取的蓝图数据,构建注入 GameState 的初始状态字典 -func _build_initial_state(settings: Dictionary, task_dev: Dictionary) -> Dictionary: +func _build_initial_state(settings: Dictionary, task_dev: Dictionary, npc_defs: Dictionary) -> Dictionary: var initial_state: Dictionary = {} # 1. 合并基础设置 (Init_Base.json) - 这些保持为顶级键 @@ -77,25 +85,20 @@ func _build_initial_state(settings: Dictionary, task_dev: Dictionary) -> Diction var task_dev_state: Dictionary = {} # 3. 处理 Task Development 数据 (task_development.json),将其存入 task_dev_state - - # 处理平台 (Platforms) - 存入 task_dev_state + # ... (这部分关于 platforms, gameplays, themes, strategies, product_focus_points 的代码保持不变) ... + # (为了简洁,我省略了这部分重复代码,请确保您保留了原有的task_dev_state构建逻辑) + # --- START: task_dev_state 构建逻辑 (假设已存在) --- task_dev_state["platforms"] = {} if task_dev.has("platforms") and typeof(task_dev["platforms"]) == TYPE_DICTIONARY: for platform_key in task_dev["platforms"]: var p_data = task_dev["platforms"][platform_key] if typeof(p_data) == TYPE_DICTIONARY: - # 将从 InitialDataManager 获取的该平台的完整数据字典 (p_data) - # 直接存入 GameState 的 task_development.platforms 下。 - # 假设 p_data 已经包含了 Maker, Cost, Icon, Sales, enabled, Market_share 等所有字段。 - # 使用 duplicate(true) 确保 GameState 拥有独立的数据副本。 task_dev_state["platforms"][platform_key] = p_data.duplicate(true) else: printerr("InitializationManager: Invalid data format for platform: ", platform_key) else: print("InitializationManager: No 'platforms' data found or invalid format in task_development.json") - - # 处理玩法 (Gameplays) - 存入 task_dev_state (保持不变,只存动态) task_dev_state["gameplays"] = {} if task_dev.has("gameplays") and typeof(task_dev["gameplays"]) == TYPE_DICTIONARY: for gameplay_key in task_dev["gameplays"]: @@ -107,8 +110,6 @@ func _build_initial_state(settings: Dictionary, task_dev: Dictionary) -> Diction else: print("InitializationManager: No 'gameplays' data found or invalid format in task_development.json") - - # 处理主题 (Themes) - 存入 task_dev_state (保持不变,只存动态) task_dev_state["themes"] = {} if task_dev.has("themes") and typeof(task_dev["themes"]) == TYPE_DICTIONARY: for theme_key in task_dev["themes"]: @@ -120,8 +121,6 @@ func _build_initial_state(settings: Dictionary, task_dev: Dictionary) -> Diction else: print("InitializationManager: No 'themes' data found or invalid format in task_development.json") - - # 处理开发策略 (Strategies) - 存入 task_dev_state (保持不变,只存动态) task_dev_state["strategies"] = {} if task_dev.has("strategies") and typeof(task_dev["strategies"]) == TYPE_DICTIONARY: for strategy_key in task_dev["strategies"]: @@ -133,18 +132,27 @@ func _build_initial_state(settings: Dictionary, task_dev: Dictionary) -> Diction else: print("InitializationManager: No 'strategies' data found or invalid format in task_development.json") - - # 处理产品侧重点 (Product Focus Points) - 存入 task_dev_state (保持不变,存完整结构) if task_dev.has("product_focus_points") and typeof(task_dev["product_focus_points"]) == TYPE_DICTIONARY: task_dev_state["product_focus_points"] = task_dev["product_focus_points"].duplicate(true) else: print("InitializationManager: No 'product_focus_points' data found or invalid format in task_development.json") task_dev_state["product_focus_points"] = {} - + # --- END: task_dev_state 构建逻辑 --- # 4. 将包含所有任务开发状态的字典 task_dev_state 赋值给 initial_state 下的 "task_development" 键 initial_state["task_development"] = task_dev_state - print("InitializationManager: Initial game state built with 'task_development' structure.") + # 5. NEW: 处理 NPC 数据,将其存入 initial_state 的 "npcs" 键下 + # npc_defs 是从 npc.json 加载的完整内容,结构为 {"npc": {"米子一": {...}, "塔奇": {...}}} + # 我们希望将 {"米子一": {...}, "塔奇": {...}} 这部分存入 GameState + if npc_defs.has("npc") and typeof(npc_defs["npc"]) == TYPE_DICTIONARY: + initial_state["npcs"] = npc_defs["npc"].duplicate(true) # 深拷贝NPC数据 + print("InitializationManager: NPC data added to initial state under 'npcs' key.") + else: + # 如果 npc.json 结构不符合预期 (例如顶层没有 "npc" 键,或其值不是字典) + # 打印错误,并为 "npcs" 设置一个空字典,以避免后续代码因键不存在而出错 + printerr("InitializationManager: 'npc' key not found or not a Dictionary in npc_initial_data from npc.json. Initializing 'npcs' as empty.") + initial_state["npcs"] = {} + print("InitializationManager: Initial game state built with 'task_development' and 'npcs' structure.") return initial_state diff --git a/Data/npc.json b/Data/npc.json new file mode 100644 index 0000000..76829d8 --- /dev/null +++ b/Data/npc.json @@ -0,0 +1,28 @@ +{ + "npc": { + "米子一": { + "type": "员工", + "title": "项目总监", + "level": 1, + "power": 180, + "power_max": 180, + "design": 80, + "code": 70, + "art": 80, + "audio": 70, + "outsourcing": 0 + }, + "塔奇": { + "type": "员工", + "title": "美术设计师", + "level": 3, + "power": 150, + "power_max": 150, + "design": 80, + "code": 20, + "art": 90, + "audio": 80, + "outsourcing": 2400 + } + } +} \ No newline at end of file diff --git a/Data/task_development.json b/Data/task_development.json index c83d5d1..fba58d2 100644 --- a/Data/task_development.json +++ b/Data/task_development.json @@ -1,397 +1,397 @@ { - "platforms": { - "台式 & 笔记本": { - "enabled": true, - "Icon": "platform_1", - "Maker": "不定", - "Sales": 50, - "Market_share": 28, - "Cost": 500 + "platforms": { + "台式 & 笔记本": { + "enabled": true, + "Icon": "platform_1", + "Maker": "不定", + "Sales": 50, + "Market_share": 28, + "Cost": 500 + }, + "Switch": { + "enabled": true, + "Icon": "platform_2", + "Maker": "赛天堂", + "Sales": 120, + "Market_share": 40, + "Cost": 1500 + }, + "PS": { + "enabled": false, + "Icon": "platform_2", + "Maker": "微硬", + "Sales": 60, + "Market_share": 20, + "Cost": 2000 + }, + "XBOX": { + "enabled": false, + "Icon": "platform_2", + "Maker": "微硬", + "Sales": 30, + "Market_share": 13, + "Cost": 1300 + } }, - "Switch": { - "enabled": true, - "Icon": "platform_2", - "Maker": "赛天堂", - "Sales": 120, - "Market_share": 40, - "Cost": 1500 + "gameplays": { + "角色扮演(RPG)": { + "enabled": false, + "Cost": 500, + "Experience": 0, + "Popularity": "中" + }, + "动作角色扮演(ARPG)": { + "enabled": false, + "Cost": 600, + "Experience": 0, + "Popularity": "高" + }, + "模拟角色扮演(SRPG)": { + "enabled": false, + "Cost": 550, + "Experience": 0, + "Popularity": "中" + }, + "第一人称射击(FPS)": { + "enabled": false, + "Cost": 700, + "Experience": 0, + "Popularity": "高" + }, + "即时战略(RTS)": { + "enabled": false, + "Cost": 550, + "Experience": 0, + "Popularity": "中" + }, + "冒险(AVG)": { + "enabled": false, + "Cost": 450, + "Experience": 0, + "Popularity": "中" + }, + "策略与战棋(SLG)": { + "enabled": false, + "Cost": 500, + "Experience": 0, + "Popularity": "中" + }, + "赛车竞速(RAC)": { + "enabled": false, + "Cost": 450, + "Experience": 0, + "Popularity": "中" + }, + "动作(ACT)": { + "enabled": false, + "Cost": 550, + "Experience": 0, + "Popularity": "高" + }, + "模拟经营(SIM)": { + "enabled": false, + "Cost": 400, + "Experience": 0, + "Popularity": "中" + }, + "养成(EDU)": { + "enabled": false, + "Cost": 350, + "Experience": 0, + "Popularity": "低" + }, + "飞行模拟(FLY)": { + "enabled": false, + "Cost": 600, + "Experience": 0, + "Popularity": "低" + }, + "桌面(TAB)": { + "enabled": true, + "Cost": 300, + "Experience": 0, + "Popularity": "低" + }, + "体育(SPG)": { + "enabled": false, + "Cost": 450, + "Experience": 0, + "Popularity": "中" + }, + "格斗(FTG)": { + "enabled": false, + "Cost": 500, + "Experience": 0, + "Popularity": "中" + }, + "模拟格斗(SFTG)": { + "enabled": false, + "Cost": 550, + "Experience": 0, + "Popularity": "中" + }, + "益智(PUZ)": { + "enabled": true, + "Cost": 350, + "Experience": 0, + "Popularity": "中" + }, + "射击(STG)": { + "enabled": false, + "Cost": 600, + "Experience": 0, + "Popularity": "高" + } }, - "PS": { - "enabled": false, - "Icon": "platform_2", - "Maker": "微硬", - "Sales": 60, - "Market_share": 20, - "Cost": 2000 + "themes": { + "现代都市": { + "enabled": false, + "Cost": 400, + "Experience": 0, + "Popularity": "高" + }, + "校园青春": { + "enabled": true, + "Cost": 350, + "Experience": 0, + "Popularity": "中" + }, + "军事战争": { + "enabled": true, + "Cost": 450, + "Experience": 0, + "Popularity": "中" + }, + "历史文明": { + "enabled": false, + "Cost": 500, + "Experience": 0, + "Popularity": "中" + }, + "武侠仙侠": { + "enabled": false, + "Cost": 500, + "Experience": 0, + "Popularity": "中" + }, + "三国战国": { + "enabled": false, + "Cost": 450, + "Experience": 0, + "Popularity": "中" + }, + "东方神话": { + "enabled": true, + "Cost": 550, + "Experience": 0, + "Popularity": "中" + }, + "宫廷传奇": { + "enabled": false, + "Cost": 500, + "Experience": 0, + "Popularity": "中" + }, + "魔幻奇幻": { + "enabled": false, + "Cost": 600, + "Experience": 0, + "Popularity": "高" + }, + "西方魔法": { + "enabled": false, + "Cost": 550, + "Experience": 0, + "Popularity": "高" + }, + "古代文明": { + "enabled": true, + "Cost": 600, + "Experience": 0, + "Popularity": "低" + }, + "海盗冒险": { + "enabled": true, + "Cost": 550, + "Experience": 0, + "Popularity": "中" + }, + "科幻未来": { + "enabled": false, + "Cost": 650, + "Experience": 0, + "Popularity": "高" + }, + "末日生存": { + "enabled": false, + "Cost": 550, + "Experience": 0, + "Popularity": "中" + }, + "赛博朋克": { + "enabled": false, + "Cost": 650, + "Experience": 0, + "Popularity": "高" + }, + "蒸汽朋克": { + "enabled": false, + "Cost": 600, + "Experience": 0, + "Popularity": "中" + }, + "外星文明": { + "enabled": false, + "Cost": 600, + "Experience": 0, + "Popularity": "中" + }, + "恐怖悬疑": { + "enabled": false, + "Cost": 500, + "Experience": 0, + "Popularity": "中" + }, + "超自然生物": { + "enabled": false, + "Cost": 550, + "Experience": 0, + "Popularity": "中" + }, + "丧尸末日": { + "enabled": true, + "Cost": 500, + "Experience": 0, + "Popularity": "中" + }, + "足球": { + "enabled": false, + "Cost": 550, + "Experience": 0, + "Popularity": "极高" + }, + "篮球与街球": { + "enabled": false, + "Cost": 550, + "Experience": 0, + "Popularity": "极高" + }, + "棒球": { + "enabled": false, + "Cost": 450, + "Experience": 0, + "Popularity": "中" + }, + "网球": { + "enabled": false, + "Cost": 400, + "Experience": 0, + "Popularity": "中" + }, + "排球": { + "enabled": true, + "Cost": 400, + "Experience": 0, + "Popularity": "中" + }, + "乒乓球": { + "enabled": false, + "Cost": 350, + "Experience": 0, + "Popularity": "中" + }, + "高尔夫": { + "enabled": false, + "Cost": 500, + "Experience": 0, + "Popularity": "中" + }, + "冰雪运动": { + "enabled": false, + "Cost": 480, + "Experience": 0, + "Popularity": "低" + }, + "橄榄球与美式足球": { + "enabled": false, + "Cost": 500, + "Experience": 0, + "Popularity": "中" + }, + "格斗与搏击": { + "enabled": false, + "Cost": 450, + "Experience": 0, + "Popularity": "中" + }, + "田径": { + "enabled": false, + "Cost": 400, + "Experience": 0, + "Popularity": "中" + }, + "极限运动": { + "enabled": false, + "Cost": 550, + "Experience": 0, + "Popularity": "中" + }, + "街舞": { + "enabled": true, + "Cost": 400, + "Experience": 0, + "Popularity": "中" + } }, - "XBOX": { - "enabled": false, - "Icon": "platform_2", - "Maker": "微硬", - "Sales": 30, - "Market_share": 13, - "Cost": 1300 + "strategies": { + "正常开发": { + "enabled": true, + "Cost": 0, + "Period": 1.0, + "Quality": 0.0, + "Idea": 0.0, + "Explanation": "正常开发, 随缘推进" + }, + "快速上线": { + "enabled": true, + "Cost": 0.2, + "Period": 0.8, + "Quality": 0.0, + "Idea": 0.0, + "Explanation": "Fail Fast, Learn Fast" + }, + "质量优先": { + "enabled": true, + "Cost": 0.3, + "Period": 1.0, + "Quality": 0.3, + "Idea": 0.0, + "Explanation": "为了质量, 可以硬怼" + }, + "积累经验": { + "enabled": true, + "Cost": 0.3, + "Period": 1.0, + "Quality": 0.0, + "Idea": 0.3, + "Explanation": "跑通流程, 积累工具" + }, + "增加预算": { + "enabled": true, + "Cost": 1, + "Period": 1.0, + "Quality": 0.5, + "Idea": 0.5, + "Explanation": "不差钱, 全面提升" + } + }, + "product_focus_points": { + "总数": 10, + "视觉表现": 4, + "游戏深度": 2, + "创新性": 2, + "易玩性": 0, + "操控感": 1, + "沉浸感": 0 } - }, - "gameplays": { - "角色扮演(RPG)": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 500 - }, - "动作角色扮演(ARPG)": { - "enabled": false, - "Experience": 0, - "Popularity": "高", - "Cost": 600 - }, - "模拟角色扮演(SRPG)": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 550 - }, - "第一人称射击(FPS)": { - "enabled": false, - "Experience": 0, - "Popularity": "高", - "Cost": 700 - }, - "即时战略(RTS)": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 550 - }, - "冒险(AVG)": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 450 - }, - "策略与战棋(SLG)": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 500 - }, - "赛车竞速(RAC)": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 450 - }, - "动作(ACT)": { - "enabled": false, - "Experience": 0, - "Popularity": "高", - "Cost": 550 - }, - "模拟经营(SIM)": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 400 - }, - "养成(EDU)": { - "enabled": false, - "Experience": 0, - "Popularity": "低", - "Cost": 350 - }, - "飞行模拟(FLY)": { - "enabled": false, - "Experience": 0, - "Popularity": "低", - "Cost": 600 - }, - "桌面(TAB)": { - "enabled": true, - "Experience": 0, - "Popularity": "低", - "Cost": 300 - }, - "体育(SPG)": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 450 - }, - "格斗(FTG)": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 500 - }, - "模拟格斗(SFTG)": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 550 - }, - "益智(PUZ)": { - "enabled": true, - "Experience": 0, - "Popularity": "中", - "Cost": 350 - }, - "射击(STG)": { - "enabled": false, - "Experience": 0, - "Popularity": "高", - "Cost": 600 - } - }, - "themes": { - "现代都市": { - "enabled": false, - "Experience": 0, - "Popularity": "高", - "Cost": 400 - }, - "校园青春": { - "enabled": true, - "Experience": 0, - "Popularity": "中", - "Cost": 350 - }, - "军事战争": { - "enabled": true, - "Experience": 0, - "Popularity": "中", - "Cost": 450 - }, - "历史文明": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 500 - }, - "武侠仙侠": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 500 - }, - "三国战国": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 450 - }, - "东方神话": { - "enabled": true, - "Experience": 0, - "Popularity": "中", - "Cost": 550 - }, - "宫廷传奇": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 500 - }, - "魔幻奇幻": { - "enabled": false, - "Experience": 0, - "Popularity": "高", - "Cost": 600 - }, - "西方魔法": { - "enabled": false, - "Experience": 0, - "Popularity": "高", - "Cost": 550 - }, - "古代文明": { - "enabled": true, - "Experience": 0, - "Popularity": "低", - "Cost": 600 - }, - "海盗冒险": { - "enabled": true, - "Experience": 0, - "Popularity": "中", - "Cost": 550 - }, - "科幻未来": { - "enabled": false, - "Experience": 0, - "Popularity": "高", - "Cost": 650 - }, - "末日生存": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 550 - }, - "赛博朋克": { - "enabled": false, - "Experience": 0, - "Popularity": "高", - "Cost": 650 - }, - "蒸汽朋克": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 600 - }, - "外星文明": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 600 - }, - "恐怖悬疑": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 500 - }, - "超自然生物": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 550 - }, - "丧尸末日": { - "enabled": true, - "Experience": 0, - "Popularity": "中", - "Cost": 500 - }, - "足球": { - "enabled": false, - "Experience": 0, - "Popularity": "极高", - "Cost": 550 - }, - "篮球与街球": { - "enabled": false, - "Experience": 0, - "Popularity": "极高", - "Cost": 550 - }, - "棒球": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 450 - }, - "网球": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 400 - }, - "排球": { - "enabled": true, - "Experience": 0, - "Popularity": "中", - "Cost": 400 - }, - "乒乓球": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 350 - }, - "高尔夫": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 500 - }, - "冰雪运动": { - "enabled": false, - "Experience": 0, - "Popularity": "低", - "Cost": 480 - }, - "橄榄球与美式足球": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 500 - }, - "格斗与搏击": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 450 - }, - "田径": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 400 - }, - "极限运动": { - "enabled": false, - "Experience": 0, - "Popularity": "中", - "Cost": 550 - }, - "街舞": { - "enabled": true, - "Experience": 0, - "Popularity": "中", - "Cost": 400 - } - }, - "strategies": { - "正常开发": { - "enabled": true, - "Period": 1.0, - "Quality": 0.0, - "Idea": 0.0, - "Cost": 0.0, - "Explaination": "正常开发, 随缘推进" - }, - "快速上线": { - "enabled": true, - "Period": 0.8, - "Quality": 0.0, - "Idea": 0.0, - "Cost": 0.2, - "Explaination": "Fail Fast, Learn Fast" - }, - "质量优先": { - "enabled": true, - "Period": 1.0, - "Quality": 0.3, - "Idea": 0.0, - "Cost": 0.3, - "Explaination": "为了质量, 可以硬怼" - }, - "积累经验": { - "enabled": true, - "Period": 1.0, - "Quality": 0.0, - "Idea": 0.3, - "Cost": 0.3, - "Explaination": "跑通流程, 积累工具" - }, - "增加预算": { - "enabled": true, - "Period": 1.0, - "Quality": 0.5, - "Idea": 0.5, - "Cost": 1.0, - "Explaination": "不差钱, 全面提升" - } - }, - "product_focus_points": { - "总数": 10, - "视觉表现": 4, - "游戏深度": 2, - "创新性": 2, - "易玩性": 0, - "操控感": 1, - "沉浸感": 0 - } } diff --git a/System/TimeManager.gd b/System/TimeManager.gd index e802988..7ded273 100644 --- a/System/TimeManager.gd +++ b/System/TimeManager.gd @@ -1,5 +1,4 @@ # TimeManager.gd -# Autoload Singleton # 负责驱动游戏内时间的流逝。 # 使用 Timer 节点每秒触发一次时间推进逻辑。 # 从 GameState 读取暂停状态和当前时间,并将更新后的时间写回 GameState。 diff --git a/UI/Font/AlimamaFangYuanTiVF-Thin.ttf.import b/UI/Font/AlimamaFangYuanTiVF-Thin.ttf.import index 5b3ba31..a474315 100644 --- a/UI/Font/AlimamaFangYuanTiVF-Thin.ttf.import +++ b/UI/Font/AlimamaFangYuanTiVF-Thin.ttf.import @@ -16,7 +16,7 @@ Rendering=null antialiasing=1 generate_mipmaps=false disable_embedded_bitmaps=true -multichannel_signed_distance_field=false +multichannel_signed_distance_field=true msdf_pixel_range=8 msdf_size=48 allow_system_fallback=true @@ -29,7 +29,12 @@ Fallbacks=null fallbacks=[] Compress=null compress=true -preload=[] +preload=[{ +"chars": [], +"glyphs": [], +"name": "新建配置", +"size": Vector2i(16, 0) +}] language_support={} script_support={} opentype_features={} diff --git a/UI/popup/dialogue.gd b/UI/popup/dialogue.gd index 078bf50..9859b0a 100644 --- a/UI/popup/dialogue.gd +++ b/UI/popup/dialogue.gd @@ -18,11 +18,6 @@ var is_active: bool = false var label: Label = null # 缓存Label节点引用 var typewriter: TypewriterLogic = null # 用于存储 TypewriterLogic 实例 -# --- 移除旧的打字状态变量 --- -# var current_tween: Tween = null # 不再需要,由 TypewriterLogic 管理 -# var is_typing: bool = false # 不再需要,由 TypewriterLogic 管理 - - func _ready() -> void: node_name = str(self.name) visible = false @@ -66,7 +61,7 @@ func _start(dialogues, next_node = null) -> void: set_process_input(true) -# 4. 修改:使用 TypewriterLogic 显示当前对话 +# 4. 使用 TypewriterLogic 显示当前对话 func _show_current_dialogue() -> void: if current_dialogue_index < dialogue_queue.size(): # 检查 typewriter 实例是否有效 diff --git a/UI/popup/dialogue.tscn b/UI/popup/dialogue.tscn index 0a66359..d2f125a 100644 --- a/UI/popup/dialogue.tscn +++ b/UI/popup/dialogue.tscn @@ -149,7 +149,7 @@ grow_horizontal = 2 grow_vertical = 2 theme_override_colors/font_color = Color(0, 0, 0, 1) theme_override_fonts/font = ExtResource("3_ilhgc") -theme_override_font_sizes/font_size = 20 +theme_override_font_sizes/font_size = 18 text = "游戏杂志最新刊已发行。游戏杂志最新刊已发行。游戏杂志最新刊已发行。游戏杂志最新刊已发行。游戏杂志最新刊已发行。" autowrap_mode = 1 diff --git a/UI/popup/task_development/key_output/proposal.gd b/UI/popup/task_development/key_output/proposal.gd new file mode 100644 index 0000000..f69a20f --- /dev/null +++ b/UI/popup/task_development/key_output/proposal.gd @@ -0,0 +1,257 @@ +# proposal.gd +extends Control + +# --- UI 节点引用 --- +@onready var title_label: Label = $proposal/Title/Title +@onready var npc_name_label: Label = $proposal/Option/NPC_Info_1/Name +@onready var npc_staff_type_label: Label = $proposal/Option/NPC_Info_1/Staff # 通常显示 "员工" +@onready var npc_job_label: Label = $proposal/Option/NPC_Info_2/Info_List_0/Job/Title +@onready var npc_level_label: Label = $proposal/Option/NPC_Info_2/Info_List_0/Job/Level +@onready var npc_icon_rect: TextureRect = $proposal/Option/NPC_Info_2/Info_List_0/Icon + +@onready var stat_design_label: Label = $proposal/Option/NPC_Info_2/Info_List_1/Info_1/info +@onready var stat_code_label: Label = $proposal/Option/NPC_Info_2/Info_List_1/Info_2/info +@onready var stat_art_label: Label = $proposal/Option/NPC_Info_2/Info_List_1/Info_3/info +@onready var stat_audio_label: Label = $proposal/Option/NPC_Info_2/Info_List_1/Info_4/info + +@onready var cost_label: Label = $proposal/Option/NPC_Info_2/Info_List_3/info_4/info + +@onready var power_bar_segments_container: HBoxContainer = $proposal/Option/NPC_Info_2/Info_List_2 +var _power_bar_segments: Array[ColorRect] = [] # 用于存储体力条的各个片段 + +@onready var prev_button: Button = $proposal/Title/previous/Button +@onready var next_button: Button = $proposal/Title/next/Button +@onready var confirm_button: Button = $proposal/Confirm + +# --- 内部状态 --- +var _all_npcs_data: Dictionary = {} # 存储从 GameState 加载的所有NPC原始数据 +var enabled_npc_keys: Array[String] = [] # 存储所有当前可选的NPC的键 (名字) +var current_npc_index: int = -1 # 当前在 enabled_npc_keys 数组中选中的NPC的索引 + +# --- 常量 --- +const NPC_ICON_BASE_PATH = "res://Entity/NPC/" # NPC 图标的基础路径 (如果后续有 Icon 字段) +const DEFAULT_NPC_ICON_PATH = "res://Entity/NPC/NPC_1_UI.png" # 默认/占位NPC图标 + +const POWER_CURRENT_COLOR = Color.GREEN_YELLOW # 当前体力颜色 +const POWER_MAX_POTENTIAL_COLOR = Color(0.2, 0.4, 0.2, 0.8) # 最大潜力槽颜色 (稍暗的绿色) +const POWER_DISABLED_COLOR = Color(0.1, 0.1, 0.1, 0.3) # 体力条禁用/未达到部分的颜色 + + +func _ready() -> void: + var node_name = str(self.name) + add_to_group(node_name) # 方便父节点或其他系统查找 + + # 收集体力条的片段 + for child in power_bar_segments_container.get_children(): + if child is ColorRect: + _power_bar_segments.append(child) + if _power_bar_segments.size() != 20: + printerr(node_name + ": Expected 20 power bar segments, found " + str(_power_bar_segments.size())) + + + # 连接信号 + if prev_button and not prev_button.pressed.is_connected(_on_previous_pressed): + prev_button.pressed.connect(_on_previous_pressed) + if next_button and not next_button.pressed.is_connected(_on_next_pressed): + next_button.pressed.connect(_on_next_pressed) + if confirm_button and not confirm_button.pressed.is_connected(_on_confirm_pressed): + confirm_button.pressed.connect(_on_confirm_pressed) + + if not is_connected("visibility_changed",Callable(self,"_on_visibility_changed")): + visibility_changed.connect(Callable(self,"_on_visibility_changed")) + + # 如果节点在 _ready 时就可见,则立即刷新显示 + if is_visible_in_tree(): + reset_display() + + +func _on_visibility_changed() -> void: + if is_visible_in_tree(): + reset_display() + + +# 重置显示状态,在窗口可见时调用 +func reset_display() -> void: + print(str(self.name) + ": Resetting display state.") + _load_and_filter_npcs() + + if enabled_npc_keys.is_empty(): + current_npc_index = -1 + print(str(self.name) + ": No enabled NPCs found.") + else: + current_npc_index = 0 # 默认显示第一个可用的NPC + print(str(self.name) + ": Found %d enabled NPCs. Defaulting to index 0." % enabled_npc_keys.size()) + + _display_current_npc() + + +# 从 GameState 加载NPC数据并筛选出可用的负责人 +func _load_and_filter_npcs() -> void: + _all_npcs_data.clear() + enabled_npc_keys.clear() + + if not GameState: + printerr(str(self.name) + ": GameState not available in _load_and_filter_npcs.") + return + + var raw_npcs_data = GameState.get_value("npcs", {}) + if raw_npcs_data.is_empty(): + print(str(self.name) + ": 'npcs' data in GameState is empty or not found.") + return + + _all_npcs_data = raw_npcs_data + + for npc_key in _all_npcs_data: + var npc_info = _all_npcs_data[npc_key] + if typeof(npc_info) == TYPE_DICTIONARY and npc_info.get("type") == "员工": + enabled_npc_keys.append(npc_key) + + # 可选:对 enabled_npc_keys进行排序,以确保显示顺序一致 + # enabled_npc_keys.sort() + print(str(self.name) + ": Loaded and filtered NPCs. Enabled count: " + str(enabled_npc_keys.size())) + +# 根据 current_npc_index 更新UI显示 +func _display_current_npc() -> void: + if current_npc_index < 0 or current_npc_index >= enabled_npc_keys.size(): + # --- 处理没有可用NPC或索引无效的情况 --- + title_label.text = "策划案负责人" + npc_name_label.text = "无可用负责人" + npc_staff_type_label.text = "-" # 通常显示 "员工" + npc_job_label.text = "-" + npc_level_label.text = "-" + npc_icon_rect.texture = null # 或者一个“无”的占位图 + stat_design_label.text = "-" + stat_code_label.text = "-" + stat_art_label.text = "-" + stat_audio_label.text = "-" + cost_label.text = "-" + + # 隐藏所有体力条片段 + for segment in _power_bar_segments: + segment.visible = false + + if prev_button: prev_button.disabled = true + if next_button: next_button.disabled = true + if confirm_button: confirm_button.disabled = true + return + + # --- 如果有有效NPC --- + if prev_button: prev_button.disabled = enabled_npc_keys.size() <= 1 + if next_button: next_button.disabled = enabled_npc_keys.size() <= 1 + if confirm_button: confirm_button.disabled = false + + var display_index = current_npc_index + 1 + var total_count = enabled_npc_keys.size() + title_label.text = "策划案负责人 %d/%d" % [display_index, total_count] + + var npc_key = enabled_npc_keys[current_npc_index] + if not _all_npcs_data.has(npc_key): + printerr(str(self.name) + ": Current NPC key '%s' not found in cached _all_npcs_data!" % npc_key) + # 显示错误状态,可以做得更友好 + npc_name_label.text = "错误:数据丢失" + # 隐藏所有体力条片段 + for segment in _power_bar_segments: + segment.visible = false + return + + var npc_info = _all_npcs_data[npc_key] + + # 更新基本信息 + npc_name_label.text = npc_key + npc_staff_type_label.text = npc_info.get("type", "员工") # 根据筛选,这里应该是"员工" + npc_job_label.text = npc_info.get("title", "-") + npc_level_label.text = "Lv" + str(int(npc_info.get("level", 1))) + + # 更新图标 (后续会从npc_info.Icon获取) + var icon_name_from_data = npc_info.get("Icon", "") # 假设后续会有这个字段 + if not icon_name_from_data.is_empty(): + var dynamic_icon_path = NPC_ICON_BASE_PATH + icon_name_from_data + ".png" # 假设文件名规则 + if ResourceLoader.exists(dynamic_icon_path): + npc_icon_rect.texture = ResourceLoader.load(dynamic_icon_path) + else: + printerr(str(self.name) + ": Failed to load NPC icon: " + dynamic_icon_path + ". Falling back to default.") + npc_icon_rect.texture = ResourceLoader.load(DEFAULT_NPC_ICON_PATH) + else: + # print(str(self.name) + ": NPC icon name is empty for key '%s'. Using default." % npc_key) + npc_icon_rect.texture = ResourceLoader.load(DEFAULT_NPC_ICON_PATH) + + + # 更新能力值 (确保转换为整数显示) + stat_design_label.text = str(int(npc_info.get("design", 0.0))) + stat_code_label.text = str(int(npc_info.get("code", 0.0))) + stat_art_label.text = str(int(npc_info.get("art", 0.0))) + stat_audio_label.text = str(int(npc_info.get("audio", 0.0))) + + # 更新费用 + cost_label.text = str(int(npc_info.get("outsourcing", 0.0))) + + # --- 更新体力条 (包含 visible 控制) --- + var power = float(npc_info.get("power", 0.0)) + var power_max = float(npc_info.get("power_max", 0.0)) + + if power_max <= 0: # 防止除零错误或无效数据 + for segment in _power_bar_segments: + segment.visible = false # 如果最大体力为0或无效,所有格段都不可见 + else: + var total_visible_segments = floori(power_max / 10.0) # 根据 power_max 计算总共应显示的格数 + var current_power_segments = floori(power / 10.0) # 当前体力对应的格数 + + # 确保 current_power_segments 不会超过 total_visible_segments (逻辑上 power 不应大于 power_max) + current_power_segments = mini(current_power_segments, total_visible_segments) + + for i in range(_power_bar_segments.size()): # 遍历所有20个可能的格段 + var segment = _power_bar_segments[i] + + if i < total_visible_segments: + segment.visible = true # 此格段在NPC的最大体力范围内,设为可见 + if i < current_power_segments: + segment.color = POWER_CURRENT_COLOR # 当前体力部分 + else: + segment.color = POWER_MAX_POTENTIAL_COLOR # 最大潜力中未充满的部分 + else: + segment.visible = false # 此格段超出NPC的最大体力范围,设为不可见 + +func _on_previous_pressed() -> void: + if enabled_npc_keys.size() > 1: + current_npc_index -= 1 + if current_npc_index < 0: + current_npc_index = enabled_npc_keys.size() - 1 + _display_current_npc() + +func _on_next_pressed() -> void: + if enabled_npc_keys.size() > 1: + current_npc_index += 1 + if current_npc_index >= enabled_npc_keys.size(): + current_npc_index = 0 + _display_current_npc() + +func _on_confirm_pressed() -> void: + if current_npc_index != -1 and current_npc_index < enabled_npc_keys.size(): + var selected_npc_key = enabled_npc_keys[current_npc_index] + var parent_node = get_parent() + + if parent_node and parent_node.has_method("update_task_options"): + parent_node.update_task_options({"关键环节负责人": selected_npc_key}) + print(str(self.name) + ": Confirmed NPC '%s'. Sent to parent." % selected_npc_key) + else: + printerr(str(self.name) + ": Parent node not found or missing 'update_task_options' method.") + + # 无论父节点是否成功更新,都尝试继续后续流程 + if parent_node and parent_node.has_method("start_task"): + parent_node.start_task() + else: + printerr(str(self.name) + ": Parent node not found or missing 'start_task' method.") + + if parent_node and parent_node.has_method("close_all_popups"): + parent_node.close_all_popups() + else: + printerr(str(self.name) + ": Parent node not found or missing 'close_all_popups' method.") + self.hide() # Fallback hide + else: + print(str(self.name) + ": No valid NPC selected to confirm.") + # 即使没有有效选择,也尝试关闭(或提示用户) + var parent_node = get_parent() + if parent_node and parent_node.has_method("close_all_popups"): + parent_node.close_all_popups() # 或者只关闭自己并返回主界面 + else: + self.hide() diff --git a/UI/popup/task_development/proposal/proposal.gd.uid b/UI/popup/task_development/key_output/proposal.gd.uid similarity index 100% rename from UI/popup/task_development/proposal/proposal.gd.uid rename to UI/popup/task_development/key_output/proposal.gd.uid diff --git a/UI/popup/task_development/proposal/proposal.tscn b/UI/popup/task_development/key_output/proposal.tscn similarity index 69% rename from UI/popup/task_development/proposal/proposal.tscn rename to UI/popup/task_development/key_output/proposal.tscn index ce8020f..c669884 100644 --- a/UI/popup/task_development/proposal/proposal.tscn +++ b/UI/popup/task_development/key_output/proposal.tscn @@ -1,11 +1,10 @@ -[gd_scene load_steps=31 format=3 uid="uid://be000l53jxash"] +[gd_scene load_steps=30 format=3 uid="uid://be000l53jxash"] [ext_resource type="Texture2D" uid="uid://pucudatqrcrq" path="res://UI/popup/popup_bg_1.png" id="1_0ruly"] -[ext_resource type="Script" uid="uid://ciqayqceaadw4" path="res://UI/popup/task_development/proposal/proposal.gd" id="2_uudne"] +[ext_resource type="Script" uid="uid://ciqayqceaadw4" path="res://UI/popup/task_development/key_output/proposal.gd" id="2_uudne"] [ext_resource type="Texture2D" uid="uid://dgcugleiv7sfw" path="res://UI/popup/task_development/arrow.png" id="3_uudne"] [ext_resource type="FontFile" uid="uid://egugs822n8gr" path="res://UI/font/AlimamaFangYuanTiVF-Thin.ttf" id="4_csatq"] [ext_resource type="LabelSettings" uid="uid://qcn0aduvrgvw" path="res://UI/tres/task_development_platform_label_settings.tres" id="5_l6j0s"] -[ext_resource type="Texture2D" uid="uid://bb3kyiufyyj05" path="res://Entity/NPC/NPC_1_UI.png" id="5_uudne"] [ext_resource type="Theme" uid="uid://bau80ps6kx783" path="res://UI/tres/Bottom_Info_button_theme.tres" id="6_6v1sj"] [ext_resource type="Texture2D" uid="uid://hdidwixuokxn" path="res://Entity/NPC/npc_ability_icon.png" id="6_ybd2x"] @@ -106,7 +105,7 @@ font_color = Color(0, 0, 0, 1) [sub_resource type="LabelSettings" id="LabelSettings_6v1sj"] font = ExtResource("4_csatq") -font_size = 24 +font_size = 21 font_color = Color(0, 0, 0, 1) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nckjb"] @@ -128,8 +127,18 @@ bg_color = Color(0.913725, 0.913725, 0.913725, 0.913725) [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ci4su"] -[node name="proposal" type="NinePatchRect"] +[node name="proposal" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("2_uudne") + +[node name="proposal" type="NinePatchRect" parent="."] custom_minimum_size = Vector2(500, 350) +layout_mode = 1 anchors_preset = 8 anchor_left = 0.5 anchor_top = 0.5 @@ -147,9 +156,8 @@ patch_margin_left = 8 patch_margin_top = 35 patch_margin_right = 8 patch_margin_bottom = 32 -script = ExtResource("2_uudne") -[node name="Title" type="NinePatchRect" parent="."] +[node name="Title" type="NinePatchRect" parent="proposal"] custom_minimum_size = Vector2(500, 0) layout_mode = 1 anchors_preset = 5 @@ -166,7 +174,7 @@ patch_margin_top = 7 patch_margin_right = 8 patch_margin_bottom = 6 -[node name="Title" type="Label" parent="Title"] +[node name="Title" type="Label" parent="proposal/Title"] layout_mode = 1 anchors_preset = 8 anchor_left = 0.5 @@ -184,7 +192,7 @@ theme_override_font_sizes/font_size = 27 text = "策划案负责人" vertical_alignment = 1 -[node name="previous" type="NinePatchRect" parent="Title"] +[node name="previous" type="NinePatchRect" parent="proposal/Title"] layout_mode = 1 anchors_preset = 4 anchor_top = 0.5 @@ -197,7 +205,7 @@ grow_vertical = 2 texture = ExtResource("3_uudne") region_rect = Rect2(0, 0, 6, 9) -[node name="Button" type="Button" parent="Title/previous"] +[node name="Button" type="Button" parent="proposal/Title/previous"] layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 @@ -209,14 +217,14 @@ theme_override_styles/hover = SubResource("StyleBoxEmpty_bu5lv") theme_override_styles/pressed = SubResource("StyleBoxEmpty_mue51") flat = true -[node name="AnimationPlayer" type="AnimationPlayer" parent="Title/previous"] +[node name="AnimationPlayer" type="AnimationPlayer" parent="proposal/Title/previous"] root_node = NodePath("../../..") libraries = { &"": SubResource("AnimationLibrary_mue51") } autoplay = "base" -[node name="next" type="NinePatchRect" parent="Title"] +[node name="next" type="NinePatchRect" parent="proposal/Title"] layout_mode = 1 anchors_preset = 6 anchor_left = 1.0 @@ -232,7 +240,7 @@ grow_vertical = 2 texture = ExtResource("3_uudne") region_rect = Rect2(6, 0, 6, 9) -[node name="Button" type="Button" parent="Title/next"] +[node name="Button" type="Button" parent="proposal/Title/next"] layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 @@ -244,13 +252,13 @@ theme_override_styles/hover = SubResource("StyleBoxEmpty_r6b7x") theme_override_styles/pressed = SubResource("StyleBoxEmpty_hsiy4") flat = true -[node name="AnimationPlayer" type="AnimationPlayer" parent="Title/next"] +[node name="AnimationPlayer" type="AnimationPlayer" parent="proposal/Title/next"] libraries = { &"": SubResource("AnimationLibrary_r6b7x") } autoplay = "base" -[node name="Option" type="Control" parent="."] +[node name="Option" type="Control" parent="proposal"] layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 @@ -259,7 +267,7 @@ grow_horizontal = 2 grow_vertical = 2 mouse_filter = 2 -[node name="NPC_Info_1" type="HBoxContainer" parent="Option"] +[node name="NPC_Info_1" type="HBoxContainer" parent="proposal/Option"] layout_mode = 1 anchors_preset = 5 anchor_left = 0.5 @@ -271,7 +279,7 @@ offset_bottom = 87.0 grow_horizontal = 2 theme_override_constants/separation = 160 -[node name="Name" type="Label" parent="Option/NPC_Info_1"] +[node name="Name" type="Label" parent="proposal/Option/NPC_Info_1"] layout_mode = 2 theme_override_colors/font_color = Color(0, 0, 0, 1) theme_override_font_sizes/font_size = 24 @@ -279,7 +287,7 @@ text = "米子一" label_settings = SubResource("LabelSettings_l6j0s") horizontal_alignment = 1 -[node name="Staff" type="Label" parent="Option/NPC_Info_1"] +[node name="Staff" type="Label" parent="proposal/Option/NPC_Info_1"] custom_minimum_size = Vector2(140, 0) layout_mode = 2 theme_override_colors/font_color = Color(0, 0, 0, 1) @@ -288,7 +296,7 @@ theme_override_font_sizes/font_size = 20 text = "员工" horizontal_alignment = 2 -[node name="NPC_Info_2" type="NinePatchRect" parent="Option"] +[node name="NPC_Info_2" type="NinePatchRect" parent="proposal/Option"] custom_minimum_size = Vector2(440, 200) layout_mode = 1 anchors_preset = 8 @@ -309,7 +317,7 @@ patch_margin_top = 33 patch_margin_right = 2 patch_margin_bottom = 33 -[node name="Info_List_0" type="VBoxContainer" parent="Option/NPC_Info_2"] +[node name="Info_List_0" type="VBoxContainer" parent="proposal/Option/NPC_Info_2"] custom_minimum_size = Vector2(0, 95) layout_mode = 0 offset_left = 26.0 @@ -318,29 +326,30 @@ offset_right = 185.0 offset_bottom = 147.0 theme_override_constants/separation = 14 -[node name="Job" type="HBoxContainer" parent="Option/NPC_Info_2/Info_List_0"] +[node name="Job" type="HBoxContainer" parent="proposal/Option/NPC_Info_2/Info_List_0"] +custom_minimum_size = Vector2(180, 0) layout_mode = 2 -theme_override_constants/separation = 25 +theme_override_constants/separation = 32 -[node name="Label" type="Label" parent="Option/NPC_Info_2/Info_List_0/Job"] +[node name="Title" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_0/Job"] custom_minimum_size = Vector2(100, 0) layout_mode = 2 text = "产品总监" label_settings = SubResource("LabelSettings_6v1sj") -[node name="Level" type="Label" parent="Option/NPC_Info_2/Info_List_0/Job"] +[node name="Level" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_0/Job"] +custom_minimum_size = Vector2(50, 0) layout_mode = 2 text = "Lv1" label_settings = SubResource("LabelSettings_6v1sj") horizontal_alignment = 2 -[node name="Icon" type="TextureRect" parent="Option/NPC_Info_2/Info_List_0"] +[node name="Icon" type="TextureRect" parent="proposal/Option/NPC_Info_2/Info_List_0"] custom_minimum_size = Vector2(95, 95) layout_mode = 2 -texture = ExtResource("5_uudne") stretch_mode = 5 -[node name="Info_List_1" type="GridContainer" parent="Option/NPC_Info_2"] +[node name="Info_List_1" type="GridContainer" parent="proposal/Option/NPC_Info_2"] layout_mode = 1 anchors_preset = 6 anchor_left = 1.0 @@ -355,17 +364,17 @@ grow_horizontal = 0 grow_vertical = 2 theme_override_constants/v_separation = 7 -[node name="Info_1" type="HBoxContainer" parent="Option/NPC_Info_2/Info_List_1"] +[node name="Info_1" type="HBoxContainer" parent="proposal/Option/NPC_Info_2/Info_List_1"] layout_mode = 2 theme_override_constants/separation = 0 -[node name="icon" type="NinePatchRect" parent="Option/NPC_Info_2/Info_List_1/Info_1"] +[node name="icon" type="NinePatchRect" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_1"] custom_minimum_size = Vector2(28, 28) layout_mode = 2 texture = ExtResource("6_ybd2x") region_rect = Rect2(38, 30, 20, 15) -[node name="title" type="Label" parent="Option/NPC_Info_2/Info_List_1/Info_1"] +[node name="title" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_1"] custom_minimum_size = Vector2(60, 0) layout_mode = 2 theme_override_fonts/font = ExtResource("4_csatq") @@ -374,24 +383,24 @@ text = "策划" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 1 -[node name="info" type="Label" parent="Option/NPC_Info_2/Info_List_1/Info_1"] +[node name="info" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_1"] custom_minimum_size = Vector2(100, 0) layout_mode = 2 text = "80" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 1 -[node name="Info_2" type="HBoxContainer" parent="Option/NPC_Info_2/Info_List_1"] +[node name="Info_2" type="HBoxContainer" parent="proposal/Option/NPC_Info_2/Info_List_1"] layout_mode = 2 theme_override_constants/separation = 0 -[node name="icon" type="NinePatchRect" parent="Option/NPC_Info_2/Info_List_1/Info_2"] +[node name="icon" type="NinePatchRect" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_2"] custom_minimum_size = Vector2(28, 28) layout_mode = 2 texture = ExtResource("6_ybd2x") region_rect = Rect2(12, 31, 17, 16) -[node name="title" type="Label" parent="Option/NPC_Info_2/Info_List_1/Info_2"] +[node name="title" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_2"] custom_minimum_size = Vector2(60, 0) layout_mode = 2 theme_override_fonts/font = ExtResource("4_csatq") @@ -400,24 +409,24 @@ text = "程序" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 1 -[node name="info" type="Label" parent="Option/NPC_Info_2/Info_List_1/Info_2"] +[node name="info" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_2"] custom_minimum_size = Vector2(100, 0) layout_mode = 2 text = "80" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 1 -[node name="Info_3" type="HBoxContainer" parent="Option/NPC_Info_2/Info_List_1"] +[node name="Info_3" type="HBoxContainer" parent="proposal/Option/NPC_Info_2/Info_List_1"] layout_mode = 2 theme_override_constants/separation = 0 -[node name="icon" type="NinePatchRect" parent="Option/NPC_Info_2/Info_List_1/Info_3"] +[node name="icon" type="NinePatchRect" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_3"] custom_minimum_size = Vector2(28, 28) layout_mode = 2 texture = ExtResource("6_ybd2x") region_rect = Rect2(63, 29, 21, 16) -[node name="title" type="Label" parent="Option/NPC_Info_2/Info_List_1/Info_3"] +[node name="title" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_3"] custom_minimum_size = Vector2(60, 0) layout_mode = 2 theme_override_fonts/font = ExtResource("4_csatq") @@ -426,24 +435,24 @@ text = "美术" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 1 -[node name="info" type="Label" parent="Option/NPC_Info_2/Info_List_1/Info_3"] +[node name="info" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_3"] custom_minimum_size = Vector2(100, 0) layout_mode = 2 text = "80" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 1 -[node name="Info_4" type="HBoxContainer" parent="Option/NPC_Info_2/Info_List_1"] +[node name="Info_4" type="HBoxContainer" parent="proposal/Option/NPC_Info_2/Info_List_1"] layout_mode = 2 theme_override_constants/separation = 0 -[node name="icon" type="NinePatchRect" parent="Option/NPC_Info_2/Info_List_1/Info_4"] +[node name="icon" type="NinePatchRect" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_4"] custom_minimum_size = Vector2(28, 28) layout_mode = 2 texture = ExtResource("6_ybd2x") region_rect = Rect2(92, 29, 22, 16) -[node name="title" type="Label" parent="Option/NPC_Info_2/Info_List_1/Info_4"] +[node name="title" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_4"] custom_minimum_size = Vector2(60, 0) layout_mode = 2 theme_override_fonts/font = ExtResource("4_csatq") @@ -452,104 +461,103 @@ text = "音频" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 1 -[node name="info" type="Label" parent="Option/NPC_Info_2/Info_List_1/Info_4"] +[node name="info" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_1/Info_4"] custom_minimum_size = Vector2(100, 0) layout_mode = 2 text = "80" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 1 -[node name="Info_List_2" type="HBoxContainer" parent="Option/NPC_Info_2"] -custom_minimum_size = Vector2(160, 10) +[node name="Info_List_2" type="HBoxContainer" parent="proposal/Option/NPC_Info_2"] layout_mode = 1 -offset_left = 27.0 -offset_top = 159.0 -offset_right = 187.0 -offset_bottom = 169.0 +offset_left = 49.0 +offset_top = 164.0 +offset_right = 169.0 +offset_bottom = 164.0 theme_override_constants/separation = 0 alignment = 1 -[node name="Segment_1" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_1" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 10) +layout_mode = 2 + +[node name="Segment_2" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_2" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_3" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_3" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_4" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_4" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_5" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_5" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_6" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_6" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_7" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_7" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_8" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_8" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_9" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_9" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_10" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_10" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_11" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_11" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_12" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_12" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_13" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_13" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_14" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_14" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_15" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_15" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_16" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_16" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_17" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_17" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_18" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_18" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_19" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_19" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] +[node name="Segment_20" type="ColorRect" parent="proposal/Option/NPC_Info_2/Info_List_2"] custom_minimum_size = Vector2(6, 0) layout_mode = 2 -[node name="Segment_20" type="ColorRect" parent="Option/NPC_Info_2/Info_List_2"] -custom_minimum_size = Vector2(6, 0) -layout_mode = 2 - -[node name="Info_List_3" type="HBoxContainer" parent="Option/NPC_Info_2"] +[node name="Info_List_3" type="HBoxContainer" parent="proposal/Option/NPC_Info_2"] layout_mode = 1 anchors_preset = 7 anchor_left = 0.5 @@ -563,10 +571,10 @@ offset_bottom = -10.0 grow_horizontal = 2 grow_vertical = 0 -[node name="info_4" type="HBoxContainer" parent="Option/NPC_Info_2/Info_List_3"] +[node name="info_4" type="HBoxContainer" parent="proposal/Option/NPC_Info_2/Info_List_3"] layout_mode = 2 -[node name="title" type="Label" parent="Option/NPC_Info_2/Info_List_3/info_4"] +[node name="title" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_3/info_4"] custom_minimum_size = Vector2(100, 0) layout_mode = 2 theme_override_fonts/font = ExtResource("4_csatq") @@ -575,18 +583,18 @@ text = "费用" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 1 -[node name="info" type="Label" parent="Option/NPC_Info_2/Info_List_3/info_4"] +[node name="info" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_3/info_4"] custom_minimum_size = Vector2(70, 0) layout_mode = 2 text = "500" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 1 -[node name="info_5" type="HBoxContainer" parent="Option/NPC_Info_2/Info_List_3"] +[node name="info_5" type="HBoxContainer" parent="proposal/Option/NPC_Info_2/Info_List_3"] visible = false layout_mode = 2 -[node name="title" type="Label" parent="Option/NPC_Info_2/Info_List_3/info_5"] +[node name="title" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_3/info_5"] custom_minimum_size = Vector2(100, 0) layout_mode = 2 theme_override_styles/normal = SubResource("StyleBoxFlat_v0qi7") @@ -594,20 +602,20 @@ text = "开发次数" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 1 -[node name="info" type="Label" parent="Option/NPC_Info_2/Info_List_3/info_5"] +[node name="info" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_3/info_5"] custom_minimum_size = Vector2(30, 0) layout_mode = 2 text = "0" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 2 -[node name="unit" type="Label" parent="Option/NPC_Info_2/Info_List_3/info_5"] +[node name="unit" type="Label" parent="proposal/Option/NPC_Info_2/Info_List_3/info_5"] layout_mode = 2 text = "次" label_settings = ExtResource("5_l6j0s") horizontal_alignment = 2 -[node name="Confirm" type="Button" parent="."] +[node name="Confirm" type="Button" parent="proposal"] custom_minimum_size = Vector2(70, 0) layout_mode = 1 anchors_preset = 7 diff --git a/UI/popup/task_development/key_output/work_out.tscn b/UI/popup/task_development/key_output/work_out.tscn new file mode 100644 index 0000000..cae3329 --- /dev/null +++ b/UI/popup/task_development/key_output/work_out.tscn @@ -0,0 +1,481 @@ +[gd_scene load_steps=16 format=3 uid="uid://bdnfnakfrm6ee"] + +[ext_resource type="Texture2D" uid="uid://pucudatqrcrq" path="res://UI/popup/popup_bg_1.png" id="2_gks7y"] +[ext_resource type="FontFile" uid="uid://egugs822n8gr" path="res://UI/font/AlimamaFangYuanTiVF-Thin.ttf" id="4_yj04l"] +[ext_resource type="Texture2D" uid="uid://hdidwixuokxn" path="res://Entity/NPC/npc_ability_icon.png" id="5_gp1lg"] +[ext_resource type="LabelSettings" uid="uid://qcn0aduvrgvw" path="res://UI/tres/task_development_platform_label_settings.tres" id="6_slso3"] +[ext_resource type="Theme" uid="uid://bau80ps6kx783" path="res://UI/tres/Bottom_Info_button_theme.tres" id="7_d7mog"] + +[sub_resource type="LabelSettings" id="LabelSettings_l6j0s"] +font = ExtResource("4_yj04l") +font_size = 23 +font_color = Color(0, 0, 0, 1) + +[sub_resource type="LabelSettings" id="LabelSettings_6v1sj"] +font = ExtResource("4_yj04l") +font_size = 21 +font_color = Color(0, 0, 0, 1) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_nckjb"] +bg_color = Color(0.913725, 0.913725, 0.913725, 0.913725) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qrj6y"] +bg_color = Color(0.913725, 0.913725, 0.913725, 0.913725) + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_v0qi7"] +bg_color = Color(0.913725, 0.913725, 0.913725, 0.913725) + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_rl25l"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tndxe"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xx8ge"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ep6fu"] + +[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ci4su"] + +[node name="work_out" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="BG" type="NinePatchRect" parent="."] +custom_minimum_size = Vector2(500, 350) +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -250.0 +offset_top = -175.0 +offset_right = 250.0 +offset_bottom = 175.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = ExtResource("2_gks7y") +region_rect = Rect2(1, 35, 86, 53) +patch_margin_left = 8 +patch_margin_top = 35 +patch_margin_right = 8 +patch_margin_bottom = 32 + +[node name="Title" type="NinePatchRect" parent="BG"] +custom_minimum_size = Vector2(500, 0) +layout_mode = 1 +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -250.0 +offset_right = 250.0 +offset_bottom = 44.0 +grow_horizontal = 2 +texture = ExtResource("2_gks7y") +region_rect = Rect2(1, 27, 86, 8) +patch_margin_left = 8 +patch_margin_top = 7 +patch_margin_right = 8 +patch_margin_bottom = 6 + +[node name="Title" type="Label" parent="BG/Title"] +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -34.5 +offset_top = -18.0 +offset_right = 34.5 +offset_bottom = 18.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_font_sizes/font_size = 27 +text = "策划案负责人" +vertical_alignment = 1 + +[node name="Option" type="Control" parent="BG"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 + +[node name="NPC_Info_1" type="HBoxContainer" parent="BG/Option"] +layout_mode = 1 +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -170.0 +offset_top = 47.0 +offset_right = 202.0 +offset_bottom = 87.0 +grow_horizontal = 2 +theme_override_constants/separation = 160 + +[node name="Name" type="Label" parent="BG/Option/NPC_Info_1"] +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_font_sizes/font_size = 24 +text = "米子一" +label_settings = SubResource("LabelSettings_l6j0s") +horizontal_alignment = 1 + +[node name="Staff" type="Label" parent="BG/Option/NPC_Info_1"] +custom_minimum_size = Vector2(140, 0) +layout_mode = 2 +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_fonts/font = ExtResource("4_yj04l") +theme_override_font_sizes/font_size = 20 +text = "员工" +horizontal_alignment = 2 + +[node name="NPC_Info_2" type="NinePatchRect" parent="BG/Option"] +custom_minimum_size = Vector2(440, 200) +layout_mode = 1 +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -220.0 +offset_top = -92.0 +offset_right = 220.0 +offset_bottom = 130.0 +grow_horizontal = 2 +grow_vertical = 2 +texture = ExtResource("2_gks7y") +region_rect = Rect2(92, 38, 76, 34) +patch_margin_left = 2 +patch_margin_top = 33 +patch_margin_right = 2 +patch_margin_bottom = 33 + +[node name="Info_List_0" type="VBoxContainer" parent="BG/Option/NPC_Info_2"] +custom_minimum_size = Vector2(0, 95) +layout_mode = 0 +offset_left = 26.0 +offset_top = 23.0 +offset_right = 185.0 +offset_bottom = 147.0 +theme_override_constants/separation = 14 + +[node name="Job" type="HBoxContainer" parent="BG/Option/NPC_Info_2/Info_List_0"] +custom_minimum_size = Vector2(180, 0) +layout_mode = 2 +theme_override_constants/separation = 32 + +[node name="Title" type="Label" parent="BG/Option/NPC_Info_2/Info_List_0/Job"] +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +text = "产品总监" +label_settings = SubResource("LabelSettings_6v1sj") + +[node name="Level" type="Label" parent="BG/Option/NPC_Info_2/Info_List_0/Job"] +custom_minimum_size = Vector2(50, 0) +layout_mode = 2 +text = "Lv1" +label_settings = SubResource("LabelSettings_6v1sj") +horizontal_alignment = 2 + +[node name="Icon" type="TextureRect" parent="BG/Option/NPC_Info_2/Info_List_0"] +custom_minimum_size = Vector2(95, 95) +layout_mode = 2 +stretch_mode = 5 + +[node name="Info_List_1" type="GridContainer" parent="BG/Option/NPC_Info_2"] +layout_mode = 1 +anchors_preset = 6 +anchor_left = 1.0 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +offset_left = -204.0 +offset_top = -87.0 +offset_right = -8.0 +offset_bottom = 46.0 +grow_horizontal = 0 +grow_vertical = 2 +theme_override_constants/v_separation = 7 + +[node name="Info_1" type="HBoxContainer" parent="BG/Option/NPC_Info_2/Info_List_1"] +layout_mode = 2 +theme_override_constants/separation = 0 + +[node name="icon" type="NinePatchRect" parent="BG/Option/NPC_Info_2/Info_List_1/Info_1"] +custom_minimum_size = Vector2(28, 28) +layout_mode = 2 +texture = ExtResource("5_gp1lg") +region_rect = Rect2(38, 30, 20, 15) + +[node name="title" type="Label" parent="BG/Option/NPC_Info_2/Info_List_1/Info_1"] +custom_minimum_size = Vector2(60, 0) +layout_mode = 2 +theme_override_fonts/font = ExtResource("4_yj04l") +theme_override_styles/normal = SubResource("StyleBoxFlat_nckjb") +text = "策划" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 1 + +[node name="info" type="Label" parent="BG/Option/NPC_Info_2/Info_List_1/Info_1"] +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +text = "80" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 1 + +[node name="Info_2" type="HBoxContainer" parent="BG/Option/NPC_Info_2/Info_List_1"] +layout_mode = 2 +theme_override_constants/separation = 0 + +[node name="icon" type="NinePatchRect" parent="BG/Option/NPC_Info_2/Info_List_1/Info_2"] +custom_minimum_size = Vector2(28, 28) +layout_mode = 2 +texture = ExtResource("5_gp1lg") +region_rect = Rect2(12, 31, 17, 16) + +[node name="title" type="Label" parent="BG/Option/NPC_Info_2/Info_List_1/Info_2"] +custom_minimum_size = Vector2(60, 0) +layout_mode = 2 +theme_override_fonts/font = ExtResource("4_yj04l") +theme_override_styles/normal = SubResource("StyleBoxFlat_nckjb") +text = "程序" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 1 + +[node name="info" type="Label" parent="BG/Option/NPC_Info_2/Info_List_1/Info_2"] +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +text = "80" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 1 + +[node name="Info_3" type="HBoxContainer" parent="BG/Option/NPC_Info_2/Info_List_1"] +layout_mode = 2 +theme_override_constants/separation = 0 + +[node name="icon" type="NinePatchRect" parent="BG/Option/NPC_Info_2/Info_List_1/Info_3"] +custom_minimum_size = Vector2(28, 28) +layout_mode = 2 +texture = ExtResource("5_gp1lg") +region_rect = Rect2(63, 29, 21, 16) + +[node name="title" type="Label" parent="BG/Option/NPC_Info_2/Info_List_1/Info_3"] +custom_minimum_size = Vector2(60, 0) +layout_mode = 2 +theme_override_fonts/font = ExtResource("4_yj04l") +theme_override_styles/normal = SubResource("StyleBoxFlat_nckjb") +text = "美术" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 1 + +[node name="info" type="Label" parent="BG/Option/NPC_Info_2/Info_List_1/Info_3"] +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +text = "80" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 1 + +[node name="Info_4" type="HBoxContainer" parent="BG/Option/NPC_Info_2/Info_List_1"] +layout_mode = 2 +theme_override_constants/separation = 0 + +[node name="icon" type="NinePatchRect" parent="BG/Option/NPC_Info_2/Info_List_1/Info_4"] +custom_minimum_size = Vector2(28, 28) +layout_mode = 2 +texture = ExtResource("5_gp1lg") +region_rect = Rect2(92, 29, 22, 16) + +[node name="title" type="Label" parent="BG/Option/NPC_Info_2/Info_List_1/Info_4"] +custom_minimum_size = Vector2(60, 0) +layout_mode = 2 +theme_override_fonts/font = ExtResource("4_yj04l") +theme_override_styles/normal = SubResource("StyleBoxFlat_nckjb") +text = "音频" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 1 + +[node name="info" type="Label" parent="BG/Option/NPC_Info_2/Info_List_1/Info_4"] +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +text = "80" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 1 + +[node name="Info_List_2" type="HBoxContainer" parent="BG/Option/NPC_Info_2"] +layout_mode = 1 +offset_left = 49.0 +offset_top = 164.0 +offset_right = 169.0 +offset_bottom = 164.0 +theme_override_constants/separation = 0 +alignment = 1 + +[node name="Segment_1" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 10) +layout_mode = 2 + +[node name="Segment_2" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_3" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_4" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_5" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_6" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_7" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_8" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_9" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_10" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_11" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_12" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_13" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_14" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_15" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_16" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_17" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_18" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_19" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Segment_20" type="ColorRect" parent="BG/Option/NPC_Info_2/Info_List_2"] +custom_minimum_size = Vector2(6, 0) +layout_mode = 2 + +[node name="Info_List_3" type="HBoxContainer" parent="BG/Option/NPC_Info_2"] +layout_mode = 1 +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -191.5 +offset_top = -38.0 +offset_right = 191.5 +offset_bottom = -10.0 +grow_horizontal = 2 +grow_vertical = 0 + +[node name="info_4" type="HBoxContainer" parent="BG/Option/NPC_Info_2/Info_List_3"] +layout_mode = 2 + +[node name="title" type="Label" parent="BG/Option/NPC_Info_2/Info_List_3/info_4"] +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +theme_override_fonts/font = ExtResource("4_yj04l") +theme_override_styles/normal = SubResource("StyleBoxFlat_qrj6y") +text = "费用" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 1 + +[node name="info" type="Label" parent="BG/Option/NPC_Info_2/Info_List_3/info_4"] +custom_minimum_size = Vector2(70, 0) +layout_mode = 2 +text = "500" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 1 + +[node name="info_5" type="HBoxContainer" parent="BG/Option/NPC_Info_2/Info_List_3"] +visible = false +layout_mode = 2 + +[node name="title" type="Label" parent="BG/Option/NPC_Info_2/Info_List_3/info_5"] +custom_minimum_size = Vector2(100, 0) +layout_mode = 2 +theme_override_styles/normal = SubResource("StyleBoxFlat_v0qi7") +text = "开发次数" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 1 + +[node name="info" type="Label" parent="BG/Option/NPC_Info_2/Info_List_3/info_5"] +custom_minimum_size = Vector2(30, 0) +layout_mode = 2 +text = "0" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 2 + +[node name="unit" type="Label" parent="BG/Option/NPC_Info_2/Info_List_3/info_5"] +layout_mode = 2 +text = "次" +label_settings = ExtResource("6_slso3") +horizontal_alignment = 2 + +[node name="Confirm" type="Button" parent="BG"] +custom_minimum_size = Vector2(70, 0) +layout_mode = 1 +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -35.0 +offset_top = -43.0 +offset_right = 35.0 +grow_horizontal = 2 +grow_vertical = 0 +theme = ExtResource("7_d7mog") +theme_override_colors/font_color = Color(0, 0, 0, 1) +theme_override_colors/font_focus_color = Color(0, 0, 0, 1) +theme_override_font_sizes/font_size = 23 +theme_override_styles/focus = SubResource("StyleBoxEmpty_rl25l") +theme_override_styles/hover_pressed = SubResource("StyleBoxFlat_tndxe") +theme_override_styles/hover = SubResource("StyleBoxFlat_xx8ge") +theme_override_styles/pressed = SubResource("StyleBoxEmpty_ep6fu") +theme_override_styles/normal = SubResource("StyleBoxEmpty_ci4su") +text = "确定" diff --git a/UI/popup/task_development/proposal/proposal.gd b/UI/popup/task_development/proposal/proposal.gd deleted file mode 100644 index 4d684ff..0000000 --- a/UI/popup/task_development/proposal/proposal.gd +++ /dev/null @@ -1,16 +0,0 @@ -extends NinePatchRect - -@onready var confirm_button: Button = $Confirm - -func _ready() -> void: - var node_name = str(self.name) - add_to_group(node_name) - - if confirm_button: - if not confirm_button.pressed.is_connected(_on_confirm_pressed): - confirm_button.pressed.connect(_on_confirm_pressed) - -func _on_confirm_pressed(): - get_parent().start_task() - self.hide() - get_parent().close_all_popups() diff --git a/UI/popup/task_development/task_development.gd b/UI/popup/task_development/task_development.gd index b424a17..3085c38 100644 --- a/UI/popup/task_development/task_development.gd +++ b/UI/popup/task_development/task_development.gd @@ -23,12 +23,13 @@ var is_active: bool = false # 存储用户在当前配置过程中的临时选择 (使用中文 Key) var task_info: Dictionary = { - "平台": "", # 中文 Key for the selected platform (e.g., "台式 & 笔记本") - "玩法": "", # 中文 Key for the selected gameplay (e.g., "角色扮演(RPG)") - "题材": "", # 中文 Key for the selected theme (e.g., "现代都市") - "开发策略": "", # 中文 Key for the selected strategy (e.g., "正常开发") - "预算": 0, # Calculated budget based on selections - "产品侧重点": {} # To be filled by product_focus popup + "平台": "", + "玩法": "", + "题材": "", + "开发策略": "", + "预算": 0, + "产品侧重点": {}, + "关键环节负责人": [] # <--- 新增并初始化为空数组 } # --- 初始化 --- @@ -273,23 +274,41 @@ func _on_category_button_pressed(popup_node: Control) -> void: # 提供给子弹出窗口调用的接口函数,用于更新选择 -# options: 字典,包含更新的类别和对应的 Key,例如 {"平台": "Switch"} +# options: 字典,包含更新的类别和对应的 Key func update_task_options(options: Dictionary) -> void: var updated = false - for key in options: # key 是 "平台", "玩法" 等中文名 - if task_info.has(key): - var new_value_key = options[key] # new_value_key 是 "Switch" 等中文 Key - if task_info[key] != new_value_key: - task_info[key] = new_value_key + for key in options: + var new_value = options[key] + + if key == "关键环节负责人": + # --- 特殊处理 "关键环节负责人" --- + if not task_info.has(key) or not typeof(task_info[key]) == TYPE_ARRAY: + task_info[key] = [] # 如果不存在或类型不对,则初始化为空数组 + + if not new_value in task_info[key]: # 避免重复添加 (可选,根据需求) + task_info[key].append(new_value) updated = true - print(node_name + ": Option '%s' updated to '%s'." % [key, new_value_key]) + print(node_name + ": Appended '%s' to '%s'. Current: %s" % [new_value, key, task_info[key]]) + else: + print(node_name + ": '%s' already in '%s'. No change." % [new_value, key]) + + elif task_info.has(key): + # --- 原有逻辑处理其他普通键值对 --- + if task_info[key] != new_value: + task_info[key] = new_value + updated = true + print(node_name + ": Option '%s' updated to '%s'." % [key, new_value]) else: - printerr(node_name + ": Invalid key '%s' provided in update_task_options." % key) + printerr(node_name + ": Invalid key '%s' provided in update_task_options and not handled as a special case." % key) if updated: - update_button_texts() # 更新主界面按钮显示名称 - calculate_and_update_budget() # 重新计算预算 - print(node_name + ": Task info updated: ", task_info) # Debug + # 对于 "关键环节负责人" 的更新,通常不需要更新按钮文本或重新计算预算 + # 但如果其他选项更新了,则需要执行 + if not (options.has("关键环节负责人") and options.size() == 1): # 如果不仅仅是更新负责人 + update_button_texts() + calculate_and_update_budget() + + print(node_name + ": Task info updated: ", task_info) # 处理子弹出窗口确认后关闭并返回主页面的逻辑 func _close_child_popup_and_return(child_popup_node: Control) -> void: diff --git a/UI/popup/task_development/task_development.tscn b/UI/popup/task_development/task_development.tscn index a7baa6f..9511d1b 100644 --- a/UI/popup/task_development/task_development.tscn +++ b/UI/popup/task_development/task_development.tscn @@ -11,7 +11,7 @@ [ext_resource type="PackedScene" uid="uid://bej6f0cqirn4j" path="res://UI/popup/task_development/theme/theme.tscn" id="8_nckjb"] [ext_resource type="PackedScene" uid="uid://ctcbxvgljrkvi" path="res://UI/popup/task_development/strategy/strategy.tscn" id="9_6r1e0"] [ext_resource type="PackedScene" uid="uid://dpshanwm4o3by" path="res://UI/popup/task_development/product_focus/product_focus.tscn" id="10_at31c"] -[ext_resource type="PackedScene" uid="uid://be000l53jxash" path="res://UI/popup/task_development/proposal/proposal.tscn" id="12_v0qi7"] +[ext_resource type="PackedScene" uid="uid://be000l53jxash" path="res://UI/popup/task_development/key_output/proposal.tscn" id="12_v0qi7"] [ext_resource type="PackedScene" uid="uid://dtywh0m5odikx" path="res://UI/popup/dialogue.tscn" id="13_kctqw"] [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_xtl2p"] diff --git a/project.godot b/project.godot index 223fb80..d29db4d 100644 --- a/project.godot +++ b/project.godot @@ -10,7 +10,7 @@ config_version=5 [application] -config/name="D5_v3" +config/name="D5" run/main_scene="uid://bhikrxp56speh" config/use_custom_user_dir=true config/custom_user_dir_name="D5_v2\\Data\\Save_Data"