Compare commits

..
Author SHA1 Message Date
DKChan 5ab5af49f0 Merge branch 'master' into iter41
# Conflicts:
#	game/tests/验证集清单.md
2026-10-29 00:13:58 +08:00
DKChan b5cf393170 iter41-收尾:实现报告+反哺点清单落reports(键账对拍/豁免申报/测试移交清单/architecture现状改写申请/GDD行号随动)+并master文档面同步(art-bible成文整备/README能力清单) 2026-10-28 23:51:47 +08:00
DKChan b31d7de8b6 iter41-卡2:呈现层结构收敛批:25文件71键——67清+2豁免在册(main类变量49=architecture:183、tune_sim await=:311测量面)+2键inner class展平计数在案改善(board_cell_unit 31→30、standee_body 29→19);视图拆私有函数族+六状态件收拢(_TreeState族/_MapState/_CellPaintState/_StandeeState/_EndOverlayState/_DebugState)+ui_kit公开面26→20(删2私4哨兵收拢)+flow context三束收拢+curio_interact引用束注入+print×3删除;含u14补做、并master冲突6文件并案与无点形态改址盲区20处修复 2026-10-28 23:51:46 +08:00
DKChan 41a1959305 iter41-卡1:核心数据面结构收敛批:在册85键全清——校验族13文件/生成器族2文件/效果引擎四域拆分+config_db归位三域容器(公开44→8、类变量25→9)+存档拆件SlotStore/MetaStateStore(save 52→7)+meta_progression瘦身(31→20)+adventure_table拆段3段件(.tres等值迁移)+action_economy删并(18→15)+spawn签名束化(10→1);行为零变化逐字(校验错误清单/RNG消费序冻结/存档序列化/效果装载序/四词表),8新件键账在阈,全域改址约1330处 2026-10-28 23:51:46 +08:00
17 changed files with 57 additions and 40 deletions

No files matched your search

