Randoloot/tests/items/machine_gun_shield_recovery_test.gd

101 lines
4.1 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends Node2D
const PLAYER := preload("res://scenes/game/player_ship.tscn")
const ENEMY := preload("res://scenes/game/enemy_ship.tscn")
class AimedGun:
extends "res://scripts/game/weapon_controller.gd"
func _aim_direction_from(_origin: Vector2) -> Vector2:
return Vector2.RIGHT
func _ready() -> void:
get_tree().create_timer(20.0).timeout.connect(func() -> void:
push_error("MACHINE_GUN_SHIELD_RECOVERY_TEST: timed out")
Input.action_release("ship_fire_primary")
get_tree().quit(1)
)
seed(12345)
GameState.start_new_run()
var ship := PLAYER.instantiate() as CharacterBody2D
ship.name = "PlayerShip"
add_child(ship)
ship.set_physics_process(false)
ship.get_node("WeaponController").set_physics_process(false)
ship.set("shields", 0.0)
ship.set("energy", 0.0)
var inventory := ship.get_node("ShipInventory") as ShipInventory
var gun := ItemInstance.new()
gun.definition = preload("res://resources/items/machine_gun.tres")
assert(inventory.add_item(gun))
assert(inventory.move_item("cargo", 0, "weapon", 0))
var module := ItemInstance.new()
module.definition = preload("res://resources/items/engine_extension.tres")
var addon := ItemStatModifier.new()
addon.affix = preload("res://resources/items/affixes/shield_on_damage.tres")
addon.stat_key = addon.affix.stat_key
addon.value = addon.affix.roll_value(1)
module.additional_modifiers.append(addon)
assert(inventory.add_item(module))
assert(inventory.move_item("cargo", inventory.cargo.find(module), "module", 2))
assert(ship.get("shield_on_damage_percent") == 1.0)
var indicator := Node2D.new()
indicator.set_script(preload("res://scripts/game/ship_energy_indicator.gd"))
indicator.set("player", ship)
ship.add_child(indicator)
var enemy := ENEMY.instantiate() as CharacterBody2D
enemy.position = Vector2(240, -28)
add_child(enemy)
enemy.set_physics_process(false)
enemy.set("_player", ship)
enemy.set("max_hull", 10000.0)
enemy.set("hull", 10000.0)
enemy.set("shields", 0.0)
var controller := AimedGun.new()
ship.add_child(controller)
await get_tree().physics_frame
await get_tree().physics_frame
# Fire a real projectile with the smallest level-1 damage: 2 DMG.
gun.damage_min = 2.0
gun.damage_max = 2.0
Input.action_press("ship_fire_primary")
for frame in 60:
await get_tree().physics_frame
if inventory.ammunition < 50:
break
Input.action_release("ship_fire_primary")
assert(inventory.ammunition == 49)
for frame in 60:
await get_tree().physics_frame
if enemy.get("hull") < 10000.0:
break
assert(is_equal_approx(enemy.get("hull"), 9998.0))
assert(is_equal_approx(ship.get("shields"), 0.02))
print("MACHINE_GUN_RECOVERY: single physical hit: 2 DMG -> +%.4f shields" % ship.get("shields"))
# Restore the normal starter roll (3–4 DMG), then empty the remaining magazine.
gun.damage_min = -1.0
gun.damage_max = -1.0
Input.action_press("ship_fire_primary")
for frame in 600:
await get_tree().physics_frame
if inventory.ammunition == 0:
break
Input.action_release("ship_fire_primary")
assert(inventory.ammunition == 0)
for frame in 45:
await get_tree().physics_frame
var actual_damage := 10000.0 - float(enemy.get("hull"))
var recovered := float(ship.get("shields"))
assert(is_equal_approx(recovered, actual_damage * 0.01))
assert(recovered > 1.0 and ship.get("energy") == 0.0)
indicator.call("_process", 1.0)
assert(is_equal_approx(indicator.get("_display_shield_ratio"), recovered / float(ship.get("max_shields"))))
print("MACHINE_GUN_RECOVERY: 50 physical hits, %.0f total DMG -> +%.4f shields; white bar: %.4f%% (%.3f px)" % [actual_damage, recovered, recovered / float(ship.get("max_shields")) * 100.0, recovered / float(ship.get("max_shields")) * 88.0])
# Empty ammo cannot keep firing or generate any further shields.
Input.action_press("ship_fire_primary")
for frame in 30:
await get_tree().physics_frame
Input.action_release("ship_fire_primary")
assert(is_equal_approx(ship.get("shields"), recovered))
print("MACHINE_GUN_SHIELD_RECOVERY_TEST: PASS (real firing input, projectile flight, collisions, 2-DMG fractions, accumulated recovery, ammo consumption, zero energy, shield bar, empty ammo)")
get_tree().quit()