feat: 定时招募弹窗,开局5选3+定期3候选,配置驱动(GameConfig/RecruitPanel)

This commit is contained in:
2026-08-06 00:13:31 +08:00
parent a00c95af51
commit a3cbd738ad
10 changed files with 324 additions and 28 deletions
+108
View File
@@ -0,0 +1,108 @@
## 招募弹窗(挂载于 RecruitPanel.tscn)。
## 监听候选生成信号自动弹出,玩家勾选后点"确定"结算入宗。
extends Control
## 招募模式:开局必须选满 / 定期自由选择。
enum Mode { OPENING, PERIODIC }
@onready var title_label: Label = %TitleLabel
@onready var hint_label: Label = %HintLabel
@onready var list_container: VBoxContainer = %ListContainer
@onready var confirm_button: Button = %Button_Confirm
## 当前招募模式。
var _mode: Mode = Mode.PERIODIC
## 勾选框列表(与 _entry_disciples 按下标一一对应)。
var _check_buttons: Array[CheckButton] = []
## 对应勾选框的候选弟子。
var _entry_disciples: Array[Disciple] = []
func _ready() -> void:
# 订阅候选生成信号:开局与定期招募都会触发
DiscipleManager.applicants_generated.connect(_on_applicants_generated)
visible = false
## 候选生成时弹出:按当前候选池重建列表。
## @param is_opening: 是否开局招募
func _on_applicants_generated(is_opening: bool) -> void:
_mode = Mode.OPENING if is_opening else Mode.PERIODIC
_clear_entries()
for d in DiscipleManager.applicants:
_add_entry(d)
title_label.text = "弟子入宗(%s" % ("开局招募" if is_opening else "定期招募")
_update_ui()
visible = true
## 勾选任一候选后刷新提示与确定按钮可用性。
func _on_check_toggled(_pressed: bool, _d: Disciple) -> void:
_update_ui()
## 全部接受:勾选所有候选。
func _on_button_accept_all_button_up() -> void:
for c in _check_buttons:
c.set_pressed_no_signal(true)
_update_ui()
## 全部拒绝:取消所有勾选。
func _on_button_reject_all_button_up() -> void:
for c in _check_buttons:
c.set_pressed_no_signal(false)
_update_ui()
## 确定:勾选的入宗、未勾选的拒绝,关闭弹窗并恢复时间。
func _on_button_confirm_button_up() -> void:
var selected: Array[Disciple] = []
for i in _entry_disciples.size():
if _check_buttons[i].button_pressed:
selected.append(_entry_disciples[i])
DiscipleManager.finish_recruitment(selected)
_close()
## 刷新提示文本与确定按钮状态。
func _update_ui() -> void:
if _mode == Mode.OPENING:
var picked := 0
for c in _check_buttons:
if c.button_pressed:
picked += 1
hint_label.text = "开局招募:请选择 %d 名弟子入宗(已选 %d/%d" % [
GameConfig.opening_pick_count, picked, _check_buttons.size(),
]
confirm_button.disabled = picked < GameConfig.opening_pick_count
else:
hint_label.text = "定期招募:勾选入宗弟子,未勾选的将被拒绝(可全部拒绝)"
confirm_button.disabled = false
## 关闭弹窗:清空条目并恢复时间推进。
func _close() -> void:
_clear_entries()
visible = false
TimeSystem.set_paused(false)
## 清空候选条目。
func _clear_entries() -> void:
for child in list_container.get_children():
child.queue_free()
_check_buttons.clear()
_entry_disciples.clear()
## 添加一名候选的行条目:信息文本 + 入宗勾选框。
## @param d: 候选弟子
func _add_entry(d: Disciple) -> void:
var row := HBoxContainer.new()
var info := Label.new()
info.text = "%s %d岁 | %s资质%s | %s灵根 | %s" % [
d.name, d.age, d.get_aptitude_name(),
"·天灵根" if d.is_heavenly else "",
d.get_roots_text(), d.get_realm_text(),
]
info.size_flags_horizontal = Control.SIZE_EXPAND_FILL
var check := CheckButton.new()
check.text = "入宗"
check.toggled.connect(_on_check_toggled.bind(d))
row.add_child(info)
row.add_child(check)
list_container.add_child(row)
_check_buttons.append(check)
_entry_disciples.append(d)