Remove legacy modifier field from WeaknessResistance

Migrate all usages to the proper mode/value fields:
- Weakness: mode=MULTIPLICATIVE, value=2
- Resistance: mode=ADDITIVE, value=-30

Remove backwards compatibility code and legacy test.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Cal Corum 2026-01-29 13:16:51 -06:00
parent f512c7b2b3
commit f93f5b617a
4 changed files with 48 additions and 63 deletions

View File

@ -122,20 +122,12 @@ class WeaknessResistance(BaseModel):
mode=ModifierMode.ADDITIVE, mode=ModifierMode.ADDITIVE,
value=40, # +40 damage instead of x2 value=40, # +40 damage instead of x2
) )
Legacy Support:
The old 'modifier' field is deprecated but still works for backwards
compatibility. If 'modifier' is provided without 'value', it will be
used as the value. The mode will still default to CombatConfig.
""" """
energy_type: EnergyType energy_type: EnergyType
mode: ModifierMode | None = None mode: ModifierMode | None = None
value: int | None = None value: int | None = None
# Legacy field for backwards compatibility
modifier: int | None = None
def get_value(self, default: int) -> int: def get_value(self, default: int) -> int:
"""Get the modifier value, falling back to default if not specified. """Get the modifier value, falling back to default if not specified.
@ -147,8 +139,6 @@ class WeaknessResistance(BaseModel):
""" """
if self.value is not None: if self.value is not None:
return self.value return self.value
if self.modifier is not None:
return self.modifier
return default return default
def get_mode(self, default: ModifierMode) -> ModifierMode: def get_mode(self, default: ModifierMode) -> ModifierMode:

View File

@ -19,6 +19,7 @@ from app.core.config import RulesConfig
from app.core.enums import ( from app.core.enums import (
CardType, CardType,
EnergyType, EnergyType,
ModifierMode,
PokemonStage, PokemonStage,
PokemonVariant, PokemonVariant,
TrainerType, TrainerType,
@ -94,7 +95,9 @@ def pikachu_def() -> CardDefinition:
effect_description="Flip a coin. If heads, the Defending Pokemon is now Paralyzed.", effect_description="Flip a coin. If heads, the Defending Pokemon is now Paralyzed.",
), ),
], ],
weakness=WeaknessResistance(energy_type=EnergyType.FIGHTING, modifier=2), weakness=WeaknessResistance(
energy_type=EnergyType.FIGHTING, mode=ModifierMode.MULTIPLICATIVE, value=2
),
retreat_cost=1, retreat_cost=1,
rarity="common", rarity="common",
set_id="base", set_id="base",
@ -123,7 +126,9 @@ def raichu_def() -> CardDefinition:
damage=60, damage=60,
), ),
], ],
weakness=WeaknessResistance(energy_type=EnergyType.FIGHTING, modifier=2), weakness=WeaknessResistance(
energy_type=EnergyType.FIGHTING, mode=ModifierMode.MULTIPLICATIVE, value=2
),
retreat_cost=1, retreat_cost=1,
rarity="rare", rarity="rare",
set_id="base", set_id="base",
@ -154,8 +159,12 @@ def charizard_def() -> CardDefinition:
effect_params={"count": 2, "type": "fire"}, effect_params={"count": 2, "type": "fire"},
), ),
], ],
weakness=WeaknessResistance(energy_type=EnergyType.WATER, modifier=2), weakness=WeaknessResistance(
resistance=WeaknessResistance(energy_type=EnergyType.FIGHTING, modifier=-30), energy_type=EnergyType.WATER, mode=ModifierMode.MULTIPLICATIVE, value=2
),
resistance=WeaknessResistance(
energy_type=EnergyType.FIGHTING, mode=ModifierMode.ADDITIVE, value=-30
),
retreat_cost=3, retreat_cost=3,
rarity="rare_holo", rarity="rare_holo",
set_id="base", set_id="base",
@ -185,7 +194,9 @@ def mewtwo_ex_def() -> CardDefinition:
effect_params={"count": 1, "type": "any"}, effect_params={"count": 1, "type": "any"},
), ),
], ],
weakness=WeaknessResistance(energy_type=EnergyType.PSYCHIC, modifier=2), weakness=WeaknessResistance(
energy_type=EnergyType.PSYCHIC, mode=ModifierMode.MULTIPLICATIVE, value=2
),
retreat_cost=2, retreat_cost=2,
rarity="ultra_rare", rarity="ultra_rare",
set_id="ex_series", set_id="ex_series",
@ -215,7 +226,9 @@ def pikachu_v_def() -> CardDefinition:
effect_params={"amount": 30}, effect_params={"amount": 30},
), ),
], ],
weakness=WeaknessResistance(energy_type=EnergyType.FIGHTING, modifier=2), weakness=WeaknessResistance(
energy_type=EnergyType.FIGHTING, mode=ModifierMode.MULTIPLICATIVE, value=2
),
retreat_cost=2, retreat_cost=2,
rarity="ultra_rare", rarity="ultra_rare",
set_id="v_series", set_id="v_series",
@ -244,7 +257,9 @@ def pikachu_vmax_def() -> CardDefinition:
damage=270, damage=270,
), ),
], ],
weakness=WeaknessResistance(energy_type=EnergyType.FIGHTING, modifier=2), weakness=WeaknessResistance(
energy_type=EnergyType.FIGHTING, mode=ModifierMode.MULTIPLICATIVE, value=2
),
retreat_cost=3, retreat_cost=3,
rarity="secret_rare", rarity="secret_rare",
set_id="vmax_series", set_id="vmax_series",
@ -642,7 +657,9 @@ def charmander_def() -> CardDefinition:
damage=10, damage=10,
), ),
], ],
weakness=WeaknessResistance(energy_type=EnergyType.WATER, modifier=2), weakness=WeaknessResistance(
energy_type=EnergyType.WATER, mode=ModifierMode.MULTIPLICATIVE, value=2
),
retreat_cost=1, retreat_cost=1,
rarity="common", rarity="common",
set_id="base", set_id="base",
@ -671,7 +688,9 @@ def charmeleon_def() -> CardDefinition:
damage=30, damage=30,
), ),
], ],
weakness=WeaknessResistance(energy_type=EnergyType.WATER, modifier=2), weakness=WeaknessResistance(
energy_type=EnergyType.WATER, mode=ModifierMode.MULTIPLICATIVE, value=2
),
retreat_cost=1, retreat_cost=1,
rarity="uncommon", rarity="uncommon",
set_id="base", set_id="base",

