diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set01/set01-Elven.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set01/set01-Elven.hjson index 2d19a9926..dc06eda10 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set01/set01-Elven.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set01/set01-Elven.hjson @@ -688,20 +688,17 @@ } true: { type: optional - text: Would you like to discard an ISENGARD minion revealed to draw 2 cards? + text: Would you like to discard an {ISENGARD} minion revealed to draw 2 cards? + cost: { + type: discardFromHand + hand: shadowPlayer + forced: true + player: you + select: choose(memory(revealedCards),culture(isengard),minion) + } effect: { - type: costToEffect - cost: { - type: discardFromHand - hand: shadowPlayer - forced: true - player: you - select: choose(memory(revealedCards),culture(isengard),minion) - } - effect: { - type: drawCards - count: 2 - } + type: drawCards + count: 2 } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set05/set05-Dunland.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set05/set05-Dunland.hjson index b21503dcd..5c04be4db 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set05/set05-Dunland.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set05/set05-Dunland.hjson @@ -28,19 +28,16 @@ type: optional player: fp text: Would you like to discard 2 cards from hand to discard Dunlending Rampager? + cost: { + type: discardFromHand + forced: false + player: fp + hand: fp + count: 2 + } effect: { - type: costToEffect - cost: { - type: discardFromHand - forced: false - player: fp - hand: fp - count: 2 - } - effect: { - type: discard - select: self - } + type: discard + select: self } } } @@ -84,19 +81,16 @@ type: optional player: fp text: Would you like to discard 2 cards from hand to discard Dunlending Rampager? + cost: { + type: discardFromHand + forced: false + player: fp + hand: fp + count: 2 + } effect: { - type: costToEffect - cost: { - type: discardFromHand - forced: false - player: fp - hand: fp - count: 2 - } - effect: { - type: discard - select: self - } + type: discard + select: self } } } @@ -204,19 +198,16 @@ type: optional player: fp text: Would you like to discard 4 cards from hand to discard Wild Men of the Hills? + cost: { + type: discardFromHand + forced: false + player: fp + hand: fp + count: 4 + } effect: { - type: costToEffect - cost: { - type: discardFromHand - forced: false - player: fp - hand: fp - count: 4 - } - effect: { - type: discard - select: self - } + type: discard + select: self } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Elven.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Elven.hjson index 6ebe762a5..8293b5e5a 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Elven.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Elven.hjson @@ -240,20 +240,17 @@ { type: optional text: Would you like to exert Glorfindel to make a Nazgul he is skirmishing strength -X, where X is the twilight cost the the card revealed? + cost: { + type: exert + select: self + } effect: { - type: costToEffect - cost: { - type: exert - select: self - } - effect: { - type: modifyStrength - select: choose(nazgul,inSkirmishAgainst(self)) - amount: { - type: twilightCostInMemory - memory: revealedCard - multiplier: -1 - } + type: modifyStrength + select: choose(nazgul,inSkirmishAgainst(self)) + amount: { + type: twilightCostInMemory + memory: revealedCard + multiplier: -1 } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Gandalf.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Gandalf.hjson index 727145e47..0d1098343 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Gandalf.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Gandalf.hjson @@ -168,17 +168,17 @@ type: optional player: shadowPlayer text: Would you like to discard 2 cards to draw 2 cards? + cost: { + type: discardFromHand + player: shadow + hand: shadow + forced: false + count: 2 + } effect: { - type: costToEffect - cost: { - type: discardFromHand - forced: false - count: 2 - } - effect: { - type: drawCards - count: 2 - } + type: drawCards + player: shadow + count: 2 } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Rohan.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Rohan.hjson index b86f4c039..6f6d98837 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Rohan.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set09/set09-Rohan.hjson @@ -80,19 +80,16 @@ } { type: optional - text: Would you like exert the played ROHAN Man to play a possession on him or her? + text: Would you like exert the played {ROHAN} Man to play a possession on him or her? + cost: { + type: exert + select: memory(playedRohanMan) + ignoreCostCheckFailure: true + } effect: { - type: costToEffect - cost: { - type: exert - select: memory(playedRohanMan) - ignoreCostCheckFailure: true - } - effect: { - type: PlayCardFromHand - select: choose(possession) - on: memory(playedRohanMan) - } + type: PlayCardFromHand + select: choose(possession) + on: memory(playedRohanMan) } } { diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set10/set10-Elven.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set10/set10-Elven.hjson index afcbdea1a..0662faf09 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set10/set10-Elven.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set10/set10-Elven.hjson @@ -199,19 +199,16 @@ } true: { type: optional - text: Discard the card? + text: Discard the card to wound each minion in this skirmish? + cost: { + type: discardCardsFromDrawDeck + select: memory(revealedCard) + showAll: false + shuffle: false + } effect: { - type: costToEffect - cost: { - type: discardCardsFromDrawDeck - select: memory(revealedCard) - showAll: false - shuffle: false - } - effect: { - type: wound - select: all(minion,inSkirmish) - } + type: wound + select: all(minion,inSkirmish) } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set11/set11-Gollum.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set11/set11-Gollum.hjson index fc900cc2d..186c2456a 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set11/set11-Gollum.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set11/set11-Gollum.hjson @@ -381,15 +381,12 @@ } { type: optional - text: Do you want to return it to hand? + text: Do you want to add a burden to return {self} to hand? + cost: { + type: addBurdens + } effect: { - type: costToEffect - cost: { - type: addBurdens - } - effect: { - type: putPlayedEventIntoHand - } + type: putPlayedEventIntoHand } } ] diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set11/set11-Men.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set11/set11-Men.hjson index 48ec6d2d4..428f97598 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set11/set11-Men.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set11/set11-Men.hjson @@ -1733,16 +1733,13 @@ true: { type: optional text: Would you like to remove (3) to wound {woundedCharacter} again? + cost: { + type: removeTwilight + amount: 3 + } effect: { - type: costToEffect - cost: { - type: removeTwilight - amount: 3 - } - effect: { - type: wound - select: memory(woundedCharacter) - } + type: wound + select: memory(woundedCharacter) } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set12/set12-Shire.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set12/set12-Shire.hjson index e4c74b7ca..a1eae1ebf 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set12/set12-Shire.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set12/set12-Shire.hjson @@ -349,17 +349,14 @@ } true: { type: optional - text: Would you like to discard 2 cards to return this event to your hand? + text: Would you like to discard 2 cards to return {self} to your hand? + cost: { + type: discardFromHand + forced: false + count: 2 + } effect: { - type: costToEffect - cost: { - type: discardFromHand - forced: false - count: 2 - } - effect: { - type: putPlayedEventIntoHand - } + type: putPlayedEventIntoHand } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Gollum.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Gollum.hjson index fcab88a08..85688d038 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Gollum.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Gollum.hjson @@ -856,15 +856,12 @@ effect: { type: optional text: Would you like to heal the Ring-beaer to add a burden? + cost: { + type: heal + select: choose(ringBearer) + } effect: { - type: costToEffect - cost: { - type: heal - select: choose(ringBearer) - } - effect: { - type: addBurdens - } + type: addBurdens } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Orc.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Orc.hjson index c619ff1c8..0523d7b34 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Orc.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Orc.hjson @@ -963,18 +963,15 @@ type: event cost: { type: optional - text: Would you like to remove 2 burdens? + text: Would you like to remove 2 burdens to add +4 more strength? + cost: { + type: removeBurdens + amount: 2 + } effect: { - type: costToEffect - cost: { - type: removeBurdens - amount: 2 - } - effect: { - type: MemorizeInfo - memory: removedBurdens - info: yes - } + type: MemorizeInfo + memory: removedBurdens + info: yes } } effect: [ diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Rohan.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Rohan.hjson index 27727af1f..ce864a128 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Rohan.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set13/set13-Rohan.hjson @@ -740,10 +740,8 @@ } true: { type: optional - text: Would you like to exert Théoden? - effect: { - type: costToEffect - cost: { + text: Would you like to exert Théoden to add +3 strength and damage +1? + cost: { type: exert select: choose(name(Théoden)) } @@ -752,7 +750,6 @@ memory: exertedTheoden info: yes } - } } } { diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set18/set18-Orc.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set18/set18-Orc.hjson index 0e114bc1b..ed982d32f 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set18/set18-Orc.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set18/set18-Orc.hjson @@ -671,31 +671,28 @@ type: optional player: free people text: Would you like to add a burden or exert the Ring-bearer twice to discard Orkish Sneak? + cost: { + type: choice + player: free people + texts: [ + Add a burden + Exert the Ring-bearer twice + ] + effects: [ + { + type: addBurdens + } + { + type: exert + select: choose(ringBearer) + times: 2 + } + ] + } effect: { - type: costToEffect - cost: { - type: choice - player: free people - texts: [ - Add a burden - Exert the Ring-bearer twice - ] - effects: [ - { - type: addBurdens - } - { - type: exert - select: choose(ringBearer) - times: 2 - } - ] - } - effect: { - type: discard - player: free people - select: self - } + type: discard + player: free people + select: self } } ] diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set19/set19-Sauron.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set19/set19-Sauron.hjson index fe13e5c8a..26db65749 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set19/set19-Sauron.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/official/set19/set19-Sauron.hjson @@ -25,15 +25,12 @@ } { type: optional - text: Would you like to remove (1) to place this event on the bottom of your draw deck? + text: Would you like to remove (1) to place {self} on the bottom of your draw deck? + cost: { + type: removeTwilight + } effect: { - type: costToEffect - cost: { - type: removeTwilight - } - effect: { - type: putPlayedEventOnBottomOfDrawDeck - } + type: putPlayedEventOnBottomOfDrawDeck } } ] diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/hobbit/set30/set30-shadow.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/hobbit/set30/set30-shadow.hjson index c657a5e79..7a290d084 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/hobbit/set30/set30-shadow.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/hobbit/set30/set30-shadow.hjson @@ -281,17 +281,14 @@ { type: optional player: fp - text: Would you like to add a burden to discard this minion? + text: Would you like to add a burden to discard {self}? + cost: { + type: addBurdens + amount: 1 + } effect: { - type: costToEffect - cost: { - type: addBurdens - amount: 1 - } - effect: { - type: discard - select: self - } + type: discard + select: self } } ] diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/hobbit/set32/set32-shadow.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/hobbit/set32/set32-shadow.hjson index c5bc679f3..6ad0a7d99 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/hobbit/set32/set32-shadow.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/hobbit/set32/set32-shadow.hjson @@ -1133,10 +1133,8 @@ } { type: optional - text: Would you like to discard 2 Orcs to take this event back into hand? - effect: { - type: costToEffect - cost: { + text: Would you like to discard 2 Orcs to take {self} back into hand? + cost: { type: discard select: choose(orc) count: 2 @@ -1144,7 +1142,6 @@ effect: { type: putPlayedEventIntoHand } - } } ] } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set02/set02-Elven-errata.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set02/set02-Elven-errata.hjson index 2b96a8de4..7cc5bcbb1 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set02/set02-Elven-errata.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set02/set02-Elven-errata.hjson @@ -47,17 +47,14 @@ type: Optional player: you text: Would you like to exert another Elf ally to discard another condition? + cost: { + type: exert + select: choose(Elf,ally,not(memory(firstAlly))) + } effect: { - type: CostToEffect - cost: { - type: exert - select: choose(Elf,ally,not(memory(firstAlly))) - } - effect: { - type: Discard - count: 1 - select: choose(condition) - } + type: Discard + count: 1 + select: choose(condition) } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set09/set09-Elven-errata.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set09/set09-Elven-errata.hjson index 2fb708b4f..32162516e 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set09/set09-Elven-errata.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set09/set09-Elven-errata.hjson @@ -152,20 +152,17 @@ { type: optional text: Would you like to exert Glorfindel to make a Nazgul he is skirmishing strength -X, where X is the twilight cost the the card revealed? + cost: { + type: exert + select: self + } effect: { - type: costToEffect - cost: { - type: exert - select: self - } - effect: { - type: modifyStrength - select: choose(nazgul,inSkirmishAgainst(self)) - amount: { - type: twilightCostInMemory - memory: revealedCard - multiplier: -1 - } + type: modifyStrength + select: choose(nazgul,inSkirmishAgainst(self)) + amount: { + type: twilightCostInMemory + memory: revealedCard + multiplier: -1 } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set09/set09-Gandalf-errata.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set09/set09-Gandalf-errata.hjson index fec3c086b..1526772e0 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set09/set09-Gandalf-errata.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set09/set09-Gandalf-errata.hjson @@ -19,7 +19,6 @@ twilight: 4 type: Companion race: Wizard - #keyword: damage+1 strength: 7 vitality: 4 signet: Gandalf @@ -42,17 +41,17 @@ type: optional player: shadowPlayer text: Would you like to discard 2 cards to draw 2 cards? + cost: { + type: discardFromHand + player: shadow + hand: shadow + forced: false + count: 2 + } effect: { - type: costToEffect - cost: { - type: discardFromHand - forced: false - count: 2 - } - effect: { - type: drawCards - count: 2 - } + type: drawCards + player: shadow + count: 2 } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set13/set13-Sites-errata.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set13/set13-Sites-errata.hjson index 755881a5b..9e9d3949c 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set13/set13-Sites-errata.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/errata/set13/set13-Sites-errata.hjson @@ -30,18 +30,15 @@ type: optional player: shadow text: Would you like to discard 2 cards from hand to add a burden? + cost: { + type: discardFromHand + hand: shadowPlayer + player: shadowPlayer + forced: false + count: 2 + } effect: { - type: costToEffect - cost: { - type: discardFromHand - hand: shadowPlayer - player: shadowPlayer - forced: false - count: 2 - } - effect: { - type: addBurdens - } + type: addBurdens } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_gandalf.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_gandalf.hjson index a17e06232..c7b57f4a8 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_gandalf.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV01/V1_gandalf.hjson @@ -29,24 +29,21 @@ } effect: { type: optional - text: Would you like to pay this card's twilight cost to take it into hand? + text: Would you like to pay {chosenAlly} twilight cost to take it into hand? + cost: { + type: addtwilight + amount: { + type: twilightCostInMemory + memory: chosenAlly + } + } effect: { - type: costToEffect - cost: { - type: addtwilight - amount: { - type: twilightCostInMemory - memory: chosenAlly - } - } - effect: { - type: putcardsfromdeckintohand - count: 1 - select: memory(chosenAlly) - reveal: true - shuffle: false - showAll: false - } + type: putcardsfromdeckintohand + count: 1 + select: memory(chosenAlly) + reveal: true + shuffle: false + showAll: false } } } diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV02/V2-Sites.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV02/V2-Sites.hjson index e39c221cb..5f5f2df9b 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV02/V2-Sites.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/cards/unofficial/pc/setV02/V2-Sites.hjson @@ -32,18 +32,15 @@ effect: { type: Optional text: Would you like to discard 2 cards to draw 2? + cost: { + type: DiscardFromHand + forced: false + select: choose(any) + count: 2 + } effect: { - type: CostToEffect - cost: { - type: DiscardFromHand - forced: false - select: choose(any) - count: 2 - } - effect: { - type: DrawCards - count: 2 - } + type: DrawCards + count: 2 } } } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/CostToEffect.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/CostToEffect.java index 56b654203..ac3ce7d9c 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/CostToEffect.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/CostToEffect.java @@ -70,6 +70,16 @@ public class CostToEffect implements EffectAppenderProducer { return true; } + + @Override + public boolean isPlayabilityCheckedForEffect() { + //This is done intentinally, even though one would think that you would want to + // check the "cost" part of "CostToEffect". The reason for this is because CostToEffect + // is frequently used as a wrapper in contexts where the Cost cannot actually be checked + // ahead of time, such as when memory values are crucial to the execution (which of course + // are not popuulated before the action itself is executed at time of checking). + return false; + } }; } } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Optional.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Optional.java index 3ac025d13..b7eb62716 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Optional.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/cards/build/field/effect/appender/Optional.java @@ -17,31 +17,43 @@ import org.json.simple.JSONObject; public class Optional implements EffectAppenderProducer { @Override public EffectAppender createEffectAppender(boolean cost, JSONObject effectObject, CardGenerationEnvironment environment) throws InvalidCardDefinitionException { - FieldUtils.validateAllowedFields(effectObject, "player", "text", "effect"); + FieldUtils.validateAllowedFields(effectObject, "player", "text", "requires", "cost", "effect"); final String player = FieldUtils.getString(effectObject.get("player"), "player", "you"); final String text = FieldUtils.getString(effectObject.get("text"), "text"); + final JSONObject[] costArray = FieldUtils.getObjectArray(effectObject.get("cost"), "cost"); final JSONObject[] effectArray = FieldUtils.getObjectArray(effectObject.get("effect"), "effect"); + final JSONObject[] requiresArray = FieldUtils.getObjectArray(effectObject.get("requires"), "requires"); if (text == null) throw new InvalidCardDefinitionException("There is a text required for optional effects"); final PlayerSource playerSource = PlayerResolver.resolvePlayer(player); + final EffectAppender[] costAppenders = environment.getEffectAppenderFactory().getEffectAppenders(true, costArray, environment); final EffectAppender[] effectAppenders = environment.getEffectAppenderFactory().getEffectAppenders(cost, effectArray, environment); + final Requirement[] requirements = environment.getRequirementFactory().getRequirements(requiresArray, environment); return new DelayedAppender() { @Override protected Effect createEffect(boolean cost, CostToEffectAction action, ActionContext actionContext) { final String choosingPlayer = playerSource.getPlayer(actionContext); + ActionContext delegate = new DelegateActionContext(actionContext, + choosingPlayer, actionContext.getGame(), actionContext.getSource(), + actionContext.getEffectResult(), actionContext.getEffect()); + + if(!isPlayableInFull(actionContext)) + return null; + SubAction subAction = new SubAction(action); + subAction.appendCost( new PlayoutDecisionEffect(choosingPlayer, new YesNoDecision(GameUtils.substituteText(text, actionContext)) { @Override protected void yes() { - ActionContext delegate = new DelegateActionContext(actionContext, - choosingPlayer, actionContext.getGame(), actionContext.getSource(), - actionContext.getEffectResult(), actionContext.getEffect()); + for (EffectAppender costAppender : costAppenders) + costAppender.appendEffect(true, subAction, actionContext); + for (EffectAppender effectAppender : effectAppenders) { effectAppender.appendEffect(cost, subAction, delegate); } @@ -56,8 +68,18 @@ public class Optional implements EffectAppenderProducer { ActionContext delegate = new DelegateActionContext(actionContext, choosingPlayer, actionContext.getGame(), actionContext.getSource(), actionContext.getEffectResult(), actionContext.getEffect()); + + if(!checkRequirements(delegate)) + return false; + + for (EffectAppender costAppender : costAppenders) { + if (!costAppender.isPlayableInFull(delegate)) + return false; + } + for (EffectAppender effectAppender : effectAppenders) { - if (!effectAppender.isPlayableInFull(delegate)) + if (effectAppender.isPlayabilityCheckedForEffect() + && !effectAppender.isPlayableInFull(delegate)) return false; } @@ -72,6 +94,14 @@ public class Optional implements EffectAppenderProducer { } return false; } + + private boolean checkRequirements(ActionContext actionContext) { + for (Requirement req : requirements) { + if (!req.accepts(actionContext)) + return false; + } + return true; + } }; } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/ExertAtTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/ExertAtTest.java index ce420bb27..04cfe88df 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/ExertAtTest.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/at/ExertAtTest.java @@ -55,7 +55,7 @@ public class ExertAtTest extends AbstractAtTest{ // Pass on viewing revealed card playerDecided(P2, ""); // Can't exert (already exhausted) - playerDecided(P1, "0"); + //playerDecided(P1, "0"); assertEquals(10, _game.getModifiersQuerying().getStrength(_game, cantea)); } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set05/Card_05_001_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set05/Card_05_001_Tests.java index f80a74cc2..4ab803ee7 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set05/Card_05_001_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set05/Card_05_001_Tests.java @@ -3,7 +3,6 @@ package com.gempukku.lotro.cards.official.set05; 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,7 +17,7 @@ public class Card_05_001_Tests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "5_1"); + put("rampager", "5_1"); // put other cards in here as needed for the test case }}, GenericCardTestHelper.FellowshipSites, @@ -47,7 +46,7 @@ public class Card_05_001_Tests var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsCard("rampager"); assertEquals("Dunlending Rampager", card.getBlueprint().getTitle()); assertNull(card.getBlueprint().getSubtitle()); @@ -62,18 +61,21 @@ public class Card_05_001_Tests assertEquals(3, card.getBlueprint().getSiteNumber()); } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void DunlendingRampagerTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void DunlendingRampagerDoesNotOfferChoiceWhenNotEnoughCardsInFreepsHand() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var rampager = scn.GetShadowCard("rampager"); + scn.ShadowMoveCardToHand(rampager); scn.StartGame(); - scn.FreepsPlayCard(card); + scn.FreepsPassCurrentPhaseAction(); + assertTrue(scn.ShadowPlayAvailable(rampager)); + scn.ShadowPlayCard(rampager); - assertEquals(1, scn.GetTwilight()); + assertEquals(Zone.SHADOW_CHARACTERS, rampager.getZone()); + assertEquals(0, scn.GetFreepsHandCount()); + assertFalse(scn.FreepsDecisionAvailable("Would you like to discard 2 cards from hand to discard Dunlending Rampager?")); } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set11/Card_11_104_Tests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set11/Card_11_104_Tests.java index 614e098c7..8f4e53c83 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set11/Card_11_104_Tests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/official/set11/Card_11_104_Tests.java @@ -1,12 +1,11 @@ package com.gempukku.lotro.cards.official.set11; import com.gempukku.lotro.cards.GenericCardTestHelper; -import com.gempukku.lotro.common.CardType; -import com.gempukku.lotro.common.Culture; -import com.gempukku.lotro.common.Side; -import com.gempukku.lotro.common.Timeword; +import com.gempukku.lotro.common.*; +import com.gempukku.lotro.filters.Filters; import com.gempukku.lotro.game.CardNotFoundException; import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException; +import com.gempukku.lotro.logic.modifiers.AddKeywordModifier; import org.junit.Test; import java.util.HashMap; @@ -20,8 +19,8 @@ public class Card_11_104_Tests return new GenericCardTestHelper( new HashMap<>() {{ - put("card", "11_104"); - // put other cards in here as needed for the test case + put("death", "11_104"); + put("mouth", "12_73"); }}, GenericCardTestHelper.FellowshipSites, GenericCardTestHelper.FOTRFrodo, @@ -41,12 +40,13 @@ public class Card_11_104_Tests * Twilight Cost: 3 * Type: Event * Subtype: Skirmish - * Game Text: Wound a character skirmishing a [men] minion. If the fellowship is at a battleground site, you may remove (3) to wound that character again. + * Game Text: Wound a character skirmishing a [men] minion. + * If the fellowship is at a battleground site, you may remove (3) to wound that character again. */ var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); + var card = scn.GetFreepsCard("death"); assertEquals("Whistling Death", card.getBlueprint().getTitle()); assertNull(card.getBlueprint().getSubtitle()); @@ -58,18 +58,117 @@ public class Card_11_104_Tests assertEquals(3, card.getBlueprint().getTwilightCost()); } - // Uncomment any @Test markers below once this is ready to be used - //@Test - public void WhistlingDeathTest1() throws DecisionResultInvalidException, CardNotFoundException { + @Test + public void WhistlingDeathWoundsThenRemoves3MoreToWoundAgain() throws DecisionResultInvalidException, CardNotFoundException { //Pre-game setup var scn = GetScenario(); - var card = scn.GetFreepsCard("card"); - scn.FreepsMoveCardToHand(card); + var death = scn.GetShadowCard("death"); + var mouth = scn.GetShadowCard("mouth"); + scn.ShadowMoveCharToTable(mouth); + scn.ShadowMoveCardToHand(death); + + var frodo = scn.GetRingBearer(); + + //cheating to ensure site 2 qualifies + scn.ApplyAdHocModifier(new AddKeywordModifier(null, Filters.siteNumber(2), null, Keyword.BATTLEGROUND)); scn.StartGame(); - scn.FreepsPlayCard(card); - assertEquals(3, scn.GetTwilight()); + scn.SetTwilight(7); + scn.FreepsPassCurrentPhaseAction(); + scn.SkipToAssignments(); + scn.FreepsAssignToMinions(frodo, mouth); + scn.FreepsResolveSkirmish(frodo); + scn.FreepsPassCurrentPhaseAction(); + + assertEquals(0, scn.GetWoundsOn(frodo)); + assertEquals(10, scn.GetTwilight()); + assertTrue(scn.hasKeyword(scn.GetCurrentSite(), Keyword.BATTLEGROUND)); + assertTrue(scn.ShadowPlayAvailable(death)); + + scn.ShadowPlayCard(death); + scn.FreepsDeclineOptionalTrigger(); //the one ring + assertEquals(1, scn.GetWoundsOn(frodo)); + assertEquals(7, scn.GetTwilight()); + + assertTrue(scn.ShadowDecisionAvailable("Would you like to remove (3) to wound")); + scn.ShadowChooseYes(); + scn.FreepsDeclineOptionalTrigger(); //the one ring + assertEquals(2, scn.GetWoundsOn(frodo)); + assertEquals(4, scn.GetTwilight()); + } + + @Test + public void WhistlingDeathSecondWoundIsNotOfferedAtNonBattleground() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var death = scn.GetShadowCard("death"); + var mouth = scn.GetShadowCard("mouth"); + scn.ShadowMoveCharToTable(mouth); + scn.ShadowMoveCardToHand(death); + + var frodo = scn.GetRingBearer(); + + scn.StartGame(); + + scn.SetTwilight(7); + scn.FreepsPassCurrentPhaseAction(); + scn.SkipToAssignments(); + scn.FreepsAssignToMinions(frodo, mouth); + scn.FreepsResolveSkirmish(frodo); + scn.FreepsPassCurrentPhaseAction(); + + assertEquals(0, scn.GetWoundsOn(frodo)); + assertEquals(10, scn.GetTwilight()); + assertFalse(scn.hasKeyword(scn.GetCurrentSite(), Keyword.BATTLEGROUND)); + assertTrue(scn.ShadowPlayAvailable(death)); + + scn.ShadowPlayCard(death); + scn.FreepsDeclineOptionalTrigger(); //the one ring + assertEquals(1, scn.GetWoundsOn(frodo)); + assertEquals(7, scn.GetTwilight()); + + assertFalse(scn.ShadowDecisionAvailable("Would you like to remove (3) to wound")); + assertTrue(scn.FreepsAnyDecisionsAvailable()); + } + + @Test + public void WhistlingDeathSecondWoundIsNotOfferedWhenLessThan3TwilightAvailable() throws DecisionResultInvalidException, CardNotFoundException { + //Pre-game setup + var scn = GetScenario(); + + var death = scn.GetShadowCard("death"); + var mouth = scn.GetShadowCard("mouth"); + scn.ShadowMoveCharToTable(mouth); + scn.ShadowMoveCardToHand(death); + + var frodo = scn.GetRingBearer(); + + //cheating to ensure site 2 qualifies + scn.ApplyAdHocModifier(new AddKeywordModifier(null, Filters.siteNumber(2), null, Keyword.BATTLEGROUND)); + + scn.StartGame(); + + scn.SetTwilight(2); + scn.FreepsPassCurrentPhaseAction(); + scn.SkipToAssignments(); + scn.FreepsAssignToMinions(frodo, mouth); + scn.FreepsResolveSkirmish(frodo); + scn.FreepsPassCurrentPhaseAction(); + + assertEquals(0, scn.GetWoundsOn(frodo)); + assertEquals(5, scn.GetTwilight()); + assertTrue(scn.hasKeyword(scn.GetCurrentSite(), Keyword.BATTLEGROUND)); + assertTrue(scn.ShadowPlayAvailable(death)); + + scn.ShadowPlayCard(death); + scn.FreepsDeclineOptionalTrigger(); //the one ring + assertEquals(1, scn.GetWoundsOn(frodo)); + assertEquals(2, scn.GetTwilight()); + + assertFalse(scn.ShadowDecisionAvailable("Would you like to remove (3) to wound")); + assertTrue(scn.FreepsAnyDecisionsAvailable()); } } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set18/Card_18_134_ErrataTests.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set18/Card_18_134_ErrataTests.java index 04e02489e..7bae4a11d 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set18/Card_18_134_ErrataTests.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/unofficial/pc/errata/set18/Card_18_134_ErrataTests.java @@ -137,7 +137,7 @@ public class Card_18_134_ErrataTests assertTrue(scn.FreepsPlayAvailable(onegoodturn)); scn.FreepsPlayCard(onegoodturn); //This ensures that we have skipped over choosing a site and instead OGT has moved on to its other clause. - assertTrue(scn.FreepsDecisionAvailable("Do you want to return")); + assertTrue(scn.FreepsDecisionAvailable("Do you want to add a burden")); assertNotEquals(scn.GetSite(3), freepsSite3); assertEquals(scn.GetSite(3), doorway);