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)")