72 lines
2.7 KiB
GDScript
72 lines
2.7 KiB
GDScript
# dungeon_state_test —— GC_DUNGEON 目的地状态回归。
|
|
# godot --headless --path project --script dungeon_state_test.gd
|
|
extends SceneTree
|
|
|
|
const DungeonState = preload("res://dungeon_state.gd")
|
|
|
|
class FakeClient extends Node:
|
|
signal dungeon_event(subheader: int, x: int, y: int, has_destination: bool)
|
|
signal world_reset
|
|
|
|
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: dungeon_state_test (GC_DUNGEON destination / arrival / reset)")
|
|
quit(0)
|
|
else:
|
|
printerr("%d check(s) failed" % _fail)
|
|
quit(1)
|
|
|
|
func _run() -> void:
|
|
MapCoord.set_base(Vector2.ZERO)
|
|
var client := FakeClient.new()
|
|
var player := Node3D.new()
|
|
get_root().add_child(client)
|
|
get_root().add_child(player)
|
|
var state := DungeonState.new()
|
|
get_root().add_child(state)
|
|
state.setup(client, func() -> Node3D: return player)
|
|
await process_frame
|
|
var changes: Array = []
|
|
var alarms: Array = []
|
|
state.destination_changed.connect(func(active: bool, pos: Vector3): changes.append([active, pos]))
|
|
state.alarm_requested.connect(func(pos: Vector3): alarms.append(pos))
|
|
|
|
client.dungeon_event.emit(state.TIME_ATTACK_START, 0, 0, false)
|
|
_ck(not state.active and state.last_subheader == state.TIME_ATTACK_START,
|
|
"TIME_ATTACK_START is consumed without inventing a timer")
|
|
client.dungeon_event.emit(state.DESTINATION_POSITION, 3210, 6540, true)
|
|
_ck(state.active, "destination packet activates route")
|
|
_ck(state.destination_cm == Vector2(3210, 6540), "destination keeps server cm")
|
|
_ck(state.destination_world.distance_to(Vector3(32.1, 0.0, 65.4)) < 0.01,
|
|
"destination converts global cm through MapCoord")
|
|
_ck(changes.size() == 1 and changes[0][0] == true, "destination_changed opens target")
|
|
_ck(alarms.size() == 1, "destination alarms immediately")
|
|
|
|
# Reference uses Manhattan < 10000 cm, so exactly 100m is not complete and
|
|
# 99m is complete. Keep the player in the same global coordinate frame.
|
|
player.global_position = Vector3(32.1, 0.0, 65.4 - 100.0)
|
|
state._process(0.0)
|
|
_ck(state.active, "Manhattan distance exactly 100m remains active")
|
|
player.global_position = Vector3(32.1, 0.0, 65.4 - 99.0)
|
|
state._process(0.0)
|
|
_ck(not state.active, "Manhattan distance below 100m completes route")
|
|
_ck(changes.size() == 2 and changes[1][0] == false, "arrival closes target")
|
|
|
|
client.dungeon_event.emit(state.DESTINATION_POSITION, 10000, 20000, true)
|
|
_ck(state.active, "second destination reopens route")
|
|
client.world_reset.emit()
|
|
_ck(not state.active and state.destination_cm == Vector2.ZERO and changes.size() == 4,
|
|
"world reset clears dungeon destination")
|
|
|
|
client.queue_free()
|
|
player.queue_free()
|
|
state.queue_free()
|