Bill The Pony Errata

Added Bill the Pony errata and unit tests.  Added the Pony possession class.
This commit is contained in:
Christian 'ketura' McCarty
2021-02-06 15:19:09 -06:00
parent 24b373a3c1
commit af642546e7
8 changed files with 224 additions and 17 deletions

View File

@@ -669,4 +669,56 @@
},
"21_30106": {
"title": "*Bill the Pony",
"culture": "Shire",
"side": "free_people",
"cost": 0,
"type": "possession",
"possession": "Pony",
"target": "name(Sam)",
"effects": [
{
"type": "trigger",
"trigger": {
"type": "played",
"filter": "self"
},
"effect": {
"type": "heal",
"filter": "bearer"
}
},
{
"type": "modifier",
"modifier": {
"type": "addKeyword",
"filter": "bearer",
"keyword": "concealed"
}
},
{
"type": "trigger",
"trigger": {
"type": "condition",
"condition": [
{
"type": "location",
"filter": "underground"
},
{
"type": "canSpot",
"filter": "self,attachedTo(companion)"
}
]
},
"effect": {
"type": "discard",
"filter": "self"
}
}
]
},
}

View File

@@ -62,5 +62,6 @@ var set21 = {
'21_3042': 'https://i.lotrtcgpc.net/errata/FOTR/23_42.jpg',
'21_3068': 'https://i.lotrtcgpc.net/errata/FOTR/23_68.jpg',
'21_20121': 'https://i.lotrtcgpc.net/errata/FOTR/22_121.jpg',
'21_3038': 'https://i.lotrtcgpc.net/errata/FOTR/23_38.jpg'
'21_3038': 'https://i.lotrtcgpc.net/errata/FOTR/23_38.jpg',
'21_30106': 'https://i.lotrtcgpc.net/errata/FOTR/23_106.jpg'
}

View File

