diff --git a/backend/data/definitions/_index.json b/backend/data/definitions/_index.json index 6d9dada..88ce365 100644 --- a/backend/data/definitions/_index.json +++ b/backend/data/definitions/_index.json @@ -1,19 +1,19 @@ { - "generated_at": "2026-01-27T19:50:50.134913+00:00", + "generated_at": "2026-01-27T20:34:43.561514+00:00", "schema_version": "1.0", - "total_cards": 378, + "total_cards": 382, "sets": { "a1": { "name": "Genetic Apex", - "card_count": 283, + "card_count": 286, "pokemon_count": 267, - "trainer_count": 16 + "trainer_count": 19 }, "a1a": { "name": "Mythical Island", - "card_count": 85, + "card_count": 86, "pokemon_count": 77, - "trainer_count": 8 + "trainer_count": 9 }, "basic": { "name": "Basic Energy", @@ -1314,6 +1314,24 @@ "card_type": "pokemon", "set_id": "a1" }, + { + "id": "a1-216-helix-fossil", + "name": "Helix Fossil", + "card_type": "trainer", + "set_id": "a1" + }, + { + "id": "a1-217-dome-fossil", + "name": "Dome Fossil", + "card_type": "trainer", + "set_id": "a1" + }, + { + "id": "a1-218-old-amber", + "name": "Old Amber", + "card_type": "trainer", + "set_id": "a1" + }, { "id": "a1-219-erika", "name": "Erika", @@ -2094,6 +2112,12 @@ "card_type": "pokemon", "set_id": "a1a" }, + { + "id": "a1a-063-old-amber", + "name": "Old Amber", + "card_type": "trainer", + "set_id": "a1a" + }, { "id": "a1a-064-pokemon-flute", "name": "Pok\u00e9mon Flute", diff --git a/backend/data/definitions/pokemon/a1/030-lilligant.json b/backend/data/definitions/pokemon/a1/030-lilligant.json index 1440b09..0e2515c 100644 --- a/backend/data/definitions/pokemon/a1/030-lilligant.json +++ b/backend/data/definitions/pokemon/a1/030-lilligant.json @@ -19,7 +19,7 @@ ], "damage": 50, "damage_display": "50", - "effect_description": "Take aEnergy from your Energy Zone and attach it to 1 of your BenchedPok\u00e9mon." + "effect_description": "Take an Energy from your Energy Zone and attach it to 1 of your Benched Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/033-charmander.json b/backend/data/definitions/pokemon/a1/033-charmander.json index c1fd8a4..291c85d 100644 --- a/backend/data/definitions/pokemon/a1/033-charmander.json +++ b/backend/data/definitions/pokemon/a1/033-charmander.json @@ -17,7 +17,7 @@ ], "damage": 30, "damage_display": "30", - "effect_description": "Discard aEnergy from this Pok\u00e9mon." + "effect_description": "Discard an Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/035-charizard.json b/backend/data/definitions/pokemon/a1/035-charizard.json index 20a3651..4c2ab2f 100644 --- a/backend/data/definitions/pokemon/a1/035-charizard.json +++ b/backend/data/definitions/pokemon/a1/035-charizard.json @@ -21,7 +21,7 @@ ], "damage": 150, "damage_display": "150", - "effect_description": "Discard 2Energy from this Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/036-charizard-ex.json b/backend/data/definitions/pokemon/a1/036-charizard-ex.json index c53fa9a..9b81b98 100644 --- a/backend/data/definitions/pokemon/a1/036-charizard-ex.json +++ b/backend/data/definitions/pokemon/a1/036-charizard-ex.json @@ -31,7 +31,7 @@ ], "damage": 200, "damage_display": "200", - "effect_description": "Discard 2Energy from this Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/038-ninetales.json b/backend/data/definitions/pokemon/a1/038-ninetales.json index 9a7d21f..d3f2f13 100644 --- a/backend/data/definitions/pokemon/a1/038-ninetales.json +++ b/backend/data/definitions/pokemon/a1/038-ninetales.json @@ -19,7 +19,7 @@ ], "damage": 90, "damage_display": "90", - "effect_description": "Discard aEnergy from this Pok\u00e9mon." + "effect_description": "Discard an Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/045-flareon.json b/backend/data/definitions/pokemon/a1/045-flareon.json index 2b95786..7997cd0 100644 --- a/backend/data/definitions/pokemon/a1/045-flareon.json +++ b/backend/data/definitions/pokemon/a1/045-flareon.json @@ -20,7 +20,7 @@ ], "damage": 110, "damage_display": "110", - "effect_description": "Discard aEnergy from this Pok\u00e9mon." + "effect_description": "Discard an Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/047-moltres-ex.json b/backend/data/definitions/pokemon/a1/047-moltres-ex.json index 5d2c771..516dc18 100644 --- a/backend/data/definitions/pokemon/a1/047-moltres-ex.json +++ b/backend/data/definitions/pokemon/a1/047-moltres-ex.json @@ -16,7 +16,7 @@ "fire" ], "damage": 0, - "effect_description": "Flip 3 coins. Take an amount ofEnergy from your Energy Zone equal to the number of heads and attach it to your BenchedPok\u00e9mon in any way you like." + "effect_description": "Flip 3 coins. Take an amount of Energy from your Energy Zone equal to the number of heads and attach it to your Benched Pok\u00e9mon in any way you like." }, { "name": "Heat Blast", diff --git a/backend/data/definitions/pokemon/a1/052-centiskorch.json b/backend/data/definitions/pokemon/a1/052-centiskorch.json index 24906d7..0f4eea2 100644 --- a/backend/data/definitions/pokemon/a1/052-centiskorch.json +++ b/backend/data/definitions/pokemon/a1/052-centiskorch.json @@ -21,7 +21,7 @@ ], "damage": 130, "damage_display": "130", - "effect_description": "Discard aEnergy from this Pok\u00e9mon." + "effect_description": "Discard an Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/055-blastoise.json b/backend/data/definitions/pokemon/a1/055-blastoise.json index b2e31ce..df22449 100644 --- a/backend/data/definitions/pokemon/a1/055-blastoise.json +++ b/backend/data/definitions/pokemon/a1/055-blastoise.json @@ -20,7 +20,7 @@ ], "damage": 80, "damage_display": "80x", - "effect_description": "If this Pok\u00e9mon has at least 2 extraEnergy attached, this attack does 60 more damage.", + "effect_description": "If this Pok\u00e9mon has at least 2 extra Energy attached, this attack does 60 more damage.", "effect_params": { "damage_modifier": "x" } diff --git a/backend/data/definitions/pokemon/a1/056-blastoise-ex.json b/backend/data/definitions/pokemon/a1/056-blastoise-ex.json index 41b3936..51682ad 100644 --- a/backend/data/definitions/pokemon/a1/056-blastoise-ex.json +++ b/backend/data/definitions/pokemon/a1/056-blastoise-ex.json @@ -29,7 +29,7 @@ ], "damage": 100, "damage_display": "100x", - "effect_description": "If this Pok\u00e9mon has at least 2 extraEnergy attached, this attack does 60 more damage.", + "effect_description": "If this Pok\u00e9mon has at least 2 extra Energy attached, this attack does 60 more damage.", "effect_params": { "damage_modifier": "x" } diff --git a/backend/data/definitions/pokemon/a1/079-lapras.json b/backend/data/definitions/pokemon/a1/079-lapras.json index 0e6a245..297730f 100644 --- a/backend/data/definitions/pokemon/a1/079-lapras.json +++ b/backend/data/definitions/pokemon/a1/079-lapras.json @@ -17,7 +17,7 @@ ], "damage": 20, "damage_display": "20x", - "effect_description": "If this Pok\u00e9mon has at least 3 extraEnergy attached, this attack does 70 more damage.", + "effect_description": "If this Pok\u00e9mon has at least 3 extra Energy attached, this attack does 70 more damage.", "effect_params": { "damage_modifier": "x" } diff --git a/backend/data/definitions/pokemon/a1/096-pikachu-ex.json b/backend/data/definitions/pokemon/a1/096-pikachu-ex.json index 9bf09a6..92a9776 100644 --- a/backend/data/definitions/pokemon/a1/096-pikachu-ex.json +++ b/backend/data/definitions/pokemon/a1/096-pikachu-ex.json @@ -18,7 +18,7 @@ ], "damage": 30, "damage_display": "30+", - "effect_description": "This attack does 30 damage for each of your BenchedPok\u00e9mon.", + "effect_description": "This attack does 30 damage for each of your Benched Pok\u00e9mon.", "effect_params": { "damage_modifier": "+" } diff --git a/backend/data/definitions/pokemon/a1/098-magneton.json b/backend/data/definitions/pokemon/a1/098-magneton.json index 7d23746..5db204b 100644 --- a/backend/data/definitions/pokemon/a1/098-magneton.json +++ b/backend/data/definitions/pokemon/a1/098-magneton.json @@ -27,7 +27,7 @@ { "name": "Volt Charge", "effect_id": "unimplemented", - "effect_description": "Once during your turn, you may take aEnergy from your Energy Zone and attach it to this Pok\u00e9mon." + "effect_description": "Once during your turn, you may take an Energy from your Energy Zone and attach it to this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/128-mewtwo.json b/backend/data/definitions/pokemon/a1/128-mewtwo.json index 6522b60..215fe58 100644 --- a/backend/data/definitions/pokemon/a1/128-mewtwo.json +++ b/backend/data/definitions/pokemon/a1/128-mewtwo.json @@ -20,7 +20,7 @@ ], "damage": 120, "damage_display": "120", - "effect_description": "Discard 2Energy from this Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/129-mewtwo-ex.json b/backend/data/definitions/pokemon/a1/129-mewtwo-ex.json index ddbf5d9..a27cc16 100644 --- a/backend/data/definitions/pokemon/a1/129-mewtwo-ex.json +++ b/backend/data/definitions/pokemon/a1/129-mewtwo-ex.json @@ -29,7 +29,7 @@ ], "damage": 150, "damage_display": "150", - "effect_description": "Discard 2Energy from this Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/132-gardevoir.json b/backend/data/definitions/pokemon/a1/132-gardevoir.json index b0b124b..fad29b2 100644 --- a/backend/data/definitions/pokemon/a1/132-gardevoir.json +++ b/backend/data/definitions/pokemon/a1/132-gardevoir.json @@ -26,7 +26,7 @@ { "name": "Psy Shadow", "effect_id": "unimplemented", - "effect_description": "Once during your turn, you may take aEnergy from your Energy Zone and attach it to thePok\u00e9mon in the Active Spot." + "effect_description": "Once during your turn, you may take an Energy from your Energy Zone and attach it to the Pok\u00e9mon in the Active Spot." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/181-meltan.json b/backend/data/definitions/pokemon/a1/181-meltan.json index 64fdda7..cf25b1e 100644 --- a/backend/data/definitions/pokemon/a1/181-meltan.json +++ b/backend/data/definitions/pokemon/a1/181-meltan.json @@ -16,7 +16,7 @@ "metal" ], "damage": 0, - "effect_description": "Take aEnergy from your Energy Zone and attach it to this Pok\u00e9mon." + "effect_description": "Take an Energy from your Energy Zone and attach it to this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/230-charmander.json b/backend/data/definitions/pokemon/a1/230-charmander.json index ce532b1..4631f0a 100644 --- a/backend/data/definitions/pokemon/a1/230-charmander.json +++ b/backend/data/definitions/pokemon/a1/230-charmander.json @@ -17,7 +17,7 @@ ], "damage": 30, "damage_display": "30", - "effect_description": "Discard aEnergy from this Pok\u00e9mon." + "effect_description": "Discard an Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/234-lapras.json b/backend/data/definitions/pokemon/a1/234-lapras.json index be6a9a2..c99faed 100644 --- a/backend/data/definitions/pokemon/a1/234-lapras.json +++ b/backend/data/definitions/pokemon/a1/234-lapras.json @@ -17,7 +17,7 @@ ], "damage": 20, "damage_display": "20x", - "effect_description": "If this Pok\u00e9mon has at least 3 extraEnergy attached, this attack does 70 more damage.", + "effect_description": "If this Pok\u00e9mon has at least 3 extra Energy attached, this attack does 70 more damage.", "effect_params": { "damage_modifier": "x" } diff --git a/backend/data/definitions/pokemon/a1/253-charizard-ex.json b/backend/data/definitions/pokemon/a1/253-charizard-ex.json index aa433d9..6d60d5a 100644 --- a/backend/data/definitions/pokemon/a1/253-charizard-ex.json +++ b/backend/data/definitions/pokemon/a1/253-charizard-ex.json @@ -31,7 +31,7 @@ ], "damage": 200, "damage_display": "200", - "effect_description": "Discard 2Energy from this Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/255-moltres-ex.json b/backend/data/definitions/pokemon/a1/255-moltres-ex.json index 6b4c104..269f6b9 100644 --- a/backend/data/definitions/pokemon/a1/255-moltres-ex.json +++ b/backend/data/definitions/pokemon/a1/255-moltres-ex.json @@ -16,7 +16,7 @@ "fire" ], "damage": 0, - "effect_description": "Flip 3 coins. Take an amount ofEnergy from your Energy Zone equal to the number of heads and attach it to your BenchedPok\u00e9mon in any way you like." + "effect_description": "Flip 3 coins. Take an amount of Energy from your Energy Zone equal to the number of heads and attach it to your Benched Pok\u00e9mon in any way you like." }, { "name": "Heat Blast", diff --git a/backend/data/definitions/pokemon/a1/256-blastoise-ex.json b/backend/data/definitions/pokemon/a1/256-blastoise-ex.json index 61e9ea2..d65b34f 100644 --- a/backend/data/definitions/pokemon/a1/256-blastoise-ex.json +++ b/backend/data/definitions/pokemon/a1/256-blastoise-ex.json @@ -29,7 +29,7 @@ ], "damage": 100, "damage_display": "100x", - "effect_description": "If this Pok\u00e9mon has at least 2 extraEnergy attached, this attack does 60 more damage.", + "effect_description": "If this Pok\u00e9mon has at least 2 extra Energy attached, this attack does 60 more damage.", "effect_params": { "damage_modifier": "x" } diff --git a/backend/data/definitions/pokemon/a1/259-pikachu-ex.json b/backend/data/definitions/pokemon/a1/259-pikachu-ex.json index acc4ff0..01c5a0d 100644 --- a/backend/data/definitions/pokemon/a1/259-pikachu-ex.json +++ b/backend/data/definitions/pokemon/a1/259-pikachu-ex.json @@ -18,7 +18,7 @@ ], "damage": 30, "damage_display": "30+", - "effect_description": "This attack does 30 damage for each of your BenchedPok\u00e9mon.", + "effect_description": "This attack does 30 damage for each of your Benched Pok\u00e9mon.", "effect_params": { "damage_modifier": "+" } diff --git a/backend/data/definitions/pokemon/a1/262-mewtwo-ex.json b/backend/data/definitions/pokemon/a1/262-mewtwo-ex.json index a423977..eed941a 100644 --- a/backend/data/definitions/pokemon/a1/262-mewtwo-ex.json +++ b/backend/data/definitions/pokemon/a1/262-mewtwo-ex.json @@ -29,7 +29,7 @@ ], "damage": 150, "damage_display": "150", - "effect_description": "Discard 2Energy from this Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/274-moltres-ex.json b/backend/data/definitions/pokemon/a1/274-moltres-ex.json index 73c2aef..5e882a9 100644 --- a/backend/data/definitions/pokemon/a1/274-moltres-ex.json +++ b/backend/data/definitions/pokemon/a1/274-moltres-ex.json @@ -16,7 +16,7 @@ "fire" ], "damage": 0, - "effect_description": "Flip 3 coins. Take an amount ofEnergy from your Energy Zone equal to the number of heads and attach it to your BenchedPok\u00e9mon in any way you like." + "effect_description": "Flip 3 coins. Take an amount of Energy from your Energy Zone equal to the number of heads and attach it to your Benched Pok\u00e9mon in any way you like." }, { "name": "Heat Blast", diff --git a/backend/data/definitions/pokemon/a1/280-charizard-ex.json b/backend/data/definitions/pokemon/a1/280-charizard-ex.json index ba53f6f..e190d10 100644 --- a/backend/data/definitions/pokemon/a1/280-charizard-ex.json +++ b/backend/data/definitions/pokemon/a1/280-charizard-ex.json @@ -31,7 +31,7 @@ ], "damage": 200, "damage_display": "200", - "effect_description": "Discard 2Energy from this Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/281-pikachu-ex.json b/backend/data/definitions/pokemon/a1/281-pikachu-ex.json index 49355fb..66f1619 100644 --- a/backend/data/definitions/pokemon/a1/281-pikachu-ex.json +++ b/backend/data/definitions/pokemon/a1/281-pikachu-ex.json @@ -18,7 +18,7 @@ ], "damage": 30, "damage_display": "30+", - "effect_description": "This attack does 30 damage for each of your BenchedPok\u00e9mon.", + "effect_description": "This attack does 30 damage for each of your Benched Pok\u00e9mon.", "effect_params": { "damage_modifier": "+" } diff --git a/backend/data/definitions/pokemon/a1/282-mewtwo-ex.json b/backend/data/definitions/pokemon/a1/282-mewtwo-ex.json index 9cd2ed0..a15fc76 100644 --- a/backend/data/definitions/pokemon/a1/282-mewtwo-ex.json +++ b/backend/data/definitions/pokemon/a1/282-mewtwo-ex.json @@ -29,7 +29,7 @@ ], "damage": 150, "damage_display": "150", - "effect_description": "Discard 2Energy from this Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/284-charizard-ex.json b/backend/data/definitions/pokemon/a1/284-charizard-ex.json index 767ee9c..ba4db4e 100644 --- a/backend/data/definitions/pokemon/a1/284-charizard-ex.json +++ b/backend/data/definitions/pokemon/a1/284-charizard-ex.json @@ -31,7 +31,7 @@ ], "damage": 200, "damage_display": "200", - "effect_description": "Discard 2Energy from this Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1/285-pikachu-ex.json b/backend/data/definitions/pokemon/a1/285-pikachu-ex.json index a617012..d5f5c18 100644 --- a/backend/data/definitions/pokemon/a1/285-pikachu-ex.json +++ b/backend/data/definitions/pokemon/a1/285-pikachu-ex.json @@ -18,7 +18,7 @@ ], "damage": 30, "damage_display": "30+", - "effect_description": "This attack does 30 damage for each of your BenchedPok\u00e9mon.", + "effect_description": "This attack does 30 damage for each of your Benched Pok\u00e9mon.", "effect_params": { "damage_modifier": "+" } diff --git a/backend/data/definitions/pokemon/a1/286-mewtwo-ex.json b/backend/data/definitions/pokemon/a1/286-mewtwo-ex.json index a7f9f5f..9685adf 100644 --- a/backend/data/definitions/pokemon/a1/286-mewtwo-ex.json +++ b/backend/data/definitions/pokemon/a1/286-mewtwo-ex.json @@ -29,7 +29,7 @@ ], "damage": 150, "damage_display": "150", - "effect_description": "Discard 2Energy from this Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1a/001-exeggcute.json b/backend/data/definitions/pokemon/a1a/001-exeggcute.json index b90398f..af80fad 100644 --- a/backend/data/definitions/pokemon/a1a/001-exeggcute.json +++ b/backend/data/definitions/pokemon/a1a/001-exeggcute.json @@ -16,7 +16,7 @@ "colorless" ], "damage": 0, - "effect_description": "Take aEnergy from your Energy Zone and attach it to this Pok\u00e9mon." + "effect_description": "Take an Energy from your Energy Zone and attach it to this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1a/006-serperior.json b/backend/data/definitions/pokemon/a1a/006-serperior.json index cb00cc8..68aeb7a 100644 --- a/backend/data/definitions/pokemon/a1a/006-serperior.json +++ b/backend/data/definitions/pokemon/a1a/006-serperior.json @@ -27,7 +27,7 @@ { "name": "Jungle Totem", "effect_id": "unimplemented", - "effect_description": "EachEnergy attached to yourPok\u00e9mon provides 2Energy. This effect doesn\u2019t stack." + "effect_description": "EachEnergy attached to your Pok\u00e9mon provides 2 Energy. This effect doesn\u2019t stack." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1a/009-dhelmise.json b/backend/data/definitions/pokemon/a1a/009-dhelmise.json index 4abc918..0a23128 100644 --- a/backend/data/definitions/pokemon/a1a/009-dhelmise.json +++ b/backend/data/definitions/pokemon/a1a/009-dhelmise.json @@ -17,7 +17,7 @@ ], "damage": 20, "damage_display": "20x", - "effect_description": "If this Pok\u00e9mon has at least 3 extraEnergy attached, this attack does 70 more damage.", + "effect_description": "If this Pok\u00e9mon has at least 3 extra Energy attached, this attack does 70 more damage.", "effect_params": { "damage_modifier": "x" } diff --git a/backend/data/definitions/pokemon/a1a/012-magmar.json b/backend/data/definitions/pokemon/a1a/012-magmar.json index b8b4cee..e9934b7 100644 --- a/backend/data/definitions/pokemon/a1a/012-magmar.json +++ b/backend/data/definitions/pokemon/a1a/012-magmar.json @@ -18,7 +18,7 @@ ], "damage": 80, "damage_display": "80", - "effect_description": "Discard 2Energy from this Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1a/014-volcarona.json b/backend/data/definitions/pokemon/a1a/014-volcarona.json index 1ca2e9e..020e82f 100644 --- a/backend/data/definitions/pokemon/a1a/014-volcarona.json +++ b/backend/data/definitions/pokemon/a1a/014-volcarona.json @@ -19,7 +19,7 @@ "colorless" ], "damage": 0, - "effect_description": "Discard 2Energy from this Pok\u00e9mon. This attack does 80 damage to 1 of your opponent\u2019s Pok\u00e9mon." + "effect_description": "Discard 2 Energy from this Pok\u00e9mon. This attack does 80 damage to 1 of your opponent\u2019s Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1a/019-vaporeon.json b/backend/data/definitions/pokemon/a1a/019-vaporeon.json index 410d0e3..c01232f 100644 --- a/backend/data/definitions/pokemon/a1a/019-vaporeon.json +++ b/backend/data/definitions/pokemon/a1a/019-vaporeon.json @@ -26,7 +26,7 @@ { "name": "Wash Out", "effect_id": "unimplemented", - "effect_description": "As often as you like during your turn, you may move aEnergy from 1 of your BenchedPok\u00e9mon to your ActivePok\u00e9mon." + "effect_description": "As often as you like during your turn, you may move an Energy from 1 of your Benched Pok\u00e9mon to your Active Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1a/025-pikachu.json b/backend/data/definitions/pokemon/a1a/025-pikachu.json index ebab178..42487c6 100644 --- a/backend/data/definitions/pokemon/a1a/025-pikachu.json +++ b/backend/data/definitions/pokemon/a1a/025-pikachu.json @@ -17,7 +17,7 @@ ], "damage": 10, "damage_display": "10+", - "effect_description": "This attack does 10 damage for each of your BenchedPok\u00e9mon.", + "effect_description": "This attack does 10 damage for each of your Benched Pok\u00e9mon.", "effect_params": { "damage_modifier": "+" } diff --git a/backend/data/definitions/pokemon/a1a/070-serperior.json b/backend/data/definitions/pokemon/a1a/070-serperior.json index 63f858e..a26d65f 100644 --- a/backend/data/definitions/pokemon/a1a/070-serperior.json +++ b/backend/data/definitions/pokemon/a1a/070-serperior.json @@ -27,7 +27,7 @@ { "name": "Jungle Totem", "effect_id": "unimplemented", - "effect_description": "EachEnergy attached to yourPok\u00e9mon provides 2Energy. This effect doesn\u2019t stack." + "effect_description": "EachEnergy attached to your Pok\u00e9mon provides 2 Energy. This effect doesn\u2019t stack." } ], "weakness": { diff --git a/backend/data/definitions/pokemon/a1a/072-vaporeon.json b/backend/data/definitions/pokemon/a1a/072-vaporeon.json index af32462..85c0fc1 100644 --- a/backend/data/definitions/pokemon/a1a/072-vaporeon.json +++ b/backend/data/definitions/pokemon/a1a/072-vaporeon.json @@ -26,7 +26,7 @@ { "name": "Wash Out", "effect_id": "unimplemented", - "effect_description": "As often as you like during your turn, you may move aEnergy from 1 of your BenchedPok\u00e9mon to your ActivePok\u00e9mon." + "effect_description": "As often as you like during your turn, you may move an Energy from 1 of your Benched Pok\u00e9mon to your Active Pok\u00e9mon." } ], "weakness": { diff --git a/backend/data/definitions/trainer/a1/216-helix-fossil.json b/backend/data/definitions/trainer/a1/216-helix-fossil.json new file mode 100644 index 0000000..4db6e62 --- /dev/null +++ b/backend/data/definitions/trainer/a1/216-helix-fossil.json @@ -0,0 +1,10 @@ +{ + "id": "a1-216-helix-fossil", + "name": "Helix Fossil", + "card_type": "trainer", + "trainer_type": "item", + "set_id": "a1", + "rarity": "common", + "effect_description": "Play this card as if it were a 40 HP Basic Pok\u00e9mon.At any time during your turn, you may discard this card from play.This card can\u2019t retreat.You may play any number of Item cards during your turn.", + "illustrator": "Toyste Beach" +} \ No newline at end of file diff --git a/backend/data/definitions/trainer/a1/217-dome-fossil.json b/backend/data/definitions/trainer/a1/217-dome-fossil.json new file mode 100644 index 0000000..b627309 --- /dev/null +++ b/backend/data/definitions/trainer/a1/217-dome-fossil.json @@ -0,0 +1,10 @@ +{ + "id": "a1-217-dome-fossil", + "name": "Dome Fossil", + "card_type": "trainer", + "trainer_type": "item", + "set_id": "a1", + "rarity": "common", + "effect_description": "Play this card as if it were a 40 HP Basic Pok\u00e9mon.At any time during your turn, you may discard this card from play.This card can\u2019t retreat.You may play any number of Item cards during your turn.", + "illustrator": "Toyste Beach" +} \ No newline at end of file diff --git a/backend/data/definitions/trainer/a1/218-old-amber.json b/backend/data/definitions/trainer/a1/218-old-amber.json new file mode 100644 index 0000000..8bf1107 --- /dev/null +++ b/backend/data/definitions/trainer/a1/218-old-amber.json @@ -0,0 +1,10 @@ +{ + "id": "a1-218-old-amber", + "name": "Old Amber", + "card_type": "trainer", + "trainer_type": "item", + "set_id": "a1", + "rarity": "common", + "effect_description": "Play this card as if it were a 40 HP Basic Pok\u00e9mon.At any time during your turn, you may discard this card from play.This card can\u2019t retreat.You may play any number of Item cards during your turn.", + "illustrator": "Toyste Beach" +} \ No newline at end of file diff --git a/backend/data/definitions/trainer/a1/219-erika.json b/backend/data/definitions/trainer/a1/219-erika.json index 072c687..84e6da1 100644 --- a/backend/data/definitions/trainer/a1/219-erika.json +++ b/backend/data/definitions/trainer/a1/219-erika.json @@ -5,6 +5,6 @@ "trainer_type": "supporter", "set_id": "a1", "rarity": "uncommon", - "effect_description": "Heal 50 damage from 1 of yourPok\u00e9mon.You may play only 1 Supporter card during your turn.", + "effect_description": "Heal 50 damage from 1 of your Pok\u00e9mon.You may play only 1 Supporter card during your turn.", "illustrator": "kirisAki" } \ No newline at end of file diff --git a/backend/data/definitions/trainer/a1/220-misty.json b/backend/data/definitions/trainer/a1/220-misty.json index 8e137f1..78ecdf5 100644 --- a/backend/data/definitions/trainer/a1/220-misty.json +++ b/backend/data/definitions/trainer/a1/220-misty.json @@ -5,6 +5,6 @@ "trainer_type": "supporter", "set_id": "a1", "rarity": "uncommon", - "effect_description": "Choose 1 of yourPok\u00e9mon, and flip a coin until you get tails. For each heads, take aEnergy from your Energy Zone and attach it to that Pok\u00e9mon.You may play only 1 Supporter card during your turn.", + "effect_description": "Choose 1 of your Pok\u00e9mon, and flip a coin until you get tails. For each heads, take an Energy from your Energy Zone and attach it to that Pok\u00e9mon.You may play only 1 Supporter card during your turn.", "illustrator": "Sanosuke Sakuma" } \ No newline at end of file diff --git a/backend/data/definitions/trainer/a1/224-brock.json b/backend/data/definitions/trainer/a1/224-brock.json index c72b198..15d56cd 100644 --- a/backend/data/definitions/trainer/a1/224-brock.json +++ b/backend/data/definitions/trainer/a1/224-brock.json @@ -5,6 +5,6 @@ "trainer_type": "supporter", "set_id": "a1", "rarity": "uncommon", - "effect_description": "Take aEnergy from your Energy Zone and attach it toGolemorOnix.You may play only 1 Supporter card during your turn.", + "effect_description": "Take an Energy from your Energy Zone and attach it toGolemorOnix.You may play only 1 Supporter card during your turn.", "illustrator": "Taira Akitsu" } \ No newline at end of file diff --git a/backend/data/definitions/trainer/a1/266-erika.json b/backend/data/definitions/trainer/a1/266-erika.json index b1c45c5..5344a6e 100644 --- a/backend/data/definitions/trainer/a1/266-erika.json +++ b/backend/data/definitions/trainer/a1/266-erika.json @@ -5,6 +5,6 @@ "trainer_type": "supporter", "set_id": "a1", "rarity": "special art rare", - "effect_description": "Heal 50 damage from 1 of yourPok\u00e9mon.You may play only 1 Supporter card during your turn.", + "effect_description": "Heal 50 damage from 1 of your Pok\u00e9mon.You may play only 1 Supporter card during your turn.", "illustrator": "saino misaki" } \ No newline at end of file diff --git a/backend/data/definitions/trainer/a1/267-misty.json b/backend/data/definitions/trainer/a1/267-misty.json index fcd451a..5932813 100644 --- a/backend/data/definitions/trainer/a1/267-misty.json +++ b/backend/data/definitions/trainer/a1/267-misty.json @@ -5,6 +5,6 @@ "trainer_type": "supporter", "set_id": "a1", "rarity": "special art rare", - "effect_description": "Choose 1 of yourPok\u00e9mon, and flip a coin until you get tails. For each heads, take aEnergy from your Energy Zone and attach it to that Pok\u00e9mon.You may play only 1 Supporter card during your turn.", + "effect_description": "Choose 1 of your Pok\u00e9mon, and flip a coin until you get tails. For each heads, take an Energy from your Energy Zone and attach it to that Pok\u00e9mon.You may play only 1 Supporter card during your turn.", "illustrator": "Sanosuke Sakuma" } \ No newline at end of file diff --git a/backend/data/definitions/trainer/a1/271-brock.json b/backend/data/definitions/trainer/a1/271-brock.json index 6eb24ac..203ec8a 100644 --- a/backend/data/definitions/trainer/a1/271-brock.json +++ b/backend/data/definitions/trainer/a1/271-brock.json @@ -5,6 +5,6 @@ "trainer_type": "supporter", "set_id": "a1", "rarity": "special art rare", - "effect_description": "Take aEnergy from your Energy Zone and attach it toGolemorOnix.You may play only 1 Supporter card during your turn.", + "effect_description": "Take an Energy from your Energy Zone and attach it toGolemorOnix.You may play only 1 Supporter card during your turn.", "illustrator": "Ryuta Fuse" } \ No newline at end of file diff --git a/backend/data/definitions/trainer/a1a/063-old-amber.json b/backend/data/definitions/trainer/a1a/063-old-amber.json new file mode 100644 index 0000000..ca63743 --- /dev/null +++ b/backend/data/definitions/trainer/a1a/063-old-amber.json @@ -0,0 +1,10 @@ +{ + "id": "a1a-063-old-amber", + "name": "Old Amber", + "card_type": "trainer", + "trainer_type": "item", + "set_id": "a1a", + "rarity": "common", + "effect_description": "Play this card as if it were a 40 HP Basic Pok\u00e9mon.At any time during your turn, you may discard this card from play.This card can\u2019t retreat.You may play any number of Item cards during your turn.", + "illustrator": "Toyste Beach" +} \ No newline at end of file diff --git a/backend/data/definitions/trainer/a1a/065-mythical-slab.json b/backend/data/definitions/trainer/a1a/065-mythical-slab.json index 891c8d1..9345814 100644 --- a/backend/data/definitions/trainer/a1a/065-mythical-slab.json +++ b/backend/data/definitions/trainer/a1a/065-mythical-slab.json @@ -5,7 +5,7 @@ "trainer_type": "item", "set_id": "a1a", "rarity": "uncommon", - "effect_description": "Look at the top card of your deck. If that card is aPok\u00e9mon, put it into your hand. If it is not aPok\u00e9mon, put it on the bottom of your deck.You may play any number of Item cards during your turn.", + "effect_description": "Look at the top card of your deck. If that card is a Pok\u00e9mon, put it into your hand. If it is not a Pok\u00e9mon, put it on the bottom of your deck.You may play any number of Item cards during your turn.", "illustrator": "AYUMI ODASHIMA", "image_path": "trainer/a1a/065-mythical-slab.webp", "image_url": "https://cdn.mantimon.com/cards/trainer/a1a/065-mythical-slab.webp" diff --git a/backend/data/raw/_index.json b/backend/data/raw/_index.json index c59b35f..ac5fa9b 100644 --- a/backend/data/raw/_index.json +++ b/backend/data/raw/_index.json @@ -1,5 +1,5 @@ { - "generated_at": "2026-01-27T05:20:57.150621+00:00", + "generated_at": "2026-01-27T20:34:02.631664+00:00", "schema_version": "1.0", "sets": { "a1": { diff --git a/backend/data/raw/a1/030-lilligant.json b/backend/data/raw/a1/030-lilligant.json index d545d2d..480b3ad 100644 --- a/backend/data/raw/a1/030-lilligant.json +++ b/backend/data/raw/a1/030-lilligant.json @@ -24,7 +24,7 @@ ], "damage": 50, "damage_modifier": null, - "effect_text": "Take aEnergy from your Energy Zone and attach it to 1 of your BenchedPokémon.", + "effect_text": "Take an Energy from your Energy Zone and attach it to 1 of your Benched Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/033-charmander.json b/backend/data/raw/a1/033-charmander.json index 1f9cf40..ef8c612 100644 --- a/backend/data/raw/a1/033-charmander.json +++ b/backend/data/raw/a1/033-charmander.json @@ -23,7 +23,7 @@ ], "damage": 30, "damage_modifier": null, - "effect_text": "Discard aEnergy from this Pokémon.", + "effect_text": "Discard an Energy from this Pokémon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/035-charizard.json b/backend/data/raw/a1/035-charizard.json index 1087829..b2e8fa1 100644 --- a/backend/data/raw/a1/035-charizard.json +++ b/backend/data/raw/a1/035-charizard.json @@ -26,7 +26,7 @@ ], "damage": 150, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/036-charizard-ex.json b/backend/data/raw/a1/036-charizard-ex.json index 2f22e30..8f27568 100644 --- a/backend/data/raw/a1/036-charizard-ex.json +++ b/backend/data/raw/a1/036-charizard-ex.json @@ -38,7 +38,7 @@ ], "damage": 200, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/038-ninetales.json b/backend/data/raw/a1/038-ninetales.json index 90c5d0a..4420907 100644 --- a/backend/data/raw/a1/038-ninetales.json +++ b/backend/data/raw/a1/038-ninetales.json @@ -24,7 +24,7 @@ ], "damage": 90, "damage_modifier": null, - "effect_text": "Discard aEnergy from this Pokémon.", + "effect_text": "Discard an Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/045-flareon.json b/backend/data/raw/a1/045-flareon.json index 22105bc..2715685 100644 --- a/backend/data/raw/a1/045-flareon.json +++ b/backend/data/raw/a1/045-flareon.json @@ -25,7 +25,7 @@ ], "damage": 110, "damage_modifier": null, - "effect_text": "Discard aEnergy from this Pokémon.", + "effect_text": "Discard an Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/047-moltres-ex.json b/backend/data/raw/a1/047-moltres-ex.json index 550cd56..ad64a6d 100644 --- a/backend/data/raw/a1/047-moltres-ex.json +++ b/backend/data/raw/a1/047-moltres-ex.json @@ -23,7 +23,7 @@ ], "damage": null, "damage_modifier": null, - "effect_text": "Flip 3 coins. Take an amount ofEnergy from your Energy Zone equal to the number of heads and attach it to your BenchedPokémon in any way you like.", + "effect_text": "Flip 3 coins. Take an amount of Energy from your Energy Zone equal to the number of heads and attach it to your Benched Pok\u00e9mon in any way you like.", "effect_id": null }, { diff --git a/backend/data/raw/a1/052-centiskorch.json b/backend/data/raw/a1/052-centiskorch.json index 3d484cc..f46ad9d 100644 --- a/backend/data/raw/a1/052-centiskorch.json +++ b/backend/data/raw/a1/052-centiskorch.json @@ -26,7 +26,7 @@ ], "damage": 130, "damage_modifier": null, - "effect_text": "Discard aEnergy from this Pokémon.", + "effect_text": "Discard an Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/055-blastoise.json b/backend/data/raw/a1/055-blastoise.json index 3f0fd6c..50e3a87 100644 --- a/backend/data/raw/a1/055-blastoise.json +++ b/backend/data/raw/a1/055-blastoise.json @@ -25,7 +25,7 @@ ], "damage": 80, "damage_modifier": "x", - "effect_text": "If this Pokémon has at least 2 extraEnergy attached, this attack does 60 more damage.", + "effect_text": "If this Pok\u00e9mon has at least 2 extra Energy attached, this attack does 60 more damage.", "effect_id": null } ], diff --git a/backend/data/raw/a1/056-blastoise-ex.json b/backend/data/raw/a1/056-blastoise-ex.json index aabd0ea..5827eaa 100644 --- a/backend/data/raw/a1/056-blastoise-ex.json +++ b/backend/data/raw/a1/056-blastoise-ex.json @@ -36,7 +36,7 @@ ], "damage": 100, "damage_modifier": "x", - "effect_text": "If this Pokémon has at least 2 extraEnergy attached, this attack does 60 more damage.", + "effect_text": "If this Pok\u00e9mon has at least 2 extra Energy attached, this attack does 60 more damage.", "effect_id": null } ], diff --git a/backend/data/raw/a1/079-lapras.json b/backend/data/raw/a1/079-lapras.json index dd30f89..d8c0195 100644 --- a/backend/data/raw/a1/079-lapras.json +++ b/backend/data/raw/a1/079-lapras.json @@ -23,7 +23,7 @@ ], "damage": 20, "damage_modifier": "x", - "effect_text": "If this Pokémon has at least 3 extraEnergy attached, this attack does 70 more damage.", + "effect_text": "If this Pok\u00e9mon has at least 3 extra Energy attached, this attack does 70 more damage.", "effect_id": null } ], diff --git a/backend/data/raw/a1/096-pikachu-ex.json b/backend/data/raw/a1/096-pikachu-ex.json index 21d2f01..344fff8 100644 --- a/backend/data/raw/a1/096-pikachu-ex.json +++ b/backend/data/raw/a1/096-pikachu-ex.json @@ -24,7 +24,7 @@ ], "damage": 30, "damage_modifier": "+", - "effect_text": "This attack does 30 damage for each of your BenchedPokémon.", + "effect_text": "This attack does 30 damage for each of your Benched Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/098-magneton.json b/backend/data/raw/a1/098-magneton.json index f0df7fe..fe7a632 100644 --- a/backend/data/raw/a1/098-magneton.json +++ b/backend/data/raw/a1/098-magneton.json @@ -17,7 +17,7 @@ "abilities": [ { "name": "Volt Charge", - "effect_text": "Once during your turn, you may take aEnergy from your Energy Zone and attach it to this Pokémon.", + "effect_text": "Once during your turn, you may take an Energy from your Energy Zone and attach it to this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/128-mewtwo.json b/backend/data/raw/a1/128-mewtwo.json index a44ab90..a532d6f 100644 --- a/backend/data/raw/a1/128-mewtwo.json +++ b/backend/data/raw/a1/128-mewtwo.json @@ -26,7 +26,7 @@ ], "damage": 120, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/129-mewtwo-ex.json b/backend/data/raw/a1/129-mewtwo-ex.json index 34899a1..d6ac8d1 100644 --- a/backend/data/raw/a1/129-mewtwo-ex.json +++ b/backend/data/raw/a1/129-mewtwo-ex.json @@ -37,7 +37,7 @@ ], "damage": 150, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/132-gardevoir.json b/backend/data/raw/a1/132-gardevoir.json index e15c265..51c9deb 100644 --- a/backend/data/raw/a1/132-gardevoir.json +++ b/backend/data/raw/a1/132-gardevoir.json @@ -17,7 +17,7 @@ "abilities": [ { "name": "Psy Shadow", - "effect_text": "Once during your turn, you may take aEnergy from your Energy Zone and attach it to thePokémon in the Active Spot.", + "effect_text": "Once during your turn, you may take an Energy from your Energy Zone and attach it to the Pok\u00e9mon in the Active Spot.", "effect_id": null } ], diff --git a/backend/data/raw/a1/181-meltan.json b/backend/data/raw/a1/181-meltan.json index 67633bf..ab5bf83 100644 --- a/backend/data/raw/a1/181-meltan.json +++ b/backend/data/raw/a1/181-meltan.json @@ -23,7 +23,7 @@ ], "damage": null, "damage_modifier": null, - "effect_text": "Take aEnergy from your Energy Zone and attach it to this Pokémon.", + "effect_text": "Take an Energy from your Energy Zone and attach it to this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/216-helix-fossil.json b/backend/data/raw/a1/216-helix-fossil.json index 723da86..e258314 100644 --- a/backend/data/raw/a1/216-helix-fossil.json +++ b/backend/data/raw/a1/216-helix-fossil.json @@ -5,20 +5,11 @@ "set_name": "Genetic Apex", "card_number": 216, "rarity": "Common", - "card_type": "pokemon", + "card_type": "trainer", "image_url": "https://assets.pokemon-zone.com/game-assets/CardPreviews/cTR_10_000080_00_KAINOKASEKI_C.webp", "image_file": null, "source_url": "https://www.pokemon-zone.com/cards/a1/216/helix-fossil/", - "hp": null, - "pokemon_type": null, - "stage": "basic", - "evolves_from": null, - "is_ex": false, - "abilities": [], - "attacks": [], - "weakness": null, - "resistance": null, - "retreat_cost": 0, - "flavor_text": null, + "trainer_type": "item", + "effect_text": "Play this card as if it were a 40 HP Basic Pokémon.At any time during your turn, you may discard this card from play.This card can’t retreat.You may play any number of Item cards during your turn.", "illustrator": "Toyste Beach" } \ No newline at end of file diff --git a/backend/data/raw/a1/217-dome-fossil.json b/backend/data/raw/a1/217-dome-fossil.json index e3a1c20..0add82e 100644 --- a/backend/data/raw/a1/217-dome-fossil.json +++ b/backend/data/raw/a1/217-dome-fossil.json @@ -5,20 +5,11 @@ "set_name": "Genetic Apex", "card_number": 217, "rarity": "Common", - "card_type": "pokemon", + "card_type": "trainer", "image_url": "https://assets.pokemon-zone.com/game-assets/CardPreviews/cTR_10_000090_00_KOURANOKASEKI_C.webp", "image_file": null, "source_url": "https://www.pokemon-zone.com/cards/a1/217/dome-fossil/", - "hp": null, - "pokemon_type": null, - "stage": "basic", - "evolves_from": null, - "is_ex": false, - "abilities": [], - "attacks": [], - "weakness": null, - "resistance": null, - "retreat_cost": 0, - "flavor_text": null, + "trainer_type": "item", + "effect_text": "Play this card as if it were a 40 HP Basic Pokémon.At any time during your turn, you may discard this card from play.This card can’t retreat.You may play any number of Item cards during your turn.", "illustrator": "Toyste Beach" } \ No newline at end of file diff --git a/backend/data/raw/a1/218-old-amber.json b/backend/data/raw/a1/218-old-amber.json index ff04844..a0a950e 100644 --- a/backend/data/raw/a1/218-old-amber.json +++ b/backend/data/raw/a1/218-old-amber.json @@ -5,20 +5,11 @@ "set_name": "Genetic Apex", "card_number": 218, "rarity": "Common", - "card_type": "pokemon", + "card_type": "trainer", "image_url": "https://assets.pokemon-zone.com/game-assets/CardPreviews/cTR_10_000100_00_HIMITSUNOKOHAKU_C.webp", "image_file": null, "source_url": "https://www.pokemon-zone.com/cards/a1/218/old-amber/", - "hp": null, - "pokemon_type": null, - "stage": "basic", - "evolves_from": null, - "is_ex": false, - "abilities": [], - "attacks": [], - "weakness": null, - "resistance": null, - "retreat_cost": 0, - "flavor_text": null, + "trainer_type": "item", + "effect_text": "Play this card as if it were a 40 HP Basic Pokémon.At any time during your turn, you may discard this card from play.This card can’t retreat.You may play any number of Item cards during your turn.", "illustrator": "Toyste Beach" } \ No newline at end of file diff --git a/backend/data/raw/a1/219-erika.json b/backend/data/raw/a1/219-erika.json index 00f7209..b54b5dd 100644 --- a/backend/data/raw/a1/219-erika.json +++ b/backend/data/raw/a1/219-erika.json @@ -10,6 +10,6 @@ "image_file": null, "source_url": "https://www.pokemon-zone.com/cards/a1/219/erika/", "trainer_type": "supporter", - "effect_text": "Heal 50 damage from 1 of yourPokémon.You may play only 1 Supporter card during your turn.", + "effect_text": "Heal 50 damage from 1 of your Pok\u00e9mon.You may play only 1 Supporter card during your turn.", "illustrator": "kirisAki" } \ No newline at end of file diff --git a/backend/data/raw/a1/220-misty.json b/backend/data/raw/a1/220-misty.json index e536c34..36e4d91 100644 --- a/backend/data/raw/a1/220-misty.json +++ b/backend/data/raw/a1/220-misty.json @@ -10,6 +10,6 @@ "image_file": null, "source_url": "https://www.pokemon-zone.com/cards/a1/220/misty/", "trainer_type": "supporter", - "effect_text": "Choose 1 of yourPokémon, and flip a coin until you get tails. For each heads, take aEnergy from your Energy Zone and attach it to that Pokémon.You may play only 1 Supporter card during your turn.", + "effect_text": "Choose 1 of your Pok\u00e9mon, and flip a coin until you get tails. For each heads, take an Energy from your Energy Zone and attach it to that Pok\u00e9mon.You may play only 1 Supporter card during your turn.", "illustrator": "Sanosuke Sakuma" } \ No newline at end of file diff --git a/backend/data/raw/a1/224-brock.json b/backend/data/raw/a1/224-brock.json index 6229f2b..ded62e0 100644 --- a/backend/data/raw/a1/224-brock.json +++ b/backend/data/raw/a1/224-brock.json @@ -10,6 +10,6 @@ "image_file": null, "source_url": "https://www.pokemon-zone.com/cards/a1/224/brock/", "trainer_type": "supporter", - "effect_text": "Take aEnergy from your Energy Zone and attach it toGolemorOnix.You may play only 1 Supporter card during your turn.", + "effect_text": "Take an Energy from your Energy Zone and attach it toGolemorOnix.You may play only 1 Supporter card during your turn.", "illustrator": "Taira Akitsu" } \ No newline at end of file diff --git a/backend/data/raw/a1/230-charmander.json b/backend/data/raw/a1/230-charmander.json index cc343cb..3a9e33b 100644 --- a/backend/data/raw/a1/230-charmander.json +++ b/backend/data/raw/a1/230-charmander.json @@ -23,7 +23,7 @@ ], "damage": 30, "damage_modifier": null, - "effect_text": "Discard aEnergy from this Pokémon.", + "effect_text": "Discard an Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/234-lapras.json b/backend/data/raw/a1/234-lapras.json index 77c545e..587b5fe 100644 --- a/backend/data/raw/a1/234-lapras.json +++ b/backend/data/raw/a1/234-lapras.json @@ -23,7 +23,7 @@ ], "damage": 20, "damage_modifier": "x", - "effect_text": "If this Pokémon has at least 3 extraEnergy attached, this attack does 70 more damage.", + "effect_text": "If this Pok\u00e9mon has at least 3 extra Energy attached, this attack does 70 more damage.", "effect_id": null } ], diff --git a/backend/data/raw/a1/253-charizard-ex.json b/backend/data/raw/a1/253-charizard-ex.json index 10a3c67..c228825 100644 --- a/backend/data/raw/a1/253-charizard-ex.json +++ b/backend/data/raw/a1/253-charizard-ex.json @@ -38,7 +38,7 @@ ], "damage": 200, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/255-moltres-ex.json b/backend/data/raw/a1/255-moltres-ex.json index 2965a0c..d790eb3 100644 --- a/backend/data/raw/a1/255-moltres-ex.json +++ b/backend/data/raw/a1/255-moltres-ex.json @@ -23,7 +23,7 @@ ], "damage": null, "damage_modifier": null, - "effect_text": "Flip 3 coins. Take an amount ofEnergy from your Energy Zone equal to the number of heads and attach it to your BenchedPokémon in any way you like.", + "effect_text": "Flip 3 coins. Take an amount of Energy from your Energy Zone equal to the number of heads and attach it to your Benched Pok\u00e9mon in any way you like.", "effect_id": null }, { diff --git a/backend/data/raw/a1/256-blastoise-ex.json b/backend/data/raw/a1/256-blastoise-ex.json index 063fdea..64706bc 100644 --- a/backend/data/raw/a1/256-blastoise-ex.json +++ b/backend/data/raw/a1/256-blastoise-ex.json @@ -36,7 +36,7 @@ ], "damage": 100, "damage_modifier": "x", - "effect_text": "If this Pokémon has at least 2 extraEnergy attached, this attack does 60 more damage.", + "effect_text": "If this Pok\u00e9mon has at least 2 extra Energy attached, this attack does 60 more damage.", "effect_id": null } ], diff --git a/backend/data/raw/a1/259-pikachu-ex.json b/backend/data/raw/a1/259-pikachu-ex.json index 1c89a68..311a9b2 100644 --- a/backend/data/raw/a1/259-pikachu-ex.json +++ b/backend/data/raw/a1/259-pikachu-ex.json @@ -24,7 +24,7 @@ ], "damage": 30, "damage_modifier": "+", - "effect_text": "This attack does 30 damage for each of your BenchedPokémon.", + "effect_text": "This attack does 30 damage for each of your Benched Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/262-mewtwo-ex.json b/backend/data/raw/a1/262-mewtwo-ex.json index 8dfd660..cc332a1 100644 --- a/backend/data/raw/a1/262-mewtwo-ex.json +++ b/backend/data/raw/a1/262-mewtwo-ex.json @@ -37,7 +37,7 @@ ], "damage": 150, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/266-erika.json b/backend/data/raw/a1/266-erika.json index 30ba76e..aeab69a 100644 --- a/backend/data/raw/a1/266-erika.json +++ b/backend/data/raw/a1/266-erika.json @@ -10,6 +10,6 @@ "image_file": null, "source_url": "https://www.pokemon-zone.com/cards/a1/266/erika/", "trainer_type": "supporter", - "effect_text": "Heal 50 damage from 1 of yourPokémon.You may play only 1 Supporter card during your turn.", + "effect_text": "Heal 50 damage from 1 of your Pok\u00e9mon.You may play only 1 Supporter card during your turn.", "illustrator": "saino misaki" } \ No newline at end of file diff --git a/backend/data/raw/a1/267-misty.json b/backend/data/raw/a1/267-misty.json index af66951..f72bc5a 100644 --- a/backend/data/raw/a1/267-misty.json +++ b/backend/data/raw/a1/267-misty.json @@ -10,6 +10,6 @@ "image_file": null, "source_url": "https://www.pokemon-zone.com/cards/a1/267/misty/", "trainer_type": "supporter", - "effect_text": "Choose 1 of yourPokémon, and flip a coin until you get tails. For each heads, take aEnergy from your Energy Zone and attach it to that Pokémon.You may play only 1 Supporter card during your turn.", + "effect_text": "Choose 1 of your Pok\u00e9mon, and flip a coin until you get tails. For each heads, take an Energy from your Energy Zone and attach it to that Pok\u00e9mon.You may play only 1 Supporter card during your turn.", "illustrator": "Sanosuke Sakuma" } \ No newline at end of file diff --git a/backend/data/raw/a1/271-brock.json b/backend/data/raw/a1/271-brock.json index c6a2ac9..26ff1dd 100644 --- a/backend/data/raw/a1/271-brock.json +++ b/backend/data/raw/a1/271-brock.json @@ -10,6 +10,6 @@ "image_file": null, "source_url": "https://www.pokemon-zone.com/cards/a1/271/brock/", "trainer_type": "supporter", - "effect_text": "Take aEnergy from your Energy Zone and attach it toGolemorOnix.You may play only 1 Supporter card during your turn.", + "effect_text": "Take an Energy from your Energy Zone and attach it toGolemorOnix.You may play only 1 Supporter card during your turn.", "illustrator": "Ryuta Fuse" } \ No newline at end of file diff --git a/backend/data/raw/a1/274-moltres-ex.json b/backend/data/raw/a1/274-moltres-ex.json index 74e35a8..964c75d 100644 --- a/backend/data/raw/a1/274-moltres-ex.json +++ b/backend/data/raw/a1/274-moltres-ex.json @@ -23,7 +23,7 @@ ], "damage": null, "damage_modifier": null, - "effect_text": "Flip 3 coins. Take an amount ofEnergy from your Energy Zone equal to the number of heads and attach it to your BenchedPokémon in any way you like.", + "effect_text": "Flip 3 coins. Take an amount of Energy from your Energy Zone equal to the number of heads and attach it to your Benched Pok\u00e9mon in any way you like.", "effect_id": null }, { diff --git a/backend/data/raw/a1/280-charizard-ex.json b/backend/data/raw/a1/280-charizard-ex.json index 4c7b628..afd81c4 100644 --- a/backend/data/raw/a1/280-charizard-ex.json +++ b/backend/data/raw/a1/280-charizard-ex.json @@ -38,7 +38,7 @@ ], "damage": 200, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/281-pikachu-ex.json b/backend/data/raw/a1/281-pikachu-ex.json index 32119d1..f517ef0 100644 --- a/backend/data/raw/a1/281-pikachu-ex.json +++ b/backend/data/raw/a1/281-pikachu-ex.json @@ -24,7 +24,7 @@ ], "damage": 30, "damage_modifier": "+", - "effect_text": "This attack does 30 damage for each of your BenchedPokémon.", + "effect_text": "This attack does 30 damage for each of your Benched Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/282-mewtwo-ex.json b/backend/data/raw/a1/282-mewtwo-ex.json index 1a4eec6..6953d7f 100644 --- a/backend/data/raw/a1/282-mewtwo-ex.json +++ b/backend/data/raw/a1/282-mewtwo-ex.json @@ -37,7 +37,7 @@ ], "damage": 150, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/284-charizard-ex.json b/backend/data/raw/a1/284-charizard-ex.json index 4859081..01a2d9e 100644 --- a/backend/data/raw/a1/284-charizard-ex.json +++ b/backend/data/raw/a1/284-charizard-ex.json @@ -38,7 +38,7 @@ ], "damage": 200, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/285-pikachu-ex.json b/backend/data/raw/a1/285-pikachu-ex.json index d6e66e8..6fb5d10 100644 --- a/backend/data/raw/a1/285-pikachu-ex.json +++ b/backend/data/raw/a1/285-pikachu-ex.json @@ -24,7 +24,7 @@ ], "damage": 30, "damage_modifier": "+", - "effect_text": "This attack does 30 damage for each of your BenchedPokémon.", + "effect_text": "This attack does 30 damage for each of your Benched Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1/286-mewtwo-ex.json b/backend/data/raw/a1/286-mewtwo-ex.json index ce89cfc..f749407 100644 --- a/backend/data/raw/a1/286-mewtwo-ex.json +++ b/backend/data/raw/a1/286-mewtwo-ex.json @@ -37,7 +37,7 @@ ], "damage": 150, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1a/001-exeggcute.json b/backend/data/raw/a1a/001-exeggcute.json index d5c3ae3..2758ba3 100644 --- a/backend/data/raw/a1a/001-exeggcute.json +++ b/backend/data/raw/a1a/001-exeggcute.json @@ -23,7 +23,7 @@ ], "damage": null, "damage_modifier": null, - "effect_text": "Take aEnergy from your Energy Zone and attach it to this Pokémon.", + "effect_text": "Take an Energy from your Energy Zone and attach it to this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1a/006-serperior.json b/backend/data/raw/a1a/006-serperior.json index 8ca9f72..8b2cd3c 100644 --- a/backend/data/raw/a1a/006-serperior.json +++ b/backend/data/raw/a1a/006-serperior.json @@ -17,7 +17,7 @@ "abilities": [ { "name": "Jungle Totem", - "effect_text": "EachEnergy attached to yourPokémon provides 2Energy. This effect doesn’t stack.", + "effect_text": "EachEnergy attached to your Pok\u00e9mon provides 2 Energy. This effect doesn\u2019t stack.", "effect_id": null } ], diff --git a/backend/data/raw/a1a/009-dhelmise.json b/backend/data/raw/a1a/009-dhelmise.json index 9eb1d26..22d8c3e 100644 --- a/backend/data/raw/a1a/009-dhelmise.json +++ b/backend/data/raw/a1a/009-dhelmise.json @@ -23,7 +23,7 @@ ], "damage": 20, "damage_modifier": "x", - "effect_text": "If this Pokémon has at least 3 extraEnergy attached, this attack does 70 more damage.", + "effect_text": "If this Pok\u00e9mon has at least 3 extra Energy attached, this attack does 70 more damage.", "effect_id": null } ], diff --git a/backend/data/raw/a1a/012-magmar.json b/backend/data/raw/a1a/012-magmar.json index e1ad266..f49a57e 100644 --- a/backend/data/raw/a1a/012-magmar.json +++ b/backend/data/raw/a1a/012-magmar.json @@ -24,7 +24,7 @@ ], "damage": 80, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1a/014-volcarona.json b/backend/data/raw/a1a/014-volcarona.json index 7f38f60..66b4ffa 100644 --- a/backend/data/raw/a1a/014-volcarona.json +++ b/backend/data/raw/a1a/014-volcarona.json @@ -25,7 +25,7 @@ ], "damage": null, "damage_modifier": null, - "effect_text": "Discard 2Energy from this Pokémon. This attack does 80 damage to 1 of your opponent’s Pokémon.", + "effect_text": "Discard 2 Energy from this Pok\u00e9mon. This attack does 80 damage to 1 of your opponent\u2019s Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1a/019-vaporeon.json b/backend/data/raw/a1a/019-vaporeon.json index a94a6db..c20b9aa 100644 --- a/backend/data/raw/a1a/019-vaporeon.json +++ b/backend/data/raw/a1a/019-vaporeon.json @@ -17,7 +17,7 @@ "abilities": [ { "name": "Wash Out", - "effect_text": "As often as you like during your turn, you may move aEnergy from 1 of your BenchedPokémon to your ActivePokémon.", + "effect_text": "As often as you like during your turn, you may move an Energy from 1 of your Benched Pok\u00e9mon to your Active Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1a/025-pikachu.json b/backend/data/raw/a1a/025-pikachu.json index 405ffa7..0515a69 100644 --- a/backend/data/raw/a1a/025-pikachu.json +++ b/backend/data/raw/a1a/025-pikachu.json @@ -23,7 +23,7 @@ ], "damage": 10, "damage_modifier": "+", - "effect_text": "This attack does 10 damage for each of your BenchedPokémon.", + "effect_text": "This attack does 10 damage for each of your Benched Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/data/raw/a1a/063-old-amber.json b/backend/data/raw/a1a/063-old-amber.json index 605dfd1..f6869de 100644 --- a/backend/data/raw/a1a/063-old-amber.json +++ b/backend/data/raw/a1a/063-old-amber.json @@ -5,20 +5,11 @@ "set_name": "Mythical Island", "card_number": 63, "rarity": "Common", - "card_type": "pokemon", + "card_type": "trainer", "image_url": "https://assets.pokemon-zone.com/game-assets/CardPreviews/cTR_10_000100_00_HIMITSUNOKOHAKU_C.webp", - "image_file": "a1a/063-old-amber.webp", + "image_file": null, "source_url": "https://www.pokemon-zone.com/cards/a1a/63/old-amber/", - "hp": null, - "pokemon_type": null, - "stage": "basic", - "evolves_from": null, - "is_ex": false, - "abilities": [], - "attacks": [], - "weakness": null, - "resistance": null, - "retreat_cost": 0, - "flavor_text": null, + "trainer_type": "item", + "effect_text": "Play this card as if it were a 40 HP Basic Pokémon.At any time during your turn, you may discard this card from play.This card can’t retreat.You may play any number of Item cards during your turn.", "illustrator": "Toyste Beach" } \ No newline at end of file diff --git a/backend/data/raw/a1a/065-mythical-slab.json b/backend/data/raw/a1a/065-mythical-slab.json index 84ff464..9e69eae 100644 --- a/backend/data/raw/a1a/065-mythical-slab.json +++ b/backend/data/raw/a1a/065-mythical-slab.json @@ -10,6 +10,6 @@ "image_file": "a1a/065-mythical-slab.webp", "source_url": "https://www.pokemon-zone.com/cards/a1a/65/mythical-slab/", "trainer_type": "item", - "effect_text": "Look at the top card of your deck. If that card is aPokémon, put it into your hand. If it is not aPokémon, put it on the bottom of your deck.You may play any number of Item cards during your turn.", + "effect_text": "Look at the top card of your deck. If that card is a Pok\u00e9mon, put it into your hand. If it is not a Pok\u00e9mon, put it on the bottom of your deck.You may play any number of Item cards during your turn.", "illustrator": "AYUMI ODASHIMA" } \ No newline at end of file diff --git a/backend/data/raw/a1a/070-serperior.json b/backend/data/raw/a1a/070-serperior.json index d53bb17..35f5e55 100644 --- a/backend/data/raw/a1a/070-serperior.json +++ b/backend/data/raw/a1a/070-serperior.json @@ -17,7 +17,7 @@ "abilities": [ { "name": "Jungle Totem", - "effect_text": "EachEnergy attached to yourPokémon provides 2Energy. This effect doesn’t stack.", + "effect_text": "EachEnergy attached to your Pok\u00e9mon provides 2 Energy. This effect doesn\u2019t stack.", "effect_id": null } ], diff --git a/backend/data/raw/a1a/072-vaporeon.json b/backend/data/raw/a1a/072-vaporeon.json index 2d3e50d..6e65b1c 100644 --- a/backend/data/raw/a1a/072-vaporeon.json +++ b/backend/data/raw/a1a/072-vaporeon.json @@ -17,7 +17,7 @@ "abilities": [ { "name": "Wash Out", - "effect_text": "As often as you like during your turn, you may move aEnergy from 1 of your BenchedPokémon to your ActivePokémon.", + "effect_text": "As often as you like during your turn, you may move an Energy from 1 of your Benched Pok\u00e9mon to your Active Pok\u00e9mon.", "effect_id": null } ], diff --git a/backend/scripts/convert_cards.py b/backend/scripts/convert_cards.py index 7ee6d1e..a30ab16 100644 --- a/backend/scripts/convert_cards.py +++ b/backend/scripts/convert_cards.py @@ -383,9 +383,56 @@ def write_card_file(card: dict[str, Any], output_path: Path) -> None: json.dump(card, f, indent=2) +def validate_evolution_chains( + all_cards: list[dict[str, Any]], +) -> list[dict[str, Any]]: + """Validate that all evolves_from references point to existing cards. + + For Pokemon that evolve from other Pokemon, checks that the base form exists. + For Pokemon that evolve from items (fossils), checks that the item exists. + + Args: + all_cards: List of all converted card definitions. + + Returns: + List of validation warnings (not errors, since missing cards may be intentional). + """ + warnings = [] + + # Build lookup sets + pokemon_names = {card["name"] for card in all_cards if card.get("card_type") == "pokemon"} + trainer_names = {card["name"] for card in all_cards if card.get("card_type") == "trainer"} + all_card_names = pokemon_names | trainer_names + + # Check each Pokemon with evolves_from + for card in all_cards: + if card.get("card_type") != "pokemon": + continue + + evolves_from = card.get("evolves_from") + if not evolves_from: + continue + + # Check if the evolution source exists + if evolves_from not in all_card_names: + warnings.append( + { + "card_id": card["id"], + "card_name": card["name"], + "issue": "broken_evolution_chain", + "evolves_from": evolves_from, + "message": f"'{card['name']}' evolves from '{evolves_from}' which was not found", + } + ) + + return warnings + + def build_index( all_cards: list[dict[str, Any]], set_metadata: dict[str, dict[str, Any]], + conversion_errors: list[dict[str, Any]] | None = None, + validation_warnings: list[dict[str, Any]] | None = None, ) -> dict[str, Any]: """Build the master index file. @@ -448,7 +495,7 @@ def build_index( for card in all_cards ] - return { + index: dict[str, Any] = { "generated_at": datetime.now(UTC).isoformat(), "schema_version": "1.0", "total_cards": len(all_cards), @@ -456,12 +503,22 @@ def build_index( "cards": cards, } + # Add conversion errors if any + if conversion_errors: + index["conversion_errors"] = conversion_errors + + # Add validation warnings if any + if validation_warnings: + index["validation_warnings"] = validation_warnings + + return index + def convert_set( set_code: str, validate_only: bool = False, verbose: bool = False, -) -> list[dict[str, Any]]: +) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: """Convert all cards from a single set. Args: @@ -470,12 +527,12 @@ def convert_set( verbose: If True, print detailed progress. Returns: - List of converted card definitions. + Tuple of (converted card definitions, conversion errors). """ raw_set_dir = RAW_DATA_DIR / set_code if not raw_set_dir.exists(): print(f"Warning: Raw data directory not found: {raw_set_dir}") - return [] + return [], [] converted = [] errors = [] @@ -503,13 +560,21 @@ def convert_set( converted.append(card_dict) except Exception as e: - errors.append((card_file.name, str(e))) + errors.append( + { + "file": card_file.name, + "set_code": set_code, + "card_id": raw_card.get("id", "unknown"), + "card_name": raw_card.get("name", "unknown"), + "error": str(e), + } + ) print(f" ERROR: {card_file.name}: {e}") if errors: print(f" {len(errors)} errors in set {set_code}") - return converted + return converted, errors def main() -> int: @@ -561,18 +626,20 @@ def main() -> int: sets_to_convert = list(SET_METADATA.keys()) all_cards: list[dict[str, Any]] = [] + all_errors: list[dict[str, Any]] = [] # Convert each set for set_code in sets_to_convert: set_name = SET_METADATA.get(set_code, {}).get("name", set_code) print(f"\nConverting set: {set_code} ({set_name})") - cards = convert_set( + cards, errors = convert_set( set_code, validate_only=args.validate_only, verbose=args.verbose, ) all_cards.extend(cards) + all_errors.extend(errors) print(f" Converted {len(cards)} cards") # Generate energy cards @@ -593,10 +660,25 @@ def main() -> int: all_cards.extend(energy_cards) print(f" Generated {len(energy_cards)} energy cards") + # Validate evolution chains + print("\nValidating evolution chains...") + validation_warnings = validate_evolution_chains(all_cards) + if validation_warnings: + print(f" Found {len(validation_warnings)} broken evolution chains:") + for warning in validation_warnings: + print(f" - {warning['message']}") + else: + print(" All evolution chains valid") + # Write index file if not args.validate_only: print("\nWriting index file...") - index = build_index(all_cards, SET_METADATA) + index = build_index( + all_cards, + SET_METADATA, + conversion_errors=all_errors if all_errors else None, + validation_warnings=validation_warnings if validation_warnings else None, + ) index_path = DEFINITIONS_DIR / "_index.json" with open(index_path, "w") as f: json.dump(index, f, indent=2) @@ -605,6 +687,10 @@ def main() -> int: # Summary print("\n" + "=" * 40) print(f"Total cards converted: {len(all_cards)}") + if all_errors: + print(f"Conversion errors: {len(all_errors)}") + if validation_warnings: + print(f"Validation warnings: {len(validation_warnings)}") if args.validate_only: print("(Validation only - no files written)") diff --git a/backend/scripts/fix_raw_text.py b/backend/scripts/fix_raw_text.py new file mode 100644 index 0000000..739bd3a --- /dev/null +++ b/backend/scripts/fix_raw_text.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 +"""Fix text artifacts in existing raw scraped card data. + +This script applies the text cleaning rules to existing JSON files +without re-scraping them from the web. + +Usage: + python scripts/fix_raw_text.py +""" + +import json +import re +import sys +from pathlib import Path + +# Same patterns as in the scraper +TEXT_ARTIFACT_FIXES = [ + # Energy-related artifacts + (r"\baEnergy\b", "an Energy"), + (r"\bofEnergy\b", "of Energy"), + (r"\bextraEnergy\b", "extra Energy"), + (r"\battachedEnergy\b", "attached Energy"), + (r"\banyEnergy\b", "any Energy"), + (r"(\d+)Energy\b", r"\1 Energy"), + (r"(\d+)-HP\b", r"\1 HP"), + # Pokemon-related artifacts + (r"\bBasicPokémon\b", "Basic Pokémon"), + (r"\bBenchedPokémon\b", "Benched Pokémon"), + (r"\bthePokémon\b", "the Pokémon"), + (r"\bthisPokémon\b", "this Pokémon"), + (r"\byourPokémon\b", "your Pokémon"), + (r"\bActivePokémon\b", "Active Pokémon"), + (r"\bDefendingPokémon\b", "Defending Pokémon"), + (r"\bopponent'sPokémon\b", "opponent's Pokémon"), + (r"\bOpponent'sPokémon\b", "Opponent's Pokémon"), + (r"\bthatPokémon\b", "that Pokémon"), + (r"\beachPokémon\b", "each Pokémon"), + (r"\baPokémon\b", "a Pokémon"), +] + + +def clean_text(text: str | None) -> str | None: + """Apply text cleaning rules.""" + if not text: + return text + + result = text + for pattern, replacement in TEXT_ARTIFACT_FIXES: + result = re.sub(pattern, replacement, result) + return result + + +def fix_card_file(file_path: Path) -> bool: + """Fix text artifacts in a single card file. + + Returns True if the file was modified. + """ + with open(file_path) as f: + data = json.load(f) + + modified = False + + # Fix attack effect texts + for attack in data.get("attacks", []): + if attack.get("effect_text"): + cleaned = clean_text(attack["effect_text"]) + if cleaned != attack["effect_text"]: + attack["effect_text"] = cleaned + modified = True + + # Fix ability effect texts + for ability in data.get("abilities", []): + if ability.get("effect_text"): + cleaned = clean_text(ability["effect_text"]) + if cleaned != ability["effect_text"]: + ability["effect_text"] = cleaned + modified = True + + # Fix trainer effect text (stored in flavor_text for raw data) + if data.get("flavor_text"): + cleaned = clean_text(data["flavor_text"]) + if cleaned != data["flavor_text"]: + data["flavor_text"] = cleaned + modified = True + + # Fix effect_text field (for trainer cards) + if data.get("effect_text"): + cleaned = clean_text(data["effect_text"]) + if cleaned != data["effect_text"]: + data["effect_text"] = cleaned + modified = True + + if modified: + with open(file_path, "w") as f: + json.dump(data, f, indent=2) + + return modified + + +def main(): + raw_dir = Path(__file__).parent.parent / "data" / "raw" + + if not raw_dir.exists(): + print(f"Error: Raw data directory not found: {raw_dir}") + return 1 + + total_files = 0 + modified_files = 0 + + for set_dir in raw_dir.iterdir(): + if not set_dir.is_dir() or set_dir.name.startswith("_"): + continue + + for card_file in set_dir.glob("*.json"): + total_files += 1 + if fix_card_file(card_file): + modified_files += 1 + print(f" Fixed: {card_file.name}") + + print(f"\nProcessed {total_files} files, modified {modified_files}") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/backend/scripts/scrape_pokemon_pocket.py b/backend/scripts/scrape_pokemon_pocket.py index 22c8f52..3bfcd71 100644 --- a/backend/scripts/scrape_pokemon_pocket.py +++ b/backend/scripts/scrape_pokemon_pocket.py @@ -83,6 +83,65 @@ RARITY_CODES = { "CR": "Crown Rare", } +# Fossil cards that are Trainer/Item cards, not Pokemon +# These are often misclassified because they have Pokemon-like layouts on the source site +FOSSIL_CARDS = { + "Helix Fossil", + "Dome Fossil", + "Old Amber", +} + +# Text artifact patterns to fix (caused by stripped energy icons) +# Format: (pattern, replacement) +# Energy icons render as empty strings, merging adjacent text +TEXT_ARTIFACT_FIXES = [ + # Energy-related artifacts + (r"\baEnergy\b", "an Energy"), + (r"\bofEnergy\b", "of Energy"), + (r"\bextraEnergy\b", "extra Energy"), + (r"\battachedEnergy\b", "attached Energy"), + (r"\banyEnergy\b", "any Energy"), + (r"(\d+)Energy\b", r"\1 Energy"), # "2Energy" -> "2 Energy" + (r"(\d+)-HP\b", r"\1 HP"), # "40-HP" -> "40 HP" + # Pokemon-related artifacts + (r"\bBasicPokémon\b", "Basic Pokémon"), + (r"\bBenchedPokémon\b", "Benched Pokémon"), + (r"\bthePokémon\b", "the Pokémon"), + (r"\bthisPokémon\b", "this Pokémon"), + (r"\byourPokémon\b", "your Pokémon"), + (r"\bActivePokémon\b", "Active Pokémon"), + (r"\bDefendingPokémon\b", "Defending Pokémon"), + (r"\bopponent'sPokémon\b", "opponent's Pokémon"), + (r"\bOpponent'sPokémon\b", "Opponent's Pokémon"), + # Other common artifacts + (r"\bthatPokémon\b", "that Pokémon"), + (r"\beachPokémon\b", "each Pokémon"), + (r"\baPokémon\b", "a Pokémon"), +] + + +def clean_effect_text(text: str | None) -> str | None: + """Clean scraped effect text by fixing common artifacts. + + Energy icons on the source website are stripped during text extraction, + causing adjacent words to merge (e.g., "aEnergy" instead of "an Energy"). + + Args: + text: The raw effect text from scraping. + + Returns: + Cleaned text with artifacts fixed, or None if input was None/empty. + """ + if not text: + return None + + result = text + for pattern, replacement in TEXT_ARTIFACT_FIXES: + result = re.sub(pattern, replacement, result) + + return result if result else None + + # ============================================================================= # Logging Setup # ============================================================================= @@ -448,9 +507,8 @@ class PokemonPocketScraper: effect_text: str | None = None footer_elem = attack_row.find(class_="attack-summary-row__footer") if footer_elem: - effect_text = footer_elem.get_text(strip=True) - if not effect_text: - effect_text = None + raw_text = footer_elem.get_text(strip=True) + effect_text = clean_effect_text(raw_text) return Attack( name=name, @@ -485,7 +543,8 @@ class PokemonPocketScraper: # Get effect text desc_elem = ability_row.find(class_="ability-summary-row__description") - effect_text = desc_elem.get_text(strip=True) if desc_elem else "" + raw_text = desc_elem.get_text(strip=True) if desc_elem else "" + effect_text = clean_effect_text(raw_text) or "" return Ability(name=name, effect_text=effect_text) @@ -526,18 +585,21 @@ class PokemonPocketScraper: # Energy cards have specific energy type text # Pokemon cards have "Pokémon | Basic/Stage 1/Stage 2" text card_type = "pokemon" # Default + trainer_type: str | None = None - # Check for Trainer first (more specific match) - trainer_match = soup.find( - string=re.compile(r"Trainer\s*\|\s*(Supporter|Item|Stadium)", re.IGNORECASE) - ) - if trainer_match: + # Check for Fossil cards first (they appear as Pokemon on the site but are Items) + if name in FOSSIL_CARDS: card_type = "trainer" - else: - # Check for Energy - energy_match = soup.find(string=re.compile(r"Energy\s*$", re.IGNORECASE)) - if energy_match: - card_type = "energy" + trainer_type = "item" + logger.info(f"Detected fossil card as Trainer/Item: {name}") + # Check for Trainer (more specific match) + elif soup.find( + string=re.compile(r"Trainer\s*\|\s*(Supporter|Item|Stadium)", re.IGNORECASE) + ): + card_type = "trainer" + # Check for Energy + elif soup.find(string=re.compile(r"Energy\s*$", re.IGNORECASE)): + card_type = "energy" # Create card ID card_id = f"{set_code}-{card_number:03d}-{url_name}" @@ -584,6 +646,9 @@ class PokemonPocketScraper: if card_type == "pokemon": self._parse_pokemon_details(soup, card) elif card_type == "trainer": + # For fossil cards, we already know the trainer_type + if trainer_type: + card.stage = trainer_type self._parse_trainer_details(soup, card) elif card_type == "energy": self._parse_energy_details(soup, card) @@ -727,7 +792,7 @@ class PokemonPocketScraper: if "Illustrated by" in full_text: full_text = full_text.split("Illustrated by")[0].strip() if full_text: - card.flavor_text = full_text + card.flavor_text = clean_effect_text(full_text) else: # Fallback: look for any paragraph with effect-like text for elem in soup.find_all("p"): @@ -740,7 +805,7 @@ class PokemonPocketScraper: and "Pokemon Zone" not in text and "unofficial" not in text.lower() ): - card.flavor_text = text + card.flavor_text = clean_effect_text(text) break # Get illustrator