60 lines
4.0 KiB
GDScript
60 lines
4.0 KiB
GDScript
extends SceneTree
|
|||
|
|
var checks := 0
|
||
|
|
var failures := 0
|
||
|
|
func _initialize() -> void: call_deferred("run")
|
||
|
|
func check(value: bool, label: String) -> void:
|
||
|
|
checks += 1
|
||
|
|
if value: print("PASS ", label)
|
||
|
|
else: failures += 1; printerr("FAIL ", label)
|
||
|
|
func run() -> void:
|
||
|
|
var game: Node3D = load("res://scenes/main.tscn").instantiate(); root.add_child(game)
|
||
|
|
var path := "user://classes-test.cfg"
|
||
|
|
ClassLoadouts.restore(0, path)
|
||
|
|
check(ClassLoadouts.entries.size() == 10, "ten editable slots")
|
||
|
|
ClassLoadouts.entries[2] = ClassLoadouts.template(3)
|
||
|
|
ClassLoadouts.selected = 2
|
||
|
|
check(ClassLoadouts.save(path) == OK, "classes save")
|
||
|
|
ClassLoadouts.entries.clear(); ClassLoadouts.restore(0, path)
|
||
|
|
check(ClassLoadouts.selected == 2 and ClassLoadouts.entries[2].primary == 6, "class names selection and weapons persist")
|
||
|
|
var config := {"attachments": {"magazine": 1, "muzzle": 1, "underbarrel": 1, "stock": 1}}
|
||
|
|
var w := WeaponAttachments.stats(0, config)
|
||
|
|
check(w.mag == 42 and is_equal_approx(w.reload, 2.16), "extended magazine capacity and reload tradeoff")
|
||
|
|
check(w.range < Arsenal.DATA[0].range and w.spread < Arsenal.DATA[0].spread, "attachment range and precision")
|
||
|
|
check(Arsenal.DATA[0].mag == 30, "shared factory data remains unchanged")
|
||
|
|
check(WeaponAttachments.clean({"muzzle": 500, "stock": NAN}).muzzle == 2 and WeaponAttachments.clean({"stock": NAN}).stock == 0, "invalid attachment values sanitized")
|
||
|
|
var img := Image.create(400, 200, false, Image.FORMAT_RGBA8); img.fill(Color(0.1, 0.8, 0.9, 0.8)); img.save_png("user://class-test-sticker.png")
|
||
|
|
var id := WeaponStickers.import_file("user://class-test-sticker.png")
|
||
|
|
check(WeaponStickers.valid(id), "PNG sticker imported")
|
||
|
|
check(WeaponStickers.texture(id).get_width() == 256 and WeaponStickers.texture(id).get_height() == 128, "sticker preserves aspect and caps resolution")
|
||
|
|
config.stickers = [id, "", ""]
|
||
|
|
var packed := WeaponStickers.bundle({"0": config})
|
||
|
|
check(WeaponStickers.accept(packed).has(id), "sticker reliable payload accepted")
|
||
|
|
check(WeaponStickers.accept({id: PackedByteArray([1, 2, 3])}).is_empty(), "invalid sticker payload rejected")
|
||
|
|
check(WeaponStickers.texture("../../settings") == null, "sticker paths constrained to hashes")
|
||
|
|
var model := WeaponModels.build(0); root.add_child(model); WeaponSkins.apply(model, config)
|
||
|
|
check(model.get_node("Stickers").get_child_count() == 2, "sticker on both weapon sides")
|
||
|
|
check(model.get_node("Attachments").get_child_count() > 0, "attachments modeled")
|
||
|
|
WeaponSkins.apply(model, {})
|
||
|
|
check(model.get_node("Stickers").get_child_count() == 0 and model.get_node("Magazine").scale.y == 1, "reset removes stickers and extended magazine")
|
||
|
|
game.port = 27987; game.loadout = 0; WeaponSkins.set_design(0, config)
|
||
|
|
game.host({"server_name": "Classes test", "mode": "TDM", "max_players": 2, "bots": 0, "score_limit": 50, "time_limit": 600})
|
||
|
|
var p: Fighter = game.players[1]
|
||
|
|
check(p.magazines[0] == 42, "host spawns with attachment ammo capacity")
|
||
|
|
game.loadout = 6; WeaponSkins.set_design(6, {"attachments": {"magazine": 1}}); game.queue_local_class()
|
||
|
|
check(p.primary == 0 and p.pending_class.primary == 6, "live class change waits for spawn")
|
||
|
|
game.respawn(p)
|
||
|
|
check(p.primary == 6 and p.weapon == 6 and p.magazines[6] == 84, "spawn applies queued class and ammo")
|
||
|
|
var replica := Fighter.new(); replica.setup(game, 222, "replica", 0, false, 0); root.add_child(replica); replica.apply_snapshot(p.snapshot())
|
||
|
|
check(replica.primary == 6 and replica.weapon_stats().mag == 84, "snapshot synchronizes changed primary and attachment stats")
|
||
|
|
game.ui.loadout_menu()
|
||
|
|
var editor := game.ui.root.get_child(0) as ClassEditor
|
||
|
|
check(editor != null and editor.showcase.model != null, "class editor builds")
|
||
|
|
for i in 3: editor.tabs.selected = i; editor.rebuild_options()
|
||
|
|
check(editor.options_panel.get_child_count() > 3, "all editor panels build")
|
||
|
|
game.leave("")
|
||
|
|
model.queue_free(); replica.queue_free(); game.queue_free()
|
||
|
|
DirAccess.remove_absolute(path); DirAccess.remove_absolute("user://class-test-sticker.png")
|
||
|
|
await process_frame
|
||
|
|
print("CLASSES RESULT ", checks - failures, "/", checks)
|
||
|
|
quit(1 if failures else 0)
|