171 lines
7.2 KiB
GDScript
171 lines
7.2 KiB
GDScript
extends Node2D
|
|
const DATA := preload("res://scripts/planets/alien_research.gd")
|
|
const ENEMY := preload("res://scenes/game/enemy_ship.tscn")
|
|
var player: CharacterBody2D
|
|
var progress: Resource
|
|
|
|
class StraightAlien extends "res://scripts/game/enemy_ship.gd":
|
|
func _laser_aim_direction(direction: Vector2) -> Vector2:
|
|
return direction
|
|
|
|
func enemy_at(point: Vector2) -> CharacterBody2D:
|
|
var enemy := ENEMY.instantiate() as CharacterBody2D
|
|
enemy.set_script(StraightAlien)
|
|
add_child(enemy)
|
|
enemy.set_physics_process(false)
|
|
enemy.position = point
|
|
enemy.max_hull = 10000.0
|
|
enemy.hull = 10000.0
|
|
enemy.max_shields = 1000.0
|
|
enemy.shields = 1000.0
|
|
enemy.absorption = Vector3.ZERO
|
|
enemy._player = player
|
|
return enemy
|
|
|
|
func _ready() -> void:
|
|
GameState.start_new_run()
|
|
progress = GameState.captain.expedition
|
|
progress.analysis_samples = 1000
|
|
assert(DATA.purchase(progress,"general") and DATA.purchase(progress,"shields"))
|
|
for side in ["a","b"]:
|
|
var id: String = "shields_"+side
|
|
for level in 4:
|
|
assert(DATA.cost(id)==20+level*5 and DATA.purchase(progress,id))
|
|
assert(not DATA.purchase(progress,id))
|
|
id+="_next"
|
|
assert(DATA.ACTIVE_IDS.size()==28)
|
|
player = preload("res://scenes/game/player_ship.tscn").instantiate()
|
|
add_child(player)
|
|
player.set_physics_process(false)
|
|
var weapon := player.get_node("WeaponController")
|
|
weapon.set_physics_process(false)
|
|
var enemy := enemy_at(Vector2(1000,0))
|
|
var nearby := enemy_at(Vector2(1100,0))
|
|
var chain := enemy_at(Vector2(1200,0))
|
|
progress.alien_skills = {"shields":true,"shields_a":true}
|
|
enemy.take_research_weapon_hit(100,false,DamageTypes.Type.ENERGY,0,-1)
|
|
assert(is_equal_approx(enemy.shields,885.0),"Shield bonuses add to 15 percent")
|
|
progress.alien_skills = {"shields_a_next":true}
|
|
enemy.shields = 500
|
|
enemy.take_research_weapon_hit(10,false,DamageTypes.Type.ENERGY,0,-1)
|
|
assert(enemy._shield_regen_lock==5.0)
|
|
enemy.regenerate_defenses(1.0)
|
|
assert(enemy.shields==490.0)
|
|
enemy.tick_shield_technologies(3.0)
|
|
enemy.take_research_weapon_hit(10,false,DamageTypes.Type.ENERGY,0,-1)
|
|
assert(enemy._shield_regen_lock==5.0)
|
|
enemy.tick_shield_technologies(5.1)
|
|
enemy.regenerate_defenses(1.0)
|
|
assert(enemy.shields==490.0)
|
|
progress.alien_skills = {"shields_a_next_next":true}
|
|
enemy.shields = 50
|
|
nearby.shields = 50
|
|
enemy.take_research_weapon_hit(100,false,DamageTypes.Type.ENERGY,0,-1)
|
|
assert(nearby.shields==0 and nearby.hull==9650,"Overload deals 400 percent, including spill")
|
|
assert(chain.shields==1000,"Overload cannot trigger a chain")
|
|
assert(enemy._shield_overload_cooldown==10)
|
|
enemy.shields = 1
|
|
enemy.take_research_weapon_hit(100,false,DamageTypes.Type.ENERGY,0,-1)
|
|
assert(nearby.hull==9650,"Regrown shield cannot spam overload")
|
|
enemy.tick_shield_technologies(10.1)
|
|
enemy.shields = 1
|
|
enemy.take_research_weapon_hit(100,false,DamageTypes.Type.ENERGY,0,-1)
|
|
assert(nearby.hull==9250)
|
|
progress.alien_skills = {"shields_b":true}
|
|
player.shields = 20
|
|
player.apply_equipment_bonuses({})
|
|
assert(is_equal_approx(player.max_shields,player.base_max_shields*1.1) and player.shields==20)
|
|
player.max_shields = 100
|
|
player.max_hull = 1000
|
|
player.hull = 1000
|
|
player.absorption = Vector3.ZERO
|
|
progress.alien_skills = {"shields_b_next":true}
|
|
player.shields = 40
|
|
player.take_damage(20)
|
|
assert(player._shield_reserve_remaining==2 and player._shield_reserve_cooldown==15)
|
|
player.energy = 5
|
|
assert(weapon._consume_energy(10) and player.energy==0,"Reduced cost is applied once")
|
|
player.tick_hull_technologies(2.1)
|
|
player.energy = 5
|
|
assert(not weapon._consume_energy(10),"Normal cost after reserve expires")
|
|
player.shields = 40
|
|
player.take_damage(20)
|
|
assert(player._shield_reserve_remaining==0,"Reserve cooldown prevents retrigger")
|
|
progress.alien_skills = {"shields_b_next_next":true}
|
|
player.shields = 100
|
|
player.take_damage(100)
|
|
assert(player.shields==90 and player._salvo_cooldown==60)
|
|
player.take_damage(20)
|
|
assert(player.shields==70,"Only first hit is reduced")
|
|
player.is_docked = true
|
|
player.tick_hull_technologies(60)
|
|
assert(player._salvo_cooldown==60,"Docking does not refresh cooldown")
|
|
player.is_docked = false
|
|
player.tick_hull_technologies(60)
|
|
player.shields = 5
|
|
player.take_damage(100)
|
|
assert(player.shields==0 and player.hull==995,"First-hit reduction also covers spill")
|
|
progress.alien_skills = {"shields_b_next_next_next":true}
|
|
player.hull = 1000
|
|
player.shields = 10
|
|
player.take_damage(20)
|
|
assert(player.shields==25 and player.hull==990 and player._emergency_shield_cooldown==30)
|
|
player.take_damage(20)
|
|
assert(player.shields==15,"Emergency shield halves following hits")
|
|
progress.alien_skills["shields_b_next_next"] = true
|
|
player._salvo_cooldown = 0
|
|
player.take_damage(100)
|
|
assert(player.shields==5,"Stronger protection applies without multiplying reductions")
|
|
player.tick_hull_technologies(2.1)
|
|
player.take_damage(10)
|
|
assert(player.shields==0 and player.hull==985,"Emergency shield cannot retrigger during cooldown")
|
|
progress.alien_skills = {"shields_a_next_next_next":true}
|
|
player.shields = 100
|
|
enemy.shields = 100
|
|
player.take_enemy_weapon_hit(50,false,DamageTypes.Type.ENERGY,enemy)
|
|
assert(player.shields==50 and enemy.shields==90,"Reflection uses absorbed damage and actual shooter")
|
|
player.shields = 5
|
|
player.take_enemy_weapon_hit(50,false,DamageTypes.Type.ENERGY,enemy)
|
|
assert(enemy.shields==89,"Hull damage is not reflected")
|
|
player.take_enemy_weapon_hit(10,false,DamageTypes.Type.ENERGY,enemy)
|
|
assert(enemy.shields==89,"No reflection without shields")
|
|
player.shields = 100
|
|
enemy.virus_controlled = true
|
|
player.take_enemy_weapon_hit(10,false,DamageTypes.Type.ENERGY,enemy)
|
|
assert(enemy.shields==89,"Friendly controlled aliens do not receive reflection")
|
|
enemy.virus_controlled = false
|
|
player.shields = 100
|
|
var projectile := preload("res://scenes/game/weapon_projectile.tscn").instantiate()
|
|
projectile.enemy_shot = true
|
|
projectile.source_ship = enemy
|
|
projectile.damage = 20
|
|
add_child(projectile)
|
|
projectile.set_physics_process(false)
|
|
projectile._apply_damage_once(player)
|
|
assert(player.shields==80 and is_equal_approx(enemy.shields,85),"Enemy projectile retains its shooter for reflection")
|
|
projectile.queue_free()
|
|
var shooter := enemy_at(Vector2(0,-180))
|
|
shooter.weapon_kind = ItemDefinition.WeaponKind.LASER
|
|
shooter.weapon_damage = 20
|
|
shooter.weapon_range = 500
|
|
shooter._combat_target = player
|
|
player.shields = 100
|
|
await get_tree().physics_frame
|
|
await get_tree().physics_frame
|
|
var laser_damage: float = shooter.get_shot_damage()
|
|
shooter._fire_plasma(Vector2.DOWN)
|
|
assert(is_equal_approx(player.shields,100-laser_damage),"Actual laser hits the player")
|
|
assert(is_equal_approx(shooter.shields,1000-laser_damage*0.2),"Actual laser reflection returns to the shooter")
|
|
var orphan := preload("res://scenes/game/weapon_projectile.tscn").instantiate()
|
|
orphan.enemy_shot = true
|
|
orphan.source_ship = enemy
|
|
orphan.configure(Vector2(3000,3000),Vector2.RIGHT,ItemDefinition.WeaponKind.PLASMA,600,10,1000)
|
|
add_child(orphan)
|
|
orphan.set_physics_process(false)
|
|
enemy.free()
|
|
player.shields = 100
|
|
orphan._physics_process(0.01)
|
|
orphan._hit_target(player)
|
|
assert(player.shields==90,"Projectile still hits safely after shooter is freed; no reflection to invalid source")
|
|
print("ALIEN_SHIELD_TECHNOLOGIES_TEST: PASS (8 skills, costs, 400% overload without chains, regen lock, energy reserve, 10% first hit/60s, emergency shield, reflection)")
|