View File

@ -699,41 +699,6 @@ class TestAttackDamage:
assert result.details["weakness"]["mode"] == "multiplicative" assert result.details["weakness"]["mode"] == "multiplicative"
assert result.details["weakness"]["value"] == 3 assert result.details["weakness"]["value"] == 3
def test_legacy_modifier_field_still_works(
self, game_state: GameState, rng: SeededRandom
) -> None:
"""
Verify backwards compatibility: old 'modifier' field still works.
"""
# Using legacy 'modifier' field instead of 'value'
game_state.card_registry["charmander-001"] = CardDefinition(
id="charmander-001",
name="Charmander",
card_type=CardType.POKEMON,
stage=PokemonStage.BASIC,
hp=70,
pokemon_type=EnergyType.FIRE,
weakness=WeaknessResistance(
energy_type=EnergyType.LIGHTNING,
modifier=2, # Legacy field
),
)
ctx = make_context(
game_state,
rng,
source_card_id="pikachu-inst",
params={"amount": 30},
)
result = resolve_effect("attack_damage", ctx)
assert result.success
target = game_state.players["player2"].get_active_pokemon()
assert target is not None
assert target.damage == 60 # 30 * 2 (legacy modifier used as value)
assert result.details["weakness"]["value"] == 2
def test_fails_with_no_target(self, game_state: GameState, rng: SeededRandom) -> None: def test_fails_with_no_target(self, game_state: GameState, rng: SeededRandom) -> None:
""" """
Verify attack_damage fails when no valid target exists. Verify attack_damage fails when no valid target exists.

View File

@ -11,6 +11,7 @@ These tests verify:
from app.core.enums import ( from app.core.enums import (
CardType, CardType,
EnergyType, EnergyType,
ModifierMode,
PokemonStage, PokemonStage,
PokemonVariant, PokemonVariant,
StatusCondition, StatusCondition,
@ -156,27 +157,31 @@ class TestWeaknessResistance:
def test_weakness(self) -> None: def test_weakness(self) -> None:
""" """
Verify weakness can be defined. Verify weakness can be defined with multiplicative mode.
""" """
weakness = WeaknessResistance( weakness = WeaknessResistance(
energy_type=EnergyType.FIGHTING, energy_type=EnergyType.FIGHTING,
modifier=2, mode=ModifierMode.MULTIPLICATIVE,
value=2,
) )
assert weakness.energy_type == EnergyType.FIGHTING assert weakness.energy_type == EnergyType.FIGHTING
assert weakness.modifier == 2 assert weakness.mode == ModifierMode.MULTIPLICATIVE
assert weakness.value == 2
def test_resistance(self) -> None: def test_resistance(self) -> None:
""" """
Verify resistance can be defined. Verify resistance can be defined with additive mode.
""" """
resistance = WeaknessResistance( resistance = WeaknessResistance(
energy_type=EnergyType.METAL, energy_type=EnergyType.METAL,
modifier=-30, mode=ModifierMode.ADDITIVE,
value=-30,
) )
assert resistance.energy_type == EnergyType.METAL assert resistance.energy_type == EnergyType.METAL
assert resistance.modifier == -30 assert resistance.mode == ModifierMode.ADDITIVE
assert resistance.value == -30
class TestCardDefinitionPokemon: class TestCardDefinitionPokemon:
@ -205,7 +210,9 @@ class TestCardDefinitionPokemon:
effect_id="may_paralyze", effect_id="may_paralyze",
), ),
], ],
weakness=WeaknessResistance(energy_type=EnergyType.FIGHTING, modifier=2), weakness=WeaknessResistance(
energy_type=EnergyType.FIGHTING, mode=ModifierMode.MULTIPLICATIVE, value=2
),
retreat_cost=1, retreat_cost=1,
) )
@ -1112,8 +1119,12 @@ class TestCardDefinitionJsonRoundTrip:
abilities=[ abilities=[
Ability(name="Static", effect_id="static_paralysis"), Ability(name="Static", effect_id="static_paralysis"),
], ],
weakness=WeaknessResistance(energy_type=EnergyType.FIGHTING, modifier=2), weakness=WeaknessResistance(
resistance=WeaknessResistance(energy_type=EnergyType.METAL, modifier=-30), energy_type=EnergyType.FIGHTING, mode=ModifierMode.MULTIPLICATIVE, value=2
),
resistance=WeaknessResistance(
energy_type=EnergyType.METAL, mode=ModifierMode.ADDITIVE, value=-30
),
retreat_cost=1, retreat_cost=1,
rarity="common", rarity="common",
set_id="base", set_id="base",