卡②T4(呈现层结构收敛批): u13/u19–u24——u13 curio_interact_controller引用束注入(16抄写成员删除,正文读点改址ctx三束键名34处,构造单点零随动)+u19 hud_presenter参数束收拢(refresh 8→4ctx五键{settlement,runner,level_active,db,refresh_remaining}/_refresh_out_of_battle 6→4同ctx/tune_sim_report 10→5 stats六键)+消费点改址(main:819 ctx束形/tune_sim stats束形)+u20 CurioFlowContext三束收拢(16参16成员→4参4成员,views/getters/flow字典)+u21 CampFlowContext同形(12→4)+main_ui_build两构造行改束传参+u22 battle_narrator(bonus_card_text模板表化9→4返回+档位尾注/秘宝卡两域)+u23 tune_sim(print删除[信息由logger JSONL承载]+run统计束收拢stats字典+单局模拟提函数;await零触碰=v1.19测量面豁免在册)+u24 playtest_logger(print×2删除,路径信息已由toast/JSONL承载);gdstyle基线内28→24键[await与main两键豁免在册]
This commit is contained in:
1 parent
525529ad88
commit
836c25e41c
10 files changed
+149
-192
No files matched your search
@@ -98,31 +98,36 @@ static func curio_pick_header(payload: Dictionary) -> String:
|
||||
# 对齐 v2.2 追认 b 口径:小/大前缀(小GP/大GP 族)、恢复/AP 不带档位词;道具件掷定前置时
|
||||
# treasure_line = 具体道具「名 · 效果摘要」行——常空走通用分支)
|
||||
static func bonus_card_text(id: String, tier: String, value: int, treasure_line: String = "") -> String:
|
||||
var ts := ""
|
||||
if tier == "common":
|
||||
ts = " · 小"
|
||||
elif tier == "rare":
|
||||
ts = " · 大"
|
||||
match id:
|
||||
"attack":
|
||||
return "攻击力提升%s\n攻击 +%d" % [ts, value]
|
||||
"max_hp":
|
||||
return "生命上限提升%s\n生命上限 +%d" % [ts, value]
|
||||
"armor":
|
||||
return "护甲等级提升%s\n护甲 +%d" % [ts, value]
|
||||
"gp":
|
||||
return "GP 袋%s\nGP +%d" % [ts, value]
|
||||
"heal":
|
||||
return "恢复药剂\n生命 +%d(当即回复)" % value
|
||||
"treasure_item":
|
||||
if treasure_line != "":
|
||||
return "秘宝\n%s" % treasure_line
|
||||
return "秘宝\n随机获得一件"
|
||||
"ap":
|
||||
return "行动点提升\n每战首轮 AP +%d" % value
|
||||
if id == "treasure_item":
|
||||
return _bonus_treasure_line(treasure_line)
|
||||
var ts := _tier_suffix(tier)
|
||||
var templates := {"attack": "攻击力提升%s\n攻击 +%d", "max_hp": "生命上限提升%s\n生命上限 +%d",
|
||||
"armor": "护甲等级提升%s\n护甲 +%d", "gp": "GP 袋%s\nGP +%d"}
|
||||
if templates.has(id):
|
||||
return templates[id] % [ts, value]
|
||||
if id == "heal":
|
||||
return "恢复药剂\n生命 +%d(当即回复)" % value
|
||||
if id == "ap":
|
||||
return "行动点提升\n每战首轮 AP +%d" % value
|
||||
return id
|
||||
|
||||
|
||||
## 档位尾注域(common=小/rare=大——旧载荷防御口径)
|
||||
static func _tier_suffix(tier: String) -> String:
|
||||
if tier == "common":
|
||||
return " · 小"
|
||||
if tier == "rare":
|
||||
return " · 大"
|
||||
return ""
|
||||
|
||||
|
||||
## 秘宝卡文案域(treasure_line 空串=随机获得一件)
|
||||
static func _bonus_treasure_line(treasure_line: String) -> String:
|
||||
if treasure_line != "":
|
||||
return "秘宝\n%s" % treasure_line
|
||||
return "秘宝\n随机获得一件"
|
||||
|
||||
|
||||
# 三选一兑付反馈行(选中件效果 + 丢弃提示;tier 缺省普通档——旧载荷防御口径)
|
||||
static func bonus_result_text(result: Dictionary) -> String:
|
||||
var name := ""
|
||||
|
||||
@@ -4,33 +4,16 @@ extends RefCounted
|
||||
# 原 13 参长签名收一处命名面——单测可直接 new() 本 context + 控制器获得独立实例化缝)。
|
||||
# 字段即原构造参数逐一同名迁移;依赖仅视图句柄 + 查询/编排 Callable(组合根注入)。
|
||||
|
||||
## 三束按域收拢(u21——同 u20 形;views=视图句柄/getters=查询 Callable 活引用/flow=编排 Callable):
|
||||
## 原 12 参长签名收 4 参——字段即原构造参数逐一同名迁移,键面=消费方改址合同。
|
||||
var db
|
||||
var meta_get: Callable # () -> MetaProgressionCore(现值回调——组合根 lambda)
|
||||
var save_get: Callable # () -> SaveManagerCore
|
||||
var camp_overlay: CampOverlay
|
||||
var shop_overlay: ShopOverlay
|
||||
var toast: ToastStack
|
||||
var start_overlay: Control
|
||||
var logger # PlaytestLogger(试玩日志验收取数面)
|
||||
var runner_get: Callable # () -> LevelRunner
|
||||
var open_modal: Callable
|
||||
var close_modal: Callable
|
||||
var refresh_presentations: Callable
|
||||
var views: Dictionary = {} # {camp_overlay, shop_overlay, toast, start_overlay, logger}
|
||||
var getters: Dictionary = {} # {meta_get, save_get, runner_get}
|
||||
var flow: Dictionary = {} # {open_modal, close_modal, refresh_presentations}
|
||||
|
||||
|
||||
func _init(db_ref, meta_get_cb: Callable, save_get_cb: Callable, camp_overlay_ref: CampOverlay,
|
||||
shop_overlay_ref: ShopOverlay, toast_ref: ToastStack, start_overlay_ref: Control,
|
||||
logger_ref, runner_get_cb: Callable, open_modal_cb: Callable, close_modal_cb: Callable,
|
||||
refresh_presentations_cb: Callable) -> void:
|
||||
func _init(db_ref, views_bundle: Dictionary, getters_bundle: Dictionary, flow_bundle: Dictionary) -> void:
|
||||
db = db_ref
|
||||
meta_get = meta_get_cb
|
||||
save_get = save_get_cb
|
||||
camp_overlay = camp_overlay_ref
|
||||
shop_overlay = shop_overlay_ref
|
||||
toast = toast_ref
|
||||
start_overlay = start_overlay_ref
|
||||
logger = logger_ref
|
||||
runner_get = runner_get_cb
|
||||
open_modal = open_modal_cb
|
||||
close_modal = close_modal_cb
|
||||
refresh_presentations = refresh_presentations_cb
|
||||
views = views_bundle
|
||||
getters = getters_bundle
|
||||
flow = flow_bundle
|
||||
@@ -21,17 +21,17 @@ var _refresh_presentations: Callable
|
||||
func _init(ctx: CampFlowContext) -> void:
|
||||
# 构造参数收拢 context 对象(13 参长签名收一处命名面)
|
||||
db = ctx.db
|
||||
_meta_get = ctx.meta_get
|
||||
_save_get = ctx.save_get
|
||||
camp_overlay = ctx.camp_overlay
|
||||
shop_overlay = ctx.shop_overlay
|
||||
toast = ctx.toast
|
||||
start_overlay = ctx.start_overlay
|
||||
logger = ctx.logger
|
||||
_runner_get = ctx.runner_get
|
||||
_open_modal = ctx.open_modal
|
||||
_close_modal = ctx.close_modal
|
||||
_refresh_presentations = ctx.refresh_presentations
|
||||
_meta_get = ctx.getters.meta_get
|
||||
_save_get = ctx.getters.save_get
|
||||
camp_overlay = ctx.views.camp_overlay
|
||||
shop_overlay = ctx.views.shop_overlay
|
||||
toast = ctx.views.toast
|
||||
start_overlay = ctx.views.start_overlay
|
||||
logger = ctx.views.logger
|
||||
_runner_get = ctx.getters.runner_get
|
||||
_open_modal = ctx.flow.open_modal
|
||||
_close_modal = ctx.flow.close_modal
|
||||
_refresh_presentations = ctx.flow.refresh_presentations
|
||||
|
||||
|
||||
# 打开营地(主菜单入口——开合与开始层互斥仿设置面先例:开始覆盖层非模态且树序在后,
|
||||
|
||||
@@ -4,42 +4,16 @@ extends RefCounted
|
||||
# 原 16 参长签名收一处命名面——单测可直接 new() 本 context + 控制器获得独立实例化缝)。
|
||||
# 字段即原构造参数逐一同名迁移;依赖仅视图句柄 + 查询/编排 Callable(组合根注入)。
|
||||
|
||||
## 三束按域收拢(u20——views=视图句柄/getters=查询 Callable 活引用〔禁快照〕/flow=编排 Callable):
|
||||
## 原 16 参长签名收 4 参——字段即原构造参数逐一同名迁移,键面=消费方改址合同。
|
||||
var db
|
||||
var meta_get: Callable # () -> MetaProgressionCore(现值回调——组合根 lambda)
|
||||
var curio_overlay: CurioPickOverlay
|
||||
var end_overlay: BattleEndOverlay
|
||||
var board_view: BoardView
|
||||
var toast: ToastStack
|
||||
var save_get: Callable # () -> SaveManagerCore
|
||||
var adventure_get: Callable # () -> AdventureRunner(会话现值)
|
||||
var runner_get: Callable # () -> LevelRunner
|
||||
var adventure_mode_get: Callable # () -> bool
|
||||
var open_modal: Callable # (Control) -> void
|
||||
var open_modal_after_playback: Callable
|
||||
var close_modal: Callable
|
||||
var refresh_presentations: Callable
|
||||
var fatal_screen: Callable
|
||||
var gp_summary: Callable # (Dictionary) -> String
|
||||
var views: Dictionary = {} # {curio_overlay, end_overlay, board_view, toast}
|
||||
var getters: Dictionary = {} # {meta_get, save_get, adventure_get, runner_get, adventure_mode_get}
|
||||
var flow: Dictionary = {} # {open_modal, open_modal_after_playback, close_modal, refresh_presentations, fatal_screen, gp_summary}
|
||||
|
||||
|
||||
func _init(db_ref, meta_get_cb: Callable, curio_overlay_ref: CurioPickOverlay, end_overlay_ref: BattleEndOverlay,
|
||||
board_view_ref: BoardView, toast_ref: ToastStack, save_get_cb: Callable,
|
||||
adventure_get_cb: Callable, runner_get_cb: Callable, adventure_mode_get_cb: Callable,
|
||||
open_modal_cb: Callable, open_modal_after_playback_cb: Callable, close_modal_cb: Callable,
|
||||
refresh_presentations_cb: Callable, fatal_screen_cb: Callable, gp_summary_cb: Callable) -> void:
|
||||
func _init(db_ref, views_bundle: Dictionary, getters_bundle: Dictionary, flow_bundle: Dictionary) -> void:
|
||||
db = db_ref
|
||||
meta_get = meta_get_cb
|
||||
curio_overlay = curio_overlay_ref
|
||||
end_overlay = end_overlay_ref
|
||||
board_view = board_view_ref
|
||||
toast = toast_ref
|
||||
save_get = save_get_cb
|
||||
adventure_get = adventure_get_cb
|
||||
runner_get = runner_get_cb
|
||||
adventure_mode_get = adventure_mode_get_cb
|
||||
open_modal = open_modal_cb
|
||||
open_modal_after_playback = open_modal_after_playback_cb
|
||||
close_modal = close_modal_cb
|
||||
refresh_presentations = refresh_presentations_cb
|
||||
fatal_screen = fatal_screen_cb
|
||||
gp_summary = gp_summary_cb
|
||||
views = views_bundle
|
||||
getters = getters_bundle
|
||||
flow = flow_bundle
|
||||
@@ -8,21 +8,8 @@ extends RefCounted
|
||||
const Narrator := preload("res://presentation/battle_narrator.gd")
|
||||
|
||||
var db
|
||||
var _meta_get: Callable # () → 元进度账本现值(组合根 lambda——探针 isolate_save 换注面)
|
||||
var curio_overlay: CurioPickOverlay
|
||||
var end_overlay: BattleEndOverlay
|
||||
var board_view: BoardView
|
||||
var toast: ToastStack
|
||||
var _save_get: Callable # () → 存档承载现值(同上——Attunement.slots 读数面)
|
||||
var _adventure_get: Callable # () → 冒险结构现值(组合根 lambda——随局更替)
|
||||
var _runner_get: Callable # () → 关卡推进器现值(组合根 lambda——reward_node 继续推进)
|
||||
var _adventure_mode_get: Callable # () → 冒险模式标记现值(组合根 lambda)
|
||||
var _open_modal: Callable # 模态栈单口(组合根)
|
||||
var _open_modal_after_playback: Callable # 演播后排窗单口(组合根)
|
||||
var _close_modal: Callable
|
||||
var _refresh_presentations: Callable
|
||||
var _fatal_screen: Callable
|
||||
var _gp_summary: Callable # () → 战斗总结 GP 行文案(组合根 lambda——_last_gain_amount 取数面在根)
|
||||
# u13 引用束注入:16 个 _init 抄写成员删除——正文读点改址 ctx 束(u20 三束键名;
|
||||
# _pending_curio/_curio_context 纯内部态保持宿主)
|
||||
|
||||
var _pending_curio := {} # 三选一停点载荷暂存(战斗总结结算确认后开三选一面;续玩停点复用)
|
||||
var _curio_context := "level_clear" # 三选一面上下文(level_clear=关卡完成停点→推进下一关 / reward_node=奖励节点→回图选路)
|
||||
@@ -31,21 +18,8 @@ var _curio_context := "level_clear" # 三选一面上下文(level_clear=
|
||||
func _init(ctx: CurioFlowContext) -> void:
|
||||
# 构造参数收拢 context 对象(16 参长签名收一处命名面)
|
||||
db = ctx.db
|
||||
_meta_get = ctx.meta_get
|
||||
curio_overlay = ctx.curio_overlay
|
||||
end_overlay = ctx.end_overlay
|
||||
board_view = ctx.board_view
|
||||
toast = ctx.toast
|
||||
_save_get = ctx.save_get
|
||||
_adventure_get = ctx.adventure_get
|
||||
_runner_get = ctx.runner_get
|
||||
_adventure_mode_get = ctx.adventure_mode_get
|
||||
_open_modal = ctx.open_modal
|
||||
_open_modal_after_playback = ctx.open_modal_after_playback
|
||||
_close_modal = ctx.close_modal
|
||||
_refresh_presentations = ctx.refresh_presentations
|
||||
_fatal_screen = ctx.fatal_screen
|
||||
_gp_summary = ctx.gp_summary
|
||||
ctx.flow.fatal_screen = ctx.fatal_screen
|
||||
ctx.flow.gp_summary = ctx.gp_summary
|
||||
|
||||
|
||||
# 停点在途判据(组合根 _on_battle_end_continue 分派面——战斗总结确认后开三选一)
|
||||
@@ -66,17 +40,17 @@ func resume_if_pending() -> bool:
|
||||
# 差异仅零面可收——curio_overlay 未开不 close。core 停点经 skip_empty_curio 消化后推进
|
||||
#(continue_to_next_level 的「停点未兑付拒推进」守卫因此放行)。
|
||||
func _skip_empty_stop() -> bool:
|
||||
toast.show_toast("可用战利品为空——本次三选一跳过", "info")
|
||||
ctx.views.toast.show_toast("可用战利品为空——本次三选一跳过", "info")
|
||||
var adventure = _adventure_get.call()
|
||||
if adventure != null:
|
||||
adventure.stop().skip_empty_curio() # core 停点消化(其守卫=仅空候选放行)
|
||||
if _curio_context == "reward_node":
|
||||
var runner = _runner_get.call()
|
||||
var runner = ctx.getters.runner_get.call()
|
||||
if runner != null:
|
||||
runner.continue_after_node()
|
||||
elif _curio_context == "level_clear" and bool(_adventure_mode_get.call()):
|
||||
elif _curio_context == "level_clear" and bool(ctx.getters.adventure_mode_get.call()):
|
||||
if not adventure.continue_to_next_level():
|
||||
_fatal_screen.call("关卡推进失败——见输出日志")
|
||||
ctx.flow.fatal_screen.call("关卡推进失败——见输出日志")
|
||||
# feat_ticket = 只消化停点回店(零推进——与 on_continue 同构)
|
||||
_pending_curio = {}
|
||||
return true
|
||||
@@ -93,22 +67,22 @@ func on_presented(payload: Dictionary) -> void:
|
||||
# 空候选防御(零卡不开死面;core _redeem_feat_ticket 守卫外的末道)
|
||||
_skip_empty_stop()
|
||||
return
|
||||
_open_modal.call(curio_overlay)
|
||||
curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(payload.get("candidates", []) as Array))
|
||||
ctx.flow.open_modal.call(ctx.views.curio_overlay)
|
||||
ctx.views.curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(payload.get("candidates", []) as Array))
|
||||
return
|
||||
if int(payload.get("aux_cleared", 0)) > 0:
|
||||
toast.show_toast("上关剩余 %d 件秘宝已随关卡结束清空" % int(payload.get("aux_cleared", 0)), "info") # 清空反馈
|
||||
ctx.views.toast.show_toast("上关剩余 %d 件秘宝已随关卡结束清空" % int(payload.get("aux_cleared", 0)), "info") # 清空反馈
|
||||
_pending_curio = payload.duplicate(true)
|
||||
_curio_context = "level_clear"
|
||||
if bool(payload.get("refreshed", false)):
|
||||
# 刷新重发:refreshed 标直落选择面——不再重开胜利总结面
|
||||
show_pick()
|
||||
return
|
||||
end_overlay.open_victory(Narrator.battle_end_text("victory", false), "继续",
|
||||
board_view.get_global_rect(),
|
||||
"%s\n%s" % [String(_gp_summary.call()), Narrator.bonus_keystone_line(payload)])
|
||||
_open_modal_after_playback.call(end_overlay)
|
||||
_refresh_presentations.call()
|
||||
ctx.views.end_overlay.open_victory(Narrator.battle_end_text("victory", false), "继续",
|
||||
ctx.views.board_view.get_global_rect(),
|
||||
"%s\n%s" % [String(ctx.flow.gp_summary.call()), Narrator.bonus_keystone_line(payload)])
|
||||
ctx.flow.open_modal_after_playback.call(ctx.views.end_overlay)
|
||||
ctx.flow.refresh_presentations.call()
|
||||
|
||||
|
||||
# 奖励节点三选一(与关卡完成三选一共享同池同权重同上限;CurioPickOverlay 共用面)。
|
||||
@@ -121,13 +95,13 @@ func present_node_curio() -> void:
|
||||
if node_cands.is_empty():
|
||||
# 空池降级——不开面、不挂节点停点(present_node_curio 未调即未挂),
|
||||
# 兑付确认直落回图选路(auto-sim「node_entered 回调内立即 continue_after_node」先例)
|
||||
toast.show_toast("可用战利品为空——本次三选一跳过", "info")
|
||||
var runner = _runner_get.call()
|
||||
ctx.views.toast.show_toast("可用战利品为空——本次三选一跳过", "info")
|
||||
var runner = ctx.getters.runner_get.call()
|
||||
if runner != null:
|
||||
runner.continue_after_node()
|
||||
return
|
||||
_open_modal.call(curio_overlay)
|
||||
curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(node_cands))
|
||||
ctx.flow.open_modal.call(ctx.views.curio_overlay)
|
||||
ctx.views.curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(node_cands))
|
||||
adventure.stop().present_node_curio(node_cands)
|
||||
_feed_refresh_display(adventure) # 刷新面投喂单点
|
||||
|
||||
@@ -135,12 +109,12 @@ func present_node_curio() -> void:
|
||||
# 三选一面开出(战斗总结结算确认 / 续玩停点恢复)
|
||||
func show_pick() -> void:
|
||||
var payload: Dictionary[Variant, Variant] = _pending_curio
|
||||
_open_modal.call(curio_overlay)
|
||||
curio_overlay.open_pick(Narrator.curio_pick_header(payload), _curio_card_texts(payload.get("candidates", []) as Array))
|
||||
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 = _adventure_get.call()
|
||||
if adventure != null:
|
||||
_feed_refresh_display(adventure) # 刷新面投喂单点
|
||||
_refresh_presentations.call()
|
||||
ctx.flow.refresh_presentations.call()
|
||||
|
||||
|
||||
# 刷新呈现投喂单点(免费余量 X/Y + GP 付费价 + 冒险钱包可付——读数与商店 set_refresh_display 同构)
|
||||
@@ -148,7 +122,7 @@ func _feed_refresh_display(adventure: AdventureRunner) -> void:
|
||||
var runner = _runner_get.call()
|
||||
var gp := int(runner.gp) if runner != null else 0
|
||||
var cost: int = adventure.refresh_bank().gp_cost()
|
||||
curio_overlay.set_refresh_display(adventure.refresh_bank().free_left(), cost, gp >= cost)
|
||||
ctx.views.curio_overlay.set_refresh_display(adventure.refresh_bank().free_left(), cost, gp >= cost)
|
||||
|
||||
|
||||
func _curio_card_texts(candidates: Array) -> Array:
|
||||
@@ -189,15 +163,15 @@ func on_refresh() -> void:
|
||||
# 免费位(X/Y)已穷——GP 付费档(先扣钱包后重抽,余额不足拒绝零副作用)
|
||||
var cost: int = adventure.refresh_bank().gp_cost()
|
||||
if runner == null or not runner.spend_gp(cost):
|
||||
toast.show_toast("GP不足——刷新失败", "warn")
|
||||
ctx.views.toast.show_toast("GP不足——刷新失败", "warn")
|
||||
return
|
||||
refreshed = adventure.stop().refresh_curio_paid()
|
||||
_refresh_presentations.call() # 钱包变化上屏(对齐商店购买后刷新面)
|
||||
ctx.flow.refresh_presentations.call() # 钱包变化上屏(对齐商店购买后刷新面)
|
||||
if not refreshed:
|
||||
return
|
||||
if _curio_context == "reward_node":
|
||||
var st: Dictionary[Variant, Variant] = adventure.stop().node_curio_pending_state()
|
||||
curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(st.get("candidates", []) as Array))
|
||||
ctx.views.curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(st.get("candidates", []) as Array))
|
||||
_feed_refresh_display(adventure)
|
||||
|
||||
|
||||
@@ -218,31 +192,31 @@ func on_pick_confirmed(item_id: String) -> void:
|
||||
# 后续兑付/确认仍走节点路径回图选路)
|
||||
if _curio_context == "reward_node" and kind == "feat_ticket":
|
||||
var st2: Dictionary[Variant, Variant] = adventure.stop().node_curio_pending_state()
|
||||
curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(st2.get("candidates", []) as Array))
|
||||
ctx.views.curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(st2.get("candidates", []) as Array))
|
||||
|
||||
|
||||
# 兑付反馈(curio_resolved 到达——结果行上屏,唯一出口 = 继续)
|
||||
func on_resolved(result: Dictionary) -> void:
|
||||
_pending_curio = {}
|
||||
curio_overlay.show_result(Narrator.bonus_result_text(result))
|
||||
_refresh_presentations.call()
|
||||
ctx.views.curio_overlay.show_result(Narrator.bonus_result_text(result))
|
||||
ctx.flow.refresh_presentations.call()
|
||||
|
||||
|
||||
# 继续钮:收三选一面 → 上下文分派(关卡完成停点=推进下一关 / 奖励节点=兑付确认回图选路——零自动推进)
|
||||
func on_continue() -> void:
|
||||
_close_modal.call(curio_overlay)
|
||||
curio_overlay.close_pick()
|
||||
ctx.flow.close_modal.call(ctx.views.curio_overlay)
|
||||
ctx.views.curio_overlay.close_pick()
|
||||
var adventure = _adventure_get.call()
|
||||
if _curio_context == "feat_ticket":
|
||||
return # T5 店内专长凭证面——专长兑付完成后关面回店(无推进/无回图)
|
||||
if _curio_context == "reward_node":
|
||||
var runner = _runner_get.call()
|
||||
var runner = ctx.getters.runner_get.call()
|
||||
if runner != null:
|
||||
runner.continue_after_node()
|
||||
return
|
||||
if bool(_adventure_mode_get.call()) and adventure != null:
|
||||
if bool(ctx.getters.adventure_mode_get.call()) and adventure != null:
|
||||
if not adventure.continue_to_next_level():
|
||||
_fatal_screen.call("关卡推进失败——见输出日志")
|
||||
ctx.flow.fatal_screen.call("关卡推进失败——见输出日志")
|
||||
|
||||
|
||||
# 秘宝 item_id → 显示名投影(keystone_settle_text/替换子命名文案数据源——拼句归 Narrator);
|
||||
|
||||
@@ -11,8 +11,13 @@ const Narrator := preload("res://presentation/battle_narrator.gd")
|
||||
# 每次结算行/轮次/节点变化/动作返回后调用(组合根全量重查装配)
|
||||
# 钱包 GP/钥石不在本装配面投喂(中/大循环资源迁出战斗屏——信息归属单一展示面原则);
|
||||
# HP/状态效果单投喂 B 区站桩(B/C 双投喂属重复展示——单一展示面原则)
|
||||
static func refresh(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApBarView,
|
||||
settlement, runner, level_active: bool, db, refresh_remaining: int) -> void:
|
||||
# 运行态尾参收拢 ctx 束(u19——键 {settlement, runner, level_active, db, refresh_remaining})
|
||||
static func refresh(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApBarView, ctx: Dictionary) -> void:
|
||||
var settlement = ctx.get("settlement")
|
||||
var runner = ctx.get("runner")
|
||||
var level_active: bool = ctx.get("level_active", false)
|
||||
var db = ctx.get("db")
|
||||
var refresh_remaining: int = ctx.get("refresh_remaining", 0)
|
||||
# 特性列表(runner 统一加算区投影:商店购买与关卡大奖励
|
||||
# 共账本〔level_runner bonus{atk,max_hp,armor_class}〕;空加算=整节隐藏〔视图内空态纪律〕。
|
||||
# 呈现只读投影零核心触碰;行文格式=白名单项)
|
||||
@@ -36,7 +41,7 @@ static func refresh(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApB
|
||||
info.set_feat_holdings([])
|
||||
if settlement == null:
|
||||
info.set_board_variants([]) # 战斗域角标出战斗即隐(空态纪律)
|
||||
_refresh_out_of_battle(stage, info, ap_bar, runner, level_active, db)
|
||||
_refresh_out_of_battle(stage, info, ap_bar, ctx)
|
||||
return
|
||||
var s: Dictionary[Variant, Variant] = settlement.presentation_snapshot()
|
||||
# 地形变异常驻角标投影(整图变异快照 → 文案行;
|
||||
@@ -44,7 +49,7 @@ static func refresh(stage: BattleStageView, info: HeroInfoPanelView, ap_bar: ApB
|
||||
info.set_board_variants(board_variant_lines(db, s.get("board_variants", [])))
|
||||
var hero: Dictionary[Variant, Variant] = s.hero
|
||||
if hero.is_empty() or not bool(hero.get("alive", false)):
|
||||
_refresh_out_of_battle(stage, info, ap_bar, runner, level_active, db)
|
||||
_refresh_out_of_battle(stage, info, ap_bar, ctx)
|
||||
return
|
||||
_refresh_hero(stage, info, s)
|
||||
_refresh_economy(ap_bar, s, db, refresh_remaining)
|
||||
@@ -145,7 +150,10 @@ static func sync_settlement_visuals(stage: BattleStageView, board_view: BoardVie
|
||||
|
||||
# 战斗外(节点间隙/关卡结束)——HP 读 runner 携带值
|
||||
static func _refresh_out_of_battle(stage: BattleStageView, info: HeroInfoPanelView,
|
||||
ap_bar: ApBarView, runner, level_active: bool, db) -> void:
|
||||
ap_bar: ApBarView, ctx: Dictionary) -> void:
|
||||
var runner = ctx.get("runner")
|
||||
var level_active: bool = ctx.get("level_active", false)
|
||||
var db = ctx.get("db")
|
||||
if not level_active:
|
||||
return
|
||||
if runner != null:
|
||||
@@ -185,7 +193,14 @@ static func outcome_text(outcome: Dictionary) -> String:
|
||||
|
||||
# ---- 批量模拟报告装配(文案归 presenter——视图只 set_text) ----
|
||||
|
||||
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:
|
||||
## 统计束收拢(u19——stats 六键 {wins, dmg_all, hp_left_win, hp_boss, rounds_all, death_nodes})
|
||||
static func tune_sim_report(n: int, atk_pct: int, hp_pct: int, stats: Dictionary, base_hp: int) -> String:
|
||||
var wins: int = stats.get("wins", 0)
|
||||
var dmg_all: Array = stats.get("dmg_all", [])
|
||||
var hp_left_win: Array = stats.get("hp_left_win", [])
|
||||
var hp_boss: Array = stats.get("hp_boss", [])
|
||||
var rounds_all: Array = stats.get("rounds_all", [])
|
||||
var death_nodes: Dictionary = stats.get("death_nodes", {})
|
||||
var lines: Array[String] = []
|
||||
lines.append("[b]模拟 N=%d(atk+%d%% / hp+%d%%)[/b]" % [n, atk_pct, hp_pct])
|
||||
lines.append("关卡完成率 [color=#%s]%.0f%%[/color](%d/%d)" % [UiKit.HEX_LOG_WIN, 100.0 * float(wins) / float(maxi(1, n)), wins, n])
|
||||
|
||||
@@ -816,7 +816,7 @@ func _refresh_used_snapshot() -> int:
|
||||
func _refresh_presentations() -> void:
|
||||
# 每个核心信号/写调用返回后的全量重查装配(更新触发注记——无推送信号,命令式重查)
|
||||
var refresh_remaining: int = maxi(0, int(db.run.action_economy.refresh_cap_per_round) - _refresh_used_snapshot())
|
||||
HudPresenter.refresh(stage, info_panel, ap_bar, run_scope.settlement, run_scope.runner, run_scope.level_active, db, refresh_remaining)
|
||||
HudPresenter.refresh(stage, info_panel, ap_bar, {"settlement": run_scope.settlement, "runner": run_scope.runner, "level_active": run_scope.level_active, "db": db, "refresh_remaining": refresh_remaining})
|
||||
_treasure_ui.refresh_slots() # C 区秘宝槽重查(试炼镐积点进度随挖格刷新悬停浮窗)
|
||||
_sync_settlement_visuals()
|
||||
|
||||
|
||||
@@ -134,11 +134,17 @@ static func _build_curio(root: Variant) -> void:
|
||||
root.add_child(root.curio_overlay)
|
||||
# 提升三选一与替换子交互(本体在 curio_interact_controller.gd;本类只接线与回调注入,
|
||||
# 模态栈/演播后排窗/呈现刷新/fatal 经回调注入,adventure/runner 现值回调)
|
||||
root._bonus = CurioInteractController.new(CurioFlowContext.new(root.db, func() -> Variant: return root.meta, root.curio_overlay, root._end_overlay, root.board_view,
|
||||
root.board_zone.toast, func() -> Variant: return root.save_manager, func() -> Variant: return root.run_scope.adventure,
|
||||
func() -> Variant: return root.run_scope.runner, func() -> Variant: return root.run_scope.is_adventure,
|
||||
root._open_modal, root._open_modal_after_playback, root._close_modal, root._refresh_presentations,
|
||||
root._fatal_screen, func() -> String: return root._gp_summary_text({"gp_dropped": root.run_scope.last_gain_amount}))) # 构造参数收拢 context
|
||||
root._bonus = CurioInteractController.new(CurioFlowContext.new(root.db,
|
||||
{"curio_overlay": root.curio_overlay, "end_overlay": root._end_overlay,
|
||||
"board_view": root.board_view, "toast": root.board_zone.toast},
|
||||
{"meta_get": func() -> Variant: return root.meta, "save_get": func() -> Variant: return root.save_manager,
|
||||
"adventure_get": func() -> Variant: return root.run_scope.adventure,
|
||||
"runner_get": func() -> Variant: return root.run_scope.runner,
|
||||
"adventure_mode_get": func() -> Variant: return root.run_scope.is_adventure},
|
||||
{"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": 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)
|
||||
@@ -154,9 +160,13 @@ static func _build_menu_wiring(root: Variant) -> void:
|
||||
root.debug_badge.pressed.connect(root._on_debug_badge_pressed)
|
||||
# 营地/商店投影(本体在 camp_shop_presenter.gd;本类只接线、探针缝保缝转发;
|
||||
# 购买写调用唯一经 MetaProgression/LevelRunner core 单口——组合根 lambda 现值注入)
|
||||
root._camp_pres = CampShopPresenter.new(CampFlowContext.new(root.db, func() -> Variant: return root.meta, func() -> Variant: return root.save_manager, root.camp_overlay, root.shop_overlay,
|
||||
root.board_zone.toast, root._start_overlay, root.logger, func() -> Variant: return root.run_scope.runner,
|
||||
root._open_modal, root._close_modal, root._refresh_presentations)) # 构造参数收拢 context
|
||||
root._camp_pres = CampShopPresenter.new(CampFlowContext.new(root.db,
|
||||
{"camp_overlay": root.camp_overlay, "shop_overlay": root.shop_overlay,
|
||||
"toast": root.board_zone.toast, "start_overlay": root._start_overlay, "logger": root.logger},
|
||||
{"meta_get": func() -> Variant: return root.meta, "save_get": func() -> Variant: return root.save_manager,
|
||||
"runner_get": func() -> Variant: return root.run_scope.runner},
|
||||
{"open_modal": root._open_modal, "close_modal": root._close_modal,
|
||||
"refresh_presentations": root._refresh_presentations})) # 构造参数收拢 context(u21 三束)
|
||||
root.shop_overlay.buy_requested.connect(root._camp_pres.on_shop_buy)
|
||||
root.shop_overlay.refresh_requested.connect(root._camp_pres.on_shop_refresh) # MC-1
|
||||
root.shop_overlay.leave_pressed.connect(root._camp_pres.on_shop_leave)
|
||||
|
||||
@@ -157,8 +157,6 @@ func dump_diagnosis(context: Dictionary) -> String:
|
||||
if f != null:
|
||||
f.store_string(JSON.stringify(dump, " "))
|
||||
f.close()
|
||||
print("[playtest_logger] 诊断转储已写入: %s(项目日志目录见输出)" % path)
|
||||
print(" [diag] %s" % JSON.stringify(context))
|
||||
return path
|
||||
|
||||
|
||||
|
||||
@@ -39,32 +39,30 @@ func run(n: int) -> void:
|
||||
# 一文件多局,run 行携带种子切分局次)
|
||||
var logger = PlaytestLogger.new()
|
||||
logger.ap_per_round = int(db.run.action_economy.ap_per_round)
|
||||
var log_path: String = logger.start_session(SEED_BASE)
|
||||
print("[tune_sim] 模拟日志: %s" % log_path)
|
||||
logger.start_session(SEED_BASE)
|
||||
panel.set_sim_running(true)
|
||||
panel.set_sim_progress("模拟中:0/%d …" % n)
|
||||
var wins := 0
|
||||
var dmg_all: Array[float] = []
|
||||
var hp_left_win: Array[float] = []
|
||||
var hp_boss: Array[float] = []
|
||||
var rounds_all: Array[int] = []
|
||||
var death_nodes := {}
|
||||
var stats := {"wins": 0, "dmg_all": [], "hp_left_win": [], "hp_boss": [], "rounds_all": [], "death_nodes": {}}
|
||||
var autoplay = _autoplay()
|
||||
for i in range(n):
|
||||
var st = autoplay.run_level(db, SEED_BASE + i, 1, panel.atk_pct(), panel.hp_pct(), false, logger)
|
||||
dmg_all.append(st.hero_dmg)
|
||||
rounds_all.append(st.rounds)
|
||||
if st.result == "victory":
|
||||
wins += 1
|
||||
hp_left_win.append(st.hp_left)
|
||||
hp_boss.append(st.hp_at_boss)
|
||||
elif st.result == "defeat":
|
||||
var key := "%d.%s" % [st.defeat_node_index, st.defeat_node_type]
|
||||
death_nodes[key] = int(death_nodes.get(key, 0)) + 1
|
||||
_run_one_level(autoplay, stats, i, panel, logger)
|
||||
panel.set_sim_progress("模拟中:%d/%d …" % [i + 1, n])
|
||||
await panel.get_tree().process_frame
|
||||
logger.close_session()
|
||||
panel.set_sim_report(HudPresenter.tune_sim_report(n, panel.atk_pct(), panel.hp_pct(),
|
||||
wins, dmg_all, hp_left_win, hp_boss, rounds_all, death_nodes, _base_hp))
|
||||
panel.set_sim_report(HudPresenter.tune_sim_report(n, panel.atk_pct(), panel.hp_pct(), stats, _base_hp))
|
||||
|
||||
|
||||
## 单局模拟域(循环体提函数——结果四桶记账;u19 stats 六键同构承载)
|
||||
func _run_one_level(autoplay, stats: Dictionary, i: int, panel, logger) -> void:
|
||||
var st = autoplay.run_level(db, SEED_BASE + i, 1, panel.atk_pct(), panel.hp_pct(), false, logger)
|
||||
(stats["dmg_all"] as Array).append(st.hero_dmg)
|
||||
(stats["rounds_all"] as Array).append(st.rounds)
|
||||
if st.result == "victory":
|
||||
stats["wins"] = int(stats["wins"]) + 1
|
||||
(stats["hp_left_win"] as Array).append(st.hp_left)
|
||||
(stats["hp_boss"] as Array).append(st.hp_at_boss)
|
||||
elif st.result == "defeat":
|
||||
var key := "%d.%s" % [st.defeat_node_index, st.defeat_node_type]
|
||||
stats["death_nodes"][key] = int(stats["death_nodes"].get(key, 0)) + 1
|
||||
panel.set_sim_running(false)
|
||||
_running = false
|
||||
Reference in new issue
Block a user