Merge branch '2023-yuletide-errata'

This commit is contained in:
Christian 'ketura' McCarty
2023-12-17 16:07:52 -06:00
20 changed files with 361 additions and 95 deletions

View File

@@ -73,16 +73,16 @@
# }
# ]
gametext: While you can spot your Man, Elf, and Dwarf, the number of Free Peoples cultures that can be spotted is -1.\<b>Maneuver:</b> Exert a Dwarf companion to make each minion at a battleground lose all damage bonuses until the regroup phase.
lore: "...the sound of the great horn of Helm rang out."
promotext: ""
alts: {
//These are just CardInfo objects
promos: {
}
//These are full card definitions, with redundant info that is the same as the original card ommitted
errata: {
}
}
}
# gametext: While you can spot your Man, Elf, and Dwarf, the number of Free Peoples cultures that can be spotted is -1.\<b>Maneuver:</b> Exert a Dwarf companion to make each minion at a battleground lose all damage bonuses until the regroup phase.
# lore: "...the sound of the great horn of Helm rang out."
# promotext: ""
# alts: {
# //These are just CardInfo objects
# promos: {
# }
# //These are full card definitions, with redundant info that is the same as the original card ommitted
# errata: {
# }
# }
# }
}

View File

@@ -16,7 +16,7 @@
//Versioning differentiates releases within a particular alt path, such as PC errata
// version 1 vs version 2. PC version 2 will not conflict with, say, Decipher version 2.
//Top-level cards should always be version 0.
version: 1?
version: 1
collInfo: 2U76
rarity: U
setNum: "2"
@@ -30,18 +30,72 @@
culture: Wraith
twilight: 1
type: Condition
#keyword: support area
/*requires: [
]
keyword: support area
effects: [
{
type: modifier
modifier: {
type: DisableGameText
filter: bearer
}
}
{
type: activated
phase: maneuver
cost: {
type: exert
filter: choose(Nazgul)
}
effect: {
type: Transfer
filter: self
where: choose(companion,ring-bound)
}
}
]*/
{
type: ActivatedTrigger
trigger: {
type: RemovesBurden
}
requires: {
type: Or
requires: [
{
type: CanSpot
filter: Nazgul
}
{
type: HasCardInHand
filter: Nazgul
}
]
}
effect: [
{
# Since we are checking for both in-play and in-hand
# Nazgul, we will only prompt to reveal if there are
# no Nazgul on the table.
# Doing this as an effect and not a cost as I'm not
# sure whether violating the condition would count
# as "not paying" the cost.
type: Conditional
requires: {
type: CantSpot
filter: Nazgul
}
effect: {
type: RevealCardsFromHand
filter: choose(Nazgul)
}
}
{
type: Transfer
filter: self
where: choose(companion,ring-bound)
}
]
}
]
gametext: Bearer's game text does not apply (except keywords).<br>Maneuver: Exert a Nazgul to transfer this to a Ring-bound companion.<br>Response: If a burden is removed, spot or reveal a Nazgul from hand to transfer this to a Ring-bound companion.
lore: “He heard Frodo's voice...crying out strange words.”
promotext: ""

View File

