Fixed issue with cards creating assignments

This commit is contained in:
Marcin Sciesinski
2024-10-18 13:23:32 +07:00
parent 6dda33292b
commit 35ea56778a
13 changed files with 185 additions and 28 deletions

View File

@@ -36,11 +36,11 @@ public class Card7_174 extends AbstractPermanent {
action.appendCost(
new RemoveThreatsEffect(self, 5));
action.appendEffect(
new ChooseActiveCardEffect(self, playerId, "Choose a Nazgul", Race.NAZGUL, Filters.assignableToSkirmishAgainst(Side.SHADOW, Filters.and(CardType.COMPANION, Filters.not(Filters.ringBearer)), false, false)) {
new ChooseActiveCardEffect(self, playerId, "Choose a Nazgul", Race.NAZGUL, Filters.assignableToSkirmishAgainst(Side.SHADOW, Filters.and(CardType.COMPANION, Filters.not(Filters.ringBearer)), true, false, false)) {
@Override
protected void cardSelected(LotroGame game, final PhysicalCard nazgul) {
action.insertEffect(
new ChooseActiveCardEffect(self, playerId, "Choose a companion", CardType.COMPANION, Filters.not(Filters.ringBearer), Filters.assignableToSkirmishAgainst(Side.SHADOW, nazgul, false, false)) {
new ChooseActiveCardEffect(self, playerId, "Choose a companion", CardType.COMPANION, Filters.not(Filters.ringBearer), Filters.assignableToSkirmishAgainst(Side.SHADOW, nazgul)) {
@Override
protected void cardSelected(final LotroGame game, final PhysicalCard card) {
action.appendEffect(

View File

@@ -695,6 +695,7 @@
type: assignFpCharacterToSkirmish
fpCharacter: choose(ring bearer)
against: choose(nazgul)
ignoreFierce: true
}
{
type: addTrigger

View File

@@ -23,11 +23,12 @@ import java.util.List;
public class AssignFpCharacterToSkirmish implements EffectAppenderProducer {
@Override
public EffectAppender createEffectAppender(JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException {
FieldUtils.validateAllowedFields(effectObject, "player", "fpCharacter", "against");
FieldUtils.validateAllowedFields(effectObject, "player", "fpCharacter", "against", "ignoreFierce");
final String player = FieldUtils.getString(effectObject.get("player"), "player", "you");
final String fpCharacter = FieldUtils.getString(effectObject.get("fpCharacter"), "fpCharacter");
final String against = FieldUtils.getString(effectObject.get("against"), "against");
final boolean ignoreFierce = FieldUtils.getBoolean(effectObject.get("ignoreFierce"), "ignoreFierce", false);
final PlayerSource playerSource = PlayerResolver.resolvePlayer(player, environment);
@@ -41,7 +42,7 @@ public class AssignFpCharacterToSkirmish implements EffectAppenderProducer {
final String assigningPlayer = playerSource.getPlayer(actionContext);
Side assigningSide = GameUtils.getSide(actionContext.getGame(), assigningPlayer);
final Filterable filter = minionFilter.getFilterable(actionContext);
return Filters.assignableToSkirmishAgainst(assigningSide, filter);
return Filters.assignableToSkirmishAgainst(assigningSide, filter, ignoreFierce);
}, "_tempFpCharacter", player, "Choose character to assign to skirmish", environment));
result.addEffectAppender(
CardResolver.resolveCard(against,
@@ -49,7 +50,7 @@ public class AssignFpCharacterToSkirmish implements EffectAppenderProducer {
final String assigningPlayer = playerSource.getPlayer(actionContext);
Side assigningSide = GameUtils.getSide(actionContext.getGame(), assigningPlayer);
final Collection<? extends PhysicalCard> fpChar = actionContext.getCardsFromMemory("_tempFpCharacter");
return Filters.assignableToSkirmishAgainst(assigningSide, Filters.in(fpChar));
return Filters.assignableToSkirmishAgainst(assigningSide, Filters.in(fpChar), ignoreFierce);
}, "_tempMinion", player, "Choose minion to assign to character", environment));
result.addEffectAppender(
new DelayedAppender() {

View File

@@ -282,7 +282,11 @@ public class Filters {
}
public static Filter assignableToSkirmishAgainst(final Side assignedBySide, final Filterable againstFilter) {
return assignableToSkirmishAgainst(assignedBySide, againstFilter, false, false);
return assignableToSkirmishAgainst(assignedBySide, againstFilter, false);
}
public static Filter assignableToSkirmishAgainst(final Side assignedBySide, final Filterable againstFilter, boolean ignoreFierce) {
return assignableToSkirmishAgainst(assignedBySide, againstFilter, ignoreFierce, false, false);
}
public static Filter notPreventedByEffectToAssign(final Side assignedBySide, final PhysicalCard againstCard) {
@@ -302,15 +306,15 @@ public class Filters {
};
}
public static Filter assignableToSkirmishAgainst(final Side assignedBySide, final Filterable againstFilter, final boolean ignoreUnassigned, final boolean allowAllyToSkirmish) {
public static Filter assignableToSkirmishAgainst(final Side assignedBySide, final Filterable againstFilter, final boolean ignoreFierce, final boolean ignoreUnassigned, final boolean allowAllyToSkirmish) {
return Filters.and(
assignableToSkirmish(assignedBySide, ignoreUnassigned, allowAllyToSkirmish),
assignableToSkirmish(assignedBySide, ignoreFierce, ignoreUnassigned, allowAllyToSkirmish),
new Filter() {
@Override
public boolean accepts(LotroGame game, PhysicalCard physicalCard) {
for (PhysicalCard card : Filters.filterActive(game, againstFilter)) {
if (card.getBlueprint().getSide() != physicalCard.getBlueprint().getSide()
&& Filters.assignableToSkirmish(assignedBySide, ignoreUnassigned, allowAllyToSkirmish).accepts(game, card)) {
&& Filters.assignableToSkirmish(assignedBySide, ignoreFierce, ignoreUnassigned, allowAllyToSkirmish).accepts(game, card)) {
Map<PhysicalCard, Set<PhysicalCard>> thisAssignment = new HashMap<>();
if (card.getBlueprint().getSide() == Side.FREE_PEOPLE) {
if (thisAssignment.containsKey(card))
@@ -333,7 +337,7 @@ public class Filters {
});
}
public static Filter assignableToSkirmish(final Side assignedBySide, final boolean ignoreUnassigned, final boolean allowAllyToSkirmish) {
public static Filter assignableToSkirmish(final Side assignedBySide, final boolean ignoreFierce, final boolean ignoreUnassigned, final boolean allowAllyToSkirmish) {
Filter assignableFilter = Filters.or(
Filters.and(
CardType.ALLY,
@@ -366,7 +370,7 @@ public class Filters {
new Filter() {
@Override
public boolean accepts(LotroGame game, PhysicalCard physicalCard) {
return (!game.getGameState().isFierceSkirmishes()) || game.getModifiersQuerying().hasKeyword(game, physicalCard, Keyword.FIERCE);
return (ignoreFierce || !game.getGameState().isFierceSkirmishes()) || game.getModifiersQuerying().hasKeyword(game, physicalCard, Keyword.FIERCE);
}
}));

View File

@@ -47,7 +47,7 @@ public class AssignmentEffect extends AbstractEffect {
@Override
public boolean isPlayableInFull(LotroGame game) {
Side side = _playerId.equals(game.getGameState().getCurrentPlayerId()) ? Side.FREE_PEOPLE : Side.SHADOW;
return Filters.assignableToSkirmishAgainst(side, _fpChar, _ignoreSingleMinionRestriction, _skipAllyLocationCheck).accepts(game, _minion);
return Filters.assignableToSkirmishAgainst(side, _fpChar, false, _ignoreSingleMinionRestriction, _skipAllyLocationCheck).accepts(game, _minion);
}
@Override

View File

@@ -33,7 +33,7 @@ public class ChooseAndAssignCharacterToMinionEffect extends ChooseActiveCardEffe
@Override
protected Filter getExtraFilterForPlaying(final LotroGame game) {
final Side side = game.getGameState().getCurrentPlayerId().equals(_playerId) ? Side.FREE_PEOPLE : Side.SHADOW;
return Filters.assignableToSkirmishAgainst(side, _minion, false, _skipAllyLocationCheck);
return Filters.assignableToSkirmishAgainst(side, _minion, false, false, _skipAllyLocationCheck);
}
@Override

View File

@@ -27,7 +27,7 @@ public class ChooseAndAssignMinionToCompanionEffect extends ChooseActiveCardEffe
@Override
protected Filter getExtraFilterForPlaying(final LotroGame game) {
final Side side = game.getGameState().getCurrentPlayerId().equals(_playerId) ? Side.FREE_PEOPLE : Side.SHADOW;
return Filters.assignableToSkirmishAgainst(side, _companion, false, false);
return Filters.assignableToSkirmishAgainst(side, _companion);
}
@Override

View File

@@ -49,7 +49,7 @@ public class ChooseAndDoAssignmentEffect extends AbstractSubActionEffect {
}
private Collection<PhysicalCard> getAssignableMinions(LotroGame game) {
return Filters.filterActive(game, CardType.MINION, _minionFilter, Filters.assignableToSkirmishAgainst(getDecidingPlayerSide(game), _fpFilter, false, false));
return Filters.filterActive(game, CardType.MINION, _minionFilter, Filters.assignableToSkirmishAgainst(getDecidingPlayerSide(game), _fpFilter));
}
@Override
@@ -70,7 +70,7 @@ public class ChooseAndDoAssignmentEffect extends AbstractSubActionEffect {
}
private void minionSelected(final LotroGame game, final PhysicalCard minion) {
Collection<PhysicalCard> assignableFpCharacters = Filters.filterActive(game, Filters.or(CardType.COMPANION, CardType.ALLY), _fpFilter, Filters.assignableToSkirmishAgainst(getDecidingPlayerSide(game), minion, false, false));
Collection<PhysicalCard> assignableFpCharacters = Filters.filterActive(game, Filters.or(CardType.COMPANION, CardType.ALLY), _fpFilter, Filters.assignableToSkirmishAgainst(getDecidingPlayerSide(game), minion));
if (assignableFpCharacters.size() == 1)
assignmentSelected(game, assignableFpCharacters.iterator().next(), minion);
else

View File

@@ -30,7 +30,7 @@ public class AIPlayerAssignsMinionsGameProcess implements GameProcess {
GameState gameState = game.getGameState();
Filter minionFilter = Filters.and(CardType.MINION, Filters.owner("AI"), Filters.in(_leftoverMinions));
final Set<PhysicalCard> minions = new HashSet<>(Filters.filterActive(game, minionFilter, Filters.assignableToSkirmish(Side.SHADOW, true, false)));
final Set<PhysicalCard> minions = new HashSet<>(Filters.filterActive(game, minionFilter, Filters.assignableToSkirmish(Side.SHADOW, false, true, false)));
if (minions.size() > 0) {
final PhysicalCard ringBearer = game.getGameState().getRingBearer(game.getGameState().getCurrentPlayerId());
Map<PhysicalCard, Set<PhysicalCard>> assignments = Collections.singletonMap(ringBearer, minions);

View File

@@ -44,14 +44,14 @@ public class FreePeoplePlayerAssignsMinionsGameProcess implements GameProcess {
protected void doPlayEffect(final LotroGame game) {
final GameState gameState = game.getGameState();
final Collection<PhysicalCard> minions = Filters.filterActive(game, CardType.MINION, Filters.assignableToSkirmish(Side.FREE_PEOPLE, true, false));
final Collection<PhysicalCard> minions = Filters.filterActive(game, CardType.MINION, Filters.assignableToSkirmish(Side.FREE_PEOPLE, false, true, false));
if (minions.size() > 0) {
final Collection<PhysicalCard> freePeopleTargets =
Filters.filterActive(game,
Filters.and(
Filters.or(
CardType.COMPANION, CardType.ALLY),
Filters.assignableToSkirmish(Side.FREE_PEOPLE, true, false)));
Filters.assignableToSkirmish(Side.FREE_PEOPLE, false, true, false)));
game.getUserFeedback().sendAwaitingDecision(gameState.getCurrentPlayerId(),

View File

@@ -36,14 +36,14 @@ public class ShadowPlayerAssignsHisMinionsGameProcess implements GameProcess {
GameState gameState = game.getGameState();
Filter minionFilter = Filters.and(CardType.MINION, Filters.owner(_playerId), Filters.in(_leftoverMinions));
final Collection<PhysicalCard> minions = Filters.filterActive(game, minionFilter, Filters.assignableToSkirmish(Side.SHADOW, true, false));
final Collection<PhysicalCard> minions = Filters.filterActive(game, minionFilter, Filters.assignableToSkirmish(Side.SHADOW, false, true, false));
if (minions.size() > 0) {
final Collection<PhysicalCard> freePeopleTargets =
Filters.filterActive(game,
Filters.and(
Filters.or(
CardType.COMPANION, CardType.ALLY),
Filters.assignableToSkirmish(Side.SHADOW, true, false)));
Filters.assignableToSkirmish(Side.SHADOW, false, true, false)));
game.getUserFeedback().sendAwaitingDecision(_playerId,
new PlayerAssignMinionsDecision(1, "Assign minions to companions or allies at home", freePeopleTargets, minions) {

View File

@@ -14,10 +14,7 @@ import org.junit.Test;
import java.util.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.*;
public class IndividualCardAtTest extends AbstractAtTest {
@@ -1203,4 +1200,159 @@ public class IndividualCardAtTest extends AbstractAtTest {
assertEquals(Zone.DISCARD, morgulBlade.getZone());
assertEquals(Zone.ATTACHED, bladeTip.getZone());
}
@Test
public void returnToItsMaster() throws DecisionResultInvalidException, CardNotFoundException {
LotroDeck p1Deck = createSimplestDeck();
p1Deck.setRing("4_1");
LotroDeck p2Deck = createSimplestDeck();
Map<String, LotroDeck> decks = new HashMap<>();
decks.put(P1, p1Deck);
decks.put(P2, p2Deck);
initializeGameWithDecks(decks);
skipMulligans();
PhysicalCardImpl returnToItsMaster = new PhysicalCardImpl(102, "1_224", P2, _cardLibrary.getLotroCardBlueprint("1_224"));
_game.getGameState().addCardToZone(_game, returnToItsMaster, Zone.HAND);
PhysicalCardImpl nelya = new PhysicalCardImpl(102, "1_233", P2, _cardLibrary.getLotroCardBlueprint("1_233"));
_game.getGameState().addCardToZone(_game, nelya, Zone.SHADOW_CHARACTERS);
PhysicalCardImpl hobbitSword = new PhysicalCardImpl(102, "1_299", P1, _cardLibrary.getLotroCardBlueprint("1_299"));
_game.getGameState().attachCard(_game, hobbitSword, _game.getGameState().getRingBearer(P1));
// End fellowship
playerDecided(P1, "");
// End shadow
playerDecided(P2, "");
// End maneuvers phase
playerDecided(P1, "");
playerDecided(P2, "");
// End archery phase
playerDecided(P1, "");
playerDecided(P2, "");
// End assignment phase
playerDecided(P1, "");
playerDecided(P2, "");
// Assign
playerDecided(P1, _game.getGameState().getRingBearer(P1).getCardId() + " " + nelya.getCardId());
// Choose skirmish to resolve
playerDecided(P1, "" + _game.getGameState().getRingBearer(P1).getCardId());
// Skirmish phase
AwaitingDecision skirmishAction = _userFeedback.getAwaitingDecision(P1);
playerDecided(P1, getCardActionId(skirmishAction, "Use The One"));
assertTrue(_game.getGameState().isWearingRing());
// End skirmish phase
playerDecided(P2, "");
playerDecided(P1, "");
// Don't use Return to Its Master
playerDecided(P2, "");
// End assignment phase
playerDecided(P1, "");
playerDecided(P2, "");
// Assign
playerDecided(P1, _game.getGameState().getRingBearer(P1).getCardId() + " " + nelya.getCardId());
// Choose skirmish to resolve
playerDecided(P1, "" + _game.getGameState().getRingBearer(P1).getCardId());
// End fierce skirmish phase
playerDecided(P1, "");
playerDecided(P2, "");
AwaitingDecision playeReturnDecision = _userFeedback.getAwaitingDecision(P2);
playerDecided(P2, getCardActionId(playeReturnDecision, "Play Return"));
// Choose skirmish to resolve
playerDecided(P1, "" + _game.getGameState().getRingBearer(P1).getCardId());
assertEquals(_game.getGameState().getRingBearer(P1), _game.getGameState().getSkirmish().getFellowshipCharacter());
assertEquals(1, _game.getGameState().getSkirmish().getShadowCharacters().size());
assertEquals(nelya, _game.getGameState().getSkirmish().getShadowCharacters().iterator().next());
}
@Test
public void returnToItsMasterNonFierceNazgul() throws DecisionResultInvalidException, CardNotFoundException {
LotroDeck p1Deck = createSimplestDeck();
p1Deck.setRing("4_1");
LotroDeck p2Deck = createSimplestDeck();
Map<String, LotroDeck> decks = new HashMap<>();
decks.put(P1, p1Deck);
decks.put(P2, p2Deck);
initializeGameWithDecks(decks);
skipMulligans();
PhysicalCardImpl returnToItsMaster = new PhysicalCardImpl(102, "1_224", P2, _cardLibrary.getLotroCardBlueprint("1_224"));
_game.getGameState().addCardToZone(_game, returnToItsMaster, Zone.HAND);
PhysicalCardImpl nonFierceNazgul = new PhysicalCardImpl(102, "2_83", P2, _cardLibrary.getLotroCardBlueprint("1_233"));
_game.getGameState().addCardToZone(_game, nonFierceNazgul, Zone.SHADOW_CHARACTERS);
PhysicalCardImpl hobbitSword = new PhysicalCardImpl(102, "1_299", P1, _cardLibrary.getLotroCardBlueprint("1_299"));
_game.getGameState().attachCard(_game, hobbitSword, _game.getGameState().getRingBearer(P1));
// End fellowship
playerDecided(P1, "");
// End shadow
playerDecided(P2, "");
// End maneuvers phase
playerDecided(P1, "");
playerDecided(P2, "");
// End archery phase
playerDecided(P1, "");
playerDecided(P2, "");
// End assignment phase
playerDecided(P1, "");
playerDecided(P2, "");
// Assign
playerDecided(P1, _game.getGameState().getRingBearer(P1).getCardId() + " " + nonFierceNazgul.getCardId());
// Choose skirmish to resolve
playerDecided(P1, "" + _game.getGameState().getRingBearer(P1).getCardId());
// Skirmish phase
AwaitingDecision skirmishAction = _userFeedback.getAwaitingDecision(P1);
playerDecided(P1, getCardActionId(skirmishAction, "Use The One"));
assertTrue(_game.getGameState().isWearingRing());
// End skirmish phase
playerDecided(P2, "");
playerDecided(P1, "");
AwaitingDecision playeReturnDecision = _userFeedback.getAwaitingDecision(P2);
playerDecided(P2, getCardActionId(playeReturnDecision, "Play Return"));
// Choose skirmish to resolve
playerDecided(P1, "" + _game.getGameState().getRingBearer(P1).getCardId());
assertEquals(_game.getGameState().getRingBearer(P1), _game.getGameState().getSkirmish().getFellowshipCharacter());
assertEquals(1, _game.getGameState().getSkirmish().getShadowCharacters().size());
assertEquals(nonFierceNazgul, _game.getGameState().getSkirmish().getShadowCharacters().iterator().next());
}
}

View File

@@ -106,9 +106,8 @@ public class Card_01_224_Tests
//Can't quite get the rest
//assertEquals(2, scn.GetShadowCardChoiceCount()); // both enquea and TWK
//scn.ShadowChooseCard(enquea);
//We should now be asking freeps to choose the next skirmish to resolve and in a skirmish phase
assertEquals(2, scn.GetShadowCardChoiceCount()); // both enquea and TWK
scn.ShadowChooseCard(enquea);
}