Files
mtgodot-poc/project/ui/refine_ui.gd
T
shenleiandClaude Sonnet 5 f32064c74a 40250 classic: parallel-dev checkpoint through increment 49 (W0 interface freeze)
Captures the uncommitted parallel-development work (increments 46-49) on the
40250 classic client port, folded into docs/CLIENT-GAP.md + CLIENT-GAP-FIX.md.

Increment 49 (W0 interface-freeze batch, Phase 1 prerequisite) lands the
cross-workflow shared-file scaffolding so the 4 Phase 1 workflows can run in
isolated worktrees without contention:

- entity_store.{h,cpp}: Entity gains empire/affect_flags/owner_vid/state_flags;
  new mut_spawn_full() (single-shot two-packet merge, §2.3), mut_ownership()
  (§2.5), mut_map_bgm() + take_bgm_dirty()/bgm_name()/bgm_volume() (§9.1),
  drain_dirty() (§2.1/§2.5 bare-field-update queue); mut_char_info() now stores
  empire; reset_for_map_change() clears m_dirty.
- m2_client.cpp: new bgm_changed(name, volume) signal; classic + m2dev pump
  loops drain drain_dirty() -> entity_info and take_bgm_dirty() -> bgm_changed;
  entity_dict() exposes the 4 new keys.
- classic/classic_parser.{h,cpp}: GC_MAIN_CHARACTER3_BGM /
  GC_MAIN_CHARACTER4_BGM_VOL route bgm_name/bgm_volume to mut_map_bgm() (was
  discarded); new m_pending_actor staging map (W1 fills §2.2 merge logic).
- project/bgm_director.gd (new) + game_scene.gd: BGM consumption split out of
  net_world.gd so W2/W4 don't collide; §8.6/§4.8 keybind convergence (digits
  1-4 -> quickslots 0-3, F1-F4 -> quickslots 4-7, Ctrl+1..9 -> _emote()).

Tests: cmake --build build clean; ctest 16/16; 15 GDScript regressions green
(netbridge, gamescene, netplay, p9, p10, p2b, p8, system_menu_ui, skill,
combat_fx, skill_fx, player_motion, char_status_ui, chat, inventory), no skips.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014yvAPqPivoY7vmBbzgqK4W
2026-09-02 15:13:01 +09:00

107 lines
3.3 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RefineUI (M4) —— 精炼 / 强化对话框:`refine_ask` 来时弹。
#
# var ru := preload("res://ui/refine_ui.gd").new()
# add_child(ru)
# ru.setup(m2client, canvas_parent, proto) # proto 可空(出名字)
#
# `GC_REFINE_INFORMATION` → `M2Client.refine_ask({type,pos,src_vnum,result_vnum,cost,prob,materials})`。
# [精炼] → `M2Client.refine(pos, type)`[取消] 关闭。
extends Node
var client: Node
var proto: Node
var _root: Control
var _text: RichTextLabel
var _cur := {}
func setup(m2client: Node, parent: Node, proto_node: Node = null) -> void:
client = m2client
proto = proto_node
_build(parent)
if client.has_signal("refine_ask"):
client.refine_ask.connect(_on_ask)
if client.has_signal("refine_result"):
client.refine_result.connect(_on_result)
func is_open() -> bool:
return _root != null and _root.visible
func close() -> void:
if _root:
_root.visible = false
_cur = {}
func _name_of(vnum: int) -> String:
if vnum == 0:
return "-"
if proto and proto.has_method("item"):
var d: Dictionary = proto.item(vnum)
var n := String(d.get("locale_name", d.get("name", "")))
if n != "":
return n
return "#%d" % vnum
func _on_ask(info: Dictionary) -> void:
_cur = info
var lines := PackedStringArray()
lines.append("[b]%s[/b] → [b]%s[/b]" % [
_name_of(int(info.get("src_vnum", 0))), _name_of(int(info.get("result_vnum", 0)))])
lines.append("成功率 %d%% 费用 %d 金" % [int(info.get("prob", 0)), int(info.get("cost", 0))])
var mats: Array = info.get("materials", [])
if not mats.is_empty():
lines.append("材料:")
for m in mats:
lines.append(" %s ×%d" % [_name_of(int(m.get("vnum", 0))), int(m.get("count", 1))])
_text.text = "\n".join(lines)
_root.visible = true
func _do_refine() -> void:
if client and client.has_method("refine") and not _cur.is_empty():
client.refine(int(_cur.get("pos", 0)), int(_cur.get("type", 0)))
_root.visible = false
func _on_result(ok: bool) -> void:
_cur = {}
_text.text = "[b]精炼成功[/b]" if ok else "[b]精炼失败[/b]"
_root.visible = true
func _build(parent: Node) -> void:
_root = Control.new()
_root.set_anchors_preset(Control.PRESET_CENTER)
_root.position = Vector2(-160, -130)
_root.size = Vector2(320, 260)
_root.visible = false
_root.set_meta("is_titlebar", true)
parent.add_child(_root)
var panel := Panel.new()
panel.set_anchors_preset(Control.PRESET_FULL_RECT)
var sb := StyleBoxFlat.new()
sb.bg_color = Color(0.09, 0.07, 0.05, 0.98)
sb.set_corner_radius_all(4)
panel.add_theme_stylebox_override("panel", sb)
_root.add_child(panel)
var title := Label.new()
title.text = "精炼"
title.position = Vector2(12, 8)
_root.add_child(title)
_text = RichTextLabel.new()
_text.bbcode_enabled = true
_text.position = Vector2(14, 34)
_text.custom_minimum_size = Vector2(292, 160)
_text.size = Vector2(292, 160)
_root.add_child(_text)
var row := HBoxContainer.new()
row.position = Vector2(14, 208)
row.add_theme_constant_override("separation", 12)
_root.add_child(row)
var ok := Button.new()
ok.text = "精炼"
ok.custom_minimum_size = Vector2(120, 30)
ok.pressed.connect(_do_refine)
row.add_child(ok)
var cancel := Button.new()
cancel.text = "取消"
cancel.custom_minimum_size = Vector2(120, 30)
cancel.pressed.connect(func(): _root.visible = false)
row.add_child(cancel)