AllyRegion filter added for Horn of Boromir errata
Added errata'd Horn of Boromir and unit tests. Added new "AllyInCurrentRegion" and "AllyInRegion" filters to facilitate it. Refactored base of PC card unit tests to be a bit easier to customize card lists.
This commit is contained in:
@@ -442,19 +442,23 @@
|
||||
"effects": {
|
||||
"type": "activated",
|
||||
"phase": "assignment",
|
||||
"condition": {
|
||||
"type": "canSpot",
|
||||
"filter": "bearer,notAssignedToSkirmish"
|
||||
},
|
||||
"cost": [
|
||||
{
|
||||
"type": "exert",
|
||||
"filter": "self"
|
||||
},
|
||||
"filter": "bearer"
|
||||
}
|
||||
],
|
||||
"effect":[
|
||||
{
|
||||
"type": "assignFpCharacterToSkirmish",
|
||||
"player": "fp",
|
||||
"fpCharacter": "self",
|
||||
"against": "minion"
|
||||
}
|
||||
],
|
||||
"effect":[
|
||||
"fpCharacter": "bearer",
|
||||
"against": "choose(minion)"
|
||||
},
|
||||
{
|
||||
"type": "modifyStrength",
|
||||
"filter": "choose(ally,allyInCurrentRegion)",
|
||||
|
||||
@@ -199,6 +199,17 @@ public class FilterFactory {
|
||||
int number = Integer.parseInt(parameterSplit[1]);
|
||||
return (actionContext) -> Filters.isAllyHome(number, sitesBlock);
|
||||
});
|
||||
parameterFilters.put("allyInRegion",
|
||||
(parameter, environment) -> {
|
||||
final String[] parameterSplit = parameter.split(",");
|
||||
final SitesBlock sitesBlock = Enum.valueOf(SitesBlock.class, parameterSplit[0].toUpperCase().replace('_', ' '));
|
||||
int number = Integer.parseInt(parameterSplit[1]);
|
||||
return (actionContext) -> Filters.isAllyInRegion(number, sitesBlock);
|
||||
});
|
||||
parameterFilters.put("allyInCurrentRegion",
|
||||
(parameter, environment) -> {
|
||||
return (actionContext) -> Filters.isAllyInCurrentRegion();
|
||||
});
|
||||
parameterFilters.put("siteBlock",
|
||||
(parameter, environment) -> {
|
||||
final SitesBlock sitesBlock = Enum.valueOf(SitesBlock.class, parameter.toUpperCase().replace(' ', '_'));
|
||||
|
||||
@@ -665,6 +665,28 @@ public class Filters {
|
||||
});
|
||||
}
|
||||
|
||||
public static Filter isAllyInRegion(final int regionNumber, final SitesBlock siteBlock) {
|
||||
return Filters.and(
|
||||
CardType.ALLY,
|
||||
new Filter() {
|
||||
@Override
|
||||
public boolean accepts(LotroGame game, PhysicalCard physicalCard) {
|
||||
return RuleUtils.isAllyInRegion(physicalCard, regionNumber, siteBlock);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Filter isAllyInCurrentRegion() {
|
||||
return Filters.and(
|
||||
CardType.ALLY,
|
||||
new Filter() {
|
||||
@Override
|
||||
public boolean accepts(LotroGame game, PhysicalCard physicalCard) {
|
||||
return RuleUtils.isAllyInRegion(physicalCard, GameUtils.getRegion(game), game.getGameState().getCurrentSiteBlock());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static final Filter allyAtHome = Filters.and(
|
||||
CardType.ALLY,
|
||||
new Filter() {
|
||||
@@ -709,6 +731,8 @@ public class Filters {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
public static Filter siteNumber(final int siteNumber) {
|
||||
return siteNumberBetweenInclusive(siteNumber, siteNumber);
|
||||
}
|
||||
|
||||
@@ -7,8 +7,10 @@ import com.gempukku.lotro.game.LotroCardBlueprint;
|
||||
import com.gempukku.lotro.game.PhysicalCard;
|
||||
import com.gempukku.lotro.game.state.LotroGame;
|
||||
import com.gempukku.lotro.game.state.Skirmish;
|
||||
import com.gempukku.lotro.logic.GameUtils;
|
||||
import com.gempukku.lotro.logic.modifiers.evaluator.Evaluator;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -186,4 +188,18 @@ public class RuleUtils {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isAllyInRegion(PhysicalCard ally, int regionNumber, SitesBlock siteBlock) {
|
||||
final SitesBlock allySiteBlock = ally.getBlueprint().getAllyHomeSiteBlock();
|
||||
final int[] allyHomeSites = ally.getBlueprint().getAllyHomeSiteNumbers();
|
||||
if (allySiteBlock != siteBlock)
|
||||
return false;
|
||||
// for (int number : allyHomeSites)
|
||||
// if (regionNumber == GameUtils.getRegion(number))
|
||||
// return true;
|
||||
// return false;
|
||||
|
||||
return Arrays.stream(ally.getBlueprint().getAllyHomeSiteNumbers()).anyMatch(x -> regionNumber == GameUtils.getRegion(x));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public abstract class AbstractAtTest {
|
||||
_userFeedback = new DefaultUserFeedback();
|
||||
|
||||
LotroFormatLibrary formatLibrary = new LotroFormatLibrary(new DefaultAdventureLibrary(), _library);
|
||||
LotroFormat format = formatLibrary.getFormat("movie");
|
||||
LotroFormat format = formatLibrary.getFormat("multipath");
|
||||
|
||||
_game = new DefaultLotroGame(format, decks, _userFeedback, _library);
|
||||
_userFeedback.setGame(_game);
|
||||
|
||||
@@ -8,8 +8,10 @@ import com.gempukku.lotro.common.Zone;
|
||||
import com.gempukku.lotro.game.CardNotFoundException;
|
||||
import com.gempukku.lotro.game.PhysicalCard;
|
||||
import com.gempukku.lotro.game.PhysicalCardImpl;
|
||||
import com.gempukku.lotro.game.state.Assignment;
|
||||
import com.gempukku.lotro.logic.decisions.AwaitingDecision;
|
||||
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
|
||||
import com.gempukku.lotro.logic.vo.LotroDeck;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -19,32 +21,68 @@ public class GenericCardTest extends AbstractAtTest {
|
||||
|
||||
private int LastCardID = 100;
|
||||
|
||||
//TODO: refactor this to not have different freeps/shadows collections
|
||||
public Map<String, PhysicalCardImpl> freepsCards = new HashMap<>();
|
||||
public Map<String, PhysicalCardImpl> shadowCards = new HashMap<>();
|
||||
public static final HashMap<String, String> FellowshipSites = new HashMap<String, String>() {{
|
||||
put("site1", "1_319");
|
||||
put("site2", "1_327");
|
||||
put("site3", "1_337");
|
||||
put("site4", "1_343");
|
||||
put("site5", "1_349");
|
||||
put("site6", "1_350");
|
||||
put("site7", "1_353");
|
||||
put("site8", "1_356");
|
||||
put("site9", "1_360");
|
||||
}};
|
||||
|
||||
public GenericCardTest(Map<String, String> freepsIDs, Map<String, String> shadowIDs) throws CardNotFoundException, DecisionResultInvalidException {
|
||||
public static final String FOTRFrodo = "1_290";
|
||||
public static final String FOTRRing = "1_2";
|
||||
|
||||
|
||||
// Player key, then name/card
|
||||
public Map<String, Map<String, PhysicalCardImpl>> Cards = new HashMap<>();
|
||||
|
||||
public GenericCardTest(Map<String, String> cardIDs) throws CardNotFoundException, DecisionResultInvalidException {
|
||||
this(cardIDs, null, null, null);
|
||||
}
|
||||
|
||||
public GenericCardTest(Map<String, String> cardIDs, Map<String, String> siteIDs, String ringBearerID, String ringID) throws CardNotFoundException, DecisionResultInvalidException {
|
||||
super();
|
||||
|
||||
initializeSimplestGame();
|
||||
if(siteIDs == null || ringBearerID == null || ringID == null) {
|
||||
initializeSimplestGame();
|
||||
}
|
||||
else {
|
||||
Map<String, LotroDeck> decks = new HashMap<String, LotroDeck>();
|
||||
decks.put(P1, new LotroDeck(P1));
|
||||
decks.put(P2, new LotroDeck(P2));
|
||||
|
||||
if(freepsIDs != null) {
|
||||
for(String name : freepsIDs.keySet()) {
|
||||
String id = freepsIDs.get(name);
|
||||
PhysicalCardImpl card = CreateCard(P1, id);
|
||||
freepsCards.put(name, card);
|
||||
FreepsMoveCardToDeck(card);
|
||||
ShadowMoveCardToDeck(CreateCard(P2, id));
|
||||
for(String name : siteIDs.keySet()) {
|
||||
String id = siteIDs.get(name);
|
||||
decks.get(P1).addSite(id);
|
||||
decks.get(P2).addSite(id);
|
||||
}
|
||||
|
||||
decks.get(P1).setRingBearer(ringBearerID);
|
||||
decks.get(P2).setRingBearer(ringBearerID);
|
||||
|
||||
decks.get(P1).setRing(ringID);
|
||||
decks.get(P2).setRing(ringID);
|
||||
|
||||
initializeGameWithDecks(decks);
|
||||
}
|
||||
|
||||
if(shadowIDs != null) {
|
||||
for(String name : shadowIDs.keySet()) {
|
||||
String id = shadowIDs.get(name);
|
||||
PhysicalCardImpl card = CreateCard(P2, id);
|
||||
shadowCards.put(name, card);
|
||||
ShadowMoveCardToDeck(card);
|
||||
FreepsMoveCardToDeck(CreateCard(P1, id));
|
||||
Cards.put(P1, new HashMap<>());
|
||||
Cards.put(P2, new HashMap<>());
|
||||
|
||||
if(cardIDs != null) {
|
||||
for(String name : cardIDs.keySet()) {
|
||||
String id = cardIDs.get(name);
|
||||
PhysicalCardImpl card = CreateCard(P1, id);
|
||||
Cards.get(P1).put(name, card);
|
||||
FreepsMoveCardToDeck(card);
|
||||
|
||||
card = CreateCard(P2, id);
|
||||
Cards.get(P2).put(name, card);
|
||||
FreepsMoveCardToDeck(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,8 +95,8 @@ public class GenericCardTest extends AbstractAtTest {
|
||||
skipMulligans();
|
||||
}
|
||||
|
||||
public PhysicalCardImpl GetFreepsCard(String cardName) { return freepsCards.get(cardName); }
|
||||
public PhysicalCardImpl GetShadowCard(String cardName) { return shadowCards.get(cardName); }
|
||||
public PhysicalCardImpl GetFreepsCard(String cardName) { return Cards.get(P1).get(cardName); }
|
||||
public PhysicalCardImpl GetShadowCard(String cardName) { return Cards.get(P2).get(cardName); }
|
||||
|
||||
public List<String> FreepsGetAvailableActions() { return GetAvailableActions(P1); }
|
||||
public List<String> ShadowGetAvailableActions() { return GetAvailableActions(P2); }
|
||||
@@ -213,18 +251,38 @@ public class GenericCardTest extends AbstractAtTest {
|
||||
public void FreepsAssignToMinion(PhysicalCardImpl comp, PhysicalCardImpl minion) throws DecisionResultInvalidException {
|
||||
playerDecided(P1, comp.getCardId() + " " + minion.getCardId());
|
||||
}
|
||||
public void FreepsAssignToMinions(PhysicalCardImpl[]... groups) throws DecisionResultInvalidException {
|
||||
String result = "";
|
||||
|
||||
for (PhysicalCardImpl[] group : groups) {
|
||||
result += group[0].getCardId();
|
||||
for(int i = 1; i < group.length; i++)
|
||||
{
|
||||
result += " " + group[i].getCardId();
|
||||
}
|
||||
result += ",";
|
||||
}
|
||||
|
||||
playerDecided(P1, result);
|
||||
}
|
||||
|
||||
public List<PhysicalCardImpl> FreepsGetAttachedCards(String name) { return GetAttachedCards(GetFreepsCard(name)); }
|
||||
public List<PhysicalCardImpl> GetAttachedCards(PhysicalCardImpl card)
|
||||
{
|
||||
public List<PhysicalCardImpl> GetAttachedCards(PhysicalCardImpl card) {
|
||||
return (List<PhysicalCardImpl>)(List<?>)_game.getGameState().getAttachedCards(card);
|
||||
}
|
||||
|
||||
public void FreepsResolveSkirmish(String name) throws DecisionResultInvalidException { FreepsResolveSkirmish(GetFreepsCard(name)); }
|
||||
public void FreepsResolveSkirmish(PhysicalCardImpl comp) throws DecisionResultInvalidException {
|
||||
playerDecided(P1, String.valueOf(comp.getCardId()));
|
||||
public void FreepsResolveSkirmish(PhysicalCardImpl comp) throws DecisionResultInvalidException { FreepsChooseCard(comp); }
|
||||
public void FreepsChooseCard(PhysicalCardImpl card) throws DecisionResultInvalidException {
|
||||
playerDecided(P1, String.valueOf(card.getCardId()));
|
||||
}
|
||||
|
||||
public boolean IsCharAssigned(PhysicalCardImpl card) {
|
||||
List<Assignment> assigns = _game.getGameState().getAssignments();
|
||||
return assigns.stream().anyMatch(x -> x.getFellowshipCharacter() == card || x.getShadowCharacters().contains(card));
|
||||
}
|
||||
|
||||
|
||||
public int FreepsGetStrength(String name) { return GetStrength(GetFreepsCard(name)); }
|
||||
public int ShadowGetStrength(String name) { return GetStrength(GetShadowCard(name)); }
|
||||
public int GetStrength(PhysicalCardImpl card)
|
||||
|
||||
@@ -22,8 +22,7 @@ public class Elrond_LoRErrataTest
|
||||
{{
|
||||
put("elrond", "21_1040");
|
||||
put("randomcard", "1_3");
|
||||
}},
|
||||
null
|
||||
}}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,8 +33,7 @@ public class Elrond_LoRErrataTest
|
||||
put("elrond", "21_1040");
|
||||
put("gandalf", "1_72");
|
||||
put("arwen", "1_30");
|
||||
}},
|
||||
null
|
||||
}}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -48,8 +46,7 @@ public class Elrond_LoRErrataTest
|
||||
put("allyHome3_2", "1_27");
|
||||
put("allyHome6_1", "1_56");
|
||||
put("allyHome6_2", "1_57");
|
||||
}},
|
||||
null
|
||||
}}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,7 @@ public class FlamingBrandErrataTest
|
||||
put("arwen", "1_30");
|
||||
put("boromir", "1_97");
|
||||
put("aragorn", "1_89");
|
||||
}},
|
||||
new HashMap<String, String>()
|
||||
{{
|
||||
|
||||
put("nazgul", "1_229");
|
||||
put("runner", "1_178");
|
||||
}}
|
||||
|
||||
@@ -18,8 +18,7 @@ public class Galadriel_LoLErrataTest
|
||||
{{
|
||||
put("galadriel", "21_1045");
|
||||
put("elrond", "1_40");
|
||||
}},
|
||||
null
|
||||
}}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -32,8 +31,7 @@ public class Galadriel_LoLErrataTest
|
||||
put("allyHome3_2", "1_27");
|
||||
put("allyHome6_1", "1_56");
|
||||
put("allyHome6_2", "1_57");
|
||||
}},
|
||||
null
|
||||
}}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.gempukku.lotro.cards.unofficial.pc.errata;
|
||||
|
||||
import com.gempukku.lotro.cards.GenericCardTest;
|
||||
import com.gempukku.lotro.common.Phase;
|
||||
import com.gempukku.lotro.common.Zone;
|
||||
import com.gempukku.lotro.game.CardNotFoundException;
|
||||
import com.gempukku.lotro.game.PhysicalCardImpl;
|
||||
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class HornOfBoromirErrataTest
|
||||
{
|
||||
protected GenericCardTest GetFOTRScenario() throws CardNotFoundException, DecisionResultInvalidException {
|
||||
return new GenericCardTest(
|
||||
new HashMap<String, String>()
|
||||
{{
|
||||
put("horn", "21_3042");
|
||||
put("elrond", "1_40");
|
||||
put("boromir", "1_97");
|
||||
put("aragorn", "1_89");
|
||||
|
||||
put("runner1", "1_178");
|
||||
put("runner2", "1_178");
|
||||
}},
|
||||
GenericCardTest.FellowshipSites,
|
||||
GenericCardTest.FOTRFrodo,
|
||||
GenericCardTest.FOTRRing
|
||||
);
|
||||
}
|
||||
|
||||
protected GenericCardTest GetMovieScenario() throws CardNotFoundException, DecisionResultInvalidException {
|
||||
return new GenericCardTest(
|
||||
new HashMap<String, String>()
|
||||
{{
|
||||
put("horn", "21_3042");
|
||||
put("elrond", "1_40");
|
||||
put("boromir", "1_97");
|
||||
put("aragorn", "1_89");
|
||||
|
||||
put("runner1", "1_178");
|
||||
put("runner2", "1_178");
|
||||
}}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void CanBeBorneByBoromir() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
//Pre-game setup
|
||||
GenericCardTest scn = GetFOTRScenario();
|
||||
|
||||
PhysicalCardImpl elrond = scn.GetFreepsCard("elrond");
|
||||
PhysicalCardImpl boromir = scn.GetFreepsCard("boromir");
|
||||
PhysicalCardImpl aragorn = scn.GetFreepsCard("aragorn");
|
||||
PhysicalCardImpl horn = scn.GetFreepsCard("horn");
|
||||
|
||||
scn.FreepsMoveCharToTable(elrond);
|
||||
|
||||
scn.FreepsMoveCharToTable(aragorn);
|
||||
scn.FreepsMoveCardToHand(horn);
|
||||
scn.FreepsMoveCardToHand(boromir);
|
||||
|
||||
scn.StartGame();
|
||||
|
||||
assertFalse(scn.FreepsActionAvailable("Play Horn of Boromir"));
|
||||
scn.FreepsUseAction("Play Boromir");
|
||||
assertTrue(scn.FreepsActionAvailable("Play Horn of Boromir"));
|
||||
scn.FreepsUseAction("Play Horn of Boromir");
|
||||
|
||||
Assert.assertEquals(Zone.ATTACHED, horn.getZone());
|
||||
Assert.assertEquals(boromir, horn.getAttachedTo());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void AbilityExertsAndAssignsBoromir() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
//Pre-game setup
|
||||
GenericCardTest scn = GetFOTRScenario();
|
||||
|
||||
PhysicalCardImpl elrond = scn.GetFreepsCard("elrond");
|
||||
PhysicalCardImpl boromir = scn.GetFreepsCard("boromir");
|
||||
PhysicalCardImpl horn = scn.GetFreepsCard("horn");
|
||||
PhysicalCardImpl runner1 = scn.GetShadowCard("runner1");
|
||||
PhysicalCardImpl runner2 = scn.GetShadowCard("runner2");
|
||||
|
||||
scn.FreepsMoveCharToTable(elrond);
|
||||
scn.FreepsMoveCharToTable(boromir);
|
||||
scn.FreepsMoveCardToHand(horn);
|
||||
|
||||
scn.ShadowMoveCharToTable(runner1);
|
||||
scn.ShadowMoveCharToTable(runner2);
|
||||
|
||||
scn.StartGame();
|
||||
|
||||
scn.FreepsUseAction("Play Horn of Boromir");
|
||||
|
||||
scn.SkipToPhase(Phase.ASSIGNMENT);
|
||||
assertTrue(scn.FreepsActionAvailable("Use Horn of Boromir"));
|
||||
scn.FreepsUseAction("Use Horn of Boromir");
|
||||
scn.FreepsChooseCard(runner1);
|
||||
|
||||
assertEquals(1, scn.GetWoundsOn(boromir));
|
||||
assertEquals(11, scn.GetStrength(elrond));
|
||||
//Skip shadow player's action
|
||||
scn.SkipCurrentPhaseActions();
|
||||
assertFalse(scn.FreepsActionAvailable("Use Horn of Boromir"));
|
||||
scn.SkipCurrentPhaseActions();
|
||||
assertTrue(scn.IsCharAssigned(boromir));
|
||||
|
||||
scn.FreepsAssignToMinion(elrond, runner2);
|
||||
assertTrue(scn.IsCharAssigned(elrond));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void AbilityDoesNotPumpFarAwayAllies() throws DecisionResultInvalidException, CardNotFoundException {
|
||||
GenericCardTest scn = GetMovieScenario();
|
||||
|
||||
PhysicalCardImpl elrond = scn.GetFreepsCard("elrond");
|
||||
PhysicalCardImpl boromir = scn.GetFreepsCard("boromir");
|
||||
PhysicalCardImpl horn = scn.GetFreepsCard("horn");
|
||||
PhysicalCardImpl runner1 = scn.GetShadowCard("runner1");
|
||||
PhysicalCardImpl runner2 = scn.GetShadowCard("runner2");
|
||||
|
||||
scn.FreepsMoveCharToTable(elrond);
|
||||
scn.FreepsMoveCharToTable(boromir);
|
||||
scn.FreepsMoveCardToHand(horn);
|
||||
|
||||
scn.ShadowMoveCharToTable(runner1);
|
||||
scn.ShadowMoveCharToTable(runner2);
|
||||
|
||||
scn.StartGame();
|
||||
|
||||
scn.FreepsUseAction("Play Horn of Boromir");
|
||||
|
||||
scn.SkipToPhase(Phase.ASSIGNMENT);
|
||||
scn.FreepsUseAction("Use Horn of Boromir");
|
||||
scn.FreepsChooseCard(runner1);
|
||||
|
||||
assertEquals(1, scn.GetWoundsOn(boromir));
|
||||
assertEquals(8, scn.GetStrength(elrond));
|
||||
//Skip shadow player's action
|
||||
scn.SkipCurrentPhaseActions();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,7 @@ public class Sam_SoHErrataTest
|
||||
new HashMap<String, String>()
|
||||
{{
|
||||
put("sam", "21_10311");
|
||||
}},
|
||||
new HashMap<String, String>()
|
||||
{{
|
||||
|
||||
put("orc", "1_272");
|
||||
}}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user