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,
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
mode: ModifierMode | None = None
value: int | None = None
# Legacy field for backwards compatibility
modifier: int | None = None
def get_value(self, default: int) -> int:
"""Get the modifier value, falling back to default if not specified.
@ -147,8 +139,6 @@ class WeaknessResistance(BaseModel):
"""
if self.value is not None:
return self.value
if self.modifier is not None:
return self.modifier
return default
def get_mode(self, default: ModifierMode) -> ModifierMode:

View File

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

View File

@ -699,41 +699,6 @@ class TestAttackDamage:
assert result.details["weakness"]["mode"] == "multiplicative"
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:
"""
Verify attack_damage fails when no valid target exists.

View File

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