更新proposal方法,但是还不能正常工作

This commit is contained in:
jkboy 2025-05-09 23:39:04 +08:00
parent b35146eadd
commit dd829f599b
17 changed files with 1338 additions and 549 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -7,7 +7,8 @@ extends Node
# --- 内部数据缓存 ---
var _settings_data: Dictionary = {}
var _task_development_data: Dictionary = {}
var _task_development_data: Dictionary = {}
var _npc_data: Dictionary = {} # MODIFIED: 新增NPC数据缓存
var _is_data_loaded: bool = false
@ -25,14 +26,9 @@ func ensure_data_loaded() -> 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

View File

@ -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

28
Data/npc.json Normal file
View File

@ -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
}
}
}

View File

@ -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
}
}

View File

@ -1,5 +1,4 @@
# TimeManager.gd
# Autoload Singleton
# 负责驱动游戏内时间的流逝。
# 使用 Timer 节点每秒触发一次时间推进逻辑。
# 从 GameState 读取暂停状态和当前时间,并将更新后的时间写回 GameState。

View File

@ -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={}

View File

@ -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 实例是否有效

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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 = "确定"

View File

@ -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()

View File

@ -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:

View File

@ -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"]

View File

@ -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"