@@ -4,7 +4,12 @@ public enum PossessionClass implements Filterable {
HAND_WEAPON("Hand Weapon"), ARMOR("Armor"), HELM("Helm"), MOUNT("Mount"), RANGED_WEAPON("Ranged Weapon"),
CLOAK("Cloak"), PIPE("Pipe"), SHIELD("Shield"), BRACERS("Bracers"), STAFF("Staff"), RING("Ring"),
BROOCH("Brooch"), GAUNTLETS("Gauntlets"), BOX("Box"), PALANTIR("Palantir"), PHIAL("Phial"), HORN("Horn"),
CLASSLESS("Classless");
CLASSLESS("Classless"),
//PC Classes
PONY("Pony")
;
private String _humanReadable;

View File

@@ -369,6 +369,14 @@ public class GenericCardTestHelper extends AbstractAtTest {
return assigns.stream().anyMatch(x -> x.getFellowshipCharacter() == card || x.getShadowCharacters().contains(card));
}
public boolean IsAttachedTo(PhysicalCardImpl card, PhysicalCardImpl bearer) {
if(card.getZone() != Zone.ATTACHED) {
return false;
}
return bearer == card.getAttachedTo();
}
public int FreepsGetStrength(String name) { return GetStrength(GetFreepsCard(name)); }
public int ShadowGetStrength(String name) { return GetStrength(GetShadowCard(name)); }
@@ -396,18 +404,21 @@ public class GenericCardTestHelper extends AbstractAtTest {
public void ShadowAcceptOptionalTrigger() throws DecisionResultInvalidException { playerDecided(P2, "0"); }
public void ShadowDeclineOptionalTrigger() throws DecisionResultInvalidException { playerDecided(P2, "1"); }
public void FreepsAcceptMultipleChoiceOption(String option) throws DecisionResultInvalidException { AcceptMultipleChoiceOption(P1, option); }
public void ShadowAcceptMultipleChoiceOption(String option) throws DecisionResultInvalidException { AcceptMultipleChoiceOption(P2, option); }
public void AcceptMultipleChoiceOption(String playerID, String option) throws DecisionResultInvalidException {
List<String> choices = GetADParamAsList(playerID, "results");
for(String choice : choices){
if(choice.toLowerCase().contains(option.toLowerCase())) {
playerDecided(playerID, String.valueOf(choices.indexOf(choice)));
return;
}
}
//couldn't find an exact match, so maybe it's a direct index:
playerDecided(playerID, option);
public void FreepsChooseMultipleChoiceOption(String option) throws DecisionResultInvalidException { ChooseMultipleChoiceOption(P1, option); }
public void ShadowChooseMultipleChoiceOption(String option) throws DecisionResultInvalidException { ChooseMultipleChoiceOption(P2, option); }
public void ChooseMultipleChoiceOption(String playerID, String option) throws DecisionResultInvalidException { ChooseAction(playerID, "results", option); }
public void ChooseAction(String playerID, String paramName, String option) throws DecisionResultInvalidException {
List<String> choices = GetADParamAsList(playerID, paramName);
for(String choice : choices){
if(choice.toLowerCase().contains(option.toLowerCase())) {
playerDecided(playerID, String.valueOf(choices.indexOf(choice)));
return;
}
}
//couldn't find an exact match, so maybe it's a direct index:
playerDecided(playerID, option);
}
public void FreepsResolveActionOrder(String option) throws DecisionResultInvalidException { ChooseAction(P1, "actionText", option); }
}

View File

@@ -55,6 +55,8 @@ public class FlamingBrandErrataTests
//There are 3 companions in play, but only 2 rangers, so we should only see 2 options
assertEquals(2, scn.FreepsGetADParamAsList("cardId").size());
scn.FreepsChooseCard(aragorn);
assertTrue(scn.IsAttachedTo(brand, aragorn));
}

View File

@@ -174,7 +174,7 @@ public class Aragorn_HttWCErrataTests
scn.ShadowAcceptOptionalTrigger();
assertEquals(1, scn.GetShadowHandCount());
assertTrue(scn.ShadowDecisionAvailable("Choose action to perform"));
scn.ShadowAcceptMultipleChoiceOption("Reveal a tracker");
scn.ShadowChooseMultipleChoiceOption("Reveal a tracker");
assertFalse(scn.FreepsAnyDecisionsAvailable());
assertFalse(scn.HasKeyword(frodo, Keyword.CONCEALED));

View File

@@ -0,0 +1,137 @@
package com.gempukku.lotro.cards.unofficial.pc.errata.set3;
import com.gempukku.lotro.cards.GenericCardTestHelper;
import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.common.Keyword;
import com.gempukku.lotro.common.Phase;
import com.gempukku.lotro.common.Zone;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.CardNotFoundException;
import com.gempukku.lotro.game.PhysicalCardImpl;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
import com.gempukku.lotro.logic.modifiers.KeywordModifier;
import junit.framework.Assert;
import org.junit.Test;
import java.util.HashMap;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class BillThePonyErrataTests
{
protected GenericCardTestHelper GetSimpleScenario() throws CardNotFoundException, DecisionResultInvalidException {
return new GenericCardTestHelper(
new HashMap<String, String>()
{{
put("bill", "21_30106");
put("sam", "1_311");
}}
);
}
@Test
public void BillCanBeBorneBySam() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetSimpleScenario();
PhysicalCardImpl bill = scn.GetFreepsCard("bill");
PhysicalCardImpl sam = scn.GetFreepsCard("sam");
scn.FreepsMoveCardToHand(bill, sam);
scn.StartGame();
assertFalse(scn.FreepsCardPlayAvailable(bill));
scn.FreepsPlayCard(sam);
assertTrue(scn.FreepsCardPlayAvailable(bill));
scn.FreepsPlayCard(bill);
Assert.assertTrue(scn.IsAttachedTo(bill, sam));
}
@Test
public void BillHealsWhenPlayed() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetSimpleScenario();
PhysicalCardImpl bill = scn.GetFreepsCard("bill");
PhysicalCardImpl sam = scn.GetFreepsCard("sam");
scn.FreepsMoveCardToHand(bill, sam);
scn.StartGame();
scn.FreepsPlayCard(sam);
scn.FreepsUseCardAction(sam);
assertEquals(1, scn.GetWoundsOn(sam));
scn.FreepsPlayCard(bill);
assertEquals(0, scn.GetWoundsOn(sam));
}
@Test
public void BillGrantsConcealed() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetSimpleScenario();
PhysicalCardImpl bill = scn.GetFreepsCard("bill");
PhysicalCardImpl sam = scn.GetFreepsCard("sam");
scn.FreepsMoveCardToHand(bill, sam);
scn.StartGame();
scn.FreepsPlayCard(sam);
scn.FreepsPlayCard(bill);
assertTrue(scn.HasKeyword(sam, Keyword.CONCEALED));
}
@Test
public void BillDiscardedWhenMovingToUnderground() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetSimpleScenario();
PhysicalCardImpl bill = scn.GetFreepsCard("bill");
PhysicalCardImpl sam = scn.GetFreepsCard("sam");
scn.FreepsMoveCardToHand(bill, sam);
scn.InsertAdHocModifier(new KeywordModifier(null, Filters.siteNumber(2), Keyword.UNDERGROUND));
scn.StartGame();
scn.FreepsPlayCard(sam);
scn.FreepsPlayCard(bill);
scn.FreepsSkipCurrentPhaseAction();
//Get a timing choice between resolving concealed or discarding bill
scn.FreepsResolveActionOrder("Concealed");
assertFalse(scn.IsAttachedTo(bill, sam));
assertEquals(Zone.DISCARD, bill.getZone());
}
@Test
public void BillHealsWhenPlayedAtUnderground() throws DecisionResultInvalidException, CardNotFoundException {
//Pre-game setup
GenericCardTestHelper scn = GetSimpleScenario();
PhysicalCardImpl bill = scn.GetFreepsCard("bill");
PhysicalCardImpl sam = scn.GetFreepsCard("sam");
scn.FreepsMoveCardToHand(bill, sam);
scn.InsertAdHocModifier(new KeywordModifier(null, CardType.SITE, Keyword.UNDERGROUND));
scn.StartGame();
scn.FreepsPlayCard(sam);
scn.FreepsUseCardAction(sam);
assertEquals(1, scn.GetWoundsOn(sam));
scn.FreepsPlayCard(bill);
assertEquals(0, scn.GetWoundsOn(sam));
assertFalse(scn.IsAttachedTo(bill, sam));
assertEquals(Zone.DISCARD, bill.getZone());
}
}

View File

@@ -72,8 +72,7 @@ public class HornOfBoromirErrataTests
assertTrue(scn.FreepsCardPlayAvailable(horn));
scn.FreepsPlayCard(horn);
Assert.assertEquals(Zone.ATTACHED, horn.getZone());
Assert.assertEquals(boromir, horn.getAttachedTo());
Assert.assertTrue(scn.IsAttachedTo(horn, boromir));
}
@Test