feat: 建筑面板——资源按钮入口+建造升级产出(D6 核心)
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
> 对应开发计划表 D6(8/8):① 灵石矿场景 ② 建造→产出 ③ 升级。交付标准:建筑产资源,升级加速。
|
> 对应开发计划表 D6(8/8):① 灵石矿场景 ② 建造→产出 ③ 升级。交付标准:建筑产资源,升级加速。
|
||||||
> 本文档只描述设计,不包含代码。
|
> 本文档只描述设计,不包含代码。
|
||||||
> 状态:步骤 1–2 已实现(食物资源/HUD 灵米显示/开局 500 灵石+100 灵米配置驱动),步骤 3+ 待实现
|
> 状态:步骤 1–2、4、6 已实现(食物资源/HUD 灵米/开局赠送配置化;Building+BuildingManager 建造升级产出;BuildingsPanel 面板+资源按钮+暂停恢复),步骤 3 部分(建筑参数配置已加)、5 待实现
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ SectManager="*res://src/Core/SectManager.gd"
|
|||||||
GameConfig="*res://src/Core/GameConfig.gd"
|
GameConfig="*res://src/Core/GameConfig.gd"
|
||||||
DiscipleManager="*res://src/Character/DiscipleManager.gd"
|
DiscipleManager="*res://src/Character/DiscipleManager.gd"
|
||||||
CultivationManager="*res://src/Character/CultivationManager.gd"
|
CultivationManager="*res://src/Character/CultivationManager.gd"
|
||||||
|
BuildingManager="*res://src/Sect/BuildingManager.gd"
|
||||||
|
|
||||||
[display]
|
[display]
|
||||||
|
|
||||||
|
|||||||
@@ -34,3 +34,16 @@ hud_font_size=24 ; HUD 字体大小
|
|||||||
[building] ; 建筑系统通用
|
[building] ; 建筑系统通用
|
||||||
starting_spirit_stones=500 ; 开局赠送灵石
|
starting_spirit_stones=500 ; 开局赠送灵石
|
||||||
starting_food=100 ; 开局赠送灵米
|
starting_food=100 ; 开局赠送灵米
|
||||||
|
max_level=10 ; 建筑等级上限
|
||||||
|
|
||||||
|
[building_mine] ; 灵石矿
|
||||||
|
cost=200 ; 建造价(灵石)
|
||||||
|
output=10 ; 日产出(灵石)
|
||||||
|
upgrade_cost_x=2.0 ; 升级价格倍率
|
||||||
|
upgrade_output_x=1.5 ; 升级产出倍率
|
||||||
|
|
||||||
|
[building_field] ; 灵田
|
||||||
|
cost=100 ; 建造价(灵石)
|
||||||
|
output=5 ; 日产出(灵米)
|
||||||
|
upgrade_cost_x=2.0 ; 升级价格倍率
|
||||||
|
upgrade_output_x=1.5 ; 升级产出倍率
|
||||||
|
|||||||
@@ -47,6 +47,14 @@ var hud_font_size := 32
|
|||||||
var starting_spirit_stones := 500
|
var starting_spirit_stones := 500
|
||||||
## 开局赠送灵米(新游戏发放)。
|
## 开局赠送灵米(新游戏发放)。
|
||||||
var starting_food := 100
|
var starting_food := 100
|
||||||
|
## 建筑等级上限。
|
||||||
|
var building_max_level := 10
|
||||||
|
|
||||||
|
## 各建筑参数表(键 = 建筑类型名,值 = {cost, output, upgrade_cost_x, upgrade_output_x})。
|
||||||
|
var building_params: Dictionary = {
|
||||||
|
"mine": {"cost": 200, "output": 10, "upgrade_cost_x": 2.0, "upgrade_output_x": 1.5},
|
||||||
|
"field": {"cost": 100, "output": 5, "upgrade_cost_x": 2.0, "upgrade_output_x": 1.5},
|
||||||
|
}
|
||||||
|
|
||||||
## 各难度资质权重表(键 = 难度档位,值 = 下品/中品/上品/天骄 权重)。
|
## 各难度资质权重表(键 = 难度档位,值 = 下品/中品/上品/天骄 权重)。
|
||||||
var aptitude_weights_by_difficulty: Dictionary = {
|
var aptitude_weights_by_difficulty: Dictionary = {
|
||||||
@@ -104,6 +112,15 @@ func _load_config() -> void:
|
|||||||
# 建筑系统
|
# 建筑系统
|
||||||
starting_spirit_stones = cfg.get_value("building", "starting_spirit_stones", starting_spirit_stones)
|
starting_spirit_stones = cfg.get_value("building", "starting_spirit_stones", starting_spirit_stones)
|
||||||
starting_food = cfg.get_value("building", "starting_food", starting_food)
|
starting_food = cfg.get_value("building", "starting_food", starting_food)
|
||||||
|
building_max_level = cfg.get_value("building", "max_level", building_max_level)
|
||||||
|
for key in building_params.keys():
|
||||||
|
var p: Dictionary = building_params[key]
|
||||||
|
building_params[key] = {
|
||||||
|
"cost": cfg.get_value("building_" + key, "cost", p["cost"]),
|
||||||
|
"output": cfg.get_value("building_" + key, "output", p["output"]),
|
||||||
|
"upgrade_cost_x": cfg.get_value("building_" + key, "upgrade_cost_x", p["upgrade_cost_x"]),
|
||||||
|
"upgrade_output_x": cfg.get_value("building_" + key, "upgrade_output_x", p["upgrade_output_x"]),
|
||||||
|
}
|
||||||
var apt_raw: Variant = cfg.get_value("cultivation", "aptitude_speed", [])
|
var apt_raw: Variant = cfg.get_value("cultivation", "aptitude_speed", [])
|
||||||
if apt_raw is Array and apt_raw.size() == aptitude_speed.size():
|
if apt_raw is Array and apt_raw.size() == aptitude_speed.size():
|
||||||
var arr: Array[float] = []
|
var arr: Array[float] = []
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ func _ready() -> void:
|
|||||||
TimeSystem.apply_default_speed()
|
TimeSystem.apply_default_speed()
|
||||||
# 开局招募:清空旧数据 → 生成 5 名候选 → 暂停时间等待选择(读档流程接入后由存档还原)
|
# 开局招募:清空旧数据 → 生成 5 名候选 → 暂停时间等待选择(读档流程接入后由存档还原)
|
||||||
DiscipleManager.start_new_game()
|
DiscipleManager.start_new_game()
|
||||||
|
# 开局建筑:清空旧建筑(读档流程接入后由存档还原)
|
||||||
|
BuildingManager.reset()
|
||||||
# 开局赠送资源(数量来自配置;读档流程接入后由存档还原)
|
# 开局赠送资源(数量来自配置;读档流程接入后由存档还原)
|
||||||
SectManager.add_spirit_stones(GameConfig.starting_spirit_stones)
|
SectManager.add_spirit_stones(GameConfig.starting_spirit_stones)
|
||||||
SectManager.add_food(GameConfig.starting_food)
|
SectManager.add_food(GameConfig.starting_food)
|
||||||
@@ -20,3 +22,7 @@ func _on_top_bar_hud_sign_return_mainmenu() -> void:
|
|||||||
## 顶部 HUD 的"管理"按钮请求:打开弟子名录面板。
|
## 顶部 HUD 的"管理"按钮请求:打开弟子名录面板。
|
||||||
func _on_top_bar_hud_sign_open_disciples() -> void:
|
func _on_top_bar_hud_sign_open_disciples() -> void:
|
||||||
$DisciplesPanel.show_panel()
|
$DisciplesPanel.show_panel()
|
||||||
|
|
||||||
|
## 顶部 HUD 的"资源"按钮请求:打开建筑面板。
|
||||||
|
func _on_top_bar_hud_sign_open_buildings() -> void:
|
||||||
|
$BuildingsPanel.show_panel()
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
[ext_resource type="PackedScene" uid="uid://cahux61qqblje" path="res://src/UI/Panels/DisciplesPanel/DisciplesPanel.tscn" id="1_d5cpm"]
|
[ext_resource type="PackedScene" uid="uid://cahux61qqblje" path="res://src/UI/Panels/DisciplesPanel/DisciplesPanel.tscn" id="1_d5cpm"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dl0tb68vsw3c6" path="res://src/UI/HUD/TopBarHUD.tscn" id="1_g6xmk"]
|
[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://cahbpjpnmbcfv" path="res://src/UI/Panels/RecruitPanel/RecruitPanel.tscn" id="1_k5nrm"]
|
||||||
|
[ext_resource type="PackedScene" path="res://src/UI/Panels/BuildingsPanel/BuildingsPanel.tscn" id="1_b9dpm"]
|
||||||
[ext_resource type="Texture2D" uid="uid://cweu17mwblxmg" path="res://assets/sprites/ui/宗门后山.png" id="2_2atgf"]
|
[ext_resource type="Texture2D" uid="uid://cweu17mwblxmg" path="res://assets/sprites/ui/宗门后山.png" id="2_2atgf"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dnjuv1btbxm4o" path="res://assets/sprites/ui/宗门全景.png" id="5_58g0x"]
|
[ext_resource type="Texture2D" uid="uid://dnjuv1btbxm4o" path="res://assets/sprites/ui/宗门全景.png" id="5_58g0x"]
|
||||||
|
|
||||||
@@ -35,5 +36,8 @@ layout_mode = 3
|
|||||||
|
|
||||||
[node name="DisciplesPanel" parent="." unique_id=780000015 instance=ExtResource("1_d5cpm")]
|
[node name="DisciplesPanel" parent="." unique_id=780000015 instance=ExtResource("1_d5cpm")]
|
||||||
|
|
||||||
|
[node name="BuildingsPanel" parent="." unique_id=795000012 instance=ExtResource("1_b9dpm")]
|
||||||
|
|
||||||
|
[connection signal="sign_open_buildings" from="TopBarHud" to="." method="_on_top_bar_hud_sign_open_buildings"]
|
||||||
[connection signal="sign_open_disciples" from="TopBarHud" to="." method="_on_top_bar_hud_sign_open_disciples"]
|
[connection signal="sign_open_disciples" from="TopBarHud" to="." method="_on_top_bar_hud_sign_open_disciples"]
|
||||||
[connection signal="sign_return_mainmenu" from="TopBarHud" to="." method="_on_top_bar_hud_sign_return_mainmenu"]
|
[connection signal="sign_return_mainmenu" from="TopBarHud" to="." method="_on_top_bar_hud_sign_return_mainmenu"]
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
## 建筑管理器(Autoload 单例)。
|
||||||
|
## 负责建筑建造/升级与每日产出结算,产出直接进入 SectManager 资源。
|
||||||
|
## 本期每种建筑至多一座(面板按类型一行展示);多实例留待后续扩展。
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
## 建筑列表变化时发出(建造/升级/重置)。
|
||||||
|
signal buildings_changed
|
||||||
|
|
||||||
|
## 宗门建筑列表。
|
||||||
|
var buildings: Array[Building] = []
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
# 每日推进时结算各建筑产出
|
||||||
|
TimeSystem.day_passed.connect(_on_day_passed)
|
||||||
|
|
||||||
|
## 建造建筑:检查灵石足够 → 扣费入列。
|
||||||
|
## 同类型已存在时拒绝(本期一座一型)。
|
||||||
|
## @param type: 建筑种类
|
||||||
|
## @return 是否建造成功
|
||||||
|
func build(type: Building.Type) -> bool:
|
||||||
|
if _find(type) != null:
|
||||||
|
return false
|
||||||
|
var b := Building.new()
|
||||||
|
b.type = type
|
||||||
|
if SectManager.spirit_stones < b.get_build_cost():
|
||||||
|
return false
|
||||||
|
SectManager.remove_spirit_stones(b.get_build_cost())
|
||||||
|
buildings.append(b)
|
||||||
|
buildings_changed.emit()
|
||||||
|
return true
|
||||||
|
|
||||||
|
## 升级建筑:检查灵石足够 → 扣费提升等级。
|
||||||
|
## @param b: 要升级的建筑
|
||||||
|
## @return 是否升级成功
|
||||||
|
func upgrade(b: Building) -> bool:
|
||||||
|
if b.is_max_level() or SectManager.spirit_stones < b.get_upgrade_cost():
|
||||||
|
return false
|
||||||
|
SectManager.remove_spirit_stones(b.get_upgrade_cost())
|
||||||
|
b.level += 1
|
||||||
|
buildings_changed.emit()
|
||||||
|
return true
|
||||||
|
|
||||||
|
## 清空建筑列表(新游戏开局调用)。
|
||||||
|
func reset() -> void:
|
||||||
|
buildings.clear()
|
||||||
|
buildings_changed.emit()
|
||||||
|
|
||||||
|
## 每日结算:各建筑产出进入 SectManager 对应资源。
|
||||||
|
func _on_day_passed(_year: int, _month: int, _day: int) -> void:
|
||||||
|
for b in buildings:
|
||||||
|
match b.type:
|
||||||
|
Building.Type.MINE:
|
||||||
|
SectManager.add_spirit_stones(b.get_output())
|
||||||
|
Building.Type.FIELD:
|
||||||
|
SectManager.add_food(b.get_output())
|
||||||
|
|
||||||
|
## 查找指定类型的建筑,不存在返回 null。
|
||||||
|
func _find(type: Building.Type) -> Building:
|
||||||
|
for b in buildings:
|
||||||
|
if b.type == type:
|
||||||
|
return b
|
||||||
|
return null
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://6hi0wog110up
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
## 建筑数据模型(纯数据,不挂在场景树上)。
|
||||||
|
## 价格与产出不在建筑上存副本,运行时按 type+level 从 GameConfig 计算。
|
||||||
|
class_name Building
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
## 建筑种类。
|
||||||
|
enum Type { MINE, FIELD } # 灵石矿 / 灵田
|
||||||
|
|
||||||
|
## 建筑类型。
|
||||||
|
var type: Type = Type.MINE
|
||||||
|
## 等级(1 起)。
|
||||||
|
var level: int = 1
|
||||||
|
|
||||||
|
|
||||||
|
## 建筑类型键(对应 GameConfig.building_params 字典键)。
|
||||||
|
static func get_type_key(t: Type) -> String:
|
||||||
|
match t:
|
||||||
|
Type.MINE:
|
||||||
|
return "mine"
|
||||||
|
Type.FIELD:
|
||||||
|
return "field"
|
||||||
|
return ""
|
||||||
|
|
||||||
|
## 建筑显示名称。
|
||||||
|
static func get_type_name(t: Type) -> String:
|
||||||
|
match t:
|
||||||
|
Type.MINE:
|
||||||
|
return "灵石矿"
|
||||||
|
Type.FIELD:
|
||||||
|
return "灵田"
|
||||||
|
return ""
|
||||||
|
|
||||||
|
## 建造价格(灵石)。
|
||||||
|
func get_build_cost() -> int:
|
||||||
|
return get_build_cost_for(type)
|
||||||
|
|
||||||
|
## 建造价格(静态查询,无需实例)。
|
||||||
|
static func get_build_cost_for(t: Type) -> int:
|
||||||
|
var p: Dictionary = GameConfig.building_params[get_type_key(t)]
|
||||||
|
return int(p["cost"])
|
||||||
|
|
||||||
|
## 日产出量 = 基础产出 × 升级产出倍率^(等级-1)。
|
||||||
|
func get_output() -> int:
|
||||||
|
var p: Dictionary = GameConfig.building_params[get_type_key(type)]
|
||||||
|
return int(p["output"] * pow(p["upgrade_output_x"], level - 1))
|
||||||
|
|
||||||
|
## 升级价格 = 建造价 × 升级价格倍率^等级。
|
||||||
|
func get_upgrade_cost() -> int:
|
||||||
|
var p: Dictionary = GameConfig.building_params[get_type_key(type)]
|
||||||
|
return int(p["cost"] * pow(p["upgrade_cost_x"], level))
|
||||||
|
|
||||||
|
## 是否已达等级上限。
|
||||||
|
func is_max_level() -> bool:
|
||||||
|
return level >= GameConfig.building_max_level
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dmfhbyjwngqh3
|
||||||
@@ -224,4 +224,5 @@ size_flags_stretch_ratio = 75.0
|
|||||||
|
|
||||||
[connection signal="button_up" from="VBoxContainer/HBoxContainer2/SpeedGroup/Button_Pause" to="." method="_on_button_pause_button_up"]
|
[connection signal="button_up" from="VBoxContainer/HBoxContainer2/SpeedGroup/Button_Pause" to="." method="_on_button_pause_button_up"]
|
||||||
[connection signal="button_up" from="VBoxContainer/HBoxContainer2/Button_StaffManagement" to="." method="_on_button_staff_management_button_up"]
|
[connection signal="button_up" from="VBoxContainer/HBoxContainer2/Button_StaffManagement" to="." method="_on_button_staff_management_button_up"]
|
||||||
|
[connection signal="button_up" from="VBoxContainer/HBoxContainer2/Button_ResourcesManagement" to="." method="_on_button_resources_management_button_up"]
|
||||||
[connection signal="button_up" from="VBoxContainer/HBoxContainer2/Button_Return" to="." method="_on_button_return_button_up"]
|
[connection signal="button_up" from="VBoxContainer/HBoxContainer2/Button_Return" to="." method="_on_button_return_button_up"]
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ extends Control
|
|||||||
signal sign_return_mainmenu
|
signal sign_return_mainmenu
|
||||||
## 请求打开弟子名录面板。
|
## 请求打开弟子名录面板。
|
||||||
signal sign_open_disciples
|
signal sign_open_disciples
|
||||||
|
## 请求打开建筑面板。
|
||||||
|
signal sign_open_buildings
|
||||||
|
|
||||||
@onready var time_label: Label = %Value_Time
|
@onready var time_label: Label = %Value_Time
|
||||||
@onready var currency_label: Label = %Value_Currency
|
@onready var currency_label: Label = %Value_Currency
|
||||||
@@ -62,6 +64,10 @@ func _on_button_return_button_up() -> void:
|
|||||||
func _on_button_staff_management_button_up() -> void:
|
func _on_button_staff_management_button_up() -> void:
|
||||||
sign_open_disciples.emit()
|
sign_open_disciples.emit()
|
||||||
|
|
||||||
|
## 点击"资源"按钮:请求打开建筑面板(由 MainGame 处理)。
|
||||||
|
func _on_button_resources_management_button_up() -> void:
|
||||||
|
sign_open_buildings.emit()
|
||||||
|
|
||||||
## 点击暂停/继续按钮,切换后刷新按钮状态。
|
## 点击暂停/继续按钮,切换后刷新按钮状态。
|
||||||
func _on_button_pause_button_up() -> void:
|
func _on_button_pause_button_up() -> void:
|
||||||
TimeSystem.toggle_pause()
|
TimeSystem.toggle_pause()
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
[gd_scene format=3 uid="uid://b9k4v8q2x5n3m7p6"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://src/UI/Panels/BuildingsPanel/buildings_panel.gd" id="1_script"]
|
||||||
|
[ext_resource type="FontFile" uid="uid://4su41gib4l5u" path="res://assets/fonts/lxgw-wenkai-v1.522/LXGWWenKaiMono-Medium.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="BuildingsPanel" type="Control" unique_id=795000001]
|
||||||
|
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=795000002]
|
||||||
|
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=795000003]
|
||||||
|
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=795000004]
|
||||||
|
theme_override_styles/panel = SubResource("StyleBoxFlat_dialog")
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="CenterContainer/Panel" unique_id=795000005]
|
||||||
|
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=795000006]
|
||||||
|
theme_override_constants/separation = 12
|
||||||
|
|
||||||
|
[node name="TitleLabel" type="Label" parent="CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=795000007]
|
||||||
|
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="ListContainer" type="VBoxContainer" parent="CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=795000008]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
theme_override_constants/separation = 10
|
||||||
|
|
||||||
|
[node name="ButtonRow" type="HBoxContainer" parent="CenterContainer/Panel/MarginContainer/VBoxContainer" unique_id=795000009]
|
||||||
|
|
||||||
|
[node name="Spacer" type="Control" parent="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow" unique_id=795000010]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
[node name="Button_Close" type="Button" parent="CenterContainer/Panel/MarginContainer/VBoxContainer/ButtonRow" unique_id=795000011]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
theme_override_fonts/font = ExtResource("2_font")
|
||||||
|
theme_override_font_sizes/font_size = 22
|
||||||
|
text = "关闭"
|
||||||
|
|
||||||
|
[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"]
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
## 建筑面板(挂载于 BuildingsPanel.tscn)。
|
||||||
|
## 展示可建/已建建筑(灵石矿/灵田),提供建造与升级操作。
|
||||||
|
## 打开面板暂停时间,关闭恢复;监听建筑变化信号实时刷新。
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
@onready var title_label: Label = %TitleLabel
|
||||||
|
@onready var list_container: VBoxContainer = %ListContainer
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
BuildingManager.buildings_changed.connect(_on_buildings_changed)
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
## 打开面板并刷新列表(暂停时间推进)。
|
||||||
|
func show_panel() -> void:
|
||||||
|
_refresh()
|
||||||
|
TimeSystem.set_paused(true)
|
||||||
|
visible = true
|
||||||
|
|
||||||
|
## 关闭面板(恢复时间推进)。
|
||||||
|
func hide_panel() -> void:
|
||||||
|
visible = false
|
||||||
|
TimeSystem.set_paused(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_buildings_changed() -> void:
|
||||||
|
if visible:
|
||||||
|
_refresh()
|
||||||
|
|
||||||
|
## 重建列表:按建筑类型逐行生成(未建显示建造按钮,已建显示等级/产出/升级按钮)。
|
||||||
|
func _refresh() -> void:
|
||||||
|
for child in list_container.get_children():
|
||||||
|
child.queue_free()
|
||||||
|
title_label.text = "宗门建筑"
|
||||||
|
for type in [Building.Type.MINE, Building.Type.FIELD]:
|
||||||
|
_add_row(type)
|
||||||
|
|
||||||
|
## 添加一行建筑条目。
|
||||||
|
## @param type: 建筑种类
|
||||||
|
func _add_row(type: Building.Type) -> void:
|
||||||
|
var b := BuildingManager._find(type)
|
||||||
|
var row := HBoxContainer.new()
|
||||||
|
row.add_theme_constant_override("separation", 12)
|
||||||
|
|
||||||
|
var name_label := Label.new()
|
||||||
|
name_label.text = Building.get_type_name(type)
|
||||||
|
name_label.custom_minimum_size = Vector2(140, 0)
|
||||||
|
row.add_child(name_label)
|
||||||
|
|
||||||
|
var info_label := Label.new()
|
||||||
|
info_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
if b == null:
|
||||||
|
info_label.text = "未建造"
|
||||||
|
else:
|
||||||
|
info_label.text = "等级 %d 日产出 %d" % [b.level, b.get_output()]
|
||||||
|
row.add_child(info_label)
|
||||||
|
|
||||||
|
var btn := Button.new()
|
||||||
|
if b == null:
|
||||||
|
var cost := Building.get_build_cost_for(type)
|
||||||
|
btn.text = "建造(%d 灵石)" % cost
|
||||||
|
btn.disabled = SectManager.spirit_stones < cost
|
||||||
|
btn.button_up.connect(_on_build_button_up.bind(type))
|
||||||
|
else:
|
||||||
|
if b.is_max_level():
|
||||||
|
btn.text = "已满级"
|
||||||
|
btn.disabled = true
|
||||||
|
else:
|
||||||
|
btn.text = "升级(%d 灵石)" % b.get_upgrade_cost()
|
||||||
|
btn.disabled = SectManager.spirit_stones < b.get_upgrade_cost()
|
||||||
|
btn.button_up.connect(_on_upgrade_button_up.bind(b))
|
||||||
|
row.add_child(btn)
|
||||||
|
|
||||||
|
list_container.add_child(row)
|
||||||
|
|
||||||
|
## 点击建造按钮。
|
||||||
|
## @param type: 建筑种类
|
||||||
|
func _on_build_button_up(type: Building.Type) -> void:
|
||||||
|
if BuildingManager.build(type):
|
||||||
|
_refresh()
|
||||||
|
|
||||||
|
## 点击升级按钮。
|
||||||
|
## @param b: 要升级的建筑
|
||||||
|
func _on_upgrade_button_up(b: Building) -> void:
|
||||||
|
if BuildingManager.upgrade(b):
|
||||||
|
_refresh()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bhvcvw4ufjhxv
|
||||||
Reference in New Issue
Block a user