diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/autoZoomHandler.js b/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/autoZoomHandler.js index b3ff51e8d..cc4f62829 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/autoZoomHandler.js +++ b/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/autoZoomHandler.js @@ -114,10 +114,10 @@ class AutoZoom { var targetShort = Math.min(maxShortSide, CardDisplay.TargetShort); if(card.horizontal || card.effectivelyHorizontal()) { - this.cardDisplay.reloadFromCard(card, targetLong, targetShort); + this.cardDisplay.reloadFromCard(card, targetLong, targetShort, true); } else { - this.cardDisplay.reloadFromCard(card, targetShort, targetLong); + this.cardDisplay.reloadFromCard(card, targetShort, targetLong, true); } // get position and size of the reference image (or card hint): @@ -206,7 +206,7 @@ class AutoZoom { // However if shift IS held AND it's rotated, we act like it's not. // This is basically XOR; when they are the same they cancel out, // but when they are different they cause a rotation. - this.cardDisplay.setInvert(shiftHeld != invertShift); + //this.cardDisplay.setInvert(shiftHeld != invertShift); } setPreviewMessage(reversible) { diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/cards/Card.js b/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/cards/Card.js index a81386469..8f260588d 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/cards/Card.js +++ b/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/cards/Card.js @@ -55,6 +55,49 @@ class Card { static GetAlternateImage(bpid) { return bpid.includes("^", 2); } + + static GetImageFromCache(blueprintid, tengwar) { + if(tengwar) + return Card.GetTengwarImageFromCache(blueprintid); + + return Card.GetBaseImageFromCache(blueprintid); + } + + static GetBaseImageFromCache(blueprintid) { + let cached = Card.CardCache[blueprintid]; + if(cached == null) { + cached = { + imageUrl:Card.getImageUrl(blueprintid), + backSideImageUrl:Card.getBackSideUrl(blueprintid), + incomplete:Card.isIncomplete(blueprintid), + errata:Card.isErrata(blueprintid) + }; + + Card.CardCache[blueprintid] = cached; + } + + + return cached; + } + + static GetTengwarImageFromCache(blueprintid) { + let tengwarid = blueprintid + "T"; + + let cached = Card.CardCache[tengwarid]; + if(cached == null) { + cached = { + imageUrl:Card.getImageUrl(tengwarid, true), + backSideImageUrl:Card.getBackSideUrl(tengwarid), + incomplete:Card.isIncomplete(tengwarid), + errata:Card.isErrata(tengwarid) + }; + + Card.CardCache[tengwarid] = cached; + } + + + return cached; + } //blueprintId, zone, cardId, owner, siteNumber constructor (blueprintId, testingText, backSideTestingText, zone, cardId, owner, siteNumber, upsideDown, onSide) { @@ -106,32 +149,11 @@ class Card { this.horizontal = Card.isHorizontal(this.bareBlueprint, this.zone); - if (this.bareBlueprint != "-1_1" && this.bareBlueprint != "-1_2" && Card.CardCache[this.bareBlueprint] != null) { - var cardFromCache = Card.CardCache[this.bareBlueprint]; - this.imageUrl = cardFromCache.imageUrl; - this.backSideImageUrl = cardFromCache.backSideImageUrl; - this.incomplete = cardFromCache.incomplete; - this.errata = cardFromCache.errata; - } else { - this.imageUrl = Card.getImageUrl(this.bareBlueprint, this.tengwar); - this.backSideImageUrl = Card.getBackSideUrl(this.bareBlueprint); - this.incomplete = Card.isIncomplete(this.bareBlueprint); - - var separator = this.bareBlueprint.indexOf("_"); - var setNo = parseInt(this.bareBlueprint.substr(0, separator)); - var cardNo = parseInt(this.bareBlueprint.substr(separator + 1)); - - this.errata = Card.getErrata(setNo, cardNo) != null; - - if (this.bareBlueprint != "-1_1" && this.bareBlueprint != "-1_2") { - Card.CardCache[this.bareBlueprint] = { - imageUrl:this.imageUrl, - backSideImageUrl:this.backSideImageUrl, - incomplete:this.incomplete, - errata:this.errata - }; - } - } + var cardFromCache = Card.GetImageFromCache(this.bareBlueprint, this.tengwar); + this.imageUrl = cardFromCache.imageUrl; + this.backSideImageUrl = cardFromCache.backSideImageUrl; + this.incomplete = cardFromCache.incomplete; + this.errata = cardFromCache.errata; } static getFixedImage (blueprintId) { @@ -328,6 +350,14 @@ class Card { return false; } + static isErrata(blueprintId) { + var separator = blueprintId.indexOf("_"); + var setNo = parseInt(blueprintId.substr(0, separator)); + var cardNo = parseInt(blueprintId.substr(separator + 1)); + + return Card.getErrata(setNo, cardNo) != null; + } + static getImageUrl(blueprintId, tengwar, ignoreErrata) { let image = Card.getFixedImage(blueprintId) if (image != null) diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/cards/CardDisplay.js b/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/cards/CardDisplay.js index 2738e25e3..135165894 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/cards/CardDisplay.js +++ b/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/cards/CardDisplay.js @@ -117,13 +117,21 @@ class CardDisplay { this.backside = null; } - reloadFromCard(card, maxWidth, maxHeight, noborder) { + reloadFromCard(card, maxWidth, maxHeight, ignoreTengwar) { this.baseDiv.data("card", card); - this.currentBP = card.blueprintId; - this.frontside = card.imageUrl; - if(!this.frontside) { - this.frontside = Card.getImageUrl(this.currentBP); + if(ignoreTengwar && card.isTengwar()) { + this.currentBP = card.bareBlueprint; + this.frontside = Card.GetBaseImageFromCache(this.currentBP).imageUrl; } + else { + this.currentBP = card.blueprintId; + this.frontside = card.imageUrl; + } + + if(!this.frontside) { + this.frontside = Card.getImageUrl(this.currentBP); + } + let back = card.backSideImageUrl; if(back && !back.includes("darkcardback") && !back.includes("lightcardback")) { @@ -143,11 +151,9 @@ class CardDisplay { this.backside = null; } } - - - this.reload(maxWidth, maxHeight, card.imageUrl, - card.horizontal || card.effectivelyHorizontal(), card.foil, noborder, card.testingText); + this.reload(maxWidth, maxHeight, this.frontside, + card.horizontal || card.effectivelyHorizontal(), card.foil, false, card.testingText); } reload(maxWidth, maxHeight, image, horizontal, foil, noborder, testingText) { diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set08/set08-Sites.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set08/set08-Sites.hjson index eb9c145f8..ee157de78 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set08/set08-Sites.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set08/set08-Sites.hjson @@ -140,10 +140,15 @@ } { type: If - check: { - type: HasMemory - memory: opponent - } + check: [ + { + type: HasMemory + memory: opponent + } + { + type: SiteAvailableToControl + } + ] true: { type: Optional player: shadow diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/lotrFormats.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/lotrFormats.hjson index 530f31fba..4a0c49812 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/lotrFormats.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/lotrFormats.hjson @@ -109,9 +109,9 @@ "0_56", "0_57", "0_58", "0_59", "0_60" ] blocks: [ - Fellowship Block|The Fellowship of the Ring:1,Mines of Moria:2,Realms of the Elf-lords:3,V1 - Shadow of the Past:101 - Towers Block|The Two Towers:4,Battle of Helm's Deep:5,Ents of Fangorn:6,V2 - King of the Golden Hall:102 - king_block + pc_fotr_block + pc_ttt_block + pc_king_block Additional Sets|Promotional:0,Reflections:9 Player's Council V-sets|V1 - Shadow of the Past:101,V2 - King of the Golden Hall:102 Player's Council Errata|The Fellowship of the Ring Errata:51,Mines of Moria Errata:52,Realms of the Elf-lords Errata:53,The Two Towers Errata:54,Battle of Helm's Deep Errata:55,Ents of Fangorn Errata:56,Return of the King Errata:57,Siege of Gondor Errata:58,Reflections Errata:59,Mount Doom Errata:60 @@ -121,6 +121,44 @@ 51,52,53,54,55,56,57,58,59,60 ] } + { + name: Towers Block (PC) + code: pc_ttt_block + hall: false + order: 9 + sites: TWO_TOWERS + cancelRingBearerSkirmish: true + sets: [ + 4, 5, 6 + ] + errataSets: [ + 54,55,66 + ] + blocks: [ + ttt_block + ] + } + { + name: King Block (PC) + code: pc_king_block + + hall: false + order: 118 + sites: KING + cancelRingBearerSkirmish: true + restricted: [ + "7_49" + ] + sets: [ + 7, 8, 10 + ] + errataSets: [ + 57,58,60 + ] + blocks: [ + king_block + ] + } { name: Latest PC Errata code: pc_errata diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/product/PC-Packs.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/product/PC-Packs.hjson index b703dba46..d0f58fbfa 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/product/PC-Packs.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/product/PC-Packs.hjson @@ -119,7 +119,7 @@ //Cave Troll of Moria, Scourge of the Black Pit FA 1x1_380 //Gimli, Vengeful Longbeard MW - 1x101_67 + 1x101_103 #Easterling Captain FA 1x4_367 //The Tale of the Great Ring MW @@ -393,7 +393,7 @@ //Treebeard, Enraged Shepherd MW 1x15_209 //Gimli, Vengeful Longbeard MW - 1x101_67 + 1x101_103 //The Tale of the Great Ring MW 1x10_126 #Gandalf, The Grey Pilgrim MW @@ -524,7 +524,7 @@ //Treebeard, Enraged Shepherd MW 1x15_209 //Gimli, Vengeful Longbeard MW - 1x101_67 + 1x101_103 //The Tale of the Great Ring MW 1x10_126 #Gandalf, The Grey Pilgrim MW diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/TakeControlOfSite.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/TakeControlOfSite.java index 0d94733d4..25d4963db 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/TakeControlOfSite.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/TakeControlOfSite.java @@ -8,8 +8,7 @@ import com.gempukku.lotro.cards.build.field.FieldUtils; import com.gempukku.lotro.cards.build.field.effect.EffectAppender; import com.gempukku.lotro.cards.build.field.effect.EffectAppenderProducer; import com.gempukku.lotro.cards.build.field.effect.appender.resolver.PlayerResolver; -import com.gempukku.lotro.game.PhysicalCard; -import com.gempukku.lotro.game.state.LotroGame; +import com.gempukku.lotro.logic.GameUtils; import com.gempukku.lotro.logic.actions.CostToEffectAction; import com.gempukku.lotro.logic.effects.TakeControlOfASiteEffect; import com.gempukku.lotro.logic.timing.Effect; @@ -26,18 +25,7 @@ public class TakeControlOfSite implements EffectAppenderProducer { return new DelayedAppender() { @Override public boolean isPlayableInFull(ActionContext actionContext) { - final LotroGame game = actionContext.getGame(); - int maxUnoccupiedSite = Integer.MAX_VALUE; - for (String playerId : game.getGameState().getPlayerOrder().getAllPlayers()) - maxUnoccupiedSite = Math.min(maxUnoccupiedSite, game.getGameState().getPlayerPosition(playerId) - 1); - - for (int i = 1; i <= maxUnoccupiedSite; i++) { - final PhysicalCard site = game.getGameState().getSite(i); - if (site.getCardController() == null) - return true; - } - - return false; + return GameUtils.anySiteAvailableToControl(actionContext.getGame()); } @Override diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/HasMemory.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/HasMemory.java index f7c296c99..420b8fc72 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/HasMemory.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/HasMemory.java @@ -15,8 +15,15 @@ public class HasMemory implements RequirementProducer { final String memory = FieldUtils.getString(object.get("memory"), "memory"); - return actionContext -> - actionContext.getValueFromMemory(memory) != null && actionContext.getCardsFromMemory(memory) != null; + return actionContext -> { + try { + return actionContext.getValueFromMemory(memory) != null && actionContext.getCardsFromMemory( + memory) != null; + } + catch (IllegalArgumentException ex) { + return false; + } + }; } } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/RequirementFactory.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/RequirementFactory.java index 15599f503..d6abfd603 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/RequirementFactory.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/RequirementFactory.java @@ -72,6 +72,7 @@ public class RequirementFactory { requirementProducers.put("ringison", new RingIsOn()); requirementProducers.put("sarumanfirstsentenceactive", new SarumanFirstSentenceActive()); requirementProducers.put("shadowplayerreplacedcurrentsite", new ShadowPlayerReplacedCurrentSite()); + requirementProducers.put("siteavailabletocontrol", new SiteAvailableToControl()); requirementProducers.put("twilightpoollessthan", new TwilightPoolLessThan()); requirementProducers.put("wasassignedtoskirmish", new WasAssignedToSkirmish()); requirementProducers.put("wasplayedfromzone", new WasPlayedFromZone()); diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/SiteAvailableToControl.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/SiteAvailableToControl.java new file mode 100644 index 000000000..6d46323a8 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/requirement/SiteAvailableToControl.java @@ -0,0 +1,19 @@ +package com.gempukku.lotro.cards.build.field.effect.requirement; + +import com.gempukku.lotro.cards.build.CardGenerationEnvironment; +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.logic.GameUtils; +import org.json.simple.JSONObject; + +public class SiteAvailableToControl implements RequirementProducer { + + @Override + public Requirement getPlayRequirement( + JSONObject object, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { + FieldUtils.validateAllowedFields(object); + + return (actionContext) -> GameUtils.anySiteAvailableToControl(actionContext.getGame()); + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/GameUtils.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/GameUtils.java index 757825f2b..0974b8e0e 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/GameUtils.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/GameUtils.java @@ -348,4 +348,19 @@ public class GameUtils { } return total; } + + public static boolean anySiteAvailableToControl(LotroGame game) { + int maxUnoccupiedSite = Integer.MAX_VALUE; + for (String playerId : game.getGameState().getPlayerOrder().getAllPlayers()) { + maxUnoccupiedSite = Math.min(maxUnoccupiedSite, game.getGameState().getPlayerPosition(playerId) - 1); + } + + for (int i = 1; i <= maxUnoccupiedSite; i++) { + final PhysicalCard site = game.getGameState().getSite(i); + if (site.getCardController() == null) + return true; + } + + return false; + } } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ResolveSkirmishEffect.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ResolveSkirmishEffect.java index 3424418d6..cdf2f56e7 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ResolveSkirmishEffect.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/effects/ResolveSkirmishEffect.java @@ -37,7 +37,7 @@ public class ResolveSkirmishEffect extends AbstractEffect { public Result getUpcomingResult(LotroGame game) { final Skirmish skirmish = game.getGameState().getSkirmish(); - if (skirmish.getShadowCharacters().size() == 0) + if (skirmish.getShadowCharacters().isEmpty()) return Result.SHADOW_LOSES; if (skirmish.getFellowshipCharacter() == null) return Result.FELLOWSHIP_LOSES; @@ -76,7 +76,7 @@ public class ResolveSkirmishEffect extends AbstractEffect { involving.addAll(skirmish.getShadowCharacters()); if (result == Result.FELLOWSHIP_LOSES) { - game.getGameState().sendMessage("Skirmish resolved with a normal win"); + game.getGameState().sendMessage("Skirmish resolved with a normal win for Free Peoples"); game.getActionsEnvironment().emitEffectResult(new NormalSkirmishResult(skirmish.getShadowCharacters(), fpList(skirmish.getFellowshipCharacter()), skirmish.getRemovedFromSkirmish())); for (PhysicalCard minion : skirmish.getShadowCharacters()) @@ -86,7 +86,7 @@ public class ResolveSkirmishEffect extends AbstractEffect { for (PhysicalCard removedCharacter : skirmish.getRemovedFromSkirmish()) game.getActionsEnvironment().emitEffectResult(new CharacterLostSkirmishResult(CharacterLostSkirmishResult.SkirmishType.NORMAL, removedCharacter, involving)); } else if (result == Result.SHADOW_LOSES) { - game.getGameState().sendMessage("Skirmish resolved with a normal win"); + game.getGameState().sendMessage("Skirmish resolved with a normal win for Shadow"); game.getActionsEnvironment().emitEffectResult(new NormalSkirmishResult(fpList(skirmish.getFellowshipCharacter()), skirmish.getShadowCharacters(), skirmish.getRemovedFromSkirmish())); for (PhysicalCard minion : skirmish.getShadowCharacters()) @@ -96,7 +96,7 @@ public class ResolveSkirmishEffect extends AbstractEffect { for (PhysicalCard removedCharacter : skirmish.getRemovedFromSkirmish()) game.getActionsEnvironment().emitEffectResult(new CharacterLostSkirmishResult(CharacterLostSkirmishResult.SkirmishType.NORMAL, removedCharacter, involving)); } else if (result == Result.FELLOWSHIP_OVERWHELMED) { - game.getGameState().sendMessage("Skirmish resolved with an overwhelm"); + game.getGameState().sendMessage("Skirmish resolved with an overwhelm win for Shadow"); game.getActionsEnvironment().emitEffectResult(new OverwhelmSkirmishResult(skirmish.getShadowCharacters(), fpList(skirmish.getFellowshipCharacter()), skirmish.getRemovedFromSkirmish())); for (PhysicalCard minion : skirmish.getShadowCharacters()) @@ -106,7 +106,7 @@ public class ResolveSkirmishEffect extends AbstractEffect { for (PhysicalCard removedCharacter : skirmish.getRemovedFromSkirmish()) game.getActionsEnvironment().emitEffectResult(new CharacterLostSkirmishResult(CharacterLostSkirmishResult.SkirmishType.OVERWHELM, removedCharacter, involving)); } else { - game.getGameState().sendMessage("Skirmish resolved with an overwhelm"); + game.getGameState().sendMessage("Skirmish resolved with an overwhelm win for Free Peoples"); game.getActionsEnvironment().emitEffectResult(new OverwhelmSkirmishResult(fpList(skirmish.getFellowshipCharacter()), skirmish.getShadowCharacters(), skirmish.getRemovedFromSkirmish())); for (PhysicalCard minion : skirmish.getShadowCharacters()) diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/processes/turn/skirmish/PlayoutSkirmishesGameProcess.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/processes/turn/skirmish/PlayoutSkirmishesGameProcess.java index a0a445ae3..a882c9ec3 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/processes/turn/skirmish/PlayoutSkirmishesGameProcess.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/processes/turn/skirmish/PlayoutSkirmishesGameProcess.java @@ -30,7 +30,7 @@ public class PlayoutSkirmishesGameProcess implements GameProcess { final GameState gameState = game.getGameState(); final List assignments = gameState.getAssignments(); - if (assignments.size() > 0) { + if (!assignments.isEmpty()) { Set nonLurkerSkirmishFps = new HashSet<>(); Set lurkerSkirmishFps = new HashSet<>(); for (Assignment assignment : assignments) { @@ -51,7 +51,7 @@ public class PlayoutSkirmishesGameProcess implements GameProcess { SystemQueueAction chooseNextSkirmishAction = new SystemQueueAction(); Set skirmishChoice; - if (nonLurkerSkirmishFps.size() > 0) + if (!nonLurkerSkirmishFps.isEmpty()) skirmishChoice = nonLurkerSkirmishFps; else skirmishChoice = lurkerSkirmishFps; diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_221_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_221_Tests.java index 3757ade43..4bed139d0 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_221_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set01/Card_01_221_Tests.java @@ -3,7 +3,6 @@ package com.gempukku.lotro.cards.official.set01; import com.gempukku.lotro.cards.GenericCardTestHelper; import com.gempukku.lotro.common.*; import com.gempukku.lotro.game.CardNotFoundException; -import com.gempukku.lotro.game.PhysicalCardImpl; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; import org.junit.Test; @@ -18,8 +17,14 @@ public class Card_01_221_Tests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "1_221"); - // put other cards in here as needed for the test case + put("paleblade", "1_221"); + put("twk", "1_237"); + + put("gimli", "1_13"); + put("condition1", "1_16"); + put("condition2", "1_21"); + put("condition3", "2_1"); + put("condition4", "2_9"); }}, GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, @@ -45,7 +50,7 @@ public class Card_01_221_Tests var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsCard("paleblade"); assertEquals("The Pale Blade", card.getBlueprint().getTitle()); assertNull(card.getBlueprint().getSubtitle()); @@ -58,18 +63,56 @@ public class Card_01_221_Tests assertEquals(3, card.getBlueprint().getStrength()); } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void ThePaleBladeTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void ThePaleBladeCanBeTriggeredMultipleTimesFromSameVictory() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var twk = scn.GetShadowCard("twk"); + var paleblade = scn.GetShadowCard("paleblade"); + scn.ShadowMoveCharToTable(twk); + scn.AttachCardsTo(twk, paleblade); + + var gimli = scn.GetFreepsCard("gimli"); + var condition1 = scn.GetFreepsCard("condition1"); + var condition2 = scn.GetFreepsCard("condition2"); + var condition3 = scn.GetFreepsCard("condition3"); + var condition4 = scn.GetFreepsCard("condition4"); + scn.FreepsMoveCharToTable(gimli); + scn.FreepsMoveCardToSupportArea(condition1, condition2, condition3, condition4); scn.StartGame(); - scn.FreepsPlayCard(card); + scn.SkipToAssignments(); + scn.FreepsAssignToMinions(gimli, twk); + scn.FreepsResolveSkirmish(gimli); + assertEquals(Zone.SUPPORT, condition1.getZone()); + assertEquals(Zone.SUPPORT, condition2.getZone()); + assertEquals(Zone.SUPPORT, condition3.getZone()); + assertEquals(Zone.SUPPORT, condition4.getZone()); + assertEquals(0, scn.GetWoundsOn(twk)); + + scn.PassCurrentPhaseActions(); + + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); + assertEquals(1, scn.GetWoundsOn(twk)); + scn.ShadowChooseCard(condition1); + assertEquals(Zone.DISCARD, condition1.getZone()); + + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); + assertEquals(2, scn.GetWoundsOn(twk)); + scn.ShadowChooseCard(condition2); + assertEquals(Zone.DISCARD, condition2.getZone()); + + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); + assertEquals(3, scn.GetWoundsOn(twk)); + scn.ShadowChooseCard(condition3); + assertEquals(Zone.DISCARD, condition3.getZone()); + + assertFalse(scn.ShadowHasOptionalTriggerAvailable()); + assertEquals(Phase.ASSIGNMENT, scn.GetCurrentPhase()); - assertEquals(2, scn.GetTwilight()); } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set04/Card_04_004_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set04/Card_04_004_Tests.java index f9c2b8fe9..6b22b7c05 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set04/Card_04_004_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set04/Card_04_004_Tests.java @@ -3,7 +3,6 @@ package com.gempukku.lotro.cards.official.set04; import com.gempukku.lotro.cards.GenericCardTestHelper; import com.gempukku.lotro.common.*; import com.gempukku.lotro.game.CardNotFoundException; -import com.gempukku.lotro.game.PhysicalCardImpl; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; import org.junit.Test; @@ -18,8 +17,10 @@ public class Card_04_004_Tests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "4_4"); - // put other cards in here as needed for the test case + put("band", "4_4"); + + put("sam", "1_311"); + put("gimli", "1_13"); }}, GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, @@ -47,7 +48,7 @@ public class Card_04_004_Tests var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsCard("band"); assertEquals("Band of Wild Men", card.getBlueprint().getTitle()); assertNull(card.getBlueprint().getSubtitle()); @@ -62,18 +63,75 @@ public class Card_04_004_Tests assertEquals(3, card.getBlueprint().getSiteNumber()); } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void BandofWildMenTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void BandofWildMenBecomesFierceIfWinningSkirmishNormally() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var band = scn.GetShadowCard("band"); + scn.ShadowMoveCharToTable(band); + + var gimli = scn.GetFreepsCard("gimli"); + scn.FreepsMoveCharToTable(gimli); scn.StartGame(); - scn.FreepsPlayCard(card); + scn.SkipToAssignments(); + scn.FreepsAssignToMinions(gimli, band); + scn.FreepsResolveSkirmish(gimli); + scn.PassCurrentPhaseActions(); - assertEquals(5, scn.GetTwilight()); + assertFalse(scn.hasKeyword(band, Keyword.FIERCE)); + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); + assertTrue(scn.hasKeyword(band, Keyword.FIERCE)); + } + + @Test + public void BandofWildMenBecomesFierceIfWinningSkirmishWithOverwhelm() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var band = scn.GetShadowCard("band"); + scn.ShadowMoveCharToTable(band); + + var sam = scn.GetFreepsCard("sam"); + scn.FreepsMoveCharToTable(sam); + + scn.StartGame(); + scn.SkipToAssignments(); + scn.FreepsAssignToMinions(sam, band); + scn.FreepsResolveSkirmish(sam); + scn.PassCurrentPhaseActions(); + + assertFalse(scn.hasKeyword(band, Keyword.FIERCE)); + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); + assertTrue(scn.hasKeyword(band, Keyword.FIERCE)); + } + + @Test + public void BandofWildMenBecomesFierceIfWinningSkirmishKillsOpponentWithWound() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var band = scn.GetShadowCard("band"); + scn.ShadowMoveCharToTable(band); + + var gimli = scn.GetFreepsCard("gimli"); + scn.FreepsMoveCharToTable(gimli); + + scn.StartGame(); + + scn.AddWoundsToChar(gimli, 2); + + scn.SkipToAssignments(); + scn.FreepsAssignToMinions(gimli, band); + scn.FreepsResolveSkirmish(gimli); + scn.PassCurrentPhaseActions(); + + assertFalse(scn.hasKeyword(band, Keyword.FIERCE)); + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + scn.ShadowAcceptOptionalTrigger(); + assertTrue(scn.hasKeyword(band, Keyword.FIERCE)); } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set08/Card_08_119_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set08/Card_08_119_Tests.java index e70605c41..2e01ee293 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set08/Card_08_119_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set08/Card_08_119_Tests.java @@ -1,9 +1,9 @@ package com.gempukku.lotro.cards.official.set08; import com.gempukku.lotro.cards.GenericCardTestHelper; -import com.gempukku.lotro.common.*; +import com.gempukku.lotro.common.CardType; +import com.gempukku.lotro.common.Phase; import com.gempukku.lotro.game.CardNotFoundException; -import com.gempukku.lotro.game.PhysicalCardImpl; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; import org.junit.Test; @@ -18,10 +18,21 @@ public class Card_08_119_Tests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "8_119"); - // put other cards in here as needed for the test case + put("merry", "4_310"); + put("pippin", "4_314"); + put("sam", "1_311"); + }}, + new HashMap<>() {{ + put("site1", "7_330"); + put("site2", "7_335"); + put("site3", "8_117"); + put("site4", "7_342"); + put("site5", "8_119"); // + put("site6", "7_350"); + put("site7", "8_120"); + put("site8", "10_120"); + put("site9", "7_360"); }}, - GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, GenericCardTestHelper.RulingRing ); @@ -44,10 +55,7 @@ public class Card_08_119_Tests */ var scn = GetScenario(); - - //Use this once you have set the deck up properly - //var card = scn.GetFreepsSite(5); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsSite(5); assertEquals("Crashed Gate", card.getBlueprint().getTitle()); assertNull(card.getBlueprint().getSubtitle()); @@ -57,18 +65,134 @@ public class Card_08_119_Tests assertEquals(5, card.getBlueprint().getSiteNumber()); } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void CrashedGateTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void CrashedGateOffers3ThreatsChoiceWhenBothAvailable() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var site1 = scn.GetFreepsSite(1); + + //Threat limit is now 4 + scn.FreepsMoveCharToTable("sam", "merry", "pippin"); scn.StartGame(); - scn.FreepsPlayCard(card); + scn.SkipToSite(4); + scn.SkipToPhase(Phase.REGROUP); - assertEquals(7, scn.GetTwilight()); + assertEquals(0, scn.GetThreats()); + assertFalse(scn.IsSiteControlled(site1)); + assertEquals(2, scn.FreepsGetChoiceCount()); + assertTrue(scn.FreepsDecisionAvailable("Choose action to perform")); + + scn.FreepsChooseMultipleChoiceOption("threat"); + assertEquals(3, scn.GetThreats()); + assertFalse(scn.IsSiteControlled(site1)); + } + + @Test + public void CrashedGateOffersSiteControlChoiceWhenBothAvailable() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var site1 = scn.GetFreepsSite(1); + + //Threat limit is now 4 + scn.FreepsMoveCharToTable("sam", "merry", "pippin"); + + scn.StartGame(); + scn.SkipToSite(4); + scn.SkipToPhase(Phase.REGROUP); + + assertEquals(0, scn.GetThreats()); + assertFalse(scn.IsSiteControlled(site1)); + assertEquals(2, scn.FreepsGetChoiceCount()); + assertTrue(scn.FreepsDecisionAvailable("Choose action to perform")); + + scn.FreepsChooseMultipleChoiceOption("opponent"); + assertTrue(scn.ShadowDecisionAvailable("Would you like to take control of a site?")); + scn.ShadowChooseYes(); + assertEquals(0, scn.GetThreats()); + assertTrue(scn.IsSiteControlled(site1)); + } + + @Test + public void CrashedGateOffersOpponentChoiceWhenSiteControlNotAvailable() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var site1 = scn.GetFreepsSite(1); + + //Threat limit is now 4 + scn.FreepsMoveCharToTable("sam", "merry", "pippin"); + + scn.StartGame(); + scn.SkipToSite(4); + scn.FreepsPassCurrentPhaseAction(); + + scn.ShadowTakeControlOfSite(); + scn.ShadowTakeControlOfSite(); + scn.ShadowTakeControlOfSite(); + scn.SkipToPhase(Phase.REGROUP); + + assertEquals(0, scn.GetThreats()); + assertEquals(2, scn.FreepsGetChoiceCount()); + assertTrue(scn.FreepsDecisionAvailable("Choose action to perform")); + + scn.FreepsChooseMultipleChoiceOption("opponent"); + assertFalse(scn.ShadowDecisionAvailable("Would you like to take control of a site?")); + + assertTrue(scn.FreepsAnyDecisionsAvailable()); + } + + @Test + public void CrashedGateChoosesOpponentChoiceAutomaticallyWhen3ThreatsCantBeAdded() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var site1 = scn.GetFreepsSite(1); + + //Threat limit is now 4 + scn.FreepsMoveCharToTable("sam", "merry", "pippin"); + + scn.StartGame(); + scn.SkipToSite(4); + scn.FreepsPassCurrentPhaseAction(); + + //Only 2 threat slots left + scn.AddThreats(2); + scn.SkipToPhase(Phase.REGROUP); + + assertEquals(2, scn.GetThreats()); + assertFalse(scn.FreepsDecisionAvailable("Choose action to perform")); + assertTrue(scn.ShadowDecisionAvailable("Would you like to take control of a site?")); + + } + + @Test + public void CrashedGateChoosesOpponentChoiceAutomaticallyWhen3ThreatsCantBeAddedAndNoSiteAvailableToControl() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var site1 = scn.GetFreepsSite(1); + + //Threat limit is now 4 + scn.FreepsMoveCharToTable("sam", "merry", "pippin"); + + scn.StartGame(); + scn.SkipToSite(4); + scn.FreepsPassCurrentPhaseAction(); + + //Only 2 threat slots left + scn.AddThreats(2); + scn.ShadowTakeControlOfSite(); + scn.ShadowTakeControlOfSite(); + scn.ShadowTakeControlOfSite(); + scn.SkipToPhase(Phase.REGROUP); + + assertEquals(2, scn.GetThreats()); + assertFalse(scn.FreepsDecisionAvailable("Choose action to perform")); + assertFalse(scn.ShadowDecisionAvailable("Would you like to take control of a site?")); + + assertTrue(scn.FreepsAnyDecisionsAvailable()); } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set11/Card_11_060_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set11/Card_11_060_Tests.java index 4cf4739c7..4c347b619 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set11/Card_11_060_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set11/Card_11_060_Tests.java @@ -20,7 +20,7 @@ public class Card_11_060_Tests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "11_60"); + put("quality", "11_60"); // put other cards in here as needed for the test case }}, GenericCardTestHelper.FellowshipSites, @@ -41,12 +41,14 @@ public class Card_11_060_Tests * Twilight Cost: 2 * Type: Event * Subtype: Skirmish - * Game Text: Exert any number of [gondor] companions who have total resistance 12 or more to make a minion skirmishing a [gondor] companion strength -3 for each companion exerted this way. + * Game Text: Exert any number of [gondor] companions who have total resistance 12 + * or more to make a minion skirmishing a [gondor] companion strength -3 for each + * companion exerted this way. */ var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsCard("quality"); assertEquals("The Highest Quality", card.getBlueprint().getTitle()); assertNull(card.getBlueprint().getSubtitle()); @@ -58,17 +60,16 @@ public class Card_11_060_Tests assertEquals(2, card.getBlueprint().getTwilightCost()); } - // Uncomment any @Test markers below once this is ready to be used //@Test public void TheHighestQualityTest1() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); - - scn.StartGame(); - scn.FreepsPlayCard(card); + var quality = scn.GetFreepsCard("quality"); +// scn.FreepsMoveCardToHand(card); +// +// scn.StartGame(); +// scn.FreepsPlayCard(card); assertEquals(2, scn.GetTwilight()); } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set12/Card_12_184_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set12/Card_12_184_Tests.java index 40365c1a9..8aa9c9f2b 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set12/Card_12_184_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set12/Card_12_184_Tests.java @@ -23,6 +23,7 @@ public class Card_12_184_Tests put("fodder1", "1_302"); put("fodder2", "1_307"); + put("fodder3", "1_310"); }}, GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, @@ -76,7 +77,8 @@ public class Card_12_184_Tests var frodo = scn.GetRingBearer(); var fodder1 = scn.GetFreepsCard("fodder1"); var fodder2 = scn.GetFreepsCard("fodder2"); - scn.FreepsMoveCharToTable(fodder1, fodder2); + var fodder3 = scn.GetFreepsCard("fodder3"); + scn.FreepsMoveCharToTable(fodder1, fodder2, fodder3); scn.StartGame(); scn.SkipToPhase(Phase.ASSIGNMENT); @@ -103,8 +105,10 @@ public class Card_12_184_Tests assertEquals(Phase.ASSIGNMENT, scn.GetCurrentPhase()); scn.PassCurrentPhaseActions(); - scn.FreepsDeclineAssignments(); - scn.ShadowDeclineAssignments(); + scn.FreepsAssignToMinions(fodder3, twk); + scn.FreepsResolveSkirmish(fodder3); + assertEquals(Phase.SKIRMISH, scn.GetCurrentPhase()); + scn.PassCurrentPhaseActions(); assertEquals(Phase.REGROUP, scn.GetCurrentPhase()); } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set02/Card_02_076_ErrataTests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set02/Card_02_076_ErrataTests.java index dcd23b8e8..afcc6e598 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set02/Card_02_076_ErrataTests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set02/Card_02_076_ErrataTests.java @@ -3,7 +3,6 @@ package com.gempukku.lotro.cards.unofficial.pc.errata.set02; import com.gempukku.lotro.cards.GenericCardTestHelper; import com.gempukku.lotro.common.*; import com.gempukku.lotro.game.CardNotFoundException; -import com.gempukku.lotro.game.PhysicalCardImpl; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; import org.junit.Test; @@ -18,8 +17,10 @@ public class Card_02_076_ErrataTests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "52_76"); - // put other cards in here as needed for the test case + put("sam", "1_311"); + put("helpless", "52_76"); + put("toto", "10_68"); + put("nelya","1_233"); }}, GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, @@ -45,7 +46,7 @@ public class Card_02_076_ErrataTests var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsCard("helpless"); assertEquals("Helpless", card.getBlueprint().getTitle()); assertNull(card.getBlueprint().getSubtitle()); @@ -57,18 +58,96 @@ public class Card_02_076_ErrataTests assertEquals(1, card.getBlueprint().getTwilightCost()); } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void HelplessTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void HelplessBlocksSpecialAbilities() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var frodo = scn.GetRingBearer(); + var sam = scn.GetFreepsCard("sam"); + scn.FreepsMoveCharToTable(sam); + + var helpless = scn.GetShadowCard("helpless"); + var nelya = scn.GetShadowCard("nelya"); + scn.ShadowAttachCardsTo(sam, helpless); + scn.ShadowMoveCharToTable(nelya); scn.StartGame(); - scn.FreepsPlayCard(card); + //The Fellowship burden-removing special ability should be blocked + assertFalse(scn.FreepsActionAvailable(sam)); - assertEquals(1, scn.GetTwilight()); + scn.SkipToAssignments(); + scn.FreepsAssignToMinions(frodo, nelya); + scn.FreepsResolveSkirmish(frodo); + scn.PassCurrentPhaseActions(); + + //The Response ring-bearer special ability should also be blocked + assertFalse(scn.FreepsHasOptionalTriggerAvailable()); } + + @Test + public void HelplessDoesNotBlockAbilitiesWhileInSupportArea() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var frodo = scn.GetRingBearer(); + var sam = scn.GetFreepsCard("sam"); + scn.FreepsMoveCharToTable(sam); + + var helpless = scn.GetShadowCard("helpless"); + var nelya = scn.GetShadowCard("nelya"); + scn.ShadowMoveCardToSupportArea(helpless); + scn.ShadowMoveCharToTable(nelya); + + scn.StartGame(); + //The Fellowship burden-removing special ability should NOT be blocked + assertTrue(scn.FreepsActionAvailable(sam)); + + scn.SkipToAssignments(); + scn.FreepsAssignToMinions(frodo, nelya); + scn.FreepsResolveSkirmish(frodo); + scn.PassCurrentPhaseActions(); + + //The Response ring-bearer special ability should also NOT be blocked + assertTrue(scn.FreepsHasOptionalTriggerAvailable()); + } + + @Test + public void HelplessManeuverActionTransfersToRingBoundCompanion() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var frodo = scn.GetRingBearer(); + var sam = scn.GetFreepsCard("sam"); + scn.FreepsMoveCharToTable(sam); + + var helpless = scn.GetShadowCard("helpless"); + var toto = scn.GetShadowCard("toto"); + var nelya = scn.GetShadowCard("nelya"); + scn.ShadowMoveCardToSupportArea(helpless); + scn.ShadowMoveCharToTable(toto, nelya); + + scn.StartGame(); + + scn.SkipToPhase(Phase.MANEUVER); + scn.FreepsPassCurrentPhaseAction(); + + assertTrue(scn.ShadowActionAvailable(helpless)); + assertEquals(0, scn.GetWoundsOn(toto)); + assertEquals(0, scn.GetWoundsOn(nelya)); + assertEquals(Zone.SUPPORT, helpless.getZone()); + + scn.ShadowUseCardAction(helpless); + assertEquals(2, scn.ShadowGetCardChoiceCount()); + scn.ShadowChooseCard(toto); + assertEquals(1, scn.GetWoundsOn(toto)); + assertEquals(0, scn.GetWoundsOn(nelya)); + + //Can go on either Sam or Frodo + assertEquals(2, scn.ShadowGetCardChoiceCount()); + scn.ShadowChooseCard(frodo); + assertEquals(Zone.ATTACHED, helpless.getZone()); + assertEquals(frodo, helpless.getAttachedTo()); + } + }