feat: 三选一刷新对齐商店(2026-10-06 用户令)——免费双源 X/Y 用尽后 GP 付费档(同 shop_refresh_* 旋钮/同冒险钱包 spend_gp 单口/同 reward_pick 池重抽),付费刷计数每停点清零;CurioPickOverlay.set_refresh_display 与商店同构(钮常驻选择态/两源皆穷禁用/角标免费余量/价签行 GP 价);通关停点刷新重发带 refreshed 标直落选择面不再重开胜利总结;店内门票专长三选一维持无刷新;单测 curio_refresh_paid_test+覆盖层刷新面断言;落文=秘宝.md 双源节 GP 付费档+冒险结构 v0.16+06 商店刷新条目换代(机制已落码态)
This commit is contained in:
1 parent
ced5fb75c3
commit
12807298eb
11 files changed
+185
-30
No files matched your search
@@ -112,8 +112,9 @@ func on_presented(payload: Dictionary) -> void:
|
||||
toast.show_toast("上关剩余 %d 件秘宝已随关卡结束清空" % int(payload.get("aux_cleared", 0)), "info") # 迭代 7 T4 清空反馈
|
||||
_pending_curio = payload.duplicate(true)
|
||||
_curio_context = "level_clear"
|
||||
if bool(payload.get("replace_pending", false)):
|
||||
if bool(payload.get("replace_pending", false)) or bool(payload.get("refreshed", false)):
|
||||
# 续玩:替换子交互在途中断——重建三选一面后直落替换子态(候选不重抽)
|
||||
# 刷新重发(2026-10-06):refreshed 标直落选择面——不再重开胜利总结面
|
||||
show_pick()
|
||||
return
|
||||
end_overlay.open_victory(Narrator.battle_end_text("victory", false), "继续",
|
||||
@@ -142,7 +143,7 @@ func present_node_curio() -> void:
|
||||
_open_modal.call(curio_overlay)
|
||||
curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(node_cands, node_draw.get("aux_detail", []) as Array))
|
||||
adventure.present_node_curio(node_cands, node_draw.get("aux_detail", []) as Array)
|
||||
curio_overlay.set_refresh_info(adventure.attune_refresh_left()) # 迭代 11 第①批 T5b——刷新余量投喂
|
||||
_feed_refresh_display(adventure) # 迭代 11 第①批 T5b + 2026-10-06 对齐商店——刷新面投喂单点
|
||||
|
||||
|
||||
# 三选一面开出(战斗总结结算确认 / 续玩停点恢复;替换在途由 treasure_replace_presented 续发直落子态)
|
||||
@@ -151,10 +152,19 @@ func show_pick() -> void:
|
||||
_open_modal.call(curio_overlay)
|
||||
curio_overlay.open_pick(Narrator.curio_pick_header(payload), _curio_card_texts(payload.get("candidates", []) as Array, payload.get("aux_detail", []) as Array))
|
||||
var adventure = _adventure_get.call()
|
||||
curio_overlay.set_refresh_info(adventure.attune_refresh_left() if adventure != null else 0) # 迭代 11 第①批 T5b——刷新余量投喂
|
||||
if adventure != null:
|
||||
_feed_refresh_display(adventure) # 迭代 11 第①批 T5b + 2026-10-06 对齐商店——刷新面投喂单点
|
||||
_refresh_presentations.call()
|
||||
|
||||
|
||||
# 刷新呈现投喂单点(免费余量 X/Y + GP 付费价 + 冒险钱包可付——读数与商店 set_refresh_display 同构)
|
||||
func _feed_refresh_display(adventure) -> void:
|
||||
var runner = _runner_get.call()
|
||||
var gp := int(runner.gp) if runner != null else 0
|
||||
var cost: int = adventure.curio_refresh_gp_cost()
|
||||
curio_overlay.set_refresh_display(adventure.attune_refresh_left(), cost, gp >= cost)
|
||||
|
||||
|
||||
func _curio_card_texts(candidates: Array, treasure_detail: Array = []) -> Array:
|
||||
# TP0 令牌池——候选 = {"kind","tier"} 令牌字典;卡片 id = "kind|tier|feat_id" 复合键(同 kind
|
||||
# 大小两档/同档多 relic 可同屏,kind 单键不构成唯一身份),确认回程拆键(on_pick_confirmed)
|
||||
@@ -204,18 +214,29 @@ func _treasure_card_line(iid: String) -> String:
|
||||
return "%s · %s" % [String(row.get("display_name", iid)), " ".join(parts)]
|
||||
|
||||
|
||||
# 三选一刷新(迭代 11 第①批 T5b——P1 甲 X/Y 双源;通关停点经重发 curio_choice_presented 自然重建,
|
||||
# 节点停点在此读在途态重 present——零自动推进契约不破,停点仍在途)
|
||||
# 三选一刷新(迭代 11 第①批 T5b X/Y 双源 + 2026-10-06 用户令对齐商店 MC-1——免费位用尽转 GP 付费档:
|
||||
# 同 shop_refresh_cost_base/curve 旋钮、同冒险钱包 runner.gp;通关停点经重发 curio_choice_presented 直落
|
||||
# 选择面,节点停点在此读在途态重 present——零自动推进契约不破,停点仍在途)
|
||||
func on_refresh() -> void:
|
||||
var adventure = _adventure_get.call()
|
||||
if adventure == null:
|
||||
if adventure == null or not adventure.curio_stop_pending():
|
||||
return
|
||||
if not adventure.refresh_curio():
|
||||
var runner = _runner_get.call()
|
||||
var refreshed: bool = adventure.refresh_curio()
|
||||
if not refreshed:
|
||||
# 免费位(X/Y)已穷——GP 付费档(先扣钱包后重抽,余额不足拒绝零副作用)
|
||||
var cost: int = adventure.curio_refresh_gp_cost()
|
||||
if runner == null or not runner.spend_gp(cost):
|
||||
toast.show_toast("金币不足——刷新失败", "warn")
|
||||
return
|
||||
refreshed = adventure.refresh_curio_paid()
|
||||
_refresh_presentations.call() # 钱包变化上屏(对齐商店购买后刷新面)
|
||||
if not refreshed:
|
||||
return
|
||||
if _curio_context == "reward_node":
|
||||
var st: Dictionary = adventure.node_curio_pending_state()
|
||||
curio_overlay.open_pick(Narrator.node_curio_header(), _curio_card_texts(st.get("candidates", []) as Array, st.get("aux_detail", []) as Array))
|
||||
curio_overlay.set_refresh_info(adventure.attune_refresh_left())
|
||||
_feed_refresh_display(adventure)
|
||||
|
||||
|
||||
func on_pick_confirmed(item_id: String) -> void:
|
||||
|
||||
@@ -20,7 +20,8 @@ var _continue_btn: Button # 继续钮(兑付反馈态唯一
|
||||
var _refresh_btn: Button # 刷新钮(迭代 11 第①批 T5b——余量>0 才显示;M7 升顶条图标钮)
|
||||
var _refresh_badge: Label # M7 余量角标(图标钮右上——demo ⑥ 同构)
|
||||
var _refresh_l: Label # 刷新余量读数(X 优先 + Y 冒险池)
|
||||
var _refresh_allowance := 0 # 组合根投喂余量(本视图零核心引用)
|
||||
var _refresh_allowance := 0 # 组合根投喂免费余量(X/Y——本视图零核心引用)
|
||||
var _refresh_gp_cost := 0 # 组合根投喂 GP 刷新价(免费位用尽后的付费档读数)
|
||||
var _selected := "" # 点选暂存(确认前可改选)
|
||||
var _header := "" # 停点头部文案(选择态保持显示)
|
||||
var _card_meta: Array = [] # open_pick 缓存 [{id, text}]——高亮还原读面
|
||||
@@ -105,18 +106,22 @@ func open_pick(header: String, cards: Array) -> void:
|
||||
_confirm_btn.visible = false
|
||||
_replace_box.visible = false
|
||||
_continue_btn.visible = false
|
||||
_refresh_btn.visible = false # 刷新余量随 set_refresh_info 投喂后现形(open 先归零防残留)
|
||||
_refresh_btn.visible = false # 刷新面随 set_refresh_display 投喂后现形(open 先归零防残留;店内门票面不投喂=无刷新)
|
||||
_refresh_l.text = ""
|
||||
visible = true
|
||||
|
||||
|
||||
# 三选一刷新余量投喂(组合根读 adventure.attune_refresh_left()——0 = 刷新面隐藏)
|
||||
func set_refresh_info(allowance: int) -> void:
|
||||
_refresh_allowance = maxi(0, int(allowance))
|
||||
_refresh_btn.visible = _refresh_allowance > 0
|
||||
# 三选一刷新呈现投喂(2026-10-06 用户令对齐商店 MC-1 同构——free_left=X/Y 免费位余量〔基础 0〕,
|
||||
# 免费位用尽转 GP 付费档:gp_cost=本次 GP 刷新价、can_afford=冒险钱包可付;钮常驻选择态,两源皆穷=禁用不隐藏)
|
||||
func set_refresh_display(free_left: int, gp_cost: int, can_afford: bool) -> void:
|
||||
_refresh_allowance = maxi(0, int(free_left))
|
||||
_refresh_gp_cost = maxi(0, int(gp_cost))
|
||||
_refresh_btn.visible = _refresh_allowance > 0 or _refresh_gp_cost > 0
|
||||
_refresh_badge.text = str(_refresh_allowance)
|
||||
_refresh_l.text = "免费 · 不消耗 AP" if _refresh_allowance > 0 else ""
|
||||
_refresh_l.visible = _refresh_allowance > 0
|
||||
_refresh_l.text = "免费 · 不消耗 AP" if _refresh_allowance > 0 else ("刷新 %d 金币" % _refresh_gp_cost if _refresh_gp_cost > 0 else "")
|
||||
_refresh_l.visible = _refresh_l.text != ""
|
||||
_refresh_btn.tooltip_text = "刷新候选——换一批战利品\n免费 %d 次(刷新件 X 优先 + 冒险池 Y)\nGP 刷新 %d 金币\n池源=共享池,与商店货架同源" % [_refresh_allowance, _refresh_gp_cost]
|
||||
_refresh_btn.disabled = _refresh_allowance <= 0 and not can_afford
|
||||
|
||||
|
||||
func _emit_refresh_requested() -> void:
|
||||
@@ -152,6 +157,11 @@ func press_continue() -> void:
|
||||
_continue_btn.pressed.emit()
|
||||
|
||||
|
||||
# 探针/测试复用:以真实按钮路径触发刷新意图(信号外发——受理归组合根)
|
||||
func press_refresh() -> void:
|
||||
_refresh_btn.pressed.emit()
|
||||
|
||||
|
||||
func selected_id() -> String:
|
||||
return _selected
|
||||
|
||||
@@ -163,6 +173,7 @@ func show_result(text: String) -> void:
|
||||
_confirm_btn.visible = false
|
||||
_replace_box.visible = false
|
||||
_continue_btn.visible = true
|
||||
_refresh_btn.visible = false # 刷新=选择态专属功能(结果态停点已兑付——残钮零意图可点)
|
||||
visible = true
|
||||
|
||||
|
||||
@@ -184,6 +195,7 @@ func open_replace(items: Array, incoming_name: String, holding: int, slots: int)
|
||||
_confirm_btn.visible = false
|
||||
_replace_box.visible = true
|
||||
_continue_btn.visible = false
|
||||
_refresh_btn.visible = false # 刷新=选择态专属功能(替换子态不换候选)
|
||||
visible = true
|
||||
|
||||
|
||||
@@ -193,6 +205,7 @@ func close_pick() -> void:
|
||||
_replace_box.visible = false
|
||||
_continue_btn.visible = false
|
||||
_confirm_btn.visible = false
|
||||
_refresh_btn.visible = false
|
||||
visible = false
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user