Complete remaining client gap features
This commit is contained in:
+91
-2
@@ -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 黄字 Label3D(SetItemTextTailOwner)
|
||||
# + 名字实例下移 15px(ArrangeTextTail :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")):
|
||||
|
||||
Reference in New Issue
Block a user