@@ -16,7 +16,7 @@
//Versioning differentiates releases within a particular alt path, such as PC errata
// version 1 vs version 2. PC version 2 will not conflict with, say, Decipher version 2.
//Top-level cards should always be version 0.
version: 1?
version: 1
collInfo: 3R50
rarity: R
setNum: "3"
@@ -30,19 +30,65 @@
culture: Isengard
twilight: 1
type: Condition
#keyword: support area
/*requires: [
]
target: companion
effects: [
{
type: Trigger
optional: false
trigger: {
type: WinsSkirmish
filter: bearer
against: culture(isengard),minion
}
effect: {
type: AddBurdens
amount: 1
}
}
{
type: Trigger
trigger: {
type: StartOfPhase
phase: regroup
}
requires: {
type: IsGreaterThanOrEqual
firstNumber: {
type: ForEachVitality
filter: bearer
}
secondNumber: 3
}
effect: [
{
# We do this just to make the option prompt a
# little more elegant.
type: Memorize
filter: bearer
memory: bearer
}
{
type: Optional
player: freeps
text: Would you like to exert {bearer} twice to discard Can You Protect Me From Yourself?
effect: {
type: CostToEffect
cost: {
type: exert
player: freeps
times: 2
filter: bearer
}
effect: {
type: Discard
filter: self
}
}
}
]
}
]*/
gametext: To play, spot an [isengard] minion. Bearer must be a companion.<br>Each time bearer wins a skirmish, add a burden.<br>At the start of the regroup phase, the Free Peoples player may exert bearer twice to discard this condition.
]
gametext: Bearer must be a companion or ally.<br>Each time bearer wins a skirmish against an [isengard] minion, add a burden.<br>At the start of the regroup phase, the Free Peoples player may exert bearer twice to discard this condition.
lore: “Where is the Ring?'”
promotext: ""
alts: {

View File

@@ -16,7 +16,7 @@
//Versioning differentiates releases within a particular alt path, such as PC errata
// version 1 vs version 2. PC version 2 will not conflict with, say, Decipher version 2.
//Top-level cards should always be version 0.
version: 1?
version: 1
collInfo: 3R80
rarity: R
setNum: "3"
@@ -30,19 +30,51 @@
culture: Moria
twilight: 0
type: Condition
#keyword: support area
/*requires: [
]
target: unbound,companion,not(hasAttached(name(Such a Little Thing)))
effects: [
{
type: Trigger
optional: false
trigger: {
type: StartOfPhase
phase: skirmish
}
requires: {
type: CanSpot
filter: bearer,InSkirmishAgainst(culture(moria),minion)
}
effect: [
{
# We do this just to make the option prompt a
# little more elegant.
type: Memorize
filter: bearer
memory: bearer
}
{
type: choice
player: freeps
texts: [
Discard an item from {bearer}
Wound {bearer}
]
effects: [
{
type: Discard
player: freeps
filter: choose(item,AttachedTo(bearer))
}
{
type: wound
filter: bearer
times: 1
}
]
}
]
}
{
}
]*/
gametext: To play, spot a [moria] minion. Bearer must be an unbound companion.<br>At the start of each skirmish involving bearer, the Free Peoples player must discard an item borne by bearer or wound bearer.<br>At the start of the regroup phase, the Free Peoples player may exert 2 other companions to discard this condition.
]
gametext: Bearer must be an unbound companion. Limit 1 per bearer.<br>At the start of each skirmish involving bearer and a [moria] minion, the Free Peoples player must discard an item borne by bearer or wound bearer.
lore: ""
promotext: ""
alts: {

View File

@@ -16,7 +16,7 @@
//Versioning differentiates releases within a particular alt path, such as PC errata
// version 1 vs version 2. PC version 2 will not conflict with, say, Decipher version 2.
//Top-level cards should always be version 0.
version: 1?
version: 1
collInfo: 3R85
rarity: R
setNum: "3"
@@ -30,19 +30,61 @@
culture: Wraith
twilight: 1
type: Condition
#keyword: support area
/*requires: [
]
target: companion
effects: [
{
type: ExtraCost
cost: {
type: exert
filter: choose(culture(ringwraith), minion)
}
}
{
type: modifier
modifier: {
type: CantBeExerted
filter: bearer
by: side(freeps)
}
}
]*/
gametext: To play, exert a [ringwraith] minion. Bearer must<br>be a companion. Bearer cannot be exerted by Free Peoples cards.<br>At the start of the regroup phase, the Free Peoples player may discard 2 cards from hand of bearer's culture to discard this condition.
{
type: Trigger
trigger: {
type: StartOfPhase
phase: regroup
}
effect: [
{
# We do this just to make the option prompt a
# little more elegant.
type: Memorize
filter: bearer
memory: bearer
}
{
type: Optional
player: freeps
text: Would you like to exert 2 cards from hand matching {bearer}'s culture to discard Too Great and Terrible?
effect: {
type: CostToEffect
cost: {
type: DiscardFromHand
player: freeps
hand: freeps
forced: false
count: 2
filter: choose(CultureFromMemory(bearer))
}
effect: {
type: Discard
filter: self
}
}
}
]
}
]
gametext: To play, exert a [ringwraith] minion. Bearer must be a companion or ally. Bearer cannot be exerted by Free Peoples cards.<br>At the start of the regroup phase, the Free Peoples player may discard 2 cards from hand of bearer's culture to discard this condition.
lore: “I do not wish to become like the Dark Lord himself.'”
promotext: ""
alts: {

View File

@@ -16,7 +16,7 @@
//Versioning differentiates releases within a particular alt path, such as PC errata
// version 1 vs version 2. PC version 2 will not conflict with, say, Decipher version 2.
//Top-level cards should always be version 0.
version: 1?
version: 2
collInfo: 3R103
rarity: R
setNum: "3"
@@ -30,19 +30,52 @@
culture: Sauron
twilight: 2
type: Condition
#keyword: support area
/*requires: [
]
target: or(companion, ally)
effects: [
{
type: ExtraCost
cost: {
type: exert
filter: choose(culture(sauron), orc)
}
}
{
type: Trigger
trigger: {
type: UsesSpecialAbility
filter: bearer
}
effect: [
{
# We do this just to make the option prompt a
# little more elegant.
type: Memorize
filter: bearer
memory: bearer
}
{
type: Choice
player: freeps
texts: [
Discard a Free Peoples character (except the Ring-bearer)
Wound {bearer}
]
effects: [
{
type: Discard
player: freeps
filter: choose(side(freeps),character)
}
{
type: wound
filter: bearer
}
]
}
]
}
]*/
gametext: To play, exert a [sauron] Orc. Bearer must be a companion or ally.<br>Bearer's special abilities gain this cost: "Add 2 burdens or discard another Free Peoples character of the same race."<br>At the start of the regroup phase, the Free Peoples player may exert bearer twice to discard this condition.
]
gametext: To play, exert a [sauron] Orc. Bearer must be a companion or ally. Each time one of bearer's special abilities are used, the Free Peoples player must discard a Free Peoples character or wound bearer.
lore: ""
promotext: ""
alts: {
@@ -71,7 +104,7 @@
//Versioning differentiates releases within a particular alt path, such as PC errata
// version 1 vs version 2. PC version 2 will not conflict with, say, Decipher version 2.
//Top-level cards should always be version 0.
version: 1?
version: 1
collInfo: 3R105
rarity: R
setNum: "3"
@@ -85,18 +118,41 @@
culture: Sauron
twilight: 2
type: Condition
#keyword: support area
/*requires: [
]
target: or(companion,ally)
requires: {
type: CanSpot
filter: or(and(culture(sauron),minion),title(Gollum))
}
effects: [
{
type: Trigger
trigger: {
type: UsesSpecialAbility
filter: bearer
}
effect: [
{
type: Choice
player: freeps
texts: [
Discard a Free Peoples condition
Add a burden
]
effects: [
{
type: Discard
player: freeps
filter: choose(side(freeps),condition)
}
{
type: AddBurdens
amount: 1
}
]
}
]
}
{
}
]*/
]
gametext: To play, spot a [sauron] minion (or Gollum). Bearer must be a companion or ally.<br>Bearer's special abilities gain this cost: "Discard 2 of your conditions or wound this character."<br>At the start of the regroup phase, the Free Peoples player may discard a Free Peoples character to discard this condition.
lore: ""
promotext: ""

