diff --git a/src/Core/MainGame.gd b/src/Core/MainGame.gd index ca40c28..620daf8 100644 --- a/src/Core/MainGame.gd +++ b/src/Core/MainGame.gd @@ -13,3 +13,7 @@ func _ready() -> void: ## 顶部 HUD 的返回主菜单请求。 func _on_top_bar_hud_sign_return_mainmenu() -> void: get_tree().change_scene_to_file("res://src/UI/Panels/MainMenu/MainMenu.tscn") + +## 顶部 HUD 的"管理"按钮请求:打开弟子名录面板。 +func _on_top_bar_hud_sign_open_disciples() -> void: + $DisciplesPanel.show_panel() diff --git a/src/Core/MainGame.tscn b/src/Core/MainGame.tscn index 65a58fc..3d85dae 100644 --- a/src/Core/MainGame.tscn +++ b/src/Core/MainGame.tscn @@ -2,14 +2,18 @@ [ext_resource type="Script" uid="uid://centrk8l54j7c" path="res://src/Core/MainGame.gd" id="1_8bu23"] [ext_resource type="PackedScene" uid="uid://dl0tb68vsw3c6" path="res://src/UI/HUD/TopBarHUD.tscn" id="1_g6xmk"] -[ext_resource type="PackedScene" uid="uid://cahbpjpnmbcfv" path="res://src/UI/Panels/RecruitPanel/RecruitPanel.tscn" id="1_k5nrm"] +[ext_resource type="PackedScene" uid="uid://d4y7q3m6k2x5n7w2" path="res://src/UI/Panels/RecruitPanel/RecruitPanel.tscn" id="1_k5nrm"] +[ext_resource type="PackedScene" path="res://src/UI/Panels/DisciplesPanel/DisciplesPanel.tscn" id="1_d5cpm"] [node name="MainGame" type="Node" unique_id=2053561265] +groups = ["game_scene"] script = ExtResource("1_8bu23") [node name="TopBarHud" parent="." unique_id=1115394694 instance=ExtResource("1_g6xmk")] [node name="RecruitPanel" parent="." unique_id=770000016 instance=ExtResource("1_k5nrm")] -layout_mode = 3 + +[node name="DisciplesPanel" parent="." unique_id=780000015 instance=ExtResource("1_d5cpm")] [connection signal="sign_return_mainmenu" from="TopBarHud" to="." method="_on_top_bar_hud_sign_return_mainmenu"] +[connection signal="sign_open_disciples" from="TopBarHud" to="." method="_on_top_bar_hud_sign_open_disciples"] diff --git a/src/UI/HUD/TopBarHUD.tscn b/src/UI/HUD/TopBarHUD.tscn index 07b7acf..eedeabc 100644 --- a/src/UI/HUD/TopBarHUD.tscn +++ b/src/UI/HUD/TopBarHUD.tscn @@ -163,4 +163,5 @@ theme_override_font_sizes/font_size = 32 text = "返回" [connection signal="button_up" from="HBoxContainer/SpeedGroup/Button_Pause" to="." method="_on_button_pause_button_up"] +[connection signal="button_up" from="HBoxContainer/Button_StaffManagement" to="." method="_on_button_staff_management_button_up"] [connection signal="button_up" from="HBoxContainer/Button_Return" to="." method="_on_button_return_button_up"] diff --git a/src/UI/HUD/top_bar_hud.gd b/src/UI/HUD/top_bar_hud.gd index 73dbc8c..0b4b7ff 100644 --- a/src/UI/HUD/top_bar_hud.gd +++ b/src/UI/HUD/top_bar_hud.gd @@ -4,6 +4,8 @@ extends Control ## 请求返回主菜单。 signal sign_return_mainmenu +## 请求打开弟子名录面板。 +signal sign_open_disciples @onready var time_label: Label = %Value_Time @onready var currency_label: Label = %Value_Currency @@ -44,6 +46,10 @@ func _on_reputation_changed(new_value: int, _delta: int) -> void: func _on_button_return_button_up() -> void: sign_return_mainmenu.emit() +## 点击"管理"按钮:请求打开弟子名录面板(由 MainGame 处理)。 +func _on_button_staff_management_button_up() -> void: + sign_open_disciples.emit() + ## 点击暂停/继续按钮,切换后刷新按钮状态。 func _on_button_pause_button_up() -> void: TimeSystem.toggle_pause() diff --git a/src/UI/Panels/DisciplesPanel/DiscipleDetailPanel.tscn b/src/UI/Panels/DisciplesPanel/DiscipleDetailPanel.tscn new file mode 100644 index 0000000..0c51b7f --- /dev/null +++ b/src/UI/Panels/DisciplesPanel/DiscipleDetailPanel.tscn @@ -0,0 +1,79 @@ +[gd_scene format=3 uid="uid://b3i7xibxjq303"] + +[ext_resource type="Script" path="res://src/UI/Panels/DisciplesPanel/disciple_detail_panel.gd" id="1_script"] +[ext_resource type="FontFile" uid="uid://drt448qncx27p" path="res://assets/fonts/dingliezhuhaifont-20240831GengXinBan)-2.ttf" id="2_font"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dialog"] +bg_color = Color(0.07, 0.13, 0.12, 0.97) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.4, 0.72, 0.6, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[node name="DiscipleDetailPanel" type="Control" unique_id=781000001] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_script") + +[node name="Backdrop" type="ColorRect" parent="." unique_id=781000002] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.02, 0.05, 0.05, 0.65) + +[node name="CenterContainer" type="CenterContainer" parent="." unique_id=781000003] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Panel" type="PanelContainer" parent="CenterContainer" unique_id=781000004] +theme_override_styles/panel = SubResource("StyleBoxFlat_dialog") + +[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/Panel" unique_id=781000005] +theme_override_constants/margin_left = 32 +theme_override_constants/margin_top = 24 +theme_override_constants/margin_right = 32 +theme_override_constants/margin_bottom = 24 + +[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/Panel/MarginContainer" unique_id=781000006] +theme_override_constants/separation = 16 + +[node name="TitleLabel" type="Label" parent="CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=781000007] +unique_name_in_owner = true +theme_override_fonts/font = ExtResource("2_font") +theme_override_font_sizes/font_size = 30 +theme_override_colors/font_color = Color(0.82, 0.95, 0.88, 1) +text = "弟子详情" + +[node name="InfoLabel" type="Label" parent="CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=781000008] +unique_name_in_owner = true +theme_override_fonts/font = ExtResource("2_font") +theme_override_font_sizes/font_size = 22 +theme_override_colors/font_color = Color(0.82, 0.95, 0.88, 1) +text = "" + +[node name="ButtonRow" type="HBoxContainer" parent="CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=781000009] + +[node name="Spacer" type="Control" parent="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow" unique_id=781000010] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Button_Close" type="Button" parent="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow" unique_id=781000011] +unique_name_in_owner = true +theme_override_fonts/font = ExtResource("2_font") +theme_override_font_sizes/font_size = 22 +text = "关闭" + +[connection signal="button_up" from="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow/Button_Close" to="." method="_on_button_close_button_up"] diff --git a/src/UI/Panels/DisciplesPanel/DisciplesPanel.tscn b/src/UI/Panels/DisciplesPanel/DisciplesPanel.tscn new file mode 100644 index 0000000..6eb57c7 --- /dev/null +++ b/src/UI/Panels/DisciplesPanel/DisciplesPanel.tscn @@ -0,0 +1,104 @@ +[gd_scene format=3 uid="uid://cahux61qqblje"] + +[ext_resource type="Script" path="res://src/UI/Panels/DisciplesPanel/disciples_panel.gd" id="1_script"] +[ext_resource type="FontFile" uid="uid://drt448qncx27p" path="res://assets/fonts/dingliezhuhaifont-20240831GengXinBan)-2.ttf" id="2_font"] +[ext_resource type="PackedScene" uid="uid://b3i7xibxjq303" path="res://src/UI/Panels/DisciplesPanel/DiscipleDetailPanel.tscn" id="3_detail"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dialog"] +bg_color = Color(0.07, 0.13, 0.12, 0.97) +border_width_left = 2 +border_width_top = 2 +border_width_right = 2 +border_width_bottom = 2 +border_color = Color(0.4, 0.72, 0.6, 1) +corner_radius_top_left = 8 +corner_radius_top_right = 8 +corner_radius_bottom_right = 8 +corner_radius_bottom_left = 8 + +[node name="DisciplesPanel" type="Control" unique_id=1362665771] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_script") + +[node name="Backdrop" type="ColorRect" parent="." unique_id=1162009235] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +color = Color(0.02, 0.05, 0.05, 0.65) + +[node name="CenterContainer" type="CenterContainer" parent="." unique_id=47958673] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Panel" type="PanelContainer" parent="CenterContainer" unique_id=1341680090] +layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_dialog") + +[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/Panel" unique_id=1155028384] +layout_mode = 2 +theme_override_constants/margin_left = 28 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 28 +theme_override_constants/margin_bottom = 20 + +[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/Panel/MarginContainer" unique_id=523691907] +layout_mode = 2 +theme_override_constants/separation = 12 + +[node name="TitleLabel" type="Label" parent="CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=780000007] +unique_name_in_owner = true +layout_mode = 2 +theme_override_fonts/font = ExtResource("2_font") +theme_override_font_sizes/font_size = 30 +theme_override_colors/font_color = Color(0.82, 0.95, 0.88, 1) +text = "弟子名录" + +[node name="ScrollContainer" type="ScrollContainer" parent="CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=780000008] +custom_minimum_size = Vector2(640, 340) +layout_mode = 2 +size_flags_vertical = 3 + +[node name="ListContainer" type="VBoxContainer" parent="CenterContainer/Panel/MarginContainer/VBoxContainer/ScrollContainer" unique_id=780000009] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="EmptyLabel" type="Label" parent="CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=780000010] +unique_name_in_owner = true +layout_mode = 2 +theme_override_fonts/font = ExtResource("2_font") +theme_override_font_sizes/font_size = 22 +theme_override_colors/font_color = Color(0.6, 0.78, 0.7, 1) +text = "暂无弟子" + +[node name="ButtonRow" type="HBoxContainer" parent="CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=780000011] +layout_mode = 2 + +[node name="Spacer" type="Control" parent="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow" unique_id=780000012] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Button_Close" type="Button" parent="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow" unique_id=780000013] +unique_name_in_owner = true +layout_mode = 2 +theme_override_fonts/font = ExtResource("2_font") +theme_override_font_sizes/font_size = 22 +text = "关闭" + +[node name="DiscipleDetailPanel" parent="." unique_id=780000014 instance=ExtResource("3_detail")] +unique_name_in_owner = true + +[connection signal="gui_input" from="Backdrop" to="." method="_on_backdrop_gui_input"] +[connection signal="button_up" from="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow/Button_Close" to="." method="hide_panel"] diff --git a/src/UI/Panels/DisciplesPanel/disciple_detail_panel.gd b/src/UI/Panels/DisciplesPanel/disciple_detail_panel.gd new file mode 100644 index 0000000..750cb13 --- /dev/null +++ b/src/UI/Panels/DisciplesPanel/disciple_detail_panel.gd @@ -0,0 +1,29 @@ +## 弟子详情弹窗(挂载于 DiscipleDetailPanel.tscn)。 +## 静态展示弟子信息(资质/年龄/灵根/境界/编号/入宗时间), +## 修炼进度等动态内容留待 D5 修炼循环填充。 +extends Control + +@onready var title_label: Label = %TitleLabel +@onready var info_label: Label = %InfoLabel + + +func _ready() -> void: + visible = false + +## 显示指定弟子的详情。 +## @param d: 要展示的弟子 +func show_detail(d: Disciple) -> void: + title_label.text = d.name + ("(天灵根)" if d.is_heavenly else "") + info_label.text = "资质:%s\n年龄:%d岁\n灵根:%s\n境界:%s\n编号:%d\n入宗时间:%s" % [ + d.get_aptitude_name(), + d.age, + d.get_roots_text(), + d.get_realm_text(), + d.id, + d.get_join_date_text(), + ] + visible = true + +## 点击"关闭"按钮。 +func _on_button_close_button_up() -> void: + visible = false diff --git a/src/UI/Panels/DisciplesPanel/disciple_detail_panel.gd.uid b/src/UI/Panels/DisciplesPanel/disciple_detail_panel.gd.uid new file mode 100644 index 0000000..c8c12e1 --- /dev/null +++ b/src/UI/Panels/DisciplesPanel/disciple_detail_panel.gd.uid @@ -0,0 +1 @@ +uid://da0d24brddyxk diff --git a/src/UI/Panels/DisciplesPanel/disciples_panel.gd b/src/UI/Panels/DisciplesPanel/disciples_panel.gd new file mode 100644 index 0000000..cc0b8bf --- /dev/null +++ b/src/UI/Panels/DisciplesPanel/disciples_panel.gd @@ -0,0 +1,89 @@ +## 弟子名录列表面板(挂载于 DisciplesPanel.tscn)。 +## 展示宗门已入宗弟子名录,点条目"详情"打开详情弹窗。 +## 监听名录变化信号实时刷新,打开面板不暂停时间。 +extends Control + +## 资质颜色提示(天骄金色、上品亮青,其余默认)。 +const APTITUDE_COLORS := { + Disciple.Aptitude.HEAVENLY: Color(1.0, 0.84, 0.35), + Disciple.Aptitude.SUPERIOR: Color(0.55, 0.9, 0.8), +} + +@onready var title_label: Label = %TitleLabel +@onready var list_container: VBoxContainer = %ListContainer +@onready var empty_label: Label = %EmptyLabel +@onready var detail_panel: Control = %DiscipleDetailPanel + + +func _ready() -> void: + # 名录变化时刷新(面板打开期间也同步) + DiscipleManager.disciples_changed.connect(_on_disciples_changed) + visible = false + +## 打开面板并刷新列表。 +func show_panel() -> void: + _refresh_list() + visible = true + +## 关闭面板(含子层详情弹窗,作为子节点随父隐藏)。 +func hide_panel() -> void: + visible = false + +## 点击遮罩关闭面板。 +func _on_backdrop_gui_input(event: InputEvent) -> void: + if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT: + hide_panel() + +## 名录变化时刷新列表。 +func _on_disciples_changed() -> void: + if visible: + _refresh_list() + +## 重建列表:清空旧条目,按名录顺序逐条生成。 +func _refresh_list() -> void: + for child in list_container.get_children(): + child.queue_free() + for d in DiscipleManager.disciples: + _add_entry(d) + empty_label.visible = DiscipleManager.disciples.is_empty() + title_label.text = "弟子名录(%d 人)" % DiscipleManager.disciples.size() + +## 添加一名弟子的行条目:姓名/资质/灵根/境界 + 详情按钮。 +## @param d: 已入宗弟子 +func _add_entry(d: Disciple) -> void: + var row := HBoxContainer.new() + row.add_theme_constant_override("separation", 12) + + var name_label := Label.new() + name_label.text = d.name + name_label.custom_minimum_size = Vector2(90, 0) + row.add_child(name_label) + + var aptitude_label := Label.new() + aptitude_label.text = d.get_aptitude_name() + ("·天灵根" if d.is_heavenly else "") + if APTITUDE_COLORS.has(d.aptitude): + aptitude_label.add_theme_color_override("font_color", APTITUDE_COLORS[d.aptitude]) + aptitude_label.custom_minimum_size = Vector2(130, 0) + row.add_child(aptitude_label) + + var roots_label := Label.new() + roots_label.text = d.get_roots_text() + "灵根" + roots_label.custom_minimum_size = Vector2(160, 0) + row.add_child(roots_label) + + var realm_label := Label.new() + realm_label.text = d.get_realm_text() + realm_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL + row.add_child(realm_label) + + var detail_button := Button.new() + detail_button.text = "详情" + detail_button.button_up.connect(_on_detail_button_up.bind(d)) + row.add_child(detail_button) + + list_container.add_child(row) + +## 点击条目"详情"按钮:在子层弹窗中展示该弟子信息。 +## @param d: 对应弟子 +func _on_detail_button_up(d: Disciple) -> void: + detail_panel.show_detail(d) diff --git a/src/UI/Panels/DisciplesPanel/disciples_panel.gd.uid b/src/UI/Panels/DisciplesPanel/disciples_panel.gd.uid new file mode 100644 index 0000000..7e21257 --- /dev/null +++ b/src/UI/Panels/DisciplesPanel/disciples_panel.gd.uid @@ -0,0 +1 @@ +uid://cfqhusp28ku5x