+1 -1
View File
@@ -680,7 +680,7 @@ func _roll_round_actions() -> void:
# 容器内直读主角行)
var facts := {
"round_index": round_index,
"last_round_end": "none" if action_economy.last_round_end().is_empty() else String(action_economy.last_round_end().get("path_tag", "none")),
"last_round_end": "none" if (action_economy.last_round_end as Dictionary).is_empty() else String((action_economy.last_round_end as Dictionary).get("path_tag", "none")),
"mines_hit_last": int(_mines_hits["last"]),
"mines_hit_total": int(_mines_hits["total"]),
}
-1
View File
@@ -1 +0,0 @@
uid://dpy0a6fcggbwe
-1
View File
@@ -1 +0,0 @@
uid://du0gxv0lnrxnp
-1
View File
@@ -1 +0,0 @@
uid://jaxlqd8ml3co
+6 -6
View File
@@ -145,7 +145,7 @@ func forge_buy_level(route_id: String) -> bool:
var row: Dictionary[Variant, Variant] = db.crossrun.forge.route(route_id)
if row.is_empty() or not _forge_route_unlocked(route_id):
return false
var lvl: int = meta_state.forge_state().levels.get(route_id, 0)
var lvl := meta_state.forge_state().levels.get(route_id, 0)
if lvl >= int(row.get("cap", 0)):
return false
var price := ForgeTable.level_price(row, lvl)
@@ -206,13 +206,13 @@ func forge_shop_status() -> Array:
var out: Array[Dictionary] = []
for row in db.crossrun.forge.route_rows():
var rid := String(row.get("route_id", ""))
var lvl: int = meta_state.forge_state().levels.get(rid, 0)
var lvl := meta_state.forge_state().levels.get(rid, 0)
var cap_v := int(row.get("cap", 0))
var unlocked := _forge_route_unlocked(rid)
var prereq := String(row.get("prereq_route", ""))
var plvl: int = meta_state.forge_state().levels.get(prereq, 0) if prereq != "" else 0
var plvl := meta_state.forge_state().levels.get(prereq, 0) if prereq != "" else 0
var pcap := int(db.crossrun.forge.route(prereq).get("cap", 0)) if prereq != "" else 0
var selected: bool = (String(row.get("kind", "")) == "weapon" and meta_state.forge_state().weapon == rid) \
var selected := (String(row.get("kind", "")) == "weapon" and meta_state.forge_state().weapon == rid) \
or (String(row.get("kind", "")) == "armor" and meta_state.forge_state().armor == rid)
out.append({
"route_id": rid,
@@ -362,7 +362,7 @@ func tree_buy(node_id: String) -> bool:
func tree_toggle_fork(group: String, side: String) -> bool:
if not db.crossrun.meta_tree.FORK_GROUPS.has(group) or not (side == "a" or side == "b"):
return false
var cur: String = meta_state.tree_state().fork_sides.get(group, "")
var cur := meta_state.tree_state().fork_sides.get(group, "")
if cur == "" or cur == side:
return false # 未解锁走购买面;同态零操作
meta_state.set_fork_side(group, side)
@@ -521,7 +521,7 @@ func attune_camp_status() -> Dictionary:
"equipped": equipped.has(iid),
"unlocked": meta_state.item_unlocked(iid),
})
var lvl: int = meta_state.attune_state().refresh_level
var lvl := meta_state.attune_state().refresh_level
var next_row: Dictionary[Variant, Variant] = db.crossrun.meta.attune_refresh_row(lvl + 1)
return {
"slots": Attunement.slots(db, save),
-1
View File
@@ -1 +0,0 @@
uid://bc5perm32w2yp
-1
View File
@@ -1 +0,0 @@
uid://dylsba7whx5ql
@@ -1 +0,0 @@
uid://b88nnsq53mium
@@ -1 +0,0 @@
uid://bi52mqsld3mpc
@@ -1 +0,0 @@
uid://c0y3hcpqyv1li
+15 -13
View File
@@ -8,16 +8,18 @@ extends RefCounted
const Narrator := preload("res://presentation/battle_narrator.gd")
var db
var ctx: CurioFlowContext # u13 引用束注入:构造注入 context 活引用(views/getters/flow 三束键名)
# _pending_curio/_curio_context 纯内部态保持宿主
# u13 引用束注入:16 个 _init 抄写成员删除——正文读点改址 ctx 束(u20 三束键名;
# _pending_curio/_curio_context 纯内部态保持宿主)
var _pending_curio := {} # 三选一停点载荷暂存(战斗总结结算确认后开三选一面;续玩停点复用)
var _curio_context := "level_clear" # 三选一面上下文(level_clear=关卡完成停点→推进下一关 / reward_node=奖励节点→回图选路)
func _init(ctx_ref: CurioFlowContext) -> void:
ctx = ctx_ref
func _init(ctx: CurioFlowContext) -> void:
# 构造参数收拢 context 对象(16 参长签名收一处命名面)
db = ctx.db
ctx.flow.fatal_screen = ctx.fatal_screen
ctx.flow.gp_summary = ctx.gp_summary
# 停点在途判据(组合根 _on_battle_end_continue 分派面——战斗总结确认后开三选一)
@@ -39,7 +41,7 @@ func resume_if_pending() -> bool:
#(continue_to_next_level 的「停点未兑付拒推进」守卫因此放行)。
func _skip_empty_stop() -> bool:
ctx.views.toast.show_toast("可用战利品为空——本次三选一跳过", "info")
var adventure = ctx.getters.adventure_get.call()
var adventure = _adventure_get.call()
if adventure != null:
adventure.stop().skip_empty_curio() # core 停点消化(其守卫=仅空候选放行)
if _curio_context == "reward_node":
@@ -86,7 +88,7 @@ func on_presented(payload: Dictionary) -> void:
# 奖励节点三选一(与关卡完成三选一共享同池同权重同上限;CurioPickOverlay 共用面)。
# 无替换子交互(同调装配不可变,见类头)。
func present_node_curio() -> void:
var adventure = ctx.getters.adventure_get.call()
var adventure = _adventure_get.call()
_curio_context = "reward_node"
var node_draw: Dictionary[Variant, Variant] = adventure.stop().node_curio_candidates()
var node_cands: Array[Variant] = node_draw.get("candidates", []) as Array
@@ -109,7 +111,7 @@ func show_pick() -> void:
var payload: Dictionary[Variant, Variant] = _pending_curio
ctx.flow.open_modal.call(ctx.views.curio_overlay)
ctx.views.curio_overlay.open_pick(Narrator.curio_pick_header(payload), _curio_card_texts(payload.get("candidates", []) as Array))
var adventure = ctx.getters.adventure_get.call()
var adventure = _adventure_get.call()
if adventure != null:
_feed_refresh_display(adventure) # 刷新面投喂单点
ctx.flow.refresh_presentations.call()
@@ -117,7 +119,7 @@ func show_pick() -> void:
# 刷新呈现投喂单点(免费余量 X/Y + GP 付费价 + 冒险钱包可付——读数与商店 set_refresh_display 同构)
func _feed_refresh_display(adventure: AdventureRunner) -> void:
var runner = ctx.getters.runner_get.call()
var runner = _runner_get.call()
var gp := int(runner.gp) if runner != null else 0
var cost: int = adventure.refresh_bank().gp_cost()
ctx.views.curio_overlay.set_refresh_display(adventure.refresh_bank().free_left(), cost, gp >= cost)
@@ -152,10 +154,10 @@ func _curio_card_texts(candidates: Array) -> Array:
# 同 shop_refresh_cost_base/curve 旋钮、同冒险钱包 runner.gp;关卡完成停点经重发 curio_choice_presented 直落
# 选择面,节点停点在此读在途态重 present——零自动推进契约不破,停点仍在途)
func on_refresh() -> void:
var adventure = ctx.getters.adventure_get.call()
var adventure = _adventure_get.call()
if adventure == null or not adventure.stop().curio_stop_pending():
return
var runner = ctx.getters.runner_get.call()
var runner = _runner_get.call()
var refreshed: bool = adventure.stop().refresh_curio()
if not refreshed:
# 免费位(X/Y)已穷——GP 付费档(先扣钱包后重抽,余额不足拒绝零副作用)
@@ -174,7 +176,7 @@ func on_refresh() -> void:
func on_pick_confirmed(item_id: String) -> void:
var adventure = ctx.getters.adventure_get.call()
var adventure = _adventure_get.call()
if adventure == null:
return
# TP0 令牌池——卡片 id "kind|tier|feat_id" 拆键(缺 | = 旧载荷防御归普通档;relic 三段)
@@ -204,7 +206,7 @@ func on_resolved(result: Dictionary) -> void:
func on_continue() -> void:
ctx.flow.close_modal.call(ctx.views.curio_overlay)
ctx.views.curio_overlay.close_pick()
var adventure = ctx.getters.adventure_get.call()
var adventure = _adventure_get.call()
if _curio_context == "feat_ticket":
return # T5 店内专长凭证面——专长兑付完成后关面回店(无推进/无回图)
if _curio_context == "reward_node":
@@ -221,7 +223,7 @@ func on_continue() -> void:
# 数据源=treasure 装配词表 12 件
func item_name_lookup() -> Dictionary:
var lookup := {}
var meta = ctx.getters.meta_get.call()
var meta = _meta_get.call()
if meta != null:
for row in db.crossrun.treasure_items.attunement_rows():
lookup[String(row.get("item_id", ""))] = String(row.get("display_name", ""))
+1 -6
View File
@@ -144,7 +144,7 @@ static func _build_curio(root: Variant) -> void:
{"open_modal": root._open_modal, "open_modal_after_playback": root._open_modal_after_playback,
"close_modal": root._close_modal, "refresh_presentations": root._refresh_presentations,
"fatal_screen": root._fatal_screen,
"gp_summary": _gp_summary_cb(root)})) # 构造参数收拢 context(u20 三束)
"gp_summary": func() -> String: return root._gp_summary_text({"gp_dropped": root.run_scope.last_gain_amount}}))) # 构造参数收拢 context(u20 三束)
root.curio_overlay.pick_confirmed.connect(root._bonus.on_pick_confirmed)
root.curio_overlay.continue_pressed.connect(root._bonus.on_continue)
root.curio_overlay.refresh_requested.connect(root._bonus.on_refresh)
@@ -251,8 +251,3 @@ static func fatal_screen(root: Variant, msg: String) -> void:
var l := UiKit.label(msg,UiKit.FS_SUB, true, UiKit.RED_ALERT)
l.set_anchors_preset(Control.PRESET_CENTER)
root.add_child(l)
# GP 总结行回调(gp_summary 束键——单行 lambda 内嵌字典实参收尾歧义,提函数承载)
static func _gp_summary_cb(root: Variant) -> Callable:
return func() -> String: return root._gp_summary_text({"gp_dropped": root.run_scope.last_gain_amount})
@@ -271,7 +271,12 @@ func _spawn_seal_dot(i: int, base: Vector2) -> void:
tw.tween_callback(dot.queue_free)
# ---- 演出密度(程序化 tween,确定性散布,零新帧资产;计数与碎砖驻留面在 _EndOverlayState) ----
# ---- 演出密度(程序化 tween,确定性散布,零新帧资产) ----
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)
+1 -1
View File
@@ -323,7 +323,7 @@ func _draw_bevel() -> void:
## 变异标记域:真视格=危险红内缩框/未开格伤害型变异=左下角危险红三角
func _draw_mutation_marks() -> void:
if st.treasure_mark == "mine_reveal":
if treasure_mark == "mine_reveal":
var inset := st.edge * 0.14
draw_rect(Rect2(inset, inset, st.edge - inset * 2.0, st.edge - inset * 2.0),
Color(UiKit.RED_MINE, 0.9), false, 2.0)
+4 -3
View File
@@ -24,6 +24,7 @@ func _init() -> void:
vb.add_theme_constant_override("separation", 4)
add_child(vb)
_build_views(vb)
_build_status_corner()
## 视图三件域:AP 条+棋盘区(含动效与 toast 叠层)
@@ -36,11 +37,11 @@ func _build_views(vb: VBoxContainer) -> void:
vb.add_child(board_area)
_board_area = board_area
board_area.resized.connect(_on_board_area_resized)
_build_board_children(board_area, vb)
_build_board_children(board_area)
## 棋盘子件域:视图+动效+toast 三叠层挂接+状态角标+操作提示条(hint 回挂 vb——树序与拆分前一致)
func _build_board_children(board_area: Control, vb: VBoxContainer) -> void:
## 棋盘子件域:视图+动效+toast 三叠层挂接
func _build_board_children(board_area: Control) -> void:
board_view = BoardView.new()
board_view.set_anchors_preset(Control.PRESET_FULL_RECT)
board_area.add_child(board_view)
@@ -62,6 +62,28 @@ func _build_top_row(top: HBoxContainer) -> void:
## 主体域:入账信息行+三竖卡列+底部确认/继续钮与免费选择注记
func _build_body(box: VBoxContainer) -> void:
_label = UiKit.label("",UiKit.FS_BODY, false, UiKit.WARM_SOFT)
_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
box.add_child(_label)
_choice_box = HBoxContainer.new()
_choice_box.add_theme_constant_override("separation", 26) # demo .cards gap 26(T7 对齐)
_choice_box.alignment = BoxContainer.ALIGNMENT_CENTER
_choice_box.size_flags_vertical = Control.SIZE_EXPAND_FILL
box.add_child(_choice_box)
var foot := HBoxContainer.new()
foot.alignment = BoxContainer.ALIGNMENT_CENTER
foot.add_theme_constant_override("separation", 16)
box.add_child(foot)
_confirm_btn = UiKit.primary_button("确认选择")
_confirm_btn.pressed.connect(_on_confirm_pressed)
_confirm_btn.visible = false
foot.add_child(_confirm_btn)
_continue_btn = UiKit.button("继续")
_continue_btn.pressed.connect(_emit_continue_pressed)
_continue_btn.visible = false
foot.add_child(_continue_btn)
_foot_hint = UiKit.label("免费选择 · 刷新不消耗 AP",UiKit.FS_HINT, false, UiKit.WARM_FAINT)
foot.add_child(_foot_hint)
_label = UiKit.label("",UiKit.FS_BODY, false, UiKit.WARM_SOFT)
_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
box.add_child(_label)
+1 -1
View File
@@ -351,7 +351,7 @@ const BEAMS_PEAK := 0.05
## 光带像素域(循环体提函数——12° 斜向光带双三角衰减:带内峰值×纵向衰减逐像素着色)
static func _paint_beams(img: Image) -> void:
func _paint_beams(img: Image) -> void:
var ca := BEAMS_TILT_CA
var sa := BEAMS_TILT_SA
var beam_col := Color(1.0, 236.0 / 255.0, 200.0 / 255.0)