extends Node2D const PLAYER := preload("res://scenes/game/player_ship.tscn") const ENEMY := preload("res://scenes/game/enemy_ship.tscn") const PROJECTILE := preload("res://scenes/game/weapon_projectile.tscn") func _ready() -> void: GameState.start_new_run() var ship := PLAYER.instantiate() as CharacterBody2D ship.name = "PlayerShip" 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 var modifier := ItemStatModifier.new() modifier.stat_key = "shield_on_damage_percent" modifier.value = 1.0 var module := ItemInstance.new() module.definition = preload("res://resources/items/engine_extension.tres") module.additional_modifiers.append(modifier) assert(inventory.add_item(module)) assert(inventory.move_item("cargo", 0, "module", 2)) assert(ship.get("shield_on_damage_percent") == 1.0) ship.set("shields", 0.0) var enemy := _enemy(ship, 100.0) # A gun without the addon still benefits from the global module stat. weapons.call("_apply_damage", enemy, 20.0, false) assert(is_equal_approx(ship.get("shields"), 0.2)) var projectile := PROJECTILE.instantiate() as Area2D projectile.set("damage", 10.0) projectile.set("is_critical", true) add_child(projectile) projectile.set_physics_process(false) projectile.call("_apply_damage_once", enemy) projectile.call("_apply_damage_once", enemy) assert(is_equal_approx(ship.get("shields"), 0.3)) enemy.call("take_weapon_hit", 1000.0, true) assert(is_equal_approx(ship.get("shields"), 1.0)) # Only remaining 70 HP. enemy.call("take_weapon_hit", 1000.0, true) assert(is_equal_approx(ship.get("shields"), 1.0)) # Addons on weapons and modules sum globally. inventory.weapon_slots[0].additional_modifiers.append(modifier) inventory.call("_recalculate_ship_stats") assert(ship.get("shield_on_damage_percent") == 2.0) enemy = _enemy(ship, 100.0) enemy.call("take_damage", 10.0) assert(is_equal_approx(ship.get("shields"), 1.0)) enemy.call("take_weapon_hit", -5.0, false) assert(is_equal_approx(ship.get("shields"), 1.0)) enemy.call("take_weapon_hit", 50.0, false) assert(is_equal_approx(ship.get("shields"), 2.0)) ship.set("shields", ship.get("max_shields") - 0.1) enemy.call("take_weapon_hit", 10.0, false) assert(ship.get("shields") == ship.get("max_shields")) assert(inventory.move_item("module", 2, "cargo", 0)) inventory.weapon_slots[0].additional_modifiers.clear() inventory.call("_recalculate_ship_stats") ship.set("shields", 0.0) enemy.call("take_weapon_hit", 10.0, false) assert(ship.get("shields") == 0.0) var affix := load("res://resources/items/affixes/shield_on_damage.tres") as ItemAffixDefinition assert(affix.roll_value(1) == 1.0 and affix.roll_value(1000) == 5.0) assert(affix.can_roll(module.definition, 1)) assert(affix.can_roll(inventory.weapon_slots[0].definition, 1)) print("SHIELD_ON_DAMAGE_TEST: PASS (global addon, laser/projectile hits, stacking, actual HP, overkill, duplicate hits, caps, unequipping, scaling)") get_tree().quit() func _enemy(ship: CharacterBody2D, hp: float) -> CharacterBody2D: var enemy := ENEMY.instantiate() as CharacterBody2D enemy.position = Vector2(700, 0) add_child(enemy) enemy.set_physics_process(false) enemy.set("_player", ship) enemy.set("hull", hp) enemy.set("shields", 0.0) return enemy