Files
zombie-fps/tools/test_rebalance_branding.gd
Matteo Benedetto 323a7cdbae Leaderboard attiva di default, senza configurazione
La classifica globale non dipende più da un argomento: sui build desktop il client
usa il servizio pubblico DEFAULT_API_BASE (https://enne2.net/api/zombie-fps).

- scripts/leaderboard.gd: resolve_base() statica con priorità --api=<url> (test)
  → --offline/--no-api (opt-out esplicito per le partite di prova) → origine della
  pagina sul Web → servizio pubblico. Rimosso l'avviso "Classifica disattivata".
- Le suite di test (--script) restano spente a meno di un --api= esplicito, così
  nessun test può scrivere nella classifica pubblica.
- tools/test_start_screen.gd: verifica default attivo, opt-out e override;
  tools/test_rebalance_branding.gd: suite di test senza invii.
- docs/HIGHSCORES.md: nuova regola della base URL e diagnostica aggiornata.

Verifiche: test_start_screen 18/18 PASS con display; test_rebalance_branding
14/14 PASS; test_leaderboard.sh invariato (12 PASS, 2 FAIL preesistenti su questa
macchina anche prima della modifica).
2026-10-24 15:57:42 +02:00

92 lines
4.0 KiB
GDScript

extends SceneTree
## Exact damage regression + visible game identity. La classifica e' attiva di default
## nelle build di gioco; qui, girando come --script, resta spenta.
const Player = preload("res://scripts/player.gd")
const Grenade = preload("res://scripts/grenade.gd")
const Boss = preload("res://scripts/alien_grunt.gd")
const Target = preload("res://tools/grenade_test_target.gd")
var checks := 0
var failures := 0
func _initialize() -> void:
call_deferred("run_test")
func check(ok: bool, label: String) -> void:
checks += 1
if not ok:
failures += 1
print("PASS: " if ok else "FAIL: ", label)
func run_test() -> void:
check(Player.BULLET_DAMAGE == 17.5, "fucile: 35 -> 17,5 senza arrotondamento")
check(Grenade.MAX_DAMAGE == 320 and Grenade.BLAST_RADIUS == 5,
"granata: 160 -> 320, raggio invariato a 5m")
check(Boss.stats_for_wave(10).ranged == 8 and Boss.stats_for_wave(20).ranged == 10,
"proiettili alieni invariati a tutti i gradi")
check(ProjectSettings.get_setting("application/config/name") == "Work-Death Balance",
"titolo nativo del progetto aggiornato")
var icon: Texture2D = load(ProjectSettings.get_setting("application/config/icon"))
check(icon != null and icon.get_size() == Vector2(512, 512), "icona del progetto caricata, 512x512")
var preset := ConfigFile.new()
preset.load("res://export_presets.cfg")
check(preset.get_value("preset.0.options", "html/export_icon", false),
"favicon Web abilitata tramite esportazione icona ufficiale")
var world = load("res://scenes/main.tscn").instantiate()
root.add_child(world) # first real renamed startup also exercises profile migration
world.player.set_physics_process(false)
world.player.hp = 100000
world.player.position = Vector3(0, 0.1, 2)
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
var title_found := false
for label in world.start_screen.find_children("*", "Label", true, false):
if label.text == "Work-Death Balance":
title_found = true
check(title_found, "menu mostra Work-Death Balance")
check(world.leaderboard.disabled and world.leaderboard.base_url == "",
"suite di test: nessun invio alla classifica pubblica")
var zombie = load("res://scripts/zombie.gd").new()
zombie.player = world.player
zombie.position = Vector3(0, 0.05, -3)
world.add_child(zombie)
zombie.entering = false
zombie.set_physics_process(false)
world.player.camera.look_at(zombie.position + Vector3.UP)
await physics_frame
await physics_frame
world.player.shoot()
check(is_equal_approx(zombie.hp, 82.5), "colpo reale al corpo: esattamente 17,5 danni")
world.player.camera.look_at(zombie.position + Vector3.UP * 1.7)
world.player.shoot()
check(is_equal_approx(zombie.hp, 38.75), "headshot zombie: 43,75 danni, moltiplicatore 2,5 invariato")
zombie.queue_free()
await process_frame
var near := Target.new()
near.position = Vector3(0, 0, -1)
world.add_child(near)
var half := Target.new()
half.position = Vector3(0, 0, -2.5)
world.add_child(half)
var far := Target.new()
far.position = Vector3(0, 0, -6)
world.add_child(far)
var grenade := Grenade.new()
grenade.position = Vector3(0, 0.9, 0)
grenade.thrower = world.player
world.add_child(grenade)
grenade.freeze = true
var hp_before: float = world.player.hp
var player_distance: float = grenade.position.distance_to(world.player.position + Vector3.UP * 0.9)
var expected_self_damage := 320.0 * (1.0 - player_distance / 5.0)
grenade._request_detonation(grenade.position)
await process_frame
await process_frame
check(is_equal_approx(near.damage_taken, 256.0), "esplosione a 1m: 256 danni, decadimento lineare invariato")
check(is_equal_approx(half.damage_taken, 160.0), "esplosione a 2,5m: 160 danni, il doppio di prima")
check(far.damage_taken == 0, "nessun danno oltre il raggio originale")
check(is_equal_approx(hp_before - world.player.hp, expected_self_damage),
"danno dell'esplosione al tiratore raddoppiato con lo stesso decadimento")
world.queue_free()
await process_frame
print(checks - failures, " controlli superati, ", failures, " falliti")
quit(1 if failures else 0)