diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/AdminRequestHandler.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/AdminRequestHandler.java index 3f359ac4c..2a9542d46 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/AdminRequestHandler.java +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/AdminRequestHandler.java @@ -473,7 +473,7 @@ public class AdminRequestHandler extends LotroServerRequestHandler implements Ur List maxMatchesStr = getFormMultipleParametersSafely(postDecoder, "maxMatches[]"); Throw400IfStringNull("name", name); - Throw400IfValidationFails("name", name, name.length() > 45, "League name must be 45 characters or less."); + Throw400IfValidationFails("name", name, name.length() <= 45, "League name must be 45 characters or less."); int cost = Throw400IfNullOrNonInteger("cost", costStr); if(startStr.length() != 8) throw new HttpProcessingException(400, "Parameter 'start' must be exactly 8 digits long: YYYYMMDD"); @@ -629,7 +629,7 @@ public class AdminRequestHandler extends LotroServerRequestHandler implements Ur Throw400IfStringNull("name", name); - Throw400IfValidationFails("name", name, name.length() > 45, "League name must be 45 characters or less."); + Throw400IfValidationFails("name", name, name.length() <= 45, "League name must be 45 characters or less."); int cost = Throw400IfNullOrNonInteger("cost", costStr); if(startStr.length() != 8) throw new HttpProcessingException(400, "Parameter 'start' must be exactly 8 digits long: YYYYMMDD"); @@ -780,7 +780,7 @@ public class AdminRequestHandler extends LotroServerRequestHandler implements Ur Throw400IfStringNull("name", name); - Throw400IfValidationFails("name", name, name.length() > 45, "League name must be 45 characters or less."); + Throw400IfValidationFails("name", name, name.length() <= 45, "League name must be 45 characters or less."); int cost = Throw400IfNullOrNonInteger("cost", costStr); if(startStr.length() != 8) throw new HttpProcessingException(400, "Parameter 'start' must be exactly 8 digits long: YYYYMMDD"); @@ -941,7 +941,7 @@ public class AdminRequestHandler extends LotroServerRequestHandler implements Ur var type = Tournament.TournamentType.parse(typeStr); Throw400IfValidationFails("type", typeStr, type != null); Throw400IfStringNull("name", name); - Throw400IfValidationFails("name", name, name.length() > 45, "Tournament name must be 45 characters or less."); + Throw400IfValidationFails("name", name, name.length() <= 45, "Tournament name must be 45 characters or less."); boolean wc = ParseBoolean("wc", wcStr, false); Throw400IfStringNull("tournamentId", tournamentId); Throw400IfStringNull("format", formatStr); diff --git a/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/communication.js b/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/communication.js index b77917e05..a5b9c257e 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/communication.js +++ b/gemp-lotr/gemp-lotr-async/src/main/web/js/gemp-022/communication.js @@ -165,7 +165,7 @@ var GempLotrCommunication = Class.extend({ }; }, - getStatus:function (callback) { + extractStatus:function (callback) { var that = this; return function (xml, status, request) { callback(xml, request.status); @@ -1314,7 +1314,7 @@ var GempLotrCommunication = Class.extend({ login:login, password:password, participantId:getUrlParam("participantId")}, - success:this.getStatus(callback), + success:this.extractStatus(callback), error:this.errorCheck(errorMap), dataType:"html" }); diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set06/set06-Dunland.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set06/set06-Dunland.hjson index 9a453e5cc..0c3362e26 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set06/set06-Dunland.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set06/set06-Dunland.hjson @@ -310,7 +310,7 @@ type: addKeyword select: memory(playedMan) keyword: damage - amount: 1 + amount: 2 until: regroup } ] diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set08/set08-Ringwraith.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set08/set08-Ringwraith.hjson index e16317d1c..1fd04c2c5 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set08/set08-Ringwraith.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set08/set08-Ringwraith.hjson @@ -521,7 +521,7 @@ } effect: { type: playCardFromDiscard - select: choose(culture(wraith),minion) + select: choose(culture(wraith),minion,not(self)) } } { diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set12/set12-Gandalf.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set12/set12-Gandalf.hjson index ee3a2d874..136061559 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set12/set12-Gandalf.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set12/set12-Gandalf.hjson @@ -379,7 +379,7 @@ culture: Gandalf twilight: 0 type: Condition - target: companion,not(hasAttached(name(Salve))) + target: companion,OnePerBearer keywords: Spell effects: [ { @@ -395,10 +395,17 @@ type: aboutToTakeWound filter: exhausted,bearer } - cost: { - type: discard - select: self - } + cost: [ + { + type: memorize + filter: bearer + memory: bearer + } + { + type: discard + select: self + } + ] effect: { type: preventWound select: memory(bearer) diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set17/set17-Rohan.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set17/set17-Rohan.hjson index d719aa534..b98b62df7 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set17/set17-Rohan.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set17/set17-Rohan.hjson @@ -449,7 +449,7 @@ requires: [ { type: CanSpot - filter: name(Frodo,AssignableToSkirmishAgainst(minion)) + filter: name(Frodo),AssignableToSkirmishAgainst(minion) } { type: CanSpot diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_moria.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_moria.hjson index 904981eb0..a080bdb31 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_moria.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_moria.hjson @@ -717,7 +717,7 @@ ] effect: { type: StackCardsFromDiscard - select: choose(tentacle) + select: choose(other,tentacle) count: 2 where: memory(stacker) } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV02/V2-Isengard.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV02/V2-Isengard.hjson index acd1f0c04..ff0efa5cb 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV02/V2-Isengard.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV02/V2-Isengard.hjson @@ -855,7 +855,7 @@ { type: modifier modifier: { - type: cancelKeywordBonus + type: RemoveKeyword filter: companion,inSkirmishAgainst(culture(isengard),orc) keyword: damage } diff --git a/gemp-lotr/gemp-lotr-common/src/main/java/com/gempukku/lotro/common/Keyword.java b/gemp-lotr/gemp-lotr-common/src/main/java/com/gempukku/lotro/common/Keyword.java index fa071e0b0..82bb81f24 100644 --- a/gemp-lotr/gemp-lotr-common/src/main/java/com/gempukku/lotro/common/Keyword.java +++ b/gemp-lotr/gemp-lotr-common/src/main/java/com/gempukku/lotro/common/Keyword.java @@ -115,4 +115,15 @@ public enum Keyword implements Filterable { public boolean isRealKeyword() { return realKeyword; } + + public static Keyword parse(String name) { + String nameCaps = name.toUpperCase().trim().replace(' ', '_').replace('-', '_'); + String nameLower = name.toLowerCase(); + + for (Keyword keyword : values()) { + if (keyword.getHumanReadable().toLowerCase().equals(nameLower) || keyword.toString().equals(nameCaps)) + return keyword; + } + return null; + } } 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 00cff5641..440915d3f 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 @@ -50,6 +50,12 @@ public class ResolveSkirmishEffect extends AbstractEffect { multiplier = game.getModifiersQuerying().getOverwhelmMultiplier(game, fellowshipCharacter); } + int shadowMult = 2; + for(var minion : skirmish.getShadowCharacters()) { + var mult = game.getModifiersQuerying().getOverwhelmMultiplier(game, minion); + shadowMult = Math.max(shadowMult, mult); + } + if (fpStrength == 0 && shadowStrength == 0) { return Result.FELLOWSHIP_LOSES; } else if (multiplier < CantBeOverwhelmedModifier.ImmuneToOverwhelmThreshold @@ -57,7 +63,7 @@ public class ResolveSkirmishEffect extends AbstractEffect { return Result.FELLOWSHIP_OVERWHELMED; } else if (fpStrength <= shadowStrength) { return Result.FELLOWSHIP_LOSES; - } else if (fpStrength >= 2 * shadowStrength) { + } else if (fpStrength >= shadowMult * shadowStrength) { return Result.SHADOW_OVERWHELMED; } else { return Result.SHADOW_LOSES; diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set12/Card_12_032_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set12/Card_12_032_Tests.java index 921a31dc0..e7319416e 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set12/Card_12_032_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set12/Card_12_032_Tests.java @@ -17,8 +17,11 @@ public class Card_12_032_Tests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "12_32"); - // put other cards in here as needed for the test case + put("salve", "12_32"); + put("aragorn", "1_89"); + + put("marksman", "1_176"); + }}, GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, @@ -38,12 +41,13 @@ public class Card_12_032_Tests * Twilight Cost: 0 * Type: Condition * Subtype: - * Game Text: Spell. To play, spot a [gandalf] Wizard. Bearer must be a companion. Limit 1 per bearer.
Response: If bearer is about to take a wound that would kill him or her, discard this condition to prevent that wound. + * Game Text: Spell. To play, spot a [gandalf] Wizard. Bearer must be a companion. Limit 1 per bearer. + * Response: If bearer is about to take a wound that would kill him or her, discard this condition to prevent that wound. */ var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsCard("salve"); assertEquals("Salve", card.getBlueprint().getTitle()); assertNull(card.getBlueprint().getSubtitle()); @@ -55,18 +59,34 @@ public class Card_12_032_Tests assertEquals(0, card.getBlueprint().getTwilightCost()); } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void SalveTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void SalveProtectsBearerFromLethalDamage() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var salve = scn.GetFreepsCard("salve"); + var aragorn = scn.GetFreepsCard("aragorn"); + scn.FreepsMoveCharToTable(aragorn); + scn.FreepsAttachCardsTo(aragorn, salve); + + scn.ShadowMoveCharToTable("marksman"); scn.StartGame(); - scn.FreepsPlayCard(card); + scn.AddWoundsToChar(aragorn, 3); + + scn.SkipToPhase(Phase.ARCHERY); + scn.PassCurrentPhaseActions(); + scn.FreepsChooseCard(aragorn); + + assertEquals(1, scn.GetVitality(aragorn)); + assertEquals(Zone.ATTACHED, salve.getZone()); + assertEquals(Zone.FREE_CHARACTERS, aragorn.getZone()); + assertTrue(scn.FreepsHasOptionalTriggerAvailable()); + scn.FreepsAcceptOptionalTrigger(); + + assertEquals(Zone.DISCARD, salve.getZone()); + assertEquals(Zone.FREE_CHARACTERS, aragorn.getZone()); + assertEquals(1, scn.GetVitality(aragorn)); - assertEquals(0, scn.GetTwilight()); } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set17/Card_17_096_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set17/Card_17_096_Tests.java index 81b9e66f1..cc535a435 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set17/Card_17_096_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set17/Card_17_096_Tests.java @@ -18,8 +18,8 @@ public class Card_17_096_Tests new HashMap<>() {{ put("eowyn", "17_96"); + put("scout", "1_270"); - put("soldier", "1_271"); }}, GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set17/Card_17_100_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set17/Card_17_100_Tests.java index 5de385637..818e9d3be 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set17/Card_17_100_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set17/Card_17_100_Tests.java @@ -17,8 +17,9 @@ public class Card_17_100_Tests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "17_100"); - // put other cards in here as needed for the test case + put("caves", "17_100"); + + put("sauron", "9_48"); }}, GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, @@ -38,12 +39,14 @@ public class Card_17_100_Tests * Twilight Cost: 1 * Type: Condition * Subtype: Support area - * Game Text: To play, spot 3 [rohan] companions.
Assignment: Assign a minion to Frodo to make that minion lose all game text keywords of your choice and unable to gain game text keywords until the regroup phase. + * Game Text: To play, spot 3 [rohan] companions. + * Assignment: Assign a minion to Frodo to make that minion lose all game text keywords of your choice + * and unable to gain game text keywords until the regroup phase. */ var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsCard("caves"); assertEquals("Into the Caves", card.getBlueprint().getTitle()); assertNull(card.getBlueprint().getSubtitle()); @@ -55,18 +58,48 @@ public class Card_17_100_Tests assertEquals(1, card.getBlueprint().getTwilightCost()); } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void IntotheCavesTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void IntotheCavesAssignsFrodoToMinionToRemoveKeywords() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var frodo = scn.GetRingBearer(); + var caves = scn.GetFreepsCard("caves"); + scn.FreepsMoveCardToSupportArea(caves); + + var sauron = scn.GetShadowCard("sauron"); + scn.ShadowMoveCharToTable(sauron); scn.StartGame(); - scn.FreepsPlayCard(card); - assertEquals(1, scn.GetTwilight()); + scn.SkipToPhase(Phase.ARCHERY); + scn.SkipToPhase(Phase.ASSIGNMENT); + assertTrue(scn.hasKeyword(sauron, Keyword.DAMAGE)); + assertTrue(scn.hasKeyword(sauron, Keyword.ENDURING)); + assertTrue(scn.hasKeyword(sauron, Keyword.FIERCE)); + assertFalse(scn.IsCharAssigned(frodo)); + assertFalse(scn.IsCharAssigned(sauron)); + assertTrue(scn.FreepsActionAvailable(caves)); + + scn.FreepsUseCardAction(caves); + assertTrue(scn.IsCharAssigned(frodo)); + assertTrue(scn.IsCharAssigned(sauron)); + + assertTrue(scn.FreepsDecisionAvailable("keyword")); + scn.FreepsChooseMultipleChoiceOption("DAMAGE"); + assertFalse(scn.hasKeyword(sauron, Keyword.DAMAGE)); + assertTrue(scn.hasKeyword(sauron, Keyword.ENDURING)); + assertTrue(scn.hasKeyword(sauron, Keyword.FIERCE)); + scn.FreepsChooseYes(); + scn.FreepsChooseMultipleChoiceOption("ENDURING"); + assertFalse(scn.hasKeyword(sauron, Keyword.DAMAGE)); + assertFalse(scn.hasKeyword(sauron, Keyword.ENDURING)); + assertTrue(scn.hasKeyword(sauron, Keyword.FIERCE)); + scn.FreepsChooseNo(); + assertFalse(scn.hasKeyword(sauron, Keyword.DAMAGE)); + assertFalse(scn.hasKeyword(sauron, Keyword.ENDURING)); + assertTrue(scn.hasKeyword(sauron, Keyword.FIERCE)); + + assertTrue(scn.ShadowAnyDecisionsAvailable()); } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/vsets/set_v02/Card_V2_026_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/vsets/set_v02/Card_V2_026_Tests.java index 6239283e7..ed2056a16 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/vsets/set_v02/Card_V2_026_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/vsets/set_v02/Card_V2_026_Tests.java @@ -3,7 +3,6 @@ package com.gempukku.lotro.cards.unofficial.pc.vsets.set_v02; 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_V2_026_Tests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "102_26"); - // put other cards in here as needed for the test case + put("grunt", "102_26"); + put("worker", "3_62"); + + put("mithrandir", "6_30"); }}, GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, @@ -47,7 +48,7 @@ public class Card_V2_026_Tests var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsCard("grunt"); assertEquals("Isengard Grunt", card.getBlueprint().getTitle()); assertNull(card.getBlueprint().getSubtitle()); @@ -62,18 +63,36 @@ public class Card_V2_026_Tests assertEquals(4, card.getBlueprint().getSiteNumber()); } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void IsengardGruntTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void IsengardGruntCanExertToPreventIsenorcOverwhelm() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var grunt = scn.GetShadowCard("grunt"); + var worker = scn.GetShadowCard("worker"); + scn.ShadowMoveCharToTable(grunt, worker); + + var mithrandir = scn.GetFreepsCard("mithrandir"); + scn.FreepsMoveCharToTable(mithrandir); scn.StartGame(); - scn.FreepsPlayCard(card); + scn.SkipToAssignments(); - assertEquals(2, scn.GetTwilight()); + scn.FreepsAssignToMinions(mithrandir, worker); + scn.ShadowDeclineAssignments(); + scn.FreepsResolveSkirmish(mithrandir); + + scn.FreepsPassCurrentPhaseAction(); + + assertEquals(0, scn.GetWoundsOn(grunt)); + assertTrue(scn.ShadowActionAvailable(grunt)); + scn.ShadowUseCardAction(grunt); + assertEquals(1, scn.GetWoundsOn(grunt)); + assertEquals(0, scn.GetWoundsOn(worker)); + assertEquals(Zone.SHADOW_CHARACTERS, worker.getZone()); + + scn.PassCurrentPhaseActions(); + assertEquals(Zone.SHADOW_CHARACTERS, worker.getZone()); + assertEquals(2, scn.GetWoundsOn(worker)); //Mithrandir is damage +1 } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/vsets/set_v02/Card_V2_029_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/vsets/set_v02/Card_V2_029_Tests.java index 2f2ab5c04..66b0e9ef5 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/vsets/set_v02/Card_V2_029_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/vsets/set_v02/Card_V2_029_Tests.java @@ -3,13 +3,13 @@ package com.gempukku.lotro.cards.unofficial.pc.vsets.set_v02; 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; import java.util.HashMap; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class Card_V2_029_Tests { @@ -18,8 +18,12 @@ public class Card_V2_029_Tests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "102_29"); - // put other cards in here as needed for the test case + put("saruman", "102_29"); + put("worker", "3_62"); + + put("legolas", "1_50"); + put("gimli", "1_13"); + put("axe", "1_14"); }}, GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, @@ -49,7 +53,7 @@ public class Card_V2_029_Tests var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsCard("saruman"); assertEquals("Saruman", card.getBlueprint().getTitle()); assertEquals("Mind of Metal and Wheels", card.getBlueprint().getSubtitle()); @@ -64,18 +68,84 @@ public class Card_V2_029_Tests assertEquals(4, card.getBlueprint().getSiteNumber()); } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void SarumanTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void SarumanCannotBeAssignedToSkirmishes() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var saruman = scn.GetShadowCard("saruman"); + scn.ShadowMoveCharToTable(saruman); + scn.ShadowMoveCharToTable("worker"); scn.StartGame(); - scn.FreepsPlayCard(card); + scn.SkipToAssignments(); + //Worker but not Saruman + assertEquals(1, scn.FreepsGetShadowAssignmentTargetCount()); + } - assertEquals(4, scn.GetTwilight()); + @Test + public void Saruman_CAN_TakeArcheryWounds() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var saruman = scn.GetShadowCard("saruman"); + scn.ShadowMoveCharToTable(saruman); + + scn.FreepsMoveCharToTable("legolas"); + + scn.StartGame(); + scn.SkipToArcheryWounds(); + + assertEquals(1, scn.GetWoundsOn(saruman)); + } + + @Test + public void SarumanNegatesAllDamageBonusesOnCompanionsSkirmishingIsenorcs() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var saruman = scn.GetShadowCard("saruman"); + var worker = scn.GetShadowCard("worker"); + scn.ShadowMoveCharToTable(saruman, worker); + + var gimli = scn.GetFreepsCard("gimli"); + var axe = scn.GetFreepsCard("axe"); + scn.FreepsMoveCharToTable(gimli); + scn.FreepsAttachCardsTo(gimli, axe); + + scn.StartGame(); + scn.SkipToAssignments(); + + assertEquals(2, scn.GetKeywordCount(gimli, Keyword.DAMAGE)); + scn.FreepsAssignToMinions(gimli, worker); + scn.FreepsResolveSkirmish(gimli); + assertEquals(0, scn.GetKeywordCount(gimli, Keyword.DAMAGE)); + scn.PassCurrentPhaseActions(); + scn.ShadowDeclineOptionalTrigger(); + assertEquals(1, scn.GetWoundsOn(worker)); + } + + @Test + public void SarumanCanExertToPreventWoundsToIsenorcs() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var saruman = scn.GetShadowCard("saruman"); + var worker = scn.GetShadowCard("worker"); + scn.ShadowMoveCharToTable(saruman, worker); + + scn.FreepsMoveCharToTable("legolas"); + + scn.StartGame(); + scn.SkipToArcheryWounds(); + + scn.ShadowChooseCard(worker); //archery wound + assertTrue(scn.ShadowHasOptionalTriggerAvailable()); + assertEquals(0, scn.GetWoundsOn(saruman)); + assertEquals(0, scn.GetWoundsOn(worker)); + + scn.ShadowAcceptOptionalTrigger(); + assertEquals(1, scn.GetWoundsOn(saruman)); + assertEquals(0, scn.GetWoundsOn(worker)); } }