卡②T2a(呈现层结构收敛批): u5/u6——u5 hero_info_panel_view(_init拆数据行/秘宝槽/三区段构建私有族+单槽/槽图标/字形标签/浮窗四域+set_treasure_inventory填充域拆分,循环体提函数)+u6 battle_end_overlay(_EndOverlayState战末呈现与演出态状态件[fx三计数并一字典]+探针冻结4住宿主+_init拆头部[蜡封图/庆祝立绘]/三行账构建域+open_victory可选尾参收拢opts束4参[键gp_summary/ks_summary/bonus_summary/gp_gain/gp_total缺省逐字]+四处演出循环提函数[封印光点/纹章碎砖/坐砖尘絮/尘金粒子])+消费点5处改址(main×2束形/main_adventure_flow×2/ui_struct_probe×1,三参调用缺省兼容零改动)
This commit is contained in:
1 parent
f878c3c45f
commit
b33469ac09
5 files changed
+336
-247
No files matched your search
@@ -453,15 +453,19 @@ func _on_battle_finished(payload: Dictionary) -> void:
|
||||
return
|
||||
"level_end":
|
||||
_end_overlay.open_victory(Narrator.battle_end_text("victory", true),
|
||||
"返回", board_view.get_global_rect(), _gp_summary_text(payload),
|
||||
"钥石 · 累计 %d" % run_scope.runner.keystone, HudPresenter.bonus_summary_text(run_scope.runner),
|
||||
int(payload.get("gp_dropped", 0)), int(run_scope.runner.gp))
|
||||
"返回", board_view.get_global_rect(),
|
||||
{"gp_summary": _gp_summary_text(payload),
|
||||
"ks_summary": "钥石 · 累计 %d" % run_scope.runner.keystone,
|
||||
"bonus_summary": HudPresenter.bonus_summary_text(run_scope.runner),
|
||||
"gp_gain": int(payload.get("gp_dropped", 0)), "gp_total": int(run_scope.runner.gp)})
|
||||
"standalone_end":
|
||||
if result == "victory":
|
||||
_end_overlay.open_victory(Narrator.battle_end_text("victory", false),
|
||||
"回到遭遇选择", board_view.get_global_rect(), _gp_summary_text(payload),
|
||||
"钥石 · 累计 %d" % run_scope.runner.keystone, HudPresenter.bonus_summary_text(run_scope.runner),
|
||||
int(payload.get("gp_dropped", 0)), int(run_scope.runner.gp))
|
||||
"回到遭遇选择", board_view.get_global_rect(),
|
||||
{"gp_summary": _gp_summary_text(payload),
|
||||
"ks_summary": "钥石 · 累计 %d" % run_scope.runner.keystone,
|
||||
"bonus_summary": HudPresenter.bonus_summary_text(run_scope.runner),
|
||||
"gp_gain": int(payload.get("gp_dropped", 0)), "gp_total": int(run_scope.runner.gp)})
|
||||
else:
|
||||
_end_overlay.open_defeat(Narrator.battle_end_text("defeat", false),
|
||||
"返回", board_view.get_global_rect())
|
||||
|
||||
@@ -111,7 +111,7 @@ static func _on_adventure_finished(root: Variant, summary: Dictionary) -> void:
|
||||
text += "\n" + root.Narrator.keystone_settle_text(detail, root._bonus.item_name_lookup())
|
||||
if result == "completed":
|
||||
root._end_overlay.open_victory(text, "返回冒险", root.board_view.get_global_rect(),
|
||||
"本局 GP 入账 · 合计 %d" % int(summary.get("gp_final", 0))) # GP 行(取数=summary gp_final 清账前快照);钥石明细已在 text(keystone_settle_text)——三行账
|
||||
{"gp_summary": "本局 GP 入账 · 合计 %d" % int(summary.get("gp_final", 0))}) # GP 行(取数=summary gp_final 清账前快照);钥石明细已在 text(keystone_settle_text)——三行账
|
||||
else:
|
||||
root._end_overlay.open_defeat(text, "返回", root.board_view.get_global_rect())
|
||||
root.logger.log_level_end(summary) # 试玩时间线:冒险终局(摘要随载荷)
|
||||
@@ -178,7 +178,7 @@ static func _on_choices_presented(root: Variant, candidates: Array) -> void:
|
||||
root.run_scope.pending_candidates = candidates.duplicate()
|
||||
root._end_overlay.open_victory(root.Narrator.battle_end_text("victory", false), "下一节点",
|
||||
root.board_view.get_global_rect(),
|
||||
"战利品 GP +%d · 合计 %d" % [root.run_scope.last_gain_amount, int(root.run_scope.runner.gp)])
|
||||
{"gp_summary": "战利品 GP +%d · 合计 %d" % [root.run_scope.last_gain_amount, int(root.run_scope.runner.gp)]})
|
||||
root._open_modal_after_playback(root._end_overlay)
|
||||
root._refresh_presentations()
|
||||
return
|
||||
|
||||
@@ -10,22 +10,30 @@ const COL_GOLD := UiKit.GOLD
|
||||
const COL_DUSK := UiKit.DUSK # 暮蓝(全作唯一暮蓝档)
|
||||
const COL_WARM := UiKit.WARM
|
||||
|
||||
var _dim: ColorRect
|
||||
var _seal: Panel
|
||||
var _verdict: Label
|
||||
var _rows_box: VBoxContainer # 三行账(GP/钥石/本关加成——demo ⑧两列对齐;失败侧整行隐藏)
|
||||
var _gp_row: HBoxContainer
|
||||
var _gp_name: Label
|
||||
var _gp_val: Label
|
||||
var _ks_row: HBoxContainer
|
||||
var _ks_name: Label
|
||||
var _ks_val: Label
|
||||
var _bonus_row_l: HBoxContainer
|
||||
var _bonus_name: Label
|
||||
var _bonus_val: Label
|
||||
var _cele: TextureRect # 庆祝立绘(idle 占位浮动)
|
||||
var _btn: Button
|
||||
var _board_rect := Rect2()
|
||||
## 内部状态件(u6 子域拆件——契约 9 职责语句「战末呈现与演出态」):单一变化原因=终局画面呈现与
|
||||
## 演出计数。探针直读冻结成员(_btn/_gp_name/_gp_row/_gp_val)住宿主不进状态件。
|
||||
class _EndOverlayState extends RefCounted:
|
||||
var _dim: ColorRect
|
||||
var _seal: Panel
|
||||
var _verdict: Label
|
||||
var _rows_box: VBoxContainer # 三行账(GP/钥石/本关加成——demo ⑧两列对齐;失败侧整行隐藏)
|
||||
var _ks_row: HBoxContainer
|
||||
var _ks_name: Label
|
||||
var _ks_val: Label
|
||||
var _bonus_row_l: HBoxContainer
|
||||
var _bonus_name: Label
|
||||
var _bonus_val: Label
|
||||
var _cele: TextureRect # 庆祝立绘(idle 占位浮动)
|
||||
var _board_rect := Rect2()
|
||||
var _crest_bricks: Array[ColorRect] = [] # 纹章碎砖驻留面(close 时回收)
|
||||
var _fx_counts := {"crest": 0, "dust": 0, "seal": 0} # 演出计数(fx_probe 断言面——crest/dust/seal 三键)
|
||||
|
||||
|
||||
var st := _EndOverlayState.new()
|
||||
var _gp_row: HBoxContainer # 探针直读冻结(S17⑤)
|
||||
var _gp_name: Label # 探针直读冻结
|
||||
var _gp_val: Label # 探针直读冻结
|
||||
var _btn: Button # 探针直读冻结
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
@@ -35,19 +43,43 @@ func _init() -> void:
|
||||
# 骨架经 UiKit.modal_shell;_dim 引用摘出供 open_* 换氛围色。
|
||||
var shell := UiKit.modal_shell(self, Color(COL_WARM, 0.0), Vector2(520, 0), 12, true,
|
||||
UiKit.panel_skinned(Vector4(16, 14, 16, 14)))
|
||||
_dim = shell.dim
|
||||
st._dim = shell.dim
|
||||
var box: VBoxContainer = shell.box
|
||||
_build_header(box)
|
||||
_build_ledger(box)
|
||||
# 无明细回看钮——冒险中回看归「生涯」
|
||||
_btn = UiKit.primary_button("继续")
|
||||
_btn.size_flags_horizontal = Control.SIZE_SHRINK_CENTER # 紧凑钮
|
||||
_btn.custom_minimum_size.x = 150
|
||||
_btn.pressed.connect(_emit_continue_pressed)
|
||||
box.add_child(_btn)
|
||||
visible = false
|
||||
|
||||
|
||||
## 头部域:金蜡封徽记+判定行+庆祝立绘(demo ⑧——idle 帧浮动占位;减动效=静帧)
|
||||
func _build_header(box: VBoxContainer) -> void:
|
||||
var header := HBoxContainer.new()
|
||||
header.add_theme_constant_override("separation", 12)
|
||||
header.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
box.add_child(header)
|
||||
_seal = Panel.new()
|
||||
_seal.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
st._seal = Panel.new()
|
||||
st._seal.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
var sb := UiKit.panel_flat(COL_GOLD, UiKit.GOLD_DEEP, 200, 4)
|
||||
_seal.add_theme_stylebox_override("panel", sb)
|
||||
_seal.custom_minimum_size = Vector2(52, 52)
|
||||
_seal.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
header.add_child(_seal)
|
||||
st._seal.add_theme_stylebox_override("panel", sb)
|
||||
st._seal.custom_minimum_size = Vector2(52, 52)
|
||||
st._seal.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
header.add_child(st._seal)
|
||||
st._seal.add_child(_seal_img())
|
||||
st._verdict = UiKit.label("",UiKit.FS_TITLE, true, UiKit.INK_TITLE)
|
||||
st._verdict.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
st._verdict.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
header.add_child(st._verdict)
|
||||
st._cele = _cele_rect()
|
||||
header.add_child(st._cele)
|
||||
|
||||
|
||||
## 蜡封图域(32px 像素过滤居中)
|
||||
func _seal_img() -> TextureRect:
|
||||
var seal_img := TextureRect.new()
|
||||
var seal_tex := UiKit.load_tex("res://assets/art/board/seal_mark.png")
|
||||
if seal_tex != null:
|
||||
@@ -58,76 +90,76 @@ func _init() -> void:
|
||||
seal_img.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
seal_img.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
seal_img.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
_seal.add_child(seal_img)
|
||||
_verdict = UiKit.label("",UiKit.FS_TITLE, true, UiKit.INK_TITLE)
|
||||
_verdict.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
_verdict.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
header.add_child(_verdict)
|
||||
# 庆祝立绘(demo ⑧——idle 帧浮动占位;减动效=静帧)
|
||||
_cele = TextureRect.new()
|
||||
return seal_img
|
||||
|
||||
|
||||
## 庆祝立绘域(64px idle 帧)
|
||||
func _cele_rect() -> TextureRect:
|
||||
var cele := TextureRect.new()
|
||||
var cele_tex := UiKit.load_tex(UiKit.TEX_HERO_IDLE)
|
||||
if cele_tex != null:
|
||||
_cele.texture = cele_tex
|
||||
_cele.custom_minimum_size = Vector2(64, 64)
|
||||
_cele.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||
_cele.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
_cele.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
_cele.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
_cele.visible = false
|
||||
header.add_child(_cele)
|
||||
_rows_box = VBoxContainer.new()
|
||||
_rows_box.add_theme_constant_override("separation", 6)
|
||||
_rows_box.visible = false
|
||||
box.add_child(_rows_box)
|
||||
# 两列对齐账行(审计差距④对齐 demo ⑧——项目名左/数值右,定宽 360)
|
||||
cele.texture = cele_tex
|
||||
cele.custom_minimum_size = Vector2(64, 64)
|
||||
cele.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||
cele.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
cele.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
cele.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
cele.visible = false
|
||||
return cele
|
||||
|
||||
|
||||
## 三行账域(两列对齐账行——审计差距④对齐 demo ⑧:项目名左/数值右,定宽 360)
|
||||
func _build_ledger(box: VBoxContainer) -> void:
|
||||
st._rows_box = VBoxContainer.new()
|
||||
st._rows_box.add_theme_constant_override("separation", 6)
|
||||
st._rows_box.visible = false
|
||||
box.add_child(st._rows_box)
|
||||
_gp_row = _ledger_row()
|
||||
_gp_name = _ledger_name(UiKit.FS_SUB, UiKit.GOLD_INK, true) # GOLD_DEEP 对结算板 2.67:1 越带,换深金墨 5.21:1
|
||||
_gp_val = _ledger_value(UiKit.FS_SUB, UiKit.GOLD_INK, true) # 同上
|
||||
_gp_row.add_child(_gp_name)
|
||||
_gp_row.add_child(_gp_val)
|
||||
_rows_box.add_child(_gp_row)
|
||||
_ks_row = _ledger_row()
|
||||
_ks_name = _ledger_name(UiKit.FS_BODY, UiKit.INK_LABEL, false)
|
||||
_ks_val = _ledger_value(UiKit.FS_BODY, UiKit.INK_LABEL, true)
|
||||
_ks_row.add_child(_ks_name)
|
||||
_ks_row.add_child(_ks_val)
|
||||
_ks_row.visible = false
|
||||
_rows_box.add_child(_ks_row)
|
||||
_bonus_row_l = _ledger_row()
|
||||
_bonus_name = _ledger_name(UiKit.FS_HINT, UiKit.INK_LABEL, false)
|
||||
_bonus_val = _ledger_value(UiKit.FS_HINT, UiKit.INK_LABEL, true)
|
||||
_bonus_row_l.add_child(_bonus_name)
|
||||
_bonus_row_l.add_child(_bonus_val)
|
||||
_bonus_row_l.visible = false
|
||||
_rows_box.add_child(_bonus_row_l)
|
||||
st._rows_box.add_child(_gp_row)
|
||||
st._ks_row = _ledger_row()
|
||||
st._ks_name = _ledger_name(UiKit.FS_BODY, UiKit.INK_LABEL, false)
|
||||
st._ks_val = _ledger_value(UiKit.FS_BODY, UiKit.INK_LABEL, true)
|
||||
st._ks_row.add_child(st._ks_name)
|
||||
st._ks_row.add_child(st._ks_val)
|
||||
st._ks_row.visible = false
|
||||
st._rows_box.add_child(st._ks_row)
|
||||
st._bonus_row_l = _ledger_row()
|
||||
st._bonus_name = _ledger_name(UiKit.FS_HINT, UiKit.INK_LABEL, false)
|
||||
st._bonus_val = _ledger_value(UiKit.FS_HINT, UiKit.INK_LABEL, true)
|
||||
st._bonus_row_l.add_child(st._bonus_name)
|
||||
st._bonus_row_l.add_child(st._bonus_val)
|
||||
st._bonus_row_l.visible = false
|
||||
st._rows_box.add_child(st._bonus_row_l)
|
||||
box.add_child(HSeparator.new())
|
||||
# 无明细回看钮——冒险中回看归「生涯」
|
||||
_btn = UiKit.primary_button("继续")
|
||||
_btn.size_flags_horizontal = Control.SIZE_SHRINK_CENTER # 紧凑钮
|
||||
_btn.custom_minimum_size.x = 150
|
||||
_btn.pressed.connect(_emit_continue_pressed)
|
||||
box.add_child(_btn)
|
||||
visible = false
|
||||
|
||||
|
||||
# 终局画面数据锚 = 战斗结算 判定行(verdict)——判定行文案由组合根装配传入。
|
||||
# gp_summary(胜利总结结算展示 GP 总量+增量):组合根装配「战利品 +增量 · 合计总量」
|
||||
# 传入(入账次序 = LevelRunner 入账先于组合根 handler,runner.gp 即战后总量);空串 = 不显示(失败侧恒空)。
|
||||
func open_victory(verdict_line: String, continue_label: String, board_rect: Rect2, gp_summary: String = "",
|
||||
ks_summary: String = "", bonus_summary: String = "", gp_gain := -1, gp_total := -1) -> void:
|
||||
_dim.color = Color(UiKit.DIM_NIGHT, 0.62) # 全屏压暗对齐 demo
|
||||
_verdict.text = verdict_line
|
||||
_seal.visible = true # 胜利徽记(面板头部静态)
|
||||
_seal.modulate = Color.WHITE
|
||||
# 可选尾参收拢 opts 束(u6——键 {gp_summary, ks_summary, bonus_summary, gp_gain, gp_total},缺省逐字同值)
|
||||
func open_victory(verdict_line: String, continue_label: String, board_rect: Rect2, opts := {}) -> void:
|
||||
var gp_summary: String = opts.get("gp_summary", "")
|
||||
var ks_summary: String = opts.get("ks_summary", "")
|
||||
var bonus_summary: String = opts.get("bonus_summary", "")
|
||||
var gp_gain: int = opts.get("gp_gain", -1)
|
||||
var gp_total: int = opts.get("gp_total", -1)
|
||||
st._dim.color = Color(UiKit.DIM_NIGHT, 0.62) # 全屏压暗对齐 demo
|
||||
st._verdict.text = verdict_line
|
||||
st._seal.visible = true # 胜利徽记(面板头部静态)
|
||||
st._seal.modulate = Color.WHITE
|
||||
_set_ledger_row(_gp_name, _gp_val, gp_summary, true) # GP 行=固定名「战利品 GP」(滚动/整串均只入值列)
|
||||
_set_ledger_row(_ks_name, _ks_val, ks_summary)
|
||||
_ks_row.visible = ks_summary != ""
|
||||
_set_ledger_row(_bonus_name, _bonus_val, bonus_summary)
|
||||
_bonus_row_l.visible = bonus_summary != ""
|
||||
_rows_box.visible = gp_summary != "" or ks_summary != "" or bonus_summary != ""
|
||||
_set_ledger_row(st._ks_name, st._ks_val, ks_summary)
|
||||
st._ks_row.visible = ks_summary != ""
|
||||
_set_ledger_row(st._bonus_name, st._bonus_val, bonus_summary)
|
||||
st._bonus_row_l.visible = bonus_summary != ""
|
||||
st._rows_box.visible = gp_summary != "" or ks_summary != "" or bonus_summary != ""
|
||||
_btn.text = continue_label
|
||||
_board_rect = board_rect
|
||||
_cele.visible = true
|
||||
st._board_rect = board_rect
|
||||
st._cele.visible = true
|
||||
_play_celebrate()
|
||||
visible = true
|
||||
if UiKit.victory_fx_style == "dust":
|
||||
@@ -141,23 +173,23 @@ func open_victory(verdict_line: String, continue_label: String, board_rect: Rect
|
||||
|
||||
func open_defeat(verdict_line: String, continue_label: String, board_rect: Rect2) -> void:
|
||||
# 明度不变的暮蓝色相氛围(全屏唯一暮蓝档——§2.5 最静一拍)
|
||||
_dim.color = Color(COL_DUSK, 0.6) # 同族压暗
|
||||
_verdict.text = verdict_line
|
||||
_board_rect = board_rect
|
||||
st._dim.color = Color(COL_DUSK, 0.6) # 同族压暗
|
||||
st._verdict.text = verdict_line
|
||||
st._board_rect = board_rect
|
||||
visible = true
|
||||
_seal.visible = true
|
||||
_seal.modulate = Color(0.4, 0.4, 0.4) # 失败徽记灰化(demo ⑧)
|
||||
_cele.visible = false
|
||||
_rows_box.visible = false # 失败侧不呈现账行
|
||||
st._seal.visible = true
|
||||
st._seal.modulate = Color(0.4, 0.4, 0.4) # 失败徽记灰化(demo ⑧)
|
||||
st._cele.visible = false
|
||||
st._rows_box.visible = false # 失败侧不呈现账行
|
||||
_play_dust_sadle() # 坐砖掸灰(§2.5——终稿)
|
||||
_play_seal_recall(8)
|
||||
|
||||
|
||||
func close() -> void:
|
||||
visible = false
|
||||
_seal.visible = false
|
||||
_seal.modulate = Color.WHITE
|
||||
_cele.visible = false
|
||||
st._seal.visible = false
|
||||
st._seal.modulate = Color.WHITE
|
||||
st._cele.visible = false
|
||||
var tw: Tween = get_meta(&"celebrate_tw", null) # 循环句柄随节点存(跨 open/close,close 必杀)
|
||||
if tw != null and tw.is_valid():
|
||||
tw.kill()
|
||||
@@ -170,7 +202,7 @@ func is_open() -> bool:
|
||||
|
||||
|
||||
func verdict_text() -> String:
|
||||
return _verdict.text
|
||||
return st._verdict.text
|
||||
|
||||
|
||||
# 两列账行工厂(审计差距④——名左/值右,定宽 360)
|
||||
@@ -217,68 +249,83 @@ func _fx_center() -> Vector2:
|
||||
|
||||
# 封印化光点收回(失败——插过的封印逐面化光点收回占位,§2.5)
|
||||
func _play_seal_recall(count: int) -> void:
|
||||
_fx_seal_dots = count
|
||||
st._fx_counts["seal"] = count
|
||||
var base := st._board_rect.get_center() if st._board_rect.size != Vector2.ZERO else get_viewport_rect().size * 0.5
|
||||
for i in count:
|
||||
var dot := ColorRect.new()
|
||||
dot.color = COL_GOLD
|
||||
dot.size = Vector2(6, 6)
|
||||
var base := _board_rect.get_center() if _board_rect.size != Vector2.ZERO else get_viewport_rect().size * 0.5
|
||||
dot.position = base + Vector2((float(i % 5) - 2.0) * _board_rect.size.x * 0.14 if _board_rect.size.x > 0 else 0.0,
|
||||
(float(i % 3) - 1.0) * _board_rect.size.y * 0.18) # 确定性散布(S2 禁全局随机——占位演出同守)
|
||||
dot.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
add_child(dot)
|
||||
var tw := dot.create_tween()
|
||||
tw.tween_interval(UiKit.motion(0.1 * i))
|
||||
tw.tween_property(dot, "position:y", dot.position.y - 120.0, UiKit.motion(0.8))
|
||||
tw.parallel().tween_property(dot, "modulate:a", 0.0, UiKit.motion(0.8))
|
||||
tw.tween_callback(dot.queue_free)
|
||||
_spawn_seal_dot(i, base)
|
||||
|
||||
|
||||
## 单光点域(循环体提函数——延迟升空渐隐回收;确定性散布 S2 禁全局随机)
|
||||
func _spawn_seal_dot(i: int, base: Vector2) -> void:
|
||||
var dot := ColorRect.new()
|
||||
dot.color = COL_GOLD
|
||||
dot.size = Vector2(6, 6)
|
||||
dot.position = base + Vector2((float(i % 5) - 2.0) * st._board_rect.size.x * 0.14 if st._board_rect.size.x > 0 else 0.0,
|
||||
(float(i % 3) - 1.0) * st._board_rect.size.y * 0.18)
|
||||
dot.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
add_child(dot)
|
||||
var tw := dot.create_tween()
|
||||
tw.tween_interval(UiKit.motion(0.1 * i))
|
||||
tw.tween_property(dot, "position:y", dot.position.y - 120.0, UiKit.motion(0.8))
|
||||
tw.parallel().tween_property(dot, "modulate:a", 0.0, UiKit.motion(0.8))
|
||||
tw.tween_callback(dot.queue_free)
|
||||
|
||||
|
||||
# ---- 演出密度(程序化 tween,确定性散布,零新帧资产) ----
|
||||
|
||||
var _crest_bricks: Array[ColorRect] = [] # 纹章碎砖驻留面(close 时回收)
|
||||
var _fx_crest_shards := 0
|
||||
var _fx_dust_motes := 0
|
||||
var _fx_seal_dots := 0
|
||||
var st._crest_bricks: Array[ColorRect] = [] # 纹章碎砖驻留面(close 时回收)
|
||||
var st._fx_crest_shards := 0
|
||||
var st._fx_dust_motes := 0
|
||||
var st._fx_seal_dots := 0
|
||||
|
||||
|
||||
# 碎砖拼纹章(胜利 §2.4——蜡封落定后十枚碎砖自四周向蜡封外环收拢拼成纹章环,驻留至 close)
|
||||
func _play_crest_assemble() -> void:
|
||||
_clear_crest_bricks()
|
||||
_fx_crest_shards = 10
|
||||
st._fx_counts["crest"] = 10
|
||||
var c := _fx_center()
|
||||
for i in 10:
|
||||
var brick := ColorRect.new()
|
||||
brick.color = UiKit.BRICK if i % 2 == 0 else UiKit.FLOOR # 碎砖=砖面族色(掩尘/裸土——图底同源)
|
||||
brick.size = Vector2(12, 7)
|
||||
brick.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
var ang := TAU * float(i) / 10.0
|
||||
var ring := c + Vector2(cos(ang), sin(ang)) * 64.0
|
||||
brick.position = c + Vector2(cos(ang), sin(ang)) * 200.0 # 自四周场外入场
|
||||
add_child(brick)
|
||||
_crest_bricks.append(brick)
|
||||
var btw := brick.create_tween()
|
||||
btw.tween_interval(UiKit.motion(0.52)) # 待蜡封落定(seal 0.42+0.22 弹跳中段)
|
||||
btw.tween_property(brick, "position", ring - brick.size * 0.5, UiKit.motion(0.4)).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
|
||||
btw.parallel().tween_property(brick, "rotation", sin(ang) * 0.35, UiKit.motion(0.4))
|
||||
_spawn_crest_brick(i, c)
|
||||
|
||||
|
||||
## 单碎砖域(循环体提函数——待蜡封落定后自场外收拢入环;碎砖=砖面族色〔掩尘/裸土——图底同源〕)
|
||||
func _spawn_crest_brick(i: int, c: Vector2) -> void:
|
||||
var brick := ColorRect.new()
|
||||
brick.color = UiKit.BRICK if i % 2 == 0 else UiKit.FLOOR
|
||||
brick.size = Vector2(12, 7)
|
||||
brick.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
var ang := TAU * float(i) / 10.0
|
||||
var ring := c + Vector2(cos(ang), sin(ang)) * 64.0
|
||||
brick.position = c + Vector2(cos(ang), sin(ang)) * 200.0 # 自四周场外入场
|
||||
add_child(brick)
|
||||
st._crest_bricks.append(brick)
|
||||
var btw := brick.create_tween()
|
||||
btw.tween_interval(UiKit.motion(0.52)) # 待蜡封落定(seal 0.42+0.22 弹跳中段)
|
||||
btw.tween_property(brick, "position", ring - brick.size * 0.5, UiKit.motion(0.4)).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
|
||||
btw.parallel().tween_property(brick, "rotation", sin(ang) * 0.35, UiKit.motion(0.4))
|
||||
|
||||
|
||||
# 坐砖掸灰(失败 §2.5——暖灰尘絮自棋盘中带缓缓飘落,最静一拍的运动承载)
|
||||
func _play_dust_sadle() -> void:
|
||||
_fx_dust_motes = 8
|
||||
st._fx_counts["dust"] = 8
|
||||
var base := _fx_center()
|
||||
for i in 8:
|
||||
var mote := ColorRect.new()
|
||||
mote.color = Color(UiKit.WARM_FAINT, 0.85)
|
||||
mote.size = Vector2(4, 4)
|
||||
mote.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
mote.position = base + Vector2((float(i % 4) - 1.5) * 30.0, -24.0 - 8.0 * float(i / 4))
|
||||
add_child(mote)
|
||||
var mtw := mote.create_tween()
|
||||
mtw.tween_interval(UiKit.motion(0.08 * i))
|
||||
mtw.tween_property(mote, "position:y", mote.position.y + 64.0, UiKit.motion(0.9))
|
||||
mtw.parallel().tween_property(mote, "modulate:a", 0.0, UiKit.motion(0.9))
|
||||
mtw.tween_callback(mote.queue_free)
|
||||
_spawn_dust_mote(i, base)
|
||||
|
||||
|
||||
## 单尘絮域(循环体提函数——中带散布缓降渐隐)
|
||||
func _spawn_dust_mote(i: int, base: Vector2) -> void:
|
||||
var mote := ColorRect.new()
|
||||
mote.color = Color(UiKit.WARM_FAINT, 0.85)
|
||||
mote.size = Vector2(4, 4)
|
||||
mote.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
mote.position = base + Vector2((float(i % 4) - 1.5) * 30.0, -24.0 - 8.0 * float(i / 4))
|
||||
add_child(mote)
|
||||
var mtw := mote.create_tween()
|
||||
mtw.tween_interval(UiKit.motion(0.08 * i))
|
||||
mtw.tween_property(mote, "position:y", mote.position.y + 64.0, UiKit.motion(0.9))
|
||||
mtw.parallel().tween_property(mote, "modulate:a", 0.0, UiKit.motion(0.9))
|
||||
mtw.tween_callback(mote.queue_free)
|
||||
|
||||
|
||||
# 庆祝立绘浮动(idle 占位——UiKit.motion 守减动效;motion_scale<1 静帧)
|
||||
@@ -288,29 +335,34 @@ func _play_celebrate() -> void:
|
||||
var prev: Tween = get_meta(&"celebrate_tw", null)
|
||||
if prev != null and prev.is_valid():
|
||||
prev.kill()
|
||||
var tw := _cele.create_tween()
|
||||
var tw := st._cele.create_tween()
|
||||
set_meta(&"celebrate_tw", tw)
|
||||
tw.set_loops()
|
||||
tw.tween_property(_cele, "position:y", _cele.position.y - 4.0, UiKit.motion(0.6)).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
tw.tween_property(_cele, "position:y", _cele.position.y, UiKit.motion(0.6)).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
tw.tween_property(st._cele, "position:y", st._cele.position.y - 4.0, UiKit.motion(0.6)).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
tw.tween_property(st._cele, "position:y", st._cele.position.y, UiKit.motion(0.6)).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||
|
||||
|
||||
# 尘金粒子(备选演出——金屑自面板上带飘落闪灭;确定性散布守 S2)
|
||||
func _play_victory_dust() -> void:
|
||||
_fx_dust_motes += 10
|
||||
st._fx_counts["dust"] += 10
|
||||
var c := _fx_center()
|
||||
for i in 10:
|
||||
var mote := ColorRect.new()
|
||||
mote.color = UiKit.CANDLE
|
||||
mote.size = Vector2(5, 5)
|
||||
mote.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
mote.position = c + Vector2((float(i % 5) - 2.0) * 44.0, -40.0 - 10.0 * float(i / 5))
|
||||
add_child(mote)
|
||||
var tw := mote.create_tween()
|
||||
tw.tween_interval(UiKit.motion(0.12 * i))
|
||||
tw.tween_property(mote, "position:y", mote.position.y + 90.0, UiKit.motion(1.1))
|
||||
tw.parallel().tween_property(mote, "modulate:a", 0.0, UiKit.motion(1.1))
|
||||
tw.tween_callback(mote.queue_free)
|
||||
_spawn_victory_mote(i, c)
|
||||
|
||||
|
||||
## 单金屑域(循环体提函数——上带散布飘落闪灭)
|
||||
func _spawn_victory_mote(i: int, c: Vector2) -> void:
|
||||
var mote := ColorRect.new()
|
||||
mote.color = UiKit.CANDLE
|
||||
mote.size = Vector2(5, 5)
|
||||
mote.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
mote.position = c + Vector2((float(i % 5) - 2.0) * 44.0, -40.0 - 10.0 * float(i / 5))
|
||||
add_child(mote)
|
||||
var tw := mote.create_tween()
|
||||
tw.tween_interval(UiKit.motion(0.12 * i))
|
||||
tw.tween_property(mote, "position:y", mote.position.y + 90.0, UiKit.motion(1.1))
|
||||
tw.parallel().tween_property(mote, "modulate:a", 0.0, UiKit.motion(1.1))
|
||||
tw.tween_callback(mote.queue_free)
|
||||
|
||||
|
||||
# GP 行数字滚动(demo ⑧——0.8s 三次缓出;减动效直出终值)
|
||||
@@ -325,15 +377,15 @@ func _roll_gp(gp_gain: int, gp_total: int) -> void:
|
||||
|
||||
|
||||
func _clear_crest_bricks() -> void:
|
||||
for b in _crest_bricks:
|
||||
for b in st._crest_bricks:
|
||||
if is_instance_valid(b):
|
||||
b.queue_free()
|
||||
_crest_bricks.clear()
|
||||
st._crest_bricks.clear()
|
||||
|
||||
|
||||
# 演出探针出口(fx_probe——胜利纹章/失败掸灰/封印光收回三断言面)
|
||||
func fx_probe() -> Dictionary:
|
||||
return {"crest_shards": _fx_crest_shards, "dust_motes": _fx_dust_motes, "seal_dots": _fx_seal_dots}
|
||||
return {"crest_shards": st._fx_counts["crest"], "dust_motes": st._fx_counts["dust"], "seal_dots": st._fx_counts["seal"]}
|
||||
|
||||
|
||||
func _emit_continue_pressed() -> void:
|
||||
|
||||
@@ -30,9 +30,14 @@ func _init() -> void:
|
||||
var col := VBoxContainer.new()
|
||||
col.add_theme_constant_override("separation", 14) # 布局充实(区段间距放大)
|
||||
add_child(col)
|
||||
_build_data_row(col)
|
||||
_build_slots(col)
|
||||
_build_side_sections(col)
|
||||
|
||||
|
||||
## 数据行域(直角细线数据框——battle.md Component Inventory C 区行规格落形;同时消化纵向空白)
|
||||
func _build_data_row(col: VBoxContainer) -> void:
|
||||
col.add_child(UiKit.label("探险者",UiKit.FS_SUB, true))
|
||||
# 数据行装框(直角细线数据框——battle.md Component Inventory C 区行规格落形;同时消化纵向空白)
|
||||
var data_box := PanelContainer.new()
|
||||
data_box.add_theme_stylebox_override("panel",
|
||||
UiKit.panel_flat(UiKit.PANEL_DATA, UiKit.PANEL_BORDER, 0, 1, Vector4(6, 4, 6, 4)))
|
||||
@@ -45,55 +50,60 @@ func _init() -> void:
|
||||
_armor_label = _data_line()
|
||||
data_col.add_child(_armor_label)
|
||||
|
||||
# 秘宝槽(预留):随身战斗用道具的唯一展示面——空槽占位承诺格子在此,
|
||||
# 不预设交互(挖掘期指向交互归 E 区既有裁决)
|
||||
|
||||
## 秘宝槽域(预留):随身战斗用道具的唯一展示面——空槽占位承诺格子在此,
|
||||
## 不预设交互(挖掘期指向交互归 E 区既有裁决)
|
||||
func _build_slots(col: VBoxContainer) -> void:
|
||||
col.add_child(UiKit.label("秘宝",UiKit.FS_BODY, true))
|
||||
item_slots = HBoxContainer.new()
|
||||
item_slots.add_theme_constant_override("separation", 10)
|
||||
col.add_child(item_slots)
|
||||
for i in 4:
|
||||
var slot := PanelContainer.new()
|
||||
slot.custom_minimum_size = Vector2(48, 48)
|
||||
slot.add_theme_stylebox_override("panel",
|
||||
UiKit.panel_flat(UiKit.PANEL_DATA, UiKit.PANEL_BORDER, 0, 1, Vector4(4, 4, 4, 4)))
|
||||
var idx := i
|
||||
slot.gui_input.connect(func(ev: InputEvent):
|
||||
if ev is InputEventMouseButton and ev.pressed and ev.button_index == MOUSE_BUTTON_LEFT:
|
||||
# 空槽/越界槽点击=取消选中(handle 0);有效槽发其 handle(组合根判 AP 即用/进选中态)
|
||||
treasure_slot_clicked.emit(_slot_handles[idx] if idx < _slot_handles.size() else 0))
|
||||
item_slots.add_child(slot)
|
||||
_slot_panels.append(slot)
|
||||
_slot_panels.append(_build_slot(i))
|
||||
|
||||
# 特性持有段(三选一特性兑付后常驻可读:逐件行「件名 ×N」;空态整节隐藏。
|
||||
# 上移承载——构筑核心信息优先级高于临时强化,且防 C 区下部裁切不可见)
|
||||
_feat_section = VBoxContainer.new()
|
||||
_feat_section.add_theme_constant_override("separation", 4)
|
||||
_feat_section.visible = false
|
||||
col.add_child(_feat_section)
|
||||
_feat_section.add_child(UiKit.label("专长",UiKit.FS_BODY, true))
|
||||
_feat_list = VBoxContainer.new()
|
||||
_feat_list.add_theme_constant_override("separation", 2)
|
||||
_feat_section.add_child(_feat_list)
|
||||
# 地形变异常驻角标(Boss 图整图型战斗全程可见防中局遗忘;
|
||||
# 空态整节隐藏=特性段先例;摆位/文案 provisional)
|
||||
_board_variant_section = VBoxContainer.new()
|
||||
_board_variant_section.add_theme_constant_override("separation", 4)
|
||||
_board_variant_section.visible = false
|
||||
col.add_child(_board_variant_section)
|
||||
_board_variant_section.add_child(UiKit.label("地形变异",UiKit.FS_BODY, true))
|
||||
_board_variant_list = VBoxContainer.new()
|
||||
_board_variant_list.add_theme_constant_override("separation", 2)
|
||||
_board_variant_section.add_child(_board_variant_list)
|
||||
# 特性(预留):锻造/大奖励/关卡奖励节点的属性提升——中循环数据因改变战斗数学准入;
|
||||
# 与战斗内状态效果(B 区站桩,随战斗消散)分区,防「战斗结束被清」误读;空态整节隐藏
|
||||
_curio_section = VBoxContainer.new()
|
||||
_curio_section.add_theme_constant_override("separation", 4)
|
||||
_curio_section.visible = false
|
||||
col.add_child(_curio_section)
|
||||
_curio_section.add_child(UiKit.label("属性值提升",UiKit.FS_BODY, true))
|
||||
_curio_list = VBoxContainer.new()
|
||||
_curio_list.add_theme_constant_override("separation", 2)
|
||||
_curio_section.add_child(_curio_list)
|
||||
|
||||
## 单槽构建域:48px 槽牌+点击路由(空槽/越界槽点击=取消选中 handle 0;有效槽发其 handle)
|
||||
func _build_slot(i: int) -> PanelContainer:
|
||||
var slot := PanelContainer.new()
|
||||
slot.custom_minimum_size = Vector2(48, 48)
|
||||
slot.add_theme_stylebox_override("panel",
|
||||
UiKit.panel_flat(UiKit.PANEL_DATA, UiKit.PANEL_BORDER, 0, 1, Vector4(4, 4, 4, 4)))
|
||||
var idx := i
|
||||
slot.gui_input.connect(func(ev: InputEvent):
|
||||
if ev is InputEventMouseButton and ev.pressed and ev.button_index == MOUSE_BUTTON_LEFT:
|
||||
# 空槽/越界槽点击=取消选中(handle 0);有效槽发其 handle(组合根判 AP 即用/进选中态)
|
||||
treasure_slot_clicked.emit(_slot_handles[idx] if idx < _slot_handles.size() else 0))
|
||||
item_slots.add_child(slot)
|
||||
return slot
|
||||
|
||||
|
||||
## 三区段域(特性持有段上移承载——构筑核心信息优先级高于临时强化,且防 C 区下部裁切不可见/
|
||||
## 地形变异常驻角标 Boss 图整图型战斗全程可见防中局遗忘/特性预留段防「战斗结束被清」误读;空态整节隐藏)
|
||||
func _build_side_sections(col: VBoxContainer) -> void:
|
||||
_feat_section = _labeled_section(col, "专长")
|
||||
_feat_list = _list_of(_feat_section)
|
||||
_board_variant_section = _labeled_section(col, "地形变异")
|
||||
_board_variant_list = _list_of(_board_variant_section)
|
||||
_curio_section = _labeled_section(col, "属性值提升")
|
||||
_curio_list = _list_of(_curio_section)
|
||||
|
||||
|
||||
## 区段骨架(标题+隐藏容器)
|
||||
func _labeled_section(col: VBoxContainer, title: String) -> VBoxContainer:
|
||||
var section := VBoxContainer.new()
|
||||
section.add_theme_constant_override("separation", 4)
|
||||
section.visible = false
|
||||
col.add_child(section)
|
||||
section.add_child(UiKit.label(title,UiKit.FS_BODY, true))
|
||||
return section
|
||||
|
||||
|
||||
## 行板容器(separation 2)
|
||||
func _list_of(section: VBoxContainer) -> VBoxContainer:
|
||||
var list := VBoxContainer.new()
|
||||
list.add_theme_constant_override("separation", 2)
|
||||
section.add_child(list)
|
||||
return list
|
||||
|
||||
|
||||
func set_attack(atk: int, mod_text: String) -> void:
|
||||
@@ -174,46 +184,69 @@ func set_treasure_inventory(items: Array, selected_handle: int) -> void:
|
||||
continue
|
||||
var rec: Dictionary[Variant, Variant] = items[i]
|
||||
_slot_handles.append(int(rec.get("handle", 0)))
|
||||
var used := bool(rec.get("used", false))
|
||||
var usable := bool(rec.get("usable", true))
|
||||
var selected := selected_handle != 0 and int(rec.get("handle", 0)) == selected_handle
|
||||
# 槽内容=手绘像素图标(demo ⑦;glyph 字符→图标键映射,未映射/used/不可用回退字形+条件墨色)
|
||||
var glyph_ch := String(rec.get("glyph", "?"))
|
||||
var icon_map := {"爆": UiKit.TEX_ICON_BLAST, "医": UiKit.TEX_ICON_MEDKIT,
|
||||
"铲": UiKit.TEX_ICON_SHOVEL, "袋": UiKit.TEX_ICON_COINBAG, "钥": UiKit.TEX_ICON_KEYSHARD,
|
||||
"剑": UiKit.TEX_ICON_SWORD, "盾": UiKit.TEX_ICON_SHIELD, "心": UiKit.TEX_ICON_HEART,
|
||||
"行": UiKit.TEX_ICON_POUCH}
|
||||
var icon_path: String = icon_map.get(glyph_ch, "")
|
||||
var itex := UiKit.load_tex(icon_path) if icon_path != "" else null
|
||||
if itex != null and not used and usable:
|
||||
var tr := TextureRect.new()
|
||||
tr.texture = itex
|
||||
tr.custom_minimum_size = Vector2(40, 40)
|
||||
tr.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||
tr.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
tr.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
tr.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
tr.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
slot.add_child(tr)
|
||||
else:
|
||||
var glyph := UiKit.label(glyph_ch,UiKit.FS_SUB, true)
|
||||
glyph.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
glyph.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
glyph.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
glyph.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
if used:
|
||||
# 「已用」占位墨=灰石深化(STONE_FAINT 对 PANEL_DATA 槽牌 2.7:1;
|
||||
# STONE_DEEP = 5.6:1;语义分档保持双墨)
|
||||
glyph.add_theme_color_override("font_color", UiKit.STONE_DEEP)
|
||||
elif not usable:
|
||||
# 「不可用」置灰墨=标签深墨(STONE 对槽牌 3.4:1;INK_LABEL = 10.4:1,虚位/失效更强置灰语义)
|
||||
glyph.add_theme_color_override("font_color", UiKit.INK_LABEL)
|
||||
slot.add_child(glyph)
|
||||
var border_col: Color = UiKit.GOLD if selected else UiKit.PANEL_BORDER
|
||||
slot.add_theme_stylebox_override("panel",
|
||||
UiKit.panel_flat(UiKit.PANEL_DATA, border_col, 0, 1 if not selected else 2, Vector4(4, 4, 4, 4)))
|
||||
# note=积点进度行(自动兑付件悬停浮窗补「积点 N/M」,进度随挖格经组合根重查刷新)
|
||||
var note := String(rec.get("note", ""))
|
||||
slot.tooltip_text = "%s%s%s" % [String(rec.get("name", "")),
|
||||
"(%s)" % note if note != "" else "",
|
||||
"(已用)" if used else ("(不可用——当前无有效目标)" if not usable else "")]
|
||||
_fill_slot(slot, rec, selected_handle)
|
||||
|
||||
|
||||
## 单槽内容填充域:图标优先(像素图标未映射/used/不可用回退字形+条件墨色)+选中金框+悬停浮窗
|
||||
func _fill_slot(slot: PanelContainer, rec: Dictionary, selected_handle: int) -> void:
|
||||
var used := bool(rec.get("used", false))
|
||||
var usable := bool(rec.get("usable", true))
|
||||
var selected := selected_handle != 0 and int(rec.get("handle", 0)) == selected_handle
|
||||
# 槽内容=手绘像素图标(demo ⑦;glyph 字符→图标键映射,未映射/used/不可用回退字形+条件墨色)
|
||||
var itex := _slot_icon_tex(String(rec.get("glyph", "?")))
|
||||
if itex != null and not used and usable:
|
||||
slot.add_child(_slot_icon_rect(itex))
|
||||
else:
|
||||
slot.add_child(_slot_glyph_label(String(rec.get("glyph", "?")), used, usable))
|
||||
var border_col: Color = UiKit.GOLD if selected else UiKit.PANEL_BORDER
|
||||
slot.add_theme_stylebox_override("panel",
|
||||
UiKit.panel_flat(UiKit.PANEL_DATA, border_col, 0, 1 if not selected else 2, Vector4(4, 4, 4, 4)))
|
||||
slot.tooltip_text = _slot_tooltip(rec, used, usable)
|
||||
|
||||
|
||||
## 字形→图标纹理映射(demo ⑦ 键表单点)
|
||||
func _slot_icon_tex(glyph_ch: String) -> Texture2D:
|
||||
var icon_map := {"爆": UiKit.TEX_ICON_BLAST, "医": UiKit.TEX_ICON_MEDKIT,
|
||||
"铲": UiKit.TEX_ICON_SHOVEL, "袋": UiKit.TEX_ICON_COINBAG, "钥": UiKit.TEX_ICON_KEYSHARD,
|
||||
"剑": UiKit.TEX_ICON_SWORD, "盾": UiKit.TEX_ICON_SHIELD, "心": UiKit.TEX_ICON_HEART,
|
||||
"行": UiKit.TEX_ICON_POUCH}
|
||||
var icon_path: String = icon_map.get(glyph_ch, "")
|
||||
return UiKit.load_tex(icon_path) if icon_path != "" else null
|
||||
|
||||
|
||||
## 图标矩形域(40px 素描框,像素过滤)
|
||||
func _slot_icon_rect(itex: Texture2D) -> TextureRect:
|
||||
var tr := TextureRect.new()
|
||||
tr.texture = itex
|
||||
tr.custom_minimum_size = Vector2(40, 40)
|
||||
tr.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||
tr.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
tr.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
tr.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
tr.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
return tr
|
||||
|
||||
|
||||
## 字形回退标签域(used=灰石深化墨 5.6:1/不可用=标签深墨 10.4:1 虚位失效更强置灰——语义分档双墨)
|
||||
func _slot_glyph_label(glyph_ch: String, used: bool, usable: bool) -> Label:
|
||||
var glyph := UiKit.label(glyph_ch,UiKit.FS_SUB, true)
|
||||
glyph.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
glyph.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
glyph.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
glyph.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
if used:
|
||||
# 「已用」占位墨=灰石深化(STONE_FAINT 对 PANEL_DATA 槽牌 2.7:1;
|
||||
# STONE_DEEP = 5.6:1;语义分档保持双墨)
|
||||
glyph.add_theme_color_override("font_color", UiKit.STONE_DEEP)
|
||||
elif not usable:
|
||||
# 「不可用」置灰墨=标签深墨(STONE 对槽牌 3.4:1;INK_LABEL = 10.4:1,虚位/失效更强置灰语义)
|
||||
glyph.add_theme_color_override("font_color", UiKit.INK_LABEL)
|
||||
return glyph
|
||||
|
||||
|
||||
## 悬停浮窗域(note=积点进度行——自动兑付件悬停浮窗补「积点 N/M」,进度随挖格经组合根重查刷新)
|
||||
func _slot_tooltip(rec: Dictionary, used: bool, usable: bool) -> String:
|
||||
var note := String(rec.get("note", ""))
|
||||
return "%s%s%s" % [String(rec.get("name", "")),
|
||||
"(%s)" % note if note != "" else "",
|
||||
"(已用)" if used else ("(不可用——当前无有效目标)" if not usable else "")]
|
||||
@@ -157,7 +157,7 @@ func _ready() -> void:
|
||||
problems.append("[battle_hud] 候选中无战斗节点(驱动中断——候选=%s)" % str(main.level_screen._cand_ids))
|
||||
|
||||
# ---- 兑付屏(真实 open 面 + 合成最小数据——结构断言只看矩形/宽度/可见性)----
|
||||
main._end_overlay.open_victory("结构探针·胜利演算", "返回", Rect2(200, 200, 400, 300), "GP 0")
|
||||
main._end_overlay.open_victory("结构探针·胜利演算", "返回", Rect2(200, 200, 400, 300), {"gp_summary": "GP 0"})
|
||||
_settle()
|
||||
await _audit("battle_end", [main._end_overlay])
|
||||
main._end_overlay.close()
|
||||
|
||||
Reference in new issue
Block a user