160 lines
7.5 KiB
GDScript
160 lines
7.5 KiB
GDScript
extends Node2D
|
|
const LAB := preload("res://scripts/planets/laboratory.gd")
|
|
const GEN := preload("res://scripts/items/item_generator.gd")
|
|
var player: CharacterBody2D
|
|
|
|
class StraightLaser extends "res://scripts/game/weapon_controller.gd":
|
|
func _aim_direction_from(_origin: Vector2) -> Vector2: return Vector2.RIGHT
|
|
|
|
func target_at(point: Vector2) -> CharacterBody2D:
|
|
var enemy := preload("res://scenes/game/enemy_ship.tscn").instantiate()
|
|
add_child(enemy)
|
|
enemy.set_physics_process(false)
|
|
enemy.position = point
|
|
enemy.max_hull = 10000
|
|
enemy.hull = 10000
|
|
enemy.shields = 0
|
|
enemy.absorption = Vector3.ZERO
|
|
enemy._player = player
|
|
return enemy
|
|
|
|
func snapshot(path: String) -> void:
|
|
for i in 8: await get_tree().process_frame
|
|
await RenderingServer.frame_post_draw
|
|
get_viewport().get_texture().get_image().save_png(path)
|
|
|
|
func _ready() -> void:
|
|
seed(49141)
|
|
GameState.start_new_run()
|
|
var captain := GameState.captain
|
|
var progress: Resource = captain.expedition
|
|
LAB.ensure_offers(progress)
|
|
assert(progress.laboratory_offers.size()==3)
|
|
var offers: Array = progress.laboratory_offers.duplicate()
|
|
LAB.ensure_offers(progress)
|
|
assert(progress.laboratory_offers==offers,"Opening laboratory does not reroll offers")
|
|
assert(GEN.available_definitions().size()==GEN.DEFINITIONS.size())
|
|
assert(not LAB.start(captain,offers[0]),"Laboratory must be built")
|
|
progress.freighter_rooms.expansion_1 = "laboratory"
|
|
assert(not LAB.start(captain,offers[0]),"Cannot research without materials")
|
|
for cost in LAB.COSTS.values():
|
|
for key in cost: captain.minerals[key] = 1000
|
|
var game := preload("res://scenes/game/game.tscn").instantiate()
|
|
add_child(game)
|
|
game.set_physics_process(false)
|
|
player = game.player
|
|
player.set_physics_process(false)
|
|
player.get_node("WeaponController").set_physics_process(false)
|
|
for enemy in get_tree().get_nodes_in_group("enemies"): enemy.set_physics_process(false)
|
|
var manager := game.get_node("PlanetExpeditions")
|
|
manager.open_freighter()
|
|
manager.screen._select_section("expansion_1")
|
|
assert(manager.screen._content.find_child("Research_incendiary_missile",true,false)!=null)
|
|
await snapshot("res://artifacts/laboratory_projects.png")
|
|
var before: Dictionary = captain.minerals.duplicate()
|
|
assert(LAB.start(captain,"incendiary_missile"))
|
|
for key in LAB.COSTS.incendiary_missile: assert(captain.minerals[key]==before[key]-LAB.COSTS.incendiary_missile[key])
|
|
assert(not LAB.start(captain,"radiation_laser"),"Only one project at a time")
|
|
GameState.advance_play_time(30.0,game)
|
|
assert(progress.laboratory_remaining==30,"Research advances while docked without any mining stations")
|
|
assert(not progress.laboratory_unlocks.has("incendiary_missile"))
|
|
assert(ResourceSaver.save(progress,"user://laboratory_progress_test.tres")==OK)
|
|
var saved: Resource = ResourceLoader.load("user://laboratory_progress_test.tres","",ResourceLoader.CACHE_MODE_IGNORE)
|
|
assert(saved.laboratory_project=="incendiary_missile" and saved.laboratory_remaining==30 and saved.laboratory_offers==offers)
|
|
await snapshot("res://artifacts/laboratory_progress.png")
|
|
manager._leave()
|
|
get_tree().paused = true
|
|
GameState.advance_play_time(30,game)
|
|
assert(progress.laboratory_remaining==30,"Ordinary pause stops research")
|
|
get_tree().paused = false
|
|
GameState.advance_play_time(29.9,game)
|
|
assert(not progress.laboratory_unlocks.has("incendiary_missile"))
|
|
GameState.advance_play_time(0.1,game)
|
|
assert(progress.laboratory_unlocks.has("incendiary_missile") and progress.laboratory_offers.size()==2)
|
|
assert(GEN.available_definitions().has(LAB.definition("incendiary_missile")))
|
|
for id in ["radiation_laser","artillery_cannon"]:
|
|
assert(LAB.start(captain,id))
|
|
LAB.advance(progress,60)
|
|
assert(progress.laboratory_offers.is_empty() and progress.laboratory_unlocks.size()==3)
|
|
assert(GEN.available_definitions().size()==GEN.DEFINITIONS.size()+3)
|
|
var inventory: ShipInventory = player.get_node("ShipInventory")
|
|
var cannon := ItemInstance.new()
|
|
cannon.definition = LAB.definition("artillery_cannon")
|
|
var controller := StraightLaser.new()
|
|
player.add_child(controller)
|
|
controller.set_physics_process(false)
|
|
inventory.ammunition = 9
|
|
assert(not controller._consume_shot_resource(cannon) and inventory.ammunition==9)
|
|
inventory.ammunition = 10
|
|
assert(controller._consume_shot_resource(cannon) and inventory.ammunition==0)
|
|
assert(cannon.get_fire_interval()==2.2 and cannon.get_damage_type()==DamageTypes.Type.KINETIC)
|
|
var camera_offset: Vector2 = player.get_node("Camera2D").offset
|
|
controller._fire_projectile(cannon)
|
|
assert(preload("res://scripts/game/artillery_effect.gd")._sound.get_length()>0.1)
|
|
inventory.unlocked_weapon_slots = 3
|
|
var incendiary := ItemInstance.new()
|
|
incendiary.definition = LAB.definition("incendiary_missile")
|
|
inventory.weapon_slots[2] = incendiary
|
|
inventory.missile_ammunition = 2
|
|
assert(controller.try_fire_missile(2) and inventory.missile_ammunition==1)
|
|
assert(not controller.try_fire_missile(2) and inventory.missile_ammunition==1,"Incendiary uses shared missile cooldown")
|
|
var launched := false
|
|
for child in player.get_parent().get_children():
|
|
if child.get_script() == preload("res://scripts/game/weapon_projectile.gd"):
|
|
child.set_physics_process(false)
|
|
if child.weapon_effect == "incendiary":
|
|
assert(child.missile_homing and child.get_damage_type()==DamageTypes.Type.KINETIC)
|
|
launched = true
|
|
assert(launched,"Incendiary launcher creates a homing missile")
|
|
player.position = Vector2.ZERO
|
|
var target := target_at(Vector2(200,-28))
|
|
var laser := ItemInstance.new()
|
|
laser.definition = LAB.definition("radiation_laser")
|
|
laser.damage_min = 4
|
|
laser.damage_max = 4
|
|
inventory.weapon_slots[0] = laser
|
|
player.energy = player.max_energy
|
|
await get_tree().physics_frame
|
|
await get_tree().physics_frame
|
|
controller._fire_laser(0,laser)
|
|
assert(controller._laser_lines[0].radiation_beam and target.hull==9996)
|
|
var status := target.get_node("RadiationStatus")
|
|
status.set_physics_process(false)
|
|
status._physics_process(0.5)
|
|
assert(target.hull==9994,"Green laser deals radiation over time")
|
|
status.remaining = 0
|
|
var missile := preload("res://scenes/game/weapon_projectile.tscn").instantiate()
|
|
missile.weapon_effect = "incendiary"
|
|
missile.configure(target.position,Vector2.RIGHT,ItemDefinition.WeaponKind.MISSILE,400,20,1000)
|
|
add_child(missile)
|
|
missile.set_physics_process(false)
|
|
var hp: float = target.hull
|
|
missile._hit_target(target)
|
|
assert(target.hull==hp-20)
|
|
await get_tree().process_frame
|
|
var clouds := get_tree().get_nodes_in_group("burning_gas")
|
|
assert(clouds.size()==1)
|
|
var gas: Node2D = clouds[0]
|
|
gas.set_physics_process(false)
|
|
gas.remaining = 5
|
|
gas._tick_elapsed = 0
|
|
var overlap := Node2D.new()
|
|
overlap.set_script(preload("res://scripts/game/burning_gas.gd"))
|
|
overlap.position = gas.position
|
|
overlap.damage_per_second = 10
|
|
add_child(overlap)
|
|
overlap.set_physics_process(false)
|
|
hp = target.hull
|
|
gas._physics_process(1)
|
|
overlap._physics_process(1)
|
|
assert(is_equal_approx(target.hull,hp-22),"Overlapping clouds use only strongest damage")
|
|
target.position += Vector2(200,0)
|
|
hp = target.hull
|
|
gas._physics_process(1)
|
|
assert(target.hull==hp,"Leaving the cloud stops gas damage")
|
|
gas._physics_process(10)
|
|
assert(gas.is_queued_for_deletion(),"Cloud expires after five seconds")
|
|
await get_tree().create_timer(0.22).timeout
|
|
assert(player.get_node("Camera2D").offset.is_equal_approx(camera_offset),"Artillery camera impulse restores the original offset")
|
|
print("LABORATORY_TEST: PASS (3 persistent choices, costs, gameplay clock, pause, save, unlock-only loot pool, artillery 10 ammo, green radiation laser, homing incendiary impact and non-stacking 5s gas, camera recovery)")
|