Prepare Void Bastion alpha 7 release
This commit is contained in:
1 parent
56077e88a5
commit
e63e08ddde
18 files changed
+799
-95
No files matched your search
+76
-10
@@ -29,6 +29,12 @@ func _run() -> void:
|
||||
var ads_manager = game.get_node("AdsManager")
|
||||
var account_manager = game.get_node("AccountManager")
|
||||
var multiplayer_manager = game.get_node("MultiplayerManager")
|
||||
game.set("core_crystals", 0)
|
||||
game.call("_adjust_core_crystals", 25)
|
||||
assert(game.get("core_crystals") == 25, "Der Entwicklermodus muss Testkristalle hinzufügen können.")
|
||||
game.call("_adjust_core_crystals", -25)
|
||||
game.call("_adjust_core_crystals", -25)
|
||||
assert(game.get("core_crystals") == 0, "Der Entwicklermodus muss Kristalle abziehen können, ohne unter null zu fallen.")
|
||||
assert(game.get("MAP_NAMES").size() == 7, "Es müssen sieben Karten vorhanden sein.")
|
||||
assert(game.get("MAP_TEXTURES").size() == 7, "Jede Karte benötigt einen eigenen Hintergrund.")
|
||||
assert(game.get("map_buttons").size() == 7, "Alle sieben Kartenvorschauen müssen gleichzeitig auswählbar sein.")
|
||||
@@ -135,10 +141,10 @@ func _run() -> void:
|
||||
assert(game.get("game_mode") == "menu", "Die Bestenliste benötigt einen funktionierenden Zurück-Button.")
|
||||
assert(not account_manager.player_id.is_empty(), "Beim ersten Start muss automatisch ein stabiles Gastprofil angelegt werden.")
|
||||
assert(not account_manager.display_name.is_empty(), "Das Gastprofil benötigt einen sichtbaren Pilotennamen.")
|
||||
assert(game.call("_app_version") == "0.1.0-alpha.5", "Profil, Installer und Online-Übertragung müssen dieselbe Alpha-Version verwenden.")
|
||||
assert(game.call("_app_version") == "0.1.0-alpha.7", "Profil, Installer und Online-Übertragung müssen dieselbe Alpha-Version verwenden.")
|
||||
var support_url: String = game.call("_support_email_url")
|
||||
assert(support_url.begins_with("mailto:support@gergames.de?"), "Die Feedback-Schaltfläche muss die öffentliche Supportadresse verwenden.")
|
||||
assert(support_url.contains("0.1.0-alpha.5") and support_url.contains(account_manager.short_id()), "Die Support-Mail muss Version und gekürzte Spieler-ID zur Fehlerzuordnung enthalten.")
|
||||
assert(support_url.contains("0.1.0-alpha.7") and support_url.contains(account_manager.short_id()), "Die Support-Mail muss Version und gekürzte Spieler-ID zur Fehlerzuordnung enthalten.")
|
||||
account_manager.storage_enabled = false
|
||||
var original_display_name: String = account_manager.display_name
|
||||
assert(account_manager.validate_display_name("Kommandant Ägir").is_empty(), "Ein normaler internationaler Spielername muss gültig sein.")
|
||||
@@ -152,14 +158,14 @@ func _run() -> void:
|
||||
assert(account_manager.get_map_best_wave(0, false) >= 3, "Die Profilansicht muss den gespeicherten Missionsbestwert lesen können.")
|
||||
assert(not ads_manager.mobile_ads_supported, "Auf Windows müssen Anzeigen vollständig deaktiviert bleiben.")
|
||||
var update_manager = game.get_node("UpdateManager")
|
||||
assert(update_manager.call("_is_newer_version", "0.1.0-alpha.5", "0.1.0-alpha.4"), "Eine neuere Alpha-Version muss als Update erkannt werden.")
|
||||
assert(update_manager.call("_is_newer_version", "0.1.0-alpha.6", "0.1.0-alpha.5"), "Eine neuere Alpha-Version muss als Update erkannt werden.")
|
||||
assert(update_manager.call("_is_newer_version", "0.1.0", "0.1.0-alpha.2"), "Eine stabile Version muss neuer als ihre Alpha-Version sein.")
|
||||
assert(not update_manager.call("_is_newer_version", "0.1.0-alpha.5", "0.1.0-alpha.5"), "Die installierte Version darf nicht als Update angeboten werden.")
|
||||
assert(not update_manager.call("_is_newer_version", "0.1.0-alpha.6", "0.1.0-alpha.6"), "Die installierte Version darf nicht als Update angeboten werden.")
|
||||
var announced_update := {}
|
||||
update_manager.update_available.connect(func(info: Dictionary): announced_update.merge(info, true))
|
||||
var fake_release_body := JSON.stringify([{"tag_name": "v0.1.0-alpha.6", "name": "Alpha.6", "draft": false, "assets": [{"name": "Void-Bastion-Setup-x64.exe", "browser_download_url": "https://git.dominicspringer.de/public-test.exe"}]}]).to_utf8_buffer()
|
||||
var fake_release_body := JSON.stringify([{"tag_name": "v0.1.0-alpha.8", "name": "Alpha.8", "draft": false, "assets": [{"name": "Void-Bastion-Setup-x64.exe", "browser_download_url": "https://git.dominicspringer.de/public-test.exe"}]}]).to_utf8_buffer()
|
||||
update_manager.call("_on_request_completed", HTTPRequest.RESULT_SUCCESS, 200, PackedStringArray(), fake_release_body)
|
||||
assert(announced_update.get("version") == "0.1.0-alpha.6", "Die Update-Prüfung muss eine neuere öffentliche Version ankündigen.")
|
||||
assert(announced_update.get("version") == "0.1.0-alpha.8", "Die Update-Prüfung muss eine neuere öffentliche Version ankündigen.")
|
||||
assert(str(announced_update.get("url", "")).begins_with("https://git.dominicspringer.de/"), "Der Update-Hinweis darf nur einen öffentlichen Download-Link öffnen.")
|
||||
assert(game.get("path_points").size() == 9, "Bastion Prime sollte mit einer eigenen Einfahrt im Reaktor enden.")
|
||||
_assert_grid_aligned_path(game.get("path_points"), "Bastion Prime")
|
||||
@@ -266,7 +272,53 @@ func _run() -> void:
|
||||
game.call("_start_game")
|
||||
assert(game.get("credits") == 340 and game.get("reactor_lives") == 12, "Schwer muss mit knapperen Startressourcen und weniger Reaktorleben beginnen.")
|
||||
assert(int(game.call("_difficulty").crystals) == 12, "Ein Sieg auf Schwer muss den höheren Kristallbonus gewähren.")
|
||||
assert(game.get("ENEMY_DATA").size() == 6, "Drei zusätzliche Gegnerrollen müssen im Spiel verfügbar sein.")
|
||||
assert(game.get("ENEMY_DATA").size() == 9, "Drei zusätzliche Gegnerrollen müssen im Spiel verfügbar sein.")
|
||||
assert(game.call("_enemy_category", 0) == "air" and game.call("_enemy_category", 6) == "ground", "Luft- und Bodeneinheiten müssen eindeutig klassifiziert sein.")
|
||||
assert(not game.call("_tower_can_target", 0, 0) and game.call("_tower_can_target", 1, 0) and game.call("_tower_can_target", 1, 6) and game.call("_tower_can_target", 5, 6), "Kinetik muss auf Boden beschränkt sein; Laser und Railgun dürfen beide Kategorien angreifen.")
|
||||
assert(game.call("_enemy_texture", 6).get_width() > 0 and game.call("_enemy_texture", 8).get_height() > 0, "Bodeneinheiten benötigen eigene lesbare Grafiken.")
|
||||
assert(game.get("TOWER_DATA")[0].target_class == "ground" and game.get("TOWER_DATA")[1].target_class == "both", "Der Laser muss neben Luft- auch Bodenziele angreifen können.")
|
||||
assert(game.get("TOWER_DATA")[1].both_damage_scale < 1.0 and game.get("TOWER_DATA")[3].both_damage_scale < 1.0 and game.get("TOWER_DATA")[5].both_damage_scale < 1.0, "Laser, Plasma und Railgun müssen für ihre Mehrzweckfähigkeit einen Schadensmultiplikator erhalten.")
|
||||
assert(game.get("TOWER_DATA")[4].damage == 20.0 and game.get("TOWER_DATA")[4].target_class == "both", "EMP muss Luft- und Bodenziele mit rund 20 Schaden erfassen.")
|
||||
assert(game.call("_tower_display_order") == [0, 2, 1, 3, 4, 5], "Die Turmauswahl muss zuerst Luft-, dann Boden- und anschließend Mehrzwecktürme gruppieren.")
|
||||
assert(game.call("_tower_class_color", 0).g > game.call("_tower_class_color", 0).r and game.call("_tower_class_color", 1).b > game.call("_tower_class_color", 1).r, "Bodenfelder müssen grün und Mehrzweckfelder blau-cyan eingefärbt sein.")
|
||||
game.get("enemies").clear()
|
||||
var rail_front := {"id": 96001, "type": 0, "pos": Vector2(400, 300), "hp": 1000.0, "max_hp": 1000.0, "flash": 0.0, "shield": false, "reward": 1}
|
||||
var rail_behind := {"id": 96002, "type": 6, "pos": Vector2(500, 300), "hp": 1000.0, "max_hp": 1000.0, "flash": 0.0, "shield": false, "reward": 1}
|
||||
var rail_offline := {"id": 96003, "type": 0, "pos": Vector2(450, 326), "hp": 1000.0, "max_hp": 1000.0, "flash": 0.0, "shield": false, "reward": 1}
|
||||
game.get("enemies").append_array([rail_front, rail_behind, rail_offline])
|
||||
game.call("_fire_tower", {"type": 5, "level": 1, "pos": Vector2(300, 300), "owner": 0}, rail_front)
|
||||
assert(rail_front.hp < 1000.0 and rail_behind.hp < 1000.0 and is_equal_approx(rail_offline.hp, 1000.0), "Der Railgun-Strahl muss Gegner hinter dem Ziel auf der Linie durchschlagen, aber keine Ziele neben der Linie treffen.")
|
||||
assert(game.get("beams")[-1].piercing and game.get("beams")[-1].color == Color("c86bff"), "Der durchschlagende Railgun-Strahl muss sichtbar lila sein.")
|
||||
game.get("enemies").clear()
|
||||
game.get("projectiles").clear()
|
||||
var emp_air := {"id": 96101, "type": 0, "pos": Vector2(500, 500), "hp": 1000.0, "max_hp": 1000.0, "flash": 0.0, "shield": false, "reward": 1}
|
||||
var emp_ground := {"id": 96102, "type": 6, "pos": Vector2(550, 500), "hp": 1000.0, "max_hp": 1000.0, "flash": 0.0, "shield": false, "reward": 1}
|
||||
var emp_outside := {"id": 96103, "type": 6, "pos": Vector2(700, 500), "hp": 1000.0, "max_hp": 1000.0, "flash": 0.0, "shield": false, "reward": 1}
|
||||
game.get("enemies").append_array([emp_air, emp_ground, emp_outside])
|
||||
game.call("_fire_tower", {"type": 4, "level": 1, "pos": Vector2(400, 500), "owner": 0}, emp_air)
|
||||
game.get("projectiles")[-1].speed = 0.0
|
||||
game.get("projectiles")[-1].pos = emp_air.pos
|
||||
game.call("_update_projectiles", 0.01)
|
||||
assert(is_equal_approx(emp_air.hp, 980.0) and is_equal_approx(emp_ground.hp, 980.0) and is_equal_approx(emp_outside.hp, 1000.0), "Der EMP muss Luft und Boden im 118er-Radius jeweils um 20 treffen und Gegner außerhalb verschonen.")
|
||||
game.get("enemies").clear()
|
||||
game.set("path_points", PackedVector2Array([Vector2(0, 0), Vector2(1000, 0), Vector2(1600, 0)]))
|
||||
game.get("enemies").clear()
|
||||
var shield_target := {"id": 201, "type": 6, "pos": Vector2(850, 0), "path_index": 1, "hp": 100.0, "shield": true}
|
||||
var unshielded_target := {"id": 202, "type": 6, "pos": Vector2(950, 0), "path_index": 1, "hp": 500.0, "shield": false}
|
||||
game.get("enemies").append(shield_target)
|
||||
game.get("enemies").append(unshielded_target)
|
||||
assert(game.call("_find_target", {"type": 1, "level": 1, "pos": Vector2(800, 0)}).id == 201, "Lasertürme müssen unabhängig vom Fortschritt immer zuerst ein Schildziel in Reichweite wählen.")
|
||||
assert(game.call("_find_target", {"type": 0, "level": 1, "pos": Vector2(800, 0), "target_priority": "strongest"}).id == 202, "Die Priorität MEISTE HP muss das Ziel mit den meisten Lebenspunkten wählen.")
|
||||
assert(game.call("_find_target", {"type": 0, "level": 1, "pos": Vector2(800, 0), "target_priority": "last"}).id == 201, "Die Priorität LETZTE muss die Einheit mit dem geringsten Wegfortschritt wählen.")
|
||||
game.get("towers").clear()
|
||||
game.get("towers").append({"type": 0, "target_priority": "first"})
|
||||
game.set("selected_tower_index", 0)
|
||||
game.call("_cycle_selected_tower_priority")
|
||||
assert(game.get("towers")[0].target_priority == "last", "Die Zielpriorität eines ausgewählten Turms muss umstellbar sein.")
|
||||
game.set("selected_tower_index", -1)
|
||||
game.get("towers").clear()
|
||||
game.get("enemies").clear()
|
||||
game.call("_select_map", 0)
|
||||
assert(game.call("_enemy_type_for_wave", 3, 0.9, false) == 3, "Auf Schwer muss der Abfangjäger ab Welle 3 auftreten.")
|
||||
assert(game.call("_enemy_type_for_wave", 5, 0.85, false) == 4, "Auf Schwer muss der Schildkreuzer ab Welle 5 auftreten.")
|
||||
assert(game.call("_enemy_type_for_wave", 8, 0.95, false) == 5, "Auf Schwer muss der Belagerer ab Welle 8 auftreten.")
|
||||
@@ -282,13 +334,25 @@ func _run() -> void:
|
||||
game.set("wave", 3)
|
||||
game.call("_start_wave")
|
||||
assert(game.get("enemies_to_spawn") > 15, "Ab Welle 4 muss die Gegnerzahl merklich steigen.")
|
||||
var preview_types: Array[int] = game.call("_wave_preview_types", 3)
|
||||
assert(preview_types.has(6) and preview_types.has(0), "Die Vorschau muss Luft- und Bodentypen der gleichen Welle zeigen.")
|
||||
var preview_summary: Dictionary = game.call("_wave_preview_summary", 3)
|
||||
assert(preview_summary.total == preview_types.size() and preview_summary.air + preview_summary.ground == preview_summary.total, "Die Vorschau muss die Gesamtzahl der Schiffe sowie die korrekten Luft-/Bodenanteile zählen.")
|
||||
assert(game.get("wave_type_schedule").size() == game.get("enemies_to_spawn"), "Die Vorschau und der tatsächliche Spawnplan müssen übereinstimmen.")
|
||||
var test_enemy := {"hp": 100.0, "max_hp": 100.0, "base_max_hp": 100.0, "type": 0, "flash": 0.0, "pos": Vector2.ZERO}
|
||||
game.get("enemies").append(test_enemy)
|
||||
game.call("_set_enemy_strength_multiplier", 1.6)
|
||||
assert(is_equal_approx(test_enemy.max_hp, 160.0) and is_equal_approx(test_enemy.hp, 160.0), "Der Testmultiplikator muss die Hülle laufender Gegner anpassen.")
|
||||
game.call("_set_enemy_strength_multiplier", 1.0)
|
||||
game.get("enemies").clear()
|
||||
var shielded_enemy := {"hp": 1000.0, "max_hp": 1000.0, "flash": 0.0, "id": 98001, "type": 0, "pos": Vector2.ZERO, "speed": 1.0, "reward": 1, "boss": false, "size_scale": 1.0, "shield": true}
|
||||
var shielded_enemy := {"hp": 1000.0, "max_hp": 1000.0, "flash": 0.0, "id": 98001, "type": 0, "pos": Vector2.ZERO, "speed": 1.0, "reward": 1, "boss": false, "size_scale": 1.0, "shield": true, "shield_hp": 50.0, "max_shield_hp": 50.0, "shield_resistance": 0.28}
|
||||
game.get("enemies").append(shielded_enemy)
|
||||
game.call("_apply_damage", shielded_enemy, 100.0, 0, 0)
|
||||
assert(is_equal_approx(shielded_enemy.hp, 972.0), "Schilde müssen kinetischen Schaden deutlich reduzieren, aber nicht vollständig blockieren.")
|
||||
game.call("_apply_damage", shielded_enemy, 100.0, 0, 1)
|
||||
assert(is_equal_approx(shielded_enemy.hp, 872.0), "Laser müssen Schildgegner effektiv beschädigen.")
|
||||
game.call("_apply_damage", shielded_enemy, 30.0, 0, 1)
|
||||
assert(is_equal_approx(shielded_enemy.hp, 972.0) and is_equal_approx(shielded_enemy.shield_hp, 20.0), "Laser müssen das Schildleben statt der Hülle abbauen.")
|
||||
game.call("_apply_damage", shielded_enemy, 30.0, 0, 1)
|
||||
assert(not shielded_enemy.shield and is_equal_approx(shielded_enemy.hp, 962.0), "Der Laser muss beim Schildbruch überschüssigen Schaden auf die Hülle übertragen.")
|
||||
game.get("enemies").clear()
|
||||
game.set("wave", 5)
|
||||
game.set("reactor_lives", 12)
|
||||
@@ -305,6 +369,8 @@ func _run() -> void:
|
||||
game.set("wave", 4)
|
||||
game.call("_start_wave")
|
||||
game.set("enemies_to_spawn", 1)
|
||||
game.set("wave_spawn_index", 0)
|
||||
game.set("wave_type_schedule", game.call("_build_wave_schedule", 5, 1))
|
||||
game.call("_spawn_enemy")
|
||||
var boss: Dictionary = game.get("enemies")[-1]
|
||||
assert(boss.boss, "Jede fünfte Welle sollte ein Kommandoschiff erzeugen.")
|
||||
|
||||
Reference in new issue
Block a user