161 lines
6.7 KiB
GDScript
161 lines
6.7 KiB
GDScript
extends Node2D
|
|
|
|
const GENERATOR := preload("res://scripts/items/item_generator.gd")
|
|
const PLAYER_SCENE := preload("res://scenes/game/player_ship.tscn")
|
|
const PROJECTILE_SCRIPT := preload("res://scripts/game/weapon_projectile.gd")
|
|
|
|
class LaserProbe:
|
|
extends "res://scripts/game/weapon_controller.gd"
|
|
var hits: Array[float] = []
|
|
func _aim_direction_from(_origin: Vector2) -> Vector2:
|
|
return Vector2.RIGHT
|
|
func _apply_damage(_target: Variant, damage: float, _critical: bool = false) -> void:
|
|
hits.append(damage)
|
|
|
|
func _ready() -> void:
|
|
var saw_laser_1_2 := false
|
|
var saw_laser_3_6 := false
|
|
for definition in GENERATOR.DEFINITIONS:
|
|
if definition.category != ItemDefinition.Category.WEAPON:
|
|
continue
|
|
var starter := ItemInstance.new()
|
|
starter.definition = definition
|
|
assert(is_equal_approx(starter.get_energy_cost(), definition.energy_cost))
|
|
var stronger := ItemInstance.new()
|
|
stronger.definition = definition
|
|
var initial_range := starter.get_damage_range()
|
|
stronger.damage_min = initial_range.x * 4.0
|
|
stronger.damage_max = initial_range.y * 4.0
|
|
assert(is_equal_approx(stronger.get_energy_cost(), definition.energy_cost * 2.0))
|
|
var cost_before_addon := stronger.get_energy_cost()
|
|
var addon := ItemStatModifier.new()
|
|
addon.stat_key = "damage_percent"
|
|
addon.value = 10.0
|
|
stronger.additional_modifiers.append(addon)
|
|
if definition.weapon_kind in [ItemDefinition.WeaponKind.MACHINE_GUN, ItemDefinition.WeaponKind.MISSILE, ItemDefinition.WeaponKind.GAMMA]:
|
|
assert(stronger.get_energy_cost() == 0.0)
|
|
else:
|
|
assert(stronger.get_energy_cost() > cost_before_addon)
|
|
for level in [1, 50, 1000]:
|
|
for sample in 100:
|
|
var item := GENERATOR.generate_for_definition(definition, level)
|
|
var bounds := item.get_damage_range()
|
|
assert(bounds.x >= 1 and bounds.y > bounds.x)
|
|
var scale_factor: float = 1.0 + 0.05 * (level - 1)
|
|
assert(bounds.x >= roundf(definition.damage_lower_roll_min * scale_factor))
|
|
assert(bounds.x <= roundf(definition.damage_lower_roll_max * scale_factor))
|
|
assert(bounds.y <= roundf((definition.damage_lower_roll_max + definition.damage_spread_roll_max) * scale_factor))
|
|
for shot in 20:
|
|
var damage := item.roll_damage()
|
|
assert(damage >= bounds.x and damage <= bounds.y)
|
|
assert(item.get_damage_range() == bounds)
|
|
assert(item.get_tooltip_text().contains(item.get_damage_range_text()))
|
|
if definition.item_id == "beam_laser" and level == 1:
|
|
saw_laser_1_2 = saw_laser_1_2 or bounds == Vector2(1, 2)
|
|
saw_laser_3_6 = saw_laser_3_6 or bounds == Vector2(3, 6)
|
|
assert(saw_laser_1_2 and saw_laser_3_6)
|
|
|
|
var laser := ItemInstance.new()
|
|
laser.definition = preload("res://resources/items/beam_laser.tres")
|
|
laser.damage_min = 1
|
|
laser.damage_max = 5
|
|
var results: Dictionary = {}
|
|
for shot in 300:
|
|
results[laser.roll_damage()] = true
|
|
assert(results.size() == 5 and results.has(1.0) and results.has(5.0))
|
|
var legacy := ItemInstance.new()
|
|
legacy.definition = laser.definition
|
|
legacy.primary_value_override = 7.5
|
|
assert(legacy.roll_damage() == 7.5)
|
|
|
|
var player := PLAYER_SCENE.instantiate() as CharacterBody2D
|
|
add_child(player)
|
|
player.set_physics_process(false)
|
|
player.get_node("WeaponController").set_physics_process(false)
|
|
player.set("damage_multiplier", 1.25)
|
|
var probe := LaserProbe.new()
|
|
player.add_child(probe)
|
|
probe.set_physics_process(false)
|
|
var inventory := player.get_node("ShipInventory") as ShipInventory
|
|
assert(inventory.ammunition == ShipInventory.STARTING_AMMUNITION)
|
|
var machine_gun := ItemInstance.new()
|
|
machine_gun.definition = preload("res://resources/items/machine_gun.tres")
|
|
player.set("energy", 0.0)
|
|
inventory.ammunition = 1
|
|
assert(probe._consume_shot_resource(machine_gun))
|
|
assert(inventory.ammunition == 0 and player.get("energy") == 0.0)
|
|
assert(not probe._consume_shot_resource(machine_gun))
|
|
GameState.captain.parts = 49.0
|
|
assert(not inventory.craft_ammunition())
|
|
assert(inventory.ammunition == 0 and GameState.captain.parts == 49.0)
|
|
GameState.captain.minerals["titanium"] = 1
|
|
GameState.captain.minerals["sulfur"] = 1
|
|
assert(inventory.craft_ammunition())
|
|
assert(inventory.ammunition == 10 and GameState.captain.parts == 49.0)
|
|
GameState.system_level = 3
|
|
var buy_cost := ShipInventory.AMMUNITION_BUY_BASE_COST * 3
|
|
assert(inventory.get_ammunition_buy_cost() == buy_cost)
|
|
GameState.captain.credits = buy_cost - 1
|
|
assert(not inventory.buy_ammunition())
|
|
assert(inventory.ammunition == 10 and GameState.captain.credits == buy_cost - 1)
|
|
GameState.captain.credits = buy_cost * 2
|
|
assert(inventory.buy_ammunition())
|
|
assert(inventory.ammunition == 110 and GameState.captain.credits == buy_cost)
|
|
assert(inventory.buy_ammunition())
|
|
assert(inventory.ammunition == 210 and GameState.captain.credits == 0)
|
|
assert(not inventory.buy_ammunition())
|
|
GameState.system_level = 1
|
|
inventory.preserve_for_restart()
|
|
var restored_player := PLAYER_SCENE.instantiate() as CharacterBody2D
|
|
add_child(restored_player)
|
|
assert(restored_player.get_node("ShipInventory").get("ammunition") == 210)
|
|
restored_player.queue_free()
|
|
var target := StaticBody2D.new()
|
|
target.position = Vector2(200, -28)
|
|
target.collision_layer = 4
|
|
var collision := CollisionShape2D.new()
|
|
var shape := CircleShape2D.new()
|
|
shape.radius = 20
|
|
collision.shape = shape
|
|
target.add_child(collision)
|
|
add_child(target)
|
|
await get_tree().physics_frame
|
|
await get_tree().physics_frame
|
|
for shot in 100:
|
|
player.set("energy", 100.0)
|
|
probe.set("_shot_timers", [0.0, 0.0])
|
|
probe._fire_laser(0, laser)
|
|
assert(probe.hits.size() == 100)
|
|
var laser_hits: Dictionary = {}
|
|
for hit in probe.hits:
|
|
assert(hit >= 1.25 and hit <= 6.25)
|
|
laser_hits[hit] = true
|
|
assert(laser_hits.size() == 5)
|
|
player.set("energy", 0.0)
|
|
probe.set("_shot_timers", [0.0, 0.0])
|
|
probe._fire_laser(0, laser)
|
|
assert(probe.hits.size() == 100)
|
|
player.set("energy", 100.0)
|
|
probe.set("_shot_timers", [10.0, 0.0])
|
|
probe._fire_laser(0, laser)
|
|
assert(probe.hits.size() == 100)
|
|
|
|
for definition in GENERATOR.DEFINITIONS:
|
|
if definition.category != ItemDefinition.Category.WEAPON or definition.weapon_kind == ItemDefinition.WeaponKind.LASER:
|
|
continue
|
|
var item := GENERATOR.generate_for_definition(definition, 1)
|
|
var bounds := item.get_damage_range()
|
|
var projectile_results: Dictionary = {}
|
|
for shot in 100:
|
|
var previous_child_count := get_child_count()
|
|
probe._fire_projectile(item)
|
|
var projectile := get_child(previous_child_count)
|
|
assert(projectile.get_script() == PROJECTILE_SCRIPT)
|
|
var damage := float(projectile.get("damage"))
|
|
assert(damage >= bounds.x * 1.25 and damage <= bounds.y * 1.25)
|
|
projectile_results[damage] = true
|
|
remove_child(projectile)
|
|
projectile.free()
|
|
assert(projectile_results.size() > 1)
|
|
print("WEAPON_DAMAGE_TEST: PASS (1200 weapon rolls, 24000 damage rolls, 100 laser pulses and 300 projectiles; bonuses and energy/cooldown gates)")
|