Fixed V2 Breaching Shot being playable if there aren't enough tokens on machines to assign an uruk, and also fixed it crashing the game if not enough tokens were removed to assign an uruk.
This commit is contained in:
@@ -183,11 +183,18 @@
|
|||||||
timewords: Assignment
|
timewords: Assignment
|
||||||
effects: {
|
effects: {
|
||||||
type: event
|
type: event
|
||||||
requires: {
|
requires: [
|
||||||
|
{
|
||||||
type: CanSpotCultureTokens
|
type: CanSpotCultureTokens
|
||||||
culture: isengard
|
culture: isengard
|
||||||
filter: machine
|
filter: machine
|
||||||
|
memorize: tokenCount
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
type: CanSpot
|
||||||
|
filter: uruk-hai,MaxTwilight(memory(tokenCount))
|
||||||
|
}
|
||||||
|
]
|
||||||
cost: [
|
cost: [
|
||||||
{
|
{
|
||||||
type: ChooseANumber
|
type: ChooseANumber
|
||||||
@@ -199,7 +206,6 @@
|
|||||||
}
|
}
|
||||||
memorize: removed
|
memorize: removed
|
||||||
}
|
}
|
||||||
|
|
||||||
],
|
],
|
||||||
effect: [
|
effect: [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ public class ValueResolver {
|
|||||||
return (game, cardAffected) -> {
|
return (game, cardAffected) -> {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for (PhysicalCard physicalCard : Filters.filterActive(game, filterable)) {
|
for (PhysicalCard physicalCard : Filters.filterActive(game, filterable)) {
|
||||||
result += game.getModifiersQuerying().getTwilightCostToPlay(game, physicalCard, null, 0, false);
|
result += game.getModifiersQuerying().getCurrentTwilightCost(game, physicalCard);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -406,6 +406,50 @@ public class FilterFactory {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
parameterFilters.put("highesttwilight",
|
||||||
|
(parameter, environment) -> {
|
||||||
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
||||||
|
return actionContext -> {
|
||||||
|
final Filterable sourceFilterable = filterableSource.getFilterable(actionContext);
|
||||||
|
return Filters.and(
|
||||||
|
sourceFilterable, Filters.strengthEqual(
|
||||||
|
new SingleMemoryEvaluator(
|
||||||
|
new Evaluator() {
|
||||||
|
@Override
|
||||||
|
public int evaluateExpression(LotroGame game, PhysicalCard cardAffected) {
|
||||||
|
int maxTwilight = Integer.MIN_VALUE;
|
||||||
|
for (PhysicalCard card : Filters.filterActive(game, sourceFilterable))
|
||||||
|
maxTwilight = Math.max(maxTwilight, game.getModifiersQuerying().getCurrentTwilightCost(game, card));
|
||||||
|
return maxTwilight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
parameterFilters.put("lowesttwilight",
|
||||||
|
(parameter, environment) -> {
|
||||||
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
||||||
|
return actionContext -> {
|
||||||
|
final Filterable sourceFilterable = filterableSource.getFilterable(actionContext);
|
||||||
|
return Filters.and(
|
||||||
|
sourceFilterable, Filters.strengthEqual(
|
||||||
|
new SingleMemoryEvaluator(
|
||||||
|
new Evaluator() {
|
||||||
|
@Override
|
||||||
|
public int evaluateExpression(LotroGame game, PhysicalCard cardAffected) {
|
||||||
|
int minTwilight = Integer.MAX_VALUE;
|
||||||
|
for (PhysicalCard card : Filters.filterActive(game, sourceFilterable))
|
||||||
|
minTwilight = Math.min(minTwilight, game.getModifiersQuerying().getCurrentTwilightCost(game, card));
|
||||||
|
return minTwilight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
});
|
||||||
parameterFilters.put("inskirmishagainst",
|
parameterFilters.put("inskirmishagainst",
|
||||||
(parameter, environment) -> {
|
(parameter, environment) -> {
|
||||||
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(parameter, environment);
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package com.gempukku.lotro.cards.build.field.effect.requirement;
|
package com.gempukku.lotro.cards.build.field.effect.requirement;
|
||||||
|
|
||||||
import com.gempukku.lotro.cards.build.CardGenerationEnvironment;
|
import com.gempukku.lotro.cards.build.*;
|
||||||
import com.gempukku.lotro.cards.build.FilterableSource;
|
|
||||||
import com.gempukku.lotro.cards.build.InvalidCardDefinitionException;
|
|
||||||
import com.gempukku.lotro.cards.build.Requirement;
|
|
||||||
import com.gempukku.lotro.cards.build.field.FieldUtils;
|
import com.gempukku.lotro.cards.build.field.FieldUtils;
|
||||||
|
import com.gempukku.lotro.cards.build.field.effect.appender.resolver.ValueResolver;
|
||||||
import com.gempukku.lotro.common.Culture;
|
import com.gempukku.lotro.common.Culture;
|
||||||
import com.gempukku.lotro.common.Filterable;
|
import com.gempukku.lotro.common.Filterable;
|
||||||
import com.gempukku.lotro.common.Token;
|
import com.gempukku.lotro.common.Token;
|
||||||
@@ -15,12 +13,13 @@ import org.json.simple.JSONObject;
|
|||||||
public class CanSpotCultureTokens implements RequirementProducer {
|
public class CanSpotCultureTokens implements RequirementProducer {
|
||||||
@Override
|
@Override
|
||||||
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
|
public Requirement getPlayRequirement(JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
|
||||||
FieldUtils.validateAllowedFields(object, "culture", "filter", "amount");
|
FieldUtils.validateAllowedFields(object, "culture", "filter", "amount", "memorize");
|
||||||
|
|
||||||
final int count = FieldUtils.getInteger(object.get("amount"), "amount", 1);
|
final ValueSource valueSource = ValueResolver.resolveEvaluator(object.get("amount"), 1, environment);
|
||||||
final String filter = FieldUtils.getString(object.get("filter"), "filter", "any");
|
final String filter = FieldUtils.getString(object.get("filter"), "filter", "any");
|
||||||
final Culture culture = FieldUtils.getEnum(Culture.class, object.get("culture"), "culture");
|
final Culture culture = FieldUtils.getEnum(Culture.class, object.get("culture"), "culture");
|
||||||
final Token tokenForCulture = culture != null ? Token.findTokenForCulture(culture) : null;
|
final Token tokenForCulture = culture != null ? Token.findTokenForCulture(culture) : null;
|
||||||
|
final String memory = FieldUtils.getString(object.get("memorize"), "memorize");
|
||||||
|
|
||||||
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment);
|
final FilterableSource filterableSource = environment.getFilterFactory().generateFilter(filter, environment);
|
||||||
|
|
||||||
@@ -28,13 +27,22 @@ public class CanSpotCultureTokens implements RequirementProducer {
|
|||||||
return (actionContext) -> {
|
return (actionContext) -> {
|
||||||
LotroGame game = actionContext.getGame();
|
LotroGame game = actionContext.getGame();
|
||||||
Filterable[] filters = new Filterable[]{filterableSource.getFilterable(actionContext)};
|
Filterable[] filters = new Filterable[]{filterableSource.getFilterable(actionContext)};
|
||||||
|
int count = valueSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
|
||||||
|
|
||||||
return GameUtils.getAllSpottableCultureTokens(game, filters) >= count;
|
return GameUtils.getAllSpottableCultureTokens(game, filters) >= count;
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return (actionContext) -> {
|
return (actionContext) -> {
|
||||||
LotroGame game = actionContext.getGame();
|
LotroGame game = actionContext.getGame();
|
||||||
Filterable[] filters = new Filterable[]{filterableSource.getFilterable(actionContext)};
|
Filterable[] filters = new Filterable[]{filterableSource.getFilterable(actionContext)};
|
||||||
return GameUtils.getSpottableCultureTokensOfType(game, tokenForCulture, filters) >= count;
|
int count = valueSource.getEvaluator(actionContext).evaluateExpression(actionContext.getGame(), null);
|
||||||
|
int tokens = GameUtils.getSpottableCultureTokensOfType(game, tokenForCulture, filters);
|
||||||
|
|
||||||
|
if (memory != null) {
|
||||||
|
actionContext.setValueToMemory(memory, String.valueOf(tokens));
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokens >= count;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ public class GameUtils {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<PhysicalCard> getRandomCards(List<? extends PhysicalCard> cards, int count) {
|
public static List<PhysicalCard> getRandomCards(Collection<? extends PhysicalCard> cards, int count) {
|
||||||
List<PhysicalCard> randomizedCards = new ArrayList<>(cards);
|
List<PhysicalCard> randomizedCards = new ArrayList<>(cards);
|
||||||
Collections.shuffle(randomizedCards, ThreadLocalRandom.current());
|
Collections.shuffle(randomizedCards, ThreadLocalRandom.current());
|
||||||
|
|
||||||
|
|||||||
@@ -492,6 +492,11 @@ public class ModifiersLogic implements ModifiersEnvironment, ModifiersQuerying {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentTwilightCost(LotroGame game, PhysicalCard physicalCard) {
|
||||||
|
return getTwilightCostToPlay(game, physicalCard, null, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getTwilightCostToPlay(LotroGame game, PhysicalCard physicalCard, PhysicalCard target, int twilightCostModifier, boolean ignoreRoamingPenalty) {
|
public int getTwilightCostToPlay(LotroGame game, PhysicalCard physicalCard, PhysicalCard target, int twilightCostModifier, boolean ignoreRoamingPenalty) {
|
||||||
LoggingThreadLocal.logMethodStart(physicalCard, "getTwilightCost");
|
LoggingThreadLocal.logMethodStart(physicalCard, "getTwilightCost");
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public interface ModifiersQuerying {
|
|||||||
|
|
||||||
// Twilight cost
|
// Twilight cost
|
||||||
int getTwilightCostToPlay(LotroGame game, PhysicalCard physicalCard, PhysicalCard target, int twilightCostModifier, boolean ignoreRoamingPenalty);
|
int getTwilightCostToPlay(LotroGame game, PhysicalCard physicalCard, PhysicalCard target, int twilightCostModifier, boolean ignoreRoamingPenalty);
|
||||||
|
int getCurrentTwilightCost(LotroGame game, PhysicalCard physicalCard);
|
||||||
|
|
||||||
int getRoamingPenalty(LotroGame game, PhysicalCard physicalCard);
|
int getRoamingPenalty(LotroGame game, PhysicalCard physicalCard);
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.gempukku.lotro.cards.unofficial.pc.vsets.set_v02;
|
|||||||
import com.gempukku.lotro.cards.GenericCardTestHelper;
|
import com.gempukku.lotro.cards.GenericCardTestHelper;
|
||||||
import com.gempukku.lotro.common.*;
|
import com.gempukku.lotro.common.*;
|
||||||
import com.gempukku.lotro.game.CardNotFoundException;
|
import com.gempukku.lotro.game.CardNotFoundException;
|
||||||
import com.gempukku.lotro.game.PhysicalCardImpl;
|
|
||||||
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
|
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -18,8 +17,14 @@ public class Card_V2_021_Tests
|
|||||||
return new GenericCardTestHelper(
|
return new GenericCardTestHelper(
|
||||||
new HashMap<>()
|
new HashMap<>()
|
||||||
{{
|
{{
|
||||||
put("card", "102_21");
|
put("shot", "102_21");
|
||||||
// put other cards in here as needed for the test case
|
put("ram", "5_44");
|
||||||
|
put("ladder", "5_57");
|
||||||
|
put("fighter", "1_146"); // 3
|
||||||
|
put("guard", "1_147"); // 4
|
||||||
|
|
||||||
|
put("merry", "1_302");
|
||||||
|
|
||||||
}},
|
}},
|
||||||
GenericCardTestHelper.FellowshipSites,
|
GenericCardTestHelper.FellowshipSites,
|
||||||
GenericCardTestHelper.FOTRFrodo,
|
GenericCardTestHelper.FOTRFrodo,
|
||||||
@@ -44,7 +49,7 @@ public class Card_V2_021_Tests
|
|||||||
|
|
||||||
var scn = GetScenario();
|
var scn = GetScenario();
|
||||||
|
|
||||||
var card = scn.GetFreepsCard("card");
|
var card = scn.GetFreepsCard("shot");
|
||||||
|
|
||||||
assertEquals("Breaching Shot", card.getBlueprint().getTitle());
|
assertEquals("Breaching Shot", card.getBlueprint().getTitle());
|
||||||
assertNull(card.getBlueprint().getSubtitle());
|
assertNull(card.getBlueprint().getSubtitle());
|
||||||
@@ -56,18 +61,191 @@ public class Card_V2_021_Tests
|
|||||||
assertEquals(2, card.getBlueprint().getTwilightCost());
|
assertEquals(2, card.getBlueprint().getTwilightCost());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uncomment any @Test markers below once this is ready to be used
|
@Test
|
||||||
//@Test
|
public void BreachingShotCanRemove3TokensToAssignAnUrukCosting3() throws DecisionResultInvalidException, CardNotFoundException {
|
||||||
public void BreachingShotTest1() throws DecisionResultInvalidException, CardNotFoundException {
|
|
||||||
//Pre-game setup
|
//Pre-game setup
|
||||||
var scn = GetScenario();
|
var scn = GetScenario();
|
||||||
|
|
||||||
var card = scn.GetFreepsCard("card");
|
var shot = scn.GetShadowCard("shot");
|
||||||
scn.FreepsMoveCardToHand(card);
|
var ladder = scn.GetShadowCard("ladder");
|
||||||
|
var fighter = scn.GetShadowCard("fighter");
|
||||||
|
var guard = scn.GetShadowCard("guard");
|
||||||
|
scn.ShadowMoveCardToHand(shot);
|
||||||
|
scn.ShadowMoveCardToSupportArea(ladder);
|
||||||
|
scn.ShadowMoveCharToTable(fighter, guard);
|
||||||
|
|
||||||
|
var frodo = scn.GetRingBearer();
|
||||||
|
var merry = scn.GetFreepsCard("merry");
|
||||||
|
scn.FreepsMoveCharToTable(merry);
|
||||||
|
|
||||||
scn.StartGame();
|
scn.StartGame();
|
||||||
scn.FreepsPlayCard(card);
|
scn.AddTokensToCard(ladder, 3);
|
||||||
|
scn.SkipToPhase(Phase.ASSIGNMENT);
|
||||||
|
scn.FreepsPassCurrentPhaseAction();
|
||||||
|
|
||||||
assertEquals(2, scn.GetTwilight());
|
assertTrue(scn.ShadowPlayAvailable(shot));
|
||||||
|
assertEquals(3, scn.GetCultureTokensOn(ladder));
|
||||||
|
assertEquals(3, fighter.getBlueprint().getTwilightCost());
|
||||||
|
assertEquals(4, guard.getBlueprint().getTwilightCost());
|
||||||
|
assertFalse(scn.IsCharAssigned(merry));
|
||||||
|
assertFalse(scn.IsCharAssigned(fighter));
|
||||||
|
assertFalse(scn.IsCharAssigned(guard));
|
||||||
|
scn.ShadowPlayCard(shot);
|
||||||
|
scn.ShadowChoose("3");
|
||||||
|
|
||||||
|
assertEquals(0, scn.GetCultureTokensOn(ladder));
|
||||||
|
assertTrue(scn.IsCharAssigned(merry));
|
||||||
|
assertTrue(scn.IsCharAssigned(fighter));
|
||||||
|
assertFalse(scn.IsCharAssigned(guard));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void BreachingShotCanRemove3TokensFromVariousMachinesToAssignAnUrukCosting3() throws DecisionResultInvalidException, CardNotFoundException {
|
||||||
|
//Pre-game setup
|
||||||
|
var scn = GetScenario();
|
||||||
|
|
||||||
|
var shot = scn.GetShadowCard("shot");
|
||||||
|
var ladder = scn.GetShadowCard("ladder");
|
||||||
|
var ram = scn.GetShadowCard("ram");
|
||||||
|
var fighter = scn.GetShadowCard("fighter");
|
||||||
|
var guard = scn.GetShadowCard("guard");
|
||||||
|
scn.ShadowMoveCardToHand(shot);
|
||||||
|
scn.ShadowMoveCardToSupportArea(ladder, ram);
|
||||||
|
scn.ShadowMoveCharToTable(fighter, guard);
|
||||||
|
|
||||||
|
var merry = scn.GetFreepsCard("merry");
|
||||||
|
scn.FreepsMoveCharToTable(merry);
|
||||||
|
|
||||||
|
scn.StartGame();
|
||||||
|
scn.AddTokensToCard(ladder, 2);
|
||||||
|
scn.AddTokensToCard(ram, 2);
|
||||||
|
scn.SkipToPhase(Phase.ASSIGNMENT);
|
||||||
|
scn.FreepsPassCurrentPhaseAction();
|
||||||
|
|
||||||
|
assertTrue(scn.ShadowPlayAvailable(shot));
|
||||||
|
assertEquals(2, scn.GetCultureTokensOn(ladder));
|
||||||
|
assertEquals(2, scn.GetCultureTokensOn(ram));
|
||||||
|
assertEquals(3, fighter.getBlueprint().getTwilightCost());
|
||||||
|
assertEquals(4, guard.getBlueprint().getTwilightCost());
|
||||||
|
assertFalse(scn.IsCharAssigned(merry));
|
||||||
|
assertFalse(scn.IsCharAssigned(fighter));
|
||||||
|
assertFalse(scn.IsCharAssigned(guard));
|
||||||
|
scn.ShadowPlayCard(shot);
|
||||||
|
scn.ShadowChoose("3");
|
||||||
|
|
||||||
|
assertEquals(2, scn.ShadowGetCardChoiceCount()); //2 machines with tokens
|
||||||
|
scn.ShadowChooseCard(ram);
|
||||||
|
scn.ShadowChooseCard(ladder);
|
||||||
|
scn.ShadowChooseCard(ram);
|
||||||
|
|
||||||
|
assertEquals(0, scn.GetCultureTokensOn(ram));
|
||||||
|
assertEquals(1, scn.GetCultureTokensOn(ladder));
|
||||||
|
assertTrue(scn.IsCharAssigned(merry));
|
||||||
|
assertTrue(scn.IsCharAssigned(fighter));
|
||||||
|
assertFalse(scn.IsCharAssigned(guard));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void BreachingShotCanRemove4TokensToAssignAnUrukCosting3Or4() throws DecisionResultInvalidException, CardNotFoundException {
|
||||||
|
//Pre-game setup
|
||||||
|
var scn = GetScenario();
|
||||||
|
|
||||||
|
var shot = scn.GetShadowCard("shot");
|
||||||
|
var ladder = scn.GetShadowCard("ladder");
|
||||||
|
var fighter = scn.GetShadowCard("fighter");
|
||||||
|
var guard = scn.GetShadowCard("guard");
|
||||||
|
scn.ShadowMoveCardToHand(shot);
|
||||||
|
scn.ShadowMoveCardToSupportArea(ladder);
|
||||||
|
scn.ShadowMoveCharToTable(fighter, guard);
|
||||||
|
|
||||||
|
var frodo = scn.GetRingBearer();
|
||||||
|
var merry = scn.GetFreepsCard("merry");
|
||||||
|
scn.FreepsMoveCharToTable(merry);
|
||||||
|
|
||||||
|
scn.StartGame();
|
||||||
|
scn.AddTokensToCard(ladder, 4);
|
||||||
|
scn.SkipToPhase(Phase.ASSIGNMENT);
|
||||||
|
scn.FreepsPassCurrentPhaseAction();
|
||||||
|
|
||||||
|
assertTrue(scn.ShadowPlayAvailable(shot));
|
||||||
|
assertEquals(4, scn.GetCultureTokensOn(ladder));
|
||||||
|
assertEquals(3, fighter.getBlueprint().getTwilightCost());
|
||||||
|
assertEquals(4, guard.getBlueprint().getTwilightCost());
|
||||||
|
assertFalse(scn.IsCharAssigned(merry));
|
||||||
|
assertFalse(scn.IsCharAssigned(fighter));
|
||||||
|
assertFalse(scn.IsCharAssigned(guard));
|
||||||
|
scn.ShadowPlayCard(shot);
|
||||||
|
scn.ShadowChoose("4");
|
||||||
|
|
||||||
|
assertEquals(2, scn.ShadowGetCardChoiceCount()); //Both uruks, one costing 3, the other 4
|
||||||
|
scn.ShadowChooseCard(guard);
|
||||||
|
|
||||||
|
assertEquals(0, scn.GetCultureTokensOn(ladder));
|
||||||
|
assertTrue(scn.IsCharAssigned(merry));
|
||||||
|
assertFalse(scn.IsCharAssigned(fighter));
|
||||||
|
assertTrue(scn.IsCharAssigned(guard));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void BreachingShotNotPlayableIfFewerTokensThanTwilightCostOfUruk() throws DecisionResultInvalidException, CardNotFoundException {
|
||||||
|
//Pre-game setup
|
||||||
|
var scn = GetScenario();
|
||||||
|
|
||||||
|
var shot = scn.GetShadowCard("shot");
|
||||||
|
var ladder = scn.GetShadowCard("ladder");
|
||||||
|
var fighter = scn.GetShadowCard("fighter");
|
||||||
|
var guard = scn.GetShadowCard("guard");
|
||||||
|
scn.ShadowMoveCardToHand(shot);
|
||||||
|
scn.ShadowMoveCardToSupportArea(ladder);
|
||||||
|
scn.ShadowMoveCharToTable(fighter, guard);
|
||||||
|
|
||||||
|
var frodo = scn.GetRingBearer();
|
||||||
|
var merry = scn.GetFreepsCard("merry");
|
||||||
|
scn.FreepsMoveCharToTable(merry);
|
||||||
|
|
||||||
|
scn.StartGame();
|
||||||
|
scn.AddTokensToCard(ladder, 2);
|
||||||
|
scn.SkipToPhase(Phase.ASSIGNMENT);
|
||||||
|
scn.FreepsPassCurrentPhaseAction();
|
||||||
|
|
||||||
|
assertFalse(scn.ShadowPlayAvailable(shot));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void BreachingShotDoesNotCrashIfTooFewTokensAreRemovedToAssign() throws DecisionResultInvalidException, CardNotFoundException {
|
||||||
|
//Pre-game setup
|
||||||
|
var scn = GetScenario();
|
||||||
|
|
||||||
|
var shot = scn.GetShadowCard("shot");
|
||||||
|
var ladder = scn.GetShadowCard("ladder");
|
||||||
|
var fighter = scn.GetShadowCard("fighter");
|
||||||
|
var guard = scn.GetShadowCard("guard");
|
||||||
|
scn.ShadowMoveCardToHand(shot);
|
||||||
|
scn.ShadowMoveCardToSupportArea(ladder);
|
||||||
|
scn.ShadowMoveCharToTable(fighter, guard);
|
||||||
|
|
||||||
|
var frodo = scn.GetRingBearer();
|
||||||
|
var merry = scn.GetFreepsCard("merry");
|
||||||
|
scn.FreepsMoveCharToTable(merry);
|
||||||
|
|
||||||
|
scn.StartGame();
|
||||||
|
scn.AddTokensToCard(ladder, 3);
|
||||||
|
scn.SkipToPhase(Phase.ASSIGNMENT);
|
||||||
|
scn.FreepsPassCurrentPhaseAction();
|
||||||
|
|
||||||
|
assertTrue(scn.ShadowPlayAvailable(shot));
|
||||||
|
assertEquals(3, scn.GetCultureTokensOn(ladder));
|
||||||
|
|
||||||
|
assertFalse(scn.IsCharAssigned(merry));
|
||||||
|
assertFalse(scn.IsCharAssigned(fighter));
|
||||||
|
assertFalse(scn.IsCharAssigned(guard));
|
||||||
|
scn.ShadowPlayCard(shot);
|
||||||
|
scn.ShadowChoose("2");
|
||||||
|
|
||||||
|
assertEquals(1, scn.GetCultureTokensOn(ladder));
|
||||||
|
assertFalse(scn.IsCharAssigned(merry));
|
||||||
|
assertFalse(scn.IsCharAssigned(fighter));
|
||||||
|
assertFalse(scn.IsCharAssigned(guard));
|
||||||
|
assertTrue(scn.FreepsAnyDecisionsAvailable());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user