T4 UiKit色彩骨架收口段: modal_shell/modal_dim收10处overlay骨架(dim色/min_size/panel参数化对照表在报告,探针私有件同名同层级保留)+label加color参收全层两行式+裸色收口(standee/camp/stage/level_map/board_world Color8→UiKit档13色+HEX_LOG_*/HEX_ROUTE/SEED 13档——值逐字节不变)+杂并七件(UiKit.scaled收双实现/到达拍块合并/点阵合并/画布常数单点/瓦片词表单点化/占位文案const/with_bar判据/bonus内联lambda改具名);ArmedConfirm三处语义异构降级记06(不做了半套);闸=冲烟636/0+run_all 15套+八探针全绿+熵增闸PASS
This commit is contained in:
1 parent
315e46038c
commit
5584feb6e5
27 files changed
+263
-345
No files matched your search
@@ -6,24 +6,24 @@
|
||||
extends RefCounted
|
||||
|
||||
|
||||
# 节点进入横幅(棋盘日志——battle/boss 用;节点编号 = 行进器编号空间读面)
|
||||
# 节点进入横幅(棋盘日志——battle/boss 用;节点编号 = 行进器编号空间读面;行色 = UiKit.HEX_* 语义档单点)
|
||||
static func node_banner(runner, node: Dictionary, t: String) -> String:
|
||||
return "[color=#e0b860]── 节点 %d/%d · %s(编号 %d)──[/color]" % [
|
||||
return "[color=#%s]── 节点 %d/%d · %s(编号 %d)──[/color]" % [UiKit.HEX_LOG_GAIN,
|
||||
runner.node_index + 1, runner.nodes().size(),
|
||||
"Boss 房" if t == "boss" else "战斗", runner.node_id_of(node)]
|
||||
|
||||
|
||||
static func reward_line() -> String:
|
||||
return "[color=#d0c090]关卡奖励点(节点内容待定——直通)[/color]"
|
||||
return "[color=#%s]关卡奖励点(节点内容待定——直通)[/color]" % UiKit.HEX_ROUTE_NOTE
|
||||
|
||||
|
||||
static func rest_line(healed: int, hp: int, max_hp: int) -> String:
|
||||
return "[color=#7cc47c]恢复点:回复 %d HP(→ %d/%d)[/color]" % [healed, hp, max_hp]
|
||||
return "[color=#%s]恢复点:回复 %d HP(→ %d/%d)[/color]" % [UiKit.HEX_LOG_HEAL, healed, hp, max_hp]
|
||||
|
||||
|
||||
# 商店房行(GP+商店房实施批——到达即开店;购买/离开归玩家意图)
|
||||
static func shop_line(gp: int) -> String:
|
||||
return "[color=#e0b860]商店房:金币 %d——购买即时生效,离开后选下一跳[/color]" % gp
|
||||
return "[color=#%s]商店房:金币 %d——购买即时生效,离开后选下一跳[/color]" % [UiKit.HEX_LOG_GAIN, gp]
|
||||
|
||||
|
||||
# 选路口行(零自动推进停点——战斗胜利/兑付确认后出现)
|
||||
@@ -31,18 +31,18 @@ static func route_line(candidates: Array, runner) -> String:
|
||||
var names: Array[String] = []
|
||||
for cand in candidates:
|
||||
names.append("节点 %d" % runner.node_id_of(cand))
|
||||
return "[color=#e0b860]── 岔路口:可选下一跳 %s ──[/color]" % " / ".join(names)
|
||||
return "[color=#%s]── 岔路口:可选下一跳 %s ──[/color]" % [UiKit.HEX_LOG_GAIN, " / ".join(names)]
|
||||
|
||||
|
||||
# 关卡开场行(种子/加成口径注记——面板加成是否生效由调用方传入)
|
||||
static func level_open_line(level_display: String, seed_val: int, atk: int, max_hp: int, boosted: bool) -> String:
|
||||
return "[color=#c8a860]%s · 种子 %d · 攻击 %d / 生命 %d%s[/color]" % [
|
||||
return "[color=#%s]%s · 种子 %d · 攻击 %d / 生命 %d%s[/color]" % [UiKit.HEX_SEED_NOTE,
|
||||
level_display, seed_val, atk, max_hp, "(含面板加成)" if boosted else ""]
|
||||
|
||||
|
||||
# 调试开场行
|
||||
static func debug_open_line(seed_val: int, level: int, level_mode: bool) -> String:
|
||||
return "[color=#c8a860]种子 %d · 遭遇 %d 层%s[/color]" % [
|
||||
return "[color=#%s]种子 %d · 遭遇 %d 层%s[/color]" % [UiKit.HEX_SEED_NOTE,
|
||||
seed_val, level, "(关卡模式 · HP 延续)" if level_mode else ""]
|
||||
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ static func outcome_text(outcome: Dictionary) -> String:
|
||||
static func tune_sim_report(n: int, atk_pct: int, hp_pct: int, wins: int, dmg_all: Array, hp_left_win: Array, hp_boss: Array, rounds_all: Array, death_nodes: Dictionary, base_hp: int) -> String:
|
||||
var lines: Array[String] = []
|
||||
lines.append("[b]模拟 N=%d(atk+%d%% / hp+%d%%)[/b]" % [n, atk_pct, hp_pct])
|
||||
lines.append("通关率 [color=#80d080]%.0f%%[/color](%d/%d)" % [100.0 * float(wins) / float(maxi(1, n)), wins, n])
|
||||
lines.append("通关率 [color=#%s]%.0f%%[/color](%d/%d)" % [UiKit.HEX_LOG_WIN, 100.0 * float(wins) / float(maxi(1, n)), wins, n])
|
||||
lines.append("整关承伤:均 %.1f · p90 %.0f(基础 HP %d)" % [_mean(dmg_all), _p90(dmg_all), base_hp])
|
||||
if not hp_left_win.is_empty():
|
||||
lines.append("通关剩余 HP 均 %.1f · 进 Boss HP 均 %.1f" % [_mean(hp_left_win), _mean(hp_boss)])
|
||||
|
||||
@@ -268,8 +268,7 @@ func _build_ui() -> void:
|
||||
|
||||
|
||||
func _fatal_screen(msg: String) -> void:
|
||||
var l := UiKit.label(msg, 20, true)
|
||||
l.add_theme_color_override("font_color", UiKit.RED_ALERT)
|
||||
var l := UiKit.label(msg, 20, true, UiKit.RED_ALERT)
|
||||
l.set_anchors_preset(Control.PRESET_CENTER)
|
||||
add_child(l)
|
||||
|
||||
@@ -689,14 +688,11 @@ func _on_inter_next_pressed() -> void:
|
||||
|
||||
|
||||
# E4:加成生效值供给(debug_session 注入 Callable——每次从面板百分比现算,经 encounter 传参零表写;
|
||||
# 原表写路径 _apply_hero_override/_scaled_override 已废除,双写叠加 6→18→54 整类隐患随之移除)
|
||||
# 原表写路径 _apply_hero_override/_scaled_override 已废除,双写叠加 6→18→54 整类隐患随之移除;
|
||||
# 合成式单点在 UiKit.scaled——与 TunePanel 生效值预览共用,本类不再持有同式私有实现)
|
||||
func _debug_hero_override() -> Dictionary:
|
||||
return {"atk": _scaled(int(db.hero.atk), tune_panel.atk_pct()),
|
||||
"max_hp": _scaled(int(db.hero.max_hp), tune_panel.hp_pct())}
|
||||
|
||||
|
||||
func _scaled(base: int, pct: int) -> int:
|
||||
return maxi(1, int(round(float(base) * (100.0 + float(pct)) / 100.0)))
|
||||
return {"atk": UiKit.scaled(int(db.hero.atk), tune_panel.atk_pct()),
|
||||
"max_hp": UiKit.scaled(int(db.hero.max_hp), tune_panel.hp_pct())}
|
||||
|
||||
|
||||
# 奖励徽章身份解析(组合根守卫:仅挖掘期 Active 相位内查询——地图战斗资源 Ready 域外零读、零诊断噪音;
|
||||
|
||||
@@ -114,18 +114,17 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary:
|
||||
bd.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
overlay.add_child(bd)
|
||||
var box := overlay_box(overlay)
|
||||
var title := UiKit.label("Dungeon Sweeper", 34, true)
|
||||
title.add_theme_color_override("font_color", UiKit.WARM)
|
||||
var title := UiKit.label("Dungeon Sweeper", 34, true, UiKit.WARM)
|
||||
box.add_child(title)
|
||||
var sub := UiKit.label("战斗屏战斗屏改造批 —— 扫雷的因,逐行兑现的果", 16, false)
|
||||
sub.add_theme_color_override("font_color", UiKit.WARM) # 对比度修复(v3.5 批 B3——WARM_SOFT 对深石底实测 3.54:1→暖白 ≥6:1)
|
||||
# 对比度修复(v3.5 批 B3——WARM_SOFT 对深石底实测 3.54:1→暖白 ≥6:1)
|
||||
var sub := UiKit.label("战斗屏战斗屏改造批 —— 扫雷的因,逐行兑现的果", 16, false, UiKit.WARM)
|
||||
box.add_child(sub)
|
||||
box.add_child(HSeparator.new())
|
||||
|
||||
var seed_row := HBoxContainer.new()
|
||||
box.add_child(seed_row)
|
||||
var seed_label := UiKit.label("随机种子:", 16, false) # 字号下限(v3.5 批 B3——正文 ≥16)+暗底显式暖白
|
||||
seed_label.add_theme_color_override("font_color", UiKit.WARM)
|
||||
# 字号下限(v3.5 批 B3——正文 ≥16)+暗底显式暖白
|
||||
var seed_label := UiKit.label("随机种子:", 16, false, UiKit.WARM)
|
||||
seed_row.add_child(seed_label)
|
||||
var seed_edit := LineEdit.new()
|
||||
seed_edit.text = "42"
|
||||
@@ -153,9 +152,8 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary:
|
||||
# 玩法帮助文案(表值驱动——2026-09-16 AP 压速批遗留硬编码 8 随手修正;护甲等级掷点批同步"减伤"→"护甲强化")
|
||||
var help_text := "玩法:每轮 %d AP——挖开(1AP)/插旗(1AP)/移动(免费)/连锁(免费)。\n每个非封锁格都藏一种格面资源(增伤/护甲强化/回血/爆裂/削弱)。开安全格、标中雷 = 正向兑付;\n开雷格、标错安全格 = 负向兑付——全部在轮末结算逐行兑现;吃掷点的基础攻击按护甲等级判定,无 miss、最低保底 1 点。\n停手:剩余 AP 转存 RAP;弃图刷新:RAP−%d 当场换图继续挖(每轮剩 %d 次)。\n敌人全灭胜、主角倒下负。悬停可看三态光标与可挖域微光。" % [
|
||||
int(db.action_economy.ap_per_round), int(db.action_economy.rap_refresh_cost), int(db.action_economy.refresh_cap_per_round)]
|
||||
var help := UiKit.label(help_text, 16, false) # 字号下限(v3.5 批 B3——正文 ≥16)
|
||||
# 对比度修复(v3.5 批 B3——WARM_FAINT 对深石底实测 2.58:1→暖白 ≥6:1;暗底双色墨制)
|
||||
help.add_theme_color_override("font_color", UiKit.WARM)
|
||||
# 字号下限(v3.5 批 B3——正文 ≥16);对比度修复(v3.5 批 B3——WARM_FAINT 对深石底实测 2.58:1→暖白 ≥6:1;暗底双色墨制)
|
||||
var help := UiKit.label(help_text, 16, false, UiKit.WARM)
|
||||
box.add_child(help)
|
||||
|
||||
return {"overlay": overlay, "box": box, "seed_edit": seed_edit,
|
||||
@@ -167,8 +165,7 @@ static func build_start_overlay(host: Control, db = null) -> Dictionary:
|
||||
static func build_inter_overlay(host: Control) -> Dictionary:
|
||||
var overlay := overlay_bg(host, Color(0, 0, 0, 0.6))
|
||||
var box := overlay_box(overlay)
|
||||
var label := UiKit.label("", 24, true)
|
||||
label.add_theme_color_override("font_color", UiKit.WARM)
|
||||
var label := UiKit.label("", 24, true, UiKit.WARM)
|
||||
box.add_child(label)
|
||||
var next_btn := UiKit.button("进入下一层")
|
||||
box.add_child(next_btn)
|
||||
|
||||
@@ -71,8 +71,7 @@ func _init() -> void:
|
||||
_rap_label = UiKit.label("RAP 0", 14, true)
|
||||
_rap_label.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
row.add_child(_rap_label)
|
||||
_rap_feedback = UiKit.label("", 11, false)
|
||||
_rap_feedback.add_theme_color_override("font_color", UiKit.STONE_FAINT)
|
||||
_rap_feedback = UiKit.label("", 11, false, UiKit.STONE_FAINT)
|
||||
_rap_feedback.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
row.add_child(_rap_feedback)
|
||||
|
||||
@@ -81,8 +80,7 @@ func _init() -> void:
|
||||
_confirm_row.add_theme_constant_override("separation", 4)
|
||||
_confirm_row.visible = false
|
||||
row.add_child(_confirm_row)
|
||||
_confirm_lab = UiKit.label("RAP−%d · 旧板旗作废" % refresh_cost, 14, true)
|
||||
_confirm_lab.add_theme_color_override("font_color", COL_INK)
|
||||
_confirm_lab = UiKit.label("RAP−%d · 旧板旗作废" % refresh_cost, 14, true, COL_INK)
|
||||
_confirm_row.add_child(_confirm_lab)
|
||||
var confirm_btn := UiKit.button("确认弃图")
|
||||
confirm_btn.pressed.connect(_disarm_and_fire)
|
||||
@@ -153,21 +151,21 @@ func set_rap(rap: int) -> void:
|
||||
_rap_feedback.text = ""
|
||||
|
||||
|
||||
# 资源面拒绝反馈(pattern 1 resource_face 腿):RAP 数字脉冲(RAP<8 弃图刷新被拒)
|
||||
func pulse_rap() -> void:
|
||||
# 资源读数拒绝脉冲单点(pattern 1 resource_face 腿——RAP/AP 两份逐字重复合并:朱红脉冲一拍回白)
|
||||
func _pulse(label: Label) -> void:
|
||||
var tw := create_tween()
|
||||
tw.tween_property(_rap_label, "modulate", Color(1.0, 0.4, 0.3), UiKit.motion(0.1))
|
||||
tw.tween_property(_rap_label, "modulate", Color(1, 1, 1), UiKit.motion(0.25))
|
||||
tw.tween_property(label, "modulate", Color(1.0, 0.4, 0.3), UiKit.motion(0.1))
|
||||
tw.tween_property(label, "modulate", Color(1, 1, 1), UiKit.motion(0.25))
|
||||
|
||||
|
||||
func pulse_rap() -> void:
|
||||
_pulse(_rap_label)
|
||||
|
||||
|
||||
func _render_rap_dots(rap: int) -> void:
|
||||
var shown := mini(rap, 16)
|
||||
while _rap_dots.get_child_count() < shown:
|
||||
var d := ColorRect.new()
|
||||
d.custom_minimum_size = Vector2(8, 8)
|
||||
d.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
d.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
_rap_dots.add_child(d)
|
||||
_rap_dots.add_child(_make_dot(8.0, true)) # RAP 点阵 8px 窄档(随读数字号)——建点单点共用
|
||||
for i in _rap_dots.get_child_count():
|
||||
var d: ColorRect = _rap_dots.get_child(i)
|
||||
d.color = COL_GOLD if i < shown else COL_DOT_OFF
|
||||
@@ -226,14 +224,14 @@ func _disarm() -> void:
|
||||
|
||||
# 资源面拒绝反馈(pattern 1 resource_face 腿):AP 数字脉冲
|
||||
func pulse_ap() -> void:
|
||||
var tw := create_tween()
|
||||
tw.tween_property(_ap_label, "modulate", Color(1.0, 0.4, 0.3), UiKit.motion(0.1))
|
||||
tw.tween_property(_ap_label, "modulate", Color(1, 1, 1), UiKit.motion(0.25))
|
||||
_pulse(_ap_label)
|
||||
|
||||
|
||||
func _make_dot() -> ColorRect:
|
||||
# 点阵建点单点(AP 10px / RAP 8px 两套建点参数化合并;初始色=熄灭档——投影循环当拍覆写)
|
||||
func _make_dot(px := 10.0, shrink_center := false) -> ColorRect:
|
||||
var d := ColorRect.new()
|
||||
d.custom_minimum_size = Vector2(10, 10)
|
||||
d.custom_minimum_size = Vector2(px, px)
|
||||
d.size_flags_vertical = Control.SIZE_SHRINK_CENTER if shrink_center else Control.SIZE_FILL
|
||||
d.color = COL_DOT_OFF
|
||||
d.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
return d
|
||||
|
||||
@@ -24,22 +24,13 @@ var _board_rect := Rect2()
|
||||
|
||||
func _init() -> void:
|
||||
# 二轮修改批 B(2026-09-29 用户目检裁决):半透明浮层文字不可读 → 实底石板皮面板形态
|
||||
#(与营地/设置/图例同族)。半透明氛围 dim 保留(胜利暖纱/失败暮蓝),信息与按钮全部上板;
|
||||
# 金蜡封 = 面板头部静态徽记(原全屏坠落演出退役——落点被面板遮挡)。
|
||||
_dim = ColorRect.new()
|
||||
_dim.color = Color(COL_WARM, 0.0)
|
||||
_dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(_dim)
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
_dim.add_child(center)
|
||||
var panel := PanelContainer.new()
|
||||
panel.add_theme_stylebox_override("panel", UiKit.panel_skinned(Vector4(16, 14, 16, 14)))
|
||||
center.add_child(panel)
|
||||
var box := VBoxContainer.new()
|
||||
box.custom_minimum_size = Vector2(520, 0)
|
||||
box.add_theme_constant_override("separation", 12)
|
||||
panel.add_child(box)
|
||||
#(与营地/设置/图例同族)。半透明氛围 dim 保留(胜利暖纱/失败暮蓝——open_* 就地换色),信息与
|
||||
# 按钮全部上板;金蜡封 = 面板头部静态徽记(原全屏坠落演出退役——落点被面板遮挡)。
|
||||
# 骨架经 UiKit.modal_shell(T4 收口批);_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
|
||||
var box: VBoxContainer = shell.box
|
||||
var header := HBoxContainer.new()
|
||||
header.add_theme_constant_override("separation", 12)
|
||||
header.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
@@ -51,13 +42,11 @@ func _init() -> void:
|
||||
_seal.custom_minimum_size = Vector2(34, 34)
|
||||
_seal.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
header.add_child(_seal)
|
||||
_verdict = UiKit.label("", 24, true)
|
||||
_verdict.add_theme_color_override("font_color", UiKit.INK_TITLE)
|
||||
_verdict = UiKit.label("", 24, true, UiKit.INK_TITLE)
|
||||
_verdict.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
_verdict.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
header.add_child(_verdict)
|
||||
_gp_line = UiKit.label("", 16, true)
|
||||
_gp_line.add_theme_color_override("font_color", UiKit.INK_LABEL)
|
||||
_gp_line = UiKit.label("", 16, true, UiKit.INK_LABEL)
|
||||
_gp_line.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
_gp_line.visible = false
|
||||
box.add_child(_gp_line)
|
||||
|
||||
@@ -40,15 +40,13 @@ func _init(db_ref) -> void:
|
||||
add_child(vb)
|
||||
var head := HBoxContainer.new()
|
||||
vb.add_child(head)
|
||||
_summary = UiKit.label("", 16, false)
|
||||
# 对比度修复(v3.5 批 B3 2026-09-30——明细条灰字对深灰底实测 2.63:1):暗底双色墨制=暖白族
|
||||
_summary.add_theme_color_override("font_color", UiKit.WARM)
|
||||
_summary = UiKit.label("", 16, false, UiKit.WARM)
|
||||
_summary.custom_minimum_size = Vector2(0, BAND_H_DIG - 4)
|
||||
_summary.clip_text = true
|
||||
_summary.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
|
||||
head.add_child(_summary)
|
||||
_hint = UiKit.label("结算明细 ▸ 点击展开回看", 14, false)
|
||||
_hint.add_theme_color_override("font_color", UiKit.WARM) # 辅助提示(≥14 辅助档)随上暖白
|
||||
_hint = UiKit.label("结算明细 ▸ 点击展开回看", 14, false, UiKit.WARM) # 辅助提示(≥14 辅助档)随上暖白
|
||||
_hint.size_flags_horizontal = Control.SIZE_SHRINK_END
|
||||
head.add_child(_hint)
|
||||
_log = RichTextLabel.new()
|
||||
@@ -162,7 +160,7 @@ func _gold_frame(text: String) -> String:
|
||||
func _format_row(row: Dictionary, agg_count := -1) -> String:
|
||||
var src := _source_label(String(row.get("source_class", "")))
|
||||
var round_no: int = int(row.get("round_index", 0))
|
||||
var prefix := " [color=#9a8a72]R%d%s[/color] " % [round_no, ("·" + src) if src != "" else ""]
|
||||
var prefix := " [color=#%s]R%d%s[/color] " % [UiKit.HEX_LOG_ROUND, round_no, ("·" + src) if src != "" else ""]
|
||||
var hl := String(row.get("highlight", ""))
|
||||
var v: int = int(row.get("value", 0))
|
||||
var name_: String = String(row.get("display_name", ""))
|
||||
@@ -174,12 +172,12 @@ func _format_row(row: Dictionary, agg_count := -1) -> String:
|
||||
# GP 型效果行(GP+商店房实施批 2026-09-21):「金币袋 +3」兑付反馈——value = 本行 ±power,
|
||||
# escrow = 战斗内缓冲现值(入钱包在战斗末一次上抛——呈现语义与增益池分账)
|
||||
if String(row.get("effect_id", "")) in ["gp_gain", "gp_loss"]:
|
||||
var gp_col := "#e0b860" if v > 0 else "#c47c7c"
|
||||
var gp_col := UiKit.HEX_LOG_GAIN if v > 0 else UiKit.HEX_LOG_LOSS
|
||||
var gp_body := "%s %+d(战斗暂存 %+d)%s" % [name_, v, int(row.get("escrow", 0)), suffix]
|
||||
return prefix + (_gold_frame(gp_body) if hl != "" else "[color=%s]%s[/color]" % [gp_col, gp_body])
|
||||
# 效果行 value = 单次贡献值,pool_value = 池合成值——禁相加呈现(战斗结算 呈现细则)
|
||||
var pool: int = int(row.get("pool_value", 0))
|
||||
var col := "#7cc47c" if v > 0 else "#c47c7c"
|
||||
var col := UiKit.HEX_LOG_HEAL if v > 0 else UiKit.HEX_LOG_LOSS
|
||||
var body := "%s 单次%+d(池 %+d)%s" % [name_, v, pool, suffix]
|
||||
return prefix + (_gold_frame(body) if hl != "" else "[color=%s]%s[/color]" % [col, body])
|
||||
"damage":
|
||||
@@ -197,29 +195,29 @@ func _format_row(row: Dictionary, agg_count := -1) -> String:
|
||||
var kill := " ⚔击杀!" if row.get("killed", false) else ""
|
||||
# 二轮修改批 C(2026-09-29 用户目检——「每次结算标出的伤害数字不明显」):
|
||||
# 伤害值放大加色独立于行文(朱红大一号——数字即信息主角,非同字号色温微差)
|
||||
var body := "%s [color=#d9402a][size=17]-%d[/size][/color]%s%s%s%s" % [name_, v, roll_txt, tail, kill, suffix]
|
||||
var body_col := "#e07050" if row.get("killed", false) else ("#9a8a72" if v == 0 else "#e0a050")
|
||||
var body := "%s [color=#%s][size=17]-%d[/size][/color]%s%s%s%s" % [name_, UiKit.HEX_LOG_DMG_NUM, v, roll_txt, tail, kill, suffix]
|
||||
var body_col := UiKit.HEX_LOG_DMG_KILL if row.get("killed", false) else (UiKit.HEX_LOG_ROUND if v == 0 else UiKit.HEX_LOG_DMG_BODY)
|
||||
if bool(row.get("crit", false)):
|
||||
return prefix + _gold_frame(body) # nat 最大面暴击 = 金框高亮行
|
||||
return prefix + "[color=%s]%s[/color]" % [body_col, body]
|
||||
"heal":
|
||||
return prefix + "[color=#7cc47c]%s +%d%s%s[/color]" % [name_, v, tail, suffix]
|
||||
return prefix + "[color=#%s]%s +%d%s%s[/color]" % [UiKit.HEX_LOG_HEAL, name_, v, tail, suffix]
|
||||
"reward_ineffective":
|
||||
# 未生效类行:⚠ icon + 划线形状冗余(非色相独载)+ 聚合计数
|
||||
var n := (" ×%d" % agg_count) if agg_count > 1 else ""
|
||||
return prefix + "[s][color=#b08060]⚠ %s%s[/color][/s]%s" % [name_, n, suffix]
|
||||
return prefix + "[s][color=#%s]⚠ %s%s[/color][/s]%s" % [UiKit.HEX_LOG_VOIDED, name_, n, suffix]
|
||||
"flag_miss":
|
||||
var body := "✗ %s%s" % [name_, "(本板完美排雷已破——归因此旗)" if hl == "perfect_broken" else ""]
|
||||
return prefix + (_gold_frame(body) if hl == "perfect_broken" else "[color=#9a8a72]%s[/color]" % body)
|
||||
return prefix + (_gold_frame(body) if hl == "perfect_broken" else "[color=#%s]%s[/color]" % [UiKit.HEX_LOG_ROUND, body])
|
||||
"cast":
|
||||
# 施放行(敌人技能池批——蓄力行 charge 改型):增益技 0 伤害施放,具名技能
|
||||
return prefix + "[color=#b09a72]✦ %s%s[/color]" % [name_, suffix]
|
||||
return prefix + "[color=#%s]✦ %s%s[/color]" % [UiKit.HEX_LOG_CAST, name_, suffix]
|
||||
"decay":
|
||||
return prefix + "[color=#8a9ab0]状态衰减 ×%d[/color]" % v
|
||||
return prefix + "[color=#%s]状态衰减 ×%d[/color]" % [UiKit.HEX_LOG_DECAY, v]
|
||||
"verdict":
|
||||
if int(row.value) == 1:
|
||||
return "[color=#80d080][b]◆ %s[/b][/color]" % name_
|
||||
return "[color=#e0b860][b]◆ %s[/b][/color]" % name_
|
||||
return "[color=#%s][b]◆ %s[/b][/color]" % [UiKit.HEX_LOG_WIN, name_]
|
||||
return "[color=#%s][b]◆ %s[/b][/color]" % [UiKit.HEX_LOG_GAIN, name_]
|
||||
"highlight":
|
||||
return prefix + _gold_frame("★ %s" % name_)
|
||||
return prefix + name_ + suffix
|
||||
|
||||
@@ -25,6 +25,7 @@ const _STANDEE_BODY := preload("res://presentation/views/standee_body.gd")
|
||||
const _CONTENT_MARGINS := Rect2(6, 4, 6, 4) # 原 PanelContainer stylebox 内容边距(子面几何零漂移)
|
||||
const _STANDEE_W := 150.0 # 站桩盒宽(旧 StandeeView custom_minimum_size)
|
||||
const _STANDEE_GAP := 8.0 # 敌站桩间距(旧 enemy_box HBox separation)
|
||||
const STAGE_CENTER_HINT := "兑现演出区\n(结算期:光带 → 弹道 → 受击)" # 演出区占位文案(set_settle_focus 恢复态同源——字面量双写退役)
|
||||
|
||||
var hero_standee: Node2D # StandeeBody——主角站桩本体(世界内;slot_row = 壳层伴随件引用)
|
||||
var round_label: Label
|
||||
@@ -42,17 +43,18 @@ var world: Node2D # StageWorld(preload 脚本实例——Node2D 世
|
||||
func _init(db_ref) -> void:
|
||||
custom_minimum_size = Vector2(0, 252)
|
||||
# 面板底(圣经 v3.5 批 B4 2026-09-30——§6.1 舞台正面目标落码:B 区=地窟看台,世界底层暗背景
|
||||
# Color8(62,52,42)=方向稿 render_battle_screen 取值——替换原浅石板皮〔实测 L0.027 旧深底与
|
||||
# 上半米黄割裂的 opposite 端——v3.5 定暖暗中档〕;描边=PANEL_BORDER 同方向稿)
|
||||
# =方向稿 render_battle_screen 取值(值单点收 UiKit.STAGE_BG——T4 裸色收口)——替换原浅石板皮
|
||||
# 〔实测 L0.027 旧深底与上半米黄割裂的 opposite 端——v3.5 定暖暗中档〕;描边=PANEL_BORDER 同方向稿)
|
||||
var bg := Panel.new()
|
||||
var sb := UiKit.panel_flat(Color8(62, 52, 42), UiKit.PANEL_BORDER, 0, 1)
|
||||
var sb := UiKit.panel_flat(UiKit.STAGE_BG, UiKit.PANEL_BORDER, 0, 1)
|
||||
bg.add_theme_stylebox_override("panel", sb)
|
||||
bg.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
bg.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
add_child(bg)
|
||||
|
||||
# 顶光柱氛围层(§6.1 光源氛围——方向稿四柱:x 基准 110/900/1055/1210@1280,暖光 (255,236,200)
|
||||
# 自顶向下 60 段渐宽窄渐隐〔顶 α26→0〕;绘制在暗底之上/世界站桩之下——层序=bg < 光柱 < 世界)
|
||||
# 顶光柱氛围层(§6.1 光源氛围——方向稿四柱:x 基准 110/900/1055/1210@1280,暖光(值单点收
|
||||
# UiKit.BEAM_LIGHT——T4 裸色收口)自顶向下 60 段渐宽窄渐隐〔顶 α26→0〕;绘制在暗底之上/
|
||||
# 世界站桩之下——层序=bg < 光柱 < 世界)
|
||||
var beams := Control.new()
|
||||
beams.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
beams.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
@@ -86,9 +88,8 @@ func _init(db_ref) -> void:
|
||||
vb.offset_bottom = -_CONTENT_MARGINS.size.y
|
||||
add_child(vb)
|
||||
|
||||
round_label = UiKit.label("第 — 轮 · —", 15, true)
|
||||
round_label = UiKit.label("第 — 轮 · —", 15, true, UiKit.WARM) # 暗底双色墨制(v3.5 批 B4——原深墨对暗底不可读)
|
||||
round_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
round_label.add_theme_color_override("font_color", UiKit.WARM) # 暗底双色墨制(v3.5 批 B4——原深墨对暗底不可读)
|
||||
vb.add_child(round_label)
|
||||
|
||||
_row = HBoxContainer.new()
|
||||
@@ -103,8 +104,7 @@ func _init(db_ref) -> void:
|
||||
var center_col := VBoxContainer.new()
|
||||
center_col.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
center.add_child(center_col)
|
||||
stage_center = UiKit.label("兑现演出区\n(结算期:光带 → 弹道 → 受击)", 13, false)
|
||||
stage_center.add_theme_color_override("font_color", UiKit.WARM_SOFT) # 暗底双色墨制(原 STONE_FAINT 对暗底不可读)
|
||||
stage_center = UiKit.label(STAGE_CENTER_HINT, 13, false, UiKit.WARM_SOFT) # 暗底双色墨制(原 STONE_FAINT 对暗底不可读)
|
||||
stage_center.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
center_col.add_child(stage_center)
|
||||
_row.add_child(center)
|
||||
@@ -146,7 +146,7 @@ func _draw_light_beams(c: Control) -> void:
|
||||
var a := int(26.0 * (1.0 - float(i) / 60.0))
|
||||
var half := 46.0 - float(i) / 3.0
|
||||
c.draw_rect(Rect2(x0 - half, 0.0, half * 2.0, 40.0 + float(i) * 3.0),
|
||||
Color8(255, 236, 200, a), true)
|
||||
Color(UiKit.BEAM_LIGHT, float(a) / 255.0), true)
|
||||
|
||||
|
||||
func _make_slot_companion(parent: Control) -> StatusSlotRow:
|
||||
@@ -314,31 +314,27 @@ func on_step_row_fx(row: Dictionary) -> void:
|
||||
# 主角受击演出(迭代 6 T5 拆早退——旧「敌→主角零反馈」):弹道到达拍对齐,
|
||||
# 受击态+闪白+打击火花+击杀塌陷与敌方路径同密度(演出对等——计划书 §1.4)
|
||||
hero_standee.set_hero_state("hit") # 受击态(短驻自回 idle)
|
||||
var hero_arrived := func():
|
||||
hero_standee.play_hit_impact()
|
||||
hero_standee.flash_hit()
|
||||
if bool(row.get("killed", false)):
|
||||
hero_standee.mark_dead()
|
||||
if get_tree() != null:
|
||||
get_tree().create_timer(UiKit.motion(0.33)).timeout.connect(hero_arrived)
|
||||
else:
|
||||
hero_arrived.call()
|
||||
_schedule_arrival_fx(hero_standee, bool(row.get("killed", false)))
|
||||
return
|
||||
hero_standee.set_hero_state("attack") # 我方攻击行——attack 态(短驻自回)
|
||||
var card: Node2D = _card_by_name(target)
|
||||
if card == null:
|
||||
return
|
||||
# 弹道到达拍对齐(迭代 6 T4 终稿):闪白/打击火花/击杀塌陷延迟 ≈弹道飞行时长
|
||||
# (play_projectile 0.16+0.19)——呈现链序=弹道→闪白+火花→血条(投影刷新)→灰化塌陷。
|
||||
# 行突发同拍多定时器互不干扰(flash 重启语义/死亡幂等守卫);卡片提前释放=守卫跳过;
|
||||
# 树外(防御)=即时执行不调度。
|
||||
_schedule_arrival_fx(card, bool(row.get("killed", false)))
|
||||
|
||||
|
||||
# 弹道到达拍调度单点(主角受击/敌方受击两份「0.33s 定时器+到达 lambda」同构块合并——T4 杂并批):
|
||||
# 闪白/打击火花/击杀塌陷延迟 ≈弹道飞行时长(play_projectile 0.16+0.19)——呈现链序=弹道→闪白+火花
|
||||
# →血条(投影刷新)→灰化塌陷。行突发同拍多定时器互不干扰(flash 重启语义/死亡幂等守卫);
|
||||
# 本体提前释放=is_instance_valid 守卫跳过;树外(防御)=即时执行不调度。
|
||||
func _schedule_arrival_fx(body: Node2D, killed: bool) -> void:
|
||||
var arrived := func():
|
||||
if not is_instance_valid(card):
|
||||
if not is_instance_valid(body):
|
||||
return
|
||||
card.play_hit_impact()
|
||||
card.flash_hit()
|
||||
if bool(row.get("killed", false)):
|
||||
card.mark_dead()
|
||||
body.play_hit_impact()
|
||||
body.flash_hit()
|
||||
if killed:
|
||||
body.mark_dead()
|
||||
if get_tree() != null:
|
||||
get_tree().create_timer(UiKit.motion(0.33)).timeout.connect(arrived)
|
||||
else:
|
||||
@@ -381,4 +377,4 @@ func settle_hero_idle() -> void:
|
||||
# 结算期 B 区第一注视点切换(能量 7/10 清算调性):结算中占位文案退位——兑现演出由
|
||||
# SettlementFxView 弹道/光带本体接管(演出链批);挖掘期恢复教学占位文案
|
||||
func set_settle_focus(on: bool) -> void:
|
||||
stage_center.text = "" if on else "兑现演出区\n(结算期:光带 → 弹道 → 受击)"
|
||||
stage_center.text = "" if on else STAGE_CENTER_HINT
|
||||
@@ -17,8 +17,7 @@ var _banner: Label
|
||||
func _init() -> void:
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
_banner = UiKit.label("", 26, true)
|
||||
_banner.add_theme_color_override("font_color", COL_GOLD)
|
||||
_banner = UiKit.label("", 26, true, COL_GOLD)
|
||||
_banner.set_anchors_preset(Control.PRESET_CENTER_TOP)
|
||||
_banner.grow_horizontal = Control.GROW_DIRECTION_BOTH
|
||||
_banner.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
|
||||
@@ -858,24 +858,11 @@ func _reset_breath() -> void:
|
||||
func _load_board_tiles(board_type: String = "dungeon") -> void:
|
||||
if board_type == "":
|
||||
board_type = "dungeon"
|
||||
var t := {
|
||||
"wall_center": UiKit.load_tex(TILE_WALL_FMT % ["wall_center", board_type]),
|
||||
"wall_center_crack": UiKit.load_tex(TILE_WALL_FMT % ["wall_center_crack", board_type]),
|
||||
"wall_center_speckle": UiKit.load_tex(TILE_WALL_FMT % ["wall_center_speckle", board_type]),
|
||||
"wall_n": UiKit.load_tex(TILE_WALL_FMT % ["wall_n", board_type]),
|
||||
"wall_s": UiKit.load_tex(TILE_WALL_FMT % ["wall_s", board_type]),
|
||||
"wall_w": UiKit.load_tex(TILE_WALL_FMT % ["wall_w", board_type]),
|
||||
"wall_nw": UiKit.load_tex(TILE_WALL_FMT % ["wall_nw", board_type]),
|
||||
"wall_sw": UiKit.load_tex(TILE_WALL_FMT % ["wall_sw", board_type]),
|
||||
"wall_hrun": UiKit.load_tex(TILE_WALL_FMT % ["wall_hrun", board_type]),
|
||||
"wall_vrun": UiKit.load_tex(TILE_WALL_FMT % ["wall_vrun", board_type]),
|
||||
"wall_end_n": UiKit.load_tex(TILE_WALL_FMT % ["wall_end_n", board_type]),
|
||||
"wall_end_s": UiKit.load_tex(TILE_WALL_FMT % ["wall_end_s", board_type]),
|
||||
"wall_end_w": UiKit.load_tex(TILE_WALL_FMT % ["wall_end_w", board_type]),
|
||||
"wall_lone": UiKit.load_tex(TILE_WALL_FMT % ["wall_lone", board_type]),
|
||||
"wall_in_nw": UiKit.load_tex(TILE_WALL_FMT % ["wall_in_nw", board_type]),
|
||||
"wall_in_sw": UiKit.load_tex(TILE_WALL_FMT % ["wall_in_sw", board_type]),
|
||||
}
|
||||
# 16 墙瓦片装载循环节(词表 TILE_WALL_NAMES 单点——T4 杂并:手写 16 条字典项重复退役;
|
||||
# 词表本身被 terrain_tile_sets_test 直读,保留)
|
||||
var t := {}
|
||||
for wall_name in TILE_WALL_NAMES:
|
||||
t[wall_name] = UiKit.load_tex(TILE_WALL_FMT % [wall_name, board_type])
|
||||
var floors: Array[Texture2D] = []
|
||||
for i in range(1, TILE_FLOOR_VARIANTS + 1):
|
||||
floors.append(UiKit.load_tex(TILE_FLOOR_FMT % [board_type, i]))
|
||||
|
||||
@@ -76,7 +76,7 @@ var cols := 0: # 列数(正面悬崖竖缝数 = cols−1)
|
||||
set(v):
|
||||
cols = v
|
||||
queue_redraw()
|
||||
var mat := Color8(201, 175, 131) # 材质锚色(掩尘 #C9AF83——侧面由此派生明暗;BoardView 传入)
|
||||
var mat: Color = UiKit.BRICK # 材质锚色(掩尘 #C9AF83 与 UiKit.BRICK 同值——T4 裸色收口改引单点;侧面由此派生明暗,BoardView 传入可覆写)
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
|
||||
@@ -22,18 +22,8 @@ var _card_meta: Array = [] # open_pick 缓存 [{id, text}]—
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
var dim := ColorRect.new()
|
||||
dim.color = Color(0, 0, 0, 0.6)
|
||||
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(dim)
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.add_child(center)
|
||||
var box := VBoxContainer.new()
|
||||
box.add_theme_constant_override("separation", 12)
|
||||
center.add_child(box)
|
||||
_label = UiKit.label("", 20, true)
|
||||
_label.add_theme_color_override("font_color", UiKit.WARM)
|
||||
var box: VBoxContainer = UiKit.modal_shell(self, Color(0, 0, 0, 0.6)).box
|
||||
_label = UiKit.label("", 20, true, UiKit.WARM)
|
||||
_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
box.add_child(_label)
|
||||
_choice_box = HBoxContainer.new()
|
||||
@@ -49,7 +39,7 @@ func _init() -> void:
|
||||
_replace_box.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
box.add_child(_replace_box)
|
||||
_continue_btn = UiKit.button("继续")
|
||||
_continue_btn.pressed.connect(func(): continue_pressed.emit())
|
||||
_continue_btn.pressed.connect(_emit_continue_pressed)
|
||||
_continue_btn.visible = false
|
||||
box.add_child(_continue_btn)
|
||||
visible = false
|
||||
@@ -68,7 +58,7 @@ func open_pick(header: String, cards: Array) -> void:
|
||||
var cid := String(ch.get("id", ""))
|
||||
var btn := UiKit.button(String(ch.get("text", "")))
|
||||
btn.custom_minimum_size = Vector2(170, 88)
|
||||
btn.pressed.connect(func(): _select_card(cid))
|
||||
btn.pressed.connect(_select_card.bind(cid)) # 具名方法 bind(仓内惯例——内联 lambda 退役)
|
||||
_choice_box.add_child(btn)
|
||||
_choice_box.visible = true
|
||||
_confirm_btn.visible = false
|
||||
@@ -129,10 +119,10 @@ func open_replace(items: Array, incoming_name: String, holding: int, slots: int)
|
||||
for it in items:
|
||||
var tag: int = int(it.get("index", it.get("handle", -1))) # 通关渠道=携带序号 / 节点渠道=库存句柄(核心分发面裁决)
|
||||
var btn := UiKit.button("丢弃「%s」换新" % String(it.get("display_name", it.get("item_id", ""))))
|
||||
btn.pressed.connect(func(): replace_chosen.emit(tag))
|
||||
btn.pressed.connect(_emit_replace_chosen.bind(tag))
|
||||
_replace_box.add_child(btn)
|
||||
var decline := UiKit.button("放弃新件(不获取)")
|
||||
decline.pressed.connect(func(): replace_chosen.emit(-1))
|
||||
decline.pressed.connect(_emit_replace_chosen.bind(-1))
|
||||
_replace_box.add_child(decline)
|
||||
_choice_box.visible = false
|
||||
_confirm_btn.visible = false
|
||||
@@ -148,3 +138,11 @@ func close_pick() -> void:
|
||||
_continue_btn.visible = false
|
||||
_confirm_btn.visible = false
|
||||
visible = false
|
||||
|
||||
|
||||
func _emit_continue_pressed() -> void:
|
||||
continue_pressed.emit()
|
||||
|
||||
|
||||
func _emit_replace_chosen(tag: int) -> void:
|
||||
replace_chosen.emit(tag)
|
||||
@@ -15,10 +15,10 @@ signal buy_requested(attr: String)
|
||||
signal closed
|
||||
|
||||
const ATTR_LABELS := {"atk": "攻击", "max_hp": "生命上限", "armor_class": "护甲"} # 档位文案轴(数据契约 attr 词表,与 ShopOverlay 同款)
|
||||
# 方向稿取色(4-camp.png——柜台头带深棕/行板暖米;双色墨=亮板配深墨)
|
||||
const HEADER_BAND_COL := Color8(122, 82, 50)
|
||||
const ROW_PLATE_COL := Color8(240, 230, 206)
|
||||
const BADGE_PANEL_COL := Color8(40, 32, 24)
|
||||
# 方向稿取色(4-camp.png——柜台头带深棕/行板暖米;双色墨=亮板配深墨)——值单点收 UiKit(T4 裸色收口批)
|
||||
const HEADER_BAND_COL := UiKit.CAMP_HEADER_BAND
|
||||
const ROW_PLATE_COL := UiKit.CAMP_ROW_PLATE
|
||||
const BADGE_PANEL_COL := UiKit.CAMP_BADGE_PANEL
|
||||
|
||||
var _balance_label: Label
|
||||
var _forge_holder: VBoxContainer
|
||||
@@ -29,10 +29,7 @@ var _recent_list: Label # 最近冒险(逐行拼接 label——只读
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
var dim := ColorRect.new()
|
||||
dim.color = Color(0, 0, 0, 0.45) # 方向稿=石纹底透出(浅 dim——石纹全屏底担当氛围)
|
||||
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(dim)
|
||||
var dim := UiKit.modal_dim(self, Color(0, 0, 0, 0.45)) # 方向稿=石纹底透出(浅 dim——石纹全屏底担当氛围)
|
||||
# 石纹底噪(样张 v2 冻结件——start overlay 同款;缺位不挂即回退平 dim)
|
||||
var bd_tex := UiKit.load_tex(UiKit.TEX_BACKDROP_STONE)
|
||||
if bd_tex != null:
|
||||
@@ -65,11 +62,9 @@ func _init() -> void:
|
||||
top.add_child(plaque)
|
||||
var plaque_col := VBoxContainer.new()
|
||||
plaque.add_child(plaque_col)
|
||||
var title := UiKit.label("营地 · 永久强化", 22, true)
|
||||
title.add_theme_color_override("font_color", UiKit.INK_TITLE)
|
||||
var title := UiKit.label("营地 · 永久强化", 22, true, UiKit.INK_TITLE)
|
||||
plaque_col.add_child(title)
|
||||
var sub := UiKit.label("跨局成长账本——钥石换永久属性", 13, false)
|
||||
sub.add_theme_color_override("font_color", UiKit.STONE)
|
||||
var sub := UiKit.label("跨局成长账本——钥石换永久属性", 13, false, UiKit.STONE)
|
||||
plaque_col.add_child(sub)
|
||||
var spacer := Control.new()
|
||||
spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
@@ -84,8 +79,7 @@ func _init() -> void:
|
||||
var keystone_icon := UiKit.icon_rect(UiKit.TEX_ICON_KEYSTONE, 18) # 缺位 null → 纯文本回退
|
||||
if keystone_icon != null:
|
||||
bal_row.add_child(keystone_icon)
|
||||
_balance_label = UiKit.label("钥石 0", 18, true)
|
||||
_balance_label.add_theme_color_override("font_color", UiKit.GOLD)
|
||||
_balance_label = UiKit.label("钥石 0", 18, true, UiKit.GOLD)
|
||||
bal_row.add_child(_balance_label)
|
||||
|
||||
# ── 三柜台列(方向稿同构:头带深棕+米色板身)──
|
||||
@@ -102,8 +96,7 @@ func _init() -> void:
|
||||
mid.add_child(_counter_panel("道具工坊", UiKit.TEX_ICON_WORKSHOP, _workshop_holder, 356))
|
||||
var atlas_holder := VBoxContainer.new()
|
||||
mid.add_child(_counter_panel("奖励格图鉴", UiKit.TEX_ICON_ATLAS, atlas_holder, 356))
|
||||
var lock_l := UiKit.label(" —— 柜台结构位预留:内容排 Alpha(地图战斗资源差异化批)", 13, false)
|
||||
lock_l.add_theme_color_override("font_color", UiKit.STONE)
|
||||
var lock_l := UiKit.label(" —— 柜台结构位预留:内容排 Alpha(地图战斗资源差异化批)", 13, false, UiKit.STONE)
|
||||
lock_l.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
lock_l.custom_minimum_size = Vector2(300, 0)
|
||||
atlas_holder.add_child(lock_l)
|
||||
@@ -117,12 +110,10 @@ func _init() -> void:
|
||||
var spacer2 := Control.new()
|
||||
spacer2.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
bottom.add_child(spacer2)
|
||||
var caption := UiKit.label("每购得一件永久强化,对应柜台亮起一格暖光 · 价格为钥石", 13, false)
|
||||
caption.add_theme_color_override("font_color", UiKit.WARM_SOFT)
|
||||
var caption := UiKit.label("每购得一件永久强化,对应柜台亮起一格暖光 · 价格为钥石", 13, false, UiKit.WARM_SOFT)
|
||||
bottom.add_child(caption)
|
||||
col.add_child(bottom)
|
||||
_recent_list = UiKit.label("", 13, false)
|
||||
_recent_list.add_theme_color_override("font_color", UiKit.WARM_SOFT)
|
||||
_recent_list = UiKit.label("", 13, false, UiKit.WARM_SOFT)
|
||||
_recent_list.clip_text = true
|
||||
_recent_list.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
|
||||
col.add_child(_recent_list)
|
||||
@@ -148,8 +139,7 @@ func _counter_panel(title_text: String, icon_path: String, holder: VBoxContainer
|
||||
var ic := UiKit.icon_rect(icon_path, 16) # 缺位 null → 纯文本回退
|
||||
if ic != null:
|
||||
head.add_child(ic)
|
||||
var l := UiKit.label(title_text, 16, true)
|
||||
l.add_theme_color_override("font_color", UiKit.WARM)
|
||||
var l := UiKit.label(title_text, 16, true, UiKit.WARM)
|
||||
head.add_child(l)
|
||||
vbox.add_child(holder)
|
||||
return panel
|
||||
@@ -223,16 +213,13 @@ func _build_forge_row(holder: VBoxContainer, row: Dictionary) -> Dictionary:
|
||||
line.add_theme_constant_override("separation", 12)
|
||||
card.add_child(line)
|
||||
var attr := String(row.get("attr", ""))
|
||||
var name_l := UiKit.label("%s %+d/级" % [String(row.get("display_name", "")), int(row.get("flat", 0))], 14, true)
|
||||
name_l.add_theme_color_override("font_color", UiKit.INK)
|
||||
var name_l := UiKit.label("%s %+d/级" % [String(row.get("display_name", "")), int(row.get("flat", 0))], 14, true, UiKit.INK)
|
||||
name_l.custom_minimum_size = Vector2(132, 0)
|
||||
line.add_child(name_l)
|
||||
var level_l := UiKit.label("", 14, false)
|
||||
level_l.add_theme_color_override("font_color", UiKit.INK)
|
||||
var level_l := UiKit.label("", 14, false, UiKit.INK)
|
||||
level_l.custom_minimum_size = Vector2(44, 0)
|
||||
line.add_child(level_l)
|
||||
var price_l := UiKit.label("", 14, false)
|
||||
price_l.add_theme_color_override("font_color", UiKit.STONE)
|
||||
var price_l := UiKit.label("", 14, false, UiKit.STONE)
|
||||
price_l.custom_minimum_size = Vector2(64, 0)
|
||||
line.add_child(price_l)
|
||||
var btn := UiKit.button("锻造 +1 级")
|
||||
@@ -252,16 +239,14 @@ func _rebuild_workshop(data: Dictionary) -> void:
|
||||
var line := HBoxContainer.new()
|
||||
line.add_theme_constant_override("separation", 12)
|
||||
card.add_child(line)
|
||||
var name_l := UiKit.label(String(row.get("display_name", "")), 14, true)
|
||||
name_l.add_theme_color_override("font_color", UiKit.INK)
|
||||
var name_l := UiKit.label(String(row.get("display_name", "")), 14, true, UiKit.INK)
|
||||
name_l.custom_minimum_size = Vector2(132, 0)
|
||||
line.add_child(name_l)
|
||||
var progress_l := UiKit.label("", 13, false)
|
||||
progress_l.add_theme_color_override("font_color", UiKit.STONE)
|
||||
var progress_l := UiKit.label("", 13, false, UiKit.STONE)
|
||||
progress_l.custom_minimum_size = Vector2(110, 0)
|
||||
line.add_child(progress_l)
|
||||
var status_l := UiKit.label("", 13, true)
|
||||
status_l.add_theme_color_override("font_color", UiKit.STONE)
|
||||
# 状态色随卡⑭ 亮板双色墨制(深墨族替代暖白族)——色随刷新态条件赋值,非机械两行式(T4 收口保留)
|
||||
var status_l := UiKit.label("", 13, true, UiKit.STONE)
|
||||
line.add_child(status_l)
|
||||
_workshop_holder.add_child(card)
|
||||
_workshop_rows.append({"item_id": String(row.get("item_id", "")), "progress_l": progress_l, "status_l": status_l})
|
||||
|
||||
@@ -15,22 +15,9 @@ var _cancel_btn: Button
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
var dim := ColorRect.new()
|
||||
dim.color = Color(UiKit.DIM, 0.55)
|
||||
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(dim)
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.add_child(center)
|
||||
var panel := PanelContainer.new()
|
||||
panel.add_theme_stylebox_override("panel", UiKit.panel_skinned(Vector4(14, 12, 14, 12)))
|
||||
center.add_child(panel)
|
||||
var box := VBoxContainer.new()
|
||||
box.custom_minimum_size = Vector2(460, 0)
|
||||
box.add_theme_constant_override("separation", 12)
|
||||
panel.add_child(box)
|
||||
_text = UiKit.label("", 16, false)
|
||||
_text.add_theme_color_override("font_color", UiKit.INK_TITLE)
|
||||
var box: VBoxContainer = UiKit.modal_shell(self, Color(UiKit.DIM, 0.55), Vector2(460, 0), 12,
|
||||
true, UiKit.panel_skinned(Vector4(14, 12, 14, 12))).box
|
||||
_text = UiKit.label("", 16, false, UiKit.INK_TITLE)
|
||||
_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
_text.custom_minimum_size = Vector2(430, 0)
|
||||
box.add_child(_text)
|
||||
|
||||
@@ -94,8 +94,7 @@ func set_level_bonuses(lines: Array) -> void:
|
||||
_bonus_list.remove_child(c)
|
||||
c.queue_free()
|
||||
for line in lines:
|
||||
var l := UiKit.label(String(line), 16, false) # 字号下限(v3.5 批 B3——正文 ≥16)
|
||||
l.add_theme_color_override("font_color", COL_INK)
|
||||
var l := UiKit.label(String(line), 16, false, COL_INK) # 字号下限(v3.5 批 B3——正文 ≥16)
|
||||
_bonus_list.add_child(l)
|
||||
_bonus_section.visible = not lines.is_empty()
|
||||
|
||||
@@ -115,10 +114,9 @@ func armor_text() -> String:
|
||||
|
||||
|
||||
func _data_line() -> Label:
|
||||
var l := UiKit.label("", 16, false)
|
||||
# 对比度修复(v3.5 批 B3 2026-09-30——非粗体 label 默认浅灰对米色数据框仅 1.31:1,
|
||||
# 实测=ui-redesign 对比报告 §一):显式主墨(对 PANEL_DATA ≈10:1)
|
||||
l.add_theme_color_override("font_color", UiKit.INK)
|
||||
var l := UiKit.label("", 16, false, UiKit.INK)
|
||||
l.clip_text = true
|
||||
l.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
|
||||
return l
|
||||
@@ -150,6 +148,7 @@ func set_aux_inventory(items: Array, selected_handle: int) -> void:
|
||||
glyph.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
glyph.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
glyph.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
# 墨色随 used/usable 条件赋值——非机械两行式,T4 收口保留原分支
|
||||
if used:
|
||||
glyph.add_theme_color_override("font_color", UiKit.STONE_FAINT)
|
||||
elif not usable:
|
||||
|
||||
@@ -27,23 +27,12 @@ var _rap_cost := -1 # <0 = 不渲染 RAP 行(打磨包 2026-09-29——构
|
||||
|
||||
func _init(rap_cost: int = -1) -> void:
|
||||
_rap_cost = rap_cost
|
||||
var dim := ColorRect.new()
|
||||
dim.color = Color(UiKit.DIM, 0.55)
|
||||
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.gui_input.connect(_on_dim_gui_input)
|
||||
add_child(dim)
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.add_child(center)
|
||||
_panel = PanelContainer.new()
|
||||
_panel.add_theme_stylebox_override("panel", UiKit.panel_skinned(Vector4(12, 10, 12, 10))) # 石板皮(T2;缺位回退 flat)
|
||||
center.add_child(_panel)
|
||||
var box := VBoxContainer.new()
|
||||
box.custom_minimum_size = Vector2(520, 0)
|
||||
box.add_theme_constant_override("separation", 6)
|
||||
_panel.add_child(box)
|
||||
var title := UiKit.label("图例 · 格态", 20, true)
|
||||
title.add_theme_color_override("font_color", UiKit.INK_TITLE) # 亮底墨字(§7.2 数据素面)
|
||||
var shell := UiKit.modal_shell(self, Color(UiKit.DIM, 0.55), Vector2(520, 0), 6, true,
|
||||
UiKit.panel_skinned(Vector4(12, 10, 12, 10))) # 石板皮(T2;缺位回退 flat)
|
||||
_panel = shell.panel
|
||||
(shell.dim as ColorRect).gui_input.connect(_on_dim_gui_input)
|
||||
var box: VBoxContainer = shell.box
|
||||
var title := UiKit.label("图例 · 格态", 20, true, UiKit.INK_TITLE) # 亮底墨字(§7.2 数据素面)
|
||||
box.add_child(title)
|
||||
box.add_child(HSeparator.new())
|
||||
for e in ENTRIES:
|
||||
@@ -53,8 +42,7 @@ func _init(rap_cost: int = -1) -> void:
|
||||
chip.custom_minimum_size = Vector2(18, 18)
|
||||
chip.color = Color(e[0])
|
||||
row.add_child(chip)
|
||||
var lab := UiKit.label("%s —— %s" % [e[1], e[2]], 13, false)
|
||||
lab.add_theme_color_override("font_color", UiKit.INK_LABEL) # 亮底墨字(§7.2 数据素面)
|
||||
var lab := UiKit.label("%s —— %s" % [e[1], e[2]], 13, false, UiKit.INK_LABEL) # 亮底墨字(§7.2 数据素面)
|
||||
lab.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
lab.custom_minimum_size = Vector2(440, 0)
|
||||
row.add_child(lab)
|
||||
@@ -66,10 +54,9 @@ func _init(rap_cost: int = -1) -> void:
|
||||
rap_row.add_theme_constant_override("separation", 8)
|
||||
var rap_chip := ColorRect.new()
|
||||
rap_chip.custom_minimum_size = Vector2(18, 18)
|
||||
rap_chip.color = Color("#F0A828")
|
||||
rap_chip.color = UiKit.GOLD # 同 #F0A828——金徽章同源单点(T4 裸色收口)
|
||||
rap_row.add_child(rap_chip)
|
||||
var rap_lab := UiKit.label("RAP 储备行动点 —— 停手时剩余 AP 转存;弃图刷新消耗 RAP−%d(旧板旗作废,AP 保留继续挖)" % _rap_cost, 13, false)
|
||||
rap_lab.add_theme_color_override("font_color", UiKit.INK_LABEL)
|
||||
var rap_lab := UiKit.label("RAP 储备行动点 —— 停手时剩余 AP 转存;弃图刷新消耗 RAP−%d(旧板旗作废,AP 保留继续挖)" % _rap_cost, 13, false, UiKit.INK_LABEL)
|
||||
rap_lab.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
rap_lab.custom_minimum_size = Vector2(440, 0)
|
||||
rap_row.add_child(rap_lab)
|
||||
|
||||
@@ -38,9 +38,13 @@ const TITLE_ENTRY := "出发——选择首个节点" # 入口停点
|
||||
const TITLE_SINGLE := "继续前进" # 单链停点
|
||||
const TITLE_FORK := "选择下一节点" # 岔路停点
|
||||
const NODE_HALF := Vector2(26, 18) # 节点方块半宽高(52×36 占位画布参数——样张批终稿)
|
||||
const LAYER_BASE_X := 70 # 首层节点原点 x(画布拟合与布局公式共用——T4 杂并:双写退役)
|
||||
const LAYER_STEP_X := 122 # 层间横向步距(同上)
|
||||
const SLOT_BASE_Y := 52 # 槽位原点 y(同上)
|
||||
const SLOT_STEP_Y := 58 # 同层槽位纵向步距(同上)
|
||||
const HIT_PAD := 6.0 # 图上命中外扩(指宽容差)
|
||||
const CONFIRM_WINDOW_S := 3.0 # 放弃确认态窗口(秒——超时回落)
|
||||
const COL_HP_BAR_BACK := Color8(40, 34, 28) # 迷你血条深底(样张 v1 冻结——对暗面板可辨)
|
||||
const COL_HP_BAR_BACK := UiKit.HP_BAR_BACK # 迷你血条深底(样张 v1 冻结——对暗面板可辨;值单点收 UiKit)
|
||||
|
||||
var _runner = null
|
||||
var _title: Label
|
||||
@@ -92,8 +96,7 @@ func _init() -> void:
|
||||
var top := HBoxContainer.new()
|
||||
top.add_theme_constant_override("separation", 12)
|
||||
box.add_child(top)
|
||||
_level_label = UiKit.label("", 16, true)
|
||||
_level_label.add_theme_color_override("font_color", UiKit.WARM)
|
||||
_level_label = UiKit.label("", 16, true, UiKit.WARM)
|
||||
_level_label.custom_minimum_size.x = 420
|
||||
top.add_child(_level_label)
|
||||
var gp_box := PanelContainer.new()
|
||||
@@ -102,11 +105,9 @@ func _init() -> void:
|
||||
var gp_row := HBoxContainer.new()
|
||||
gp_row.add_theme_constant_override("separation", 6)
|
||||
gp_box.add_child(gp_row)
|
||||
_gp_value = UiKit.label("", 16, true)
|
||||
_gp_value.add_theme_color_override("font_color", UiKit.GOLD)
|
||||
_gp_value = UiKit.label("", 16, true, UiKit.GOLD)
|
||||
gp_row.add_child(_gp_value)
|
||||
_title = UiKit.label(TITLE_FORK, 18, true)
|
||||
_title.add_theme_color_override("font_color", UiKit.WARM)
|
||||
_title = UiKit.label(TITLE_FORK, 18, true, UiKit.WARM)
|
||||
_title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
box.add_child(_title)
|
||||
# 节点图画布(图上点击 = 唯一提交通道——布局决策 2;mouse_filter STOP 接悬停/点击)
|
||||
@@ -130,11 +131,9 @@ func _init() -> void:
|
||||
_bonus_row.add_child(bonus_box)
|
||||
var bonus_inner := VBoxContainer.new()
|
||||
bonus_box.add_child(bonus_inner)
|
||||
var bonus_cap := UiKit.label("本关加成", 12, false)
|
||||
bonus_cap.add_theme_color_override("font_color", UiKit.WARM_SOFT)
|
||||
var bonus_cap := UiKit.label("本关加成", 12, false, UiKit.WARM_SOFT)
|
||||
bonus_inner.add_child(bonus_cap)
|
||||
_bonus_value = UiKit.label("", 15, true)
|
||||
_bonus_value.add_theme_color_override("font_color", UiKit.WARM)
|
||||
_bonus_value = UiKit.label("", 15, true, UiKit.WARM)
|
||||
bonus_inner.add_child(_bonus_value)
|
||||
bottom.add_child(_bonus_row)
|
||||
var spacer := Control.new()
|
||||
@@ -148,25 +147,24 @@ func _init() -> void:
|
||||
visible = false
|
||||
|
||||
|
||||
# 状态数据框工厂(直角细线数据框——pattern 5 族;hp_box = 带迷你血条。墨色按样张 v1 冻结:
|
||||
# 暗底标签 WARM_SOFT/读数 WARM——§7.1 数据素面墨来自世界的墨在暗底侧的落法,L3 ≥4.5:1)
|
||||
# 状态数据框工厂(直角细线数据框——pattern 5 族;with_bar = 带迷你血条(生命框),值读数随行挂回
|
||||
# _hp_value/_attr_value(T4 杂并:旧「caption == "生命"」文案做控制流退役——分组判据复用 with_bar)。
|
||||
# 墨色按样张 v1 冻结:暗底标签 WARM_SOFT/读数 WARM——§7.1 数据素面墨来自世界的墨在暗底侧的落法,L3 ≥4.5:1)
|
||||
func _status_box(caption: String, with_bar: bool) -> PanelContainer:
|
||||
var panel := PanelContainer.new()
|
||||
panel.add_theme_stylebox_override("panel", UiKit.panel_flat(UiKit.DARK_UPCOMING, UiKit.PANEL_BORDER, 0, 1))
|
||||
var inner := VBoxContainer.new()
|
||||
panel.add_child(inner)
|
||||
var cap := UiKit.label(caption, 12, false)
|
||||
cap.add_theme_color_override("font_color", UiKit.WARM_SOFT)
|
||||
var cap := UiKit.label(caption, 12, false, UiKit.WARM_SOFT)
|
||||
inner.add_child(cap)
|
||||
if with_bar:
|
||||
_hp_bar = Control.new()
|
||||
_hp_bar.custom_minimum_size = Vector2(120, 6)
|
||||
_hp_bar.draw.connect(_draw_hp_bar.bind(_hp_bar))
|
||||
inner.add_child(_hp_bar)
|
||||
var value := UiKit.label("", 15, true)
|
||||
value.add_theme_color_override("font_color", UiKit.WARM)
|
||||
var value := UiKit.label("", 15, true, UiKit.WARM)
|
||||
inner.add_child(value)
|
||||
if caption == "生命":
|
||||
if with_bar:
|
||||
_hp_value = value
|
||||
else:
|
||||
_attr_value = value
|
||||
@@ -174,7 +172,7 @@ func _status_box(caption: String, with_bar: bool) -> PanelContainer:
|
||||
|
||||
|
||||
func _draw_hp_bar(bar: Control) -> void:
|
||||
# 迷你血条(样张 v1 冻结:深底 Color8(40,34,28)(对暗面板可辨)+金填充——比例 = hero_hp / effective_max_hp)
|
||||
# 迷你血条(样张 v1 冻结:深底 UiKit.HP_BAR_BACK #28221C(对暗面板可辨)+金填充——比例 = hero_hp / effective_max_hp)
|
||||
if _runner == null:
|
||||
return
|
||||
var max_hp := maxi(1, _runner.effective_max_hp())
|
||||
@@ -268,7 +266,8 @@ func _fit_canvas(nodes: Array) -> void:
|
||||
maxl = maxi(maxl, int(layer[k]))
|
||||
for k in slot.keys():
|
||||
maxslot = maxi(maxslot, int(slot[k]))
|
||||
_content_size = Vector2(70 + maxl * 122 + NODE_HALF.x + 8.0, 52 + maxslot * 58 + NODE_HALF.y + 8.0)
|
||||
_content_size = Vector2(LAYER_BASE_X + maxl * LAYER_STEP_X + NODE_HALF.x + 8.0,
|
||||
SLOT_BASE_Y + maxslot * SLOT_STEP_Y + NODE_HALF.y + 8.0)
|
||||
_content_size = _content_size.max(Vector2(620, 240)) # 下限 = 旧定值画布(小图观感不变)
|
||||
_canvas.custom_minimum_size = _content_size
|
||||
|
||||
@@ -450,7 +449,8 @@ func _layout(nodes: Array, canvas: Control) -> Dictionary:
|
||||
var pos := {}
|
||||
var origin := (canvas.size - _content_size) / 2.0
|
||||
for node in nodes:
|
||||
pos[node] = origin + Vector2(70 + int(layer[node]) * 122, 52 + int(slot[node]) * 58)
|
||||
pos[node] = origin + Vector2(LAYER_BASE_X + int(layer[node]) * LAYER_STEP_X,
|
||||
SLOT_BASE_Y + int(slot[node]) * SLOT_STEP_Y)
|
||||
return pos
|
||||
|
||||
|
||||
|
||||
@@ -12,18 +12,8 @@ var _btn: Button
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
var dim := ColorRect.new()
|
||||
dim.color = Color(0, 0, 0, 0.6)
|
||||
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(dim)
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.add_child(center)
|
||||
var box := VBoxContainer.new()
|
||||
box.add_theme_constant_override("separation", 12)
|
||||
center.add_child(box)
|
||||
_label = UiKit.label("", 20, true)
|
||||
_label.add_theme_color_override("font_color", UiKit.WARM)
|
||||
var box: VBoxContainer = UiKit.modal_shell(self, Color(0, 0, 0, 0.6)).box
|
||||
_label = UiKit.label("", 20, true, UiKit.WARM)
|
||||
_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
box.add_child(_label)
|
||||
_btn = UiKit.button("继续")
|
||||
|
||||
@@ -30,23 +30,11 @@ func retarget(store) -> void:
|
||||
|
||||
|
||||
func _build() -> void:
|
||||
var dim := ColorRect.new()
|
||||
dim.color = UiKit.BG_OVERLAY
|
||||
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(dim)
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.add_child(center)
|
||||
var box := VBoxContainer.new()
|
||||
box.custom_minimum_size = Vector2(560, 0)
|
||||
box.add_theme_constant_override("separation", 8)
|
||||
center.add_child(box)
|
||||
var box: VBoxContainer = UiKit.modal_shell(self, UiKit.BG_OVERLAY, Vector2(560, 0), 8).box
|
||||
|
||||
var title := UiKit.label("设置", 26, true)
|
||||
title.add_theme_color_override("font_color", UiKit.WARM)
|
||||
var title := UiKit.label("设置", 26, true, UiKit.WARM)
|
||||
box.add_child(title)
|
||||
var hint := UiKit.label("系统级设置——独立存储不随存档(一安装一份,删游戏才消失)", 13, false)
|
||||
hint.add_theme_color_override("font_color", UiKit.WARM_SOFT)
|
||||
var hint := UiKit.label("系统级设置——独立存储不随存档(一安装一份,删游戏才消失)", 13, false, UiKit.WARM_SOFT)
|
||||
box.add_child(hint)
|
||||
box.add_child(HSeparator.new())
|
||||
|
||||
|
||||
@@ -47,8 +47,7 @@ func play_round_sweep(board_rect: Rect2) -> void:
|
||||
# 跨区弹道:glyph 字形自 from 飞向 to(0.35s + 轻微上抛弧线 + 终点淡出,自动回收)——
|
||||
# 开格之因 → 站桩之果的因果可视承载(P2);crit 弹道由调用方传加重标记
|
||||
func play_projectile(from: Vector2, to: Vector2, glyph: String, col: Color, crit: bool = false) -> void:
|
||||
var shot := UiKit.label(glyph, 22 if crit else 16, true)
|
||||
shot.add_theme_color_override("font_color", col)
|
||||
var shot := UiKit.label(glyph, 22 if crit else 16, true, col)
|
||||
shot.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
shot.size = Vector2(24, 24)
|
||||
shot.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
@@ -92,8 +91,7 @@ func play_damage_number(pos: Vector2, text: String, col: Color, crit: bool = fal
|
||||
_fx_damage_marks += 1
|
||||
# T17 修复(用户实机「完全没看到伤害数字」):26/32px 大字+1.1s 驻留——旧 20px/0.7s 在
|
||||
# 结算排播节奏下视觉存在感不足;描边 4→6 同步加重(亮舞台底上保读数)。
|
||||
var lab := UiKit.label(text, 32 if crit else 26, true)
|
||||
lab.add_theme_color_override("font_color", col)
|
||||
var lab := UiKit.label(text, 32 if crit else 26, true, col)
|
||||
lab.add_theme_color_override("font_outline_color", Color(0.1, 0.08, 0.06, 0.9))
|
||||
lab.add_theme_constant_override("outline_size", 6)
|
||||
lab.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
@@ -130,8 +128,7 @@ func play_round_banner(ri: int) -> void:
|
||||
var banner := Panel.new()
|
||||
banner.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
banner.add_theme_stylebox_override("panel", UiKit.panel_flat(Color(UiKit.BG_OVERLAY, 0.88), UiKit.GOLD_DEEP, 8, 2))
|
||||
var lab := UiKit.label("第 %d 轮" % ri, 22, true)
|
||||
lab.add_theme_color_override("font_color", UiKit.GOLD)
|
||||
var lab := UiKit.label("第 %d 轮" % ri, 22, true, UiKit.GOLD)
|
||||
lab.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
lab.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
lab.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
|
||||
@@ -11,20 +11,9 @@ var _log: RichTextLabel
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
var dim := ColorRect.new()
|
||||
dim.color = Color(UiKit.DIM, 0.62)
|
||||
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.gui_input.connect(_on_dim_gui_input)
|
||||
add_child(dim)
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.add_child(center)
|
||||
var panel := PanelContainer.new()
|
||||
center.add_child(panel)
|
||||
var box := VBoxContainer.new()
|
||||
box.custom_minimum_size = Vector2(760, 560)
|
||||
box.add_theme_constant_override("separation", 6)
|
||||
panel.add_child(box)
|
||||
var shell := UiKit.modal_shell(self, Color(UiKit.DIM, 0.62), Vector2(760, 560), 6, true)
|
||||
(shell.dim as ColorRect).gui_input.connect(_on_dim_gui_input)
|
||||
var box: VBoxContainer = shell.box
|
||||
box.add_child(UiKit.label("结算明细回看(完整流水 · 逐行归因)", 18, true))
|
||||
_log = RichTextLabel.new()
|
||||
_log.bbcode_enabled = true
|
||||
|
||||
@@ -19,22 +19,11 @@ var _card_rows: Array[Dictionary] = [] # [{product_id, price, bought, btn}]—
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
var dim := ColorRect.new()
|
||||
dim.color = Color(0, 0, 0, 0.6)
|
||||
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(dim)
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.add_child(center)
|
||||
var box := VBoxContainer.new()
|
||||
box.add_theme_constant_override("separation", 12)
|
||||
center.add_child(box)
|
||||
var title := UiKit.label("商店", 26, true)
|
||||
title.add_theme_color_override("font_color", UiKit.WARM)
|
||||
var box: VBoxContainer = UiKit.modal_shell(self, Color(0, 0, 0, 0.6)).box
|
||||
var title := UiKit.label("商店", 26, true, UiKit.WARM)
|
||||
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
box.add_child(title)
|
||||
_gp_label = UiKit.label("金币 0", 18, true)
|
||||
_gp_label.add_theme_color_override("font_color", UiKit.GOLD)
|
||||
_gp_label = UiKit.label("金币 0", 18, true, UiKit.GOLD)
|
||||
_gp_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
box.add_child(_gp_label)
|
||||
_cards_box = VBoxContainer.new()
|
||||
@@ -82,12 +71,10 @@ func _build_card(p: Dictionary) -> Dictionary:
|
||||
var name_l := UiKit.label(_card_title(p), 15, true)
|
||||
name_l.custom_minimum_size = Vector2(190, 0)
|
||||
row.add_child(name_l)
|
||||
var price_l := UiKit.label("", 14, false)
|
||||
price_l.add_theme_color_override("font_color", UiKit.WARM_SOFT)
|
||||
var price_l := UiKit.label("", 14, false, UiKit.WARM_SOFT)
|
||||
price_l.custom_minimum_size = Vector2(110, 0)
|
||||
row.add_child(price_l)
|
||||
var bought_l := UiKit.label("", 14, false)
|
||||
bought_l.add_theme_color_override("font_color", UiKit.WARM_FAINT)
|
||||
var bought_l := UiKit.label("", 14, false, UiKit.WARM_FAINT)
|
||||
row.add_child(bought_l)
|
||||
var btn := UiKit.button("购买")
|
||||
btn.pressed.connect(_emit_buy_requested.bind(p))
|
||||
|
||||
@@ -143,8 +143,7 @@ func set_effects_cleared_feedback() -> void:
|
||||
return
|
||||
slot_row.visible = true
|
||||
slot_row.set_cleared_feedback()
|
||||
var note := UiKit.label("状态随战斗结束消散", 11, false)
|
||||
note.add_theme_color_override("font_color", UiKit.STONE_FAINT)
|
||||
var note := UiKit.label("状态随战斗结束消散", 11, false, UiKit.STONE_FAINT)
|
||||
note.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
note.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
var parent := slot_row.get_parent()
|
||||
@@ -418,11 +417,11 @@ func _draw() -> void:
|
||||
var ang := TAU * float(i) / 24.0
|
||||
pts.append(sh_center + Vector2(cos(ang) * sh_rx, sin(ang) * sh_ry))
|
||||
draw_colored_polygon(pts, Color(0, 0, 0, 0.27))
|
||||
# 石板地台(v3.5——方向稿取色:板身 (150,130,100)/描边 (90,76,58)/顶缘受光线 2px (196,172,132);
|
||||
# 几何沿用现行底座位〔margin 26/高 10→方向稿 18/12——按方向稿对齐〕)
|
||||
draw_rect(Rect2(18.0, box.y - 18.0, box.x - 36.0, 12.0), Color8(150, 130, 100), true)
|
||||
draw_rect(Rect2(18.0, box.y - 18.0, box.x - 36.0, 12.0), Color8(90, 76, 58), false, 1.0)
|
||||
draw_rect(Rect2(18.0, box.y - 18.0, box.x - 36.0, 2.0), Color8(196, 172, 132), true)
|
||||
# 石板地台(v3.5——方向稿取色:板身/描边/顶缘受光线 2px——取色单点收 UiKit.STAND_STONE 族
|
||||
# (T4 裸色收口);几何沿用现行底座位〔margin 26/高 10→方向稿 18/12——按方向稿对齐〕)
|
||||
draw_rect(Rect2(18.0, box.y - 18.0, box.x - 36.0, 12.0), UiKit.STAND_STONE, true)
|
||||
draw_rect(Rect2(18.0, box.y - 18.0, box.x - 36.0, 12.0), UiKit.STAND_STONE_EDGE, false, 1.0)
|
||||
draw_rect(Rect2(18.0, box.y - 18.0, box.x - 36.0, 2.0), UiKit.STAND_STONE_RIM, true)
|
||||
|
||||
# 血条(直角递减):敌附顺位徽标(GOLD_DEEP ①②③)——旧 top VBox 几何等价(左 8 / 右 -8)
|
||||
var bar_x := 8.0
|
||||
|
||||
@@ -64,8 +64,7 @@ func _init() -> void:
|
||||
_tip.visible = false
|
||||
var sb := UiKit.panel_flat(UiKit.TIP_BG, UiKit.GOLD, 2, 1, Vector4(6, 3, 6, 3))
|
||||
_tip.add_theme_stylebox_override("panel", sb)
|
||||
_tip_label = UiKit.label("", 13, false)
|
||||
_tip_label.add_theme_color_override("font_color", UiKit.WARM)
|
||||
_tip_label = UiKit.label("", 13, false, UiKit.WARM)
|
||||
_tip_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
_tip_label.custom_minimum_size = Vector2(210, 0)
|
||||
_tip.add_child(_tip_label)
|
||||
|
||||
@@ -43,8 +43,7 @@ func show_toast(text: String, tone: String = "info") -> void:
|
||||
col = COL_GOLD
|
||||
sb.border_color = col
|
||||
row.add_theme_stylebox_override("panel", sb)
|
||||
var lab := UiKit.label(("⚠ " if tone == "warn" else "") + text, 14, tone != "info")
|
||||
lab.add_theme_color_override("font_color", col)
|
||||
var lab := UiKit.label(("⚠ " if tone == "warn" else "") + text, 14, tone != "info", col)
|
||||
lab.clip_text = true
|
||||
row.add_child(lab)
|
||||
_slot_box.add_child(row)
|
||||
|
||||
@@ -110,35 +110,23 @@ func _reset_btn_pressed() -> void:
|
||||
|
||||
|
||||
func effective_atk() -> int:
|
||||
return _scaled(_base_atk, atk_pct())
|
||||
return UiKit.scaled(_base_atk, atk_pct())
|
||||
|
||||
|
||||
func effective_max_hp() -> int:
|
||||
return _scaled(_base_hp, hp_pct())
|
||||
return UiKit.scaled(_base_hp, hp_pct())
|
||||
|
||||
|
||||
# ---- 内部构建 ----
|
||||
|
||||
func _build() -> void:
|
||||
var dim := ColorRect.new()
|
||||
dim.color = UiKit.BG_OVERLAY
|
||||
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(dim)
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.add_child(center)
|
||||
var box := VBoxContainer.new()
|
||||
box.custom_minimum_size = Vector2(640, 0)
|
||||
box.add_theme_constant_override("separation", 8)
|
||||
center.add_child(box)
|
||||
var box: VBoxContainer = UiKit.modal_shell(self, UiKit.BG_OVERLAY, Vector2(640, 0), 8).box
|
||||
|
||||
var title := UiKit.label("测试用 · 角色数值调整板", 26, true)
|
||||
title.add_theme_color_override("font_color", UiKit.WARM)
|
||||
var title := UiKit.label("测试用 · 角色数值调整板", 26, true, UiKit.WARM)
|
||||
box.add_child(title)
|
||||
var desc := UiKit.label(
|
||||
"模拟玩家在循环中解锁天赋获得的属性提升(仅测试工具,不落盘)。\n百分比叠加基础值:攻击 %d / 生命 %d。影响所有模式(手动与模拟)。" % [_base_atk, _base_hp],
|
||||
13, false)
|
||||
desc.add_theme_color_override("font_color", UiKit.WARM_SOFT)
|
||||
13, false, UiKit.WARM_SOFT)
|
||||
box.add_child(desc)
|
||||
box.add_child(HSeparator.new())
|
||||
|
||||
@@ -210,10 +198,6 @@ func _sync_labels() -> void:
|
||||
_base_atk, effective_atk(), _base_hp, effective_max_hp()]
|
||||
|
||||
|
||||
func _scaled(base: int, pct: int) -> int:
|
||||
return maxi(1, int(round(float(base) * (100.0 + float(pct)) / 100.0)))
|
||||
|
||||
|
||||
func _emit_simulate_requested() -> void:
|
||||
simulate_requested.emit(int(_sim_count.value))
|
||||
|
||||
|
||||
@@ -73,10 +73,36 @@ const DIM := Color(0.08, 0.06, 0.05) # 遮罩基色(用时乘 alpha
|
||||
const TOAST_BG := Color(0.94, 0.91, 0.84, 0.95) # toast 面底
|
||||
const TIP_BG := Color(0.16, 0.12, 0.09, 0.96) # tooltip 深底
|
||||
|
||||
# 呈现杂色档(T4 裸色收口批 2026-10-02——各视图裸 Color8 字面量单点化;值 = 收口时各来源行现值快照)
|
||||
const STAGE_BG := Color8(62, 52, 42) # B 区舞台暗底(方向稿 render_battle_screen——battle_stage_view 面板底)
|
||||
const BEAM_LIGHT := Color8(255, 236, 200) # B 区顶光柱暖光(用时乘 alpha 渐隐——battle_stage_view 光柱层)
|
||||
const STAND_STONE := Color8(150, 130, 100) # 站桩石板地台·板身(standee_body 方向稿取色)
|
||||
const STAND_STONE_EDGE := Color8(90, 76, 58) # 站桩石板地台·描边
|
||||
const STAND_STONE_RIM := Color8(196, 172, 132) # 站桩石板地台·顶缘受光线(与 board_cell_unit.FACADE_HIGHLIGHT_COL 异源同值——并档归清扫卡)
|
||||
const CAMP_HEADER_BAND := Color8(122, 82, 50) # 营地柜台头带深棕(4-camp.png 方向稿取色)
|
||||
const CAMP_ROW_PLATE := Color8(240, 230, 206) # 营地行板暖米(同上)
|
||||
const CAMP_BADGE_PANEL := Color8(40, 32, 24) # 营地钥石徽暗底(同上)
|
||||
const HP_BAR_BACK := Color8(40, 34, 28) # 迷你血条深底(关卡画面样张 v1 冻结——对暗面板可辨)
|
||||
|
||||
# BBCode 十六进制(RichTextLabel 用;与上同值)
|
||||
const HEX_GOLD := "f0a828"
|
||||
const HEX_INK := "33261b"
|
||||
const HEX_ON_GOLD := "3a2a08"
|
||||
# 结算行/叙事行语义档(T4 收口批——battle_log_view 行格式化与 narrator 横幅行的裸 hex 单点化;
|
||||
# 名随呈现语义、值 = 2026-09 起各行现值快照,色值逐字节不变)
|
||||
const HEX_LOG_ROUND := "9a8a72" # 轮次前缀/零值行暖灰石
|
||||
const HEX_LOG_GAIN := "e0b860" # 收益金(GP 袋/商店行/败判定/节点横幅)
|
||||
const HEX_LOG_LOSS := "c47c7c" # 损失红(GP 流失/负效果)
|
||||
const HEX_LOG_HEAL := "7cc47c" # 治疗绿(效果正值/治疗行/恢复点行)
|
||||
const HEX_LOG_DMG_NUM := "d9402a" # 伤害数字朱(放大加色——数字即信息主角)
|
||||
const HEX_LOG_DMG_KILL := "e07050" # 击杀行正文橙红
|
||||
const HEX_LOG_DMG_BODY := "e0a050" # 伤害行正文橙
|
||||
const HEX_LOG_VOIDED := "b08060" # 未生效行暗橙(⚠ 划线)
|
||||
const HEX_LOG_CAST := "b09a72" # 施放行暖石(✦ 具名技能)
|
||||
const HEX_LOG_DECAY := "8a9ab0" # 状态衰减蓝灰
|
||||
const HEX_LOG_WIN := "80d080" # 胜利判定绿(模拟报告通关率同档)
|
||||
const HEX_ROUTE_NOTE := "d0c090" # 奖励点预告暗金(narrator 行)
|
||||
const HEX_SEED_NOTE := "c8a860" # 种子/开场行暗金(narrator 行)
|
||||
|
||||
# 语义别名(同值异名——语义站点用别名,值仍单点)
|
||||
const DOT_OFF := PANEL_BORDER
|
||||
@@ -163,15 +189,59 @@ static func panel_flat(bg: Color, border: Color, corner: int = 0, border_w: int
|
||||
return sb
|
||||
|
||||
|
||||
static func label(text: String, size: int, bold: bool) -> Label:
|
||||
# color 缺省哨兵 = alpha<0(真实用色不取负 alpha)——传色即一次到位(旧「label() 后跟
|
||||
# add_theme_color_override」两行式收单行);省略时保持旧默认:bold=INK_LABEL / 非 bold=主题缺省
|
||||
static func label(text: String, size: int, bold: bool, color: Color = Color(-1, -1, -1, -1)) -> Label:
|
||||
var l := Label.new()
|
||||
l.text = text
|
||||
l.add_theme_font_size_override("font_size", size)
|
||||
if bold:
|
||||
if color.a >= 0.0:
|
||||
l.add_theme_color_override("font_color", color)
|
||||
elif bold:
|
||||
l.add_theme_color_override("font_color", INK_LABEL)
|
||||
return l
|
||||
|
||||
|
||||
# ── 模态壳工厂(T4 收口批 2026-10-02——各 overlay 手搓 dim+Center+VBox/Panel 骨架单点化)──
|
||||
# dim = 全屏半透明遮罩(全屏锚定纪律同既有各 overlay);center 全屏锚定居中;with_panel = 内容包
|
||||
# PanelContainer(panel_sb 缺省 = 主题默认板——settlement_review 同款);box = 内容列
|
||||
#(min_size/separation 参数化,min_size ZERO = 不设)。返回 Dictionary{dim, center, panel, box}
|
||||
#——探针直读的私有件由调用方按名摘引,结构同名同层级不变。
|
||||
static func modal_dim(parent: Control, dim_color: Color) -> ColorRect:
|
||||
var dim := ColorRect.new()
|
||||
dim.color = dim_color
|
||||
dim.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
parent.add_child(dim)
|
||||
return dim
|
||||
|
||||
|
||||
static func modal_shell(parent: Control, dim_color: Color, min_size := Vector2.ZERO, separation := 12,
|
||||
with_panel := false, panel_sb: StyleBox = null) -> Dictionary:
|
||||
var dim := modal_dim(parent, dim_color)
|
||||
var center := CenterContainer.new()
|
||||
center.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
dim.add_child(center)
|
||||
var panel: PanelContainer = null
|
||||
var host: Control = center
|
||||
if with_panel:
|
||||
panel = PanelContainer.new()
|
||||
if panel_sb != null:
|
||||
panel.add_theme_stylebox_override("panel", panel_sb)
|
||||
center.add_child(panel)
|
||||
host = panel
|
||||
var box := VBoxContainer.new()
|
||||
if min_size != Vector2.ZERO:
|
||||
box.custom_minimum_size = min_size
|
||||
box.add_theme_constant_override("separation", separation)
|
||||
host.add_child(box)
|
||||
return {"dim": dim, "center": center, "panel": panel, "box": box}
|
||||
|
||||
|
||||
# 属性百分比合成(main._debug_hero_override 与 TunePanel 生效值预览共用单点——两处同式实现收口)
|
||||
static func scaled(base: int, pct: int) -> int:
|
||||
return maxi(1, int(round(float(base) * (100.0 + float(pct)) / 100.0)))
|
||||
|
||||
|
||||
static func button(text: String) -> Button:
|
||||
var b := Button.new()
|
||||
b.text = text
|
||||
|
||||
Reference in new issue
Block a user