Complete remaining client gap features
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# screen_hp_bar_test —— §8.8 屏幕空间 HP 条 headless 自检。
|
||||
# godot --headless --path project --script screen_hp_bar_test.gd
|
||||
# 覆盖:不再创建 3D Sprite3D、实体血量同步、世界坐标投影、镜头后/死亡隐藏、地图清理。
|
||||
extends SceneTree
|
||||
|
||||
const NetWorld = preload("res://net_world.gd")
|
||||
const ScreenHpBar = preload("res://screen_hp_bar.gd")
|
||||
|
||||
class FakeClient extends Node:
|
||||
signal entity_spawned(entity: Dictionary)
|
||||
signal entity_despawned(vid: int)
|
||||
signal entity_moved(vid: int)
|
||||
signal entity_main_set(vid: int)
|
||||
signal entity_info(vid: int, entity: Dictionary)
|
||||
signal chat(type: int, vid: int, text: String)
|
||||
signal vitals_changed(vid: int)
|
||||
signal entity_dead(vid: int)
|
||||
signal damage(vid: int, amount: int, flag: int)
|
||||
var entities := {}
|
||||
func get_entity(vid: int) -> Dictionary: return entities.get(vid, {})
|
||||
func get_entities() -> Array: return entities.values()
|
||||
func get_pvp_relations() -> Array: return []
|
||||
func get_duel() -> Dictionary: return {}
|
||||
func add(vid: int, pos: Vector3, main := false) -> Dictionary:
|
||||
var d := {"vid": vid, "name": "e%d" % vid, "is_main": main,
|
||||
"pos": pos, "pos_cm": Vector3(pos.x * 100.0, -pos.z * 100.0, 0.0),
|
||||
"func": 0, "moving": false, "angle_deg": 0.0,
|
||||
"hp": 100, "max_hp": 100, "dead": false, "race": 0,
|
||||
"affect_flags": 0, "parts": [0, 0, 0, 0]}
|
||||
entities[vid] = d
|
||||
return d
|
||||
|
||||
var _fail := 0
|
||||
func _ck(condition: bool, message: String) -> void:
|
||||
if not condition:
|
||||
_fail += 1
|
||||
printerr("FAIL: " + message)
|
||||
|
||||
func _init() -> void:
|
||||
await _run()
|
||||
if _fail == 0:
|
||||
print("PASS: screen_hp_bar_test (§8.8 screen-space HP bar)")
|
||||
quit(0)
|
||||
else:
|
||||
printerr("%d check(s) failed" % _fail)
|
||||
quit(1)
|
||||
|
||||
func _run() -> void:
|
||||
var mount := Node3D.new()
|
||||
var client := FakeClient.new()
|
||||
var camera := Camera3D.new()
|
||||
var nw: Node = NetWorld.new()
|
||||
get_root().add_child(mount)
|
||||
get_root().add_child(client)
|
||||
get_root().add_child(camera)
|
||||
get_root().add_child(nw)
|
||||
camera.position = Vector3(0.0, 2.0, 6.0)
|
||||
camera.look_at_from_position(Vector3(0.0, 2.0, 6.0), Vector3.ZERO, Vector3.UP)
|
||||
camera.current = true
|
||||
nw.setup(client, mount)
|
||||
nw.set_camera(camera)
|
||||
client.add(1, Vector3.ZERO, true)
|
||||
client.entity_main_set.emit(1)
|
||||
nw.set_local_vid(1)
|
||||
var entity := client.add(2, Vector3.ZERO)
|
||||
client.entity_spawned.emit(entity)
|
||||
await process_frame
|
||||
await process_frame
|
||||
|
||||
var node: Node3D = nw.node_for(2)
|
||||
var bar := nw._hp_bars.get(2, null) as Control
|
||||
_ck(node != null, "remote entity exists")
|
||||
_ck(bar != null and bar is ScreenHpBar, "entity owns a screen Control HP bar")
|
||||
_ck(node.get_node_or_null("HpBar") == null, "legacy Sprite3D HpBar removed")
|
||||
_ck(bar != null and bar.visible, "front-facing living entity shows HP bar")
|
||||
if bar != null:
|
||||
var expected := camera.unproject_position(node.global_position + Vector3(0, nw.HP_BAR_WORLD_Y, 0))
|
||||
_ck(is_equal_approx(bar.position.x, expected.x - bar.size.x * 0.5),
|
||||
"bar x is centered on projected world anchor")
|
||||
_ck(is_equal_approx(bar.ratio, 1.0), "initial hp ratio = 1")
|
||||
|
||||
entity["hp"] = 25
|
||||
client.vitals_changed.emit(2)
|
||||
await process_frame
|
||||
_ck(is_equal_approx(bar.ratio, 0.25), "vitals update changes screen bar ratio")
|
||||
entity["dead"] = true
|
||||
client.vitals_changed.emit(2)
|
||||
await process_frame
|
||||
_ck(not bar.visible, "dead entity hides screen bar")
|
||||
|
||||
entity["dead"] = false
|
||||
entity["pos"] = Vector3(0, 0, -12)
|
||||
client.vitals_changed.emit(2)
|
||||
await process_frame
|
||||
_ck(not bar.visible, "entity behind camera hides screen bar")
|
||||
|
||||
nw.clear_for_map_change()
|
||||
_ck(nw._hp_bars.is_empty(), "map change clears screen bars")
|
||||
Reference in New Issue
Block a user