138 lines
6.8 KiB
GDScript
138 lines
6.8 KiB
GDScript
extends Node
|
|
|
|
const PROGRESS := preload("res://scripts/captain/captain_progress.gd")
|
|
const COMBAT := preload("res://scripts/game/combat_rolls.gd")
|
|
const GAME_SCENE := preload("res://scenes/game/game.tscn")
|
|
const GENERATOR := preload("res://scripts/items/item_generator.gd")
|
|
const PROJECTILE := preload("res://scenes/game/weapon_projectile.tscn")
|
|
|
|
class DamageReceiver:
|
|
extends Node2D
|
|
var hits: Array[Dictionary] = []
|
|
func take_weapon_hit(amount: float, critical: bool) -> void:
|
|
hits.append({"damage": amount, "critical": critical})
|
|
|
|
func _ready() -> void:
|
|
var profile := PROGRESS.new()
|
|
assert(not profile.train_skill("gunner"))
|
|
profile.add_rewards(99, 60)
|
|
assert(profile.level == 1 and profile.experience == 99)
|
|
profile.add_rewards(1, 15)
|
|
assert(profile.level == 2 and profile.experience == 0 and profile.learning_points == 1 and profile.credits == 75)
|
|
assert(profile.train_skill("gunner") and profile.get_skill_rank("gunner") == 1)
|
|
assert(not profile.train_skill("piloting") and not profile.train_skill("unknown"))
|
|
profile.add_rewards(450, 0)
|
|
assert(profile.level == 4 and profile.experience == 100 and profile.learning_points == 2)
|
|
profile.skills["piloting"] = 100
|
|
assert(not profile.train_skill("piloting"))
|
|
assert(profile.reward_enemy(10, 2, 1.25, 1.5) == Vector2i(272, 261))
|
|
var hit := COMBAT.weapon_hit(10, 1.1, 0, 2, 0)
|
|
assert(not hit["critical"] and is_equal_approx(hit["damage"], 11))
|
|
hit = COMBAT.weapon_hit(10, 1.1, 1, 2.4, 1)
|
|
assert(hit["critical"] and is_equal_approx(hit["damage"], 26.4))
|
|
assert(not COMBAT.weapon_hit(10, 1, 0.01, 2, 0.01)["critical"])
|
|
assert(COMBAT.incoming_hit(100, 1, 0, 1)["evaded"])
|
|
assert(is_equal_approx(COMBAT.incoming_hit(100, 0.01, 0.5, 0.01)["damage"], 50))
|
|
assert(COMBAT.incoming_hit(100, 0, 1, 0)["damage"] == 0)
|
|
assert(COMBAT.incoming_hit(-100, 0, 0, 0)["damage"] == 0)
|
|
|
|
GameState.start_new_run()
|
|
var game := GAME_SCENE.instantiate() as Node2D
|
|
get_tree().root.call_deferred("add_child", game)
|
|
await get_tree().process_frame
|
|
await get_tree().process_frame
|
|
get_tree().current_scene = game
|
|
_freeze(game)
|
|
profile = GameState.captain
|
|
var enemies := get_tree().get_nodes_in_group("enemies")
|
|
for enemy in enemies:
|
|
enemy.call("take_weapon_hit", 1000000.0, true)
|
|
enemy.call("take_damage", 1000000.0)
|
|
assert(profile.level == 2 and profile.experience == 0 and profile.learning_points == 1)
|
|
assert(profile.credits == 75)
|
|
var panel := game.get_node("HUD/HUDRoot/CaptainPanel")
|
|
panel.get_node("Contents/Skills/gunner/Train_gunner").emit_signal("pressed")
|
|
assert(profile.get_skill_rank("gunner") == 1 and profile.learning_points == 0)
|
|
panel.get_node("Contents/Skills/piloting/Train_piloting").emit_signal("pressed")
|
|
assert(profile.get_skill_rank("piloting") == 0)
|
|
assert(panel.get_node("Contents/Header/Level").get("text") == "POZ. 2")
|
|
var player := game.get_node("PlayerShip") as CharacterBody2D
|
|
profile.skills["piloting"] = 100
|
|
var before := Vector2(float(player.get("hull")), float(player.get("shields")))
|
|
player.call("take_damage", 1000.0)
|
|
assert(before == Vector2(float(player.get("hull")), float(player.get("shields"))))
|
|
profile.skills["piloting"] = 0
|
|
profile.skills["mechanic"] = 50
|
|
player.set("shields", 100.0) # Fixed fixture, independent of selected chassis capacity.
|
|
player.call("take_damage", 100.0)
|
|
assert(float(player.get("shields")) == 50 and float(player.get("hull")) == 100)
|
|
player.set("shields", 0.0)
|
|
player.call("take_damage", 40.0)
|
|
assert(float(player.get("hull")) == 80)
|
|
profile.skills["mechanic"] = 100
|
|
player.call("take_damage", 1000000.0)
|
|
assert(float(player.get("hull")) == 80)
|
|
profile.skills["mechanic"] = 0
|
|
profile.skills["sharp_eye"] = 1
|
|
var inventory := player.get_node("ShipInventory") as ShipInventory
|
|
var weapon := GENERATOR.generate_for_definition(preload("res://resources/items/plasma_cannon.tres"), 1)
|
|
weapon.additional_modifiers.clear()
|
|
weapon.damage_min = 10
|
|
weapon.damage_max = 10
|
|
for data in [["critical_chance_percent", 25.0], ["critical_damage_percent", 20.0], ["damage_percent", 10.0], ["experience_percent", 25.0], ["credits_percent", 50.0]]:
|
|
var modifier := ItemStatModifier.new()
|
|
modifier.stat_key = data[0]
|
|
modifier.value = data[1]
|
|
weapon.additional_modifiers.append(modifier)
|
|
var free_slot := inventory.cargo.find(null)
|
|
assert(inventory.add_item(weapon) and inventory.move_item("cargo", free_slot, "weapon", 0))
|
|
assert(is_equal_approx(float(player.call("get_critical_chance")), 0.26))
|
|
assert(is_equal_approx(float(player.call("get_critical_multiplier")), 2.4))
|
|
assert(is_equal_approx(float(player.call("get_weapon_damage_multiplier")), 1.111))
|
|
profile.skills["sharp_eye"] = 100
|
|
hit = player.call("roll_weapon_hit", weapon)
|
|
assert(hit["critical"] and is_equal_approx(hit["damage"], 26.664))
|
|
var receiver := DamageReceiver.new()
|
|
game.add_child(receiver)
|
|
var projectile := PROJECTILE.instantiate()
|
|
projectile.call("configure", Vector2.ZERO, Vector2.RIGHT, ItemDefinition.WeaponKind.MISSILE, 400.0, 26.664, 1000.0, null, true)
|
|
game.add_child(projectile)
|
|
projectile.set_physics_process(false)
|
|
projectile.call("_apply_damage_once", receiver)
|
|
projectile.call("_apply_damage_once", receiver)
|
|
assert(receiver.hits.size() == 1 and receiver.hits[0]["critical"])
|
|
assert(is_equal_approx(receiver.hits[0]["damage"], 26.664))
|
|
player.call("take_damage", 1000000.0)
|
|
await get_tree().create_timer(1.3).timeout
|
|
game = get_tree().current_scene as Node2D
|
|
_freeze(game)
|
|
assert(GameState.captain == profile and profile.level == 2 and profile.credits == 75)
|
|
player = game.get_node("PlayerShip") as CharacterBody2D
|
|
assert(player.get_node("ShipInventory").call("get_item", "weapon", 0) == weapon)
|
|
for enemy in get_tree().get_nodes_in_group("enemies"):
|
|
enemy.call("take_damage", 1000000.0)
|
|
assert(profile.experience == 125 and profile.credits == 190)
|
|
var planet: Node2D = game.get("protected_planet")
|
|
player.position = planet.position
|
|
game.call("_physics_process", 0.0)
|
|
assert(bool(game.call("advance_to_next_level")))
|
|
await get_tree().process_frame
|
|
await get_tree().process_frame
|
|
await get_tree().process_frame
|
|
game = get_tree().current_scene as Node2D
|
|
_freeze(game)
|
|
assert(GameState.captain == profile and GameState.system_level == 2)
|
|
assert(profile.get_skill_rank("gunner") == 1 and profile.get_skill_rank("sharp_eye") == 100)
|
|
var enemy := get_tree().get_nodes_in_group("enemies")[0] as CharacterBody2D
|
|
enemy.call("take_damage", 1000000.0)
|
|
assert(profile.level == 3 and profile.experience == 1 and profile.credits == 214)
|
|
print("CAPTAIN_SYSTEM_TEST: PASS (XP, multiple levels, learning UI, rewards once, dodge, reduction, critical addons, projectile metadata, death and next system)")
|
|
|
|
func _freeze(game: Node2D) -> void:
|
|
game.set_physics_process(false)
|
|
game.get_node("PlayerShip").set_physics_process(false)
|
|
game.get_node("PlayerShip/WeaponController").set_physics_process(false)
|
|
for enemy in get_tree().get_nodes_in_group("enemies"):
|
|
if game.is_ancestor_of(enemy):
|
|
enemy.set_physics_process(false)
|