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
+91 -2
View File
@@ -4,6 +4,7 @@ extends SceneTree
const GroundItems = preload("res://ui/ground_items.gd")
const PlayerView = preload("res://ui/player_view.gd")
const TextTailArrange = preload("res://text_tail_arrange.gd")
class FakeClient extends Node:
signal ground_item_added(item: Dictionary)
@@ -12,8 +13,10 @@ class FakeClient extends Node:
var picked := []
func get_ground_items() -> Array: return ground.values()
func pickup_item(vid) -> bool: picked.append(vid); return true
func add_ground(vid, vnum, pos):
ground[vid] = {"vid": vid, "vnum": vnum, "pos": pos}
func add_ground(vid, vnum, pos, owner := "", item_color: Variant = null):
ground[vid] = {"vid": vid, "vnum": vnum, "pos": pos, "owner": owner}
if item_color != null:
ground[vid]["item_color"] = item_color
ground_item_added.emit(ground[vid])
func del_ground(vid):
ground.erase(vid); ground_item_removed.emit(vid)
@@ -74,6 +77,92 @@ func _run() -> void:
# 远处的捡不到
_ck(gi.try_pickup() == 0, "far item not picked")
# --- §8.8 seam ⑩:多条名条投影后去重叠(ArrangeTextTail item 块)---------------
# 独立的 mount / FakeClient,避免与上面的 gi 抢同名 drop 节点。
var mount2 := Node3D.new()
var fc2 := FakeClient.new()
get_root().add_child(mount2)
get_root().add_child(fc2)
var cam := Camera3D.new()
get_root().add_child(cam)
cam.position = Vector3(0, 3, 6)
cam.look_at(Vector3.ZERO, Vector3.UP)
cam.current = true
var gi2: Node = GroundItems.new()
get_root().add_child(gi2)
gi2.setup(fc2, mount2, func() -> Node: return pl, fp, null, func() -> Camera3D: return cam)
# 单条:名条留默认局部 y。
fc2.add_ground(201, 27, Vector3(0, 0, 0))
await process_frame
gi2._process(0.0)
var t201 := mount2.get_node("drop_201").get_node("tag") as Label3D
_ck(absf(t201.position.y - gi2.TAG_BASE_Y) < 0.0001, "单条名条 -> 留默认局部 y 0.75")
# 同位两条:靠前的(vid 小,m_ItemTextTailList 先)被顶下去,靠后的留原位。
fc2.add_ground(202, 28, Vector3(0, 0, 0))
await process_frame
gi2._process(0.0)
var t202 := mount2.get_node("drop_202").get_node("tag") as Label3D
_ck(t201.position.y < gi2.TAG_BASE_Y - 0.0001, "重叠 -> 靠前名条被下推(世界 y 变小)")
_ck(absf(t202.position.y - gi2.TAG_BASE_Y) < 0.0001, "重叠 -> 靠后名条留默认")
# 被下推量 = (h + gap) px 折世界:(15 + 5) * pixel_size(0.005) = 0.1。
_ck(absf(t201.position.y - (gi2.TAG_BASE_Y - (gi2.TAG_LINE_H_PX + TextTailArrange.PUSH_GAP) * t201.pixel_size)) < 0.0001,
"下推量 = (TAG_LINE_H_PX + PUSH_GAP) * pixel_size = 0.1")
_ck(absf(t201.position.y - t202.position.y) > 0.0001, "两名条错开后局部 y 不同")
# 远离:把 202 挪远,重跑 -> 两条都回默认。
mount2.get_node("drop_202").position = Vector3(-40, 0, -2)
gi2._process(0.0)
_ck(absf(t201.position.y - gi2.TAG_BASE_Y) < 0.0001, "拉开距离 -> 201 名条回默认")
_ck(absf(t202.position.y - gi2.TAG_BASE_Y) < 0.0001, "拉开距离 -> 202 名条回默认")
# --- §8.8 seam ⑩ 末尾:owner 拆成独立 CENTER 黄字 Label3DSetItemTextTailOwner
# + 名字实例下移 15pxArrangeTextTail :200);框仍 yEnd += ownerH + 4(增量 125---
var mount3 := Node3D.new()
var fc3 := FakeClient.new()
get_root().add_child(mount3)
get_root().add_child(fc3)
var gi3: Node = GroundItems.new()
get_root().add_child(gi3)
gi3.setup(fc3, mount3, func() -> Node: return pl, fp, null, func() -> Camera3D: return cam)
fc3.add_ground(301, 27, Vector3(0, 0, 0)) # 靠前、无 owner
var owner_color := Color(0.25, 0.75, 1.0)
fc3.add_ground(302, 28, Vector3(0, 0, 0), "Alice", owner_color) # 靠后、有 owner
await process_frame
gi3._process(0.0)
var d301 := mount3.get_node("drop_301")
var d302 := mount3.get_node("drop_302")
var t301 := d301.get_node("tag") as Label3D
var t302 := d302.get_node("tag") as Label3D
# owner 拆成独立 owner_tag:名字实例只放名字,owner_tag 放 "Alice" + "'s"(黄 / CENTER)。
_ck(t302.text == "掉落28", "名字实例只放名字(owner 后缀不再拼串,:723)")
_ck(d301.get_node_or_null("owner_tag") == null, "无 owner 的掉落不建 owner_tag:741-745")
var o302 := d302.get_node_or_null("owner_tag") as Label3D
_ck(o302 != null, "有 owner 的掉落建独立 owner_tag:715")
_ck(o302.text == "Alice's", "owner_tag 文本 = owner + strOwnership:722 字面 \"'s\"")
_ck(o302.horizontal_alignment == HORIZONTAL_ALIGNMENT_CENTER, "owner_tag CENTER 对齐(:727")
_ck(o302.modulate.is_equal_approx(owner_color), "owner_tag 使用道具品阶色(:729 pInsertTextTail->Color")
# owner 名条框:无字体度量时 name_h = owner_h = 15 -> yEnd = 15 + 15 + 4 = 34(增量 125 不变)。
# 靠前 301(无 owner)被顶 (34 + PUSH_GAP) px 折世界:(34 + 5) * 0.005 = 0.195。
var push_owner: float = (gi3.TAG_LINE_H_PX * 2.0 + 4.0 + TextTailArrange.PUSH_GAP) * t301.pixel_size
_ck(absf(t301.position.y - (gi3.TAG_BASE_Y - push_owner)) < 0.0001,
"靠前名条被带 owner 的框顶 (34+5)*px = 0.195")
# 靠后 302 未被推:owner 行落基点、名字行下移 15px:195 owner 在 y、:200 名字在 y+15)。
_ck(absf(o302.position.y - gi3.TAG_BASE_Y) < 0.0001, "owner_tag 落尾标基点(:195")
_ck(absf(t302.position.y - (gi3.TAG_BASE_Y - gi3.OWNER_NAME_GAP_PX * t302.pixel_size)) < 0.0001,
"名字实例在 owner 行下移 15px:200 y + 15.0f")
# --- strOwnership 经 setup(possessive) 注入(SetItemTextTailOwner :722 本地化语素)---
var mount4 := Node3D.new()
var fc4 := FakeClient.new()
get_root().add_child(mount4)
get_root().add_child(fc4)
var gi4: Node = GroundItems.new()
get_root().add_child(gi4)
gi4.setup(fc4, mount4, func() -> Node: return pl, fp, null, func() -> Camera3D: return cam, "@")
fc4.add_ground(401, 27, Vector3(0, 0, 0), "Bob")
await process_frame
var o401 := mount4.get_node("drop_401").get_node_or_null("owner_tag") as Label3D
_ck(o401 != null and o401.text == "Bob@", "setup(possessive=\"@\") -> owner_tag 文本 = \"Bob@\"")
# --- player view(有真资产才建)---
var assets := AssetRoot.path()
if not DirAccess.dir_exists_absolute(assets.path_join("PC/ymir work/pc/warrior")):