Randoloot/tests/ships/alien_weapon_technologies_test.gd
2026-10-25 12:34:56 +01:00

159 lines
6.7 KiB
GDScript

extends Node2D
const DATA := preload("res://scripts/planets/alien_research.gd")
const EFFECTS := preload("res://scripts/game/alien_weapon_effects.gd")
const ENEMY := preload("res://scenes/game/enemy_ship.tscn")
const PROJECTILE := preload("res://scenes/game/weapon_projectile.tscn")
var player: CharacterBody2D
var progress: Resource
var _enemy_index := 0
func enemy_at(position_value: Vector2) -> CharacterBody2D:
var enemy := ENEMY.instantiate() as CharacterBody2D
add_child(enemy)
enemy.set_physics_process(false)
enemy._player = player
enemy.position = position_value
enemy.absorption = Vector3.ZERO
enemy.hull = 1000.0
enemy.max_hull = 1000.0
enemy.shields = 100.0
enemy.max_shields = 100.0
_enemy_index += 1
return enemy
func reset_enemy(enemy: Node, shields := 100.0) -> void:
enemy.hull = 1000.0
enemy.shields = shields
enemy._disabled_systems = [0.0,0.0,0.0]
func _ready() -> void:
GameState.start_new_run()
progress = GameState.captain.expedition
progress.analysis_samples = 1000
assert(not DATA.purchase(progress,"weapons_a"))
assert(DATA.purchase(progress,"general") and DATA.cost("general")==10)
assert(DATA.purchase(progress,"weapons") and DATA.cost("weapons")==15)
for path in ["a","b"]:
var id: String = "weapons_"+path
for level in 4:
assert(DATA.cost(id)==20+level*5)
var before: int = progress.analysis_samples
assert(DATA.purchase(progress,id))
assert(progress.analysis_samples==before-DATA.cost(id))
assert(not DATA.purchase(progress,id))
id += "_next"
assert(DATA.learned_count(progress)==10)
assert(not DATA.purchase(progress,"hull_a"))
progress.alien_skills = {"weapons_a":true}
player = preload("res://scenes/game/player_ship.tscn").instantiate()
add_child(player)
player.set_physics_process(false)
var weapons: Node = player.get_node("WeaponController")
weapons.set_physics_process(false)
var target := enemy_at(Vector2(1000,0))
target.shields = 0.0
weapons._apply_damage(target,10.0,false,0.0,DamageTypes.Type.ENERGY)
assert(target.hull==985.0,"Weak point applies to lasers")
reset_enemy(target,0.0)
var shot := PROJECTILE.instantiate()
shot.damage = 10.0
shot._apply_damage_once(target)
shot._apply_damage_once(target)
assert(target.hull==985.0,"Projectiles get weak point once per impact")
shot.free()
progress.alien_skills.weapons_a_next = true
for system in 3:
assert(EFFECTS.roll_disabled_system(0.0099,system)==system)
assert(EFFECTS.roll_disabled_system(0.01,0)==-1)
reset_enemy(target)
target.take_research_weapon_hit(10,false,DamageTypes.Type.ENERGY,0,2)
assert(target.system_disabled(2) and target.shields==0.0)
target.regenerate_defenses(1.0)
assert(target.shields==0.0)
target.tick_disabled_systems(3.1)
assert(not target.system_disabled(2) and target.shields==85.0)
target.disable_system(1)
var count := get_child_count()
target._fire_plasma(Vector2.RIGHT)
assert(get_child_count()==count,"Disabled weapons cannot fire")
target.disable_system(0)
target.velocity = Vector2.ZERO
target._activated = true
target._physics_process(0.1)
assert(target.velocity.is_zero_approx(),"Disabled engines cannot produce thrust")
target.tick_disabled_systems(3.1)
assert(not target.system_disabled(0) and not target.system_disabled(1))
reset_enemy(target,0.0)
target.take_research_dot(10,DamageTypes.Type.RADIATION,0)
assert(target.hull==990.0 and not target.system_disabled(0) and not target.system_disabled(1) and not target.system_disabled(2),"DoT does not reroll shot technologies")
progress.alien_skills = {"weapons_a":true,"weapons_a_next_next":true}
var first := enemy_at(Vector2.ZERO)
var second := enemy_at(Vector2(60,0))
var third := enemy_at(Vector2(120,0))
first.shields = 0.0
second.shields = 0.0
third.shields = 0.0
weapons._apply_damage(first,10.0)
assert(first.hull==985.0 and second.hull==985.0 and third.hull==1000.0,"Splash extends 10px beyond hulls without chaining")
reset_enemy(first,0.0)
reset_enemy(second,0.0)
shot = PROJECTILE.instantiate()
shot.damage = 10.0
shot._apply_damage_once(first)
shot._apply_damage_once(second)
assert(first.hull==985.0 and second.hull==985.0,"Area hits cannot deal duplicate damage")
shot.free()
progress.alien_skills = {"weapons_a":true,"weapons_a_next_next_next":true}
reset_enemy(target)
target.take_research_weapon_hit(10,false,DamageTypes.Type.ENERGY,0.5,-1)
assert(target.hull==985.0 and target.shields==85.0,"Perfect shot deals full damage to both layers without double piercing")
reset_enemy(target)
target.absorption = Vector3(0,50,0)
target.take_research_weapon_hit(10,false,DamageTypes.Type.ENERGY,0,-1)
assert(target.hull==992.5 and target.shields==92.5,"Absorption still applies")
progress.alien_skills = {"weapons_b":true}
assert(is_equal_approx(player.get_evasion_chance(),0.05))
progress.alien_skills = {"weapons_b_next":true}
player.position = Vector2(500,500)
shot = PROJECTILE.instantiate()
shot.enemy_shot = true
shot.weapon_kind = ItemDefinition.WeaponKind.MISSILE
shot.damage = 100.0
add_child(shot)
shot.position = player.position
shot.set_physics_process(false)
var shields: float = player.shields
var hull: float = player.hull
assert(shot.try_intercept(player,0.24999))
shot._hit_target(player)
shot._explode_at_target(player)
shot._apply_damage_once(player)
assert(player.shields==shields and player.hull==hull,"Intercepted missile cannot hurt player or splash targets")
var failed := PROJECTILE.instantiate()
failed.enemy_shot = true
failed.weapon_kind = ItemDefinition.WeaponKind.MISSILE
add_child(failed)
failed.set_physics_process(false)
failed.position = player.position
assert(not failed.try_intercept(player,0.25))
assert(not failed.try_intercept(player,0.0),"One interception roll per missile")
failed.free()
progress.alien_skills = {"weapons_b_next_next":true}
assert(not target.research_aim_direction(Vector2.RIGHT,0.249,1).is_equal_approx(Vector2.RIGHT))
assert(target.research_aim_direction(Vector2.RIGHT,0.25,1).is_equal_approx(Vector2.RIGHT))
progress.alien_skills = {"weapons_b_next_next_next":true}
target.absorption = Vector3.ZERO
target.weapon_kind = ItemDefinition.WeaponKind.PLASMA
target._fire_plasma(Vector2.RIGHT)
var friendly: Node
for child in get_children():
if child.get_script()==preload("res://scripts/game/weapon_projectile.gd") and child.source_ship==target: friendly=child
assert(friendly!=null and (friendly.collision_mask&4)!=0)
reset_enemy(second,0.0)
var source_hull: float = target.hull
friendly._apply_damage_once(target)
assert(target.hull==source_hull,"Friendly fire excludes the shooter")
friendly._apply_damage_once(second)
assert(second.hull<1000.0,"Hostile projectiles can damage other aliens")
print("ALIEN_WEAPON_TECHNOLOGIES_TEST: PASS (costs, prerequisites, all 8 effects, roll boundaries, no DoT rerolls, no splash chains, harmless interception, friendly fire)")