View File

@@ -80,16 +80,5 @@
}
}
]
gametext: <b>Damage +1.</b> <br>While Gimli is the Ring-bearer, at the start of each skirmish involving him, add 2 burdens or 2 threats. <br>While Gimli is damage +X, he is resistance +X.
lore: “Never trust an Elf.'”
promotext: ""
alts: {
//These are just CardInfo objects
promos: {
}
//These are full card definitions, with redundant info that is the same as the original card ommitted
errata: {
}
}
}
}

View File

@@ -43,6 +43,8 @@ public class FieldUtils {
public static String getString(Object value, String key, String defaultValue) throws InvalidCardDefinitionException {
if (value == null)
return defaultValue;
if ((value instanceof Number))
return value.toString();
if (!(value instanceof String))
throw new InvalidCardDefinitionException("Unknown type in " + key + " field");
return (String) value;

View File

@@ -77,6 +77,7 @@ public class EffectAppenderFactory {
effectAppenderProducers.put("lookattopcardsofdrawdeck", new LookAtTopCardsOfDrawDeck());
effectAppenderProducers.put("makeselfringbearer", new MakeSelfRingBearer());
effectAppenderProducers.put("memorize", new MemorizeActive());
effectAppenderProducers.put("memorizeactive", new MemorizeActive());
effectAppenderProducers.put("memorizenumber", new MemorizeNumber());
effectAppenderProducers.put("memorizestacked", new MemorizeStacked());
effectAppenderProducers.put("memorizevalue", new MemorizeValue());

View File

@@ -26,6 +26,9 @@ public class MemorizeActive implements EffectAppenderProducer {
final String filter = FieldUtils.getString(effectObject.get("filter"), "filter");
final String memory = FieldUtils.getString(effectObject.get("memory"), "memory");
if (memory == null)
throw new InvalidCardDefinitionException("Memory is required for a Memorize effect.");
final FilterableSource filterSource = environment.getFilterFactory().generateFilter(filter, environment);
return new DelayedAppender() {

View File

@@ -19,9 +19,13 @@ public class MemorizeNumber implements EffectAppenderProducer {
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "amount", "memory");
final ValueSource amountSource = ValueResolver.resolveEvaluator(effectObject.get("amount"), environment);
final String memory = FieldUtils.getString(effectObject.get("memory"), "memory");
if (memory == null)
throw new InvalidCardDefinitionException("Memory is required for a MemorizeNumber effect.");
final ValueSource amountSource = ValueResolver.resolveEvaluator(effectObject.get("amount"), environment);
return new DelayedAppender() {
@Override
protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) {

View File

@@ -29,6 +29,9 @@ public class MemorizeStacked implements EffectAppenderProducer {
final String on = FieldUtils.getString(effectObject.get("on"), "on");
final String memory = FieldUtils.getString(effectObject.get("memory"), "memory");
if (memory == null)
throw new InvalidCardDefinitionException("Memory is required for a MemorizeStacked effect.");
final FilterableSource filterSource = environment.getFilterFactory().generateFilter(filter, environment);
final FilterableSource onFilterSource = environment.getFilterFactory().generateFilter(on, environment);

View File

@@ -0,0 +1,24 @@
package com.gempukku.lotro.cards.build.field.effect.modifier;
import com.gempukku.lotro.cards.build.*;
import com.gempukku.lotro.cards.build.field.FieldUtils;
import com.gempukku.lotro.logic.modifiers.CantHealModifier;
import com.gempukku.lotro.logic.modifiers.RemoveGameTextModifier;
import org.json.simple.JSONObject;
public class DisableGameText implements ModifierSourceProducer {
@Override
public ModifierSource getModifierSource(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(object, "filter", "requires");
final JSONObject[] conditionArray = FieldUtils.getObjectArray(object.get("requires"), "requires");
final String filter = FieldUtils.getString(object.get("filter"), "filter");
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment);
final Requirement[] requirements = environment.getRequirementFactory().getRequirements(conditionArray, environment);
return (actionContext) -> new RemoveGameTextModifier(actionContext.getSource(),
new RequirementCondition(requirements, actionContext),
filterableSource.getFilterable(actionContext));
}
}

View File

@@ -45,6 +45,7 @@ public class ModifierSourceFactory {
modifierProducers.put("canttakemorewoundsthan", new CantTakeMoreWoundsThan());
modifierProducers.put("canttakewounds", new CantTakeWounds());
modifierProducers.put("cantusespecialabilities", new CantUseSpecialAbilities());
modifierProducers.put("disablegametext", new DisableGameText());
modifierProducers.put("extracosttoplay", new ExtraCostToPlay());
modifierProducers.put("fpculturespot", new FPCultureSpot());
modifierProducers.put("fpusesresinsteadofstr", new FPUsesResInsteadOfStr());

View File

@@ -325,12 +325,20 @@ public class LotroCardBlueprintLibrary {
card = errataMappings.get(base);
}
else {
var basecard = _blueprints.get(base);
//This should only really happen when errata IDs are made
//that do not line up with their official counterparts, such
//as when making multiple errata candidates.
if(basecard == null)
continue;
card = new JSONDefs.ErrataInfo();
card.BaseID = base;
card.Name = GameUtils.getFullName(_blueprints.get(base));
card.LinkText = GameUtils.getDeluxeCardLink(id, _blueprints.get(base));
card.Name = GameUtils.getFullName(basecard);
card.LinkText = GameUtils.getDeluxeCardLink(id, basecard);
card.ErrataIDs = new HashMap<>();
errataMappings.put(base, card);
}
card.ErrataIDs.put(JSONDefs.ErrataInfo.PC_Errata, id);

View File

@@ -42,8 +42,8 @@ public class Card_3_050_ErrataTests
* Twilight Cost: 1
* Type: condition
* Subtype:
* Game Text: To play, spot an [isengard] minion. Bearer must be a companion.
* Each time bearer wins a skirmish, add a burden.
* Game Text: Bearer must be a companion or ally.
* Each time bearer wins a skirmish against an [isengard] minion, add a burden.
* At the start of the regroup phase, the Free Peoples player may exert bearer twice to discard this condition.
*/

View File

@@ -42,9 +42,9 @@ public class Card_3_080_ErrataTests
* Twilight Cost: 0
* Type: condition
* Subtype:
* Game Text: To play, spot a [moria] minion. Bearer must be an unbound companion.
* At the start of each skirmish involving bearer, the Free Peoples player must discard an item borne by bearer or wound bearer.
* At the start of the regroup phase, the Free Peoples player may exert 2 other companions to discard this condition.
* Game Text: Bearer must be an unbound companion. Limit 1 per bearer.
* At the start of each skirmish involving bearer, the Free Peoples player must discard an item borne by
* bearer or wound bearer.
*/
//Pre-game setup

View File

@@ -42,9 +42,10 @@ public class Card_3_085_ErrataTests
* Twilight Cost: 1
* Type: condition
* Subtype:
* Game Text: To play, exert a [ringwraith] minion. Bearer must
* be a companion. Bearer cannot be exerted by Free Peoples cards.
* At the start of the regroup phase, the Free Peoples player may discard 2 cards from hand of bearer's culture to discard this condition.
* Game Text: To play, exert a [ringwraith] minion. Bearer must be a companion.
* Bearer cannot be exerted by Free Peoples cards.
* At the start of the regroup phase, the Free Peoples player may discard 2
* cards from hand of bearer's culture to discard this condition.
*/
//Pre-game setup

View File

@@ -43,8 +43,8 @@ public class Card_3_103_ErrataTests
* Type: condition
* Subtype:
* Game Text: To play, exert a [sauron] Orc. Bearer must be a companion or ally.
* Bearer's special abilities gain this cost: "Add 2 burdens or discard another Free Peoples character of the same race."
* At the start of the regroup phase, the Free Peoples player may exert bearer twice to discard this condition.
* Each time one of bearer's special abilities are used, the Free Peoples player must
* add discard a Free Peoples character or wound bearer.
*/
//Pre-game setup

View File

@@ -43,8 +43,8 @@ public class Card_3_105_ErrataTests
* Type: condition
* Subtype:
* Game Text: To play, spot a [sauron] minion (or Gollum). Bearer must be a companion or ally.
* Bearer's special abilities gain this cost: "Discard 2 of your conditions or wound this character."
* At the start of the regroup phase, the Free Peoples player may discard a Free Peoples character to discard this condition.
* Each time one of bearer's special abilities are used, the Free Peoples player must discard
* a Free Peoples condition or add a burden.
*/
//Pre-game setup
@@ -59,7 +59,7 @@ public class Card_3_105_ErrataTests
//assertEquals(Race., card.getBlueprint().getRace());
//assertTrue(card.getBlueprint().getPossessionClasses().contains(PossessionClass.));
assertTrue(scn.HasKeyword(card, Keyword.SUPPORT_AREA));
assertEquals(2, card.getBlueprint().getTwilightCost());
assertEquals(1, card.getBlueprint().getTwilightCost());
//assertEquals(, card.getBlueprint().getStrength());
//assertEquals(, card.getBlueprint().getVitality());
//assertEquals(, card.getBlueprint().getResistance());