Complete remaining client gap features

This commit is contained in:
shenlei
2026-09-04 13:25:05 +09:00
parent 13ccb8d02d
commit 9a4a044da5
47 changed files with 6667 additions and 140 deletions
+106
View File
@@ -0,0 +1,106 @@
# DungeonResultUI —— CPythonEventManager::ShowDungeonResult 的轻量 Godot 载体。
#
# 参考端收到 [DUNGEON_RESULT] 后直接调用 interface.ShowDungeonResult,并把
# 九个整数交给独立结算窗口。本组件只负责呈现这九个服务端字段,不修改副本
# 状态,也不凭空发奖励;奖励仍由网络协议驱动。
extends Node
const RESULT_KEYS := [
"killstone_count", "killmob_count", "find_hidden", "hidden_total",
"use_potion", "is_revived", "killallmob", "total_time", "bonus_exp",
]
var _root: Control
var _rows: VBoxContainer
var _result: Dictionary = {}
func setup(parent: Node) -> void:
if _root != null:
return
_root = Control.new()
_root.name = "DungeonResult"
_root.set_anchors_preset(Control.PRESET_CENTER)
_root.position = Vector2(-190, -175)
_root.size = Vector2(380, 350)
_root.visible = false
_root.mouse_filter = Control.MOUSE_FILTER_STOP
_root.z_index = 120
parent.add_child(_root)
var panel := Panel.new()
panel.set_anchors_preset(Control.PRESET_FULL_RECT)
var style := StyleBoxFlat.new()
style.bg_color = Color(0.055, 0.045, 0.035, 0.98)
style.border_color = Color(0.78, 0.62, 0.30, 1.0)
style.set_border_width_all(2)
style.set_corner_radius_all(6)
panel.add_theme_stylebox_override("panel", style)
_root.add_child(panel)
var title := Label.new()
title.text = "副本结算"
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
title.position = Vector2(16, 14)
title.size = Vector2(348, 32)
title.add_theme_font_size_override("font_size", 20)
_root.add_child(title)
_rows = VBoxContainer.new()
_rows.position = Vector2(34, 58)
_rows.size = Vector2(312, 218)
_rows.add_theme_constant_override("separation", 5)
_root.add_child(_rows)
var close_button := Button.new()
close_button.text = "关闭"
close_button.position = Vector2(130, 300)
close_button.size = Vector2(120, 32)
close_button.pressed.connect(close)
_root.add_child(close_button)
func show_result(result: Dictionary) -> void:
if _root == null:
return
_result = result.duplicate(true)
for child in _rows.get_children():
child.queue_free()
for spec in _display_rows():
var row := Label.new()
row.text = str(spec[0]) + "" + str(spec[1])
row.add_theme_font_size_override("font_size", 14)
_rows.add_child(row)
_root.visible = true
func open(result: Dictionary) -> void:
show_result(result)
func close() -> void:
if _root:
_root.visible = false
func is_open() -> bool:
return _root != null and _root.visible
func result() -> Dictionary:
return _result.duplicate(true)
func _display_rows() -> Array:
var elapsed := maxi(0, int(_result.get("total_time", 0)))
var mins := elapsed / 60
var secs := elapsed % 60
return [
["击杀石碑", int(_result.get("killstone_count", 0))],
["击杀怪物", int(_result.get("killmob_count", 0))],
["隐藏目标", "%d / %d" % [int(_result.get("find_hidden", 0)), int(_result.get("hidden_total", 0))]],
["使用药水", int(_result.get("use_potion", 0))],
["复活次数", int(_result.get("is_revived", 0))],
["完成条件", "已完成" if int(_result.get("killallmob", 0)) != 0 else "未完成"],
["用时", "%02d:%02d" % [mins, secs]],
["奖励经验", int(_result.get("bonus_exp", 0))],
]
func _unhandled_input(event: InputEvent) -> void:
if is_open() and event is InputEventKey and event.pressed \
and not event.echo and event.keycode == KEY_ESCAPE:
close()
get_viewport().set_input_as_handled()