feature updates

This commit is contained in:
2026-02-02 16:28:53 -05:00
parent bf9aa3fa23
commit 44c06530ac
83 changed files with 282641 additions and 11251 deletions

View File

@@ -0,0 +1,348 @@
extends GutTest
## Tests for ability cost validation in AbilitySystem
# =============================================================================
# CP COST VALIDATION TESTS
# =============================================================================
func test_validate_empty_cost_always_valid() -> void:
var ability_system = AbilitySystem.new()
var cost = {}
var player = MockPlayer.new()
var result = ability_system._validate_ability_cost(cost, null, player)
assert_true(result.valid, "Empty cost should always be valid")
ability_system.free()
func test_validate_cp_cost_with_sufficient_cp() -> void:
var ability_system = AbilitySystem.new()
var cost = {"cp": 3}
var player = MockPlayer.new()
player.cp_pool.add_cp(Enums.Element.FIRE, 5)
var result = ability_system._validate_ability_cost(cost, null, player)
assert_true(result.valid, "Should be valid with sufficient CP")
ability_system.free()
func test_validate_cp_cost_with_insufficient_cp() -> void:
var ability_system = AbilitySystem.new()
var cost = {"cp": 5}
var player = MockPlayer.new()
player.cp_pool.add_cp(Enums.Element.FIRE, 3)
var result = ability_system._validate_ability_cost(cost, null, player)
assert_false(result.valid, "Should be invalid with insufficient CP")
assert_true("Not enough CP" in result.reason, "Reason should mention CP")
ability_system.free()
func test_validate_specific_element_cp_cost_valid() -> void:
var ability_system = AbilitySystem.new()
var cost = {"cp": 2, "element": "FIRE"}
var player = MockPlayer.new()
player.cp_pool.add_cp(Enums.Element.FIRE, 3)
var result = ability_system._validate_ability_cost(cost, null, player)
assert_true(result.valid, "Should be valid with sufficient Fire CP")
ability_system.free()
func test_validate_specific_element_cp_cost_invalid() -> void:
var ability_system = AbilitySystem.new()
var cost = {"cp": 2, "element": "FIRE"}
var player = MockPlayer.new()
player.cp_pool.add_cp(Enums.Element.ICE, 5) # Wrong element
var result = ability_system._validate_ability_cost(cost, null, player)
assert_false(result.valid, "Should be invalid with wrong element CP")
assert_true("FIRE CP" in result.reason, "Reason should mention Fire")
ability_system.free()
func test_validate_any_element_cp_cost() -> void:
var ability_system = AbilitySystem.new()
var cost = {"cp": 4, "element": "ANY"}
var player = MockPlayer.new()
player.cp_pool.add_cp(Enums.Element.FIRE, 2)
player.cp_pool.add_cp(Enums.Element.ICE, 2)
var result = ability_system._validate_ability_cost(cost, null, player)
assert_true(result.valid, "Should be valid with total CP from multiple elements")
ability_system.free()
# =============================================================================
# DISCARD COST VALIDATION TESTS
# =============================================================================
func test_validate_discard_cost_with_sufficient_cards() -> void:
var ability_system = AbilitySystem.new()
var cost = {"discard": 2}
var player = MockPlayer.new()
# Add 3 cards to hand
for i in range(3):
var card = _create_mock_card()
player.hand.add_card(card)
var result = ability_system._validate_ability_cost(cost, null, player)
assert_true(result.valid, "Should be valid with sufficient cards to discard")
ability_system.free()
func test_validate_discard_cost_with_insufficient_cards() -> void:
var ability_system = AbilitySystem.new()
var cost = {"discard": 3}
var player = MockPlayer.new()
# Add only 1 card to hand
player.hand.add_card(_create_mock_card())
var result = ability_system._validate_ability_cost(cost, null, player)
assert_false(result.valid, "Should be invalid with insufficient cards")
assert_true("discard" in result.reason, "Reason should mention discard")
ability_system.free()
# =============================================================================
# DULL SELF COST VALIDATION TESTS
# =============================================================================
func test_validate_dull_self_cost_when_active() -> void:
var ability_system = AbilitySystem.new()
var cost = {"dull_self": true}
var source = _create_mock_card()
source.activate() # Ensure active
var player = MockPlayer.new()
var result = ability_system._validate_ability_cost(cost, source, player)
assert_true(result.valid, "Should be valid when card is active")
ability_system.free()
func test_validate_dull_self_cost_when_already_dull() -> void:
var ability_system = AbilitySystem.new()
var cost = {"dull_self": true}
var source = _create_mock_card()
source.dull() # Already dull
var player = MockPlayer.new()
var result = ability_system._validate_ability_cost(cost, source, player)
assert_false(result.valid, "Should be invalid when card is already dull")
assert_true("dulled" in result.reason, "Reason should mention dulled")
ability_system.free()
# =============================================================================
# SPECIFIC DISCARD COST VALIDATION TESTS
# =============================================================================
func test_validate_specific_discard_cost_with_matching_card() -> void:
var ability_system = AbilitySystem.new()
var cost = {"specific_discard": "Cloud"}
var player = MockPlayer.new()
var cloud = _create_mock_card_with_name("Cloud")
player.hand.add_card(cloud)
var result = ability_system._validate_ability_cost(cost, null, player)
assert_true(result.valid, "Should be valid with matching card in hand")
ability_system.free()
func test_validate_specific_discard_cost_without_matching_card() -> void:
var ability_system = AbilitySystem.new()
var cost = {"specific_discard": "Cloud"}
var player = MockPlayer.new()
var sephiroth = _create_mock_card_with_name("Sephiroth")
player.hand.add_card(sephiroth)
var result = ability_system._validate_ability_cost(cost, null, player)
assert_false(result.valid, "Should be invalid without matching card")
assert_true("Cloud" in result.reason, "Reason should mention required card")
ability_system.free()
# =============================================================================
# COMBINED COST VALIDATION TESTS
# =============================================================================
func test_validate_combined_cp_and_dull_cost() -> void:
var ability_system = AbilitySystem.new()
var cost = {"cp": 2, "dull_self": true}
var source = _create_mock_card()
source.activate()
var player = MockPlayer.new()
player.cp_pool.add_cp(Enums.Element.FIRE, 3)
var result = ability_system._validate_ability_cost(cost, source, player)
assert_true(result.valid, "Should be valid when all requirements met")
ability_system.free()
func test_validate_combined_cost_fails_on_cp() -> void:
var ability_system = AbilitySystem.new()
var cost = {"cp": 5, "dull_self": true}
var source = _create_mock_card()
source.activate()
var player = MockPlayer.new()
player.cp_pool.add_cp(Enums.Element.FIRE, 2) # Insufficient
var result = ability_system._validate_ability_cost(cost, source, player)
assert_false(result.valid, "Should fail on CP requirement")
ability_system.free()
func test_validate_combined_cost_fails_on_dull() -> void:
var ability_system = AbilitySystem.new()
var cost = {"cp": 2, "dull_self": true}
var source = _create_mock_card()
source.dull() # Already dull
var player = MockPlayer.new()
player.cp_pool.add_cp(Enums.Element.FIRE, 5)
var result = ability_system._validate_ability_cost(cost, source, player)
assert_false(result.valid, "Should fail on dull requirement")
ability_system.free()
# =============================================================================
# COST PAYMENT TESTS
# =============================================================================
func test_pay_empty_cost() -> void:
var ability_system = AbilitySystem.new()
var cost = {}
var player = MockPlayer.new()
var success = ability_system._pay_ability_cost(cost, null, player)
assert_true(success, "Paying empty cost should succeed")
ability_system.free()
func test_pay_generic_cp_cost() -> void:
var ability_system = AbilitySystem.new()
var cost = {"cp": 3}
var player = MockPlayer.new()
player.cp_pool.add_cp(Enums.Element.FIRE, 5)
var initial_cp = player.cp_pool.get_total_cp()
var success = ability_system._pay_ability_cost(cost, null, player)
assert_true(success, "Should successfully pay cost")
assert_eq(player.cp_pool.get_total_cp(), initial_cp - 3, "Should spend 3 CP")
ability_system.free()
func test_pay_specific_element_cp_cost() -> void:
var ability_system = AbilitySystem.new()
var cost = {"cp": 2, "element": "FIRE"}
var player = MockPlayer.new()
player.cp_pool.add_cp(Enums.Element.FIRE, 4)
player.cp_pool.add_cp(Enums.Element.ICE, 3)
var success = ability_system._pay_ability_cost(cost, null, player)
assert_true(success, "Should successfully pay cost")
assert_eq(player.cp_pool.get_cp(Enums.Element.FIRE), 2, "Should spend 2 Fire CP")
assert_eq(player.cp_pool.get_cp(Enums.Element.ICE), 3, "Ice CP should be unchanged")
ability_system.free()
func test_pay_dull_self_cost() -> void:
var ability_system = AbilitySystem.new()
var cost = {"dull_self": true}
var source = _create_mock_card()
source.activate()
var player = MockPlayer.new()
assert_true(source.is_active(), "Source should start active")
var success = ability_system._pay_ability_cost(cost, source, player)
assert_true(success, "Should successfully pay cost")
assert_true(source.is_dull(), "Source should be dulled")
ability_system.free()
func test_pay_combined_cost() -> void:
var ability_system = AbilitySystem.new()
var cost = {"cp": 2, "dull_self": true}
var source = _create_mock_card()
source.activate()
var player = MockPlayer.new()
player.cp_pool.add_cp(Enums.Element.FIRE, 5)
var success = ability_system._pay_ability_cost(cost, source, player)
assert_true(success, "Should successfully pay combined cost")
assert_eq(player.cp_pool.get_total_cp(), 3, "Should spend 2 CP")
assert_true(source.is_dull(), "Source should be dulled")
ability_system.free()
# =============================================================================
# SIGNAL TESTS
# =============================================================================
func test_ability_cost_failed_signal_declared() -> void:
var ability_system = AbilitySystem.new()
# Check signal exists
var signal_exists = ability_system.has_signal("ability_cost_failed")
assert_true(signal_exists, "AbilitySystem should have ability_cost_failed signal")
ability_system.free()
# =============================================================================
# HELPER FUNCTIONS
# =============================================================================
func _create_mock_card() -> CardInstance:
var card = CardInstance.new()
var data = CardDatabase.CardData.new()
data.type = Enums.CardType.FORWARD
data.power = 5000
data.cost = 3
data.name = "Test Card"
data.elements = [Enums.Element.FIRE]
card.card_data = data
card.current_power = 5000
return card
func _create_mock_card_with_name(card_name: String) -> CardInstance:
var card = _create_mock_card()
card.card_data.name = card_name
return card
# =============================================================================
# MOCK CLASSES
# =============================================================================
class MockPlayer:
var cp_pool: CPPool
var hand: Zone
func _init():
cp_pool = CPPool.new()
hand = Zone.new(Enums.ZoneType.HAND, 0)