extends Node2D const PLAYER := preload("res://scenes/game/player_ship.tscn") const PROJECTILE := preload("res://scenes/game/weapon_projectile.tscn") func _ready() -> void: GameState.start_new_run() var ship := PLAYER.instantiate() as CharacterBody2D add_child(ship) ship.set_physics_process(false) var weapons := ship.get_node("WeaponController") weapons.set_physics_process(false) var inventory := ship.get_node("ShipInventory") as ShipInventory assert(inventory.weapon_slots.size() == 3) assert(inventory.get_missile_count() == 2 and inventory.get_cargo_used() == 0) var launcher := ItemInstance.new() launcher.definition = ShipInventory.MISSILE_DEFINITIONS[0] assert(inventory.add_item(launcher)) assert(inventory.can_move_item("cargo", 0, "weapon", 0)) assert(inventory.can_move_item("weapon", 0, "weapon", 2)) assert(inventory.move_item("cargo", 0, "weapon", 2)) assert(inventory.can_move_item("weapon", 2, "weapon", 0)) assert(not inventory.move_item("weapon", 2, "module", 0)) var energy_before := float(ship.get("energy")) var missile := inventory.weapon_slots[2] assert(missile.get_energy_cost() == 0.0) var addon := ItemStatModifier.new() addon.stat_key = "missile_cooldown_reduction" addon.value = 0.1 missile.additional_modifiers.append(addon) assert(is_equal_approx(inventory.get_missile_cooldown(missile), 4.9)) var middle := InputEventMouseButton.new() middle.button_index = MOUSE_BUTTON_MIDDLE middle.pressed = true assert(InputMap.action_has_event("ship_fire_missile", middle)) weapons.call("_unhandled_input", middle) weapons.call("_physics_process", 0.1) assert(ship.get("energy") == energy_before and inventory.get_missile_count() == 1) assert(inventory.weapon_slots[2] == missile and missile.additional_modifiers[0] == addon) assert(is_equal_approx(weapons.get("missile_cooldown_remaining"), 4.9)) assert(not weapons.call("try_fire_missile")) weapons.call("_physics_process", 2.0) assert(is_equal_approx(weapons.get("missile_cooldown_remaining"), 2.9)) weapons.call("_physics_process", 3.0) assert(weapons.call("try_fire_missile")) assert(inventory.get_missile_count() == 0 and inventory.weapon_slots[2] == missile) weapons.set("missile_cooldown_remaining", 0.0) assert(not weapons.call("try_fire_missile")) assert(inventory.weapon_slots[2] == missile and ship.get("energy") == energy_before) GameState.captain.parts = 49.0 assert(not inventory.craft_missile()) GameState.captain.minerals.merge({"iron": 1, "sulfur": 1, "uranium": 1}, true) assert(inventory.craft_missile() and GameState.captain.parts == 49.0) var unguided := ItemInstance.new() unguided.definition = ShipInventory.MISSILE_DEFINITIONS[1] assert(inventory.add_item(unguided)) assert(not unguided.definition.missile_homing) assert(unguided.get_damage_range().x > missile.get_damage_range().y) assert(inventory.move_item("cargo", 0, "weapon", 2)) weapons.set("missile_cooldown_remaining", 0.0) assert(weapons.call("try_fire_missile")) var found_unguided := false for child in get_children(): if child.scene_file_path == "res://scenes/game/weapon_projectile.tscn" and not child.get("missile_homing"): found_unguided = true assert(found_unguided) var target := Node2D.new() target.position = Vector2(0, 100) add_child(target) var straight := PROJECTILE.instantiate() as Area2D straight.call("configure", Vector2.ZERO, Vector2.RIGHT, ItemDefinition.WeaponKind.MISSILE, 480.0, 100.0, 1000.0, target) straight.set("missile_homing", false) straight.collision_mask = 0 add_child(straight) straight.set_physics_process(false) straight.call("_physics_process", 0.5) assert(straight.position.is_equal_approx(Vector2(240, 0))) GameState.system_level = 3 GameState.captain.credits = 29 assert(not inventory.buy_missile()) GameState.captain.credits = 30 assert(inventory.buy_missile() and GameState.captain.credits == 0) GameState.captain.parts = 100.0 GameState.captain.credits = 100 for index in inventory.cargo.size(): if inventory.cargo[index] == null: inventory.cargo[index] = missile var ammo_before := inventory.missile_ammunition GameState.captain.minerals.merge({"iron": 1, "sulfur": 1, "uranium": 1}, true) assert(inventory.craft_missile() and GameState.captain.parts == 100.0) assert(inventory.buy_missile() and GameState.captain.credits == 70) assert(inventory.missile_ammunition == ammo_before + 2) addon.value = 100.0 assert(inventory.get_missile_cooldown(missile) == 1.0) var affix := load("res://resources/items/affixes/missile_cooldown.tres") as ItemAffixDefinition assert(affix.can_roll(ShipInventory.MISSILE_DEFINITIONS[0], 1)) assert(affix.roll_value(1) >= 0.1 and affix.roll_value(1000) >= 1.0) inventory.preserve_for_restart() assert(GameState.restart_inventory["weapon"].size() == 3) var restored := PLAYER.instantiate() as CharacterBody2D add_child(restored) restored.set_physics_process(false) restored.get_node("WeaponController").set_physics_process(false) var restored_inventory := restored.get_node("ShipInventory") as ShipInventory assert(restored_inventory.missile_ammunition == inventory.missile_ammunition) assert(restored_inventory.weapon_slots[2] == unguided) print("MISSILE_SYSTEM_TEST: PASS (slots, permanent launchers, separate ammo, cooldown, no energy, variants, crafting, purchases, affix, restart)") get_tree().quit()